ondc-code-generator 0.7.0 → 0.7.4

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 (53) hide show
  1. package/README.md +6 -0
  2. package/dist/bin/cli-tool.d.ts +70 -0
  3. package/dist/bin/cli-tool.js +310 -0
  4. package/dist/bin/cli.d.ts +2 -0
  5. package/dist/bin/cli.js +112 -0
  6. package/dist/constants/syntax.js +26 -0
  7. package/dist/generator/config-compiler.d.ts +3 -2
  8. package/dist/generator/config-compiler.js +18 -6
  9. package/dist/generator/generators/{golang → go}/go-ast.js +2 -2
  10. package/dist/generator/generators/go/go-generator.d.ts +13 -0
  11. package/dist/generator/generators/go/go-generator.js +322 -0
  12. package/dist/generator/generators/go/templates/api-tests.mustache +65 -0
  13. package/dist/generator/generators/go/templates/go-mod.mustache +3 -0
  14. package/dist/generator/generators/go/templates/index.mustache +34 -0
  15. package/dist/generator/generators/go/templates/json-normalizer.mustache +155 -0
  16. package/dist/generator/generators/go/templates/json-path-utils.mustache +63 -0
  17. package/dist/generator/generators/go/templates/storage-templates/api-save-utils.mustache +84 -0
  18. package/dist/generator/generators/go/templates/storage-templates/api-save.mustache +44 -0
  19. package/dist/generator/generators/go/templates/storage-templates/index.mustache +72 -0
  20. package/dist/generator/generators/go/templates/storage-templates/save-utils.mustache +75 -0
  21. package/dist/generator/generators/{golang → go}/templates/storage-templates/storage-interface.mustache +33 -22
  22. package/dist/generator/generators/go/templates/test-config.mustache +62 -0
  23. package/dist/generator/generators/go/templates/test-object.mustache +52 -0
  24. package/dist/generator/generators/go/templates/validation-code.mustache +66 -0
  25. package/dist/generator/generators/go/templates/validation-utils.mustache +321 -0
  26. package/dist/generator/generators/typescript/templates/index.mustache +1 -1
  27. package/dist/generator/generators/typescript/ts-generator.js +2 -2
  28. package/dist/index.d.ts +5 -0
  29. package/dist/index.js +4 -0
  30. package/dist/index.test.js +1 -0
  31. package/dist/types/build.d.ts +2 -0
  32. package/dist/types/compiler-types.d.ts +1 -1
  33. package/dist/types/compiler-types.js +1 -1
  34. package/dist/utils/fs-utils.d.ts +1 -0
  35. package/dist/utils/fs-utils.js +18 -34
  36. package/dist/utils/general-utils/string-utils.d.ts +1 -0
  37. package/dist/utils/general-utils/string-utils.js +11 -0
  38. package/package.json +5 -1
  39. package/dist/generator/generators/golang/go-generator.d.ts +0 -23
  40. package/dist/generator/generators/golang/go-generator.js +0 -511
  41. package/dist/generator/generators/golang/templates/api-test.mustache +0 -48
  42. package/dist/generator/generators/golang/templates/json-normalizer.mustache +0 -46
  43. package/dist/generator/generators/golang/templates/json-path-utils.mustache +0 -21
  44. package/dist/generator/generators/golang/templates/storage-templates/api-save.mustache +0 -30
  45. package/dist/generator/generators/golang/templates/storage-templates/index.mustache +0 -41
  46. package/dist/generator/generators/golang/templates/storage-templates/save-utils.mustache +0 -37
  47. package/dist/generator/generators/golang/templates/storage-templates/storage-helpers.mustache +0 -51
  48. package/dist/generator/generators/golang/templates/storage-templates/storage-types.mustache +0 -15
  49. package/dist/generator/generators/golang/templates/test-config.mustache +0 -39
  50. package/dist/generator/generators/golang/templates/test-object.mustache +0 -39
  51. package/dist/generator/generators/golang/templates/validation-code.mustache +0 -51
  52. package/dist/generator/generators/golang/templates/validation-utils.mustache +0 -246
  53. /package/dist/generator/generators/{golang → go}/go-ast.d.ts +0 -0
package/README.md CHANGED
@@ -190,3 +190,9 @@ await comp.initialize(buildString);
190
190
  const x_validations = JSON.parse(buildString)["x-validations"] as any;
191
191
  await comp.generateCode(x_validations, "L1-validations"); // pass the validations object and the name of the function of the generated code
