ondc-code-generator 0.4.5 → 0.5.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.
Files changed (31) hide show
  1. package/dist/constants/syntax.d.ts +1 -1
  2. package/dist/constants/syntax.js +98 -2
  3. package/dist/generator/config-compiler.js +7 -3
  4. package/dist/generator/generators/python/py-ast.d.ts +1 -0
  5. package/dist/generator/generators/python/py-ast.js +72 -0
  6. package/dist/generator/generators/python/py-generator.d.ts +19 -0
  7. package/dist/generator/generators/python/py-generator.js +247 -1
  8. package/dist/generator/generators/python/templates/api-test.mustache +29 -0
  9. package/dist/generator/generators/python/templates/api-tests-init.mustache +12 -0
  10. package/dist/generator/generators/python/templates/json-normalizer.mustache +86 -0
  11. package/dist/generator/generators/python/templates/json-path-utils.mustache +33 -0
  12. package/dist/generator/generators/python/templates/master-doc.mustache +40 -0
  13. package/dist/generator/generators/python/templates/requirements.mustache +2 -0
  14. package/dist/generator/generators/python/templates/test-config.mustache +62 -0
  15. package/dist/generator/generators/python/templates/test-object.mustache +29 -0
  16. package/dist/generator/generators/python/templates/validation-code.mustache +35 -0
  17. package/dist/generator/generators/python/templates/validation-utils.mustache +93 -0
  18. package/dist/generator/generators/typescript/templates/api-test.mustache +29 -1
  19. package/dist/generator/generators/typescript/templates/index.mustache +33 -0
  20. package/dist/generator/generators/typescript/templates/json-normalizer.mustache +101 -36
  21. package/dist/generator/generators/typescript/templates/test-config.mustache +45 -5
  22. package/dist/generator/generators/typescript/templates/test-object.mustache +11 -1
  23. package/dist/generator/generators/typescript/templates/validation-code.mustache +12 -12
  24. package/dist/generator/generators/typescript/ts-generator.js +25 -13
  25. package/dist/generator/validators/tests-config/sub-validations.js +3 -3
  26. package/dist/index.js +15 -2
  27. package/dist/types/compiler-types.d.ts +2 -1
  28. package/dist/types/compiler-types.js +1 -0
  29. package/dist/utils/fs-utils.js +43 -0
  30. package/dist/utils/general-utils/string-utils.js +2 -2
  31. package/package.json +1 -1
@@ -23,13 +23,14 @@ export class TypescriptGenerator extends CodeGenerator {
23
23
  for (const key in testConfig) {
24
24
  const testObjects = testConfig[key];
25
25
  const betaConfig = {
26
- [TestObjectSyntax.Name]: key,
26
+ [TestObjectSyntax.Name]: key + "Validations",
27
27
  [TestObjectSyntax.Return]: testObjects,
28
28
  };
29
29
  const testFunction = await this.generateTestFunction(betaConfig);
30
30
  const apiTestTemplate = readFileSync(path.resolve(__dirname, "./templates/api-test.mustache"), "utf-8");
31
31
  const finalCode = Mustache.render(apiTestTemplate, {
32
32
  functionCode: testFunction.code,
33
+ apiName: key,
33
34
  });
34
35
  await writeAndFormatCode(this.rootPath, `./api-tests/${key}.ts`, finalCode, "typescript");
35
36
  }
@@ -63,6 +64,9 @@ export class TypescriptGenerator extends CodeGenerator {
63
64
  : undefined,
64
65
  validationCode: await this.createValidationLogicCode(testObject),
65
66
  successCode: testObject[TestObjectSyntax.SuccessCode] ?? 200,
67
+ errorCode: testObject[TestObjectSyntax.ErrorCode] ?? 30000,
68
+ testName: testObject[TestObjectSyntax.Name],
69
+ TEST_OBJECT: `${JSON.stringify(testObject)}`,
66
70
  };
67
71
  return {
68
72
  funcName: testObject[TestObjectSyntax.Name],
@@ -80,6 +84,8 @@ export class TypescriptGenerator extends CodeGenerator {
80
84
  returnStatement: returnStatement,
81
85
  errorCode: testObject[TestObjectSyntax.ErrorCode] ?? 30000,
82
86
  errorDescription: this.CreateErrorMarkdown(testObject, skipList),
87
+ testName: testObject[TestObjectSyntax.Name],
88
+ TEST_OBJECT: `${JSON.stringify(testObject)}`,
83
89
  });
84
90
  }
85
91
  else {
@@ -96,6 +102,8 @@ export class TypescriptGenerator extends CodeGenerator {
96
102
  isNested: true,
97
103
  nestedFunctions: functionCodes.map((f) => f.code).join("\n"),
98
104
  names: names,
105
+ testName: testObject[TestObjectSyntax.Name],
106
+ TEST_OBJECT: `${JSON.stringify(testObject)}`,
99
107
  });
