morio_bridge 0.1.0 → 0.1.2
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.
- checksums.yaml +4 -4
- data/bin/post-install.sh +1 -1
- data/morio_bridge.gemspec +4 -3
- data/server/bun.lock +116 -0
- data/server/db/pg-dev/client/client.ts +47 -0
- data/server/db/pg-dev/client/commonInputTypes.ts +141 -0
- data/server/db/pg-dev/client/enums.ts +13 -0
- data/server/db/pg-dev/client/index.ts +5 -0
- data/server/db/pg-dev/client/internal/class.ts +242 -0
- data/server/db/pg-dev/client/internal/prismaNamespace.ts +760 -0
- data/server/db/pg-dev/client/models/User.ts +1151 -0
- data/server/db/pg-dev/client/models.ts +11 -0
- data/server/db/pg-dev/schema.prisma +24 -0
- data/server/examples/commands.ts +95 -0
- data/server/examples/create-test.ts +21 -0
- data/server/index.ts +349 -0
- data/server/package.json +45 -0
- data/server/plugins/index.ts +26 -0
- data/server/plugins/lib/correct.schema.prisma +131 -0
- data/server/plugins/lib/schema-converter.ts +1393 -0
- data/server/plugins/lib/schema.ts +469 -0
- data/server/plugins/lib/util.ts +51 -0
- data/server/plugins/orm.ts +32 -0
- data/server/plugins/validator.ts +191 -0
- data/server/tsconfig.json +28 -0
- metadata +23 -1
@@ -0,0 +1,469 @@
|
|
1
|
+
import { execSync } from "child_process";
|
2
|
+
|
3
|
+
// Prisma scalar types
|
4
|
+
type PrismaScalarType =
|
5
|
+
| "String"
|
6
|
+
| "Int"
|
7
|
+
| "BigInt"
|
8
|
+
| "Float"
|
9
|
+
| "Decimal"
|
10
|
+
| "Boolean"
|
11
|
+
| "DateTime"
|
12
|
+
| "Json"
|
13
|
+
| "Bytes";
|
14
|
+
|
15
|
+
// DSL field type
|
16
|
+
interface DSLField {
|
17
|
+
name: string;
|
18
|
+
type: PrismaScalarType;
|
19
|
+
primaryKey?: boolean;
|
20
|
+
nullable?: boolean;
|
21
|
+
autoIncrement?: boolean;
|
22
|
+
unique?: boolean;
|
23
|
+
default?: string | number | boolean;
|
24
|
+
length?: number;
|
25
|
+
precision?: number;
|
26
|
+
index?: boolean;
|
27
|
+
}
|
28
|
+
|
29
|
+
// DSL relation type
|
30
|
+
interface DSLRelation {
|
31
|
+
foreignKey?: string;
|
32
|
+
relatedTo: string;
|
33
|
+
relationType: "ManyToOne" | "OneToMany" | "OneToOne" | "ManyToMany";
|
34
|
+
onDelete?: "CASCADE" | "SET NULL" | "RESTRICT" | "NO ACTION";
|
35
|
+
relationName?: string;
|
36
|
+
}
|
37
|
+
|
38
|
+
// DSL model type
|
39
|
+
interface DSLModel {
|
40
|
+
model: string;
|
41
|
+
tableName?: string;
|
42
|
+
fields: DSLField[];
|
43
|
+
relations?: DSLRelation[];
|
44
|
+
indexes?: Record<
|
45
|
+
string,
|
46
|
+
{ name: string; fields: string[]; unique?: boolean }
|
47
|
+
>;
|
48
|
+
}
|
49
|
+
|
50
|
+
// DSL structure
|
51
|
+
interface DSL {
|
52
|
+
database: {
|
53
|
+
name: string;
|
54
|
+
type: string;
|
55
|
+
environment?: string;
|
56
|
+
enabled?: boolean;
|
57
|
+
connectionStringEnv: string;
|
58
|
+
};
|
59
|
+
schemas: DSLModel[];
|
60
|
+
}
|
61
|
+
|
62
|
+
const validatePrismaSchema = (schemaPath: string) => {
|
63
|
+
execSync(`prisma format --schema=${schemaPath}`, { stdio: "inherit" });
|
64
|
+
};
|
65
|
+
|
66
|
+
// Standalone method to convert DSL to Prisma schema
|
67
|
+
const dslToPrismaSchema = async ({
|
68
|
+
dsl,
|
69
|
+
outputPath,
|
70
|
+
}: {
|
71
|
+
dsl: DSL;
|
72
|
+
outputPath: string;
|
73
|
+
}): Promise<string> => {
|
74
|
+
if (!dsl.database || !dsl.schemas) {
|
75
|
+
throw new Error('Invalid DSL: Missing "database" or "schemas" section');
|
76
|
+
}
|
77
|
+
|
78
|
+
let schema = "";
|
79
|
+
|
80
|
+
schema += `datasource db {\n`;
|
81
|
+
schema += ` provider = "${dsl.database.type}"\n`;
|
82
|
+
schema += ` url = env("${dsl.database.connectionStringEnv}")\n`;
|
83
|
+
schema += `}\n\n`;
|
84
|
+
|
85
|
+
schema += `generator client {\n`;
|
86
|
+
schema += ` provider = "prisma-client-js"\n`;
|
87
|
+
schema += `}\n\n`;
|
88
|
+
|
89
|
+
dsl.schemas.forEach((model: DSLModel) => {
|
90
|
+
schema += `model ${model.model} {\n`;
|
91
|
+
|
92
|
+
// Fields
|
93
|
+
model.fields.forEach((field: DSLField) => {
|
94
|
+
let fieldDef = ` ${field.name} ${field.type}${
|
95
|
+
field.nullable ? "?" : ""
|
96
|
+
}`;
|
97
|
+
|
98
|
+
if (field.primaryKey) {
|
99
|
+
fieldDef += " @id";
|
100
|
+
if (field.autoIncrement) fieldDef += " @default(autoincrement())";
|
101
|
+
}
|
102
|
+
if (field.unique) fieldDef += " @unique";
|
103
|
+
if (field.default !== undefined) {
|
104
|
+
fieldDef += ` @default(${
|
105
|
+
field.default === "now" ? "now()" : field.default
|
106
|
+
})`;
|
107
|
+
}
|
108
|
+
// Apply length only to String types as VarChar
|
109
|
+
if (field.type === "String" && field.length) {
|
110
|
+
fieldDef += ` @db.VarChar(${field.length})`;
|
111
|
+
}
|
112
|
+
// Apply length and precision to Decimal types
|
113
|
+
if (field.type === "Decimal" && (field.length || field.precision)) {
|
114
|
+
fieldDef += ` @db.Decimal(${field.length || 15}, ${
|
115
|
+
field.precision || 0
|
116
|
+
})`;
|
117
|
+
}
|
118
|
+
if (field.index) {
|
119
|
+
schema += `${fieldDef}\n`;
|
120
|
+
schema += ` @@index([${field.name}])\n`;
|
121
|
+
return;
|
122
|
+
}
|
123
|
+
|
124
|
+
schema += `${fieldDef}\n`;
|
125
|
+
});
|
126
|
+
|
127
|
+
// Relations
|
128
|
+
if (model.relations) {
|
129
|
+
model.relations.forEach((rel: DSLRelation) => {
|
130
|
+
const relationName = rel.relationName
|
131
|
+
? `"${rel.relationName}"`
|
132
|
+
: undefined;
|
133
|
+
const relatedFieldName = rel.relatedTo.toLowerCase();
|
134
|
+
|
135
|
+
switch (rel.relationType) {
|
136
|
+
case "ManyToOne":
|
137
|
+
schema += ` ${rel.foreignKey} Int\n`;
|
138
|
+
schema += ` ${relatedFieldName} ${rel.relatedTo} @relation(${
|
139
|
+
relationName ? `${relationName}, ` : ""
|
140
|
+
}fields: [${rel.foreignKey}], references: [id]${
|
141
|
+
rel.onDelete ? `, onDelete: ${rel.onDelete}` : ""
|
142
|
+
})\n`;
|
143
|
+
break;
|
144
|
+
case "OneToMany":
|
145
|
+
schema += ` ${relatedFieldName} ${rel.relatedTo}[]${
|
146
|
+
relationName ? ` @relation(${relationName})` : ""
|
147
|
+
}\n`;
|
148
|
+
break;
|
149
|
+
case "OneToOne":
|
150
|
+
if (rel.foreignKey) {
|
151
|
+
schema += ` ${rel.foreignKey} Int @unique\n`;
|
152
|
+
schema += ` ${relatedFieldName} ${rel.relatedTo} @relation(${
|
153
|
+
relationName ? `${relationName}, ` : ""
|
154
|
+
}fields: [${rel.foreignKey}], references: [id]${
|
155
|
+
rel.onDelete ? `, onDelete: ${rel.onDelete}` : ""
|
156
|
+
})\n`;
|
157
|
+
} else {
|
158
|
+
schema += ` ${relatedFieldName} ${rel.relatedTo}?${
|
159
|
+
relationName ? ` @relation(${relationName})` : ""
|
160
|
+
}\n`;
|
161
|
+
}
|
162
|
+
break;
|
163
|
+
case "ManyToMany":
|
164
|
+
throw new Error(
|
165
|
+
"ManyToMany relations require explicit join table definition in DSL"
|
166
|
+
);
|
167
|
+
default:
|
168
|
+
throw new Error(`Unsupported relation type: ${rel.relationType}`);
|
169
|
+
}
|
170
|
+
});
|
171
|
+
}
|
172
|
+
|
173
|
+
// Indexes
|
174
|
+
if (model.indexes) {
|
175
|
+
Object.values(model.indexes).forEach((idx) => {
|
176
|
+
const fields = idx.fields.join(", ");
|
177
|
+
schema += ` @@index([${fields}], name: "${idx.name}"${
|
178
|
+
idx.unique ? ", unique: true" : ""
|
179
|
+
})\n`;
|
180
|
+
});
|
181
|
+
}
|
182
|
+
|
183
|
+
// map table names
|
184
|
+
if (model.tableName) {
|
185
|
+
schema += ` @@map("${model.tableName}")\n`;
|
186
|
+
}
|
187
|
+
|
188
|
+
schema += `}\n\n`;
|
189
|
+
});
|
190
|
+
|
191
|
+
try {
|
192
|
+
await Bun.write(outputPath, schema, { createPath: true });
|
193
|
+
validatePrismaSchema(outputPath);
|
194
|
+
} catch (error: any) {
|
195
|
+
throw new Error(`Failed to format schema: ${error.message}`);
|
196
|
+
}
|
197
|
+
|
198
|
+
return schema;
|
199
|
+
};
|
200
|
+
|
201
|
+
// Example DSL with inverse OneToMany and custom relation names
|
202
|
+
await dslToPrismaSchema({
|
203
|
+
dsl: {
|
204
|
+
database: {
|
205
|
+
name: "uwazi_spring_db",
|
206
|
+
type: "postgres",
|
207
|
+
environment: "prod",
|
208
|
+
enabled: true,
|
209
|
+
connectionStringEnv: "UWAZI_SPRING_DATABASE_URL",
|
210
|
+
},
|
211
|
+
schemas: [
|
212
|
+
{
|
213
|
+
model: "AuditTrail",
|
214
|
+
tableName: "audit_trails",
|
215
|
+
fields: [
|
216
|
+
{
|
217
|
+
name: "id",
|
218
|
+
type: "Int",
|
219
|
+
primaryKey: true,
|
220
|
+
nullable: false,
|
221
|
+
autoIncrement: true,
|
222
|
+
},
|
223
|
+
{ name: "log_ref", type: "String", length: 50, nullable: false },
|
224
|
+
{ name: "user_name", type: "String", length: 50 },
|
225
|
+
{ name: "active_page", type: "String", length: 255 },
|
226
|
+
{ name: "activity_done", type: "String", length: 255 },
|
227
|
+
{ name: "system_module", type: "String", length: 100 },
|
228
|
+
{ name: "audit_date", type: "DateTime", default: "now" },
|
229
|
+
{ name: "ip_address", type: "String", length: 50 },
|
230
|
+
],
|
231
|
+
},
|
232
|
+
{
|
233
|
+
model: "Claim",
|
234
|
+
tableName: "claims",
|
235
|
+
fields: [
|
236
|
+
{
|
237
|
+
name: "id",
|
238
|
+
type: "Int",
|
239
|
+
primaryKey: true,
|
240
|
+
nullable: false,
|
241
|
+
autoIncrement: true,
|
242
|
+
},
|
243
|
+
{
|
244
|
+
name: "claim_reference",
|
245
|
+
type: "String",
|
246
|
+
length: 50,
|
247
|
+
nullable: false,
|
248
|
+
index: true,
|
249
|
+
},
|
250
|
+
{
|
251
|
+
name: "invoice_number",
|
252
|
+
type: "String",
|
253
|
+
length: 50,
|
254
|
+
unique: true,
|
255
|
+
nullable: false,
|
256
|
+
index: true,
|
257
|
+
},
|
258
|
+
{ name: "policy_number", type: "String", length: 50 },
|
259
|
+
{
|
260
|
+
name: "invoice_amount",
|
261
|
+
type: "Decimal",
|
262
|
+
nullable: false,
|
263
|
+
length: 15,
|
264
|
+
precision: 2,
|
265
|
+
},
|
266
|
+
{ name: "min_cost", type: "Decimal", length: 15, precision: 2 },
|
267
|
+
{ name: "maximum_cost", type: "Decimal", length: 15, precision: 2 },
|
268
|
+
{ name: "risk_classification", type: "String", length: 50 },
|
269
|
+
{ name: "claim_narration", type: "String", length: 500 },
|
270
|
+
{ name: "created_by", type: "String", length: 100 },
|
271
|
+
{ name: "approved_by", type: "String", length: 100 },
|
272
|
+
{ name: "created_at", type: "DateTime", default: "now" },
|
273
|
+
{ name: "date_approved", type: "DateTime" },
|
274
|
+
{ name: "approval_remarks", type: "String", length: 255 },
|
275
|
+
{ name: "status_code", type: "String", length: 50 },
|
276
|
+
{ name: "status_description", type: "String" }, // Changed from Text to String
|
277
|
+
],
|
278
|
+
relations: [
|
279
|
+
{
|
280
|
+
foreignKey: "treatment_id",
|
281
|
+
relatedTo: "Treatment",
|
282
|
+
relationType: "ManyToOne",
|
283
|
+
onDelete: "CASCADE",
|
284
|
+
},
|
285
|
+
{
|
286
|
+
foreignKey: "hospital_id",
|
287
|
+
relatedTo: "Organisation",
|
288
|
+
relationType: "ManyToOne",
|
289
|
+
onDelete: "CASCADE",
|
290
|
+
relationName: "HospitalClaims",
|
291
|
+
},
|
292
|
+
{
|
293
|
+
foreignKey: "insured_id",
|
294
|
+
relatedTo: "Organisation",
|
295
|
+
relationType: "ManyToOne",
|
296
|
+
onDelete: "CASCADE",
|
297
|
+
relationName: "InsuredClaims",
|
298
|
+
},
|
299
|
+
],
|
300
|
+
},
|
301
|
+
{
|
302
|
+
model: "Organisation",
|
303
|
+
tableName: "organisations",
|
304
|
+
fields: [
|
305
|
+
{
|
306
|
+
name: "id",
|
307
|
+
type: "Int",
|
308
|
+
primaryKey: true,
|
309
|
+
autoIncrement: true,
|
310
|
+
nullable: false,
|
311
|
+
},
|
312
|
+
{
|
313
|
+
name: "code",
|
314
|
+
type: "String",
|
315
|
+
length: 50,
|
316
|
+
unique: true,
|
317
|
+
nullable: false,
|
318
|
+
index: true,
|
319
|
+
},
|
320
|
+
{ name: "name", type: "String", length: 255, nullable: false },
|
321
|
+
{ name: "type", type: "String", length: 50, nullable: false },
|
322
|
+
{ name: "kra_pin", type: "String", length: 50, nullable: true },
|
323
|
+
{ name: "head_quarter_location", type: "String", nullable: true },
|
324
|
+
{
|
325
|
+
name: "email_address",
|
326
|
+
type: "String",
|
327
|
+
length: 255,
|
328
|
+
unique: true,
|
329
|
+
nullable: true,
|
330
|
+
},
|
331
|
+
{ name: "mobile_number", type: "String", length: 20, nullable: true },
|
332
|
+
{
|
333
|
+
name: "hospital_category",
|
334
|
+
type: "String",
|
335
|
+
length: 50,
|
336
|
+
nullable: true,
|
337
|
+
},
|
338
|
+
{ name: "created_at", type: "DateTime", default: "now" },
|
339
|
+
{ name: "updated_at", type: "DateTime" },
|
340
|
+
{ name: "created_by", type: "String", length: 100 },
|
341
|
+
{ name: "approved_by", type: "String", length: 100 },
|
342
|
+
{ name: "approved_at", type: "DateTime", default: "now" },
|
343
|
+
{ name: "status_code", type: "String", length: 50, nullable: false },
|
344
|
+
{ name: "status_description", type: "String", nullable: true }, // Changed from Text to String
|
345
|
+
],
|
346
|
+
relations: [
|
347
|
+
{
|
348
|
+
relatedTo: "Claim",
|
349
|
+
relationType: "OneToMany",
|
350
|
+
relationName: "HospitalClaims",
|
351
|
+
},
|
352
|
+
{
|
353
|
+
relatedTo: "Claim",
|
354
|
+
relationType: "OneToMany",
|
355
|
+
relationName: "InsuredClaims",
|
356
|
+
},
|
357
|
+
{
|
358
|
+
relatedTo: "User",
|
359
|
+
relationType: "OneToMany",
|
360
|
+
relationName: "OrganisationUsers",
|
361
|
+
},
|
362
|
+
],
|
363
|
+
},
|
364
|
+
{
|
365
|
+
model: "User",
|
366
|
+
tableName: "users",
|
367
|
+
fields: [
|
368
|
+
{
|
369
|
+
name: "id",
|
370
|
+
type: "Int",
|
371
|
+
primaryKey: true,
|
372
|
+
nullable: false,
|
373
|
+
autoIncrement: true,
|
374
|
+
},
|
375
|
+
{
|
376
|
+
name: "user_name",
|
377
|
+
type: "String",
|
378
|
+
length: 100,
|
379
|
+
unique: true,
|
380
|
+
nullable: false,
|
381
|
+
index: true,
|
382
|
+
},
|
383
|
+
{ name: "first_name", type: "String", length: 100, nullable: false },
|
384
|
+
{ name: "second_name", type: "String", length: 100, nullable: true },
|
385
|
+
{ name: "last_name", type: "String", length: 100, nullable: false },
|
386
|
+
{
|
387
|
+
name: "national_id",
|
388
|
+
type: "String",
|
389
|
+
length: 50,
|
390
|
+
nullable: true,
|
391
|
+
unique: true,
|
392
|
+
},
|
393
|
+
{ name: "gender", type: "String", length: 10, nullable: true },
|
394
|
+
{ name: "dob", type: "DateTime", nullable: true }, // Changed from Date to DateTime
|
395
|
+
{
|
396
|
+
name: "mobile_number",
|
397
|
+
type: "String",
|
398
|
+
length: 20,
|
399
|
+
unique: true,
|
400
|
+
nullable: true,
|
401
|
+
},
|
402
|
+
{
|
403
|
+
name: "email",
|
404
|
+
type: "String",
|
405
|
+
length: 255,
|
406
|
+
unique: true,
|
407
|
+
nullable: false,
|
408
|
+
index: true,
|
409
|
+
},
|
410
|
+
{
|
411
|
+
name: "password_hash",
|
412
|
+
type: "String",
|
413
|
+
length: 255,
|
414
|
+
nullable: false,
|
415
|
+
},
|
416
|
+
{ name: "last_login_date", type: "DateTime", nullable: true },
|
417
|
+
{ name: "login_trials", type: "Int", default: 3, nullable: true },
|
418
|
+
{ name: "login_ip", type: "String", length: 50, nullable: true },
|
419
|
+
{ name: "created_by", type: "String", length: 100, nullable: false },
|
420
|
+
{
|
421
|
+
name: "created_at",
|
422
|
+
type: "DateTime",
|
423
|
+
default: "now",
|
424
|
+
nullable: true,
|
425
|
+
},
|
426
|
+
{ name: "approved_by", type: "String", length: 100, nullable: true },
|
427
|
+
{
|
428
|
+
name: "approved_at",
|
429
|
+
type: "DateTime",
|
430
|
+
default: "now",
|
431
|
+
nullable: true,
|
432
|
+
},
|
433
|
+
{ name: "updated_at", type: "DateTime", nullable: true },
|
434
|
+
{ name: "status_code", type: "String", length: 50, nullable: false },
|
435
|
+
{ name: "status_description", type: "String", nullable: true }, // Changed from Text to String
|
436
|
+
],
|
437
|
+
relations: [
|
438
|
+
{
|
439
|
+
foreignKey: "role_id",
|
440
|
+
relatedTo: "Role",
|
441
|
+
relationType: "ManyToOne",
|
442
|
+
},
|
443
|
+
{
|
444
|
+
foreignKey: "organisation_id",
|
445
|
+
relatedTo: "Organisation",
|
446
|
+
relationType: "ManyToOne",
|
447
|
+
relationName: "OrganisationUsers",
|
448
|
+
},
|
449
|
+
],
|
450
|
+
indexes: {
|
451
|
+
user_name_email_idx: {
|
452
|
+
name: "user_name_email_idx",
|
453
|
+
fields: ["user_name", "email"],
|
454
|
+
unique: true,
|
455
|
+
},
|
456
|
+
mobile_national_id_idx: {
|
457
|
+
name: "mobile_national_id_idx",
|
458
|
+
fields: ["mobile_number", "national_id"],
|
459
|
+
},
|
460
|
+
login_perf_idx: {
|
461
|
+
name: "login_perf_idx",
|
462
|
+
fields: ["last_login_date", "status_code"],
|
463
|
+
},
|
464
|
+
},
|
465
|
+
},
|
466
|
+
],
|
467
|
+
},
|
468
|
+
outputPath: "./schema.prisma",
|
469
|
+
});
|
@@ -0,0 +1,51 @@
|
|
1
|
+
import path from "path";
|
2
|
+
import YAML from "yaml";
|
3
|
+
|
4
|
+
type ParsedConfig = {
|
5
|
+
parsed: Record<string, any[]>;
|
6
|
+
folder: string;
|
7
|
+
mask: string;
|
8
|
+
};
|
9
|
+
|
10
|
+
const parseConfigs = async (): Promise<ParsedConfig> => {
|
11
|
+
const configFolder = path.join(process.cwd(), "config");
|
12
|
+
const mask = "**/*{database,.database}.yml";
|
13
|
+
|
14
|
+
// Get all yml files in one glob which accepts database.yml or *.database.yml
|
15
|
+
const glob = new Bun.Glob(mask);
|
16
|
+
const files = await Array.fromAsync(glob.scan(configFolder));
|
17
|
+
|
18
|
+
// Group files by their parent directory
|
19
|
+
const filesByFolder = files.reduce((acc, file) => {
|
20
|
+
const [folder] = file.split("/");
|
21
|
+
if (!folder) return acc;
|
22
|
+
|
23
|
+
if (!acc[folder]) acc[folder] = [];
|
24
|
+
acc[folder].push(file);
|
25
|
+
return acc;
|
26
|
+
}, {} as Record<string, string[]>);
|
27
|
+
|
28
|
+
// Process each folder's files in parallel
|
29
|
+
const results = await Promise.all(
|
30
|
+
Object.entries(filesByFolder).map(async ([folder, files]) => {
|
31
|
+
// Process all files in this folder in parallel
|
32
|
+
const configs = await Promise.all(
|
33
|
+
files.map(async (file) => {
|
34
|
+
const fullPath = path.join(configFolder, file);
|
35
|
+
const content = await Bun.file(fullPath).text();
|
36
|
+
return YAML.parse(content);
|
37
|
+
})
|
38
|
+
);
|
39
|
+
return [folder, configs] as const;
|
40
|
+
})
|
41
|
+
);
|
42
|
+
|
43
|
+
// Convert results back to record
|
44
|
+
return {
|
45
|
+
folder: configFolder,
|
46
|
+
mask,
|
47
|
+
parsed: Object.fromEntries(results),
|
48
|
+
};
|
49
|
+
};
|
50
|
+
|
51
|
+
export { parseConfigs };
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import { PrismaPg } from "@prisma/adapter-pg";
|
2
|
+
|
3
|
+
export class MorioOrm {
|
4
|
+
private prisma: any;
|
5
|
+
|
6
|
+
constructor() {}
|
7
|
+
|
8
|
+
public async init(): Promise<MorioOrm> {
|
9
|
+
// we need to require the prisma client dynamically
|
10
|
+
const connectionString: string = process.env.DATABASE_URL || "";
|
11
|
+
const { PrismaClient } = await import("../db/pg-dev/client");
|
12
|
+
const adapter = new PrismaPg({ connectionString });
|
13
|
+
this.prisma = new PrismaClient({ adapter });
|
14
|
+
|
15
|
+
return this;
|
16
|
+
}
|
17
|
+
|
18
|
+
public async run(options: any) {
|
19
|
+
try {
|
20
|
+
if (!this.prisma) throw new Error("ORM not initialized");
|
21
|
+
return await (this.prisma as any)[options.model][options.action](
|
22
|
+
options.payload
|
23
|
+
);
|
24
|
+
} catch (error) {
|
25
|
+
if (error instanceof Error) {
|
26
|
+
return {
|
27
|
+
error: error.message,
|
28
|
+
};
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|