192
192
  ```
193
+
194
+ ## scripts:
195
+
196
+ ```
197
+ node ./dist/bin/cli.js xval -c "./samples/build.yaml" -o "./alpha/" -l "go"
198
+ ```
@@ -0,0 +1,70 @@
1
+ import chalkLib from "chalk";
2
+ /** Color variants for different message types */
3
+ export declare enum CliVariant {
4
+ INFO = "info",
5
+ SUCCESS = "success",
6
+ WARNING = "warning",
7
+ ERROR = "error",
8
+ DEBUG = "debug",
9
+ SUBTLE = "subtle",
10
+ PRIMARY = "primary",
11
+ SECONDARY = "secondary"
12
+ }
13
+ /** Multiline-safe padding config */
14
+ export type CliPadding = {
15
+ top?: number;
16
+ bottom?: number;
17
+ left?: number;
18
+ };
19
+ export type TitleOptions = {
20
+ indentation?: number;
21
+ padding?: CliPadding;
22
+ badge?: string | null;
23
+ };
24
+ export type SkipOptions = {
25
+ indentation?: number;
26
+ reasonLabel?: string;
27
+ };
28
+ export type DescriptionOptions = {
29
+ indentation?: number;
30
+ padding?: CliPadding;
31
+ icon?: string | null;
32
+ prefix?: string | null;
33
+ };
34
+ type Formatter<TOpts = any> = (text: string, opts?: Partial<TOpts>) => string;
35
+ /**
36
+ * Main CLI kit with:
37
+ * - Multiline-safe indent/padding
38
+ * - Extensible "dot-pattern" style registry (Cli.title.fancy, Cli.skip.subtle, etc.)
39
+ * - Pluggable chalk instance (DI) to avoid hard-binding
40
+ */
41
+ export default class Cli {
42
+ private static _chalk;
43
+ static setChalk(chalk: typeof chalkLib): void;
44
+ /** Style registry, editable at runtime with Cli.use("path", fn). */
45
+ private static registry;
46
+ /**
47
+ * Register/override a style function:
48
+ * Cli.use("title.fancy", (text, opts) => "...custom...");
49
+ * Cli.use("skip.warn", (text, opts) => "...custom...");
50
+ */
51
+ static use<T = any>(path: string, fn: Formatter<T>): void;
52
+ /** Resolve a formatter by path; throws if missing. */
53
+ private static resolve;
54
+ static readonly title: {
55
+ (text: string, opts?: Partial<TitleOptions>): string;
56
+ [variant: string]: (text: string, opts?: Partial<TitleOptions>) => string;
57
+ };
58
+ static readonly skip: {
59
+ (text: string, opts?: Partial<SkipOptions>): string;
60
+ [variant: string]: (text: string, opts?: Partial<SkipOptions>) => string;
61
+ };
62
+ static readonly description: {
63
+ (text: string, opts?: Partial<DescriptionOptions>): string;
64
+ [variant: string]: (text: string, opts?: Partial<DescriptionOptions>) => string;
65
+ };
66
+ static indent(text: string, spaces?: number): any;
67
+ static padding(text: string, padding: CliPadding): any;
68
+ static hr(width?: number): any;
69
+ }
70
+ export {};
@@ -0,0 +1,310 @@
1
+ var _a;
2
+ import chalkLib from "chalk";
3
+ /** Color variants for different message types */
4
+ export var CliVariant;
5
+ (function (CliVariant) {
6
+ CliVariant["INFO"] = "info";
7
+ CliVariant["SUCCESS"] = "success";
8
+ CliVariant["WARNING"] = "warning";
9
+ CliVariant["ERROR"] = "error";
10
+ CliVariant["DEBUG"] = "debug";
11
+ CliVariant["SUBTLE"] = "subtle";
12
+ CliVariant["PRIMARY"] = "primary";
13
+ CliVariant["SECONDARY"] = "secondary";
14
+ })(CliVariant || (CliVariant = {}));
15
+ /**
16
+ * A tiny utility to safely indent/pad across multiple lines (ANSI-friendly).
17
+ */
18
+ function padLines(text, padding = {}) {
19
+ const { top = 0, bottom = 0, left = 0 } = padding;
20
+ const leftPad = " ".repeat(left);
21
+ const lines = text.split("\n").map((l) => (left > 0 ? leftPad + l : l));
22
+ const topPad = Array.from({ length: top }, () => "").join("\n");
23
+ const bottomPad = Array.from({ length: bottom }, () => "").join("\n");
24
+ return ((top ? topPad + "\n" : "") +
25
+ lines.join("\n") +
26
+ (bottom ? "\n" + bottomPad : ""));
27
+ }
28
+ /**
29
+ * Path helpers for dot-pattern registry: "title.fancy", "skip.subtle", etc.
30
+ */
31
+ function getByPath(obj, path) {
32
+ return path
33
+ .split(".")
34
+ .reduce((acc, key) => (acc ? acc[key] : undefined), obj);
35
+ }
36
+ function setByPath(obj, path, value) {
37
+ const keys = path.split(".");
38
+ const last = keys.pop();
39
+ const parent = keys.reduce((acc, key) => (acc[key] ?? (acc[key] = {})), obj);
40
+ parent[last] = value;
41
+ }
42
+ /**
43
+ * Main CLI kit with:
44
+ * - Multiline-safe indent/padding
45
+ * - Extensible "dot-pattern" style registry (Cli.title.fancy, Cli.skip.subtle, etc.)
46
+ * - Pluggable chalk instance (DI) to avoid hard-binding
47
+ */
48
+ class Cli {
49
+ static setChalk(chalk) {
50
+ this._chalk = chalk;
51
+ }
52
+ /**
53
+ * Register/override a style function:
54
+ * Cli.use("title.fancy", (text, opts) => "...custom...");
55
+ * Cli.use("skip.warn", (text, opts) => "...custom...");
56
+ */
57
+ static use(path, fn) {
58
+ setByPath(this.registry, path, fn);
59
+ }
60
+ /** Resolve a formatter by path; throws if missing. */
61
+ static resolve(path) {
62
+ const got = getByPath(this.registry, path);
63
+ if (!got)
64
+ throw new Error(`Cli: style "${path}" not found. Register it with Cli.use("${path}", fn).`);
65
+ return got;
66
+ }
67
+ // Utility passthroughs
68
+ static indent(text, spaces = 0) {
69
+ return this.registry.util.indent(text, spaces);
70
+ }
71
+ static padding(text, padding) {
72
+ return this.registry.util.padding(text, padding);
73
+ }
74
+ static hr(width) {
75
+ return this.registry.util.hr(width);
76
+ }
77
+ }
78
+ _a = Cli;
79
+ // You can inject your own chalk-like instance if needed (for tests, themes, etc.)
80
+ Cli._chalk = chalkLib;
81
+ /** Style registry, editable at runtime with Cli.use("path", fn). */
82
+ Cli.registry = {
83
+ title: {
84
+ default: ((text, opts) => {
85
+ const { indentation = 0, padding, badge } = opts || {};
86
+ const inner = (badge ? _a._chalk.black.bgYellow(` ${badge} `) + " " : "") +
87
+ _a._chalk.bold.black.bgYellow(` ${text} `);
88
+ const block = " ".repeat(indentation) + inner;
89
+ return padLines(block, padding ?? {});
90
+ }),
91
+ info: ((text, opts) => {
92
+ const { indentation = 0, padding, badge } = opts || {};
93
+ const inner = (badge ? _a._chalk.white.bgBlue(` ${badge} `) + " " : "") +
94
+ _a._chalk.bold.bgBlue.white(` ${text} `);
95
+ const block = " ".repeat(indentation) + inner;
96
+ return padLines(block, padding ?? {});
97
+ }),
98
+ success: ((text, opts) => {
99
+ const { indentation = 0, padding, badge } = opts || {};
100
+ const inner = (badge ? _a._chalk.black.bgGreen(` ${badge} `) + " " : "") +
101
+ _a._chalk.bold.bgGreen.black(` ${text} `);
102
+ const block = " ".repeat(indentation) + inner;
103
+ return padLines(block, padding ?? {});
104
+ }),
105
+ warning: ((text, opts) => {
106
+ const { indentation = 0, padding, badge } = opts || {};
107
+ const inner = (badge ? _a._chalk.black.bgYellow(` ${badge} `) + " " : "") +
108
+ _a._chalk.bold.bgYellow.black(` ${text} `);
109
+ const block = " ".repeat(indentation) + inner;
110
+ return padLines(block, padding ?? {});
111
+ }),
112
+ error: ((text, opts) => {
113
+ const { indentation = 0, padding, badge } = opts || {};
114
+ const inner = (badge ? _a._chalk.white.bgRed(` ${badge} `) + " " : "") +
115
+ _a._chalk.bold.bgRed.white(` ${text} `);
116
+ const block = " ".repeat(indentation) + inner;
117
+ return padLines(block, padding ?? {});
118
+ }),
119
+ debug: ((text, opts) => {
120
+ const { indentation = 0, padding, badge } = opts || {};
121
+ const inner = (badge ? _a._chalk.white.bgMagenta(` ${badge} `) + " " : "") +
122
+ _a._chalk.bold.bgMagenta.white(` ${text} `);
123
+ const block = " ".repeat(indentation) + inner;
124
+ return padLines(block, padding ?? {});
125
+ }),
126
+ primary: ((text, opts) => {
127
+ const { indentation = 0, padding, badge } = opts || {};
128
+ const inner = (badge ? _a._chalk.white.bgCyan(` ${badge} `) + " " : "") +
129
+ _a._chalk.bold.bgCyan.black(` ${text} `);
130
+ const block = " ".repeat(indentation) + inner;
131
+ return padLines(block, padding ?? {});
132
+ }),
133
+ secondary: ((text, opts) => {
134
+ const { indentation = 0, padding, badge } = opts || {};
135
+ const inner = (badge ? _a._chalk.black.bgGray(` ${badge} `) + " " : "") +
136
+ _a._chalk.bold.bgGray.white(` ${text} `);
137
+ const block = " ".repeat(indentation) + inner;
138
+ return padLines(block, padding ?? {});
139
+ }),
140
+ subtle: ((text, opts) => {
141
+ const { indentation = 0, padding, badge } = opts || {};
142
+ const inner = (badge ? _a._chalk.gray(`(${badge}) `) : "") +
143
+ _a._chalk.bold.underline(text);
144
+ const block = " ".repeat(indentation) + inner;
145
+ return padLines(block, padding ?? {});
146
+ }),
147
+ box: ((text, opts) => {
148
+ const { indentation = 0, padding, badge } = opts || {};
149
+ const label = badge ? `[${badge}] ` : "";
150
+ const content = label + text;
151
+ const lines = content.split("\n");
152
+ const width = Math.max(...lines.map((l) => l.length));
153
+ const top = "┌" + "─".repeat(width + 2) + "┐";
154
+ const bottom = "└" + "─".repeat(width + 2) + "┘";
155
+ const body = lines.map((l) => `│ ${l.padEnd(width, " ")} │`).join("\n");
156
+ const boxed = [top, body, bottom].join("\n");
157
+ const prefixed = " ".repeat(indentation) +
158
+ boxed.replace(/\n/g, "\n" + " ".repeat(indentation));
159
+ return padLines(prefixed, padding ?? {});
160
+ }),
161
+ },
162
+ skip: {
163
+ default: ((text, opts) => {
164
+ const { indentation = 0, reasonLabel = "skipped" } = opts || {};
165
+ return (" ".repeat(indentation) +
166
+ _a._chalk.yellowBright.italic(`- ${text} (${reasonLabel})`));
167
+ }),
168
+ info: ((text, opts) => {
169
+ const { indentation = 0, reasonLabel = "skipped" } = opts || {};
170
+ return (" ".repeat(indentation) +
171
+ _a._chalk.blue.italic(`- ${text} (${reasonLabel})`));
172
+ }),
173
+ success: ((text, opts) => {
174
+ const { indentation = 0, reasonLabel = "skipped" } = opts || {};
175
+ return (" ".repeat(indentation) +
176
+ _a._chalk.green.italic(`- ${text} (${reasonLabel})`));
177
+ }),
178
+ warning: ((text, opts) => {
179
+ const { indentation = 0, reasonLabel = "warning" } = opts || {};
180
+ return (" ".repeat(indentation) +
181
+ _a._chalk.yellow.italic(`⚠ ${text} (${reasonLabel})`));
182
+ }),
183
+ error: ((text, opts) => {
184
+ const { indentation = 0, reasonLabel = "error" } = opts || {};
185
+ return (" ".repeat(indentation) +
186
+ _a._chalk.red.italic(`✗ ${text} (${reasonLabel})`));
187
+ }),
188
+ debug: ((text, opts) => {
189
+ const { indentation = 0, reasonLabel = "debug" } = opts || {};
190
+ return (" ".repeat(indentation) +
191
+ _a._chalk.magenta.italic(`• ${text} (${reasonLabel})`));
192
+ }),
193
+ primary: ((text, opts) => {
194
+ const { indentation = 0, reasonLabel = "skipped" } = opts || {};
195
+ return (" ".repeat(indentation) +
196
+ _a._chalk.cyan.italic(`- ${text} (${reasonLabel})`));
197
+ }),
198
+ secondary: ((text, opts) => {
199
+ const { indentation = 0, reasonLabel = "skipped" } = opts || {};
200
+ return (" ".repeat(indentation) +
201
+ _a._chalk.gray.italic(`- ${text} (${reasonLabel})`));
202
+ }),
203
+ subtle: ((text, opts) => {
204
+ const { indentation = 0, reasonLabel = "skipped" } = opts || {};
205
+ return (" ".repeat(indentation) +
206
+ _a._chalk.dim(`- ${text} (${reasonLabel})`));
207
+ }),
208
+ },
209
+ description: {
210
+ default: ((text, opts) => {
211
+ const { indentation = 0, padding, icon, prefix } = opts || {};
212
+ const iconStr = icon ? `${icon} ` : "";
213
+ const prefixStr = prefix ? `${_a._chalk.bold(prefix)} ` : "";
214
+ const inner = iconStr + prefixStr + _a._chalk.gray(text);
215
+ const block = " ".repeat(indentation) + inner;
216
+ return padLines(block, padding ?? {});
217
+ }),
218
+ info: ((text, opts) => {
219
+ const { indentation = 0, padding, icon, prefix } = opts || {};
220
+ const iconStr = icon ? `${icon} ` : "ℹ️ ";
221
+ const prefixStr = prefix ? `${_a._chalk.blue.bold(prefix)} ` : "";
222
+ const inner = iconStr + prefixStr + _a._chalk.blue(text);
223
+ const block = " ".repeat(indentation) + inner;
224
+ return padLines(block, padding ?? {});
225
+ }),
226
+ success: ((text, opts) => {
227
+ const { indentation = 0, padding, icon, prefix } = opts || {};
228
+ const iconStr = icon ? `${icon} ` : "";
229
+ const prefixStr = prefix ? `${_a._chalk.green.bold(prefix)} ` : "";
230
+ const inner = iconStr + prefixStr + _a._chalk.green(text);
231
+ const block = " ".repeat(indentation) + inner;
232
+ return padLines(block, padding ?? {});
233
+ }),
234
+ warning: ((text, opts) => {
235
+ const { indentation = 0, padding, icon, prefix } = opts || {};
236
+ const iconStr = icon ? `${icon} ` : "";
237
+ const prefixStr = prefix ? `${_a._chalk.yellow.bold(prefix)} ` : "";
238
+ const inner = iconStr + prefixStr + _a._chalk.yellow(text);
239
+ const block = " ".repeat(indentation) + inner;
240
+ return padLines(block, padding ?? {});
241
+ }),
242
+ error: ((text, opts) => {
243
+ const { indentation = 0, padding, icon, prefix } = opts || {};
244
+ const iconStr = icon ? `${icon} ` : "";
245
+ const prefixStr = prefix ? `${_a._chalk.red.bold(prefix)} ` : "";
246
+ const inner = iconStr + prefixStr + _a._chalk.red(text);
247
+ const block = " ".repeat(indentation) + inner;
248
+ return padLines(block, padding ?? {});
249
+ }),
250
+ debug: ((text, opts) => {
251
+ const { indentation = 0, padding, icon, prefix } = opts || {};
252
+ const iconStr = icon ? `${icon} ` : "";
253
+ const prefixStr = prefix ? `${_a._chalk.magenta.bold(prefix)} ` : "";
254
+ const inner = iconStr + prefixStr + _a._chalk.magenta(text);
255
+ const block = " ".repeat(indentation) + inner;
256
+ return padLines(block, padding ?? {});
257
+ }),
258
+ primary: ((text, opts) => {
259
+ const { indentation = 0, padding, icon, prefix } = opts || {};
260
+ const iconStr = icon ? `${icon} ` : "";
261
+ const prefixStr = prefix ? `${_a._chalk.cyan.bold(prefix)} ` : "";
262
+ const inner = iconStr + prefixStr + _a._chalk.cyan(text);
263
+ const block = " ".repeat(indentation) + inner;
264
+ return padLines(block, padding ?? {});
265
+ }),
266
+ secondary: ((text, opts) => {
267
+ const { indentation = 0, padding, icon, prefix } = opts || {};
268
+ const iconStr = icon ? `${icon} ` : "";
269
+ const prefixStr = prefix ? `${_a._chalk.gray.bold(prefix)} ` : "";
270
+ const inner = iconStr + prefixStr + _a._chalk.gray(text);
271
+ const block = " ".repeat(indentation) + inner;
272
+ return padLines(block, padding ?? {});
273
+ }),
274
+ subtle: ((text, opts) => {
275
+ const { indentation = 0, padding, icon, prefix } = opts || {};
276
+ const iconStr = icon ? `${_a._chalk.dim(icon)} ` : "";
277
+ const prefixStr = prefix ? `${_a._chalk.dim.bold(prefix)} ` : "";
278
+ const inner = iconStr + prefixStr + _a._chalk.dim(text);
279
+ const block = " ".repeat(indentation) + inner;
280
+ return padLines(block, padding ?? {});
281
+ }),
282
+ },
283
+ util: {
284
+ // Multiline-safe indentation (kept public as method wrapper below)
285
+ indent: ((text, spaces = 0) => padLines(text, { left: spaces })),
286
+ // Multiline-safe padding helper (kept public as method wrapper below)
287
+ padding: ((text, padding) => padLines(text, padding)),
288
+ // A clean horizontal rule that adapts to terminal width (fallback to 80)
289
+ hr: ((width) => {
290
+ const w = width ?? (process.stdout.columns || 80);
291
+ return "─".repeat(Math.max(16, w)); // ensure some minimum length
292
+ }),
293
+ },
294
+ };
295
+ // ----------------------------
296
+ // DOT-PATTERN PROXIES
297
+ // ----------------------------
298
+ // Title proxy: supports `Cli.title("text")` (default) and `Cli.title.box("text")`, etc.
299
+ Cli.title = new Proxy(((text, opts) => _a.resolve("title.default")(text, opts)), {
300
+ get: (_target, prop) => (text, opts) => _a.resolve(`title.${prop}`)(text, opts),
301
+ });
302
+ // Skip proxy: supports `Cli.skip("...", { reasonLabel: "ignored" })` and `Cli.skip.subtle("...")`
303
+ Cli.skip = new Proxy(((text, opts) => _a.resolve("skip.default")(text, opts)), {
304
+ get: (_target, prop) => (text, opts) => _a.resolve(`skip.${prop}`)(text, opts),
305
+ });
306
+ // Description proxy: supports `Cli.description("text")` and `Cli.description.info("text")`, etc.
307
+ Cli.description = new Proxy(((text, opts) => _a.resolve("description.default")(text, opts)), {
308
+ get: (_target, prop) => (text, opts) => _a.resolve(`description.${prop}`)(text, opts),
309
+ });
310
+ export default Cli;
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env node
2
+ import path from "path";
3
+ import fs from "fs/promises";
4
+ import { fileURLToPath } from "url";
5
+ import { program } from "commander";
6
+ import { ConfigCompiler, SupportedLanguages } from "../index.js";
7
+ import Cli from "./cli-tool.js";
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+ // interface CLIOptions {
10
+ // config: string;
11
+ // output: string;
12
+ // lang: string;
13
+ // }
14
+ program
15
+ .name("ondc-code-generator")
16
+ .description("Ondc Validation Code Generator")
17
+ .version("0.0.1");
18
+ program
19
+ .command("ondc-validation-gen")
20
+ .alias("xval")
21
+ .option("-c, --config <path>", "Path to build.yaml file")
22
+ .option("-f, --function-name <name>", "Name of the validation function to generate")
23
+ .option("-o, --output <directory>", "Output directory for generated code")
24
+ .option("-l, --lang <language>", "Target programming language (typescript, python, javascript, go)")
25
+ .description("Generate validation code")
26
+ .action(async (options) => {
27
+ const { config, output, lang, functionName } = options;
28
+ console.log(Cli.title("Ondc Validation Code Generator"));
29
+ if (!config || !output || !lang) {
30
+ console.log(Cli.description.error("Please provide all required options: --config, --output, --lang"));
31
+ process.exit(1);
32
+ }
33
+ try {
34
+ console.log(Cli.description.info(`Generating validation code for language: ${lang}`));
35
+ const functionName = options.functionName || "L1validations";
36
+ const language = getSupportedLanguage(lang);
37
+ const compiler = new ConfigCompiler(language);
38
+ const buildPath = path.resolve(process.cwd(), config);
39
+ console.log(Cli.description.info(`Reading build file from ${buildPath}...`));
40
+ const buildYaml = await fs.readFile(buildPath, "utf-8");
41
+ console.log(Cli.description.info("Initializing compiler..."));
42
+ await compiler.initialize(buildYaml);
43
+ console.log(Cli.description.info("Generating validation code..."));
44
+ await compiler.generateValidationFromBuild(functionName, output, true);
45
+ console.log(Cli.description.success(`Validation code generated successfully in ${output} for language ${lang}`));
46
+ }
47
+ catch (error) {
48
+ const message = error instanceof Error ? error.message : String(error);
49
+ console.error(Cli.description.error(`Error: ${message}`));
50
+ process.exit(1);
51
+ }
52
+ });
53
+ program
54
+ .command("schema-gen")
55
+ .alias("schema")
56
+ .option("-c, --config <path>", "Path to build.yaml file")
57
+ .option("-o, --output <directory>", "Output directory for generated schema")
58
+ .option("-f, --format <format>", "Output format (json, yaml,typescript)")
59
+ .description("Generate L0 schema")
60
+ .action(async (options) => {
61
+ console.log(Cli.title("Ondc Schema Generator"));
62
+ try {
63
+ const { config, output, format } = options;
64
+ if (!config || !output || !format) {
65
+ console.log(Cli.description.error("Please provide all required options: --config, --output, --format"));
66
+ process.exit(1);
67
+ }
68
+ console.log(Cli.description.info(`Generating L0 schema...`));
69
+ const buildPath = path.resolve(process.cwd(), config);
70
+ console.log(Cli.description.info(`Reading build file from ${buildPath}...`));
71
+ const buildYaml = await fs.readFile(buildPath, "utf-8");
72
+ const compiler = new ConfigCompiler(SupportedLanguages.Typescript);
73
+ await compiler.initialize(buildYaml);
74
+ const formatType = getSchemaFormat(format);
75
+ await compiler.generateL0Schema(output, formatType, true);
76
+ }
77
+ catch (error) {
78
+ const message = error instanceof Error ? error.message : String(error);
79
+ console.error(Cli.description.error(`Error: ${message}`));
80
+ process.exit(1);
81
+ }
82
+ });
83
+ program.parse();
84
+ function getSupportedLanguage(lang) {
85
+ switch (lang.toLowerCase()) {
86
+ case "typescript":
87
+ return SupportedLanguages.Typescript;
88
+ case "python":
89
+ return SupportedLanguages.Python;
90
+ case "javascript":
91
+ return SupportedLanguages.Javascript;
92
+ case "go":
93
+ return SupportedLanguages.Golang;
94
+ default:
95
+ throw new Error(`Unsupported language: ${lang}. Supported languages are: ${getValidLanguageOptions()}`);
96
+ }
97
+ }
98
+ function getSchemaFormat(format) {
99
+ switch (format.toLowerCase()) {
100
+ case "json":
101
+ return "json";
102
+ case "typescript":
103
+ return "typescript";
104
+ case "yaml":
105
+ throw new Error("YAML format is not yet supported");
106
+ default:
107
+ throw new Error(`Unsupported format: ${format}. Supported formats are: json, typescript`);
108
+ }
109
+ }
110
+ function getValidLanguageOptions() {
111
+ return Object.values(SupportedLanguages).join(", ");
112
+ }
@@ -168,4 +168,30 @@ export const ReservedKeywords = new Set([
168
168
  "match",
169
169
  "case",
170
170
  "_",
171
+ // golang keywords
172
+ "break",
173
+ "default",
174
+ "func",
175
+ "interface",
176
+ "select",
177
+ "case",
178
+ "defer",
179
+ "go",
180
+ "map",
181
+ "struct",
182
+ "chan",
183
+ "else",
184
+ "goto",
185
+ "package",
186
+ "switch",
187
+ "const",
188
+ "fallthrough",
189
+ "if",
190
+ "range",
191
+ "type",
192
+ "continue",
193
+ "for",
194
+ "import",
195
+ "return",
196
+ "var",
171
197
  ]);
@@ -20,8 +20,9 @@ export declare class ConfigCompiler {
20
20
  initialize: (buildYaml: string, generatorConfig?: Partial<CodeGeneratorConfig>) => Promise<void>;
21
21
  performValidations: (valConfig: ValidationConfig) => Promise<void>;
22
22
  withMinimalValidations: (valConfig: ValidationConfig) => Promise<void>;
23
- generateCode: (valConfig: ValidationConfig, codeName?: string, minimal?: boolean, outputPath?: string) => Promise<void>;
24
- generateL0Schema: (outputPath?: string, type?: "json" | "typescript") => Promise<void>;
23
+ generateCode: (valConfig: ValidationConfig, codeName?: string, minimal?: boolean, outputPath?: string, absolutePath?: boolean) => Promise<void>;
24
+ generateL0Schema: (outputPath?: string, type?: "json" | "typescript", absolutePath?: boolean) => Promise<void>;
25
25
  generateValidPaths: () => Promise<Record<string, string[]>>;
26
+ generateValidationFromBuild: (codeName: string, outputPath: string, absolutePath?: boolean) => Promise<void>;
26
27
  }
27
28
  export {};
@@ -11,7 +11,7 @@ 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
13
  import { JavascriptGenerator } from "./generators/javascript/js-generator.js";
14
- import { GolangGenerator } from "./generators/golang/go-generator.js";
14
+ import { GoGenerator } from "./generators/go/go-generator.js";
15
15
  const __filename = fileURLToPath(import.meta.url);
16
16
  const __dirname = path.dirname(__filename);
17
17
  const defaultConfig = {
@@ -57,7 +57,7 @@ export class ConfigCompiler {
57
57
  // throw new Error("validation failed");
58
58
  };
59
59
  // };
60
- this.generateCode = async (valConfig, codeName = "L1-Validations", minimal = false, outputPath = "./") => {
60
+ this.generateCode = async (valConfig, codeName = "L1-Validations", minimal = false, outputPath = "./", absolutePath = false) => {
61
61
  valConfig = JSON.parse(JSON.stringify(valConfig));
62
62
  if (this.generatorConfig?.duplicateVariablesInChildren) {
63
63
  valConfig = duplicateVariablesInChildren(valConfig);
@@ -69,7 +69,9 @@ export class ConfigCompiler {
69
69
  await this.performValidations(valConfig);
70
70
  }
71
71
  // Generate code based on the language
72
- const targetPath = `${outputPath}generated/${codeName}`;
72
+ const targetPath = absolutePath
73
+ ? outputPath
74
+ : `${outputPath}generated/${codeName}`;
73
75
  switch (this.language) {
74
76
  case SupportedLanguages.Typescript:
75
77
  await new TypescriptGenerator(valConfig, this.errorDefinitions ?? [], targetPath).generateCode({
@@ -87,7 +89,7 @@ export class ConfigCompiler {
87
89
  });
88
90
  break;
89
91
  case SupportedLanguages.Golang:
90
- await new GolangGenerator(valConfig, this.errorDefinitions ?? [], targetPath).generateCode({
92
+ await new GoGenerator(valConfig, this.errorDefinitions ?? [], targetPath).generateCode({
91
93
  codeName: codeName,
92
94
  });
93
95
  break;
@@ -95,11 +97,13 @@ export class ConfigCompiler {
95
97
  throw new Error("Language not supported");
96
98
  }
97
99
  };
98
- this.generateL0Schema = async (outputPath = "./", type = "typescript") => {
100
+ this.generateL0Schema = async (outputPath = "./", type = "typescript", absolutePath = false) => {
99
101
  if (!this.jsonSchemas) {
100
102
  throw new Error("Schemas not initialized");
101
103
  }
102
- const targetPath = `${outputPath}generated/L0-schemas/`;
104
+ const targetPath = absolutePath
105
+ ? outputPath
106
+ : `${outputPath}generated/L0-schemas/`;
103
107
  for (const schema in this.jsonSchemas) {
104
108
  const json = this.jsonSchemas[schema];
105
109
  if (type === "typescript") {
@@ -129,6 +133,14 @@ export class ConfigCompiler {
129
133
  // );
130
134
  return this.possibleJsonPaths;
131
135
  };
136
+ this.generateValidationFromBuild = async (codeName, outputPath, absolutePath = false) => {
137
+ if (!this.buildData)
138
+ throw new Error("Build data not initialized");
139
+ const valConfig = this.buildData["x-validations"];
140
+ if (!valConfig)
141
+ throw new Error("No validation config found in build data");
142
+ await this.generateCode(valConfig, codeName, false, outputPath, absolutePath);
143
+ };
132
144
  this.language = language;
133
145
  this.SchemaExtractionService = new SchemaExtractionService();
134
146
  }
@@ -43,14 +43,14 @@ function compileToGo(node) {
43
43
  const unary = node;
44
44
  const func = uniaryFunction[unary.customFunction];
45
45
  const varName = unary.expression.name;
46
- return `utils.${func}(${varName})`;
46
+ return `validationutils.${func}(${varName})`;
47
47
  }
48
48
  if (node.type === "customBinaryFunction") {
49
49
  const binary = node;
50
50
  const func = binaryFunction[binary.customFunction];
51
51
  const lhs = binary.lhs.name;
52
52
  const rhs = binary.rhs.name;
53
- return `utils.${func}(${lhs}, ${rhs})`;
53
+ return `validationutils.${func}(${lhs}, ${rhs})`;
54
54
  }
55
55
  throw new Error("Unknown node type");
56
56
  }
@@ -0,0 +1,13 @@
1
+ import { CodeGenerator, CodeGeneratorProps } from "../classes/abstract-generator.js";
2
+ export declare class GoGenerator extends CodeGenerator {
3
+ codeConfig: CodeGeneratorProps | undefined;
4
+ generateSessionDataCode(): Promise<void>;
5
+ generateValidationCode(): Promise<void>;
6
+ generateCode: (codeConfig: CodeGeneratorProps) => Promise<void>;
7
+ private generateIndexFile;
8
+ private getExternalKeys;
9
+ private generateTestFunction;
10
+ private createVariablesCode;
11
+ private createValidationLogicCode;
12
+ private CreateErrorMarkdown;
13
+ }