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.
- package/dist/constants/syntax.d.ts +1 -1
- package/dist/constants/syntax.js +98 -2
- package/dist/generator/config-compiler.js +7 -3
- package/dist/generator/generators/python/py-ast.d.ts +1 -0
- package/dist/generator/generators/python/py-ast.js +72 -0
- package/dist/generator/generators/python/py-generator.d.ts +19 -0
- package/dist/generator/generators/python/py-generator.js +247 -1
- package/dist/generator/generators/python/templates/api-test.mustache +29 -0
- package/dist/generator/generators/python/templates/api-tests-init.mustache +12 -0
- package/dist/generator/generators/python/templates/json-normalizer.mustache +86 -0
- package/dist/generator/generators/python/templates/json-path-utils.mustache +33 -0
- package/dist/generator/generators/python/templates/master-doc.mustache +40 -0
- package/dist/generator/generators/python/templates/requirements.mustache +2 -0
- package/dist/generator/generators/python/templates/test-config.mustache +62 -0
- package/dist/generator/generators/python/templates/test-object.mustache +29 -0
- package/dist/generator/generators/python/templates/validation-code.mustache +35 -0
- package/dist/generator/generators/python/templates/validation-utils.mustache +93 -0
- package/dist/generator/generators/typescript/templates/api-test.mustache +29 -1
- package/dist/generator/generators/typescript/templates/index.mustache +33 -0
- package/dist/generator/generators/typescript/templates/json-normalizer.mustache +101 -36
- package/dist/generator/generators/typescript/templates/test-config.mustache +45 -5
- package/dist/generator/generators/typescript/templates/test-object.mustache +11 -1
- package/dist/generator/generators/typescript/templates/validation-code.mustache +12 -12
- package/dist/generator/generators/typescript/ts-generator.js +25 -13
- package/dist/generator/validators/tests-config/sub-validations.js +3 -3
- package/dist/index.js +15 -2
- package/dist/types/compiler-types.d.ts +2 -1
- package/dist/types/compiler-types.js +1 -0
- package/dist/utils/fs-utils.js +43 -0
- package/dist/utils/general-utils/string-utils.js +2 -2
- 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
|
-
|
|
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,
|
|
166
|
-
|
|
167
|
-
|
|
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
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
`;
|
|
195
|
+
return Mustache.render(masterTemplate, {
|
|
196
|
+
importsCode: importsCode,
|
|
197
|
+
masterFunction: masterFunction,
|
|
198
|
+
});
|
|
187
199
|
}
|
|
188
200
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TestObjectSyntax,
|
|
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 (
|
|
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 (
|
|
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.
|
|
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(
|
|
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();
|
package/dist/utils/fs-utils.js
CHANGED
|
@@ -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 {
|
|
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 = !
|
|
18
|
+
const isNotReservedKeyword = !ReservedKeywords.has(input);
|
|
19
19
|
return matchesPattern && isNotReservedKeyword;
|
|
20
20
|
}
|
|
21
21
|
/**
|