@lark-apaas/fullstack-nestjs-core 1.1.34-alpha.62 → 1.1.34-alpha.63
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 +133 -21
- package/dist/index.d.cts +11 -3
- package/dist/index.d.ts +11 -3
- package/dist/index.js +132 -21
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -34423,7 +34423,8 @@ __export(index_exports, {
|
|
|
34423
34423
|
UserContextMiddleware: () => UserContextMiddleware,
|
|
34424
34424
|
ViewContextMiddleware: () => ViewContextMiddleware,
|
|
34425
34425
|
configureApp: () => configureApp,
|
|
34426
|
-
createLegacyPathRedirectMiddleware: () => createLegacyPathRedirectMiddleware
|
|
34426
|
+
createLegacyPathRedirectMiddleware: () => createLegacyPathRedirectMiddleware,
|
|
34427
|
+
registerOpenApiSpecEndpoint: () => registerOpenApiSpecEndpoint
|
|
34427
34428
|
});
|
|
34428
34429
|
module.exports = __toCommonJS(index_exports);
|
|
34429
34430
|
|
|
@@ -34627,32 +34628,31 @@ var ViewContextMiddleware = class _ViewContextMiddleware {
|
|
|
34627
34628
|
constructor(client) {
|
|
34628
34629
|
this.client = client;
|
|
34629
34630
|
}
|
|
34630
|
-
async
|
|
34631
|
+
async getAppInfo(appId) {
|
|
34631
34632
|
if (!appId) {
|
|
34632
|
-
this.logger.warn(`appId is empty, skip get app
|
|
34633
|
+
this.logger.warn(`appId is empty, skip get app info`);
|
|
34633
34634
|
return null;
|
|
34634
34635
|
}
|
|
34635
34636
|
try {
|
|
34636
34637
|
const resp = await this.client.get(`/b/${appId}/get_published_v2`);
|
|
34637
34638
|
if (resp.status !== 200) {
|
|
34638
|
-
throw new Error(`Failed to get app
|
|
34639
|
+
throw new Error(`Failed to get app info, status: ${resp.status}`);
|
|
34639
34640
|
}
|
|
34640
34641
|
const data = await resp.json();
|
|
34641
34642
|
if (data.status_code !== "0") {
|
|
34642
|
-
throw new Error(`Failed to get app
|
|
34643
|
+
throw new Error(`Failed to get app info, status_code: ${data.status_code}`);
|
|
34643
34644
|
}
|
|
34644
|
-
return data.data ??
|
|
34645
|
+
return data.data.app_info ?? {};
|
|
34645
34646
|
} catch (err) {
|
|
34646
|
-
this.logger.error(err, "Failed to get app
|
|
34647
|
+
this.logger.error(err, "Failed to get app info");
|
|
34647
34648
|
return null;
|
|
34648
34649
|
}
|
|
34649
34650
|
}
|
|
34650
34651
|
async use(req, res, next) {
|
|
34651
34652
|
const { userId, tenantId, appId, loginUrl, userType } = req.userContext;
|
|
34652
34653
|
const csrfToken = req.csrfToken;
|
|
34654
|
+
const appInfo = await this.getAppInfo(appId);
|
|
34653
34655
|
const environment = mapToWindowEnvironment(process.env.FORCE_FRAMEWORK_ENVIRONMENT);
|
|
34654
|
-
const appPublishedData = await this.getAppPublished(appId);
|
|
34655
|
-
const appInfo = appPublishedData?.app_info ?? null;
|
|
34656
34656
|
req.__platform_data__ = {
|
|
34657
34657
|
csrfToken: csrfToken ?? "",
|
|
34658
34658
|
userId: userId ?? "",
|
|
@@ -34663,9 +34663,7 @@ var ViewContextMiddleware = class _ViewContextMiddleware {
|
|
|
34663
34663
|
loginUrl: loginUrl ?? "",
|
|
34664
34664
|
userType: userType ?? "",
|
|
34665
34665
|
tenantId,
|
|
34666
|
-
environment
|
|
34667
|
-
showBadge: appInfo?.show_badge !== false,
|
|
34668
|
-
appPublished: appPublishedData ?? null
|
|
34666
|
+
environment
|
|
34669
34667
|
};
|
|
34670
34668
|
res.locals = {
|
|
34671
34669
|
...res.locals ?? {},
|
|
@@ -34776,18 +34774,24 @@ function createApiNotFoundResponse(req) {
|
|
|
34776
34774
|
};
|
|
34777
34775
|
}
|
|
34778
34776
|
__name(createApiNotFoundResponse, "createApiNotFoundResponse");
|
|
34779
|
-
function
|
|
34777
|
+
function getApiPathPrefixes() {
|
|
34780
34778
|
const globalPrefix = process.env.CLIENT_BASE_PATH ?? "";
|
|
34781
34779
|
if (!globalPrefix) {
|
|
34782
|
-
return
|
|
34780
|
+
return [
|
|
34781
|
+
"/api/",
|
|
34782
|
+
"/openapi/"
|
|
34783
|
+
];
|
|
34783
34784
|
}
|
|
34784
34785
|
const normalizedPrefix = globalPrefix.replace(/\/+$/, "");
|
|
34785
|
-
return
|
|
34786
|
+
return [
|
|
34787
|
+
`${normalizedPrefix}/api/`,
|
|
34788
|
+
`${normalizedPrefix}/openapi/`
|
|
34789
|
+
];
|
|
34786
34790
|
}
|
|
34787
|
-
__name(
|
|
34791
|
+
__name(getApiPathPrefixes, "getApiPathPrefixes");
|
|
34788
34792
|
function apiResponseInterceptor(req, res, next) {
|
|
34789
|
-
const
|
|
34790
|
-
if (!req.baseUrl.startsWith(
|
|
34793
|
+
const apiPrefixes = getApiPathPrefixes();
|
|
34794
|
+
if (!apiPrefixes.some((prefix) => req.baseUrl.startsWith(prefix))) {
|
|
34791
34795
|
return next();
|
|
34792
34796
|
}
|
|
34793
34797
|
res.render = function() {
|
|
@@ -36440,16 +36444,18 @@ var PlatformModule = class _PlatformModule {
|
|
|
36440
36444
|
*/
|
|
36441
36445
|
configure(consumer) {
|
|
36442
36446
|
const options = _PlatformModule.moduleOptions;
|
|
36443
|
-
consumer.apply(apiResponseInterceptor).forRoutes("/api/*");
|
|
36447
|
+
consumer.apply(apiResponseInterceptor).forRoutes("/api/*", "/openapi/*");
|
|
36444
36448
|
if (process.env.NODE_ENV === "development") {
|
|
36445
36449
|
consumer.apply(FrameworkDebugMiddleware).forRoutes("/api/__framework__/debug");
|
|
36446
36450
|
}
|
|
36447
36451
|
consumer.apply(UserContextMiddleware, RequestContextMiddleware, import_nestjs_logger2.LoggerContextMiddleware, import_nestjs_observable.ObservableTraceMiddleware, ...DISABLE_DATAPASS ? [] : [
|
|
36448
36452
|
import_nestjs_datapaas.SqlExecutionContextMiddleware
|
|
36449
36453
|
]).forRoutes("/*");
|
|
36450
|
-
consumer.apply(CsrfTokenMiddleware, ViewContextMiddleware, HtmlHotUpdateViewMiddleware).exclude("/api/(.*)", "/static/(.*)").forRoutes("*");
|
|
36454
|
+
consumer.apply(CsrfTokenMiddleware, ViewContextMiddleware, HtmlHotUpdateViewMiddleware).exclude("/api/(.*)", "/openapi/(.*)", "/static/(.*)").forRoutes("*");
|
|
36451
36455
|
if (options.enableCsrf !== false) {
|
|
36452
|
-
const csrfRoutes = options.csrfRoutes ||
|
|
36456
|
+
const csrfRoutes = options.csrfRoutes || [
|
|
36457
|
+
"/api/*"
|
|
36458
|
+
];
|
|
36453
36459
|
if (Array.isArray(csrfRoutes)) {
|
|
36454
36460
|
csrfRoutes.forEach((route) => {
|
|
36455
36461
|
consumer.apply(CsrfMiddleware).forRoutes(route);
|
|
@@ -36506,6 +36512,108 @@ function createLegacyPathRedirectMiddleware() {
|
|
|
36506
36512
|
}
|
|
36507
36513
|
__name(createLegacyPathRedirectMiddleware, "createLegacyPathRedirectMiddleware");
|
|
36508
36514
|
|
|
36515
|
+
// src/middlewares/openapi-spec/index.ts
|
|
36516
|
+
var import_swagger3 = require("@nestjs/swagger");
|
|
36517
|
+
function registerOpenApiSpecEndpoint(app) {
|
|
36518
|
+
const globalPrefix = process.env.CLIENT_BASE_PATH ?? "";
|
|
36519
|
+
let cachedResult = null;
|
|
36520
|
+
const httpAdapter = app.getHttpAdapter();
|
|
36521
|
+
httpAdapter.get(`${globalPrefix}/api/__framework__/openapi-spec`, (_req, res) => {
|
|
36522
|
+
try {
|
|
36523
|
+
if (!cachedResult) {
|
|
36524
|
+
const config = new import_swagger3.DocumentBuilder().setTitle("OpenAPI Spec").setVersion("1.0").build();
|
|
36525
|
+
const spec = import_swagger3.SwaggerModule.createDocument(app, config);
|
|
36526
|
+
cachedResult = buildFilteredSpec(spec, globalPrefix);
|
|
36527
|
+
}
|
|
36528
|
+
res.json(cachedResult);
|
|
36529
|
+
} catch (err) {
|
|
36530
|
+
console.error("[openapi-spec] Failed to generate spec:", err);
|
|
36531
|
+
res.json({
|
|
36532
|
+
openapi: "3.0.0",
|
|
36533
|
+
paths: {},
|
|
36534
|
+
components: {
|
|
36535
|
+
schemas: {}
|
|
36536
|
+
}
|
|
36537
|
+
});
|
|
36538
|
+
}
|
|
36539
|
+
});
|
|
36540
|
+
console.log(`[OpenAPI] Registered GET ${globalPrefix}/api/__framework__/openapi-spec`);
|
|
36541
|
+
}
|
|
36542
|
+
__name(registerOpenApiSpecEndpoint, "registerOpenApiSpecEndpoint");
|
|
36543
|
+
function buildFilteredSpec(spec, globalPrefix) {
|
|
36544
|
+
const schemas = spec.components?.schemas ?? {};
|
|
36545
|
+
const paths = spec.paths ?? {};
|
|
36546
|
+
const filteredPaths = {};
|
|
36547
|
+
for (const [pathKey, methods] of Object.entries(paths)) {
|
|
36548
|
+
const cleanPath = stripPrefix(pathKey, globalPrefix);
|
|
36549
|
+
if (!cleanPath.startsWith("/openapi")) continue;
|
|
36550
|
+
filteredPaths[cleanPath] = {};
|
|
36551
|
+
for (const [method, operation] of Object.entries(methods)) {
|
|
36552
|
+
if ([
|
|
36553
|
+
"parameters",
|
|
36554
|
+
"summary",
|
|
36555
|
+
"description",
|
|
36556
|
+
"servers"
|
|
36557
|
+
].includes(method)) continue;
|
|
36558
|
+
filteredPaths[cleanPath][method] = resolveRefsDeep(structuredClone(operation), schemas);
|
|
36559
|
+
}
|
|
36560
|
+
}
|
|
36561
|
+
return {
|
|
36562
|
+
openapi: spec.openapi,
|
|
36563
|
+
paths: filteredPaths,
|
|
36564
|
+
components: {
|
|
36565
|
+
schemas: resolveAllSchemaRefs(structuredClone(schemas))
|
|
36566
|
+
}
|
|
36567
|
+
};
|
|
36568
|
+
}
|
|
36569
|
+
__name(buildFilteredSpec, "buildFilteredSpec");
|
|
36570
|
+
function stripPrefix(path2, prefix) {
|
|
36571
|
+
if (prefix && path2.startsWith(prefix)) {
|
|
36572
|
+
return path2.slice(prefix.length);
|
|
36573
|
+
}
|
|
36574
|
+
return path2;
|
|
36575
|
+
}
|
|
36576
|
+
__name(stripPrefix, "stripPrefix");
|
|
36577
|
+
var MAX_REF_DEPTH = 5;
|
|
36578
|
+
function resolveRefsDeep(obj, schemas, depth = 0) {
|
|
36579
|
+
if (depth > MAX_REF_DEPTH || obj === null || obj === void 0) return obj;
|
|
36580
|
+
if (typeof obj !== "object") return obj;
|
|
36581
|
+
if (Array.isArray(obj)) {
|
|
36582
|
+
return obj.map((item) => resolveRefsDeep(item, schemas, depth));
|
|
36583
|
+
}
|
|
36584
|
+
const record = obj;
|
|
36585
|
+
if (typeof record["$ref"] === "string") {
|
|
36586
|
+
const resolved = resolveRef(record["$ref"], schemas);
|
|
36587
|
+
if (resolved !== void 0) {
|
|
36588
|
+
return resolveRefsDeep(structuredClone(resolved), schemas, depth + 1);
|
|
36589
|
+
}
|
|
36590
|
+
return record;
|
|
36591
|
+
}
|
|
36592
|
+
const result = {};
|
|
36593
|
+
for (const [key, value] of Object.entries(record)) {
|
|
36594
|
+
result[key] = resolveRefsDeep(value, schemas, depth);
|
|
36595
|
+
}
|
|
36596
|
+
return result;
|
|
36597
|
+
}
|
|
36598
|
+
__name(resolveRefsDeep, "resolveRefsDeep");
|
|
36599
|
+
function resolveRef(ref, schemas) {
|
|
36600
|
+
const prefix = "#/components/schemas/";
|
|
36601
|
+
if (ref.startsWith(prefix)) {
|
|
36602
|
+
const name = ref.slice(prefix.length);
|
|
36603
|
+
return schemas[name];
|
|
36604
|
+
}
|
|
36605
|
+
return void 0;
|
|
36606
|
+
}
|
|
36607
|
+
__name(resolveRef, "resolveRef");
|
|
36608
|
+
function resolveAllSchemaRefs(schemas) {
|
|
36609
|
+
const result = {};
|
|
36610
|
+
for (const [name, schema] of Object.entries(schemas)) {
|
|
36611
|
+
result[name] = resolveRefsDeep(schema, schemas);
|
|
36612
|
+
}
|
|
36613
|
+
return result;
|
|
36614
|
+
}
|
|
36615
|
+
__name(resolveAllSchemaRefs, "resolveAllSchemaRefs");
|
|
36616
|
+
|
|
36509
36617
|
// src/setup.ts
|
|
36510
36618
|
var DEFAULT_BODY_LIMIT = "1mb";
|
|
36511
36619
|
var defaultPerms = {
|
|
@@ -36538,6 +36646,9 @@ async function configureApp(app, perms = defaultPerms) {
|
|
|
36538
36646
|
console.error("[OpenAPI] OpenAPI \u751F\u6210\u5931\u8D25:", err);
|
|
36539
36647
|
}
|
|
36540
36648
|
}
|
|
36649
|
+
if (process.env.NODE_ENV !== "production") {
|
|
36650
|
+
registerOpenApiSpecEndpoint(app);
|
|
36651
|
+
}
|
|
36541
36652
|
console.log("App Started Successfully.");
|
|
36542
36653
|
}
|
|
36543
36654
|
__name(configureApp, "configureApp");
|
|
@@ -36574,6 +36685,7 @@ var import_nestjs_authzpaas2 = require("@lark-apaas/nestjs-authzpaas");
|
|
|
36574
36685
|
ViewContextMiddleware,
|
|
36575
36686
|
configureApp,
|
|
36576
36687
|
createLegacyPathRedirectMiddleware,
|
|
36688
|
+
registerOpenApiSpecEndpoint,
|
|
36577
36689
|
...require("@lark-apaas/nestjs-authnpaas"),
|
|
36578
36690
|
...require("@lark-apaas/nestjs-capability"),
|
|
36579
36691
|
...require("@lark-apaas/nestjs-datapaas"),
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NestModule, DynamicModule, MiddlewareConsumer, OnModuleInit, NestMiddleware } from '@nestjs/common';
|
|
1
|
+
import { NestModule, DynamicModule, MiddlewareConsumer, OnModuleInit, NestMiddleware, INestApplication } from '@nestjs/common';
|
|
2
2
|
import { HttpClientConfig, PlatformPluginOptions, HttpClient } from '@lark-apaas/http-client';
|
|
3
3
|
import { AuthZPaasModuleOptions } from '@lark-apaas/nestjs-authzpaas';
|
|
4
4
|
export { AddMembersParams, AuthZPaasModule, AuthorizationSDK, Can, CanRole, ChatSimpleDTO, CommonParam, CreateRoleParams, CreateRoleResponse, DepartmentDTO, DepartmentEntity, DepartmentSimpleDTO, FilterParams, ForceRoleDTO, I18nText, IPermissionResolver, ListMembersParams, ListMembersResponse, ListRolesParams, MemberMutationData, MemberType, PERMISSION_RESOLVER_TOKEN, PermissionPoint, PermissionRequirement, PresetGroupDTO, RemoveMembersParams, RoleMemberDTO, SearchChatEntity, SearchParams, SearchResponse, SearchResult, SearchUserEntity, UpdateRoleParams, UserSimpleDTO } from '@lark-apaas/nestjs-authzpaas';
|
|
@@ -201,7 +201,7 @@ declare class ViewContextMiddleware implements NestMiddleware {
|
|
|
201
201
|
private readonly client;
|
|
202
202
|
private readonly logger;
|
|
203
203
|
constructor(client: PlatformHttpClient);
|
|
204
|
-
private
|
|
204
|
+
private getAppInfo;
|
|
205
205
|
use(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
206
206
|
}
|
|
207
207
|
|
|
@@ -221,6 +221,14 @@ declare class ViewContextMiddleware implements NestMiddleware {
|
|
|
221
221
|
*/
|
|
222
222
|
declare function createLegacyPathRedirectMiddleware(): (req: Request, res: Response, next: NextFunction) => void;
|
|
223
223
|
|
|
224
|
+
/**
|
|
225
|
+
* 注册 OpenAPI spec 端点(仅开发环境)
|
|
226
|
+
*
|
|
227
|
+
* 在 NestJS 进程中注册 GET /api/__framework__/openapi-spec,
|
|
228
|
+
* 返回过滤后的 OpenAPI 3.0 子集(仅 /openapi/** 路由,$ref 已解引用)。
|
|
229
|
+
*/
|
|
230
|
+
declare function registerOpenApiSpecEndpoint(app: INestApplication): void;
|
|
231
|
+
|
|
224
232
|
/**
|
|
225
233
|
* API 404 响应格式
|
|
226
234
|
*/
|
|
@@ -401,4 +409,4 @@ declare class PlatformHttpClientService {
|
|
|
401
409
|
private registerInterceptorsForClient;
|
|
402
410
|
}
|
|
403
411
|
|
|
404
|
-
export { type ApiNotFoundResponse, CsrfMiddleware, CsrfTokenMiddleware, FileService, HtmlHotUpdateModule, HtmlHotUpdateService, type PlatformHttpClientOptions, PlatformHttpClientService, PlatformModule, type PlatformModuleOptions, StaticModule, UserContextMiddleware, ViewContextMiddleware, configureApp, createLegacyPathRedirectMiddleware };
|
|
412
|
+
export { type ApiNotFoundResponse, CsrfMiddleware, CsrfTokenMiddleware, FileService, HtmlHotUpdateModule, HtmlHotUpdateService, type PlatformHttpClientOptions, PlatformHttpClientService, PlatformModule, type PlatformModuleOptions, StaticModule, UserContextMiddleware, ViewContextMiddleware, configureApp, createLegacyPathRedirectMiddleware, registerOpenApiSpecEndpoint };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NestModule, DynamicModule, MiddlewareConsumer, OnModuleInit, NestMiddleware } from '@nestjs/common';
|
|
1
|
+
import { NestModule, DynamicModule, MiddlewareConsumer, OnModuleInit, NestMiddleware, INestApplication } from '@nestjs/common';
|
|
2
2
|
import { HttpClientConfig, PlatformPluginOptions, HttpClient } from '@lark-apaas/http-client';
|
|
3
3
|
import { AuthZPaasModuleOptions } from '@lark-apaas/nestjs-authzpaas';
|
|
4
4
|
export { AddMembersParams, AuthZPaasModule, AuthorizationSDK, Can, CanRole, ChatSimpleDTO, CommonParam, CreateRoleParams, CreateRoleResponse, DepartmentDTO, DepartmentEntity, DepartmentSimpleDTO, FilterParams, ForceRoleDTO, I18nText, IPermissionResolver, ListMembersParams, ListMembersResponse, ListRolesParams, MemberMutationData, MemberType, PERMISSION_RESOLVER_TOKEN, PermissionPoint, PermissionRequirement, PresetGroupDTO, RemoveMembersParams, RoleMemberDTO, SearchChatEntity, SearchParams, SearchResponse, SearchResult, SearchUserEntity, UpdateRoleParams, UserSimpleDTO } from '@lark-apaas/nestjs-authzpaas';
|
|
@@ -201,7 +201,7 @@ declare class ViewContextMiddleware implements NestMiddleware {
|
|
|
201
201
|
private readonly client;
|
|
202
202
|
private readonly logger;
|
|
203
203
|
constructor(client: PlatformHttpClient);
|
|
204
|
-
private
|
|
204
|
+
private getAppInfo;
|
|
205
205
|
use(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
206
206
|
}
|
|
207
207
|
|
|
@@ -221,6 +221,14 @@ declare class ViewContextMiddleware implements NestMiddleware {
|
|
|
221
221
|
*/
|
|
222
222
|
declare function createLegacyPathRedirectMiddleware(): (req: Request, res: Response, next: NextFunction) => void;
|
|
223
223
|
|
|
224
|
+
/**
|
|
225
|
+
* 注册 OpenAPI spec 端点(仅开发环境)
|
|
226
|
+
*
|
|
227
|
+
* 在 NestJS 进程中注册 GET /api/__framework__/openapi-spec,
|
|
228
|
+
* 返回过滤后的 OpenAPI 3.0 子集(仅 /openapi/** 路由,$ref 已解引用)。
|
|
229
|
+
*/
|
|
230
|
+
declare function registerOpenApiSpecEndpoint(app: INestApplication): void;
|
|
231
|
+
|
|
224
232
|
/**
|
|
225
233
|
* API 404 响应格式
|
|
226
234
|
*/
|
|
@@ -401,4 +409,4 @@ declare class PlatformHttpClientService {
|
|
|
401
409
|
private registerInterceptorsForClient;
|
|
402
410
|
}
|
|
403
411
|
|
|
404
|
-
export { type ApiNotFoundResponse, CsrfMiddleware, CsrfTokenMiddleware, FileService, HtmlHotUpdateModule, HtmlHotUpdateService, type PlatformHttpClientOptions, PlatformHttpClientService, PlatformModule, type PlatformModuleOptions, StaticModule, UserContextMiddleware, ViewContextMiddleware, configureApp, createLegacyPathRedirectMiddleware };
|
|
412
|
+
export { type ApiNotFoundResponse, CsrfMiddleware, CsrfTokenMiddleware, FileService, HtmlHotUpdateModule, HtmlHotUpdateService, type PlatformHttpClientOptions, PlatformHttpClientService, PlatformModule, type PlatformModuleOptions, StaticModule, UserContextMiddleware, ViewContextMiddleware, configureApp, createLegacyPathRedirectMiddleware, registerOpenApiSpecEndpoint };
|
package/dist/index.js
CHANGED
|
@@ -34600,32 +34600,31 @@ var ViewContextMiddleware = class _ViewContextMiddleware {
|
|
|
34600
34600
|
constructor(client) {
|
|
34601
34601
|
this.client = client;
|
|
34602
34602
|
}
|
|
34603
|
-
async
|
|
34603
|
+
async getAppInfo(appId) {
|
|
34604
34604
|
if (!appId) {
|
|
34605
|
-
this.logger.warn(`appId is empty, skip get app
|
|
34605
|
+
this.logger.warn(`appId is empty, skip get app info`);
|
|
34606
34606
|
return null;
|
|
34607
34607
|
}
|
|
34608
34608
|
try {
|
|
34609
34609
|
const resp = await this.client.get(`/b/${appId}/get_published_v2`);
|
|
34610
34610
|
if (resp.status !== 200) {
|
|
34611
|
-
throw new Error(`Failed to get app
|
|
34611
|
+
throw new Error(`Failed to get app info, status: ${resp.status}`);
|
|
34612
34612
|
}
|
|
34613
34613
|
const data = await resp.json();
|
|
34614
34614
|
if (data.status_code !== "0") {
|
|
34615
|
-
throw new Error(`Failed to get app
|
|
34615
|
+
throw new Error(`Failed to get app info, status_code: ${data.status_code}`);
|
|
34616
34616
|
}
|
|
34617
|
-
return data.data ??
|
|
34617
|
+
return data.data.app_info ?? {};
|
|
34618
34618
|
} catch (err) {
|
|
34619
|
-
this.logger.error(err, "Failed to get app
|
|
34619
|
+
this.logger.error(err, "Failed to get app info");
|
|
34620
34620
|
return null;
|
|
34621
34621
|
}
|
|
34622
34622
|
}
|
|
34623
34623
|
async use(req, res, next) {
|
|
34624
34624
|
const { userId, tenantId, appId, loginUrl, userType } = req.userContext;
|
|
34625
34625
|
const csrfToken = req.csrfToken;
|
|
34626
|
+
const appInfo = await this.getAppInfo(appId);
|
|
34626
34627
|
const environment = mapToWindowEnvironment(process.env.FORCE_FRAMEWORK_ENVIRONMENT);
|
|
34627
|
-
const appPublishedData = await this.getAppPublished(appId);
|
|
34628
|
-
const appInfo = appPublishedData?.app_info ?? null;
|
|
34629
34628
|
req.__platform_data__ = {
|
|
34630
34629
|
csrfToken: csrfToken ?? "",
|
|
34631
34630
|
userId: userId ?? "",
|
|
@@ -34636,9 +34635,7 @@ var ViewContextMiddleware = class _ViewContextMiddleware {
|
|
|
34636
34635
|
loginUrl: loginUrl ?? "",
|
|
34637
34636
|
userType: userType ?? "",
|
|
34638
34637
|
tenantId,
|
|
34639
|
-
environment
|
|
34640
|
-
showBadge: appInfo?.show_badge !== false,
|
|
34641
|
-
appPublished: appPublishedData ?? null
|
|
34638
|
+
environment
|
|
34642
34639
|
};
|
|
34643
34640
|
res.locals = {
|
|
34644
34641
|
...res.locals ?? {},
|
|
@@ -34749,18 +34746,24 @@ function createApiNotFoundResponse(req) {
|
|
|
34749
34746
|
};
|
|
34750
34747
|
}
|
|
34751
34748
|
__name(createApiNotFoundResponse, "createApiNotFoundResponse");
|
|
34752
|
-
function
|
|
34749
|
+
function getApiPathPrefixes() {
|
|
34753
34750
|
const globalPrefix = process.env.CLIENT_BASE_PATH ?? "";
|
|
34754
34751
|
if (!globalPrefix) {
|
|
34755
|
-
return
|
|
34752
|
+
return [
|
|
34753
|
+
"/api/",
|
|
34754
|
+
"/openapi/"
|
|
34755
|
+
];
|
|
34756
34756
|
}
|
|
34757
34757
|
const normalizedPrefix = globalPrefix.replace(/\/+$/, "");
|
|
34758
|
-
return
|
|
34758
|
+
return [
|
|
34759
|
+
`${normalizedPrefix}/api/`,
|
|
34760
|
+
`${normalizedPrefix}/openapi/`
|
|
34761
|
+
];
|
|
34759
34762
|
}
|
|
34760
|
-
__name(
|
|
34763
|
+
__name(getApiPathPrefixes, "getApiPathPrefixes");
|
|
34761
34764
|
function apiResponseInterceptor(req, res, next) {
|
|
34762
|
-
const
|
|
34763
|
-
if (!req.baseUrl.startsWith(
|
|
34765
|
+
const apiPrefixes = getApiPathPrefixes();
|
|
34766
|
+
if (!apiPrefixes.some((prefix) => req.baseUrl.startsWith(prefix))) {
|
|
34764
34767
|
return next();
|
|
34765
34768
|
}
|
|
34766
34769
|
res.render = function() {
|
|
@@ -36413,16 +36416,18 @@ var PlatformModule = class _PlatformModule {
|
|
|
36413
36416
|
*/
|
|
36414
36417
|
configure(consumer) {
|
|
36415
36418
|
const options = _PlatformModule.moduleOptions;
|
|
36416
|
-
consumer.apply(apiResponseInterceptor).forRoutes("/api/*");
|
|
36419
|
+
consumer.apply(apiResponseInterceptor).forRoutes("/api/*", "/openapi/*");
|
|
36417
36420
|
if (process.env.NODE_ENV === "development") {
|
|
36418
36421
|
consumer.apply(FrameworkDebugMiddleware).forRoutes("/api/__framework__/debug");
|
|
36419
36422
|
}
|
|
36420
36423
|
consumer.apply(UserContextMiddleware, RequestContextMiddleware, LoggerContextMiddleware, ObservableTraceMiddleware, ...DISABLE_DATAPASS ? [] : [
|
|
36421
36424
|
SqlExecutionContextMiddleware
|
|
36422
36425
|
]).forRoutes("/*");
|
|
36423
|
-
consumer.apply(CsrfTokenMiddleware, ViewContextMiddleware, HtmlHotUpdateViewMiddleware).exclude("/api/(.*)", "/static/(.*)").forRoutes("*");
|
|
36426
|
+
consumer.apply(CsrfTokenMiddleware, ViewContextMiddleware, HtmlHotUpdateViewMiddleware).exclude("/api/(.*)", "/openapi/(.*)", "/static/(.*)").forRoutes("*");
|
|
36424
36427
|
if (options.enableCsrf !== false) {
|
|
36425
|
-
const csrfRoutes = options.csrfRoutes ||
|
|
36428
|
+
const csrfRoutes = options.csrfRoutes || [
|
|
36429
|
+
"/api/*"
|
|
36430
|
+
];
|
|
36426
36431
|
if (Array.isArray(csrfRoutes)) {
|
|
36427
36432
|
csrfRoutes.forEach((route) => {
|
|
36428
36433
|
consumer.apply(CsrfMiddleware).forRoutes(route);
|
|
@@ -36479,6 +36484,108 @@ function createLegacyPathRedirectMiddleware() {
|
|
|
36479
36484
|
}
|
|
36480
36485
|
__name(createLegacyPathRedirectMiddleware, "createLegacyPathRedirectMiddleware");
|
|
36481
36486
|
|
|
36487
|
+
// src/middlewares/openapi-spec/index.ts
|
|
36488
|
+
import { SwaggerModule, DocumentBuilder } from "@nestjs/swagger";
|
|
36489
|
+
function registerOpenApiSpecEndpoint(app) {
|
|
36490
|
+
const globalPrefix = process.env.CLIENT_BASE_PATH ?? "";
|
|
36491
|
+
let cachedResult = null;
|
|
36492
|
+
const httpAdapter = app.getHttpAdapter();
|
|
36493
|
+
httpAdapter.get(`${globalPrefix}/api/__framework__/openapi-spec`, (_req, res) => {
|
|
36494
|
+
try {
|
|
36495
|
+
if (!cachedResult) {
|
|
36496
|
+
const config = new DocumentBuilder().setTitle("OpenAPI Spec").setVersion("1.0").build();
|
|
36497
|
+
const spec = SwaggerModule.createDocument(app, config);
|
|
36498
|
+
cachedResult = buildFilteredSpec(spec, globalPrefix);
|
|
36499
|
+
}
|
|
36500
|
+
res.json(cachedResult);
|
|
36501
|
+
} catch (err) {
|
|
36502
|
+
console.error("[openapi-spec] Failed to generate spec:", err);
|
|
36503
|
+
res.json({
|
|
36504
|
+
openapi: "3.0.0",
|
|
36505
|
+
paths: {},
|
|
36506
|
+
components: {
|
|
36507
|
+
schemas: {}
|
|
36508
|
+
}
|
|
36509
|
+
});
|
|
36510
|
+
}
|
|
36511
|
+
});
|
|
36512
|
+
console.log(`[OpenAPI] Registered GET ${globalPrefix}/api/__framework__/openapi-spec`);
|
|
36513
|
+
}
|
|
36514
|
+
__name(registerOpenApiSpecEndpoint, "registerOpenApiSpecEndpoint");
|
|
36515
|
+
function buildFilteredSpec(spec, globalPrefix) {
|
|
36516
|
+
const schemas = spec.components?.schemas ?? {};
|
|
36517
|
+
const paths = spec.paths ?? {};
|
|
36518
|
+
const filteredPaths = {};
|
|
36519
|
+
for (const [pathKey, methods] of Object.entries(paths)) {
|
|
36520
|
+
const cleanPath = stripPrefix(pathKey, globalPrefix);
|
|
36521
|
+
if (!cleanPath.startsWith("/openapi")) continue;
|
|
36522
|
+
filteredPaths[cleanPath] = {};
|
|
36523
|
+
for (const [method, operation] of Object.entries(methods)) {
|
|
36524
|
+
if ([
|
|
36525
|
+
"parameters",
|
|
36526
|
+
"summary",
|
|
36527
|
+
"description",
|
|
36528
|
+
"servers"
|
|
36529
|
+
].includes(method)) continue;
|
|
36530
|
+
filteredPaths[cleanPath][method] = resolveRefsDeep(structuredClone(operation), schemas);
|
|
36531
|
+
}
|
|
36532
|
+
}
|
|
36533
|
+
return {
|
|
36534
|
+
openapi: spec.openapi,
|
|
36535
|
+
paths: filteredPaths,
|
|
36536
|
+
components: {
|
|
36537
|
+
schemas: resolveAllSchemaRefs(structuredClone(schemas))
|
|
36538
|
+
}
|
|
36539
|
+
};
|
|
36540
|
+
}
|
|
36541
|
+
__name(buildFilteredSpec, "buildFilteredSpec");
|
|
36542
|
+
function stripPrefix(path2, prefix) {
|
|
36543
|
+
if (prefix && path2.startsWith(prefix)) {
|
|
36544
|
+
return path2.slice(prefix.length);
|
|
36545
|
+
}
|
|
36546
|
+
return path2;
|
|
36547
|
+
}
|
|
36548
|
+
__name(stripPrefix, "stripPrefix");
|
|
36549
|
+
var MAX_REF_DEPTH = 5;
|
|
36550
|
+
function resolveRefsDeep(obj, schemas, depth = 0) {
|
|
36551
|
+
if (depth > MAX_REF_DEPTH || obj === null || obj === void 0) return obj;
|
|
36552
|
+
if (typeof obj !== "object") return obj;
|
|
36553
|
+
if (Array.isArray(obj)) {
|
|
36554
|
+
return obj.map((item) => resolveRefsDeep(item, schemas, depth));
|
|
36555
|
+
}
|
|
36556
|
+
const record = obj;
|
|
36557
|
+
if (typeof record["$ref"] === "string") {
|
|
36558
|
+
const resolved = resolveRef(record["$ref"], schemas);
|
|
36559
|
+
if (resolved !== void 0) {
|
|
36560
|
+
return resolveRefsDeep(structuredClone(resolved), schemas, depth + 1);
|
|
36561
|
+
}
|
|
36562
|
+
return record;
|
|
36563
|
+
}
|
|
36564
|
+
const result = {};
|
|
36565
|
+
for (const [key, value] of Object.entries(record)) {
|
|
36566
|
+
result[key] = resolveRefsDeep(value, schemas, depth);
|
|
36567
|
+
}
|
|
36568
|
+
return result;
|
|
36569
|
+
}
|
|
36570
|
+
__name(resolveRefsDeep, "resolveRefsDeep");
|
|
36571
|
+
function resolveRef(ref, schemas) {
|
|
36572
|
+
const prefix = "#/components/schemas/";
|
|
36573
|
+
if (ref.startsWith(prefix)) {
|
|
36574
|
+
const name = ref.slice(prefix.length);
|
|
36575
|
+
return schemas[name];
|
|
36576
|
+
}
|
|
36577
|
+
return void 0;
|
|
36578
|
+
}
|
|
36579
|
+
__name(resolveRef, "resolveRef");
|
|
36580
|
+
function resolveAllSchemaRefs(schemas) {
|
|
36581
|
+
const result = {};
|
|
36582
|
+
for (const [name, schema] of Object.entries(schemas)) {
|
|
36583
|
+
result[name] = resolveRefsDeep(schema, schemas);
|
|
36584
|
+
}
|
|
36585
|
+
return result;
|
|
36586
|
+
}
|
|
36587
|
+
__name(resolveAllSchemaRefs, "resolveAllSchemaRefs");
|
|
36588
|
+
|
|
36482
36589
|
// src/setup.ts
|
|
36483
36590
|
var DEFAULT_BODY_LIMIT = "1mb";
|
|
36484
36591
|
var defaultPerms = {
|
|
@@ -36511,6 +36618,9 @@ async function configureApp(app, perms = defaultPerms) {
|
|
|
36511
36618
|
console.error("[OpenAPI] OpenAPI \u751F\u6210\u5931\u8D25:", err);
|
|
36512
36619
|
}
|
|
36513
36620
|
}
|
|
36621
|
+
if (process.env.NODE_ENV !== "production") {
|
|
36622
|
+
registerOpenApiSpecEndpoint(app);
|
|
36623
|
+
}
|
|
36514
36624
|
console.log("App Started Successfully.");
|
|
36515
36625
|
}
|
|
36516
36626
|
__name(configureApp, "configureApp");
|
|
@@ -36545,7 +36655,8 @@ export {
|
|
|
36545
36655
|
UserContextMiddleware,
|
|
36546
36656
|
ViewContextMiddleware,
|
|
36547
36657
|
configureApp,
|
|
36548
|
-
createLegacyPathRedirectMiddleware
|
|
36658
|
+
createLegacyPathRedirectMiddleware,
|
|
36659
|
+
registerOpenApiSpecEndpoint
|
|
36549
36660
|
};
|
|
36550
36661
|
/*! Bundled license information:
|
|
36551
36662
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lark-apaas/fullstack-nestjs-core",
|
|
3
|
-
"version": "1.1.34-alpha.
|
|
3
|
+
"version": "1.1.34-alpha.63",
|
|
4
4
|
"description": "FullStack Nestjs Core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@lark-apaas/nestjs-authzpaas": "^0.1.8",
|
|
46
46
|
"@lark-apaas/nestjs-capability": "^0.1.11",
|
|
47
47
|
"@lark-apaas/nestjs-common": "^0.1.8",
|
|
48
|
-
"@lark-apaas/nestjs-datapaas": "^1.0.
|
|
48
|
+
"@lark-apaas/nestjs-datapaas": "^1.0.18",
|
|
49
49
|
"@lark-apaas/nestjs-logger": "^1.0.16",
|
|
50
50
|
"@lark-apaas/nestjs-observable": "^0.0.11",
|
|
51
51
|
"@lark-apaas/nestjs-openapi-devtools": "^1.0.10",
|