@ruiapp/rapid-core 0.1.82 → 0.1.83

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 (100) hide show
  1. package/dist/index.js +14 -5
  2. package/package.json +1 -1
  3. package/rollup.config.js +16 -16
  4. package/src/core/actionHandler.ts +22 -22
  5. package/src/core/eventManager.ts +20 -20
  6. package/src/core/facility.ts +7 -7
  7. package/src/core/http/formDataParser.ts +89 -89
  8. package/src/core/pluginManager.ts +175 -175
  9. package/src/core/providers/runtimeProvider.ts +5 -5
  10. package/src/core/request.ts +86 -86
  11. package/src/core/response.ts +76 -76
  12. package/src/core/routeContext.ts +43 -43
  13. package/src/core/routesBuilder.ts +88 -88
  14. package/src/dataAccess/dataAccessor.ts +137 -137
  15. package/src/dataAccess/entityManager.ts +14 -5
  16. package/src/deno-std/datetime/to_imf.ts +32 -32
  17. package/src/deno-std/encoding/base64.ts +141 -141
  18. package/src/facilities/log/LogFacility.ts +35 -35
  19. package/src/helpers/entityHelpers.ts +76 -76
  20. package/src/plugins/auth/actionHandlers/changePassword.ts +54 -54
  21. package/src/plugins/auth/actionHandlers/createSession.ts +63 -63
  22. package/src/plugins/auth/actionHandlers/deleteSession.ts +18 -18
  23. package/src/plugins/auth/actionHandlers/getMyProfile.ts +35 -35
  24. package/src/plugins/auth/actionHandlers/index.ts +8 -8
  25. package/src/plugins/auth/actionHandlers/resetPassword.ts +38 -38
  26. package/src/plugins/auth/models/AccessToken.ts +56 -56
  27. package/src/plugins/auth/models/index.ts +3 -3
  28. package/src/plugins/auth/routes/changePassword.ts +15 -15
  29. package/src/plugins/auth/routes/getMyProfile.ts +15 -15
  30. package/src/plugins/auth/routes/index.ts +7 -7
  31. package/src/plugins/auth/routes/resetPassword.ts +15 -15
  32. package/src/plugins/auth/routes/signin.ts +15 -15
  33. package/src/plugins/auth/routes/signout.ts +15 -15
  34. package/src/plugins/cronJob/CronJobPluginTypes.ts +49 -49
  35. package/src/plugins/cronJob/actionHandlers/index.ts +4 -4
  36. package/src/plugins/cronJob/actionHandlers/runCronJob.ts +29 -29
  37. package/src/plugins/cronJob/routes/index.ts +3 -3
  38. package/src/plugins/cronJob/routes/runCronJob.ts +15 -15
  39. package/src/plugins/dataManage/actionHandlers/addEntityRelations.ts +20 -20
  40. package/src/plugins/dataManage/actionHandlers/countCollectionEntities.ts +15 -15
  41. package/src/plugins/dataManage/actionHandlers/createCollectionEntitiesBatch.ts +42 -42
  42. package/src/plugins/dataManage/actionHandlers/createCollectionEntity.ts +24 -24
  43. package/src/plugins/dataManage/actionHandlers/findCollectionEntities.ts +26 -26
  44. package/src/plugins/dataManage/actionHandlers/findCollectionEntityById.ts +21 -21
  45. package/src/plugins/dataManage/actionHandlers/queryDatabase.ts +22 -22
  46. package/src/plugins/dataManage/actionHandlers/removeEntityRelations.ts +20 -20
  47. package/src/plugins/dataManage/actionHandlers/updateCollectionEntityById.ts +35 -35
  48. package/src/plugins/fileManage/actionHandlers/downloadDocument.ts +36 -36
  49. package/src/plugins/fileManage/actionHandlers/uploadFile.ts +33 -33
  50. package/src/plugins/fileManage/routes/downloadDocument.ts +15 -15
  51. package/src/plugins/fileManage/routes/downloadFile.ts +15 -15
  52. package/src/plugins/fileManage/routes/index.ts +5 -5
  53. package/src/plugins/fileManage/routes/uploadFile.ts +15 -15
  54. package/src/plugins/metaManage/actionHandlers/getMetaModelDetail.ts +10 -10
  55. package/src/plugins/metaManage/actionHandlers/listMetaModels.ts +9 -9
  56. package/src/plugins/metaManage/actionHandlers/listMetaRoutes.ts +9 -9
  57. package/src/plugins/routeManage/actionHandlers/httpProxy.ts +13 -13
  58. package/src/plugins/sequence/SequenceService.ts +81 -81
  59. package/src/plugins/sequence/actionHandlers/generateSn.ts +32 -32
  60. package/src/plugins/sequence/actionHandlers/index.ts +4 -4
  61. package/src/plugins/sequence/models/SequenceAutoIncrementRecord.ts +49 -49
  62. package/src/plugins/sequence/models/SequenceRule.ts +42 -42
  63. package/src/plugins/sequence/models/index.ts +4 -4
  64. package/src/plugins/sequence/routes/generateSn.ts +15 -15
  65. package/src/plugins/sequence/routes/index.ts +3 -3
  66. package/src/plugins/sequence/segment-utility.ts +11 -11
  67. package/src/plugins/sequence/segments/index.ts +9 -9
  68. package/src/plugins/serverOperation/ServerOperationPlugin.ts +91 -91
  69. package/src/plugins/serverOperation/ServerOperationPluginTypes.ts +15 -15
  70. package/src/plugins/serverOperation/actionHandlers/index.ts +4 -4
  71. package/src/plugins/setting/SettingService.ts +213 -213
  72. package/src/plugins/setting/actionHandlers/getSystemSettingValues.ts +30 -30
  73. package/src/plugins/setting/actionHandlers/getUserSettingValues.ts +38 -38
  74. package/src/plugins/setting/actionHandlers/index.ts +6 -6
  75. package/src/plugins/setting/actionHandlers/setSystemSettingValues.ts +30 -30
  76. package/src/plugins/setting/models/SystemSettingGroupSetting.ts +57 -57
  77. package/src/plugins/setting/models/SystemSettingItem.ts +42 -42
  78. package/src/plugins/setting/models/SystemSettingItemSetting.ts +73 -73
  79. package/src/plugins/setting/models/UserSettingGroupSetting.ts +57 -57
  80. package/src/plugins/setting/models/UserSettingItem.ts +49 -49
  81. package/src/plugins/setting/models/UserSettingItemSetting.ts +73 -73
  82. package/src/plugins/setting/models/index.ts +8 -8
  83. package/src/plugins/setting/routes/getSystemSettingValues.ts +15 -15
  84. package/src/plugins/setting/routes/getUserSettingValues.ts +15 -15
  85. package/src/plugins/setting/routes/index.ts +5 -5
  86. package/src/plugins/setting/routes/setSystemSettingValues.ts +15 -15
  87. package/src/plugins/stateMachine/actionHandlers/index.ts +4 -4
  88. package/src/plugins/stateMachine/actionHandlers/sendStateMachineEvent.ts +51 -51
  89. package/src/plugins/stateMachine/models/StateMachine.ts +42 -42
  90. package/src/plugins/stateMachine/models/index.ts +3 -3
  91. package/src/plugins/stateMachine/routes/index.ts +3 -3
  92. package/src/plugins/stateMachine/routes/sendStateMachineEvent.ts +15 -15
  93. package/src/polyfill.ts +5 -5
  94. package/src/proxy/mod.ts +38 -38
  95. package/src/utilities/accessControlUtility.ts +33 -33
  96. package/src/utilities/fsUtility.ts +61 -61
  97. package/src/utilities/httpUtility.ts +19 -19
  98. package/src/utilities/jwtUtility.ts +26 -26
  99. package/src/utilities/timeUtility.ts +9 -9
  100. package/tsconfig.json +19 -19
