@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.
- package/dist/bootstrapApplicationConfig.d.ts +3 -0
- package/dist/core/eventManager.d.ts +7 -0
- package/dist/core/http-types.d.ts +3 -0
- package/dist/core/httpHandler.d.ts +18 -0
- package/dist/core/plugin.d.ts +6 -0
- package/dist/core/pluginManager.d.ts +27 -0
- package/dist/core/request.d.ts +15 -0
- package/dist/core/response.d.ts +17 -0
- package/dist/core/routeContext.d.ts +17 -0
- package/dist/core/routesBuilder.d.ts +4 -0
- package/dist/core/server.d.ts +83 -0
- package/dist/dataAccess/dataAccessor.d.ts +20 -0
- package/dist/dataAccess/entityManager.d.ts +6 -0
- package/dist/dataAccess/entityMapper.d.ts +3 -0
- package/dist/dataAccess/filterHelper.d.ts +2 -0
- package/dist/dataAccess/propertyMapper.d.ts +3 -0
- package/dist/deno-std/assert/assert.d.ts +2 -0
- package/dist/deno-std/assert/assertion_error.d.ts +4 -0
- package/dist/deno-std/datetime/to_imf.d.ts +17 -0
- package/dist/deno-std/http/cookie.d.ts +134 -0
- package/dist/helpers/entityHelpers.d.ts +1 -0
- package/dist/helpers/inputHelper.d.ts +1 -0
- package/dist/helpers/runCollectionEntityHttpHandler.d.ts +5 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +3590 -0
- package/dist/plugins/authManager/httpHandlers/createSession.d.ts +8 -0
- package/dist/plugins/authManager/httpHandlers/deleteSession.d.ts +4 -0
- package/dist/plugins/authManager/httpHandlers/getMyProfile.d.ts +4 -0
- package/dist/plugins/authManager/httpHandlers/index.d.ts +5 -0
- package/dist/plugins/authManager/mod.d.ts +16 -0
- package/dist/plugins/authManager/models/AccessToken.d.ts +3 -0
- package/dist/plugins/authManager/models/index.d.ts +2 -0
- package/dist/plugins/authManager/routes/getMyProfile.d.ts +3 -0
- package/dist/plugins/authManager/routes/index.d.ts +2 -0
- package/dist/plugins/authManager/routes/signin.d.ts +3 -0
- package/dist/plugins/authManager/routes/signout.d.ts +3 -0
- package/dist/plugins/dataManager/httpHandlers/addEntityRelations.d.ts +4 -0
- package/dist/plugins/dataManager/httpHandlers/countCollectionEntities.d.ts +4 -0
- package/dist/plugins/dataManager/httpHandlers/createCollectionEntitiesBatch.d.ts +4 -0
- package/dist/plugins/dataManager/httpHandlers/createCollectionEntity.d.ts +4 -0
- package/dist/plugins/dataManager/httpHandlers/deleteCollectionEntityById.d.ts +4 -0
- package/dist/plugins/dataManager/httpHandlers/findCollectionEntities.d.ts +4 -0
- package/dist/plugins/dataManager/httpHandlers/findCollectionEntityById.d.ts +4 -0
- package/dist/plugins/dataManager/httpHandlers/queryDatabase.d.ts +4 -0
- package/dist/plugins/dataManager/httpHandlers/removeEntityRelations.d.ts +4 -0
- package/dist/plugins/dataManager/httpHandlers/updateCollectionEntityById.d.ts +4 -0
- package/dist/plugins/dataManager/mod.d.ts +16 -0
- package/dist/plugins/metaManager/httpHandlers/getMetaModelDetail.d.ts +4 -0
- package/dist/plugins/metaManager/httpHandlers/listMetaModels.d.ts +4 -0
- package/dist/plugins/metaManager/mod.d.ts +15 -0
- package/dist/plugins/routeManager/httpHandlers/httpProxy.d.ts +4 -0
- package/dist/plugins/routeManager/httpHandlers/listMetaRoutes.d.ts +4 -0
- package/dist/plugins/routeManager/mod.d.ts +15 -0
- package/dist/plugins/webhooks/mod.d.ts +24 -0
- package/dist/plugins/webhooks/pluginConfig.d.ts +48 -0
- package/dist/polyfill.d.ts +1 -0
- package/dist/proxy/mod.d.ts +13 -0
- package/dist/proxy/types.d.ts +17 -0
- package/dist/queryBuilder/index.d.ts +1 -0
- package/dist/queryBuilder/queryBuilder.d.ts +34 -0
- package/dist/server.d.ts +31 -0
- package/dist/types.d.ts +327 -0
- package/dist/utilities/httpUtility.d.ts +1 -0
- package/dist/utilities/jwtUtility.d.ts +8 -0
- package/dist/utilities/rapidUtility.d.ts +2 -0
- package/dist/utilities/typeUtility.d.ts +3 -0
- package/package.json +29 -0
- package/rollup.config.js +20 -0
- package/src/bootstrapApplicationConfig.ts +524 -0
- package/src/core/eventManager.ts +21 -0
- package/src/core/http-types.ts +4 -0
- package/src/core/httpHandler.ts +29 -0
- package/src/core/plugin.ts +13 -0
- package/src/core/pluginManager.ts +143 -0
- package/src/core/request.ts +23 -0
- package/src/core/response.ts +77 -0
- package/src/core/routeContext.ts +38 -0
- package/src/core/routesBuilder.ts +86 -0
- package/src/core/server.ts +144 -0
- package/src/dataAccess/dataAccessor.ts +110 -0
- package/src/dataAccess/entityManager.ts +651 -0
- package/src/dataAccess/entityMapper.ts +74 -0
- package/src/dataAccess/filterHelper.ts +47 -0
- package/src/dataAccess/propertyMapper.ts +27 -0
- package/src/deno-std/assert/assert.ts +9 -0
- package/src/deno-std/assert/assertion_error.ts +7 -0
- package/src/deno-std/datetime/to_imf.ts +47 -0
- package/src/deno-std/http/cookie.ts +398 -0
- package/src/helpers/entityHelpers.ts +24 -0
- package/src/helpers/inputHelper.ts +11 -0
- package/src/helpers/runCollectionEntityHttpHandler.ts +34 -0
- package/src/index.ts +12 -0
- package/src/plugins/authManager/httpHandlers/createSession.ts +57 -0
- package/src/plugins/authManager/httpHandlers/deleteSession.ts +22 -0
- package/src/plugins/authManager/httpHandlers/getMyProfile.ts +43 -0
- package/src/plugins/authManager/httpHandlers/index.ts +10 -0
- package/src/plugins/authManager/mod.ts +56 -0
- package/src/plugins/authManager/models/AccessToken.ts +56 -0
- package/src/plugins/authManager/models/index.ts +5 -0
- package/src/plugins/authManager/routes/getMyProfile.ts +15 -0
- package/src/plugins/authManager/routes/index.ts +9 -0
- package/src/plugins/authManager/routes/signin.ts +15 -0
- package/src/plugins/authManager/routes/signout.ts +15 -0
- package/src/plugins/dataManager/httpHandlers/addEntityRelations.ts +76 -0
- package/src/plugins/dataManager/httpHandlers/countCollectionEntities.ts +22 -0
- package/src/plugins/dataManager/httpHandlers/createCollectionEntitiesBatch.ts +57 -0
- package/src/plugins/dataManager/httpHandlers/createCollectionEntity.ts +43 -0
- package/src/plugins/dataManager/httpHandlers/deleteCollectionEntityById.ts +38 -0
- package/src/plugins/dataManager/httpHandlers/findCollectionEntities.ts +35 -0
- package/src/plugins/dataManager/httpHandlers/findCollectionEntityById.ts +30 -0
- package/src/plugins/dataManager/httpHandlers/queryDatabase.ts +29 -0
- package/src/plugins/dataManager/httpHandlers/removeEntityRelations.ts +72 -0
- package/src/plugins/dataManager/httpHandlers/updateCollectionEntityById.ts +53 -0
- package/src/plugins/dataManager/mod.ts +150 -0
- package/src/plugins/metaManager/httpHandlers/getMetaModelDetail.ts +14 -0
- package/src/plugins/metaManager/httpHandlers/listMetaModels.ts +13 -0
- package/src/plugins/metaManager/mod.ts +419 -0
- package/src/plugins/routeManager/httpHandlers/httpProxy.ts +15 -0
- package/src/plugins/routeManager/httpHandlers/listMetaRoutes.ts +13 -0
- package/src/plugins/routeManager/mod.ts +97 -0
- package/src/plugins/webhooks/mod.ts +144 -0
- package/src/plugins/webhooks/pluginConfig.ts +74 -0
- package/src/polyfill.ts +5 -0
- package/src/proxy/mod.ts +47 -0
- package/src/proxy/types.ts +21 -0
- package/src/queryBuilder/index.ts +1 -0
- package/src/queryBuilder/queryBuilder.ts +424 -0
- package/src/server.ts +192 -0
- package/src/types.ts +438 -0
- package/src/utilities/httpUtility.ts +23 -0
- package/src/utilities/jwtUtility.ts +16 -0
- package/src/utilities/rapidUtility.ts +5 -0
- package/src/utilities/typeUtility.ts +11 -0
- package/tsconfig.json +19 -0
package/src/server.ts
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import * as _ from "lodash";
|
|
2
|
+
import DataAccessor from "./dataAccess/dataAccessor";
|
|
3
|
+
import {
|
|
4
|
+
GetDataAccessorOptions,
|
|
5
|
+
GetModelOptions,
|
|
6
|
+
IDatabaseAccessor,
|
|
7
|
+
IDatabaseConfig,
|
|
8
|
+
IPluginInstance,
|
|
9
|
+
IQueryBuilder,
|
|
10
|
+
IRpdDataAccessor,
|
|
11
|
+
RpdApplicationConfig,
|
|
12
|
+
RpdDataModel,
|
|
13
|
+
RpdServerEventTypes,
|
|
14
|
+
RapidServerConfig,
|
|
15
|
+
} from "./types";
|
|
16
|
+
|
|
17
|
+
import QueryBuilder from "./queryBuilder/queryBuilder";
|
|
18
|
+
import * as pluginManager from "./core/pluginManager";
|
|
19
|
+
import EventManager from "./core/eventManager";
|
|
20
|
+
import { HttpRequestHandler, IPluginHttpHandler } from "./core/httpHandler";
|
|
21
|
+
import { IRpdServer } from "./core/server";
|
|
22
|
+
import { buildRoutes } from "./core/routesBuilder";
|
|
23
|
+
import { Next, RouteContext } from "./core/routeContext";
|
|
24
|
+
import { RapidRequest } from "./core/request";
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
export interface InitServerOptions {
|
|
28
|
+
databaseAccessor: IDatabaseAccessor;
|
|
29
|
+
databaseConfig: IDatabaseConfig;
|
|
30
|
+
serverConfig: RapidServerConfig;
|
|
31
|
+
applicationConfig: RpdApplicationConfig;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default class RpdServer implements IRpdServer {
|
|
35
|
+
#eventManager: EventManager;
|
|
36
|
+
#middlewares: any[];
|
|
37
|
+
#bootstrapApplicationConfig: RpdApplicationConfig;
|
|
38
|
+
#applicationConfig: RpdApplicationConfig;
|
|
39
|
+
#httpHandlersMapByCode: Map<string, HttpRequestHandler>;
|
|
40
|
+
#databaseAccessor: IDatabaseAccessor;
|
|
41
|
+
queryBuilder: IQueryBuilder;
|
|
42
|
+
config: RapidServerConfig;
|
|
43
|
+
databaseConfig: IDatabaseConfig;
|
|
44
|
+
#buildedRoutes: (ctx: any, next: any) => any;
|
|
45
|
+
|
|
46
|
+
constructor(options: InitServerOptions) {
|
|
47
|
+
this.#eventManager = new EventManager();
|
|
48
|
+
this.#middlewares = [];
|
|
49
|
+
this.#bootstrapApplicationConfig = options.applicationConfig;
|
|
50
|
+
|
|
51
|
+
this.#applicationConfig = {} as RpdApplicationConfig;
|
|
52
|
+
this.#httpHandlersMapByCode = new Map();
|
|
53
|
+
this.#databaseAccessor = options.databaseAccessor;
|
|
54
|
+
|
|
55
|
+
this.queryBuilder = new QueryBuilder({
|
|
56
|
+
dbDefaultSchema: options.databaseConfig.dbDefaultSchema,
|
|
57
|
+
});
|
|
58
|
+
this.databaseConfig = options.databaseConfig;
|
|
59
|
+
this.config = options.serverConfig;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
getApplicationConfig() {
|
|
63
|
+
return this.#applicationConfig;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
registerHttpHandler(
|
|
67
|
+
plugin: IPluginInstance,
|
|
68
|
+
options: IPluginHttpHandler,
|
|
69
|
+
) {
|
|
70
|
+
const handler = _.bind(options.handler, null, plugin);
|
|
71
|
+
this.#httpHandlersMapByCode.set(options.code, handler);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
getHttpHandlerByCode(code: string) {
|
|
75
|
+
return this.#httpHandlersMapByCode.get(code);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
registerMiddleware(middleware: any) {
|
|
79
|
+
this.#middlewares.push(middleware);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
getDataAccessor<T = any>(
|
|
83
|
+
options: GetDataAccessorOptions,
|
|
84
|
+
): IRpdDataAccessor<T> {
|
|
85
|
+
const { namespace, singularCode } = options;
|
|
86
|
+
// TODO: Should reuse the and DataAccessor instance
|
|
87
|
+
const model = this.getModel(options);
|
|
88
|
+
if (!model) {
|
|
89
|
+
throw new Error(`Data model ${namespace}.${singularCode} not found.`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const dataAccessor = new DataAccessor<T>({
|
|
93
|
+
model,
|
|
94
|
+
queryBuilder: this.queryBuilder as QueryBuilder,
|
|
95
|
+
});
|
|
96
|
+
return dataAccessor;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
getModel(options: GetModelOptions): RpdDataModel | undefined {
|
|
100
|
+
if (options.namespace) {
|
|
101
|
+
return this.#applicationConfig?.models.find((e) => e.namespace === options.namespace && e.singularCode === options.singularCode);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return this.#applicationConfig?.models.find((e) => e.singularCode === options.singularCode);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
registerEventHandler<K extends keyof RpdServerEventTypes>(
|
|
108
|
+
eventName: K,
|
|
109
|
+
listener: (...args: RpdServerEventTypes[K]) => void,
|
|
110
|
+
): this {
|
|
111
|
+
this.#eventManager.on(eventName, listener);
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async emitEvent<K extends keyof RpdServerEventTypes>(
|
|
116
|
+
eventName: K,
|
|
117
|
+
sender: IPluginInstance,
|
|
118
|
+
payload: RpdServerEventTypes[K][1],
|
|
119
|
+
) {
|
|
120
|
+
console.log(`Emit event "${eventName}"`, payload);
|
|
121
|
+
await this.#eventManager.emit<K>(eventName, sender, payload as any);
|
|
122
|
+
|
|
123
|
+
// TODO: should move this logic into metaManager
|
|
124
|
+
// if (
|
|
125
|
+
// (eventName === "entity.create" || eventName === "entity.update" ||
|
|
126
|
+
// eventName === "entity.delete") &&
|
|
127
|
+
// payload.namespace === "meta"
|
|
128
|
+
// ) {
|
|
129
|
+
// await this.configureApplication();
|
|
130
|
+
// }
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async start() {
|
|
134
|
+
console.log("Starting rapid server...");
|
|
135
|
+
await pluginManager.loadPlugins();
|
|
136
|
+
|
|
137
|
+
await pluginManager.initPlugins(this);
|
|
138
|
+
|
|
139
|
+
await pluginManager.registerMiddlewares(this);
|
|
140
|
+
await pluginManager.registerHttpHandlers(this);
|
|
141
|
+
await pluginManager.registerEventHandlers(this);
|
|
142
|
+
await pluginManager.registerMessageHandlers(this);
|
|
143
|
+
await pluginManager.registerTaskProcessors(this);
|
|
144
|
+
|
|
145
|
+
await this.configureApplication();
|
|
146
|
+
|
|
147
|
+
console.log(`Application ready.`);
|
|
148
|
+
await pluginManager.onApplicationReady(this, this.#applicationConfig);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async configureApplication() {
|
|
152
|
+
this.#applicationConfig = _.merge(
|
|
153
|
+
{},
|
|
154
|
+
this.#bootstrapApplicationConfig,
|
|
155
|
+
) as RpdApplicationConfig;
|
|
156
|
+
|
|
157
|
+
await pluginManager.onLoadingApplication(this, this.#applicationConfig);
|
|
158
|
+
await pluginManager.configureModels(this, this.#applicationConfig);
|
|
159
|
+
await pluginManager.configureModelProperties(this, this.#applicationConfig);
|
|
160
|
+
await pluginManager.configureRoutes(this, this.#applicationConfig);
|
|
161
|
+
|
|
162
|
+
// TODO: check application configuration.
|
|
163
|
+
|
|
164
|
+
await pluginManager.onApplicationLoaded(this, this.#applicationConfig);
|
|
165
|
+
|
|
166
|
+
this.#buildedRoutes = await buildRoutes(this, this.#applicationConfig);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async queryDatabaseObject(sql: string, params?: unknown[] | Record<string,unknown>) : Promise<any[]> {
|
|
170
|
+
return await this.#databaseAccessor.queryDatabaseObject(sql, params);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
async tryQueryDatabaseObject(sql: string, params?: unknown[] | Record<string,unknown>) : Promise<any[]> {
|
|
174
|
+
try {
|
|
175
|
+
return await this.queryDatabaseObject(sql, params);
|
|
176
|
+
} catch (err) {
|
|
177
|
+
console.error(err.message);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return [];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
get middlewares() {
|
|
184
|
+
return this.#middlewares;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async handleRequest(request: Request, next: Next) {
|
|
188
|
+
const routeContext = new RouteContext(new RapidRequest(request));
|
|
189
|
+
await this.#buildedRoutes(routeContext, next);
|
|
190
|
+
return routeContext.response.getResponse();
|
|
191
|
+
}
|
|
192
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
export type RapidServerConfig = {
|
|
2
|
+
sessionCookieName: string;
|
|
3
|
+
jwtKey: string;
|
|
4
|
+
localFileStoragePath: string;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export interface IDatabaseConfig {
|
|
8
|
+
dbHost?: string;
|
|
9
|
+
dbPort?: number;
|
|
10
|
+
dbName?: string;
|
|
11
|
+
dbUser?: string;
|
|
12
|
+
dbPassword?: string;
|
|
13
|
+
dbDefaultSchema?: string;
|
|
14
|
+
dbPoolConnections?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface IDatabaseAccessor {
|
|
18
|
+
queryDatabaseObject: (sql: string, params?: unknown[] | Record<string, unknown>) => Promise<any[]>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
export interface RunEntityHttpHandlerOptions {
|
|
23
|
+
/** 模型所在的命名空间 */
|
|
24
|
+
namespace: string;
|
|
25
|
+
/** 模型Code的单数表示 */
|
|
26
|
+
singularCode: string;
|
|
27
|
+
/** 默认输入 */
|
|
28
|
+
defaultInput: Record<string, any>;
|
|
29
|
+
/** 固定输入 */
|
|
30
|
+
fixedInput: Record<string, any>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface RunQueryDatabaseHandlerOptions {
|
|
34
|
+
sql: string;
|
|
35
|
+
|
|
36
|
+
querySingle?: boolean;
|
|
37
|
+
|
|
38
|
+
/** 默认输入 */
|
|
39
|
+
defaultInput: Record<string, any>;
|
|
40
|
+
/** 固定输入 */
|
|
41
|
+
fixedInput: Record<string, any>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface RunProxyHandlerOptions {
|
|
45
|
+
/** Timeout milli seconds, default as 60000 */
|
|
46
|
+
timeout?: number;
|
|
47
|
+
/** Target url to proxy */
|
|
48
|
+
target: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface GetDataAccessorOptions {
|
|
52
|
+
namespace?: string;
|
|
53
|
+
singularCode: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface GetModelOptions {
|
|
57
|
+
namespace?: string;
|
|
58
|
+
singularCode: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export type RpdServerEventTypes = {
|
|
62
|
+
"entity.create": [IPluginInstance, RpdEntityCreateEventPayload];
|
|
63
|
+
"entity.update": [IPluginInstance, RpdEntityUpdateEventPayload];
|
|
64
|
+
"entity.delete": [IPluginInstance, RpdEntityDeleteEventPayload];
|
|
65
|
+
"entity.addRelations": [IPluginInstance, RpdEntityAddRelationsEventPayload];
|
|
66
|
+
"entity.removeRelations": [IPluginInstance, RpdEntityRemoveRelationsEventPayload];
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export interface RpdEntityCreateEventPayload {
|
|
70
|
+
namespace: string;
|
|
71
|
+
modelSingularCode: string;
|
|
72
|
+
after: any;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface RpdEntityUpdateEventPayload {
|
|
76
|
+
namespace: string;
|
|
77
|
+
modelSingularCode: string;
|
|
78
|
+
before: any;
|
|
79
|
+
after: any;
|
|
80
|
+
changes: any;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface RpdEntityDeleteEventPayload {
|
|
84
|
+
namespace: string;
|
|
85
|
+
modelSingularCode: string;
|
|
86
|
+
before: any;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface RpdEntityAddRelationsEventPayload {
|
|
90
|
+
namespace: string;
|
|
91
|
+
modelSingularCode: string;
|
|
92
|
+
entity: any;
|
|
93
|
+
property: string;
|
|
94
|
+
relations: any[];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface RpdEntityRemoveRelationsEventPayload {
|
|
98
|
+
namespace: string;
|
|
99
|
+
modelSingularCode: string;
|
|
100
|
+
entity: any;
|
|
101
|
+
property: string;
|
|
102
|
+
relations: any[];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface QuoteTableOptions {
|
|
106
|
+
schema?: string;
|
|
107
|
+
tableName: string;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface IQueryBuilder {
|
|
111
|
+
quoteTable: (options: QuoteTableOptions) => string;
|
|
112
|
+
quoteObject: (name: string) => string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
export interface RpdApplicationConfig {
|
|
117
|
+
code?: string;
|
|
118
|
+
name?: string;
|
|
119
|
+
models: RpdDataModel[];
|
|
120
|
+
routes: RpdRoute[];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export interface RpdDataModel {
|
|
124
|
+
maintainedBy?: string;
|
|
125
|
+
name: string;
|
|
126
|
+
namespace: string;
|
|
127
|
+
singularCode: string;
|
|
128
|
+
pluralCode: string;
|
|
129
|
+
schema?: string;
|
|
130
|
+
tableName: string;
|
|
131
|
+
properties: RpdDataModelProperty[];
|
|
132
|
+
extensions?: RpdDataModelExtension[];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface RpdDataModelProperty {
|
|
136
|
+
/**
|
|
137
|
+
* 表示此属性由谁来维护
|
|
138
|
+
*/
|
|
139
|
+
maintainedBy?: string;
|
|
140
|
+
/**
|
|
141
|
+
* 字段名称。可以包含中文。
|
|
142
|
+
*/
|
|
143
|
+
name: string;
|
|
144
|
+
/**
|
|
145
|
+
* 字段代码。会用于数据表列名和 API 的字段名。
|
|
146
|
+
*/
|
|
147
|
+
code: string;
|
|
148
|
+
/**
|
|
149
|
+
* 数据表列名。如果没有设置则使用 code。
|
|
150
|
+
*/
|
|
151
|
+
columnName?: string;
|
|
152
|
+
/**
|
|
153
|
+
* 字段类型。
|
|
154
|
+
*/
|
|
155
|
+
type: RpdDataPropertyTypes;
|
|
156
|
+
/**
|
|
157
|
+
* 是否必须有值。默认为 false。
|
|
158
|
+
*/
|
|
159
|
+
required?: boolean;
|
|
160
|
+
/**
|
|
161
|
+
* 默认值。使用默认值的 SQL 表达式表示。
|
|
162
|
+
*/
|
|
163
|
+
defaultValue?: string;
|
|
164
|
+
/**
|
|
165
|
+
* 属性配置。
|
|
166
|
+
*/
|
|
167
|
+
// deno-lint-ignore no-explicit-any
|
|
168
|
+
config?: Record<string, any>;
|
|
169
|
+
/**
|
|
170
|
+
* 是否自增长。
|
|
171
|
+
*/
|
|
172
|
+
autoIncrement?: boolean;
|
|
173
|
+
/**
|
|
174
|
+
* 字段值的最小长度。
|
|
175
|
+
*/
|
|
176
|
+
minLength?: number;
|
|
177
|
+
/**
|
|
178
|
+
* 字段值的最大长度。
|
|
179
|
+
*/
|
|
180
|
+
maxLength?: number;
|
|
181
|
+
/**
|
|
182
|
+
* 当 type 为 relation 时,设置关联实体为一个还是多个。
|
|
183
|
+
*/
|
|
184
|
+
relation?: "one" | "many";
|
|
185
|
+
/**
|
|
186
|
+
* 关联实体的singular code,不管 relation 为 one 或者 many 都需要设置。
|
|
187
|
+
*/
|
|
188
|
+
targetSingularCode?: string;
|
|
189
|
+
/**
|
|
190
|
+
* 当 relation 为 one 时,设置当前模型表中表示关联实体 id 的列名。
|
|
191
|
+
* 当 relation 为 many,并且使用关联关系表保存关联信息时,设置关联关系表中表示关联实体 id 的列名。
|
|
192
|
+
* 当 relation 为 many,并且不使用关联关系表保存关联信息时,关联实体 id 的列名默认为`id`,此时可以不设置 targetIdColumnName。
|
|
193
|
+
*/
|
|
194
|
+
targetIdColumnName?: string;
|
|
195
|
+
/**
|
|
196
|
+
* 当 relation 为 many 时,设置目标模型表或关联关系表中表示自身实体 id 的列名。
|
|
197
|
+
*/
|
|
198
|
+
selfIdColumnName?: string;
|
|
199
|
+
/**
|
|
200
|
+
* 当 relation 为 many 时,可以使用关联关系表保存关联信息,此时需要设置关联关系表的名称。
|
|
201
|
+
*/
|
|
202
|
+
linkTableName?: string;
|
|
203
|
+
/**
|
|
204
|
+
* 当设置了 linkTableName 时,可以设置关联关系表所在的 Schema。
|
|
205
|
+
*/
|
|
206
|
+
linkSchema?: string;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export type RpdDataPropertyTypes =
|
|
210
|
+
| "integer"
|
|
211
|
+
| "long"
|
|
212
|
+
| "float"
|
|
213
|
+
| "double"
|
|
214
|
+
| "decimal"
|
|
215
|
+
| "text"
|
|
216
|
+
| "boolean"
|
|
217
|
+
| "date"
|
|
218
|
+
| "datetime"
|
|
219
|
+
| "json"
|
|
220
|
+
| "relation"
|
|
221
|
+
| "relation[]"
|
|
222
|
+
| "option";
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* 数据字典
|
|
227
|
+
*/
|
|
228
|
+
export type RpdDataDictionary = {
|
|
229
|
+
/**
|
|
230
|
+
* 字典编码
|
|
231
|
+
*/
|
|
232
|
+
code: string;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* 字典名称
|
|
236
|
+
*/
|
|
237
|
+
description?: string;
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* 字典项值类型
|
|
241
|
+
*/
|
|
242
|
+
type: 'string' | 'integer';
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* 字典项
|
|
246
|
+
*/
|
|
247
|
+
entries: RpdDataDictionaryEntry[];
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* 数据字典项
|
|
252
|
+
*/
|
|
253
|
+
export type RpdDataDictionaryEntry = {
|
|
254
|
+
/**
|
|
255
|
+
* 名称
|
|
256
|
+
*/
|
|
257
|
+
name: string;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* 值
|
|
261
|
+
*/
|
|
262
|
+
value: string;
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* 描述
|
|
266
|
+
*/
|
|
267
|
+
description?: string;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* 排序号
|
|
271
|
+
*/
|
|
272
|
+
orderNum: number;
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* 是否禁用
|
|
276
|
+
*/
|
|
277
|
+
disabled: boolean;
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
export interface RpdDataModelExtension {
|
|
282
|
+
code: string;
|
|
283
|
+
config: any;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
export interface IPluginInstance {
|
|
288
|
+
getName(): string;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
export type EventHandler<T = any> = (
|
|
292
|
+
sender: IPluginInstance,
|
|
293
|
+
payload: T,
|
|
294
|
+
) => void;
|
|
295
|
+
|
|
296
|
+
export interface RpdRoute {
|
|
297
|
+
name: string;
|
|
298
|
+
namespace: string;
|
|
299
|
+
code: string;
|
|
300
|
+
type: "RESTful";
|
|
301
|
+
method: RpdHttpMethod;
|
|
302
|
+
endpoint: string;
|
|
303
|
+
handlers: RpdHttpHandler[];
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export type RpdHttpMethod = "get" | "post" | "put" | "delete";
|
|
307
|
+
|
|
308
|
+
export interface RpdHttpHandler {
|
|
309
|
+
code: string;
|
|
310
|
+
config: any;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export interface IRpdDataAccessor<T = any> {
|
|
314
|
+
getModel(): RpdDataModel;
|
|
315
|
+
create(entity: any): Promise<any>;
|
|
316
|
+
updateById(id: any, entity: any): Promise<any>;
|
|
317
|
+
find(options: FindEntityOptions): Promise<T[]>;
|
|
318
|
+
findOne(options: FindEntityOptions): Promise<T | null>;
|
|
319
|
+
findById(id: any): Promise<T | null>;
|
|
320
|
+
count(options: CountEntityOptions): Promise<any>;
|
|
321
|
+
deleteById(id: any): Promise<void>;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
export type EntityFilterRelationalOperators =
|
|
325
|
+
| "eq"
|
|
326
|
+
| "ne"
|
|
327
|
+
| "lt"
|
|
328
|
+
| "lte"
|
|
329
|
+
| "gt"
|
|
330
|
+
| "gte"
|
|
331
|
+
| "contains"
|
|
332
|
+
| "notContains"
|
|
333
|
+
| "containsCS"
|
|
334
|
+
| "notContainsCS"
|
|
335
|
+
| "startsWith"
|
|
336
|
+
| "notStartsWith"
|
|
337
|
+
| "endsWith"
|
|
338
|
+
| "notEndsWith";
|
|
339
|
+
|
|
340
|
+
export type EntityFilterSetOperators =
|
|
341
|
+
| "in"
|
|
342
|
+
| "notIn";
|
|
343
|
+
|
|
344
|
+
export type EntityFilterLogicalOperators =
|
|
345
|
+
| "or"
|
|
346
|
+
| "and";
|
|
347
|
+
|
|
348
|
+
export type EntityFilterUnaryOperators =
|
|
349
|
+
| "null"
|
|
350
|
+
| "notNull";
|
|
351
|
+
|
|
352
|
+
export type EntityFilterExistenceOperators =
|
|
353
|
+
| "exists"
|
|
354
|
+
| "notExists";
|
|
355
|
+
|
|
356
|
+
export type EntityFilterOperators =
|
|
357
|
+
| EntityFilterRelationalOperators
|
|
358
|
+
| EntityFilterSetOperators
|
|
359
|
+
| EntityFilterLogicalOperators
|
|
360
|
+
| EntityFilterUnaryOperators
|
|
361
|
+
| EntityFilterExistenceOperators;
|
|
362
|
+
|
|
363
|
+
export type EntityFilterOptions =
|
|
364
|
+
| FindEntityRelationalFilterOptions
|
|
365
|
+
| FindEntitySetFilterOptions
|
|
366
|
+
| FindEntityLogicalFilterOptions
|
|
367
|
+
| FindEntityUnaryFilterOptions
|
|
368
|
+
| FindEntityExistenceFilterOptions;
|
|
369
|
+
|
|
370
|
+
export interface FindEntityOptions {
|
|
371
|
+
filters?: EntityFilterOptions[];
|
|
372
|
+
orderBy?: FindEntityOrderByOptions[];
|
|
373
|
+
pagination?: FindEntityPaginationOptions;
|
|
374
|
+
properties?: string[] | Record<string, any>;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
export interface FindEntityRelationalFilterOptions {
|
|
378
|
+
field: string;
|
|
379
|
+
operator: EntityFilterRelationalOperators;
|
|
380
|
+
value: any;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export interface FindEntitySetFilterOptions {
|
|
384
|
+
field: string;
|
|
385
|
+
operator: EntityFilterSetOperators;
|
|
386
|
+
value: any[];
|
|
387
|
+
itemType?: string;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export interface FindEntityLogicalFilterOptions {
|
|
391
|
+
operator: EntityFilterLogicalOperators;
|
|
392
|
+
filters: EntityFilterOptions[];
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
export interface FindEntityUnaryFilterOptions {
|
|
396
|
+
field: string;
|
|
397
|
+
operator: EntityFilterUnaryOperators;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
export interface FindEntityExistenceFilterOptions {
|
|
401
|
+
field: string;
|
|
402
|
+
operator: EntityFilterExistenceOperators;
|
|
403
|
+
filters: EntityFilterOptions[];
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export interface FindEntityPaginationOptions {
|
|
407
|
+
offset: number;
|
|
408
|
+
limit: number;
|
|
409
|
+
withoutTotal?: boolean;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
export interface FindEntityOrderByOptions {
|
|
413
|
+
field: string;
|
|
414
|
+
desc?: boolean;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
export interface CountEntityOptions {
|
|
418
|
+
filters?: EntityFilterOptions[];
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
export interface CreateEntityOptions {
|
|
422
|
+
entity: any;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
export interface UpdateEntityOptions {
|
|
426
|
+
filters?: EntityFilterOptions[];
|
|
427
|
+
entity: any;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
export interface UpdateEntityByIdOptions {
|
|
431
|
+
id: any;
|
|
432
|
+
entity: any;
|
|
433
|
+
changes: any;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
export interface DeleteEntityOptions {
|
|
437
|
+
filters?: EntityFilterOptions[];
|
|
438
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export async function fetchWithTimeout(
|
|
2
|
+
url: string,
|
|
3
|
+
reqInit: RequestInit,
|
|
4
|
+
timeout?: number,
|
|
5
|
+
) : Promise<Response> {
|
|
6
|
+
if (!timeout) {
|
|
7
|
+
return await fetch(url, reqInit);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let timer: any;
|
|
11
|
+
const [res] = await Promise.all([
|
|
12
|
+
fetch(url, reqInit).then((res) => {
|
|
13
|
+
clearTimeout(timer);
|
|
14
|
+
return res;
|
|
15
|
+
}),
|
|
16
|
+
new Promise((_, reject) => {
|
|
17
|
+
timer = setTimeout(() => {
|
|
18
|
+
reject(new Error(`Request to "${url}" was timeout.`));
|
|
19
|
+
}, timeout);
|
|
20
|
+
}),
|
|
21
|
+
]);
|
|
22
|
+
return res;
|
|
23
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
export function getJWTKey() {
|
|
3
|
+
return "";
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export async function createJWT(payload: Record<string, any>) {
|
|
7
|
+
return "";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export async function verifyJWT(jwt: string) {
|
|
11
|
+
return {};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function decodeJWT(jwt: string) {
|
|
15
|
+
return { header: {}, payload: {}, signature: {} };
|
|
16
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
|
5
|
+
"esModuleInterop": true,
|
|
6
|
+
"jsx": "react-jsx",
|
|
7
|
+
"module": "ESNext",
|
|
8
|
+
"moduleResolution": "Node",
|
|
9
|
+
"allowJs": true,
|
|
10
|
+
"sourceMap": true,
|
|
11
|
+
"declaration": true,
|
|
12
|
+
"outDir": "./dist",
|
|
13
|
+
"paths": {
|
|
14
|
+
"~/*": ["./src/*"]
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"exclude": ["src/**/*.spec.ts", "src/**/*.spec.tsx", "node_modules"],
|
|
18
|
+
"include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]
|
|
19
|
+
}
|