@beignet/provider-db-drizzle 0.0.9
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/CHANGELOG.md +82 -0
- package/README.md +1046 -0
- package/dist/mysql/index.d.ts +254 -0
- package/dist/mysql/index.d.ts.map +1 -0
- package/dist/mysql/index.js +348 -0
- package/dist/mysql/index.js.map +1 -0
- package/dist/postgres/index.d.ts +240 -0
- package/dist/postgres/index.d.ts.map +1 -0
- package/dist/postgres/index.js +296 -0
- package/dist/postgres/index.js.map +1 -0
- package/dist/shared/idempotency-core.d.ts +71 -0
- package/dist/shared/idempotency-core.d.ts.map +1 -0
- package/dist/shared/idempotency-core.js +169 -0
- package/dist/shared/idempotency-core.js.map +1 -0
- package/dist/shared/identifiers.d.ts +20 -0
- package/dist/shared/identifiers.d.ts.map +1 -0
- package/dist/shared/identifiers.js +27 -0
- package/dist/shared/identifiers.js.map +1 -0
- package/dist/shared/instrumentation.d.ts +19 -0
- package/dist/shared/instrumentation.d.ts.map +1 -0
- package/dist/shared/instrumentation.js +41 -0
- package/dist/shared/instrumentation.js.map +1 -0
- package/dist/shared/outbox-core.d.ts +76 -0
- package/dist/shared/outbox-core.d.ts.map +1 -0
- package/dist/shared/outbox-core.js +193 -0
- package/dist/shared/outbox-core.js.map +1 -0
- package/dist/shared/rows.d.ts +84 -0
- package/dist/shared/rows.d.ts.map +1 -0
- package/dist/shared/rows.js +128 -0
- package/dist/shared/rows.js.map +1 -0
- package/dist/sqlite/index.d.ts +235 -0
- package/dist/sqlite/index.d.ts.map +1 -0
- package/dist/sqlite/index.js +293 -0
- package/dist/sqlite/index.js.map +1 -0
- package/package.json +173 -0
- package/src/mysql/index.ts +627 -0
- package/src/postgres/index.ts +572 -0
- package/src/shared/idempotency-core.ts +280 -0
- package/src/shared/identifiers.ts +28 -0
- package/src/shared/instrumentation.ts +49 -0
- package/src/shared/outbox-core.ts +322 -0
- package/src/shared/rows.ts +197 -0
- package/src/sqlite/index.ts +547 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared row encode/decode helpers for Drizzle database providers.
|
|
3
|
+
*
|
|
4
|
+
* Every dialect stores timestamps as ISO-8601 UTC strings in `text` columns.
|
|
5
|
+
* This is deliberate: lexicographic order equals chronological order, the
|
|
6
|
+
* storage semantics stay byte-identical across SQLite, Postgres, and MySQL,
|
|
7
|
+
* and all values route through this single encode/decode point so a dialect
|
|
8
|
+
* could later move to native timestamp types without touching the shared
|
|
9
|
+
* orchestration in `outbox-core.ts` and `idempotency-core.ts`.
|
|
10
|
+
*/
|
|
11
|
+
import type { IdempotencyReservation } from "@beignet/core/idempotency";
|
|
12
|
+
import { type ClaimedOutboxMessage, type OutboxErrorInfo, type OutboxMessage, type OutboxMessageKind, type OutboxMessageStatus } from "@beignet/core/outbox";
|
|
13
|
+
/**
|
|
14
|
+
* Encode a timestamp for storage. All dialects store ISO-8601 UTC strings.
|
|
15
|
+
*/
|
|
16
|
+
export declare function encodeTimestamp(value: Date): string;
|
|
17
|
+
/**
|
|
18
|
+
* Decode a stored timestamp string back into a `Date`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function decodeTimestamp(value: string): Date;
|
|
21
|
+
/**
|
|
22
|
+
* Decode a nullable stored timestamp string.
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseNullableDate(value: string | null): Date | null;
|
|
25
|
+
/**
|
|
26
|
+
* Decode a stored outbox error JSON column.
|
|
27
|
+
*/
|
|
28
|
+
export declare function parseLastError(value: string | null): OutboxErrorInfo | null;
|
|
29
|
+
/**
|
|
30
|
+
* Raw outbox table row shape shared by every dialect.
|
|
31
|
+
*/
|
|
32
|
+
export interface OutboxRow {
|
|
33
|
+
id: string;
|
|
34
|
+
kind: OutboxMessageKind;
|
|
35
|
+
name: string;
|
|
36
|
+
payload_json: string;
|
|
37
|
+
status: OutboxMessageStatus;
|
|
38
|
+
attempts: number;
|
|
39
|
+
max_attempts: number;
|
|
40
|
+
available_at: string;
|
|
41
|
+
claimed_at: string | null;
|
|
42
|
+
locked_until: string | null;
|
|
43
|
+
claim_token: string | null;
|
|
44
|
+
delivered_at: string | null;
|
|
45
|
+
last_error_json: string | null;
|
|
46
|
+
created_at: string;
|
|
47
|
+
updated_at: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Decode a raw outbox row into an `OutboxMessage`.
|
|
51
|
+
*/
|
|
52
|
+
export declare function rowToMessage(row: OutboxRow): OutboxMessage;
|
|
53
|
+
/**
|
|
54
|
+
* Decode a raw outbox row into a `ClaimedOutboxMessage`.
|
|
55
|
+
*
|
|
56
|
+
* @throws OutboxClaimError when the row is not in a fully claimed state.
|
|
57
|
+
*/
|
|
58
|
+
export declare function rowToClaimedMessage(row: OutboxRow): ClaimedOutboxMessage;
|
|
59
|
+
/**
|
|
60
|
+
* Stored idempotency record status values shared by every dialect.
|
|
61
|
+
*/
|
|
62
|
+
export type IdempotencyRowStatus = "in-progress" | "completed";
|
|
63
|
+
/**
|
|
64
|
+
* Raw idempotency table row shape shared by every dialect.
|
|
65
|
+
*/
|
|
66
|
+
export interface IdempotencyRow {
|
|
67
|
+
storage_key: string;
|
|
68
|
+
namespace: string;
|
|
69
|
+
idempotency_key: string;
|
|
70
|
+
scope_key: string;
|
|
71
|
+
fingerprint: string;
|
|
72
|
+
status: IdempotencyRowStatus;
|
|
73
|
+
result_json: string | null;
|
|
74
|
+
reserved_at: string;
|
|
75
|
+
completed_at: string | null;
|
|
76
|
+
expires_at: string | null;
|
|
77
|
+
updated_at: string;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Decode a raw idempotency row into the reservation outcome for a caller
|
|
81
|
+
* holding `receivedFingerprint`.
|
|
82
|
+
*/
|
|
83
|
+
export declare function idempotencyReservationFromRow(row: IdempotencyRow, receivedFingerprint: string): IdempotencyReservation;
|
|
84
|
+
//# sourceMappingURL=rows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../../src/shared/rows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EACL,KAAK,oBAAoB,EAEzB,KAAK,eAAe,EAEpB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACzB,MAAM,sBAAsB,CAAC;AAE9B;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEnD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAEnE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,eAAe,GAAG,IAAI,CAE3E;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,SAAS,GAAG,aAAa,CAkB1D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,SAAS,GAAG,oBAAoB,CAqBxE;AAED;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG,WAAW,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,cAAc,EACnB,mBAAmB,EAAE,MAAM,GAC1B,sBAAsB,CA6CxB"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared row encode/decode helpers for Drizzle database providers.
|
|
3
|
+
*
|
|
4
|
+
* Every dialect stores timestamps as ISO-8601 UTC strings in `text` columns.
|
|
5
|
+
* This is deliberate: lexicographic order equals chronological order, the
|
|
6
|
+
* storage semantics stay byte-identical across SQLite, Postgres, and MySQL,
|
|
7
|
+
* and all values route through this single encode/decode point so a dialect
|
|
8
|
+
* could later move to native timestamp types without touching the shared
|
|
9
|
+
* orchestration in `outbox-core.ts` and `idempotency-core.ts`.
|
|
10
|
+
*/
|
|
11
|
+
import { OutboxClaimError, } from "@beignet/core/outbox";
|
|
12
|
+
/**
|
|
13
|
+
* Encode a timestamp for storage. All dialects store ISO-8601 UTC strings.
|
|
14
|
+
*/
|
|
15
|
+
export function encodeTimestamp(value) {
|
|
16
|
+
return value.toISOString();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Decode a stored timestamp string back into a `Date`.
|
|
20
|
+
*/
|
|
21
|
+
export function decodeTimestamp(value) {
|
|
22
|
+
return new Date(value);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Decode a nullable stored timestamp string.
|
|
26
|
+
*/
|
|
27
|
+
export function parseNullableDate(value) {
|
|
28
|
+
return value ? decodeTimestamp(value) : null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Decode a stored outbox error JSON column.
|
|
32
|
+
*/
|
|
33
|
+
export function parseLastError(value) {
|
|
34
|
+
return value ? JSON.parse(value) : null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Decode a raw outbox row into an `OutboxMessage`.
|
|
38
|
+
*/
|
|
39
|
+
export function rowToMessage(row) {
|
|
40
|
+
return {
|
|
41
|
+
id: row.id,
|
|
42
|
+
kind: row.kind,
|
|
43
|
+
name: row.name,
|
|
44
|
+
payload: JSON.parse(row.payload_json),
|
|
45
|
+
status: row.status,
|
|
46
|
+
attempts: row.attempts,
|
|
47
|
+
maxAttempts: row.max_attempts,
|
|
48
|
+
availableAt: decodeTimestamp(row.available_at),
|
|
49
|
+
claimedAt: parseNullableDate(row.claimed_at),
|
|
50
|
+
lockedUntil: parseNullableDate(row.locked_until),
|
|
51
|
+
claimToken: row.claim_token,
|
|
52
|
+
deliveredAt: parseNullableDate(row.delivered_at),
|
|
53
|
+
lastError: parseLastError(row.last_error_json),
|
|
54
|
+
createdAt: decodeTimestamp(row.created_at),
|
|
55
|
+
updatedAt: decodeTimestamp(row.updated_at),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Decode a raw outbox row into a `ClaimedOutboxMessage`.
|
|
60
|
+
*
|
|
61
|
+
* @throws OutboxClaimError when the row is not in a fully claimed state.
|
|
62
|
+
*/
|
|
63
|
+
export function rowToClaimedMessage(row) {
|
|
64
|
+
const message = rowToMessage(row);
|
|
65
|
+
if (message.status !== "claimed" ||
|
|
66
|
+
!message.claimToken ||
|
|
67
|
+
!message.claimedAt ||
|
|
68
|
+
!message.lockedUntil) {
|
|
69
|
+
throw new OutboxClaimError({
|
|
70
|
+
id: message.id,
|
|
71
|
+
message: `Outbox message "${message.id}" is not claimed.`,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
...message,
|
|
76
|
+
status: "claimed",
|
|
77
|
+
claimToken: message.claimToken,
|
|
78
|
+
claimedAt: message.claimedAt,
|
|
79
|
+
lockedUntil: message.lockedUntil,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Decode a raw idempotency row into the reservation outcome for a caller
|
|
84
|
+
* holding `receivedFingerprint`.
|
|
85
|
+
*/
|
|
86
|
+
export function idempotencyReservationFromRow(row, receivedFingerprint) {
|
|
87
|
+
const reservedAt = decodeTimestamp(row.reserved_at);
|
|
88
|
+
const completedAt = parseNullableDate(row.completed_at);
|
|
89
|
+
const expiresAt = parseNullableDate(row.expires_at);
|
|
90
|
+
if (row.fingerprint !== receivedFingerprint) {
|
|
91
|
+
return {
|
|
92
|
+
status: "conflict",
|
|
93
|
+
namespace: row.namespace,
|
|
94
|
+
key: row.idempotency_key,
|
|
95
|
+
scopeKey: row.scope_key,
|
|
96
|
+
storedFingerprint: row.fingerprint,
|
|
97
|
+
receivedFingerprint,
|
|
98
|
+
reservedAt,
|
|
99
|
+
completedAt: completedAt ?? undefined,
|
|
100
|
+
expiresAt,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
if (row.status === "completed" && completedAt) {
|
|
104
|
+
return {
|
|
105
|
+
status: "replay",
|
|
106
|
+
namespace: row.namespace,
|
|
107
|
+
key: row.idempotency_key,
|
|
108
|
+
scopeKey: row.scope_key,
|
|
109
|
+
fingerprint: row.fingerprint,
|
|
110
|
+
result: row.result_json === null
|
|
111
|
+
? undefined
|
|
112
|
+
: JSON.parse(row.result_json),
|
|
113
|
+
reservedAt,
|
|
114
|
+
completedAt,
|
|
115
|
+
expiresAt,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
status: "inProgress",
|
|
120
|
+
namespace: row.namespace,
|
|
121
|
+
key: row.idempotency_key,
|
|
122
|
+
scopeKey: row.scope_key,
|
|
123
|
+
fingerprint: row.fingerprint,
|
|
124
|
+
reservedAt,
|
|
125
|
+
expiresAt,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=rows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rows.js","sourceRoot":"","sources":["../../src/shared/rows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAEL,gBAAgB,GAMjB,MAAM,sBAAsB,CAAC;AAE9B;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAW;IACzC,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAoB;IACpD,OAAO,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAoB;IACjD,OAAO,KAAK,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAqB,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AAuBD;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,GAAc;IACzC,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAoB;QACxD,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,WAAW,EAAE,GAAG,CAAC,YAAY;QAC7B,WAAW,EAAE,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC;QAC9C,SAAS,EAAE,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC;QAC5C,WAAW,EAAE,iBAAiB,CAAC,GAAG,CAAC,YAAY,CAAC;QAChD,UAAU,EAAE,GAAG,CAAC,WAAW;QAC3B,WAAW,EAAE,iBAAiB,CAAC,GAAG,CAAC,YAAY,CAAC;QAChD,SAAS,EAAE,cAAc,CAAC,GAAG,CAAC,eAAe,CAAC;QAC9C,SAAS,EAAE,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC;QAC1C,SAAS,EAAE,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAc;IAChD,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAClC,IACE,OAAO,CAAC,MAAM,KAAK,SAAS;QAC5B,CAAC,OAAO,CAAC,UAAU;QACnB,CAAC,OAAO,CAAC,SAAS;QAClB,CAAC,OAAO,CAAC,WAAW,EACpB,CAAC;QACD,MAAM,IAAI,gBAAgB,CAAC;YACzB,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,OAAO,EAAE,mBAAmB,OAAO,CAAC,EAAE,mBAAmB;SAC1D,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,GAAG,OAAO;QACV,MAAM,EAAE,SAAS;QACjB,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC;AACJ,CAAC;AAwBD;;;GAGG;AACH,MAAM,UAAU,6BAA6B,CAC3C,GAAmB,EACnB,mBAA2B;IAE3B,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,iBAAiB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAEpD,IAAI,GAAG,CAAC,WAAW,KAAK,mBAAmB,EAAE,CAAC;QAC5C,OAAO;YACL,MAAM,EAAE,UAAU;YAClB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,GAAG,EAAE,GAAG,CAAC,eAAe;YACxB,QAAQ,EAAE,GAAG,CAAC,SAAS;YACvB,iBAAiB,EAAE,GAAG,CAAC,WAAW;YAClC,mBAAmB;YACnB,UAAU;YACV,WAAW,EAAE,WAAW,IAAI,SAAS;YACrC,SAAS;SACV,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW,IAAI,WAAW,EAAE,CAAC;QAC9C,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,GAAG,EAAE,GAAG,CAAC,eAAe;YACxB,QAAQ,EAAE,GAAG,CAAC,SAAS;YACvB,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,MAAM,EACJ,GAAG,CAAC,WAAW,KAAK,IAAI;gBACtB,CAAC,CAAC,SAAS;gBACX,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAa;YAC9C,UAAU;YACV,WAAW;YACX,SAAS;SACV,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE,YAAY;QACpB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,GAAG,EAAE,GAAG,CAAC,eAAe;QACxB,QAAQ,EAAE,GAAG,CAAC,SAAS;QACvB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,UAAU;QACV,SAAS;KACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @beignet/provider-db-drizzle/sqlite
|
|
3
|
+
*
|
|
4
|
+
* Drizzle ORM SQLite provider, backed by libSQL, that creates a typed
|
|
5
|
+
* database port. Works with local `file:` SQLite databases and with Turso's
|
|
6
|
+
* hosted libSQL service.
|
|
7
|
+
*
|
|
8
|
+
* Configuration:
|
|
9
|
+
* - SQLITE_DB_URL: libSQL database URL (required)
|
|
10
|
+
* - SQLITE_DB_AUTH_TOKEN: auth token for remote connections such as Turso
|
|
11
|
+
* (optional for local dev)
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import * as schema from "@/db/schema";
|
|
16
|
+
* import { createDrizzleSqliteProvider } from "@beignet/provider-db-drizzle/sqlite";
|
|
17
|
+
*
|
|
18
|
+
* export const drizzleSqliteProvider = createDrizzleSqliteProvider({ schema });
|
|
19
|
+
*
|
|
20
|
+
* // In createNextServer:
|
|
21
|
+
* const server = await createNextServer({
|
|
22
|
+
* ports: basePorts,
|
|
23
|
+
* providers: [drizzleSqliteProvider],
|
|
24
|
+
* // ...
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* // In infra:
|
|
28
|
+
* const todos = createDrizzleTodoRepository(ctx.ports.db.db);
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
import type { IdempotencyPort } from "@beignet/core/idempotency";
|
|
32
|
+
import type { OutboxPort } from "@beignet/core/outbox";
|
|
33
|
+
import { type BufferedDomainEventRecorder, type EventBusPort, type UnitOfWorkPort } from "@beignet/core/ports";
|
|
34
|
+
import { type Client } from "@libsql/client";
|
|
35
|
+
import { type ExtractTablesWithRelations } from "drizzle-orm";
|
|
36
|
+
import { type LibSQLDatabase } from "drizzle-orm/libsql";
|
|
37
|
+
import type { LibSQLTransaction } from "drizzle-orm/libsql/session";
|
|
38
|
+
import type { SQLiteTransactionConfig } from "drizzle-orm/sqlite-core";
|
|
39
|
+
import { z } from "zod";
|
|
40
|
+
/**
|
|
41
|
+
* Typed database port interface.
|
|
42
|
+
* Exposes a typed Drizzle database instance for your schema.
|
|
43
|
+
*
|
|
44
|
+
* @template TSchema - The Drizzle schema type (e.g., `typeof schema`)
|
|
45
|
+
*/
|
|
46
|
+
export interface DbPort<TSchema extends Record<string, unknown> = Record<string, unknown>> {
|
|
47
|
+
/**
|
|
48
|
+
* The typed Drizzle database instance.
|
|
49
|
+
* Use this to query your database with full type safety.
|
|
50
|
+
*/
|
|
51
|
+
db: LibSQLDatabase<TSchema>;
|
|
52
|
+
/**
|
|
53
|
+
* The underlying libSQL client instance.
|
|
54
|
+
* Use this for advanced operations not covered by Drizzle ORM.
|
|
55
|
+
*/
|
|
56
|
+
client: Client;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Drizzle database or transaction client accepted by repository factories.
|
|
60
|
+
*/
|
|
61
|
+
export type DrizzleSqliteDatabase<TSchema extends Record<string, unknown> = Record<string, unknown>> = LibSQLDatabase<TSchema> | LibSQLTransaction<TSchema, ExtractTablesWithRelations<TSchema>>;
|
|
62
|
+
/**
|
|
63
|
+
* Drizzle transaction client passed to Unit of Work repository factories.
|
|
64
|
+
*/
|
|
65
|
+
export type DrizzleSqliteTransaction<TSchema extends Record<string, unknown> = Record<string, unknown>> = LibSQLTransaction<TSchema, ExtractTablesWithRelations<TSchema>>;
|
|
66
|
+
/**
|
|
67
|
+
* Options for creating a Drizzle SQLite-backed Unit of Work port.
|
|
68
|
+
*/
|
|
69
|
+
export interface DrizzleSqliteUnitOfWorkOptions<TSchema extends Record<string, unknown>, TxPorts> {
|
|
70
|
+
/**
|
|
71
|
+
* The root Drizzle database instance from `ctx.ports.db.db`.
|
|
72
|
+
*/
|
|
73
|
+
db: LibSQLDatabase<TSchema>;
|
|
74
|
+
/**
|
|
75
|
+
* Create transaction-scoped ports from the Drizzle transaction client.
|
|
76
|
+
*
|
|
77
|
+
* The event recorder is transaction-local. Record domain events inside the
|
|
78
|
+
* callback and pass `eventBus` to publish them after the database commit.
|
|
79
|
+
*/
|
|
80
|
+
createTransactionPorts: (db: DrizzleSqliteTransaction<TSchema>, events: BufferedDomainEventRecorder) => TxPorts;
|
|
81
|
+
/**
|
|
82
|
+
* Optional event bus used to flush recorded domain events after commit.
|
|
83
|
+
*/
|
|
84
|
+
eventBus?: EventBusPort;
|
|
85
|
+
/**
|
|
86
|
+
* Optional Drizzle transaction configuration.
|
|
87
|
+
*/
|
|
88
|
+
transactionConfig?: SQLiteTransactionConfig;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create a Unit of Work port backed by Drizzle's libSQL transaction API.
|
|
92
|
+
*
|
|
93
|
+
* Beignet does not own your repository interfaces. This helper only
|
|
94
|
+
* provides the transaction boundary and post-commit event flushing; your app
|
|
95
|
+
* decides which transaction-scoped ports to create.
|
|
96
|
+
*/
|
|
97
|
+
export declare function createDrizzleSqliteUnitOfWork<TSchema extends Record<string, unknown>, TxPorts>(options: DrizzleSqliteUnitOfWorkOptions<TSchema, TxPorts>): UnitOfWorkPort<TxPorts>;
|
|
98
|
+
/**
|
|
99
|
+
* Options for a Drizzle SQLite-backed outbox port.
|
|
100
|
+
*/
|
|
101
|
+
export interface DrizzleSqliteOutboxOptions {
|
|
102
|
+
/**
|
|
103
|
+
* Table that stores outbox messages.
|
|
104
|
+
*
|
|
105
|
+
* Default: "outbox_messages".
|
|
106
|
+
*/
|
|
107
|
+
tableName?: string;
|
|
108
|
+
/**
|
|
109
|
+
* Clock used by tests and deterministic environments.
|
|
110
|
+
*/
|
|
111
|
+
now?: () => Date;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Create idempotent SQL statements for the Drizzle SQLite outbox table.
|
|
115
|
+
*
|
|
116
|
+
* Run these during migrations or local setup before using
|
|
117
|
+
* `createDrizzleSqliteOutboxPort(...)`.
|
|
118
|
+
*/
|
|
119
|
+
export declare function createDrizzleSqliteOutboxSetupStatements(options?: DrizzleSqliteOutboxOptions): readonly string[];
|
|
120
|
+
/**
|
|
121
|
+
* Create a Beignet outbox port backed by a Drizzle SQLite database.
|
|
122
|
+
*
|
|
123
|
+
* Claiming uses a claim-token lease so concurrent workers can safely compete
|
|
124
|
+
* for eligible messages.
|
|
125
|
+
*/
|
|
126
|
+
export declare function createDrizzleSqliteOutboxPort<TSchema extends Record<string, unknown>>(db: DrizzleSqliteDatabase<TSchema>, adapterOptions?: DrizzleSqliteOutboxOptions): OutboxPort;
|
|
127
|
+
/**
|
|
128
|
+
* Options for a Drizzle SQLite-backed idempotency port.
|
|
129
|
+
*/
|
|
130
|
+
export interface DrizzleSqliteIdempotencyOptions {
|
|
131
|
+
/**
|
|
132
|
+
* Table that stores idempotency records.
|
|
133
|
+
*
|
|
134
|
+
* Default: "idempotency_records".
|
|
135
|
+
*/
|
|
136
|
+
tableName?: string;
|
|
137
|
+
/**
|
|
138
|
+
* Clock used by tests and deterministic environments.
|
|
139
|
+
*/
|
|
140
|
+
now?: () => Date;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Error thrown when `complete(...)` or `fail(...)` does not match an
|
|
144
|
+
* in-progress idempotency reservation with the provided fingerprint.
|
|
145
|
+
*
|
|
146
|
+
* This usually signals a workflow bug: the reservation was never made, was
|
|
147
|
+
* already completed or released, expired and was cleaned up, or the caller
|
|
148
|
+
* passed a different fingerprint than the one used to reserve.
|
|
149
|
+
*/
|
|
150
|
+
export declare class DrizzleSqliteIdempotencyMutationError extends Error {
|
|
151
|
+
readonly action: "complete" | "fail";
|
|
152
|
+
readonly namespace: string;
|
|
153
|
+
readonly key: string;
|
|
154
|
+
readonly scopeKey: string;
|
|
155
|
+
constructor(args: {
|
|
156
|
+
action: "complete" | "fail";
|
|
157
|
+
namespace: string;
|
|
158
|
+
key: string;
|
|
159
|
+
scopeKey: string;
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Create idempotent SQL statements for the Drizzle SQLite idempotency table.
|
|
164
|
+
*
|
|
165
|
+
* Run these during migrations or local setup before using
|
|
166
|
+
* `createDrizzleSqliteIdempotencyPort(...)`.
|
|
167
|
+
*/
|
|
168
|
+
export declare function createDrizzleSqliteIdempotencySetupStatements(options?: DrizzleSqliteIdempotencyOptions): readonly string[];
|
|
169
|
+
/**
|
|
170
|
+
* Create a Beignet idempotency port backed by a Drizzle SQLite database.
|
|
171
|
+
*
|
|
172
|
+
* The port accepts both the root Drizzle database and transaction clients, so
|
|
173
|
+
* applications can expose root idempotency for ordinary retry-safe commands and
|
|
174
|
+
* transaction-scoped idempotency from Unit of Work.
|
|
175
|
+
*/
|
|
176
|
+
export declare function createDrizzleSqliteIdempotencyPort<TSchema extends Record<string, unknown>>(db: DrizzleSqliteDatabase<TSchema>, adapterOptions?: DrizzleSqliteIdempotencyOptions): IdempotencyPort;
|
|
177
|
+
/**
|
|
178
|
+
* Configuration schema for the Drizzle SQLite provider.
|
|
179
|
+
* Validates environment variables with SQLITE_ prefix.
|
|
180
|
+
*/
|
|
181
|
+
declare const SqliteConfigSchema: z.ZodObject<{
|
|
182
|
+
DB_URL: z.ZodString;
|
|
183
|
+
DB_AUTH_TOKEN: z.ZodOptional<z.ZodString>;
|
|
184
|
+
}, z.core.$strip>;
|
|
185
|
+
/**
|
|
186
|
+
* SQLite provider config loaded from `SQLITE_*` env vars.
|
|
187
|
+
*/
|
|
188
|
+
export type SqliteConfig = z.infer<typeof SqliteConfigSchema>;
|
|
189
|
+
/**
|
|
190
|
+
* Options for creating a Drizzle SQLite provider.
|
|
191
|
+
*
|
|
192
|
+
* @template TSchema - The Drizzle schema type
|
|
193
|
+
*/
|
|
194
|
+
export interface DrizzleSqliteProviderOptions<TSchema extends Record<string, unknown>, PortName extends string = "db"> {
|
|
195
|
+
/**
|
|
196
|
+
* The Drizzle schema object (e.g. `import * as schema from '@/db/schema'`).
|
|
197
|
+
* This schema is used to create a typed Drizzle database instance.
|
|
198
|
+
*/
|
|
199
|
+
schema: TSchema;
|
|
200
|
+
/**
|
|
201
|
+
* Optional port name. Defaults to "db".
|
|
202
|
+
* Renames the contributed port. The provider always reads its connection
|
|
203
|
+
* from `SQLITE_DB_URL`; for a second database, wire an app-owned provider
|
|
204
|
+
* with its own env prefix instead.
|
|
205
|
+
*/
|
|
206
|
+
portName?: PortName;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Create a Drizzle SQLite provider factory.
|
|
210
|
+
*
|
|
211
|
+
* This factory creates a service provider that:
|
|
212
|
+
* - Uses libSQL via @libsql/client, for local `file:` SQLite databases and
|
|
213
|
+
* Turso's hosted libSQL service
|
|
214
|
+
* - Uses Drizzle ORM via drizzle-orm/libsql
|
|
215
|
+
* - Exposes a typed DbPort<TSchema> on ports
|
|
216
|
+
* - Uses SQLITE_-prefixed env vars for connection config
|
|
217
|
+
*
|
|
218
|
+
* @template TSchema - The Drizzle schema type (inferred from the schema parameter)
|
|
219
|
+
* @param options - Configuration options including the schema
|
|
220
|
+
* @returns A service provider that can be used with createNextServer
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```ts
|
|
224
|
+
* import * as schema from "@/db/schema";
|
|
225
|
+
* import { createDrizzleSqliteProvider } from "@beignet/provider-db-drizzle/sqlite";
|
|
226
|
+
*
|
|
227
|
+
* export const drizzleSqliteProvider = createDrizzleSqliteProvider({ schema });
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
export declare function createDrizzleSqliteProvider<TSchema extends Record<string, unknown>, PortName extends string = "db">(options: DrizzleSqliteProviderOptions<TSchema, PortName>): import("@beignet/core/providers").ServiceProvider<unknown, z.ZodObject<{
|
|
231
|
+
DB_URL: z.ZodString;
|
|
232
|
+
DB_AUTH_TOKEN: z.ZodOptional<z.ZodString>;
|
|
233
|
+
}, z.core.$strip>, Record<PortName, DbPort<TSchema>>, unknown, void>;
|
|
234
|
+
export {};
|
|
235
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sqlite/index.ts"],"names":[],"mappings":"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"}
|