@opra/cli 0.14.3 → 0.16.0
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/bin/oprimp.mjs +1 -1
- package/cjs/api-exporter/api-exporter.js +107 -0
- package/cjs/{oprimp → api-exporter}/index.js +1 -1
- package/cjs/api-exporter/process-resources.js +50 -0
- package/cjs/api-exporter/process-types.js +215 -0
- package/cjs/api-exporter/ts-file.js +90 -0
- package/cjs/index.js +1 -1
- package/cjs/{oprimp.js → oprimp-cli.js} +8 -9
- package/esm/api-exporter/api-exporter.js +107 -0
- package/esm/api-exporter/file-writer.js +11 -0
- package/esm/api-exporter/index.js +4 -0
- package/esm/api-exporter/process-resources.js +50 -0
- package/esm/api-exporter/process-types.js +215 -0
- package/esm/api-exporter/ts-file.js +90 -0
- package/esm/index.js +4 -1
- package/esm/interfaces/file-writer.interface.js +2 -1
- package/esm/interfaces/logger.interface.js +2 -1
- package/esm/interfaces/service-generation-context.interface.js +2 -1
- package/esm/oprimp-cli.js +35 -0
- package/esm/utils/get-caller-file.util.js +5 -1
- package/esm/utils/string-utils.js +14 -6
- package/package.json +10 -10
- package/types/api-exporter/api-exporter.d.ts +46 -0
- package/types/api-exporter/index.d.ts +1 -0
- package/types/api-exporter/process-resources.d.ts +6 -0
- package/types/api-exporter/process-types.d.ts +54 -0
- package/types/api-exporter/ts-file.d.ts +18 -0
- package/types/index.d.ts +1 -0
- package/{esm → types}/interfaces/service-generation-context.interface.d.ts +2 -2
- package/cjs/oprimp/delete-files.js +0 -27
- package/cjs/oprimp/generate-service.js +0 -54
- package/cjs/oprimp/process-resoruces.js +0 -59
- package/cjs/oprimp/process-types.js +0 -130
- package/cjs/utils/ts-file.js +0 -55
- package/esm/index.d.ts +0 -1
- package/esm/oprimp/delete-files.d.ts +0 -1
- package/esm/oprimp/delete-files.js +0 -22
- package/esm/oprimp/file-writer.js +0 -6
- package/esm/oprimp/generate-service.d.ts +0 -13
- package/esm/oprimp/generate-service.js +0 -49
- package/esm/oprimp/index.d.ts +0 -1
- package/esm/oprimp/index.js +0 -1
- package/esm/oprimp/process-resoruces.d.ts +0 -2
- package/esm/oprimp/process-resoruces.js +0 -54
- package/esm/oprimp/process-types.d.ts +0 -2
- package/esm/oprimp/process-types.js +0 -125
- package/esm/oprimp.js +0 -33
- package/esm/utils/ts-file.d.ts +0 -11
- package/esm/utils/ts-file.js +0 -50
- /package/cjs/{oprimp → api-exporter}/file-writer.js +0 -0
- /package/{esm/oprimp → types/api-exporter}/file-writer.d.ts +0 -0
- /package/{esm → types}/interfaces/file-writer.interface.d.ts +0 -0
- /package/{esm → types}/interfaces/logger.interface.d.ts +0 -0
- /package/{esm/oprimp.d.ts → types/oprimp-cli.d.ts} +0 -0
- /package/{esm → types}/utils/get-caller-file.util.d.ts +0 -0
- /package/{esm → types}/utils/string-utils.d.ts +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processResources = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
6
|
+
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
7
|
+
const common_1 = require("@opra/common");
|
|
8
|
+
const string_utils_js_1 = require("../utils/string-utils.js");
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @param targetDir
|
|
12
|
+
*/
|
|
13
|
+
async function processResources(targetDir = '') {
|
|
14
|
+
this.logger.log(chalk_1.default.yellow('Processing resources'));
|
|
15
|
+
const { document } = this;
|
|
16
|
+
const serviceTs = this.addFile(node_path_1.default.join(targetDir, this.name + '.ts'));
|
|
17
|
+
serviceTs.addImportPackage('@opra/client', ['HttpServiceBase']);
|
|
18
|
+
const indexTs = this.addFile('/index.ts', true);
|
|
19
|
+
indexTs.addExportFile(serviceTs.filename);
|
|
20
|
+
serviceTs.content = `\nexport class ${this.name} extends HttpServiceBase {\n`;
|
|
21
|
+
for (const resource of document.resources.values()) {
|
|
22
|
+
serviceTs.content += `\n/**\n * ${(0, string_utils_js_1.wrapJSDocString)(resource.description || resource.name)}
|
|
23
|
+
* @url ${(0, common_1.joinPath)(this.client.serviceUrl, '$metadata#resources/' + resource.name)}
|
|
24
|
+
*/`;
|
|
25
|
+
if (resource instanceof common_1.Collection) {
|
|
26
|
+
const typeName = resource.type.name || '';
|
|
27
|
+
serviceTs.addImportPackage('@opra/client', ['HttpCollectionNode']);
|
|
28
|
+
serviceTs.addImportFile('types/' + typeName, [typeName]);
|
|
29
|
+
const operations = Object.keys(resource.operations)
|
|
30
|
+
.map(x => `'${x}'`).join(' | ');
|
|
31
|
+
serviceTs.content += `
|
|
32
|
+
get ${resource.name}(): Pick<HttpCollectionNode<${typeName}>, ${operations}> {
|
|
33
|
+
return this.$client.collection('${resource.name}');
|
|
34
|
+
}\n`;
|
|
35
|
+
}
|
|
36
|
+
else if (resource instanceof common_1.Singleton) {
|
|
37
|
+
const typeName = resource.type.name || '';
|
|
38
|
+
serviceTs.addImportPackage('@opra/client', ['HttpSingletonNode']);
|
|
39
|
+
serviceTs.addImportFile('types/' + typeName, [typeName]);
|
|
40
|
+
const operations = Object.keys(resource.operations)
|
|
41
|
+
.map(x => `'${x}'`).join(' | ');
|
|
42
|
+
serviceTs.content += `
|
|
43
|
+
get ${resource.name}(): Pick<HttpSingletonNode<${typeName}>, ${operations}> {
|
|
44
|
+
return this.$client.singleton('${resource.name}');
|
|
45
|
+
}\n`;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
serviceTs.content += '}';
|
|
49
|
+
}
|
|
50
|
+
exports.processResources = processResources;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateMappedTypeDefinition = exports.generateUnionTypeDefinition = exports.generateEnumTypeDefinition = exports.generateSimpleTypeDefinition = exports.generateComplexTypeDefinition = exports.resolveTypeNameOrDef = exports.generateTypeFile = exports.processTypes = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
6
|
+
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
7
|
+
const common_1 = require("@opra/common");
|
|
8
|
+
const string_utils_js_1 = require("../utils/string-utils.js");
|
|
9
|
+
const internalTypeNames = ['boolean', 'bigint', 'number', 'null', 'string'];
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param targetDir
|
|
13
|
+
*/
|
|
14
|
+
async function processTypes(targetDir = '') {
|
|
15
|
+
this.logger.log(chalk_1.default.yellow('Processing types'));
|
|
16
|
+
const { document } = this;
|
|
17
|
+
const typesTs = this.addFile(node_path_1.default.join(targetDir, 'types.ts'));
|
|
18
|
+
for (const dataType of document.types.values()) {
|
|
19
|
+
const expFile = await this.generateTypeFile(dataType, targetDir);
|
|
20
|
+
typesTs.addExportFile(expFile.filename);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.processTypes = processTypes;
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
* @param dataType
|
|
27
|
+
* @param targetDir
|
|
28
|
+
*/
|
|
29
|
+
async function generateTypeFile(dataType, targetDir = '') {
|
|
30
|
+
const typeName = dataType.name;
|
|
31
|
+
if (!typeName)
|
|
32
|
+
throw new TypeError(`DataType has no name`);
|
|
33
|
+
let filePath;
|
|
34
|
+
if (dataType instanceof common_1.SimpleType)
|
|
35
|
+
filePath = '/simple-types.ts';
|
|
36
|
+
else if (dataType instanceof common_1.ComplexType)
|
|
37
|
+
filePath = `/types/${typeName}.ts`;
|
|
38
|
+
else if (dataType instanceof common_1.EnumType) {
|
|
39
|
+
filePath = `/enums/${typeName}.ts`;
|
|
40
|
+
}
|
|
41
|
+
else
|
|
42
|
+
throw new TypeError(`Unimplemented DataType (${dataType.kind})`);
|
|
43
|
+
const file = this.addFile(node_path_1.default.join(targetDir, filePath), true);
|
|
44
|
+
if (file.exportTypes.includes(typeName))
|
|
45
|
+
return file;
|
|
46
|
+
file.exportTypes.push(typeName);
|
|
47
|
+
const indexTs = this.addFile('/index.ts', true);
|
|
48
|
+
indexTs.addExportFile(file.filename);
|
|
49
|
+
file.content += `\n/**\n * ${(0, string_utils_js_1.wrapJSDocString)(dataType.description || typeName)}
|
|
50
|
+
* @type ${typeName}
|
|
51
|
+
* @kind ${dataType.kind}
|
|
52
|
+
* @url ${(0, common_1.joinPath)(this.client.serviceUrl, '$metadata#types/' + typeName)}
|
|
53
|
+
*/\n`;
|
|
54
|
+
if (dataType instanceof common_1.SimpleType) {
|
|
55
|
+
file.content += `export type ${typeName} = ` + await this.generateSimpleTypeDefinition(file, dataType);
|
|
56
|
+
}
|
|
57
|
+
else if (dataType instanceof common_1.EnumType) {
|
|
58
|
+
file.content += `export enum ${typeName} ` + await this.generateEnumTypeDefinition(file, dataType);
|
|
59
|
+
}
|
|
60
|
+
else if (dataType instanceof common_1.ComplexType) {
|
|
61
|
+
file.content += `export class ${typeName} {
|
|
62
|
+
constructor(init?: Partial<I${typeName}>) {
|
|
63
|
+
if (init)
|
|
64
|
+
Object.assign(this, init);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface ${typeName} extends I${typeName} {
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface I${typeName} ${await this.generateComplexTypeDefinition(file, dataType, true)}
|
|
72
|
+
`;
|
|
73
|
+
}
|
|
74
|
+
return file;
|
|
75
|
+
}
|
|
76
|
+
exports.generateTypeFile = generateTypeFile;
|
|
77
|
+
/**
|
|
78
|
+
*
|
|
79
|
+
* @param file
|
|
80
|
+
* @param dataType
|
|
81
|
+
* @param forInterface
|
|
82
|
+
*/
|
|
83
|
+
async function resolveTypeNameOrDef(file, dataType, forInterface) {
|
|
84
|
+
if (dataType.name) {
|
|
85
|
+
if (internalTypeNames.includes(dataType.name))
|
|
86
|
+
return dataType.name;
|
|
87
|
+
const f = await this.generateTypeFile(dataType);
|
|
88
|
+
file.addImportFile(f.filename, [dataType.name]);
|
|
89
|
+
return dataType.name;
|
|
90
|
+
}
|
|
91
|
+
if (dataType instanceof common_1.ComplexType)
|
|
92
|
+
return this.generateComplexTypeDefinition(file, dataType, forInterface);
|
|
93
|
+
if (dataType instanceof common_1.SimpleType)
|
|
94
|
+
return this.generateSimpleTypeDefinition(file, dataType);
|
|
95
|
+
if (dataType instanceof common_1.EnumType)
|
|
96
|
+
return this.generateEnumTypeDefinition(file, dataType);
|
|
97
|
+
if (dataType instanceof common_1.UnionType)
|
|
98
|
+
return this.generateUnionTypeDefinition(file, dataType, forInterface);
|
|
99
|
+
if (dataType instanceof common_1.MappedType)
|
|
100
|
+
return this.generateMappedTypeDefinition(file, dataType, forInterface);
|
|
101
|
+
return 'xxx';
|
|
102
|
+
}
|
|
103
|
+
exports.resolveTypeNameOrDef = resolveTypeNameOrDef;
|
|
104
|
+
/**
|
|
105
|
+
*
|
|
106
|
+
* @param file
|
|
107
|
+
* @param dataType
|
|
108
|
+
* @param forInterface
|
|
109
|
+
*/
|
|
110
|
+
async function generateComplexTypeDefinition(file, dataType, forInterface) {
|
|
111
|
+
let out = '';
|
|
112
|
+
if (dataType.base) {
|
|
113
|
+
const base = await this.resolveTypeNameOrDef(file, dataType.base, forInterface);
|
|
114
|
+
out += forInterface ? `extends ${base} ` : `${base} & `;
|
|
115
|
+
}
|
|
116
|
+
out += '{\n\n\t';
|
|
117
|
+
for (const field of dataType.own.fields.values()) {
|
|
118
|
+
// Print JSDoc
|
|
119
|
+
let jsDoc = '';
|
|
120
|
+
if (field.description)
|
|
121
|
+
jsDoc += ` * ${field.description}\n`;
|
|
122
|
+
if (field.default)
|
|
123
|
+
jsDoc += ` * @default ` + field.default + '\n';
|
|
124
|
+
if (field.format)
|
|
125
|
+
jsDoc += ` * @format ` + field.format + '\n';
|
|
126
|
+
if (field.exclusive)
|
|
127
|
+
jsDoc += ` * @exclusive\n`;
|
|
128
|
+
if (field.deprecated)
|
|
129
|
+
jsDoc += ` * @deprecated ` + (typeof field.deprecated === 'string' ? field.deprecated : '') + '\n';
|
|
130
|
+
if (jsDoc)
|
|
131
|
+
out += `/**\n${jsDoc}*/\n`;
|
|
132
|
+
// Print field name
|
|
133
|
+
out += `${field.name}${field.required ? '' : '?'}: `;
|
|
134
|
+
if (field.fixed)
|
|
135
|
+
out += `${field.fixed}`;
|
|
136
|
+
else {
|
|
137
|
+
out += await this.resolveTypeNameOrDef(file, field.type) +
|
|
138
|
+
`${field.isArray ? '[]' : ''};\n\n`;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (dataType.additionalFields)
|
|
142
|
+
out += '[key: string]: any;\n';
|
|
143
|
+
return out + '\b}';
|
|
144
|
+
}
|
|
145
|
+
exports.generateComplexTypeDefinition = generateComplexTypeDefinition;
|
|
146
|
+
/**
|
|
147
|
+
*
|
|
148
|
+
* @param file
|
|
149
|
+
* @param dataType
|
|
150
|
+
*/
|
|
151
|
+
async function generateSimpleTypeDefinition(file, dataType) {
|
|
152
|
+
if (dataType.ctor === Boolean)
|
|
153
|
+
return 'boolean';
|
|
154
|
+
if (dataType.ctor === String)
|
|
155
|
+
return 'string';
|
|
156
|
+
if (dataType.ctor === Number)
|
|
157
|
+
return 'number';
|
|
158
|
+
if (dataType.ctor === Date)
|
|
159
|
+
return 'Date';
|
|
160
|
+
if (dataType.extendsFrom('bigint'))
|
|
161
|
+
return 'Date';
|
|
162
|
+
if (dataType.extendsFrom('object'))
|
|
163
|
+
return 'object';
|
|
164
|
+
return 'any';
|
|
165
|
+
}
|
|
166
|
+
exports.generateSimpleTypeDefinition = generateSimpleTypeDefinition;
|
|
167
|
+
/**
|
|
168
|
+
*
|
|
169
|
+
* @param file
|
|
170
|
+
* @param dataType
|
|
171
|
+
*/
|
|
172
|
+
async function generateEnumTypeDefinition(file, dataType) {
|
|
173
|
+
let out = '{\n\t';
|
|
174
|
+
for (const [k, v] of Object.entries(dataType.values)) {
|
|
175
|
+
// Print JSDoc
|
|
176
|
+
let jsDoc = '';
|
|
177
|
+
if (dataType.meanings[k])
|
|
178
|
+
jsDoc += ` * ${dataType.meanings[k]}\n`;
|
|
179
|
+
if (jsDoc)
|
|
180
|
+
out += `/**\n${jsDoc}*/\n`;
|
|
181
|
+
out += `${k}`;
|
|
182
|
+
if (v)
|
|
183
|
+
out += ' = ' + (typeof v === 'number' ? v : ('"' + ('' + v).replace('"', '\\"')) + '"');
|
|
184
|
+
out += ',\n\n';
|
|
185
|
+
}
|
|
186
|
+
return out + '\b}';
|
|
187
|
+
}
|
|
188
|
+
exports.generateEnumTypeDefinition = generateEnumTypeDefinition;
|
|
189
|
+
/**
|
|
190
|
+
*
|
|
191
|
+
* @param file
|
|
192
|
+
* @param dataType
|
|
193
|
+
* @param forInterface
|
|
194
|
+
*/
|
|
195
|
+
async function generateUnionTypeDefinition(file, dataType, forInterface) {
|
|
196
|
+
// let out = '';
|
|
197
|
+
return (await Promise.all(dataType.types
|
|
198
|
+
.map(t => this.resolveTypeNameOrDef(file, t, forInterface)))).join(forInterface ? ', ' : ' & ');
|
|
199
|
+
}
|
|
200
|
+
exports.generateUnionTypeDefinition = generateUnionTypeDefinition;
|
|
201
|
+
/**
|
|
202
|
+
*
|
|
203
|
+
* @param file
|
|
204
|
+
* @param dataType
|
|
205
|
+
* @param forInterface
|
|
206
|
+
*/
|
|
207
|
+
async function generateMappedTypeDefinition(file, dataType, forInterface) {
|
|
208
|
+
return (dataType.pick ? 'Pick<' : 'Omit<') +
|
|
209
|
+
(await this.resolveTypeNameOrDef(file, dataType.type, forInterface)) +
|
|
210
|
+
', ' +
|
|
211
|
+
(dataType.pick || dataType.omit || [])
|
|
212
|
+
.map(x => `'${x}'`).join(' | ') +
|
|
213
|
+
'>';
|
|
214
|
+
}
|
|
215
|
+
exports.generateMappedTypeDefinition = generateMappedTypeDefinition;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setExt = exports.relativePath = exports.TsFile = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
6
|
+
const putil_flattentext_1 = tslib_1.__importDefault(require("putil-flattentext"));
|
|
7
|
+
class TsFile {
|
|
8
|
+
constructor(filename) {
|
|
9
|
+
this.filename = filename;
|
|
10
|
+
this.importFiles = {};
|
|
11
|
+
this.exportFiles = {};
|
|
12
|
+
this.exportTypes = [];
|
|
13
|
+
this.header = '';
|
|
14
|
+
this.content = '';
|
|
15
|
+
this.addImportPackage = (name, types) => {
|
|
16
|
+
this.importFiles[name] = this.importFiles[name] || [];
|
|
17
|
+
types?.forEach(x => {
|
|
18
|
+
if (!this.importFiles[name].includes(x))
|
|
19
|
+
this.importFiles[name].push(x);
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
this.addImportFile = (filename, types) => {
|
|
23
|
+
filename = path_1.default.resolve(this.dirname, filename);
|
|
24
|
+
this.importFiles[filename] = this.importFiles[filename] || [];
|
|
25
|
+
types?.forEach(x => {
|
|
26
|
+
if (!this.importFiles[filename].includes(x))
|
|
27
|
+
this.importFiles[filename].push(x);
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
this.addExportFile = (filename, types) => {
|
|
31
|
+
filename = path_1.default.resolve(this.dirname, filename);
|
|
32
|
+
if (filename.endsWith('.ts') || filename.endsWith('.js'))
|
|
33
|
+
filename = setExt(filename, '');
|
|
34
|
+
this.exportFiles[filename] = this.exportFiles[filename] || [];
|
|
35
|
+
types?.forEach(x => {
|
|
36
|
+
if (!this.exportFiles[filename].includes(x))
|
|
37
|
+
this.exportFiles[filename].push(x);
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
this.dirname = path_1.default.dirname(filename);
|
|
41
|
+
}
|
|
42
|
+
generate(options) {
|
|
43
|
+
const dirname = path_1.default.dirname(this.filename);
|
|
44
|
+
let output = '/* #!oprimp_auto_generated!# !! Do NOT remove this line */\n' +
|
|
45
|
+
(this.header ? (0, putil_flattentext_1.default)(this.header) + '\n\n' : '\n');
|
|
46
|
+
const importStr = Object.keys(this.importFiles)
|
|
47
|
+
.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
|
|
48
|
+
.map(filename => {
|
|
49
|
+
const types = this.importFiles[filename];
|
|
50
|
+
let relFile = filename;
|
|
51
|
+
if (path_1.default.isAbsolute(filename)) {
|
|
52
|
+
relFile = relativePath(dirname, filename);
|
|
53
|
+
if (options?.importExt)
|
|
54
|
+
relFile = setExt(relFile, options.importExt);
|
|
55
|
+
}
|
|
56
|
+
return `import ${types.length ? '{' + types.join(', ') + '} from ' : ''}'${relFile}';`;
|
|
57
|
+
})
|
|
58
|
+
.join('\n');
|
|
59
|
+
if (importStr)
|
|
60
|
+
output += (0, putil_flattentext_1.default)(importStr) + '\n';
|
|
61
|
+
output += (0, putil_flattentext_1.default)(this.content);
|
|
62
|
+
const exportStr = Object.keys(this.exportFiles)
|
|
63
|
+
.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
|
|
64
|
+
.map(filename => {
|
|
65
|
+
const types = this.exportFiles[filename];
|
|
66
|
+
let relFile = filename;
|
|
67
|
+
if (path_1.default.isAbsolute(filename)) {
|
|
68
|
+
relFile = relativePath(dirname, filename);
|
|
69
|
+
if (options?.importExt)
|
|
70
|
+
relFile = setExt(relFile, options.importExt);
|
|
71
|
+
}
|
|
72
|
+
return `export ${types.length ? '{' + types.join(', ') + '}' : '*'} from '${relFile}';`;
|
|
73
|
+
})
|
|
74
|
+
.join('\n');
|
|
75
|
+
if (exportStr)
|
|
76
|
+
output += (0, putil_flattentext_1.default)(exportStr) + '\n';
|
|
77
|
+
return output;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.TsFile = TsFile;
|
|
81
|
+
function relativePath(from, to) {
|
|
82
|
+
const s = path_1.default.relative(from, to);
|
|
83
|
+
return s.startsWith('.') ? s : ('./' + s);
|
|
84
|
+
}
|
|
85
|
+
exports.relativePath = relativePath;
|
|
86
|
+
function setExt(filename, ext) {
|
|
87
|
+
const e = path_1.default.extname(filename);
|
|
88
|
+
return filename.substring(0, filename.length - e.length) + (ext ? '.' + ext : '');
|
|
89
|
+
}
|
|
90
|
+
exports.setExt = setExt;
|
package/esm/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
5
|
+
const commander_1 = require("commander");
|
|
6
|
+
const console = tslib_1.__importStar(require("console"));
|
|
7
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
8
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
9
|
+
const process = tslib_1.__importStar(require("process"));
|
|
10
|
+
const api_exporter_js_1 = require("./api-exporter/api-exporter.js");
|
|
11
|
+
const get_caller_file_util_js_1 = require("./utils/get-caller-file.util.js");
|
|
12
|
+
const dirname = path_1.default.dirname((0, get_caller_file_util_js_1.getCallerFile)());
|
|
13
|
+
const pkgJson = JSON.parse(fs.readFileSync(path_1.default.resolve(dirname, '../package.json'), 'utf-8'));
|
|
14
|
+
commander_1.program
|
|
15
|
+
.version(pkgJson.version)
|
|
16
|
+
.argument('<serviceUrl>', 'OPRA service url')
|
|
17
|
+
.argument('<outDir>', 'Output directory')
|
|
18
|
+
.option('--name <name>', 'Name of the service')
|
|
19
|
+
.option('--ext', 'Adds js extension to imports')
|
|
20
|
+
.option('--no-color', 'Disables colors in logs messages')
|
|
21
|
+
.action(async (serviceUrl, outDir, options) => {
|
|
22
|
+
if (!options.color)
|
|
23
|
+
chalk_1.default.level = 0;
|
|
24
|
+
await api_exporter_js_1.ApiExporter.execute({
|
|
25
|
+
serviceUrl,
|
|
26
|
+
logger: console,
|
|
27
|
+
outDir,
|
|
28
|
+
name: options.name,
|
|
29
|
+
importExt: (options.ext ? 'js' : ''),
|
|
30
|
+
fileHeader: '/* Generated by OPRA Service Generator, Version ' + pkgJson.version + '*/\n' +
|
|
31
|
+
'/* eslint-disable import/extensions,simple-import-sort/imports */\n'
|
|
32
|
+
});
|
|
33
|
+
console.log(chalk_1.default.greenBright('Completed'));
|
|
34
|
+
});
|
|
35
|
+
commander_1.program.parse(process.argv);
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCallerFile = void 0;
|
|
1
4
|
const PATH_PATTERN = /^(?:file:\/\/)?(.+)$/;
|
|
2
|
-
|
|
5
|
+
function getCallerFile(position = 1) {
|
|
3
6
|
if (position >= Error.stackTraceLimit) {
|
|
4
7
|
throw new TypeError('getCallerFile(position) requires position be less then Error.stackTraceLimit but position was: `' +
|
|
5
8
|
position + '` and Error.stackTraceLimit was: `' + Error.stackTraceLimit + '`');
|
|
@@ -18,3 +21,4 @@ export function getCallerFile(position = 1) {
|
|
|
18
21
|
}
|
|
19
22
|
return '';
|
|
20
23
|
}
|
|
24
|
+
exports.getCallerFile = getCallerFile;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wrapTypeArray = exports.wrapStringArray = exports.wrapQuotedString = exports.wrapJSDocString = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const js_string_escape_1 = tslib_1.__importDefault(require("js-string-escape"));
|
|
6
|
+
function wrapJSDocString(s, indent, currentColumn) {
|
|
3
7
|
const arr = (s || '')
|
|
4
8
|
.split(/[ \n\r]/)
|
|
5
9
|
.map((x, i, a) => i < a.length - 1 ? x + ' ' : x);
|
|
@@ -10,8 +14,9 @@ export function wrapJSDocString(s, indent, currentColumn) {
|
|
|
10
14
|
lineEnd: ''
|
|
11
15
|
});
|
|
12
16
|
}
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
exports.wrapJSDocString = wrapJSDocString;
|
|
18
|
+
function wrapQuotedString(s, indent, currentColumn) {
|
|
19
|
+
const arr = (0, js_string_escape_1.default)(s || '')
|
|
15
20
|
.split(' ')
|
|
16
21
|
.map((x, i, a) => i < a.length - 1 ? x + ' ' : x);
|
|
17
22
|
return '\'' + _printLines(arr, {
|
|
@@ -21,16 +26,19 @@ export function wrapQuotedString(s, indent, currentColumn) {
|
|
|
21
26
|
lineEnd: '\' +',
|
|
22
27
|
}) + '\'';
|
|
23
28
|
}
|
|
24
|
-
|
|
29
|
+
exports.wrapQuotedString = wrapQuotedString;
|
|
30
|
+
function wrapStringArray(arr, indent, currentColumn) {
|
|
25
31
|
const ar1 = arr
|
|
26
32
|
.map((x, i, a) => ('\'' + x + '\'') + (i < a.length - 1 ? ', ' : ''));
|
|
27
33
|
return '[' + _printLines(ar1, { indent, currentColumn }) + ']';
|
|
28
34
|
}
|
|
29
|
-
|
|
35
|
+
exports.wrapStringArray = wrapStringArray;
|
|
36
|
+
function wrapTypeArray(arr, indent, currentColumn) {
|
|
30
37
|
const ar1 = arr
|
|
31
38
|
.map((x, i, a) => x + (i < a.length - 1 ? ' | ' : ''));
|
|
32
39
|
return _printLines(ar1, { indent, currentColumn });
|
|
33
40
|
}
|
|
41
|
+
exports.wrapTypeArray = wrapTypeArray;
|
|
34
42
|
function _printLines(arr, opts = {}) {
|
|
35
43
|
let s = '';
|
|
36
44
|
let line = '';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opra/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Opra CLI tools",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,24 +20,23 @@
|
|
|
20
20
|
"copy:bin": "cp -R bin ../../build/cli/bin",
|
|
21
21
|
"lint": "eslint . --max-warnings=0",
|
|
22
22
|
"check": "madge --circular src/**",
|
|
23
|
-
"test": "
|
|
24
|
-
"cover": "
|
|
23
|
+
"test": "jest",
|
|
24
|
+
"cover": "jest --collect-coverage",
|
|
25
25
|
"clean": "npm run clean:src && npm run clean:dist && npm run clean:cover",
|
|
26
26
|
"clean:src": "ts-cleanup -s src --all",
|
|
27
27
|
"clean:dist": "rimraf ../../build/cli ../../build/client",
|
|
28
28
|
"clean:cover": "rimraf ../../coverage/client"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@opra/node-client": "^0.
|
|
31
|
+
"@opra/node-client": "^0.16.0",
|
|
32
32
|
"chalk": "^5.2.0",
|
|
33
|
-
"commander": "^10.0.
|
|
33
|
+
"commander": "^10.0.1",
|
|
34
|
+
"js-string-escape": "^1.0.1",
|
|
34
35
|
"putil-flattentext": "^2.1.1",
|
|
35
|
-
"putil-varhelpers": "^1.6.5"
|
|
36
|
-
"js-string-escape": "^1.0.1"
|
|
36
|
+
"putil-varhelpers": "^1.6.5"
|
|
37
37
|
},
|
|
38
|
-
"devDependencies": {},
|
|
39
38
|
"type": "module",
|
|
40
|
-
"types": "
|
|
39
|
+
"types": "types/index.d.ts",
|
|
41
40
|
"exports": {
|
|
42
41
|
".": {
|
|
43
42
|
"require": "./cjs/index.js",
|
|
@@ -55,6 +54,7 @@
|
|
|
55
54
|
"bin/",
|
|
56
55
|
"cjs/",
|
|
57
56
|
"esm/",
|
|
57
|
+
"types/",
|
|
58
58
|
"LICENSE",
|
|
59
59
|
"README.md"
|
|
60
60
|
],
|
|
@@ -64,4 +64,4 @@
|
|
|
64
64
|
"tool",
|
|
65
65
|
"oprimp"
|
|
66
66
|
]
|
|
67
|
-
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ApiDocument } from '@opra/common';
|
|
2
|
+
import { OpraHttpClient } from '@opra/node-client';
|
|
3
|
+
import { IFileWriter } from '../interfaces/file-writer.interface.js';
|
|
4
|
+
import { ILogger } from '../interfaces/logger.interface.js';
|
|
5
|
+
import { processResources } from './process-resources.js';
|
|
6
|
+
import { generateComplexTypeDefinition, generateEnumTypeDefinition, generateMappedTypeDefinition, generateSimpleTypeDefinition, generateTypeFile, generateUnionTypeDefinition, processTypes, resolveTypeNameOrDef } from './process-types.js';
|
|
7
|
+
import { TsFile } from './ts-file.js';
|
|
8
|
+
export declare namespace ApiExporter {
|
|
9
|
+
interface Config {
|
|
10
|
+
serviceUrl: string;
|
|
11
|
+
outDir: string;
|
|
12
|
+
name?: string;
|
|
13
|
+
cwd?: string;
|
|
14
|
+
logger?: ILogger;
|
|
15
|
+
writer?: IFileWriter;
|
|
16
|
+
fileHeader?: string;
|
|
17
|
+
importExt?: string;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export declare class ApiExporter {
|
|
21
|
+
protected client: OpraHttpClient;
|
|
22
|
+
protected document: ApiDocument;
|
|
23
|
+
protected logger: ILogger;
|
|
24
|
+
protected outDir: string;
|
|
25
|
+
protected cwd: string;
|
|
26
|
+
protected name: string;
|
|
27
|
+
protected fileHeader: string;
|
|
28
|
+
protected writer: IFileWriter;
|
|
29
|
+
protected importExt: string;
|
|
30
|
+
protected files: Record<string, TsFile>;
|
|
31
|
+
protected processResources: typeof processResources;
|
|
32
|
+
protected processTypes: typeof processTypes;
|
|
33
|
+
protected generateTypeFile: typeof generateTypeFile;
|
|
34
|
+
protected generateComplexTypeDefinition: typeof generateComplexTypeDefinition;
|
|
35
|
+
protected generateSimpleTypeDefinition: typeof generateSimpleTypeDefinition;
|
|
36
|
+
protected resolveTypeNameOrDef: typeof resolveTypeNameOrDef;
|
|
37
|
+
protected generateEnumTypeDefinition: typeof generateEnumTypeDefinition;
|
|
38
|
+
protected generateUnionTypeDefinition: typeof generateUnionTypeDefinition;
|
|
39
|
+
protected generateMappedTypeDefinition: typeof generateMappedTypeDefinition;
|
|
40
|
+
protected constructor(config: ApiExporter.Config);
|
|
41
|
+
protected execute(): Promise<void>;
|
|
42
|
+
protected getFile(filePath: string): TsFile;
|
|
43
|
+
protected addFile(filePath: string, returnExists?: boolean): TsFile;
|
|
44
|
+
protected cleanDirectory(dirname: string): void;
|
|
45
|
+
static execute(config: ApiExporter.Config): Promise<void>;
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './api-exporter.js';
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ComplexType, DataType, EnumType, MappedType, SimpleType, UnionType } from '@opra/common';
|
|
2
|
+
import type { ApiExporter } from './api-exporter.js';
|
|
3
|
+
import { TsFile } from './ts-file.js';
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param targetDir
|
|
7
|
+
*/
|
|
8
|
+
export declare function processTypes(this: ApiExporter, targetDir?: string): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @param dataType
|
|
12
|
+
* @param targetDir
|
|
13
|
+
*/
|
|
14
|
+
export declare function generateTypeFile(this: ApiExporter, dataType: DataType, targetDir?: string): Promise<TsFile>;
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
* @param file
|
|
18
|
+
* @param dataType
|
|
19
|
+
* @param forInterface
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveTypeNameOrDef(this: ApiExporter, file: TsFile, dataType: DataType, forInterface?: boolean): Promise<string>;
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* @param file
|
|
25
|
+
* @param dataType
|
|
26
|
+
* @param forInterface
|
|
27
|
+
*/
|
|
28
|
+
export declare function generateComplexTypeDefinition(this: ApiExporter, file: TsFile, dataType: ComplexType, forInterface?: boolean): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @param file
|
|
32
|
+
* @param dataType
|
|
33
|
+
*/
|
|
34
|
+
export declare function generateSimpleTypeDefinition(this: ApiExporter, file: TsFile, dataType: SimpleType): Promise<string>;
|
|
35
|
+
/**
|
|
36
|
+
*
|
|
37
|
+
* @param file
|
|
38
|
+
* @param dataType
|
|
39
|
+
*/
|
|
40
|
+
export declare function generateEnumTypeDefinition(this: ApiExporter, file: TsFile, dataType: EnumType): Promise<string>;
|
|
41
|
+
/**
|
|
42
|
+
*
|
|
43
|
+
* @param file
|
|
44
|
+
* @param dataType
|
|
45
|
+
* @param forInterface
|
|
46
|
+
*/
|
|
47
|
+
export declare function generateUnionTypeDefinition(this: ApiExporter, file: TsFile, dataType: UnionType, forInterface?: boolean): Promise<string>;
|
|
48
|
+
/**
|
|
49
|
+
*
|
|
50
|
+
* @param file
|
|
51
|
+
* @param dataType
|
|
52
|
+
* @param forInterface
|
|
53
|
+
*/
|
|
54
|
+
export declare function generateMappedTypeDefinition(this: ApiExporter, file: TsFile, dataType: MappedType, forInterface?: boolean): Promise<string>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare class TsFile {
|
|
2
|
+
filename: string;
|
|
3
|
+
dirname: string;
|
|
4
|
+
importFiles: Record<string, string[]>;
|
|
5
|
+
exportFiles: Record<string, string[]>;
|
|
6
|
+
exportTypes: string[];
|
|
7
|
+
header: string;
|
|
8
|
+
content: string;
|
|
9
|
+
constructor(filename: string);
|
|
10
|
+
addImportPackage: (name: string, types?: string[]) => void;
|
|
11
|
+
addImportFile: (filename: string, types?: string[]) => void;
|
|
12
|
+
addExportFile: (filename: string, types?: string[]) => void;
|
|
13
|
+
generate(options?: {
|
|
14
|
+
importExt?: string;
|
|
15
|
+
}): string;
|
|
16
|
+
}
|
|
17
|
+
export declare function relativePath(from: string, to: string): string;
|
|
18
|
+
export declare function setExt(filename: string, ext: string): string;
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './api-exporter/index.js';
|