@ruiapp/rapid-core 0.1.76 → 0.1.78

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.
Files changed (104) hide show
  1. package/dist/index.js +11 -5
  2. package/dist/plugins/fileManage/actionHandlers/downloadFile.d.ts +6 -0
  3. package/package.json +1 -1
  4. package/rollup.config.js +16 -16
  5. package/src/core/actionHandler.ts +22 -22
  6. package/src/core/eventManager.ts +20 -20
  7. package/src/core/facility.ts +7 -7
  8. package/src/core/http/formDataParser.ts +89 -89
  9. package/src/core/pluginManager.ts +175 -175
  10. package/src/core/providers/runtimeProvider.ts +5 -5
  11. package/src/core/request.ts +86 -86
  12. package/src/core/response.ts +76 -76
  13. package/src/core/routeContext.ts +43 -43
  14. package/src/core/routesBuilder.ts +88 -88
  15. package/src/dataAccess/dataAccessor.ts +137 -137
  16. package/src/dataAccess/entityManager.ts +4 -0
  17. package/src/deno-std/datetime/to_imf.ts +32 -32
  18. package/src/deno-std/encoding/base64.ts +141 -141
  19. package/src/facilities/log/LogFacility.ts +35 -35
  20. package/src/helpers/entityHelpers.ts +76 -76
  21. package/src/index.ts +44 -44
  22. package/src/plugins/auth/actionHandlers/changePassword.ts +54 -54
  23. package/src/plugins/auth/actionHandlers/createSession.ts +63 -63
  24. package/src/plugins/auth/actionHandlers/deleteSession.ts +18 -18
  25. package/src/plugins/auth/actionHandlers/getMyProfile.ts +35 -35
  26. package/src/plugins/auth/actionHandlers/index.ts +8 -8
  27. package/src/plugins/auth/actionHandlers/resetPassword.ts +38 -38
  28. package/src/plugins/auth/models/AccessToken.ts +56 -56
  29. package/src/plugins/auth/models/index.ts +3 -3
  30. package/src/plugins/auth/routes/changePassword.ts +15 -15
  31. package/src/plugins/auth/routes/getMyProfile.ts +15 -15
  32. package/src/plugins/auth/routes/index.ts +7 -7
  33. package/src/plugins/auth/routes/resetPassword.ts +15 -15
  34. package/src/plugins/auth/routes/signin.ts +15 -15
  35. package/src/plugins/auth/routes/signout.ts +15 -15
  36. package/src/plugins/cronJob/CronJobPluginTypes.ts +49 -49
  37. package/src/plugins/cronJob/actionHandlers/index.ts +4 -4
  38. package/src/plugins/cronJob/actionHandlers/runCronJob.ts +29 -29
  39. package/src/plugins/cronJob/routes/index.ts +3 -3
  40. package/src/plugins/cronJob/routes/runCronJob.ts +15 -15
  41. package/src/plugins/dataManage/actionHandlers/addEntityRelations.ts +20 -20
  42. package/src/plugins/dataManage/actionHandlers/countCollectionEntities.ts +15 -15
  43. package/src/plugins/dataManage/actionHandlers/createCollectionEntitiesBatch.ts +42 -42
  44. package/src/plugins/dataManage/actionHandlers/createCollectionEntity.ts +24 -24
  45. package/src/plugins/dataManage/actionHandlers/findCollectionEntities.ts +26 -26
  46. package/src/plugins/dataManage/actionHandlers/findCollectionEntityById.ts +21 -21
  47. package/src/plugins/dataManage/actionHandlers/queryDatabase.ts +22 -22
  48. package/src/plugins/dataManage/actionHandlers/removeEntityRelations.ts +20 -20
  49. package/src/plugins/dataManage/actionHandlers/updateCollectionEntityById.ts +35 -35
  50. package/src/plugins/entityAccessControl/EntityAccessControlPlugin.ts +146 -146
  51. package/src/plugins/fileManage/actionHandlers/downloadDocument.ts +36 -36
  52. package/src/plugins/fileManage/actionHandlers/downloadFile.ts +13 -2
  53. package/src/plugins/fileManage/actionHandlers/uploadFile.ts +33 -33
  54. package/src/plugins/fileManage/routes/downloadDocument.ts +15 -15
  55. package/src/plugins/fileManage/routes/downloadFile.ts +15 -15
  56. package/src/plugins/fileManage/routes/index.ts +5 -5
  57. package/src/plugins/fileManage/routes/uploadFile.ts +15 -15
  58. package/src/plugins/metaManage/actionHandlers/getMetaModelDetail.ts +10 -10
  59. package/src/plugins/metaManage/actionHandlers/listMetaModels.ts +9 -9
  60. package/src/plugins/metaManage/actionHandlers/listMetaRoutes.ts +9 -9
  61. package/src/plugins/routeManage/actionHandlers/httpProxy.ts +13 -13
  62. package/src/plugins/sequence/SequenceService.ts +81 -81
  63. package/src/plugins/sequence/actionHandlers/generateSn.ts +32 -32
  64. package/src/plugins/sequence/actionHandlers/index.ts +4 -4
  65. package/src/plugins/sequence/models/SequenceAutoIncrementRecord.ts +49 -49
  66. package/src/plugins/sequence/models/SequenceRule.ts +42 -42
  67. package/src/plugins/sequence/models/index.ts +4 -4
  68. package/src/plugins/sequence/routes/generateSn.ts +15 -15
  69. package/src/plugins/sequence/routes/index.ts +3 -3
  70. package/src/plugins/sequence/segment-utility.ts +11 -11
  71. package/src/plugins/sequence/segments/index.ts +9 -9
  72. package/src/plugins/serverOperation/ServerOperationPlugin.ts +91 -91
  73. package/src/plugins/serverOperation/ServerOperationPluginTypes.ts +15 -15
  74. package/src/plugins/serverOperation/actionHandlers/index.ts +4 -4
  75. package/src/plugins/setting/SettingService.ts +213 -213
  76. package/src/plugins/setting/actionHandlers/getSystemSettingValues.ts +30 -30
  77. package/src/plugins/setting/actionHandlers/getUserSettingValues.ts +38 -38
  78. package/src/plugins/setting/actionHandlers/index.ts +6 -6
  79. package/src/plugins/setting/actionHandlers/setSystemSettingValues.ts +30 -30
  80. package/src/plugins/setting/models/SystemSettingGroupSetting.ts +57 -57
  81. package/src/plugins/setting/models/SystemSettingItem.ts +42 -42
  82. package/src/plugins/setting/models/SystemSettingItemSetting.ts +73 -73
  83. package/src/plugins/setting/models/UserSettingGroupSetting.ts +57 -57
  84. package/src/plugins/setting/models/UserSettingItem.ts +49 -49
  85. package/src/plugins/setting/models/UserSettingItemSetting.ts +73 -73
  86. package/src/plugins/setting/models/index.ts +8 -8
  87. package/src/plugins/setting/routes/getSystemSettingValues.ts +15 -15
  88. package/src/plugins/setting/routes/getUserSettingValues.ts +15 -15
  89. package/src/plugins/setting/routes/index.ts +5 -5
  90. package/src/plugins/setting/routes/setSystemSettingValues.ts +15 -15
  91. package/src/plugins/stateMachine/actionHandlers/index.ts +4 -4
  92. package/src/plugins/stateMachine/actionHandlers/sendStateMachineEvent.ts +51 -51
  93. package/src/plugins/stateMachine/models/StateMachine.ts +42 -42
  94. package/src/plugins/stateMachine/models/index.ts +3 -3
  95. package/src/plugins/stateMachine/routes/index.ts +3 -3
  96. package/src/plugins/stateMachine/routes/sendStateMachineEvent.ts +15 -15
  97. package/src/polyfill.ts +5 -5
  98. package/src/proxy/mod.ts +38 -38
  99. package/src/utilities/accessControlUtility.ts +33 -33
  100. package/src/utilities/fsUtility.ts +61 -61
  101. package/src/utilities/httpUtility.ts +19 -19
  102. package/src/utilities/jwtUtility.ts +26 -26
  103. package/src/utilities/timeUtility.ts +9 -9
  104. package/tsconfig.json +19 -19
