@modern-admin/system-prisma 0.1.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/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/stores/ai-task-store.d.ts +43 -0
- package/dist/stores/ai-task-store.d.ts.map +1 -0
- package/dist/stores/ai-task-store.js +108 -0
- package/dist/stores/ai-task-store.js.map +1 -0
- package/dist/stores/cache-store.d.ts +30 -0
- package/dist/stores/cache-store.d.ts.map +1 -0
- package/dist/stores/cache-store.js +61 -0
- package/dist/stores/cache-store.js.map +1 -0
- package/dist/stores/config-store.d.ts +20 -0
- package/dist/stores/config-store.d.ts.map +1 -0
- package/dist/stores/config-store.js +61 -0
- package/dist/stores/config-store.js.map +1 -0
- package/dist/stores/history-store.d.ts +33 -0
- package/dist/stores/history-store.d.ts.map +1 -0
- package/dist/stores/history-store.js +57 -0
- package/dist/stores/history-store.js.map +1 -0
- package/dist/stores/log-store.d.ts +23 -0
- package/dist/stores/log-store.d.ts.map +1 -0
- package/dist/stores/log-store.js +65 -0
- package/dist/stores/log-store.js.map +1 -0
- package/dist/stores/webhook-store.d.ts +43 -0
- package/dist/stores/webhook-store.d.ts.map +1 -0
- package/dist/stores/webhook-store.js +111 -0
- package/dist/stores/webhook-store.js.map +1 -0
- package/dist/types.d.ts +67 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +30 -0
- package/dist/types.js.map +1 -0
- package/package.json +52 -0
- package/src/index.ts +88 -0
- package/src/stores/ai-task-store.ts +154 -0
- package/src/stores/cache-store.ts +79 -0
- package/src/stores/config-store.ts +80 -0
- package/src/stores/history-store.ts +84 -0
- package/src/stores/log-store.ts +77 -0
- package/src/stores/webhook-store.ts +150 -0
- package/src/types.ts +70 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { uuidv7 } from '@modern-admin/core';
|
|
2
|
+
const rowToEntry = (row) => ({
|
|
3
|
+
id: row.id,
|
|
4
|
+
resourceId: row.resourceId,
|
|
5
|
+
action: row.action,
|
|
6
|
+
...(row.recordId !== null ? { recordId: row.recordId } : {}),
|
|
7
|
+
...(Array.isArray(row.recordIds) ? { recordIds: row.recordIds } : {}),
|
|
8
|
+
...(row.userId !== null ? { userId: row.userId } : {}),
|
|
9
|
+
...(row.payload !== null && row.payload !== undefined
|
|
10
|
+
? { payload: row.payload }
|
|
11
|
+
: {}),
|
|
12
|
+
...(row.result !== null && row.result !== undefined
|
|
13
|
+
? { result: row.result }
|
|
14
|
+
: {}),
|
|
15
|
+
at: Number(row.at),
|
|
16
|
+
});
|
|
17
|
+
export class PrismaLogStore {
|
|
18
|
+
constructor(delegate) {
|
|
19
|
+
this.delegate = delegate;
|
|
20
|
+
}
|
|
21
|
+
async record(entry) {
|
|
22
|
+
await this.delegate.create({
|
|
23
|
+
data: {
|
|
24
|
+
// Prefer the writer-supplied id (UUID v7 from `actionLoggingPlugin`)
|
|
25
|
+
// so React lists keyed on `entry.id` line up with the persisted row.
|
|
26
|
+
id: entry.id ?? uuidv7(),
|
|
27
|
+
resourceId: entry.resourceId,
|
|
28
|
+
action: entry.action,
|
|
29
|
+
recordId: entry.recordId ?? null,
|
|
30
|
+
recordIds: entry.recordIds ?? null,
|
|
31
|
+
userId: entry.userId ?? null,
|
|
32
|
+
payload: entry.payload ?? null,
|
|
33
|
+
result: entry.result ?? null,
|
|
34
|
+
at: BigInt(entry.at),
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
async list(filter = {}) {
|
|
39
|
+
const where = {};
|
|
40
|
+
if (filter.resourceId)
|
|
41
|
+
where['resourceId'] = filter.resourceId;
|
|
42
|
+
if (filter.recordId)
|
|
43
|
+
where['recordId'] = filter.recordId;
|
|
44
|
+
if (filter.userId)
|
|
45
|
+
where['userId'] = filter.userId;
|
|
46
|
+
if (filter.actions?.length)
|
|
47
|
+
where['action'] = { in: filter.actions };
|
|
48
|
+
if (filter.from || filter.to) {
|
|
49
|
+
const range = {};
|
|
50
|
+
if (filter.from)
|
|
51
|
+
range['gte'] = BigInt(filter.from.getTime());
|
|
52
|
+
if (filter.to)
|
|
53
|
+
range['lte'] = BigInt(filter.to.getTime());
|
|
54
|
+
where['at'] = range;
|
|
55
|
+
}
|
|
56
|
+
const rows = await this.delegate.findMany({
|
|
57
|
+
where,
|
|
58
|
+
orderBy: { at: 'desc' },
|
|
59
|
+
...(filter.limit !== undefined ? { take: filter.limit } : {}),
|
|
60
|
+
...(filter.offset !== undefined ? { skip: filter.offset } : {}),
|
|
61
|
+
});
|
|
62
|
+
return rows.map(rowToEntry);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=log-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-store.js","sourceRoot":"","sources":["../../src/stores/log-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type IWebhookStore, type Webhook, type WebhookDelivery, type WebhookInput } from '@modern-admin/core';
|
|
2
|
+
import type { PrismaDelegate } from '../types.js';
|
|
3
|
+
interface WebhookRow {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
url: string;
|
|
7
|
+
events: unknown;
|
|
8
|
+
resourceId: string | null;
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
secret: string | null;
|
|
11
|
+
headers: unknown;
|
|
12
|
+
filters: unknown;
|
|
13
|
+
payloadFields: unknown;
|
|
14
|
+
createdAt: Date;
|
|
15
|
+
updatedAt: Date;
|
|
16
|
+
}
|
|
17
|
+
interface DeliveryRow {
|
|
18
|
+
id: string;
|
|
19
|
+
webhookId: string;
|
|
20
|
+
event: string;
|
|
21
|
+
payload: unknown;
|
|
22
|
+
status: string;
|
|
23
|
+
responseStatus: number | null;
|
|
24
|
+
responseBody: string | null;
|
|
25
|
+
error: string | null;
|
|
26
|
+
attempt: number;
|
|
27
|
+
createdAt: Date;
|
|
28
|
+
deliveredAt: Date | null;
|
|
29
|
+
}
|
|
30
|
+
export declare class PrismaWebhookStore implements IWebhookStore {
|
|
31
|
+
private readonly webhookDelegate;
|
|
32
|
+
private readonly deliveryDelegate;
|
|
33
|
+
constructor(webhookDelegate: PrismaDelegate<WebhookRow>, deliveryDelegate: PrismaDelegate<DeliveryRow>);
|
|
34
|
+
list(): Promise<Webhook[]>;
|
|
35
|
+
get(id: string): Promise<Webhook | null>;
|
|
36
|
+
create(input: WebhookInput): Promise<Webhook>;
|
|
37
|
+
update(id: string, patch: Partial<WebhookInput>): Promise<Webhook>;
|
|
38
|
+
delete(id: string): Promise<void>;
|
|
39
|
+
recordDelivery(delivery: Omit<WebhookDelivery, 'id' | 'createdAt'>): Promise<WebhookDelivery>;
|
|
40
|
+
listDeliveries(webhookId: string, limit?: number): Promise<WebhookDelivery[]>;
|
|
41
|
+
}
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=webhook-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-store.d.ts","sourceRoot":"","sources":["../../src/stores/webhook-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,OAAO,EACZ,KAAK,eAAe,EAEpB,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,UAAU,UAAU;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,OAAO,CAAA;IACf,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,aAAa,EAAE,OAAO,CAAA;IACtB,SAAS,EAAE,IAAI,CAAA;IACf,SAAS,EAAE,IAAI,CAAA;CAChB;AAED,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,IAAI,CAAA;IACf,WAAW,EAAE,IAAI,GAAG,IAAI,CAAA;CACzB;AA+BD,qBAAa,kBAAmB,YAAW,aAAa;IAEpD,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBADhB,eAAe,EAAE,cAAc,CAAC,UAAU,CAAC,EAC3C,gBAAgB,EAAE,cAAc,CAAC,WAAW,CAAC;IAG1D,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAK1B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAKxC,MAAM,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC;IAkB7C,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAelE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjC,cAAc,CAClB,QAAQ,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,GAAG,WAAW,CAAC,GAClD,OAAO,CAAC,eAAe,CAAC;IAkBrB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAQhF"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { uuidv7, } from '@modern-admin/core';
|
|
2
|
+
const rowToWebhook = (row) => ({
|
|
3
|
+
id: row.id,
|
|
4
|
+
name: row.name,
|
|
5
|
+
url: row.url,
|
|
6
|
+
events: Array.isArray(row.events) ? row.events : [],
|
|
7
|
+
resourceId: row.resourceId,
|
|
8
|
+
enabled: row.enabled,
|
|
9
|
+
...(row.secret !== null ? { secret: row.secret } : {}),
|
|
10
|
+
headers: row.headers ?? {},
|
|
11
|
+
filters: row.filters ?? {},
|
|
12
|
+
payloadFields: Array.isArray(row.payloadFields) ? row.payloadFields : [],
|
|
13
|
+
createdAt: row.createdAt.toISOString(),
|
|
14
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
15
|
+
});
|
|
16
|
+
const rowToDelivery = (row) => ({
|
|
17
|
+
id: row.id,
|
|
18
|
+
webhookId: row.webhookId,
|
|
19
|
+
event: row.event,
|
|
20
|
+
payload: row.payload ?? {},
|
|
21
|
+
status: row.status,
|
|
22
|
+
...(row.responseStatus !== null ? { responseStatus: row.responseStatus } : {}),
|
|
23
|
+
...(row.responseBody !== null ? { responseBody: row.responseBody } : {}),
|
|
24
|
+
...(row.error !== null ? { error: row.error } : {}),
|
|
25
|
+
attempt: row.attempt,
|
|
26
|
+
createdAt: row.createdAt.toISOString(),
|
|
27
|
+
...(row.deliveredAt !== null ? { deliveredAt: row.deliveredAt.toISOString() } : {}),
|
|
28
|
+
});
|
|
29
|
+
export class PrismaWebhookStore {
|
|
30
|
+
constructor(webhookDelegate, deliveryDelegate) {
|
|
31
|
+
this.webhookDelegate = webhookDelegate;
|
|
32
|
+
this.deliveryDelegate = deliveryDelegate;
|
|
33
|
+
}
|
|
34
|
+
async list() {
|
|
35
|
+
const rows = await this.webhookDelegate.findMany({ orderBy: { createdAt: 'desc' } });
|
|
36
|
+
return rows.map(rowToWebhook);
|
|
37
|
+
}
|
|
38
|
+
async get(id) {
|
|
39
|
+
const row = await this.webhookDelegate.findUnique({ where: { id } });
|
|
40
|
+
return row ? rowToWebhook(row) : null;
|
|
41
|
+
}
|
|
42
|
+
async create(input) {
|
|
43
|
+
const row = await this.webhookDelegate.create({
|
|
44
|
+
data: {
|
|
45
|
+
id: uuidv7(),
|
|
46
|
+
name: input.name,
|
|
47
|
+
url: input.url,
|
|
48
|
+
events: input.events,
|
|
49
|
+
resourceId: input.resourceId ?? null,
|
|
50
|
+
enabled: input.enabled ?? true,
|
|
51
|
+
secret: input.secret ?? null,
|
|
52
|
+
headers: input.headers ?? {},
|
|
53
|
+
filters: input.filters ?? {},
|
|
54
|
+
payloadFields: input.payloadFields ?? [],
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
return rowToWebhook(row);
|
|
58
|
+
}
|
|
59
|
+
async update(id, patch) {
|
|
60
|
+
const data = {};
|
|
61
|
+
if (patch.name !== undefined)
|
|
62
|
+
data['name'] = patch.name;
|
|
63
|
+
if (patch.url !== undefined)
|
|
64
|
+
data['url'] = patch.url;
|
|
65
|
+
if (patch.events !== undefined)
|
|
66
|
+
data['events'] = patch.events;
|
|
67
|
+
if (patch.resourceId !== undefined)
|
|
68
|
+
data['resourceId'] = patch.resourceId ?? null;
|
|
69
|
+
if (patch.enabled !== undefined)
|
|
70
|
+
data['enabled'] = patch.enabled;
|
|
71
|
+
if (patch.secret !== undefined)
|
|
72
|
+
data['secret'] = patch.secret;
|
|
73
|
+
if (patch.headers !== undefined)
|
|
74
|
+
data['headers'] = patch.headers;
|
|
75
|
+
if (patch.filters !== undefined)
|
|
76
|
+
data['filters'] = patch.filters;
|
|
77
|
+
if (patch.payloadFields !== undefined)
|
|
78
|
+
data['payloadFields'] = patch.payloadFields;
|
|
79
|
+
const row = await this.webhookDelegate.update({ where: { id }, data });
|
|
80
|
+
return rowToWebhook(row);
|
|
81
|
+
}
|
|
82
|
+
async delete(id) {
|
|
83
|
+
await this.webhookDelegate.delete({ where: { id } });
|
|
84
|
+
}
|
|
85
|
+
async recordDelivery(delivery) {
|
|
86
|
+
const row = await this.deliveryDelegate.create({
|
|
87
|
+
data: {
|
|
88
|
+
id: uuidv7(),
|
|
89
|
+
webhookId: delivery.webhookId,
|
|
90
|
+
event: delivery.event,
|
|
91
|
+
payload: delivery.payload,
|
|
92
|
+
status: delivery.status,
|
|
93
|
+
responseStatus: delivery.responseStatus ?? null,
|
|
94
|
+
responseBody: delivery.responseBody ?? null,
|
|
95
|
+
error: delivery.error ?? null,
|
|
96
|
+
attempt: delivery.attempt,
|
|
97
|
+
deliveredAt: delivery.deliveredAt ? new Date(delivery.deliveredAt) : null,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
return rowToDelivery(row);
|
|
101
|
+
}
|
|
102
|
+
async listDeliveries(webhookId, limit = 50) {
|
|
103
|
+
const rows = await this.deliveryDelegate.findMany({
|
|
104
|
+
where: { webhookId },
|
|
105
|
+
orderBy: { createdAt: 'desc' },
|
|
106
|
+
take: limit,
|
|
107
|
+
});
|
|
108
|
+
return rows.map(rowToDelivery);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=webhook-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-store.js","sourceRoot":"","sources":["../../src/stores/webhook-store.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural Prisma typings used by the system stores.
|
|
3
|
+
*
|
|
4
|
+
* Prisma generates a fully-typed client per project, so we can't import a
|
|
5
|
+
* concrete `PrismaClient` here. Instead, every store consumes a minimal
|
|
6
|
+
* delegate shape — the same handful of methods Prisma always emits for a
|
|
7
|
+
* model. The host's actual generated client matches this surface
|
|
8
|
+
* structurally, no casts required.
|
|
9
|
+
*/
|
|
10
|
+
export interface PrismaDelegate<TRow = any> {
|
|
11
|
+
findMany(args?: any): Promise<TRow[]>;
|
|
12
|
+
findUnique(args: {
|
|
13
|
+
where: any;
|
|
14
|
+
}): Promise<TRow | null>;
|
|
15
|
+
findFirst(args?: any): Promise<TRow | null>;
|
|
16
|
+
create(args: {
|
|
17
|
+
data: any;
|
|
18
|
+
}): Promise<TRow>;
|
|
19
|
+
update(args: {
|
|
20
|
+
where: any;
|
|
21
|
+
data: any;
|
|
22
|
+
}): Promise<TRow>;
|
|
23
|
+
upsert(args: {
|
|
24
|
+
where: any;
|
|
25
|
+
update: any;
|
|
26
|
+
create: any;
|
|
27
|
+
}): Promise<TRow>;
|
|
28
|
+
delete(args: {
|
|
29
|
+
where: any;
|
|
30
|
+
}): Promise<TRow>;
|
|
31
|
+
deleteMany(args?: {
|
|
32
|
+
where?: any;
|
|
33
|
+
}): Promise<{
|
|
34
|
+
count: number;
|
|
35
|
+
}>;
|
|
36
|
+
count(args?: any): Promise<number>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Whatever `prisma` instance the host injects. We index into it by model
|
|
40
|
+
* name (default: `maLog`, `maWebhook`, …); see `setupPrismaSystem`'s
|
|
41
|
+
* `models` option for renames.
|
|
42
|
+
*
|
|
43
|
+
* Uses `{ [K: string]: any }` (not `Record<string, PrismaDelegate>`) so that
|
|
44
|
+
* the generated `PrismaClient` — which carries utility methods like
|
|
45
|
+
* `$connect`, `$disconnect`, `$transaction` that are NOT `PrismaDelegate` —
|
|
46
|
+
* is directly assignable without a cast. TypeScript only waives the
|
|
47
|
+
* "missing index signature" check when the index value type is `any`; any
|
|
48
|
+
* other type (including `unknown`) still rejects `PrismaClient`. The shape
|
|
49
|
+
* of each delegate is validated at runtime in `resolveDelegate()`.
|
|
50
|
+
*/
|
|
51
|
+
export type PrismaLike = {
|
|
52
|
+
[K: string]: any;
|
|
53
|
+
};
|
|
54
|
+
export declare const DEFAULT_MODELS: {
|
|
55
|
+
readonly log: "maLog";
|
|
56
|
+
readonly webhook: "maWebhook";
|
|
57
|
+
readonly webhookDelivery: "maWebhookDelivery";
|
|
58
|
+
readonly config: "maConfig";
|
|
59
|
+
readonly history: "maHistory";
|
|
60
|
+
readonly aiTask: "maAiTask";
|
|
61
|
+
readonly aiTaskEvent: "maAiTaskEvent";
|
|
62
|
+
readonly cache: "maCache";
|
|
63
|
+
};
|
|
64
|
+
export type ModelKey = keyof typeof DEFAULT_MODELS;
|
|
65
|
+
export type ModelOverrides = Partial<Record<ModelKey, string>>;
|
|
66
|
+
export declare function resolveDelegate(prisma: PrismaLike, key: ModelKey, overrides: ModelOverrides | undefined): PrismaDelegate;
|
|
67
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,MAAM,WAAW,cAAc,CAAC,IAAI,GAAG,GAAG;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IACrC,UAAU,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,GAAG,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;IACtD,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;IAC3C,MAAM,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,GAAG,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1C,MAAM,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,GAAG,CAAC;QAAC,IAAI,EAAE,GAAG,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACtD,MAAM,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,GAAG,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACrE,MAAM,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,GAAG,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3C,UAAU,CAAC,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,GAAG,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC9D,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACnC;AAED;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,UAAU,GAAG;IAAE,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,CAAA;AAE7C,eAAO,MAAM,cAAc;;;;;;;;;CASjB,CAAA;AAEV,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,cAAc,CAAA;AAClD,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;AAE9D,wBAAgB,eAAe,CAC7B,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,QAAQ,EACb,SAAS,EAAE,cAAc,GAAG,SAAS,GACpC,cAAc,CAWhB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural Prisma typings used by the system stores.
|
|
3
|
+
*
|
|
4
|
+
* Prisma generates a fully-typed client per project, so we can't import a
|
|
5
|
+
* concrete `PrismaClient` here. Instead, every store consumes a minimal
|
|
6
|
+
* delegate shape — the same handful of methods Prisma always emits for a
|
|
7
|
+
* model. The host's actual generated client matches this surface
|
|
8
|
+
* structurally, no casts required.
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_MODELS = {
|
|
11
|
+
log: 'maLog',
|
|
12
|
+
webhook: 'maWebhook',
|
|
13
|
+
webhookDelivery: 'maWebhookDelivery',
|
|
14
|
+
config: 'maConfig',
|
|
15
|
+
history: 'maHistory',
|
|
16
|
+
aiTask: 'maAiTask',
|
|
17
|
+
aiTaskEvent: 'maAiTaskEvent',
|
|
18
|
+
cache: 'maCache',
|
|
19
|
+
};
|
|
20
|
+
export function resolveDelegate(prisma, key, overrides) {
|
|
21
|
+
const name = overrides?.[key] ?? DEFAULT_MODELS[key];
|
|
22
|
+
const delegate = prisma[name];
|
|
23
|
+
if (!delegate || typeof delegate.findMany !== 'function') {
|
|
24
|
+
throw new Error(`[modern-admin/system-prisma] missing delegate "prisma.${name}". ` +
|
|
25
|
+
`Make sure the Modern Admin schema fragment is included in your schema.prisma ` +
|
|
26
|
+
`(see @modern-admin/system-prisma/schema), and that the Prisma client has been generated.`);
|
|
27
|
+
}
|
|
28
|
+
return delegate;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgCH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,GAAG,EAAE,OAAO;IACZ,OAAO,EAAE,WAAW;IACpB,eAAe,EAAE,mBAAmB;IACpC,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,WAAW;IACpB,MAAM,EAAE,UAAU;IAClB,WAAW,EAAE,eAAe;IAC5B,KAAK,EAAE,SAAS;CACR,CAAA;AAKV,MAAM,UAAU,eAAe,CAC7B,MAAkB,EAClB,GAAa,EACb,SAAqC;IAErC,MAAM,IAAI,GAAG,SAAS,EAAE,CAAC,GAAG,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC,CAAA;IACpD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAA+B,CAAA;IAC3D,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CACb,yDAAyD,IAAI,KAAK;YAClE,+EAA+E;YAC/E,0FAA0F,CAC3F,CAAA;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@modern-admin/system-prisma",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Prisma-backed implementation of Modern Admin system stores (logs, history, webhooks, AI tasks).",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/modern-admin/modern-admin.git",
|
|
10
|
+
"directory": "packages/system-prisma"
|
|
11
|
+
},
|
|
12
|
+
"main": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"src"
|
|
23
|
+
],
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"registry": "https://registry.npmjs.org",
|
|
26
|
+
"access": "public",
|
|
27
|
+
"main": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"default": "./dist/index.js"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@modern-admin/core": "0.1.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@modern-admin/tsconfig": "0.1.0",
|
|
41
|
+
"@types/bun": "^1.3.13",
|
|
42
|
+
"typescript": "^6.0.3"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@prisma/client": ">=7"
|
|
46
|
+
},
|
|
47
|
+
"peerDependenciesMeta": {
|
|
48
|
+
"@prisma/client": {
|
|
49
|
+
"optional": true
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// @modern-admin/system-prisma — Prisma-backed implementations of the
|
|
2
|
+
// runtime system stores defined in `@modern-admin/core/system`.
|
|
3
|
+
//
|
|
4
|
+
// Quick start:
|
|
5
|
+
// 1. Copy `prisma/modern-admin.prisma` into your application's schema
|
|
6
|
+
// (or include via Prisma multi-file schema).
|
|
7
|
+
// 2. Run your usual Prisma migration workflow.
|
|
8
|
+
// 3. Wire stores to subsystems:
|
|
9
|
+
//
|
|
10
|
+
// import { PrismaClient } from '@prisma/client'
|
|
11
|
+
// import { setupPrismaSystem } from '@modern-admin/system-prisma'
|
|
12
|
+
// import { actionLoggingPlugin } from '@modern-admin-pro/feature-logging'
|
|
13
|
+
//
|
|
14
|
+
// const prisma = new PrismaClient()
|
|
15
|
+
// const system = setupPrismaSystem(prisma)
|
|
16
|
+
//
|
|
17
|
+
// new ModernAdmin({
|
|
18
|
+
// databases: [...],
|
|
19
|
+
// plugins: [actionLoggingPlugin({ store: system.logStore })],
|
|
20
|
+
// })
|
|
21
|
+
//
|
|
22
|
+
// If you renamed the shipped models, pass `{ models: { log: 'myLog', ... } }`.
|
|
23
|
+
|
|
24
|
+
import type { ISystemStores } from '@modern-admin/core'
|
|
25
|
+
import { PrismaLogStore } from './stores/log-store.js'
|
|
26
|
+
import { PrismaWebhookStore } from './stores/webhook-store.js'
|
|
27
|
+
import { PrismaConfigStore } from './stores/config-store.js'
|
|
28
|
+
import { PrismaHistoryStore } from './stores/history-store.js'
|
|
29
|
+
import { PrismaAiTaskStore } from './stores/ai-task-store.js'
|
|
30
|
+
import { PrismaCacheStore } from './stores/cache-store.js'
|
|
31
|
+
import { type ModelOverrides, type PrismaLike, resolveDelegate } from './types.js'
|
|
32
|
+
|
|
33
|
+
export interface PrismaSystemOptions {
|
|
34
|
+
/**
|
|
35
|
+
* Override Prisma client property names if you renamed the shipped
|
|
36
|
+
* models. Defaults match the camelCased model identifiers from
|
|
37
|
+
* `prisma/modern-admin.prisma`:
|
|
38
|
+
*
|
|
39
|
+
* { log: 'maLog', webhook: 'maWebhook', webhookDelivery: 'maWebhookDelivery',
|
|
40
|
+
* config: 'maConfig', history: 'maHistory', aiTask: 'maAiTask',
|
|
41
|
+
* aiTaskEvent: 'maAiTaskEvent', cache: 'maCache' }
|
|
42
|
+
*/
|
|
43
|
+
models?: ModelOverrides
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface PrismaSystem extends ISystemStores {
|
|
47
|
+
logStore: PrismaLogStore
|
|
48
|
+
webhookStore: PrismaWebhookStore
|
|
49
|
+
configStore: PrismaConfigStore
|
|
50
|
+
historyStore: PrismaHistoryStore
|
|
51
|
+
aiTaskStore: PrismaAiTaskStore
|
|
52
|
+
cacheStore: PrismaCacheStore
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Build the full bundle of system stores from a Prisma client instance.
|
|
57
|
+
* The host owns the client lifecycle (connect/disconnect); this just wires
|
|
58
|
+
* the model delegates to thin store classes.
|
|
59
|
+
*/
|
|
60
|
+
export function setupPrismaSystem(
|
|
61
|
+
prisma: PrismaLike,
|
|
62
|
+
options: PrismaSystemOptions = {},
|
|
63
|
+
): PrismaSystem {
|
|
64
|
+
const m = options.models
|
|
65
|
+
return {
|
|
66
|
+
logStore: new PrismaLogStore(resolveDelegate(prisma, 'log', m)),
|
|
67
|
+
webhookStore: new PrismaWebhookStore(
|
|
68
|
+
resolveDelegate(prisma, 'webhook', m),
|
|
69
|
+
resolveDelegate(prisma, 'webhookDelivery', m),
|
|
70
|
+
),
|
|
71
|
+
configStore: new PrismaConfigStore(resolveDelegate(prisma, 'config', m)),
|
|
72
|
+
historyStore: new PrismaHistoryStore(resolveDelegate(prisma, 'history', m)),
|
|
73
|
+
aiTaskStore: new PrismaAiTaskStore(
|
|
74
|
+
resolveDelegate(prisma, 'aiTask', m),
|
|
75
|
+
resolveDelegate(prisma, 'aiTaskEvent', m),
|
|
76
|
+
),
|
|
77
|
+
cacheStore: new PrismaCacheStore(resolveDelegate(prisma, 'cache', m)),
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { PrismaLogStore } from './stores/log-store.js'
|
|
82
|
+
export { PrismaWebhookStore } from './stores/webhook-store.js'
|
|
83
|
+
export { PrismaConfigStore } from './stores/config-store.js'
|
|
84
|
+
export { PrismaHistoryStore } from './stores/history-store.js'
|
|
85
|
+
export { PrismaAiTaskStore } from './stores/ai-task-store.js'
|
|
86
|
+
export { PrismaCacheStore } from './stores/cache-store.js'
|
|
87
|
+
export type { PrismaDelegate, PrismaLike, ModelOverrides, ModelKey } from './types.js'
|
|
88
|
+
export { DEFAULT_MODELS } from './types.js'
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import {
|
|
2
|
+
uuidv7,
|
|
3
|
+
type AiTask,
|
|
4
|
+
type AiTaskEvent,
|
|
5
|
+
type AiTaskInput,
|
|
6
|
+
type AiTaskStatus,
|
|
7
|
+
type IAiTaskStore,
|
|
8
|
+
} from '@modern-admin/core'
|
|
9
|
+
import type { PrismaDelegate } from '../types.js'
|
|
10
|
+
|
|
11
|
+
interface TaskRow {
|
|
12
|
+
id: string
|
|
13
|
+
kind: string
|
|
14
|
+
resourceId: string | null
|
|
15
|
+
recordId: string | null
|
|
16
|
+
userId: string | null
|
|
17
|
+
status: string
|
|
18
|
+
input: unknown
|
|
19
|
+
output: unknown
|
|
20
|
+
error: string | null
|
|
21
|
+
progress: number | null
|
|
22
|
+
createdAt: Date
|
|
23
|
+
updatedAt: Date
|
|
24
|
+
startedAt: Date | null
|
|
25
|
+
finishedAt: Date | null
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface EventRow {
|
|
29
|
+
id: string
|
|
30
|
+
taskId: string
|
|
31
|
+
type: string
|
|
32
|
+
data: unknown
|
|
33
|
+
createdAt: Date
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const rowToTask = (row: TaskRow): AiTask => ({
|
|
37
|
+
id: row.id,
|
|
38
|
+
kind: row.kind,
|
|
39
|
+
...(row.resourceId !== null ? { resourceId: row.resourceId } : {}),
|
|
40
|
+
...(row.recordId !== null ? { recordId: row.recordId } : {}),
|
|
41
|
+
...(row.userId !== null ? { userId: row.userId } : {}),
|
|
42
|
+
status: row.status as AiTaskStatus,
|
|
43
|
+
input: (row.input as Record<string, unknown>) ?? {},
|
|
44
|
+
...(row.output !== null && row.output !== undefined
|
|
45
|
+
? { output: row.output as Record<string, unknown> }
|
|
46
|
+
: {}),
|
|
47
|
+
...(row.error !== null ? { error: row.error } : {}),
|
|
48
|
+
progress: row.progress,
|
|
49
|
+
createdAt: row.createdAt.toISOString(),
|
|
50
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
51
|
+
...(row.startedAt !== null ? { startedAt: row.startedAt.toISOString() } : {}),
|
|
52
|
+
...(row.finishedAt !== null ? { finishedAt: row.finishedAt.toISOString() } : {}),
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
const rowToEvent = (row: EventRow): AiTaskEvent => ({
|
|
56
|
+
id: row.id,
|
|
57
|
+
taskId: row.taskId,
|
|
58
|
+
type: row.type,
|
|
59
|
+
data: (row.data as Record<string, unknown>) ?? {},
|
|
60
|
+
createdAt: row.createdAt.toISOString(),
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const TERMINAL: AiTaskStatus[] = ['succeeded', 'failed', 'cancelled']
|
|
64
|
+
|
|
65
|
+
export class PrismaAiTaskStore implements IAiTaskStore {
|
|
66
|
+
constructor(
|
|
67
|
+
private readonly taskDelegate: PrismaDelegate<TaskRow>,
|
|
68
|
+
private readonly eventDelegate: PrismaDelegate<EventRow>,
|
|
69
|
+
) {}
|
|
70
|
+
|
|
71
|
+
async enqueue(input: AiTaskInput): Promise<AiTask> {
|
|
72
|
+
const row = await this.taskDelegate.create({
|
|
73
|
+
data: {
|
|
74
|
+
id: uuidv7(),
|
|
75
|
+
kind: input.kind,
|
|
76
|
+
resourceId: input.resourceId ?? null,
|
|
77
|
+
recordId: input.recordId ?? null,
|
|
78
|
+
userId: input.userId ?? null,
|
|
79
|
+
status: 'pending',
|
|
80
|
+
input: input.input ?? {},
|
|
81
|
+
progress: null,
|
|
82
|
+
},
|
|
83
|
+
})
|
|
84
|
+
return rowToTask(row)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async get(id: string): Promise<AiTask | null> {
|
|
88
|
+
const row = await this.taskDelegate.findUnique({ where: { id } })
|
|
89
|
+
return row ? rowToTask(row) : null
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async list(filter: Parameters<IAiTaskStore['list']>[0] = {}): Promise<AiTask[]> {
|
|
93
|
+
const where: Record<string, unknown> = {}
|
|
94
|
+
if (filter.kind) where['kind'] = filter.kind
|
|
95
|
+
if (filter.status) {
|
|
96
|
+
const list = Array.isArray(filter.status) ? filter.status : [filter.status]
|
|
97
|
+
where['status'] = { in: list }
|
|
98
|
+
}
|
|
99
|
+
if (filter.userId) where['userId'] = filter.userId
|
|
100
|
+
if (filter.resourceId) where['resourceId'] = filter.resourceId
|
|
101
|
+
const rows = await this.taskDelegate.findMany({
|
|
102
|
+
where,
|
|
103
|
+
orderBy: { createdAt: 'desc' },
|
|
104
|
+
...(filter.limit !== undefined ? { take: filter.limit } : {}),
|
|
105
|
+
})
|
|
106
|
+
return rows.map(rowToTask)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async updateStatus(
|
|
110
|
+
id: string,
|
|
111
|
+
patch: {
|
|
112
|
+
status: AiTaskStatus
|
|
113
|
+
progress?: number | null
|
|
114
|
+
output?: Record<string, unknown>
|
|
115
|
+
error?: string
|
|
116
|
+
},
|
|
117
|
+
): Promise<AiTask> {
|
|
118
|
+
const data: Record<string, unknown> = { status: patch.status }
|
|
119
|
+
if (patch.progress !== undefined) data['progress'] = patch.progress
|
|
120
|
+
if (patch.output !== undefined) data['output'] = patch.output
|
|
121
|
+
if (patch.error !== undefined) data['error'] = patch.error
|
|
122
|
+
if (patch.status === 'running') {
|
|
123
|
+
// only set startedAt the first time we transition to running
|
|
124
|
+
const current = await this.taskDelegate.findUnique({ where: { id } })
|
|
125
|
+
if (current && !current.startedAt) data['startedAt'] = new Date()
|
|
126
|
+
}
|
|
127
|
+
if (TERMINAL.includes(patch.status)) {
|
|
128
|
+
data['finishedAt'] = new Date()
|
|
129
|
+
}
|
|
130
|
+
const row = await this.taskDelegate.update({ where: { id }, data })
|
|
131
|
+
return rowToTask(row)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async appendEvent(
|
|
135
|
+
taskId: string,
|
|
136
|
+
type: string,
|
|
137
|
+
data: Record<string, unknown>,
|
|
138
|
+
): Promise<AiTaskEvent> {
|
|
139
|
+
const row = await this.eventDelegate.create({
|
|
140
|
+
data: { id: uuidv7(), taskId, type, data },
|
|
141
|
+
})
|
|
142
|
+
return rowToEvent(row)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async events(taskId: string, sinceId?: string): Promise<AiTaskEvent[]> {
|
|
146
|
+
const all = await this.eventDelegate.findMany({
|
|
147
|
+
where: { taskId },
|
|
148
|
+
orderBy: { createdAt: 'asc' },
|
|
149
|
+
})
|
|
150
|
+
if (!sinceId) return all.map(rowToEvent)
|
|
151
|
+
const idx = all.findIndex((r) => r.id === sinceId)
|
|
152
|
+
return (idx < 0 ? all : all.slice(idx + 1)).map(rowToEvent)
|
|
153
|
+
}
|
|
154
|
+
}
|