@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
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ISystemStores } from '@modern-admin/core';
|
|
2
|
+
import { PrismaLogStore } from './stores/log-store.js';
|
|
3
|
+
import { PrismaWebhookStore } from './stores/webhook-store.js';
|
|
4
|
+
import { PrismaConfigStore } from './stores/config-store.js';
|
|
5
|
+
import { PrismaHistoryStore } from './stores/history-store.js';
|
|
6
|
+
import { PrismaAiTaskStore } from './stores/ai-task-store.js';
|
|
7
|
+
import { PrismaCacheStore } from './stores/cache-store.js';
|
|
8
|
+
import { type ModelOverrides, type PrismaLike } from './types.js';
|
|
9
|
+
export interface PrismaSystemOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Override Prisma client property names if you renamed the shipped
|
|
12
|
+
* models. Defaults match the camelCased model identifiers from
|
|
13
|
+
* `prisma/modern-admin.prisma`:
|
|
14
|
+
*
|
|
15
|
+
* { log: 'maLog', webhook: 'maWebhook', webhookDelivery: 'maWebhookDelivery',
|
|
16
|
+
* config: 'maConfig', history: 'maHistory', aiTask: 'maAiTask',
|
|
17
|
+
* aiTaskEvent: 'maAiTaskEvent', cache: 'maCache' }
|
|
18
|
+
*/
|
|
19
|
+
models?: ModelOverrides;
|
|
20
|
+
}
|
|
21
|
+
export interface PrismaSystem extends ISystemStores {
|
|
22
|
+
logStore: PrismaLogStore;
|
|
23
|
+
webhookStore: PrismaWebhookStore;
|
|
24
|
+
configStore: PrismaConfigStore;
|
|
25
|
+
historyStore: PrismaHistoryStore;
|
|
26
|
+
aiTaskStore: PrismaAiTaskStore;
|
|
27
|
+
cacheStore: PrismaCacheStore;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Build the full bundle of system stores from a Prisma client instance.
|
|
31
|
+
* The host owns the client lifecycle (connect/disconnect); this just wires
|
|
32
|
+
* the model delegates to thin store classes.
|
|
33
|
+
*/
|
|
34
|
+
export declare function setupPrismaSystem(prisma: PrismaLike, options?: PrismaSystemOptions): PrismaSystem;
|
|
35
|
+
export { PrismaLogStore } from './stores/log-store.js';
|
|
36
|
+
export { PrismaWebhookStore } from './stores/webhook-store.js';
|
|
37
|
+
export { PrismaConfigStore } from './stores/config-store.js';
|
|
38
|
+
export { PrismaHistoryStore } from './stores/history-store.js';
|
|
39
|
+
export { PrismaAiTaskStore } from './stores/ai-task-store.js';
|
|
40
|
+
export { PrismaCacheStore } from './stores/cache-store.js';
|
|
41
|
+
export type { PrismaDelegate, PrismaLike, ModelOverrides, ModelKey } from './types.js';
|
|
42
|
+
export { DEFAULT_MODELS } from './types.js';
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,UAAU,EAAmB,MAAM,YAAY,CAAA;AAElF,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,cAAc,CAAA;CACxB;AAED,MAAM,WAAW,YAAa,SAAQ,aAAa;IACjD,QAAQ,EAAE,cAAc,CAAA;IACxB,YAAY,EAAE,kBAAkB,CAAA;IAChC,WAAW,EAAE,iBAAiB,CAAA;IAC9B,YAAY,EAAE,kBAAkB,CAAA;IAChC,WAAW,EAAE,iBAAiB,CAAA;IAC9B,UAAU,EAAE,gBAAgB,CAAA;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE,mBAAwB,GAChC,YAAY,CAgBd;AAED,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACtF,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
import { PrismaLogStore } from './stores/log-store.js';
|
|
24
|
+
import { PrismaWebhookStore } from './stores/webhook-store.js';
|
|
25
|
+
import { PrismaConfigStore } from './stores/config-store.js';
|
|
26
|
+
import { PrismaHistoryStore } from './stores/history-store.js';
|
|
27
|
+
import { PrismaAiTaskStore } from './stores/ai-task-store.js';
|
|
28
|
+
import { PrismaCacheStore } from './stores/cache-store.js';
|
|
29
|
+
import { resolveDelegate } from './types.js';
|
|
30
|
+
/**
|
|
31
|
+
* Build the full bundle of system stores from a Prisma client instance.
|
|
32
|
+
* The host owns the client lifecycle (connect/disconnect); this just wires
|
|
33
|
+
* the model delegates to thin store classes.
|
|
34
|
+
*/
|
|
35
|
+
export function setupPrismaSystem(prisma, options = {}) {
|
|
36
|
+
const m = options.models;
|
|
37
|
+
return {
|
|
38
|
+
logStore: new PrismaLogStore(resolveDelegate(prisma, 'log', m)),
|
|
39
|
+
webhookStore: new PrismaWebhookStore(resolveDelegate(prisma, 'webhook', m), resolveDelegate(prisma, 'webhookDelivery', m)),
|
|
40
|
+
configStore: new PrismaConfigStore(resolveDelegate(prisma, 'config', m)),
|
|
41
|
+
historyStore: new PrismaHistoryStore(resolveDelegate(prisma, 'history', m)),
|
|
42
|
+
aiTaskStore: new PrismaAiTaskStore(resolveDelegate(prisma, 'aiTask', m), resolveDelegate(prisma, 'aiTaskEvent', m)),
|
|
43
|
+
cacheStore: new PrismaCacheStore(resolveDelegate(prisma, 'cache', m)),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export { PrismaLogStore } from './stores/log-store.js';
|
|
47
|
+
export { PrismaWebhookStore } from './stores/webhook-store.js';
|
|
48
|
+
export { PrismaConfigStore } from './stores/config-store.js';
|
|
49
|
+
export { PrismaHistoryStore } from './stores/history-store.js';
|
|
50
|
+
export { PrismaAiTaskStore } from './stores/ai-task-store.js';
|
|
51
|
+
export { PrismaCacheStore } from './stores/cache-store.js';
|
|
52
|
+
export { DEFAULT_MODELS } from './types.js';
|
|
53
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,gEAAgE;AAChE,EAAE;AACF,eAAe;AACf,sEAAsE;AACtE,gDAAgD;AAChD,+CAA+C;AAC/C,gCAAgC;AAChC,EAAE;AACF,mDAAmD;AACnD,qEAAqE;AACrE,6EAA6E;AAC7E,EAAE;AACF,uCAAuC;AACvC,8CAA8C;AAC9C,EAAE;AACF,uBAAuB;AACvB,yBAAyB;AACzB,mEAAmE;AACnE,QAAQ;AACR,EAAE;AACF,+EAA+E;AAG/E,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAwC,eAAe,EAAE,MAAM,YAAY,CAAA;AAwBlF;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAkB,EAClB,UAA+B,EAAE;IAEjC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAA;IACxB,OAAO;QACL,QAAQ,EAAE,IAAI,cAAc,CAAC,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QAC/D,YAAY,EAAE,IAAI,kBAAkB,CAClC,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,EACrC,eAAe,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAC9C;QACD,WAAW,EAAE,IAAI,iBAAiB,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QACxE,YAAY,EAAE,IAAI,kBAAkB,CAAC,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QAC3E,WAAW,EAAE,IAAI,iBAAiB,CAChC,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,EACpC,eAAe,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC,CAC1C;QACD,UAAU,EAAE,IAAI,gBAAgB,CAAC,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;KACtE,CAAA;AACH,CAAC;AAED,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAE1D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type AiTask, type AiTaskEvent, type AiTaskInput, type AiTaskStatus, type IAiTaskStore } from '@modern-admin/core';
|
|
2
|
+
import type { PrismaDelegate } from '../types.js';
|
|
3
|
+
interface TaskRow {
|
|
4
|
+
id: string;
|
|
5
|
+
kind: string;
|
|
6
|
+
resourceId: string | null;
|
|
7
|
+
recordId: string | null;
|
|
8
|
+
userId: string | null;
|
|
9
|
+
status: string;
|
|
10
|
+
input: unknown;
|
|
11
|
+
output: unknown;
|
|
12
|
+
error: string | null;
|
|
13
|
+
progress: number | null;
|
|
14
|
+
createdAt: Date;
|
|
15
|
+
updatedAt: Date;
|
|
16
|
+
startedAt: Date | null;
|
|
17
|
+
finishedAt: Date | null;
|
|
18
|
+
}
|
|
19
|
+
interface EventRow {
|
|
20
|
+
id: string;
|
|
21
|
+
taskId: string;
|
|
22
|
+
type: string;
|
|
23
|
+
data: unknown;
|
|
24
|
+
createdAt: Date;
|
|
25
|
+
}
|
|
26
|
+
export declare class PrismaAiTaskStore implements IAiTaskStore {
|
|
27
|
+
private readonly taskDelegate;
|
|
28
|
+
private readonly eventDelegate;
|
|
29
|
+
constructor(taskDelegate: PrismaDelegate<TaskRow>, eventDelegate: PrismaDelegate<EventRow>);
|
|
30
|
+
enqueue(input: AiTaskInput): Promise<AiTask>;
|
|
31
|
+
get(id: string): Promise<AiTask | null>;
|
|
32
|
+
list(filter?: Parameters<IAiTaskStore['list']>[0]): Promise<AiTask[]>;
|
|
33
|
+
updateStatus(id: string, patch: {
|
|
34
|
+
status: AiTaskStatus;
|
|
35
|
+
progress?: number | null;
|
|
36
|
+
output?: Record<string, unknown>;
|
|
37
|
+
error?: string;
|
|
38
|
+
}): Promise<AiTask>;
|
|
39
|
+
appendEvent(taskId: string, type: string, data: Record<string, unknown>): Promise<AiTaskEvent>;
|
|
40
|
+
events(taskId: string, sinceId?: string): Promise<AiTaskEvent[]>;
|
|
41
|
+
}
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=ai-task-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-task-store.d.ts","sourceRoot":"","sources":["../../src/stores/ai-task-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,MAAM,EACX,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,UAAU,OAAO;IACf,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,OAAO,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;IACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,SAAS,EAAE,IAAI,CAAA;IACf,SAAS,EAAE,IAAI,CAAA;IACf,SAAS,EAAE,IAAI,GAAG,IAAI,CAAA;IACtB,UAAU,EAAE,IAAI,GAAG,IAAI,CAAA;CACxB;AAED,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,OAAO,CAAA;IACb,SAAS,EAAE,IAAI,CAAA;CAChB;AA+BD,qBAAa,iBAAkB,YAAW,YAAY;IAElD,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,aAAa;gBADb,YAAY,EAAE,cAAc,CAAC,OAAO,CAAC,EACrC,aAAa,EAAE,cAAc,CAAC,QAAQ,CAAC;IAGpD,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAgB5C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKvC,IAAI,CAAC,MAAM,GAAE,UAAU,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAiBzE,YAAY,CAChB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE;QACL,MAAM,EAAE,YAAY,CAAA;QACpB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAChC,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,GACA,OAAO,CAAC,MAAM,CAAC;IAiBZ,WAAW,CACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,WAAW,CAAC;IAOjB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;CASvE"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { uuidv7, } from '@modern-admin/core';
|
|
2
|
+
const rowToTask = (row) => ({
|
|
3
|
+
id: row.id,
|
|
4
|
+
kind: row.kind,
|
|
5
|
+
...(row.resourceId !== null ? { resourceId: row.resourceId } : {}),
|
|
6
|
+
...(row.recordId !== null ? { recordId: row.recordId } : {}),
|
|
7
|
+
...(row.userId !== null ? { userId: row.userId } : {}),
|
|
8
|
+
status: row.status,
|
|
9
|
+
input: row.input ?? {},
|
|
10
|
+
...(row.output !== null && row.output !== undefined
|
|
11
|
+
? { output: row.output }
|
|
12
|
+
: {}),
|
|
13
|
+
...(row.error !== null ? { error: row.error } : {}),
|
|
14
|
+
progress: row.progress,
|
|
15
|
+
createdAt: row.createdAt.toISOString(),
|
|
16
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
17
|
+
...(row.startedAt !== null ? { startedAt: row.startedAt.toISOString() } : {}),
|
|
18
|
+
...(row.finishedAt !== null ? { finishedAt: row.finishedAt.toISOString() } : {}),
|
|
19
|
+
});
|
|
20
|
+
const rowToEvent = (row) => ({
|
|
21
|
+
id: row.id,
|
|
22
|
+
taskId: row.taskId,
|
|
23
|
+
type: row.type,
|
|
24
|
+
data: row.data ?? {},
|
|
25
|
+
createdAt: row.createdAt.toISOString(),
|
|
26
|
+
});
|
|
27
|
+
const TERMINAL = ['succeeded', 'failed', 'cancelled'];
|
|
28
|
+
export class PrismaAiTaskStore {
|
|
29
|
+
constructor(taskDelegate, eventDelegate) {
|
|
30
|
+
this.taskDelegate = taskDelegate;
|
|
31
|
+
this.eventDelegate = eventDelegate;
|
|
32
|
+
}
|
|
33
|
+
async enqueue(input) {
|
|
34
|
+
const row = await this.taskDelegate.create({
|
|
35
|
+
data: {
|
|
36
|
+
id: uuidv7(),
|
|
37
|
+
kind: input.kind,
|
|
38
|
+
resourceId: input.resourceId ?? null,
|
|
39
|
+
recordId: input.recordId ?? null,
|
|
40
|
+
userId: input.userId ?? null,
|
|
41
|
+
status: 'pending',
|
|
42
|
+
input: input.input ?? {},
|
|
43
|
+
progress: null,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
return rowToTask(row);
|
|
47
|
+
}
|
|
48
|
+
async get(id) {
|
|
49
|
+
const row = await this.taskDelegate.findUnique({ where: { id } });
|
|
50
|
+
return row ? rowToTask(row) : null;
|
|
51
|
+
}
|
|
52
|
+
async list(filter = {}) {
|
|
53
|
+
const where = {};
|
|
54
|
+
if (filter.kind)
|
|
55
|
+
where['kind'] = filter.kind;
|
|
56
|
+
if (filter.status) {
|
|
57
|
+
const list = Array.isArray(filter.status) ? filter.status : [filter.status];
|
|
58
|
+
where['status'] = { in: list };
|
|
59
|
+
}
|
|
60
|
+
if (filter.userId)
|
|
61
|
+
where['userId'] = filter.userId;
|
|
62
|
+
if (filter.resourceId)
|
|
63
|
+
where['resourceId'] = filter.resourceId;
|
|
64
|
+
const rows = await this.taskDelegate.findMany({
|
|
65
|
+
where,
|
|
66
|
+
orderBy: { createdAt: 'desc' },
|
|
67
|
+
...(filter.limit !== undefined ? { take: filter.limit } : {}),
|
|
68
|
+
});
|
|
69
|
+
return rows.map(rowToTask);
|
|
70
|
+
}
|
|
71
|
+
async updateStatus(id, patch) {
|
|
72
|
+
const data = { status: patch.status };
|
|
73
|
+
if (patch.progress !== undefined)
|
|
74
|
+
data['progress'] = patch.progress;
|
|
75
|
+
if (patch.output !== undefined)
|
|
76
|
+
data['output'] = patch.output;
|
|
77
|
+
if (patch.error !== undefined)
|
|
78
|
+
data['error'] = patch.error;
|
|
79
|
+
if (patch.status === 'running') {
|
|
80
|
+
// only set startedAt the first time we transition to running
|
|
81
|
+
const current = await this.taskDelegate.findUnique({ where: { id } });
|
|
82
|
+
if (current && !current.startedAt)
|
|
83
|
+
data['startedAt'] = new Date();
|
|
84
|
+
}
|
|
85
|
+
if (TERMINAL.includes(patch.status)) {
|
|
86
|
+
data['finishedAt'] = new Date();
|
|
87
|
+
}
|
|
88
|
+
const row = await this.taskDelegate.update({ where: { id }, data });
|
|
89
|
+
return rowToTask(row);
|
|
90
|
+
}
|
|
91
|
+
async appendEvent(taskId, type, data) {
|
|
92
|
+
const row = await this.eventDelegate.create({
|
|
93
|
+
data: { id: uuidv7(), taskId, type, data },
|
|
94
|
+
});
|
|
95
|
+
return rowToEvent(row);
|
|
96
|
+
}
|
|
97
|
+
async events(taskId, sinceId) {
|
|
98
|
+
const all = await this.eventDelegate.findMany({
|
|
99
|
+
where: { taskId },
|
|
100
|
+
orderBy: { createdAt: 'asc' },
|
|
101
|
+
});
|
|
102
|
+
if (!sinceId)
|
|
103
|
+
return all.map(rowToEvent);
|
|
104
|
+
const idx = all.findIndex((r) => r.id === sinceId);
|
|
105
|
+
return (idx < 0 ? all : all.slice(idx + 1)).map(rowToEvent);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=ai-task-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-task-store.js","sourceRoot":"","sources":["../../src/stores/ai-task-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CacheEntry, ICacheStore } from '@modern-admin/core';
|
|
2
|
+
import type { PrismaDelegate } from '../types.js';
|
|
3
|
+
interface CacheRow {
|
|
4
|
+
key: string;
|
|
5
|
+
value: unknown;
|
|
6
|
+
tags: unknown;
|
|
7
|
+
expiresAt: Date | null;
|
|
8
|
+
createdAt: Date;
|
|
9
|
+
updatedAt: Date;
|
|
10
|
+
}
|
|
11
|
+
export declare class PrismaCacheStore implements ICacheStore {
|
|
12
|
+
private readonly delegate;
|
|
13
|
+
constructor(delegate: PrismaDelegate<CacheRow>);
|
|
14
|
+
get(key: string): Promise<CacheEntry | null>;
|
|
15
|
+
set(key: string, value: unknown, options?: {
|
|
16
|
+
ttlMs?: number;
|
|
17
|
+
tags?: string[];
|
|
18
|
+
}): Promise<void>;
|
|
19
|
+
delete(key: string): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Tag invalidation walks the table because Prisma's portable `Json` field
|
|
22
|
+
* doesn't support array-contains across all DB engines. For high-volume
|
|
23
|
+
* caches use a Postgres-specific implementation (`tags String[]`) or
|
|
24
|
+
* Redis. Here correctness > throughput by design.
|
|
25
|
+
*/
|
|
26
|
+
invalidateTags(tags: string[]): Promise<number>;
|
|
27
|
+
prune(): Promise<number>;
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=cache-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-store.d.ts","sourceRoot":"","sources":["../../src/stores/cache-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,UAAU,QAAQ;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,OAAO,CAAA;IACd,IAAI,EAAE,OAAO,CAAA;IACb,SAAS,EAAE,IAAI,GAAG,IAAI,CAAA;IACtB,SAAS,EAAE,IAAI,CAAA;IACf,SAAS,EAAE,IAAI,CAAA;CAChB;AAWD,qBAAa,gBAAiB,YAAW,WAAW;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,cAAc,CAAC,QAAQ,CAAC;IAEzD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAU5C,GAAG,CACP,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAO,GAChD,OAAO,CAAC,IAAI,CAAC;IAUV,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC;;;;;OAKG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAc/C,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;CAM/B"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const rowToEntry = (row) => ({
|
|
2
|
+
key: row.key,
|
|
3
|
+
value: row.value,
|
|
4
|
+
tags: Array.isArray(row.tags) ? row.tags : [],
|
|
5
|
+
expiresAt: row.expiresAt ? row.expiresAt.toISOString() : null,
|
|
6
|
+
createdAt: row.createdAt.toISOString(),
|
|
7
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
8
|
+
});
|
|
9
|
+
export class PrismaCacheStore {
|
|
10
|
+
constructor(delegate) {
|
|
11
|
+
this.delegate = delegate;
|
|
12
|
+
}
|
|
13
|
+
async get(key) {
|
|
14
|
+
const row = await this.delegate.findUnique({ where: { key } });
|
|
15
|
+
if (!row)
|
|
16
|
+
return null;
|
|
17
|
+
if (row.expiresAt && row.expiresAt.getTime() < Date.now()) {
|
|
18
|
+
await this.delegate.delete({ where: { key } }).catch(() => undefined);
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return rowToEntry(row);
|
|
22
|
+
}
|
|
23
|
+
async set(key, value, options = {}) {
|
|
24
|
+
const expiresAt = options.ttlMs ? new Date(Date.now() + options.ttlMs) : null;
|
|
25
|
+
const tags = options.tags ?? [];
|
|
26
|
+
await this.delegate.upsert({
|
|
27
|
+
where: { key },
|
|
28
|
+
create: { key, value: value ?? null, tags, expiresAt },
|
|
29
|
+
update: { value: value ?? null, tags, expiresAt },
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
async delete(key) {
|
|
33
|
+
await this.delegate.delete({ where: { key } }).catch(() => undefined);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Tag invalidation walks the table because Prisma's portable `Json` field
|
|
37
|
+
* doesn't support array-contains across all DB engines. For high-volume
|
|
38
|
+
* caches use a Postgres-specific implementation (`tags String[]`) or
|
|
39
|
+
* Redis. Here correctness > throughput by design.
|
|
40
|
+
*/
|
|
41
|
+
async invalidateTags(tags) {
|
|
42
|
+
if (!tags.length)
|
|
43
|
+
return 0;
|
|
44
|
+
const set = new Set(tags);
|
|
45
|
+
const rows = await this.delegate.findMany({});
|
|
46
|
+
const targets = rows.filter((r) => Array.isArray(r.tags) && r.tags.some((t) => set.has(t)));
|
|
47
|
+
if (!targets.length)
|
|
48
|
+
return 0;
|
|
49
|
+
const result = await this.delegate.deleteMany({
|
|
50
|
+
where: { key: { in: targets.map((r) => r.key) } },
|
|
51
|
+
});
|
|
52
|
+
return result.count;
|
|
53
|
+
}
|
|
54
|
+
async prune() {
|
|
55
|
+
const result = await this.delegate.deleteMany({
|
|
56
|
+
where: { expiresAt: { lt: new Date() } },
|
|
57
|
+
});
|
|
58
|
+
return result.count;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=cache-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-store.js","sourceRoot":"","sources":["../../src/stores/cache-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ConfigEntry, type ConfigScope, type IConfigStore } from '@modern-admin/core';
|
|
2
|
+
import type { PrismaDelegate } from '../types.js';
|
|
3
|
+
interface ConfigRow {
|
|
4
|
+
id: string;
|
|
5
|
+
scope: string;
|
|
6
|
+
scopeId: string;
|
|
7
|
+
key: string;
|
|
8
|
+
value: unknown;
|
|
9
|
+
updatedAt: Date;
|
|
10
|
+
}
|
|
11
|
+
export declare class PrismaConfigStore implements IConfigStore {
|
|
12
|
+
private readonly delegate;
|
|
13
|
+
constructor(delegate: PrismaDelegate<ConfigRow>);
|
|
14
|
+
get(scope: ConfigScope, scopeId: string | null, key: string): Promise<unknown>;
|
|
15
|
+
set(scope: ConfigScope, scopeId: string | null, key: string, value: unknown): Promise<void>;
|
|
16
|
+
delete(scope: ConfigScope, scopeId: string | null, key: string): Promise<void>;
|
|
17
|
+
list(scope: ConfigScope, scopeId: string | null): Promise<ConfigEntry[]>;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=config-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-store.d.ts","sourceRoot":"","sources":["../../src/stores/config-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAU,MAAM,oBAAoB,CAAA;AAClG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,OAAO,CAAA;IACd,SAAS,EAAE,IAAI,CAAA;CAChB;AAcD,qBAAa,iBAAkB,YAAW,YAAY;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,cAAc,CAAC,SAAS,CAAC;IAG1D,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU9E,GAAG,CACP,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,IAAI,CAAC;IAsBV,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9E,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;CAO/E"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { uuidv7 } from '@modern-admin/core';
|
|
2
|
+
const GLOBAL_SCOPE_ID = '';
|
|
3
|
+
const encodeScopeId = (scopeId) => scopeId ?? GLOBAL_SCOPE_ID;
|
|
4
|
+
const decodeScopeId = (scopeId) => scopeId === GLOBAL_SCOPE_ID ? null : scopeId;
|
|
5
|
+
const rowToEntry = (row) => ({
|
|
6
|
+
scope: row.scope,
|
|
7
|
+
scopeId: decodeScopeId(row.scopeId),
|
|
8
|
+
key: row.key,
|
|
9
|
+
value: row.value,
|
|
10
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
11
|
+
});
|
|
12
|
+
export class PrismaConfigStore {
|
|
13
|
+
constructor(delegate) {
|
|
14
|
+
this.delegate = delegate;
|
|
15
|
+
}
|
|
16
|
+
async get(scope, scopeId, key) {
|
|
17
|
+
// findFirst instead of findUnique: tolerates accidental duplicates and
|
|
18
|
+
// returns the most-recently-updated row rather than throwing.
|
|
19
|
+
const row = await this.delegate.findFirst({
|
|
20
|
+
where: { scope, scopeId: encodeScopeId(scopeId), key },
|
|
21
|
+
orderBy: { updatedAt: 'desc' },
|
|
22
|
+
});
|
|
23
|
+
return row?.value;
|
|
24
|
+
}
|
|
25
|
+
async set(scope, scopeId, key, value) {
|
|
26
|
+
const encodedScopeId = encodeScopeId(scopeId);
|
|
27
|
+
// Use findFirst + update-by-id / create instead of upsert with a
|
|
28
|
+
// compound unique key. Prisma 7 + PrismaPg adapter can misidentify
|
|
29
|
+
// compound-key upserts and issue a second INSERT rather than an UPDATE,
|
|
30
|
+
// which violates the unique constraint. Anchoring the update on the
|
|
31
|
+
// surrogate id is always safe.
|
|
32
|
+
const existing = await this.delegate.findFirst({
|
|
33
|
+
where: { scope, scopeId: encodedScopeId, key },
|
|
34
|
+
});
|
|
35
|
+
if (existing) {
|
|
36
|
+
await this.delegate.update({
|
|
37
|
+
where: { id: existing.id },
|
|
38
|
+
data: { value: value ?? null },
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
await this.delegate.create({
|
|
43
|
+
data: { id: uuidv7(), scope, scopeId: encodedScopeId, key, value: value ?? null },
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async delete(scope, scopeId, key) {
|
|
48
|
+
// deleteMany avoids "record not found" and also cleans up any duplicates.
|
|
49
|
+
await this.delegate
|
|
50
|
+
.deleteMany({ where: { scope, scopeId: encodeScopeId(scopeId), key } })
|
|
51
|
+
.catch(() => undefined);
|
|
52
|
+
}
|
|
53
|
+
async list(scope, scopeId) {
|
|
54
|
+
const rows = await this.delegate.findMany({
|
|
55
|
+
where: { scope, scopeId: encodeScopeId(scopeId) },
|
|
56
|
+
orderBy: { key: 'asc' },
|
|
57
|
+
});
|
|
58
|
+
return rows.map(rowToEntry);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=config-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-store.js","sourceRoot":"","sources":["../../src/stores/config-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type HistoryEntry, type HistoryOp, type IHistoryStore } from '@modern-admin/core';
|
|
2
|
+
import type { PrismaDelegate } from '../types.js';
|
|
3
|
+
interface HistoryRow {
|
|
4
|
+
id: string;
|
|
5
|
+
resourceId: string;
|
|
6
|
+
recordId: string;
|
|
7
|
+
op: string;
|
|
8
|
+
userId: string | null;
|
|
9
|
+
snapshot: unknown;
|
|
10
|
+
snapshotBefore: unknown;
|
|
11
|
+
diff: unknown;
|
|
12
|
+
createdAt: Date;
|
|
13
|
+
}
|
|
14
|
+
export declare class PrismaHistoryStore implements IHistoryStore {
|
|
15
|
+
private readonly delegate;
|
|
16
|
+
constructor(delegate: PrismaDelegate<HistoryRow>);
|
|
17
|
+
append(input: {
|
|
18
|
+
resourceId: string;
|
|
19
|
+
recordId: string;
|
|
20
|
+
op: HistoryOp;
|
|
21
|
+
userId?: string;
|
|
22
|
+
snapshot: Record<string, unknown>;
|
|
23
|
+
snapshotBefore?: Record<string, unknown>;
|
|
24
|
+
}): Promise<HistoryEntry>;
|
|
25
|
+
list(resourceId: string, recordId: string, options?: {
|
|
26
|
+
limit?: number;
|
|
27
|
+
offset?: number;
|
|
28
|
+
}): Promise<HistoryEntry[]>;
|
|
29
|
+
get(resourceId: string, recordId: string, revisionId: string): Promise<HistoryEntry | null>;
|
|
30
|
+
latest(resourceId: string, recordId: string): Promise<HistoryEntry | null>;
|
|
31
|
+
}
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=history-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history-store.d.ts","sourceRoot":"","sources":["../../src/stores/history-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,UAAU,UAAU;IAClB,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,QAAQ,EAAE,OAAO,CAAA;IACjB,cAAc,EAAE,OAAO,CAAA;IACvB,IAAI,EAAE,OAAO,CAAA;IACb,SAAS,EAAE,IAAI,CAAA;CAChB;AAeD,qBAAa,kBAAmB,YAAW,aAAa;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC;IAE3D,MAAM,CAAC,KAAK,EAAE;QAClB,UAAU,EAAE,MAAM,CAAA;QAClB,QAAQ,EAAE,MAAM,CAAA;QAChB,EAAE,EAAE,SAAS,CAAA;QACb,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACjC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KACzC,GAAG,OAAO,CAAC,YAAY,CAAC;IAenB,IAAI,CACR,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GAChD,OAAO,CAAC,YAAY,EAAE,CAAC;IAYpB,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAO3F,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;CAOjF"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { uuidv7 } from '@modern-admin/core';
|
|
2
|
+
const rowToEntry = (row) => ({
|
|
3
|
+
id: row.id,
|
|
4
|
+
resourceId: row.resourceId,
|
|
5
|
+
recordId: row.recordId,
|
|
6
|
+
op: row.op,
|
|
7
|
+
...(row.userId !== null ? { userId: row.userId } : {}),
|
|
8
|
+
snapshot: row.snapshot ?? {},
|
|
9
|
+
...(row.snapshotBefore !== null && row.snapshotBefore !== undefined
|
|
10
|
+
? { snapshotBefore: row.snapshotBefore }
|
|
11
|
+
: {}),
|
|
12
|
+
createdAt: row.createdAt.toISOString(),
|
|
13
|
+
});
|
|
14
|
+
export class PrismaHistoryStore {
|
|
15
|
+
constructor(delegate) {
|
|
16
|
+
this.delegate = delegate;
|
|
17
|
+
}
|
|
18
|
+
async append(input) {
|
|
19
|
+
const row = await this.delegate.create({
|
|
20
|
+
data: {
|
|
21
|
+
id: uuidv7(),
|
|
22
|
+
resourceId: input.resourceId,
|
|
23
|
+
recordId: input.recordId,
|
|
24
|
+
op: input.op,
|
|
25
|
+
userId: input.userId ?? null,
|
|
26
|
+
snapshot: input.snapshot,
|
|
27
|
+
snapshotBefore: input.snapshotBefore ?? null,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
return rowToEntry(row);
|
|
31
|
+
}
|
|
32
|
+
async list(resourceId, recordId, options = {}) {
|
|
33
|
+
const limit = options.limit ?? 50;
|
|
34
|
+
const offset = options.offset ?? 0;
|
|
35
|
+
const rows = await this.delegate.findMany({
|
|
36
|
+
where: { resourceId, recordId },
|
|
37
|
+
orderBy: { createdAt: 'desc' },
|
|
38
|
+
take: limit,
|
|
39
|
+
...(offset > 0 ? { skip: offset } : {}),
|
|
40
|
+
});
|
|
41
|
+
return rows.map(rowToEntry);
|
|
42
|
+
}
|
|
43
|
+
async get(resourceId, recordId, revisionId) {
|
|
44
|
+
const row = await this.delegate.findFirst({
|
|
45
|
+
where: { id: revisionId, resourceId, recordId },
|
|
46
|
+
});
|
|
47
|
+
return row ? rowToEntry(row) : null;
|
|
48
|
+
}
|
|
49
|
+
async latest(resourceId, recordId) {
|
|
50
|
+
const row = await this.delegate.findFirst({
|
|
51
|
+
where: { resourceId, recordId },
|
|
52
|
+
orderBy: { createdAt: 'desc' },
|
|
53
|
+
});
|
|
54
|
+
return row ? rowToEntry(row) : null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=history-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history-store.js","sourceRoot":"","sources":["../../src/stores/history-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ActionLogEntry, type ILogStore, type IQueryableLogStore } from '@modern-admin/core';
|
|
2
|
+
import type { PrismaDelegate } from '../types.js';
|
|
3
|
+
interface LogRow {
|
|
4
|
+
id: string;
|
|
5
|
+
resourceId: string;
|
|
6
|
+
action: string;
|
|
7
|
+
recordId: string | null;
|
|
8
|
+
recordIds: unknown;
|
|
9
|
+
userId: string | null;
|
|
10
|
+
payload: unknown;
|
|
11
|
+
result: unknown;
|
|
12
|
+
at: bigint;
|
|
13
|
+
createdAt: Date;
|
|
14
|
+
}
|
|
15
|
+
export declare class PrismaLogStore implements IQueryableLogStore {
|
|
16
|
+
private readonly delegate;
|
|
17
|
+
constructor(delegate: PrismaDelegate<LogRow>);
|
|
18
|
+
record(entry: ActionLogEntry): Promise<void>;
|
|
19
|
+
list(filter?: Parameters<IQueryableLogStore['list']>[0]): Promise<ActionLogEntry[]>;
|
|
20
|
+
}
|
|
21
|
+
/** Narrow type-test: a pure `ILogStore` is enough where readback isn't needed. */
|
|
22
|
+
export type { ILogStore };
|
|
23
|
+
//# sourceMappingURL=log-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-store.d.ts","sourceRoot":"","sources":["../../src/stores/log-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACzG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,UAAU,MAAM;IACd,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,SAAS,EAAE,OAAO,CAAA;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,IAAI,CAAA;CAChB;AAkBD,qBAAa,cAAe,YAAW,kBAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC;IAEvD,MAAM,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB5C,IAAI,CAAC,MAAM,GAAE,UAAU,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;CAoB9F;AAED,kFAAkF;AAClF,YAAY,EAAE,SAAS,EAAE,CAAA"}
|