@codenotch/codenotch.cli 1.0.36 → 1.0.38

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 (105) hide show
  1. package/README.md +2 -2
  2. package/dist/commands/generate/app.d.ts +2 -0
  3. package/dist/commands/generate/app.js +45 -0
  4. package/dist/commands/generate/app.js.map +1 -0
  5. package/dist/commands/generate/appmanifest.d.ts +2 -0
  6. package/dist/commands/generate/appmanifest.js +34 -0
  7. package/dist/commands/generate/appmanifest.js.map +1 -0
  8. package/dist/commands/generate/dbcontext.d.ts +2 -0
  9. package/dist/commands/generate/dbcontext.js +32 -0
  10. package/dist/commands/generate/dbcontext.js.map +1 -0
  11. package/dist/commands/generate/i18n.d.ts +2 -0
  12. package/dist/commands/generate/i18n.js +29 -0
  13. package/dist/commands/generate/i18n.js.map +1 -0
  14. package/dist/commands/generate/index.d.ts +0 -1
  15. package/dist/commands/generate/index.js +14 -33
  16. package/dist/commands/generate/index.js.map +1 -1
  17. package/dist/commands/generate/manifest.d.ts +2 -0
  18. package/dist/commands/generate/manifest.js +29 -0
  19. package/dist/commands/generate/manifest.js.map +1 -0
  20. package/dist/commands/generate/openapi.d.ts +2 -0
  21. package/dist/commands/generate/openapi.js +32 -0
  22. package/dist/commands/generate/openapi.js.map +1 -0
  23. package/dist/commands/generate/pkg.d.ts +2 -0
  24. package/dist/commands/generate/pkg.js +34 -0
  25. package/dist/commands/generate/pkg.js.map +1 -0
  26. package/dist/commands/generate/shared.d.ts +17 -0
  27. package/dist/commands/generate/shared.js +70 -0
  28. package/dist/commands/generate/shared.js.map +1 -0
  29. package/dist/commands/project/new.js +108 -96
  30. package/dist/commands/project/new.js.map +1 -1
  31. package/dist/commands/react/build.js +11 -5
  32. package/dist/commands/react/build.js.map +1 -1
  33. package/dist/commands/react/clean.d.ts +2 -0
  34. package/dist/commands/react/clean.js +46 -0
  35. package/dist/commands/react/clean.js.map +1 -0
  36. package/dist/commands/react/dev.d.ts +2 -0
  37. package/dist/commands/react/dev.js +28 -0
  38. package/dist/commands/react/dev.js.map +1 -0
  39. package/dist/commands/react/index.js +5 -1
  40. package/dist/commands/react/index.js.map +1 -1
  41. package/dist/commands/react/serve.js +33 -4
  42. package/dist/commands/react/serve.js.map +1 -1
  43. package/dist/commands/react/shared.d.ts +21 -0
  44. package/dist/commands/react/shared.js +80 -0
  45. package/dist/commands/react/shared.js.map +1 -0
  46. package/dist/commands/validation/ValidationUtils.d.ts +1 -1
  47. package/dist/commands/validation/ValidationUtils.js +3 -0
  48. package/dist/commands/validation/ValidationUtils.js.map +1 -1
  49. package/dist/commands/validation/files/I18nValidator.d.ts +29 -0
  50. package/dist/commands/validation/files/I18nValidator.js +198 -0
  51. package/dist/commands/validation/files/I18nValidator.js.map +1 -0
  52. package/dist/commands/validation/files/ProjectManifestValidator.d.ts +5 -0
  53. package/dist/commands/validation/files/ProjectManifestValidator.js +31 -0
  54. package/dist/commands/validation/files/ProjectManifestValidator.js.map +1 -0
  55. package/dist/commands/validation/files/ScriptValidator.js +1 -1
  56. package/dist/commands/validation/files/ScriptValidator.js.map +1 -1
  57. package/dist/commands/validation/validate.js +11 -6
  58. package/dist/commands/validation/validate.js.map +1 -1
  59. package/dist/utils/BuildUtils.d.ts +62 -7
  60. package/dist/utils/BuildUtils.js +310 -222
  61. package/dist/utils/BuildUtils.js.map +1 -1
  62. package/dist/utils/ConsoleUtils.d.ts +8 -0
  63. package/dist/utils/ConsoleUtils.js +25 -0
  64. package/dist/utils/ConsoleUtils.js.map +1 -1
  65. package/dist/utils/DbSchemaUtils.d.ts +49 -0
  66. package/dist/utils/DbSchemaUtils.js +246 -0
  67. package/dist/utils/DbSchemaUtils.js.map +1 -0
  68. package/dist/utils/FileUtils.d.ts +104 -15
  69. package/dist/utils/FileUtils.js +285 -100
  70. package/dist/utils/FileUtils.js.map +1 -1
  71. package/dist/utils/I18nTsUtils.d.ts +66 -0
  72. package/dist/utils/I18nTsUtils.js +221 -0
  73. package/dist/utils/I18nTsUtils.js.map +1 -0
  74. package/dist/utils/OpenApiUtils.d.ts +81 -0
  75. package/dist/utils/OpenApiUtils.js +123 -0
  76. package/dist/utils/OpenApiUtils.js.map +1 -0
  77. package/dist/utils/ProjectCompilationUtils.d.ts +0 -1
  78. package/dist/utils/ProjectCompilationUtils.js +4 -52
  79. package/dist/utils/ProjectCompilationUtils.js.map +1 -1
  80. package/dist/utils/ProjectGeneratorUtils.d.ts +35 -0
  81. package/dist/utils/ProjectGeneratorUtils.js +119 -0
  82. package/dist/utils/ProjectGeneratorUtils.js.map +1 -0
  83. package/dist/utils/ProjectTemplates.d.ts +102 -0
  84. package/dist/utils/ProjectTemplates.js +284 -0
  85. package/dist/utils/ProjectTemplates.js.map +1 -0
  86. package/dist/utils/ProjectUtils.d.ts +216 -3
  87. package/dist/utils/ProjectUtils.js +387 -22
  88. package/dist/utils/ProjectUtils.js.map +1 -1
  89. package/dist/utils/RuntimeUtils.js +14 -8
  90. package/dist/utils/RuntimeUtils.js.map +1 -1
  91. package/dist/utils/ScriptDeclarationUtils.d.ts +169 -0
  92. package/dist/utils/ScriptDeclarationUtils.js +398 -0
  93. package/dist/utils/ScriptDeclarationUtils.js.map +1 -0
  94. package/dist/utils/ServeUtils.js +10 -5
  95. package/dist/utils/ServeUtils.js.map +1 -1
  96. package/dist/utils/ShellUtils.d.ts +6 -0
  97. package/dist/utils/ShellUtils.js +13 -0
  98. package/dist/utils/ShellUtils.js.map +1 -1
  99. package/dist/utils/TemplateUtils.d.ts +62 -0
  100. package/dist/utils/TemplateUtils.js +218 -0
  101. package/dist/utils/TemplateUtils.js.map +1 -0
  102. package/dist/utils/TypeSchemaUtils.d.ts +42 -0
  103. package/dist/utils/TypeSchemaUtils.js +171 -0
  104. package/dist/utils/TypeSchemaUtils.js.map +1 -0
  105. package/package.json +3 -2
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.APP_NAME_PATTERN = void 0;
7
+ const BuildUtils_1 = __importDefault(require("./BuildUtils"));
8
+ /**
9
+ * An app name is used both as the file name and as the React component name, it must be a valid identifier
10
+ */
11
+ exports.APP_NAME_PATTERN = /^[A-Za-z_$][\w$]*$/;
12
+ /**
13
+ * Single source of truth for the content of the files generated by the CLI.
14
+ *
15
+ * Both 'cn project new' (which scaffolds a whole project) and 'cn generate ...'
16
+ * (which generates one file at a time) build their files from here, so a template
17
+ * only has to be updated once.
18
+ */
19
+ class TemplateUtils {
20
+ static isValidAppName(appName) {
21
+ return exports.APP_NAME_PATTERN.test(appName);
22
+ }
23
+ /**
24
+ * Empty React app, e.g. 'apps/index.tsx'
25
+ */
26
+ static createAppTsx(appName) {
27
+ return [
28
+ `import React from 'react';`,
29
+ `import { useCodenotch } from '@codenotch/codenotch.react';`,
30
+ ``,
31
+ `const ${appName}: React.FC<{}> = () => {`,
32
+ `\tconst cn = useCodenotch();`,
33
+ ``,
34
+ `\treturn <div>`,
35
+ `\t\t<h1>My new Codenotch App</h1>`,
36
+ `\t\t<pre>{JSON.stringify(cn.env, null, 4)}</pre>`,
37
+ `\t</div>`,
38
+ `};`,
39
+ ``,
40
+ `export default ${appName};`,
41
+ ``
42
+ ].join('\n');
43
+ }
44
+ /**
45
+ * Manifest of an app, e.g. 'apps/index.manifest.json'
46
+ */
47
+ static createAppManifest(appName) {
48
+ return {
49
+ app: {
50
+ name: appName
51
+ },
52
+ html: {
53
+ title: appName
54
+ },
55
+ pwa: {
56
+ name: appName,
57
+ display: 'standalone',
58
+ display_override: [
59
+ 'window-controls-overlay'
60
+ ],
61
+ start_url: './',
62
+ icons: [
63
+ { src: 'logo512.png', sizes: '512x512', type: 'image/png' },
64
+ { src: 'logo192.png', sizes: '192x192', type: 'image/png' }
65
+ ]
66
+ }
67
+ };
68
+ }
69
+ /**
70
+ * package.json of a Codenotch project
71
+ * @param name npm package name, usually the service name of the project
72
+ * @param extra dependencies a template adds on top of the base ones
73
+ * @param withReact false for a project without any app, which needs no React at all
74
+ */
75
+ static createPackageJson(name, extra = {}, withReact = true) {
76
+ return {
77
+ name: name,
78
+ version: '0.0.0',
79
+ description: 'New Codenotch Project',
80
+ main: 'index.js',
81
+ scripts: {},
82
+ keywords: [],
83
+ author: '',
84
+ license: 'MIT',
85
+ dependencies: {
86
+ ...(withReact ? {
87
+ 'react': '^19.2.8',
88
+ 'react-dom': '^19.2.8',
89
+ '@codenotch/codenotch.react': BuildUtils_1.default.CN_REACT_VERSION
90
+ } : {}),
91
+ ...extra.dependencies
92
+ },
93
+ devDependencies: {
94
+ ...(withReact ? {
95
+ '@types/react': '^19.2.18',
96
+ '@types/react-dom': '^19.2.4',
97
+ '@vitejs/plugin-react': '^6.0.5'
98
+ } : {}),
99
+ 'typescript': '^5.9.3',
100
+ ...extra.devDependencies
101
+ }
102
+ };
103
+ }
104
+ /**
105
+ * Folders of a new project, relative to its root
106
+ */
107
+ static PROJECT_FOLDERS = ['processes', 'apps', 'documents', 'typings', 'tables'];
108
+ static createGitignore() {
109
+ return [
110
+ 'package-lock.json',
111
+ '/.codenotch',
112
+ '/node_modules',
113
+ '/typings'
114
+ ].join('\n') + '\n';
115
+ }
116
+ /**
117
+ * readme.md of a new project: what the generated files are and how to work with them
118
+ */
119
+ static createReadmeMd(projectName, serviceName) {
120
+ // Markdown code fences cannot be written as-is inside a template literal
121
+ const fence = '```';
122
+ return `# ${projectName}
123
+
124
+ A [Codenotch](https://codenotch.com/) project.
125
+
126
+ Its service name is \`${serviceName}\`: it identifies the project on the runtime and is part of its URL.
127
+ Renaming it later means updating every reference to it, so it is better chosen once.
128
+
129
+ ## Requirements
130
+
131
+ ${fence}sh
132
+ npm install -g codenotch-cli # the 'cn' command
133
+ cn runtime update # install (or update) the local Codenotch runtime
134
+ ${fence}
135
+
136
+ ## Getting started
137
+
138
+ ${fence}sh
139
+ npm install # install the project dependencies
140
+ cn runtime start # start the local runtime
141
+ cn project start # build, deploy and open this project
142
+ ${fence}
143
+
144
+ Then, after each change:
145
+
146
+ ${fence}sh
147
+ cn project refresh # sync the project with the runtime
148
+ ${fence}
149
+
150
+ ## Project structure
151
+
152
+ | Path | Contains |
153
+ | --- | --- |
154
+ | \`manifest.json\` | project name, service name, version, languages and roles |
155
+ | \`package.json\` | npm dependencies, React and \`@codenotch/codenotch.react\` |
156
+ | \`processes/\` | server side processes, one TypeScript file each |
157
+ | \`tables/\` | SQL table definitions |
158
+ | \`documents/\` | NoSQL document schemas |
159
+ | \`apps/\` | React apps: \`<App>.tsx\` and its \`<App>.manifest.json\` |
160
+ | \`*.i18n.csv\` | translations, one column per language |
161
+
162
+ ## Apps
163
+
164
+ An app is a React component using the \`useCodenotch()\` hook to reach the runtime:
165
+
166
+ ${fence}tsx
167
+ import React from 'react';
168
+ import { useCodenotch } from '@codenotch/codenotch.react';
169
+
170
+ const index: React.FC<{}> = () => {
171
+ const cn = useCodenotch();
172
+ return <div>
173
+ <h1>My new Codenotch App</h1>
174
+ </div>
175
+ };
176
+
177
+ export default index;
178
+ ${fence}
179
+
180
+ Each app is described by a \`<App>.manifest.json\` next to it (title, PWA settings, roles).
181
+
182
+ ## Translations
183
+
184
+ A \`*.i18n.csv\` file holds one \`key\` column plus one column per language:
185
+
186
+ ${fence}csv
187
+ key,en,de
188
+ userWelcome,hello,hallo
189
+ hiMr,hello mister {0},hallo herr {0}
190
+ ${fence}
191
+
192
+ \`{0}\`, \`{1}\`, ... are the placeholders of the arguments. Turn the csv into a typed class with:
193
+
194
+ ${fence}sh
195
+ cn generate i18n -f globals.i18n.csv
196
+ ${fence}
197
+
198
+ ## Commands
199
+
200
+ | Command | What it does |
201
+ | --- | --- |
202
+ | \`cn project inspect\` | parse the project and display its structure |
203
+ | \`cn project start\` | build, deploy and start the project locally |
204
+ | \`cn project refresh\` | deploy the changes to the running project |
205
+ | \`cn project test\` | run the tests of the project |
206
+ | \`cn project package\` | compile and package the project as a zip |
207
+ | \`cn project deploy <service> <zip>\` | deploy a package to the runtime |
208
+ | \`cn validate .\` | report hints, warnings and errors of every file |
209
+ | \`cn generate app -n <Name>\` | generate an empty app and its manifest |
210
+ | \`cn generate i18n -f <file>.i18n.csv\` | generate the typed class of a translation file |
211
+ | \`cn runtime info\` | status and version of the local runtime |
212
+
213
+ Run \`cn --help\` (or \`cn <command> --help\`) for the complete list.
214
+ `;
215
+ }
216
+ }
217
+ exports.default = TemplateUtils;
218
+ //# sourceMappingURL=TemplateUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateUtils.js","sourceRoot":"","sources":["../../src/utils/TemplateUtils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import ts from 'typescript';
2
+ /** The subset of JSON Schema (draft 7 / OpenAPI 3.0 flavour) a TypeScript annotation maps to */
3
+ export interface IJsonSchema {
4
+ type?: 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array' | 'null';
5
+ properties?: Record<string, IJsonSchema>;
6
+ required?: string[];
7
+ items?: IJsonSchema;
8
+ enum?: (string | number | boolean)[];
9
+ oneOf?: IJsonSchema[];
10
+ nullable?: boolean;
11
+ additionalProperties?: IJsonSchema | boolean;
12
+ format?: string;
13
+ title?: string;
14
+ description?: string;
15
+ /** Name or text of a TypeScript type that could not be expanded without a type checker */
16
+ 'x-codenotch-type'?: string;
17
+ }
18
+ /**
19
+ * Turns a TypeScript type annotation into a JSON schema, from the syntax alone.
20
+ *
21
+ * Without a type checker, only what is written inline can be expanded: `{ title: string }`
22
+ * becomes an object schema, but a reference such as `Book` stays opaque and is reported as
23
+ * `{ title: 'Book', 'x-codenotch-type': 'Book' }`, which keeps the document valid and tells
24
+ * the reader where to look. Nothing is guessed.
25
+ */
26
+ export default abstract class TypeSchemaUtils {
27
+ static fromTypeNode(node: ts.TypeNode): IJsonSchema;
28
+ private static fromKeyword;
29
+ private static fromLiteral;
30
+ /** `{ title: string; pages?: number }` gives an object schema with 'title' required */
31
+ private static fromMembers;
32
+ private static getMemberName;
33
+ /**
34
+ * `'a' | 'b'` gives an enum, `T | null` a nullable T, anything else a oneOf
35
+ */
36
+ private static fromUnion;
37
+ private static isNullish;
38
+ /**
39
+ * The generic helpers a payload commonly uses are expanded, any other reference stays opaque
40
+ */
41
+ private static fromReference;
42
+ }
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const typescript_1 = __importDefault(require("typescript"));
7
+ /**
8
+ * Turns a TypeScript type annotation into a JSON schema, from the syntax alone.
9
+ *
10
+ * Without a type checker, only what is written inline can be expanded: `{ title: string }`
11
+ * becomes an object schema, but a reference such as `Book` stays opaque and is reported as
12
+ * `{ title: 'Book', 'x-codenotch-type': 'Book' }`, which keeps the document valid and tells
13
+ * the reader where to look. Nothing is guessed.
14
+ */
15
+ class TypeSchemaUtils {
16
+ static fromTypeNode(node) {
17
+ // (T) and readonly T[] add nothing to the schema
18
+ if (typescript_1.default.isParenthesizedTypeNode(node) || typescript_1.default.isTypeOperatorNode(node)) {
19
+ return this.fromTypeNode(node.type);
20
+ }
21
+ if (typescript_1.default.isLiteralTypeNode(node)) {
22
+ return this.fromLiteral(node);
23
+ }
24
+ if (typescript_1.default.isArrayTypeNode(node)) {
25
+ return { type: 'array', items: this.fromTypeNode(node.elementType) };
26
+ }
27
+ if (typescript_1.default.isTupleTypeNode(node)) {
28
+ return { type: 'array', 'x-codenotch-type': node.getText() };
29
+ }
30
+ if (typescript_1.default.isTypeLiteralNode(node)) {
31
+ return this.fromMembers(node.members);
32
+ }
33
+ if (typescript_1.default.isUnionTypeNode(node)) {
34
+ return this.fromUnion(node);
35
+ }
36
+ if (typescript_1.default.isTypeReferenceNode(node)) {
37
+ return this.fromReference(node);
38
+ }
39
+ const keyword = this.fromKeyword(node.kind);
40
+ if (keyword !== undefined) {
41
+ return keyword;
42
+ }
43
+ // Conditional, mapped, indexed access, typeof... only a checker could resolve them
44
+ return { 'x-codenotch-type': node.getText() };
45
+ }
46
+ static fromKeyword(kind) {
47
+ switch (kind) {
48
+ case typescript_1.default.SyntaxKind.StringKeyword: return { type: 'string' };
49
+ case typescript_1.default.SyntaxKind.NumberKeyword: return { type: 'number' };
50
+ case typescript_1.default.SyntaxKind.BigIntKeyword: return { type: 'integer' };
51
+ case typescript_1.default.SyntaxKind.BooleanKeyword: return { type: 'boolean' };
52
+ case typescript_1.default.SyntaxKind.ObjectKeyword: return { type: 'object' };
53
+ case typescript_1.default.SyntaxKind.AnyKeyword:
54
+ case typescript_1.default.SyntaxKind.UnknownKeyword: return {};
55
+ case typescript_1.default.SyntaxKind.VoidKeyword:
56
+ case typescript_1.default.SyntaxKind.UndefinedKeyword:
57
+ case typescript_1.default.SyntaxKind.NeverKeyword: return { 'x-codenotch-type': 'void' };
58
+ default: return undefined;
59
+ }
60
+ }
61
+ static fromLiteral(node) {
62
+ const literal = node.literal;
63
+ if (typescript_1.default.isStringLiteral(literal) || typescript_1.default.isNoSubstitutionTemplateLiteral(literal)) {
64
+ return { type: 'string', enum: [literal.text] };
65
+ }
66
+ if (typescript_1.default.isNumericLiteral(literal)) {
67
+ return { type: 'number', enum: [Number(literal.text)] };
68
+ }
69
+ if (typescript_1.default.isPrefixUnaryExpression(literal) && typescript_1.default.isNumericLiteral(literal.operand)) {
70
+ return { type: 'number', enum: [-Number(literal.operand.text)] };
71
+ }
72
+ if (literal.kind === typescript_1.default.SyntaxKind.TrueKeyword || literal.kind === typescript_1.default.SyntaxKind.FalseKeyword) {
73
+ return { type: 'boolean', enum: [literal.kind === typescript_1.default.SyntaxKind.TrueKeyword] };
74
+ }
75
+ if (literal.kind === typescript_1.default.SyntaxKind.NullKeyword) {
76
+ return { type: 'null' };
77
+ }
78
+ return { 'x-codenotch-type': node.getText() };
79
+ }
80
+ /** `{ title: string; pages?: number }` gives an object schema with 'title' required */
81
+ static fromMembers(members) {
82
+ const schema = { type: 'object', properties: {} };
83
+ const required = [];
84
+ for (const member of members) {
85
+ if (typescript_1.default.isIndexSignatureDeclaration(member)) {
86
+ // { [key: string]: T } accepts any property of type T
87
+ schema.additionalProperties = member.type === undefined ? true : this.fromTypeNode(member.type);
88
+ continue;
89
+ }
90
+ if (!typescript_1.default.isPropertySignature(member) || member.type === undefined) {
91
+ continue; // methods and call signatures do not travel in a payload
92
+ }
93
+ const name = this.getMemberName(member.name);
94
+ if (name === undefined) {
95
+ continue;
96
+ }
97
+ schema.properties[name] = this.fromTypeNode(member.type);
98
+ if (member.questionToken === undefined) {
99
+ required.push(name);
100
+ }
101
+ }
102
+ if (required.length > 0) {
103
+ schema.required = required;
104
+ }
105
+ return schema;
106
+ }
107
+ static getMemberName(name) {
108
+ if (typescript_1.default.isIdentifier(name) || typescript_1.default.isStringLiteral(name) || typescript_1.default.isNumericLiteral(name)) {
109
+ return name.text;
110
+ }
111
+ return undefined;
112
+ }
113
+ /**
114
+ * `'a' | 'b'` gives an enum, `T | null` a nullable T, anything else a oneOf
115
+ */
116
+ static fromUnion(node) {
117
+ const nullable = node.types.some(type => this.isNullish(type));
118
+ const members = node.types.filter(type => !this.isNullish(type)).map(type => this.fromTypeNode(type));
119
+ let schema;
120
+ if (members.length === 0) {
121
+ schema = { type: 'null' };
122
+ }
123
+ else if (members.length === 1) {
124
+ schema = members[0];
125
+ }
126
+ else if (members.every(member => member.enum !== undefined && member.type === members[0].type)) {
127
+ // A union of literals of the same kind is an enumeration
128
+ schema = { type: members[0].type, enum: members.flatMap(member => member.enum) };
129
+ }
130
+ else {
131
+ schema = { oneOf: members };
132
+ }
133
+ return nullable && schema.type !== 'null' ? { ...schema, nullable: true } : schema;
134
+ }
135
+ static isNullish(node) {
136
+ return node.kind === typescript_1.default.SyntaxKind.UndefinedKeyword
137
+ || (typescript_1.default.isLiteralTypeNode(node) && node.literal.kind === typescript_1.default.SyntaxKind.NullKeyword);
138
+ }
139
+ /**
140
+ * The generic helpers a payload commonly uses are expanded, any other reference stays opaque
141
+ */
142
+ static fromReference(node) {
143
+ const name = typescript_1.default.isIdentifier(node.typeName) ? node.typeName.text : node.typeName.getText();
144
+ const [first, second] = node.typeArguments ?? [];
145
+ switch (name) {
146
+ case 'Promise':
147
+ case 'Readonly':
148
+ case 'Required':
149
+ case 'Awaited':
150
+ // Promise<T> resolves to T, the others only affect the TypeScript side
151
+ return first === undefined ? {} : this.fromTypeNode(first);
152
+ case 'Partial': {
153
+ // Every property becomes optional
154
+ const { required, ...inner } = first === undefined ? {} : this.fromTypeNode(first);
155
+ return inner;
156
+ }
157
+ case 'Array':
158
+ case 'ReadonlyArray':
159
+ return { type: 'array', items: first === undefined ? {} : this.fromTypeNode(first) };
160
+ case 'Record':
161
+ return { type: 'object', additionalProperties: second === undefined ? true : this.fromTypeNode(second) };
162
+ case 'Date':
163
+ return { type: 'string', format: 'date-time' };
164
+ default:
165
+ // 'Book' or 'Loan[]' cannot be expanded here, the name is enough to find it in the project
166
+ return { title: name, 'x-codenotch-type': node.getText() };
167
+ }
168
+ }
169
+ }
170
+ exports.default = TypeSchemaUtils;
171
+ //# sourceMappingURL=TypeSchemaUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TypeSchemaUtils.js","sourceRoot":"","sources":["../../src/utils/TypeSchemaUtils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codenotch/codenotch.cli",
3
- "version": "1.0.36",
3
+ "version": "1.0.38",
4
4
  "description": "A CLI tool for code management",
5
5
  "main": "dist/index.js",
6
6
  "files": [
@@ -38,7 +38,7 @@
38
38
  "access": "public"
39
39
  },
40
40
  "dependencies": {
41
- "@codenotch/codenotch.core": "1.0.23",
41
+ "@codenotch/codenotch.core": "1.0.25",
42
42
  "@octokit/auth-oauth-device": "^8.0.3",
43
43
  "@types/express": "^5.0.6",
44
44
  "adm-zip": "^0.5.17",
@@ -47,6 +47,7 @@
47
47
  "cross-keychain": "^1.1.0",
48
48
  "decompress": "^4.2.1",
49
49
  "dotenv": "^17.4.2",
50
+ "ignore": "^7.0.6",
50
51
  "express": "^5.2.1",
51
52
  "fs-extra": "^10.0.0",
52
53
  "js2xmlparser": "^5.0.0",