@nestia/migrate 14.0.1 → 14.0.2
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/lib/NestiaMigrateApplication.d.ts +111 -0
- package/lib/NestiaMigrateApplication.js +148 -9
- package/lib/NestiaMigrateApplication.js.map +1 -1
- package/lib/NestiaMigrateApplication.mjs +147 -5
- package/lib/analyzers/NestiaMigrateControllerAnalyzer.d.ts +45 -0
- package/lib/analyzers/NestiaMigrateControllerAnalyzer.js +59 -3
- package/lib/analyzers/NestiaMigrateControllerAnalyzer.js.map +1 -1
- package/lib/analyzers/NestiaMigrateControllerAnalyzer.mjs +9 -3
- package/lib/archivers/NestiaMigrateFileArchiver.d.ts +34 -0
- package/lib/archivers/NestiaMigrateFileArchiver.js +34 -0
- package/lib/archivers/NestiaMigrateFileArchiver.js.map +1 -1
- package/lib/bundles/NEST_TEMPLATE.js +1 -1
- package/lib/bundles/NEST_TEMPLATE.mjs +1 -1
- package/lib/bundles/SDK_TEMPLATE.js +1 -1
- package/lib/bundles/SDK_TEMPLATE.mjs +1 -1
- package/lib/executable/NestiaMigrateCommander.d.ts +36 -0
- package/lib/executable/NestiaMigrateCommander.js +38 -0
- package/lib/executable/NestiaMigrateCommander.js.map +1 -1
- package/lib/executable/NestiaMigrateCommander.mjs +3 -1
- package/lib/executable/NestiaMigrateInquirer.d.ts +29 -0
- package/lib/executable/NestiaMigrateInquirer.js +20 -0
- package/lib/executable/NestiaMigrateInquirer.js.map +1 -1
- package/lib/factories/ExpressionFactory.d.ts +14 -0
- package/lib/factories/ExpressionFactory.js +14 -0
- package/lib/factories/ExpressionFactory.js.map +1 -1
- package/lib/factories/IdentifierFactory.d.ts +20 -0
- package/lib/factories/IdentifierFactory.js +20 -0
- package/lib/factories/IdentifierFactory.js.map +1 -1
- package/lib/factories/LiteralFactory.d.ts +18 -2
- package/lib/factories/LiteralFactory.js +18 -2
- package/lib/factories/LiteralFactory.js.map +1 -1
- package/lib/factories/StatementFactory.d.ts +26 -1
- package/lib/factories/StatementFactory.js +26 -1
- package/lib/factories/StatementFactory.js.map +1 -1
- package/lib/factories/SupportedStringFormats.d.ts +6 -0
- package/lib/factories/SupportedStringFormats.js +33 -0
- package/lib/factories/SupportedStringFormats.js.map +1 -0
- package/lib/factories/SupportedStringFormats.mjs +34 -0
- package/lib/factories/SupportedStringFormats.mjs.map +1 -0
- package/lib/factories/TypeFactory.d.ts +21 -0
- package/lib/factories/TypeFactory.js +13 -0
- package/lib/factories/TypeFactory.js.map +1 -1
- package/lib/factories/TypeLiteralFactory.d.ts +18 -0
- package/lib/factories/TypeLiteralFactory.js +18 -0
- package/lib/factories/TypeLiteralFactory.js.map +1 -1
- package/lib/internal/ts.d.ts +153 -0
- package/lib/internal/ts.js.map +1 -1
- package/lib/programmers/NestiaMigrateApiFileProgrammer.d.ts +31 -0
- package/lib/programmers/NestiaMigrateApiFileProgrammer.js +17 -0
- package/lib/programmers/NestiaMigrateApiFileProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateApiFunctionProgrammer.d.ts +40 -0
- package/lib/programmers/NestiaMigrateApiFunctionProgrammer.js +27 -0
- package/lib/programmers/NestiaMigrateApiFunctionProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateApiNamespaceProgrammer.d.ts +39 -0
- package/lib/programmers/NestiaMigrateApiNamespaceProgrammer.js +26 -0
- package/lib/programmers/NestiaMigrateApiNamespaceProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateApiProgrammer.d.ts +18 -0
- package/lib/programmers/NestiaMigrateApiProgrammer.js +18 -0
- package/lib/programmers/NestiaMigrateApiProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateApiProgrammer.mjs +1 -1
- package/lib/programmers/NestiaMigrateApiSimulationProgrammer.d.ts +40 -0
- package/lib/programmers/NestiaMigrateApiSimulationProgrammer.js +27 -0
- package/lib/programmers/NestiaMigrateApiSimulationProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateApiStartProgrammer.d.ts +17 -0
- package/lib/programmers/NestiaMigrateApiStartProgrammer.js +19 -8
- package/lib/programmers/NestiaMigrateApiStartProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateApiStartProgrammer.mjs +1 -6
- package/lib/programmers/NestiaMigrateDtoProgrammer.d.ts +30 -0
- package/lib/programmers/NestiaMigrateDtoProgrammer.js +17 -0
- package/lib/programmers/NestiaMigrateDtoProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateE2eFileProgrammer.d.ts +39 -0
- package/lib/programmers/NestiaMigrateE2eFileProgrammer.js +26 -0
- package/lib/programmers/NestiaMigrateE2eFileProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateE2eProgrammer.d.ts +16 -0
- package/lib/programmers/NestiaMigrateE2eProgrammer.js +16 -0
- package/lib/programmers/NestiaMigrateE2eProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateImportProgrammer.d.ts +75 -0
- package/lib/programmers/NestiaMigrateImportProgrammer.js +58 -3
- package/lib/programmers/NestiaMigrateImportProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateImportProgrammer.mjs +58 -3
- package/lib/programmers/NestiaMigrateNestControllerProgrammer.d.ts +28 -0
- package/lib/programmers/NestiaMigrateNestControllerProgrammer.js +16 -0
- package/lib/programmers/NestiaMigrateNestControllerProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateNestMethodProgrammer.d.ts +30 -0
- package/lib/programmers/NestiaMigrateNestMethodProgrammer.js +16 -0
- package/lib/programmers/NestiaMigrateNestMethodProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateNestModuleProgrammer.d.ts +16 -0
- package/lib/programmers/NestiaMigrateNestModuleProgrammer.js +16 -0
- package/lib/programmers/NestiaMigrateNestModuleProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateNestProgrammer.d.ts +17 -0
- package/lib/programmers/NestiaMigrateNestProgrammer.js +17 -0
- package/lib/programmers/NestiaMigrateNestProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateSchemaProgrammer.d.ts +16 -0
- package/lib/programmers/NestiaMigrateSchemaProgrammer.js +20 -5
- package/lib/programmers/NestiaMigrateSchemaProgrammer.js.map +1 -1
- package/lib/programmers/NestiaMigrateSchemaProgrammer.mjs +4 -4
- package/lib/structures/INestiaMigrateConfig.d.ts +21 -0
- package/lib/structures/INestiaMigrateContext.d.ts +15 -0
- package/lib/structures/INestiaMigrateController.d.ts +13 -0
- package/lib/structures/INestiaMigrateFile.d.ts +11 -0
- package/lib/utils/FilePrinter.d.ts +33 -0
- package/lib/utils/FilePrinter.js +33 -0
- package/lib/utils/FilePrinter.js.map +1 -1
- package/lib/utils/MapUtil.d.ts +17 -0
- package/lib/utils/MapUtil.js +19 -3
- package/lib/utils/MapUtil.js.map +1 -1
- package/lib/utils/MapUtil.mjs +1 -2
- package/lib/utils/PathTemplate.d.ts +23 -1
- package/lib/utils/PathTemplate.js +15 -1
- package/lib/utils/PathTemplate.js.map +1 -1
- package/lib/utils/RequestBody.d.ts +13 -0
- package/lib/utils/RequestBody.js +13 -0
- package/lib/utils/RequestBody.js.map +1 -1
- package/lib/utils/StringUtil.d.ts +55 -0
- package/lib/utils/StringUtil.js +93 -8
- package/lib/utils/StringUtil.js.map +1 -1
- package/lib/utils/StringUtil.mjs +30 -8
- package/lib/utils/SuccessStatus.d.ts +21 -1
- package/lib/utils/SuccessStatus.js +21 -1
- package/lib/utils/SuccessStatus.js.map +1 -1
- package/package.json +4 -3
- package/src/NestiaMigrateApplication.ts +151 -13
- package/src/analyzers/NestiaMigrateControllerAnalyzer.ts +59 -4
- package/src/archivers/NestiaMigrateFileArchiver.ts +34 -0
- package/src/bundles/NEST_TEMPLATE.ts +1 -1
- package/src/bundles/SDK_TEMPLATE.ts +1 -1
- package/src/executable/NestiaMigrateCommander.ts +40 -0
- package/src/executable/NestiaMigrateInquirer.ts +29 -0
- package/src/factories/ExpressionFactory.ts +14 -0
- package/src/factories/IdentifierFactory.ts +20 -0
- package/src/factories/LiteralFactory.ts +18 -2
- package/src/factories/StatementFactory.ts +26 -1
- package/src/factories/SupportedStringFormats.ts +29 -0
- package/src/factories/TypeFactory.ts +21 -0
- package/src/factories/TypeLiteralFactory.ts +18 -0
- package/src/internal/ts.ts +153 -0
- package/src/programmers/NestiaMigrateApiFileProgrammer.ts +35 -0
- package/src/programmers/NestiaMigrateApiFunctionProgrammer.ts +43 -0
- package/src/programmers/NestiaMigrateApiNamespaceProgrammer.ts +42 -0
- package/src/programmers/NestiaMigrateApiProgrammer.ts +18 -0
- package/src/programmers/NestiaMigrateApiSimulationProgrammer.ts +43 -0
- package/src/programmers/NestiaMigrateApiStartProgrammer.ts +19 -10
- package/src/programmers/NestiaMigrateDtoProgrammer.ts +33 -0
- package/src/programmers/NestiaMigrateE2eFileProgrammer.ts +42 -0
- package/src/programmers/NestiaMigrateE2eProgrammer.ts +16 -0
- package/src/programmers/NestiaMigrateImportProgrammer.ts +86 -5
- package/src/programmers/NestiaMigrateNestControllerProgrammer.ts +30 -0
- package/src/programmers/NestiaMigrateNestMethodProgrammer.ts +34 -0
- package/src/programmers/NestiaMigrateNestModuleProgrammer.ts +16 -0
- package/src/programmers/NestiaMigrateNestProgrammer.ts +17 -0
- package/src/programmers/NestiaMigrateSchemaProgrammer.ts +25 -8
- package/src/structures/INestiaMigrateConfig.ts +26 -0
- package/src/structures/INestiaMigrateContext.ts +17 -0
- package/src/structures/INestiaMigrateController.ts +16 -0
- package/src/structures/INestiaMigrateFile.ts +13 -0
- package/src/utils/FilePrinter.ts +33 -0
- package/src/utils/MapUtil.ts +18 -2
- package/src/utils/PathTemplate.ts +23 -1
- package/src/utils/RequestBody.ts +13 -0
- package/src/utils/StringUtil.ts +101 -9
- package/src/utils/SuccessStatus.ts +21 -1
- package/lib/factories/FormatCheatSheet.d.ts +0 -25
- package/lib/factories/FormatCheatSheet.js +0 -34
- package/lib/factories/FormatCheatSheet.js.map +0 -1
- package/lib/factories/FormatCheatSheet.mjs +0 -31
- package/lib/factories/FormatCheatSheet.mjs.map +0 -1
- package/src/factories/FormatCheatSheet.ts +0 -71
|
@@ -1,5 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String helpers that turn arbitrary text into valid identifiers and names.
|
|
3
|
+
*
|
|
4
|
+
* Identifier escaping traverses the input with a fixed punctuation table and
|
|
5
|
+
* Unicode-aware per-segment replacements; total work and intermediate storage
|
|
6
|
+
* scale with encoded output length.
|
|
7
|
+
*
|
|
8
|
+
* @evidence contracts/common.md#principled-implementation The namespace holds the capitalization, path segment normalization, and identifier escaping rules used by the generators.
|
|
9
|
+
* @evidence contracts/common.md#clear-and-simple-design Three functions and private tables of reserved words and replacements.
|
|
10
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The tables are the language's reserved words and a fixed replacement of punctuation.
|
|
11
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
12
|
+
*/
|
|
1
13
|
export declare namespace StringUtil {
|
|
14
|
+
/**
|
|
15
|
+
* Upper-cases the first character and lower-cases the rest; an empty string
|
|
16
|
+
* stays empty.
|
|
17
|
+
*
|
|
18
|
+
* One leading-character conversion and one remainder conversion cost O(N) in
|
|
19
|
+
* the input length.
|
|
20
|
+
*
|
|
21
|
+
* @evidence contracts/common.md#principled-implementation The first character is transformed alone and the remainder is lower-cased, so the result is a normalized word.
|
|
22
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression.
|
|
23
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It applies to every input.
|
|
24
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the rule and the empty case.
|
|
25
|
+
*/
|
|
2
26
|
const capitalize: (str: string) => string;
|
|
27
|
+
/**
|
|
28
|
+
* Splits a path by slashes and normalizes each non-empty segment into a name.
|
|
29
|
+
*
|
|
30
|
+
* The path is split once and each segment normalized with a fixed number of
|
|
31
|
+
* transformations: O(N) total text work and output storage.
|
|
32
|
+
*
|
|
33
|
+
* @evidence contracts/common.md#principled-implementation Each segment loses dots and dashes, a reserved word or a leading digit gets an underscore prefix, and empty segments are dropped.
|
|
34
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression over the private normalizer.
|
|
35
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The rules apply to every segment.
|
|
36
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the normalization.
|
|
37
|
+
*/
|
|
3
38
|
const splitWithNormalization: (path: string) => string[];
|
|
39
|
+
/**
|
|
40
|
+
* Escapes a string into a valid, possibly qualified, name.
|
|
41
|
+
*
|
|
42
|
+
* A dot separates the segments of a qualified name, so each segment is
|
|
43
|
+
* escaped as one identifier. Punctuation is replaced by a word such as
|
|
44
|
+
* `_at_`, any other character an identifier cannot hold by its code point, a
|
|
45
|
+
* reserved word or a segment that cannot start an identifier gets an
|
|
46
|
+
* underscore prefix, and an empty segment is `_empty_`. The last segment
|
|
47
|
+
* names a type, so it is also prefixed when it is a predefined type name.
|
|
48
|
+
*
|
|
49
|
+
* A fixed punctuation table traverses the text before per-segment Unicode
|
|
50
|
+
* escaping. Work scales linearly with the encoded text length for the fixed
|
|
51
|
+
* table; expanded code-point spellings are retained only in the returned
|
|
52
|
+
* string.
|
|
53
|
+
*
|
|
54
|
+
* @evidence contracts/common.md#principled-implementation Whitespace at the edges is trimmed and the punctuation table is applied in its fixed order over the whole string; the string is then split at the dots, which stay as the namespace separators the DTO tree reads, and every segment is made an identifier by the ECMAScript rule: characters outside `ID_Continue` become their code point, and a reserved word, a predefined type name in the last segment or a segment not starting with `ID_Start`, `_` or `$` is prefixed with an underscore, so each segment is a valid identifier even where the punctuation table does not cover its characters.
|
|
55
|
+
* @evidence contracts/common.md#clear-and-simple-design One function over one segment helper and three private tables of reserved words, predefined type names and replacements.
|
|
56
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts No schema name is special-cased; the fixed punctuation table and Unicode identifier rules apply to every segment.
|
|
57
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the segment rule, the replacements, the prefixes and the empty case.
|
|
58
|
+
*/
|
|
4
59
|
const escapeNonVariable: (str: string) => string;
|
|
5
60
|
}
|
package/lib/utils/StringUtil.js
CHANGED
|
@@ -1,25 +1,78 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.StringUtil = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* String helpers that turn arbitrary text into valid identifiers and names.
|
|
6
|
+
*
|
|
7
|
+
* Identifier escaping traverses the input with a fixed punctuation table and
|
|
8
|
+
* Unicode-aware per-segment replacements; total work and intermediate storage
|
|
9
|
+
* scale with encoded output length.
|
|
10
|
+
*
|
|
11
|
+
* @evidence contracts/common.md#principled-implementation The namespace holds the capitalization, path segment normalization, and identifier escaping rules used by the generators.
|
|
12
|
+
* @evidence contracts/common.md#clear-and-simple-design Three functions and private tables of reserved words and replacements.
|
|
13
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The tables are the language's reserved words and a fixed replacement of punctuation.
|
|
14
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
15
|
+
*/
|
|
4
16
|
var StringUtil;
|
|
5
17
|
(function (StringUtil) {
|
|
6
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Upper-cases the first character and lower-cases the rest; an empty string
|
|
20
|
+
* stays empty.
|
|
21
|
+
*
|
|
22
|
+
* One leading-character conversion and one remainder conversion cost O(N) in
|
|
23
|
+
* the input length.
|
|
24
|
+
*
|
|
25
|
+
* @evidence contracts/common.md#principled-implementation The first character is transformed alone and the remainder is lower-cased, so the result is a normalized word.
|
|
26
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression.
|
|
27
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It applies to every input.
|
|
28
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the rule and the empty case.
|
|
29
|
+
*/
|
|
30
|
+
StringUtil.capitalize = (str) => str.length === 0 ? str : str[0].toUpperCase() + str.slice(1).toLowerCase();
|
|
31
|
+
/**
|
|
32
|
+
* Splits a path by slashes and normalizes each non-empty segment into a name.
|
|
33
|
+
*
|
|
34
|
+
* The path is split once and each segment normalized with a fixed number of
|
|
35
|
+
* transformations: O(N) total text work and output storage.
|
|
36
|
+
*
|
|
37
|
+
* @evidence contracts/common.md#principled-implementation Each segment loses dots and dashes, a reserved word or a leading digit gets an underscore prefix, and empty segments are dropped.
|
|
38
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression over the private normalizer.
|
|
39
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The rules apply to every segment.
|
|
40
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the normalization.
|
|
41
|
+
*/
|
|
7
42
|
StringUtil.splitWithNormalization = (path) => path
|
|
8
43
|
.split("/")
|
|
9
44
|
.map((str) => normalize(str.trim()))
|
|
10
45
|
.filter((str) => !!str.length);
|
|
46
|
+
/**
|
|
47
|
+
* Escapes a string into a valid, possibly qualified, name.
|
|
48
|
+
*
|
|
49
|
+
* A dot separates the segments of a qualified name, so each segment is
|
|
50
|
+
* escaped as one identifier. Punctuation is replaced by a word such as
|
|
51
|
+
* `_at_`, any other character an identifier cannot hold by its code point, a
|
|
52
|
+
* reserved word or a segment that cannot start an identifier gets an
|
|
53
|
+
* underscore prefix, and an empty segment is `_empty_`. The last segment
|
|
54
|
+
* names a type, so it is also prefixed when it is a predefined type name.
|
|
55
|
+
*
|
|
56
|
+
* A fixed punctuation table traverses the text before per-segment Unicode
|
|
57
|
+
* escaping. Work scales linearly with the encoded text length for the fixed
|
|
58
|
+
* table; expanded code-point spellings are retained only in the returned
|
|
59
|
+
* string.
|
|
60
|
+
*
|
|
61
|
+
* @evidence contracts/common.md#principled-implementation Whitespace at the edges is trimmed and the punctuation table is applied in its fixed order over the whole string; the string is then split at the dots, which stay as the namespace separators the DTO tree reads, and every segment is made an identifier by the ECMAScript rule: characters outside `ID_Continue` become their code point, and a reserved word, a predefined type name in the last segment or a segment not starting with `ID_Start`, `_` or `$` is prefixed with an underscore, so each segment is a valid identifier even where the punctuation table does not cover its characters.
|
|
62
|
+
* @evidence contracts/common.md#clear-and-simple-design One function over one segment helper and three private tables of reserved words, predefined type names and replacements.
|
|
63
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts No schema name is special-cased; the fixed punctuation table and Unicode identifier rules apply to every segment.
|
|
64
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the segment rule, the replacements, the prefixes and the empty case.
|
|
65
|
+
*/
|
|
11
66
|
StringUtil.escapeNonVariable = (str) => {
|
|
12
|
-
str =
|
|
67
|
+
str = str.trim();
|
|
13
68
|
for (const [before, after] of VARIABLE_REPLACERS)
|
|
14
69
|
str = str.split(before).join(after);
|
|
15
|
-
for (let i = 0; i <= 9; ++i)
|
|
16
|
-
if (str[0] === i.toString()) {
|
|
17
|
-
str = "_" + str;
|
|
18
|
-
break;
|
|
19
|
-
}
|
|
20
70
|
if (str === "")
|
|
21
71
|
return "_empty_";
|
|
22
|
-
|
|
72
|
+
const segments = str.split(".");
|
|
73
|
+
return segments
|
|
74
|
+
.map((segment, index) => escapeSegment(segment, index === segments.length - 1))
|
|
75
|
+
.join(".");
|
|
23
76
|
};
|
|
24
77
|
})(StringUtil || (exports.StringUtil = StringUtil = {}));
|
|
25
78
|
const escape = (str) => {
|
|
@@ -30,8 +83,35 @@ const escape = (str) => {
|
|
|
30
83
|
str = `_${str}`;
|
|
31
84
|
return str;
|
|
32
85
|
};
|
|
86
|
+
// One identifier. The patterns are built at run time because the property
|
|
87
|
+
// escapes need a newer script target than the one this package compiles to.
|
|
88
|
+
const NON_IDENTIFIER_PART = new RegExp("[^\\p{ID_Continue}]", "gu");
|
|
89
|
+
const IDENTIFIER_START = new RegExp("^[\\p{ID_Start}_$]", "u");
|
|
90
|
+
const escapeSegment = (segment, type) => {
|
|
91
|
+
segment = segment.replace(NON_IDENTIFIER_PART, (char) => `_u${char.codePointAt(0).toString(16)}_`);
|
|
92
|
+
if (segment.length === 0)
|
|
93
|
+
return "_empty_";
|
|
94
|
+
return RESERVED.has(segment) ||
|
|
95
|
+
(type && TYPE_NAMES.has(segment)) ||
|
|
96
|
+
IDENTIFIER_START.test(segment) === false
|
|
97
|
+
? `_${segment}`
|
|
98
|
+
: segment;
|
|
99
|
+
};
|
|
33
100
|
const normalize = (str) => escape(str.split(".").join("_").split("-").join("_"));
|
|
101
|
+
const TYPE_NAMES = new Set([
|
|
102
|
+
"any",
|
|
103
|
+
"bigint",
|
|
104
|
+
"boolean",
|
|
105
|
+
"never",
|
|
106
|
+
"number",
|
|
107
|
+
"object",
|
|
108
|
+
"string",
|
|
109
|
+
"symbol",
|
|
110
|
+
"undefined",
|
|
111
|
+
"unknown",
|
|
112
|
+
]);
|
|
34
113
|
const RESERVED = new Set([
|
|
114
|
+
"await",
|
|
35
115
|
"break",
|
|
36
116
|
"case",
|
|
37
117
|
"catch",
|
|
@@ -51,9 +131,12 @@ const RESERVED = new Set([
|
|
|
51
131
|
"for",
|
|
52
132
|
"function",
|
|
53
133
|
"if",
|
|
134
|
+
"implements",
|
|
54
135
|
"import",
|
|
55
136
|
"in",
|
|
56
137
|
"instanceof",
|
|
138
|
+
"interface",
|
|
139
|
+
"let",
|
|
57
140
|
"module",
|
|
58
141
|
"new",
|
|
59
142
|
"null",
|
|
@@ -62,6 +145,7 @@ const RESERVED = new Set([
|
|
|
62
145
|
"private",
|
|
63
146
|
"protected",
|
|
64
147
|
"return",
|
|
148
|
+
"static",
|
|
65
149
|
"super",
|
|
66
150
|
"switch",
|
|
67
151
|
"this",
|
|
@@ -73,6 +157,7 @@ const RESERVED = new Set([
|
|
|
73
157
|
"void",
|
|
74
158
|
"while",
|
|
75
159
|
"with",
|
|
160
|
+
"yield",
|
|
76
161
|
]);
|
|
77
162
|
const VARIABLE_REPLACERS = [
|
|
78
163
|
["`", "_backquote_"],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StringUtil.js","sourceRoot":"","sources":["../../src/utils/StringUtil.ts"],"names":[],"mappings":";;;AAAA,IAAiB,UAAU,
|
|
1
|
+
{"version":3,"file":"StringUtil.js","sourceRoot":"","sources":["../../src/utils/StringUtil.ts"],"names":[],"mappings":"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"}
|
package/lib/utils/StringUtil.mjs
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
//#region src/utils/StringUtil.ts
|
|
2
2
|
let StringUtil;
|
|
3
3
|
(function(_StringUtil) {
|
|
4
|
-
_StringUtil.capitalize = (str) => str[0].toUpperCase() + str.slice(1).toLowerCase();
|
|
4
|
+
_StringUtil.capitalize = (str) => str.length === 0 ? str : str[0].toUpperCase() + str.slice(1).toLowerCase();
|
|
5
5
|
_StringUtil.splitWithNormalization = (path) => path.split("/").map((str) => normalize(str.trim())).filter((str) => !!str.length);
|
|
6
6
|
_StringUtil.escapeNonVariable = (str) => {
|
|
7
|
-
str =
|
|
7
|
+
str = str.trim();
|
|
8
8
|
for (const [before, after] of VARIABLE_REPLACERS) str = str.split(before).join(after);
|
|
9
|
-
for (let i = 0; i <= 9; ++i) if (str[0] === i.toString()) {
|
|
10
|
-
str = "_" + str;
|
|
11
|
-
break;
|
|
12
|
-
}
|
|
13
9
|
if (str === "") return "_empty_";
|
|
14
|
-
|
|
10
|
+
const segments = str.split(".");
|
|
11
|
+
return segments.map((segment, index) => escapeSegment(segment, index === segments.length - 1)).join(".");
|
|
15
12
|
};
|
|
16
13
|
})(StringUtil || (StringUtil = {}));
|
|
17
14
|
const escape = (str) => {
|
|
@@ -20,8 +17,28 @@ const escape = (str) => {
|
|
|
20
17
|
else if (str.length !== 0 && "0" <= str[0] && str[0] <= "9") str = `_${str}`;
|
|
21
18
|
return str;
|
|
22
19
|
};
|
|
20
|
+
const NON_IDENTIFIER_PART = /* @__PURE__ */ new RegExp("[^\\p{ID_Continue}]", "gu");
|
|
21
|
+
const IDENTIFIER_START = /* @__PURE__ */ new RegExp("^[\\p{ID_Start}_$]", "u");
|
|
22
|
+
const escapeSegment = (segment, type) => {
|
|
23
|
+
segment = segment.replace(NON_IDENTIFIER_PART, (char) => `_u${char.codePointAt(0).toString(16)}_`);
|
|
24
|
+
if (segment.length === 0) return "_empty_";
|
|
25
|
+
return RESERVED.has(segment) || type && TYPE_NAMES.has(segment) || IDENTIFIER_START.test(segment) === false ? `_${segment}` : segment;
|
|
26
|
+
};
|
|
23
27
|
const normalize = (str) => escape(str.split(".").join("_").split("-").join("_"));
|
|
28
|
+
const TYPE_NAMES = /* @__PURE__ */ new Set([
|
|
29
|
+
"any",
|
|
30
|
+
"bigint",
|
|
31
|
+
"boolean",
|
|
32
|
+
"never",
|
|
33
|
+
"number",
|
|
34
|
+
"object",
|
|
35
|
+
"string",
|
|
36
|
+
"symbol",
|
|
37
|
+
"undefined",
|
|
38
|
+
"unknown"
|
|
39
|
+
]);
|
|
24
40
|
const RESERVED = /* @__PURE__ */ new Set([
|
|
41
|
+
"await",
|
|
25
42
|
"break",
|
|
26
43
|
"case",
|
|
27
44
|
"catch",
|
|
@@ -41,9 +58,12 @@ const RESERVED = /* @__PURE__ */ new Set([
|
|
|
41
58
|
"for",
|
|
42
59
|
"function",
|
|
43
60
|
"if",
|
|
61
|
+
"implements",
|
|
44
62
|
"import",
|
|
45
63
|
"in",
|
|
46
64
|
"instanceof",
|
|
65
|
+
"interface",
|
|
66
|
+
"let",
|
|
47
67
|
"module",
|
|
48
68
|
"new",
|
|
49
69
|
"null",
|
|
@@ -52,6 +72,7 @@ const RESERVED = /* @__PURE__ */ new Set([
|
|
|
52
72
|
"private",
|
|
53
73
|
"protected",
|
|
54
74
|
"return",
|
|
75
|
+
"static",
|
|
55
76
|
"super",
|
|
56
77
|
"switch",
|
|
57
78
|
"this",
|
|
@@ -62,7 +83,8 @@ const RESERVED = /* @__PURE__ */ new Set([
|
|
|
62
83
|
"var",
|
|
63
84
|
"void",
|
|
64
85
|
"while",
|
|
65
|
-
"with"
|
|
86
|
+
"with",
|
|
87
|
+
"yield"
|
|
66
88
|
]);
|
|
67
89
|
const VARIABLE_REPLACERS = [
|
|
68
90
|
["`", "_backquote_"],
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { IHttpMigrateRoute } from "@typia/interface";
|
|
2
|
+
/**
|
|
3
|
+
* Helpers about the success status of a route.
|
|
4
|
+
*
|
|
5
|
+
* @evidence contracts/common.md#principled-implementation The namespace holds the status that the SDK should treat as success and the status that the generated NestJS controller answers.
|
|
6
|
+
* @evidence contracts/common.md#clear-and-simple-design Two functions and one private priority.
|
|
7
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The rules follow HTTP conventions.
|
|
8
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
9
|
+
*/
|
|
2
10
|
export declare namespace SuccessStatus {
|
|
3
11
|
/**
|
|
4
12
|
* The route's success status code, or null when the document declares only a
|
|
@@ -7,8 +15,20 @@ export declare namespace SuccessStatus {
|
|
|
7
15
|
* The success response is the one typia's route composer selects: 200, then
|
|
8
16
|
* 201, then the lowest other 2xx. A bodiless one, such as a 204 No Content,
|
|
9
17
|
* leaves `route.success` null, so its status is read from the responses.
|
|
18
|
+
*
|
|
19
|
+
* @evidence contracts/common.md#principled-implementation The candidates are the 2xx keys of the responses ordered by a fixed priority, and a value that is not a three-digit number is rejected.
|
|
20
|
+
* @evidence contracts/common.md#clear-and-simple-design One function with one priority helper.
|
|
21
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The order is the HTTP convention.
|
|
22
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the selection.
|
|
10
23
|
*/
|
|
11
24
|
const of: (route: IHttpMigrateRoute) => number | null;
|
|
12
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* The status NestJS answers without `@HttpCode()`.
|
|
27
|
+
*
|
|
28
|
+
* @evidence contracts/common.md#principled-implementation NestJS answers 201 for POST and 200 for the other methods when no status is set, so a generated controller matches without an explicit one.
|
|
29
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression.
|
|
30
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The rule is NestJS's.
|
|
31
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the two statuses.
|
|
32
|
+
*/
|
|
13
33
|
const nest: (route: IHttpMigrateRoute) => number;
|
|
14
34
|
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SuccessStatus = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Helpers about the success status of a route.
|
|
6
|
+
*
|
|
7
|
+
* @evidence contracts/common.md#principled-implementation The namespace holds the status that the SDK should treat as success and the status that the generated NestJS controller answers.
|
|
8
|
+
* @evidence contracts/common.md#clear-and-simple-design Two functions and one private priority.
|
|
9
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The rules follow HTTP conventions.
|
|
10
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
11
|
+
*/
|
|
4
12
|
var SuccessStatus;
|
|
5
13
|
(function (SuccessStatus) {
|
|
6
14
|
/**
|
|
@@ -10,6 +18,11 @@ var SuccessStatus;
|
|
|
10
18
|
* The success response is the one typia's route composer selects: 200, then
|
|
11
19
|
* 201, then the lowest other 2xx. A bodiless one, such as a 204 No Content,
|
|
12
20
|
* leaves `route.success` null, so its status is read from the responses.
|
|
21
|
+
*
|
|
22
|
+
* @evidence contracts/common.md#principled-implementation The candidates are the 2xx keys of the responses ordered by a fixed priority, and a value that is not a three-digit number is rejected.
|
|
23
|
+
* @evidence contracts/common.md#clear-and-simple-design One function with one priority helper.
|
|
24
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The order is the HTTP convention.
|
|
25
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the selection.
|
|
13
26
|
*/
|
|
14
27
|
SuccessStatus.of = (route) => {
|
|
15
28
|
var _a;
|
|
@@ -21,7 +34,14 @@ var SuccessStatus;
|
|
|
21
34
|
? Number(status)
|
|
22
35
|
: null;
|
|
23
36
|
};
|
|
24
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* The status NestJS answers without `@HttpCode()`.
|
|
39
|
+
*
|
|
40
|
+
* @evidence contracts/common.md#principled-implementation NestJS answers 201 for POST and 200 for the other methods when no status is set, so a generated controller matches without an explicit one.
|
|
41
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression.
|
|
42
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The rule is NestJS's.
|
|
43
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the two statuses.
|
|
44
|
+
*/
|
|
25
45
|
SuccessStatus.nest = (route) => route.method === "post" ? 201 : 200;
|
|
26
46
|
const priority = (status) => status === "200" ? 0 : status === "201" ? 1 : Number(status);
|
|
27
47
|
})(SuccessStatus || (exports.SuccessStatus = SuccessStatus = {}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SuccessStatus.js","sourceRoot":"","sources":["../../src/utils/SuccessStatus.ts"],"names":[],"mappings":";;;AAEA,IAAiB,aAAa,
|
|
1
|
+
{"version":3,"file":"SuccessStatus.js","sourceRoot":"","sources":["../../src/utils/SuccessStatus.ts"],"names":[],"mappings":";;;AAEA;;;;;;;GAOG;AACH,IAAiB,aAAa,CAsC7B;AAtCD,WAAiB,aAAa;IAC5B;;;;;;;;;;;;OAYG;IACU,gBAAE,GAAG,CAAC,KAAwB,EAAiB,EAAE;;;QAC5D,MAAM,MAAM,SACV,MAAA,KAAK,CAAC,OAAO,0CAAE,MAAM,mCACrB,MAAM,CAAC,IAAI,OAAC,KAAK,CAAC,SAAS,EAAE,CAAC,SAAS,mCAAI,EAAE,CAAC;aAC3C,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;aACpC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,OAAO,MAAM,KAAK,SAAS,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;YACnD,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;YAChB,CAAC,CAAC,IAAI,CAAC;IACX,CAAC,CAAC;IAEF;;;;;;;OAOG;IACU,kBAAI,GAAG,CAAC,KAAwB,EAAU,EAAE,CACvD,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAEtC,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAU,EAAE,CAC1C,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACjE,CAAC,EAtCgB,aAAa,aAAb,aAAa,GAAb,aAAa,QAsC7B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestia/migrate",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.2",
|
|
4
4
|
"description": "Migration program from swagger to NestJS",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -67,10 +67,11 @@
|
|
|
67
67
|
"access": "public"
|
|
68
68
|
},
|
|
69
69
|
"scripts": {
|
|
70
|
-
"build": "pnpm run bundle && rimraf lib && ttsc && tsc --emitDeclarationOnly && rolldown -c
|
|
70
|
+
"build": "pnpm run bundle && rimraf lib && ttsc && tsc --emitDeclarationOnly && rolldown -c",
|
|
71
71
|
"bundle": "node src/executable/bundle.js",
|
|
72
72
|
"dev": "rimraf lib && ttsc --watch",
|
|
73
|
-
"test": "node lib/test"
|
|
73
|
+
"test": "node lib/test",
|
|
74
|
+
"evidence": "evidence"
|
|
74
75
|
},
|
|
75
76
|
"types": "lib/index.d.ts",
|
|
76
77
|
"module": "lib/index.mjs"
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from "@typia/interface";
|
|
10
10
|
import type { IValidation } from "@typia/interface";
|
|
11
11
|
import { HttpMigration, OpenApiConverter } from "@typia/utils";
|
|
12
|
+
import { TreeSet } from "tstl";
|
|
12
13
|
|
|
13
14
|
import { NEST_TEMPLATE } from "./bundles/NEST_TEMPLATE";
|
|
14
15
|
import { SDK_TEMPLATE } from "./bundles/SDK_TEMPLATE";
|
|
@@ -19,6 +20,32 @@ import { NestiaMigrateNestProgrammer } from "./programmers/NestiaMigrateNestProg
|
|
|
19
20
|
import { INestiaMigrateConfig } from "./structures/INestiaMigrateConfig";
|
|
20
21
|
import { INestiaMigrateContext } from "./structures/INestiaMigrateContext";
|
|
21
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Converts an OpenAPI document into a NestJS project or an SDK project, as a
|
|
25
|
+
* map from file path to file content.
|
|
26
|
+
*
|
|
27
|
+
* The constructor analyzes an emended OpenAPI document once; `assert` and
|
|
28
|
+
* `validate` upgrade a document of any supported version to that form first.
|
|
29
|
+
* `nest` and `sdk` then compose the files of the bundled template with the
|
|
30
|
+
* generated ones.
|
|
31
|
+
*
|
|
32
|
+
* The constructor analyzes the document once; generation walks templates and
|
|
33
|
+
* delegates per-route/schema emission, with the context builder’s accessor trie
|
|
34
|
+
* indexing strict prefixes.
|
|
35
|
+
*
|
|
36
|
+
* The instance shares its analyzed application between nest and sdk calls.
|
|
37
|
+
* Generation creates fresh context/accessor copies because its mode and config
|
|
38
|
+
* can differ.
|
|
39
|
+
*
|
|
40
|
+
* One instance retains its original document and analysis until callers release
|
|
41
|
+
* it; generated file maps are returned to callers rather than accumulated on
|
|
42
|
+
* the instance.
|
|
43
|
+
*
|
|
44
|
+
* @evidence contracts/common.md#principled-implementation The constructor analyzes the emended document into routes with `HttpMigration`, and the two generators start from the bundled template files, drop the paths the generators own (structures, functional API, controllers, feature tests), and add the generated files, so the result is the template with those trees replaced.
|
|
45
|
+
* @evidence contracts/common.md#clear-and-simple-design One class with two generators sharing one context builder; the accessor conflict escape and the package renaming are module-private functions.
|
|
46
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Route analysis and the OpenAPI upgrade come from `@typia/utils`, and no document, path, or type name is special-cased; QUERY-method routes are left out because the SDK has no representation for them.
|
|
47
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the class produces, when the document is analyzed, and how the two generators use the template.
|
|
48
|
+
*/
|
|
22
49
|
export class NestiaMigrateApplication {
|
|
23
50
|
private readonly data_: IHttpMigrateApplication;
|
|
24
51
|
|
|
@@ -29,6 +56,18 @@ export class NestiaMigrateApplication {
|
|
|
29
56
|
this.data_ = HttpMigration.application(document);
|
|
30
57
|
}
|
|
31
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Creates the application from a document of any supported OpenAPI or Swagger
|
|
61
|
+
* version, and throws when the document cannot be upgraded.
|
|
62
|
+
*
|
|
63
|
+
* Version conversion and route analysis scale with the document’s routes and
|
|
64
|
+
* schemas; this wrapper delegates each once.
|
|
65
|
+
*
|
|
66
|
+
* @evidence contracts/common.md#principled-implementation The document is upgraded by `OpenApiConverter.upgradeDocument`, which owns the version differences, so this function only wraps a successful result.
|
|
67
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression.
|
|
68
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It does not repair or guess invalid documents.
|
|
69
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the accepted versions and the throwing behavior.
|
|
70
|
+
*/
|
|
32
71
|
public static assert(
|
|
33
72
|
document:
|
|
34
73
|
| SwaggerV2.IDocument
|
|
@@ -42,6 +81,18 @@ export class NestiaMigrateApplication {
|
|
|
42
81
|
);
|
|
43
82
|
}
|
|
44
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Creates the application, or returns the failure as an `IValidation` instead
|
|
86
|
+
* of throwing.
|
|
87
|
+
*
|
|
88
|
+
* Version conversion and route analysis scale with the document’s routes and
|
|
89
|
+
* schemas; validation delegates once and formats one caught failure.
|
|
90
|
+
*
|
|
91
|
+
* @evidence contracts/common.md#principled-implementation The upgrade runs inside a `try`, and an error becomes one validation error whose path is the input and whose value is the message, so a caller can report it.
|
|
92
|
+
* @evidence contracts/common.md#clear-and-simple-design The non-throwing twin of `assert`, sharing its constructor call.
|
|
93
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The failure is reported, not hidden, and the message is the original one.
|
|
94
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the result shape.
|
|
95
|
+
*/
|
|
45
96
|
public static validate(
|
|
46
97
|
document:
|
|
47
98
|
| SwaggerV2.IDocument
|
|
@@ -77,10 +128,47 @@ export class NestiaMigrateApplication {
|
|
|
77
128
|
/* -----------------------------------------------------------
|
|
78
129
|
ACCESSORS
|
|
79
130
|
----------------------------------------------------------- */
|
|
131
|
+
/**
|
|
132
|
+
* Returns the analyzed application: the routes and the operations that could
|
|
133
|
+
* not be migrated.
|
|
134
|
+
*
|
|
135
|
+
* Returning the existing analysis reference uses constant work.
|
|
136
|
+
*
|
|
137
|
+
* The constructor’s analysis is returned directly to every caller; callers
|
|
138
|
+
* receive mutable shared state rather than an independently refreshed view.
|
|
139
|
+
*
|
|
140
|
+
* @evidence contracts/common.md#principled-implementation The analysis is done once in the constructor and returned by reference.
|
|
141
|
+
* @evidence contracts/common.md#clear-and-simple-design One accessor.
|
|
142
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It exposes what the analysis produced.
|
|
143
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what is returned.
|
|
144
|
+
*/
|
|
80
145
|
public getData(): IHttpMigrateApplication {
|
|
81
146
|
return this.data_;
|
|
82
147
|
}
|
|
83
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Generates a NestJS monorepo project from the document.
|
|
151
|
+
*
|
|
152
|
+
* The files are the template, the controllers, the module, the DTO
|
|
153
|
+
* structures, the functional API, and, when requested, the e2e tests. A
|
|
154
|
+
* package name replaces the placeholder in every file.
|
|
155
|
+
*
|
|
156
|
+
* Template filtering and renaming scale with template/output bytes;
|
|
157
|
+
* programmers traverse routes and schemas. Accessor conflict escape indexes R
|
|
158
|
+
* routes with at most D segments in a trie. Ordered terminal sets preserve
|
|
159
|
+
* first-route precedence with logarithmic updates, and each escape probes
|
|
160
|
+
* only the current D-segment path rather than scanning R routes. Trie state
|
|
161
|
+
* holds original/final prefixes only and is local to generation.
|
|
162
|
+
*
|
|
163
|
+
* The instance’s route analysis is reused. Each call recomputes
|
|
164
|
+
* mode/config-dependent output and copies accessors because conflict escaping
|
|
165
|
+
* mutates them; returned maps remain caller-owned.
|
|
166
|
+
*
|
|
167
|
+
* @evidence contracts/common.md#principled-implementation The context copies the routes and escapes accessors that would collide with a shorter accessor, the template entries of the generated trees are removed, the programmers write the replacements, and `keyword: false` rewrites the one template setting that selects keyword parameters.
|
|
168
|
+
* @evidence contracts/common.md#clear-and-simple-design One method that composes the generators; each generator owns its own files.
|
|
169
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The template is the published starter, and the only textual edit of it is the documented keyword setting.
|
|
170
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what is generated and the package renaming.
|
|
171
|
+
*/
|
|
84
172
|
public nest(config: INestiaMigrateConfig): Record<string, string> {
|
|
85
173
|
const context: INestiaMigrateContext = createContext(
|
|
86
174
|
"nest",
|
|
@@ -111,6 +199,30 @@ export class NestiaMigrateApplication {
|
|
|
111
199
|
return config.package ? renameSlug(config.package, files) : files;
|
|
112
200
|
}
|
|
113
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Generates an SDK project from the document.
|
|
204
|
+
*
|
|
205
|
+
* The files are the template, the DTO structures, the functional API, the
|
|
206
|
+
* start script, the swagger document in its emended form, and, when
|
|
207
|
+
* requested, the e2e tests. A package name replaces the placeholder in every
|
|
208
|
+
* file.
|
|
209
|
+
*
|
|
210
|
+
* Template filtering and renaming scale with template/output bytes;
|
|
211
|
+
* programmers traverse routes and schemas. Accessor conflict escape indexes R
|
|
212
|
+
* routes with at most D segments in a trie. Ordered terminal sets preserve
|
|
213
|
+
* first-route precedence with logarithmic updates, and each escape probes
|
|
214
|
+
* only the current D-segment path rather than scanning R routes. Trie state
|
|
215
|
+
* holds original/final prefixes only and is local to generation.
|
|
216
|
+
*
|
|
217
|
+
* The instance’s route analysis is reused; mode/config-dependent output is
|
|
218
|
+
* recomputed with fresh accessor copies, and returned maps remain
|
|
219
|
+
* caller-owned.
|
|
220
|
+
*
|
|
221
|
+
* @evidence contracts/common.md#principled-implementation The context is built as for `nest`, the template entries of the generated trees are removed, the programmers write the replacements, and the emended document the application was built from, which is the input after any upgrade, is written beside them as `swagger.json`.
|
|
222
|
+
* @evidence contracts/common.md#clear-and-simple-design One method that composes the generators, sharing the context builder with `nest`.
|
|
223
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The template is the published starter, and no document is special-cased.
|
|
224
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what is generated and the package renaming.
|
|
225
|
+
*/
|
|
114
226
|
public sdk(config: INestiaMigrateConfig): Record<string, string> {
|
|
115
227
|
const context: INestiaMigrateContext = createContext(
|
|
116
228
|
"sdk",
|
|
@@ -161,21 +273,47 @@ const createContext = (
|
|
|
161
273
|
const escapeConflictingAccessors = (
|
|
162
274
|
routes: IHttpMigrateRoute[],
|
|
163
275
|
): IHttpMigrateRoute[] => {
|
|
164
|
-
|
|
276
|
+
type Prefix = {
|
|
277
|
+
children: Map<string, Prefix>;
|
|
278
|
+
terminal: TreeSet<number>;
|
|
279
|
+
};
|
|
280
|
+
const create = (): Prefix => ({
|
|
281
|
+
children: new Map(),
|
|
282
|
+
terminal: new TreeSet(),
|
|
283
|
+
});
|
|
284
|
+
const root: Prefix = create();
|
|
285
|
+
const insert = (accessor: string[], index: number): Prefix => {
|
|
286
|
+
let node = root;
|
|
287
|
+
for (const segment of accessor) {
|
|
288
|
+
let child = node.children.get(segment);
|
|
289
|
+
if (child === undefined) {
|
|
290
|
+
child = create();
|
|
291
|
+
node.children.set(segment, child);
|
|
292
|
+
}
|
|
293
|
+
node = child;
|
|
294
|
+
}
|
|
295
|
+
node.terminal.insert(index);
|
|
296
|
+
return node;
|
|
297
|
+
};
|
|
298
|
+
const terminals = routes.map((route, index) => insert(route.accessor, index));
|
|
299
|
+
for (const [routeIndex, route] of routes.entries()) {
|
|
165
300
|
while (true) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
const
|
|
177
|
-
route.accessor[
|
|
301
|
+
let node = root;
|
|
302
|
+
let neighborIndex = Infinity;
|
|
303
|
+
for (let depth = 0; depth < route.accessor.length - 1; ++depth) {
|
|
304
|
+
const child = node.children.get(route.accessor[depth]!);
|
|
305
|
+
if (child === undefined) break;
|
|
306
|
+
node = child;
|
|
307
|
+
if (!node.terminal.empty())
|
|
308
|
+
neighborIndex = Math.min(neighborIndex, node.terminal.begin().value);
|
|
309
|
+
}
|
|
310
|
+
if (neighborIndex === Infinity) break;
|
|
311
|
+
const conflict = routes[neighborIndex]!.accessor.length - 1;
|
|
312
|
+
route.accessor[conflict] = `_${route.accessor[conflict]}`;
|
|
178
313
|
}
|
|
314
|
+
terminals[routeIndex]!.terminal.erase(routeIndex);
|
|
315
|
+
insert(route.accessor, routeIndex);
|
|
316
|
+
}
|
|
179
317
|
return routes;
|
|
180
318
|
};
|
|
181
319
|
|