diff --git a/packages/tagscript/src/lib/Interpreter/Interpreter.ts b/packages/tagscript/src/lib/Interpreter/Interpreter.ts index 95bbbe89..fddf68ec 100644 --- a/packages/tagscript/src/lib/Interpreter/Interpreter.ts +++ b/packages/tagscript/src/lib/Interpreter/Interpreter.ts @@ -84,8 +84,7 @@ export class Interpreter { } protected getAcceptors(ctx: Context) { - const acceptors = asyncFilter(this.parsers, (p) => p.willAccept(ctx)); - return acceptors; + return asyncFilter(this.parsers, (p) => p.willAccept(ctx)); } private getContext(node: Node, final: string, response: Response, originalMessage: string, tagLimit: number, parenType = ParenType.Both) { diff --git a/packages/tagscript/src/lib/Parsers/JSONVar.ts b/packages/tagscript/src/lib/Parsers/JSONVar.ts new file mode 100644 index 00000000..deede250 --- /dev/null +++ b/packages/tagscript/src/lib/Parsers/JSONVar.ts @@ -0,0 +1,27 @@ +import { SafeObjectTransformer } from '../Transformer'; +import type { IParser } from '../interfaces'; +import type { Context } from '../Interpreter'; +import { BaseParser } from './Base'; + +/** + * JSON is useful when using fetch. You can get all the properties of a JSON object using parameters. + * @usage + * ```yaml + * {json(name):value} + * ``` + * @example + * ```yaml + * {json(data):{"name": "John Doe", "age": 30}} + * Your age is `{data.age}`. + * ``` + */ +export class JSONVarParser extends BaseParser implements IParser { + public constructor() { + super(['json'], true, true); + } + + public parse(ctx: Context) { + ctx.response.variables[ctx.tag.parameter!] = new SafeObjectTransformer(ctx.tag.payload!); + return ''; + } +} diff --git a/packages/tagscript/src/lib/Parsers/index.ts b/packages/tagscript/src/lib/Parsers/index.ts index d8d31b95..183034d5 100644 --- a/packages/tagscript/src/lib/Parsers/index.ts +++ b/packages/tagscript/src/lib/Parsers/index.ts @@ -5,6 +5,7 @@ export * from './Define'; export * from './FiftyFifty'; export * from './Format'; export * from './Includes'; +export * from './JSONVar'; export * from './LooseVars'; export * from './Random'; export * from './Range'; diff --git a/packages/tagscript/src/lib/Transformer/Object.ts b/packages/tagscript/src/lib/Transformer/Object.ts index 448955fb..16adf113 100644 --- a/packages/tagscript/src/lib/Transformer/Object.ts +++ b/packages/tagscript/src/lib/Transformer/Object.ts @@ -6,7 +6,8 @@ import type { Lexer } from '../Interpreter'; */ export class SafeObjectTransformer implements ITransformer { private obj: Record; - public constructor(obj: Record) { + + public constructor(obj: Record | string) { this.obj = this.makeObject(obj); } @@ -18,8 +19,8 @@ export class SafeObjectTransformer implements ITransformer { return attribute ? `${attribute}` : null; } - private makeObject(obj: Record) { - const safeObject = JSON.parse(JSON.stringify(obj)) as Record; + private makeObject(obj: Record | string) { + const safeObject = JSON.parse(typeof obj === 'string' ? obj : JSON.stringify(obj)) as Record; Object.defineProperty(safeObject, 'toString', { value: obj.toString.bind(obj) }); diff --git a/packages/tagscript/tests/Parsers/JSONVar.test.ts b/packages/tagscript/tests/Parsers/JSONVar.test.ts new file mode 100644 index 00000000..cecf36b1 --- /dev/null +++ b/packages/tagscript/tests/Parsers/JSONVar.test.ts @@ -0,0 +1,23 @@ +import { Interpreter, JSONVarParser, Response, SafeObjectTransformer, StrictVarsParser } from '../../src'; + +describe('JSONVar', () => { + test('GIVEN a JSON in json var THEN store it as an object and show results using the parameter', async () => { + const ts = new Interpreter(new JSONVarParser(), new StrictVarsParser()); + + const text = '{json(data):{"name": "John Doe", "age": 30}}'; + + expect(await ts.run(text)).toStrictEqual( + new Response({ + data: new SafeObjectTransformer('{"name": "John Doe", "age": 30}') + }).setValues('', text) + ); + + const text1 = `${text}{data.name}`; + + expect(await ts.run(text1)).toStrictEqual( + new Response({ + data: new SafeObjectTransformer('{"name": "John Doe", "age": 30}') + }).setValues('John Doe', text1) + ); + }); +});