@lark-apaas/fullstack-nestjs-core 1.1.14-alpha.4 → 1.1.14-alpha.6
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 +425 -21
- package/dist/index.d.cts +34 -2
- package/dist/index.d.ts +34 -2
- package/dist/index.js +414 -12
- package/package.json +6 -5
package/dist/index.cjs
CHANGED
|
@@ -32,11 +32,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
32
32
|
// src/index.ts
|
|
33
33
|
var index_exports = {};
|
|
34
34
|
__export(index_exports, {
|
|
35
|
-
AutoTrace: () =>
|
|
35
|
+
AutoTrace: () => import_nestjs_common6.AutoTrace,
|
|
36
36
|
CsrfMiddleware: () => CsrfMiddleware,
|
|
37
37
|
CsrfTokenMiddleware: () => CsrfTokenMiddleware,
|
|
38
38
|
DevToolsModule: () => import_nestjs_openapi_devtools2.DevToolsModule,
|
|
39
39
|
DevToolsV2Module: () => import_nestjs_openapi_devtools2.DevToolsV2Module,
|
|
40
|
+
FileService: () => FileService,
|
|
40
41
|
PlatformModule: () => PlatformModule,
|
|
41
42
|
UserContextMiddleware: () => UserContextMiddleware,
|
|
42
43
|
ViewContextMiddleware: () => ViewContextMiddleware,
|
|
@@ -45,9 +46,9 @@ __export(index_exports, {
|
|
|
45
46
|
module.exports = __toCommonJS(index_exports);
|
|
46
47
|
|
|
47
48
|
// src/modules/platform/module.ts
|
|
48
|
-
var
|
|
49
|
+
var import_common10 = require("@nestjs/common");
|
|
49
50
|
var import_core2 = require("@nestjs/core");
|
|
50
|
-
var
|
|
51
|
+
var import_nestjs_common4 = require("@lark-apaas/nestjs-common");
|
|
51
52
|
var import_config2 = require("@nestjs/config");
|
|
52
53
|
var import_nestjs_observable = require("@lark-apaas/nestjs-observable");
|
|
53
54
|
var import_axios2 = require("@nestjs/axios");
|
|
@@ -55,7 +56,7 @@ var import_nestjs_logger2 = require("@lark-apaas/nestjs-logger");
|
|
|
55
56
|
var import_nestjs_datapaas = require("@lark-apaas/nestjs-datapaas");
|
|
56
57
|
var import_nestjs_authnpaas = require("@lark-apaas/nestjs-authnpaas");
|
|
57
58
|
var import_nestjs_trigger = require("@lark-apaas/nestjs-trigger");
|
|
58
|
-
var
|
|
59
|
+
var import_nestjs_common5 = require("@lark-apaas/nestjs-common");
|
|
59
60
|
var import_nestjs_capability = require("@lark-apaas/nestjs-capability");
|
|
60
61
|
|
|
61
62
|
// src/middlewares/user-context/index.ts
|
|
@@ -267,6 +268,7 @@ var ViewContextMiddleware = class _ViewContextMiddleware {
|
|
|
267
268
|
const { userId, tenantId, appId } = req.userContext;
|
|
268
269
|
const csrfToken = req.csrfToken;
|
|
269
270
|
const appInfo = await this.getAppInfo(appId);
|
|
271
|
+
const environment = mapToWindowEnvironment(process.env.FORCE_FRAMEWORK_ENVIRONMENT);
|
|
270
272
|
req.__platform_data__ = {
|
|
271
273
|
csrfToken: csrfToken ?? "",
|
|
272
274
|
userId: userId ?? "",
|
|
@@ -274,7 +276,8 @@ var ViewContextMiddleware = class _ViewContextMiddleware {
|
|
|
274
276
|
appName: safeEscape(appInfo?.app_name ?? "\u5999\u642D\u5E94\u7528"),
|
|
275
277
|
appAvatar: appInfo?.app_avatar ?? "",
|
|
276
278
|
appDescription: safeEscape(appInfo?.app_description ?? ""),
|
|
277
|
-
tenantId
|
|
279
|
+
tenantId,
|
|
280
|
+
environment
|
|
278
281
|
};
|
|
279
282
|
res.locals = {
|
|
280
283
|
...res.locals ?? {},
|
|
@@ -284,7 +287,8 @@ var ViewContextMiddleware = class _ViewContextMiddleware {
|
|
|
284
287
|
appId: appId ?? "",
|
|
285
288
|
appName: safeEscape(appInfo?.app_name ?? "\u5999\u642D\u5E94\u7528"),
|
|
286
289
|
appAvatar: appInfo?.app_avatar ?? "",
|
|
287
|
-
appDescription: safeEscape(appInfo?.app_description ?? "")
|
|
290
|
+
appDescription: safeEscape(appInfo?.app_description ?? ""),
|
|
291
|
+
environment
|
|
288
292
|
};
|
|
289
293
|
next();
|
|
290
294
|
}
|
|
@@ -297,6 +301,14 @@ ViewContextMiddleware = _ts_decorate3([
|
|
|
297
301
|
typeof PlatformHttpClient === "undefined" ? Object : PlatformHttpClient
|
|
298
302
|
])
|
|
299
303
|
], ViewContextMiddleware);
|
|
304
|
+
function mapToWindowEnvironment(input) {
|
|
305
|
+
const value = (input || "").trim().toLowerCase();
|
|
306
|
+
if (value === "boe") return "staging";
|
|
307
|
+
if (value === "pre") return "gray";
|
|
308
|
+
if (value === "online") return "online";
|
|
309
|
+
return "online";
|
|
310
|
+
}
|
|
311
|
+
__name(mapToWindowEnvironment, "mapToWindowEnvironment");
|
|
300
312
|
|
|
301
313
|
// src/middlewares/csrf_token/index.ts
|
|
302
314
|
var import_common4 = require("@nestjs/common");
|
|
@@ -769,7 +781,10 @@ PlatformHttpClientService = _ts_decorate8([
|
|
|
769
781
|
// src/modules/platform/config/feature-switch.ts
|
|
770
782
|
var DISABLE_DATAPASS = process.env.FORCE_FRAMEWORK_DISABLE_DATAPASS === "true";
|
|
771
783
|
|
|
772
|
-
// src/
|
|
784
|
+
// src/services/file.service.ts
|
|
785
|
+
var import_common9 = require("@nestjs/common");
|
|
786
|
+
var import_nestjs_common3 = require("@lark-apaas/nestjs-common");
|
|
787
|
+
var import_file_service = require("@lark-apaas/file-service");
|
|
773
788
|
function _ts_decorate9(decorators, target, key, desc) {
|
|
774
789
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
775
790
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -777,6 +792,390 @@ function _ts_decorate9(decorators, target, key, desc) {
|
|
|
777
792
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
778
793
|
}
|
|
779
794
|
__name(_ts_decorate9, "_ts_decorate");
|
|
795
|
+
function _ts_metadata6(k, v) {
|
|
796
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
797
|
+
}
|
|
798
|
+
__name(_ts_metadata6, "_ts_metadata");
|
|
799
|
+
function _ts_param2(paramIndex, decorator) {
|
|
800
|
+
return function(target, key) {
|
|
801
|
+
decorator(target, key, paramIndex);
|
|
802
|
+
};
|
|
803
|
+
}
|
|
804
|
+
__name(_ts_param2, "_ts_param");
|
|
805
|
+
var FileService = class {
|
|
806
|
+
static {
|
|
807
|
+
__name(this, "FileService");
|
|
808
|
+
}
|
|
809
|
+
requestContextService;
|
|
810
|
+
httpClient;
|
|
811
|
+
observable;
|
|
812
|
+
fileServiceCore;
|
|
813
|
+
nestLogger;
|
|
814
|
+
constructor(requestContextService, httpClient, observable) {
|
|
815
|
+
this.requestContextService = requestContextService;
|
|
816
|
+
this.httpClient = httpClient;
|
|
817
|
+
this.observable = observable;
|
|
818
|
+
this.fileServiceCore = new import_file_service.FileService(this.httpClient);
|
|
819
|
+
this.nestLogger = new import_common9.Logger("file");
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* 返回一个绑定了指定 bucket 的代理对象
|
|
823
|
+
* 不会修改 context,避免副作用
|
|
824
|
+
*/
|
|
825
|
+
from(bucket) {
|
|
826
|
+
return {
|
|
827
|
+
upload: /* @__PURE__ */ __name((file, options) => this._upload(bucket, file, options), "upload"),
|
|
828
|
+
download: /* @__PURE__ */ __name((path) => this._download(bucket, path), "download"),
|
|
829
|
+
list: /* @__PURE__ */ __name((prefix, searchOptions) => this._list(bucket, prefix, searchOptions), "list"),
|
|
830
|
+
remove: /* @__PURE__ */ __name((filePaths) => this._remove(bucket, filePaths), "remove"),
|
|
831
|
+
createSignedUrl: /* @__PURE__ */ __name((path, expiresIn) => this._createSignedUrl(bucket, path, expiresIn), "createSignedUrl"),
|
|
832
|
+
getFileMetadata: /* @__PURE__ */ __name((filePath) => this._getFileMetadata(bucket, filePath), "getFileMetadata")
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
// ============ 公开方法(使用默认 bucket)============
|
|
836
|
+
async upload(file, options) {
|
|
837
|
+
return this._upload(await this.getDefaultBucket(), file, options);
|
|
838
|
+
}
|
|
839
|
+
download(path) {
|
|
840
|
+
const capturedBucketPromise = this.getDefaultBucket();
|
|
841
|
+
return this._download(capturedBucketPromise, path);
|
|
842
|
+
}
|
|
843
|
+
async list(prefix, searchOptions) {
|
|
844
|
+
return this._list(await this.getDefaultBucket(), prefix, searchOptions);
|
|
845
|
+
}
|
|
846
|
+
async remove(filePaths) {
|
|
847
|
+
return this._remove(await this.getDefaultBucket(), filePaths);
|
|
848
|
+
}
|
|
849
|
+
async createSignedUrl(path, expiresIn) {
|
|
850
|
+
return this._createSignedUrl(await this.getDefaultBucket(), path, expiresIn);
|
|
851
|
+
}
|
|
852
|
+
async getFileMetadata(filePath) {
|
|
853
|
+
return this._getFileMetadata(await this.getDefaultBucket(), filePath);
|
|
854
|
+
}
|
|
855
|
+
async getDefaultBucket() {
|
|
856
|
+
const reqContext = this.requestContextService.getContext();
|
|
857
|
+
const bucketFromContext = reqContext?.bucket;
|
|
858
|
+
if (bucketFromContext) {
|
|
859
|
+
return bucketFromContext;
|
|
860
|
+
}
|
|
861
|
+
const appId = this.getAppId();
|
|
862
|
+
const bucket = await this.fileServiceCore.getDefaultBucket(appId);
|
|
863
|
+
return bucket;
|
|
864
|
+
}
|
|
865
|
+
getAppId() {
|
|
866
|
+
const requestCtx = this.requestContextService.getContext();
|
|
867
|
+
return requestCtx?.appId ?? "";
|
|
868
|
+
}
|
|
869
|
+
// ============ 核心实现方法(接受 bucket 参数)============
|
|
870
|
+
async _upload(bucket, file, options) {
|
|
871
|
+
const span = this.observable.startTrace("\u6587\u4EF6: upload", this.requestContextService.getContext()?.requestRootSpan);
|
|
872
|
+
span.setAttribute("module", "file");
|
|
873
|
+
span.setAttribute("source_type", "platform");
|
|
874
|
+
const spanContext = {
|
|
875
|
+
traceId: span.spanContext().traceId,
|
|
876
|
+
spanId: span.spanContext().spanId
|
|
877
|
+
};
|
|
878
|
+
const logContext = {
|
|
879
|
+
source_type: "platform",
|
|
880
|
+
paas_attributes_module: "file",
|
|
881
|
+
paas_parent_span_context: spanContext
|
|
882
|
+
};
|
|
883
|
+
const baseParams = {
|
|
884
|
+
method: "upload",
|
|
885
|
+
source_type: "server",
|
|
886
|
+
request: {
|
|
887
|
+
options
|
|
888
|
+
}
|
|
889
|
+
};
|
|
890
|
+
const startTime = Date.now();
|
|
891
|
+
try {
|
|
892
|
+
const res = await this.fileServiceCore.upload({
|
|
893
|
+
appId: this.getAppId(),
|
|
894
|
+
bucketId: await bucket,
|
|
895
|
+
fileBody: file,
|
|
896
|
+
options
|
|
897
|
+
});
|
|
898
|
+
this.nestLogger.log(JSON.stringify({
|
|
899
|
+
...baseParams,
|
|
900
|
+
response: res,
|
|
901
|
+
status: "succeed",
|
|
902
|
+
duration_ms: Date.now() - startTime
|
|
903
|
+
}), logContext);
|
|
904
|
+
return res;
|
|
905
|
+
} catch (e) {
|
|
906
|
+
this.nestLogger.error(JSON.stringify({
|
|
907
|
+
...baseParams,
|
|
908
|
+
error_message: e instanceof Error ? e.message : String(e),
|
|
909
|
+
status: "failed",
|
|
910
|
+
duration_ms: Date.now() - startTime
|
|
911
|
+
}), logContext);
|
|
912
|
+
throw e;
|
|
913
|
+
} finally {
|
|
914
|
+
span.end();
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
_download(bucket, path) {
|
|
918
|
+
const capturedAppId = this.getAppId();
|
|
919
|
+
const capturedRootSpan = this.requestContextService.getContext()?.requestRootSpan;
|
|
920
|
+
const downloadFn = /* @__PURE__ */ __name(async () => {
|
|
921
|
+
const span = this.observable.startTrace("\u6587\u4EF6: download", capturedRootSpan);
|
|
922
|
+
span.setAttribute("module", "file");
|
|
923
|
+
span.setAttribute("source_type", "platform");
|
|
924
|
+
const spanContext = {
|
|
925
|
+
traceId: span.spanContext().traceId,
|
|
926
|
+
spanId: span.spanContext().spanId
|
|
927
|
+
};
|
|
928
|
+
const logContext = {
|
|
929
|
+
source_type: "platform",
|
|
930
|
+
paas_attributes_module: "file",
|
|
931
|
+
paas_parent_span_context: spanContext
|
|
932
|
+
};
|
|
933
|
+
const baseParams = {
|
|
934
|
+
method: "download",
|
|
935
|
+
source_type: "server",
|
|
936
|
+
request: {
|
|
937
|
+
path
|
|
938
|
+
}
|
|
939
|
+
};
|
|
940
|
+
const startTime = Date.now();
|
|
941
|
+
try {
|
|
942
|
+
const res = await this.fileServiceCore.downloadInner({
|
|
943
|
+
appId: capturedAppId,
|
|
944
|
+
bucketId: await bucket,
|
|
945
|
+
filePath: path
|
|
946
|
+
});
|
|
947
|
+
this.nestLogger.log(JSON.stringify({
|
|
948
|
+
...baseParams,
|
|
949
|
+
response: {
|
|
950
|
+
metadata: res.metadata
|
|
951
|
+
},
|
|
952
|
+
status: "succeed",
|
|
953
|
+
duration_ms: Date.now() - startTime
|
|
954
|
+
}), logContext);
|
|
955
|
+
return res;
|
|
956
|
+
} catch (e) {
|
|
957
|
+
this.nestLogger.error(JSON.stringify({
|
|
958
|
+
...baseParams,
|
|
959
|
+
error_message: e instanceof Error ? e.message : String(e),
|
|
960
|
+
status: "failed",
|
|
961
|
+
duration_ms: Date.now() - startTime
|
|
962
|
+
}), logContext);
|
|
963
|
+
throw e;
|
|
964
|
+
} finally {
|
|
965
|
+
span.end();
|
|
966
|
+
}
|
|
967
|
+
}, "downloadFn");
|
|
968
|
+
return new import_file_service.FileDownloadBuilder(downloadFn);
|
|
969
|
+
}
|
|
970
|
+
async _list(bucket, prefix, searchOptions) {
|
|
971
|
+
const span = this.observable.startTrace("\u6587\u4EF6: list", this.requestContextService.getContext()?.requestRootSpan);
|
|
972
|
+
span.setAttribute("module", "file");
|
|
973
|
+
span.setAttribute("source_type", "platform");
|
|
974
|
+
const spanContext = {
|
|
975
|
+
traceId: span.spanContext().traceId,
|
|
976
|
+
spanId: span.spanContext().spanId
|
|
977
|
+
};
|
|
978
|
+
const logContext = {
|
|
979
|
+
source_type: "platform",
|
|
980
|
+
paas_attributes_module: "file",
|
|
981
|
+
paas_parent_span_context: spanContext
|
|
982
|
+
};
|
|
983
|
+
const baseParams = {
|
|
984
|
+
method: "list",
|
|
985
|
+
source_type: "server",
|
|
986
|
+
request: {
|
|
987
|
+
prefix,
|
|
988
|
+
searchOptions
|
|
989
|
+
}
|
|
990
|
+
};
|
|
991
|
+
const startTime = Date.now();
|
|
992
|
+
try {
|
|
993
|
+
const res = await this.fileServiceCore.list({
|
|
994
|
+
appId: this.getAppId(),
|
|
995
|
+
bucketId: await bucket,
|
|
996
|
+
prefix,
|
|
997
|
+
searchOptions
|
|
998
|
+
});
|
|
999
|
+
this.nestLogger.log(JSON.stringify({
|
|
1000
|
+
...baseParams,
|
|
1001
|
+
response: res,
|
|
1002
|
+
status: "succeed",
|
|
1003
|
+
duration_ms: Date.now() - startTime
|
|
1004
|
+
}), logContext);
|
|
1005
|
+
return res;
|
|
1006
|
+
} catch (e) {
|
|
1007
|
+
this.nestLogger.error(JSON.stringify({
|
|
1008
|
+
...baseParams,
|
|
1009
|
+
error_message: e instanceof Error ? e.message : String(e),
|
|
1010
|
+
status: "failed",
|
|
1011
|
+
duration_ms: Date.now() - startTime
|
|
1012
|
+
}), logContext);
|
|
1013
|
+
throw e;
|
|
1014
|
+
} finally {
|
|
1015
|
+
span.end();
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
async _remove(bucket, filePaths) {
|
|
1019
|
+
const span = this.observable.startTrace("\u6587\u4EF6: remove", this.requestContextService.getContext()?.requestRootSpan);
|
|
1020
|
+
span.setAttribute("module", "file");
|
|
1021
|
+
span.setAttribute("source_type", "platform");
|
|
1022
|
+
const spanContext = {
|
|
1023
|
+
traceId: span.spanContext().traceId,
|
|
1024
|
+
spanId: span.spanContext().spanId
|
|
1025
|
+
};
|
|
1026
|
+
const logContext = {
|
|
1027
|
+
source_type: "platform",
|
|
1028
|
+
paas_attributes_module: "file",
|
|
1029
|
+
paas_parent_span_context: spanContext
|
|
1030
|
+
};
|
|
1031
|
+
const baseParams = {
|
|
1032
|
+
method: "remove",
|
|
1033
|
+
source_type: "server",
|
|
1034
|
+
request: {
|
|
1035
|
+
filePaths
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
const startTime = Date.now();
|
|
1039
|
+
try {
|
|
1040
|
+
const res = await this.fileServiceCore.remove({
|
|
1041
|
+
appId: this.getAppId(),
|
|
1042
|
+
bucketId: await bucket,
|
|
1043
|
+
filePaths
|
|
1044
|
+
});
|
|
1045
|
+
this.nestLogger.log(JSON.stringify({
|
|
1046
|
+
...baseParams,
|
|
1047
|
+
response: res,
|
|
1048
|
+
status: "succeed",
|
|
1049
|
+
duration_ms: Date.now() - startTime
|
|
1050
|
+
}), logContext);
|
|
1051
|
+
return res;
|
|
1052
|
+
} catch (e) {
|
|
1053
|
+
this.nestLogger.error(JSON.stringify({
|
|
1054
|
+
...baseParams,
|
|
1055
|
+
error_message: e instanceof Error ? e.message : String(e),
|
|
1056
|
+
status: "failed",
|
|
1057
|
+
duration_ms: Date.now() - startTime
|
|
1058
|
+
}), logContext);
|
|
1059
|
+
throw e;
|
|
1060
|
+
} finally {
|
|
1061
|
+
span.end();
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
async _createSignedUrl(bucket, path, expiresIn) {
|
|
1065
|
+
const span = this.observable.startTrace("\u6587\u4EF6: createSignedUrl", this.requestContextService.getContext()?.requestRootSpan);
|
|
1066
|
+
span.setAttribute("module", "file");
|
|
1067
|
+
span.setAttribute("source_type", "platform");
|
|
1068
|
+
const spanContext = {
|
|
1069
|
+
traceId: span.spanContext().traceId,
|
|
1070
|
+
spanId: span.spanContext().spanId
|
|
1071
|
+
};
|
|
1072
|
+
const logContext = {
|
|
1073
|
+
source_type: "platform",
|
|
1074
|
+
paas_attributes_module: "file",
|
|
1075
|
+
paas_parent_span_context: spanContext
|
|
1076
|
+
};
|
|
1077
|
+
const baseParams = {
|
|
1078
|
+
method: "createSignedUrl",
|
|
1079
|
+
source_type: "server",
|
|
1080
|
+
request: {
|
|
1081
|
+
path,
|
|
1082
|
+
expiresIn
|
|
1083
|
+
}
|
|
1084
|
+
};
|
|
1085
|
+
const startTime = Date.now();
|
|
1086
|
+
try {
|
|
1087
|
+
const res = await this.fileServiceCore.createSignedUrl({
|
|
1088
|
+
appId: this.getAppId(),
|
|
1089
|
+
bucketId: await bucket,
|
|
1090
|
+
filePath: path,
|
|
1091
|
+
expiresIn
|
|
1092
|
+
});
|
|
1093
|
+
this.nestLogger.log(JSON.stringify({
|
|
1094
|
+
...baseParams,
|
|
1095
|
+
response: res,
|
|
1096
|
+
status: "succeed",
|
|
1097
|
+
duration_ms: Date.now() - startTime
|
|
1098
|
+
}), logContext);
|
|
1099
|
+
return res;
|
|
1100
|
+
} catch (e) {
|
|
1101
|
+
this.nestLogger.error(JSON.stringify({
|
|
1102
|
+
...baseParams,
|
|
1103
|
+
error_message: e instanceof Error ? e.message : String(e),
|
|
1104
|
+
status: "failed",
|
|
1105
|
+
duration_ms: Date.now() - startTime
|
|
1106
|
+
}), logContext);
|
|
1107
|
+
throw e;
|
|
1108
|
+
} finally {
|
|
1109
|
+
span.end();
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
async _getFileMetadata(bucket, filePath) {
|
|
1113
|
+
const span = this.observable.startTrace("\u6587\u4EF6: getFileMetadata", this.requestContextService.getContext()?.requestRootSpan);
|
|
1114
|
+
span.setAttribute("module", "file");
|
|
1115
|
+
span.setAttribute("source_type", "platform");
|
|
1116
|
+
const spanContext = {
|
|
1117
|
+
traceId: span.spanContext().traceId,
|
|
1118
|
+
spanId: span.spanContext().spanId
|
|
1119
|
+
};
|
|
1120
|
+
const logContext = {
|
|
1121
|
+
source_type: "platform",
|
|
1122
|
+
paas_attributes_module: "file",
|
|
1123
|
+
paas_parent_span_context: spanContext
|
|
1124
|
+
};
|
|
1125
|
+
const baseParams = {
|
|
1126
|
+
method: "getFileMetadata",
|
|
1127
|
+
source_type: "server",
|
|
1128
|
+
request: {
|
|
1129
|
+
filePath
|
|
1130
|
+
}
|
|
1131
|
+
};
|
|
1132
|
+
const startTime = Date.now();
|
|
1133
|
+
try {
|
|
1134
|
+
const res = await this.fileServiceCore.getFileMetadata({
|
|
1135
|
+
appId: this.getAppId(),
|
|
1136
|
+
bucketId: await bucket,
|
|
1137
|
+
filePath
|
|
1138
|
+
});
|
|
1139
|
+
this.nestLogger.log(JSON.stringify({
|
|
1140
|
+
...baseParams,
|
|
1141
|
+
response: res,
|
|
1142
|
+
status: "succeed",
|
|
1143
|
+
duration_ms: Date.now() - startTime
|
|
1144
|
+
}), logContext);
|
|
1145
|
+
return res;
|
|
1146
|
+
} catch (e) {
|
|
1147
|
+
this.nestLogger.error(JSON.stringify({
|
|
1148
|
+
...baseParams,
|
|
1149
|
+
error_message: e instanceof Error ? e.message : String(e),
|
|
1150
|
+
status: "failed",
|
|
1151
|
+
duration_ms: Date.now() - startTime
|
|
1152
|
+
}), logContext);
|
|
1153
|
+
throw e;
|
|
1154
|
+
} finally {
|
|
1155
|
+
span.end();
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
};
|
|
1159
|
+
FileService = _ts_decorate9([
|
|
1160
|
+
(0, import_common9.Injectable)(),
|
|
1161
|
+
_ts_param2(1, (0, import_common9.Inject)(import_nestjs_common3.PLATFORM_HTTP_CLIENT)),
|
|
1162
|
+
_ts_param2(2, (0, import_common9.Inject)(import_nestjs_common3.OBSERVABLE_SERVICE)),
|
|
1163
|
+
_ts_metadata6("design:type", Function),
|
|
1164
|
+
_ts_metadata6("design:paramtypes", [
|
|
1165
|
+
typeof import_nestjs_common3.RequestContextService === "undefined" ? Object : import_nestjs_common3.RequestContextService,
|
|
1166
|
+
typeof PlatformHttpClient === "undefined" ? Object : PlatformHttpClient,
|
|
1167
|
+
typeof import_nestjs_common3.ObservableService === "undefined" ? Object : import_nestjs_common3.ObservableService
|
|
1168
|
+
])
|
|
1169
|
+
], FileService);
|
|
1170
|
+
|
|
1171
|
+
// src/modules/platform/module.ts
|
|
1172
|
+
function _ts_decorate10(decorators, target, key, desc) {
|
|
1173
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1174
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1175
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1176
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1177
|
+
}
|
|
1178
|
+
__name(_ts_decorate10, "_ts_decorate");
|
|
780
1179
|
var PLATFORM_MODULE_OPTIONS = /* @__PURE__ */ Symbol("PLATFORM_MODULE_OPTIONS");
|
|
781
1180
|
var PlatformModule = class _PlatformModule {
|
|
782
1181
|
static {
|
|
@@ -798,7 +1197,7 @@ var PlatformModule = class _PlatformModule {
|
|
|
798
1197
|
app_config_default
|
|
799
1198
|
]
|
|
800
1199
|
}),
|
|
801
|
-
|
|
1200
|
+
import_nestjs_common4.CommonModule,
|
|
802
1201
|
import_nestjs_observable.NestjsObservableModule,
|
|
803
1202
|
import_nestjs_logger2.LoggerModule,
|
|
804
1203
|
import_axios2.HttpModule.register({
|
|
@@ -850,7 +1249,7 @@ var PlatformModule = class _PlatformModule {
|
|
|
850
1249
|
},
|
|
851
1250
|
{
|
|
852
1251
|
provide: import_core2.APP_PIPE,
|
|
853
|
-
useValue: new
|
|
1252
|
+
useValue: new import_common10.ValidationPipe({
|
|
854
1253
|
transform: true,
|
|
855
1254
|
transformOptions: {
|
|
856
1255
|
enableImplicitConversion: true
|
|
@@ -858,12 +1257,12 @@ var PlatformModule = class _PlatformModule {
|
|
|
858
1257
|
})
|
|
859
1258
|
},
|
|
860
1259
|
{
|
|
861
|
-
provide:
|
|
1260
|
+
provide: import_nestjs_common4.OBSERVABLE_SERVICE,
|
|
862
1261
|
useClass: import_nestjs_observable.Observable
|
|
863
1262
|
},
|
|
864
1263
|
PlatformHttpClientService,
|
|
865
1264
|
{
|
|
866
|
-
provide:
|
|
1265
|
+
provide: import_nestjs_common5.PLATFORM_HTTP_CLIENT,
|
|
867
1266
|
useFactory: /* @__PURE__ */ __name((svc) => svc.instance, "useFactory"),
|
|
868
1267
|
inject: [
|
|
869
1268
|
PlatformHttpClientService
|
|
@@ -873,15 +1272,17 @@ var PlatformModule = class _PlatformModule {
|
|
|
873
1272
|
{
|
|
874
1273
|
provide: import_core2.APP_INTERCEPTOR,
|
|
875
1274
|
useClass: import_nestjs_observable.TraceInterceptor
|
|
876
|
-
}
|
|
1275
|
+
},
|
|
1276
|
+
FileService
|
|
877
1277
|
],
|
|
878
1278
|
exports: [
|
|
879
1279
|
import_config2.ConfigModule,
|
|
880
1280
|
import_nestjs_logger2.LoggerModule,
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
import_nestjs_capability.CapabilityModule
|
|
1281
|
+
import_nestjs_common4.CommonModule,
|
|
1282
|
+
import_nestjs_common4.OBSERVABLE_SERVICE,
|
|
1283
|
+
import_nestjs_common5.PLATFORM_HTTP_CLIENT,
|
|
1284
|
+
import_nestjs_capability.CapabilityModule,
|
|
1285
|
+
FileService
|
|
885
1286
|
]
|
|
886
1287
|
};
|
|
887
1288
|
}
|
|
@@ -910,9 +1311,9 @@ var PlatformModule = class _PlatformModule {
|
|
|
910
1311
|
}
|
|
911
1312
|
}
|
|
912
1313
|
};
|
|
913
|
-
PlatformModule =
|
|
914
|
-
(0,
|
|
915
|
-
(0,
|
|
1314
|
+
PlatformModule = _ts_decorate10([
|
|
1315
|
+
(0, import_common10.Global)(),
|
|
1316
|
+
(0, import_common10.Module)({})
|
|
916
1317
|
], PlatformModule);
|
|
917
1318
|
|
|
918
1319
|
// src/setup.ts
|
|
@@ -951,7 +1352,8 @@ __reExport(index_exports, require("@lark-apaas/nestjs-capability"), module.expor
|
|
|
951
1352
|
__reExport(index_exports, require("@lark-apaas/nestjs-datapaas"), module.exports);
|
|
952
1353
|
__reExport(index_exports, require("@lark-apaas/nestjs-observable"), module.exports);
|
|
953
1354
|
__reExport(index_exports, require("@lark-apaas/nestjs-trigger"), module.exports);
|
|
954
|
-
|
|
1355
|
+
__reExport(index_exports, require("@lark-apaas/file-service"), module.exports);
|
|
1356
|
+
var import_nestjs_common6 = require("@lark-apaas/nestjs-common");
|
|
955
1357
|
// Annotate the CommonJS export names for ESM import in node:
|
|
956
1358
|
0 && (module.exports = {
|
|
957
1359
|
AutoTrace,
|
|
@@ -959,6 +1361,7 @@ var import_nestjs_common5 = require("@lark-apaas/nestjs-common");
|
|
|
959
1361
|
CsrfTokenMiddleware,
|
|
960
1362
|
DevToolsModule,
|
|
961
1363
|
DevToolsV2Module,
|
|
1364
|
+
FileService,
|
|
962
1365
|
PlatformModule,
|
|
963
1366
|
UserContextMiddleware,
|
|
964
1367
|
ViewContextMiddleware,
|
|
@@ -967,5 +1370,6 @@ var import_nestjs_common5 = require("@lark-apaas/nestjs-common");
|
|
|
967
1370
|
...require("@lark-apaas/nestjs-capability"),
|
|
968
1371
|
...require("@lark-apaas/nestjs-datapaas"),
|
|
969
1372
|
...require("@lark-apaas/nestjs-observable"),
|
|
970
|
-
...require("@lark-apaas/nestjs-trigger")
|
|
1373
|
+
...require("@lark-apaas/nestjs-trigger"),
|
|
1374
|
+
...require("@lark-apaas/file-service")
|
|
971
1375
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -3,8 +3,11 @@ import { HttpClientConfig, PlatformPluginOptions } from '@lark-apaas/http-client
|
|
|
3
3
|
import { NestExpressApplication } from '@nestjs/platform-express';
|
|
4
4
|
export { DevToolsModule, DevToolsOptions, DevToolsV2Module, DevToolsV2Options } from '@lark-apaas/nestjs-openapi-devtools';
|
|
5
5
|
import { Request, Response, NextFunction } from 'express';
|
|
6
|
-
import { PlatformHttpClient } from '@lark-apaas/nestjs-common';
|
|
6
|
+
import { PlatformHttpClient, RequestContextService, ObservableService } from '@lark-apaas/nestjs-common';
|
|
7
7
|
export { AutoTrace } from '@lark-apaas/nestjs-common';
|
|
8
|
+
import * as _lark_apaas_file_service from '@lark-apaas/file-service';
|
|
9
|
+
import { FileBody, UploadOptions, FileDownloadBuilder, SearchOptions } from '@lark-apaas/file-service';
|
|
10
|
+
export * from '@lark-apaas/file-service';
|
|
8
11
|
export * from '@lark-apaas/nestjs-authnpaas';
|
|
9
12
|
export * from '@lark-apaas/nestjs-capability';
|
|
10
13
|
export * from '@lark-apaas/nestjs-datapaas';
|
|
@@ -135,4 +138,33 @@ interface ApiNotFoundResponse {
|
|
|
135
138
|
timestamp: string;
|
|
136
139
|
}
|
|
137
140
|
|
|
138
|
-
|
|
141
|
+
type BucketScopedFileService = Pick<FileService, 'upload' | 'download' | 'list' | 'remove' | 'createSignedUrl' | 'getFileMetadata'>;
|
|
142
|
+
declare class FileService {
|
|
143
|
+
private readonly requestContextService;
|
|
144
|
+
private readonly httpClient;
|
|
145
|
+
private readonly observable;
|
|
146
|
+
private readonly fileServiceCore;
|
|
147
|
+
private readonly nestLogger;
|
|
148
|
+
constructor(requestContextService: RequestContextService, httpClient: PlatformHttpClient, observable: ObservableService);
|
|
149
|
+
/**
|
|
150
|
+
* 返回一个绑定了指定 bucket 的代理对象
|
|
151
|
+
* 不会修改 context,避免副作用
|
|
152
|
+
*/
|
|
153
|
+
from(bucket: string): BucketScopedFileService;
|
|
154
|
+
upload(file: FileBody, options?: UploadOptions): Promise<_lark_apaas_file_service.FileMeta>;
|
|
155
|
+
download(path: string): FileDownloadBuilder;
|
|
156
|
+
list(prefix: string, searchOptions?: SearchOptions): Promise<_lark_apaas_file_service.ListResponse>;
|
|
157
|
+
remove(filePaths: string[]): Promise<_lark_apaas_file_service.FileMeta[]>;
|
|
158
|
+
createSignedUrl(path: string, expiresIn: number): Promise<string>;
|
|
159
|
+
getFileMetadata(filePath: string): Promise<_lark_apaas_file_service.FileMeta | null>;
|
|
160
|
+
getDefaultBucket(): Promise<string>;
|
|
161
|
+
private getAppId;
|
|
162
|
+
private _upload;
|
|
163
|
+
private _download;
|
|
164
|
+
private _list;
|
|
165
|
+
private _remove;
|
|
166
|
+
private _createSignedUrl;
|
|
167
|
+
private _getFileMetadata;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export { type ApiNotFoundResponse, CsrfMiddleware, CsrfTokenMiddleware, FileService, type PlatformHttpClientOptions, PlatformModule, type PlatformModuleOptions, UserContextMiddleware, ViewContextMiddleware, configureApp };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,8 +3,11 @@ import { HttpClientConfig, PlatformPluginOptions } from '@lark-apaas/http-client
|
|
|
3
3
|
import { NestExpressApplication } from '@nestjs/platform-express';
|
|
4
4
|
export { DevToolsModule, DevToolsOptions, DevToolsV2Module, DevToolsV2Options } from '@lark-apaas/nestjs-openapi-devtools';
|
|
5
5
|
import { Request, Response, NextFunction } from 'express';
|
|
6
|
-
import { PlatformHttpClient } from '@lark-apaas/nestjs-common';
|
|
6
|
+
import { PlatformHttpClient, RequestContextService, ObservableService } from '@lark-apaas/nestjs-common';
|
|
7
7
|
export { AutoTrace } from '@lark-apaas/nestjs-common';
|
|
8
|
+
import * as _lark_apaas_file_service from '@lark-apaas/file-service';
|
|
9
|
+
import { FileBody, UploadOptions, FileDownloadBuilder, SearchOptions } from '@lark-apaas/file-service';
|
|
10
|
+
export * from '@lark-apaas/file-service';
|
|
8
11
|
export * from '@lark-apaas/nestjs-authnpaas';
|
|
9
12
|
export * from '@lark-apaas/nestjs-capability';
|
|
10
13
|
export * from '@lark-apaas/nestjs-datapaas';
|
|
@@ -135,4 +138,33 @@ interface ApiNotFoundResponse {
|
|
|
135
138
|
timestamp: string;
|
|
136
139
|
}
|
|
137
140
|
|
|
138
|
-
|
|
141
|
+
type BucketScopedFileService = Pick<FileService, 'upload' | 'download' | 'list' | 'remove' | 'createSignedUrl' | 'getFileMetadata'>;
|
|
142
|
+
declare class FileService {
|
|
143
|
+
private readonly requestContextService;
|
|
144
|
+
private readonly httpClient;
|
|
145
|
+
private readonly observable;
|
|
146
|
+
private readonly fileServiceCore;
|
|
147
|
+
private readonly nestLogger;
|
|
148
|
+
constructor(requestContextService: RequestContextService, httpClient: PlatformHttpClient, observable: ObservableService);
|
|
149
|
+
/**
|
|
150
|
+
* 返回一个绑定了指定 bucket 的代理对象
|
|
151
|
+
* 不会修改 context,避免副作用
|
|
152
|
+
*/
|
|
153
|
+
from(bucket: string): BucketScopedFileService;
|
|
154
|
+
upload(file: FileBody, options?: UploadOptions): Promise<_lark_apaas_file_service.FileMeta>;
|
|
155
|
+
download(path: string): FileDownloadBuilder;
|
|
156
|
+
list(prefix: string, searchOptions?: SearchOptions): Promise<_lark_apaas_file_service.ListResponse>;
|
|
157
|
+
remove(filePaths: string[]): Promise<_lark_apaas_file_service.FileMeta[]>;
|
|
158
|
+
createSignedUrl(path: string, expiresIn: number): Promise<string>;
|
|
159
|
+
getFileMetadata(filePath: string): Promise<_lark_apaas_file_service.FileMeta | null>;
|
|
160
|
+
getDefaultBucket(): Promise<string>;
|
|
161
|
+
private getAppId;
|
|
162
|
+
private _upload;
|
|
163
|
+
private _download;
|
|
164
|
+
private _list;
|
|
165
|
+
private _remove;
|
|
166
|
+
private _createSignedUrl;
|
|
167
|
+
private _getFileMetadata;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export { type ApiNotFoundResponse, CsrfMiddleware, CsrfTokenMiddleware, FileService, type PlatformHttpClientOptions, PlatformModule, type PlatformModuleOptions, UserContextMiddleware, ViewContextMiddleware, configureApp };
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
4
4
|
// src/modules/platform/module.ts
|
|
5
5
|
import { Global, Module, ValidationPipe } from "@nestjs/common";
|
|
6
6
|
import { APP_INTERCEPTOR, APP_PIPE } from "@nestjs/core";
|
|
7
|
-
import { CommonModule, OBSERVABLE_SERVICE } from "@lark-apaas/nestjs-common";
|
|
7
|
+
import { CommonModule, OBSERVABLE_SERVICE as OBSERVABLE_SERVICE2 } from "@lark-apaas/nestjs-common";
|
|
8
8
|
import { ConfigModule, ConfigService } from "@nestjs/config";
|
|
9
9
|
import { NestjsObservableModule as ObservableModule, Observable, ObservableTraceMiddleware, TraceInterceptor } from "@lark-apaas/nestjs-observable";
|
|
10
10
|
import { HttpModule } from "@nestjs/axios";
|
|
@@ -12,7 +12,7 @@ import { LoggerModule, AppLogger as AppLogger2, LoggerContextMiddleware } from "
|
|
|
12
12
|
import { DataPaasModule, SqlExecutionContextMiddleware } from "@lark-apaas/nestjs-datapaas";
|
|
13
13
|
import { AuthNPaasModule } from "@lark-apaas/nestjs-authnpaas";
|
|
14
14
|
import { AutomationModule } from "@lark-apaas/nestjs-trigger";
|
|
15
|
-
import { PLATFORM_HTTP_CLIENT as
|
|
15
|
+
import { PLATFORM_HTTP_CLIENT as PLATFORM_HTTP_CLIENT3 } from "@lark-apaas/nestjs-common";
|
|
16
16
|
import { CapabilityModule } from "@lark-apaas/nestjs-capability";
|
|
17
17
|
|
|
18
18
|
// src/middlewares/user-context/index.ts
|
|
@@ -224,6 +224,7 @@ var ViewContextMiddleware = class _ViewContextMiddleware {
|
|
|
224
224
|
const { userId, tenantId, appId } = req.userContext;
|
|
225
225
|
const csrfToken = req.csrfToken;
|
|
226
226
|
const appInfo = await this.getAppInfo(appId);
|
|
227
|
+
const environment = mapToWindowEnvironment(process.env.FORCE_FRAMEWORK_ENVIRONMENT);
|
|
227
228
|
req.__platform_data__ = {
|
|
228
229
|
csrfToken: csrfToken ?? "",
|
|
229
230
|
userId: userId ?? "",
|
|
@@ -231,7 +232,8 @@ var ViewContextMiddleware = class _ViewContextMiddleware {
|
|
|
231
232
|
appName: safeEscape(appInfo?.app_name ?? "\u5999\u642D\u5E94\u7528"),
|
|
232
233
|
appAvatar: appInfo?.app_avatar ?? "",
|
|
233
234
|
appDescription: safeEscape(appInfo?.app_description ?? ""),
|
|
234
|
-
tenantId
|
|
235
|
+
tenantId,
|
|
236
|
+
environment
|
|
235
237
|
};
|
|
236
238
|
res.locals = {
|
|
237
239
|
...res.locals ?? {},
|
|
@@ -241,7 +243,8 @@ var ViewContextMiddleware = class _ViewContextMiddleware {
|
|
|
241
243
|
appId: appId ?? "",
|
|
242
244
|
appName: safeEscape(appInfo?.app_name ?? "\u5999\u642D\u5E94\u7528"),
|
|
243
245
|
appAvatar: appInfo?.app_avatar ?? "",
|
|
244
|
-
appDescription: safeEscape(appInfo?.app_description ?? "")
|
|
246
|
+
appDescription: safeEscape(appInfo?.app_description ?? ""),
|
|
247
|
+
environment
|
|
245
248
|
};
|
|
246
249
|
next();
|
|
247
250
|
}
|
|
@@ -254,6 +257,14 @@ ViewContextMiddleware = _ts_decorate3([
|
|
|
254
257
|
typeof PlatformHttpClient === "undefined" ? Object : PlatformHttpClient
|
|
255
258
|
])
|
|
256
259
|
], ViewContextMiddleware);
|
|
260
|
+
function mapToWindowEnvironment(input) {
|
|
261
|
+
const value = (input || "").trim().toLowerCase();
|
|
262
|
+
if (value === "boe") return "staging";
|
|
263
|
+
if (value === "pre") return "gray";
|
|
264
|
+
if (value === "online") return "online";
|
|
265
|
+
return "online";
|
|
266
|
+
}
|
|
267
|
+
__name(mapToWindowEnvironment, "mapToWindowEnvironment");
|
|
257
268
|
|
|
258
269
|
// src/middlewares/csrf_token/index.ts
|
|
259
270
|
import { Injectable as Injectable4 } from "@nestjs/common";
|
|
@@ -726,7 +737,10 @@ PlatformHttpClientService = _ts_decorate8([
|
|
|
726
737
|
// src/modules/platform/config/feature-switch.ts
|
|
727
738
|
var DISABLE_DATAPASS = process.env.FORCE_FRAMEWORK_DISABLE_DATAPASS === "true";
|
|
728
739
|
|
|
729
|
-
// src/
|
|
740
|
+
// src/services/file.service.ts
|
|
741
|
+
import { Injectable as Injectable9, Inject as Inject2, Logger as Logger3 } from "@nestjs/common";
|
|
742
|
+
import { ObservableService, RequestContextService as RequestContextService2, PLATFORM_HTTP_CLIENT as PLATFORM_HTTP_CLIENT2, OBSERVABLE_SERVICE } from "@lark-apaas/nestjs-common";
|
|
743
|
+
import { FileService as FileServiceCore, FileDownloadBuilder } from "@lark-apaas/file-service";
|
|
730
744
|
function _ts_decorate9(decorators, target, key, desc) {
|
|
731
745
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
732
746
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -734,6 +748,390 @@ function _ts_decorate9(decorators, target, key, desc) {
|
|
|
734
748
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
735
749
|
}
|
|
736
750
|
__name(_ts_decorate9, "_ts_decorate");
|
|
751
|
+
function _ts_metadata6(k, v) {
|
|
752
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
753
|
+
}
|
|
754
|
+
__name(_ts_metadata6, "_ts_metadata");
|
|
755
|
+
function _ts_param2(paramIndex, decorator) {
|
|
756
|
+
return function(target, key) {
|
|
757
|
+
decorator(target, key, paramIndex);
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
__name(_ts_param2, "_ts_param");
|
|
761
|
+
var FileService = class {
|
|
762
|
+
static {
|
|
763
|
+
__name(this, "FileService");
|
|
764
|
+
}
|
|
765
|
+
requestContextService;
|
|
766
|
+
httpClient;
|
|
767
|
+
observable;
|
|
768
|
+
fileServiceCore;
|
|
769
|
+
nestLogger;
|
|
770
|
+
constructor(requestContextService, httpClient, observable) {
|
|
771
|
+
this.requestContextService = requestContextService;
|
|
772
|
+
this.httpClient = httpClient;
|
|
773
|
+
this.observable = observable;
|
|
774
|
+
this.fileServiceCore = new FileServiceCore(this.httpClient);
|
|
775
|
+
this.nestLogger = new Logger3("file");
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* 返回一个绑定了指定 bucket 的代理对象
|
|
779
|
+
* 不会修改 context,避免副作用
|
|
780
|
+
*/
|
|
781
|
+
from(bucket) {
|
|
782
|
+
return {
|
|
783
|
+
upload: /* @__PURE__ */ __name((file, options) => this._upload(bucket, file, options), "upload"),
|
|
784
|
+
download: /* @__PURE__ */ __name((path) => this._download(bucket, path), "download"),
|
|
785
|
+
list: /* @__PURE__ */ __name((prefix, searchOptions) => this._list(bucket, prefix, searchOptions), "list"),
|
|
786
|
+
remove: /* @__PURE__ */ __name((filePaths) => this._remove(bucket, filePaths), "remove"),
|
|
787
|
+
createSignedUrl: /* @__PURE__ */ __name((path, expiresIn) => this._createSignedUrl(bucket, path, expiresIn), "createSignedUrl"),
|
|
788
|
+
getFileMetadata: /* @__PURE__ */ __name((filePath) => this._getFileMetadata(bucket, filePath), "getFileMetadata")
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
// ============ 公开方法(使用默认 bucket)============
|
|
792
|
+
async upload(file, options) {
|
|
793
|
+
return this._upload(await this.getDefaultBucket(), file, options);
|
|
794
|
+
}
|
|
795
|
+
download(path) {
|
|
796
|
+
const capturedBucketPromise = this.getDefaultBucket();
|
|
797
|
+
return this._download(capturedBucketPromise, path);
|
|
798
|
+
}
|
|
799
|
+
async list(prefix, searchOptions) {
|
|
800
|
+
return this._list(await this.getDefaultBucket(), prefix, searchOptions);
|
|
801
|
+
}
|
|
802
|
+
async remove(filePaths) {
|
|
803
|
+
return this._remove(await this.getDefaultBucket(), filePaths);
|
|
804
|
+
}
|
|
805
|
+
async createSignedUrl(path, expiresIn) {
|
|
806
|
+
return this._createSignedUrl(await this.getDefaultBucket(), path, expiresIn);
|
|
807
|
+
}
|
|
808
|
+
async getFileMetadata(filePath) {
|
|
809
|
+
return this._getFileMetadata(await this.getDefaultBucket(), filePath);
|
|
810
|
+
}
|
|
811
|
+
async getDefaultBucket() {
|
|
812
|
+
const reqContext = this.requestContextService.getContext();
|
|
813
|
+
const bucketFromContext = reqContext?.bucket;
|
|
814
|
+
if (bucketFromContext) {
|
|
815
|
+
return bucketFromContext;
|
|
816
|
+
}
|
|
817
|
+
const appId = this.getAppId();
|
|
818
|
+
const bucket = await this.fileServiceCore.getDefaultBucket(appId);
|
|
819
|
+
return bucket;
|
|
820
|
+
}
|
|
821
|
+
getAppId() {
|
|
822
|
+
const requestCtx = this.requestContextService.getContext();
|
|
823
|
+
return requestCtx?.appId ?? "";
|
|
824
|
+
}
|
|
825
|
+
// ============ 核心实现方法(接受 bucket 参数)============
|
|
826
|
+
async _upload(bucket, file, options) {
|
|
827
|
+
const span = this.observable.startTrace("\u6587\u4EF6: upload", this.requestContextService.getContext()?.requestRootSpan);
|
|
828
|
+
span.setAttribute("module", "file");
|
|
829
|
+
span.setAttribute("source_type", "platform");
|
|
830
|
+
const spanContext = {
|
|
831
|
+
traceId: span.spanContext().traceId,
|
|
832
|
+
spanId: span.spanContext().spanId
|
|
833
|
+
};
|
|
834
|
+
const logContext = {
|
|
835
|
+
source_type: "platform",
|
|
836
|
+
paas_attributes_module: "file",
|
|
837
|
+
paas_parent_span_context: spanContext
|
|
838
|
+
};
|
|
839
|
+
const baseParams = {
|
|
840
|
+
method: "upload",
|
|
841
|
+
source_type: "server",
|
|
842
|
+
request: {
|
|
843
|
+
options
|
|
844
|
+
}
|
|
845
|
+
};
|
|
846
|
+
const startTime = Date.now();
|
|
847
|
+
try {
|
|
848
|
+
const res = await this.fileServiceCore.upload({
|
|
849
|
+
appId: this.getAppId(),
|
|
850
|
+
bucketId: await bucket,
|
|
851
|
+
fileBody: file,
|
|
852
|
+
options
|
|
853
|
+
});
|
|
854
|
+
this.nestLogger.log(JSON.stringify({
|
|
855
|
+
...baseParams,
|
|
856
|
+
response: res,
|
|
857
|
+
status: "succeed",
|
|
858
|
+
duration_ms: Date.now() - startTime
|
|
859
|
+
}), logContext);
|
|
860
|
+
return res;
|
|
861
|
+
} catch (e) {
|
|
862
|
+
this.nestLogger.error(JSON.stringify({
|
|
863
|
+
...baseParams,
|
|
864
|
+
error_message: e instanceof Error ? e.message : String(e),
|
|
865
|
+
status: "failed",
|
|
866
|
+
duration_ms: Date.now() - startTime
|
|
867
|
+
}), logContext);
|
|
868
|
+
throw e;
|
|
869
|
+
} finally {
|
|
870
|
+
span.end();
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
_download(bucket, path) {
|
|
874
|
+
const capturedAppId = this.getAppId();
|
|
875
|
+
const capturedRootSpan = this.requestContextService.getContext()?.requestRootSpan;
|
|
876
|
+
const downloadFn = /* @__PURE__ */ __name(async () => {
|
|
877
|
+
const span = this.observable.startTrace("\u6587\u4EF6: download", capturedRootSpan);
|
|
878
|
+
span.setAttribute("module", "file");
|
|
879
|
+
span.setAttribute("source_type", "platform");
|
|
880
|
+
const spanContext = {
|
|
881
|
+
traceId: span.spanContext().traceId,
|
|
882
|
+
spanId: span.spanContext().spanId
|
|
883
|
+
};
|
|
884
|
+
const logContext = {
|
|
885
|
+
source_type: "platform",
|
|
886
|
+
paas_attributes_module: "file",
|
|
887
|
+
paas_parent_span_context: spanContext
|
|
888
|
+
};
|
|
889
|
+
const baseParams = {
|
|
890
|
+
method: "download",
|
|
891
|
+
source_type: "server",
|
|
892
|
+
request: {
|
|
893
|
+
path
|
|
894
|
+
}
|
|
895
|
+
};
|
|
896
|
+
const startTime = Date.now();
|
|
897
|
+
try {
|
|
898
|
+
const res = await this.fileServiceCore.downloadInner({
|
|
899
|
+
appId: capturedAppId,
|
|
900
|
+
bucketId: await bucket,
|
|
901
|
+
filePath: path
|
|
902
|
+
});
|
|
903
|
+
this.nestLogger.log(JSON.stringify({
|
|
904
|
+
...baseParams,
|
|
905
|
+
response: {
|
|
906
|
+
metadata: res.metadata
|
|
907
|
+
},
|
|
908
|
+
status: "succeed",
|
|
909
|
+
duration_ms: Date.now() - startTime
|
|
910
|
+
}), logContext);
|
|
911
|
+
return res;
|
|
912
|
+
} catch (e) {
|
|
913
|
+
this.nestLogger.error(JSON.stringify({
|
|
914
|
+
...baseParams,
|
|
915
|
+
error_message: e instanceof Error ? e.message : String(e),
|
|
916
|
+
status: "failed",
|
|
917
|
+
duration_ms: Date.now() - startTime
|
|
918
|
+
}), logContext);
|
|
919
|
+
throw e;
|
|
920
|
+
} finally {
|
|
921
|
+
span.end();
|
|
922
|
+
}
|
|
923
|
+
}, "downloadFn");
|
|
924
|
+
return new FileDownloadBuilder(downloadFn);
|
|
925
|
+
}
|
|
926
|
+
async _list(bucket, prefix, searchOptions) {
|
|
927
|
+
const span = this.observable.startTrace("\u6587\u4EF6: list", this.requestContextService.getContext()?.requestRootSpan);
|
|
928
|
+
span.setAttribute("module", "file");
|
|
929
|
+
span.setAttribute("source_type", "platform");
|
|
930
|
+
const spanContext = {
|
|
931
|
+
traceId: span.spanContext().traceId,
|
|
932
|
+
spanId: span.spanContext().spanId
|
|
933
|
+
};
|
|
934
|
+
const logContext = {
|
|
935
|
+
source_type: "platform",
|
|
936
|
+
paas_attributes_module: "file",
|
|
937
|
+
paas_parent_span_context: spanContext
|
|
938
|
+
};
|
|
939
|
+
const baseParams = {
|
|
940
|
+
method: "list",
|
|
941
|
+
source_type: "server",
|
|
942
|
+
request: {
|
|
943
|
+
prefix,
|
|
944
|
+
searchOptions
|
|
945
|
+
}
|
|
946
|
+
};
|
|
947
|
+
const startTime = Date.now();
|
|
948
|
+
try {
|
|
949
|
+
const res = await this.fileServiceCore.list({
|
|
950
|
+
appId: this.getAppId(),
|
|
951
|
+
bucketId: await bucket,
|
|
952
|
+
prefix,
|
|
953
|
+
searchOptions
|
|
954
|
+
});
|
|
955
|
+
this.nestLogger.log(JSON.stringify({
|
|
956
|
+
...baseParams,
|
|
957
|
+
response: res,
|
|
958
|
+
status: "succeed",
|
|
959
|
+
duration_ms: Date.now() - startTime
|
|
960
|
+
}), logContext);
|
|
961
|
+
return res;
|
|
962
|
+
} catch (e) {
|
|
963
|
+
this.nestLogger.error(JSON.stringify({
|
|
964
|
+
...baseParams,
|
|
965
|
+
error_message: e instanceof Error ? e.message : String(e),
|
|
966
|
+
status: "failed",
|
|
967
|
+
duration_ms: Date.now() - startTime
|
|
968
|
+
}), logContext);
|
|
969
|
+
throw e;
|
|
970
|
+
} finally {
|
|
971
|
+
span.end();
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
async _remove(bucket, filePaths) {
|
|
975
|
+
const span = this.observable.startTrace("\u6587\u4EF6: remove", this.requestContextService.getContext()?.requestRootSpan);
|
|
976
|
+
span.setAttribute("module", "file");
|
|
977
|
+
span.setAttribute("source_type", "platform");
|
|
978
|
+
const spanContext = {
|
|
979
|
+
traceId: span.spanContext().traceId,
|
|
980
|
+
spanId: span.spanContext().spanId
|
|
981
|
+
};
|
|
982
|
+
const logContext = {
|
|
983
|
+
source_type: "platform",
|
|
984
|
+
paas_attributes_module: "file",
|
|
985
|
+
paas_parent_span_context: spanContext
|
|
986
|
+
};
|
|
987
|
+
const baseParams = {
|
|
988
|
+
method: "remove",
|
|
989
|
+
source_type: "server",
|
|
990
|
+
request: {
|
|
991
|
+
filePaths
|
|
992
|
+
}
|
|
993
|
+
};
|
|
994
|
+
const startTime = Date.now();
|
|
995
|
+
try {
|
|
996
|
+
const res = await this.fileServiceCore.remove({
|
|
997
|
+
appId: this.getAppId(),
|
|
998
|
+
bucketId: await bucket,
|
|
999
|
+
filePaths
|
|
1000
|
+
});
|
|
1001
|
+
this.nestLogger.log(JSON.stringify({
|
|
1002
|
+
...baseParams,
|
|
1003
|
+
response: res,
|
|
1004
|
+
status: "succeed",
|
|
1005
|
+
duration_ms: Date.now() - startTime
|
|
1006
|
+
}), logContext);
|
|
1007
|
+
return res;
|
|
1008
|
+
} catch (e) {
|
|
1009
|
+
this.nestLogger.error(JSON.stringify({
|
|
1010
|
+
...baseParams,
|
|
1011
|
+
error_message: e instanceof Error ? e.message : String(e),
|
|
1012
|
+
status: "failed",
|
|
1013
|
+
duration_ms: Date.now() - startTime
|
|
1014
|
+
}), logContext);
|
|
1015
|
+
throw e;
|
|
1016
|
+
} finally {
|
|
1017
|
+
span.end();
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
async _createSignedUrl(bucket, path, expiresIn) {
|
|
1021
|
+
const span = this.observable.startTrace("\u6587\u4EF6: createSignedUrl", this.requestContextService.getContext()?.requestRootSpan);
|
|
1022
|
+
span.setAttribute("module", "file");
|
|
1023
|
+
span.setAttribute("source_type", "platform");
|
|
1024
|
+
const spanContext = {
|
|
1025
|
+
traceId: span.spanContext().traceId,
|
|
1026
|
+
spanId: span.spanContext().spanId
|
|
1027
|
+
};
|
|
1028
|
+
const logContext = {
|
|
1029
|
+
source_type: "platform",
|
|
1030
|
+
paas_attributes_module: "file",
|
|
1031
|
+
paas_parent_span_context: spanContext
|
|
1032
|
+
};
|
|
1033
|
+
const baseParams = {
|
|
1034
|
+
method: "createSignedUrl",
|
|
1035
|
+
source_type: "server",
|
|
1036
|
+
request: {
|
|
1037
|
+
path,
|
|
1038
|
+
expiresIn
|
|
1039
|
+
}
|
|
1040
|
+
};
|
|
1041
|
+
const startTime = Date.now();
|
|
1042
|
+
try {
|
|
1043
|
+
const res = await this.fileServiceCore.createSignedUrl({
|
|
1044
|
+
appId: this.getAppId(),
|
|
1045
|
+
bucketId: await bucket,
|
|
1046
|
+
filePath: path,
|
|
1047
|
+
expiresIn
|
|
1048
|
+
});
|
|
1049
|
+
this.nestLogger.log(JSON.stringify({
|
|
1050
|
+
...baseParams,
|
|
1051
|
+
response: res,
|
|
1052
|
+
status: "succeed",
|
|
1053
|
+
duration_ms: Date.now() - startTime
|
|
1054
|
+
}), logContext);
|
|
1055
|
+
return res;
|
|
1056
|
+
} catch (e) {
|
|
1057
|
+
this.nestLogger.error(JSON.stringify({
|
|
1058
|
+
...baseParams,
|
|
1059
|
+
error_message: e instanceof Error ? e.message : String(e),
|
|
1060
|
+
status: "failed",
|
|
1061
|
+
duration_ms: Date.now() - startTime
|
|
1062
|
+
}), logContext);
|
|
1063
|
+
throw e;
|
|
1064
|
+
} finally {
|
|
1065
|
+
span.end();
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
async _getFileMetadata(bucket, filePath) {
|
|
1069
|
+
const span = this.observable.startTrace("\u6587\u4EF6: getFileMetadata", this.requestContextService.getContext()?.requestRootSpan);
|
|
1070
|
+
span.setAttribute("module", "file");
|
|
1071
|
+
span.setAttribute("source_type", "platform");
|
|
1072
|
+
const spanContext = {
|
|
1073
|
+
traceId: span.spanContext().traceId,
|
|
1074
|
+
spanId: span.spanContext().spanId
|
|
1075
|
+
};
|
|
1076
|
+
const logContext = {
|
|
1077
|
+
source_type: "platform",
|
|
1078
|
+
paas_attributes_module: "file",
|
|
1079
|
+
paas_parent_span_context: spanContext
|
|
1080
|
+
};
|
|
1081
|
+
const baseParams = {
|
|
1082
|
+
method: "getFileMetadata",
|
|
1083
|
+
source_type: "server",
|
|
1084
|
+
request: {
|
|
1085
|
+
filePath
|
|
1086
|
+
}
|
|
1087
|
+
};
|
|
1088
|
+
const startTime = Date.now();
|
|
1089
|
+
try {
|
|
1090
|
+
const res = await this.fileServiceCore.getFileMetadata({
|
|
1091
|
+
appId: this.getAppId(),
|
|
1092
|
+
bucketId: await bucket,
|
|
1093
|
+
filePath
|
|
1094
|
+
});
|
|
1095
|
+
this.nestLogger.log(JSON.stringify({
|
|
1096
|
+
...baseParams,
|
|
1097
|
+
response: res,
|
|
1098
|
+
status: "succeed",
|
|
1099
|
+
duration_ms: Date.now() - startTime
|
|
1100
|
+
}), logContext);
|
|
1101
|
+
return res;
|
|
1102
|
+
} catch (e) {
|
|
1103
|
+
this.nestLogger.error(JSON.stringify({
|
|
1104
|
+
...baseParams,
|
|
1105
|
+
error_message: e instanceof Error ? e.message : String(e),
|
|
1106
|
+
status: "failed",
|
|
1107
|
+
duration_ms: Date.now() - startTime
|
|
1108
|
+
}), logContext);
|
|
1109
|
+
throw e;
|
|
1110
|
+
} finally {
|
|
1111
|
+
span.end();
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
};
|
|
1115
|
+
FileService = _ts_decorate9([
|
|
1116
|
+
Injectable9(),
|
|
1117
|
+
_ts_param2(1, Inject2(PLATFORM_HTTP_CLIENT2)),
|
|
1118
|
+
_ts_param2(2, Inject2(OBSERVABLE_SERVICE)),
|
|
1119
|
+
_ts_metadata6("design:type", Function),
|
|
1120
|
+
_ts_metadata6("design:paramtypes", [
|
|
1121
|
+
typeof RequestContextService2 === "undefined" ? Object : RequestContextService2,
|
|
1122
|
+
typeof PlatformHttpClient === "undefined" ? Object : PlatformHttpClient,
|
|
1123
|
+
typeof ObservableService === "undefined" ? Object : ObservableService
|
|
1124
|
+
])
|
|
1125
|
+
], FileService);
|
|
1126
|
+
|
|
1127
|
+
// src/modules/platform/module.ts
|
|
1128
|
+
function _ts_decorate10(decorators, target, key, desc) {
|
|
1129
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1130
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1131
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
1132
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
1133
|
+
}
|
|
1134
|
+
__name(_ts_decorate10, "_ts_decorate");
|
|
737
1135
|
var PLATFORM_MODULE_OPTIONS = /* @__PURE__ */ Symbol("PLATFORM_MODULE_OPTIONS");
|
|
738
1136
|
var PlatformModule = class _PlatformModule {
|
|
739
1137
|
static {
|
|
@@ -815,12 +1213,12 @@ var PlatformModule = class _PlatformModule {
|
|
|
815
1213
|
})
|
|
816
1214
|
},
|
|
817
1215
|
{
|
|
818
|
-
provide:
|
|
1216
|
+
provide: OBSERVABLE_SERVICE2,
|
|
819
1217
|
useClass: Observable
|
|
820
1218
|
},
|
|
821
1219
|
PlatformHttpClientService,
|
|
822
1220
|
{
|
|
823
|
-
provide:
|
|
1221
|
+
provide: PLATFORM_HTTP_CLIENT3,
|
|
824
1222
|
useFactory: /* @__PURE__ */ __name((svc) => svc.instance, "useFactory"),
|
|
825
1223
|
inject: [
|
|
826
1224
|
PlatformHttpClientService
|
|
@@ -830,15 +1228,17 @@ var PlatformModule = class _PlatformModule {
|
|
|
830
1228
|
{
|
|
831
1229
|
provide: APP_INTERCEPTOR,
|
|
832
1230
|
useClass: TraceInterceptor
|
|
833
|
-
}
|
|
1231
|
+
},
|
|
1232
|
+
FileService
|
|
834
1233
|
],
|
|
835
1234
|
exports: [
|
|
836
1235
|
ConfigModule,
|
|
837
1236
|
LoggerModule,
|
|
838
1237
|
CommonModule,
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
CapabilityModule
|
|
1238
|
+
OBSERVABLE_SERVICE2,
|
|
1239
|
+
PLATFORM_HTTP_CLIENT3,
|
|
1240
|
+
CapabilityModule,
|
|
1241
|
+
FileService
|
|
842
1242
|
]
|
|
843
1243
|
};
|
|
844
1244
|
}
|
|
@@ -867,7 +1267,7 @@ var PlatformModule = class _PlatformModule {
|
|
|
867
1267
|
}
|
|
868
1268
|
}
|
|
869
1269
|
};
|
|
870
|
-
PlatformModule =
|
|
1270
|
+
PlatformModule = _ts_decorate10([
|
|
871
1271
|
Global(),
|
|
872
1272
|
Module({})
|
|
873
1273
|
], PlatformModule);
|
|
@@ -908,6 +1308,7 @@ export * from "@lark-apaas/nestjs-capability";
|
|
|
908
1308
|
export * from "@lark-apaas/nestjs-datapaas";
|
|
909
1309
|
export * from "@lark-apaas/nestjs-observable";
|
|
910
1310
|
export * from "@lark-apaas/nestjs-trigger";
|
|
1311
|
+
export * from "@lark-apaas/file-service";
|
|
911
1312
|
import { AutoTrace } from "@lark-apaas/nestjs-common";
|
|
912
1313
|
export {
|
|
913
1314
|
AutoTrace,
|
|
@@ -915,6 +1316,7 @@ export {
|
|
|
915
1316
|
CsrfTokenMiddleware,
|
|
916
1317
|
DevToolsModule,
|
|
917
1318
|
DevToolsV2Module2 as DevToolsV2Module,
|
|
1319
|
+
FileService,
|
|
918
1320
|
PlatformModule,
|
|
919
1321
|
UserContextMiddleware,
|
|
920
1322
|
ViewContextMiddleware,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lark-apaas/fullstack-nestjs-core",
|
|
3
|
-
"version": "1.1.14-alpha.
|
|
3
|
+
"version": "1.1.14-alpha.6",
|
|
4
4
|
"description": "FullStack Nestjs Core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -39,15 +39,16 @@
|
|
|
39
39
|
"prepublishOnly": "npm run build"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
+
"@lark-apaas/file-service": "0.0.1-alpha.12",
|
|
42
43
|
"@lark-apaas/http-client": "^0.1.2",
|
|
43
44
|
"@lark-apaas/nestjs-authnpaas": "^1.0.2",
|
|
44
45
|
"@lark-apaas/nestjs-capability": "^0.1.2",
|
|
45
46
|
"@lark-apaas/nestjs-common": "^0.1.2",
|
|
46
|
-
"@lark-apaas/nestjs-datapaas": "^1.0.8-alpha.
|
|
47
|
-
"@lark-apaas/nestjs-logger": "1.0.9-alpha.
|
|
48
|
-
"@lark-apaas/nestjs-observable": "^0.0.4-alpha.
|
|
47
|
+
"@lark-apaas/nestjs-datapaas": "^1.0.8-alpha.15",
|
|
48
|
+
"@lark-apaas/nestjs-logger": "1.0.9-alpha.9",
|
|
49
|
+
"@lark-apaas/nestjs-observable": "^0.0.4-alpha.6",
|
|
49
50
|
"@lark-apaas/nestjs-openapi-devtools": "^1.0.9",
|
|
50
|
-
"@lark-apaas/nestjs-trigger": "
|
|
51
|
+
"@lark-apaas/nestjs-trigger": "0.0.2-alpha.3",
|
|
51
52
|
"@nestjs/axios": "^4.0.1",
|
|
52
53
|
"axios": "^1.13.2",
|
|
53
54
|
"cookie-parser": "^1.4.7"
|