@opra/cli 1.0.0-alpha.11 → 1.0.0-alpha.13
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/cjs/ts-generator/generators/clean-directory.js +35 -0
- package/cjs/ts-generator/generators/generate-data-type.js +258 -0
- package/cjs/ts-generator/generators/generate-document.js +60 -0
- package/cjs/ts-generator/generators/generate-http-api.js +45 -0
- package/cjs/ts-generator/generators/generate-http-controller.js +228 -0
- package/cjs/ts-generator/processors/process-data-types.js +116 -120
- package/cjs/ts-generator/processors/process-http-controller.js +38 -25
- package/cjs/ts-generator/ts-generator.js +16 -16
- package/esm/ts-generator/generators/clean-directory.js +30 -0
- package/esm/ts-generator/generators/generate-data-type.js +247 -0
- package/esm/ts-generator/generators/generate-document.js +55 -0
- package/esm/ts-generator/generators/generate-http-api.js +40 -0
- package/esm/ts-generator/generators/generate-http-controller.js +223 -0
- package/esm/ts-generator/processors/process-data-types.js +113 -117
- package/esm/ts-generator/processors/process-http-controller.js +38 -25
- package/esm/ts-generator/ts-generator.js +16 -16
- package/package.json +4 -3
- package/types/ts-generator/generators/clean-directory.d.ts +2 -0
- package/types/ts-generator/generators/generate-data-type.d.ts +41 -0
- package/types/ts-generator/generators/generate-document.d.ts +8 -0
- package/types/ts-generator/generators/generate-http-api.d.ts +3 -0
- package/types/ts-generator/generators/generate-http-controller.d.ts +3 -0
- package/types/ts-generator/processors/process-data-types.d.ts +19 -8
- package/types/ts-generator/ts-generator.d.ts +15 -15
|
@@ -3,108 +3,119 @@ import path from 'path';
|
|
|
3
3
|
import { CodeBlock } from '../../code-block.js';
|
|
4
4
|
import { wrapJSDocString } from '../utils/string-utils.js';
|
|
5
5
|
const internalTypeNames = ['any', 'boolean', 'bigint', 'number', 'null', 'string', 'object'];
|
|
6
|
-
export async function processDataType(dataType) {
|
|
6
|
+
export async function processDataType(dataType, currentFile, intent) {
|
|
7
7
|
const doc = dataType.node.getDocument();
|
|
8
8
|
if (doc.id !== this._document?.id) {
|
|
9
9
|
const { generator } = await this.processDocument(doc);
|
|
10
|
-
return await generator.processDataType(dataType);
|
|
10
|
+
return await generator.processDataType(dataType, currentFile, intent);
|
|
11
11
|
}
|
|
12
12
|
const typeName = dataType.name;
|
|
13
|
-
if (typeName
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
if (typeName) {
|
|
14
|
+
if (internalTypeNames.includes(typeName))
|
|
15
|
+
return { kind: 'internal', typeName: dataType.name };
|
|
16
|
+
let file = this._filesMap.get(dataType);
|
|
17
|
+
if (file) {
|
|
18
|
+
if (currentFile)
|
|
19
|
+
currentFile.addImport(file.filename, [typeName]);
|
|
20
|
+
return { kind: 'named', file, typeName: dataType.name };
|
|
21
|
+
}
|
|
22
|
+
if (dataType instanceof SimpleType)
|
|
23
|
+
file = this.addFile(path.join(this._documentRoot, '/simple-types.ts'), true);
|
|
24
|
+
else if (dataType instanceof EnumType)
|
|
24
25
|
file = this.addFile(path.join(this._typesRoot, 'enums', typeName + '.ts'));
|
|
25
26
|
else
|
|
26
27
|
file = this.addFile(path.join(this._typesRoot, 'types', typeName + '.ts'));
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
codeBlock.head +=
|
|
40
|
-
codeBlock.head += `
|
|
28
|
+
this._filesMap.set(dataType, file);
|
|
29
|
+
if (file.exportTypes.includes(typeName)) {
|
|
30
|
+
if (currentFile)
|
|
31
|
+
currentFile.addImport(file.filename, [typeName]);
|
|
32
|
+
return { kind: 'named', file, typeName: dataType.name };
|
|
33
|
+
}
|
|
34
|
+
file.exportTypes.push(typeName);
|
|
35
|
+
const typesIndexTs = this.addFile(path.join(this._typesRoot, 'index.ts'), true);
|
|
36
|
+
const indexTs = this.addFile('/index.ts', true);
|
|
37
|
+
indexTs.addExport(typesIndexTs.filename);
|
|
38
|
+
const codeBlock = (file.code['type_' + typeName] = new CodeBlock());
|
|
39
|
+
codeBlock.head = `/**\n * ${wrapJSDocString(dataType.description || '')}\n *`;
|
|
40
|
+
codeBlock.head += `
|
|
41
41
|
* @url ${path.posix.join(doc.url || this.serviceUrl, '$schema', '#types/' + typeName)}
|
|
42
42
|
*/
|
|
43
43
|
export `;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
codeBlock.typeDef = (await this.generateTypeDefinition(file, dataType, 'root')) + '\n\n';
|
|
45
|
+
typesIndexTs.addExport(file.filename);
|
|
46
|
+
if (currentFile)
|
|
47
|
+
currentFile.addImport(file.filename, [typeName]);
|
|
48
|
+
return { kind: 'named', file, typeName };
|
|
49
|
+
}
|
|
50
|
+
if (!currentFile)
|
|
51
|
+
throw new TypeError(`You must provide currentFile to generate data type`);
|
|
52
|
+
const code = await this.generateTypeDefinition(currentFile, dataType, intent);
|
|
53
|
+
return { kind: 'embedded', code };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
*/
|
|
58
|
+
export async function generateTypeDefinition(currentFile, dataType, intent) {
|
|
59
|
+
if (intent === 'root' && !dataType.name) {
|
|
60
|
+
throw new TypeError(`Name required to generate data type code to root intent`);
|
|
61
|
+
}
|
|
62
|
+
if (dataType instanceof EnumType) {
|
|
63
|
+
return await this.generateEnumTypeDefinition(currentFile, dataType, intent);
|
|
64
|
+
}
|
|
65
|
+
if (dataType instanceof ComplexType) {
|
|
66
|
+
return await this.generateComplexTypeDefinition(currentFile, dataType, intent);
|
|
48
67
|
}
|
|
49
|
-
|
|
50
|
-
|
|
68
|
+
if (dataType instanceof SimpleType) {
|
|
69
|
+
return await this.generateSimpleTypeDefinition(currentFile, dataType, intent);
|
|
51
70
|
}
|
|
52
|
-
|
|
53
|
-
|
|
71
|
+
if (dataType instanceof MappedType) {
|
|
72
|
+
return await this.generateMappedTypeDefinition(currentFile, dataType, intent);
|
|
54
73
|
}
|
|
55
|
-
|
|
56
|
-
|
|
74
|
+
if (dataType instanceof MixinType) {
|
|
75
|
+
return await this.generateMixinTypeDefinition(currentFile, dataType, intent);
|
|
57
76
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
typesIndexTs.addExport(file.filename);
|
|
61
|
-
return file;
|
|
77
|
+
/* istanbul ignore next */
|
|
78
|
+
throw new TypeError(`${dataType.kind} data types can not be directly exported`);
|
|
62
79
|
}
|
|
63
80
|
/**
|
|
64
81
|
*
|
|
65
82
|
*/
|
|
66
|
-
export async function generateEnumTypeDefinition(dataType, intent) {
|
|
67
|
-
if (intent === '
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (dataType.attributes[value].description)
|
|
83
|
-
jsDoc += ` * ${dataType.attributes[value].description}\n`;
|
|
84
|
-
if (jsDoc)
|
|
85
|
-
out += `/**\n${jsDoc} */\n`;
|
|
86
|
-
out +=
|
|
87
|
-
`${info.alias || value} = ` + (typeof value === 'number' ? value : "'" + String(value).replace("'", "\\'") + "'");
|
|
88
|
-
out += ',\n\n';
|
|
83
|
+
export async function generateEnumTypeDefinition(currentFile, dataType, intent) {
|
|
84
|
+
if (intent === 'root') {
|
|
85
|
+
let out = `enum ${dataType.name} {\n\t`;
|
|
86
|
+
for (const [value, info] of Object.entries(dataType.attributes)) {
|
|
87
|
+
// Print JSDoc
|
|
88
|
+
let jsDoc = '';
|
|
89
|
+
if (dataType.attributes[value].description)
|
|
90
|
+
jsDoc += ` * ${dataType.attributes[value].description}\n`;
|
|
91
|
+
if (jsDoc)
|
|
92
|
+
out += `/**\n${jsDoc} */\n`;
|
|
93
|
+
out +=
|
|
94
|
+
`${info.alias || value} = ` +
|
|
95
|
+
(typeof value === 'number' ? value : "'" + String(value).replace("'", "\\'") + "'");
|
|
96
|
+
out += ',\n\n';
|
|
97
|
+
}
|
|
98
|
+
return out + '\b}';
|
|
89
99
|
}
|
|
90
|
-
return
|
|
100
|
+
return ('(' +
|
|
101
|
+
Object.keys(dataType.attributes)
|
|
102
|
+
.map(t => `'${t}'`)
|
|
103
|
+
.join(' | ') +
|
|
104
|
+
')');
|
|
91
105
|
}
|
|
92
106
|
/**
|
|
93
107
|
*
|
|
94
108
|
*/
|
|
95
|
-
export async function generateComplexTypeDefinition(
|
|
96
|
-
|
|
97
|
-
throw new TypeError(`Name required to generate ComplexType for "${intent}" intent`);
|
|
98
|
-
}
|
|
99
|
-
let out = intent === 'scope' ? `interface ${dataType.name} ` : '';
|
|
109
|
+
export async function generateComplexTypeDefinition(currentFile, dataType, intent) {
|
|
110
|
+
let out = intent === 'root' ? `interface ${dataType.name} ` : '';
|
|
100
111
|
const ownFields = [...dataType.fields.values()].filter(f => f.origin === dataType);
|
|
101
112
|
if (dataType.base) {
|
|
102
|
-
const base = await this.
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (intent === '
|
|
113
|
+
const base = await this.processDataType(dataType.base, currentFile, 'extends');
|
|
114
|
+
let baseDef = base.kind === 'embedded' ? base.code : base.typeName;
|
|
115
|
+
const omitBaseFields = ownFields.filter(f => dataType.base.fields.has(f.name));
|
|
116
|
+
if (omitBaseFields.length)
|
|
117
|
+
baseDef = `Omit<${baseDef}, ${omitBaseFields.map(x => "'" + x.name + "'").join(' | ')}>`;
|
|
118
|
+
if (intent === 'root')
|
|
108
119
|
out += `extends ${baseDef} `;
|
|
109
120
|
else {
|
|
110
121
|
out += baseDef;
|
|
@@ -143,7 +154,8 @@ export async function generateComplexTypeDefinition(dataType, file, intent) {
|
|
|
143
154
|
out += `${t === 'number' || t === 'boolean' || t === 'bigint' ? field.fixed : "'" + field.fixed + "'"}\n`;
|
|
144
155
|
}
|
|
145
156
|
else {
|
|
146
|
-
|
|
157
|
+
const x = await this.processDataType(field.type, currentFile);
|
|
158
|
+
out += (x.kind === 'embedded' ? x.code : x.typeName) + `${field.isArray ? '[]' : ''};\n`;
|
|
147
159
|
}
|
|
148
160
|
}
|
|
149
161
|
if (dataType.additionalFields)
|
|
@@ -153,27 +165,37 @@ export async function generateComplexTypeDefinition(dataType, file, intent) {
|
|
|
153
165
|
/**
|
|
154
166
|
*
|
|
155
167
|
*/
|
|
156
|
-
export async function generateSimpleTypeDefinition(dataType, intent) {
|
|
157
|
-
|
|
158
|
-
throw new TypeError(`Name required to generate SimpleType for "${intent}" intent`);
|
|
159
|
-
}
|
|
160
|
-
let out = intent === 'scope' ? `type ${dataType.name} = ` : '';
|
|
168
|
+
export async function generateSimpleTypeDefinition(currentFile, dataType, intent) {
|
|
169
|
+
let out = intent === 'root' ? `type ${dataType.name} = ` : '';
|
|
161
170
|
out += dataType.nameMappings.js || 'any';
|
|
162
|
-
return intent === '
|
|
171
|
+
return intent === 'root' ? out + ';' : out;
|
|
163
172
|
}
|
|
164
173
|
/**
|
|
165
174
|
*
|
|
166
175
|
*/
|
|
167
|
-
export async function generateMixinTypeDefinition(
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
176
|
+
export async function generateMixinTypeDefinition(currentFile, dataType, intent) {
|
|
177
|
+
const outArray = [];
|
|
178
|
+
for (const t of dataType.types) {
|
|
179
|
+
const x = await this.processDataType(t, currentFile);
|
|
180
|
+
if (x.kind === 'embedded') {
|
|
181
|
+
outArray.push(x.code.includes('|') ? '(' + x.code + ')' : x.code);
|
|
182
|
+
}
|
|
183
|
+
else
|
|
184
|
+
outArray.push(x.typeName);
|
|
185
|
+
}
|
|
186
|
+
if (intent === 'root')
|
|
187
|
+
return `type ${dataType.name} = ${outArray.join(' & ')}`;
|
|
188
|
+
if (intent === 'extends')
|
|
189
|
+
return outArray.join(', ');
|
|
190
|
+
return outArray.join(' & ');
|
|
171
191
|
}
|
|
172
192
|
/**
|
|
173
193
|
*
|
|
174
194
|
*/
|
|
175
|
-
export async function generateMappedTypeDefinition(
|
|
176
|
-
|
|
195
|
+
export async function generateMappedTypeDefinition(currentFile, dataType, intent) {
|
|
196
|
+
let out = intent === 'root' ? `type ${dataType.name} = ` : '';
|
|
197
|
+
const base = await this.processDataType(dataType.base, currentFile);
|
|
198
|
+
const typeDef = base.kind === 'embedded' ? base.code : base.typeName;
|
|
177
199
|
const pick = dataType.pick?.length ? dataType.pick : undefined;
|
|
178
200
|
const omit = !pick && dataType.omit?.length ? dataType.omit : undefined;
|
|
179
201
|
const partial = dataType.partial === true || (Array.isArray(dataType.partial) && dataType.partial.length > 0)
|
|
@@ -184,18 +206,17 @@ export async function generateMappedTypeDefinition(dataType, file, intent) {
|
|
|
184
206
|
: undefined;
|
|
185
207
|
if (!(pick || omit || partial || required))
|
|
186
208
|
return typeDef;
|
|
187
|
-
let out = '';
|
|
188
209
|
if (partial === true)
|
|
189
210
|
out += 'Partial<';
|
|
190
211
|
else if (partial) {
|
|
191
212
|
out += 'PartialSome<';
|
|
192
|
-
|
|
213
|
+
currentFile.addExport('ts-gems', ['PartialSome']);
|
|
193
214
|
}
|
|
194
215
|
if (required === true)
|
|
195
216
|
out += 'Partial<';
|
|
196
217
|
else if (required) {
|
|
197
218
|
out += 'RequiredSome<';
|
|
198
|
-
|
|
219
|
+
currentFile.addExport('ts-gems', ['RequiredSome']);
|
|
199
220
|
}
|
|
200
221
|
if (pick)
|
|
201
222
|
out += 'Pick<';
|
|
@@ -224,28 +245,3 @@ export async function generateMappedTypeDefinition(dataType, file, intent) {
|
|
|
224
245
|
}
|
|
225
246
|
return out;
|
|
226
247
|
}
|
|
227
|
-
/**
|
|
228
|
-
*
|
|
229
|
-
*/
|
|
230
|
-
export async function resolveTypeNameOrDef(dataType, file, intent) {
|
|
231
|
-
if (dataType.name && !dataType.embedded) {
|
|
232
|
-
if (internalTypeNames.includes(dataType.name))
|
|
233
|
-
return dataType.name;
|
|
234
|
-
const f = await this.processDataType(dataType);
|
|
235
|
-
if (!f)
|
|
236
|
-
return '';
|
|
237
|
-
file.addImport(f.filename, [dataType.name], true);
|
|
238
|
-
return dataType.name;
|
|
239
|
-
}
|
|
240
|
-
if (dataType instanceof SimpleType)
|
|
241
|
-
return this.generateSimpleTypeDefinition(dataType, intent);
|
|
242
|
-
if (dataType instanceof EnumType)
|
|
243
|
-
return this.generateEnumTypeDefinition(dataType, intent);
|
|
244
|
-
if (dataType instanceof MixinType)
|
|
245
|
-
return this.generateMixinTypeDefinition(dataType, file, intent);
|
|
246
|
-
if (dataType instanceof MappedType)
|
|
247
|
-
return this.generateMappedTypeDefinition(dataType, file, intent);
|
|
248
|
-
if (dataType instanceof ComplexType)
|
|
249
|
-
return this.generateComplexTypeDefinition(dataType, file, intent);
|
|
250
|
-
return '';
|
|
251
|
-
}
|
|
@@ -86,8 +86,13 @@ export async function processHttpController(controller) {
|
|
|
86
86
|
}
|
|
87
87
|
let argIndex = 0;
|
|
88
88
|
for (const prm of pathParams) {
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
let typeName;
|
|
90
|
+
if (prm.type) {
|
|
91
|
+
const xt = await this.processDataType(prm.type, file);
|
|
92
|
+
typeName = xt.kind === 'embedded' ? xt.code : xt.typeName;
|
|
93
|
+
}
|
|
94
|
+
else
|
|
95
|
+
typeName = `any`;
|
|
91
96
|
if (argIndex++ > 0)
|
|
92
97
|
operationBlock.head += ', ';
|
|
93
98
|
operationBlock.head += `${prm.name}: ${typeName}`;
|
|
@@ -99,8 +104,10 @@ export async function processHttpController(controller) {
|
|
|
99
104
|
let typeArr = [];
|
|
100
105
|
for (const content of operation.requestBody.content) {
|
|
101
106
|
if (content.type) {
|
|
102
|
-
const
|
|
107
|
+
const xt = await this.processDataType(content.type, file);
|
|
108
|
+
const typeName = xt.kind === 'embedded' ? xt.code : xt.typeName;
|
|
103
109
|
typeArr.push(typeName);
|
|
110
|
+
continue;
|
|
104
111
|
}
|
|
105
112
|
typeArr = [];
|
|
106
113
|
break;
|
|
@@ -127,18 +134,15 @@ export async function processHttpController(controller) {
|
|
|
127
134
|
operationBlock.head += ', ';
|
|
128
135
|
operationBlock.head += '\n\t$params' + (isHeadersRequired || isQueryRequired ? '' : '?') + ': {\n\t';
|
|
129
136
|
for (const prm of queryParams) {
|
|
130
|
-
const type = locateNamedType(prm.type);
|
|
131
137
|
operationBlock.head += `/**\n * ${prm.description || ''}\n */\n`;
|
|
132
138
|
operationBlock.head += `${prm.name}${prm.required ? '' : '?'}: `;
|
|
133
|
-
if (type
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
operationBlock.head += `${type.name};\n`;
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
139
|
+
if (prm.type) {
|
|
140
|
+
const xt = await this.processDataType(prm.type, file);
|
|
141
|
+
const typeDef = xt.kind === 'embedded' ? xt.code : xt.typeName;
|
|
142
|
+
operationBlock.head += `${typeDef};\n`;
|
|
140
143
|
}
|
|
141
|
-
|
|
144
|
+
else
|
|
145
|
+
operationBlock.head += `any;\n`;
|
|
142
146
|
}
|
|
143
147
|
operationBlock.head += '\b}\b';
|
|
144
148
|
}
|
|
@@ -148,30 +152,39 @@ export async function processHttpController(controller) {
|
|
|
148
152
|
operationBlock.head += ', \n';
|
|
149
153
|
operationBlock.head += '\t$headers' + (isHeadersRequired ? '' : '?') + ': {\n\t';
|
|
150
154
|
for (const prm of headerParams) {
|
|
151
|
-
const type = locateNamedType(prm.type);
|
|
152
155
|
operationBlock.head += `/**\n * ${prm.description || ''}\n */\n`;
|
|
153
156
|
operationBlock.head += `${prm.name}${prm.required ? '' : '?'}: `;
|
|
154
|
-
if (type
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
operationBlock.head += `${type.name};\n`;
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
157
|
+
if (prm.type) {
|
|
158
|
+
const xt = await this.processDataType(prm.type, file);
|
|
159
|
+
const typeDef = xt.kind === 'embedded' ? xt.code : xt.typeName;
|
|
160
|
+
operationBlock.head += `${typeDef};\n`;
|
|
161
161
|
}
|
|
162
|
-
|
|
162
|
+
else
|
|
163
|
+
operationBlock.head += `any;\n`;
|
|
163
164
|
}
|
|
164
165
|
operationBlock.head += '\b}\b';
|
|
165
166
|
}
|
|
167
|
+
/* Determine return type */
|
|
168
|
+
// let returnType = '';
|
|
169
|
+
// for (const resp of operation.responses) {
|
|
170
|
+
// if (resp.type) {
|
|
171
|
+
// const typeFile = await this.processDataType(resp.type);
|
|
172
|
+
// // if (typeFile) {
|
|
173
|
+
// // file.addImport(typeFile.filename, [resp.type.name!]);
|
|
174
|
+
// // operationBlock.head += `${type.name};\n`;
|
|
175
|
+
// // continue;
|
|
176
|
+
// // }
|
|
177
|
+
// }
|
|
178
|
+
// }
|
|
166
179
|
operationBlock.head += `\n): HttpRequestObservable<any>{`;
|
|
167
180
|
operationBlock.body = `\n\t`;
|
|
168
181
|
operationBlock.body +=
|
|
169
182
|
`const url = this._prepareUrl('${operation.getFullUrl()}', {` + pathParams.map(p => p.name).join(', ') + '});';
|
|
170
183
|
operationBlock.body +=
|
|
171
|
-
`\nreturn this[kClient].request(url, {` +
|
|
172
|
-
(hasBody ? ' body: $body
|
|
173
|
-
(queryParams.length ? ' params: $params as any
|
|
174
|
-
(headerParams.length ? ' headers: $headers as any
|
|
184
|
+
`\nreturn this[kClient].request(url, { method: '${operation.method}'` +
|
|
185
|
+
(hasBody ? ', body: $body' : '') +
|
|
186
|
+
(queryParams.length ? ', params: $params as any' : '') +
|
|
187
|
+
(headerParams.length ? ', headers: $headers as any' : '') +
|
|
175
188
|
'});';
|
|
176
189
|
operationBlock.tail = `\b\n};\n`;
|
|
177
190
|
}
|
|
@@ -4,11 +4,11 @@ import path from 'node:path';
|
|
|
4
4
|
import process from 'node:process';
|
|
5
5
|
import chalk from 'chalk';
|
|
6
6
|
import { FileWriter } from '../file-writer.js';
|
|
7
|
-
import { cleanDirectory } from './
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
7
|
+
import { cleanDirectory } from './generators/clean-directory.js';
|
|
8
|
+
import { _generateComplexTypeCode, _generateEnumTypeCode, _generateMappedTypeCode, _generateMixinTypeCode, _generateSimpleTypeCode, _generateTypeCode, generateDataType, } from './generators/generate-data-type.js';
|
|
9
|
+
import { generateDocument } from './generators/generate-document.js';
|
|
10
|
+
import { generateHttpApi } from './generators/generate-http-api.js';
|
|
11
|
+
import { generateHttpController } from './generators/generate-http-controller.js';
|
|
12
12
|
import { TsFile } from './ts-file.js';
|
|
13
13
|
/**
|
|
14
14
|
* @class TsGenerator
|
|
@@ -45,7 +45,7 @@ export class TsGenerator extends EventEmitter {
|
|
|
45
45
|
this.emit('log', chalk.cyan('Removing old files..'));
|
|
46
46
|
this.cleanDirectory(this.outDir);
|
|
47
47
|
this._apiPath = '/api';
|
|
48
|
-
await this.
|
|
48
|
+
await this.generateDocument();
|
|
49
49
|
const { importExt } = this.options;
|
|
50
50
|
// Write files
|
|
51
51
|
for (const file of Object.values(this._files)) {
|
|
@@ -90,14 +90,14 @@ export class TsGenerator extends EventEmitter {
|
|
|
90
90
|
}
|
|
91
91
|
(() => {
|
|
92
92
|
TsGenerator.prototype.cleanDirectory = cleanDirectory;
|
|
93
|
-
TsGenerator.prototype.
|
|
94
|
-
TsGenerator.prototype.
|
|
95
|
-
TsGenerator.prototype.
|
|
96
|
-
TsGenerator.prototype.
|
|
97
|
-
TsGenerator.prototype.
|
|
98
|
-
TsGenerator.prototype.
|
|
99
|
-
TsGenerator.prototype.
|
|
100
|
-
TsGenerator.prototype.
|
|
101
|
-
TsGenerator.prototype.
|
|
102
|
-
TsGenerator.prototype.
|
|
93
|
+
TsGenerator.prototype.generateDocument = generateDocument;
|
|
94
|
+
TsGenerator.prototype.generateDataType = generateDataType;
|
|
95
|
+
TsGenerator.prototype._generateTypeCode = _generateTypeCode;
|
|
96
|
+
TsGenerator.prototype._generateEnumTypeCode = _generateEnumTypeCode;
|
|
97
|
+
TsGenerator.prototype._generateComplexTypeCode = _generateComplexTypeCode;
|
|
98
|
+
TsGenerator.prototype._generateSimpleTypeCode = _generateSimpleTypeCode;
|
|
99
|
+
TsGenerator.prototype._generateMappedTypeCode = _generateMappedTypeCode;
|
|
100
|
+
TsGenerator.prototype._generateMixinTypeCode = _generateMixinTypeCode;
|
|
101
|
+
TsGenerator.prototype.generateHttpApi = generateHttpApi;
|
|
102
|
+
TsGenerator.prototype.generateHttpController = generateHttpController;
|
|
103
103
|
})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opra/cli",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.13",
|
|
4
4
|
"description": "Opra CLI tools",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,8 +31,9 @@
|
|
|
31
31
|
"clean:cover": "rimraf ../../coverage/client"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@
|
|
35
|
-
"@opra/
|
|
34
|
+
"@browsery/type-is": "^1.6.18-r3",
|
|
35
|
+
"@opra/client": "^1.0.0-alpha.13",
|
|
36
|
+
"@opra/common": "^1.0.0-alpha.13",
|
|
36
37
|
"chalk": "^5.3.0",
|
|
37
38
|
"commander": "^12.0.0",
|
|
38
39
|
"js-string-escape": "^1.0.1",
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ComplexType, DataType, EnumType, MappedType, MixinType, SimpleType } from '@opra/common';
|
|
2
|
+
import { TsFile } from '../ts-file.js';
|
|
3
|
+
import type { TsGenerator } from '../ts-generator';
|
|
4
|
+
type Intent = 'root' | 'extends' | 'typeDef';
|
|
5
|
+
export type generateDataTypeResult = {
|
|
6
|
+
kind: 'internal';
|
|
7
|
+
typeName: string;
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'named';
|
|
10
|
+
typeName: string;
|
|
11
|
+
file: TsFile;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'embedded';
|
|
14
|
+
code: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function generateDataType(this: TsGenerator, dataType: DataType, intent: Intent, currentFile?: TsFile): Promise<generateDataTypeResult>;
|
|
17
|
+
/**
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
export declare function _generateTypeCode(this: TsGenerator, currentFile: TsFile, dataType: DataType, intent?: Intent): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
*
|
|
23
|
+
*/
|
|
24
|
+
export declare function _generateEnumTypeCode(this: TsGenerator, currentFile: TsFile, dataType: EnumType, intent?: Intent): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
*/
|
|
28
|
+
export declare function _generateComplexTypeCode(this: TsGenerator, currentFile: TsFile, dataType: ComplexType, intent?: Intent): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
*/
|
|
32
|
+
export declare function _generateSimpleTypeCode(this: TsGenerator, currentFile: TsFile, dataType: SimpleType, intent?: Intent): Promise<string>;
|
|
33
|
+
/**
|
|
34
|
+
*
|
|
35
|
+
*/
|
|
36
|
+
export declare function _generateMixinTypeCode(this: TsGenerator, currentFile: TsFile, dataType: MixinType, intent?: Intent): Promise<string>;
|
|
37
|
+
/**
|
|
38
|
+
*
|
|
39
|
+
*/
|
|
40
|
+
export declare function _generateMappedTypeCode(this: TsGenerator, currentFile: TsFile, dataType: MappedType, intent?: Intent): Promise<string>;
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ApiDocument } from '@opra/common';
|
|
2
|
+
import type { TsGenerator } from '../ts-generator';
|
|
3
|
+
export declare function generateDocument(this: TsGenerator, document?: string | ApiDocument, options?: {
|
|
4
|
+
typesOnly?: boolean;
|
|
5
|
+
}): Promise<{
|
|
6
|
+
document: ApiDocument;
|
|
7
|
+
generator: TsGenerator;
|
|
8
|
+
}>;
|
|
@@ -1,30 +1,41 @@
|
|
|
1
1
|
import { ComplexType, DataType, EnumType, MappedType, MixinType, SimpleType } from '@opra/common';
|
|
2
2
|
import { TsFile } from '../ts-file.js';
|
|
3
3
|
import type { TsGenerator } from '../ts-generator';
|
|
4
|
-
type Intent = '
|
|
5
|
-
export
|
|
4
|
+
type Intent = 'root' | 'extends' | 'property';
|
|
5
|
+
export type ProcessDataTypeResult = {
|
|
6
|
+
kind: 'internal';
|
|
7
|
+
typeName: string;
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'named';
|
|
10
|
+
typeName: string;
|
|
11
|
+
file: TsFile;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'embedded';
|
|
14
|
+
code: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function processDataType(this: TsGenerator, dataType: DataType, currentFile?: TsFile, intent?: Intent): Promise<ProcessDataTypeResult>;
|
|
6
17
|
/**
|
|
7
18
|
*
|
|
8
19
|
*/
|
|
9
|
-
export declare function
|
|
20
|
+
export declare function generateTypeDefinition(this: TsGenerator, currentFile: TsFile, dataType: DataType, intent?: Intent): Promise<string>;
|
|
10
21
|
/**
|
|
11
22
|
*
|
|
12
23
|
*/
|
|
13
|
-
export declare function
|
|
24
|
+
export declare function generateEnumTypeDefinition(this: TsGenerator, currentFile: TsFile, dataType: EnumType, intent?: Intent): Promise<string>;
|
|
14
25
|
/**
|
|
15
26
|
*
|
|
16
27
|
*/
|
|
17
|
-
export declare function
|
|
28
|
+
export declare function generateComplexTypeDefinition(this: TsGenerator, currentFile: TsFile, dataType: ComplexType, intent?: Intent): Promise<string>;
|
|
18
29
|
/**
|
|
19
30
|
*
|
|
20
31
|
*/
|
|
21
|
-
export declare function
|
|
32
|
+
export declare function generateSimpleTypeDefinition(this: TsGenerator, currentFile: TsFile, dataType: SimpleType, intent?: Intent): Promise<string>;
|
|
22
33
|
/**
|
|
23
34
|
*
|
|
24
35
|
*/
|
|
25
|
-
export declare function
|
|
36
|
+
export declare function generateMixinTypeDefinition(this: TsGenerator, currentFile: TsFile, dataType: MixinType, intent?: Intent): Promise<string>;
|
|
26
37
|
/**
|
|
27
38
|
*
|
|
28
39
|
*/
|
|
29
|
-
export declare function
|
|
40
|
+
export declare function generateMappedTypeDefinition(this: TsGenerator, currentFile: TsFile, dataType: MappedType, intent?: Intent): Promise<string>;
|
|
30
41
|
export {};
|