| 1 | import { valueMap } from '@deepseek-ai/cosmokit' |
| 2 | |
| 3 | // eslint-disable-next-line no-new-func |
| 4 | /** Evaluate a JavaScript expression against a loader context scope. */ |
| 5 | export const evaluate = new Function('ctx', 'expr', ` |
| 6 | with (ctx) { |
| 7 | return eval(expr) |
| 8 | } |
| 9 | `) as ((ctx: object, expr: string) => any) |
| 10 | |
| 11 | /** Recursively replace YAML `!!js` expression nodes with evaluated values. */ |
| 12 | export function interpolate(ctx: object, value: any): any { |
| 13 | if (isJsExpr(value)) { |
| 14 | return evaluate(ctx, value.__jsExpr) |
| 15 | } else if (!value || typeof value !== 'object') { |
| 16 | return value |
| 17 | } else if (Array.isArray(value)) { |
| 18 | return value.map(item => interpolate(ctx, item)) |
| 19 | } else { |
| 20 | return valueMap(value, item => interpolate(ctx, item)) |
| 21 | } |
| 22 | } |
| 23 | |
| 24 | /** Return true when a value is a serialized loader JavaScript expression. */ |
| 25 | export function isJsExpr(value: any): value is JsExpr { |
| 26 | return value instanceof Object && '__jsExpr' in value |
| 27 | } |
| 28 | |
| 29 | /** Serialized JavaScript expression produced by the include YAML tag. */ |
| 30 | export interface JsExpr { |
| 31 | __jsExpr: string |
| 32 | } |
| 33 |