@naiv/flazy-api 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2024 ADF Language. https://adf-lang.com
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,202 @@
1
+ ### How to test
2
+
3
+ 0. Build project (on this project)
4
+ ```bash
5
+ npm run build
6
+ ```
7
+
8
+ build action will create `codegen-nodejs-typeorm` binary and accessible from terminal.
9
+
10
+ 1. Create testing folder
11
+ ```bash
12
+ mkdir naiv-test-server
13
+ cd naiv-test-server
14
+ ```
15
+
16
+ 2. Init Typescript Project
17
+ ```bash
18
+ npm init -y
19
+ npm install --save-dev typescript
20
+ ```
21
+
22
+ 3. Modify `package.json` script
23
+
24
+ ```json
25
+ "scripts": {
26
+ "typeorm": "typeorm-ts-node-commonjs",
27
+ "generate-migration": "npm run typeorm migration:generate -- $1 -d ./data-source.ts",
28
+ "migrate": "npm run typeorm migration:run -- -d ./data-source.ts",
29
+ "codegen": "codegen-nodejs-typeorm -d design -o types",
30
+ "codegen-init": "npx ts-node ./generate-initial-api.ts",
31
+ "build": "rm -rf dist && tsc",
32
+ "start": "node dist",
33
+ "dev": "npm run build && npm start"
34
+ },
35
+ ```
36
+
37
+ 4. Create TS-Config file
38
+ ```json
39
+ {
40
+ // Visit https://aka.ms/tsconfig to read more about this file
41
+ "compilerOptions": {
42
+
43
+ // Environment Settings
44
+ // See also https://aka.ms/tsconfig/module
45
+ "module": "nodenext",
46
+ "target": "esnext",
47
+ "types": ["node"],
48
+
49
+ // Stricter Typechecking Options
50
+ "noUncheckedIndexedAccess": true,
51
+ "exactOptionalPropertyTypes": true,
52
+
53
+ // Recommended Options
54
+ "strict": true,
55
+ "jsx": "react-jsx",
56
+ "verbatimModuleSyntax": false,
57
+ "isolatedModules": true,
58
+ "noUncheckedSideEffectImports": true,
59
+ "moduleDetection": "force",
60
+ "skipLibCheck": true,
61
+ "experimentalDecorators": true,
62
+ "emitDecoratorMetadata": true,
63
+ "outDir": "dist"
64
+ }
65
+ }
66
+ ```
67
+
68
+ 5. Install dependency
69
+ ```bash
70
+ npm install --save express cors class-validator class-transformer
71
+ npm install --save-dev @types/express @types/cors
72
+ ```
73
+
74
+ 6. Create `generate-initial-api.ts`
75
+
76
+ ```typescript
77
+ import * as fs from 'fs';
78
+ import * as path from 'path';
79
+
80
+ function getAllTsFiles(dir: string): string[] {
81
+ const files = fs.readdirSync(dir, { withFileTypes: true });
82
+ const tsFiles: string[] = [];
83
+
84
+ for (const file of files) {
85
+ if (file.isFile() && file.name.endsWith('.ts')) {
86
+ tsFiles.push(file.name);
87
+ const filePath = path.resolve(`./implementation/${file.name}`);
88
+ if (fs.existsSync(filePath)) {
89
+ console.log(`✅ File already exists: ${filePath}`);
90
+ } else {
91
+ const [fn] = file.name.split('.');
92
+ const prefix = fn?.slice(0, 2);
93
+ const only_name = fn?.slice(2);
94
+ const is_streaming = prefix == 'S_';
95
+ fs.writeFileSync(filePath, `\
96
+ import { ${prefix}${only_name} } from "../types/api/${prefix}${only_name}";
97
+
98
+ export const ${prefix?.toLowerCase()}${only_name}: ${prefix}${only_name} = async ${is_streaming ? '(req, stream, res)' : '(req, res)'} => {
99
+ throw new Error('Implement this');
100
+ }
101
+ `, 'utf8');
102
+ console.log(`📝 File created: ${filePath}`);
103
+ }
104
+ }
105
+ }
106
+
107
+ return tsFiles;
108
+ }
109
+
110
+ console.log(getAllTsFiles('./types/api'));
111
+ ```
112
+
113
+ 7. Create simple api design `design/api.naiv`
114
+ ```
115
+ schema Z {
116
+ data string required
117
+ }
118
+
119
+ api get /test-streaming {
120
+ alias testX
121
+ query {
122
+ q string
123
+ }
124
+ return stream of string required
125
+ }
126
+
127
+ api get /common-api {
128
+ alias getY
129
+ query {
130
+ limit number
131
+ offset number
132
+ }
133
+ return array string required
134
+ }
135
+ ```
136
+
137
+ 8. Generate code
138
+ ```bash
139
+ npm run codegen
140
+ ```
141
+
142
+ 9. Generate code-stub
143
+ ```bash
144
+ npm run codegen-init
145
+ ```
146
+
147
+ 10. Copy `server.ts` from this project to `naiv-test-server` project
148
+
149
+ 11. Create `index.ts`
150
+ ```typescript
151
+ import path from 'path';
152
+ import { Server } from './server';
153
+
154
+ const server = new Server();
155
+ server.run({
156
+ port: +(process.env.PORT ?? 9415),
157
+ types_path: path.resolve(__dirname, 'types'),
158
+ implementation_path: path.resolve(__dirname, 'implementation'),
159
+ async beforeStart() {
160
+ console.log('before start script.')
161
+ }
162
+ });
163
+ ```
164
+
165
+ 12. Implement logic
166
+ ```typescript
167
+ import { S_testX } from "../types/api/S_testX";
168
+
169
+ export const s_testX: S_testX = async (req, stream, res) => {
170
+ stream(req.query.q ?? 'no query');
171
+ stream('\n');
172
+ stream('aaa\n');
173
+ await new Promise(resolve => setTimeout(resolve, 1000));
174
+ stream('ccc\n');
175
+ await new Promise(resolve => setTimeout(resolve, 1000));
176
+ stream('bbb\n');
177
+ await new Promise(resolve => setTimeout(resolve, 1000));
178
+ stream('eee\n');
179
+ await new Promise(resolve => setTimeout(resolve, 1000));
180
+ stream('ddd\n');
181
+ await new Promise(resolve => setTimeout(resolve, 1000));
182
+ stream('fff\n');
183
+ await new Promise(resolve => setTimeout(resolve, 1000));
184
+ }
185
+ ```
186
+
187
+ ```typescript
188
+ import { T_getY } from "../types/api/T_getY";
189
+
190
+ export const t_getY: T_getY = async (req, res) => {
191
+ return ['nice'];
192
+ }
193
+ ```
194
+
195
+ 13. `curl` testing
196
+ ```bash
197
+ curl localhost:9415/test-streaming?q=lorem-ipsum -N
198
+ ```
199
+
200
+ ```bash
201
+ curl localhost:9415/common-api
202
+ ```
@@ -0,0 +1,5 @@
1
+ import { NVAPI } from "@naiv/core/build/semantic-checker/check_api";
2
+ import { ItemOutput } from "./data-types";
3
+ import { NVSchema } from "@naiv/core/build/semantic-checker/check_schema";
4
+ export declare function getAPIFileName(api_alias: string, api: NVAPI, extension?: string): string;
5
+ export declare function buildFromAPI(api: NVAPI, list_schema: NVSchema[]): ItemOutput;
@@ -0,0 +1,110 @@
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.getAPIFileName = getAPIFileName;
7
+ exports.buildFromAPI = buildFromAPI;
8
+ const build_from_schema_1 = require("./build-from-schema");
9
+ const lodash_1 = __importDefault(require("lodash"));
10
+ function getAPIFileName(api_alias, api, extension) {
11
+ const is_streaming = api.data.return_type.kind === 'stream';
12
+ return `./api/${is_streaming ? 'S_' : 'T_'}${api_alias}${extension !== null && extension !== void 0 ? extension : ''}`;
13
+ }
14
+ function buildFromAPI(api, list_schema) {
15
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
16
+ const is_streaming = api.data.return_type.kind === 'stream';
17
+ const prefix = is_streaming ? 'S_' : 'T_';
18
+ if (!api.data.alias) {
19
+ throw new Error(`no api alias`);
20
+ }
21
+ let header_schema;
22
+ if (((_b = (_a = api.data.headers) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0) {
23
+ const s = {
24
+ name: `${prefix}${api.data.alias}_headers`,
25
+ items: (_c = api.data.headers) !== null && _c !== void 0 ? _c : []
26
+ };
27
+ header_schema = (0, build_from_schema_1.getSchemaContent)(s, list_schema);
28
+ }
29
+ let query_schema;
30
+ if (((_e = (_d = api.data.query) === null || _d === void 0 ? void 0 : _d.length) !== null && _e !== void 0 ? _e : 0) > 0) {
31
+ const s = {
32
+ name: `${prefix}${api.data.alias}_query`,
33
+ items: (_f = api.data.query) !== null && _f !== void 0 ? _f : []
34
+ };
35
+ query_schema = (0, build_from_schema_1.getSchemaContent)(s, list_schema);
36
+ }
37
+ let path_schema;
38
+ if (((_h = (_g = api.data.path) === null || _g === void 0 ? void 0 : _g.length) !== null && _h !== void 0 ? _h : 0) > 0) {
39
+ const s = {
40
+ name: `${prefix}${api.data.alias}_path`,
41
+ items: (_j = api.data.path) !== null && _j !== void 0 ? _j : []
42
+ };
43
+ path_schema = (0, build_from_schema_1.getSchemaContent)(s, list_schema);
44
+ }
45
+ let body_schema;
46
+ if (((_l = (_k = api.data.body) === null || _k === void 0 ? void 0 : _k.length) !== null && _l !== void 0 ? _l : 0) > 0) {
47
+ const s = {
48
+ name: `${prefix}${api.data.alias}_body`,
49
+ items: (_m = api.data.body) !== null && _m !== void 0 ? _m : []
50
+ };
51
+ body_schema = (0, build_from_schema_1.getSchemaContent)(s, list_schema);
52
+ }
53
+ const fake_return_type_schema = {
54
+ name: 'ReturnType',
55
+ items: [{
56
+ key: 'rrr',
57
+ type: api.data.return_type.type
58
+ }]
59
+ };
60
+ const fake_return_type_schema_result = (0, build_from_schema_1.getSchemaContent)(fake_return_type_schema, list_schema);
61
+ const fake_return_type = {
62
+ key: 'rrr',
63
+ type: api.data.return_type.type
64
+ };
65
+ const fake_return_type_field_result = (0, build_from_schema_1.buildField)(fake_return_type, 0, { name: 'ReturnType', items: [] }, list_schema);
66
+ return {
67
+ files: [{
68
+ filename: getAPIFileName(api.data.alias, api, '.ts'),
69
+ content: [
70
+ 'import { Response } from "express";',
71
+ `${lodash_1.default.uniq([
72
+ ...((_o = header_schema === null || header_schema === void 0 ? void 0 : header_schema.deps) !== null && _o !== void 0 ? _o : []),
73
+ ...((_p = query_schema === null || query_schema === void 0 ? void 0 : query_schema.deps) !== null && _p !== void 0 ? _p : []),
74
+ ...((_q = path_schema === null || path_schema === void 0 ? void 0 : path_schema.deps) !== null && _q !== void 0 ? _q : []),
75
+ ...((_r = body_schema === null || body_schema === void 0 ? void 0 : body_schema.deps) !== null && _r !== void 0 ? _r : []),
76
+ ...((_s = fake_return_type_schema_result.deps) !== null && _s !== void 0 ? _s : []),
77
+ ...((_t = fake_return_type_field_result.new_deps_lines) !== null && _t !== void 0 ? _t : []),
78
+ ].join('\n').split('\n')).join('\n')}
79
+
80
+ ${[
81
+ ...((_u = header_schema === null || header_schema === void 0 ? void 0 : header_schema.content) !== null && _u !== void 0 ? _u : []),
82
+ ...((_v = query_schema === null || query_schema === void 0 ? void 0 : query_schema.content) !== null && _v !== void 0 ? _v : []),
83
+ ...((_w = path_schema === null || path_schema === void 0 ? void 0 : path_schema.content) !== null && _w !== void 0 ? _w : []),
84
+ ...((_x = body_schema === null || body_schema === void 0 ? void 0 : body_schema.content) !== null && _x !== void 0 ? _x : []),
85
+ ...fake_return_type_field_result.new_class_lines,
86
+ ].join('\n')}
87
+
88
+ export type ${prefix}${api.data.alias} = (request: {
89
+ ${[
90
+ ((_y = header_schema === null || header_schema === void 0 ? void 0 : header_schema.content.length) !== null && _y !== void 0 ? _y : 0) > 0 ? ` headers: ${prefix}${api.data.alias}_headers` : '',
91
+ ((_z = query_schema === null || query_schema === void 0 ? void 0 : query_schema.content.length) !== null && _z !== void 0 ? _z : 0) > 0 ? ` query: ${prefix}${api.data.alias}_query` : '',
92
+ ((_0 = path_schema === null || path_schema === void 0 ? void 0 : path_schema.content.length) !== null && _0 !== void 0 ? _0 : 0) > 0 ? ` path: ${prefix}${api.data.alias}_path` : '',
93
+ ((_1 = body_schema === null || body_schema === void 0 ? void 0 : body_schema.content.length) !== null && _1 !== void 0 ? _1 : 0) > 0 ? ` body: ${prefix}${api.data.alias}_body` : '',
94
+ ].filter(Boolean).join('\n')}
95
+ ${is_streaming
96
+ ? `}, stream: (chunk: ${fake_return_type_field_result.type_only}${api.data.return_type.type.required ? '' : ' | null'}) => void, response: Response) => Promise<void>;`
97
+ : `}, response: Response) => Promise<${fake_return_type_field_result.type_only}${api.data.return_type.type.required ? '' : ' | null'}>;`}
98
+
99
+ export const method = '${api.method.toLowerCase()}';
100
+ export const url_path = '${api.url_path}';
101
+ export const alias = '${prefix}${api.data.alias}';
102
+ export const is_streaming = ${is_streaming ? 'true' : 'false'};
103
+ `
104
+ ].join('\n')
105
+ }],
106
+ map: {
107
+ [api.data.alias]: getAPIFileName(api.data.alias, api)
108
+ }
109
+ };
110
+ }
@@ -0,0 +1,4 @@
1
+ import { NVEnum } from "@naiv/core";
2
+ import { ItemOutput } from "./data-types";
3
+ export declare function getEnumFileName(item: NVEnum, extension?: string): string;
4
+ export declare function buildFromEnum(enume: NVEnum): ItemOutput;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getEnumFileName = getEnumFileName;
4
+ exports.buildFromEnum = buildFromEnum;
5
+ function getEnumFileName(item, extension) {
6
+ return `./model/enum/${item.name}${extension !== null && extension !== void 0 ? extension : ''}`;
7
+ }
8
+ function buildFromEnum(enume) {
9
+ return {
10
+ files: [{
11
+ filename: getEnumFileName(enume, '.ts'),
12
+ content: [
13
+ `export enum ${enume.name} {`,
14
+ ...enume.items
15
+ .map(s => `'${s}' = '${s}',`)
16
+ .map(line => ' ' + line),
17
+ `};`
18
+ ].join('\n')
19
+ }],
20
+ map: {
21
+ [enume.name]: getEnumFileName(enume)
22
+ }
23
+ };
24
+ }
@@ -0,0 +1,24 @@
1
+ import { NVSchema } from "@naiv/core/build/semantic-checker/check_schema";
2
+ import { ItemOutput } from "./data-types";
3
+ import { NVSchemaItem } from "@naiv/core/build/semantic-checker/check_schema_item";
4
+ export declare function getSchemaFileName(schema: NVSchema, extension?: string): string;
5
+ export declare function buildSchemaDependency(schema: NVSchema, list_schema: NVSchema[]): string[];
6
+ export declare function buildFromSchema(schema: NVSchema, list_schema: NVSchema[]): ItemOutput;
7
+ export interface SchemaContentResult {
8
+ deps: string[];
9
+ content: string[];
10
+ }
11
+ export declare function getSchemaContent(schema: NVSchema, list_schema: NVSchema[], no_export?: boolean): SchemaContentResult;
12
+ export declare function getDecorators(item: NVSchemaItem): string[];
13
+ export interface BuildFieldResult {
14
+ field_lines: string[];
15
+ type_only: string;
16
+ new_class_lines: string[];
17
+ new_deps_lines: string[];
18
+ }
19
+ export declare function buildField(item: NVSchemaItem, index: number, schema: NVSchema, list_schema: NVSchema[]): BuildFieldResult;
20
+ export declare function buildInlineSchemaClass(items: NVSchemaItem[], parent_schema_name: string, index: number, list_schema: NVSchema[]): {
21
+ new_class_deps: string[];
22
+ new_class_content: string[];
23
+ inline_schema_name: string;
24
+ };
@@ -0,0 +1,207 @@
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.getSchemaFileName = getSchemaFileName;
7
+ exports.buildSchemaDependency = buildSchemaDependency;
8
+ exports.buildFromSchema = buildFromSchema;
9
+ exports.getSchemaContent = getSchemaContent;
10
+ exports.getDecorators = getDecorators;
11
+ exports.buildField = buildField;
12
+ exports.buildInlineSchemaClass = buildInlineSchemaClass;
13
+ const lodash_1 = __importDefault(require("lodash"));
14
+ function getSchemaFileName(schema, extension) {
15
+ return `./schema/${schema.name}${extension !== null && extension !== void 0 ? extension : ''}`;
16
+ }
17
+ function buildSchemaDependency(schema, list_schema) {
18
+ return schema.items
19
+ .filter((item) => item.type.type === 'schema' || item.type.type === 'table' || item.type.type === 'enum')
20
+ .map((item) => {
21
+ switch (item.type.type) {
22
+ case 'schema':
23
+ const schema_item = list_schema.find((s) => item.type.type === 'schema' && s.name === item.type.subtype_native);
24
+ if (!schema_item) {
25
+ throw new Error(`Schema "${item.type.subtype_native}" is not available`);
26
+ }
27
+ return `import { ${schema_item.name} } from '.${getSchemaFileName(schema_item)}'`;
28
+ case 'table':
29
+ return `import { ${item.type.subtype_native} } from '../model/table/${item.type.subtype_native}'`;
30
+ case 'enum':
31
+ return `import { ${item.type.subtype_native} } from '../model/enum/${item.type.subtype_native}'`;
32
+ default:
33
+ return '';
34
+ }
35
+ });
36
+ }
37
+ function buildFromSchema(schema, list_schema) {
38
+ const { deps, content } = getSchemaContent(schema, list_schema);
39
+ return {
40
+ files: [{
41
+ filename: getSchemaFileName(schema, '.ts'),
42
+ content: [
43
+ ...deps,
44
+ '',
45
+ ...content,
46
+ ].join('\n')
47
+ }],
48
+ map: {
49
+ [schema.name]: getSchemaFileName(schema)
50
+ }
51
+ };
52
+ }
53
+ function getSchemaContent(schema, list_schema, no_export) {
54
+ const field_lines = [];
55
+ const new_class_lines = [];
56
+ const new_deps_lines = [];
57
+ let i = 0;
58
+ for (const c of schema.items) {
59
+ const field_result = buildField(c, i, schema, list_schema);
60
+ field_lines.push(...field_result.field_lines);
61
+ new_class_lines.push(...field_result.new_class_lines);
62
+ new_deps_lines.push(...field_result.new_deps_lines);
63
+ i++;
64
+ }
65
+ const complete_deps = lodash_1.default.uniq([
66
+ `import { ClassConstructor, Transform, Type, plainToInstance } from "class-transformer";`,
67
+ `import { IsNotEmpty, IsNumber, IsObject, IsBoolean, IsOptional, IsISO8601, IsString, IsEnum, ValidateNested, IsArray, ValidationError, validateOrReject } from "class-validator";`,
68
+ ...buildSchemaDependency(schema, list_schema),
69
+ ...new_deps_lines
70
+ ].join('\n').split('\n'));
71
+ return {
72
+ deps: complete_deps,
73
+ content: [
74
+ ...new_class_lines,
75
+ `${no_export ? '' : 'export '}class ${schema.name} {`,
76
+ ...field_lines.map(line => ' ' + line),
77
+ `}`
78
+ ]
79
+ };
80
+ }
81
+ const transform_integer = `(param?: any): number | null => (param?.value === null || param?.value === undefined || param?.value === '') ? null : parseInt(param.value)`;
82
+ const transform_arrayinteger = `(param?: any): (number | null)[] | null => !Array.isArray(param?.value) ? null : param?.value.map((value: any) => (value === null || value === undefined || value === '') ? null : parseInt(value))`;
83
+ const transform_decimal = `(param?: any): number | null => (param?.value === null || param?.value === undefined || param?.value === '') ? null : parseFloat(param.value)`;
84
+ const transform_arraydecimal = `(param?: any): (number | null)[] | null => !Array.isArray(param?.value) ? null : param?.value.map((value: any) => (value === null || value === undefined || value === '') ? null : parseFloat(value))`;
85
+ const transform_boolean = `(param?: any): boolean | null => (param?.value === null || param?.value === undefined || param?.value === '') ? null : (param?.value === 'true' || ((typeof param?.value === 'boolean') && param?.value))`;
86
+ const transform_arrayboolean = `(param?: any): (boolean | null)[] | null => !Array.isArray(param?.value) ? null : param?.value.map((value: any) => (value === null || value === undefined || value === '') ? null : (value === 'true' || ((typeof value === 'boolean') && value)))`;
87
+ const transform_date = `(param?: any): Date | null => (param?.value === null || param?.value === undefined || param?.value === '') ? null : new Date(param?.value)`;
88
+ const transform_arraydate = `(param?: any): (Date | null)[] | null => !Array.isArray(param?.value) ? null : param?.value.map((value: any) => (value === null || value === undefined || value === '') ? null : new Date(value))`;
89
+ function getDecorators(item) {
90
+ const list_decorator = [];
91
+ if (item.type.required) {
92
+ list_decorator.push(`@IsNotEmpty({ message: '${item.key} cannot be empty' })`);
93
+ }
94
+ else {
95
+ list_decorator.push(`@IsOptional()`);
96
+ }
97
+ const is_array = item.type.array_dimension > 0;
98
+ if (item.type.type === 'native') {
99
+ const array_property = is_array ? ', each: true' : '';
100
+ switch (item.type.type_native) {
101
+ case 'number':
102
+ list_decorator.push(`@Transform(${is_array ? transform_arraydecimal : transform_decimal})`);
103
+ list_decorator.push(`@IsNumber({}, { message: '${item.key} must be a number (decimal)'${array_property} })`);
104
+ break;
105
+ case 'boolean':
106
+ list_decorator.push(`@Transform(${is_array ? transform_arrayboolean : transform_boolean})`);
107
+ list_decorator.push(`@IsBoolean({ message: '${item.key} must be a boolean'${array_property} })`);
108
+ break;
109
+ case 'string':
110
+ list_decorator.push(`@IsString({ message: '${item.key} must be a string'${array_property} })`);
111
+ break;
112
+ }
113
+ }
114
+ if (item.type.type === 'enum') {
115
+ const array_property = is_array ? ', each: true' : '';
116
+ list_decorator.push(`@IsEnum(${item.type.subtype_native}, { message: '${item.key} must be enum ${item.type.subtype_native}'${array_property} })`);
117
+ }
118
+ if (item.type.type === 'schema') {
119
+ if (is_array) {
120
+ list_decorator.push(`@IsArray()`);
121
+ list_decorator.push(`@ValidateNested({ each: true })`);
122
+ }
123
+ else {
124
+ list_decorator.push(`@IsObject()`);
125
+ list_decorator.push(`@ValidateNested()`);
126
+ }
127
+ list_decorator.push(`@Type(() => ${item.type.subtype_native})`);
128
+ }
129
+ if (item.type.type === 'table') {
130
+ if (is_array) {
131
+ list_decorator.push(`@IsArray()`);
132
+ list_decorator.push(`@ValidateNested({ each: true })`);
133
+ }
134
+ else {
135
+ list_decorator.push(`@IsObject()`);
136
+ list_decorator.push(`@ValidateNested()`);
137
+ }
138
+ list_decorator.push(`@Type(() => ${item.type.subtype_native})`);
139
+ }
140
+ return list_decorator;
141
+ }
142
+ function buildField(item, index, schema, list_schema) {
143
+ var _a;
144
+ const is_array = item.type.array_dimension > 0;
145
+ const array_token = Array(item.type.array_dimension).fill('[]').join('');
146
+ switch (item.type.type) {
147
+ case "native":
148
+ return {
149
+ field_lines: [
150
+ ...getDecorators(item),
151
+ `${item.key}${item.type.required ? '!' : '?'}: ${item.type.type_native}${is_array ? array_token : ''}`
152
+ ],
153
+ type_only: `${item.type.type_native}${is_array ? array_token : ''}`,
154
+ new_class_lines: [],
155
+ new_deps_lines: []
156
+ };
157
+ case "schema":
158
+ return {
159
+ field_lines: [
160
+ ...getDecorators(item),
161
+ `${item.key}${item.type.required ? '!' : '?'}: ${item.type.subtype_native}${is_array ? array_token : ''}`
162
+ ],
163
+ type_only: `${item.type.subtype_native}${is_array ? array_token : ''}`,
164
+ new_class_lines: [],
165
+ new_deps_lines: []
166
+ };
167
+ case "table":
168
+ return {
169
+ field_lines: [
170
+ ...getDecorators(item),
171
+ `${item.key}${item.type.required ? '!' : '?'}: ${item.type.subtype_native}${is_array ? array_token : ''}`
172
+ ],
173
+ type_only: `${item.type.subtype_native}${is_array ? array_token : ''}`,
174
+ new_class_lines: [],
175
+ new_deps_lines: []
176
+ };
177
+ case "enum":
178
+ return {
179
+ field_lines: [
180
+ ...getDecorators(item),
181
+ `${item.key}${item.type.required ? '!' : '?'}: ${item.type.subtype_native}${is_array ? array_token : ''}`
182
+ ],
183
+ type_only: `${item.type.subtype_native}${is_array ? array_token : ''}`,
184
+ new_class_lines: [],
185
+ new_deps_lines: []
186
+ };
187
+ case "inline-schema":
188
+ const { new_class_deps, new_class_content, inline_schema_name } = buildInlineSchemaClass(((_a = item.type.type_inline_schema) !== null && _a !== void 0 ? _a : []), schema.name, index, list_schema);
189
+ return {
190
+ field_lines: [
191
+ ...getDecorators(Object.assign(Object.assign({}, item), { type: Object.assign(Object.assign({}, item.type), { subtype_native: inline_schema_name, type: 'schema' }) })),
192
+ `${item.key}${item.type.required ? '!' : '?'}: ${inline_schema_name}${is_array ? array_token : ''}`
193
+ ],
194
+ type_only: `${inline_schema_name}${is_array ? array_token : ''}`,
195
+ new_class_lines: new_class_content,
196
+ new_deps_lines: new_class_deps
197
+ };
198
+ }
199
+ }
200
+ function buildInlineSchemaClass(items, parent_schema_name, index, list_schema) {
201
+ const inline_schema = {
202
+ name: [parent_schema_name, index].join('_'),
203
+ items
204
+ };
205
+ const new_class = getSchemaContent(inline_schema, list_schema, true);
206
+ return { new_class_deps: new_class.deps, new_class_content: new_class.content, inline_schema_name: inline_schema.name };
207
+ }
@@ -0,0 +1,10 @@
1
+ import { NVResult, NVTable, NVTableField, NVTableFieldType } from "@naiv/core";
2
+ import { ItemOutput } from "./data-types";
3
+ export declare function getTableFileName(item: NVTable, extension?: string): string;
4
+ export declare function buildTableDependency(table: NVTable, source: NVResult): string[];
5
+ export declare function mapSQLTypeToJSType(type: NVTableFieldType): string;
6
+ export declare function buildColumnNative(type: NVTableFieldType, column: NVTableField, source: NVResult): string[];
7
+ export declare function buildColumnEnum(type: NVTableFieldType, column: NVTableField): string[];
8
+ export declare function buildColumnRelation(type: NVTableFieldType, column: NVTableField, table: NVTable, source: NVResult): string[];
9
+ export declare function buildColumn(column: NVTableField, table: NVTable, source: NVResult): string[];
10
+ export declare function buildFromTable(table: NVTable, source: NVResult): ItemOutput;