@opra/cli 0.18.4 → 0.19.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/cjs/api-exporter/api-exporter.js +3 -1
- package/cjs/api-exporter/process-resources.js +1 -1
- package/cjs/api-exporter/process-types.js +17 -12
- package/cjs/api-exporter/ts-file.js +9 -3
- package/cjs/oprimp-cli.js +2 -0
- package/esm/api-exporter/api-exporter.js +3 -1
- package/esm/api-exporter/process-resources.js +1 -1
- package/esm/api-exporter/process-types.js +17 -12
- package/esm/api-exporter/ts-file.js +9 -3
- package/esm/oprimp-cli.js +2 -0
- package/package.json +3 -3
- package/types/api-exporter/api-exporter.d.ts +2 -0
- package/types/api-exporter/process-types.d.ts +1 -1
- package/types/api-exporter/ts-file.d.ts +3 -1
|
@@ -27,6 +27,7 @@ class ApiExporter {
|
|
|
27
27
|
this.fileHeader = config.fileHeader || '';
|
|
28
28
|
this.writer = config.writer || new file_writer_js_1.FileWriter();
|
|
29
29
|
this.serviceClassName = config.name;
|
|
30
|
+
this.importExt = config.importExt;
|
|
30
31
|
// this.nsMap = nsMap || new ResponsiveMap(); // implement references later
|
|
31
32
|
}
|
|
32
33
|
async execute() {
|
|
@@ -46,11 +47,12 @@ class ApiExporter {
|
|
|
46
47
|
node_fs_1.default.mkdirSync(this.outDir, { recursive: true });
|
|
47
48
|
await this.processTypes();
|
|
48
49
|
await this.processResources();
|
|
50
|
+
const { importExt } = this;
|
|
49
51
|
// Write files
|
|
50
52
|
for (const file of Object.values(this.files)) {
|
|
51
53
|
const targetDir = node_path_1.default.dirname(file.filename);
|
|
52
54
|
node_fs_1.default.mkdirSync(targetDir, { recursive: true });
|
|
53
|
-
await this.writer.writeFile(file.filename, file.generate());
|
|
55
|
+
await this.writer.writeFile(file.filename, file.generate({ importExt }));
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
58
|
getFile(filePath) {
|
|
@@ -15,7 +15,7 @@ async function processResources(targetDir = '') {
|
|
|
15
15
|
const { document } = this;
|
|
16
16
|
const serviceTs = this.addFile(node_path_1.default.join(targetDir, this.serviceClassName + '.ts'));
|
|
17
17
|
serviceTs.addImportPackage('@opra/client', ['HttpServiceBase']);
|
|
18
|
-
const indexTs = this.addFile('/index.
|
|
18
|
+
const indexTs = this.addFile('/index.ts', true);
|
|
19
19
|
indexTs.addExportFile(serviceTs.filename);
|
|
20
20
|
serviceTs.content = `\nexport class ${this.serviceClassName} extends HttpServiceBase {\n`;
|
|
21
21
|
for (const resource of document.resources.values()) {
|
|
@@ -14,10 +14,11 @@ const internalTypeNames = ['boolean', 'bigint', 'number', 'null', 'string'];
|
|
|
14
14
|
async function processTypes(targetDir = '') {
|
|
15
15
|
this.logger.log(chalk_1.default.yellow('Processing types'));
|
|
16
16
|
const { document } = this;
|
|
17
|
-
const typesTs = this.addFile(node_path_1.default.join(targetDir, 'types.
|
|
17
|
+
const typesTs = this.addFile(node_path_1.default.join(targetDir, 'types.ts'));
|
|
18
18
|
for (const dataType of document.types.values()) {
|
|
19
19
|
const expFile = await this.generateTypeFile(dataType, targetDir);
|
|
20
|
-
|
|
20
|
+
if (expFile)
|
|
21
|
+
typesTs.addExportFile(expFile.filename);
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
exports.processTypes = processTypes;
|
|
@@ -28,15 +29,17 @@ exports.processTypes = processTypes;
|
|
|
28
29
|
*/
|
|
29
30
|
async function generateTypeFile(dataType, targetDir = '') {
|
|
30
31
|
const typeName = dataType.name;
|
|
32
|
+
if (typeName === 'any')
|
|
33
|
+
return;
|
|
31
34
|
if (!typeName)
|
|
32
35
|
throw new TypeError(`DataType has no name`);
|
|
33
36
|
let filePath;
|
|
34
37
|
if (dataType instanceof common_1.SimpleType)
|
|
35
|
-
filePath = '/simple-types.
|
|
38
|
+
filePath = '/simple-types.ts';
|
|
36
39
|
else if (dataType instanceof common_1.ComplexType)
|
|
37
|
-
filePath = `/types/${typeName}-type.
|
|
40
|
+
filePath = `/types/${typeName}-type.ts`;
|
|
38
41
|
else if (dataType instanceof common_1.EnumType) {
|
|
39
|
-
filePath = `/enums/${typeName}-enum.
|
|
42
|
+
filePath = `/enums/${typeName}-enum.ts`;
|
|
40
43
|
}
|
|
41
44
|
else
|
|
42
45
|
throw new TypeError(`Unimplemented DataType (${dataType.kind})`);
|
|
@@ -44,7 +47,7 @@ async function generateTypeFile(dataType, targetDir = '') {
|
|
|
44
47
|
if (file.exportTypes.includes(typeName))
|
|
45
48
|
return file;
|
|
46
49
|
file.exportTypes.push(typeName);
|
|
47
|
-
const indexTs = this.addFile('/index.
|
|
50
|
+
const indexTs = this.addFile('/index.ts', true);
|
|
48
51
|
indexTs.addExportFile(file.filename);
|
|
49
52
|
file.content += `\n/**\n * ${(0, string_utils_js_1.wrapJSDocString)(dataType.description || typeName)}
|
|
50
53
|
* @interface ${typeName}
|
|
@@ -74,6 +77,8 @@ async function resolveTypeNameOrDef(file, dataType, forInterface) {
|
|
|
74
77
|
if (internalTypeNames.includes(dataType.name))
|
|
75
78
|
return dataType.name;
|
|
76
79
|
const f = await this.generateTypeFile(dataType);
|
|
80
|
+
if (!f)
|
|
81
|
+
return '';
|
|
77
82
|
file.addImportFile(f.filename, [dataType.name]);
|
|
78
83
|
return dataType.name;
|
|
79
84
|
}
|
|
@@ -87,7 +92,7 @@ async function resolveTypeNameOrDef(file, dataType, forInterface) {
|
|
|
87
92
|
return this.generateUnionTypeDefinition(file, dataType, forInterface);
|
|
88
93
|
if (dataType instanceof common_1.MappedType)
|
|
89
94
|
return this.generateMappedTypeDefinition(file, dataType, forInterface);
|
|
90
|
-
return '
|
|
95
|
+
return '';
|
|
91
96
|
}
|
|
92
97
|
exports.resolveTypeNameOrDef = resolveTypeNameOrDef;
|
|
93
98
|
/**
|
|
@@ -138,16 +143,16 @@ exports.generateComplexTypeDefinition = generateComplexTypeDefinition;
|
|
|
138
143
|
* @param dataType
|
|
139
144
|
*/
|
|
140
145
|
async function generateSimpleTypeDefinition(file, dataType) {
|
|
141
|
-
if (dataType.
|
|
146
|
+
if (dataType.extendsFrom('boolean'))
|
|
142
147
|
return 'boolean';
|
|
143
|
-
if (dataType.
|
|
148
|
+
if (dataType.extendsFrom('string'))
|
|
144
149
|
return 'string';
|
|
145
|
-
if (dataType.
|
|
150
|
+
if (dataType.extendsFrom('number') || dataType.extendsFrom('integer'))
|
|
146
151
|
return 'number';
|
|
147
|
-
if (dataType.
|
|
152
|
+
if (dataType.extendsFrom('timestamp') || dataType.extendsFrom('date'))
|
|
148
153
|
return 'Date';
|
|
149
154
|
if (dataType.extendsFrom('bigint'))
|
|
150
|
-
return '
|
|
155
|
+
return 'bigint';
|
|
151
156
|
if (dataType.extendsFrom('object'))
|
|
152
157
|
return 'object';
|
|
153
158
|
return 'any';
|
|
@@ -45,7 +45,7 @@ class TsFile {
|
|
|
45
45
|
};
|
|
46
46
|
this.dirname = path_1.default.dirname(filename);
|
|
47
47
|
}
|
|
48
|
-
generate() {
|
|
48
|
+
generate(options) {
|
|
49
49
|
const dirname = path_1.default.dirname(this.filename);
|
|
50
50
|
let output = '/* #!oprimp_auto_generated!# !! Do NOT remove this line */\n' +
|
|
51
51
|
(this.header ? (0, putil_flattentext_1.default)(this.header) + '\n\n' : '\n');
|
|
@@ -54,8 +54,11 @@ class TsFile {
|
|
|
54
54
|
.map(filename => {
|
|
55
55
|
const types = this.importFiles[filename];
|
|
56
56
|
let relFile = filename;
|
|
57
|
-
if (path_1.default.isAbsolute(filename))
|
|
57
|
+
if (path_1.default.isAbsolute(filename)) {
|
|
58
58
|
relFile = relativePath(dirname, filename);
|
|
59
|
+
if (options?.importExt)
|
|
60
|
+
relFile += '.js';
|
|
61
|
+
}
|
|
59
62
|
return `import ${types.length ? '{ ' + types.join(', ') + ' } from ' : ''}'${relFile}';`;
|
|
60
63
|
})
|
|
61
64
|
.join('\n');
|
|
@@ -67,8 +70,11 @@ class TsFile {
|
|
|
67
70
|
.map(filename => {
|
|
68
71
|
const types = this.exportFiles[filename];
|
|
69
72
|
let relFile = filename;
|
|
70
|
-
if (path_1.default.isAbsolute(filename))
|
|
73
|
+
if (path_1.default.isAbsolute(filename)) {
|
|
71
74
|
relFile = relativePath(dirname, filename);
|
|
75
|
+
if (options?.importExt)
|
|
76
|
+
relFile += '.js';
|
|
77
|
+
}
|
|
72
78
|
return `export ${types.length ? '{ ' + types.join(', ') + ' }' : '*'} from '${relFile}';`;
|
|
73
79
|
})
|
|
74
80
|
.join('\n');
|
package/cjs/oprimp-cli.js
CHANGED
|
@@ -16,6 +16,7 @@ commander_1.program
|
|
|
16
16
|
.argument('<serviceUrl>', 'OPRA service url')
|
|
17
17
|
.argument('<outDir>', 'Output directory')
|
|
18
18
|
.option('--name <name>', 'Name of the service')
|
|
19
|
+
.option('--ext', 'Adds js extension to imports')
|
|
19
20
|
.option('--no-color', 'Disables colors in logs messages')
|
|
20
21
|
.action(async (serviceUrl, outDir, options) => {
|
|
21
22
|
if (!options.color)
|
|
@@ -25,6 +26,7 @@ commander_1.program
|
|
|
25
26
|
logger: console,
|
|
26
27
|
outDir,
|
|
27
28
|
name: options.name,
|
|
29
|
+
importExt: options.ext,
|
|
28
30
|
fileHeader: '/* Generated by OPRA Service Generator, Version ' + pkgJson.version + '*/\n' +
|
|
29
31
|
'/* eslint-disable import/extensions,simple-import-sort/imports */\n'
|
|
30
32
|
});
|
|
@@ -23,6 +23,7 @@ export class ApiExporter {
|
|
|
23
23
|
this.fileHeader = config.fileHeader || '';
|
|
24
24
|
this.writer = config.writer || new FileWriter();
|
|
25
25
|
this.serviceClassName = config.name;
|
|
26
|
+
this.importExt = config.importExt;
|
|
26
27
|
// this.nsMap = nsMap || new ResponsiveMap(); // implement references later
|
|
27
28
|
}
|
|
28
29
|
async execute() {
|
|
@@ -42,11 +43,12 @@ export class ApiExporter {
|
|
|
42
43
|
fs.mkdirSync(this.outDir, { recursive: true });
|
|
43
44
|
await this.processTypes();
|
|
44
45
|
await this.processResources();
|
|
46
|
+
const { importExt } = this;
|
|
45
47
|
// Write files
|
|
46
48
|
for (const file of Object.values(this.files)) {
|
|
47
49
|
const targetDir = path.dirname(file.filename);
|
|
48
50
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
49
|
-
await this.writer.writeFile(file.filename, file.generate());
|
|
51
|
+
await this.writer.writeFile(file.filename, file.generate({ importExt }));
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
54
|
getFile(filePath) {
|
|
@@ -11,7 +11,7 @@ export async function processResources(targetDir = '') {
|
|
|
11
11
|
const { document } = this;
|
|
12
12
|
const serviceTs = this.addFile(path.join(targetDir, this.serviceClassName + '.ts'));
|
|
13
13
|
serviceTs.addImportPackage('@opra/client', ['HttpServiceBase']);
|
|
14
|
-
const indexTs = this.addFile('/index.
|
|
14
|
+
const indexTs = this.addFile('/index.ts', true);
|
|
15
15
|
indexTs.addExportFile(serviceTs.filename);
|
|
16
16
|
serviceTs.content = `\nexport class ${this.serviceClassName} extends HttpServiceBase {\n`;
|
|
17
17
|
for (const resource of document.resources.values()) {
|
|
@@ -10,10 +10,11 @@ const internalTypeNames = ['boolean', 'bigint', 'number', 'null', 'string'];
|
|
|
10
10
|
export async function processTypes(targetDir = '') {
|
|
11
11
|
this.logger.log(chalk.yellow('Processing types'));
|
|
12
12
|
const { document } = this;
|
|
13
|
-
const typesTs = this.addFile(path.join(targetDir, 'types.
|
|
13
|
+
const typesTs = this.addFile(path.join(targetDir, 'types.ts'));
|
|
14
14
|
for (const dataType of document.types.values()) {
|
|
15
15
|
const expFile = await this.generateTypeFile(dataType, targetDir);
|
|
16
|
-
|
|
16
|
+
if (expFile)
|
|
17
|
+
typesTs.addExportFile(expFile.filename);
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
/**
|
|
@@ -23,15 +24,17 @@ export async function processTypes(targetDir = '') {
|
|
|
23
24
|
*/
|
|
24
25
|
export async function generateTypeFile(dataType, targetDir = '') {
|
|
25
26
|
const typeName = dataType.name;
|
|
27
|
+
if (typeName === 'any')
|
|
28
|
+
return;
|
|
26
29
|
if (!typeName)
|
|
27
30
|
throw new TypeError(`DataType has no name`);
|
|
28
31
|
let filePath;
|
|
29
32
|
if (dataType instanceof SimpleType)
|
|
30
|
-
filePath = '/simple-types.
|
|
33
|
+
filePath = '/simple-types.ts';
|
|
31
34
|
else if (dataType instanceof ComplexType)
|
|
32
|
-
filePath = `/types/${typeName}-type.
|
|
35
|
+
filePath = `/types/${typeName}-type.ts`;
|
|
33
36
|
else if (dataType instanceof EnumType) {
|
|
34
|
-
filePath = `/enums/${typeName}-enum.
|
|
37
|
+
filePath = `/enums/${typeName}-enum.ts`;
|
|
35
38
|
}
|
|
36
39
|
else
|
|
37
40
|
throw new TypeError(`Unimplemented DataType (${dataType.kind})`);
|
|
@@ -39,7 +42,7 @@ export async function generateTypeFile(dataType, targetDir = '') {
|
|
|
39
42
|
if (file.exportTypes.includes(typeName))
|
|
40
43
|
return file;
|
|
41
44
|
file.exportTypes.push(typeName);
|
|
42
|
-
const indexTs = this.addFile('/index.
|
|
45
|
+
const indexTs = this.addFile('/index.ts', true);
|
|
43
46
|
indexTs.addExportFile(file.filename);
|
|
44
47
|
file.content += `\n/**\n * ${wrapJSDocString(dataType.description || typeName)}
|
|
45
48
|
* @interface ${typeName}
|
|
@@ -68,6 +71,8 @@ export async function resolveTypeNameOrDef(file, dataType, forInterface) {
|
|
|
68
71
|
if (internalTypeNames.includes(dataType.name))
|
|
69
72
|
return dataType.name;
|
|
70
73
|
const f = await this.generateTypeFile(dataType);
|
|
74
|
+
if (!f)
|
|
75
|
+
return '';
|
|
71
76
|
file.addImportFile(f.filename, [dataType.name]);
|
|
72
77
|
return dataType.name;
|
|
73
78
|
}
|
|
@@ -81,7 +86,7 @@ export async function resolveTypeNameOrDef(file, dataType, forInterface) {
|
|
|
81
86
|
return this.generateUnionTypeDefinition(file, dataType, forInterface);
|
|
82
87
|
if (dataType instanceof MappedType)
|
|
83
88
|
return this.generateMappedTypeDefinition(file, dataType, forInterface);
|
|
84
|
-
return '
|
|
89
|
+
return '';
|
|
85
90
|
}
|
|
86
91
|
/**
|
|
87
92
|
*
|
|
@@ -130,16 +135,16 @@ export async function generateComplexTypeDefinition(file, dataType, forInterface
|
|
|
130
135
|
* @param dataType
|
|
131
136
|
*/
|
|
132
137
|
export async function generateSimpleTypeDefinition(file, dataType) {
|
|
133
|
-
if (dataType.
|
|
138
|
+
if (dataType.extendsFrom('boolean'))
|
|
134
139
|
return 'boolean';
|
|
135
|
-
if (dataType.
|
|
140
|
+
if (dataType.extendsFrom('string'))
|
|
136
141
|
return 'string';
|
|
137
|
-
if (dataType.
|
|
142
|
+
if (dataType.extendsFrom('number') || dataType.extendsFrom('integer'))
|
|
138
143
|
return 'number';
|
|
139
|
-
if (dataType.
|
|
144
|
+
if (dataType.extendsFrom('timestamp') || dataType.extendsFrom('date'))
|
|
140
145
|
return 'Date';
|
|
141
146
|
if (dataType.extendsFrom('bigint'))
|
|
142
|
-
return '
|
|
147
|
+
return 'bigint';
|
|
143
148
|
if (dataType.extendsFrom('object'))
|
|
144
149
|
return 'object';
|
|
145
150
|
return 'any';
|
|
@@ -41,7 +41,7 @@ export class TsFile {
|
|
|
41
41
|
};
|
|
42
42
|
this.dirname = path.dirname(filename);
|
|
43
43
|
}
|
|
44
|
-
generate() {
|
|
44
|
+
generate(options) {
|
|
45
45
|
const dirname = path.dirname(this.filename);
|
|
46
46
|
let output = '/* #!oprimp_auto_generated!# !! Do NOT remove this line */\n' +
|
|
47
47
|
(this.header ? flattenText(this.header) + '\n\n' : '\n');
|
|
@@ -50,8 +50,11 @@ export class TsFile {
|
|
|
50
50
|
.map(filename => {
|
|
51
51
|
const types = this.importFiles[filename];
|
|
52
52
|
let relFile = filename;
|
|
53
|
-
if (path.isAbsolute(filename))
|
|
53
|
+
if (path.isAbsolute(filename)) {
|
|
54
54
|
relFile = relativePath(dirname, filename);
|
|
55
|
+
if (options?.importExt)
|
|
56
|
+
relFile += '.js';
|
|
57
|
+
}
|
|
55
58
|
return `import ${types.length ? '{ ' + types.join(', ') + ' } from ' : ''}'${relFile}';`;
|
|
56
59
|
})
|
|
57
60
|
.join('\n');
|
|
@@ -63,8 +66,11 @@ export class TsFile {
|
|
|
63
66
|
.map(filename => {
|
|
64
67
|
const types = this.exportFiles[filename];
|
|
65
68
|
let relFile = filename;
|
|
66
|
-
if (path.isAbsolute(filename))
|
|
69
|
+
if (path.isAbsolute(filename)) {
|
|
67
70
|
relFile = relativePath(dirname, filename);
|
|
71
|
+
if (options?.importExt)
|
|
72
|
+
relFile += '.js';
|
|
73
|
+
}
|
|
68
74
|
return `export ${types.length ? '{ ' + types.join(', ') + ' }' : '*'} from '${relFile}';`;
|
|
69
75
|
})
|
|
70
76
|
.join('\n');
|
package/esm/oprimp-cli.js
CHANGED
|
@@ -13,6 +13,7 @@ program
|
|
|
13
13
|
.argument('<serviceUrl>', 'OPRA service url')
|
|
14
14
|
.argument('<outDir>', 'Output directory')
|
|
15
15
|
.option('--name <name>', 'Name of the service')
|
|
16
|
+
.option('--ext', 'Adds js extension to imports')
|
|
16
17
|
.option('--no-color', 'Disables colors in logs messages')
|
|
17
18
|
.action(async (serviceUrl, outDir, options) => {
|
|
18
19
|
if (!options.color)
|
|
@@ -22,6 +23,7 @@ program
|
|
|
22
23
|
logger: console,
|
|
23
24
|
outDir,
|
|
24
25
|
name: options.name,
|
|
26
|
+
importExt: options.ext,
|
|
25
27
|
fileHeader: '/* Generated by OPRA Service Generator, Version ' + pkgJson.version + '*/\n' +
|
|
26
28
|
'/* eslint-disable import/extensions,simple-import-sort/imports */\n'
|
|
27
29
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opra/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "Opra CLI tools",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"clean:cover": "rimraf ../../coverage/client"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@opra/client": "^0.
|
|
31
|
+
"@opra/client": "^0.19.0",
|
|
32
32
|
"chalk": "^5.2.0",
|
|
33
|
-
"commander": "^
|
|
33
|
+
"commander": "^11.0.0",
|
|
34
34
|
"js-string-escape": "^1.0.1",
|
|
35
35
|
"putil-flattentext": "^2.1.1",
|
|
36
36
|
"putil-varhelpers": "^1.6.5"
|
|
@@ -14,6 +14,7 @@ export declare namespace ApiExporter {
|
|
|
14
14
|
logger?: ILogger;
|
|
15
15
|
writer?: IFileWriter;
|
|
16
16
|
fileHeader?: string;
|
|
17
|
+
importExt?: boolean;
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
export declare class ApiExporter {
|
|
@@ -26,6 +27,7 @@ export declare class ApiExporter {
|
|
|
26
27
|
protected fileHeader: string;
|
|
27
28
|
protected writer: IFileWriter;
|
|
28
29
|
protected files: Record<string, TsFile>;
|
|
30
|
+
protected importExt?: boolean;
|
|
29
31
|
protected processResources: typeof processResources;
|
|
30
32
|
protected processTypes: typeof processTypes;
|
|
31
33
|
protected generateTypeFile: typeof generateTypeFile;
|
|
@@ -11,7 +11,7 @@ export declare function processTypes(this: ApiExporter, targetDir?: string): Pro
|
|
|
11
11
|
* @param dataType
|
|
12
12
|
* @param targetDir
|
|
13
13
|
*/
|
|
14
|
-
export declare function generateTypeFile(this: ApiExporter, dataType: DataType, targetDir?: string): Promise<TsFile>;
|
|
14
|
+
export declare function generateTypeFile(this: ApiExporter, dataType: DataType, targetDir?: string): Promise<TsFile | undefined>;
|
|
15
15
|
/**
|
|
16
16
|
*
|
|
17
17
|
* @param file
|
|
@@ -10,6 +10,8 @@ export declare class TsFile {
|
|
|
10
10
|
addImportPackage: (name: string, types?: string[]) => void;
|
|
11
11
|
addImportFile: (filename: string, types?: string[]) => void;
|
|
12
12
|
addExportFile: (filename: string, types?: string[]) => void;
|
|
13
|
-
generate(
|
|
13
|
+
generate(options?: {
|
|
14
|
+
importExt?: boolean;
|
|
15
|
+
}): string;
|
|
14
16
|
}
|
|
15
17
|
export declare function relativePath(from: string, to: string): string;
|