@ondc/automation-mock-runner 1.3.49 → 1.3.51

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.
@@ -15,9 +15,12 @@ export declare class CodeValidator {
15
15
  * Validate that return statements match expected structure
16
16
  */
17
17
  /**
18
- * Collect ReturnStatement arguments belonging only to the outer (top-level)
19
- * function. Nested function/arrow bodies are skipped their returns are
20
- * not the function's contract and would otherwise produce false positives.
18
+ * Collect ReturnStatement arguments belonging only to the target function.
19
+ * When `targetFnName` is given and a top-level `function <name>(...)` exists,
20
+ * we walk only that body sibling helpers like `function x(){return "hi"}`
21
+ * declared next to `validate` are ignored. Returns inside nested
22
+ * functions/arrows are also skipped (they aren't the contract).
23
+ * Falls back to the whole AST when no named match is found.
21
24
  */
22
25
  private static collectTopLevelReturns;
23
26
  private static validateReturnStructure;
@@ -139,7 +139,7 @@ class CodeValidator {
139
139
  });
140
140
  // 5. Validate return type structure (for validate and meetsRequirements)
141
141
  if (schema.returnType.properties) {
142
- const returnValidation = this.validateReturnStructure(ast, schema.returnType.properties);
142
+ const returnValidation = this.validateReturnStructure(ast, schema.returnType.properties, schema.name);
143
143
  errors.push(...returnValidation);
144
144
  }
145
145
  // 6. Check for best practices
