mirror of
https://github.com/leon-ai/leon.git
synced 2024-09-11 10:25:40 +03:00
refactor(server): string helper to TypeScript
This commit is contained in:
parent
da0233495d
commit
35a9f6e0ea
@ -5,7 +5,7 @@ import { prompt } from 'inquirer'
|
||||
import path from 'path'
|
||||
|
||||
import log from '@/helpers/log'
|
||||
import string from '@/helpers/string'
|
||||
import { randomString } from '@/helpers/string'
|
||||
|
||||
dotenv.config()
|
||||
|
||||
@ -19,7 +19,7 @@ const generateHttpApiKey = () =>
|
||||
|
||||
try {
|
||||
const shasum = crypto.createHash('sha1')
|
||||
const str = string.random(11)
|
||||
const str = randomString(11)
|
||||
const dotEnvPath = path.join(process.cwd(), '.env')
|
||||
const envVarKey = 'LEON_HTTP_API_KEY'
|
||||
let content = fs.readFileSync(dotEnvPath, 'utf8')
|
||||
|
@ -4,7 +4,7 @@ import { composeFromPattern } from '@nlpjs/utils'
|
||||
|
||||
import log from '@/helpers/log'
|
||||
import json from '@/helpers/json'
|
||||
import string from '@/helpers/string'
|
||||
import { findAndMap } from '@/helpers/string'
|
||||
import domain from '@/helpers/domain'
|
||||
|
||||
/**
|
||||
@ -116,7 +116,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.pnr(answers[l], variablesObj)
|
||||
answers[l] = 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 { findAndMap, randomString } from '@/helpers/string'
|
||||
import Synchronizer from '@/core/synchronizer'
|
||||
import lang from '@/helpers/lang'
|
||||
import domain from '@/helpers/domain'
|
||||
@ -130,7 +130,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.pnr(answer, obj)
|
||||
answer = findAndMap(answer, obj)
|
||||
}
|
||||
|
||||
return answer
|
||||
@ -147,7 +147,7 @@ class Brain {
|
||||
}
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const utteranceId = `${Date.now()}-${string.random(4)}`
|
||||
const utteranceId = `${Date.now()}-${randomString(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.pnr(answer, {
|
||||
answer = findAndMap(answer, {
|
||||
[`{{ ${entityObj.entity} }}`]: entityObj.resolution.value
|
||||
})
|
||||
|
||||
@ -469,7 +469,7 @@ class Brain {
|
||||
const valuesArr =
|
||||
entities[entity].options[entityObj.option].data[dataKey]
|
||||
|
||||
answer = string.pnr(answer, {
|
||||
answer = 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 { ucFirst } from '@/helpers/string'
|
||||
|
||||
const getDownloads = async (fastify, options) => {
|
||||
fastify.get(`/api/${options.apiVersion}/downloads`, (request, reply) => {
|
||||
@ -28,12 +28,10 @@ const getDownloads = async (fastify, options) => {
|
||||
const skill = path.join(dlDomainDir, `${request.query.skill}.py`)
|
||||
|
||||
log.info(
|
||||
`Checking existence of the ${string.ucfirst(
|
||||
request.query.skill
|
||||
)} skill...`
|
||||
`Checking existence of the ${ucFirst(request.query.skill)} skill...`
|
||||
)
|
||||
if (fs.existsSync(skill)) {
|
||||
log.success(`${string.ucfirst(request.query.skill)} skill exists`)
|
||||
log.success(`${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 { removeEndPunctuation, snakeToPascalCase } from '@/helpers/string'
|
||||
|
||||
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 = `${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${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 { ucFirst } from '@/helpers/string'
|
||||
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]: [ucFirst(resolution.value)]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,20 @@ import log from '@/helpers/log'
|
||||
dayjs.extend(utc)
|
||||
dayjs.extend(timezone)
|
||||
|
||||
/**
|
||||
* Get date time
|
||||
*
|
||||
* @example getDateTime() // 2022-09-12T12:42:57+08:00
|
||||
*/
|
||||
export function getDateTime() {
|
||||
return dayjs().tz(getTimeZone()).format()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time zone
|
||||
*
|
||||
* @example getTimeZone() // Asia/Shanghai
|
||||
*/
|
||||
export function getTimeZone() {
|
||||
let { timeZone } = Intl.DateTimeFormat().resolvedOptions()
|
||||
|
||||
|
@ -1,49 +0,0 @@
|
||||
const string = {}
|
||||
|
||||
/**
|
||||
* Parse, map (with object) and replace value(s) in a string
|
||||
*/
|
||||
string.pnr = (s, obj) =>
|
||||
s.replace(
|
||||
new RegExp(Object.keys(obj).join('|'), 'gi'),
|
||||
(matched) => obj[matched]
|
||||
)
|
||||
|
||||
/**
|
||||
* Uppercase for the first letter
|
||||
*/
|
||||
string.ucfirst = (s) => s.charAt(0).toUpperCase() + s.substr(1)
|
||||
|
||||
/**
|
||||
* Transform snake_case string to PascalCase
|
||||
*/
|
||||
string.snakeToPascalCase = (s) =>
|
||||
s
|
||||
.split('_')
|
||||
.map((chunk) => string.ucfirst(chunk))
|
||||
.join('')
|
||||
|
||||
/**
|
||||
* Random string
|
||||
*/
|
||||
string.random = (n) => Math.random().toString(36).slice(-n)
|
||||
|
||||
/**
|
||||
* Remove accents
|
||||
*/
|
||||
string.removeAccents = (s) => s.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
|
||||
|
||||
/**
|
||||
* Remove end-punctuation
|
||||
*/
|
||||
string.removeEndPunctuation = (s) => {
|
||||
const punctuations = ['.', ';', ':', '?', '!']
|
||||
|
||||
if (punctuations.includes(s[s.length - 1])) {
|
||||
return s.substr(s, s.length - 1)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
export default string
|
73
server/src/helpers/string.ts
Normal file
73
server/src/helpers/string.ts
Normal file
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* 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!
|
||||
*/
|
||||
export function findAndMap(toReplace: string, obj: Record<string, unknown>) {
|
||||
return toReplace.replace(
|
||||
new RegExp(Object.keys(obj).join('|'), 'gi'),
|
||||
(matched) => obj[matched] as string
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Set first letter as uppercase
|
||||
*
|
||||
* @param str String to transform
|
||||
* @example ucFirst('hello world') // Hello world
|
||||
*/
|
||||
export function ucFirst(str: string) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform snake_case string to PascalCase
|
||||
*
|
||||
* @param str String to transform
|
||||
* @example snakeToPascalCase('hello_world') // => HelloWorld
|
||||
*/
|
||||
export function snakeToPascalCase(str: string) {
|
||||
return str
|
||||
.split('_')
|
||||
.map((chunk) => ucFirst(chunk))
|
||||
.join('')
|
||||
}
|
||||
|
||||
/**
|
||||
* Random string
|
||||
*
|
||||
* @param length Length of the string
|
||||
* @example randomString(6) // 4f3a2b
|
||||
*/
|
||||
export function randomString(length: number) {
|
||||
return Math.random().toString(36).slice(-length)
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove accents
|
||||
*
|
||||
* @param str String to remove accents
|
||||
* @example removeAccents('éèà') // eea
|
||||
*/
|
||||
export function removeAccents(str: string) {
|
||||
return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove punctuation at the end of the string
|
||||
*
|
||||
* @param str String to remove punctuation
|
||||
* @example removeEndPunctuation('Hello world!') // Hello world
|
||||
*/
|
||||
export function removeEndPunctuation(str: string) {
|
||||
const punctuations = ['.', ';', ':', '?', '!']
|
||||
const lastChar = str.charAt(str.length - 1)
|
||||
|
||||
if (punctuations.includes(lastChar)) {
|
||||
return str.slice(0, -1)
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
@ -6,7 +6,7 @@ import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import log from '@/helpers/log'
|
||||
import string from '@/helpers/string'
|
||||
import { randomString } from '@/helpers/string'
|
||||
|
||||
log.title('Amazon Polly Synthesizer')
|
||||
|
||||
@ -51,7 +51,7 @@ 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()}-${randomString(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 { randomString } from '@/helpers/string'
|
||||
|
||||
log.title('Flite Synthesizer')
|
||||
|
||||
@ -48,7 +48,7 @@ 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()}-${randomString(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 { randomString } from '@/helpers/string'
|
||||
|
||||
log.title('Google Cloud TTS Synthesizer')
|
||||
|
||||
@ -57,7 +57,7 @@ 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()}-${randomString(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 { randomString } from '@/helpers/string'
|
||||
|
||||
log.title('Watson TTS Synthesizer')
|
||||
|
||||
@ -55,7 +55,7 @@ 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()}-${randomString(4)}.wav`
|
||||
|
||||
synthesizer.conf.text = speech
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user