@opra/cli 0.14.2 → 0.15.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.d.ts +46 -0
- package/esm/api-exporter/api-exporter.js +102 -0
- package/esm/api-exporter/index.d.ts +1 -0
- package/esm/api-exporter/index.js +1 -0
- package/esm/api-exporter/process-resources.d.ts +6 -0
- package/esm/api-exporter/process-resources.js +45 -0
- package/esm/api-exporter/process-types.d.ts +54 -0
- package/esm/api-exporter/process-types.js +203 -0
- package/esm/api-exporter/ts-file.d.ts +18 -0
- package/esm/api-exporter/ts-file.js +83 -0
- package/esm/index.d.ts +1 -1
- package/esm/index.js +1 -1
- package/esm/interfaces/service-generation-context.interface.d.ts +2 -2
- package/esm/{oprimp.js → oprimp-cli.js} +8 -9
- package/package.json +8 -9
- 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/oprimp/delete-files.d.ts +0 -1
- package/esm/oprimp/delete-files.js +0 -22
- 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/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 → api-exporter}/file-writer.d.ts +0 -0
- /package/esm/{oprimp → api-exporter}/file-writer.js +0 -0
- /package/esm/{oprimp.d.ts → oprimp-cli.d.ts} +0 -0
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.processTypes = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
6
|
-
const fs_1 = tslib_1.__importDefault(require("fs"));
|
|
7
|
-
const path_1 = tslib_1.__importDefault(require("path"));
|
|
8
|
-
const common_1 = require("@opra/common");
|
|
9
|
-
const string_utils_js_1 = require("../utils/string-utils.js");
|
|
10
|
-
const ts_file_js_1 = require("../utils/ts-file.js");
|
|
11
|
-
const builtinsMap = {
|
|
12
|
-
base64Binary: 'Buffer',
|
|
13
|
-
dateString: 'string',
|
|
14
|
-
guid: 'string',
|
|
15
|
-
integer: 'number',
|
|
16
|
-
date: 'Date'
|
|
17
|
-
};
|
|
18
|
-
async function processTypes(ctx) {
|
|
19
|
-
const targetDir = path_1.default.join(ctx.absoluteDir, 'types');
|
|
20
|
-
ctx.logger.log(chalk_1.default.yellow('Processing types'));
|
|
21
|
-
const typesTs = new ts_file_js_1.TsFile();
|
|
22
|
-
typesTs.header = ctx.fileHeader;
|
|
23
|
-
let i = 0;
|
|
24
|
-
const builtinsTs = new ts_file_js_1.TsFile();
|
|
25
|
-
typesTs.header = ctx.fileHeader;
|
|
26
|
-
fs_1.default.mkdirSync(targetDir, { recursive: true });
|
|
27
|
-
const typeNames = Array.from(ctx.document.types.keys()).sort();
|
|
28
|
-
for (const typeName of typeNames) {
|
|
29
|
-
const dataType = ctx.document.getDataType(typeName);
|
|
30
|
-
if (dataType.isBuiltin) {
|
|
31
|
-
if (!builtinsMap[dataType.name])
|
|
32
|
-
continue;
|
|
33
|
-
typesTs.addExport('./types/builtins' + ctx.extension);
|
|
34
|
-
builtinsTs.content += `export type ${dataType.name} = ${builtinsMap[dataType.name]};\n`;
|
|
35
|
-
continue;
|
|
36
|
-
}
|
|
37
|
-
const tsFile = new ts_file_js_1.TsFile();
|
|
38
|
-
tsFile.header = ctx.fileHeader;
|
|
39
|
-
tsFile.content = `\n/**\n * ${(0, string_utils_js_1.wrapJSDocString)(dataType.description || dataType.name)}
|
|
40
|
-
* @type ${dataType.name}
|
|
41
|
-
* @kind ${dataType.kind}
|
|
42
|
-
* @url ${(0, common_1.joinPath)(ctx.serviceUrl, '$metadata/types/' + dataType.name)}
|
|
43
|
-
*/\n`;
|
|
44
|
-
const filename = `./types/${dataType.name}`;
|
|
45
|
-
if (dataType instanceof common_1.ComplexType) {
|
|
46
|
-
await generateComplexType(ctx, dataType, tsFile);
|
|
47
|
-
await tsFile.writeFile(ctx, path_1.default.join(targetDir, dataType.name + '.ts'));
|
|
48
|
-
typesTs.addExport(`${filename}` + ctx.extension);
|
|
49
|
-
i++;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
await builtinsTs.writeFile(ctx, path_1.default.join(targetDir, 'builtins.ts'));
|
|
53
|
-
if (i) {
|
|
54
|
-
await typesTs.writeFile(ctx, path_1.default.join(ctx.absoluteDir, 'types.ts'));
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
exports.processTypes = processTypes;
|
|
58
|
-
async function generateComplexType(ctx, dataType, tsFile) {
|
|
59
|
-
tsFile.header = ctx.fileHeader;
|
|
60
|
-
tsFile.content = `
|
|
61
|
-
export class ${dataType.name} {
|
|
62
|
-
constructor(init?: Partial<I${dataType.name}>) {
|
|
63
|
-
if (init)
|
|
64
|
-
Object.assign(this, init);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export interface ${dataType.name} extends I${dataType.name} {
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
interface I${dataType.name}`;
|
|
72
|
-
if (dataType.extends) {
|
|
73
|
-
tsFile.content += ' extends ' +
|
|
74
|
-
dataType.extends.map(ex => {
|
|
75
|
-
tsFile.addImport('./' + ex.type + ctx.extension, ex.type);
|
|
76
|
-
let s = '';
|
|
77
|
-
if (ex.omit)
|
|
78
|
-
s += 'Omit<';
|
|
79
|
-
if (ex.pick)
|
|
80
|
-
s += 'Pick<';
|
|
81
|
-
s += ex.type;
|
|
82
|
-
if (ex.pick)
|
|
83
|
-
s += ex.pick.map(x => `'${x}`).join(' | ') + '>';
|
|
84
|
-
if (ex.omit)
|
|
85
|
-
s += ex.omit.map(x => `'${x}`).join(' | ') + '>';
|
|
86
|
-
return s;
|
|
87
|
-
}).join(', ');
|
|
88
|
-
}
|
|
89
|
-
const getTypeName = (dt) => {
|
|
90
|
-
if (dt.isBuiltin) {
|
|
91
|
-
if (!builtinsMap[dt.name])
|
|
92
|
-
return dt.name;
|
|
93
|
-
tsFile.addImport('./builtins' + ctx.extension, dt.name);
|
|
94
|
-
return dt.name;
|
|
95
|
-
}
|
|
96
|
-
tsFile.addImport('./' + dt.name + ctx.extension, dt.name);
|
|
97
|
-
return dt.name;
|
|
98
|
-
};
|
|
99
|
-
tsFile.content += ' {\n\t';
|
|
100
|
-
for (const f of dataType.ownFields.values()) {
|
|
101
|
-
const fieldType = ctx.document.getDataType(f.type);
|
|
102
|
-
// Print JSDoc
|
|
103
|
-
tsFile.content += `/**\n * ${f.description || f.name}\n`;
|
|
104
|
-
if (f.default)
|
|
105
|
-
tsFile.content += ` * @default ` + f.default + '\n';
|
|
106
|
-
if (f.format)
|
|
107
|
-
tsFile.content += ` * @format ` + f.format + '\n';
|
|
108
|
-
if (f.exclusive)
|
|
109
|
-
tsFile.content += ` * @exclusive\n`;
|
|
110
|
-
if (f.deprecated)
|
|
111
|
-
tsFile.content += ` * @deprecated ` + (typeof f.deprecated === 'string' ? f.deprecated : '') + '\n';
|
|
112
|
-
tsFile.content += ` */\n`;
|
|
113
|
-
// Print field name
|
|
114
|
-
tsFile.content += `${f.name}${f.required ? '' : '?'}: `;
|
|
115
|
-
if (f.fixed)
|
|
116
|
-
tsFile.content += `${f.fixed}`;
|
|
117
|
-
else {
|
|
118
|
-
if (fieldType instanceof common_1.UnionType) {
|
|
119
|
-
const s = fieldType.types.map(t => getTypeName(t)).join(' | ');
|
|
120
|
-
tsFile.content += `(${s})`;
|
|
121
|
-
}
|
|
122
|
-
else
|
|
123
|
-
tsFile.content += `${getTypeName(fieldType)}`;
|
|
124
|
-
tsFile.content += `${f.isArray ? '[]' : ''};\n\n`;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
if (dataType.additionalFields)
|
|
128
|
-
tsFile.content += '[key: string]: any;\n';
|
|
129
|
-
tsFile.content += '\b\b}\n';
|
|
130
|
-
}
|
package/cjs/utils/ts-file.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TsFile = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
6
|
-
const path_1 = tslib_1.__importDefault(require("path"));
|
|
7
|
-
const putil_flattentext_1 = tslib_1.__importDefault(require("putil-flattentext"));
|
|
8
|
-
class TsFile {
|
|
9
|
-
constructor() {
|
|
10
|
-
this.imports = {};
|
|
11
|
-
this.exports = {};
|
|
12
|
-
this.header = '';
|
|
13
|
-
this.content = '';
|
|
14
|
-
this.addImport = (filename, ...imported) => {
|
|
15
|
-
this.imports[filename] = this.imports[filename] || [];
|
|
16
|
-
imported.forEach(x => {
|
|
17
|
-
if (!this.imports[filename].includes(x))
|
|
18
|
-
this.imports[filename].push(x);
|
|
19
|
-
});
|
|
20
|
-
};
|
|
21
|
-
this.addExport = (filename, ...exported) => {
|
|
22
|
-
this.exports[filename] = this.exports[filename] || [];
|
|
23
|
-
exported.forEach(x => {
|
|
24
|
-
if (!this.exports[filename].includes(x))
|
|
25
|
-
this.exports[filename].push(x);
|
|
26
|
-
});
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
generate() {
|
|
30
|
-
let output = '/* #!oprimp_auto_generated!# !! Do NOT remove this line */\n' +
|
|
31
|
-
(this.header ? (0, putil_flattentext_1.default)(this.header) + '\n\n' : '\n');
|
|
32
|
-
const importStr = Object.keys(this.imports)
|
|
33
|
-
.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
|
|
34
|
-
.map(i => `import { ${this.imports[i].join(', ')} } from '${i}';`)
|
|
35
|
-
.join('\n');
|
|
36
|
-
if (importStr)
|
|
37
|
-
output += (0, putil_flattentext_1.default)(importStr) + '\n';
|
|
38
|
-
output += (0, putil_flattentext_1.default)(this.content);
|
|
39
|
-
const exportStr = Object.keys(this.exports)
|
|
40
|
-
.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
|
|
41
|
-
.map(i => {
|
|
42
|
-
const a = this.exports[i];
|
|
43
|
-
return `export ${a.length ? '{' + a.join(', ') + '}' : '*'} from '${i}';`;
|
|
44
|
-
})
|
|
45
|
-
.join('\n');
|
|
46
|
-
if (exportStr)
|
|
47
|
-
output += (0, putil_flattentext_1.default)(exportStr) + '\n';
|
|
48
|
-
return output;
|
|
49
|
-
}
|
|
50
|
-
async writeFile(ctx, filename) {
|
|
51
|
-
await ctx.writer.writeFile(filename, this.generate());
|
|
52
|
-
ctx.logger.log(' - Written', chalk_1.default.whiteBright('./' + path_1.default.relative(ctx.absoluteDir, filename)));
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
exports.TsFile = TsFile;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function deleteFiles(dirname: string): void;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
export function deleteFiles(dirname) {
|
|
4
|
-
if (!fs.existsSync(dirname))
|
|
5
|
-
return;
|
|
6
|
-
const files = fs.readdirSync(dirname);
|
|
7
|
-
for (const f of files) {
|
|
8
|
-
const filename = path.join(dirname, f);
|
|
9
|
-
if (fs.statSync(filename).isDirectory()) {
|
|
10
|
-
deleteFiles(filename);
|
|
11
|
-
if (!fs.readdirSync(filename).length)
|
|
12
|
-
fs.rmdirSync(filename);
|
|
13
|
-
continue;
|
|
14
|
-
}
|
|
15
|
-
if (path.extname(f) === '.ts') {
|
|
16
|
-
const contents = fs.readFileSync(filename, 'utf-8');
|
|
17
|
-
if (contents.includes('#!oprimp_auto_generated!#')) {
|
|
18
|
-
fs.unlinkSync(filename);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { IFileWriter } from '../interfaces/file-writer.interface.js';
|
|
2
|
-
import { ILogger } from '../interfaces/logger.interface.js';
|
|
3
|
-
export interface ServiceGenerateConfig {
|
|
4
|
-
serviceUrl: string;
|
|
5
|
-
outDir: string;
|
|
6
|
-
name?: string;
|
|
7
|
-
cwd?: string;
|
|
8
|
-
logger?: ILogger;
|
|
9
|
-
writer?: IFileWriter;
|
|
10
|
-
fileHeader?: string;
|
|
11
|
-
extension?: string;
|
|
12
|
-
}
|
|
13
|
-
export declare function generateService(config: ServiceGenerateConfig): Promise<void>;
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import console from 'console';
|
|
3
|
-
import * as fs from 'fs';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import * as process from 'process';
|
|
6
|
-
import { OpraHttpClient } from '@opra/node-client';
|
|
7
|
-
import { TsFile } from '../utils/ts-file.js';
|
|
8
|
-
import { deleteFiles } from './delete-files.js';
|
|
9
|
-
import { FileWriter } from './file-writer.js';
|
|
10
|
-
import { processResources } from './process-resoruces.js';
|
|
11
|
-
import { processTypes } from './process-types.js';
|
|
12
|
-
export async function generateService(config) {
|
|
13
|
-
const cwd = config.cwd || process.cwd();
|
|
14
|
-
const logger = config.logger || console;
|
|
15
|
-
try {
|
|
16
|
-
console.log(chalk.yellow('Fetching service metadata from'), chalk.whiteBright(config.serviceUrl));
|
|
17
|
-
const client = await OpraHttpClient.create(config.serviceUrl);
|
|
18
|
-
const metadata = client.metadata;
|
|
19
|
-
console.log(chalk.yellow('Retrieved service info:'), chalk.whiteBright(metadata.info.title), '-', chalk.whiteBright(metadata.info.version));
|
|
20
|
-
console.log(chalk.yellow('Removing old files..'));
|
|
21
|
-
deleteFiles(config.outDir);
|
|
22
|
-
let name = (metadata.info.title || 'Service1').replace(/[^\w_$]*/g, '');
|
|
23
|
-
name = name.charAt(0).toUpperCase() + name.substring(1);
|
|
24
|
-
const ctx = {
|
|
25
|
-
serviceUrl: config.serviceUrl,
|
|
26
|
-
document: client.metadata,
|
|
27
|
-
name,
|
|
28
|
-
logger,
|
|
29
|
-
cwd,
|
|
30
|
-
relativeDir: config.outDir,
|
|
31
|
-
absoluteDir: path.resolve(cwd, config.outDir),
|
|
32
|
-
fileHeader: config.fileHeader || '',
|
|
33
|
-
extension: config.extension,
|
|
34
|
-
writer: config.writer || new FileWriter()
|
|
35
|
-
};
|
|
36
|
-
fs.mkdirSync(ctx.absoluteDir, { recursive: true });
|
|
37
|
-
await processTypes(ctx);
|
|
38
|
-
await processResources(ctx);
|
|
39
|
-
const indexTs = new TsFile();
|
|
40
|
-
indexTs.header = ctx.fileHeader;
|
|
41
|
-
indexTs.addExport('./' + ctx.name + ctx.extension);
|
|
42
|
-
indexTs.addExport('./types' + ctx.extension);
|
|
43
|
-
await indexTs.writeFile(ctx, path.join(ctx.absoluteDir, 'index.ts'));
|
|
44
|
-
}
|
|
45
|
-
catch (error) {
|
|
46
|
-
logger.error(chalk.red(error.message));
|
|
47
|
-
process.exit(1);
|
|
48
|
-
}
|
|
49
|
-
}
|
package/esm/oprimp/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './generate-service.js';
|
package/esm/oprimp/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './generate-service.js';
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { CollectionResourceInfo, joinPath, SingletonResourceInfo } from '@opra/common';
|
|
4
|
-
import { wrapJSDocString } from '../utils/string-utils.js';
|
|
5
|
-
import { TsFile } from '../utils/ts-file.js';
|
|
6
|
-
export async function processResources(ctx) {
|
|
7
|
-
const targetDir = ctx.absoluteDir;
|
|
8
|
-
ctx.logger.log(chalk.yellow('Processing resources'));
|
|
9
|
-
const serviceTs = new TsFile();
|
|
10
|
-
serviceTs.header = ctx.fileHeader;
|
|
11
|
-
serviceTs.addImport('@opra/client', 'OpraHttpClient');
|
|
12
|
-
serviceTs.content = `
|
|
13
|
-
const kClient = Symbol('client');
|
|
14
|
-
|
|
15
|
-
export class ${ctx.name} {
|
|
16
|
-
static kClient = kClient;
|
|
17
|
-
[kClient]: OpraHttpClient;
|
|
18
|
-
|
|
19
|
-
constructor(client: OpraHttpClient) {
|
|
20
|
-
this[kClient] = client;
|
|
21
|
-
}
|
|
22
|
-
`;
|
|
23
|
-
const resourceNames = Array.from(ctx.document.resources.keys()).sort();
|
|
24
|
-
for (const resourceName of resourceNames) {
|
|
25
|
-
const resource = ctx.document.getResource(resourceName);
|
|
26
|
-
serviceTs.content += `\n/**\n * ${wrapJSDocString(resource.description || resource.name)}
|
|
27
|
-
* @url ${joinPath(ctx.serviceUrl, '$metadata/resources/' + resource.name)}
|
|
28
|
-
*/`;
|
|
29
|
-
if (resource instanceof CollectionResourceInfo) {
|
|
30
|
-
serviceTs.addImport('@opra/client', 'HttpCollectionService');
|
|
31
|
-
serviceTs.addImport('./types/' + resource.dataType.name + ctx.extension, resource.dataType.name);
|
|
32
|
-
const methods = resource.getHandlerNames()
|
|
33
|
-
.filter(x => x !== 'count')
|
|
34
|
-
.map(x => `'${x}'`).join(' | ');
|
|
35
|
-
serviceTs.content += `
|
|
36
|
-
get ${resource.name}(): Pick<HttpCollectionService<${resource.dataType.name}, never>, ${methods}> {
|
|
37
|
-
return this[kClient].collection('${resource.name}');
|
|
38
|
-
}\n`;
|
|
39
|
-
}
|
|
40
|
-
else if (resource instanceof SingletonResourceInfo) {
|
|
41
|
-
serviceTs.addImport('@opra/client', 'HttpSingletonService');
|
|
42
|
-
serviceTs.addImport('./types/' + resource.dataType.name + ctx.extension, resource.dataType.name);
|
|
43
|
-
const methods = resource.getHandlerNames()
|
|
44
|
-
.map(x => `'${x}'`).join(' | ');
|
|
45
|
-
serviceTs.content += `
|
|
46
|
-
get ${resource.name}(): Pick<HttpSingletonService<${resource.dataType.name}, never>, ${methods}> {
|
|
47
|
-
return this[kClient].singleton('${resource.name}');
|
|
48
|
-
}\n`;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
serviceTs.content += `
|
|
52
|
-
}\n`;
|
|
53
|
-
await serviceTs.writeFile(ctx, path.join(targetDir, ctx.name + '.ts'));
|
|
54
|
-
}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import { ComplexType, joinPath, UnionType } from '@opra/common';
|
|
5
|
-
import { wrapJSDocString } from '../utils/string-utils.js';
|
|
6
|
-
import { TsFile } from '../utils/ts-file.js';
|
|
7
|
-
const builtinsMap = {
|
|
8
|
-
base64Binary: 'Buffer',
|
|
9
|
-
dateString: 'string',
|
|
10
|
-
guid: 'string',
|
|
11
|
-
integer: 'number',
|
|
12
|
-
date: 'Date'
|
|
13
|
-
};
|
|
14
|
-
export async function processTypes(ctx) {
|
|
15
|
-
const targetDir = path.join(ctx.absoluteDir, 'types');
|
|
16
|
-
ctx.logger.log(chalk.yellow('Processing types'));
|
|
17
|
-
const typesTs = new TsFile();
|
|
18
|
-
typesTs.header = ctx.fileHeader;
|
|
19
|
-
let i = 0;
|
|
20
|
-
const builtinsTs = new TsFile();
|
|
21
|
-
typesTs.header = ctx.fileHeader;
|
|
22
|
-
fs.mkdirSync(targetDir, { recursive: true });
|
|
23
|
-
const typeNames = Array.from(ctx.document.types.keys()).sort();
|
|
24
|
-
for (const typeName of typeNames) {
|
|
25
|
-
const dataType = ctx.document.getDataType(typeName);
|
|
26
|
-
if (dataType.isBuiltin) {
|
|
27
|
-
if (!builtinsMap[dataType.name])
|
|
28
|
-
continue;
|
|
29
|
-
typesTs.addExport('./types/builtins' + ctx.extension);
|
|
30
|
-
builtinsTs.content += `export type ${dataType.name} = ${builtinsMap[dataType.name]};\n`;
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
const tsFile = new TsFile();
|
|
34
|
-
tsFile.header = ctx.fileHeader;
|
|
35
|
-
tsFile.content = `\n/**\n * ${wrapJSDocString(dataType.description || dataType.name)}
|
|
36
|
-
* @type ${dataType.name}
|
|
37
|
-
* @kind ${dataType.kind}
|
|
38
|
-
* @url ${joinPath(ctx.serviceUrl, '$metadata/types/' + dataType.name)}
|
|
39
|
-
*/\n`;
|
|
40
|
-
const filename = `./types/${dataType.name}`;
|
|
41
|
-
if (dataType instanceof ComplexType) {
|
|
42
|
-
await generateComplexType(ctx, dataType, tsFile);
|
|
43
|
-
await tsFile.writeFile(ctx, path.join(targetDir, dataType.name + '.ts'));
|
|
44
|
-
typesTs.addExport(`${filename}` + ctx.extension);
|
|
45
|
-
i++;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
await builtinsTs.writeFile(ctx, path.join(targetDir, 'builtins.ts'));
|
|
49
|
-
if (i) {
|
|
50
|
-
await typesTs.writeFile(ctx, path.join(ctx.absoluteDir, 'types.ts'));
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
async function generateComplexType(ctx, dataType, tsFile) {
|
|
54
|
-
tsFile.header = ctx.fileHeader;
|
|
55
|
-
tsFile.content = `
|
|
56
|
-
export class ${dataType.name} {
|
|
57
|
-
constructor(init?: Partial<I${dataType.name}>) {
|
|
58
|
-
if (init)
|
|
59
|
-
Object.assign(this, init);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export interface ${dataType.name} extends I${dataType.name} {
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
interface I${dataType.name}`;
|
|
67
|
-
if (dataType.extends) {
|
|
68
|
-
tsFile.content += ' extends ' +
|
|
69
|
-
dataType.extends.map(ex => {
|
|
70
|
-
tsFile.addImport('./' + ex.type + ctx.extension, ex.type);
|
|
71
|
-
let s = '';
|
|
72
|
-
if (ex.omit)
|
|
73
|
-
s += 'Omit<';
|
|
74
|
-
if (ex.pick)
|
|
75
|
-
s += 'Pick<';
|
|
76
|
-
s += ex.type;
|
|
77
|
-
if (ex.pick)
|
|
78
|
-
s += ex.pick.map(x => `'${x}`).join(' | ') + '>';
|
|
79
|
-
if (ex.omit)
|
|
80
|
-
s += ex.omit.map(x => `'${x}`).join(' | ') + '>';
|
|
81
|
-
return s;
|
|
82
|
-
}).join(', ');
|
|
83
|
-
}
|
|
84
|
-
const getTypeName = (dt) => {
|
|
85
|
-
if (dt.isBuiltin) {
|
|
86
|
-
if (!builtinsMap[dt.name])
|
|
87
|
-
return dt.name;
|
|
88
|
-
tsFile.addImport('./builtins' + ctx.extension, dt.name);
|
|
89
|
-
return dt.name;
|
|
90
|
-
}
|
|
91
|
-
tsFile.addImport('./' + dt.name + ctx.extension, dt.name);
|
|
92
|
-
return dt.name;
|
|
93
|
-
};
|
|
94
|
-
tsFile.content += ' {\n\t';
|
|
95
|
-
for (const f of dataType.ownFields.values()) {
|
|
96
|
-
const fieldType = ctx.document.getDataType(f.type);
|
|
97
|
-
// Print JSDoc
|
|
98
|
-
tsFile.content += `/**\n * ${f.description || f.name}\n`;
|
|
99
|
-
if (f.default)
|
|
100
|
-
tsFile.content += ` * @default ` + f.default + '\n';
|
|
101
|
-
if (f.format)
|
|
102
|
-
tsFile.content += ` * @format ` + f.format + '\n';
|
|
103
|
-
if (f.exclusive)
|
|
104
|
-
tsFile.content += ` * @exclusive\n`;
|
|
105
|
-
if (f.deprecated)
|
|
106
|
-
tsFile.content += ` * @deprecated ` + (typeof f.deprecated === 'string' ? f.deprecated : '') + '\n';
|
|
107
|
-
tsFile.content += ` */\n`;
|
|
108
|
-
// Print field name
|
|
109
|
-
tsFile.content += `${f.name}${f.required ? '' : '?'}: `;
|
|
110
|
-
if (f.fixed)
|
|
111
|
-
tsFile.content += `${f.fixed}`;
|
|
112
|
-
else {
|
|
113
|
-
if (fieldType instanceof UnionType) {
|
|
114
|
-
const s = fieldType.types.map(t => getTypeName(t)).join(' | ');
|
|
115
|
-
tsFile.content += `(${s})`;
|
|
116
|
-
}
|
|
117
|
-
else
|
|
118
|
-
tsFile.content += `${getTypeName(fieldType)}`;
|
|
119
|
-
tsFile.content += `${f.isArray ? '[]' : ''};\n\n`;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
if (dataType.additionalFields)
|
|
123
|
-
tsFile.content += '[key: string]: any;\n';
|
|
124
|
-
tsFile.content += '\b\b}\n';
|
|
125
|
-
}
|
package/esm/utils/ts-file.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { ServiceGenerationContext } from '../interfaces/service-generation-context.interface.js';
|
|
2
|
-
export declare class TsFile {
|
|
3
|
-
imports: Record<string, string[]>;
|
|
4
|
-
exports: Record<string, string[]>;
|
|
5
|
-
header: string;
|
|
6
|
-
content: string;
|
|
7
|
-
addImport: (filename: string, ...imported: string[]) => void;
|
|
8
|
-
addExport: (filename: string, ...exported: string[]) => void;
|
|
9
|
-
generate(): string;
|
|
10
|
-
writeFile(ctx: ServiceGenerationContext, filename: string): Promise<void>;
|
|
11
|
-
}
|
package/esm/utils/ts-file.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import flattenText from 'putil-flattentext';
|
|
4
|
-
export class TsFile {
|
|
5
|
-
constructor() {
|
|
6
|
-
this.imports = {};
|
|
7
|
-
this.exports = {};
|
|
8
|
-
this.header = '';
|
|
9
|
-
this.content = '';
|
|
10
|
-
this.addImport = (filename, ...imported) => {
|
|
11
|
-
this.imports[filename] = this.imports[filename] || [];
|
|
12
|
-
imported.forEach(x => {
|
|
13
|
-
if (!this.imports[filename].includes(x))
|
|
14
|
-
this.imports[filename].push(x);
|
|
15
|
-
});
|
|
16
|
-
};
|
|
17
|
-
this.addExport = (filename, ...exported) => {
|
|
18
|
-
this.exports[filename] = this.exports[filename] || [];
|
|
19
|
-
exported.forEach(x => {
|
|
20
|
-
if (!this.exports[filename].includes(x))
|
|
21
|
-
this.exports[filename].push(x);
|
|
22
|
-
});
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
generate() {
|
|
26
|
-
let output = '/* #!oprimp_auto_generated!# !! Do NOT remove this line */\n' +
|
|
27
|
-
(this.header ? flattenText(this.header) + '\n\n' : '\n');
|
|
28
|
-
const importStr = Object.keys(this.imports)
|
|
29
|
-
.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
|
|
30
|
-
.map(i => `import { ${this.imports[i].join(', ')} } from '${i}';`)
|
|
31
|
-
.join('\n');
|
|
32
|
-
if (importStr)
|
|
33
|
-
output += flattenText(importStr) + '\n';
|
|
34
|
-
output += flattenText(this.content);
|
|
35
|
-
const exportStr = Object.keys(this.exports)
|
|
36
|
-
.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()))
|
|
37
|
-
.map(i => {
|
|
38
|
-
const a = this.exports[i];
|
|
39
|
-
return `export ${a.length ? '{' + a.join(', ') + '}' : '*'} from '${i}';`;
|
|
40
|
-
})
|
|
41
|
-
.join('\n');
|
|
42
|
-
if (exportStr)
|
|
43
|
-
output += flattenText(exportStr) + '\n';
|
|
44
|
-
return output;
|
|
45
|
-
}
|
|
46
|
-
async writeFile(ctx, filename) {
|
|
47
|
-
await ctx.writer.writeFile(filename, this.generate());
|
|
48
|
-
ctx.logger.log(' - Written', chalk.whiteBright('./' + path.relative(ctx.absoluteDir, filename)));
|
|
49
|
-
}
|
|
50
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|