100
108
  }
101
109
  };
@@ -158,31 +166,35 @@ export class TypescriptGenerator extends CodeGenerator {
158
166
  }
159
167
  generateIndexFile(apis, functionName = "L1Validations") {
160
168
  functionName = functionName.replace(/[^a-zA-Z0-9_]/g, "");
161
- const importsCode = apis
169
+ let importsCode = apis
162
170
  .map((api) => `import ${api} from "./api-tests/${api}";`)
163
171
  .join("\n");
172
+ importsCode += `\nimport { ValidationConfig,validationOutput } from "./types/test-config";`;
173
+ importsCode += `\nimport normalizeKeys from "./utils/json-normalizer";`;
174
+ const masterTemplate = readFileSync(path.resolve(__dirname, "./templates/index.mustache"), "utf-8");
164
175
  const masterFunction = `
165
- export function perform${functionName}(action: string, payload: any,allErrors = false, externalData : any = {}) {
166
- const normalizedPayload = normalizeKeys(payload);
167
- externalData._SELF = normalizedPayload;
176
+ export function perform${functionName}(action: string, payload: any, config?: Partial<ValidationConfig>, externalData: any = {}) {
177
+ const completeConfig: ValidationConfig = {
178
+ ...{ onlyInvalid: true, standardLogs: false, hideParentErrors: true, _debug: false },
179
+ ...config,
180
+ };
181
+ const normalizedPayload = normalizeKeys(JSON.parse(JSON.stringify(payload)));
182
+ externalData._SELF = normalizedPayload;
168
183
  switch (action) {
169
184
  ${apis
170
185
  .map((api) => `case "${api}": return ${api}({
171
186
  payload: normalizedPayload,
172
187
  externalData: externalData,
173
- config: {
174
- runAllValidations: allErrors,
175
- },
188
+ config: completeConfig,
176
189
  });`)
177
190
  .join("\n")}
178
191
  default:
179
192
  throw new Error("Action not found");
180
193
  }
181
194
  }`;
182
- return `
183
- import normalizeKeys from "./utils/json-normalizer";
184
- ${importsCode}
185
- ${masterFunction}
186
- `;
195
+ return Mustache.render(masterTemplate, {
196
+ importsCode: importsCode,
197
+ masterFunction: masterFunction,
198
+ });
187
199
  }
188
200
  }
@@ -1,4 +1,4 @@
1
- import { TestObjectSyntax, nodeReservedKeywords, ExternalDataSyntax, ConfigSyntax, } from "../../../constants/syntax.js";
1
+ import { TestObjectSyntax, ReservedKeywords, ExternalDataSyntax, ConfigSyntax, } from "../../../constants/syntax.js";
2
2
  import { buildAst } from "../../../services/return-complier/ast.js";
3
3
  import { checkValidVariables } from "../../../services/return-complier/ast-functions/semantic-validations.js";
4
4
  import { parseReturnInput } from "../../../services/return-complier/parser.js";