@@ -172,24 +172,27 @@ class CodeValidator {
172
172
  * Validate that return statements match expected structure
173
173
  */
174
174
  /**
175
- * Collect ReturnStatement arguments belonging only to the outer (top-level)
176
- * function. Nested function/arrow bodies are skipped their returns are
177
- * not the function's contract and would otherwise produce false positives.
175
+ * Collect ReturnStatement arguments belonging only to the target function.
176
+ * When `targetFnName` is given and a top-level `function <name>(...)` exists,
177
+ * we walk only that body sibling helpers like `function x(){return "hi"}`
178
+ * declared next to `validate` are ignored. Returns inside nested
179
+ * functions/arrows are also skipped (they aren't the contract).
180
+ * Falls back to the whole AST when no named match is found.
178
181
  */
179
- static collectTopLevelReturns(ast) {
182
+ static collectTopLevelReturns(ast, targetFnName) {
180
183
  const returns = [];
181
- let depth = 0;
182
- const enterFn = (node, _st, c) => {
183
- if (depth === 0) {
184
- depth++;
185
- c(node.body, null);
186
- depth--;
187
- }
188
- };
189
- walk.recursive(ast, null, {
190
- FunctionDeclaration: enterFn,
191
- FunctionExpression: enterFn,
192
- ArrowFunctionExpression: enterFn,
184
+ const programBody = Array.isArray(ast.body)
185
+ ? ast.body
186
+ : [];
187
+ const targetFn = targetFnName
188
+ ? programBody.find((n) => n.type === "FunctionDeclaration" && n.id?.name === targetFnName)
189
+ : undefined;
190
+ const walkRoot = targetFn ? targetFn.body : ast;
191
+ const skip = () => { };
192
+ walk.recursive(walkRoot, null, {
193
+ FunctionDeclaration: skip,
194
+ FunctionExpression: skip,
195
+ ArrowFunctionExpression: skip,
193
196
  ReturnStatement(node) {
194
197
  if (node.argument)
195
198
  returns.push(node.argument);
@@ -197,9 +200,9 @@ class CodeValidator {
197
200
  });
198
201
  return returns;
199
202
  }
200
- static validateReturnStructure(ast, expectedProperties) {
203
+ static validateReturnStructure(ast, expectedProperties, targetFnName) {
201
204
  const warnings = [];
202
- const foundReturns = this.collectTopLevelReturns(ast);
205
+ const foundReturns = this.collectTopLevelReturns(ast, targetFnName);
203
206
  // Check if we have return statements
204
207
  if (foundReturns.length === 0) {
205
208
  warnings.push(`Function should return an object with properties: ${Object.keys(expectedProperties).join(", ")}`);
@@ -339,7 +342,7 @@ class CodeValidator {
339
342
  */
340
343
  static checkBestPractices(ast, schema) {
341
344
  const warnings = [];
342
- const hasReturn = this.collectTopLevelReturns(ast).length > 0;
345
+ const hasReturn = this.collectTopLevelReturns(ast, schema.name).length > 0;
343
346
  if (!hasReturn) {
344
347
  warnings.push(`Function should return a value (expected: ${schema.returnType.description})`);
345
348
  }
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const code_validator_1 = require("../lib/validators/code-validator");
4
4
  const function_registry_1 = require("../lib/constants/function-registry");
5
5
  const validateSchema = (0, function_registry_1.getFunctionSchema)("validate");
6
+ const meetsRequirementsSchema = (0, function_registry_1.getFunctionSchema)("meetsRequirements");
7
+ const generateSchema = (0, function_registry_1.getFunctionSchema)("generate");
6
8
  describe("CodeValidator.validate — return structure", () => {
7
9
  it("accepts an outer return with the full expected shape", () => {
8
10
  const code = `
@@ -63,6 +65,54 @@ describe("CodeValidator.validate — return structure", () => {
63
65
  expect(result.errors).toEqual([]);
64
66
  expect(result.isValid).toBe(true);
65
67
  });
68
+ it("ignores sibling top-level helper function returns (validate)", () => {
69
+ const code = `
70
+ function x() {
71
+ return "hello";
72
+ }
73
+ function validate(targetPayload, sessionData) {
74
+ let some = x();
75
+ return { valid: true, code: 200, description: "Valid request" };
76
+ }
77
+ `;
78
+ const result = code_validator_1.CodeValidator.validate(code, validateSchema);
79
+ expect(result.errors).toEqual([]);
80
+ expect(result.warnings).toEqual([]);
81
+ expect(result.isValid).toBe(true);
82
+ });
83
+ it("does not warn 'should return a value' when target fn has a return (validate)", () => {
84
+ const code = `
85
+ function validate(targetPayload, sessionData) {
86
+ return { valid: true, code: 200, description: "Valid request" };
87
+ }
88
+ `;
89
+ const result = code_validator_1.CodeValidator.validate(code, validateSchema);
90
+ expect(result.warnings.some((w) => w.includes("should return a value"))).toBe(false);
91
+ });
92
+ it("does not warn 'should return a value' for generate with a return", () => {
93
+ const code = `
94
+ async function generate(defaultPayload, sessionData) {
95
+ return defaultPayload;
96
+ }
97
+ `;
98
+ const result = code_validator_1.CodeValidator.validate(code, generateSchema);
99
+ expect(result.warnings.some((w) => w.includes("should return a value"))).toBe(false);
100
+ expect(result.isValid).toBe(true);
101
+ });
102
+ it("ignores sibling top-level helper function returns (meetsRequirements)", () => {
103
+ const code = `
104
+ function helper() {
105
+ return 123;
106
+ }
107
+ function meetsRequirements(sessionData) {
108
+ const n = helper();
109
+ return { valid: true, code: 200, description: "Requirements met" };
110
+ }
111
+ `;
112
+ const result = code_validator_1.CodeValidator.validate(code, meetsRequirementsSchema);
113
+ expect(result.errors).toEqual([]);
114
+ expect(result.isValid).toBe(true);
115
+ });
66
116
  it("warns when only a nested helper returns and the outer function has no return", () => {
67
117
  const code = `
68
118
  function validate(targetPayload, sessionData) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ondc/automation-mock-runner",
3
- "version": "1.3.49",
3
+ "version": "1.3.51",
4
4
  "description": "A TypeScript library for ONDC automation mock runner",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",