@ruiapp/rapid-core 0.0.1

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 (134) hide show
  1. package/dist/bootstrapApplicationConfig.d.ts +3 -0
  2. package/dist/core/eventManager.d.ts +7 -0
  3. package/dist/core/http-types.d.ts +3 -0
  4. package/dist/core/httpHandler.d.ts +18 -0
  5. package/dist/core/plugin.d.ts +6 -0
  6. package/dist/core/pluginManager.d.ts +27 -0
  7. package/dist/core/request.d.ts +15 -0
  8. package/dist/core/response.d.ts +17 -0
  9. package/dist/core/routeContext.d.ts +17 -0
  10. package/dist/core/routesBuilder.d.ts +4 -0
  11. package/dist/core/server.d.ts +83 -0
  12. package/dist/dataAccess/dataAccessor.d.ts +20 -0
  13. package/dist/dataAccess/entityManager.d.ts +6 -0
  14. package/dist/dataAccess/entityMapper.d.ts +3 -0
  15. package/dist/dataAccess/filterHelper.d.ts +2 -0
  16. package/dist/dataAccess/propertyMapper.d.ts +3 -0
  17. package/dist/deno-std/assert/assert.d.ts +2 -0
  18. package/dist/deno-std/assert/assertion_error.d.ts +4 -0
  19. package/dist/deno-std/datetime/to_imf.d.ts +17 -0
  20. package/dist/deno-std/http/cookie.d.ts +134 -0
  21. package/dist/helpers/entityHelpers.d.ts +1 -0
  22. package/dist/helpers/inputHelper.d.ts +1 -0
  23. package/dist/helpers/runCollectionEntityHttpHandler.d.ts +5 -0
  24. package/dist/index.d.ts +7 -0
  25. package/dist/index.js +3590 -0
  26. package/dist/plugins/authManager/httpHandlers/createSession.d.ts +8 -0
  27. package/dist/plugins/authManager/httpHandlers/deleteSession.d.ts +4 -0
  28. package/dist/plugins/authManager/httpHandlers/getMyProfile.d.ts +4 -0
  29. package/dist/plugins/authManager/httpHandlers/index.d.ts +5 -0
  30. package/dist/plugins/authManager/mod.d.ts +16 -0
  31. package/dist/plugins/authManager/models/AccessToken.d.ts +3 -0
  32. package/dist/plugins/authManager/models/index.d.ts +2 -0
  33. package/dist/plugins/authManager/routes/getMyProfile.d.ts +3 -0
  34. package/dist/plugins/authManager/routes/index.d.ts +2 -0
  35. package/dist/plugins/authManager/routes/signin.d.ts +3 -0
  36. package/dist/plugins/authManager/routes/signout.d.ts +3 -0
  37. package/dist/plugins/dataManager/httpHandlers/addEntityRelations.d.ts +4 -0
  38. package/dist/plugins/dataManager/httpHandlers/countCollectionEntities.d.ts +4 -0
  39. package/dist/plugins/dataManager/httpHandlers/createCollectionEntitiesBatch.d.ts +4 -0
  40. package/dist/plugins/dataManager/httpHandlers/createCollectionEntity.d.ts +4 -0
  41. package/dist/plugins/dataManager/httpHandlers/deleteCollectionEntityById.d.ts +4 -0
  42. package/dist/plugins/dataManager/httpHandlers/findCollectionEntities.d.ts +4 -0
  43. package/dist/plugins/dataManager/httpHandlers/findCollectionEntityById.d.ts +4 -0
  44. package/dist/plugins/dataManager/httpHandlers/queryDatabase.d.ts +4 -0
  45. package/dist/plugins/dataManager/httpHandlers/removeEntityRelations.d.ts +4 -0
  46. package/dist/plugins/dataManager/httpHandlers/updateCollectionEntityById.d.ts +4 -0
  47. package/dist/plugins/dataManager/mod.d.ts +16 -0
  48. package/dist/plugins/metaManager/httpHandlers/getMetaModelDetail.d.ts +4 -0
  49. package/dist/plugins/metaManager/httpHandlers/listMetaModels.d.ts +4 -0
  50. package/dist/plugins/metaManager/mod.d.ts +15 -0
  51. package/dist/plugins/routeManager/httpHandlers/httpProxy.d.ts +4 -0
  52. package/dist/plugins/routeManager/httpHandlers/listMetaRoutes.d.ts +4 -0
  53. package/dist/plugins/routeManager/mod.d.ts +15 -0
  54. package/dist/plugins/webhooks/mod.d.ts +24 -0
  55. package/dist/plugins/webhooks/pluginConfig.d.ts +48 -0
  56. package/dist/polyfill.d.ts +1 -0
  57. package/dist/proxy/mod.d.ts +13 -0
  58. package/dist/proxy/types.d.ts +17 -0
  59. package/dist/queryBuilder/index.d.ts +1 -0
  60. package/dist/queryBuilder/queryBuilder.d.ts +34 -0
  61. package/dist/server.d.ts +31 -0
  62. package/dist/types.d.ts +327 -0
  63. package/dist/utilities/httpUtility.d.ts +1 -0
  64. package/dist/utilities/jwtUtility.d.ts +8 -0
  65. package/dist/utilities/rapidUtility.d.ts +2 -0
  66. package/dist/utilities/typeUtility.d.ts +3 -0
  67. package/package.json +29 -0
  68. package/rollup.config.js +20 -0
  69. package/src/bootstrapApplicationConfig.ts +524 -0
  70. package/src/core/eventManager.ts +21 -0
  71. package/src/core/http-types.ts +4 -0
  72. package/src/core/httpHandler.ts +29 -0
  73. package/src/core/plugin.ts +13 -0
  74. package/src/core/pluginManager.ts +143 -0
  75. package/src/core/request.ts +23 -0
  76. package/src/core/response.ts +77 -0
  77. package/src/core/routeContext.ts +38 -0
  78. package/src/core/routesBuilder.ts +86 -0
  79. package/src/core/server.ts +144 -0
  80. package/src/dataAccess/dataAccessor.ts +110 -0
  81. package/src/dataAccess/entityManager.ts +651 -0
  82. package/src/dataAccess/entityMapper.ts +74 -0
  83. package/src/dataAccess/filterHelper.ts +47 -0
  84. package/src/dataAccess/propertyMapper.ts +27 -0
  85. package/src/deno-std/assert/assert.ts +9 -0
  86. package/src/deno-std/assert/assertion_error.ts +7 -0
  87. package/src/deno-std/datetime/to_imf.ts +47 -0
  88. package/src/deno-std/http/cookie.ts +398 -0
  89. package/src/helpers/entityHelpers.ts +24 -0
  90. package/src/helpers/inputHelper.ts +11 -0
  91. package/src/helpers/runCollectionEntityHttpHandler.ts +34 -0
  92. package/src/index.ts +12 -0
  93. package/src/plugins/authManager/httpHandlers/createSession.ts +57 -0
  94. package/src/plugins/authManager/httpHandlers/deleteSession.ts +22 -0
  95. package/src/plugins/authManager/httpHandlers/getMyProfile.ts +43 -0
  96. package/src/plugins/authManager/httpHandlers/index.ts +10 -0
  97. package/src/plugins/authManager/mod.ts +56 -0
  98. package/src/plugins/authManager/models/AccessToken.ts +56 -0
  99. package/src/plugins/authManager/models/index.ts +5 -0
  100. package/src/plugins/authManager/routes/getMyProfile.ts +15 -0
  101. package/src/plugins/authManager/routes/index.ts +9 -0
  102. package/src/plugins/authManager/routes/signin.ts +15 -0
  103. package/src/plugins/authManager/routes/signout.ts +15 -0
  104. package/src/plugins/dataManager/httpHandlers/addEntityRelations.ts +76 -0
  105. package/src/plugins/dataManager/httpHandlers/countCollectionEntities.ts +22 -0
  106. package/src/plugins/dataManager/httpHandlers/createCollectionEntitiesBatch.ts +57 -0
  107. package/src/plugins/dataManager/httpHandlers/createCollectionEntity.ts +43 -0
  108. package/src/plugins/dataManager/httpHandlers/deleteCollectionEntityById.ts +38 -0
  109. package/src/plugins/dataManager/httpHandlers/findCollectionEntities.ts +35 -0
  110. package/src/plugins/dataManager/httpHandlers/findCollectionEntityById.ts +30 -0
  111. package/src/plugins/dataManager/httpHandlers/queryDatabase.ts +29 -0
  112. package/src/plugins/dataManager/httpHandlers/removeEntityRelations.ts +72 -0
  113. package/src/plugins/dataManager/httpHandlers/updateCollectionEntityById.ts +53 -0
  114. package/src/plugins/dataManager/mod.ts +150 -0
  115. package/src/plugins/metaManager/httpHandlers/getMetaModelDetail.ts +14 -0
  116. package/src/plugins/metaManager/httpHandlers/listMetaModels.ts +13 -0
  117. package/src/plugins/metaManager/mod.ts +419 -0
  118. package/src/plugins/routeManager/httpHandlers/httpProxy.ts +15 -0
  119. package/src/plugins/routeManager/httpHandlers/listMetaRoutes.ts +13 -0
  120. package/src/plugins/routeManager/mod.ts +97 -0
  121. package/src/plugins/webhooks/mod.ts +144 -0
  122. package/src/plugins/webhooks/pluginConfig.ts +74 -0
  123. package/src/polyfill.ts +5 -0
  124. package/src/proxy/mod.ts +47 -0
  125. package/src/proxy/types.ts +21 -0
  126. package/src/queryBuilder/index.ts +1 -0
  127. package/src/queryBuilder/queryBuilder.ts +424 -0
  128. package/src/server.ts +192 -0
  129. package/src/types.ts +438 -0
  130. package/src/utilities/httpUtility.ts +23 -0
  131. package/src/utilities/jwtUtility.ts +16 -0
  132. package/src/utilities/rapidUtility.ts +5 -0
  133. package/src/utilities/typeUtility.ts +11 -0
  134. package/tsconfig.json +19 -0
