@lark-apaas/fullstack-nestjs-core 0.0.0-alpha.1 → 0.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +108 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +22 -0
- package/dist/index.d.ts +21 -2
- package/dist/index.js +67 -6
- package/dist/index.js.map +1 -1
- package/package.json +16 -5
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
DevToolsModule: () => DevToolsModule
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_exports);
|
|
36
|
+
|
|
37
|
+
// src/modules/devtool/devtool.module.ts
|
|
38
|
+
var import_swagger = require("@nestjs/swagger");
|
|
39
|
+
var import_node_fs2 = require("fs");
|
|
40
|
+
var import_node_path2 = require("path");
|
|
41
|
+
|
|
42
|
+
// src/modules/devtool/helper.ts
|
|
43
|
+
var import_node_path = require("path");
|
|
44
|
+
var import_node_fs = require("fs");
|
|
45
|
+
function normalizeBasePath(rawBasePath) {
|
|
46
|
+
const normalizedBasePath = rawBasePath.startsWith("/") ? rawBasePath : `/${rawBasePath}`;
|
|
47
|
+
return normalizedBasePath.endsWith("/") ? normalizedBasePath.slice(0, -1) : normalizedBasePath;
|
|
48
|
+
}
|
|
49
|
+
function resolveOptsWithDefaultValue(options) {
|
|
50
|
+
const basePath = normalizeBasePath(options.basePath || "/");
|
|
51
|
+
const docsPath = normalizeBasePath(options.docsPath || `api/docs`);
|
|
52
|
+
return {
|
|
53
|
+
...options,
|
|
54
|
+
basePath,
|
|
55
|
+
docsPath: `${basePath}${docsPath}`,
|
|
56
|
+
openapiOut: options.openapiOut || "./client/src/api/gen/openapi.json",
|
|
57
|
+
clientSdkOut: options.clientSdkOut || "./client/src/api/gen",
|
|
58
|
+
needGenerateClientSdk: options.needGenerateClientSdk ?? true,
|
|
59
|
+
swaggerOptions: {
|
|
60
|
+
title: options.swaggerOptions?.title ?? "NestJS Fullstack API",
|
|
61
|
+
version: options.swaggerOptions?.version ?? "1.0.0",
|
|
62
|
+
customSiteTitle: options.swaggerOptions?.customSiteTitle ?? "API Documentation",
|
|
63
|
+
customCss: options.swaggerOptions?.customCss ?? ".swagger-ui .topbar { display: none }"
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function ensureDirAndWrite(filePath, content) {
|
|
68
|
+
const dir = (0, import_node_path.dirname)(filePath);
|
|
69
|
+
(0, import_node_fs.mkdirSync)(dir, { recursive: true });
|
|
70
|
+
(0, import_node_fs.writeFileSync)(filePath, content);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// src/modules/devtool/devtool.module.ts
|
|
74
|
+
var DevToolsModule = class {
|
|
75
|
+
static async mount(app, opts = {}) {
|
|
76
|
+
const options = resolveOptsWithDefaultValue(opts);
|
|
77
|
+
const baseDirname = process.cwd();
|
|
78
|
+
const builder = new import_swagger.DocumentBuilder().setTitle(options.swaggerOptions.title).setVersion(options.swaggerOptions.version);
|
|
79
|
+
const document = import_swagger.SwaggerModule.createDocument(app, builder.build(), {
|
|
80
|
+
operationIdFactory: (_c, m) => m
|
|
81
|
+
});
|
|
82
|
+
import_swagger.SwaggerModule.setup(options.docsPath, app, document, {
|
|
83
|
+
customSiteTitle: options.swaggerOptions.customSiteTitle,
|
|
84
|
+
customCss: options.swaggerOptions.customCss,
|
|
85
|
+
swaggerOptions: { persistAuthorization: true }
|
|
86
|
+
});
|
|
87
|
+
const openapiPath = (0, import_node_path2.resolve)(baseDirname, options.openapiOut);
|
|
88
|
+
ensureDirAndWrite(openapiPath, JSON.stringify(document, null, 2));
|
|
89
|
+
if (options.needGenerateClientSdk) {
|
|
90
|
+
const clientSdkOutPath = (0, import_node_path2.resolve)(baseDirname, options.clientSdkOut);
|
|
91
|
+
(0, import_node_fs2.mkdirSync)(clientSdkOutPath, { recursive: true });
|
|
92
|
+
const { generate } = await import("openapi-typescript-codegen");
|
|
93
|
+
await generate({
|
|
94
|
+
input: openapiPath,
|
|
95
|
+
output: clientSdkOutPath,
|
|
96
|
+
httpClient: "axios",
|
|
97
|
+
useOptions: false,
|
|
98
|
+
exportServices: true
|
|
99
|
+
});
|
|
100
|
+
console.log("[OpenAPI] \u5BFC\u51FA openapi.json \u5E76\u751F\u6210 axios SDK \u2705");
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
105
|
+
0 && (module.exports = {
|
|
106
|
+
DevToolsModule
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/modules/devtool/devtool.module.ts","../src/modules/devtool/helper.ts"],"sourcesContent":["export { DevToolsModule } from './modules/devtool/devtool.module';\n","import type { INestApplication } from '@nestjs/common';\nimport type { NestExpressApplication } from '@nestjs/platform-express';\n\nimport { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';\nimport { mkdirSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { resolveOptsWithDefaultValue, ensureDirAndWrite } from './helper';\nimport { DevToolsOptions } from './type';\n\nexport class DevToolsModule {\n static async mount(\n app: INestApplication | NestExpressApplication,\n opts: DevToolsOptions = {}\n ) {\n const options = resolveOptsWithDefaultValue(opts);\n const baseDirname = process.cwd(); // 跟随命令的根目录\n\n // 1) 生成 Swagger 文档\n const builder = new DocumentBuilder()\n .setTitle(options.swaggerOptions.title)\n .setVersion(options.swaggerOptions.version);\n const document = SwaggerModule.createDocument(app, builder.build(), {\n operationIdFactory: (_c, m) => m,\n });\n\n SwaggerModule.setup(options.docsPath, app, document, {\n customSiteTitle: options.swaggerOptions.customSiteTitle,\n customCss: options.swaggerOptions.customCss,\n swaggerOptions: { persistAuthorization: true },\n });\n\n // 2) 导出 openapi.json\n const openapiPath = resolve(baseDirname, options.openapiOut);\n ensureDirAndWrite(openapiPath, JSON.stringify(document, null, 2));\n\n // 3) 生成 axios SDK(可关)\n if (options.needGenerateClientSdk) {\n const clientSdkOutPath = resolve(baseDirname, options.clientSdkOut);\n mkdirSync(clientSdkOutPath, { recursive: true });\n const { generate } = await import('openapi-typescript-codegen');\n await generate({\n input: openapiPath,\n output: clientSdkOutPath,\n httpClient: 'axios',\n useOptions: false,\n exportServices: true,\n });\n console.log('[OpenAPI] 导出 openapi.json 并生成 axios SDK ✅');\n }\n }\n}\n","import { dirname } from 'node:path';\nimport { writeFileSync, mkdirSync } from 'node:fs';\n\nimport { DevToolsOptions } from './type';\n/**\n * 标准化基础路径,确保以 '/' 开头且以 '/' 结尾\n *\n * @param rawBasePath 原始的基础路径,可能以 '/' 开头或结尾\n * @returns 标准化后的基础路径,确保以 '/' 开头且不以 '/' 结尾\n */\nexport function normalizeBasePath(rawBasePath: string): string {\n const normalizedBasePath = rawBasePath.startsWith('/')\n ? rawBasePath\n : `/${rawBasePath}`;\n return normalizedBasePath.endsWith('/')\n ? normalizedBasePath.slice(0, -1)\n : normalizedBasePath;\n}\n\ntype ResolvedDevToolsOptions = Required<\n Omit<DevToolsOptions, 'swaggerOptions'>\n> & {\n swaggerOptions: Required<NonNullable<DevToolsOptions['swaggerOptions']>>;\n};\n\nexport function resolveOptsWithDefaultValue(\n options: DevToolsOptions\n): ResolvedDevToolsOptions {\n const basePath = normalizeBasePath(options.basePath || '/');\n const docsPath = normalizeBasePath(options.docsPath || `api/docs`);\n return {\n ...options,\n basePath,\n docsPath: `${basePath}${docsPath}`,\n openapiOut: options.openapiOut || './client/src/api/gen/openapi.json',\n clientSdkOut: options.clientSdkOut || './client/src/api/gen',\n needGenerateClientSdk: options.needGenerateClientSdk ?? true,\n swaggerOptions: {\n title: options.swaggerOptions?.title ?? 'NestJS Fullstack API',\n version: options.swaggerOptions?.version ?? '1.0.0',\n customSiteTitle:\n options.swaggerOptions?.customSiteTitle ?? 'API Documentation',\n customCss:\n options.swaggerOptions?.customCss ??\n '.swagger-ui .topbar { display: none }',\n },\n };\n}\n\nexport function ensureDirAndWrite(filePath: string, content: string) {\n // 1. 拿到文件的上级目录\n const dir = dirname(filePath);\n\n // 2. 确保目录存在,不存在就递归创建\n mkdirSync(dir, { recursive: true });\n\n // 3. 写文件\n writeFileSync(filePath, content);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGA,qBAA+C;AAC/C,IAAAA,kBAA0B;AAC1B,IAAAC,oBAAwB;;;ACLxB,uBAAwB;AACxB,qBAAyC;AASlC,SAAS,kBAAkB,aAA6B;AAC7D,QAAM,qBAAqB,YAAY,WAAW,GAAG,IACjD,cACA,IAAI,WAAW;AACnB,SAAO,mBAAmB,SAAS,GAAG,IAClC,mBAAmB,MAAM,GAAG,EAAE,IAC9B;AACN;AAQO,SAAS,4BACd,SACyB;AACzB,QAAM,WAAW,kBAAkB,QAAQ,YAAY,GAAG;AAC1D,QAAM,WAAW,kBAAkB,QAAQ,YAAY,UAAU;AACjE,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA,UAAU,GAAG,QAAQ,GAAG,QAAQ;AAAA,IAChC,YAAY,QAAQ,cAAc;AAAA,IAClC,cAAc,QAAQ,gBAAgB;AAAA,IACtC,uBAAuB,QAAQ,yBAAyB;AAAA,IACxD,gBAAgB;AAAA,MACd,OAAO,QAAQ,gBAAgB,SAAS;AAAA,MACxC,SAAS,QAAQ,gBAAgB,WAAW;AAAA,MAC5C,iBACE,QAAQ,gBAAgB,mBAAmB;AAAA,MAC7C,WACE,QAAQ,gBAAgB,aACxB;AAAA,IACJ;AAAA,EACF;AACF;AAEO,SAAS,kBAAkB,UAAkB,SAAiB;AAEnE,QAAM,UAAM,0BAAQ,QAAQ;AAG5B,gCAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAGlC,oCAAc,UAAU,OAAO;AACjC;;;ADhDO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,aAAa,MACX,KACA,OAAwB,CAAC,GACzB;AACA,UAAM,UAAU,4BAA4B,IAAI;AAChD,UAAM,cAAc,QAAQ,IAAI;AAGhC,UAAM,UAAU,IAAI,+BAAgB,EACjC,SAAS,QAAQ,eAAe,KAAK,EACrC,WAAW,QAAQ,eAAe,OAAO;AAC5C,UAAM,WAAW,6BAAc,eAAe,KAAK,QAAQ,MAAM,GAAG;AAAA,MAClE,oBAAoB,CAAC,IAAI,MAAM;AAAA,IACjC,CAAC;AAED,iCAAc,MAAM,QAAQ,UAAU,KAAK,UAAU;AAAA,MACnD,iBAAiB,QAAQ,eAAe;AAAA,MACxC,WAAW,QAAQ,eAAe;AAAA,MAClC,gBAAgB,EAAE,sBAAsB,KAAK;AAAA,IAC/C,CAAC;AAGD,UAAM,kBAAc,2BAAQ,aAAa,QAAQ,UAAU;AAC3D,sBAAkB,aAAa,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAGhE,QAAI,QAAQ,uBAAuB;AACjC,YAAM,uBAAmB,2BAAQ,aAAa,QAAQ,YAAY;AAClE,qCAAU,kBAAkB,EAAE,WAAW,KAAK,CAAC;AAC/C,YAAM,EAAE,SAAS,IAAI,MAAM,OAAO,4BAA4B;AAC9D,YAAM,SAAS;AAAA,QACb,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,gBAAgB;AAAA,MAClB,CAAC;AACD,cAAQ,IAAI,yEAA2C;AAAA,IACzD;AAAA,EACF;AACF;","names":["import_node_fs","import_node_path"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { INestApplication } from '@nestjs/common';
|
|
2
|
+
import { NestExpressApplication } from '@nestjs/platform-express';
|
|
3
|
+
|
|
4
|
+
interface DevToolsOptions {
|
|
5
|
+
basePath?: string;
|
|
6
|
+
docsPath?: string;
|
|
7
|
+
openapiOut?: string;
|
|
8
|
+
needGenerateClientSdk?: boolean;
|
|
9
|
+
clientSdkOut?: string;
|
|
10
|
+
swaggerOptions?: {
|
|
11
|
+
title?: string;
|
|
12
|
+
version?: string;
|
|
13
|
+
customSiteTitle?: string;
|
|
14
|
+
customCss?: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare class DevToolsModule {
|
|
19
|
+
static mount(app: INestApplication | NestExpressApplication, opts?: DevToolsOptions): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { DevToolsModule };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
import { INestApplication } from '@nestjs/common';
|
|
2
|
+
import { NestExpressApplication } from '@nestjs/platform-express';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
interface DevToolsOptions {
|
|
5
|
+
basePath?: string;
|
|
6
|
+
docsPath?: string;
|
|
7
|
+
openapiOut?: string;
|
|
8
|
+
needGenerateClientSdk?: boolean;
|
|
9
|
+
clientSdkOut?: string;
|
|
10
|
+
swaggerOptions?: {
|
|
11
|
+
title?: string;
|
|
12
|
+
version?: string;
|
|
13
|
+
customSiteTitle?: string;
|
|
14
|
+
customCss?: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare class DevToolsModule {
|
|
19
|
+
static mount(app: INestApplication | NestExpressApplication, opts?: DevToolsOptions): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { DevToolsModule };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,71 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// src/modules/devtool/devtool.module.ts
|
|
2
|
+
import { SwaggerModule, DocumentBuilder } from "@nestjs/swagger";
|
|
3
|
+
import { mkdirSync as mkdirSync2 } from "fs";
|
|
4
|
+
import { resolve } from "path";
|
|
5
|
+
|
|
6
|
+
// src/modules/devtool/helper.ts
|
|
7
|
+
import { dirname } from "path";
|
|
8
|
+
import { writeFileSync, mkdirSync } from "fs";
|
|
9
|
+
function normalizeBasePath(rawBasePath) {
|
|
10
|
+
const normalizedBasePath = rawBasePath.startsWith("/") ? rawBasePath : `/${rawBasePath}`;
|
|
11
|
+
return normalizedBasePath.endsWith("/") ? normalizedBasePath.slice(0, -1) : normalizedBasePath;
|
|
4
12
|
}
|
|
5
|
-
|
|
13
|
+
function resolveOptsWithDefaultValue(options) {
|
|
14
|
+
const basePath = normalizeBasePath(options.basePath || "/");
|
|
15
|
+
const docsPath = normalizeBasePath(options.docsPath || `api/docs`);
|
|
16
|
+
return {
|
|
17
|
+
...options,
|
|
18
|
+
basePath,
|
|
19
|
+
docsPath: `${basePath}${docsPath}`,
|
|
20
|
+
openapiOut: options.openapiOut || "./client/src/api/gen/openapi.json",
|
|
21
|
+
clientSdkOut: options.clientSdkOut || "./client/src/api/gen",
|
|
22
|
+
needGenerateClientSdk: options.needGenerateClientSdk ?? true,
|
|
23
|
+
swaggerOptions: {
|
|
24
|
+
title: options.swaggerOptions?.title ?? "NestJS Fullstack API",
|
|
25
|
+
version: options.swaggerOptions?.version ?? "1.0.0",
|
|
26
|
+
customSiteTitle: options.swaggerOptions?.customSiteTitle ?? "API Documentation",
|
|
27
|
+
customCss: options.swaggerOptions?.customCss ?? ".swagger-ui .topbar { display: none }"
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function ensureDirAndWrite(filePath, content) {
|
|
32
|
+
const dir = dirname(filePath);
|
|
33
|
+
mkdirSync(dir, { recursive: true });
|
|
34
|
+
writeFileSync(filePath, content);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/modules/devtool/devtool.module.ts
|
|
38
|
+
var DevToolsModule = class {
|
|
39
|
+
static async mount(app, opts = {}) {
|
|
40
|
+
const options = resolveOptsWithDefaultValue(opts);
|
|
41
|
+
const baseDirname = process.cwd();
|
|
42
|
+
const builder = new DocumentBuilder().setTitle(options.swaggerOptions.title).setVersion(options.swaggerOptions.version);
|
|
43
|
+
const document = SwaggerModule.createDocument(app, builder.build(), {
|
|
44
|
+
operationIdFactory: (_c, m) => m
|
|
45
|
+
});
|
|
46
|
+
SwaggerModule.setup(options.docsPath, app, document, {
|
|
47
|
+
customSiteTitle: options.swaggerOptions.customSiteTitle,
|
|
48
|
+
customCss: options.swaggerOptions.customCss,
|
|
49
|
+
swaggerOptions: { persistAuthorization: true }
|
|
50
|
+
});
|
|
51
|
+
const openapiPath = resolve(baseDirname, options.openapiOut);
|
|
52
|
+
ensureDirAndWrite(openapiPath, JSON.stringify(document, null, 2));
|
|
53
|
+
if (options.needGenerateClientSdk) {
|
|
54
|
+
const clientSdkOutPath = resolve(baseDirname, options.clientSdkOut);
|
|
55
|
+
mkdirSync2(clientSdkOutPath, { recursive: true });
|
|
56
|
+
const { generate } = await import("openapi-typescript-codegen");
|
|
57
|
+
await generate({
|
|
58
|
+
input: openapiPath,
|
|
59
|
+
output: clientSdkOutPath,
|
|
60
|
+
httpClient: "axios",
|
|
61
|
+
useOptions: false,
|
|
62
|
+
exportServices: true
|
|
63
|
+
});
|
|
64
|
+
console.log("[OpenAPI] \u5BFC\u51FA openapi.json \u5E76\u751F\u6210 axios SDK \u2705");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
6
68
|
export {
|
|
7
|
-
|
|
8
|
-
index_default as default
|
|
69
|
+
DevToolsModule
|
|
9
70
|
};
|
|
10
71
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/
|
|
1
|
+
{"version":3,"sources":["../src/modules/devtool/devtool.module.ts","../src/modules/devtool/helper.ts"],"sourcesContent":["import type { INestApplication } from '@nestjs/common';\nimport type { NestExpressApplication } from '@nestjs/platform-express';\n\nimport { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';\nimport { mkdirSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { resolveOptsWithDefaultValue, ensureDirAndWrite } from './helper';\nimport { DevToolsOptions } from './type';\n\nexport class DevToolsModule {\n static async mount(\n app: INestApplication | NestExpressApplication,\n opts: DevToolsOptions = {}\n ) {\n const options = resolveOptsWithDefaultValue(opts);\n const baseDirname = process.cwd(); // 跟随命令的根目录\n\n // 1) 生成 Swagger 文档\n const builder = new DocumentBuilder()\n .setTitle(options.swaggerOptions.title)\n .setVersion(options.swaggerOptions.version);\n const document = SwaggerModule.createDocument(app, builder.build(), {\n operationIdFactory: (_c, m) => m,\n });\n\n SwaggerModule.setup(options.docsPath, app, document, {\n customSiteTitle: options.swaggerOptions.customSiteTitle,\n customCss: options.swaggerOptions.customCss,\n swaggerOptions: { persistAuthorization: true },\n });\n\n // 2) 导出 openapi.json\n const openapiPath = resolve(baseDirname, options.openapiOut);\n ensureDirAndWrite(openapiPath, JSON.stringify(document, null, 2));\n\n // 3) 生成 axios SDK(可关)\n if (options.needGenerateClientSdk) {\n const clientSdkOutPath = resolve(baseDirname, options.clientSdkOut);\n mkdirSync(clientSdkOutPath, { recursive: true });\n const { generate } = await import('openapi-typescript-codegen');\n await generate({\n input: openapiPath,\n output: clientSdkOutPath,\n httpClient: 'axios',\n useOptions: false,\n exportServices: true,\n });\n console.log('[OpenAPI] 导出 openapi.json 并生成 axios SDK ✅');\n }\n }\n}\n","import { dirname } from 'node:path';\nimport { writeFileSync, mkdirSync } from 'node:fs';\n\nimport { DevToolsOptions } from './type';\n/**\n * 标准化基础路径,确保以 '/' 开头且以 '/' 结尾\n *\n * @param rawBasePath 原始的基础路径,可能以 '/' 开头或结尾\n * @returns 标准化后的基础路径,确保以 '/' 开头且不以 '/' 结尾\n */\nexport function normalizeBasePath(rawBasePath: string): string {\n const normalizedBasePath = rawBasePath.startsWith('/')\n ? rawBasePath\n : `/${rawBasePath}`;\n return normalizedBasePath.endsWith('/')\n ? normalizedBasePath.slice(0, -1)\n : normalizedBasePath;\n}\n\ntype ResolvedDevToolsOptions = Required<\n Omit<DevToolsOptions, 'swaggerOptions'>\n> & {\n swaggerOptions: Required<NonNullable<DevToolsOptions['swaggerOptions']>>;\n};\n\nexport function resolveOptsWithDefaultValue(\n options: DevToolsOptions\n): ResolvedDevToolsOptions {\n const basePath = normalizeBasePath(options.basePath || '/');\n const docsPath = normalizeBasePath(options.docsPath || `api/docs`);\n return {\n ...options,\n basePath,\n docsPath: `${basePath}${docsPath}`,\n openapiOut: options.openapiOut || './client/src/api/gen/openapi.json',\n clientSdkOut: options.clientSdkOut || './client/src/api/gen',\n needGenerateClientSdk: options.needGenerateClientSdk ?? true,\n swaggerOptions: {\n title: options.swaggerOptions?.title ?? 'NestJS Fullstack API',\n version: options.swaggerOptions?.version ?? '1.0.0',\n customSiteTitle:\n options.swaggerOptions?.customSiteTitle ?? 'API Documentation',\n customCss:\n options.swaggerOptions?.customCss ??\n '.swagger-ui .topbar { display: none }',\n },\n };\n}\n\nexport function ensureDirAndWrite(filePath: string, content: string) {\n // 1. 拿到文件的上级目录\n const dir = dirname(filePath);\n\n // 2. 确保目录存在,不存在就递归创建\n mkdirSync(dir, { recursive: true });\n\n // 3. 写文件\n writeFileSync(filePath, content);\n}\n"],"mappings":";AAGA,SAAS,eAAe,uBAAuB;AAC/C,SAAS,aAAAA,kBAAiB;AAC1B,SAAS,eAAe;;;ACLxB,SAAS,eAAe;AACxB,SAAS,eAAe,iBAAiB;AASlC,SAAS,kBAAkB,aAA6B;AAC7D,QAAM,qBAAqB,YAAY,WAAW,GAAG,IACjD,cACA,IAAI,WAAW;AACnB,SAAO,mBAAmB,SAAS,GAAG,IAClC,mBAAmB,MAAM,GAAG,EAAE,IAC9B;AACN;AAQO,SAAS,4BACd,SACyB;AACzB,QAAM,WAAW,kBAAkB,QAAQ,YAAY,GAAG;AAC1D,QAAM,WAAW,kBAAkB,QAAQ,YAAY,UAAU;AACjE,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA,UAAU,GAAG,QAAQ,GAAG,QAAQ;AAAA,IAChC,YAAY,QAAQ,cAAc;AAAA,IAClC,cAAc,QAAQ,gBAAgB;AAAA,IACtC,uBAAuB,QAAQ,yBAAyB;AAAA,IACxD,gBAAgB;AAAA,MACd,OAAO,QAAQ,gBAAgB,SAAS;AAAA,MACxC,SAAS,QAAQ,gBAAgB,WAAW;AAAA,MAC5C,iBACE,QAAQ,gBAAgB,mBAAmB;AAAA,MAC7C,WACE,QAAQ,gBAAgB,aACxB;AAAA,IACJ;AAAA,EACF;AACF;AAEO,SAAS,kBAAkB,UAAkB,SAAiB;AAEnE,QAAM,MAAM,QAAQ,QAAQ;AAG5B,YAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAGlC,gBAAc,UAAU,OAAO;AACjC;;;ADhDO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,aAAa,MACX,KACA,OAAwB,CAAC,GACzB;AACA,UAAM,UAAU,4BAA4B,IAAI;AAChD,UAAM,cAAc,QAAQ,IAAI;AAGhC,UAAM,UAAU,IAAI,gBAAgB,EACjC,SAAS,QAAQ,eAAe,KAAK,EACrC,WAAW,QAAQ,eAAe,OAAO;AAC5C,UAAM,WAAW,cAAc,eAAe,KAAK,QAAQ,MAAM,GAAG;AAAA,MAClE,oBAAoB,CAAC,IAAI,MAAM;AAAA,IACjC,CAAC;AAED,kBAAc,MAAM,QAAQ,UAAU,KAAK,UAAU;AAAA,MACnD,iBAAiB,QAAQ,eAAe;AAAA,MACxC,WAAW,QAAQ,eAAe;AAAA,MAClC,gBAAgB,EAAE,sBAAsB,KAAK;AAAA,IAC/C,CAAC;AAGD,UAAM,cAAc,QAAQ,aAAa,QAAQ,UAAU;AAC3D,sBAAkB,aAAa,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAGhE,QAAI,QAAQ,uBAAuB;AACjC,YAAM,mBAAmB,QAAQ,aAAa,QAAQ,YAAY;AAClE,MAAAC,WAAU,kBAAkB,EAAE,WAAW,KAAK,CAAC;AAC/C,YAAM,EAAE,SAAS,IAAI,MAAM,OAAO,4BAA4B;AAC9D,YAAM,SAAS;AAAA,QACb,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,gBAAgB;AAAA,MAClB,CAAC;AACD,cAAQ,IAAI,yEAA2C;AAAA,IACzD;AAAA,EACF;AACF;","names":["mkdirSync","mkdirSync"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lark-apaas/fullstack-nestjs-core",
|
|
3
|
-
"version": "0.0.0-alpha.
|
|
3
|
+
"version": "0.0.0-alpha.2",
|
|
4
4
|
"description": "FullStack Nestjs Core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"exports": {
|
|
25
25
|
".": {
|
|
26
26
|
"import": "./dist/index.js",
|
|
27
|
-
"types": "./dist/index.d.ts"
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"require": "./dist/index.cjs"
|
|
28
29
|
}
|
|
29
30
|
},
|
|
30
31
|
"scripts": {
|
|
@@ -36,9 +37,19 @@
|
|
|
36
37
|
"lint": "echo 'ESLint skipped for TypeScript files'",
|
|
37
38
|
"lint:fix": "eslint src --ext .ts --fix"
|
|
38
39
|
},
|
|
39
|
-
"dependencies": {
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"openapi-typescript-codegen": "^0.29.0"
|
|
42
|
+
},
|
|
40
43
|
"devDependencies": {
|
|
41
44
|
"typescript": "^5.2.0",
|
|
42
|
-
"tsup": "^8.0.0"
|
|
45
|
+
"tsup": "^8.0.0",
|
|
46
|
+
"@nestjs/common": "^10.4.20",
|
|
47
|
+
"@nestjs/platform-express": "^10.4.20",
|
|
48
|
+
"@nestjs/swagger": "^7.4.2"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"@nestjs/common": "^10.4.20",
|
|
52
|
+
"@nestjs/platform-express": "^10.4.20",
|
|
53
|
+
"@nestjs/swagger": "^7.4.2"
|
|
43
54
|
}
|
|
44
|
-
}
|
|
55
|
+
}
|