@ondc/automation-mock-runner 0.2.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,7 +20,8 @@ export declare class MockRunner {
20
20
  runMeetRequirementsWithSession(actionId: string, sessionData: any): Promise<ExecutionResult>;
21
21
  getDefaultStep(api: string, actionId: string): MockPlaygroundConfigType["steps"][0];
22
22
  generateContext(actionId: string, action: string, sessionData?: any): any;
23
- getSessionDataUpToStep(index: number): Record<string, any>;
23
+ getSessionDataUpToStep(index: number): Promise<Record<string, any>>;
24
+ static runGetSave(payload: any, expression: string): Promise<ExecutionResult>;
24
25
  static encodeBase64(input: string): string;
25
26
  static decodeBase64(encoded: string): string;
26
27
  }
@@ -64,7 +64,7 @@ class MockRunner {
64
64
  const index = this.config.steps.findIndex((s) => s.action_id === actionId);
65
65
  // Deep clone to avoid mutations
66
66
  const defaultPayload = JSON.parse(JSON.stringify(step.mock.defaultPayload));
67
- const sessionData = this.getSessionDataUpToStep(index);
67
+ const sessionData = await this.getSessionDataUpToStep(index);
68
68
  // Validate inputs against schema if provided
69
69
  if (step.mock.inputs?.jsonSchema && Object.keys(inputs).length > 0) {
70
70
  // TODO: Add JSON schema validation for inputs
@@ -160,7 +160,7 @@ class MockRunner {
160
160
  }
161
161
  const index = this.config.steps.findIndex((s) => s.action_id === actionId);
162
162
  const schema = (0, function_registry_1.getFunctionSchema)("validate");
163
- const sessionData = this.getSessionDataUpToStep(index);
163
+ const sessionData = await this.getSessionDataUpToStep(index);
164
164
  const result = await this.getRunnerInstance().execute(MockRunner.decodeBase64(step.mock.validate), schema, [targetPayload, sessionData]);
165
165
  return result;
166
166
  }
@@ -210,7 +210,7 @@ class MockRunner {
210
210
  }
211
211
  const index = this.config.steps.findIndex((s) => s.action_id === actionId);
212
212
  const schema = (0, function_registry_1.getFunctionSchema)("meetsRequirements");
213
- const sessionData = this.getSessionDataUpToStep(index);
213
+ const sessionData = await this.getSessionDataUpToStep(index);
214
214
  const result = await this.getRunnerInstance().execute(MockRunner.decodeBase64(step.mock.requirements), schema, [sessionData]);
215
215
  return result;
216
216
  }
@@ -372,7 +372,7 @@ class MockRunner {
372
372
  },
373
373
  };
374
374
  }