@@ -0,0 +1,143 @@
1
+ import { RpdApplicationConfig } from "~/types";
2
+ import Plugin from "./plugin";
3
+ import * as metaManager from "~/plugins/metaManager/mod";
4
+ import * as dataManager from "~/plugins/dataManager/mod";
5
+ import * as routeManager from "~/plugins/routeManager/mod";
6
+ import * as webhooks from "~/plugins/webhooks/mod";
7
+ import * as authManager from "~/plugins/authManager/mod";
8
+ import { IRpdServer, IRpdServerPlugin } from "./server";
9
+
10
+ const plugins: IRpdServerPlugin[] = [];
11
+
12
+ export async function loadPlugins() {
13
+ plugins.push(metaManager);
14
+ plugins.push(dataManager);
15
+ plugins.push(routeManager);
16
+ plugins.push(webhooks);
17
+ plugins.push(authManager);
18
+ }
19
+
20
+ /** 初始化插件时调用。 */
21
+ export async function initPlugins(server: IRpdServer) {
22
+ for (const plugin of plugins) {
23
+ const pluginInstance = new Plugin(plugin.code);
24
+ await plugin.initPlugin(pluginInstance, server);
25
+ }
26
+ }
27
+
28
+ /** 注册中间件 */
29
+ export async function registerMiddlewares(server: IRpdServer) {
30
+ for (const plugin of plugins) {
31
+ if (plugin.registerMiddlewares) {
32
+ await plugin.registerMiddlewares(server);
33
+ }
34
+ }
35
+ }
36
+
37
+ /** 注册接口动作处理程序 */
38
+ export async function registerHttpHandlers(server: IRpdServer) {
39
+ for (const plugin of plugins) {
40
+ if (plugin.registerHttpHandlers) {
41
+ await plugin.registerHttpHandlers(server);
42
+ }
43
+ }
44
+ }
45
+
46
+ /** 注册事件处理程序 */
47
+ export async function registerEventHandlers(server: IRpdServer) {
48
+ for (const plugin of plugins) {
49
+ if (plugin.registerEventHandlers) {
50
+ await plugin.registerEventHandlers(server);
51
+ }
52
+ }
53
+ }
54
+
55
+ /** 注册消息处理程序 */
56
+ export async function registerMessageHandlers(server: IRpdServer) {
57
+ for (const plugin of plugins) {
58
+ if (plugin.registerMessageHandlers) {
59
+ await plugin.registerMessageHandlers(server);
60
+ }
61
+ }
62
+ }
63
+
64
+ /** 注册任务处理程序 */
65
+ export async function registerTaskProcessors(server: IRpdServer) {
66
+ for (const plugin of plugins) {
67
+ if (plugin.registerTaskProcessors) {
68
+ await plugin.registerTaskProcessors(server);
69
+ }
70
+ }
71
+ }
72
+
73
+ /** 在加载应用前调用。 */
74
+ export async function onLoadingApplication(
75
+ server: IRpdServer,
76
+ applicationConfig: RpdApplicationConfig,
77
+ ) {
78
+ for (const plugin of plugins) {
79
+ if (plugin.onLoadingApplication) {
80
+ await plugin.onLoadingApplication(server, applicationConfig);
81
+ }
82
+ }
83
+ }
84
+
85
+ /** 配置数据模型 */
86
+ export async function configureModels(
87
+ server: IRpdServer,
88
+ applicationConfig: RpdApplicationConfig,
89
+ ) {
90
+ for (const plugin of plugins) {
91
+ if (plugin.configureModels) {
92
+ await plugin.configureModels(server, applicationConfig);
93
+ }
94
+ }
95
+ }
96
+
97
+ /** 配置模型属性 */
98
+ export async function configureModelProperties(
99
+ server: IRpdServer,
100
+ applicationConfig: RpdApplicationConfig,
101
+ ) {
102
+ for (const plugin of plugins) {
103
+ if (plugin.configureModelProperties) {
104
+ await plugin.configureModelProperties(server, applicationConfig);
105
+ }
106
+ }
107
+ }
108
+
109
+ /** 配置路由 */
110
+ export async function configureRoutes(
111
+ server: IRpdServer,
112
+ applicationConfig: RpdApplicationConfig,
113
+ ) {
114
+ for (const plugin of plugins) {
115
+ if (plugin.configureRoutes) {
116
+ await plugin.configureRoutes(server, applicationConfig);
117
+ }
118
+ }
119
+ }
120
+
121
+ /** 在应用配置加载完成后调用。此时插件可以进行一些数据的初始化工作。 */
122
+ export async function onApplicationLoaded(
123
+ server: IRpdServer,
124
+ applicationConfig: RpdApplicationConfig,
125
+ ) {
126
+ for (const plugin of plugins) {
127
+ if (plugin.onApplicationLoaded) {
128
+ await plugin.onApplicationLoaded(server, applicationConfig);
129
+ }
130
+ }
131
+ }
132
+
133
+ /** 在应用准备完成后调用。此时服务器已经可以处理网络请求。 */
134
+ export async function onApplicationReady(
135
+ server: IRpdServer,
136
+ applicationConfig: RpdApplicationConfig,
137
+ ) {
138
+ for (const plugin of plugins) {
139
+ if (plugin.onApplicationReady) {
140
+ await plugin.onApplicationReady(server, applicationConfig);
141
+ }
142
+ }
143
+ }
@@ -0,0 +1,23 @@
1
+ export const GlobalRequest = global.Request;
2
+
3
+
4
+ export interface RapidRequestBody {
5
+ type: string;
6
+ value: any;
7
+ }
8
+
9
+ export class RapidRequest {
10
+ method: string;
11
+ url: URL;
12
+ hasBody: boolean;
13
+
14
+ constructor(init: RequestInit) {
15
+ }
16
+
17
+ body(): RapidRequestBody {
18
+ return {
19
+ type: "",
20
+ value: {}
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,77 @@
1
+ import { isArray, isObject } from "lodash";
2
+ import { HttpStatus, ResponseData } from "./http-types";
3
+
4
+ export const GlobalResponse = global.Response;
5
+
6
+
7
+ function mergeHeaders(target: Headers, source: HeadersInit) {
8
+ if (source instanceof Headers) {
9
+ for (const keyValuePair of source.entries()) {
10
+ target.set(keyValuePair[0], keyValuePair[1]);
11
+ }
12
+ } else if (isArray(source)) {
13
+ for (const keyValuePair of source) {
14
+ target.set(keyValuePair[0], keyValuePair[1]);
15
+ }
16
+ } else if (isObject(source)) {
17
+ Object.entries(source).forEach(([key, value]) => target.set(key, value));
18
+ }
19
+ return target;
20
+ }
21
+
22
+ interface NewResponseOptions {
23
+ body?: ResponseData;
24
+ status?: HttpStatus;
25
+ headers?: HeadersInit;
26
+ }
27
+
28
+ function newResponse(options: NewResponseOptions) {
29
+ return new Response(options.body, {
30
+ headers: options.headers,
31
+ status: options.status || 200,
32
+ });
33
+ }
34
+
35
+ export class RapidResponse {
36
+ #response: Response;
37
+ status: number;
38
+ body: BodyInit;
39
+ headers: Headers;
40
+
41
+ constructor(body?: BodyInit, init?: ResponseInit) {
42
+ this.body = body;
43
+ this.headers = new Headers(init.headers);
44
+ this.status = init.status;
45
+ }
46
+
47
+ json(
48
+ obj: any,
49
+ status?: HttpStatus,
50
+ headers?: HeadersInit,
51
+ ) {
52
+ const body = JSON.stringify(obj);
53
+ const responseHeaders = new Headers(this.headers);
54
+ if (headers) {
55
+ mergeHeaders(responseHeaders, headers);
56
+ }
57
+ this.#response = newResponse({body, status: status || 200, headers: responseHeaders});
58
+ }
59
+
60
+ redirect(location: string, status?: HttpStatus) {
61
+ this.headers.set("Location", location);
62
+ this.#response = newResponse({
63
+ headers: this.headers,
64
+ status: status || 302,
65
+ });
66
+ }
67
+
68
+ getResponse() {
69
+ if (!this.#response) {
70
+ this.#response = new Response(this.body, {
71
+ status: this.status || (this.body ? 200 : 404),
72
+ headers: this.headers,
73
+ });
74
+ }
75
+ return this.#response;
76
+ }
77
+ }
@@ -0,0 +1,38 @@
1
+ import { isArray, isObject } from "lodash";
2
+ import { RapidRequest } from "./request";
3
+ import { RapidResponse } from "./response";
4
+ import { HttpStatus, ResponseData } from "./http-types";
5
+
6
+ export type Next = () => Promise<void>;
7
+
8
+ export class RouteContext {
9
+ readonly request: RapidRequest;
10
+ readonly response: RapidResponse;
11
+ readonly state: Record<string, any>;
12
+ method: string;
13
+ path: string;
14
+ status: HttpStatus;
15
+ params: Record<string, string>;
16
+
17
+ constructor(request: RapidRequest) {
18
+ this.request = request;
19
+ this.state = {};
20
+ this.response = new RapidResponse();
21
+ }
22
+
23
+ set(headerName: string, headerValue: string) {
24
+ this.response.headers.set(headerName, headerValue);
25
+ }
26
+
27
+ json(
28
+ obj: any,
29
+ status?: HttpStatus,
30
+ headers?: HeadersInit,
31
+ ) {
32
+ this.response.json(obj, status, headers);
33
+ }
34
+
35
+ redirect(url: string, status?: HttpStatus) {
36
+ this.response.redirect(url, status);
37
+ }
38
+ }
@@ -0,0 +1,86 @@
1
+ import Router from "koa-tree-router";
2
+ import qs from "qs";
3
+ import { HttpHandlerContext } from "~/core/httpHandler";
4
+ import { IRpdServer } from "~/core/server";
5
+ import { RpdApplicationConfig } from "~/types";
6
+ import { isNullOrUndefined } from "~/utilities/typeUtility";
7
+ import { Next, RouteContext } from "./routeContext";
8
+
9
+ export async function buildRoutes(
10
+ server: IRpdServer,
11
+ applicationConfig: RpdApplicationConfig,
12
+ ) {
13
+ const router = new Router();
14
+
15
+ applicationConfig.routes.forEach((routeConfig) => {
16
+ if (routeConfig.type !== "RESTful") {
17
+ return;
18
+ }
19
+
20
+ (router as any)[routeConfig.method](
21
+ routeConfig.endpoint,
22
+ async (routerContext: RouteContext, next: Next) => {
23
+ const { request, params } = routerContext;
24
+
25
+ let search = request.url.search;
26
+ if (search && search.startsWith("?")) {
27
+ search = search.substring(1);
28
+ }
29
+ const query = qs.parse(search);
30
+ const input = Object.assign({}, params, query);
31
+
32
+ const requestMethod = request.method;
33
+ if (
34
+ (requestMethod === "POST" || requestMethod === "PUT" ||
35
+ requestMethod === "PATCH") && request.hasBody
36
+ ) {
37
+ const body = request.body();
38
+ if (body.type === "form-data") {
39
+ const formDataReader = body.value;
40
+ const formDataBody = await formDataReader.read({ maxFileSize: 1073741824 /* 1GB */});
41
+ Object.assign(input, {
42
+ formData: formDataBody
43
+ });
44
+ } else {
45
+ Object.assign(input, await body.value);
46
+ }
47
+ }
48
+
49
+ // Normalize input value
50
+
51
+ console.debug(`${requestMethod} ${request.url.toString()}`);
52
+ console.debug(`input: ${JSON.stringify(input)}`);
53
+
54
+ let handlerContext: HttpHandlerContext = {
55
+ routerContext,
56
+ next,
57
+ server,
58
+ applicationConfig,
59
+ input,
60
+ };
61
+
62
+ for (const handlerConfig of routeConfig.handlers) {
63
+ const handler = server.getHttpHandlerByCode(handlerConfig.code);
64
+ if (!handler) {
65
+ throw new Error("Unknown handler: " + handlerConfig.code);
66
+ }
67
+
68
+ const result = handler(handlerContext, handlerConfig.config);
69
+ if (result instanceof Promise) {
70
+ await result;
71
+ }
72
+ }
73
+
74
+ if (handlerContext.status) {
75
+ routerContext.status = handlerContext.status;
76
+ }
77
+
78
+ if (!isNullOrUndefined(handlerContext.output)) {
79
+ routerContext.json(handlerContext.output);
80
+ }
81
+ },
82
+ );
83
+ });
84
+
85
+ return router.routes();
86
+ }
@@ -0,0 +1,144 @@
1
+ import { GetDataAccessorOptions, GetModelOptions, IDatabaseConfig, IPluginInstance, IQueryBuilder, IRpdDataAccessor, RapidServerConfig, RpdApplicationConfig, RpdDataModel, RpdServerEventTypes } from "~/types";
2
+ import { IPluginHttpHandler, HttpRequestHandler } from "./httpHandler";
3
+ import { Next } from "./routeContext";
4
+
5
+ export interface IRpdServer {
6
+ config: RapidServerConfig;
7
+ databaseConfig: IDatabaseConfig;
8
+ queryBuilder: IQueryBuilder;
9
+ queryDatabaseObject: (
10
+ sql: string,
11
+ params?: unknown[] | Record<string, unknown>,
12
+ ) => Promise<any[]>;
13
+ tryQueryDatabaseObject: (
14
+ sql: string,
15
+ params?: unknown[] | Record<string, unknown>,
16
+ ) => Promise<any[]>;
17
+ registerMiddleware(middleware: any): void;
18
+ registerHttpHandler(
19
+ plugin: IPluginInstance,
20
+ options: IPluginHttpHandler,
21
+ ): void;
22
+ getHttpHandlerByCode(code: string): HttpRequestHandler | undefined;
23
+ getDataAccessor<T = any>(
24
+ options: GetDataAccessorOptions,
25
+ ): IRpdDataAccessor<T>;
26
+ getApplicationConfig(): RpdApplicationConfig;
27
+ getModel(options: GetModelOptions): RpdDataModel | undefined;
28
+ registerEventHandler<K extends keyof RpdServerEventTypes>(
29
+ eventName: K,
30
+ listener: (...args: RpdServerEventTypes[K]) => void,
31
+ ): this;
32
+ emitEvent<K extends keyof RpdServerEventTypes>(
33
+ eventName: K,
34
+ sender: IPluginInstance,
35
+ payload: RpdServerEventTypes[K][1],
36
+ ): void;
37
+ handleRequest(request: Request, next: Next): Promise<Response>;
38
+ }
39
+
40
+
41
+
42
+ export type RpdConfigurationItemTypes =
43
+ | "integer"
44
+ | "text"
45
+ | "boolean"
46
+ | "date"
47
+ | "datetime"
48
+ | "json";
49
+
50
+ export interface RpdConfigurationItemOptions {
51
+ /**
52
+ * 配置项名称。可以包含中文。
53
+ */
54
+ name: string;
55
+ /**
56
+ * 配置项代码。
57
+ */
58
+ code: string;
59
+ /**
60
+ * 配置项类型。
61
+ */
62
+ type: RpdConfigurationItemTypes;
63
+ /**
64
+ * 是否必须有值。默认为 false。
65
+ */
66
+ required?: boolean;
67
+ /**
68
+ * 默认值。使用默认值的 JavaScript 字面量表示。
69
+ */
70
+ defaultValue?: string;
71
+ }
72
+
73
+ export type RpdServerPluginExtendingAbilities =
74
+ | /** 是指提供处理网络请求的middleware的能力。 */ "extendMiddleware"
75
+ | /** 是指增加系统中的集合的能力。 */ "extendModel"
76
+ | /** 是指可以对模型增加属性的能力。 */ "extendProperty"
77
+ | /** 是指增加接口动作的能力。 */ "extendHttpHandler"
78
+ | /** 是指增加或者修改接口定义的能力。 */ "extendRoute"
79
+ | /** 是指对实体数据进行标准化的能力。 */ "normalizeEntity"
80
+ | /** 处理事件总线发送过来的事件的能力。 */ "handleEvent"
81
+ | /** 处理消息队列发送过来的消息的能力。 */ "handleMessage"
82
+ | /** 对特定任务进行处理的能力。 */ "processTask";
83
+
84
+ export interface RpdServerPluginConfigurableTargetOptions {
85
+ targetCode: string;
86
+
87
+ configurations: RpdConfigurationItemOptions[];
88
+ }
89
+
90
+ export interface IRpdServerPlugin {
91
+ /** 插件代码 */
92
+ code: string;
93
+ /** 插件描述 */
94
+ description: string;
95
+ /** 插件可以提供哪些扩展能力 */
96
+ extendingAbilities: RpdServerPluginExtendingAbilities[];
97
+ /** 插件可以配置的目标实体,以及和配置目标相关的配置项 */
98
+ configurableTargets?: RpdServerPluginConfigurableTargetOptions[];
99
+ /** 插件的全局配置项 */
100
+ configurations?: RpdConfigurationItemOptions[];
101
+ /** 初始化插件时调用。插件可以在此时进行一些内部对象的初始化工作。 */
102
+ initPlugin: (plugin: IPluginInstance, server: IRpdServer) => Promise<any>;
103
+ /** 注册中间件 */
104
+ registerMiddlewares?: (server: IRpdServer) => Promise<any>;
105
+ /** 注册接口动作处理程序 */
106
+ registerHttpHandlers?: (server: IRpdServer) => Promise<any>;
107
+ /** 注册事件处理程序 */
108
+ registerEventHandlers?: (server: IRpdServer) => Promise<any>;
109
+ /** 注册消息处理程序 */
110
+ registerMessageHandlers?: (server: IRpdServer) => Promise<any>;
111
+ /** 注册任务处理程序 */
112
+ registerTaskProcessors?: (server: IRpdServer) => Promise<any>;
113
+ /** 在加载应用前调用。 */
114
+ onLoadingApplication?: (
115
+ server: IRpdServer,
116
+ applicationConfig: RpdApplicationConfig,
117
+ ) => Promise<any>;
118
+ /** 配置数据集合 */
119
+ configureModels?: (
120
+ server: IRpdServer,
121
+ applicationConfig: RpdApplicationConfig,
122
+ ) => Promise<any>;
123
+ /** 配置模型属性 */
124
+ configureModelProperties?: (
125
+ server: IRpdServer,
126
+ applicationConfig: RpdApplicationConfig,
127
+ ) => Promise<any>;
128
+ /** 配置路由 */
129
+ configureRoutes?: (
130
+ server: IRpdServer,
131
+ applicationConfig: RpdApplicationConfig,
132
+ ) => Promise<any>;
133
+ /** 在应用配置加载完成后调用。此时插件可以进行一些数据的初始化工作。 */
134
+ onApplicationLoaded?: (
135
+ server: IRpdServer,
136
+ applicationConfig: RpdApplicationConfig,
137
+ ) => Promise<any>;
138
+ /** 在应用准备完成后调用。此时服务器已经可以处理网络请求,可以对外广播消息。 */
139
+ onApplicationReady?: (
140
+ server: IRpdServer,
141
+ applicationConfig: RpdApplicationConfig,
142
+ ) => Promise<any>;
143
+ }
144
+
@@ -0,0 +1,110 @@
1
+ import * as _ from "lodash";
2
+ import {
3
+ CountEntityOptions,
4
+ FindEntityOptions,
5
+ CreateEntityOptions,
6
+ IRpdDataAccessor,
7
+ RpdDataModel,
8
+ UpdateEntityOptions,
9
+ IDatabaseAccessor,
10
+ } from "~/types";
11
+ import QueryBuilder from "~/queryBuilder/queryBuilder";
12
+
13
+ export interface IDataAccessorOptions {
14
+ model: RpdDataModel;
15
+ queryBuilder: QueryBuilder;
16
+ }
17
+
18
+ export default class DataAccessor<T = any> implements IRpdDataAccessor<T> {
19
+ #model: RpdDataModel;
20
+ #queryBuilder: QueryBuilder;
21
+ #databaseAccessor: IDatabaseAccessor;
22
+
23
+ constructor(options: IDataAccessorOptions) {
24
+ this.#queryBuilder = options.queryBuilder;
25
+ this.#model = options.model;
26
+ }
27
+
28
+ getModel() {
29
+ return this.#model;
30
+ }
31
+
32
+ async create(entity: Partial<T>): Promise<T> {
33
+ const options: CreateEntityOptions = {
34
+ entity,
35
+ };
36
+ const query = this.#queryBuilder.insert(this.#model, options);
37
+ const result = await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
38
+ return _.first(result);
39
+ }
40
+
41
+ async updateById(id: any, entity: Partial<T>): Promise<{ count: number }> {
42
+ const options: UpdateEntityOptions = {
43
+ entity,
44
+ filters: [
45
+ {
46
+ field: "id",
47
+ operator: "eq",
48
+ value: id,
49
+ },
50
+ ],
51
+ };
52
+ const query = this.#queryBuilder.update(this.#model, options);
53
+ const result = await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
54
+ return _.first(result);
55
+ }
56
+
57
+ async find(options: FindEntityOptions): Promise<T[]> {
58
+ console.debug("DataAccessor.find() with options:", options);
59
+ const query = this.#queryBuilder.select(this.#model, options);
60
+ return await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
61
+ }
62
+
63
+ async findOne(options: FindEntityOptions): Promise<T> {
64
+ _.set(options, "pagination.limit", 1);
65
+ const list = await this.find(options);
66
+ return _.first(list);
67
+ }
68
+
69
+ async findById(id: any): Promise<T | null> {
70
+ const options: FindEntityOptions = {
71
+ filters: [
72
+ {
73
+ field: "id",
74
+ operator: "eq",
75
+ value: id,
76
+ },
77
+ ],
78
+ };
79
+ const query = this.#queryBuilder.select(this.#model, options);
80
+ const result = await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
81
+ return _.first(result);
82
+ }
83
+
84
+ async count(options: CountEntityOptions): Promise<any> {
85
+ const query = this.#queryBuilder.count(this.#model, options);
86
+ const result = await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
87
+
88
+ const row = _.first(result);
89
+ if (row) {
90
+ return row;
91
+ }
92
+ return {
93
+ count: 0,
94
+ };
95
+ }
96
+
97
+ async deleteById(id: any) {
98
+ const options: FindEntityOptions = {
99
+ filters: [
100
+ {
101
+ field: "id",
102
+ operator: "eq",
103
+ value: id,
104
+ },
105
+ ],
106
+ };
107
+ const query = this.#queryBuilder.delete(this.#model, options);
108
+ await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
109
+ }
110
+ }