@nestia/sdk 12.0.0-dev.20260601.1 → 12.0.0-dev.20260619.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/LICENSE +21 -21
- package/README.md +93 -93
- package/assets/bundle/api/HttpError.ts +1 -1
- package/assets/bundle/api/IConnection.ts +1 -1
- package/assets/bundle/api/Primitive.ts +1 -1
- package/assets/bundle/api/Resolved.ts +1 -1
- package/assets/bundle/api/index.ts +4 -4
- package/assets/bundle/api/module.ts +6 -6
- package/assets/bundle/distribute/README.md +37 -37
- package/assets/bundle/distribute/package.json +28 -28
- package/assets/bundle/distribute/tsconfig.json +109 -109
- package/assets/bundle/e2e/index.ts +42 -42
- package/assets/config/nestia.config.ts +97 -97
- package/lib/NestiaSdkApplication.js +29 -7
- package/lib/NestiaSdkApplication.js.map +1 -1
- package/lib/NestiaSwaggerComposer.js +21 -13
- package/lib/NestiaSwaggerComposer.js.map +1 -1
- package/lib/analyses/AccessorAnalyzer.d.ts +4 -1
- package/lib/analyses/AccessorAnalyzer.js.map +1 -1
- package/lib/analyses/ConfigAnalyzer.js +1 -1
- package/lib/analyses/PathAnalyzer.d.ts +18 -3
- package/lib/analyses/PathAnalyzer.js +32 -0
- package/lib/analyses/PathAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectControllerAnalyzer.js +3 -2
- package/lib/analyses/ReflectControllerAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationAnalyzer.d.ts +1 -1
- package/lib/analyses/ReflectHttpOperationAnalyzer.js +1 -1
- package/lib/analyses/ReflectHttpOperationAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationResponseAnalyzer.d.ts +1 -1
- package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js +53 -20
- package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectMcpOperationAnalyzer.d.ts +14 -0
- package/lib/analyses/ReflectMcpOperationAnalyzer.js +79 -0
- package/lib/analyses/ReflectMcpOperationAnalyzer.js.map +1 -0
- package/lib/analyses/TypedMcpRouteAnalyzer.d.ts +9 -0
- package/lib/analyses/TypedMcpRouteAnalyzer.js +31 -0
- package/lib/analyses/TypedMcpRouteAnalyzer.js.map +1 -0
- package/lib/executable/internal/NestiaConfigLoader.js +5 -1
- package/lib/executable/internal/NestiaConfigLoader.js.map +1 -1
- package/lib/executable/internal/NestiaSdkCommand.js +30 -14
- package/lib/executable/internal/NestiaSdkCommand.js.map +1 -1
- package/lib/executable/internal/NestiaSdkWatcher.d.ts +10 -0
- package/lib/executable/internal/NestiaSdkWatcher.js +322 -0
- package/lib/executable/internal/NestiaSdkWatcher.js.map +1 -0
- package/lib/executable/sdk.js +12 -12
- package/lib/executable/sdk.js.map +1 -1
- package/lib/factories/ExpressionFactory.d.ts +9 -0
- package/lib/factories/ExpressionFactory.js +16 -0
- package/lib/factories/ExpressionFactory.js.map +1 -0
- package/lib/factories/IdentifierFactory.d.ts +22 -0
- package/lib/factories/IdentifierFactory.js +50 -0
- package/lib/factories/IdentifierFactory.js.map +1 -0
- package/lib/factories/LiteralFactory.d.ts +9 -0
- package/lib/factories/LiteralFactory.js +48 -0
- package/lib/factories/LiteralFactory.js.map +1 -0
- package/lib/factories/StatementFactory.d.ts +14 -0
- package/lib/factories/StatementFactory.js +20 -0
- package/lib/factories/StatementFactory.js.map +1 -0
- package/lib/factories/TypeFactory.d.ts +24 -0
- package/lib/factories/TypeFactory.js +27 -0
- package/lib/factories/TypeFactory.js.map +1 -0
- package/lib/generates/CloneGenerator.js +6 -4
- package/lib/generates/CloneGenerator.js.map +1 -1
- package/lib/generates/SdkGenerator.js +50 -1
- package/lib/generates/SdkGenerator.js.map +1 -1
- package/lib/generates/SwaggerGenerator.js +18 -2
- package/lib/generates/SwaggerGenerator.js.map +1 -1
- package/lib/generates/internal/E2eFileProgrammer.js +32 -29
- package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
- package/lib/generates/internal/FilePrinter.d.ts +2 -2
- package/lib/generates/internal/FilePrinter.js +14 -25
- package/lib/generates/internal/FilePrinter.js.map +1 -1
- package/lib/generates/internal/ImportDictionary.d.ts +2 -1
- package/lib/generates/internal/ImportDictionary.js +16 -10
- package/lib/generates/internal/ImportDictionary.js.map +1 -1
- package/lib/generates/internal/SdkAliasCollection.d.ts +12 -10
- package/lib/generates/internal/SdkAliasCollection.js +29 -22
- package/lib/generates/internal/SdkAliasCollection.js.map +1 -1
- package/lib/generates/internal/SdkDistributionComposer.d.ts +1 -0
- package/lib/generates/internal/SdkDistributionComposer.js +3 -0
- package/lib/generates/internal/SdkDistributionComposer.js.map +1 -1
- package/lib/generates/internal/SdkFileProgrammer.js +6 -3
- package/lib/generates/internal/SdkFileProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpCloneProgrammer.d.ts +1 -1
- package/lib/generates/internal/SdkHttpCloneProgrammer.js +3 -3
- package/lib/generates/internal/SdkHttpCloneProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpCloneReferencer.d.ts +1 -1
- package/lib/generates/internal/SdkHttpCloneReferencer.js +42 -9
- package/lib/generates/internal/SdkHttpCloneReferencer.js.map +1 -1
- package/lib/generates/internal/SdkHttpFunctionProgrammer.d.ts +1 -1
- package/lib/generates/internal/SdkHttpFunctionProgrammer.js +47 -51
- package/lib/generates/internal/SdkHttpFunctionProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpNamespaceProgrammer.d.ts +1 -1
- package/lib/generates/internal/SdkHttpNamespaceProgrammer.js +63 -61
- package/lib/generates/internal/SdkHttpNamespaceProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpParameterProgrammer.d.ts +2 -2
- package/lib/generates/internal/SdkHttpParameterProgrammer.js +11 -13
- package/lib/generates/internal/SdkHttpParameterProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpRouteProgrammer.d.ts +1 -1
- package/lib/generates/internal/SdkHttpSimulationProgrammer.d.ts +1 -1
- package/lib/generates/internal/SdkHttpSimulationProgrammer.js +52 -47
- package/lib/generates/internal/SdkHttpSimulationProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkMcpRouteProgrammer.d.ts +15 -0
- package/lib/generates/internal/SdkMcpRouteProgrammer.js +149 -0
- package/lib/generates/internal/SdkMcpRouteProgrammer.js.map +1 -0
- package/lib/generates/internal/SdkRouteDirectory.d.ts +2 -1
- package/lib/generates/internal/SdkRouteDirectory.js.map +1 -1
- package/lib/generates/internal/SdkTypeProgrammer.d.ts +3 -3
- package/lib/generates/internal/SdkTypeProgrammer.js +42 -43
- package/lib/generates/internal/SdkTypeProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkTypeTagProgrammer.d.ts +2 -1
- package/lib/generates/internal/SdkTypeTagProgrammer.js +7 -9
- package/lib/generates/internal/SdkTypeTagProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketCloneProgrammer.d.ts +6 -0
- package/lib/generates/internal/SdkWebSocketCloneProgrammer.js +283 -0
- package/lib/generates/internal/SdkWebSocketCloneProgrammer.js.map +1 -0
- package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.d.ts +2 -2
- package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js +45 -47
- package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketParameterProgrammer.d.ts +3 -3
- package/lib/generates/internal/SdkWebSocketParameterProgrammer.js +9 -9
- package/lib/generates/internal/SdkWebSocketParameterProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.d.ts +2 -2
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.js +37 -41
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.js.map +1 -1
- package/lib/generates/internal/SwaggerOperationParameterComposer.js +10 -2
- package/lib/generates/internal/SwaggerOperationParameterComposer.js.map +1 -1
- package/lib/generates/internal/SwaggerOperationResponseComposer.d.ts +1 -1
- package/lib/generates/internal/SwaggerOperationResponseComposer.js +6 -1
- package/lib/generates/internal/SwaggerOperationResponseComposer.js.map +1 -1
- package/lib/generates/internal/SwaggerReadonlyArrayEmender.d.ts +9 -0
- package/lib/generates/internal/SwaggerReadonlyArrayEmender.js +174 -0
- package/lib/generates/internal/SwaggerReadonlyArrayEmender.js.map +1 -0
- package/lib/structures/INestiaSdkInput.d.ts +9 -2
- package/lib/structures/IReflectController.d.ts +2 -1
- package/lib/structures/IReflectHttpOperationSuccess.d.ts +4 -2
- package/lib/structures/IReflectMcpOperation.d.ts +35 -0
- package/lib/structures/IReflectMcpOperation.js +3 -0
- package/lib/structures/IReflectMcpOperation.js.map +1 -0
- package/lib/structures/IReflectMcpOperationParameter.d.ts +19 -0
- package/lib/structures/IReflectMcpOperationParameter.js +3 -0
- package/lib/structures/IReflectMcpOperationParameter.js.map +1 -0
- package/lib/structures/ITypedApplication.d.ts +2 -1
- package/lib/structures/ITypedHttpRouteSuccess.d.ts +3 -1
- package/lib/structures/ITypedMcpRoute.d.ts +31 -0
- package/lib/structures/ITypedMcpRoute.js +3 -0
- package/lib/structures/ITypedMcpRoute.js.map +1 -0
- package/lib/transform.d.ts +5 -9
- package/lib/transform.js +8 -31
- package/lib/transform.js.map +1 -1
- package/lib/utils/HttpResponseContentTypeUtil.d.ts +5 -0
- package/lib/utils/HttpResponseContentTypeUtil.js +22 -0
- package/lib/utils/HttpResponseContentTypeUtil.js.map +1 -0
- package/native/go.mod +52 -52
- package/native/go.sum +84 -54
- package/native/sdk/register.go +322 -165
- package/native/sdk/sdk.go +17 -17
- package/native/sdk/sdk_metadata_json.go +327 -327
- package/native/sdk/sdk_transform.go +1879 -1549
- package/package.json +13 -11
- package/src/INestiaConfig.ts +267 -267
- package/src/NestiaSdkApplication.ts +39 -8
- package/src/NestiaSwaggerComposer.ts +153 -142
- package/src/analyses/AccessorAnalyzer.ts +64 -67
- package/src/analyses/ConfigAnalyzer.ts +330 -330
- package/src/analyses/ImportAnalyzer.ts +92 -92
- package/src/analyses/PathAnalyzer.ts +130 -69
- package/src/analyses/ReflectControllerAnalyzer.ts +112 -105
- package/src/analyses/ReflectHttpOperationAnalyzer.ts +183 -183
- package/src/analyses/ReflectHttpOperationExceptionAnalyzer.ts +90 -90
- package/src/analyses/ReflectHttpOperationParameterAnalyzer.ts +350 -350
- package/src/analyses/ReflectHttpOperationResponseAnalyzer.ts +163 -130
- package/src/analyses/ReflectMcpOperationAnalyzer.ts +124 -0
- package/src/analyses/ReflectMetadataAnalyzer.ts +44 -44
- package/src/analyses/SecurityAnalyzer.ts +25 -25
- package/src/analyses/TypedMcpRouteAnalyzer.ts +34 -0
- package/src/decorators/OperationMetadata.ts +29 -29
- package/src/executable/internal/CommandParser.ts +15 -15
- package/src/executable/internal/NestiaConfigLoader.ts +451 -446
- package/src/executable/internal/NestiaSdkCommand.ts +124 -106
- package/src/executable/internal/NestiaSdkWatcher.ts +342 -0
- package/src/executable/sdk.ts +90 -88
- package/src/factories/ExpressionFactory.ts +23 -0
- package/src/factories/IdentifierFactory.ts +84 -0
- package/src/factories/LiteralFactory.ts +54 -0
- package/src/factories/StatementFactory.ts +56 -0
- package/src/factories/TypeFactory.ts +27 -0
- package/src/generates/CloneGenerator.ts +74 -66
- package/src/generates/E2eGenerator.ts +32 -32
- package/src/generates/SdkGenerator.ts +176 -118
- package/src/generates/SwaggerGenerator.ts +342 -310
- package/src/generates/internal/E2eFileProgrammer.ts +246 -233
- package/src/generates/internal/FilePrinter.ts +57 -65
- package/src/generates/internal/ImportDictionary.ts +207 -204
- package/src/generates/internal/SdkAliasCollection.ts +280 -261
- package/src/generates/internal/SdkDistributionComposer.ts +123 -116
- package/src/generates/internal/SdkFileProgrammer.ts +113 -112
- package/src/generates/internal/SdkHttpCloneProgrammer.ts +124 -126
- package/src/generates/internal/SdkHttpCloneReferencer.ts +131 -77
- package/src/generates/internal/SdkHttpFunctionProgrammer.ts +290 -301
- package/src/generates/internal/SdkHttpNamespaceProgrammer.ts +507 -510
- package/src/generates/internal/SdkHttpParameterProgrammer.ts +163 -165
- package/src/generates/internal/SdkHttpRouteProgrammer.ts +109 -109
- package/src/generates/internal/SdkHttpSimulationProgrammer.ts +322 -314
- package/src/generates/internal/SdkImportWizard.ts +62 -62
- package/src/generates/internal/SdkMcpRouteProgrammer.ts +447 -0
- package/src/generates/internal/SdkRouteDirectory.ts +21 -18
- package/src/generates/internal/SdkTypeProgrammer.ts +389 -382
- package/src/generates/internal/SdkTypeTagProgrammer.ts +110 -114
- package/src/generates/internal/SdkWebSocketCloneProgrammer.ts +319 -0
- package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +383 -389
- package/src/generates/internal/SdkWebSocketParameterProgrammer.ts +91 -89
- package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +304 -323
- package/src/generates/internal/SwaggerDescriptionComposer.ts +64 -64
- package/src/generates/internal/SwaggerOperationComposer.ts +119 -119
- package/src/generates/internal/SwaggerOperationParameterComposer.ts +175 -162
- package/src/generates/internal/SwaggerOperationResponseComposer.ts +115 -110
- package/src/generates/internal/SwaggerReadonlyArrayEmender.ts +262 -0
- package/src/index.ts +4 -4
- package/src/internal/legacy.ts +492 -492
- package/src/module.ts +4 -4
- package/src/structures/INestiaProject.ts +10 -10
- package/src/structures/INestiaSdkInput.ts +27 -20
- package/src/structures/IOperationMetadata.ts +41 -41
- package/src/structures/IReflectController.ts +18 -15
- package/src/structures/IReflectHttpOperation.ts +26 -26
- package/src/structures/IReflectHttpOperationException.ts +18 -18
- package/src/structures/IReflectHttpOperationParameter.ts +79 -79
- package/src/structures/IReflectHttpOperationSuccess.ts +18 -21
- package/src/structures/IReflectImport.ts +6 -6
- package/src/structures/IReflectMcpOperation.ts +38 -0
- package/src/structures/IReflectMcpOperationParameter.ts +27 -0
- package/src/structures/IReflectOperationError.ts +26 -26
- package/src/structures/IReflectType.ts +4 -4
- package/src/structures/IReflectWebSocketOperation.ts +17 -17
- package/src/structures/ITypedApplication.ts +12 -11
- package/src/structures/ITypedHttpRoute.ts +41 -41
- package/src/structures/ITypedHttpRouteException.ts +15 -15
- package/src/structures/ITypedHttpRouteParameter.ts +41 -41
- package/src/structures/ITypedHttpRouteSuccess.ts +18 -22
- package/src/structures/ITypedMcpRoute.ts +33 -0
- package/src/structures/ITypedWebSocketRoute.ts +24 -24
- package/src/structures/ITypedWebSocketRouteParameter.ts +3 -3
- package/src/transform.ts +28 -59
- package/src/typings/get-function-location.d.ts +7 -7
- package/src/utils/ArrayUtil.ts +26 -26
- package/src/utils/EmittedJavaScriptPatcher.ts +88 -88
- package/src/utils/FileRetriever.ts +22 -22
- package/src/utils/HttpResponseContentTypeUtil.ts +30 -0
- package/src/utils/MapUtil.ts +14 -14
- package/src/utils/PathUtil.ts +10 -10
- package/src/utils/SourceFinder.ts +63 -63
- package/src/utils/StringUtil.ts +17 -17
- package/src/utils/TsConfigReader.ts +108 -108
- package/src/utils/TtscExecutor.ts +68 -68
- package/src/utils/VersioningStrategy.ts +28 -28
- package/src/validators/HttpHeadersValidator.ts +11 -11
- package/src/validators/HttpQueryValidator.ts +11 -11
- package/src/validators/TextPlainValidator.ts +17 -17
|
@@ -1,330 +1,330 @@
|
|
|
1
|
-
/// <reference path="../typings/get-function-location.d.ts" />
|
|
2
|
-
import { INestApplication, VersioningType } from "@nestjs/common";
|
|
3
|
-
import { MODULE_PATH } from "@nestjs/common/constants";
|
|
4
|
-
import { NestContainer } from "@nestjs/core";
|
|
5
|
-
import { Module } from "@nestjs/core/injector/module";
|
|
6
|
-
import fs from "fs";
|
|
7
|
-
import getFunctionLocation from "get-function-location";
|
|
8
|
-
import path from "path";
|
|
9
|
-
import { HashMap, Pair, Singleton } from "tstl";
|
|
10
|
-
|
|
11
|
-
import { INestiaConfig } from "../INestiaConfig";
|
|
12
|
-
import { SdkGenerator } from "../generates/SdkGenerator";
|
|
13
|
-
import { INestiaSdkInput } from "../structures/INestiaSdkInput";
|
|
14
|
-
import { ArrayUtil } from "../utils/ArrayUtil";
|
|
15
|
-
import { EmittedJavaScriptPatcher } from "../utils/EmittedJavaScriptPatcher";
|
|
16
|
-
import { MapUtil } from "../utils/MapUtil";
|
|
17
|
-
import { SourceFinder } from "../utils/SourceFinder";
|
|
18
|
-
import { TsConfigReader } from "../utils/TsConfigReader";
|
|
19
|
-
import { TtscExecutor } from "../utils/TtscExecutor";
|
|
20
|
-
|
|
21
|
-
export namespace ConfigAnalyzer {
|
|
22
|
-
export const input = async (
|
|
23
|
-
config: INestiaConfig,
|
|
24
|
-
): Promise<INestiaSdkInput> => {
|
|
25
|
-
return MapUtil.take(memory, config, async () => {
|
|
26
|
-
if (typeof config.input === "function")
|
|
27
|
-
return application(await config.input());
|
|
28
|
-
|
|
29
|
-
const sources: string[] = await SourceFinder.find({
|
|
30
|
-
include: Array.isArray(config.input)
|
|
31
|
-
? config.input
|
|
32
|
-
: typeof config.input === "object"
|
|
33
|
-
? config.input.include
|
|
34
|
-
: [config.input],
|
|
35
|
-
exclude:
|
|
36
|
-
typeof config.input === "object" && !Array.isArray(config.input)
|
|
37
|
-
? (config.input.exclude ?? [])
|
|
38
|
-
: [],
|
|
39
|
-
filter: filter(config),
|
|
40
|
-
});
|
|
41
|
-
const runtime: RuntimeCompiler = await RuntimeCompiler.compile(sources);
|
|
42
|
-
const controllers: INestiaSdkInput.IController[] = [];
|
|
43
|
-
for (const file of sources) {
|
|
44
|
-
const external: any[] = await import(runtime.output(file));
|
|
45
|
-
for (const key in external) {
|
|
46
|
-
const instance: Function = external[key];
|
|
47
|
-
if (Reflect.getMetadata("path", instance) !== undefined)
|
|
48
|
-
controllers.push({
|
|
49
|
-
class: instance,
|
|
50
|
-
location: file,
|
|
51
|
-
prefixes: [],
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
56
|
-
controllers,
|
|
57
|
-
};
|
|
58
|
-
});
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
export const application = async (
|
|
62
|
-
app: INestApplication,
|
|
63
|
-
): Promise<INestiaSdkInput> => {
|
|
64
|
-
const container: NestContainer = (app as any).container as NestContainer;
|
|
65
|
-
const modules: Module[] = [...container.getModules().values()].filter(
|
|
66
|
-
(m) => !!m.controllers.size,
|
|
67
|
-
);
|
|
68
|
-
const unique: HashMap<Function, Set<string>> = new HashMap();
|
|
69
|
-
|
|
70
|
-
for (const m of modules) {
|
|
71
|
-
const path: string =
|
|
72
|
-
Reflect.getMetadata(
|
|
73
|
-
MODULE_PATH + container.getModules().applicationId,
|
|
74
|
-
m.metatype,
|
|
75
|
-
) ??
|
|
76
|
-
Reflect.getMetadata(MODULE_PATH, m.metatype) ??
|
|
77
|
-
"";
|
|
78
|
-
for (const controller of [...m.controllers.keys()])
|
|
79
|
-
if (typeof controller === "function")
|
|
80
|
-
unique.take(controller, () => new Set()).add(path);
|
|
81
|
-
}
|
|
82
|
-
const controllers: INestiaSdkInput.IController[] = [];
|
|
83
|
-
for (const it of unique) {
|
|
84
|
-
const file: string | null =
|
|
85
|
-
(await getFunctionLocation(it.first))?.source ?? null;
|
|
86
|
-
if (file === null) continue;
|
|
87
|
-
const location: string = normalize_file(file);
|
|
88
|
-
if (location.length === 0) continue;
|
|
89
|
-
controllers.push({
|
|
90
|
-
class: it.first,
|
|
91
|
-
prefixes: Array.from(it.second),
|
|
92
|
-
location,
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const versioning = (app as any).config?.versioningOptions;
|
|
97
|
-
return {
|
|
98
|
-
controllers,
|
|
99
|
-
globalPrefix:
|
|
100
|
-
typeof (app as any).config?.globalPrefix === "string"
|
|
101
|
-
? {
|
|
102
|
-
prefix: (app as any).config.globalPrefix,
|
|
103
|
-
exclude: (app as any).config.globalPrefixOptions?.exclude ??
|
|
104
|
-
}
|
|
105
|
-
: undefined,
|
|
106
|
-
versioning:
|
|
107
|
-
versioning === undefined || versioning.type !== VersioningType.URI
|
|
108
|
-
? undefined
|
|
109
|
-
: {
|
|
110
|
-
prefix:
|
|
111
|
-
versioning.prefix === undefined || versioning.prefix === false
|
|
112
|
-
? "v"
|
|
113
|
-
: versioning.prefix,
|
|
114
|
-
defaultVersion: versioning.defaultVersion,
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
const memory = new Map<INestiaConfig, Promise<INestiaSdkInput>>();
|
|
120
|
-
class RuntimeCompiler {
|
|
121
|
-
private constructor(
|
|
122
|
-
private readonly cwd: string,
|
|
123
|
-
private readonly outDir: string,
|
|
124
|
-
) {}
|
|
125
|
-
|
|
126
|
-
public static async compile(sources: string[]): Promise<RuntimeCompiler> {
|
|
127
|
-
const cwd: string = process.cwd();
|
|
128
|
-
const runtimeRoot: string = path.join(
|
|
129
|
-
cwd,
|
|
130
|
-
"node_modules",
|
|
131
|
-
".nestia",
|
|
132
|
-
"runtime",
|
|
133
|
-
);
|
|
134
|
-
await fs.promises.mkdir(runtimeRoot, { recursive: true });
|
|
135
|
-
ensureRuntimeCleanup(runtimeRoot);
|
|
136
|
-
const outDir: string = await fs.promises.mkdtemp(
|
|
137
|
-
path.join(runtimeRoot, "run-"),
|
|
138
|
-
);
|
|
139
|
-
const project: string = path.join(
|
|
140
|
-
cwd,
|
|
141
|
-
`.nestia.runtime.${process.pid}.${Date.now()}.json`,
|
|
142
|
-
);
|
|
143
|
-
const relative = (file: string): string =>
|
|
144
|
-
path.relative(cwd, file).split("\\").join("/");
|
|
145
|
-
await fs.promises.writeFile(
|
|
146
|
-
project,
|
|
147
|
-
JSON.stringify(
|
|
148
|
-
{
|
|
149
|
-
extends: normalizeProjectPath(process.env.NESTIA_PROJECT),
|
|
150
|
-
compilerOptions: {
|
|
151
|
-
noEmit: false,
|
|
152
|
-
noUnusedLocals: false,
|
|
153
|
-
noUnusedParameters: false,
|
|
154
|
-
outDir,
|
|
155
|
-
plugins: await runtimePlugins(cwd),
|
|
156
|
-
rootDir: ".",
|
|
157
|
-
},
|
|
158
|
-
include: sources.map(relative),
|
|
159
|
-
},
|
|
160
|
-
null,
|
|
161
|
-
2,
|
|
162
|
-
),
|
|
163
|
-
"utf8",
|
|
164
|
-
);
|
|
165
|
-
try {
|
|
166
|
-
TtscExecutor.run({
|
|
167
|
-
cwd,
|
|
168
|
-
env: sdkTransformEnv(),
|
|
169
|
-
project,
|
|
170
|
-
});
|
|
171
|
-
} catch (error) {
|
|
172
|
-
const output =
|
|
173
|
-
error instanceof Error && "stderr" in error
|
|
174
|
-
? String((error as Error & { stderr?: Buffer }).stderr ?? "")
|
|
175
|
-
: "";
|
|
176
|
-
throw new Error(output || `Failed to compile Nestia runtime inputs.`);
|
|
177
|
-
} finally {
|
|
178
|
-
await fs.promises.rm(project, { force: true });
|
|
179
|
-
}
|
|
180
|
-
await EmittedJavaScriptPatcher.importMetaUrl(outDir);
|
|
181
|
-
return new RuntimeCompiler(cwd, outDir);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
public output(source: string): string {
|
|
185
|
-
const relative: string = path.relative(this.cwd, source);
|
|
186
|
-
const emitted: string = path.join(
|
|
187
|
-
this.outDir,
|
|
188
|
-
replaceExtension(relative, ".js"),
|
|
189
|
-
);
|
|
190
|
-
return emitted;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
const RUNTIME_ROOTS: Set<string> = new Set();
|
|
195
|
-
let RUNTIME_CLEANUP_REGISTERED: boolean = false;
|
|
196
|
-
|
|
197
|
-
const ensureRuntimeCleanup = (runtimeRoot: string): void => {
|
|
198
|
-
RUNTIME_ROOTS.add(runtimeRoot);
|
|
199
|
-
if (RUNTIME_CLEANUP_REGISTERED === true) return;
|
|
200
|
-
RUNTIME_CLEANUP_REGISTERED = true;
|
|
201
|
-
const sweep = (): void => {
|
|
202
|
-
for (const location of RUNTIME_ROOTS)
|
|
203
|
-
fs.rmSync(location, { force: true, recursive: true });
|
|
204
|
-
};
|
|
205
|
-
process.once("exit", sweep);
|
|
206
|
-
// process.once("exit", …) does not fire on SIGINT/SIGTERM. Without these
|
|
207
|
-
// handlers a Ctrl-C during codegen leaves `run-*` mkdtemp directories
|
|
208
|
-
// behind under node_modules/.nestia/runtime/ until a subsequent clean exit.
|
|
209
|
-
// The module-level RUNTIME_CLEANUP_REGISTERED flag above guards against
|
|
210
|
-
// re-entrancy within this module; we deliberately do NOT gate on
|
|
211
|
-
// `process.listenerCount(signal) > 0` because NestiaConfigLoader's parallel
|
|
212
|
-
// sweep registers first, and that gate would skip our registration —
|
|
213
|
-
// leaving RUNTIME_ROOTS unswept on Ctrl-C while config-loader cleans up.
|
|
214
|
-
// Windows note: `process.kill(pid, "SIGINT")` calls TerminateProcess
|
|
215
|
-
// rather than re-raising through the listener queue, so the handler
|
|
216
|
-
// cascade documented above only holds on POSIX. On Windows, whichever
|
|
217
|
-
// module registers FIRST runs its sweep and the second is skipped —
|
|
218
|
-
// RUNTIME_ROOTS cleanup is best-effort there. SIGHUP is a no-op for
|
|
219
|
-
// most common code paths on Windows (Node fires it on console-close
|
|
220
|
-
// and exits within seconds).
|
|
221
|
-
const onSignal = (signal: NodeJS.Signals): void => {
|
|
222
|
-
sweep();
|
|
223
|
-
process.kill(process.pid, signal);
|
|
224
|
-
};
|
|
225
|
-
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"] as const) {
|
|
226
|
-
process.once(signal, onSignal);
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
type RuntimePlugin = Record<string, unknown> & { transform?: unknown };
|
|
231
|
-
|
|
232
|
-
const sdkTransformEnv = (): NodeJS.ProcessEnv =>
|
|
233
|
-
process.env.NESTIA_SDK_TRANSFORM === undefined
|
|
234
|
-
? { NESTIA_SDK_TRANSFORM: "1" }
|
|
235
|
-
: {};
|
|
236
|
-
|
|
237
|
-
const runtimePlugins = async (cwd: string): Promise<RuntimePlugin[]> => {
|
|
238
|
-
const plugins: RuntimePlugin[] = await readProjectPlugins(cwd);
|
|
239
|
-
const typia: RuntimePlugin | undefined = plugins.find((p) =>
|
|
240
|
-
isTransform(p, "typia"),
|
|
241
|
-
);
|
|
242
|
-
const core: RuntimePlugin | undefined = plugins.find((p) =>
|
|
243
|
-
isTransform(p, "@nestia/core"),
|
|
244
|
-
);
|
|
245
|
-
return [
|
|
246
|
-
{
|
|
247
|
-
...(typia ?? {}),
|
|
248
|
-
transform: "typia/lib/transform",
|
|
249
|
-
enabled: false,
|
|
250
|
-
},
|
|
251
|
-
normalizeRuntimePlugin({
|
|
252
|
-
...(core ?? {}),
|
|
253
|
-
transform: "@nestia/core/native/transform.cjs",
|
|
254
|
-
}),
|
|
255
|
-
];
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
const readProjectPlugins = async (cwd: string): Promise<RuntimePlugin[]> => {
|
|
259
|
-
const project: string = normalizeProjectPath(process.env.NESTIA_PROJECT);
|
|
260
|
-
const file: string = path.isAbsolute(project)
|
|
261
|
-
? project
|
|
262
|
-
: path.join(cwd, project);
|
|
263
|
-
const config = await TsConfigReader.read(file);
|
|
264
|
-
const options = config.compilerOptions as
|
|
265
|
-
| { plugins?: RuntimePlugin[] }
|
|
266
|
-
| undefined;
|
|
267
|
-
return Array.isArray(options?.plugins)
|
|
268
|
-
? options.plugins
|
|
269
|
-
.filter((p) => typeof p === "object" && p !== null)
|
|
270
|
-
.map((p) => ({ ...(p as unknown as RuntimePlugin) }))
|
|
271
|
-
: [];
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
const normalizeRuntimePlugin = (plugin: RuntimePlugin): RuntimePlugin => {
|
|
275
|
-
const output: RuntimePlugin = { ...plugin };
|
|
276
|
-
if (output.enabled === false) delete output.enabled;
|
|
277
|
-
return output;
|
|
278
|
-
};
|
|
279
|
-
|
|
280
|
-
const isTransform = (plugin: RuntimePlugin, name: string): boolean =>
|
|
281
|
-
typeof plugin.transform === "string" && plugin.transform.includes(name);
|
|
282
|
-
|
|
283
|
-
const replaceExtension = (file: string, extension: string): string =>
|
|
284
|
-
file.replace(/\.[cm]?tsx?$/i, extension);
|
|
285
|
-
|
|
286
|
-
const normalizeProjectPath = (project: string | undefined): string => {
|
|
287
|
-
const next: string = project ?? "tsconfig.json";
|
|
288
|
-
return path.isAbsolute(next) || next.startsWith(".") ? next : `./${next}`;
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
const normalize_file = (str: string) =>
|
|
292
|
-
str.substring(
|
|
293
|
-
str.startsWith("file:///")
|
|
294
|
-
? process.cwd()[0] === "/"
|
|
295
|
-
? 7
|
|
296
|
-
: 8
|
|
297
|
-
: str.startsWith("file://")
|
|
298
|
-
? 7
|
|
299
|
-
: 0,
|
|
300
|
-
);
|
|
301
|
-
|
|
302
|
-
const filter =
|
|
303
|
-
(config: INestiaConfig) =>
|
|
304
|
-
async (location: string): Promise<boolean> =>
|
|
305
|
-
location.endsWith(".ts") &&
|
|
306
|
-
!location.endsWith(".d.ts") &&
|
|
307
|
-
(config.output === undefined ||
|
|
308
|
-
(location.indexOf(path.join(config.output, "functional")) === -1 &&
|
|
309
|
-
(await (
|
|
310
|
-
await bundler.get(config.output)
|
|
311
|
-
)(location))) === false);
|
|
312
|
-
|
|
313
|
-
const bundler = new Singleton(async (output: string) => {
|
|
314
|
-
const assets: string[] = await fs.promises.readdir(SdkGenerator.BUNDLE_PATH);
|
|
315
|
-
const tuples: Pair<string, boolean>[] = await ArrayUtil.asyncMap(
|
|
316
|
-
assets,
|
|
317
|
-
async (file) => {
|
|
318
|
-
const relative: string = path.join(output, file);
|
|
319
|
-
const location: string = path.join(SdkGenerator.BUNDLE_PATH, file);
|
|
320
|
-
const stats: fs.Stats = await fs.promises.stat(location);
|
|
321
|
-
return new Pair(relative, stats.isDirectory());
|
|
322
|
-
},
|
|
323
|
-
);
|
|
324
|
-
return async (file: string): Promise<boolean> => {
|
|
325
|
-
for (const it of tuples)
|
|
326
|
-
if (it.second === false && file === it.first) return true;
|
|
327
|
-
else if (it.second === true && file.indexOf(it.first) === 0) return true;
|
|
328
|
-
return false;
|
|
329
|
-
};
|
|
330
|
-
});
|
|
1
|
+
/// <reference path="../typings/get-function-location.d.ts" />
|
|
2
|
+
import { INestApplication, VersioningType } from "@nestjs/common";
|
|
3
|
+
import { MODULE_PATH } from "@nestjs/common/constants";
|
|
4
|
+
import { NestContainer } from "@nestjs/core";
|
|
5
|
+
import { Module } from "@nestjs/core/injector/module";
|
|
6
|
+
import fs from "fs";
|
|
7
|
+
import getFunctionLocation from "get-function-location";
|
|
8
|
+
import path from "path";
|
|
9
|
+
import { HashMap, Pair, Singleton } from "tstl";
|
|
10
|
+
|
|
11
|
+
import { INestiaConfig } from "../INestiaConfig";
|
|
12
|
+
import { SdkGenerator } from "../generates/SdkGenerator";
|
|
13
|
+
import { INestiaSdkInput } from "../structures/INestiaSdkInput";
|
|
14
|
+
import { ArrayUtil } from "../utils/ArrayUtil";
|
|
15
|
+
import { EmittedJavaScriptPatcher } from "../utils/EmittedJavaScriptPatcher";
|
|
16
|
+
import { MapUtil } from "../utils/MapUtil";
|
|
17
|
+
import { SourceFinder } from "../utils/SourceFinder";
|
|
18
|
+
import { TsConfigReader } from "../utils/TsConfigReader";
|
|
19
|
+
import { TtscExecutor } from "../utils/TtscExecutor";
|
|
20
|
+
|
|
21
|
+
export namespace ConfigAnalyzer {
|
|
22
|
+
export const input = async (
|
|
23
|
+
config: INestiaConfig,
|
|
24
|
+
): Promise<INestiaSdkInput> => {
|
|
25
|
+
return MapUtil.take(memory, config, async () => {
|
|
26
|
+
if (typeof config.input === "function")
|
|
27
|
+
return application(await config.input());
|
|
28
|
+
|
|
29
|
+
const sources: string[] = await SourceFinder.find({
|
|
30
|
+
include: Array.isArray(config.input)
|
|
31
|
+
? config.input
|
|
32
|
+
: typeof config.input === "object"
|
|
33
|
+
? config.input.include
|
|
34
|
+
: [config.input],
|
|
35
|
+
exclude:
|
|
36
|
+
typeof config.input === "object" && !Array.isArray(config.input)
|
|
37
|
+
? (config.input.exclude ?? [])
|
|
38
|
+
: [],
|
|
39
|
+
filter: filter(config),
|
|
40
|
+
});
|
|
41
|
+
const runtime: RuntimeCompiler = await RuntimeCompiler.compile(sources);
|
|
42
|
+
const controllers: INestiaSdkInput.IController[] = [];
|
|
43
|
+
for (const file of sources) {
|
|
44
|
+
const external: any[] = await import(runtime.output(file));
|
|
45
|
+
for (const key in external) {
|
|
46
|
+
const instance: Function = external[key];
|
|
47
|
+
if (Reflect.getMetadata("path", instance) !== undefined)
|
|
48
|
+
controllers.push({
|
|
49
|
+
class: instance,
|
|
50
|
+
location: file,
|
|
51
|
+
prefixes: [],
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
controllers,
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const application = async (
|
|
62
|
+
app: INestApplication,
|
|
63
|
+
): Promise<INestiaSdkInput> => {
|
|
64
|
+
const container: NestContainer = (app as any).container as NestContainer;
|
|
65
|
+
const modules: Module[] = [...container.getModules().values()].filter(
|
|
66
|
+
(m) => !!m.controllers.size,
|
|
67
|
+
);
|
|
68
|
+
const unique: HashMap<Function, Set<string>> = new HashMap();
|
|
69
|
+
|
|
70
|
+
for (const m of modules) {
|
|
71
|
+
const path: string =
|
|
72
|
+
Reflect.getMetadata(
|
|
73
|
+
MODULE_PATH + container.getModules().applicationId,
|
|
74
|
+
m.metatype,
|
|
75
|
+
) ??
|
|
76
|
+
Reflect.getMetadata(MODULE_PATH, m.metatype) ??
|
|
77
|
+
"";
|
|
78
|
+
for (const controller of [...m.controllers.keys()])
|
|
79
|
+
if (typeof controller === "function")
|
|
80
|
+
unique.take(controller, () => new Set()).add(path);
|
|
81
|
+
}
|
|
82
|
+
const controllers: INestiaSdkInput.IController[] = [];
|
|
83
|
+
for (const it of unique) {
|
|
84
|
+
const file: string | null =
|
|
85
|
+
(await getFunctionLocation(it.first))?.source ?? null;
|
|
86
|
+
if (file === null) continue;
|
|
87
|
+
const location: string = normalize_file(file);
|
|
88
|
+
if (location.length === 0) continue;
|
|
89
|
+
controllers.push({
|
|
90
|
+
class: it.first,
|
|
91
|
+
prefixes: Array.from(it.second),
|
|
92
|
+
location,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const versioning = (app as any).config?.versioningOptions;
|
|
97
|
+
return {
|
|
98
|
+
controllers,
|
|
99
|
+
globalPrefix:
|
|
100
|
+
typeof (app as any).config?.globalPrefix === "string"
|
|
101
|
+
? {
|
|
102
|
+
prefix: (app as any).config.globalPrefix,
|
|
103
|
+
exclude: (app as any).config.globalPrefixOptions?.exclude ?? [],
|
|
104
|
+
}
|
|
105
|
+
: undefined,
|
|
106
|
+
versioning:
|
|
107
|
+
versioning === undefined || versioning.type !== VersioningType.URI
|
|
108
|
+
? undefined
|
|
109
|
+
: {
|
|
110
|
+
prefix:
|
|
111
|
+
versioning.prefix === undefined || versioning.prefix === false
|
|
112
|
+
? "v"
|
|
113
|
+
: versioning.prefix,
|
|
114
|
+
defaultVersion: versioning.defaultVersion,
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const memory = new Map<INestiaConfig, Promise<INestiaSdkInput>>();
|
|
120
|
+
class RuntimeCompiler {
|
|
121
|
+
private constructor(
|
|
122
|
+
private readonly cwd: string,
|
|
123
|
+
private readonly outDir: string,
|
|
124
|
+
) {}
|
|
125
|
+
|
|
126
|
+
public static async compile(sources: string[]): Promise<RuntimeCompiler> {
|
|
127
|
+
const cwd: string = process.cwd();
|
|
128
|
+
const runtimeRoot: string = path.join(
|
|
129
|
+
cwd,
|
|
130
|
+
"node_modules",
|
|
131
|
+
".nestia",
|
|
132
|
+
"runtime",
|
|
133
|
+
);
|
|
134
|
+
await fs.promises.mkdir(runtimeRoot, { recursive: true });
|
|
135
|
+
ensureRuntimeCleanup(runtimeRoot);
|
|
136
|
+
const outDir: string = await fs.promises.mkdtemp(
|
|
137
|
+
path.join(runtimeRoot, "run-"),
|
|
138
|
+
);
|
|
139
|
+
const project: string = path.join(
|
|
140
|
+
cwd,
|
|
141
|
+
`.nestia.runtime.${process.pid}.${Date.now()}.json`,
|
|
142
|
+
);
|
|
143
|
+
const relative = (file: string): string =>
|
|
144
|
+
path.relative(cwd, file).split("\\").join("/");
|
|
145
|
+
await fs.promises.writeFile(
|
|
146
|
+
project,
|
|
147
|
+
JSON.stringify(
|
|
148
|
+
{
|
|
149
|
+
extends: normalizeProjectPath(process.env.NESTIA_PROJECT),
|
|
150
|
+
compilerOptions: {
|
|
151
|
+
noEmit: false,
|
|
152
|
+
noUnusedLocals: false,
|
|
153
|
+
noUnusedParameters: false,
|
|
154
|
+
outDir,
|
|
155
|
+
plugins: await runtimePlugins(cwd),
|
|
156
|
+
rootDir: ".",
|
|
157
|
+
},
|
|
158
|
+
include: sources.map(relative),
|
|
159
|
+
},
|
|
160
|
+
null,
|
|
161
|
+
2,
|
|
162
|
+
),
|
|
163
|
+
"utf8",
|
|
164
|
+
);
|
|
165
|
+
try {
|
|
166
|
+
TtscExecutor.run({
|
|
167
|
+
cwd,
|
|
168
|
+
env: sdkTransformEnv(),
|
|
169
|
+
project,
|
|
170
|
+
});
|
|
171
|
+
} catch (error) {
|
|
172
|
+
const output =
|
|
173
|
+
error instanceof Error && "stderr" in error
|
|
174
|
+
? String((error as Error & { stderr?: Buffer }).stderr ?? "")
|
|
175
|
+
: "";
|
|
176
|
+
throw new Error(output || `Failed to compile Nestia runtime inputs.`);
|
|
177
|
+
} finally {
|
|
178
|
+
await fs.promises.rm(project, { force: true });
|
|
179
|
+
}
|
|
180
|
+
await EmittedJavaScriptPatcher.importMetaUrl(outDir);
|
|
181
|
+
return new RuntimeCompiler(cwd, outDir);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
public output(source: string): string {
|
|
185
|
+
const relative: string = path.relative(this.cwd, source);
|
|
186
|
+
const emitted: string = path.join(
|
|
187
|
+
this.outDir,
|
|
188
|
+
replaceExtension(relative, ".js"),
|
|
189
|
+
);
|
|
190
|
+
return emitted;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const RUNTIME_ROOTS: Set<string> = new Set();
|
|
195
|
+
let RUNTIME_CLEANUP_REGISTERED: boolean = false;
|
|
196
|
+
|
|
197
|
+
const ensureRuntimeCleanup = (runtimeRoot: string): void => {
|
|
198
|
+
RUNTIME_ROOTS.add(runtimeRoot);
|
|
199
|
+
if (RUNTIME_CLEANUP_REGISTERED === true) return;
|
|
200
|
+
RUNTIME_CLEANUP_REGISTERED = true;
|
|
201
|
+
const sweep = (): void => {
|
|
202
|
+
for (const location of RUNTIME_ROOTS)
|
|
203
|
+
fs.rmSync(location, { force: true, recursive: true });
|
|
204
|
+
};
|
|
205
|
+
process.once("exit", sweep);
|
|
206
|
+
// process.once("exit", …) does not fire on SIGINT/SIGTERM. Without these
|
|
207
|
+
// handlers a Ctrl-C during codegen leaves `run-*` mkdtemp directories
|
|
208
|
+
// behind under node_modules/.nestia/runtime/ until a subsequent clean exit.
|
|
209
|
+
// The module-level RUNTIME_CLEANUP_REGISTERED flag above guards against
|
|
210
|
+
// re-entrancy within this module; we deliberately do NOT gate on
|
|
211
|
+
// `process.listenerCount(signal) > 0` because NestiaConfigLoader's parallel
|
|
212
|
+
// sweep registers first, and that gate would skip our registration —
|
|
213
|
+
// leaving RUNTIME_ROOTS unswept on Ctrl-C while config-loader cleans up.
|
|
214
|
+
// Windows note: `process.kill(pid, "SIGINT")` calls TerminateProcess
|
|
215
|
+
// rather than re-raising through the listener queue, so the handler
|
|
216
|
+
// cascade documented above only holds on POSIX. On Windows, whichever
|
|
217
|
+
// module registers FIRST runs its sweep and the second is skipped —
|
|
218
|
+
// RUNTIME_ROOTS cleanup is best-effort there. SIGHUP is a no-op for
|
|
219
|
+
// most common code paths on Windows (Node fires it on console-close
|
|
220
|
+
// and exits within seconds).
|
|
221
|
+
const onSignal = (signal: NodeJS.Signals): void => {
|
|
222
|
+
sweep();
|
|
223
|
+
process.kill(process.pid, signal);
|
|
224
|
+
};
|
|
225
|
+
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"] as const) {
|
|
226
|
+
process.once(signal, onSignal);
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
type RuntimePlugin = Record<string, unknown> & { transform?: unknown };
|
|
231
|
+
|
|
232
|
+
const sdkTransformEnv = (): NodeJS.ProcessEnv =>
|
|
233
|
+
process.env.NESTIA_SDK_TRANSFORM === undefined
|
|
234
|
+
? { NESTIA_SDK_TRANSFORM: "1" }
|
|
235
|
+
: {};
|
|
236
|
+
|
|
237
|
+
const runtimePlugins = async (cwd: string): Promise<RuntimePlugin[]> => {
|
|
238
|
+
const plugins: RuntimePlugin[] = await readProjectPlugins(cwd);
|
|
239
|
+
const typia: RuntimePlugin | undefined = plugins.find((p) =>
|
|
240
|
+
isTransform(p, "typia"),
|
|
241
|
+
);
|
|
242
|
+
const core: RuntimePlugin | undefined = plugins.find((p) =>
|
|
243
|
+
isTransform(p, "@nestia/core"),
|
|
244
|
+
);
|
|
245
|
+
return [
|
|
246
|
+
{
|
|
247
|
+
...(typia ?? {}),
|
|
248
|
+
transform: "typia/lib/transform",
|
|
249
|
+
enabled: false,
|
|
250
|
+
},
|
|
251
|
+
normalizeRuntimePlugin({
|
|
252
|
+
...(core ?? {}),
|
|
253
|
+
transform: "@nestia/core/native/transform.cjs",
|
|
254
|
+
}),
|
|
255
|
+
];
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const readProjectPlugins = async (cwd: string): Promise<RuntimePlugin[]> => {
|
|
259
|
+
const project: string = normalizeProjectPath(process.env.NESTIA_PROJECT);
|
|
260
|
+
const file: string = path.isAbsolute(project)
|
|
261
|
+
? project
|
|
262
|
+
: path.join(cwd, project);
|
|
263
|
+
const config = await TsConfigReader.read(file);
|
|
264
|
+
const options = config.compilerOptions as
|
|
265
|
+
| { plugins?: RuntimePlugin[] }
|
|
266
|
+
| undefined;
|
|
267
|
+
return Array.isArray(options?.plugins)
|
|
268
|
+
? options.plugins
|
|
269
|
+
.filter((p) => typeof p === "object" && p !== null)
|
|
270
|
+
.map((p) => ({ ...(p as unknown as RuntimePlugin) }))
|
|
271
|
+
: [];
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
const normalizeRuntimePlugin = (plugin: RuntimePlugin): RuntimePlugin => {
|
|
275
|
+
const output: RuntimePlugin = { ...plugin };
|
|
276
|
+
if (output.enabled === false) delete output.enabled;
|
|
277
|
+
return output;
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
const isTransform = (plugin: RuntimePlugin, name: string): boolean =>
|
|
281
|
+
typeof plugin.transform === "string" && plugin.transform.includes(name);
|
|
282
|
+
|
|
283
|
+
const replaceExtension = (file: string, extension: string): string =>
|
|
284
|
+
file.replace(/\.[cm]?tsx?$/i, extension);
|
|
285
|
+
|
|
286
|
+
const normalizeProjectPath = (project: string | undefined): string => {
|
|
287
|
+
const next: string = project ?? "tsconfig.json";
|
|
288
|
+
return path.isAbsolute(next) || next.startsWith(".") ? next : `./${next}`;
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
const normalize_file = (str: string) =>
|
|
292
|
+
str.substring(
|
|
293
|
+
str.startsWith("file:///")
|
|
294
|
+
? process.cwd()[0] === "/"
|
|
295
|
+
? 7
|
|
296
|
+
: 8
|
|
297
|
+
: str.startsWith("file://")
|
|
298
|
+
? 7
|
|
299
|
+
: 0,
|
|
300
|
+
);
|
|
301
|
+
|
|
302
|
+
const filter =
|
|
303
|
+
(config: INestiaConfig) =>
|
|
304
|
+
async (location: string): Promise<boolean> =>
|
|
305
|
+
location.endsWith(".ts") &&
|
|
306
|
+
!location.endsWith(".d.ts") &&
|
|
307
|
+
(config.output === undefined ||
|
|
308
|
+
(location.indexOf(path.join(config.output, "functional")) === -1 &&
|
|
309
|
+
(await (
|
|
310
|
+
await bundler.get(config.output)
|
|
311
|
+
)(location))) === false);
|
|
312
|
+
|
|
313
|
+
const bundler = new Singleton(async (output: string) => {
|
|
314
|
+
const assets: string[] = await fs.promises.readdir(SdkGenerator.BUNDLE_PATH);
|
|
315
|
+
const tuples: Pair<string, boolean>[] = await ArrayUtil.asyncMap(
|
|
316
|
+
assets,
|
|
317
|
+
async (file) => {
|
|
318
|
+
const relative: string = path.join(output, file);
|
|
319
|
+
const location: string = path.join(SdkGenerator.BUNDLE_PATH, file);
|
|
320
|
+
const stats: fs.Stats = await fs.promises.stat(location);
|
|
321
|
+
return new Pair(relative, stats.isDirectory());
|
|
322
|
+
},
|
|
323
|
+
);
|
|
324
|
+
return async (file: string): Promise<boolean> => {
|
|
325
|
+
for (const it of tuples)
|
|
326
|
+
if (it.second === false && file === it.first) return true;
|
|
327
|
+
else if (it.second === true && file.indexOf(it.first) === 0) return true;
|
|
328
|
+
return false;
|
|
329
|
+
};
|
|
330
|
+
});
|