mirror of
https://github.com/leon-ai/leon.git
synced 2024-09-11 10:25:40 +03:00
refactor(server): string helper from singleton to static
This commit is contained in:
parent
1a4e09f908
commit
9065d713e9
@ -5,7 +5,7 @@ import { prompt } from 'inquirer'
|
||||
import path from 'path'
|
||||
|
||||
import { LOG } from '@/helpers/log'
|
||||
import { STRING } from '@/helpers/string'
|
||||
import { StringHelper } from '@/helpers/string-helper'
|
||||
|
||||
dotenv.config()
|
||||
|
||||
@ -19,7 +19,7 @@ const generateHttpApiKey = () =>
|
||||
|
||||
try {
|
||||
const shasum = crypto.createHash('sha1')
|
||||
const str = STRING.random(11)
|
||||
const str = StringHelper.random(11)
|
||||
const dotEnvPath = path.join(process.cwd(), '.env')
|
||||
const envVarKey = 'LEON_HTTP_API_KEY'
|
||||
let content = fs.readFileSync(dotEnvPath, 'utf8')
|
||||
|
@ -3,7 +3,7 @@ import fs from 'fs'
|
||||
import { composeFromPattern } from '@nlpjs/utils'
|
||||
|
||||
import { LOG } from '@/helpers/log'
|
||||
import { STRING } from '@/helpers/string'
|
||||
import { StringHelper } from '@/helpers/string-helper'
|
||||
import { SKILL_DOMAIN } from '@/helpers/skill-domain'
|
||||
|
||||
/**
|
||||
@ -111,7 +111,7 @@ export default (lang, nlp) =>
|
||||
for (let l = 0; l < answers?.length; l += 1) {
|
||||
const variableKeys = Object.keys(variablesObj)
|
||||
if (variableKeys.length > 0) {
|
||||
answers[l] = STRING.findAndMap(answers[l], variablesObj)
|
||||
answers[l] = StringHelper.findAndMap(answers[l], variablesObj)
|
||||
}
|
||||
|
||||
nlp.addAnswer(lang, `${skillName}.${actionName}`, answers[l])
|
||||
|
@ -5,7 +5,7 @@ import { spawn } from 'child_process'
|
||||
import { langs } from '@@/core/langs.json'
|
||||
import { HAS_TTS } from '@/constants'
|
||||
import { LOG } from '@/helpers/log'
|
||||
import { STRING } from '@/helpers/string'
|
||||
import { StringHelper } from '@/helpers/string-helper'
|
||||
import { LANG } from '@/helpers/lang'
|
||||
import { SKILL_DOMAIN } from '@/helpers/skill-domain'
|
||||
import Synchronizer from '@/core/synchronizer'
|
||||
@ -129,7 +129,7 @@ class Brain {
|
||||
|
||||
// Parse sentence's value(s) and replace with the given object
|
||||
if (typeof obj !== 'undefined' && Object.keys(obj).length > 0) {
|
||||
answer = STRING.findAndMap(answer, obj)
|
||||
answer = StringHelper.findAndMap(answer, obj)
|
||||
}
|
||||
|
||||
return answer
|
||||
@ -146,7 +146,7 @@ class Brain {
|
||||
}
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const utteranceId = `${Date.now()}-${STRING.random(4)}`
|
||||
const utteranceId = `${Date.now()}-${StringHelper.random(4)}`
|
||||
const intentObjectPath = path.join(
|
||||
__dirname,
|
||||
`../tmp/${utteranceId}.json`
|
||||
@ -450,7 +450,7 @@ class Brain {
|
||||
*/
|
||||
if (utteranceHasEntities && answer.indexOf('{{') !== -1) {
|
||||
obj.currentEntities.forEach((entityObj) => {
|
||||
answer = STRING.findAndMap(answer, {
|
||||
answer = StringHelper.findAndMap(answer, {
|
||||
[`{{ ${entityObj.entity} }}`]: entityObj.resolution.value
|
||||
})
|
||||
|
||||
@ -469,7 +469,7 @@ class Brain {
|
||||
const valuesArr =
|
||||
entities[entity].options[entityObj.option].data[dataKey]
|
||||
|
||||
answer = STRING.findAndMap(answer, {
|
||||
answer = StringHelper.findAndMap(answer, {
|
||||
[match]:
|
||||
valuesArr[Math.floor(Math.random() * valuesArr.length)]
|
||||
})
|
||||
|
@ -3,7 +3,7 @@ import path from 'path'
|
||||
import archiver from 'archiver'
|
||||
|
||||
import { LOG } from '@/helpers/log'
|
||||
import { STRING } from '@/helpers/string'
|
||||
import { StringHelper } from '@/helpers/string-helper'
|
||||
|
||||
const getDownloads = async (fastify, options) => {
|
||||
fastify.get(`/api/${options.apiVersion}/downloads`, (request, reply) => {
|
||||
@ -28,12 +28,12 @@ const getDownloads = async (fastify, options) => {
|
||||
const skill = path.join(dlDomainDir, `${request.query.skill}.py`)
|
||||
|
||||
LOG.info(
|
||||
`Checking existence of the ${STRING.ucFirst(
|
||||
`Checking existence of the ${StringHelper.ucFirst(
|
||||
request.query.skill
|
||||
)} skill...`
|
||||
)
|
||||
if (fs.existsSync(skill)) {
|
||||
LOG.success(`${STRING.ucFirst(request.query.skill)} skill exists`)
|
||||
LOG.success(`${StringHelper.ucFirst(request.query.skill)} skill exists`)
|
||||
const downloadsDir = `${dlDomainDir}/${request.query.skill}`
|
||||
|
||||
LOG.info('Reading downloads directory...')
|
||||
|
@ -6,7 +6,7 @@
|
||||
import fs from 'fs'
|
||||
|
||||
import { LOG } from '@/helpers/log'
|
||||
import { STRING } from '@/helpers/string'
|
||||
import { StringHelper } from '@/helpers/string-helper'
|
||||
|
||||
class Ner {
|
||||
constructor(ner) {
|
||||
@ -34,7 +34,7 @@ class Ner {
|
||||
|
||||
const { classification } = obj
|
||||
// Remove end-punctuation and add an end-whitespace
|
||||
const utterance = `${STRING.removeEndPunctuation(obj.utterance)} `
|
||||
const utterance = `${StringHelper.removeEndPunctuation(obj.utterance)} `
|
||||
const { actions } = JSON.parse(
|
||||
fs.readFileSync(utteranceSamplesFilePath, 'utf8')
|
||||
)
|
||||
@ -116,7 +116,7 @@ class Ner {
|
||||
return new Promise((resolve) => {
|
||||
for (let j = 0; j < entity.conditions.length; j += 1) {
|
||||
const condition = entity.conditions[j]
|
||||
const conditionMethod = `add${STRING.snakeToPascalCase(
|
||||
const conditionMethod = `add${StringHelper.snakeToPascalCase(
|
||||
condition.type
|
||||
)}Condition`
|
||||
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
} from '@/constants'
|
||||
import Ner from '@/core/ner'
|
||||
import { LOG } from '@/helpers/log'
|
||||
import { STRING } from '@/helpers/string'
|
||||
import { StringHelper } from '@/helpers/string-helper'
|
||||
import { LANG } from '@/helpers/lang'
|
||||
import TcpClient from '@/core/tcp-client'
|
||||
import Conversation from '@/core/conversation'
|
||||
@ -270,7 +270,7 @@ class Nlu {
|
||||
const spacyEntity = {
|
||||
[entity]: {
|
||||
options: {
|
||||
[resolution.value]: [STRING.ucFirst(resolution.value)]
|
||||
[resolution.value]: [StringHelper.ucFirst(resolution.value)]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,11 @@
|
||||
class StringHelper {
|
||||
private static instance: StringHelper
|
||||
|
||||
constructor() {
|
||||
if (StringHelper.instance == null) {
|
||||
StringHelper.instance = this
|
||||
}
|
||||
}
|
||||
|
||||
export class StringHelper {
|
||||
/**
|
||||
* Parse, map (with object) and replace value(s) in a string
|
||||
* @param toReplace The string containing the placeholders to replace
|
||||
* @param obj The object containing the value(s) to replace with
|
||||
* @example findAndMap('Hello %name%!', { '%name%': 'Louis' }) // Hello Louis!
|
||||
*/
|
||||
public findAndMap(toReplace: string, obj: Record<string, unknown>) {
|
||||
public static findAndMap(toReplace: string, obj: Record<string, unknown>) {
|
||||
return toReplace.replace(
|
||||
new RegExp(Object.keys(obj).join('|'), 'gi'),
|
||||
(matched) => obj[matched] as string
|
||||
@ -25,7 +17,7 @@ class StringHelper {
|
||||
* @param str String to transform
|
||||
* @example ucFirst('hello world') // Hello world
|
||||
*/
|
||||
public ucFirst(str: string) {
|
||||
public static ucFirst(str: string) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||
}
|
||||
|
||||
@ -34,7 +26,7 @@ class StringHelper {
|
||||
* @param str String to transform
|
||||
* @example snakeToPascalCase('hello_world') // HelloWorld
|
||||
*/
|
||||
public snakeToPascalCase(str: string) {
|
||||
public static snakeToPascalCase(str: string) {
|
||||
return str
|
||||
.split('_')
|
||||
.map((chunk) => this.ucFirst(chunk))
|
||||
@ -46,7 +38,7 @@ class StringHelper {
|
||||
* @param length Length of the string
|
||||
* @example random(6) // 4f3a2b
|
||||
*/
|
||||
public random(length: number) {
|
||||
public static random(length: number) {
|
||||
return Math.random().toString(36).slice(-length)
|
||||
}
|
||||
|
||||
@ -55,7 +47,7 @@ class StringHelper {
|
||||
* @param str String to remove accents
|
||||
* @example removeAccents('éèà') // eea
|
||||
*/
|
||||
public removeAccents(str: string) {
|
||||
public static removeAccents(str: string) {
|
||||
return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
|
||||
}
|
||||
|
||||
@ -64,7 +56,7 @@ class StringHelper {
|
||||
* @param str String to remove punctuation
|
||||
* @example removeEndPunctuation('Hello world!') // Hello world
|
||||
*/
|
||||
public removeEndPunctuation(str: string) {
|
||||
public static removeEndPunctuation(str: string) {
|
||||
const punctuations = ['.', ';', ':', '?', '!']
|
||||
const lastChar = str.charAt(str.length - 1)
|
||||
|
||||
@ -75,5 +67,3 @@ class StringHelper {
|
||||
return str
|
||||
}
|
||||
}
|
||||
|
||||
export const STRING = new StringHelper()
|
@ -6,7 +6,7 @@ import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { LOG } from '@/helpers/log'
|
||||
import { STRING } from '@/helpers/string'
|
||||
import { StringHelper } from '@/helpers/string-helper'
|
||||
|
||||
LOG.title('Amazon Polly Synthesizer')
|
||||
|
||||
@ -51,7 +51,9 @@ synthesizer.init = (lang) => {
|
||||
* Save string to audio file
|
||||
*/
|
||||
synthesizer.save = (speech, em, cb) => {
|
||||
const file = `${__dirname}/../../tmp/${Date.now()}-${STRING.random(4)}.mp3`
|
||||
const file = `${__dirname}/../../tmp/${Date.now()}-${StringHelper.random(
|
||||
4
|
||||
)}.mp3`
|
||||
|
||||
synthesizer.conf.Text = speech
|
||||
|
||||
|
@ -5,7 +5,7 @@ import { path as ffprobePath } from '@ffprobe-installer/ffprobe'
|
||||
import fs from 'fs'
|
||||
|
||||
import { LOG } from '@/helpers/log'
|
||||
import { STRING } from '@/helpers/string'
|
||||
import { StringHelper } from '@/helpers/string-helper'
|
||||
|
||||
LOG.title('Flite Synthesizer')
|
||||
|
||||
@ -48,7 +48,9 @@ synthesizer.init = (lang) => {
|
||||
* Save string to audio file
|
||||
*/
|
||||
synthesizer.save = (speech, em, cb) => {
|
||||
const file = `${__dirname}/../../tmp/${Date.now()}-${STRING.random(4)}.wav`
|
||||
const file = `${__dirname}/../../tmp/${Date.now()}-${StringHelper.random(
|
||||
4
|
||||
)}.wav`
|
||||
const process = spawn('bin/flite/flite', [
|
||||
speech,
|
||||
'--setf',
|
||||
|
@ -6,7 +6,7 @@ import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { LOG } from '@/helpers/log'
|
||||
import { STRING } from '@/helpers/string'
|
||||
import { StringHelper } from '@/helpers/string-helper'
|
||||
|
||||
LOG.title('Google Cloud TTS Synthesizer')
|
||||
|
||||
@ -57,7 +57,9 @@ synthesizer.init = (lang) => {
|
||||
* Save string to audio file
|
||||
*/
|
||||
synthesizer.save = (speech, em, cb) => {
|
||||
const file = `${__dirname}/../../tmp/${Date.now()}-${STRING.random(4)}.mp3`
|
||||
const file = `${__dirname}/../../tmp/${Date.now()}-${StringHelper.random(
|
||||
4
|
||||
)}.mp3`
|
||||
|
||||
synthesizer.conf.input = { text: speech }
|
||||
|
||||
|
@ -7,7 +7,7 @@ import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { LOG } from '@/helpers/log'
|
||||
import { STRING } from '@/helpers/string'
|
||||
import { StringHelper } from '@/helpers/string-helper'
|
||||
|
||||
LOG.title('Watson TTS Synthesizer')
|
||||
|
||||
@ -55,7 +55,9 @@ synthesizer.init = (lang) => {
|
||||
* Save string to audio file
|
||||
*/
|
||||
synthesizer.save = (speech, em, cb) => {
|
||||
const file = `${__dirname}/../../tmp/${Date.now()}-${STRING.random(4)}.wav`
|
||||
const file = `${__dirname}/../../tmp/${Date.now()}-${StringHelper.random(
|
||||
4
|
||||
)}.wav`
|
||||
|
||||
synthesizer.conf.text = speech
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import string from '@/helpers/string'
|
||||
import string from '@/helpers/string-helper'
|
||||
|
||||
describe('string helper', () => {
|
||||
describe('pnr()', () => {
|
||||
test('replaces substring to a string defined in an object', () => {
|
||||
expect(string.pnr('Hello %name%', { '%name%': 'Leon' })).toBe(
|
||||
expect(StringHelper.pnr('Hello %name%', { '%name%': 'Leon' })).toBe(
|
||||
'Hello Leon'
|
||||
)
|
||||
})
|
||||
@ -11,20 +11,20 @@ describe('string helper', () => {
|
||||
|
||||
describe('ucfirst()', () => {
|
||||
test('transforms first letter to uppercase', () => {
|
||||
expect(string.ucfirst('leon')).toBe('Leon')
|
||||
expect(StringHelper.ucfirst('leon')).toBe('Leon')
|
||||
})
|
||||
})
|
||||
|
||||
describe('snakeToPascalCase()', () => {
|
||||
test('transforms snake_case string to PascalCase', () => {
|
||||
expect(string.snakeToPascalCase('leon')).toBe('Leon')
|
||||
expect(string.snakeToPascalCase('this_is_leon')).toBe('ThisIsLeon')
|
||||
expect(StringHelper.snakeToPascalCase('leon')).toBe('Leon')
|
||||
expect(StringHelper.snakeToPascalCase('this_is_leon')).toBe('ThisIsLeon')
|
||||
})
|
||||
})
|
||||
|
||||
describe('random()', () => {
|
||||
test('generates a random string with a length defined by a given number', () => {
|
||||
const s = string.random(6)
|
||||
const s = StringHelper.random(6)
|
||||
expect(typeof s).toBe('string')
|
||||
expect(s.length).toBe(6)
|
||||
})
|
||||
@ -32,18 +32,22 @@ describe('string helper', () => {
|
||||
|
||||
describe('removeAccents()', () => {
|
||||
test('removes accents', () => {
|
||||
expect(string.removeAccents('àâèéêëîïôöûüùÛÜç')).toBe('aaeeeeiioouuuUUc')
|
||||
expect(StringHelper.removeAccents('àâèéêëîïôöûüùÛÜç')).toBe(
|
||||
'aaeeeeiioouuuUUc'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('removeEndPunctuation()', () => {
|
||||
test('removes end-punctuation', () => {
|
||||
expect(string.removeEndPunctuation('Who are you?')).toBe('Who are you')
|
||||
expect(string.removeEndPunctuation('This is great.')).toBe(
|
||||
expect(StringHelper.removeEndPunctuation('Who are you?')).toBe(
|
||||
'Who are you'
|
||||
)
|
||||
expect(StringHelper.removeEndPunctuation('This is great.')).toBe(
|
||||
'This is great'
|
||||
)
|
||||
expect(
|
||||
string.removeEndPunctuation('This string has no punctuation')
|
||||
StringHelper.removeEndPunctuation('This string has no punctuation')
|
||||
).toBe('This string has no punctuation')
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user