@ruiapp/rapid-core 0.1.79 → 0.1.81
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.js +83 -42
- package/dist/plugins/dataManage/actionHandlers/deleteCollectionEntities.d.ts +8 -0
- package/package.json +1 -1
- package/rollup.config.js +16 -16
- package/src/core/actionHandler.ts +22 -22
- package/src/core/eventManager.ts +20 -20
- package/src/core/facility.ts +7 -7
- package/src/core/http/formDataParser.ts +89 -89
- package/src/core/pluginManager.ts +175 -175
- package/src/core/providers/runtimeProvider.ts +5 -5
- package/src/core/request.ts +86 -86
- package/src/core/response.ts +76 -76
- package/src/core/routeContext.ts +43 -43
- package/src/core/routesBuilder.ts +88 -88
- package/src/dataAccess/dataAccessor.ts +137 -137
- package/src/deno-std/datetime/to_imf.ts +32 -32
- package/src/deno-std/encoding/base64.ts +141 -141
- package/src/facilities/log/LogFacility.ts +35 -35
- package/src/helpers/entityHelpers.ts +76 -76
- package/src/plugins/auth/actionHandlers/changePassword.ts +54 -54
- package/src/plugins/auth/actionHandlers/createSession.ts +63 -63
- package/src/plugins/auth/actionHandlers/deleteSession.ts +18 -18
- package/src/plugins/auth/actionHandlers/getMyProfile.ts +35 -35
- package/src/plugins/auth/actionHandlers/index.ts +8 -8
- package/src/plugins/auth/actionHandlers/resetPassword.ts +38 -38
- package/src/plugins/auth/models/AccessToken.ts +56 -56
- package/src/plugins/auth/models/index.ts +3 -3
- package/src/plugins/auth/routes/changePassword.ts +15 -15
- package/src/plugins/auth/routes/getMyProfile.ts +15 -15
- package/src/plugins/auth/routes/index.ts +7 -7
- package/src/plugins/auth/routes/resetPassword.ts +15 -15
- package/src/plugins/auth/routes/signin.ts +15 -15
- package/src/plugins/auth/routes/signout.ts +15 -15
- package/src/plugins/cronJob/CronJobPluginTypes.ts +49 -49
- package/src/plugins/cronJob/actionHandlers/index.ts +4 -4
- package/src/plugins/cronJob/actionHandlers/runCronJob.ts +29 -29
- package/src/plugins/cronJob/routes/index.ts +3 -3
- package/src/plugins/cronJob/routes/runCronJob.ts +15 -15
- package/src/plugins/dataManage/DataManagePlugin.ts +8 -0
- package/src/plugins/dataManage/actionHandlers/addEntityRelations.ts +20 -20
- package/src/plugins/dataManage/actionHandlers/countCollectionEntities.ts +15 -15
- package/src/plugins/dataManage/actionHandlers/createCollectionEntitiesBatch.ts +42 -42
- package/src/plugins/dataManage/actionHandlers/createCollectionEntity.ts +24 -24
- package/src/plugins/dataManage/actionHandlers/deleteCollectionEntities.ts +38 -0
- package/src/plugins/dataManage/actionHandlers/findCollectionEntities.ts +26 -26
- package/src/plugins/dataManage/actionHandlers/findCollectionEntityById.ts +21 -21
- package/src/plugins/dataManage/actionHandlers/queryDatabase.ts +22 -22
- package/src/plugins/dataManage/actionHandlers/removeEntityRelations.ts +20 -20
- package/src/plugins/dataManage/actionHandlers/updateCollectionEntityById.ts +35 -35
- package/src/plugins/entityAccessControl/EntityAccessControlPlugin.ts +1 -1
- package/src/plugins/fileManage/actionHandlers/downloadDocument.ts +36 -36
- package/src/plugins/fileManage/actionHandlers/uploadFile.ts +33 -33
- package/src/plugins/fileManage/routes/downloadDocument.ts +15 -15
- package/src/plugins/fileManage/routes/downloadFile.ts +15 -15
- package/src/plugins/fileManage/routes/index.ts +5 -5
- package/src/plugins/fileManage/routes/uploadFile.ts +15 -15
- package/src/plugins/metaManage/actionHandlers/getMetaModelDetail.ts +10 -10
- package/src/plugins/metaManage/actionHandlers/listMetaModels.ts +9 -9
- package/src/plugins/metaManage/actionHandlers/listMetaRoutes.ts +9 -9
- package/src/plugins/routeManage/actionHandlers/httpProxy.ts +13 -13
- package/src/plugins/sequence/SequenceService.ts +81 -81
- package/src/plugins/sequence/actionHandlers/generateSn.ts +32 -32
- package/src/plugins/sequence/actionHandlers/index.ts +4 -4
- package/src/plugins/sequence/models/SequenceAutoIncrementRecord.ts +49 -49
- package/src/plugins/sequence/models/SequenceRule.ts +42 -42
- package/src/plugins/sequence/models/index.ts +4 -4
- package/src/plugins/sequence/routes/generateSn.ts +15 -15
- package/src/plugins/sequence/routes/index.ts +3 -3
- package/src/plugins/sequence/segment-utility.ts +11 -11
- package/src/plugins/sequence/segments/index.ts +9 -9
- package/src/plugins/serverOperation/ServerOperationPlugin.ts +91 -91
- package/src/plugins/serverOperation/ServerOperationPluginTypes.ts +15 -15
- package/src/plugins/serverOperation/actionHandlers/index.ts +4 -4
- package/src/plugins/setting/SettingService.ts +213 -213
- package/src/plugins/setting/actionHandlers/getSystemSettingValues.ts +30 -30
- package/src/plugins/setting/actionHandlers/getUserSettingValues.ts +38 -38
- package/src/plugins/setting/actionHandlers/index.ts +6 -6
- package/src/plugins/setting/actionHandlers/setSystemSettingValues.ts +30 -30
- package/src/plugins/setting/models/SystemSettingGroupSetting.ts +57 -57
- package/src/plugins/setting/models/SystemSettingItem.ts +42 -42
- package/src/plugins/setting/models/SystemSettingItemSetting.ts +73 -73
- package/src/plugins/setting/models/UserSettingGroupSetting.ts +57 -57
- package/src/plugins/setting/models/UserSettingItem.ts +49 -49
- package/src/plugins/setting/models/UserSettingItemSetting.ts +73 -73
- package/src/plugins/setting/models/index.ts +8 -8
- package/src/plugins/setting/routes/getSystemSettingValues.ts +15 -15
- package/src/plugins/setting/routes/getUserSettingValues.ts +15 -15
- package/src/plugins/setting/routes/index.ts +5 -5
- package/src/plugins/setting/routes/setSystemSettingValues.ts +15 -15
- package/src/plugins/stateMachine/actionHandlers/index.ts +4 -4
- package/src/plugins/stateMachine/actionHandlers/sendStateMachineEvent.ts +51 -51
- package/src/plugins/stateMachine/models/StateMachine.ts +42 -42
- package/src/plugins/stateMachine/models/index.ts +3 -3
- package/src/plugins/stateMachine/routes/index.ts +3 -3
- package/src/plugins/stateMachine/routes/sendStateMachineEvent.ts +15 -15
- package/src/polyfill.ts +5 -5
- package/src/proxy/mod.ts +38 -38
- package/src/queryBuilder/queryBuilder.ts +5 -1
- package/src/utilities/accessControlUtility.ts +33 -33
- package/src/utilities/fsUtility.ts +61 -61
- package/src/utilities/httpUtility.ts +19 -19
- package/src/utilities/jwtUtility.ts +26 -26
- package/src/utilities/timeUtility.ts +9 -9
- package/tsconfig.json +19 -19
package/dist/index.js
CHANGED
|
@@ -598,7 +598,12 @@ function buildInFilterQuery(ctx, filter) {
|
|
|
598
598
|
if (ctx.paramToLiteral) ;
|
|
599
599
|
else {
|
|
600
600
|
ctx.params.push(filter.value);
|
|
601
|
-
|
|
601
|
+
if (filter.operator === "in") {
|
|
602
|
+
command += `ANY($${ctx.params.length}::${filter.itemType || "int"}[])`;
|
|
603
|
+
}
|
|
604
|
+
else {
|
|
605
|
+
command += `ALL($${ctx.params.length}::${filter.itemType || "int"}[])`;
|
|
606
|
+
}
|
|
602
607
|
}
|
|
603
608
|
return command;
|
|
604
609
|
}
|
|
@@ -4006,32 +4011,32 @@ async function generateJwtSecretKey() {
|
|
|
4006
4011
|
return encode(exportedKey);
|
|
4007
4012
|
}
|
|
4008
4013
|
|
|
4009
|
-
const code$
|
|
4010
|
-
async function handler$
|
|
4014
|
+
const code$t = "listMetaModels";
|
|
4015
|
+
async function handler$t(plugin, ctx, options) {
|
|
4011
4016
|
const { applicationConfig } = ctx;
|
|
4012
4017
|
ctx.output = { list: applicationConfig.models };
|
|
4013
4018
|
}
|
|
4014
4019
|
|
|
4015
4020
|
var listMetaModels = /*#__PURE__*/Object.freeze({
|
|
4016
4021
|
__proto__: null,
|
|
4017
|
-
code: code$
|
|
4018
|
-
handler: handler$
|
|
4022
|
+
code: code$t,
|
|
4023
|
+
handler: handler$t
|
|
4019
4024
|
});
|
|
4020
4025
|
|
|
4021
|
-
const code$
|
|
4022
|
-
async function handler$
|
|
4026
|
+
const code$s = "listMetaRoutes";
|
|
4027
|
+
async function handler$s(plugin, ctx, options) {
|
|
4023
4028
|
const { applicationConfig } = ctx;
|
|
4024
4029
|
ctx.output = { list: applicationConfig.routes };
|
|
4025
4030
|
}
|
|
4026
4031
|
|
|
4027
4032
|
var listMetaRoutes = /*#__PURE__*/Object.freeze({
|
|
4028
4033
|
__proto__: null,
|
|
4029
|
-
code: code$
|
|
4030
|
-
handler: handler$
|
|
4034
|
+
code: code$s,
|
|
4035
|
+
handler: handler$s
|
|
4031
4036
|
});
|
|
4032
4037
|
|
|
4033
|
-
const code$
|
|
4034
|
-
async function handler$
|
|
4038
|
+
const code$r = "getMetaModelDetail";
|
|
4039
|
+
async function handler$r(plugin, ctx, options) {
|
|
4035
4040
|
const { server, input } = ctx;
|
|
4036
4041
|
const model = server.getModel(input);
|
|
4037
4042
|
ctx.output = model;
|
|
@@ -4039,8 +4044,8 @@ async function handler$q(plugin, ctx, options) {
|
|
|
4039
4044
|
|
|
4040
4045
|
var getMetaModelDetail = /*#__PURE__*/Object.freeze({
|
|
4041
4046
|
__proto__: null,
|
|
4042
|
-
code: code$
|
|
4043
|
-
handler: handler$
|
|
4047
|
+
code: code$r,
|
|
4048
|
+
handler: handler$r
|
|
4044
4049
|
});
|
|
4045
4050
|
|
|
4046
4051
|
/**
|
|
@@ -4459,9 +4464,9 @@ function transformFilterWithSubFilters(filter) {
|
|
|
4459
4464
|
return filter;
|
|
4460
4465
|
}
|
|
4461
4466
|
|
|
4462
|
-
const code$
|
|
4463
|
-
async function handler$
|
|
4464
|
-
await runCollectionEntityActionHandler(ctx, options, code$
|
|
4467
|
+
const code$q = "findCollectionEntities";
|
|
4468
|
+
async function handler$q(plugin, ctx, options) {
|
|
4469
|
+
await runCollectionEntityActionHandler(ctx, options, code$q, async (entityManager, input) => {
|
|
4465
4470
|
input.filters = removeFiltersWithNullValue(input.filters);
|
|
4466
4471
|
input.routeContext = ctx.routerContext;
|
|
4467
4472
|
const entities = await entityManager.findEntities(input);
|
|
@@ -4477,14 +4482,14 @@ async function handler$p(plugin, ctx, options) {
|
|
|
4477
4482
|
|
|
4478
4483
|
var findCollectionEntities = /*#__PURE__*/Object.freeze({
|
|
4479
4484
|
__proto__: null,
|
|
4480
|
-
code: code$
|
|
4481
|
-
handler: handler$
|
|
4485
|
+
code: code$q,
|
|
4486
|
+
handler: handler$q
|
|
4482
4487
|
});
|
|
4483
4488
|
|
|
4484
|
-
const code$
|
|
4485
|
-
async function handler$
|
|
4489
|
+
const code$p = "findCollectionEntityById";
|
|
4490
|
+
async function handler$p(plugin, ctx, options) {
|
|
4486
4491
|
const { logger, server, input } = ctx;
|
|
4487
|
-
logger.debug(`Running ${code$
|
|
4492
|
+
logger.debug(`Running ${code$p} handler...`, { input });
|
|
4488
4493
|
const { id } = input;
|
|
4489
4494
|
const entityManager = server.getEntityManager(options.singularCode);
|
|
4490
4495
|
const entity = await entityManager.findById({
|
|
@@ -4499,13 +4504,13 @@ async function handler$o(plugin, ctx, options) {
|
|
|
4499
4504
|
|
|
4500
4505
|
var findCollectionEntityById = /*#__PURE__*/Object.freeze({
|
|
4501
4506
|
__proto__: null,
|
|
4502
|
-
code: code$
|
|
4503
|
-
handler: handler$
|
|
4507
|
+
code: code$p,
|
|
4508
|
+
handler: handler$p
|
|
4504
4509
|
});
|
|
4505
4510
|
|
|
4506
|
-
const code$
|
|
4507
|
-
async function handler$
|
|
4508
|
-
await runCollectionEntityActionHandler(ctx, options, code$
|
|
4511
|
+
const code$o = "countCollectionEntities";
|
|
4512
|
+
async function handler$o(plugin, ctx, options) {
|
|
4513
|
+
await runCollectionEntityActionHandler(ctx, options, code$o, (entityManager, input) => {
|
|
4509
4514
|
input.filters = removeFiltersWithNullValue(input.filters);
|
|
4510
4515
|
input.routeContext = ctx.routerContext;
|
|
4511
4516
|
return entityManager.count(input);
|
|
@@ -4514,16 +4519,16 @@ async function handler$n(plugin, ctx, options) {
|
|
|
4514
4519
|
|
|
4515
4520
|
var countCollectionEntities = /*#__PURE__*/Object.freeze({
|
|
4516
4521
|
__proto__: null,
|
|
4517
|
-
code: code$
|
|
4518
|
-
handler: handler$
|
|
4522
|
+
code: code$o,
|
|
4523
|
+
handler: handler$o
|
|
4519
4524
|
});
|
|
4520
4525
|
|
|
4521
|
-
const code$
|
|
4522
|
-
async function handler$
|
|
4526
|
+
const code$n = "createCollectionEntity";
|
|
4527
|
+
async function handler$n(plugin, ctx, options) {
|
|
4523
4528
|
const { logger, server, input } = ctx;
|
|
4524
4529
|
const { defaultInput, fixedInput } = options;
|
|
4525
4530
|
const mergedInput = mergeInput(defaultInput, input, fixedInput);
|
|
4526
|
-
logger.debug(`Running ${code$
|
|
4531
|
+
logger.debug(`Running ${code$n} handler...`, { defaultInput, fixedInput, mergedInput });
|
|
4527
4532
|
const entityManager = server.getEntityManager(options.singularCode);
|
|
4528
4533
|
const output = await entityManager.createEntity({
|
|
4529
4534
|
entity: input,
|
|
@@ -4534,15 +4539,15 @@ async function handler$m(plugin, ctx, options) {
|
|
|
4534
4539
|
|
|
4535
4540
|
var createCollectionEntity = /*#__PURE__*/Object.freeze({
|
|
4536
4541
|
__proto__: null,
|
|
4537
|
-
code: code$
|
|
4538
|
-
handler: handler$
|
|
4542
|
+
code: code$n,
|
|
4543
|
+
handler: handler$n
|
|
4539
4544
|
});
|
|
4540
4545
|
|
|
4541
|
-
const code$
|
|
4542
|
-
async function handler$
|
|
4546
|
+
const code$m = "createCollectionEntitiesBatch";
|
|
4547
|
+
async function handler$m(plugin, ctx, options) {
|
|
4543
4548
|
const { logger, server, input } = ctx;
|
|
4544
4549
|
const { defaultInput, fixedInput } = options;
|
|
4545
|
-
logger.debug(`Running ${code$
|
|
4550
|
+
logger.debug(`Running ${code$m} handler...`, { defaultInput, fixedInput, input });
|
|
4546
4551
|
const { entities } = input;
|
|
4547
4552
|
if (!lodash.isArray(entities)) {
|
|
4548
4553
|
throw new Error("input.entities should be an array.");
|
|
@@ -4566,16 +4571,16 @@ async function handler$l(plugin, ctx, options) {
|
|
|
4566
4571
|
|
|
4567
4572
|
var createCollectionEntitiesBatch = /*#__PURE__*/Object.freeze({
|
|
4568
4573
|
__proto__: null,
|
|
4569
|
-
code: code$
|
|
4570
|
-
handler: handler$
|
|
4574
|
+
code: code$m,
|
|
4575
|
+
handler: handler$m
|
|
4571
4576
|
});
|
|
4572
4577
|
|
|
4573
|
-
const code$
|
|
4574
|
-
async function handler$
|
|
4578
|
+
const code$l = "updateCollectionEntityById";
|
|
4579
|
+
async function handler$l(plugin, ctx, options) {
|
|
4575
4580
|
const { logger, server, input } = ctx;
|
|
4576
4581
|
const { defaultInput, fixedInput } = options;
|
|
4577
4582
|
const mergedInput = mergeInput(defaultInput, input, fixedInput);
|
|
4578
|
-
logger.debug(`Running ${code$
|
|
4583
|
+
logger.debug(`Running ${code$l} handler...`, { defaultInput, fixedInput, mergedInput });
|
|
4579
4584
|
const operation = mergedInput.$operation;
|
|
4580
4585
|
if (operation) {
|
|
4581
4586
|
delete mergedInput.$operation;
|
|
@@ -4597,6 +4602,35 @@ async function handler$k(plugin, ctx, options) {
|
|
|
4597
4602
|
}
|
|
4598
4603
|
|
|
4599
4604
|
var updateCollectionEntityById = /*#__PURE__*/Object.freeze({
|
|
4605
|
+
__proto__: null,
|
|
4606
|
+
code: code$l,
|
|
4607
|
+
handler: handler$l
|
|
4608
|
+
});
|
|
4609
|
+
|
|
4610
|
+
const code$k = "deleteCollectionEntities";
|
|
4611
|
+
async function handler$k(plugin, ctx, options) {
|
|
4612
|
+
const { logger, server, routerContext } = ctx;
|
|
4613
|
+
const input = ctx.input;
|
|
4614
|
+
logger.debug(`Running ${code$k} handler...`);
|
|
4615
|
+
if (!input.filters || !input.filters.length) {
|
|
4616
|
+
throw new Error("Filters are required when deleting entities.");
|
|
4617
|
+
}
|
|
4618
|
+
const entityManager = server.getEntityManager(options.singularCode);
|
|
4619
|
+
const entities = await entityManager.findEntities({
|
|
4620
|
+
routeContext: routerContext,
|
|
4621
|
+
filters: input.filters,
|
|
4622
|
+
});
|
|
4623
|
+
for (const entity of entities) {
|
|
4624
|
+
await entityManager.deleteById({
|
|
4625
|
+
routeContext: ctx.routerContext,
|
|
4626
|
+
id: entity.id,
|
|
4627
|
+
}, plugin);
|
|
4628
|
+
}
|
|
4629
|
+
ctx.status = 200;
|
|
4630
|
+
ctx.output = {};
|
|
4631
|
+
}
|
|
4632
|
+
|
|
4633
|
+
var deleteCollectionEntities = /*#__PURE__*/Object.freeze({
|
|
4600
4634
|
__proto__: null,
|
|
4601
4635
|
code: code$k,
|
|
4602
4636
|
handler: handler$k
|
|
@@ -4702,6 +4736,12 @@ const routeConfigs = [
|
|
|
4702
4736
|
endpoint: "/operations/count",
|
|
4703
4737
|
handlerCode: "countCollectionEntities",
|
|
4704
4738
|
},
|
|
4739
|
+
{
|
|
4740
|
+
code: "delete",
|
|
4741
|
+
method: "POST",
|
|
4742
|
+
endpoint: "/operations/delete",
|
|
4743
|
+
handlerCode: "deleteCollectionEntities",
|
|
4744
|
+
},
|
|
4705
4745
|
{
|
|
4706
4746
|
code: "addRelations",
|
|
4707
4747
|
method: "POST",
|
|
@@ -4764,6 +4804,7 @@ class DataManager {
|
|
|
4764
4804
|
server.registerActionHandler(this, updateCollectionEntityById);
|
|
4765
4805
|
server.registerActionHandler(this, addEntityRelations);
|
|
4766
4806
|
server.registerActionHandler(this, removeEntityRelations);
|
|
4807
|
+
server.registerActionHandler(this, deleteCollectionEntities);
|
|
4767
4808
|
server.registerActionHandler(this, deleteCollectionEntityById);
|
|
4768
4809
|
server.registerActionHandler(this, queryDatabase);
|
|
4769
4810
|
}
|
|
@@ -7306,7 +7347,7 @@ class EntityAccessControlPlugin {
|
|
|
7306
7347
|
lodash.set(action, "config.permissionCheck", permissionPolicies.update);
|
|
7307
7348
|
}
|
|
7308
7349
|
}
|
|
7309
|
-
else if (action.code === "deleteCollectionEntityById") {
|
|
7350
|
+
else if (action.code === "deleteCollectionEntityById" || action.code === "deleteCollectionEntities") {
|
|
7310
7351
|
const model = lodash.find(applicationConfig.models, (item) => item.singularCode === action.config.singularCode);
|
|
7311
7352
|
if (!model) {
|
|
7312
7353
|
continue;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FindEntityOptions, RunEntityActionHandlerOptions } from "../../../types";
|
|
2
|
+
import { ActionHandlerContext } from "../../../core/actionHandler";
|
|
3
|
+
import { RapidPlugin } from "../../../core/server";
|
|
4
|
+
export interface DeleteCollectionEntitiesInput {
|
|
5
|
+
filters: FindEntityOptions["filters"];
|
|
6
|
+
}
|
|
7
|
+
export declare const code = "deleteCollectionEntities";
|
|
8
|
+
export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: RunEntityActionHandlerOptions): Promise<void>;
|
package/package.json
CHANGED
package/rollup.config.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import typescript from "rollup-plugin-typescript2";
|
|
2
|
-
import tscAlias from "rollup-plugin-tsc-alias";
|
|
3
|
-
|
|
4
|
-
export default {
|
|
5
|
-
input: ["src/index.ts"],
|
|
6
|
-
output: [
|
|
7
|
-
{
|
|
8
|
-
dir: "dist",
|
|
9
|
-
entryFileNames: "[name].js",
|
|
10
|
-
format: "cjs",
|
|
11
|
-
exports: "named",
|
|
12
|
-
},
|
|
13
|
-
],
|
|
14
|
-
plugins: [typescript(), tscAlias()],
|
|
15
|
-
external: [],
|
|
16
|
-
};
|
|
1
|
+
import typescript from "rollup-plugin-typescript2";
|
|
2
|
+
import tscAlias from "rollup-plugin-tsc-alias";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
input: ["src/index.ts"],
|
|
6
|
+
output: [
|
|
7
|
+
{
|
|
8
|
+
dir: "dist",
|
|
9
|
+
entryFileNames: "[name].js",
|
|
10
|
+
format: "cjs",
|
|
11
|
+
exports: "named",
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
plugins: [typescript(), tscAlias()],
|
|
15
|
+
external: [],
|
|
16
|
+
};
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { RpdApplicationConfig } from "~/types";
|
|
2
|
-
import { IRpdServer, RapidPlugin } from "./server";
|
|
3
|
-
import { Next, RouteContext } from "./routeContext";
|
|
4
|
-
import { Logger } from "~/facilities/log/LogFacility";
|
|
5
|
-
|
|
6
|
-
export interface ActionHandlerContext {
|
|
7
|
-
logger: Logger;
|
|
8
|
-
routerContext: RouteContext;
|
|
9
|
-
next: Next;
|
|
10
|
-
server: IRpdServer;
|
|
11
|
-
applicationConfig: RpdApplicationConfig;
|
|
12
|
-
input?: any;
|
|
13
|
-
output?: any;
|
|
14
|
-
status?: Response["status"];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export type ActionHandler = (ctx: ActionHandlerContext, options: any) => void | Promise<void>;
|
|
18
|
-
|
|
19
|
-
export interface IPluginActionHandler {
|
|
20
|
-
code: string;
|
|
21
|
-
handler: (plugin: RapidPlugin, ctx: ActionHandlerContext, options: any) => void | Promise<void>;
|
|
22
|
-
}
|
|
1
|
+
import { RpdApplicationConfig } from "~/types";
|
|
2
|
+
import { IRpdServer, RapidPlugin } from "./server";
|
|
3
|
+
import { Next, RouteContext } from "./routeContext";
|
|
4
|
+
import { Logger } from "~/facilities/log/LogFacility";
|
|
5
|
+
|
|
6
|
+
export interface ActionHandlerContext {
|
|
7
|
+
logger: Logger;
|
|
8
|
+
routerContext: RouteContext;
|
|
9
|
+
next: Next;
|
|
10
|
+
server: IRpdServer;
|
|
11
|
+
applicationConfig: RpdApplicationConfig;
|
|
12
|
+
input?: any;
|
|
13
|
+
output?: any;
|
|
14
|
+
status?: Response["status"];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type ActionHandler = (ctx: ActionHandlerContext, options: any) => void | Promise<void>;
|
|
18
|
+
|
|
19
|
+
export interface IPluginActionHandler {
|
|
20
|
+
code: string;
|
|
21
|
+
handler: (plugin: RapidPlugin, ctx: ActionHandlerContext, options: any) => void | Promise<void>;
|
|
22
|
+
}
|
package/src/core/eventManager.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { EventEmitter } from "events";
|
|
2
|
-
|
|
3
|
-
export default class EventManager<EventTypes extends Record<string, any[]>> {
|
|
4
|
-
#eventEmitter: EventEmitter;
|
|
5
|
-
|
|
6
|
-
constructor() {
|
|
7
|
-
this.#eventEmitter = new EventEmitter();
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
on<K extends keyof EventTypes>(eventName: K, listener: (...args: EventTypes[K]) => void) {
|
|
11
|
-
this.#eventEmitter.on(eventName as string, listener);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
async emit<K extends keyof EventTypes>(eventName: K, ...args: EventTypes[K]) {
|
|
15
|
-
const listeners = this.#eventEmitter.listeners(eventName as string);
|
|
16
|
-
for (const listener of listeners) {
|
|
17
|
-
await listener(...args);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
1
|
+
import { EventEmitter } from "events";
|
|
2
|
+
|
|
3
|
+
export default class EventManager<EventTypes extends Record<string, any[]>> {
|
|
4
|
+
#eventEmitter: EventEmitter;
|
|
5
|
+
|
|
6
|
+
constructor() {
|
|
7
|
+
this.#eventEmitter = new EventEmitter();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
on<K extends keyof EventTypes>(eventName: K, listener: (...args: EventTypes[K]) => void) {
|
|
11
|
+
this.#eventEmitter.on(eventName as string, listener);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async emit<K extends keyof EventTypes>(eventName: K, ...args: EventTypes[K]) {
|
|
15
|
+
const listeners = this.#eventEmitter.listeners(eventName as string);
|
|
16
|
+
for (const listener of listeners) {
|
|
17
|
+
await listener(...args);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
package/src/core/facility.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { IRpdServer } from "./server";
|
|
2
|
-
|
|
3
|
-
export interface FacilityFactory {
|
|
4
|
-
name: string;
|
|
5
|
-
|
|
6
|
-
createFacility: (server: IRpdServer, options?: any) => Promise<any>;
|
|
7
|
-
}
|
|
1
|
+
import { IRpdServer } from "./server";
|
|
2
|
+
|
|
3
|
+
export interface FacilityFactory {
|
|
4
|
+
name: string;
|
|
5
|
+
|
|
6
|
+
createFacility: (server: IRpdServer, options?: any) => Promise<any>;
|
|
7
|
+
}
|
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
import type { RapidRequest } from "../request";
|
|
2
|
-
|
|
3
|
-
export type BodyData = Record<string, string | File | (string | File)[]>;
|
|
4
|
-
export type ParseBodyOptions = {
|
|
5
|
-
/**
|
|
6
|
-
* Parse all fields with multiple values should be parsed as an array.
|
|
7
|
-
* @default false
|
|
8
|
-
* @example
|
|
9
|
-
* ```ts
|
|
10
|
-
* const data = new FormData()
|
|
11
|
-
* data.append('file', 'aaa')
|
|
12
|
-
* data.append('file', 'bbb')
|
|
13
|
-
* data.append('message', 'hello')
|
|
14
|
-
* ```
|
|
15
|
-
*
|
|
16
|
-
* If `all` is `false`:
|
|
17
|
-
* parseBody should return `{ file: 'bbb', message: 'hello' }`
|
|
18
|
-
*
|
|
19
|
-
* If `all` is `true`:
|
|
20
|
-
* parseBody should return `{ file: ['aaa', 'bbb'], message: 'hello' }`
|
|
21
|
-
*/
|
|
22
|
-
all?: boolean;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export const parseFormDataBody = async <T extends BodyData = BodyData>(request: Request, options: ParseBodyOptions = { all: false }): Promise<T> => {
|
|
26
|
-
const contentType = request.headers.get("Content-Type");
|
|
27
|
-
|
|
28
|
-
if (isFormDataContent(contentType)) {
|
|
29
|
-
return parseFormData<T>(request, options);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return {} as T;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
function isFormDataContent(contentType: string | null): boolean {
|
|
36
|
-
if (contentType === null) {
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return contentType.startsWith("multipart/form-data") || contentType.startsWith("application/x-www-form-urlencoded");
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async function parseFormData<T extends BodyData = BodyData>(request: Request, options: ParseBodyOptions): Promise<T> {
|
|
44
|
-
const formData = await (request as Request).formData();
|
|
45
|
-
|
|
46
|
-
if (formData) {
|
|
47
|
-
return convertFormDataToBodyData<T>(formData, options);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return {} as T;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function convertFormDataToBodyData<T extends BodyData = BodyData>(formData: FormData, options: ParseBodyOptions): T {
|
|
54
|
-
const form: BodyData = {};
|
|
55
|
-
|
|
56
|
-
formData.forEach((value, key) => {
|
|
57
|
-
const shouldParseAllValues = options.all || key.endsWith("[]");
|
|
58
|
-
|
|
59
|
-
if (!shouldParseAllValues) {
|
|
60
|
-
form[key] = value;
|
|
61
|
-
} else {
|
|
62
|
-
handleParsingAllValues(form, key, value);
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
return form as T;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const handleParsingAllValues = (form: BodyData, key: string, value: FormDataEntryValue): void => {
|
|
70
|
-
if (form[key] && isArrayField(form[key])) {
|
|
71
|
-
appendToExistingArray(form[key] as (string | File)[], value);
|
|
72
|
-
} else if (form[key]) {
|
|
73
|
-
convertToNewArray(form, key, value);
|
|
74
|
-
} else {
|
|
75
|
-
form[key] = value;
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
function isArrayField(field: unknown): field is (string | File)[] {
|
|
80
|
-
return Array.isArray(field);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const appendToExistingArray = (arr: (string | File)[], value: FormDataEntryValue): void => {
|
|
84
|
-
arr.push(value);
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
const convertToNewArray = (form: BodyData, key: string, value: FormDataEntryValue): void => {
|
|
88
|
-
form[key] = [form[key] as string | File, value];
|
|
89
|
-
};
|
|
1
|
+
import type { RapidRequest } from "../request";
|
|
2
|
+
|
|
3
|
+
export type BodyData = Record<string, string | File | (string | File)[]>;
|
|
4
|
+
export type ParseBodyOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* Parse all fields with multiple values should be parsed as an array.
|
|
7
|
+
* @default false
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const data = new FormData()
|
|
11
|
+
* data.append('file', 'aaa')
|
|
12
|
+
* data.append('file', 'bbb')
|
|
13
|
+
* data.append('message', 'hello')
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* If `all` is `false`:
|
|
17
|
+
* parseBody should return `{ file: 'bbb', message: 'hello' }`
|
|
18
|
+
*
|
|
19
|
+
* If `all` is `true`:
|
|
20
|
+
* parseBody should return `{ file: ['aaa', 'bbb'], message: 'hello' }`
|
|
21
|
+
*/
|
|
22
|
+
all?: boolean;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const parseFormDataBody = async <T extends BodyData = BodyData>(request: Request, options: ParseBodyOptions = { all: false }): Promise<T> => {
|
|
26
|
+
const contentType = request.headers.get("Content-Type");
|
|
27
|
+
|
|
28
|
+
if (isFormDataContent(contentType)) {
|
|
29
|
+
return parseFormData<T>(request, options);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return {} as T;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
function isFormDataContent(contentType: string | null): boolean {
|
|
36
|
+
if (contentType === null) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return contentType.startsWith("multipart/form-data") || contentType.startsWith("application/x-www-form-urlencoded");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function parseFormData<T extends BodyData = BodyData>(request: Request, options: ParseBodyOptions): Promise<T> {
|
|
44
|
+
const formData = await (request as Request).formData();
|
|
45
|
+
|
|
46
|
+
if (formData) {
|
|
47
|
+
return convertFormDataToBodyData<T>(formData, options);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return {} as T;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function convertFormDataToBodyData<T extends BodyData = BodyData>(formData: FormData, options: ParseBodyOptions): T {
|
|
54
|
+
const form: BodyData = {};
|
|
55
|
+
|
|
56
|
+
formData.forEach((value, key) => {
|
|
57
|
+
const shouldParseAllValues = options.all || key.endsWith("[]");
|
|
58
|
+
|
|
59
|
+
if (!shouldParseAllValues) {
|
|
60
|
+
form[key] = value;
|
|
61
|
+
} else {
|
|
62
|
+
handleParsingAllValues(form, key, value);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return form as T;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const handleParsingAllValues = (form: BodyData, key: string, value: FormDataEntryValue): void => {
|
|
70
|
+
if (form[key] && isArrayField(form[key])) {
|
|
71
|
+
appendToExistingArray(form[key] as (string | File)[], value);
|
|
72
|
+
} else if (form[key]) {
|
|
73
|
+
convertToNewArray(form, key, value);
|
|
74
|
+
} else {
|
|
75
|
+
form[key] = value;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
function isArrayField(field: unknown): field is (string | File)[] {
|
|
80
|
+
return Array.isArray(field);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const appendToExistingArray = (arr: (string | File)[], value: FormDataEntryValue): void => {
|
|
84
|
+
arr.push(value);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const convertToNewArray = (form: BodyData, key: string, value: FormDataEntryValue): void => {
|
|
88
|
+
form[key] = [form[key] as string | File, value];
|
|
89
|
+
};
|