Skip to content

Commit

Permalink
feat(StringTemplate): 支持仅代码渲染
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Aug 7, 2024
1 parent 0140a4a commit 2c75262
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 22 deletions.
41 changes: 41 additions & 0 deletions src/utils/StringTemplate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,45 @@ describe('StringTemplate', () => {
),
).toBe('hello爱你,${用户}')
})

test('onlyCode', () => {
expect(
StringTemplate.render(
'{用户}爱你',
{
用户: 'hello',
},
{
onlyCode: true,
},
),
).toBe('{用户}爱你')
expect(
StringTemplate.render(
'{{用户}}爱你',
{
用户: 'hello',
},
{
onlyCode: true,
},
),
).toBe('hello爱你')

expect(
StringTemplate.render(
'{{ _.sum(1, 2) }}爱你{么}',
{
_: {
sum(a: number, b: number) {
return a + b
},
},
},
{
onlyCode: true,
},
),
).toBe('3爱你{么}')
})
})
51 changes: 29 additions & 22 deletions src/utils/StringTemplate.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export interface StringTemplateRenderOptions {
/** 是否启用代码渲染,需环境支持 eval */
code?: boolean
/** 是否仅代码渲染 */
onlyCode?: boolean
}

/**
Expand All @@ -24,32 +26,37 @@ export class StringTemplate {
data: Record<string, any>,
options?: StringTemplateRenderOptions,
) {
const enableCode = !!options?.code
const onlyCode = !!options?.onlyCode
const enableCode = onlyCode || !!options?.code
const keys = Object.keys(data)
for (const key of keys) {
template =
typeof data[key] === 'function'
? template.replace(
new RegExp(`\\{${key}(:.+?)?\\}`, 'g'),
(_, params: string) => {
return data[key].call(
null,
...(params ? params.substring(1) : '').split(','),
)
},
)
: enableCode
? template.replace(new RegExp(`(?<!\\$)\\{${key}\\}`, 'g'), data[key])
: template.replaceAll(`{${key}}`, data[key])
if (!onlyCode) {
for (const key of keys) {
template =
typeof data[key] === 'function'
? template.replace(
new RegExp(`\\{${key}(:.+?)?\\}`, 'g'),
(_, params: string) => {
return data[key].call(
null,
...(params ? params.substring(1) : '').split(','),
)
},
)
: enableCode
? template.replace(
new RegExp(`(?<!\\$)\\{${key}\\}`, 'g'),
data[key],
)
: template.replaceAll(`{${key}}`, data[key])
}
}
if (enableCode) {
template = template.replace(/\{\{(.+?)\}\}/g, (_, code) => {
return eval(`
(() => {
const {${keys.join(',')}} = ${JSON.stringify(data)};
return ${code};
})()
`)
// 需在 eval 里函数两边加上括号才能返回函数
return eval(`(function (data) {
${keys.map(key => `var ${key} = data["${key}"];`).join('')}
return ${code};
})`)(data)
})
}
return template
Expand Down

0 comments on commit 2c75262

Please sign in to comment.