ondc-code-generator 0.5.41 → 0.5.42

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.
@@ -10,6 +10,7 @@ import { fileURLToPath } from "url";
10
10
  import path from "path";
11
11
  import { duplicateVariablesInChildren } from "../utils/config-utils/duplicateVariables.js";
12
12
  import { PythonGenerator } from "./generators/python/py-generator.js";
13
+ import { JavascriptGenerator } from "./generators/javascript/js-generator.js";
13
14
  const __filename = fileURLToPath(import.meta.url);
14
15
  const __dirname = path.dirname(__filename);
15
16
  const defaultConfig = {
@@ -58,7 +59,6 @@ export class ConfigCompiler {
58
59
  this.generateCode = async (valConfig, codeName = "L1-Validations", minimal = false, outputPath = "./") => {
59
60
  valConfig = JSON.parse(JSON.stringify(valConfig));
60
61
  if (this.generatorConfig?.duplicateVariablesInChildren) {
61
- console.log("Duplicating variables");
62
62
  valConfig = duplicateVariablesInChildren(valConfig);
63
63
  }
64
64
  if (minimal) {
@@ -80,6 +80,11 @@ export class ConfigCompiler {
80
80
  codeName: codeName,
81
81
  });
82
82
  break;
83
+ case SupportedLanguages.Javascript:
84
+ await new JavascriptGenerator(valConfig, this.errorDefinitions ?? [], targetPath).generateCode({
85
+ codeName: codeName,
86
+ });
87
+ break;
83
88
  default:
84
89
  throw new Error("Language not supported");
85
90
  }
@@ -105,7 +110,6 @@ export class ConfigCompiler {
105
110
  };
106
111
  });
107
112
  const template = readFileSync(path.resolve(__dirname, "../generator/generators/typescript/templates/schema-template.mustache"), "utf-8");
108
- console.log(actions);
109
113
  const l0 = Mustache.render(template, { actions });
110
114
  await writeAndFormatCode(targetPath, `index.ts`, l0, "typescript");
111
115
  }
