@zudojs/database 0.1.0 → 1.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/LICENSE +21 -0
- package/README.md +225 -17
- package/dist/cache/cache.memory.d.ts +167 -0
- package/dist/cache/cache.memory.js +186 -40
- package/dist/cache/index.d.ts +2 -2
- package/dist/cache/index.js +2 -2
- package/dist/database/database.core.d.ts +91 -0
- package/dist/database/database.core.js +21 -4
- package/dist/databaseClient/databaseClient.core.d.ts +171 -14
- package/dist/databaseClient/databaseClient.core.js +350 -70
- package/dist/databaseClient/databaseClient.errors.d.ts +112 -0
- package/dist/databaseClient/databaseClient.errors.js +425 -0
- package/dist/databaseClient/index.d.ts +2 -1
- package/dist/databaseClient/index.js +2 -1
- package/dist/databaseConnection/databaseConnection.manager.d.ts +163 -0
- package/dist/databaseConnection/databaseConnection.manager.js +138 -76
- package/dist/databaseConnection/index.d.ts +1 -1
- package/dist/databaseType/databaseType.type.d.ts +224 -0
- package/dist/databaseType/databaseType.type.js +0 -35
- package/dist/health/health.check.d.ts +74 -0
- package/dist/health/health.check.js +78 -47
- package/dist/health/index.d.ts +1 -1
- package/dist/health/index.js +1 -1
- package/dist/index.d.ts +14 -14
- package/dist/index.js +11 -11
- package/dist/locks/index.d.ts +2 -2
- package/dist/locks/index.js +2 -2
- package/dist/locks/locks.core.d.ts +132 -0
- package/dist/locks/locks.core.js +150 -85
- package/dist/migration/index.d.ts +3 -1
- package/dist/migration/index.js +2 -0
- package/dist/migration/migration.dialect.d.ts +65 -0
- package/dist/migration/migration.dialect.js +63 -0
- package/dist/migration/migration.helpers.d.ts +65 -0
- package/dist/migration/migration.helpers.js +60 -18
- package/dist/migration/migration.runner.d.ts +75 -0
- package/dist/migration/migration.runner.js +195 -107
- package/dist/migration/migration.types.d.ts +85 -0
- package/dist/pagination/index.d.ts +2 -1
- package/dist/pagination/index.js +2 -1
- package/dist/pagination/pagination.core.d.ts +163 -0
- package/dist/pagination/pagination.core.js +78 -9
- package/dist/pagination/pagination.keyset.d.ts +55 -0
- package/dist/pagination/pagination.keyset.js +108 -0
- package/dist/queryBuilder/index.d.ts +4 -3
- package/dist/queryBuilder/index.js +3 -2
- package/dist/queryBuilder/queryBuilder.core.d.ts +178 -0
- package/dist/queryBuilder/queryBuilder.core.js +92 -14
- package/dist/queryBuilder/queryBuilder.factory.d.ts +6 -0
- package/dist/queryBuilder/queryBuilder.factory.js +0 -25
- package/dist/queryBuilder/queryBuilder.filter.d.ts +170 -0
- package/dist/queryBuilder/queryBuilder.filter.js +191 -30
- package/dist/queryBuilder/queryBuilder.prisma.d.ts +60 -0
- package/dist/queryBuilder/queryBuilder.prisma.js +233 -0
- package/dist/queryBuilder/queryBuilder.type.d.ts +48 -0
- package/dist/relations/index.d.ts +1 -1
- package/dist/relations/index.js +1 -1
- package/dist/relations/relations.definition.d.ts +184 -0
- package/dist/relations/relations.definition.js +186 -19
- package/dist/repository/index.d.ts +2 -1
- package/dist/repository/index.js +1 -0
- package/dist/repository/repository.base.d.ts +283 -0
- package/dist/repository/repository.base.js +370 -89
- package/dist/repository/repository.errors.d.ts +60 -0
- package/dist/repository/repository.errors.js +235 -0
- package/dist/seed/index.d.ts +2 -2
- package/dist/seed/index.js +1 -1
- package/dist/seed/seed.runner.d.ts +160 -0
- package/dist/seed/seed.runner.js +194 -225
- package/dist/transaction/index.d.ts +1 -1
- package/dist/transaction/index.js +1 -1
- package/dist/transaction/transaction.core.d.ts +117 -0
- package/dist/transaction/transaction.core.js +83 -56
- package/dist/unitOfWork/unitOfWork.core.d.ts +44 -0
- package/dist/unitOfWork/unitOfWork.core.js +9 -20
- package/package.json +44 -24
- package/dist/cache/cache.memory.d.ts.map +0 -1
- package/dist/cache/cache.memory.js.map +0 -1
- package/dist/cache/index.d.ts.map +0 -1
- package/dist/cache/index.js.map +0 -1
- package/dist/database/database.core.d.ts.map +0 -1
- package/dist/database/database.core.js.map +0 -1
- package/dist/database/index.d.ts.map +0 -1
- package/dist/database/index.js.map +0 -1
- package/dist/databaseClient/databaseClient.core.d.ts.map +0 -1
- package/dist/databaseClient/databaseClient.core.js.map +0 -1
- package/dist/databaseClient/databaseClient.logger.d.ts.map +0 -1
- package/dist/databaseClient/databaseClient.logger.js.map +0 -1
- package/dist/databaseClient/index.d.ts.map +0 -1
- package/dist/databaseClient/index.js.map +0 -1
- package/dist/databaseConnection/databaseConnection.manager.d.ts.map +0 -1
- package/dist/databaseConnection/databaseConnection.manager.js.map +0 -1
- package/dist/databaseConnection/index.d.ts.map +0 -1
- package/dist/databaseConnection/index.js.map +0 -1
- package/dist/databaseType/databaseType.type.d.ts.map +0 -1
- package/dist/databaseType/databaseType.type.js.map +0 -1
- package/dist/databaseType/index.d.ts.map +0 -1
- package/dist/databaseType/index.js.map +0 -1
- package/dist/health/health.check.d.ts.map +0 -1
- package/dist/health/health.check.js.map +0 -1
- package/dist/health/index.d.ts.map +0 -1
- package/dist/health/index.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/locks/index.d.ts.map +0 -1
- package/dist/locks/index.js.map +0 -1
- package/dist/locks/locks.core.d.ts.map +0 -1
- package/dist/locks/locks.core.js.map +0 -1
- package/dist/migration/index.d.ts.map +0 -1
- package/dist/migration/index.js.map +0 -1
- package/dist/migration/migration.helpers.d.ts.map +0 -1
- package/dist/migration/migration.helpers.js.map +0 -1
- package/dist/migration/migration.runner.d.ts.map +0 -1
- package/dist/migration/migration.runner.js.map +0 -1
- package/dist/migration/migration.types.d.ts.map +0 -1
- package/dist/migration/migration.types.js.map +0 -1
- package/dist/pagination/index.d.ts.map +0 -1
- package/dist/pagination/index.js.map +0 -1
- package/dist/pagination/pagination.core.d.ts.map +0 -1
- package/dist/pagination/pagination.core.js.map +0 -1
- package/dist/queryBuilder/index.d.ts.map +0 -1
- package/dist/queryBuilder/index.js.map +0 -1
- package/dist/queryBuilder/queryBuilder.core.d.ts.map +0 -1
- package/dist/queryBuilder/queryBuilder.core.js.map +0 -1
- package/dist/queryBuilder/queryBuilder.factory.d.ts.map +0 -1
- package/dist/queryBuilder/queryBuilder.factory.js.map +0 -1
- package/dist/queryBuilder/queryBuilder.filter.d.ts.map +0 -1
- package/dist/queryBuilder/queryBuilder.filter.js.map +0 -1
- package/dist/queryBuilder/queryBuilder.type.d.ts.map +0 -1
- package/dist/queryBuilder/queryBuilder.type.js.map +0 -1
- package/dist/relations/index.d.ts.map +0 -1
- package/dist/relations/index.js.map +0 -1
- package/dist/relations/relations.definition.d.ts.map +0 -1
- package/dist/relations/relations.definition.js.map +0 -1
- package/dist/repository/index.d.ts.map +0 -1
- package/dist/repository/index.js.map +0 -1
- package/dist/repository/repository.base.d.ts.map +0 -1
- package/dist/repository/repository.base.js.map +0 -1
- package/dist/seed/index.d.ts.map +0 -1
- package/dist/seed/index.js.map +0 -1
- package/dist/seed/seed.runner.d.ts.map +0 -1
- package/dist/seed/seed.runner.js.map +0 -1
- package/dist/transaction/index.d.ts.map +0 -1
- package/dist/transaction/index.js.map +0 -1
- package/dist/transaction/transaction.core.d.ts.map +0 -1
- package/dist/transaction/transaction.core.js.map +0 -1
- package/dist/unitOfWork/index.d.ts.map +0 -1
- package/dist/unitOfWork/index.js.map +0 -1
- package/dist/unitOfWork/unitOfWork.core.d.ts.map +0 -1
- package/dist/unitOfWork/unitOfWork.core.js.map +0 -1
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { DatabaseError, DatabaseOperation, ErrorCode, } from "@zudojs/errors";
|
|
2
|
+
import { isDatabaseErrorLike } from "../databaseClient/databaseClient.errors.js";
|
|
3
|
+
const PRISMA_CODE_PATTERN = /^P\d{4}$/;
|
|
4
|
+
/**
|
|
5
|
+
* Determines whether a value looks like a Prisma known request error.
|
|
6
|
+
*/
|
|
7
|
+
export function isPrismaErrorLike(value) {
|
|
8
|
+
if (value === null || typeof value !== "object") {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
const candidate = value;
|
|
12
|
+
return (typeof candidate.code === "string" &&
|
|
13
|
+
PRISMA_CODE_PATTERN.test(candidate.code) &&
|
|
14
|
+
typeof candidate.message === "string");
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Maps a repository operation name to the errors package operation enum.
|
|
18
|
+
*/
|
|
19
|
+
export function toDatabaseOperation(operation) {
|
|
20
|
+
switch (operation) {
|
|
21
|
+
case "create":
|
|
22
|
+
case "createMany":
|
|
23
|
+
return DatabaseOperation.INSERT;
|
|
24
|
+
case "update":
|
|
25
|
+
case "upsert":
|
|
26
|
+
case "softDelete":
|
|
27
|
+
case "restore":
|
|
28
|
+
return DatabaseOperation.UPDATE;
|
|
29
|
+
case "delete":
|
|
30
|
+
case "deleteMany":
|
|
31
|
+
return DatabaseOperation.DELETE;
|
|
32
|
+
case "findById":
|
|
33
|
+
case "findOne":
|
|
34
|
+
case "findMany":
|
|
35
|
+
case "findPaginated":
|
|
36
|
+
case "findByQuery":
|
|
37
|
+
case "paginateCursor":
|
|
38
|
+
case "findDeleted":
|
|
39
|
+
case "count":
|
|
40
|
+
case "exists":
|
|
41
|
+
return DatabaseOperation.QUERY;
|
|
42
|
+
default:
|
|
43
|
+
return DatabaseOperation.UNKNOWN;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Normalizes any failure raised by a repository operation into a
|
|
48
|
+
* `DatabaseError`, mapping Prisma error codes to typed outcomes:
|
|
49
|
+
*
|
|
50
|
+
* - `P2002` unique violation → `ERR_CONFLICT` / 409
|
|
51
|
+
* - `P2025` record not found → `ERR_NOT_FOUND` / 404
|
|
52
|
+
* - `P2003` foreign key violation → `ERR_CONFLICT` / 409
|
|
53
|
+
* - `P2034` serialization failure → `ERR_DATABASE_TRANSACTION` / 409 (retryable)
|
|
54
|
+
* - `P2024` pool timeout → `ERR_DATABASE_TIMEOUT` / 503
|
|
55
|
+
* - `P1xxx` connection failures → `ERR_DATABASE_CONNECTION` / 503
|
|
56
|
+
*
|
|
57
|
+
* Existing `DatabaseError`s are returned unchanged.
|
|
58
|
+
*/
|
|
59
|
+
export function mapRepositoryError(error, context) {
|
|
60
|
+
if (isDatabaseErrorLike(error)) {
|
|
61
|
+
return error;
|
|
62
|
+
}
|
|
63
|
+
const operation = toDatabaseOperation(context.operation);
|
|
64
|
+
const metadata = {
|
|
65
|
+
...toErrorMetadata(context.metadata),
|
|
66
|
+
model: context.model,
|
|
67
|
+
operation: context.operation,
|
|
68
|
+
durationMs: context.durationMs,
|
|
69
|
+
};
|
|
70
|
+
const base = {
|
|
71
|
+
cause: error,
|
|
72
|
+
operation,
|
|
73
|
+
driver: "prisma",
|
|
74
|
+
};
|
|
75
|
+
if (!isPrismaErrorLike(error)) {
|
|
76
|
+
return new DatabaseError(error instanceof Error
|
|
77
|
+
? error.message
|
|
78
|
+
: `${context.model} ${context.operation} failed.`, {
|
|
79
|
+
...base,
|
|
80
|
+
driver: undefined,
|
|
81
|
+
metadata,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
const target = extractTarget(error.meta);
|
|
85
|
+
if (target !== undefined) {
|
|
86
|
+
metadata["target"] = target;
|
|
87
|
+
}
|
|
88
|
+
const fieldName = error.meta?.["field_name"];
|
|
89
|
+
if (typeof fieldName === "string") {
|
|
90
|
+
metadata["field"] = fieldName;
|
|
91
|
+
}
|
|
92
|
+
const options = {
|
|
93
|
+
...base,
|
|
94
|
+
databaseCode: error.code,
|
|
95
|
+
metadata,
|
|
96
|
+
};
|
|
97
|
+
switch (error.code) {
|
|
98
|
+
case "P2002":
|
|
99
|
+
return new DatabaseError(`${context.model} already exists.`, {
|
|
100
|
+
...options,
|
|
101
|
+
code: ErrorCode.CONFLICT,
|
|
102
|
+
statusCode: 409,
|
|
103
|
+
expose: true,
|
|
104
|
+
});
|
|
105
|
+
case "P2025":
|
|
106
|
+
return new DatabaseError(`${context.model} was not found.`, {
|
|
107
|
+
...options,
|
|
108
|
+
code: ErrorCode.NOT_FOUND,
|
|
109
|
+
statusCode: 404,
|
|
110
|
+
expose: true,
|
|
111
|
+
});
|
|
112
|
+
case "P2003":
|
|
113
|
+
return new DatabaseError(`${context.model} ${context.operation} violates a foreign key constraint.`, {
|
|
114
|
+
...options,
|
|
115
|
+
code: ErrorCode.CONFLICT,
|
|
116
|
+
statusCode: 409,
|
|
117
|
+
expose: true,
|
|
118
|
+
});
|
|
119
|
+
case "P2034":
|
|
120
|
+
return new DatabaseError(`${context.model} ${context.operation} failed due to a transaction conflict.`, {
|
|
121
|
+
...options,
|
|
122
|
+
code: ErrorCode.DATABASE_TRANSACTION,
|
|
123
|
+
statusCode: 409,
|
|
124
|
+
metadata: { ...metadata, retryable: true },
|
|
125
|
+
});
|
|
126
|
+
case "P2024":
|
|
127
|
+
return new DatabaseError(`${context.model} ${context.operation} timed out waiting for a connection.`, {
|
|
128
|
+
...options,
|
|
129
|
+
code: ErrorCode.DATABASE_TIMEOUT,
|
|
130
|
+
statusCode: 503,
|
|
131
|
+
});
|
|
132
|
+
default:
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
if (error.code.startsWith("P1")) {
|
|
136
|
+
return new DatabaseError(`${context.model} ${context.operation} failed: database unavailable.`, {
|
|
137
|
+
...options,
|
|
138
|
+
code: ErrorCode.DATABASE_CONNECTION,
|
|
139
|
+
statusCode: 503,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return new DatabaseError(`${context.model} ${context.operation} failed.`, {
|
|
143
|
+
...options,
|
|
144
|
+
code: ErrorCode.DATABASE_QUERY,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Creates the error raised when an operation is aborted via `AbortSignal`.
|
|
149
|
+
*/
|
|
150
|
+
export function createAbortError(context, reason) {
|
|
151
|
+
return new DatabaseError(`${context.model} ${context.operation} was aborted.`, {
|
|
152
|
+
code: ErrorCode.OPERATION_CANCELLED,
|
|
153
|
+
statusCode: 499,
|
|
154
|
+
operation: toDatabaseOperation(context.operation),
|
|
155
|
+
cause: reason,
|
|
156
|
+
metadata: {
|
|
157
|
+
...toErrorMetadata(context.metadata),
|
|
158
|
+
model: context.model,
|
|
159
|
+
operation: context.operation,
|
|
160
|
+
aborted: true,
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Creates the error raised when a client-side timeout elapses.
|
|
166
|
+
*/
|
|
167
|
+
export function createTimeoutError(context, timeoutMs) {
|
|
168
|
+
return new DatabaseError(`${context.model} ${context.operation} timed out after ${timeoutMs}ms.`, {
|
|
169
|
+
code: ErrorCode.DATABASE_TIMEOUT,
|
|
170
|
+
statusCode: 503,
|
|
171
|
+
operation: toDatabaseOperation(context.operation),
|
|
172
|
+
metadata: {
|
|
173
|
+
...toErrorMetadata(context.metadata),
|
|
174
|
+
model: context.model,
|
|
175
|
+
operation: context.operation,
|
|
176
|
+
timeoutMs,
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Converts arbitrary metadata into the serializable shape the errors
|
|
182
|
+
* package accepts.
|
|
183
|
+
*/
|
|
184
|
+
export function toErrorMetadata(value) {
|
|
185
|
+
const result = {};
|
|
186
|
+
if (!value) {
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
190
|
+
result[key] = toMetadataValue(entry);
|
|
191
|
+
}
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
function toMetadataValue(value) {
|
|
195
|
+
if (value === undefined) {
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
if (value === null ||
|
|
199
|
+
typeof value === "string" ||
|
|
200
|
+
typeof value === "number" ||
|
|
201
|
+
typeof value === "boolean") {
|
|
202
|
+
return value;
|
|
203
|
+
}
|
|
204
|
+
if (value instanceof Date) {
|
|
205
|
+
return value.toISOString();
|
|
206
|
+
}
|
|
207
|
+
if (typeof value === "bigint") {
|
|
208
|
+
return value.toString();
|
|
209
|
+
}
|
|
210
|
+
if (Array.isArray(value)) {
|
|
211
|
+
return value.map((entry) => toMetadataValue(entry) ?? null);
|
|
212
|
+
}
|
|
213
|
+
if (typeof value === "object") {
|
|
214
|
+
const result = {};
|
|
215
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
216
|
+
const converted = toMetadataValue(entry);
|
|
217
|
+
if (converted !== undefined) {
|
|
218
|
+
result[key] = converted;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return result;
|
|
222
|
+
}
|
|
223
|
+
return String(value);
|
|
224
|
+
}
|
|
225
|
+
function extractTarget(meta) {
|
|
226
|
+
const target = meta?.["target"];
|
|
227
|
+
if (typeof target === "string") {
|
|
228
|
+
return target;
|
|
229
|
+
}
|
|
230
|
+
if (Array.isArray(target)) {
|
|
231
|
+
return target.map((entry) => String(entry));
|
|
232
|
+
}
|
|
233
|
+
return undefined;
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=repository.errors.js.map
|
package/dist/seed/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @zudojs/database — Seeds
|
|
3
3
|
*
|
|
4
|
-
* Database seed runner with execution tracking.
|
|
4
|
+
* Database seed runner with execution tracking (PostgreSQL).
|
|
5
5
|
*/
|
|
6
|
-
export { SeedRunner, createSeedRunner, normalizeSeeds, validateSeed, DEFAULT_SEED_TABLE, DEFAULT_SEED_LOCK, type Seed, type SeedRecord, type SeedResult, type SeedRunnerOptions, } from "./seed.runner.js";
|
|
6
|
+
export { SeedRunner, createSeedRunner, normalizeSeeds, validateSeed, DEFAULT_SEED_TABLE, DEFAULT_SEED_LOCK, type Seed, type SeedRecord, type SeedResult, type SeedStatus, type SeedRunnerOptions, } from "./seed.runner.js";
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/seed/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @zudojs/database — Seeds
|
|
3
3
|
*
|
|
4
|
-
* Database seed runner with execution tracking.
|
|
4
|
+
* Database seed runner with execution tracking (PostgreSQL).
|
|
5
5
|
*/
|
|
6
6
|
export { SeedRunner, createSeedRunner, normalizeSeeds, validateSeed, DEFAULT_SEED_TABLE, DEFAULT_SEED_LOCK, } from "./seed.runner.js";
|
|
7
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import type { DatabaseClient, DatabaseTransactionContext } from "../databaseClient/databaseClient.core.js";
|
|
2
|
+
import { type SqlDialectName } from "../migration/migration.dialect.js";
|
|
3
|
+
import type { RunnerTransactionOptions } from "../migration/migration.types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Defines a database seed operation.
|
|
6
|
+
*/
|
|
7
|
+
export interface Seed {
|
|
8
|
+
/**
|
|
9
|
+
* Unique seed name.
|
|
10
|
+
*/
|
|
11
|
+
readonly name: string;
|
|
12
|
+
/**
|
|
13
|
+
* Seed execution order. Seeds with equal order run in declaration order.
|
|
14
|
+
*/
|
|
15
|
+
readonly order?: number;
|
|
16
|
+
/**
|
|
17
|
+
* Executes the seed.
|
|
18
|
+
*/
|
|
19
|
+
readonly run: (database: DatabaseTransactionContext) => Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Optional cleanup operation.
|
|
22
|
+
*/
|
|
23
|
+
readonly rollback?: (database: DatabaseTransactionContext) => Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Persisted seed execution record.
|
|
27
|
+
*/
|
|
28
|
+
export interface SeedRecord {
|
|
29
|
+
readonly name: string;
|
|
30
|
+
readonly appliedAt: Date;
|
|
31
|
+
/**
|
|
32
|
+
* Execution sequence number. Rollbacks walk this in descending order so
|
|
33
|
+
* seeds applied together in one batch are reverted in reverse execution
|
|
34
|
+
* order rather than alphabetically.
|
|
35
|
+
*/
|
|
36
|
+
readonly sequence: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Result returned by the seed runner.
|
|
40
|
+
*/
|
|
41
|
+
export interface SeedResult {
|
|
42
|
+
readonly applied: readonly SeedRecord[];
|
|
43
|
+
readonly skipped: readonly SeedRecord[];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Seed runner status.
|
|
47
|
+
*/
|
|
48
|
+
export interface SeedStatus {
|
|
49
|
+
readonly pending: readonly Seed[];
|
|
50
|
+
readonly applied: readonly SeedRecord[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Seed runner configuration (PostgreSQL only).
|
|
54
|
+
*/
|
|
55
|
+
export interface SeedRunnerOptions {
|
|
56
|
+
/**
|
|
57
|
+
* Tracking table name. Must be a plain SQL identifier.
|
|
58
|
+
*/
|
|
59
|
+
readonly tableName?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Advisory lock key used to serialise concurrent runners.
|
|
62
|
+
*/
|
|
63
|
+
readonly lockKey?: string;
|
|
64
|
+
/**
|
|
65
|
+
* SQL dialect. Only `postgresql` is implemented.
|
|
66
|
+
*/
|
|
67
|
+
readonly dialect?: SqlDialectName;
|
|
68
|
+
/**
|
|
69
|
+
* Options forwarded to every transaction the runner opens.
|
|
70
|
+
*/
|
|
71
|
+
readonly transaction?: RunnerTransactionOptions;
|
|
72
|
+
/**
|
|
73
|
+
* When `true` (default) each seed runs in its own transaction; when
|
|
74
|
+
* `false` a whole batch runs in one all-or-nothing transaction. Applied
|
|
75
|
+
* history is always re-read under the advisory lock.
|
|
76
|
+
*/
|
|
77
|
+
readonly perItemTransaction?: boolean;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Default seed tracking table.
|
|
81
|
+
*/
|
|
82
|
+
export declare const DEFAULT_SEED_TABLE = "_seeds";
|
|
83
|
+
/**
|
|
84
|
+
* Default seed advisory lock.
|
|
85
|
+
*/
|
|
86
|
+
export declare const DEFAULT_SEED_LOCK = "database:seeds";
|
|
87
|
+
/**
|
|
88
|
+
* Runs and tracks database seeds.
|
|
89
|
+
*
|
|
90
|
+
* Every entry point re-reads the applied history *inside* the advisory
|
|
91
|
+
* lock before deciding what to execute, so two runners started together
|
|
92
|
+
* never apply or revert the same seed twice.
|
|
93
|
+
*/
|
|
94
|
+
export declare class SeedRunner {
|
|
95
|
+
private readonly client;
|
|
96
|
+
private readonly seeds;
|
|
97
|
+
private readonly tableName;
|
|
98
|
+
private readonly lockKey;
|
|
99
|
+
private readonly dialect;
|
|
100
|
+
private readonly transactionOptions;
|
|
101
|
+
private readonly perItemTransaction;
|
|
102
|
+
constructor(client: DatabaseClient, seeds: readonly Seed[], options?: SeedRunnerOptions);
|
|
103
|
+
/**
|
|
104
|
+
* Returns the seed runner status.
|
|
105
|
+
*/
|
|
106
|
+
status(): Promise<SeedStatus>;
|
|
107
|
+
/**
|
|
108
|
+
* Executes every pending seed in order.
|
|
109
|
+
*/
|
|
110
|
+
run(): Promise<SeedResult>;
|
|
111
|
+
/**
|
|
112
|
+
* Executes one named seed. Returns the existing record when already
|
|
113
|
+
* applied.
|
|
114
|
+
*/
|
|
115
|
+
runOne(name: string): Promise<SeedRecord>;
|
|
116
|
+
/**
|
|
117
|
+
* Rolls back the most recently applied seed.
|
|
118
|
+
*/
|
|
119
|
+
rollback(): Promise<SeedRecord | null>;
|
|
120
|
+
/**
|
|
121
|
+
* Rolls back every applied seed in reverse execution order.
|
|
122
|
+
*/
|
|
123
|
+
rollbackAll(): Promise<readonly SeedRecord[]>;
|
|
124
|
+
/**
|
|
125
|
+
* Creates the seed tracking table if it does not exist, adding the
|
|
126
|
+
* `sequence` column to tables created by earlier versions.
|
|
127
|
+
*/
|
|
128
|
+
ensureSeedTable(): Promise<void>;
|
|
129
|
+
/**
|
|
130
|
+
* Returns all applied seeds ordered by execution sequence.
|
|
131
|
+
*/
|
|
132
|
+
getAppliedSeeds(transaction?: DatabaseTransactionContext): Promise<readonly SeedRecord[]>;
|
|
133
|
+
/**
|
|
134
|
+
* Alias of {@link getAppliedSeeds}.
|
|
135
|
+
*/
|
|
136
|
+
getHistory(): Promise<readonly SeedRecord[]>;
|
|
137
|
+
private rollbackSteps;
|
|
138
|
+
private revertRecord;
|
|
139
|
+
private computePending;
|
|
140
|
+
private buildTransactionOptions;
|
|
141
|
+
private executor;
|
|
142
|
+
private executeSeed;
|
|
143
|
+
private recordSeed;
|
|
144
|
+
private deleteSeedRecord;
|
|
145
|
+
private acquireSeedLock;
|
|
146
|
+
private seedError;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Creates a seed runner.
|
|
150
|
+
*/
|
|
151
|
+
export declare function createSeedRunner(client: DatabaseClient, seeds: readonly Seed[], options?: SeedRunnerOptions): SeedRunner;
|
|
152
|
+
/**
|
|
153
|
+
* Validates and sorts seed definitions (stable sort on `order`).
|
|
154
|
+
*/
|
|
155
|
+
export declare function normalizeSeeds(seeds: readonly Seed[]): readonly Seed[];
|
|
156
|
+
/**
|
|
157
|
+
* Validates one seed definition.
|
|
158
|
+
*/
|
|
159
|
+
export declare function validateSeed(seed: Seed): void;
|
|
160
|
+
//# sourceMappingURL=seed.runner.d.ts.map
|