1
1
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:
louistiti 2022-09-12 16:00:46 +08:00
parent da0233495d
commit 35a9f6e0ea
No known key found for this signature in database
GPG Key ID: 7ECA3DD523793FE6
13 changed files with 108 additions and 76 deletions

View File

@ -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')

View File

@ -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])

View File

@ -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)]
})

View File

@ -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...')

View File

@ -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`

View File

@ -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)]
}
}
}

View File

@ -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()

View File

@ -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

View 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
}

View File

@ -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

View File

@ -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',

View File

@ -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 }

View File

@ -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