@@ -0,0 +1,19 @@
1
+ import { CodeGenerator, CodeGeneratorProps } from "../classes/abstract-generator.js";
2
+ export declare class JavascriptGenerator extends CodeGenerator {
3
+ private tempTsPath;
4
+ constructor(validationConfig: any, errorCodes: any[], rootPath?: string);
5
+ generateSessionDataCode: () => Promise<never>;
6
+ generateValidationCode: () => Promise<void>;
7
+ generateCode: (codeConfig: CodeGeneratorProps) => Promise<void>;
8
+ private createTsConfig;
9
+ private compileToJavaScript;
10
+ private processGeneratedFiles;
11
+ private copyAndProcessJsFiles;
12
+ private copyTypeDefinitions;
13
+ private processJavaScriptImports;
14
+ private processTypeDefinitionImports;
15
+ private getAllFiles;
16
+ private generatePackageJson;
17
+ private runCommand;
18
+ private cleanup;
19
+ }
@@ -0,0 +1,215 @@
1
+ import path from "path";
2
+ import { fileURLToPath } from "url";
3
+ import { CodeGenerator, } from "../classes/abstract-generator.js";
4
+ import { writeAndFormatCode } from "../../../utils/fs-utils.js";
5
+ import { TypescriptGenerator } from "../typescript/ts-generator.js";
6
+ import logger from "../../../utils/logger.js";
7
+ import fs from "fs-extra";
8
+ import { MarkdownDocGenerator } from "../documentation/md-generator.js";
9
+ import { exec } from "child_process";
10
+ import { promisify } from "util";
11
+ const execAsync = promisify(exec);
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = path.dirname(__filename);
14
+ export class JavascriptGenerator extends CodeGenerator {
15
+ constructor(validationConfig, errorCodes, rootPath = "./") {
16
+ super(validationConfig, errorCodes, rootPath);
17
+ this.generateSessionDataCode = async () => {
18
+ throw new Error("Method not implemented.");
19
+ };
20
+ this.generateValidationCode = async () => {
21
+ // This will be handled by the TypeScript generator in generateCode
22
+ };
23
+ this.generateCode = async (codeConfig) => {
24
+ try {
25
+ logger.info("Generating JavaScript code using TypeScript compilation...");
26
+ // Step 1: Generate TypeScript code in a temporary directory
27
+ logger.debug("Step 1: Generating TypeScript code in temp directory");
28
+ await fs.ensureDir(this.tempTsPath);
29
+ const tsGenerator = new TypescriptGenerator(this.validationConfig, this.errorCodes, this.tempTsPath);
30
+ await tsGenerator.generateCode(codeConfig);
31
+ // Step 2: Create tsconfig.json for compilation
32
+ logger.debug("Step 2: Creating TypeScript configuration");
33
+ await this.createTsConfig();
34
+ // Step 3: Install TypeScript if not available and compile
35
+ logger.debug("Step 3: Compiling TypeScript to JavaScript");
36
+ await this.compileToJavaScript();
37
+ // Step 4: Copy and modify generated files
38
+ logger.debug("Step 4: Processing generated files");
39
+ await this.processGeneratedFiles();
40
+ // Step 5: Generate package.json
41
+ logger.debug("Step 5: Creating package.json");
42
+ await this.generatePackageJson(codeConfig.codeName);
43
+ // Step 6: Generate documentation
44
+ logger.debug("Step 6: Generating documentation");
45
+ await new MarkdownDocGenerator(this.validationConfig, this.errorCodes, this.rootPath).generateCode();
46
+ // Step 7: Clean up temporary files
47
+ logger.debug("Step 7: Cleaning up temporary files");
48
+ await this.cleanup();
49
+ logger.info("JavaScript code generation completed successfully");
50
+ }
51
+ catch (error) {
52
+ logger.error("Error during JavaScript code generation:", error);
53
+ await this.cleanup(); // Ensure cleanup even on error
54
+ throw error;
55
+ }
56
+ };
57
+ this.tempTsPath = path.resolve(rootPath, "../temp-ts-generation");
58
+ }
59
+ async createTsConfig() {
60
+ const tsConfig = {
61
+ compilerOptions: {
62
+ target: "ES2020",
63
+ module: "ESNext",
64
+ moduleResolution: "node",
65
+ declaration: true,
66
+ outDir: "./js-output",
67
+ rootDir: ".",
68
+ strict: false,
69
+ esModuleInterop: true,
70
+ allowSyntheticDefaultImports: true,
71
+ skipLibCheck: true,
72
+ forceConsistentCasingInFileNames: true,
73
+ allowJs: true,
74
+ noEmitOnError: false,
75
+ removeComments: false,
76
+ },
77
+ include: ["./**/*.ts"],
78
+ exclude: ["node_modules", "./js-output"],
79
+ };
80
+ await writeAndFormatCode(this.tempTsPath, "tsconfig.json", JSON.stringify(tsConfig, null, 2), "json");
81
+ }
82
+ async compileToJavaScript() {
83
+ logger.debug("Compiling TypeScript to JavaScript...");
84
+ try {
85
+ // Try using npx tsc first
86
+ await this.runCommand("npx tsc", this.tempTsPath);
87
+ }
88
+ catch (error) {
89
+ // If npx tsc fails, try to install TypeScript locally and retry
90
+ logger.info("TypeScript compilation failed, installing TypeScript...");
91
+ await this.runCommand("npm init -y", this.tempTsPath);
92
+ await this.runCommand("npm install --save-dev typescript", this.tempTsPath);
93
+ await this.runCommand("npx tsc", this.tempTsPath);
94
+ }
95
+ }
96
+ async processGeneratedFiles() {
97
+ const jsOutputPath = path.resolve(this.tempTsPath, "js-output");
98
+ // Ensure the target directory exists
99
+ await fs.ensureDir(this.rootPath);
100
+ // Copy all .js files and modify imports
101
+ await this.copyAndProcessJsFiles(jsOutputPath, this.rootPath);
102
+ // Copy all .d.ts files
103
+ await this.copyTypeDefinitions(jsOutputPath, this.rootPath);
104
+ }
105
+ async copyAndProcessJsFiles(sourceDir, targetDir) {
106
+ if (!(await fs.pathExists(sourceDir))) {
107
+ throw new Error(`Source directory ${sourceDir} does not exist`);
108
+ }
109
+ const files = await this.getAllFiles(sourceDir, ".js");
110
+ for (const file of files) {
111
+ const relativePath = path.relative(sourceDir, file);
112
+ const targetFile = path.resolve(targetDir, relativePath);
113
+ let content = await fs.readFile(file, "utf-8");
114
+ // Convert TypeScript-style imports to work better with JavaScript
115
+ content = this.processJavaScriptImports(content);
116
+ await fs.ensureDir(path.dirname(targetFile));
117
+ await fs.writeFile(targetFile, content);
118
+ }
119
+ }
120
+ async copyTypeDefinitions(sourceDir, targetDir) {
121
+ if (!(await fs.pathExists(sourceDir))) {
122
+ logger.warn(`Type definitions source directory ${sourceDir} does not exist`);
123
+ return;
124
+ }
125
+ const files = await this.getAllFiles(sourceDir, ".d.ts");
126
+ for (const file of files) {
127
+ const relativePath = path.relative(sourceDir, file);
128
+ const targetFile = path.resolve(targetDir, relativePath);
129
+ let content = await fs.readFile(file, "utf-8");
130
+ // Process .d.ts imports
131
+ content = this.processTypeDefinitionImports(content);
132
+ await fs.ensureDir(path.dirname(targetFile));
133
+ await fs.writeFile(targetFile, content);
134
+ }
135
+ }
136
+ processJavaScriptImports(content) {
137
+ // For ES modules, we need to keep the .js extensions in imports
138
+ // But fix the .js.js issue if it occurs
139
+ return content
140
+ .replace(/\.js\.js/g, ".js")
141
+ .replace(/from\s+["']([^"']+)\.ts["']/g, "from '$1.js'")
142
+ .replace(/import\s+["']([^"']+)\.ts["']/g, "import '$1.js'");
143
+ }
144
+ processTypeDefinitionImports(content) {
145
+ // Fix TypeScript imports in .d.ts files
146
+ return content
147
+ .replace(/from\s+["']([^"']+)\.ts["']/g, "from '$1'")
148
+ .replace(/import\s+["']([^"']+)\.ts["']/g, "import '$1'")
149
+ .replace(/\.js\.js/g, ".js");
150
+ }
151
+ async getAllFiles(dir, extension) {
152
+ const files = [];
153
+ if (!(await fs.pathExists(dir))) {
154
+ return files;
155
+ }
156
+ const items = await fs.readdir(dir, { withFileTypes: true });
157
+ for (const item of items) {
158
+ const fullPath = path.resolve(dir, item.name);
159
+ if (item.isDirectory()) {
160
+ const subFiles = await this.getAllFiles(fullPath, extension);
161
+ files.push(...subFiles);
162
+ }
163
+ else if (item.isFile() && item.name.endsWith(extension)) {
164
+ files.push(fullPath);
165
+ }
166
+ }
167
+ return files;
168
+ }
169
+ async generatePackageJson(codeName) {
170
+ const packageJson = {
171
+ name: codeName.toLowerCase().replace(/[^a-z0-9-]/g, "-"),
172
+ version: "1.0.0",
173
+ description: `Generated validation library: ${codeName}`,
174
+ type: "module",
175
+ main: "index.js",
176
+ types: "index.d.ts",
177
+ scripts: {
178
+ test: 'echo "Error: no test specified" && exit 1',
179
+ },
180
+ dependencies: {
181
+ // Add any runtime dependencies your generated code needs
182
+ jsonpath: "^1.1.1",
183
+ },
184
+ keywords: ["validation", "api", "testing", "javascript", "ondc"],
185
+ author: "Generated by ONDC Code Generator",
186
+ license: "MIT",
187
+ };
188
+ await writeAndFormatCode(this.rootPath, "package.json", JSON.stringify(packageJson, null, 2), "json");
189
+ }
190
+ async runCommand(command, cwd) {
191
+ try {
192
+ const { stdout, stderr } = await execAsync(command, { cwd });
193
+ if (stderr && !stderr.includes("npm WARN")) {
194
+ logger.warn(`Command stderr: ${command}`, stderr);
195
+ }
196
+ return stdout;
197
+ }
198
+ catch (error) {
199
+ logger.error(`Command failed: ${command}`, error.message);
200
+ throw new Error(`Command failed: ${command}
201
+ ${error.message}`);
202
+ }
203
+ }
204
+ async cleanup() {
205
+ try {
206
+ if (await fs.pathExists(this.tempTsPath)) {
207
+ await fs.remove(this.tempTsPath);
208
+ logger.debug("Cleaned up temporary TypeScript files");
209
+ }
210
+ }
211
+ catch (error) {
212
+ logger.warn("Failed to clean up temporary files:", error);
213
+ }
214
+ }
215
+ }
package/dist/index.js CHANGED
@@ -15,22 +15,32 @@ export { ConfigCompiler };
15
15
  // );
