@lark-apaas/coding-preset-vite-react 1.0.21-alpha.20260902122148 → 1.0.21
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/index.d.ts.map +1 -1
- package/lib/index.js +63 -2
- package/lib/index.js.map +1 -1
- package/lib/plugins/banner.d.ts +3 -0
- package/lib/plugins/banner.d.ts.map +1 -0
- package/lib/plugins/banner.js +26 -0
- package/lib/plugins/banner.js.map +1 -0
- package/lib/plugins/dev-proxy.d.ts.map +1 -1
- package/lib/plugins/dev-proxy.js +28 -9
- package/lib/plugins/dev-proxy.js.map +1 -1
- package/lib/plugins/fonts-mirror.d.ts.map +1 -1
- package/lib/plugins/fonts-mirror.js +12 -19
- package/lib/plugins/fonts-mirror.js.map +1 -1
- package/lib/plugins/preconnect.d.ts +31 -0
- package/lib/plugins/preconnect.d.ts.map +1 -0
- package/lib/plugins/preconnect.js +65 -0
- package/lib/plugins/preconnect.js.map +1 -0
- package/lib/plugins/server-log.d.ts +2 -2
- package/lib/plugins/server-log.d.ts.map +1 -1
- package/lib/plugins/server-log.js +5 -4
- package/lib/plugins/server-log.js.map +1 -1
- package/lib/plugins/source-map-upload.d.ts +7 -0
- package/lib/plugins/source-map-upload.d.ts.map +1 -0
- package/lib/plugins/source-map-upload.js +104 -0
- package/lib/plugins/source-map-upload.js.map +1 -0
- package/lib/server-log/openapi/controller.d.ts +4 -0
- package/lib/server-log/openapi/controller.d.ts.map +1 -0
- package/lib/server-log/openapi/controller.js +60 -0
- package/lib/server-log/openapi/controller.js.map +1 -0
- package/lib/server-log/openapi/index.d.ts +2 -5
- package/lib/server-log/openapi/index.d.ts.map +1 -1
- package/lib/server-log/openapi/index.js +19 -10
- package/lib/server-log/openapi/index.js.map +1 -1
- package/lib/server-log/openapi/router.d.ts +2 -14
- package/lib/server-log/openapi/router.d.ts.map +1 -1
- package/lib/server-log/openapi/router.js +10 -9
- package/lib/server-log/openapi/router.js.map +1 -1
- package/lib/server-log/openapi/services.d.ts +7 -0
- package/lib/server-log/openapi/services.d.ts.map +1 -0
- package/lib/server-log/openapi/services.js +252 -0
- package/lib/server-log/openapi/services.js.map +1 -0
- package/lib/server-log/openapi/types.d.ts +42 -1
- package/lib/server-log/openapi/types.d.ts.map +1 -1
- package/lib/server-log/openapi/utils.d.ts +6 -0
- package/lib/server-log/openapi/utils.d.ts.map +1 -0
- package/lib/server-log/openapi/utils.js +97 -0
- package/lib/server-log/openapi/utils.js.map +1 -0
- package/lib/server-log/register.d.ts +1 -0
- package/lib/server-log/register.d.ts.map +1 -1
- package/lib/server-log/register.js +3 -2
- package/lib/server-log/register.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.sourceMapUploadPlugin = sourceMapUploadPlugin;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
function sourceMapUploadPlugin(options) {
|
|
40
|
+
if (!options.outputDir) {
|
|
41
|
+
throw new Error('SourceMapUploadPlugin: outputDir is required');
|
|
42
|
+
}
|
|
43
|
+
let config;
|
|
44
|
+
return {
|
|
45
|
+
name: 'vite-plugin-source-map-upload',
|
|
46
|
+
apply: 'build', // Only apply during build
|
|
47
|
+
enforce: 'post',
|
|
48
|
+
configResolved(resolvedConfig) {
|
|
49
|
+
config = resolvedConfig;
|
|
50
|
+
},
|
|
51
|
+
async writeBundle(outputOptions) {
|
|
52
|
+
console.log('SourceMapUploadPlugin: Starting sourcemap consolidation process...');
|
|
53
|
+
const outputDir = outputOptions.dir || config.build.outDir;
|
|
54
|
+
if (!outputDir) {
|
|
55
|
+
console.warn('SourceMapUploadPlugin: output.dir is not defined. Skipping sourcemap consolidation.');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const sourceMapFiles = fs
|
|
59
|
+
.readdirSync(outputDir, { recursive: true })
|
|
60
|
+
.filter(file => file.toString().endsWith('.map'));
|
|
61
|
+
if (sourceMapFiles.length === 0) {
|
|
62
|
+
console.log('SourceMapUploadPlugin: No sourcemaps found to consolidate.');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const outputBaseDir = path.basename(outputDir); // e.g., 'client'
|
|
66
|
+
const sourcemapTargetDir = path.join(options.outputDir, outputBaseDir); // e.g., 'dist/sourcemaps/client'
|
|
67
|
+
for (const sourceMapFile of sourceMapFiles) {
|
|
68
|
+
const sourceMapPath = path.join(outputDir, sourceMapFile.toString());
|
|
69
|
+
const destinationPath = path.join(sourcemapTargetDir, sourceMapFile.toString());
|
|
70
|
+
try {
|
|
71
|
+
// Ensure the destination directory exists
|
|
72
|
+
const destinationDir = path.dirname(destinationPath);
|
|
73
|
+
if (!fs.existsSync(destinationDir)) {
|
|
74
|
+
fs.mkdirSync(destinationDir, { recursive: true });
|
|
75
|
+
}
|
|
76
|
+
// Move the file; fallback to copy+delete on cross-filesystem (EXDEV)
|
|
77
|
+
try {
|
|
78
|
+
fs.renameSync(sourceMapPath, destinationPath);
|
|
79
|
+
}
|
|
80
|
+
catch (renameError) {
|
|
81
|
+
if (renameError.code === 'EXDEV') {
|
|
82
|
+
fs.copyFileSync(sourceMapPath, destinationPath);
|
|
83
|
+
try {
|
|
84
|
+
fs.unlinkSync(sourceMapPath);
|
|
85
|
+
}
|
|
86
|
+
catch (deleteError) {
|
|
87
|
+
console.warn(`SourceMapUploadPlugin: Failed to delete original sourcemap ${sourceMapPath}.`, deleteError);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
throw renameError;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
console.log(`SourceMapUploadPlugin: Consolidated ${sourceMapFile} to ${destinationPath}`);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
const errorMessage = `SourceMapUploadPlugin: Failed to consolidate ${sourceMapFile}.`;
|
|
98
|
+
console.error(errorMessage, error);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=source-map-upload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-map-upload.js","sourceRoot":"","sources":["../../src/plugins/source-map-upload.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Request, Response } from 'express';
|
|
2
|
+
import type { MiddlewareContext } from '../types';
|
|
3
|
+
export declare function createOpenapiHandler(openapiFilePath: string, enableEnhancement: boolean, serverDir?: string): (_req: Request, res: Response, context: MiddlewareContext) => Promise<Response<any, Record<string, any>> | undefined>;
|
|
4
|
+
//# sourceMappingURL=controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../src/server-log/openapi/controller.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAElD,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,MAAM,EACvB,iBAAiB,EAAE,OAAO,EAC1B,SAAS,CAAC,EAAE,MAAM,IAIJ,MAAM,OAAO,EAAE,KAAK,QAAQ,EAAE,SAAS,iBAAiB,6DAmDvE"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createOpenapiHandler = createOpenapiHandler;
|
|
7
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
8
|
+
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
9
|
+
const services_1 = require("./services");
|
|
10
|
+
const utils_1 = require("./utils");
|
|
11
|
+
function createOpenapiHandler(openapiFilePath, enableEnhancement, serverDir) {
|
|
12
|
+
let cache = null;
|
|
13
|
+
return async (_req, res, context) => {
|
|
14
|
+
try {
|
|
15
|
+
let fileBuffer;
|
|
16
|
+
try {
|
|
17
|
+
fileBuffer = await promises_1.default.readFile(openapiFilePath, 'utf-8');
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
if (err?.code === 'ENOENT') {
|
|
21
|
+
return res.status(404).json({
|
|
22
|
+
error: 'OpenAPI spec not found',
|
|
23
|
+
message: `${openapiFilePath} does not exist. Run code generation first.`,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
throw err;
|
|
27
|
+
}
|
|
28
|
+
const currentHash = node_crypto_1.default.createHash('md5').update(fileBuffer).digest('hex');
|
|
29
|
+
if (cache && cache.fileHash === currentHash) {
|
|
30
|
+
return res.json(cache.data);
|
|
31
|
+
}
|
|
32
|
+
let payload = JSON.parse(fileBuffer);
|
|
33
|
+
if (enableEnhancement && context.isDev) {
|
|
34
|
+
const { openapi: enhancedPayload, stats } = await (0, services_1.enhanceOpenApiWithSourceInfo)({
|
|
35
|
+
openapiData: payload,
|
|
36
|
+
writeFile: false,
|
|
37
|
+
serverDir: serverDir || context.rootDir,
|
|
38
|
+
});
|
|
39
|
+
payload = enhancedPayload;
|
|
40
|
+
console.log(`[OpenAPI] Enhanced in ${stats.duration}ms (${stats.endpointsEnhanced} endpoints)`);
|
|
41
|
+
}
|
|
42
|
+
const result = (0, utils_1.transformOpenapiPaths)(payload, context.basePath);
|
|
43
|
+
cache = {
|
|
44
|
+
data: result,
|
|
45
|
+
fileHash: currentHash,
|
|
46
|
+
};
|
|
47
|
+
res.json(result);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
52
|
+
res.status(500).json({
|
|
53
|
+
error: 'Failed to load OpenAPI spec',
|
|
54
|
+
message,
|
|
55
|
+
});
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller.js","sourceRoot":"","sources":["../../../src/server-log/openapi/controller.ts"],"names":[],"mappings":";;;;;AAUA,oDA0DC;AApED,gEAAkC;AAClC,8DAAiC;AAEjC,yCAA0D;AAC1D,mCAAgD;AAMhD,SAAgB,oBAAoB,CAClC,eAAuB,EACvB,iBAA0B,EAC1B,SAAkB;IAElB,IAAI,KAAK,GAAwB,IAAI,CAAC;IAEtC,OAAO,KAAK,EAAE,IAAa,EAAE,GAAa,EAAE,OAA0B,EAAE,EAAE;QACxE,IAAI,CAAC;YACH,IAAI,UAAkB,CAAC;YACvB,IAAI,CAAC;gBACH,UAAU,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;YAC3D,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAK,GAA6B,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACtD,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;wBAC1B,KAAK,EAAE,wBAAwB;wBAC/B,OAAO,EAAE,GAAG,eAAe,6CAA6C;qBACzE,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC;YAED,MAAM,WAAW,GAAG,qBAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAE9E,IAAI,KAAK,IAAI,KAAK,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;gBAC5C,OAAO,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;YAED,IAAI,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAErC,IAAI,iBAAiB,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBACvC,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,GAAG,MAAM,IAAA,uCAA4B,EAAC;oBAC7E,WAAW,EAAE,OAAO;oBACpB,SAAS,EAAE,KAAK;oBAChB,SAAS,EAAE,SAAS,IAAI,OAAO,CAAC,OAAO;iBACxC,CAAC,CAAC;gBACH,OAAO,GAAG,eAAe,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,yBAAyB,KAAK,CAAC,QAAQ,OAAO,KAAK,CAAC,iBAAiB,aAAa,CAAC,CAAC;YAClG,CAAC;YAED,MAAM,MAAM,GAAG,IAAA,6BAAqB,EAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;YAEhE,KAAK,GAAG;gBACN,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,WAAW;aACtB,CAAC;YAEF,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACjB,OAAO;QACT,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;YACzE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,6BAA6B;gBACpC,OAAO;aACR,CAAC,CAAC;YACH,OAAO;QACT,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import type { RouteMiddleware } from '../types';
|
|
2
2
|
import type { OpenapiMiddlewareOptions } from './types';
|
|
3
|
-
/**
|
|
4
|
-
* Creates OpenAPI middleware that serves /dev/openapi/spec —— 妙搭「开放 API」
|
|
5
|
-
* 面板消费的端点,直接读 docs/openapi.json 并过滤成 /openapi/* 子集。
|
|
6
|
-
*/
|
|
7
3
|
export declare function createOpenapiMiddleware(options: OpenapiMiddlewareOptions): RouteMiddleware;
|
|
8
|
-
export type { OpenapiMiddlewareOptions } from './types';
|
|
4
|
+
export type { OpenapiMiddlewareOptions, SourceInfo, EnhanceOptions, EnhanceResult } from './types';
|
|
5
|
+
export { enhanceOpenApiWithSourceInfo, parseApiRoutes } from './services';
|
|
9
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server-log/openapi/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,UAAU,CAAC;AAC9E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server-log/openapi/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,UAAU,CAAC;AAC9E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAgBxD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,wBAAwB,GAAG,eAAe,CAuB1F;AAED,YAAY,EAAE,wBAAwB,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnG,OAAO,EAAE,4BAA4B,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -1,31 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseApiRoutes = exports.enhanceOpenApiWithSourceInfo = void 0;
|
|
3
4
|
exports.createOpenapiMiddleware = createOpenapiMiddleware;
|
|
4
5
|
const router_1 = require("./router");
|
|
5
|
-
/**
|
|
6
|
-
* Routes provided by OpenAPI middleware
|
|
7
|
-
*/
|
|
8
6
|
const OPENAPI_ROUTES = [
|
|
7
|
+
{
|
|
8
|
+
method: 'GET',
|
|
9
|
+
path: '/openapi.json',
|
|
10
|
+
description: 'Serve enhanced OpenAPI specification with source code references',
|
|
11
|
+
},
|
|
9
12
|
{
|
|
10
13
|
method: 'GET',
|
|
11
14
|
path: '/openapi/spec',
|
|
12
15
|
description: 'Serve OpenAPI specification for /openapi/*',
|
|
13
16
|
},
|
|
14
17
|
];
|
|
15
|
-
/**
|
|
16
|
-
* Creates OpenAPI middleware that serves /dev/openapi/spec —— 妙搭「开放 API」
|
|
17
|
-
* 面板消费的端点,直接读 docs/openapi.json 并过滤成 /openapi/* 子集。
|
|
18
|
-
*/
|
|
19
18
|
function createOpenapiMiddleware(options) {
|
|
20
|
-
const { openapiSpecFilePath } = options;
|
|
19
|
+
const { openapiFilePath, openapiSpecFilePath, enableEnhancement = true, serverDir } = options;
|
|
20
|
+
const routes = OPENAPI_ROUTES.filter((route) => {
|
|
21
|
+
if (route.path === '/openapi.json' && !openapiFilePath)
|
|
22
|
+
return false;
|
|
23
|
+
if (route.path === '/openapi/spec' && !openapiSpecFilePath)
|
|
24
|
+
return false;
|
|
25
|
+
return true;
|
|
26
|
+
});
|
|
21
27
|
return {
|
|
22
28
|
name: 'openapi',
|
|
23
29
|
mountPath: '/dev',
|
|
24
|
-
routes
|
|
30
|
+
routes,
|
|
25
31
|
enabled: (context) => context.isDev,
|
|
26
32
|
createRouter: (context) => {
|
|
27
|
-
return (0, router_1.createOpenapiRouter)({ openapiSpecFilePath }, context);
|
|
33
|
+
return (0, router_1.createOpenapiRouter)({ openapiFilePath, openapiSpecFilePath, enableEnhancement, serverDir }, context);
|
|
28
34
|
},
|
|
29
35
|
};
|
|
30
36
|
}
|
|
37
|
+
var services_1 = require("./services");
|
|
38
|
+
Object.defineProperty(exports, "enhanceOpenApiWithSourceInfo", { enumerable: true, get: function () { return services_1.enhanceOpenApiWithSourceInfo; } });
|
|
39
|
+
Object.defineProperty(exports, "parseApiRoutes", { enumerable: true, get: function () { return services_1.parseApiRoutes; } });
|
|
31
40
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server-log/openapi/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server-log/openapi/index.ts"],"names":[],"mappings":";;;AAiBA,0DAuBC;AAtCD,qCAA+C;AAE/C,MAAM,cAAc,GAAgB;IAClC;QACE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,kEAAkE;KAChF;IACD;QACE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,4CAA4C;KAC1D;CACF,CAAC;AAEF,SAAgB,uBAAuB,CAAC,OAAiC;IACvE,MAAM,EAAE,eAAe,EAAE,mBAAmB,EAAE,iBAAiB,GAAG,IAAI,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAE9F,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QAC7C,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,IAAI,CAAC,eAAe;YAAE,OAAO,KAAK,CAAC;QACrE,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,IAAI,CAAC,mBAAmB;YAAE,OAAO,KAAK,CAAC;QACzE,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,IAAI,EAAE,SAAS;QACf,SAAS,EAAE,MAAM;QACjB,MAAM;QAEN,OAAO,EAAE,CAAC,OAA0B,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK;QAEtD,YAAY,EAAE,CAAC,OAA0B,EAAE,EAAE;YAC3C,OAAO,IAAA,4BAAmB,EACxB,EAAE,eAAe,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,SAAS,EAAE,EACtE,OAAO,CACR,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAGD,uCAA0E;AAAjE,wHAAA,4BAA4B,OAAA;AAAE,0GAAA,cAAc,OAAA"}
|
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
2
|
import type { MiddlewareContext } from '../types';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*/
|
|
6
|
-
export interface OpenapiRouterOptions {
|
|
7
|
-
/** Path to the OpenAPI spec source file for /openapi/spec */
|
|
8
|
-
openapiSpecFilePath: string;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Create OpenAPI router
|
|
12
|
-
*
|
|
13
|
-
* 仅提供 GET /openapi/spec —— 妙搭「开放 API」面板消费的端点,
|
|
14
|
-
* 直接读 docs/openapi.json 并过滤成 /openapi/* 的子集($refs 展平)。
|
|
15
|
-
*/
|
|
16
|
-
export declare function createOpenapiRouter(options: OpenapiRouterOptions, context: MiddlewareContext): Router;
|
|
3
|
+
import type { OpenapiMiddlewareOptions } from './types';
|
|
4
|
+
export declare function createOpenapiRouter(options: OpenapiMiddlewareOptions, context: MiddlewareContext): Router;
|
|
17
5
|
//# sourceMappingURL=router.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/server-log/openapi/router.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/server-log/openapi/router.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAIxD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,wBAAwB,EACjC,OAAO,EAAE,iBAAiB,GACzB,MAAM,CAeR"}
|
|
@@ -5,18 +5,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.createOpenapiRouter = createOpenapiRouter;
|
|
7
7
|
const express_1 = __importDefault(require("express"));
|
|
8
|
+
const controller_1 = require("./controller");
|
|
8
9
|
const spec_controller_1 = require("./spec-controller");
|
|
9
|
-
/**
|
|
10
|
-
* Create OpenAPI router
|
|
11
|
-
*
|
|
12
|
-
* 仅提供 GET /openapi/spec —— 妙搭「开放 API」面板消费的端点,
|
|
13
|
-
* 直接读 docs/openapi.json 并过滤成 /openapi/* 的子集($refs 展平)。
|
|
14
|
-
*/
|
|
15
10
|
function createOpenapiRouter(options, context) {
|
|
16
|
-
const { openapiSpecFilePath } = options;
|
|
11
|
+
const { openapiFilePath, openapiSpecFilePath, enableEnhancement = true, serverDir } = options;
|
|
17
12
|
const router = express_1.default.Router();
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
if (openapiFilePath) {
|
|
14
|
+
const handler = (0, controller_1.createOpenapiHandler)(openapiFilePath, enableEnhancement, serverDir);
|
|
15
|
+
router.get('/openapi.json', (req, res) => handler(req, res, context));
|
|
16
|
+
}
|
|
17
|
+
if (openapiSpecFilePath) {
|
|
18
|
+
const specHandler = (0, spec_controller_1.createOpenapiSpecHandler)(openapiSpecFilePath);
|
|
19
|
+
router.get('/openapi/spec', (req, res) => specHandler(req, res, context));
|
|
20
|
+
}
|
|
20
21
|
return router;
|
|
21
22
|
}
|
|
22
23
|
//# sourceMappingURL=router.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../../src/server-log/openapi/router.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../../src/server-log/openapi/router.ts"],"names":[],"mappings":";;;;;AAMA,kDAkBC;AAxBD,sDAA0C;AAG1C,6CAAoD;AACpD,uDAA6D;AAE7D,SAAgB,mBAAmB,CACjC,OAAiC,EACjC,OAA0B;IAE1B,MAAM,EAAE,eAAe,EAAE,mBAAmB,EAAE,iBAAiB,GAAG,IAAI,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAC9F,MAAM,MAAM,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAC;IAEhC,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,IAAA,iCAAoB,EAAC,eAAe,EAAE,iBAAiB,EAAE,SAAS,CAAC,CAAC;QACpF,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,IAAI,mBAAmB,EAAE,CAAC;QACxB,MAAM,WAAW,GAAG,IAAA,0CAAwB,EAAC,mBAAmB,CAAC,CAAC;QAClE,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { EnhanceOptions, EnhanceResult } from './types';
|
|
2
|
+
export declare function enhanceOpenApiWithSourceInfo(options?: EnhanceOptions): Promise<EnhanceResult>;
|
|
3
|
+
export declare function parseApiRoutes(serverDir: string): Array<{
|
|
4
|
+
method: string;
|
|
5
|
+
path: string;
|
|
6
|
+
}>;
|
|
7
|
+
//# sourceMappingURL=services.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../../src/server-log/openapi/services.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAc,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGzE,wBAAsB,4BAA4B,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAkCvG;AAyLD,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAQzF"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.enhanceOpenApiWithSourceInfo = enhanceOpenApiWithSourceInfo;
|
|
40
|
+
exports.parseApiRoutes = parseApiRoutes;
|
|
41
|
+
const node_fs_1 = require("node:fs");
|
|
42
|
+
const fsSync = __importStar(require("node:fs"));
|
|
43
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
44
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
45
|
+
const utils_1 = require("./utils");
|
|
46
|
+
async function enhanceOpenApiWithSourceInfo(options = {}) {
|
|
47
|
+
const startTime = Date.now();
|
|
48
|
+
const openapiPath = options.openapiPath || node_path_1.default.resolve(__dirname, '../client/src/api/gen/openapi.json');
|
|
49
|
+
const serverDir = options.serverDir || node_path_1.default.resolve(__dirname, '../server');
|
|
50
|
+
const writeFile = options.writeFile !== false;
|
|
51
|
+
let openapi;
|
|
52
|
+
if (options.openapiData) {
|
|
53
|
+
openapi = JSON.parse(JSON.stringify(options.openapiData));
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
const openapiContent = await node_fs_1.promises.readFile(openapiPath, 'utf-8');
|
|
57
|
+
openapi = JSON.parse(openapiContent);
|
|
58
|
+
}
|
|
59
|
+
const controllerFiles = await (0, utils_1.findControllerFiles)(serverDir);
|
|
60
|
+
const sourceMap = await (0, utils_1.buildSourceMap)(controllerFiles, processControllerFile);
|
|
61
|
+
const enhanced = (0, utils_1.enhanceOpenApiPaths)(openapi, sourceMap);
|
|
62
|
+
if (writeFile) {
|
|
63
|
+
await node_fs_1.promises.writeFile(openapiPath, JSON.stringify(openapi, null, 2) + '\n', 'utf-8');
|
|
64
|
+
}
|
|
65
|
+
const duration = Date.now() - startTime;
|
|
66
|
+
return {
|
|
67
|
+
openapi,
|
|
68
|
+
stats: {
|
|
69
|
+
duration,
|
|
70
|
+
controllersFound: controllerFiles.length,
|
|
71
|
+
endpointsExtracted: sourceMap.size,
|
|
72
|
+
endpointsEnhanced: enhanced,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
async function processControllerFile(filePath) {
|
|
77
|
+
const relativePath = node_path_1.default.relative(process.cwd(), filePath);
|
|
78
|
+
const content = await node_fs_1.promises.readFile(filePath, 'utf-8');
|
|
79
|
+
const sourceFile = typescript_1.default.createSourceFile(filePath, content, typescript_1.default.ScriptTarget.Latest, true);
|
|
80
|
+
return extractControllerMetadata(sourceFile, relativePath);
|
|
81
|
+
}
|
|
82
|
+
function extractControllerMetadata(sourceFile, filePath) {
|
|
83
|
+
const metadata = new Map();
|
|
84
|
+
let controllerPath = '';
|
|
85
|
+
let className = '';
|
|
86
|
+
function getDecorators(node) {
|
|
87
|
+
if ('modifiers' in node && Array.isArray(node.modifiers)) {
|
|
88
|
+
return node.modifiers.filter((mod) => mod.kind === typescript_1.default.SyntaxKind.Decorator);
|
|
89
|
+
}
|
|
90
|
+
if ('decorators' in node && Array.isArray(node.decorators)) {
|
|
91
|
+
return node.decorators;
|
|
92
|
+
}
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
function visit(node) {
|
|
96
|
+
if (typescript_1.default.isClassDeclaration(node)) {
|
|
97
|
+
const decorators = getDecorators(node);
|
|
98
|
+
if (node.name) {
|
|
99
|
+
className = node.name.getText(sourceFile);
|
|
100
|
+
}
|
|
101
|
+
for (const decorator of decorators) {
|
|
102
|
+
if (typescript_1.default.isCallExpression(decorator.expression)) {
|
|
103
|
+
const expression = decorator.expression;
|
|
104
|
+
const decoratorName = expression.expression.getText(sourceFile);
|
|
105
|
+
if (decoratorName === 'Controller') {
|
|
106
|
+
if (expression.arguments.length > 0) {
|
|
107
|
+
const arg = expression.arguments[0];
|
|
108
|
+
if (typescript_1.default.isStringLiteral(arg)) {
|
|
109
|
+
controllerPath = arg.text;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (typescript_1.default.isMethodDeclaration(node) && node.name) {
|
|
117
|
+
const methodName = node.name.getText(sourceFile);
|
|
118
|
+
let httpMethod = '';
|
|
119
|
+
let routePath = '';
|
|
120
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
121
|
+
const decorators = getDecorators(node);
|
|
122
|
+
for (const decorator of decorators) {
|
|
123
|
+
if (typescript_1.default.isCallExpression(decorator.expression)) {
|
|
124
|
+
const decoratorName = decorator.expression.expression.getText(sourceFile);
|
|
125
|
+
if (['Get', 'Post', 'Put', 'Delete', 'Patch', 'Options', 'Head', 'All'].includes(decoratorName)) {
|
|
126
|
+
httpMethod = decoratorName.toLowerCase();
|
|
127
|
+
if (decorator.expression.arguments.length > 0) {
|
|
128
|
+
const arg = decorator.expression.arguments[0];
|
|
129
|
+
if (typescript_1.default.isStringLiteral(arg)) {
|
|
130
|
+
routePath = arg.text;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (httpMethod && methodName && className) {
|
|
137
|
+
const operationId = `${className}_${methodName}`;
|
|
138
|
+
metadata.set(operationId, {
|
|
139
|
+
file: filePath,
|
|
140
|
+
line: line + 1,
|
|
141
|
+
method: httpMethod,
|
|
142
|
+
controllerPath,
|
|
143
|
+
routePath,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
typescript_1.default.forEachChild(node, visit);
|
|
148
|
+
}
|
|
149
|
+
visit(sourceFile);
|
|
150
|
+
return metadata;
|
|
151
|
+
}
|
|
152
|
+
const HTTP_DECORATOR_NAMES = ['Get', 'Post', 'Put', 'Delete', 'Patch', 'Options', 'Head', 'All'];
|
|
153
|
+
function findControllerFilesSync(dir) {
|
|
154
|
+
const files = [];
|
|
155
|
+
function scan(currentDir) {
|
|
156
|
+
let entries;
|
|
157
|
+
try {
|
|
158
|
+
entries = fsSync.readdirSync(currentDir, { withFileTypes: true });
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
for (const entry of entries) {
|
|
164
|
+
const fullPath = node_path_1.default.join(currentDir, entry.name);
|
|
165
|
+
if (entry.isDirectory()) {
|
|
166
|
+
scan(fullPath);
|
|
167
|
+
}
|
|
168
|
+
else if (entry.isFile() && entry.name.endsWith('.controller.ts')) {
|
|
169
|
+
files.push(fullPath);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
scan(dir);
|
|
174
|
+
return files;
|
|
175
|
+
}
|
|
176
|
+
function normalizeApiPath(controllerPath, routePath) {
|
|
177
|
+
const combined = routePath ? `${controllerPath}/${routePath}` : controllerPath;
|
|
178
|
+
let normalized = combined.replace(/\/+/g, '/');
|
|
179
|
+
if (!normalized.startsWith('/'))
|
|
180
|
+
normalized = `/${normalized}`;
|
|
181
|
+
if (normalized.length > 1 && normalized.endsWith('/'))
|
|
182
|
+
normalized = normalized.slice(0, -1);
|
|
183
|
+
return normalized;
|
|
184
|
+
}
|
|
185
|
+
function parseControllerRoutes(filePath) {
|
|
186
|
+
let content;
|
|
187
|
+
try {
|
|
188
|
+
content = fsSync.readFileSync(filePath, 'utf-8');
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return [];
|
|
192
|
+
}
|
|
193
|
+
const sourceFile = typescript_1.default.createSourceFile(filePath, content, typescript_1.default.ScriptTarget.Latest, true);
|
|
194
|
+
const routes = [];
|
|
195
|
+
function getDecoratorsCompat(node) {
|
|
196
|
+
if ('modifiers' in node && Array.isArray(node.modifiers)) {
|
|
197
|
+
return node.modifiers.filter((mod) => mod.kind === typescript_1.default.SyntaxKind.Decorator);
|
|
198
|
+
}
|
|
199
|
+
if ('decorators' in node && Array.isArray(node.decorators)) {
|
|
200
|
+
return node.decorators;
|
|
201
|
+
}
|
|
202
|
+
return [];
|
|
203
|
+
}
|
|
204
|
+
function getStringArg(expr) {
|
|
205
|
+
if (expr.arguments.length > 0 && typescript_1.default.isStringLiteral(expr.arguments[0])) {
|
|
206
|
+
return expr.arguments[0].text;
|
|
207
|
+
}
|
|
208
|
+
return '';
|
|
209
|
+
}
|
|
210
|
+
function visit(node) {
|
|
211
|
+
if (typescript_1.default.isClassDeclaration(node)) {
|
|
212
|
+
let controllerPath = '';
|
|
213
|
+
for (const dec of getDecoratorsCompat(node)) {
|
|
214
|
+
if (typescript_1.default.isCallExpression(dec.expression)) {
|
|
215
|
+
const name = dec.expression.expression.getText(sourceFile);
|
|
216
|
+
if (name === 'Controller') {
|
|
217
|
+
controllerPath = getStringArg(dec.expression);
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
for (const member of node.members) {
|
|
223
|
+
if (!typescript_1.default.isMethodDeclaration(member))
|
|
224
|
+
continue;
|
|
225
|
+
for (const dec of getDecoratorsCompat(member)) {
|
|
226
|
+
if (!typescript_1.default.isCallExpression(dec.expression))
|
|
227
|
+
continue;
|
|
228
|
+
const decoratorName = dec.expression.expression.getText(sourceFile);
|
|
229
|
+
if (!HTTP_DECORATOR_NAMES.includes(decoratorName))
|
|
230
|
+
continue;
|
|
231
|
+
const routePath = getStringArg(dec.expression);
|
|
232
|
+
const fullPath = normalizeApiPath(controllerPath, routePath);
|
|
233
|
+
const method = decoratorName === 'All' ? '*' : decoratorName.toUpperCase();
|
|
234
|
+
routes.push({ method, path: fullPath });
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
typescript_1.default.forEachChild(node, visit);
|
|
239
|
+
}
|
|
240
|
+
visit(sourceFile);
|
|
241
|
+
return routes;
|
|
242
|
+
}
|
|
243
|
+
function parseApiRoutes(serverDir) {
|
|
244
|
+
const resolvedDir = node_path_1.default.resolve(serverDir);
|
|
245
|
+
const controllerFiles = findControllerFilesSync(resolvedDir);
|
|
246
|
+
const routes = [];
|
|
247
|
+
for (const filePath of controllerFiles) {
|
|
248
|
+
routes.push(...parseControllerRoutes(filePath));
|
|
249
|
+
}
|
|
250
|
+
return routes;
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=services.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"services.js","sourceRoot":"","sources":["../../../src/server-log/openapi/services.ts"],"names":[],"mappings":"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"}
|