package/dist/index.js CHANGED
@@ -2262,6 +2262,9 @@ function convertEntityOrderByToRowOrderBy(server, model, baseModel, orderByList)
2262
2262
  }
2263
2263
  if (relationField) {
2264
2264
  const relationProperty = getEntityPropertyByCode(server, model, relationField);
2265
+ if (!relationProperty) {
2266
+ throw new Error(`Property '${relationProperty}' was not found in ${model.namespace}.${model.singularCode}`);
2267
+ }
2265
2268
  if (!isRelationProperty(relationProperty)) {
2266
2269
  throw new Error("orderBy[].relation must be a one-relation property.");
2267
2270
  }
@@ -2318,7 +2321,12 @@ async function findEntities(server, dataAccessor, options) {
2318
2321
  let relationOptions = options.relations || {};
2319
2322
  let relationPropertyCodes = Object.keys(relationOptions) || [];
2320
2323
  if (!options.properties || !options.properties.length) {
2321
- propertiesToSelect = getEntityPropertiesIncludingBase(server, model).filter((property) => !isRelationProperty(property) || relationPropertyCodes.includes(property.code));
2324
+ propertiesToSelect = getEntityPropertiesIncludingBase(server, model).filter((property) => {
2325
+ if (!property) {
2326
+ throw new Error(`Property '${property}' was not found in ${model.namespace}.${model.singularCode}`);
2327
+ }
2328
+ return !options.keepNonPropertyFields || isRelationProperty(property) || relationPropertyCodes.includes(property.code);
2329
+ });
2322
2330
  }
2323
2331
  else {
2324
2332
  propertiesToSelect = getEntityPropertiesIncludingBase(server, model).filter((property) => options.properties.includes(property.code) || relationPropertyCodes.includes(property.code));
@@ -2326,6 +2334,9 @@ async function findEntities(server, dataAccessor, options) {
2326
2334
  const columnsToSelect = [];
2327
2335
  const relationPropertiesToSelect = [];
2328
2336
  lodash.forEach(propertiesToSelect, (property) => {
2337
+ if (!property) {
2338
+ throw new Error(`Property '${property}' was not found in ${model.namespace}.${model.singularCode}`);
2339
+ }
2329
2340
  if (isRelationProperty(property)) {
2330
2341
  relationPropertiesToSelect.push(property);
2331
2342
  if (property.relation === "one" && !property.linkTableName) {
@@ -2864,8 +2875,7 @@ async function createEntity(server, dataAccessor, options, plugin) {
2864
2875
  lodash.keys(entity).forEach((propertyCode) => {
2865
2876
  const property = getEntityPropertyByCode(server, model, propertyCode);
2866
2877
  if (!property) {
2867
- // Unknown property
2868
- return;
2878
+ throw new Error(`Property '${property}' was not found in ${model.namespace}.${model.singularCode}`);
2869
2879
  }
2870
2880
  if (isRelationProperty(property)) {
2871
2881
  if (property.relation === "many") {
@@ -3097,8 +3107,7 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
3097
3107
  lodash.keys(changes).forEach((propertyCode) => {
3098
3108
  const property = getEntityPropertyByCode(server, model, propertyCode);
3099
3109
  if (!property) {
3100
- // Unknown property
3101
- return;
3110
+ throw new Error(`Property '${property}' was not found in ${model.namespace}.${model.singularCode}`);
3102
3111
  }
3103
3112
  if (isRelationProperty(property)) {
3104
3113
  if (property.relation === "many") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.1.82",
3
+ "version": "0.1.83",
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
+ };