16
16
  // const buildYaml = readFileSync(buildPath, "utf-8");
17
17
  // const valConfig = JSON.parse(readFileSync(valConfigPath, "utf-8"));
18
- // await compiler.initialize(buildYaml);
19
- // await compiler.generateCode(
18
+ // // await compiler.initialize(buildYaml);
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
+ // // );
33
+ // // JavaScript generation example
34
+ // const compilerJs = new ConfigCompiler(SupportedLanguages.Javascript);
35
+ // await compilerJs.initialize(buildYaml);
36
+ // await compilerJs.generateCode(
20
37
  // valConfig,
21
38
  // "L1_validations",
22
39
  // 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/"
40
+ // "./alpha/javascriptNative/"
32
41
  // );
33
42
  // };
34
43
  // (async () => {
35
44
  // await main();
45
+ // console.log("Code generation completed.");
36
46
  // })();
@@ -1,4 +1,5 @@
1
1
  export declare enum SupportedLanguages {
2
2
  Typescript = "typescript",
3
- Python = "python"
3
+ Python = "python",
4
+ Javascript = "javascript"
4
5
  }
@@ -2,4 +2,5 @@ export var SupportedLanguages;
2
2
  (function (SupportedLanguages) {
3
3
  SupportedLanguages["Typescript"] = "typescript";
4
4
  SupportedLanguages["Python"] = "python";
5
+ SupportedLanguages["Javascript"] = "javascript";
5
6
  })(SupportedLanguages || (SupportedLanguages = {}));
@@ -31,6 +31,7 @@ const logLevel = process.env.NODE_ENV === "production" ? "info" : "debug";
31
31
  // Configure Winston logger
32
32
  const logger = winston.createLogger({
33
33
  level: logLevel,
34
+ silent: true,
34
35
  format: combine(timestamp({ format: "YYYY-MM-DD HH:mm:ss" }), errors({ stack: true }), // Include stack trace in error messages
35
36
  logFormat),
36
37
  transports: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ondc-code-generator",
3
- "version": "0.5.41",
3
+ "version": "0.5.42",
4
4
  "description": "generate code from build.yaml ",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",