@honestjs/rpc-plugin 1.3.0 → 1.4.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/README.md +33 -59
- package/dist/index.d.mts +24 -52
- package/dist/index.d.ts +24 -52
- package/dist/index.js +79 -233
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +81 -234
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -36,7 +36,6 @@ __export(index_exports, {
|
|
|
36
36
|
DEFAULT_OPTIONS: () => DEFAULT_OPTIONS,
|
|
37
37
|
GENERIC_TYPES: () => GENERIC_TYPES,
|
|
38
38
|
LOG_PREFIX: () => LOG_PREFIX,
|
|
39
|
-
OpenApiGeneratorService: () => OpenApiGeneratorService,
|
|
40
39
|
RPCPlugin: () => RPCPlugin,
|
|
41
40
|
RouteAnalyzerService: () => RouteAnalyzerService,
|
|
42
41
|
SchemaGeneratorService: () => SchemaGeneratorService,
|
|
@@ -55,7 +54,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
55
54
|
|
|
56
55
|
// src/rpc.plugin.ts
|
|
57
56
|
var import_fs2 = __toESM(require("fs"));
|
|
58
|
-
var
|
|
57
|
+
var import_path3 = __toESM(require("path"));
|
|
59
58
|
var import_ts_morph = require("ts-morph");
|
|
60
59
|
|
|
61
60
|
// src/constants/defaults.ts
|
|
@@ -63,7 +62,13 @@ var DEFAULT_OPTIONS = {
|
|
|
63
62
|
controllerPattern: "src/modules/*/*.controller.ts",
|
|
64
63
|
tsConfigPath: "tsconfig.json",
|
|
65
64
|
outputDir: "./generated/rpc",
|
|
66
|
-
generateOnInit: true
|
|
65
|
+
generateOnInit: true,
|
|
66
|
+
context: {
|
|
67
|
+
namespace: "rpc",
|
|
68
|
+
keys: {
|
|
69
|
+
artifact: "artifact"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
67
72
|
};
|
|
68
73
|
var LOG_PREFIX = "[ RPCPlugin ]";
|
|
69
74
|
var BUILTIN_UTILITY_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -125,22 +130,22 @@ var import_path2 = __toESM(require("path"));
|
|
|
125
130
|
// src/utils/path-utils.ts
|
|
126
131
|
function buildFullPath(basePath, parameters) {
|
|
127
132
|
if (!basePath || typeof basePath !== "string") return "/";
|
|
128
|
-
let
|
|
133
|
+
let path4 = basePath;
|
|
129
134
|
if (parameters && Array.isArray(parameters)) {
|
|
130
135
|
for (const param of parameters) {
|
|
131
136
|
if (param.data && typeof param.data === "string" && param.data.startsWith(":")) {
|
|
132
137
|
const paramName = param.data.slice(1);
|
|
133
|
-
|
|
138
|
+
path4 = path4.replace(`:${paramName}`, `\${${paramName}}`);
|
|
134
139
|
}
|
|
135
140
|
}
|
|
136
141
|
}
|
|
137
|
-
return
|
|
142
|
+
return path4;
|
|
138
143
|
}
|
|
139
144
|
function buildFullApiPath(route) {
|
|
140
145
|
const prefix = route.prefix || "";
|
|
141
146
|
const version = route.version || "";
|
|
142
147
|
const routePath = route.route || "";
|
|
143
|
-
const
|
|
148
|
+
const path4 = route.path || "";
|
|
144
149
|
let fullPath = "";
|
|
145
150
|
if (prefix && prefix !== "/") {
|
|
146
151
|
fullPath += prefix.replace(/^\/+|\/+$/g, "");
|
|
@@ -151,9 +156,9 @@ function buildFullApiPath(route) {
|
|
|
151
156
|
if (routePath && routePath !== "/") {
|
|
152
157
|
fullPath += `/${routePath.replace(/^\/+|\/+$/g, "")}`;
|
|
153
158
|
}
|
|
154
|
-
if (
|
|
155
|
-
fullPath += `/${
|
|
156
|
-
} else if (
|
|
159
|
+
if (path4 && path4 !== "/") {
|
|
160
|
+
fullPath += `/${path4.replace(/^\/+|\/+$/g, "")}`;
|
|
161
|
+
} else if (path4 === "/") {
|
|
157
162
|
fullPath += "/";
|
|
158
163
|
}
|
|
159
164
|
if (fullPath && !fullPath.startsWith("/")) fullPath = "/" + fullPath;
|
|
@@ -509,192 +514,6 @@ ${this.generateControllerMethods(controllerGroups)}
|
|
|
509
514
|
}
|
|
510
515
|
};
|
|
511
516
|
|
|
512
|
-
// src/services/openapi-generator.service.ts
|
|
513
|
-
var import_promises3 = __toESM(require("fs/promises"));
|
|
514
|
-
var import_path3 = __toESM(require("path"));
|
|
515
|
-
var OpenApiGeneratorService = class {
|
|
516
|
-
constructor(outputDir) {
|
|
517
|
-
this.outputDir = outputDir;
|
|
518
|
-
}
|
|
519
|
-
async generateSpec(routes, schemas, options) {
|
|
520
|
-
await import_promises3.default.mkdir(this.outputDir, { recursive: true });
|
|
521
|
-
const schemaMap = this.buildSchemaMap(schemas);
|
|
522
|
-
const spec = this.buildSpec(routes, schemaMap, options);
|
|
523
|
-
const outputPath = import_path3.default.join(this.outputDir, options.outputFile);
|
|
524
|
-
await import_promises3.default.writeFile(outputPath, JSON.stringify(spec, null, 2), "utf-8");
|
|
525
|
-
return outputPath;
|
|
526
|
-
}
|
|
527
|
-
buildSpec(routes, schemaMap, options) {
|
|
528
|
-
const spec = {
|
|
529
|
-
openapi: "3.0.3",
|
|
530
|
-
info: {
|
|
531
|
-
title: options.title,
|
|
532
|
-
version: options.version,
|
|
533
|
-
description: options.description
|
|
534
|
-
},
|
|
535
|
-
paths: {},
|
|
536
|
-
components: { schemas: schemaMap }
|
|
537
|
-
};
|
|
538
|
-
if (options.servers.length > 0) {
|
|
539
|
-
spec.servers = options.servers.map((s) => ({ ...s }));
|
|
540
|
-
}
|
|
541
|
-
for (const route of routes) {
|
|
542
|
-
const apiPath = this.toOpenApiPath(buildFullApiPath(route));
|
|
543
|
-
const method = safeToString(route.method).toLowerCase();
|
|
544
|
-
if (!spec.paths[apiPath]) {
|
|
545
|
-
spec.paths[apiPath] = {};
|
|
546
|
-
}
|
|
547
|
-
spec.paths[apiPath][method] = this.buildOperation(route, schemaMap);
|
|
548
|
-
}
|
|
549
|
-
return spec;
|
|
550
|
-
}
|
|
551
|
-
buildOperation(route, schemaMap) {
|
|
552
|
-
const controllerName = safeToString(route.controller).replace(/Controller$/, "");
|
|
553
|
-
const handlerName = safeToString(route.handler);
|
|
554
|
-
const parameters = route.parameters || [];
|
|
555
|
-
const operation = {
|
|
556
|
-
operationId: handlerName,
|
|
557
|
-
tags: [controllerName],
|
|
558
|
-
responses: this.buildResponses(route.returns, schemaMap)
|
|
559
|
-
};
|
|
560
|
-
const openApiParams = this.buildParameters(parameters);
|
|
561
|
-
if (openApiParams.length > 0) {
|
|
562
|
-
operation.parameters = openApiParams;
|
|
563
|
-
}
|
|
564
|
-
const requestBody = this.buildRequestBody(parameters, schemaMap);
|
|
565
|
-
if (requestBody) {
|
|
566
|
-
operation.requestBody = requestBody;
|
|
567
|
-
}
|
|
568
|
-
return operation;
|
|
569
|
-
}
|
|
570
|
-
buildParameters(parameters) {
|
|
571
|
-
const result = [];
|
|
572
|
-
for (const param of parameters) {
|
|
573
|
-
if (param.decoratorType === "param") {
|
|
574
|
-
result.push({
|
|
575
|
-
name: param.data ?? param.name,
|
|
576
|
-
in: "path",
|
|
577
|
-
required: true,
|
|
578
|
-
schema: this.tsTypeToJsonSchema(param.type)
|
|
579
|
-
});
|
|
580
|
-
} else if (param.decoratorType === "query") {
|
|
581
|
-
if (param.data) {
|
|
582
|
-
result.push({
|
|
583
|
-
name: param.data,
|
|
584
|
-
in: "query",
|
|
585
|
-
required: param.required === true,
|
|
586
|
-
schema: this.tsTypeToJsonSchema(param.type)
|
|
587
|
-
});
|
|
588
|
-
} else {
|
|
589
|
-
result.push({
|
|
590
|
-
name: param.name,
|
|
591
|
-
in: "query",
|
|
592
|
-
required: param.required === true,
|
|
593
|
-
schema: this.tsTypeToJsonSchema(param.type)
|
|
594
|
-
});
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
return result;
|
|
599
|
-
}
|
|
600
|
-
buildRequestBody(parameters, schemaMap) {
|
|
601
|
-
const bodyParams = parameters.filter((p) => p.decoratorType === "body");
|
|
602
|
-
if (bodyParams.length === 0) return null;
|
|
603
|
-
const bodyParam = bodyParams[0];
|
|
604
|
-
const typeName = this.extractBaseTypeName(bodyParam.type);
|
|
605
|
-
let schema;
|
|
606
|
-
if (typeName && schemaMap[typeName]) {
|
|
607
|
-
schema = { $ref: `#/components/schemas/${typeName}` };
|
|
608
|
-
} else {
|
|
609
|
-
schema = { type: "object" };
|
|
610
|
-
}
|
|
611
|
-
return {
|
|
612
|
-
required: true,
|
|
613
|
-
content: {
|
|
614
|
-
"application/json": { schema }
|
|
615
|
-
}
|
|
616
|
-
};
|
|
617
|
-
}
|
|
618
|
-
buildResponses(returns, schemaMap) {
|
|
619
|
-
const responseSchema = this.resolveResponseSchema(returns, schemaMap);
|
|
620
|
-
if (!responseSchema) {
|
|
621
|
-
return { "200": { description: "Successful response" } };
|
|
622
|
-
}
|
|
623
|
-
return {
|
|
624
|
-
"200": {
|
|
625
|
-
description: "Successful response",
|
|
626
|
-
content: {
|
|
627
|
-
"application/json": { schema: responseSchema }
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
};
|
|
631
|
-
}
|
|
632
|
-
resolveResponseSchema(returns, schemaMap) {
|
|
633
|
-
if (!returns) return null;
|
|
634
|
-
let innerType = returns;
|
|
635
|
-
const promiseMatch = returns.match(/^Promise<(.+)>$/);
|
|
636
|
-
if (promiseMatch) {
|
|
637
|
-
innerType = promiseMatch[1];
|
|
638
|
-
}
|
|
639
|
-
const isArray = innerType.endsWith("[]");
|
|
640
|
-
const baseType = isArray ? innerType.slice(0, -2) : innerType;
|
|
641
|
-
if (["string", "number", "boolean"].includes(baseType)) {
|
|
642
|
-
const primitiveSchema = this.tsTypeToJsonSchema(baseType);
|
|
643
|
-
return isArray ? { type: "array", items: primitiveSchema } : primitiveSchema;
|
|
644
|
-
}
|
|
645
|
-
if (["void", "any", "unknown"].includes(baseType)) return null;
|
|
646
|
-
if (schemaMap[baseType]) {
|
|
647
|
-
const ref = { $ref: `#/components/schemas/${baseType}` };
|
|
648
|
-
return isArray ? { type: "array", items: ref } : ref;
|
|
649
|
-
}
|
|
650
|
-
return null;
|
|
651
|
-
}
|
|
652
|
-
buildSchemaMap(schemas) {
|
|
653
|
-
const result = {};
|
|
654
|
-
for (const schemaInfo of schemas) {
|
|
655
|
-
const definition = schemaInfo.schema?.definitions?.[schemaInfo.type];
|
|
656
|
-
if (definition) {
|
|
657
|
-
result[schemaInfo.type] = definition;
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
return result;
|
|
661
|
-
}
|
|
662
|
-
/**
|
|
663
|
-
* Converts Express-style `:param` path to OpenAPI `{param}` syntax
|
|
664
|
-
*/
|
|
665
|
-
toOpenApiPath(expressPath) {
|
|
666
|
-
return expressPath.replace(/:(\w+)/g, "{$1}");
|
|
667
|
-
}
|
|
668
|
-
tsTypeToJsonSchema(tsType) {
|
|
669
|
-
switch (tsType) {
|
|
670
|
-
case "number":
|
|
671
|
-
return { type: "number" };
|
|
672
|
-
case "boolean":
|
|
673
|
-
return { type: "boolean" };
|
|
674
|
-
case "string":
|
|
675
|
-
default:
|
|
676
|
-
return { type: "string" };
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
/**
|
|
680
|
-
* Extracts the base type name from a TS type string, stripping
|
|
681
|
-
* wrappers like `Partial<...>`, `...[]`, `Promise<...>`.
|
|
682
|
-
*/
|
|
683
|
-
extractBaseTypeName(tsType) {
|
|
684
|
-
if (!tsType) return null;
|
|
685
|
-
let type = tsType;
|
|
686
|
-
const promiseMatch = type.match(/^Promise<(.+)>$/);
|
|
687
|
-
if (promiseMatch) type = promiseMatch[1];
|
|
688
|
-
type = type.replace(/\[\]$/, "");
|
|
689
|
-
const genericMatch = type.match(/^\w+<(\w+)>$/);
|
|
690
|
-
if (genericMatch) type = genericMatch[1];
|
|
691
|
-
if (["string", "number", "boolean", "any", "void", "unknown", "object"].includes(type)) {
|
|
692
|
-
return null;
|
|
693
|
-
}
|
|
694
|
-
return type;
|
|
695
|
-
}
|
|
696
|
-
};
|
|
697
|
-
|
|
698
517
|
// src/services/route-analyzer.service.ts
|
|
699
518
|
var import_honestjs = require("honestjs");
|
|
700
519
|
var RouteAnalyzerService = class {
|
|
@@ -771,7 +590,7 @@ var RouteAnalyzerService = class {
|
|
|
771
590
|
version: route.version,
|
|
772
591
|
route: route.route,
|
|
773
592
|
path: route.path,
|
|
774
|
-
fullPath:
|
|
593
|
+
fullPath: buildFullApiPath(route),
|
|
775
594
|
parameters,
|
|
776
595
|
returns
|
|
777
596
|
};
|
|
@@ -989,41 +808,31 @@ var RPCPlugin = class {
|
|
|
989
808
|
tsConfigPath;
|
|
990
809
|
outputDir;
|
|
991
810
|
generateOnInit;
|
|
811
|
+
contextNamespace;
|
|
812
|
+
contextArtifactKey;
|
|
992
813
|
// Services
|
|
993
814
|
routeAnalyzer;
|
|
994
815
|
schemaGenerator;
|
|
995
816
|
clientGenerator;
|
|
996
|
-
openApiGenerator;
|
|
997
|
-
openApiOptions;
|
|
998
817
|
// Shared ts-morph project
|
|
999
818
|
project = null;
|
|
1000
819
|
// Internal state
|
|
1001
820
|
analyzedRoutes = [];
|
|
1002
821
|
analyzedSchemas = [];
|
|
1003
822
|
generatedInfo = null;
|
|
823
|
+
app = null;
|
|
1004
824
|
constructor(options = {}) {
|
|
1005
825
|
this.controllerPattern = options.controllerPattern ?? DEFAULT_OPTIONS.controllerPattern;
|
|
1006
|
-
this.tsConfigPath = options.tsConfigPath ??
|
|
1007
|
-
this.outputDir = options.outputDir ??
|
|
826
|
+
this.tsConfigPath = options.tsConfigPath ?? import_path3.default.resolve(process.cwd(), DEFAULT_OPTIONS.tsConfigPath);
|
|
827
|
+
this.outputDir = options.outputDir ?? import_path3.default.resolve(process.cwd(), DEFAULT_OPTIONS.outputDir);
|
|
1008
828
|
this.generateOnInit = options.generateOnInit ?? DEFAULT_OPTIONS.generateOnInit;
|
|
829
|
+
this.contextNamespace = options.context?.namespace ?? DEFAULT_OPTIONS.context.namespace;
|
|
830
|
+
this.contextArtifactKey = options.context?.keys?.artifact ?? DEFAULT_OPTIONS.context.keys.artifact;
|
|
1009
831
|
this.routeAnalyzer = new RouteAnalyzerService();
|
|
1010
832
|
this.schemaGenerator = new SchemaGeneratorService(this.controllerPattern, this.tsConfigPath);
|
|
1011
833
|
this.clientGenerator = new ClientGeneratorService(this.outputDir);
|
|
1012
|
-
this.openApiOptions = this.resolveOpenApiOptions(options.openapi);
|
|
1013
|
-
this.openApiGenerator = this.openApiOptions ? new OpenApiGeneratorService(this.outputDir) : null;
|
|
1014
834
|
this.validateConfiguration();
|
|
1015
835
|
}
|
|
1016
|
-
resolveOpenApiOptions(input) {
|
|
1017
|
-
if (!input) return null;
|
|
1018
|
-
const opts = input === true ? {} : input;
|
|
1019
|
-
return {
|
|
1020
|
-
title: opts.title ?? "API",
|
|
1021
|
-
version: opts.version ?? "1.0.0",
|
|
1022
|
-
description: opts.description ?? "",
|
|
1023
|
-
servers: opts.servers ?? [],
|
|
1024
|
-
outputFile: opts.outputFile ?? "openapi.json"
|
|
1025
|
-
};
|
|
1026
|
-
}
|
|
1027
836
|
/**
|
|
1028
837
|
* Validates the plugin configuration
|
|
1029
838
|
*/
|
|
@@ -1042,6 +851,12 @@ var RPCPlugin = class {
|
|
|
1042
851
|
if (!this.outputDir?.trim()) {
|
|
1043
852
|
errors.push("Output directory cannot be empty");
|
|
1044
853
|
}
|
|
854
|
+
if (!this.contextNamespace?.trim()) {
|
|
855
|
+
errors.push("Context namespace cannot be empty");
|
|
856
|
+
}
|
|
857
|
+
if (!this.contextArtifactKey?.trim()) {
|
|
858
|
+
errors.push("Context artifact key cannot be empty");
|
|
859
|
+
}
|
|
1045
860
|
if (errors.length > 0) {
|
|
1046
861
|
throw new Error(`Configuration validation failed: ${errors.join(", ")}`);
|
|
1047
862
|
}
|
|
@@ -1053,8 +868,10 @@ var RPCPlugin = class {
|
|
|
1053
868
|
* Called after all modules are registered
|
|
1054
869
|
*/
|
|
1055
870
|
afterModulesRegistered = async (app, hono) => {
|
|
871
|
+
this.app = app;
|
|
1056
872
|
if (this.generateOnInit) {
|
|
1057
873
|
await this.analyzeEverything();
|
|
874
|
+
this.publishArtifact(app);
|
|
1058
875
|
}
|
|
1059
876
|
};
|
|
1060
877
|
/**
|
|
@@ -1063,9 +880,6 @@ var RPCPlugin = class {
|
|
|
1063
880
|
async analyzeEverything(force = false) {
|
|
1064
881
|
try {
|
|
1065
882
|
this.log("Starting comprehensive RPC analysis...");
|
|
1066
|
-
this.analyzedRoutes = [];
|
|
1067
|
-
this.analyzedSchemas = [];
|
|
1068
|
-
this.generatedInfo = null;
|
|
1069
883
|
this.dispose();
|
|
1070
884
|
this.project = new import_ts_morph.Project({ tsConfigFilePath: this.tsConfigPath });
|
|
1071
885
|
this.project.addSourceFilesAtPaths([this.controllerPattern]);
|
|
@@ -1074,23 +888,22 @@ var RPCPlugin = class {
|
|
|
1074
888
|
const currentHash = computeHash(filePaths);
|
|
1075
889
|
const stored = readChecksum(this.outputDir);
|
|
1076
890
|
if (stored && stored.hash === currentHash && this.outputFilesExist()) {
|
|
1077
|
-
this.
|
|
1078
|
-
|
|
1079
|
-
|
|
891
|
+
if (this.loadArtifactFromDisk()) {
|
|
892
|
+
this.log("Source files unchanged \u2014 skipping regeneration");
|
|
893
|
+
this.dispose();
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
this.log("Source files unchanged but cached artifact missing/invalid \u2014 regenerating");
|
|
1080
897
|
}
|
|
1081
898
|
}
|
|
899
|
+
this.analyzedRoutes = [];
|
|
900
|
+
this.analyzedSchemas = [];
|
|
901
|
+
this.generatedInfo = null;
|
|
1082
902
|
this.analyzedRoutes = await this.routeAnalyzer.analyzeControllerMethods(this.project);
|
|
1083
903
|
this.analyzedSchemas = await this.schemaGenerator.generateSchemas(this.project);
|
|
1084
904
|
this.generatedInfo = await this.clientGenerator.generateClient(this.analyzedRoutes, this.analyzedSchemas);
|
|
1085
|
-
if (this.openApiGenerator && this.openApiOptions) {
|
|
1086
|
-
const specPath = await this.openApiGenerator.generateSpec(
|
|
1087
|
-
this.analyzedRoutes,
|
|
1088
|
-
this.analyzedSchemas,
|
|
1089
|
-
this.openApiOptions
|
|
1090
|
-
);
|
|
1091
|
-
this.log(`OpenAPI spec generated: ${specPath}`);
|
|
1092
|
-
}
|
|
1093
905
|
await writeChecksum(this.outputDir, { hash: computeHash(filePaths), files: filePaths });
|
|
906
|
+
this.writeArtifactToDisk();
|
|
1094
907
|
this.log(
|
|
1095
908
|
`\u2705 RPC analysis complete: ${this.analyzedRoutes.length} routes, ${this.analyzedSchemas.length} schemas`
|
|
1096
909
|
);
|
|
@@ -1106,6 +919,9 @@ var RPCPlugin = class {
|
|
|
1106
919
|
*/
|
|
1107
920
|
async analyze(force = true) {
|
|
1108
921
|
await this.analyzeEverything(force);
|
|
922
|
+
if (this.app) {
|
|
923
|
+
this.publishArtifact(this.app);
|
|
924
|
+
}
|
|
1109
925
|
}
|
|
1110
926
|
/**
|
|
1111
927
|
* Get the analyzed routes
|
|
@@ -1129,11 +945,42 @@ var RPCPlugin = class {
|
|
|
1129
945
|
* Checks whether expected output files exist on disk
|
|
1130
946
|
*/
|
|
1131
947
|
outputFilesExist() {
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
948
|
+
return import_fs2.default.existsSync(import_path3.default.join(this.outputDir, "client.ts")) && import_fs2.default.existsSync(import_path3.default.join(this.outputDir, "rpc-artifact.json"));
|
|
949
|
+
}
|
|
950
|
+
getArtifactPath() {
|
|
951
|
+
return import_path3.default.join(this.outputDir, "rpc-artifact.json");
|
|
952
|
+
}
|
|
953
|
+
writeArtifactToDisk() {
|
|
954
|
+
const artifact = {
|
|
955
|
+
routes: this.analyzedRoutes,
|
|
956
|
+
schemas: this.analyzedSchemas
|
|
957
|
+
};
|
|
958
|
+
import_fs2.default.mkdirSync(this.outputDir, { recursive: true });
|
|
959
|
+
import_fs2.default.writeFileSync(this.getArtifactPath(), JSON.stringify(artifact));
|
|
960
|
+
}
|
|
961
|
+
loadArtifactFromDisk() {
|
|
962
|
+
try {
|
|
963
|
+
const raw = import_fs2.default.readFileSync(this.getArtifactPath(), "utf8");
|
|
964
|
+
const parsed = JSON.parse(raw);
|
|
965
|
+
if (!Array.isArray(parsed.routes) || !Array.isArray(parsed.schemas)) {
|
|
966
|
+
return false;
|
|
967
|
+
}
|
|
968
|
+
this.analyzedRoutes = parsed.routes;
|
|
969
|
+
this.analyzedSchemas = parsed.schemas;
|
|
970
|
+
this.generatedInfo = null;
|
|
971
|
+
return true;
|
|
972
|
+
} catch {
|
|
973
|
+
return false;
|
|
1135
974
|
}
|
|
1136
|
-
|
|
975
|
+
}
|
|
976
|
+
publishArtifact(app) {
|
|
977
|
+
app.getContext().set(this.getArtifactContextKey(), {
|
|
978
|
+
routes: this.analyzedRoutes,
|
|
979
|
+
schemas: this.analyzedSchemas
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
getArtifactContextKey() {
|
|
983
|
+
return `${this.contextNamespace}.${this.contextArtifactKey}`;
|
|
1137
984
|
}
|
|
1138
985
|
/**
|
|
1139
986
|
* Cleanup resources to prevent memory leaks
|
|
@@ -1168,7 +1015,6 @@ var RPCPlugin = class {
|
|
|
1168
1015
|
DEFAULT_OPTIONS,
|
|
1169
1016
|
GENERIC_TYPES,
|
|
1170
1017
|
LOG_PREFIX,
|
|
1171
|
-
OpenApiGeneratorService,
|
|
1172
1018
|
RPCPlugin,
|
|
1173
1019
|
RouteAnalyzerService,
|
|
1174
1020
|
SchemaGeneratorService,
|