375
- getSessionDataUpToStep(index) {
375
+ async getSessionDataUpToStep(index) {
376
376
  const config = this.config;
377
377
  if (index < 0 || index > config.steps.length) {
378
378
  this.logger.warn("Invalid step index for session data", {
@@ -396,6 +396,10 @@ class MockRunner {
396
396
  const saveData = config.steps[i]?.mock.saveData ?? {};
397
397
  for (const key in saveData) {
398
398
  const path = saveData[key];
399
+ const isAppend = key.startsWith("APPEND#");
400
+ const isEval = key.startsWith("EVAL#");
401
+ const evalExpression = key.split("#")[2];
402
+ const actualKey = isAppend ? key.split("#")[1] : key;
399
403
  try {
400
404
  // Validate JSONPath expression
401
405
  if (!path || typeof path !== "string") {
@@ -407,10 +411,10 @@ class MockRunner {
407
411
  continue;
408
412
  }
409
413
  const values = jsonpath_1.default.query(histItem.payload, path);
410
- const value = values[0];
411
- if (value !== undefined) {
412
- sessionData[key] = value;
413
- this.logger.debug("Session data extracted", {
414
+ if (isEval && evalExpression) {
415
+ // Evaluate the expression using the extracted values
416
+ sessionData[actualKey] = await MockRunner.runGetSave(values, evalExpression);
417
+ this.logger.debug("Session data extracted via EVAL", {
414
418
  step: i,
415
419
  key,
416
420
  path,
@@ -418,12 +422,25 @@ class MockRunner {
418
422
  });
419
423
  }
420
424
  else {
421
- this.logger.debug("No value found for JSONPath", {
422
- step: i,
423
- key,
424
- path,
425
- });
426
- sessionData[key] = null;
425
+ if (values !== undefined) {
426
+ sessionData[actualKey] = isAppend
427
+ ? (sessionData[actualKey] || []).concat(values)
428
+ : values;
429
+ this.logger.debug("Session data extracted", {
430
+ step: i,
431
+ key,
432
+ path,
433
+ hasValue: true,
434
+ });
435
+ }
436
+ else {
437
+ this.logger.debug("No value found for JSONPath", {
438
+ step: i,
439
+ key,
440
+ path,
441
+ });
442
+ sessionData[actualKey] = null;
443
+ }
427
444
  }
428
445
  }
429
446
  catch (error) {
@@ -438,6 +455,12 @@ class MockRunner {
438
455
  });
439
456
  return sessionData;
440
457
  }
458
+ static async runGetSave(payload, expression) {
459
+ const evalExpression = MockRunner.decodeBase64(expression);
460
+ const runner = runner_factory_1.RunnerFactory.createRunner();
461
+ const schema = (0, function_registry_1.getFunctionSchema)("getSave");
462
+ return await runner.execute(evalExpression, schema, [payload]);
463
+ }
441
464
  static encodeBase64(input) {
442
465
  const bytes = new TextEncoder().encode(input);
443
466
  return btoa(String.fromCharCode(...bytes));
@@ -1,4 +1,4 @@
1
- export type FunctionNamesType = "generate" | "validate" | "meetsRequirements";
1
+ export type FunctionNamesType = "generate" | "validate" | "meetsRequirements" | "getSave";
2
2
  export interface FunctionParameter {
3
3
  name: string;
4
4
  type: string;
@@ -122,6 +122,25 @@ function meetsRequirements(sessionData) {
122
122
  ${body}
123
123
  }`,
124
124
  },
125
+ getSave: {
126
+ name: "getSave",
127
+ parameters: [
128
+ {
129
+ name: "payload",
130
+ type: "Object",
131
+ description: "The API request or response payload",
132
+ required: true,
133
+ },
134
+ ],
135
+ returnType: {
136
+ type: "any",
137
+ description: "Returns any value",
138
+ },
139
+ description: "Evaluates custom code to get save value",
140
+ timeout: 3000,
141
+ defaultBody: "return null;",
142
+ template: (body) => body,
143
+ },
125
144
  };
126
145
  function getFunctionSchema(property) {
127
146
  const item = exports.FUNCTION_REGISTRY[property];
@@ -137,13 +137,29 @@ describe("MockRunner", () => {
137
137
  });
138
138
  });
139
139
  describe("Session Data Management", () => {
140
- it("should extract session data correctly", () => {
141
- const sessionData = mockRunner.getSessionDataUpToStep(0);
140
+ it("should extract session data correctly", async () => {
141
+ const sessionData = await mockRunner.getSessionDataUpToStep(0);
142
142
  expect(sessionData).toEqual({});
143
143
  });
144
- it("should handle invalid step indices", () => {
145
- const sessionData = mockRunner.getSessionDataUpToStep(-1);
144
+ it("should handle invalid step indices", async () => {
145
+ const sessionData = await mockRunner.getSessionDataUpToStep(-1);
146
146
  expect(sessionData).toEqual({});
147
147
  });
148
148
  });
149
+ describe("Eval type in saveData", () => {
150
+ it("should evaluate expressions in saveData correctly", async () => {
151
+ const fun = MockRunner_1.MockRunner.encodeBase64(`async function getSave(payload){
152
+ console.log('Payload in getSave:', payload);
153
+ return payload.a + payload.b;
154
+ }`);
155
+ const ob = {
156
+ a: 1,
157
+ b: 2,
158
+ };
159
+ const res = await MockRunner_1.MockRunner.runGetSave(ob, fun);
160
+ console.log(JSON.stringify(res, null, 2));
161
+ console.log(Object.keys(ob).length);
162
+ expect(res.result).toBe(ob.a + ob.b);
163
+ });
164
+ });
149
165
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ondc/automation-mock-runner",
3
- "version": "0.2.2",
3
+ "version": "1.0.0",
4
4
  "description": "A TypeScript library for ONDC automation mock runner",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",