ondc-code-generator 0.0.1 → 0.0.2
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.js +2 -0
- package/dist/example.js +22 -0
- package/dist/{Generator → generator}/config-compiler.js +25 -4
- package/dist/{Generator → generator}/generators/documentation/markdown-message-generator.js +0 -13
- package/dist/{Generator → generator}/generators/typescript/ts-generator.js +3 -4
- package/dist/{Generator → generator}/validators/abstract-validator.js +1 -1
- package/dist/{Generator → generator}/validators/config-validator.js +4 -4
- package/dist/{Generator → generator}/validators/session-data-config/session-data-validator.js +2 -2
- package/dist/{Generator → generator}/validators/tests-config/sub-validations.js +38 -33
- package/dist/{Generator → generator}/validators/tests-config/test-list-validator.js +3 -3
- package/dist/{Generator → generator}/validators/tests-config/test-validator.js +7 -7
- package/dist/index.js +1 -38
- package/dist/services/return-complier/tokens.js +3 -0
- package/dist/utils/general-utils/string-utils.js +10 -2
- package/package.json +4 -2
- package/dist/Generator/config-validator.js +0 -21
- package/dist/Generator/generators/markdown-message-generator.js +0 -25
- package/dist/Generator/pipline.js +0 -1
- package/dist/Generator/validators/validation-error.js +0 -9
- package/dist/services/rename-later/main.js +0 -1
- package/dist/services/rename-later/parser.js +0 -22
- package/dist/services/rename-later/tokens.js +0 -32
- package/dist/services/rename-later/tokens1.js +0 -33
- package/dist/utils/file-system.js +0 -1
- /package/dist/{Generator → generator}/generators/classes/abstract-generator.js +0 -0
- /package/dist/{Generator → generator}/generators/documentation/md-generator.js +0 -0
- /package/dist/{Generator → generator}/generators/python/py-generator.js +0 -0
- /package/dist/{Generator → generator}/generators/typescript/templates/json-path-utils.js +0 -0
- /package/dist/{Generator → generator}/generators/typescript/templates/validation-utils.js +0 -0
- /package/dist/{Generator → generator}/generators/typescript/ts-ast.js +0 -0
package/dist/constants/syntax.js
CHANGED
|
@@ -5,6 +5,7 @@ export var TestObjectSyntax;
|
|
|
5
5
|
TestObjectSyntax["Scope"] = "_SCOPE_";
|
|
6
6
|
TestObjectSyntax["Continue"] = "_CONTINUE_";
|
|
7
7
|
TestObjectSyntax["ErrorCode"] = "_ERROR_CODE_";
|
|
8
|
+
TestObjectSyntax["SuccessCode"] = "_SUCCESS_CODE_";
|
|
8
9
|
})(TestObjectSyntax || (TestObjectSyntax = {}));
|
|
9
10
|
export const ExternalDataSyntax = "_EXTERNAL";
|
|
10
11
|
export var ConfigSyntax;
|
|
@@ -18,6 +19,7 @@ export const ConfigKeyWords = [
|
|
|
18
19
|
TestObjectSyntax.Scope,
|
|
19
20
|
TestObjectSyntax.Continue,
|
|
20
21
|
TestObjectSyntax.ErrorCode,
|
|
22
|
+
TestObjectSyntax.SuccessCode,
|
|
21
23
|
ConfigSyntax.Tests,
|
|
22
24
|
ConfigSyntax.SessionData,
|
|
23
25
|
];
|
package/dist/example.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// import { readFileSync } from "fs";
|
|
3
|
+
// import path from "path";
|
|
4
|
+
// import { fileURLToPath } from "url";
|
|
5
|
+
// import { SupportedLanguages } from "./types/compiler-types.js";
|
|
6
|
+
// const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
// const __dirname = path.dirname(__filename);
|
|
8
|
+
// const main = async () => {
|
|
9
|
+
// const compiler = new ConfigCompiler(SupportedLanguages.Typescript);
|
|
10
|
+
// const buildPath = path.resolve(__dirname, "../samples/build.yaml");
|
|
11
|
+
// const valConfigPath = path.resolve(
|
|
12
|
+
// __dirname,
|
|
13
|
+
// "../samples/validation-config.json"
|
|
14
|
+
// );
|
|
15
|
+
// const buildYaml = readFileSync(buildPath, "utf-8");
|
|
16
|
+
// const valConfig = JSON.parse(readFileSync(valConfigPath, "utf-8"));
|
|
17
|
+
// await compiler.initialize(buildYaml);
|
|
18
|
+
// await compiler.generateCode(valConfig);
|
|
19
|
+
// };
|
|
20
|
+
// (async () => {
|
|
21
|
+
// await main();
|
|
22
|
+
// })();
|
|
@@ -4,6 +4,9 @@ import logger from "../utils/logger.js";
|
|
|
4
4
|
import { SupportedLanguages } from "../types/compiler-types.js";
|
|
5
5
|
import { TypescriptGenerator } from "./generators/typescript/ts-generator.js";
|
|
6
6
|
import { ConfigValidator } from "./validators/config-validator.js";
|
|
7
|
+
import { writeAndFormatCode } from "../utils/fs-utils.js";
|
|
8
|
+
import { readFileSync } from "fs";
|
|
9
|
+
import Mustache from "mustache";
|
|
7
10
|
const defaultConfig = {
|
|
8
11
|
removeRequiredfromSchema: true,
|
|
9
12
|
removeEnumsfromSchema: true,
|
|
@@ -15,7 +18,7 @@ export class ConfigCompiler {
|
|
|
15
18
|
const finalConfig = { ...defaultConfig, ...generatorConfig };
|
|
16
19
|
this.buildData = await loadAndDereferenceYaml(buildYaml);
|
|
17
20
|
this.jsonSchemas = await this.SchemaExtactionService.extractSchemas(this.buildData, finalConfig.removeRequiredfromSchema, finalConfig.removeEnumsfromSchema);
|
|
18
|
-
this.
|
|
21
|
+
this.possibleJsonPaths = this.SchemaExtactionService.extractPossiblePaths(this.jsonSchemas);
|
|
19
22
|
const errors = this.buildData["x-errorcodes"];
|
|
20
23
|
this.errorDefinitions = errors.code;
|
|
21
24
|
};
|
|
@@ -25,11 +28,11 @@ export class ConfigCompiler {
|
|
|
25
28
|
throw new Error("Build data not initialized");
|
|
26
29
|
if (!this.jsonSchemas)
|
|
27
30
|
throw new Error("Schemas not initialized");
|
|
28
|
-
if (!this.
|
|
31
|
+
if (!this.possibleJsonPaths)
|
|
29
32
|
throw new Error("Possible paths not initialized");
|
|
30
33
|
if (!this.errorDefinitions)
|
|
31
34
|
throw new Error("Error definitions not initialized");
|
|
32
|
-
await new ConfigValidator("", valConfig, this.
|
|
35
|
+
await new ConfigValidator("", valConfig, this.possibleJsonPaths, this.errorDefinitions).validate();
|
|
33
36
|
}
|
|
34
37
|
catch (e) {
|
|
35
38
|
logger.error(e);
|
|
@@ -41,12 +44,30 @@ export class ConfigCompiler {
|
|
|
41
44
|
// Generate code based on the language
|
|
42
45
|
switch (this.language) {
|
|
43
46
|
case SupportedLanguages.Typescript:
|
|
44
|
-
await new TypescriptGenerator(valConfig, this.errorDefinitions ?? [], "./L1-validations").generateCode();
|
|
47
|
+
await new TypescriptGenerator(valConfig, this.errorDefinitions ?? [], "./generated/L1-validations").generateCode();
|
|
45
48
|
break;
|
|
46
49
|
default:
|
|
47
50
|
throw new Error("Language not supported");
|
|
48
51
|
}
|
|
49
52
|
};
|
|
53
|
+
this.generateL0Schema = async () => {
|
|
54
|
+
if (!this.jsonSchemas) {
|
|
55
|
+
throw new Error("Schemas not initialized");
|
|
56
|
+
}
|
|
57
|
+
for (const schema in this.jsonSchemas) {
|
|
58
|
+
const json = this.jsonSchemas[schema];
|
|
59
|
+
writeAndFormatCode(`./generated/L0-schemas`, `${schema}.ts`, `export const ${schema} = ${JSON.stringify(json, null, 2)}`, "typescript");
|
|
60
|
+
}
|
|
61
|
+
const actions = Object.keys(this.jsonSchemas).map((schema) => {
|
|
62
|
+
return {
|
|
63
|
+
action: schema,
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
const template = readFileSync("/Users/rudranshsinghal/ondc/automation-utility/official-code/code-generator/src/generator/generators/typescript/templates/schema-template.mustache", "utf-8");
|
|
67
|
+
console.log(actions);
|
|
68
|
+
const l0 = Mustache.render(template, { actions });
|
|
69
|
+
writeAndFormatCode(`./generated/L0-schemas`, `index.ts`, l0, "typescript");
|
|
70
|
+
};
|
|
50
71
|
this.language = language;
|
|
51
72
|
this.SchemaExtactionService = new SchemaExtactionService();
|
|
52
73
|
}
|
|
@@ -2,23 +2,10 @@ import { CompileToMarkdown } from "../../../services/return-complier/ast-functio
|
|
|
2
2
|
import { buildAstFromInput } from "../../../services/return-complier/combined.js";
|
|
3
3
|
import Mustache from "mustache";
|
|
4
4
|
import { addBlockquoteToMarkdown, addTabToMarkdown, ConvertArrayToStringsInTestObject, } from "../../../utils/general-utils/string-utils.js";
|
|
5
|
-
import { TestObjectSyntax } from "../../../constants/syntax";
|
|
6
5
|
export function markdownMessageGenerator(returnInput, variableValues, startingPointer, skipInput) {
|
|
7
6
|
const ast = buildAstFromInput(returnInput);
|
|
8
7
|
const returnTemplate = CompileToMarkdown(ast, startingPointer, 0, false);
|
|
9
|
-
if (variableValues[TestObjectSyntax.Scope]) {
|
|
10
|
-
const scope = variableValues[TestObjectSyntax.Scope];
|
|
11
|
-
for (const key in variableValues) {
|
|
12
|
-
if (Object.values(TestObjectSyntax).includes(key)) {
|
|
13
|
-
continue;
|
|
14
|
-
}
|
|
15
|
-
const path = variableValues[key];
|
|
16
|
-
const pathWithoutDollar = path.slice(2);
|
|
17
|
-
variableValues[key] = `${scope}.${pathWithoutDollar}`;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
8
|
let finalReturn = Mustache.render(returnTemplate, ConvertArrayToStringsInTestObject(variableValues));
|
|
21
|
-
console.log(finalReturn);
|
|
22
9
|
if (skipInput) {
|
|
23
10
|
let skipMarkdown = `Note: **Condition ${startingPointer}** can be skipped if the following conditions are met:`;
|
|
24
11
|
const letters = "BCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
@@ -9,7 +9,6 @@ import { ConvertArrayToString } from "../../../utils/general-utils/string-utils.
|
|
|
9
9
|
import { compileInputToTs } from "./ts-ast.js";
|
|
10
10
|
import { CodeGenerator } from "../classes/abstract-generator.js";
|
|
11
11
|
import { writeAndFormatCode } from "../../../utils/fs-utils.js";
|
|
12
|
-
import logger from "../../../utils/logger.js";
|
|
13
12
|
import { MarkdownDocGenerator } from "../documentation/md-generator.js";
|
|
14
13
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
14
|
const __dirname = path.dirname(__filename);
|
|
@@ -61,6 +60,7 @@ export class TypescriptGenerator extends CodeGenerator {
|
|
|
61
60
|
? compileInputToTs(testObject[TestObjectSyntax.Continue])
|
|
62
61
|
: undefined,
|
|
63
62
|
validationCode: await this.createValidationLogicCode(testObject),
|
|
63
|
+
successCode: testObject[TestObjectSyntax.SuccessCode] ?? 200,
|
|
64
64
|
};
|
|
65
65
|
return {
|
|
66
66
|
funcName: testObject[TestObjectSyntax.Name],
|
|
@@ -90,7 +90,6 @@ export class TypescriptGenerator extends CodeGenerator {
|
|
|
90
90
|
const names = functionCodes.map((f) => {
|
|
91
91
|
return { name: f.funcName };
|
|
92
92
|
});
|
|
93
|
-
logger.debug(JSON.stringify(names));
|
|
94
93
|
return Mustache.render(template, {
|
|
95
94
|
isNested: true,
|
|
96
95
|
nestedFunctions: functionCodes.map((f) => f.code).join("\n"),
|
|
@@ -100,7 +99,7 @@ export class TypescriptGenerator extends CodeGenerator {
|
|
|
100
99
|
};
|
|
101
100
|
}
|
|
102
101
|
CreateErrorMarkdown(testObject, skipList) {
|
|
103
|
-
return markdownMessageGenerator(testObject[TestObjectSyntax.Return], testObject,
|
|
102
|
+
return markdownMessageGenerator(testObject[TestObjectSyntax.Return], testObject, testObject[TestObjectSyntax.Name], skipList);
|
|
104
103
|
}
|
|
105
104
|
createVariablesCode(testObject) {
|
|
106
105
|
const variables = [];
|
|
@@ -108,7 +107,7 @@ export class TypescriptGenerator extends CodeGenerator {
|
|
|
108
107
|
for (const name of varNames) {
|
|
109
108
|
const value = testObject[name];
|
|
110
109
|
const final = typeof value === "string"
|
|
111
|
-
? `payloadUtils.getJsonPath(testObj,
|
|
110
|
+
? `payloadUtils.getJsonPath(testObj, "${value}")`
|
|
112
111
|
: ConvertArrayToString(value);
|
|
113
112
|
variables.push({
|
|
114
113
|
name: name,
|
|
@@ -3,7 +3,7 @@ import { getExternalVariables } from "../../utils/general-utils/validation-utils
|
|
|
3
3
|
import { SessionDataValidator } from "./session-data-config/session-data-validator.js";
|
|
4
4
|
import { TestsValidator } from "./tests-config/test-list-validator.js";
|
|
5
5
|
export class ConfigValidator {
|
|
6
|
-
constructor(
|
|
6
|
+
constructor(validationPath, config, stringJsonPaths, errorDefinitions) {
|
|
7
7
|
this.validate = async () => {
|
|
8
8
|
if (!this.config[ConfigSyntax.Tests])
|
|
9
9
|
throw new Error(`Tests not found in config`);
|
|
@@ -11,11 +11,11 @@ export class ConfigValidator {
|
|
|
11
11
|
throw new Error(`SessionData not found in config`);
|
|
12
12
|
const sessionData = this.config[ConfigSyntax.SessionData];
|
|
13
13
|
const tests = this.config[ConfigSyntax.Tests];
|
|
14
|
-
await new SessionDataValidator(`${this.
|
|
14
|
+
await new SessionDataValidator(`${this.validationPath}/${ConfigSyntax.SessionData}`, sessionData).validate();
|
|
15
15
|
const externalVariables = getExternalVariables(sessionData);
|
|
16
16
|
for (const api in tests) {
|
|
17
17
|
const testList = tests[api];
|
|
18
|
-
const path = `${this.
|
|
18
|
+
const path = `${this.validationPath}/${ConfigSyntax.Tests}/${api}`;
|
|
19
19
|
const dependencies = {
|
|
20
20
|
stringJsonPaths: this.stringJsonPaths[api],
|
|
21
21
|
errorDefinitions: this.errorDefinitions,
|
|
@@ -24,7 +24,7 @@ export class ConfigValidator {
|
|
|
24
24
|
await new TestsValidator(testList, path, dependencies).validate();
|
|
25
25
|
}
|
|
26
26
|
};
|
|
27
|
-
this.
|
|
27
|
+
this.validationPath = validationPath;
|
|
28
28
|
this.config = config;
|
|
29
29
|
this.stringJsonPaths = stringJsonPaths;
|
|
30
30
|
this.errorDefinitions = errorDefinitions;
|
package/dist/{Generator → generator}/validators/session-data-config/session-data-validator.js
RENAMED
|
@@ -3,11 +3,11 @@ export class SessionDataValidator {
|
|
|
3
3
|
constructor(validtionPath, sessionData) {
|
|
4
4
|
this.validate = async () => {
|
|
5
5
|
Object.entries(this.sessionData).forEach(([key, value]) => {
|
|
6
|
-
const newPath = `${this.
|
|
6
|
+
const newPath = `${this.validationPath}/${key}`;
|
|
7
7
|
this.validateSessionData(value, newPath);
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
this.
|
|
10
|
+
this.validationPath = validtionPath;
|
|
11
11
|
this.sessionData = sessionData;
|
|
12
12
|
}
|
|
13
13
|
validateSessionData(variable, path) {
|
|
@@ -2,7 +2,7 @@ import { TestObjectSyntax, nodeReservedKeywords, ExternalDataSyntax, ConfigSynta
|
|
|
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";
|
|
5
|
-
import { isValidVariableName, } from "../../../utils/general-utils/string-utils.js";
|
|
5
|
+
import { isSnakeCase, isValidVariableName, } from "../../../utils/general-utils/string-utils.js";
|
|
6
6
|
import { isValidVariableValueType } from "../../../utils/general-utils/validation-utils.js";
|
|
7
7
|
import { isValidJsonPath, replaceBracketsWithAsteriskNested, } from "../../../utils/json-path-utils/paths.js";
|
|
8
8
|
import { TestObjectValidator, } from "../abstract-validator.js";
|
|
@@ -12,10 +12,10 @@ export class RequiredFieldsValidator extends TestObjectValidator {
|
|
|
12
12
|
super(...arguments);
|
|
13
13
|
this.validate = async () => {
|
|
14
14
|
if (!this.targetObject[TestObjectSyntax.Name]) {
|
|
15
|
-
throw new Error(`${TestObjectSyntax.Name} is required at path ${this.
|
|
15
|
+
throw new Error(`${TestObjectSyntax.Name} is required at path ${this.validationPath}`);
|
|
16
16
|
}
|
|
17
17
|
if (!this.targetObject[TestObjectSyntax.Return]) {
|
|
18
|
-
throw new Error(`${TestObjectSyntax.Return} is required at path ${this.
|
|
18
|
+
throw new Error(`${TestObjectSyntax.Return} is required at path ${this.validationPath}`);
|
|
19
19
|
}
|
|
20
20
|
};
|
|
21
21
|
}
|
|
@@ -25,20 +25,18 @@ export class NameValidator extends TestObjectValidator {
|
|
|
25
25
|
super(...arguments);
|
|
26
26
|
this.validate = async () => {
|
|
27
27
|
if (typeof this.targetObject[TestObjectSyntax.Name] !== "string") {
|
|
28
|
-
throw new Error(`${TestObjectSyntax.Name} should be a string at path ${this.
|
|
28
|
+
throw new Error(`${TestObjectSyntax.Name} should be a string at path ${this.validationPath}`);
|
|
29
29
|
}
|
|
30
30
|
const name = this.targetObject[TestObjectSyntax.Name];
|
|
31
31
|
if (name.length < 1) {
|
|
32
|
-
throw new Error(`${TestObjectSyntax.Name} can't be a non-empty string at path ${this.
|
|
32
|
+
throw new Error(`${TestObjectSyntax.Name} can't be a non-empty string at path ${this.validationPath}`);
|
|
33
33
|
}
|
|
34
34
|
if (nodeReservedKeywords.has(name)) {
|
|
35
|
-
throw new Error(`${TestObjectSyntax.Name} can't be a reserved keyword at path ${this.
|
|
35
|
+
throw new Error(`${TestObjectSyntax.Name} can't be a reserved keyword at path ${this.validationPath}`);
|
|
36
|
+
}
|
|
37
|
+
if (!isSnakeCase(name)) {
|
|
38
|
+
throw new Error(`${TestObjectSyntax.Name} must be in snake_case at path ${this.validationPath}`);
|
|
36
39
|
}
|
|
37
|
-
// if (!isSnakeCase(name)) {
|
|
38
|
-
// throw new Error(
|
|
39
|
-
// `${TestObjectSyntax.Name} must be in snake_case at path ${this.validtionPath}`
|
|
40
|
-
// );
|
|
41
|
-
// }
|
|
42
40
|
};
|
|
43
41
|
}
|
|
44
42
|
}
|
|
@@ -48,16 +46,16 @@ export class ScopeValidator extends TestObjectValidator {
|
|
|
48
46
|
this.validate = async () => {
|
|
49
47
|
const path = this.targetObject[TestObjectSyntax.Scope];
|
|
50
48
|
if (typeof path !== "string") {
|
|
51
|
-
throw new Error(`${TestObjectSyntax.Scope} should be a string at path ${this.
|
|
49
|
+
throw new Error(`${TestObjectSyntax.Scope} should be a string at path ${this.validationPath}`);
|
|
52
50
|
}
|
|
53
51
|
if (!isValidJsonPath(path)) {
|
|
54
|
-
throw new Error(`${TestObjectSyntax.Scope} should be a valid json path at path ${this.
|
|
52
|
+
throw new Error(`${TestObjectSyntax.Scope} should be a valid json path at path ${this.validationPath}`);
|
|
55
53
|
}
|
|
56
54
|
if (!path.startsWith(`$.`)) {
|
|
57
|
-
throw new Error(`${TestObjectSyntax.Scope} json path should start with $. at ${this.
|
|
55
|
+
throw new Error(`${TestObjectSyntax.Scope} json path should start with $. at ${this.validationPath}`);
|
|
58
56
|
}
|
|
59
57
|
if (this.impossiblePaths.includes(replaceBracketsWithAsteriskNested(path))) {
|
|
60
|
-
throw new Error(`${TestObjectSyntax.Scope} can't be a path that returns a array of string it must be a json path which returns a array of objects at path ${this.
|
|
58
|
+
throw new Error(`${TestObjectSyntax.Scope} can't be a path that returns a array of string it must be a json path which returns a array of objects at path ${this.validationPath}`);
|
|
61
59
|
}
|
|
62
60
|
};
|
|
63
61
|
this.impossiblePaths = impossiblePaths;
|
|
@@ -71,14 +69,20 @@ export class ErrorCodeValidator extends TestObjectValidator {
|
|
|
71
69
|
return;
|
|
72
70
|
}
|
|
73
71
|
if (typeof this.targetObject[TestObjectSyntax.Return] !== "string") {
|
|
74
|
-
throw new Error(`You can't define a ${TestObjectSyntax.ErrorCode} with nested ${TestObjectSyntax.Return} at path ${this.
|
|
72
|
+
throw new Error(`You can't define a ${TestObjectSyntax.ErrorCode} with nested ${TestObjectSyntax.Return} at path ${this.validationPath}`);
|
|
75
73
|
}
|
|
76
74
|
if (typeof this.targetObject[TestObjectSyntax.ErrorCode] !== "number") {
|
|
77
|
-
throw new Error(`${TestObjectSyntax.ErrorCode} should be a number at path ${this.
|
|
75
|
+
throw new Error(`${TestObjectSyntax.ErrorCode} should be a number at path ${this.validationPath}`);
|
|
78
76
|
}
|
|
79
77
|
const errorCode = this.targetObject[TestObjectSyntax.ErrorCode];
|
|
80
78
|
if (!this.possibleErrorCodes.some((code) => code.code === errorCode)) {
|
|
81
|
-
throw new Error(`${TestObjectSyntax.ErrorCode} don't exist in error codes at path ${this.
|
|
79
|
+
throw new Error(`${TestObjectSyntax.ErrorCode} don't exist in error codes at path ${this.validationPath}`);
|
|
80
|
+
}
|
|
81
|
+
if (!this.targetObject[TestObjectSyntax.SuccessCode]) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (typeof this.targetObject[TestObjectSyntax.SuccessCode] !== "number") {
|
|
85
|
+
throw new Error(`${TestObjectSyntax.SuccessCode} should be a number at path ${this.validationPath}`);
|
|
82
86
|
}
|
|
83
87
|
};
|
|
84
88
|
this.possibleErrorCodes = possibleErrorCodes;
|
|
@@ -94,15 +98,16 @@ export class VariableValidator extends TestObjectValidator {
|
|
|
94
98
|
}
|
|
95
99
|
this.validateKey(key);
|
|
96
100
|
const value = this.targetObject[key];
|
|
101
|
+
console.log(value);
|
|
97
102
|
if (!isValidVariableValueType(value)) {
|
|
98
|
-
throw new Error(`Variable: ${key} should be a string or array of primitives at path ${this.
|
|
103
|
+
throw new Error(`Variable: ${key} should be a string or array of primitives at path ${this.validationPath}`);
|
|
99
104
|
}
|
|
100
105
|
if (typeof value === "string") {
|
|
101
106
|
if (!isValidJsonPath(value)) {
|
|
102
|
-
throw new Error(`Variable: ${key} should be a valid jsonPath at ${this.
|
|
107
|
+
throw new Error(`Variable: ${key} should be a valid jsonPath at ${this.validationPath}`);
|
|
103
108
|
}
|
|
104
109
|
if (!value.startsWith(`$.`)) {
|
|
105
|
-
throw new Error(`Variable: ${key} should start with $. at ${this.
|
|
110
|
+
throw new Error(`Variable: ${key} should start with $. at ${this.validationPath}`);
|
|
106
111
|
}
|
|
107
112
|
if (value.startsWith(`$.${ExternalDataSyntax}`)) {
|
|
108
113
|
this.validateExternalData(value, this.externalVariables);
|
|
@@ -116,7 +121,7 @@ export class VariableValidator extends TestObjectValidator {
|
|
|
116
121
|
}
|
|
117
122
|
const replaced = replaceBracketsWithAsteriskNested(path);
|
|
118
123
|
if (!this.possibleJsonPaths.includes(replaced)) {
|
|
119
|
-
throw new Error(`Variable: ${key} should be a jsonPath that returns a array of strings or the path don't exist in the schema, at ${this.
|
|
124
|
+
throw new Error(`Variable: ${key} should be a jsonPath that returns a array of strings or the path don't exist in the schema, at ${this.validationPath} found original ${path} replaces: ${replaced}`);
|
|
120
125
|
}
|
|
121
126
|
}
|
|
122
127
|
}
|
|
@@ -126,22 +131,22 @@ export class VariableValidator extends TestObjectValidator {
|
|
|
126
131
|
}
|
|
127
132
|
validateKey(key) {
|
|
128
133
|
if (nodeReservedKeywords.has(key)) {
|
|
129
|
-
throw new Error(`${key} can't be a reserved keyword at path ${this.
|
|
134
|
+
throw new Error(`${key} can't be a reserved keyword at path ${this.validationPath}`);
|
|
130
135
|
}
|
|
131
136
|
if (key.includes(" ")) {
|
|
132
|
-
throw new Error(`${key} can't contain spaces at path ${this.
|
|
137
|
+
throw new Error(`${key} can't contain spaces at path ${this.validationPath}`);
|
|
133
138
|
}
|
|
134
139
|
if (key === this.targetObject[TestObjectSyntax.Name]) {
|
|
135
|
-
throw new Error(`${key} can't be the same as ${TestObjectSyntax.Name} at path ${this.
|
|
140
|
+
throw new Error(`${key} can't be the same as ${TestObjectSyntax.Name} at path ${this.validationPath}`);
|
|
136
141
|
}
|
|
137
142
|
if (!isValidVariableName(key)) {
|
|
138
|
-
throw new Error(`${key} is not a valid variable name at path ${this.
|
|
143
|
+
throw new Error(`${key} is not a valid variable name at path ${this.validationPath}`);
|
|
139
144
|
}
|
|
140
145
|
}
|
|
141
146
|
validateExternalData(path, definedExternalValues) {
|
|
142
147
|
const externalData = path.split(".")[2];
|
|
143
148
|
if (!definedExternalValues.includes(externalData)) {
|
|
144
|
-
throw new Error(`${externalData} is not defined in ${ConfigSyntax.SessionData} data at path ${this.
|
|
149
|
+
throw new Error(`${externalData} is not defined in ${ConfigSyntax.SessionData} data at path ${this.validationPath}`);
|
|
145
150
|
}
|
|
146
151
|
}
|
|
147
152
|
}
|
|
@@ -154,13 +159,13 @@ export class ContinueValidator extends TestObjectValidator {
|
|
|
154
159
|
if (typeof contStatement === "string") {
|
|
155
160
|
const cst = parseReturnInput(contStatement);
|
|
156
161
|
const ast = buildAst(cst);
|
|
157
|
-
checkValidVariables(ast, this.definedVariables, this.
|
|
162
|
+
checkValidVariables(ast, this.definedVariables, this.validationPath);
|
|
158
163
|
return;
|
|
159
164
|
}
|
|
160
|
-
throw new Error(`${TestObjectSyntax.Continue} should be a string at path ${this.
|
|
165
|
+
throw new Error(`${TestObjectSyntax.Continue} should be a string at path ${this.validationPath}`);
|
|
161
166
|
}
|
|
162
167
|
catch (err) {
|
|
163
|
-
throw new Error(err.message + " at path " + this.
|
|
168
|
+
throw new Error(err.message + " at path " + this.validationPath);
|
|
164
169
|
}
|
|
165
170
|
};
|
|
166
171
|
this.definedVariables = Object.keys(testObject).filter((key) => !Object.values(TestObjectSyntax).includes(key));
|
|
@@ -175,17 +180,17 @@ export class ReturnValidator extends TestObjectValidator {
|
|
|
175
180
|
if (typeof returnStatement === "string") {
|
|
176
181
|
const cst = parseReturnInput(returnStatement);
|
|
177
182
|
const ast = buildAst(cst);
|
|
178
|
-
checkValidVariables(ast, this.definedVariables, this.
|
|
183
|
+
checkValidVariables(ast, this.definedVariables, this.validationPath);
|
|
179
184
|
return;
|
|
180
185
|
}
|
|
181
186
|
if (Array.isArray(returnStatement)) {
|
|
182
|
-
await new TestsValidator(returnStatement, this.
|
|
187
|
+
await new TestsValidator(returnStatement, this.validationPath, this.dependencies).validate();
|
|
183
188
|
return;
|
|
184
189
|
}
|
|
185
190
|
throw new Error(`${TestObjectSyntax.Return} should be a string or arrays`);
|
|
186
191
|
}
|
|
187
192
|
catch (err) {
|
|
188
|
-
throw new Error(err.message + " at path " + this.
|
|
193
|
+
throw new Error(err.message + " at path " + this.validationPath);
|
|
189
194
|
}
|
|
190
195
|
};
|
|
191
196
|
this.definedVariables = Object.keys(testObject).filter((key) => !Object.values(TestObjectSyntax).includes(key));
|
|
@@ -6,7 +6,7 @@ export class TestsValidator {
|
|
|
6
6
|
this.validateDuplicateNames();
|
|
7
7
|
let i = 0;
|
|
8
8
|
for (const test of this.tests) {
|
|
9
|
-
const newPath = `${this.
|
|
9
|
+
const newPath = `${this.validationPath}/${i}/${TestObjectSyntax.Name} = ${test[TestObjectSyntax.Name]}`;
|
|
10
10
|
await new CompleteTestObjectValidator(test, newPath, this.dependencies).validate();
|
|
11
11
|
i++;
|
|
12
12
|
}
|
|
@@ -24,13 +24,13 @@ export class TestsValidator {
|
|
|
24
24
|
}
|
|
25
25
|
});
|
|
26
26
|
if (duplicates.size > 0) {
|
|
27
|
-
throw new Error(`Duplicate test names found at ${this.
|
|
27
|
+
throw new Error(`Duplicate test names found at ${this.validationPath}: ${[
|
|
28
28
|
...duplicates,
|
|
29
29
|
].join(", ")}`);
|
|
30
30
|
}
|
|
31
31
|
};
|
|
32
32
|
this.tests = tests;
|
|
33
|
-
this.
|
|
33
|
+
this.validationPath = configPath;
|
|
34
34
|
this.dependencies = dependencies;
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -5,19 +5,19 @@ export class CompleteTestObjectValidator extends TestObjectValidator {
|
|
|
5
5
|
constructor(testObject, path, dependencies) {
|
|
6
6
|
super(testObject, path);
|
|
7
7
|
this.validate = async () => {
|
|
8
|
-
await new RequiredFieldsValidator(this.targetObject, this.
|
|
9
|
-
await new NameValidator(this.targetObject, this.
|
|
8
|
+
await new RequiredFieldsValidator(this.targetObject, this.validationPath).validate();
|
|
9
|
+
await new NameValidator(this.targetObject, this.validationPath).validate();
|
|
10
10
|
if (this.targetObject[TestObjectSyntax.Scope]) {
|
|
11
|
-
await new ScopeValidator(this.targetObject, this.
|
|
11
|
+
await new ScopeValidator(this.targetObject, this.validationPath, this.dependencies.stringJsonPaths).validate();
|
|
12
12
|
}
|
|
13
13
|
if (this.targetObject[TestObjectSyntax.ErrorCode]) {
|
|
14
|
-
await new ErrorCodeValidator(this.targetObject, this.
|
|
14
|
+
await new ErrorCodeValidator(this.targetObject, this.validationPath, this.dependencies.errorDefinitions).validate();
|
|
15
15
|
}
|
|
16
|
-
await new VariableValidator(this.targetObject, this.
|
|
16
|
+
await new VariableValidator(this.targetObject, this.validationPath, this.dependencies.stringJsonPaths, this.dependencies.externalVariables).validate();
|
|
17
17
|
if (this.targetObject[TestObjectSyntax.Continue]) {
|
|
18
|
-
await new ContinueValidator(this.targetObject, this.
|
|
18
|
+
await new ContinueValidator(this.targetObject, this.validationPath).validate();
|
|
19
19
|
}
|
|
20
|
-
await new ReturnValidator(this.targetObject, this.
|
|
20
|
+
await new ReturnValidator(this.targetObject, this.validationPath, this.dependencies).validate();
|
|
21
21
|
};
|
|
22
22
|
this.dependencies = dependencies;
|
|
23
23
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,39 +1,2 @@
|
|
|
1
|
-
import { readFileSync } from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import { fileURLToPath } from "url";
|
|
4
|
-
import { SupportedLanguages } from "./types/compiler-types.js";
|
|
5
1
|
import { ConfigCompiler } from "./generator/config-compiler.js";
|
|
6
|
-
|
|
7
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
-
const __dirname = path.dirname(__filename);
|
|
9
|
-
const main = async () => {
|
|
10
|
-
const compiler = new ConfigCompiler(SupportedLanguages.Typescript);
|
|
11
|
-
const buildPath = path.resolve(__dirname, "../samples/build.yaml");
|
|
12
|
-
const valConfigPath = path.resolve(__dirname, "../samples/validation-config.json");
|
|
13
|
-
const buildYaml = readFileSync(buildPath, "utf-8");
|
|
14
|
-
const valConfig = JSON.parse(readFileSync(valConfigPath, "utf-8"));
|
|
15
|
-
await compiler.initialize(buildYaml);
|
|
16
|
-
await compiler.generateCode(valConfig);
|
|
17
|
-
// await compiler.performValidations(valConfig);
|
|
18
|
-
// const inputs = [
|
|
19
|
-
// "a are unique && b are unique",
|
|
20
|
-
// "a are unique",
|
|
21
|
-
// "(a are unique && b are unique) || c are unique",
|
|
22
|
-
// "a are unique && b are unique || c are unique",
|
|
23
|
-
// "a are unique && (b are unique || c are unique)",
|
|
24
|
-
// "a are unique && b are unique && c are unique && d are unique",
|
|
25
|
-
// "a are unique && !(b are unique || !(c are unique))",
|
|
26
|
-
// "a are unique && (b are unique || !(!(c are unique))) && !(d are unique)",
|
|
27
|
-
// ];
|
|
28
|
-
// let output = "";
|
|
29
|
-
// for (const input of inputs) {
|
|
30
|
-
// const cst = parseReturnInput(input);
|
|
31
|
-
// const ast = buildAst(cst);
|
|
32
|
-
// const out = CompileToMarkdown(ast, "A", 0, false);
|
|
33
|
-
// output += `\n## ${input}\n\n${out}\n`;
|
|
34
|
-
// }
|
|
35
|
-
// writeFileSync(path.resolve(__dirname, "../samples/output.md"), output);
|
|
36
|
-
};
|
|
37
|
-
(async () => {
|
|
38
|
-
await main();
|
|
39
|
-
})();
|
|
2
|
+
export { ConfigCompiler };
|
|
@@ -50,16 +50,19 @@ export const NoneIn = createToken({
|
|
|
50
50
|
export const EqualTo = createToken({
|
|
51
51
|
name: "EqualTo",
|
|
52
52
|
pattern: /equal to/i,
|
|
53
|
+
categories: CustomBinaryFunctions,
|
|
53
54
|
label: "equal to",
|
|
54
55
|
});
|
|
55
56
|
export const GreaterThan = createToken({
|
|
56
57
|
name: "GreaterThan",
|
|
57
58
|
pattern: /greater than/i,
|
|
59
|
+
categories: CustomBinaryFunctions,
|
|
58
60
|
label: "greater than",
|
|
59
61
|
});
|
|
60
62
|
export const LessThan = createToken({
|
|
61
63
|
name: "LessThan",
|
|
62
64
|
pattern: /less than/i,
|
|
65
|
+
categories: CustomBinaryFunctions,
|
|
63
66
|
label: "less than",
|
|
64
67
|
});
|
|
65
68
|
export const WhiteSpace = createToken({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { nodeReservedKeywords } from "../../constants/syntax.js";
|
|
1
|
+
import { nodeReservedKeywords, 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
|
|
@@ -7,7 +7,7 @@ import { getVariablesFromTest } from "./test-object-utils.js";
|
|
|
7
7
|
* @returns true if the string is in snake_case, false otherwise
|
|
8
8
|
*/
|
|
9
9
|
export function isSnakeCase(str) {
|
|
10
|
-
const snakeCasePattern = /^[a-z0-
|
|
10
|
+
const snakeCasePattern = /^[a-z0-9A-Z]+(_[a-z0-9A-Z]+)*$/;
|
|
11
11
|
return snakeCasePattern.test(str);
|
|
12
12
|
}
|
|
13
13
|
export function isValidVariableName(input) {
|
|
@@ -33,12 +33,20 @@ export function addBlockquoteToMarkdown(markdown) {
|
|
|
33
33
|
export function ConvertArrayToStringsInTestObject(testObject) {
|
|
34
34
|
const variables = getVariablesFromTest(testObject);
|
|
35
35
|
const testDuplicate = { ...testObject };
|
|
36
|
+
const scope = testObject[TestObjectSyntax.Scope];
|
|
36
37
|
for (const variable of variables) {
|
|
37
38
|
if (Array.isArray(testObject[variable])) {
|
|
38
39
|
let vals = testObject[variable].map((v) => `"${v}"`).join(", ");
|
|
39
40
|
vals = vals.replace(/"/g, `"`);
|
|
40
41
|
testDuplicate[variable] = `[${vals}]`;
|
|
41
42
|
}
|
|
43
|
+
else {
|
|
44
|
+
if (scope) {
|
|
45
|
+
const path = testDuplicate[variable];
|
|
46
|
+
const pathWithoutDollar = path.slice(2);
|
|
47
|
+
testDuplicate[variable] = `${scope}.${pathWithoutDollar}`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
42
50
|
}
|
|
43
51
|
return testDuplicate;
|
|
44
52
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ondc-code-generator",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "generate code from build.yaml ",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tsc",
|
|
9
9
|
"start": "node ./dist/index.js",
|
|
10
|
-
"dev": "nodemon"
|
|
10
|
+
"dev": "nodemon",
|
|
11
|
+
"clean": "rm -rf dist",
|
|
12
|
+
"prepare": "npm run clean && npm run build"
|
|
11
13
|
},
|
|
12
14
|
"author": "extedcoud",
|
|
13
15
|
"license": "MIT",
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
validations:
|
|
3
|
-
a single test object validations:
|
|
4
|
-
1. name validations
|
|
5
|
-
2. scope validation
|
|
6
|
-
3. variable validation
|
|
7
|
-
4. continue and return validations
|
|
8
|
-
5. errorcode validations
|
|
9
|
-
6. json path validations
|
|
10
|
-
7. external data validations
|
|
11
|
-
|
|
12
|
-
upper validations:
|
|
13
|
-
1. unique names
|
|
14
|
-
2. _session_data_ are valid
|
|
15
|
-
3. _tests_ are valid
|
|
16
|
-
|
|
17
|
-
x-errorcode validations:
|
|
18
|
-
1. all codes are unique
|
|
19
|
-
*/
|
|
20
|
-
export class ConfigValidator {
|
|
21
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { CompileToMarkdown } from "../../services/return-complier/ast-functions/compile-to-markdown.js";
|
|
2
|
-
import { buildAstFromInput } from "../../services/return-complier/combined.js";
|
|
3
|
-
import Mustache from "mustache";
|
|
4
|
-
import { addBlockquoteToMarkdown, ConvertArrayToStringsInTestObject, } from "../../utils/general-utils/string-utils.js";
|
|
5
|
-
export function markdownMessageGenerator(returnInput, variableValues, startingPointer, skipInput) {
|
|
6
|
-
const ast = buildAstFromInput(returnInput);
|
|
7
|
-
const returnTemplate = CompileToMarkdown(ast, startingPointer, 0, false);
|
|
8
|
-
let finalReturn = Mustache.render(returnTemplate, ConvertArrayToStringsInTestObject(variableValues));
|
|
9
|
-
console.log(finalReturn);
|
|
10
|
-
if (skipInput) {
|
|
11
|
-
let skipMarkdown = `Note: **Condition ${startingPointer}** can be skipped if the following conditions are met:`;
|
|
12
|
-
const letters = "BCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
13
|
-
let index = 0;
|
|
14
|
-
for (const skip of skipInput) {
|
|
15
|
-
const skipAst = buildAstFromInput(skip);
|
|
16
|
-
const skipTemplate = CompileToMarkdown(skipAst, letters[index], 0, false);
|
|
17
|
-
const finalSkip = Mustache.render(skipTemplate, ConvertArrayToStringsInTestObject(variableValues));
|
|
18
|
-
skipMarkdown += `\n\n${finalSkip}`;
|
|
19
|
-
index++;
|
|
20
|
-
}
|
|
21
|
-
const blockSkip = addBlockquoteToMarkdown(skipMarkdown);
|
|
22
|
-
finalReturn += `\n###\n${blockSkip}`;
|
|
23
|
-
}
|
|
24
|
-
return finalReturn;
|
|
25
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { CstParser } from "chevrotain";
|
|
2
|
-
import { allTokens, NumberLiteral, PlusMinusOperator } from "./tokens.js";
|
|
3
|
-
export default class CalculatorParser extends CstParser {
|
|
4
|
-
constructor() {
|
|
5
|
-
super(allTokens);
|
|
6
|
-
const $ = this;
|
|
7
|
-
$.RULE("expression", () => {
|
|
8
|
-
$.SUBRULE($.additionExpression);
|
|
9
|
-
});
|
|
10
|
-
$.RULE("additionExpression", () => {
|
|
11
|
-
$.SUBRULE($.atomicExpression, { LABEL: "lhs" });
|
|
12
|
-
$.MANY(() => {
|
|
13
|
-
$.CONSUME(PlusMinusOperator);
|
|
14
|
-
$.SUBRULE2($.atomicExpression, { LABEL: "rhs" });
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
$.RULE("atomicExpression", () => {
|
|
18
|
-
$.CONSUME(NumberLiteral);
|
|
19
|
-
});
|
|
20
|
-
$.performSelfAnalysis();
|
|
21
|
-
}
|
|
22
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { createToken, Lexer } from "chevrotain";
|
|
2
|
-
export const NumberLiteral = createToken({
|
|
3
|
-
name: "NumberLiteral",
|
|
4
|
-
pattern: /[0-9]+/,
|
|
5
|
-
});
|
|
6
|
-
export const PlusMinusOperator = createToken({
|
|
7
|
-
name: "PlusMinusOperator",
|
|
8
|
-
pattern: Lexer.NA,
|
|
9
|
-
});
|
|
10
|
-
export const Plus = createToken({
|
|
11
|
-
name: "Plus",
|
|
12
|
-
pattern: /\+/,
|
|
13
|
-
categories: PlusMinusOperator,
|
|
14
|
-
});
|
|
15
|
-
export const Minus = createToken({
|
|
16
|
-
name: "Minus",
|
|
17
|
-
pattern: /-/,
|
|
18
|
-
categories: PlusMinusOperator,
|
|
19
|
-
});
|
|
20
|
-
export const WhiteSpace = createToken({
|
|
21
|
-
name: "WhiteSpace",
|
|
22
|
-
pattern: /\s+/,
|
|
23
|
-
line_breaks: true,
|
|
24
|
-
group: Lexer.SKIPPED,
|
|
25
|
-
});
|
|
26
|
-
export const allTokens = [
|
|
27
|
-
Plus,
|
|
28
|
-
Minus,
|
|
29
|
-
NumberLiteral,
|
|
30
|
-
PlusMinusOperator,
|
|
31
|
-
WhiteSpace,
|
|
32
|
-
];
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { createToken, Lexer } from "chevrotain";
|
|
2
|
-
export const NumberLiteral = createToken({
|
|
3
|
-
name: "NumberLiteral",
|
|
4
|
-
pattern: /[0-9]+/,
|
|
5
|
-
});
|
|
6
|
-
export const PlusMinusOperator = createToken({
|
|
7
|
-
name: "PlusMinusOperator",
|
|
8
|
-
pattern: Lexer.NA,
|
|
9
|
-
});
|
|
10
|
-
export const Plus = createToken({
|
|
11
|
-
name: "Plus",
|
|
12
|
-
pattern: /\+/,
|
|
13
|
-
categories: PlusMinusOperator,
|
|
14
|
-
});
|
|
15
|
-
export const Minus = createToken({
|
|
16
|
-
name: "Minus",
|
|
17
|
-
pattern: /-/,
|
|
18
|
-
categories: PlusMinusOperator,
|
|
19
|
-
});
|
|
20
|
-
export const WhiteSpace = createToken({
|
|
21
|
-
name: "WhiteSpace",
|
|
22
|
-
pattern: /\s+/,
|
|
23
|
-
line_breaks: true,
|
|
24
|
-
group: Lexer.SKIPPED,
|
|
25
|
-
});
|
|
26
|
-
export const allTokens = [
|
|
27
|
-
Plus,
|
|
28
|
-
Minus,
|
|
29
|
-
NumberLiteral,
|
|
30
|
-
PlusMinusOperator,
|
|
31
|
-
WhiteSpace,
|
|
32
|
-
];
|
|
33
|
-
console.log(allTokens);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|