@vkontakte/api-schema-typescript-generator 0.16.0 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/CODEOWNERS +1 -1
- package/.github/workflows/publish.yml +6 -5
- package/.github/workflows/pull_request.yml +2 -2
- package/.nvmrc +1 -0
- package/LICENSE +1 -1
- package/dist/cli.js +1 -2
- package/dist/generator.js +1 -2
- package/dist/generators/APITypingsGenerator.js +125 -6
- package/dist/generators/enums.js +5 -6
- package/dist/generators/methods.js +1 -2
- package/dist/generators/typeString.js +1 -2
- package/dist/generators/utils/mergeImports.js +1 -2
- package/dist/helpers.js +34 -25
- package/dist/index.js +1 -2
- package/dist/log.js +4 -5
- package/dist/utils.js +10 -11
- package/package.json +9 -6
- package/src/generators/APITypingsGenerator.ts +159 -10
package/.github/CODEOWNERS
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.github/
|
|
1
|
+
.github/ @VKCOM/vk-sec
|
|
@@ -10,14 +10,17 @@ on:
|
|
|
10
10
|
jobs:
|
|
11
11
|
publish:
|
|
12
12
|
runs-on: ubuntu-latest
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read # Recommended for actions/setup-node
|
|
15
|
+
id-token: write # Required for OIDC
|
|
13
16
|
steps:
|
|
14
|
-
- uses: actions/checkout@
|
|
17
|
+
- uses: actions/checkout@v5
|
|
15
18
|
with:
|
|
16
19
|
token: ${{ secrets.DEVTOOLS_GITHUB_TOKEN }}
|
|
17
20
|
|
|
18
|
-
- uses: actions/setup-node@
|
|
21
|
+
- uses: actions/setup-node@v4
|
|
19
22
|
with:
|
|
20
|
-
node-version:
|
|
23
|
+
node-version-file: '.nvmrc'
|
|
21
24
|
cache: 'yarn'
|
|
22
25
|
always-auth: true
|
|
23
26
|
registry-url: 'https://registry.npmjs.org'
|
|
@@ -43,5 +46,3 @@ jobs:
|
|
|
43
46
|
|
|
44
47
|
- name: Publushing release
|
|
45
48
|
run: yarn publish --non-interactive
|
|
46
|
-
env:
|
|
47
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPMJS_PUBLISH_TOKEN }}
|
package/.nvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
v24.11.1
|
package/LICENSE
CHANGED
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.parseArguments =
|
|
6
|
+
exports.parseArguments = parseArguments;
|
|
7
7
|
const arg_1 = __importDefault(require("arg"));
|
|
8
8
|
const utils_1 = require("./utils");
|
|
9
9
|
function parseArguments() {
|
|
@@ -26,4 +26,3 @@ function parseArguments() {
|
|
|
26
26
|
methods: (0, utils_1.trimArray)(args['--methods'] || []),
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
|
-
exports.parseArguments = parseArguments;
|
package/dist/generator.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateImportsBlock =
|
|
3
|
+
exports.generateImportsBlock = generateImportsBlock;
|
|
4
4
|
const constants_1 = require("./constants");
|
|
5
5
|
const helpers_1 = require("./helpers");
|
|
6
6
|
const types_1 = require("./types");
|
|
@@ -38,4 +38,3 @@ function generateImportsBlock(refs, section, type) {
|
|
|
38
38
|
});
|
|
39
39
|
return importLines.join(constants_1.newLineChar);
|
|
40
40
|
}
|
|
41
|
-
exports.generateImportsBlock = generateImportsBlock;
|
|
@@ -280,12 +280,12 @@ class APITypingsGenerator {
|
|
|
280
280
|
}
|
|
281
281
|
generateMethodParams(methodInfo) {
|
|
282
282
|
const section = (0, helpers_1.getMethodSection)(methodInfo.name);
|
|
283
|
-
const interfaceName = `${methodInfo.name} params
|
|
283
|
+
const interfaceName = (0, helpers_1.getInterfaceName)(`${methodInfo.name} params`);
|
|
284
284
|
let imports = {};
|
|
285
285
|
let codeBlocks = [];
|
|
286
286
|
const codeBlock = new TypeCodeBlock_1.TypeCodeBlock({
|
|
287
287
|
type: TypeCodeBlock_1.TypeScriptCodeTypes.Interface,
|
|
288
|
-
interfaceName:
|
|
288
|
+
interfaceName: interfaceName,
|
|
289
289
|
needExport: true,
|
|
290
290
|
allowEmptyInterface: true,
|
|
291
291
|
properties: [],
|
|
@@ -305,6 +305,7 @@ class APITypingsGenerator {
|
|
|
305
305
|
});
|
|
306
306
|
this.appendToFileMap(section, imports, [...codeBlocks, codeBlock]);
|
|
307
307
|
this.generateObjectsFromImports(imports);
|
|
308
|
+
return interfaceName;
|
|
308
309
|
}
|
|
309
310
|
getResponseObjectRef(ref) {
|
|
310
311
|
const objectName = (0, helpers_1.getObjectNameByRef)(ref);
|
|
@@ -404,7 +405,7 @@ class APITypingsGenerator {
|
|
|
404
405
|
generateResponse(section, response) {
|
|
405
406
|
const result = this.getResponseCodeBlock(response);
|
|
406
407
|
if (!result) {
|
|
407
|
-
|
|
408
|
+
throw new Error('Unable to generate response');
|
|
408
409
|
}
|
|
409
410
|
const { codeBlocks, imports } = result;
|
|
410
411
|
this.appendToFileMap(section, imports, codeBlocks);
|
|
@@ -430,14 +431,53 @@ class APITypingsGenerator {
|
|
|
430
431
|
const { method: normalizedMethod, parameterRefs } = (0, methods_1.normalizeMethodInfo)(method);
|
|
431
432
|
method = normalizedMethod;
|
|
432
433
|
this.generateObjectsFromRefs(parameterRefs);
|
|
433
|
-
this.generateMethodParams(new SchemaObject_1.SchemaObject(method.name, method));
|
|
434
|
-
Object.entries(method.responses)
|
|
434
|
+
const methodParamsInterfaceName = this.generateMethodParams(new SchemaObject_1.SchemaObject(method.name, method));
|
|
435
|
+
const methodResponsesInterfaceName = Object.entries(method.responses)
|
|
436
|
+
.map(([responseName, responseObject]) => {
|
|
435
437
|
if (this.ignoredResponses[methodName] && this.ignoredResponses[methodName][responseName]) {
|
|
436
438
|
return;
|
|
437
439
|
}
|
|
438
440
|
const name = `${methodName}_${responseName}`;
|
|
439
|
-
|
|
441
|
+
const interfaceName = (0, helpers_1.getInterfaceName)(name);
|
|
442
|
+
try {
|
|
443
|
+
this.generateResponse(section, new SchemaObject_1.SchemaObject(name, responseObject));
|
|
444
|
+
return interfaceName;
|
|
445
|
+
}
|
|
446
|
+
catch (e) {
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
})
|
|
450
|
+
.filter(Boolean);
|
|
451
|
+
this.generateMethodType(methodName, methodParamsInterfaceName, methodResponsesInterfaceName);
|
|
452
|
+
}
|
|
453
|
+
generateMethodType(methodName, methodParamsInterfaceName, methodResponsesInterfaceName) {
|
|
454
|
+
const codeBlock = new TypeCodeBlock_1.TypeCodeBlock({
|
|
455
|
+
type: TypeCodeBlock_1.TypeScriptCodeTypes.Interface,
|
|
456
|
+
interfaceName: (0, helpers_1.getInterfaceName)(`${methodName} method`),
|
|
457
|
+
needExport: true,
|
|
458
|
+
allowEmptyInterface: true,
|
|
459
|
+
properties: [],
|
|
460
|
+
});
|
|
461
|
+
codeBlock.addProperty({
|
|
462
|
+
name: 'method',
|
|
463
|
+
value: methodName,
|
|
464
|
+
isRequired: true,
|
|
465
|
+
wrapValue: true,
|
|
466
|
+
});
|
|
467
|
+
codeBlock.addProperty({
|
|
468
|
+
name: 'request',
|
|
469
|
+
value: methodParamsInterfaceName,
|
|
470
|
+
isRequired: true,
|
|
440
471
|
});
|
|
472
|
+
codeBlock.addProperty({
|
|
473
|
+
name: 'response',
|
|
474
|
+
value: methodResponsesInterfaceName.length > 0
|
|
475
|
+
? methodResponsesInterfaceName.join(' | ')
|
|
476
|
+
: 'unknown',
|
|
477
|
+
isRequired: true,
|
|
478
|
+
});
|
|
479
|
+
const section = (0, helpers_1.getMethodSection)(methodName);
|
|
480
|
+
this.appendToFileMap(section, {}, [codeBlock]);
|
|
441
481
|
}
|
|
442
482
|
generateMethods() {
|
|
443
483
|
(0, log_1.consoleLogInfo)('creating method params and responses...');
|
|
@@ -448,11 +488,33 @@ class APITypingsGenerator {
|
|
|
448
488
|
});
|
|
449
489
|
Object.keys(this.methodFilesMap).forEach((section) => {
|
|
450
490
|
const { imports, codeBlocks } = this.methodFilesMap[section];
|
|
491
|
+
const methodNames = [];
|
|
451
492
|
codeBlocks.forEach((codeBlock) => {
|
|
452
493
|
if (codeBlock instanceof TypeCodeBlock_1.TypeCodeBlock && codeBlock.needExport && codeBlock.interfaceName) {
|
|
494
|
+
/**
|
|
495
|
+
* for interfaceName structure
|
|
496
|
+
* @see this.generateMethodType
|
|
497
|
+
*/
|
|
498
|
+
if (codeBlock.interfaceName.endsWith('Method')) {
|
|
499
|
+
methodNames.push(codeBlock.interfaceName);
|
|
500
|
+
// Skip export as it will be exported in union type
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
453
503
|
this.registerExport(`./methods/${section}`, codeBlock.interfaceName);
|
|
454
504
|
}
|
|
455
505
|
});
|
|
506
|
+
if (methodNames.length > 0) {
|
|
507
|
+
const sectionMethodsCodeBlock = new TypeCodeBlock_1.TypeCodeBlock({
|
|
508
|
+
type: TypeCodeBlock_1.TypeScriptCodeTypes.Type,
|
|
509
|
+
interfaceName: (0, helpers_1.getInterfaceName)(`${section} methods union`),
|
|
510
|
+
needExport: true,
|
|
511
|
+
allowEmptyInterface: true,
|
|
512
|
+
value: methodNames.join(' | '),
|
|
513
|
+
properties: [],
|
|
514
|
+
});
|
|
515
|
+
codeBlocks.push(sectionMethodsCodeBlock);
|
|
516
|
+
this.registerExport(`./methods/${section}`, sectionMethodsCodeBlock.interfaceName);
|
|
517
|
+
}
|
|
456
518
|
const code = [(0, generator_1.generateImportsBlock)(imports, null), ...codeBlocks];
|
|
457
519
|
this.registerResultFile(path_1.default.join('methods', `${section}.ts`), code.join(constants_1.newLineChar.repeat(2)));
|
|
458
520
|
});
|
|
@@ -513,8 +575,22 @@ class APITypingsGenerator {
|
|
|
513
575
|
},
|
|
514
576
|
],
|
|
515
577
|
}).toString());
|
|
578
|
+
code.push(`
|
|
579
|
+
type MethodOf<M> = M extends { method: string } ? M['method'] : never;
|
|
580
|
+
type RequestOf<M> = M extends { request: unknown } ? M['request'] : never;
|
|
581
|
+
type ResponseOf<M> = M extends { response: unknown } ? M['response'] : never;
|
|
582
|
+
|
|
583
|
+
export type CreateMethodMap<Type extends { method: string }> = {
|
|
584
|
+
[Property in Type as Property['method']]: {
|
|
585
|
+
method: MethodOf<Property>;
|
|
586
|
+
request: RequestOf<Property>;
|
|
587
|
+
response: ResponseOf<Property>;
|
|
588
|
+
};
|
|
589
|
+
};
|
|
590
|
+
`);
|
|
516
591
|
this.registerExport('./common/common', 'API_VERSION');
|
|
517
592
|
this.registerExport('./common/common', (0, helpers_1.getInterfaceName)(constants_1.baseAPIParamsInterfaceName));
|
|
593
|
+
this.registerExport('./common/common', 'CreateMethodMap');
|
|
518
594
|
this.registerResultFile(path_1.default.join('common', 'common.ts'), code.join(constants_1.newLineChar.repeat(2)));
|
|
519
595
|
}
|
|
520
596
|
/**
|
|
@@ -524,6 +600,49 @@ class APITypingsGenerator {
|
|
|
524
600
|
(0, log_1.consoleLogInfo)('creating index.ts exports...');
|
|
525
601
|
const blocks = [];
|
|
526
602
|
let exportedObjects = {};
|
|
603
|
+
let methodNames = new Set();
|
|
604
|
+
(0, utils_1.sortArrayAlphabetically)(Object.keys(this.exports)).forEach((path) => {
|
|
605
|
+
if (!path.startsWith('./methods/')) {
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
const objects = Object.keys(this.exports[path]);
|
|
609
|
+
if (!objects.length) {
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
const blockLines = [];
|
|
613
|
+
(0, utils_1.sortArrayAlphabetically)(objects).forEach((object) => {
|
|
614
|
+
/**
|
|
615
|
+
* for interfaceName structure
|
|
616
|
+
* @see this.generateMethods
|
|
617
|
+
*/
|
|
618
|
+
if (!methodNames.has(object) && /^[A-Z][a-zA-Z0-9]*MethodsUnion$/.test(object)) {
|
|
619
|
+
methodNames.add(object);
|
|
620
|
+
exportedObjects[object] = true; // To skip in export block
|
|
621
|
+
blockLines.push(` ${object},`);
|
|
622
|
+
}
|
|
623
|
+
});
|
|
624
|
+
if (blockLines.length > 0) {
|
|
625
|
+
blockLines.unshift('import type {');
|
|
626
|
+
blockLines.push(`} from '${path.replace('.ts', '')}';`);
|
|
627
|
+
blocks.push(blockLines.join(constants_1.newLineChar));
|
|
628
|
+
}
|
|
629
|
+
});
|
|
630
|
+
blocks.push("import type { CreateMethodMap } from './common/common';");
|
|
631
|
+
const methodsCodeBlock = new TypeCodeBlock_1.TypeCodeBlock({
|
|
632
|
+
type: TypeCodeBlock_1.TypeScriptCodeTypes.Type,
|
|
633
|
+
interfaceName: 'ApiMethodsUnion',
|
|
634
|
+
needExport: false,
|
|
635
|
+
properties: [],
|
|
636
|
+
value: Array.from(methodNames).join(' | '),
|
|
637
|
+
});
|
|
638
|
+
blocks.push(methodsCodeBlock.toString());
|
|
639
|
+
blocks.push(new TypeCodeBlock_1.TypeCodeBlock({
|
|
640
|
+
type: TypeCodeBlock_1.TypeScriptCodeTypes.Type,
|
|
641
|
+
interfaceName: 'ApiMethodsMap',
|
|
642
|
+
needExport: true,
|
|
643
|
+
properties: [],
|
|
644
|
+
value: `CreateMethodMap<${methodsCodeBlock.interfaceName}>`,
|
|
645
|
+
}).toString());
|
|
527
646
|
(0, utils_1.sortArrayAlphabetically)(Object.keys(this.exports)).forEach((path) => {
|
|
528
647
|
const objects = Object.keys(this.exports[path]);
|
|
529
648
|
if (!objects.length) {
|
package/dist/generators/enums.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.isNumericEnum = isNumericEnum;
|
|
4
|
+
exports.getEnumNamesIdentifier = getEnumNamesIdentifier;
|
|
5
|
+
exports.generateEnumConstantObject = generateEnumConstantObject;
|
|
6
|
+
exports.generateEnumAsUnionType = generateEnumAsUnionType;
|
|
7
|
+
exports.generateInlineEnum = generateInlineEnum;
|
|
4
8
|
const constants_1 = require("../constants");
|
|
5
9
|
const helpers_1 = require("../helpers");
|
|
6
10
|
const utils_1 = require("../utils");
|
|
@@ -8,14 +12,12 @@ const TypeCodeBlock_1 = require("./TypeCodeBlock");
|
|
|
8
12
|
function isNumericEnum(object) {
|
|
9
13
|
return object.enum.some((value) => !!+value);
|
|
10
14
|
}
|
|
11
|
-
exports.isNumericEnum = isNumericEnum;
|
|
12
15
|
function getEnumNamesIdentifier(name) {
|
|
13
16
|
if (!name) {
|
|
14
17
|
throw new Error('[getEnumNamesIdentifier] empty name');
|
|
15
18
|
}
|
|
16
19
|
return `${name} enumNames`.trim();
|
|
17
20
|
}
|
|
18
|
-
exports.getEnumNamesIdentifier = getEnumNamesIdentifier;
|
|
19
21
|
function generateEnumConstantObject(object, objectName, enumNames) {
|
|
20
22
|
const enumInterfaceName = (0, helpers_1.getInterfaceName)(objectName);
|
|
21
23
|
const codeBlock = new TypeCodeBlock_1.TypeCodeBlock({
|
|
@@ -34,7 +36,6 @@ function generateEnumConstantObject(object, objectName, enumNames) {
|
|
|
34
36
|
});
|
|
35
37
|
return codeBlock;
|
|
36
38
|
}
|
|
37
|
-
exports.generateEnumConstantObject = generateEnumConstantObject;
|
|
38
39
|
/**
|
|
39
40
|
* Generates enum as union type with constant object if necessary
|
|
40
41
|
*/
|
|
@@ -58,7 +59,6 @@ function generateEnumAsUnionType(object) {
|
|
|
58
59
|
value: '',
|
|
59
60
|
};
|
|
60
61
|
}
|
|
61
|
-
exports.generateEnumAsUnionType = generateEnumAsUnionType;
|
|
62
62
|
function getEnumNames(object) {
|
|
63
63
|
let { enumNames } = object;
|
|
64
64
|
const isNumeric = isNumericEnum(object);
|
|
@@ -112,4 +112,3 @@ function generateInlineEnum(object, options = {}) {
|
|
|
112
112
|
description: descriptionLines.join(constants_1.newLineChar),
|
|
113
113
|
};
|
|
114
114
|
}
|
|
115
|
-
exports.generateInlineEnum = generateInlineEnum;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.normalizeMethodInfo =
|
|
3
|
+
exports.normalizeMethodInfo = normalizeMethodInfo;
|
|
4
4
|
const constants_1 = require("../constants");
|
|
5
5
|
const helpers_1 = require("../helpers");
|
|
6
6
|
const types_1 = require("../types");
|
|
@@ -38,4 +38,3 @@ function normalizeMethodInfo(method) {
|
|
|
38
38
|
parameterRefs,
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
-
exports.normalizeMethodInfo = normalizeMethodInfo;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateTypeString =
|
|
3
|
+
exports.generateTypeString = generateTypeString;
|
|
4
4
|
const constants_1 = require("../constants");
|
|
5
5
|
const enums_1 = require("./enums");
|
|
6
6
|
const helpers_1 = require("../helpers");
|
|
@@ -146,4 +146,3 @@ function generateTypeString(object, objects, options = {}) {
|
|
|
146
146
|
description,
|
|
147
147
|
};
|
|
148
148
|
}
|
|
149
|
-
exports.generateTypeString = generateTypeString;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.mergeImports =
|
|
3
|
+
exports.mergeImports = mergeImports;
|
|
4
4
|
const types_1 = require("../../types");
|
|
5
5
|
function mergeImports(oldImports, newImports) {
|
|
6
6
|
const result = { ...oldImports };
|
|
@@ -13,4 +13,3 @@ function mergeImports(oldImports, newImports) {
|
|
|
13
13
|
});
|
|
14
14
|
return result;
|
|
15
15
|
}
|
|
16
|
-
exports.mergeImports = mergeImports;
|
package/dist/helpers.js
CHANGED
|
@@ -15,18 +15,44 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
37
|
};
|
|
28
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.
|
|
39
|
+
exports.readJSONFile = readJSONFile;
|
|
40
|
+
exports.prepareBuildDirectory = prepareBuildDirectory;
|
|
41
|
+
exports.writeFile = writeFile;
|
|
42
|
+
exports.prepareMethodsPattern = prepareMethodsPattern;
|
|
43
|
+
exports.isMethodNeeded = isMethodNeeded;
|
|
44
|
+
exports.getMethodSection = getMethodSection;
|
|
45
|
+
exports.getInterfaceName = getInterfaceName;
|
|
46
|
+
exports.getEnumPropertyName = getEnumPropertyName;
|
|
47
|
+
exports.getObjectNameByRef = getObjectNameByRef;
|
|
48
|
+
exports.getSectionFromObjectName = getSectionFromObjectName;
|
|
49
|
+
exports.isPatternProperty = isPatternProperty;
|
|
50
|
+
exports.areQuotesNeededForProperty = areQuotesNeededForProperty;
|
|
51
|
+
exports.transformPatternPropertyName = transformPatternPropertyName;
|
|
52
|
+
exports.joinCommentLines = joinCommentLines;
|
|
53
|
+
exports.joinOneOfValues = joinOneOfValues;
|
|
54
|
+
exports.formatArrayDepth = formatArrayDepth;
|
|
55
|
+
exports.resolvePrimitiveTypesArray = resolvePrimitiveTypesArray;
|
|
30
56
|
const fs_1 = __importStar(require("fs"));
|
|
31
57
|
const path_1 = __importDefault(require("path"));
|
|
32
58
|
const utils_1 = require("./utils");
|
|
@@ -37,7 +63,6 @@ async function readJSONFile(path) {
|
|
|
37
63
|
const content = await fs_1.promises.readFile(path, 'utf-8');
|
|
38
64
|
return JSON.parse(content);
|
|
39
65
|
}
|
|
40
|
-
exports.readJSONFile = readJSONFile;
|
|
41
66
|
function deleteDirectoryRecursive(directoryPath) {
|
|
42
67
|
if (fs_1.default.existsSync(directoryPath)) {
|
|
43
68
|
fs_1.default.readdirSync(directoryPath).forEach((file) => {
|
|
@@ -56,7 +81,6 @@ function prepareBuildDirectory(directoryPath) {
|
|
|
56
81
|
deleteDirectoryRecursive(directoryPath);
|
|
57
82
|
fs_1.default.mkdirSync(directoryPath, { recursive: true });
|
|
58
83
|
}
|
|
59
|
-
exports.prepareBuildDirectory = prepareBuildDirectory;
|
|
60
84
|
function writeFile(filePath, code, insertAutoGeneratedNote = true) {
|
|
61
85
|
if (insertAutoGeneratedNote) {
|
|
62
86
|
code =
|
|
@@ -82,7 +106,6 @@ function writeFile(filePath, code, insertAutoGeneratedNote = true) {
|
|
|
82
106
|
});
|
|
83
107
|
fs_1.default.writeFileSync(filePath, code.trim() + constants_1.newLineChar);
|
|
84
108
|
}
|
|
85
|
-
exports.writeFile = writeFile;
|
|
86
109
|
function prepareMethodsPattern(methodsPattern) {
|
|
87
110
|
if (!methodsPattern) {
|
|
88
111
|
(0, log_1.consoleLogErrorAndExit)('methodsPattern is empty. Pass "*" to generate all methods');
|
|
@@ -95,7 +118,6 @@ function prepareMethodsPattern(methodsPattern) {
|
|
|
95
118
|
return acc;
|
|
96
119
|
}, {});
|
|
97
120
|
}
|
|
98
|
-
exports.prepareMethodsPattern = prepareMethodsPattern;
|
|
99
121
|
function isMethodNeeded(methodsPattern, method) {
|
|
100
122
|
const [methodSection, methodName] = method.split('.');
|
|
101
123
|
return Object.keys(methodsPattern).some((pattern) => {
|
|
@@ -109,11 +131,9 @@ function isMethodNeeded(methodsPattern, method) {
|
|
|
109
131
|
return false;
|
|
110
132
|
});
|
|
111
133
|
}
|
|
112
|
-
exports.isMethodNeeded = isMethodNeeded;
|
|
113
134
|
function getMethodSection(methodName) {
|
|
114
135
|
return methodName.split('.')[0];
|
|
115
136
|
}
|
|
116
|
-
exports.getMethodSection = getMethodSection;
|
|
117
137
|
function getInterfaceName(name) {
|
|
118
138
|
name = name
|
|
119
139
|
.replace(/\.|(\s+)|_/g, ' ')
|
|
@@ -122,24 +142,19 @@ function getInterfaceName(name) {
|
|
|
122
142
|
.join('');
|
|
123
143
|
return (0, utils_1.capitalizeFirstLetter)(name);
|
|
124
144
|
}
|
|
125
|
-
exports.getInterfaceName = getInterfaceName;
|
|
126
145
|
function getEnumPropertyName(name) {
|
|
127
146
|
return name.toUpperCase().replace(/\s+/g, '_').replace(/-/g, '_').replace(/\./g, '_');
|
|
128
147
|
}
|
|
129
|
-
exports.getEnumPropertyName = getEnumPropertyName;
|
|
130
148
|
function getObjectNameByRef(ref) {
|
|
131
149
|
const parts = ref.split('/');
|
|
132
150
|
return parts[parts.length - 1];
|
|
133
151
|
}
|
|
134
|
-
exports.getObjectNameByRef = getObjectNameByRef;
|
|
135
152
|
function getSectionFromObjectName(name) {
|
|
136
153
|
return name.split('_')[0];
|
|
137
154
|
}
|
|
138
|
-
exports.getSectionFromObjectName = getSectionFromObjectName;
|
|
139
155
|
function isPatternProperty(name) {
|
|
140
156
|
return name.startsWith('[key: ');
|
|
141
157
|
}
|
|
142
|
-
exports.isPatternProperty = isPatternProperty;
|
|
143
158
|
function areQuotesNeededForProperty(name) {
|
|
144
159
|
name = String(name);
|
|
145
160
|
if (isPatternProperty(name)) {
|
|
@@ -150,14 +165,12 @@ function areQuotesNeededForProperty(name) {
|
|
|
150
165
|
}
|
|
151
166
|
return !(/^[a-z_]([a-z0-9_])+$/i.test(name) || /^[a-z_]/i.test(name));
|
|
152
167
|
}
|
|
153
|
-
exports.areQuotesNeededForProperty = areQuotesNeededForProperty;
|
|
154
168
|
function transformPatternPropertyName(name) {
|
|
155
169
|
if (name === '^[0-9]+$') {
|
|
156
170
|
return '[key: number]';
|
|
157
171
|
}
|
|
158
172
|
return '[key: string] /* default pattern property name */';
|
|
159
173
|
}
|
|
160
|
-
exports.transformPatternPropertyName = transformPatternPropertyName;
|
|
161
174
|
function joinCommentLines(indent = 2, ...description) {
|
|
162
175
|
let descriptionLines = [];
|
|
163
176
|
description.forEach((entry) => {
|
|
@@ -184,7 +197,6 @@ function joinCommentLines(indent = 2, ...description) {
|
|
|
184
197
|
`${indentSpaces} */`,
|
|
185
198
|
];
|
|
186
199
|
}
|
|
187
|
-
exports.joinCommentLines = joinCommentLines;
|
|
188
200
|
function joinOneOfValues(values, primitive) {
|
|
189
201
|
const joined = values.join(' | ');
|
|
190
202
|
if (joined.length > 120) {
|
|
@@ -195,7 +207,6 @@ function joinOneOfValues(values, primitive) {
|
|
|
195
207
|
return joined;
|
|
196
208
|
}
|
|
197
209
|
}
|
|
198
|
-
exports.joinOneOfValues = joinOneOfValues;
|
|
199
210
|
function formatArrayDepth(value, depth) {
|
|
200
211
|
if (value.endsWith("'") || value.includes('|')) {
|
|
201
212
|
return `Array<${value}>` + '[]'.repeat(depth - 1); // Need decrement depth value because of Array<T> has its own depth
|
|
@@ -204,7 +215,6 @@ function formatArrayDepth(value, depth) {
|
|
|
204
215
|
return value + '[]'.repeat(depth);
|
|
205
216
|
}
|
|
206
217
|
}
|
|
207
|
-
exports.formatArrayDepth = formatArrayDepth;
|
|
208
218
|
function resolvePrimitiveTypesArray(types) {
|
|
209
219
|
const isEveryTypePrimitive = types.every((type) => !!constants_1.primitiveTypes[type]);
|
|
210
220
|
if (isEveryTypePrimitive) {
|
|
@@ -212,4 +222,3 @@ function resolvePrimitiveTypesArray(types) {
|
|
|
212
222
|
}
|
|
213
223
|
return null;
|
|
214
224
|
}
|
|
215
|
-
exports.resolvePrimitiveTypesArray = resolvePrimitiveTypesArray;
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.main =
|
|
6
|
+
exports.main = main;
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const perf_hooks_1 = require("perf_hooks");
|
|
@@ -84,4 +84,3 @@ async function main() {
|
|
|
84
84
|
const endTime = perf_hooks_1.performance.now();
|
|
85
85
|
(0, log_1.consoleLog)(`✨ Done in ${((endTime - startTime) / 1000).toFixed(2)}s.`);
|
|
86
86
|
}
|
|
87
|
-
exports.main = main;
|
package/dist/log.js
CHANGED
|
@@ -3,7 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.consoleLog = consoleLog;
|
|
7
|
+
exports.consoleLogInfo = consoleLogInfo;
|
|
8
|
+
exports.consoleLogError = consoleLogError;
|
|
9
|
+
exports.consoleLogErrorAndExit = consoleLogErrorAndExit;
|
|
7
10
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
11
|
const util_1 = require("util");
|
|
9
12
|
function getInspectArgs(args) {
|
|
@@ -23,17 +26,13 @@ function getInspectArgs(args) {
|
|
|
23
26
|
function consoleLog(...args) {
|
|
24
27
|
console.log(...getInspectArgs(args));
|
|
25
28
|
}
|
|
26
|
-
exports.consoleLog = consoleLog;
|
|
27
29
|
function consoleLogInfo(...args) {
|
|
28
30
|
console.log(`${chalk_1.default.cyanBright.bold('info')}`, ...getInspectArgs(args));
|
|
29
31
|
}
|
|
30
|
-
exports.consoleLogInfo = consoleLogInfo;
|
|
31
32
|
function consoleLogError(...args) {
|
|
32
33
|
console.log(`${chalk_1.default.redBright.bold('error')}`, ...getInspectArgs(args));
|
|
33
34
|
}
|
|
34
|
-
exports.consoleLogError = consoleLogError;
|
|
35
35
|
function consoleLogErrorAndExit(...args) {
|
|
36
36
|
consoleLogError(...args);
|
|
37
37
|
process.exit(1);
|
|
38
38
|
}
|
|
39
|
-
exports.consoleLogErrorAndExit = consoleLogErrorAndExit;
|
package/dist/utils.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.flatten = flatten;
|
|
4
|
+
exports.isString = isString;
|
|
5
|
+
exports.isObject = isObject;
|
|
6
|
+
exports.capitalizeFirstLetter = capitalizeFirstLetter;
|
|
7
|
+
exports.uniqueArray = uniqueArray;
|
|
8
|
+
exports.sortArrayAlphabetically = sortArrayAlphabetically;
|
|
9
|
+
exports.arrayToMap = arrayToMap;
|
|
10
|
+
exports.trimStringDoubleSpaces = trimStringDoubleSpaces;
|
|
11
|
+
exports.quoteJavaScriptValue = quoteJavaScriptValue;
|
|
12
|
+
exports.trimArray = trimArray;
|
|
4
13
|
function flatten(input) {
|
|
5
14
|
const stack = [...input];
|
|
6
15
|
const result = [];
|
|
@@ -17,27 +26,21 @@ function flatten(input) {
|
|
|
17
26
|
}
|
|
18
27
|
return result.reverse();
|
|
19
28
|
}
|
|
20
|
-
exports.flatten = flatten;
|
|
21
29
|
function isString(object) {
|
|
22
30
|
return typeof object === 'string';
|
|
23
31
|
}
|
|
24
|
-
exports.isString = isString;
|
|
25
32
|
function isObject(object) {
|
|
26
33
|
return Object.prototype.toString.call(object) === '[object Object]';
|
|
27
34
|
}
|
|
28
|
-
exports.isObject = isObject;
|
|
29
35
|
function capitalizeFirstLetter(string) {
|
|
30
36
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
31
37
|
}
|
|
32
|
-
exports.capitalizeFirstLetter = capitalizeFirstLetter;
|
|
33
38
|
function uniqueArray(array) {
|
|
34
39
|
return array.filter((v, i, a) => a.indexOf(v) === i);
|
|
35
40
|
}
|
|
36
|
-
exports.uniqueArray = uniqueArray;
|
|
37
41
|
function sortArrayAlphabetically(array) {
|
|
38
42
|
return array.sort((a, b) => a.localeCompare(b));
|
|
39
43
|
}
|
|
40
|
-
exports.sortArrayAlphabetically = sortArrayAlphabetically;
|
|
41
44
|
function arrayToMap(array) {
|
|
42
45
|
if (!array) {
|
|
43
46
|
return {};
|
|
@@ -47,15 +50,12 @@ function arrayToMap(array) {
|
|
|
47
50
|
return acc;
|
|
48
51
|
}, {});
|
|
49
52
|
}
|
|
50
|
-
exports.arrayToMap = arrayToMap;
|
|
51
53
|
function trimStringDoubleSpaces(string) {
|
|
52
54
|
return string.trim().replace(/\s\s+/g, ' ');
|
|
53
55
|
}
|
|
54
|
-
exports.trimStringDoubleSpaces = trimStringDoubleSpaces;
|
|
55
56
|
function quoteJavaScriptValue(value) {
|
|
56
57
|
return isString(value) ? `'${value}'` : value;
|
|
57
58
|
}
|
|
58
|
-
exports.quoteJavaScriptValue = quoteJavaScriptValue;
|
|
59
59
|
/**
|
|
60
60
|
* Removes empty string array elements from start and end of array, trim array elements and returns the new array
|
|
61
61
|
*
|
|
@@ -71,4 +71,3 @@ function trimArray(array) {
|
|
|
71
71
|
}
|
|
72
72
|
return trimmedArray;
|
|
73
73
|
}
|
|
74
|
-
exports.trimArray = trimArray;
|
package/package.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vkontakte/api-schema-typescript-generator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "VK API TypeScript generator",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "VK",
|
|
8
8
|
"url": "https://vk.com"
|
|
9
9
|
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
10
13
|
"keywords": [
|
|
11
14
|
"VK",
|
|
12
15
|
"VK API",
|
|
@@ -46,13 +49,13 @@
|
|
|
46
49
|
},
|
|
47
50
|
"devDependencies": {
|
|
48
51
|
"@types/jest": "^28.1.5",
|
|
49
|
-
"@types/node": "^
|
|
50
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
52
|
+
"@types/node": "^22.0.0",
|
|
53
|
+
"@typescript-eslint/eslint-plugin": "5.62.0",
|
|
51
54
|
"@typescript-eslint/parser": "5.62.0",
|
|
52
55
|
"@vkontakte/eslint-config": "3.1.0",
|
|
53
|
-
"eslint": "8.
|
|
54
|
-
"eslint-plugin-react": "7.
|
|
55
|
-
"eslint-plugin-react-hooks": "
|
|
56
|
+
"eslint": "8.57.1",
|
|
57
|
+
"eslint-plugin-react": "7.37.5",
|
|
58
|
+
"eslint-plugin-react-hooks": "5.0.0",
|
|
56
59
|
"jest": "28.1.3",
|
|
57
60
|
"pre-commit": "1.2.2",
|
|
58
61
|
"rimraf": "^3.0.2",
|
|
@@ -382,14 +382,14 @@ export class APITypingsGenerator {
|
|
|
382
382
|
|
|
383
383
|
private generateMethodParams(methodInfo: SchemaObject) {
|
|
384
384
|
const section = getMethodSection(methodInfo.name);
|
|
385
|
-
const interfaceName = `${methodInfo.name} params
|
|
385
|
+
const interfaceName = getInterfaceName(`${methodInfo.name} params`);
|
|
386
386
|
|
|
387
387
|
let imports: RefsDictionary = {};
|
|
388
388
|
let codeBlocks: CodeBlocksArray = [];
|
|
389
389
|
|
|
390
390
|
const codeBlock = new TypeCodeBlock({
|
|
391
391
|
type: TypeScriptCodeTypes.Interface,
|
|
392
|
-
interfaceName:
|
|
392
|
+
interfaceName: interfaceName,
|
|
393
393
|
needExport: true,
|
|
394
394
|
allowEmptyInterface: true,
|
|
395
395
|
properties: [],
|
|
@@ -417,6 +417,8 @@ export class APITypingsGenerator {
|
|
|
417
417
|
|
|
418
418
|
this.appendToFileMap(section, imports, [...codeBlocks, codeBlock]);
|
|
419
419
|
this.generateObjectsFromImports(imports);
|
|
420
|
+
|
|
421
|
+
return interfaceName;
|
|
420
422
|
}
|
|
421
423
|
|
|
422
424
|
private getResponseObjectRef(ref: string): SchemaObject | undefined {
|
|
@@ -543,7 +545,7 @@ export class APITypingsGenerator {
|
|
|
543
545
|
public generateResponse(section: string, response: SchemaObject) {
|
|
544
546
|
const result = this.getResponseCodeBlock(response);
|
|
545
547
|
if (!result) {
|
|
546
|
-
|
|
548
|
+
throw new Error('Unable to generate response');
|
|
547
549
|
}
|
|
548
550
|
|
|
549
551
|
const { codeBlocks, imports } = result;
|
|
@@ -578,16 +580,67 @@ export class APITypingsGenerator {
|
|
|
578
580
|
method = normalizedMethod;
|
|
579
581
|
this.generateObjectsFromRefs(parameterRefs);
|
|
580
582
|
|
|
581
|
-
this.generateMethodParams(
|
|
583
|
+
const methodParamsInterfaceName = this.generateMethodParams(
|
|
584
|
+
new SchemaObject(method.name, method),
|
|
585
|
+
);
|
|
582
586
|
|
|
583
|
-
Object.entries(method.responses)
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
+
const methodResponsesInterfaceName = Object.entries(method.responses)
|
|
588
|
+
.map(([responseName, responseObject]) => {
|
|
589
|
+
if (this.ignoredResponses[methodName] && this.ignoredResponses[methodName][responseName]) {
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
const name = `${methodName}_${responseName}`;
|
|
594
|
+
const interfaceName = getInterfaceName(name);
|
|
595
|
+
try {
|
|
596
|
+
this.generateResponse(section, new SchemaObject(name, responseObject));
|
|
597
|
+
return interfaceName;
|
|
598
|
+
} catch (e) {
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
})
|
|
602
|
+
.filter(Boolean) as string[];
|
|
603
|
+
|
|
604
|
+
this.generateMethodType(methodName, methodParamsInterfaceName, methodResponsesInterfaceName);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
private generateMethodType(
|
|
608
|
+
methodName: string,
|
|
609
|
+
methodParamsInterfaceName: string,
|
|
610
|
+
methodResponsesInterfaceName: string[],
|
|
611
|
+
) {
|
|
612
|
+
const codeBlock = new TypeCodeBlock({
|
|
613
|
+
type: TypeScriptCodeTypes.Interface,
|
|
614
|
+
interfaceName: getInterfaceName(`${methodName} method`),
|
|
615
|
+
needExport: true,
|
|
616
|
+
allowEmptyInterface: true,
|
|
617
|
+
properties: [],
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
codeBlock.addProperty({
|
|
621
|
+
name: 'method',
|
|
622
|
+
value: methodName,
|
|
623
|
+
isRequired: true,
|
|
624
|
+
wrapValue: true,
|
|
625
|
+
});
|
|
587
626
|
|
|
588
|
-
|
|
589
|
-
|
|
627
|
+
codeBlock.addProperty({
|
|
628
|
+
name: 'request',
|
|
629
|
+
value: methodParamsInterfaceName,
|
|
630
|
+
isRequired: true,
|
|
590
631
|
});
|
|
632
|
+
|
|
633
|
+
codeBlock.addProperty({
|
|
634
|
+
name: 'response',
|
|
635
|
+
value:
|
|
636
|
+
methodResponsesInterfaceName.length > 0
|
|
637
|
+
? methodResponsesInterfaceName.join(' | ')
|
|
638
|
+
: 'unknown',
|
|
639
|
+
isRequired: true,
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
const section = getMethodSection(methodName);
|
|
643
|
+
this.appendToFileMap(section, {}, [codeBlock]);
|
|
591
644
|
}
|
|
592
645
|
|
|
593
646
|
private generateMethods() {
|
|
@@ -601,11 +654,38 @@ export class APITypingsGenerator {
|
|
|
601
654
|
|
|
602
655
|
Object.keys(this.methodFilesMap).forEach((section) => {
|
|
603
656
|
const { imports, codeBlocks } = this.methodFilesMap[section];
|
|
657
|
+
const methodNames: string[] = [];
|
|
604
658
|
codeBlocks.forEach((codeBlock) => {
|
|
605
659
|
if (codeBlock instanceof TypeCodeBlock && codeBlock.needExport && codeBlock.interfaceName) {
|
|
660
|
+
/**
|
|
661
|
+
* for interfaceName structure
|
|
662
|
+
* @see this.generateMethodType
|
|
663
|
+
*/
|
|
664
|
+
if (codeBlock.interfaceName.endsWith('Method')) {
|
|
665
|
+
methodNames.push(codeBlock.interfaceName);
|
|
666
|
+
// Skip export as it will be exported in union type
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
|
|
606
670
|
this.registerExport(`./methods/${section}`, codeBlock.interfaceName);
|
|
607
671
|
}
|
|
608
672
|
});
|
|
673
|
+
|
|
674
|
+
if (methodNames.length > 0) {
|
|
675
|
+
const sectionMethodsCodeBlock = new TypeCodeBlock({
|
|
676
|
+
type: TypeScriptCodeTypes.Type,
|
|
677
|
+
interfaceName: getInterfaceName(`${section} methods union`),
|
|
678
|
+
needExport: true,
|
|
679
|
+
allowEmptyInterface: true,
|
|
680
|
+
value: methodNames.join(' | '),
|
|
681
|
+
properties: [],
|
|
682
|
+
});
|
|
683
|
+
|
|
684
|
+
codeBlocks.push(sectionMethodsCodeBlock);
|
|
685
|
+
|
|
686
|
+
this.registerExport(`./methods/${section}`, sectionMethodsCodeBlock.interfaceName);
|
|
687
|
+
}
|
|
688
|
+
|
|
609
689
|
const code = [generateImportsBlock(imports, null), ...codeBlocks];
|
|
610
690
|
|
|
611
691
|
this.registerResultFile(
|
|
@@ -685,8 +765,23 @@ export class APITypingsGenerator {
|
|
|
685
765
|
}).toString(),
|
|
686
766
|
);
|
|
687
767
|
|
|
768
|
+
code.push(`
|
|
769
|
+
type MethodOf<M> = M extends { method: string } ? M['method'] : never;
|
|
770
|
+
type RequestOf<M> = M extends { request: unknown } ? M['request'] : never;
|
|
771
|
+
type ResponseOf<M> = M extends { response: unknown } ? M['response'] : never;
|
|
772
|
+
|
|
773
|
+
export type CreateMethodMap<Type extends { method: string }> = {
|
|
774
|
+
[Property in Type as Property['method']]: {
|
|
775
|
+
method: MethodOf<Property>;
|
|
776
|
+
request: RequestOf<Property>;
|
|
777
|
+
response: ResponseOf<Property>;
|
|
778
|
+
};
|
|
779
|
+
};
|
|
780
|
+
`);
|
|
781
|
+
|
|
688
782
|
this.registerExport('./common/common', 'API_VERSION');
|
|
689
783
|
this.registerExport('./common/common', getInterfaceName(baseAPIParamsInterfaceName));
|
|
784
|
+
this.registerExport('./common/common', 'CreateMethodMap');
|
|
690
785
|
this.registerResultFile(path.join('common', 'common.ts'), code.join(newLineChar.repeat(2)));
|
|
691
786
|
}
|
|
692
787
|
|
|
@@ -698,6 +793,60 @@ export class APITypingsGenerator {
|
|
|
698
793
|
|
|
699
794
|
const blocks: string[] = [];
|
|
700
795
|
let exportedObjects: Dictionary<boolean> = {};
|
|
796
|
+
let methodNames = new Set<string>();
|
|
797
|
+
|
|
798
|
+
sortArrayAlphabetically(Object.keys(this.exports)).forEach((path) => {
|
|
799
|
+
if (!path.startsWith('./methods/')) {
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
const objects = Object.keys(this.exports[path]);
|
|
804
|
+
if (!objects.length) {
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
const blockLines: string[] = [];
|
|
809
|
+
|
|
810
|
+
sortArrayAlphabetically(objects).forEach((object) => {
|
|
811
|
+
/**
|
|
812
|
+
* for interfaceName structure
|
|
813
|
+
* @see this.generateMethods
|
|
814
|
+
*/
|
|
815
|
+
if (!methodNames.has(object) && /^[A-Z][a-zA-Z0-9]*MethodsUnion$/.test(object)) {
|
|
816
|
+
methodNames.add(object);
|
|
817
|
+
exportedObjects[object] = true; // To skip in export block
|
|
818
|
+
blockLines.push(` ${object},`);
|
|
819
|
+
}
|
|
820
|
+
});
|
|
821
|
+
|
|
822
|
+
if (blockLines.length > 0) {
|
|
823
|
+
blockLines.unshift('import type {');
|
|
824
|
+
blockLines.push(`} from '${path.replace('.ts', '')}';`);
|
|
825
|
+
|
|
826
|
+
blocks.push(blockLines.join(newLineChar));
|
|
827
|
+
}
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
blocks.push("import type { CreateMethodMap } from './common/common';");
|
|
831
|
+
|
|
832
|
+
const methodsCodeBlock = new TypeCodeBlock({
|
|
833
|
+
type: TypeScriptCodeTypes.Type,
|
|
834
|
+
interfaceName: 'ApiMethodsUnion',
|
|
835
|
+
needExport: false,
|
|
836
|
+
properties: [],
|
|
837
|
+
value: Array.from(methodNames).join(' | '),
|
|
838
|
+
});
|
|
839
|
+
blocks.push(methodsCodeBlock.toString());
|
|
840
|
+
|
|
841
|
+
blocks.push(
|
|
842
|
+
new TypeCodeBlock({
|
|
843
|
+
type: TypeScriptCodeTypes.Type,
|
|
844
|
+
interfaceName: 'ApiMethodsMap',
|
|
845
|
+
needExport: true,
|
|
846
|
+
properties: [],
|
|
847
|
+
value: `CreateMethodMap<${methodsCodeBlock.interfaceName}>`,
|
|
848
|
+
}).toString(),
|
|
849
|
+
);
|
|
701
850
|
|
|
702
851
|
sortArrayAlphabetically(Object.keys(this.exports)).forEach((path) => {
|
|
703
852
|
const objects = Object.keys(this.exports[path]);
|