package/dist/index.js CHANGED
@@ -2885,6 +2885,7 @@ async function createEntity(server, dataAccessor, options, plugin) {
2885
2885
  if (!targetEntityId) {
2886
2886
  const targetEntity = fieldValue;
2887
2887
  const newTargetEntity = await createEntity(server, targetDataAccessor, {
2888
+ routeContext,
2888
2889
  entity: targetEntity,
2889
2890
  });
2890
2891
  newEntityOneRelationProps[property.code] = newTargetEntity;
@@ -2951,6 +2952,7 @@ async function createEntity(server, dataAccessor, options, plugin) {
2951
2952
  targetEntity[property.selfIdColumnName] = newEntity.id;
2952
2953
  }
2953
2954
  const newTargetEntity = await createEntity(server, targetDataAccessor, {
2955
+ routeContext,
2954
2956
  entity: targetEntity,
2955
2957
  });
2956
2958
  if (property.linkTableName) {
@@ -3115,6 +3117,7 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
3115
3117
  if (!targetEntityId) {
3116
3118
  const targetEntity = fieldValue;
3117
3119
  const newTargetEntity = await createEntity(server, targetDataAccessor, {
3120
+ routeContext,
3118
3121
  entity: targetEntity,
3119
3122
  });
3120
3123
  updatedEntityOneRelationProps[property.code] = newTargetEntity;
@@ -3191,6 +3194,7 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
3191
3194
  targetEntity[property.selfIdColumnName] = id;
3192
3195
  }
3193
3196
  const newTargetEntity = await createEntity(server, targetDataAccessor, {
3197
+ routeContext,
3194
3198
  entity: targetEntity,
3195
3199
  });
3196
3200
  if (property.linkTableName) {
@@ -5928,9 +5932,10 @@ var downloadDocumentActionHandler = /*#__PURE__*/Object.freeze({
5928
5932
 
5929
5933
  const code$7 = "downloadFile";
5930
5934
  async function handler$7(plugin, ctx, options) {
5931
- const { server, applicationConfig, routerContext, input } = ctx;
5935
+ const { server, applicationConfig, routerContext } = ctx;
5932
5936
  const { request, response } = routerContext;
5933
5937
  //TODO: only public files can download by this handler
5938
+ const input = ctx.input;
5934
5939
  let fileKey = input.fileKey;
5935
5940
  if (!fileKey && input.fileId) {
5936
5941
  const dataAccessor = ctx.server.getDataAccessor({
@@ -5946,7 +5951,8 @@ async function handler$7(plugin, ctx, options) {
5946
5951
  const filePathName = path__default["default"].join(server.config.localFileStoragePath, fileKey);
5947
5952
  const attachmentFileName = input.fileName || path__default["default"].basename(fileKey);
5948
5953
  response.body = await readFile(filePathName);
5949
- response.headers.set("Content-Disposition", `attachment; filename="${encodeURIComponent(attachmentFileName)}"`);
5954
+ const dispositionType = input.inline ? "inline" : "attachment";
5955
+ response.headers.set("Content-Disposition", `${dispositionType}; filename="${encodeURIComponent(attachmentFileName)}"`);
5950
5956
  }
5951
5957
 
5952
5958
  var downloadFileActionHandler = /*#__PURE__*/Object.freeze({
@@ -7321,9 +7327,9 @@ class EntityAccessControlPlugin {
7321
7327
  if (!userId) {
7322
7328
  return;
7323
7329
  }
7324
- const actions = await server.queryDatabaseObject(`select distinct a.* from sys_actions a
7325
- inner join oc_role_sys_action_links ra on a.id = ra.action_id
7326
- inner join oc_role_user_links ru on ru.role_id = ra.role_id
7330
+ const actions = await server.queryDatabaseObject(`select distinct a.* from sys_actions a
7331
+ inner join oc_role_sys_action_links ra on a.id = ra.action_id
7332
+ inner join oc_role_user_links ru on ru.role_id = ra.role_id
7327
7333
  where ru.user_id = $1;`, [userId]);
7328
7334
  routeContext.state.allowedActions = actions.map((item) => item.code);
7329
7335
  }
@@ -1,4 +1,10 @@
1
1
  import { ActionHandlerContext } from "../../../core/actionHandler";
2
2
  import { RapidPlugin } from "../../../core/server";
3
+ export type DownloadFileInput = {
4
+ fileId?: string;
5
+ fileKey?: string;
6
+ fileName?: string;
7
+ inline?: boolean;
8
+ };
3
9
  export declare const code = "downloadFile";
4
10
  export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: any): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.1.76",
3
+ "version": "0.1.78",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
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
+ }
@@ -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
+ }
@@ -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
+ };