@@ -31,7 +31,7 @@ export class NameValidator extends TestObjectValidator {
31
31
  if (name.length < 1) {
32
32
  throw new Error(`${TestObjectSyntax.Name} can't be a non-empty string at path ${this.validationPath}`);
33
33
  }
34
- if (nodeReservedKeywords.has(name)) {
34
+ if (ReservedKeywords.has(name)) {
35
35
  throw new Error(`${TestObjectSyntax.Name} can't be a reserved keyword at path ${this.validationPath}`);
36
36
  }
37
37
  if (!isSnakeCase(name)) {
@@ -141,7 +141,7 @@ export class VariableValidator extends TestObjectValidator {
141
141
  this.minimal = minimal;
142
142
  }
143
143
  validateKey(key) {
144
- if (nodeReservedKeywords.has(key)) {
144
+ if (ReservedKeywords.has(key)) {
145
145
  throw new Error(`${key} can't be a reserved keyword at path ${this.validationPath}`);
146
146
  }
147
147
  if (key.includes(" ")) {
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ export { ConfigCompiler };
7
7
  // const __dirname = path.dirname(__filename);
8
8
  // import { SupportedLanguages } from "./types/compiler-types.js";
9
9
  // const main = async () => {
10
- // const compiler = new ConfigCompiler(SupportedLanguages.Typescript);
10
+ // const compiler = new ConfigCompiler(SupportedLanguages.Python);
11
11
  // const buildPath = path.resolve(__dirname, "../samples/build.yaml");
12
12
  // const valConfigPath = path.resolve(
13
13
  // __dirname,
@@ -16,7 +16,20 @@ export { ConfigCompiler };
16
16
  // const buildYaml = readFileSync(buildPath, "utf-8");
17
17
  // const valConfig = JSON.parse(readFileSync(valConfigPath, "utf-8"));
18
18
  // await compiler.initialize(buildYaml);
19
- // await compiler.generateCode(valConfig, "L1-validations", false, "./alpha/");
19
+ // await compiler.generateCode(
20
+ // valConfig,
21
+ // "L1_validations",
22
+ // false,
23
+ // "./alpha/python/"
24
+ // );
25
+ // const compilerTy = new ConfigCompiler(SupportedLanguages.Typescript);
26
+ // await compilerTy.initialize(buildYaml);
27
+ // await compilerTy.generateCode(
28
+ // valConfig,
29
+ // "L1_validations",
30
+ // false,
31
+ // "./alpha/typescript/"
32
+ // );
20
33
  // };
21
34
  // (async () => {
22
35
  // await main();
@@ -1,3 +1,4 @@
1
1
  export declare enum SupportedLanguages {
2
- Typescript = "typescript"
2
+ Typescript = "typescript",
3
+ Python = "python"
3
4
  }
@@ -1,4 +1,5 @@
1
1
  export var SupportedLanguages;
2
2
  (function (SupportedLanguages) {
3
3
  SupportedLanguages["Typescript"] = "typescript";
4
+ SupportedLanguages["Python"] = "python";
4
5
  })(SupportedLanguages || (SupportedLanguages = {}));
@@ -9,11 +9,54 @@ export function writeFileWithFsExtra(rootPath, relativeFilePath, content) {
9
9
  fs.outputFileSync(filePath, content);
10
10
  }
11
11
  export async function formatCode(code, lang) {
12
+ if (lang === "text") {
13
+ // No formatting for plain text files
14
+ return code;
15
+ }
16
+ if (lang == "python") {
17
+ // Basic Python formatting - clean up extra whitespace and blank lines
18
+ return formatPythonCode(code);
19
+ }
12
20
  return await prettier.format(code, {
13
21
  parser: lang,
14
22
  tabWidth: 4,
15
23
  });
16
24
  }
25
+ function formatPythonCode(code) {
26
+ const lines = code.split("\n");
27
+ const formattedLines = [];
28
+ for (let i = 0; i < lines.length; i++) {
29
+ const line = lines[i];
30
+ // Skip lines that are only whitespace
31
+ if (line.trim() === "") {
32
+ // Only add empty line if the previous line wasn't empty
33
+ if (formattedLines.length > 0 &&
34
+ formattedLines[formattedLines.length - 1].trim() !== "") {
35
+ formattedLines.push("");
36
+ }
37
+ continue;
38
+ }
39
+ // Add the line as-is (preserve existing indentation)
40
+ formattedLines.push(line);
41
+ }
42
+ // Remove multiple consecutive empty lines
43
+ const cleanedLines = [];
44
+ let lastWasEmpty = false;
45
+ for (const line of formattedLines) {
46
+ const isEmpty = line.trim() === "";
47
+ if (isEmpty && lastWasEmpty) {
48
+ continue; // Skip consecutive empty lines
49
+ }
50
+ cleanedLines.push(line);
51
+ lastWasEmpty = isEmpty;
52
+ }
53
+ // Remove trailing empty lines
54
+ while (cleanedLines.length > 0 &&
55
+ cleanedLines[cleanedLines.length - 1].trim() === "") {
56
+ cleanedLines.pop();
57
+ }
58
+ return cleanedLines.join("\n") + "\n";
59
+ }
17
60
  export async function writeAndFormatCode(rootPath, relativeFilePath, content, lang) {
18
61
  const formattedCode = await formatCode(content, lang);
19
62
  writeFileWithFsExtra(rootPath, relativeFilePath, formattedCode);
@@ -1,4 +1,4 @@
1
- import { nodeReservedKeywords, TestObjectSyntax, } from "../../constants/syntax.js";
1
+ import { ReservedKeywords, TestObjectSyntax } from "../../constants/syntax.js";
2
2
  import { getVariablesFromTest } from "./test-object-utils.js";
3
3
  /**
4
4
  * Check if the string matches the pattern: lowercase letters and underscores only, no leading or trailing underscores
@@ -15,7 +15,7 @@ export function isValidVariableName(input) {
15
15
  const validVariableNameRegex = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
16
16
  // Check if input matches the regex
17
17
  const matchesPattern = validVariableNameRegex.test(input);
18
- const isNotReservedKeyword = !nodeReservedKeywords.has(input);
18
+ const isNotReservedKeyword = !ReservedKeywords.has(input);
19
19
  return matchesPattern && isNotReservedKeyword;
20
20
  }
21
21
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ondc-code-generator",
3
- "version": "0.4.5",
3
+ "version": "0.5.0",
4
4
  "description": "generate code from build.yaml ",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",