@lobb-js/core 0.13.0
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/package.json +48 -0
- package/src/Lobb.ts +150 -0
- package/src/LobbError.ts +105 -0
- package/src/TypesGenerator.ts +11 -0
- package/src/api/WebServer.ts +126 -0
- package/src/api/collections/CollectionControllers.ts +485 -0
- package/src/api/collections/CollectionService.ts +162 -0
- package/src/api/collections/collectionRoutes.ts +105 -0
- package/src/api/collections/collectionStore.ts +647 -0
- package/src/api/collections/transactions.ts +166 -0
- package/src/api/collections/utils.ts +73 -0
- package/src/api/errorHandler.ts +73 -0
- package/src/api/events/index.ts +129 -0
- package/src/api/meta/route.ts +66 -0
- package/src/api/meta/service.ts +163 -0
- package/src/api/middlewares.ts +71 -0
- package/src/api/openApiRoute.ts +1017 -0
- package/src/api/schema/SchemaService.ts +71 -0
- package/src/api/schema/schemaRoutes.ts +13 -0
- package/src/config/ConfigManager.ts +252 -0
- package/src/config/validations.ts +49 -0
- package/src/coreCollections/collectionsCollection.ts +56 -0
- package/src/coreCollections/index.ts +14 -0
- package/src/coreCollections/migrationsCollection.ts +36 -0
- package/src/coreCollections/queryCollection.ts +26 -0
- package/src/coreCollections/workflowsCollection.ts +73 -0
- package/src/coreDbSetup/index.ts +72 -0
- package/src/coreMigrations/index.ts +3 -0
- package/src/database/DatabaseService.ts +44 -0
- package/src/database/DatabaseSyncManager.ts +173 -0
- package/src/database/MigrationsManager.ts +95 -0
- package/src/database/drivers/MongoDriver.ts +750 -0
- package/src/database/drivers/pgDriver/PGDriver.ts +655 -0
- package/src/database/drivers/pgDriver/QueryBuilder.ts +474 -0
- package/src/database/drivers/pgDriver/utils.ts +6 -0
- package/src/events/EventSystem.ts +191 -0
- package/src/events/coreEvents/index.ts +218 -0
- package/src/events/studioEvents/index.ts +32 -0
- package/src/extension/ExtensionSystem.ts +236 -0
- package/src/extension/dashboardRoute.ts +35 -0
- package/src/fields/ArrayField.ts +33 -0
- package/src/fields/BoolField.ts +34 -0
- package/src/fields/DateField.ts +13 -0
- package/src/fields/DateTimeField.ts +13 -0
- package/src/fields/DecimalField.ts +13 -0
- package/src/fields/FieldUtils.ts +56 -0
- package/src/fields/FloatField.ts +13 -0
- package/src/fields/IntegerField.ts +13 -0
- package/src/fields/LongField.ts +13 -0
- package/src/fields/ObjectField.ts +15 -0
- package/src/fields/StringField.ts +13 -0
- package/src/fields/TextField.ts +13 -0
- package/src/fields/TimeField.ts +13 -0
- package/src/index.ts +53 -0
- package/src/studio/Studio.ts +108 -0
- package/src/types/CollectionControllers.ts +15 -0
- package/src/types/DatabaseDriver.ts +115 -0
- package/src/types/Extension.ts +46 -0
- package/src/types/Field.ts +29 -0
- package/src/types/apiSchema.ts +12 -0
- package/src/types/collectionServiceSchema.ts +18 -0
- package/src/types/config/collectionFields.ts +85 -0
- package/src/types/config/collectionsConfig.ts +50 -0
- package/src/types/config/config.ts +66 -0
- package/src/types/config/relations.ts +17 -0
- package/src/types/filterSchema.ts +88 -0
- package/src/types/index.ts +38 -0
- package/src/types/migrations.ts +12 -0
- package/src/types/websockets.ts +34 -0
- package/src/types/workflows/processors.ts +1 -0
- package/src/utils/lockCollectionToObject.ts +204 -0
- package/src/utils/utils.ts +310 -0
- package/src/workflows/WorkflowSystem.ts +182 -0
- package/src/workflows/coreWorkflows/collectionsTable/index.ts +118 -0
- package/src/workflows/coreWorkflows/index.ts +18 -0
- package/src/workflows/coreWorkflows/processors/postOperationsWorkflows.ts +46 -0
- package/src/workflows/coreWorkflows/processors/preOperationsWorkflows.ts +27 -0
- package/src/workflows/coreWorkflows/processors/processorForDB.ts +13 -0
- package/src/workflows/coreWorkflows/processors/processors/processor.ts +23 -0
- package/src/workflows/coreWorkflows/processors/processors/processorsFunctions.ts +47 -0
- package/src/workflows/coreWorkflows/processors/utils.ts +102 -0
- package/src/workflows/coreWorkflows/processors/validator/validator.ts +19 -0
- package/src/workflows/coreWorkflows/processors/validator/validatorsFunction.ts +52 -0
- package/src/workflows/coreWorkflows/queryCoreWorkflows.ts +31 -0
- package/src/workflows/coreWorkflows/utilsCoreWorkflows.ts +40 -0
- package/src/workflows/coreWorkflows/workflowsCollection/workflowsCollectionWorkflows.ts +101 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import type { Event } from "../EventSystem.ts";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
export function getCoreEvents(): Event[] {
|
|
5
|
+
const events: Event[] = [];
|
|
6
|
+
|
|
7
|
+
events.push({
|
|
8
|
+
name: "core.init",
|
|
9
|
+
inputSchema: z.object({}),
|
|
10
|
+
outputSchema: z.object({}),
|
|
11
|
+
});
|
|
12
|
+
events.push({
|
|
13
|
+
name: "core.webserver.middlwares.pre",
|
|
14
|
+
inputSchema: z.object({}),
|
|
15
|
+
outputSchema: z.object({}),
|
|
16
|
+
});
|
|
17
|
+
events.push({
|
|
18
|
+
name: "core.webserver.middlwares.post",
|
|
19
|
+
inputSchema: z.object({}),
|
|
20
|
+
outputSchema: z.object({}),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// service events
|
|
24
|
+
events.push({
|
|
25
|
+
name: "core.store.preFindAll",
|
|
26
|
+
inputSchema: z.object({}),
|
|
27
|
+
outputSchema: z.object({}),
|
|
28
|
+
});
|
|
29
|
+
events.push({
|
|
30
|
+
name: "core.store.findAll",
|
|
31
|
+
inputSchema: z.object({}),
|
|
32
|
+
outputSchema: z.object({}),
|
|
33
|
+
});
|
|
34
|
+
events.push({
|
|
35
|
+
name: "core.store.preFindOne",
|
|
36
|
+
inputSchema: z.object({}),
|
|
37
|
+
outputSchema: z.object({}),
|
|
38
|
+
});
|
|
39
|
+
events.push({
|
|
40
|
+
name: "core.store.findOne",
|
|
41
|
+
inputSchema: z.object({}),
|
|
42
|
+
outputSchema: z.object({}),
|
|
43
|
+
});
|
|
44
|
+
events.push({
|
|
45
|
+
name: "core.store.preCreateOne",
|
|
46
|
+
inputSchema: z.object({}),
|
|
47
|
+
outputSchema: z.object({}),
|
|
48
|
+
});
|
|
49
|
+
events.push({
|
|
50
|
+
name: "core.store.createOne",
|
|
51
|
+
inputSchema: z.object({}),
|
|
52
|
+
outputSchema: z.object({}),
|
|
53
|
+
});
|
|
54
|
+
events.push({
|
|
55
|
+
name: "core.store.preUpdateOne",
|
|
56
|
+
inputSchema: z.object({}),
|
|
57
|
+
outputSchema: z.object({}),
|
|
58
|
+
});
|
|
59
|
+
events.push({
|
|
60
|
+
name: "core.store.updateOne",
|
|
61
|
+
inputSchema: z.object({}),
|
|
62
|
+
outputSchema: z.object({}),
|
|
63
|
+
});
|
|
64
|
+
events.push({
|
|
65
|
+
name: "core.store.preDeleteOne",
|
|
66
|
+
inputSchema: z.object({}),
|
|
67
|
+
outputSchema: z.object({}),
|
|
68
|
+
});
|
|
69
|
+
events.push({
|
|
70
|
+
name: "core.store.deleteOne",
|
|
71
|
+
inputSchema: z.object({}),
|
|
72
|
+
outputSchema: z.object({}),
|
|
73
|
+
});
|
|
74
|
+
events.push({
|
|
75
|
+
name: "core.collection.transaction",
|
|
76
|
+
inputSchema: z.object({}),
|
|
77
|
+
outputSchema: z.object({}),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// controller events
|
|
81
|
+
events.push({
|
|
82
|
+
name: "core.controllers.findAll",
|
|
83
|
+
inputSchema: z.object({}),
|
|
84
|
+
outputSchema: z.object({}),
|
|
85
|
+
});
|
|
86
|
+
events.push({
|
|
87
|
+
name: "core.controllers.preFindAll",
|
|
88
|
+
inputSchema: z.object({}),
|
|
89
|
+
outputSchema: z.object({}),
|
|
90
|
+
});
|
|
91
|
+
events.push({
|
|
92
|
+
name: "core.controllers.preFindOne",
|
|
93
|
+
inputSchema: z.object({}),
|
|
94
|
+
outputSchema: z.object({}),
|
|
95
|
+
});
|
|
96
|
+
events.push({
|
|
97
|
+
name: "core.controllers.preCreateOne",
|
|
98
|
+
inputSchema: z.object({}),
|
|
99
|
+
outputSchema: z.object({}),
|
|
100
|
+
});
|
|
101
|
+
events.push({
|
|
102
|
+
name: "core.controllers.createOne.override",
|
|
103
|
+
inputSchema: z.object({}),
|
|
104
|
+
outputSchema: z.object({}),
|
|
105
|
+
});
|
|
106
|
+
events.push({
|
|
107
|
+
name: "core.controllers.findOne.override",
|
|
108
|
+
inputSchema: z.object({}),
|
|
109
|
+
outputSchema: z.object({}),
|
|
110
|
+
});
|
|
111
|
+
events.push({
|
|
112
|
+
name: "core.controllers.preDeleteMany",
|
|
113
|
+
inputSchema: z.object({}),
|
|
114
|
+
outputSchema: z.object({}),
|
|
115
|
+
});
|
|
116
|
+
events.push({
|
|
117
|
+
name: "core.controllers.preReadSingleton",
|
|
118
|
+
inputSchema: z.object({}),
|
|
119
|
+
outputSchema: z.object({}),
|
|
120
|
+
});
|
|
121
|
+
events.push({
|
|
122
|
+
name: "core.controllers.preUpdateSingleton",
|
|
123
|
+
inputSchema: z.object({}),
|
|
124
|
+
outputSchema: z.object({}),
|
|
125
|
+
});
|
|
126
|
+
events.push({
|
|
127
|
+
name: "core.service.findAll.override",
|
|
128
|
+
inputSchema: z.object({}),
|
|
129
|
+
outputSchema: z.object({}),
|
|
130
|
+
});
|
|
131
|
+
events.push({
|
|
132
|
+
name: "core.service.findOne.override",
|
|
133
|
+
inputSchema: z.object({}),
|
|
134
|
+
outputSchema: z.object({}),
|
|
135
|
+
});
|
|
136
|
+
events.push({
|
|
137
|
+
name: "core.service.createOne.override",
|
|
138
|
+
inputSchema: z.object({}),
|
|
139
|
+
outputSchema: z.object({}),
|
|
140
|
+
});
|
|
141
|
+
events.push({
|
|
142
|
+
name: "core.service.updateOne.override",
|
|
143
|
+
inputSchema: z.object({}),
|
|
144
|
+
outputSchema: z.object({}),
|
|
145
|
+
});
|
|
146
|
+
events.push({
|
|
147
|
+
name: "core.service.deleteOne.override",
|
|
148
|
+
inputSchema: z.object({}),
|
|
149
|
+
outputSchema: z.object({}),
|
|
150
|
+
});
|
|
151
|
+
events.push({
|
|
152
|
+
name: "core.service.readSingleton.override",
|
|
153
|
+
inputSchema: z.object({}),
|
|
154
|
+
outputSchema: z.object({}),
|
|
155
|
+
});
|
|
156
|
+
events.push({
|
|
157
|
+
name: "core.service.updateSingleton.override",
|
|
158
|
+
inputSchema: z.object({}),
|
|
159
|
+
outputSchema: z.object({}),
|
|
160
|
+
});
|
|
161
|
+
events.push({
|
|
162
|
+
name: "core.service.deleteMany.override",
|
|
163
|
+
inputSchema: z.object({}),
|
|
164
|
+
outputSchema: z.object({}),
|
|
165
|
+
});
|
|
166
|
+
events.push({
|
|
167
|
+
name: "core.service.updateMany.override",
|
|
168
|
+
inputSchema: z.object({}),
|
|
169
|
+
outputSchema: z.object({}),
|
|
170
|
+
});
|
|
171
|
+
events.push({
|
|
172
|
+
name: "core.service.createMany.override",
|
|
173
|
+
inputSchema: z.object({}),
|
|
174
|
+
outputSchema: z.object({}),
|
|
175
|
+
});
|
|
176
|
+
events.push({
|
|
177
|
+
name: "core.controllers.updateOne.override",
|
|
178
|
+
inputSchema: z.object({}),
|
|
179
|
+
outputSchema: z.object({}),
|
|
180
|
+
});
|
|
181
|
+
events.push({
|
|
182
|
+
name: "core.controllers.deleteOne.override",
|
|
183
|
+
inputSchema: z.object({}),
|
|
184
|
+
outputSchema: z.object({}),
|
|
185
|
+
});
|
|
186
|
+
events.push({
|
|
187
|
+
name: "core.controllers.findAll.override",
|
|
188
|
+
inputSchema: z.object({}),
|
|
189
|
+
outputSchema: z.object({}),
|
|
190
|
+
});
|
|
191
|
+
events.push({
|
|
192
|
+
name: "core.controllers.deleteMany.override",
|
|
193
|
+
inputSchema: z.object({}),
|
|
194
|
+
outputSchema: z.object({}),
|
|
195
|
+
});
|
|
196
|
+
events.push({
|
|
197
|
+
name: "core.controllers.updateMany.override",
|
|
198
|
+
inputSchema: z.object({}),
|
|
199
|
+
outputSchema: z.object({}),
|
|
200
|
+
});
|
|
201
|
+
events.push({
|
|
202
|
+
name: "core.controllers.createMany.override",
|
|
203
|
+
inputSchema: z.object({}),
|
|
204
|
+
outputSchema: z.object({}),
|
|
205
|
+
});
|
|
206
|
+
events.push({
|
|
207
|
+
name: "core.controllers.readSingleton.override",
|
|
208
|
+
inputSchema: z.object({}),
|
|
209
|
+
outputSchema: z.object({}),
|
|
210
|
+
});
|
|
211
|
+
events.push({
|
|
212
|
+
name: "core.controllers.updateSingleton.override",
|
|
213
|
+
inputSchema: z.object({}),
|
|
214
|
+
outputSchema: z.object({}),
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
return events;
|
|
218
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { Event } from "../EventSystem.ts";
|
|
3
|
+
|
|
4
|
+
export function getStudioEvents(): Event[] {
|
|
5
|
+
const events: Event[] = [];
|
|
6
|
+
|
|
7
|
+
events.push({
|
|
8
|
+
name: "studio.collections.preForeignKeySelect",
|
|
9
|
+
inputSchema: z.object({}),
|
|
10
|
+
outputSchema: z.object({}),
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
events.push({
|
|
14
|
+
name: "studio.collections.preCreate",
|
|
15
|
+
inputSchema: z.object({}),
|
|
16
|
+
outputSchema: z.object({}),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
events.push({
|
|
20
|
+
name: "studio.collections.create",
|
|
21
|
+
inputSchema: z.object({}),
|
|
22
|
+
outputSchema: z.object({}),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
events.push({
|
|
26
|
+
name: "studio.collections.listView.tools",
|
|
27
|
+
inputSchema: z.object({}),
|
|
28
|
+
outputSchema: z.object({}),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
return events;
|
|
32
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import type { CollectionConfig } from "../types/index.ts";
|
|
2
|
+
import type { Migrations } from "../types/index.ts";
|
|
3
|
+
import type { Workflow } from "../workflows/WorkflowSystem.ts";
|
|
4
|
+
|
|
5
|
+
import { Hono } from "hono";
|
|
6
|
+
import { getDashboardRoute } from "./dashboardRoute.ts";
|
|
7
|
+
import { LobbError } from "../LobbError.ts";
|
|
8
|
+
import _ from "lodash";
|
|
9
|
+
import { Lobb } from "../Lobb.ts";
|
|
10
|
+
|
|
11
|
+
export class ExtensionSystem {
|
|
12
|
+
private collectionsOwners: Record<string, string> = {};
|
|
13
|
+
|
|
14
|
+
static init() {
|
|
15
|
+
const extensionSystem = new ExtensionSystem();
|
|
16
|
+
return extensionSystem;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public async executeExtensionsInitMethods() {
|
|
20
|
+
const extensions = Lobb.instance.configManager.getExtensions();
|
|
21
|
+
if (extensions) {
|
|
22
|
+
for (let index = 0; index < extensions.length; index++) {
|
|
23
|
+
const extension = extensions[index];
|
|
24
|
+
if (extension.init) {
|
|
25
|
+
await extension.init(Lobb.instance);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public async loadExtensionsCollections() {
|
|
32
|
+
const extensionCollections = await this.getExtensionCollections();
|
|
33
|
+
Lobb.instance.configManager.config.collections = {
|
|
34
|
+
...Lobb.instance.configManager.config.collections,
|
|
35
|
+
...extensionCollections,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const extensionsRelations = await this.getExtensionRelations();
|
|
39
|
+
|
|
40
|
+
if (typeof Lobb.instance.configManager.config.relations === "undefined") {
|
|
41
|
+
Lobb.instance.configManager.config.relations = [];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
Lobb.instance.configManager.config.relations = [
|
|
45
|
+
...Lobb.instance.configManager.config.relations,
|
|
46
|
+
...extensionsRelations,
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private getExtensionRelations() {
|
|
51
|
+
const extensions = Lobb.instance.configManager.getExtensions();
|
|
52
|
+
const relations = [];
|
|
53
|
+
if (extensions) {
|
|
54
|
+
for (let index = 0; index < extensions.length; index++) {
|
|
55
|
+
const extension = extensions[index];
|
|
56
|
+
if (extension.relations) {
|
|
57
|
+
const extensionRelation = extension.relations(Lobb.instance);
|
|
58
|
+
if (extensionRelation) {
|
|
59
|
+
relations.push(...extensionRelation);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return relations;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public async executeExtensionsCloseMethods() {
|
|
68
|
+
const extensions = Lobb.instance.configManager.getExtensions();
|
|
69
|
+
if (extensions) {
|
|
70
|
+
for (let index = 0; index < extensions.length; index++) {
|
|
71
|
+
const extension = extensions[index];
|
|
72
|
+
if (extension.close) {
|
|
73
|
+
await extension.close(Lobb.instance);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public collectionMiddlewares(route: Hono) {
|
|
80
|
+
const extensions = Lobb.instance.configManager.getExtensions();
|
|
81
|
+
if (extensions) {
|
|
82
|
+
for (let index = 0; index < extensions.length; index++) {
|
|
83
|
+
const extension = extensions[index];
|
|
84
|
+
if (extension.collectionMiddlewares) {
|
|
85
|
+
route.use(...extension.collectionMiddlewares);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public async getExtensionMeta(extensionName: string) {
|
|
92
|
+
const extension = Lobb.instance.configManager.getExtension(extensionName);
|
|
93
|
+
if (extension) {
|
|
94
|
+
const extensionMeta = extension.meta
|
|
95
|
+
? await extension.meta(Lobb.instance)
|
|
96
|
+
: {};
|
|
97
|
+
extensionMeta.version = extension.version;
|
|
98
|
+
return extensionMeta;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public getExtensionsOpenApiPaths() {
|
|
103
|
+
const extensions = Lobb.instance.configManager.getExtensions();
|
|
104
|
+
let extensionPaths: Record<string, any> = {};
|
|
105
|
+
if (extensions) {
|
|
106
|
+
for (let index = 0; index < extensions.length; index++) {
|
|
107
|
+
const extension = extensions[index];
|
|
108
|
+
if (extension.openapi) {
|
|
109
|
+
const extensionOpenapi = _.cloneDeep(extension.openapi);
|
|
110
|
+
extensionPaths = {
|
|
111
|
+
...extensionPaths,
|
|
112
|
+
...extensionOpenapi.paths,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return extensionPaths;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public getExtensionsOpenApiComponents() {
|
|
121
|
+
const extensions = Lobb.instance.configManager.getExtensions();
|
|
122
|
+
let extensionComponents: Record<string, any> = {};
|
|
123
|
+
|
|
124
|
+
if (extensions) {
|
|
125
|
+
for (let index = 0; index < extensions.length; index++) {
|
|
126
|
+
const extension = extensions[index];
|
|
127
|
+
if (extension.openapi) {
|
|
128
|
+
extensionComponents = {
|
|
129
|
+
...extensionComponents,
|
|
130
|
+
...extension.openapi.components,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return extensionComponents;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
public async getExtensionCollections() {
|
|
140
|
+
const extensions = Lobb.instance.configManager.getExtensions();
|
|
141
|
+
|
|
142
|
+
let extensionCollections: Record<string, CollectionConfig> = {};
|
|
143
|
+
if (extensions) {
|
|
144
|
+
for (let index = 0; index < extensions.length; index++) {
|
|
145
|
+
const extension = extensions[index];
|
|
146
|
+
if (extension.collections) {
|
|
147
|
+
const collections: Record<string, CollectionConfig> = await extension
|
|
148
|
+
.collections(Lobb.instance);
|
|
149
|
+
|
|
150
|
+
const collectionNames = Object.keys(collections);
|
|
151
|
+
for (let index = 0; index < collectionNames.length; index++) {
|
|
152
|
+
const collectionName = collectionNames[index];
|
|
153
|
+
this.collectionsOwners[collectionName] = extension.name;
|
|
154
|
+
if (!collectionName.startsWith(`${extension.name}_`)) {
|
|
155
|
+
throw new LobbError({
|
|
156
|
+
code: "INTERNAL_SERVER_ERROR",
|
|
157
|
+
message:
|
|
158
|
+
`Collections from (${extension.name}) must be prefixed with (${extension.name}_) to avoid naming conflicts.`,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
extensionCollections = {
|
|
164
|
+
...extensionCollections,
|
|
165
|
+
...collections,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return extensionCollections;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
public routes() {
|
|
175
|
+
const extensionRoute = new Hono();
|
|
176
|
+
const extensions = Lobb.instance.configManager.getExtensions();
|
|
177
|
+
if (extensions) {
|
|
178
|
+
for (let index = 0; index < extensions.length; index++) {
|
|
179
|
+
const extension = extensions[index];
|
|
180
|
+
extensionRoute.route(
|
|
181
|
+
`/${extension.name}/dashboard`,
|
|
182
|
+
getDashboardRoute(extension.dashboard),
|
|
183
|
+
);
|
|
184
|
+
if (extension.routes) {
|
|
185
|
+
extensionRoute.route(`/${extension.name}`, extension.routes());
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return extensionRoute;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
public collectionRoutes(route: Hono) {
|
|
193
|
+
const extensions = Lobb.instance.configManager.getExtensions();
|
|
194
|
+
if (extensions) {
|
|
195
|
+
for (let index = 0; index < extensions.length; index++) {
|
|
196
|
+
const extension = extensions[index];
|
|
197
|
+
if (extension.collectionRoutes) {
|
|
198
|
+
extension.collectionRoutes(route);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
public getCollectionOwner(collectionName: string) {
|
|
205
|
+
if (this.collectionsOwners[collectionName]) {
|
|
206
|
+
return this.collectionsOwners[collectionName];
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
public getMigrations(extensionName: string): Migrations {
|
|
212
|
+
const extension = Lobb.instance.configManager.getExtension(extensionName);
|
|
213
|
+
if (extension) {
|
|
214
|
+
return extension.migrations ?? {};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
throw new LobbError({
|
|
218
|
+
code: "INTERNAL_SERVER_ERROR",
|
|
219
|
+
message:
|
|
220
|
+
"Couldn't find the extension in the (getMigrations) extensionSystem function",
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
public getWorkflows(extensionName: string): Workflow[] {
|
|
225
|
+
const extension = Lobb.instance.configManager.getExtension(extensionName);
|
|
226
|
+
if (extension) {
|
|
227
|
+
return extension.workflows ?? [];
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
throw new LobbError({
|
|
231
|
+
code: "INTERNAL_SERVER_ERROR",
|
|
232
|
+
message:
|
|
233
|
+
"Couldn't find the extension in the (getWorkflows) extensionSystem function",
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
import type { Dashboard } from "../types/index.ts";
|
|
3
|
+
|
|
4
|
+
import { Hono } from "hono";
|
|
5
|
+
import { LobbError } from "../LobbError.ts";
|
|
6
|
+
|
|
7
|
+
export function getDashboardRoute(dashboard?: Dashboard) {
|
|
8
|
+
const route = new Hono();
|
|
9
|
+
|
|
10
|
+
route.get(
|
|
11
|
+
"/",
|
|
12
|
+
(c: Context) => {
|
|
13
|
+
if (!dashboard) {
|
|
14
|
+
throw new LobbError({
|
|
15
|
+
code: "NOT_FOUND",
|
|
16
|
+
message: "This extension doesnt have a dashboard",
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!dashboard.extension) {
|
|
21
|
+
throw new LobbError({
|
|
22
|
+
code: "NOT_FOUND",
|
|
23
|
+
message:
|
|
24
|
+
"The dashboard json of this extension doesnt have an extension property",
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return c.body(dashboard.extension, 200, {
|
|
29
|
+
"Content-Type": "application/javascript",
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
return route;
|
|
35
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// import { Field, type FieldOperatorsType } from "./Field.ts";
|
|
2
|
+
|
|
3
|
+
// export class ArrayField extends Field {
|
|
4
|
+
// public static override type: string = "array";
|
|
5
|
+
// protected fieldName: string;
|
|
6
|
+
// protected collectionName: string;
|
|
7
|
+
// public fieldOperatorsType: FieldOperatorsType = "string";
|
|
8
|
+
|
|
9
|
+
// constructor(fieldName: string, collectionName: string) {
|
|
10
|
+
// super();
|
|
11
|
+
// this.fieldName = fieldName;
|
|
12
|
+
// this.collectionName = collectionName;
|
|
13
|
+
// }
|
|
14
|
+
|
|
15
|
+
// public override encodeFieldValue(value: any): any[] | null {
|
|
16
|
+
// if (value === null || value === undefined) {
|
|
17
|
+
// return null;
|
|
18
|
+
// }
|
|
19
|
+
|
|
20
|
+
// if (typeof value === "string") {
|
|
21
|
+
// try {
|
|
22
|
+
// value = JSON.parse(value);
|
|
23
|
+
// } catch (_error) {
|
|
24
|
+
// this.throwIncompatibleValueTypeError();
|
|
25
|
+
// }
|
|
26
|
+
// }
|
|
27
|
+
|
|
28
|
+
// if (!Array.isArray(value)) {
|
|
29
|
+
// this.throwIncompatibleValueTypeError();
|
|
30
|
+
// }
|
|
31
|
+
// return value;
|
|
32
|
+
// }
|
|
33
|
+
// }
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Field } from "../types/index.ts";
|
|
2
|
+
|
|
3
|
+
export class BoolField extends Field {
|
|
4
|
+
public static override type: string = "bool";
|
|
5
|
+
protected fieldName: string;
|
|
6
|
+
protected collectionName: string;
|
|
7
|
+
|
|
8
|
+
constructor(fieldName: string, collectionName: string) {
|
|
9
|
+
super();
|
|
10
|
+
this.fieldName = fieldName;
|
|
11
|
+
this.collectionName = collectionName;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public override encodeFieldValue(value: any): boolean | null {
|
|
15
|
+
if (value === null || value === undefined || value === "null") {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (typeof value === "boolean") {
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (typeof value === "string") {
|
|
24
|
+
const lowerCaseValue = value.toLowerCase().trim();
|
|
25
|
+
if (lowerCaseValue === "true" || lowerCaseValue === "1") {
|
|
26
|
+
return true;
|
|
27
|
+
} else if (lowerCaseValue === "false" || lowerCaseValue === "0") {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
this.throwIncompatibleValueTypeError();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Field } from "../types/index.ts";
|
|
2
|
+
|
|
3
|
+
export class DateField extends Field {
|
|
4
|
+
public static override type: string = "date";
|
|
5
|
+
protected fieldName: string;
|
|
6
|
+
protected collectionName: string;
|
|
7
|
+
|
|
8
|
+
constructor(fieldName: string, collectionName: string) {
|
|
9
|
+
super();
|
|
10
|
+
this.fieldName = fieldName;
|
|
11
|
+
this.collectionName = collectionName;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Field } from "../types/index.ts";
|
|
2
|
+
|
|
3
|
+
export class DateTimeField extends Field {
|
|
4
|
+
public static override type: string = "datetime";
|
|
5
|
+
protected fieldName: string;
|
|
6
|
+
protected collectionName: string;
|
|
7
|
+
|
|
8
|
+
constructor(fieldName: string, collectionName: string) {
|
|
9
|
+
super();
|
|
10
|
+
this.fieldName = fieldName;
|
|
11
|
+
this.collectionName = collectionName;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Field } from "../types/index.ts";
|
|
2
|
+
|
|
3
|
+
export class DecimalField extends Field {
|
|
4
|
+
public static override type: string = "decimal";
|
|
5
|
+
protected fieldName: string;
|
|
6
|
+
protected collectionName: string;
|
|
7
|
+
|
|
8
|
+
constructor(fieldName: string, collectionName: string) {
|
|
9
|
+
super();
|
|
10
|
+
this.fieldName = fieldName;
|
|
11
|
+
this.collectionName = collectionName;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Field } from "../types/index.ts";
|
|
2
|
+
import { StringField } from "../fields/StringField.ts";
|
|
3
|
+
import { TextField } from "../fields/TextField.ts";
|
|
4
|
+
import { DateField } from "../fields/DateField.ts";
|
|
5
|
+
import { LongField } from "../fields/LongField.ts";
|
|
6
|
+
import { DecimalField } from "../fields/DecimalField.ts";
|
|
7
|
+
import { FloatField } from "../fields/FloatField.ts";
|
|
8
|
+
import { BoolField } from "../fields/BoolField.ts";
|
|
9
|
+
import { IntegerField } from "../fields/IntegerField.ts";
|
|
10
|
+
|
|
11
|
+
import { LobbError } from "../LobbError.ts";
|
|
12
|
+
import { TimeField } from "./TimeField.ts";
|
|
13
|
+
import { DateTimeField } from "./DateTimeField.ts";
|
|
14
|
+
import { Lobb } from "../Lobb.ts";
|
|
15
|
+
|
|
16
|
+
export class FieldUtils {
|
|
17
|
+
public static fieldClasses: any[] = [
|
|
18
|
+
StringField,
|
|
19
|
+
TextField,
|
|
20
|
+
LongField,
|
|
21
|
+
DecimalField,
|
|
22
|
+
FloatField,
|
|
23
|
+
BoolField,
|
|
24
|
+
IntegerField,
|
|
25
|
+
DateField,
|
|
26
|
+
TimeField,
|
|
27
|
+
DateTimeField,
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
public static getFieldInstance(
|
|
31
|
+
fieldName: string,
|
|
32
|
+
collectionName: string,
|
|
33
|
+
): Field {
|
|
34
|
+
const fieldConfig = Lobb.instance.configManager.getField(
|
|
35
|
+
fieldName,
|
|
36
|
+
collectionName,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
for (let index = 0; index < this.fieldClasses.length; index++) {
|
|
40
|
+
const FieldClass = this.fieldClasses[index];
|
|
41
|
+
if (FieldClass.type === fieldConfig.type) {
|
|
42
|
+
return new FieldClass(fieldName, collectionName) as Field;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
throw new LobbError({
|
|
47
|
+
code: "INTERNAL_SERVER_ERROR",
|
|
48
|
+
message:
|
|
49
|
+
`The ${fieldConfig.type} CollectionFieldType specified by the user doesnt exist`,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public static getFieldsTypes(): string[] {
|
|
54
|
+
return this.fieldClasses.map((Class) => Class.type);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Field } from "../types/index.ts";
|
|
2
|
+
|
|
3
|
+
export class FloatField extends Field {
|
|
4
|
+
public static override type: string = "float";
|
|
5
|
+
protected fieldName: string;
|
|
6
|
+
protected collectionName: string;
|
|
7
|
+
|
|
8
|
+
constructor(fieldName: string, collectionName: string) {
|
|
9
|
+
super();
|
|
10
|
+
this.fieldName = fieldName;
|
|
11
|
+
this.collectionName = collectionName;
|
|
12
|
+
}
|
|
13
|
+
}
|