UNPKG

@bizone-ai/json-transform-utils

Version:

Utilities for handling JSON transformers

944 lines 41.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const vitest_1 = require("vitest"); const json_schema_utils_1 = require("@bizone-ai/json-schema-utils"); const types_1 = require("../../functions/types"); const parse_1 = require("../../parse"); const functionsParser_1 = require("../../functions/functionsParser"); const index_1 = require("../../index"); const transformerResult = (transformer, givenTypeMap) => { const paths = []; const outputTypeMap = structuredClone(givenTypeMap) ?? {}; const previousPaths = givenTypeMap ? Object.keys(givenTypeMap) : []; (0, parse_1.parseTransformer)(transformer, "$", previousPaths, paths, outputTypeMap); return outputTypeMap; }; function removeUndefined(obj) { return Object.fromEntries(Object.entries(obj).filter(x => typeof x[1] !== "undefined")); } const createFlowTraversalResult = (merge) => merge?.paths ? removeUndefined(merge.paths) : {}; const NULL = { type: "null" }, ARRAY = { type: "array" }, STRING = { type: "string" }, INTEGER = { type: "integer" }, LONG = { type: "integer", $comment: "Long" }, NUMBER = { type: "number" }, BOOLEAN = { type: "boolean" }, OBJECT = { type: "object" }, ARRAY_ARRAY = { type: "array", items: ARRAY }, // eslint-disable-line @typescript-eslint/no-unused-vars STRING_ARRAY = { type: "array", items: STRING }, // eslint-disable-line @typescript-eslint/no-unused-vars INTEGER_ARRAY = { type: "array", items: INTEGER }, NUMBER_ARRAY = { type: "array", items: NUMBER }, BOOLEAN_ARRAY = { type: "array", items: BOOLEAN }, // eslint-disable-line @typescript-eslint/no-unused-vars OBJECT_ARRAY = { type: "array", items: OBJECT }; (0, vitest_1.describe)("functions schema detection", () => { for (const funcName of types_1.EmbeddedTransformerFunctions) { const func = functionsParser_1.functionsParser.get(funcName); const alias = `$$${funcName}`; const outputSchema = func.outputSchema; // if (funcName !== TransformerFunction.transform) continue; // This can make the tests run only one for easy debugging (0, vitest_1.test)(`functions - ${funcName} - outputSchema detection`, () => { switch (funcName) { case types_1.EmbeddedTransformerFunction.coalesce: { const givenTypeMap = { "$.a0": NULL, "$.a1": INTEGER, "$.a2": NUMBER_ARRAY, "$.a2[]": NUMBER, }; const altAlias = `$$${functionsParser_1.functionsParser.get(funcName).aliases?.[0]}`; (0, vitest_1.expect)(transformerResult({ inline: `${alias}:$.a2`, inlineAlias: `${altAlias}:$.a2`, object: { [alias]: [null, null, "A"], }, objectAlias: { [altAlias]: [null, null, "A"], }, object2: { [alias]: [null, null, 0.5], }, object3: { [alias]: ["$.a0", "$.a1"], }, }, givenTypeMap)).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: { inline: NUMBER, inlineAlias: NUMBER, object: STRING, objectAlias: STRING, object2: NUMBER, object3: INTEGER, }, type: "object", }, ...givenTypeMap, "$.inline": NUMBER, "$.inlineAlias": NUMBER, "$.object": STRING, "$.objectAlias": STRING, "$.object2": NUMBER, "$.object3": INTEGER, }, })); break; } case types_1.EmbeddedTransformerFunction.at: case types_1.EmbeddedTransformerFunction.concat: case types_1.EmbeddedTransformerFunction.find: case types_1.EmbeddedTransformerFunction.flat: { const givenTypeMap = { "$.a0": { type: "array", items: NUMBER_ARRAY }, "$.a0[]": NUMBER_ARRAY, "$.a0[][]": NUMBER, "$.a1": INTEGER_ARRAY, "$.a1[0]": INTEGER, "$.a2": INTEGER_ARRAY, "$.a2[]": INTEGER, }; (0, vitest_1.expect)(transformerResult({ inline: `${alias}:$.a0`, object: { [alias]: ["$.a1", "$.a2"], }, }, givenTypeMap)).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: { inline: NUMBER_ARRAY, object: INTEGER_ARRAY, }, type: "object", }, ...givenTypeMap, "$.inline": NUMBER_ARRAY, "$.inline[]": NUMBER, "$.object": INTEGER_ARRAY, "$.object[0]": INTEGER, }, })); break; } case types_1.EmbeddedTransformerFunction.if: { (0, vitest_1.expect)(transformerResult({ inline: `${alias}(A,B):$.a0`, inline2: `${alias}($$long:1,$$long:2):$.a0`, object: { [alias]: [false, "A", "B"], }, object2: { [alias]: [false, 1, 2], }, object3: { [alias]: false, then: 0.5, }, })).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: { inline: STRING, inline2: LONG, object: STRING, object2: INTEGER, object3: NUMBER, }, type: "object", }, "$.inline": STRING, "$.inline2": LONG, "$.object": STRING, "$.object2": INTEGER, "$.object3": NUMBER, }, })); break; } case types_1.EmbeddedTransformerFunction.distinct: case types_1.EmbeddedTransformerFunction.filter: case types_1.EmbeddedTransformerFunction.reverse: case types_1.EmbeddedTransformerFunction.slice: case types_1.EmbeddedTransformerFunction.sort: { const givenTypeMap = { "$.a0": NUMBER_ARRAY, "$.a0[]": NUMBER, "$.a1": INTEGER, "$.a2": INTEGER, }; (0, vitest_1.expect)(transformerResult({ inline: `${alias}:$.a0`, object: { [alias]: "$.a0", }, object2: { [alias]: ["$.a1", "$.a2"], }, }, givenTypeMap)).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: { inline: NUMBER_ARRAY, object: NUMBER_ARRAY, object2: INTEGER_ARRAY, }, type: "object", }, ...givenTypeMap, "$.inline": NUMBER_ARRAY, "$.inline[]": NUMBER, "$.object": NUMBER_ARRAY, "$.object[]": NUMBER, "$.object2": INTEGER_ARRAY, "$.object2[]": INTEGER, }, })); break; } // we don't infer output type :_( case types_1.EmbeddedTransformerFunction.eval: { (0, vitest_1.expect)(transformerResult({ inline: `${alias}:irrelevant`, object: { [alias]: "irrelevant", }, })).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, type: "object", }, }, })); break; } case types_1.EmbeddedTransformerFunction.repeat: { const givenTypeMap = { "$.a0": INTEGER_ARRAY, "$.a0[]": INTEGER, "$.a1": STRING, }; (0, vitest_1.expect)(transformerResult({ inline: `${alias}(irrelevant):$.a0`, inline2: `${alias}(irrelevant):$.a1`, object: { [alias]: "$.a0", }, }, givenTypeMap)).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: { inline: { type: "array", items: INTEGER_ARRAY }, inline2: STRING_ARRAY, object: { type: "array", items: INTEGER_ARRAY }, }, type: "object", }, ...givenTypeMap, "$.inline": { type: "array", items: INTEGER_ARRAY }, "$.inline[]": INTEGER_ARRAY, "$.inline[][]": INTEGER, "$.inline2": STRING_ARRAY, "$.inline2[]": STRING, "$.object": { type: "array", items: INTEGER_ARRAY }, "$.object[]": INTEGER_ARRAY, "$.object[][]": INTEGER, }, })); break; } case types_1.EmbeddedTransformerFunction.lookup: { const givenTypeMap = { "$.a0": ARRAY, "$.a0[]": OBJECT, "$.a0[].id": NUMBER, "$.a0[].name": STRING, "$.a1": ARRAY, "$.a1[]": OBJECT, "$.a1[].id": NUMBER, "$.a1[].age": INTEGER, }; (0, vitest_1.expect)(transformerResult({ //inline: `${alias}:$.a0`, object: { [alias]: "$.a0", using: [{ with: "$.a1", as: "match", on: {} }], }, object2: { [alias]: "$.a0", using: [{ with: "$.a1", as: "match", on: {} }], to: { name: "##current.name", age: "##match.age", }, }, }, givenTypeMap)).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: { object: OBJECT_ARRAY, object2: { type: "array", items: { type: "object", properties: { age: INTEGER, name: STRING, }, additionalProperties: false, }, }, }, type: "object", }, ...givenTypeMap, "$.object": OBJECT_ARRAY, "$.object[]": OBJECT, "$.object[].id": NUMBER, "$.object[].age": INTEGER, "$.object[].name": STRING, "$.object2": { type: "array", items: { type: "object", properties: { age: INTEGER, name: STRING, }, additionalProperties: false, }, }, "$.object2[]": { type: "object", properties: { age: INTEGER, name: STRING, }, additionalProperties: false, }, "$.object2[].age": INTEGER, "$.object2[].name": STRING, }, })); break; } case types_1.EmbeddedTransformerFunction.min: case types_1.EmbeddedTransformerFunction.max: { const givenTypeMap = { "$.a0": INTEGER_ARRAY, "$.a0[]": INTEGER, }; (0, vitest_1.expect)(transformerResult({ inline: `${alias}:$.a0`, inline_str: `${alias}(0,STRING):$.a0`, inline_num: `${alias}(0,NUMBER):$.a0`, inline_bool: `${alias}(0,BOOLEAN):$.a0`, object: { [alias]: "$.a0", }, object_str: { [alias]: "$.a0", type: "STRING", }, object_num: { [alias]: "$.a0", type: "NUMBER", }, object_bool: { [alias]: "$.a0", type: "BOOLEAN", }, }, givenTypeMap)).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: { inline: INTEGER, inline_str: STRING, inline_num: NUMBER, inline_bool: BOOLEAN, object: INTEGER, object_str: STRING, object_num: NUMBER, object_bool: BOOLEAN, }, type: "object", }, ...givenTypeMap, "$.inline": INTEGER, "$.inline_str": STRING, "$.inline_num": NUMBER, "$.inline_bool": BOOLEAN, "$.object": INTEGER, "$.object_str": STRING, "$.object_num": NUMBER, "$.object_bool": BOOLEAN, }, })); break; } case types_1.EmbeddedTransformerFunction.merge: { const givenTypeMap = { "$.a0": OBJECT, "$.a0.id": NUMBER, "$.a0.name": OBJECT, "$.a0.name.first_name": STRING, "$.a1": OBJECT, "$.a1.id": NUMBER, "$.a1.age": INTEGER, "$.a1.name": OBJECT, "$.a1.name.last_name": STRING, }; (0, vitest_1.expect)(transformerResult({ //inline: `${alias}:$.a0`, object: { [alias]: ["$.a0", "$.a1"], deep: true, }, object2: { [alias]: ["$.a0", "$.a1"], }, }, givenTypeMap)).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: { object: OBJECT, object2: OBJECT, }, type: "object", }, ...givenTypeMap, "$.object": OBJECT, "$.object.id": NUMBER, "$.object.age": INTEGER, "$.object.name": OBJECT, "$.object.name.first_name": STRING, "$.object.name.last_name": STRING, "$.object2": OBJECT, "$.object2.id": NUMBER, "$.object2.age": INTEGER, "$.object2.name": OBJECT, "$.object2.name.first_name": STRING, // TODO: should not be here "$.object2.name.last_name": STRING, }, })); break; } case types_1.EmbeddedTransformerFunction.map: { const givenTypeMap = { "$.a0": { type: "array", items: INTEGER_ARRAY }, "$.a0[]": INTEGER_ARRAY, "$.a0[][]": INTEGER, }; (0, vitest_1.expect)(transformerResult({ inline: `${alias}(##current[0]):$.a0`, object: { [alias]: "$.a0", to: "##current[0]", }, }, givenTypeMap)).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: { inline: INTEGER_ARRAY, object: INTEGER_ARRAY, }, type: "object", }, ...givenTypeMap, "$.inline": INTEGER_ARRAY, "$.inline[]": INTEGER, "$.object": INTEGER_ARRAY, "$.object[]": INTEGER, }, })); break; } case types_1.EmbeddedTransformerFunction.partition: { const givenTypeMap = { "$.a0": { type: "array", items: NUMBER }, "$.a0[]": NUMBER, }; (0, vitest_1.expect)(transformerResult({ inline: `${alias}:$.a0`, object: { [alias]: "$.a0", }, }, givenTypeMap)).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: { inline: { type: "array", items: NUMBER_ARRAY }, object: { type: "array", items: NUMBER_ARRAY }, }, type: "object", }, ...givenTypeMap, "$.inline": { type: "array", items: NUMBER_ARRAY }, "$.inline[]": NUMBER_ARRAY, "$.inline[][]": NUMBER, "$.object": { type: "array", items: NUMBER_ARRAY }, "$.object[]": NUMBER_ARRAY, "$.object[][]": NUMBER, }, })); break; } case types_1.EmbeddedTransformerFunction.transform: { const givenTypeMap = { "$.a0": INTEGER_ARRAY, "$.a0[]": INTEGER, }; (0, vitest_1.expect)(transformerResult({ inline: `${alias}(##current[0]):$.a0`, object: { [alias]: "$.a0", to: "##current[0]", }, }, givenTypeMap)).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: { inline: INTEGER, object: INTEGER, }, type: "object", }, ...givenTypeMap, "$.inline": INTEGER, "$.object": INTEGER, }, })); break; } case types_1.EmbeddedTransformerFunction.reduce: { const givenTypeMap = { "$.a0": { type: "array", items: { type: "object", properties: { amount: NUMBER } } }, "$.a0[]": { type: "object", properties: { amount: NUMBER } }, "$.a0[].number": NUMBER, }; (0, vitest_1.expect)(transformerResult({ inline: `${alias}('$$math(##accumulator,+,##current.amount)',$$long:0):$.a0`, object: { [alias]: "$.a0", identity: 0.5, to: {}, }, }, givenTypeMap)).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: { inline: LONG, object: NUMBER, }, type: "object", }, ...givenTypeMap, "$.inline": LONG, "$.object": NUMBER, }, })); break; } case types_1.EmbeddedTransformerFunction.switch: { (0, vitest_1.expect)(transformerResult({ object: { [alias]: "$.a0", cases: { a: 1, B: 2, c: 3 }, }, object2: { [alias]: "$.a0", cases: { a: 1, B: 2, c: 3 }, default: 0.5, }, })).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: { object: INTEGER, object2: NUMBER, }, type: "object", }, "$.object": INTEGER, "$.object2": NUMBER, }, })); break; } case types_1.EmbeddedTransformerFunction.raw: case types_1.EmbeddedTransformerFunction.jsonpatch: case types_1.EmbeddedTransformerFunction.value: { const givenTypeMap = { "$.a0": INTEGER_ARRAY, "$.a0[]": INTEGER, }; (0, vitest_1.expect)(transformerResult({ inline: `${alias}:$.a0`, object: { [alias]: "$.a0", }, }, givenTypeMap)).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: { inline: funcName === types_1.EmbeddedTransformerFunction.raw ? STRING : INTEGER_ARRAY, object: funcName === types_1.EmbeddedTransformerFunction.raw ? STRING : INTEGER_ARRAY, }, type: "object", }, ...givenTypeMap, "$.inline": funcName === types_1.EmbeddedTransformerFunction.raw ? STRING : INTEGER_ARRAY, "$.inline[]": funcName === types_1.EmbeddedTransformerFunction.raw ? undefined : INTEGER, "$.object": funcName === types_1.EmbeddedTransformerFunction.raw ? STRING : INTEGER_ARRAY, "$.object[]": funcName === types_1.EmbeddedTransformerFunction.raw ? undefined : INTEGER, }, })); break; } // static output schema default: { if (func.subfunctions) { // static conditional const paramName = func.arguments?.find(p => p.position === 0)?.name ?? ""; const expected = {}; const outputProperties = {}; const transformer = func.subfunctions.reduce((a, kv) => { const argValue = kv.if[0].equals; // TODO: this is not generic a["inline_" + argValue] = `${alias}(${argValue}):irrelevant`; a["object_" + argValue] = { [alias]: "irrelevant", [paramName]: argValue, }; const argOutputSchema = kv.then.outputSchema; if (argOutputSchema) { expected["$.inline_" + argValue] = argOutputSchema; outputProperties["inline_" + argValue] = argOutputSchema; expected["$.object_" + argValue] = argOutputSchema; outputProperties["object_" + argValue] = argOutputSchema; if (argOutputSchema.type === "array" && argOutputSchema.items && !Array.isArray(argOutputSchema.items)) { const firstLevelItems = argOutputSchema.items; expected["$.inline_" + argValue + "[]"] = firstLevelItems; expected["$.object_" + argValue + "[]"] = firstLevelItems; if (firstLevelItems.type === "array" && firstLevelItems.items && !Array.isArray(firstLevelItems.items)) { expected["$.inline_" + argValue + "[][]"] = firstLevelItems.items; expected["$.object_" + argValue + "[][]"] = firstLevelItems.items; } } } return a; }, {}); (0, vitest_1.expect)({ transformer, result: transformerResult(transformer) }).toStrictEqual({ transformer, result: createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: outputProperties, type: "object", }, ...expected, }, }), }); break; } // static output schema (0, vitest_1.expect)(outputSchema).toBeTruthy(); const expected = {}; const funcOutputPaths = functionsParser_1.functionsParser.get(funcName).parsedOutputSchema?.paths ?? []; funcOutputPaths.forEach(p => { const suffix = !p.$path ? "" : (p.$path[0] === "[" ? "" : ".") + p.$path; expected["$.inline" + suffix] = (0, json_schema_utils_1.cleanParsedSchemaProperty)(p); expected["$.object" + suffix] = (0, json_schema_utils_1.cleanParsedSchemaProperty)(p); }); (0, vitest_1.expect)(transformerResult({ inline: `${alias}:irrelevant`, object: { [alias]: "irrelevant", }, })).toStrictEqual(createFlowTraversalResult({ paths: { $: { additionalProperties: false, properties: { inline: outputSchema, object: outputSchema, }, type: "object", }, ...expected, }, })); break; } } }); } }); (0, vitest_1.describe)("matchInline", () => { (0, vitest_1.test)("simple", () => { (0, vitest_1.expect)(functionsParser_1.functionsParser.matchInline("$$pad(1,2):abc")).toEqual(index_1.functions.pad); }); (0, vitest_1.test)("dont match non existing", () => { (0, vitest_1.expect)(functionsParser_1.functionsParser.matchInline("$$nonexistent1:abc")).toBeNull(); }); (0, vitest_1.test)("setClientFunctions", () => { const clientFuncDescriptor = { description: "client function" }; functionsParser_1.functionsParser.setClientFunctions({ nonexistent2: clientFuncDescriptor, }); (0, vitest_1.expect)(functionsParser_1.functionsParser.matchInline("$$nonexistent2:abc")).toEqual({ ...clientFuncDescriptor, custom: true, defaultValues: {}, }); }); }); (0, vitest_1.describe)("matchAllFunctionsInLine", () => { (0, vitest_1.test)(`sanity`, () => { (0, vitest_1.expect)(functionsParser_1.functionsParser.matchAllFunctionsInLine(" : \"$$pad(1,2):$$wrap(abc,'def'):$$\" ")).toEqual([ { name: "pad", keyLength: 5, args: [ { index: 11, length: 1, value: "1", }, { index: 13, length: 1, value: "2", }, ], index: 5, input: { index: 16, length: 20, value: "$$wrap(abc,'def'):$$", }, }, { keyLength: 6, name: "wrap", args: [ { index: 23, length: 3, value: "abc", }, { index: 27, length: 5, value: "def", }, ], index: 16, input: { index: 34, length: 2, value: "$$", }, }, ]); }); (0, vitest_1.test)(`sanity 2`, () => { (0, vitest_1.expect)(functionsParser_1.functionsParser.matchAllFunctionsInLine(` "age": "$$math('$$math(\\\\'$$date(EPOCH):#now\\\\',-,\\\\'$$date(EPOCH):$.date_of_birth\\\\')',//,'$$math(365,*,\\\\'$$math(24,*,3600)\\\\')')"`)).toEqual([ { args: [ { index: 17, length: 72, value: "$$math(\\'$$date(EPOCH):#now\\',-,\\'$$date(EPOCH):$.date_of_birth\\')", }, { index: 90, length: 2, value: "//", }, { index: 93, length: 39, value: "$$math(365,*,\\'$$math(24,*,3600)\\')", }, ], index: 10, keyLength: 6, name: "math", }, ]); }); (0, vitest_1.test)(`sanity 3`, () => { (0, vitest_1.expect)(functionsParser_1.functionsParser.matchAllFunctionsInLine(`"$$pad:$$wrap:"`)).toEqual([ { index: 1, input: { index: 7, length: 7, value: "$$wrap:", }, keyLength: 5, name: "pad", }, { index: 7, input: { index: 14, length: 0, value: "", }, keyLength: 6, name: "wrap", }, ]); }); (0, vitest_1.test)(`sanity 4`, () => { (0, vitest_1.expect)(functionsParser_1.functionsParser.matchAllFunctionsInLine(`"$$pad:$$wrap:", `)).toEqual([ { index: 1, input: { index: 7, length: 7, value: "$$wrap:", }, keyLength: 5, name: "pad", }, { index: 7, input: { index: 14, length: 0, value: "", }, keyLength: 6, name: "wrap", }, ]); }); (0, vitest_1.test)(`sanity 5`, () => { (0, vitest_1.expect)(functionsParser_1.functionsParser.matchAllFunctionsInLine(` "$$pad:a", "$$wrap:" `)).toEqual([ { index: 3, input: { index: 9, length: 1, value: "a", }, keyLength: 5, name: "pad", }, { index: 14, input: { index: 21, length: 0, value: "", }, keyLength: 6, name: "wrap", }, ]); }); (0, vitest_1.test)(`sanity 6`, () => { (0, vitest_1.expect)(functionsParser_1.functionsParser.matchAllFunctionsInLine(`"$$pad", "$$wrap", "$$wrap"`)).toEqual([ { index: 1, keyLength: 5, name: "pad", }, { index: 10, keyLength: 6, name: "wrap", }, { index: 20, keyLength: 6, name: "wrap", }, ]); }); (0, vitest_1.test)(`sanity 7`, () => { (0, vitest_1.expect)(functionsParser_1.functionsParser.matchAllFunctionsInLine(` "$$pad(1):$$trim:$$", "$$wrap:$$pad('a'):b" `)).toEqual([ { args: [ { index: 9, length: 1, value: "1", }, ], index: 3, input: { index: 12, length: 9, value: "$$trim:$$", }, keyLength: 5, name: "pad", }, { index: 12, input: { index: 19, length: 2, value: "$$", }, keyLength: 6, name: "trim", }, { index: 25, input: { index: 32, length: 12, value: "$$pad('a'):b", }, keyLength: 6, name: "wrap", }, { args: [ { index: 38, length: 3, value: "a", }, ], index: 32, input: { index: 43, length: 1, value: "b", }, keyLength: 5, name: "pad", }, ]); }); (0, vitest_1.test)(`sanity 8`, () => { (0, vitest_1.expect)(functionsParser_1.functionsParser.matchAllFunctionsInLine(` '$$math\n`)).toEqual([]); }); (0, vitest_1.test)(`sanity 9`, () => { (0, vitest_1.expect)(functionsParser_1.functionsParser.matchAllFunctionsInLine(`"$$\n`)).toEqual([]); }); (0, vitest_1.test)(`sanity 10`, () => { (0, vitest_1.expect)(functionsParser_1.functionsParser.matchAllFunctionsInLine(`"$$a`)).toEqual([]); }); (0, vitest_1.test)(`sanity 11`, () => { (0, vitest_1.expect)(functionsParser_1.functionsParser.matchAllFunctionsInLine(`"$$a": "$$a"\n`)).toEqual([]); }); }); //# sourceMappingURL=functionsParser.test.js.map