@dudousxd/nestjs-durable-testing 0.4.1 → 0.5.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 +89 -1
- package/dist/index.js +85 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,94 @@ declare function assertStepsRan(store: StateStore, runId: string, names: string[
|
|
|
9
9
|
/** Assert a step ran exactly the given number of attempts (e.g. to verify retries). */
|
|
10
10
|
declare function assertStepAttempts(store: StateStore, runId: string, name: string, attempts: number): Promise<void>;
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* The canonical physical column names for the durable tables, keyed by table → entity property →
|
|
14
|
+
* column. This is the cross-adapter contract: a run written by one store adapter must be readable by
|
|
15
|
+
* another, so EVERY adapter (TypeORM, MikroORM, Prisma, Drizzle) must map these properties to these
|
|
16
|
+
* exact columns. The canonical convention is `snake_case`.
|
|
17
|
+
*
|
|
18
|
+
* Each adapter has a spec that asserts its physical columns against this map (see `assertDurableColumns`).
|
|
19
|
+
* Without it, adapters silently diverge — one defaulting to its ORM's `snake_case` naming strategy,
|
|
20
|
+
* another keeping the verbatim camelCase property name — and a store swap fails against an existing
|
|
21
|
+
* table with "Unknown column" only at runtime. The map exists so that divergence is a failing unit
|
|
22
|
+
* test, not a production incident.
|
|
23
|
+
*
|
|
24
|
+
* The camelCase ("preserve") naming is simply the property names themselves (the object keys), so no
|
|
25
|
+
* separate map is needed for it.
|
|
26
|
+
*/
|
|
27
|
+
declare const DURABLE_CANONICAL_COLUMNS: {
|
|
28
|
+
readonly durable_workflow_runs: {
|
|
29
|
+
readonly id: "id";
|
|
30
|
+
readonly workflow: "workflow";
|
|
31
|
+
readonly workflowVersion: "workflow_version";
|
|
32
|
+
readonly status: "status";
|
|
33
|
+
readonly input: "input";
|
|
34
|
+
readonly output: "output";
|
|
35
|
+
readonly error: "error";
|
|
36
|
+
readonly wakeAt: "wake_at";
|
|
37
|
+
readonly lockedBy: "locked_by";
|
|
38
|
+
readonly lockedUntil: "locked_until";
|
|
39
|
+
readonly recoveryAttempts: "recovery_attempts";
|
|
40
|
+
readonly tags: "tags";
|
|
41
|
+
readonly searchAttributes: "search_attributes";
|
|
42
|
+
readonly createdAt: "created_at";
|
|
43
|
+
readonly updatedAt: "updated_at";
|
|
44
|
+
};
|
|
45
|
+
readonly durable_step_checkpoints: {
|
|
46
|
+
readonly runId: "run_id";
|
|
47
|
+
readonly seq: "seq";
|
|
48
|
+
readonly name: "name";
|
|
49
|
+
readonly kind: "kind";
|
|
50
|
+
readonly stepId: "step_id";
|
|
51
|
+
readonly status: "status";
|
|
52
|
+
readonly input: "input";
|
|
53
|
+
readonly output: "output";
|
|
54
|
+
readonly error: "error";
|
|
55
|
+
readonly events: "events";
|
|
56
|
+
readonly attempts: "attempts";
|
|
57
|
+
readonly workerGroup: "worker_group";
|
|
58
|
+
readonly wakeAt: "wake_at";
|
|
59
|
+
readonly enqueuedAt: "enqueued_at";
|
|
60
|
+
readonly startedAt: "started_at";
|
|
61
|
+
readonly finishedAt: "finished_at";
|
|
62
|
+
};
|
|
63
|
+
readonly durable_run_attributes: {
|
|
64
|
+
readonly runId: "run_id";
|
|
65
|
+
readonly key: "key";
|
|
66
|
+
readonly strValue: "str_value";
|
|
67
|
+
readonly numValue: "num_value";
|
|
68
|
+
};
|
|
69
|
+
readonly durable_signal_waiters: {
|
|
70
|
+
readonly token: "token";
|
|
71
|
+
readonly runId: "run_id";
|
|
72
|
+
readonly seq: "seq";
|
|
73
|
+
};
|
|
74
|
+
readonly durable_buffered_signals: {
|
|
75
|
+
readonly id: "id";
|
|
76
|
+
readonly token: "token";
|
|
77
|
+
readonly payload: "payload";
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
type DurableColumnMap = typeof DURABLE_CANONICAL_COLUMNS;
|
|
81
|
+
/** A single column-name disagreement found by {@link assertDurableColumns}. */
|
|
82
|
+
interface DurableColumnMismatch {
|
|
83
|
+
table: string;
|
|
84
|
+
property: string;
|
|
85
|
+
expected: string;
|
|
86
|
+
actual: string | undefined;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Walk every (table, property) in the canonical contract and compare it to what an adapter actually
|
|
90
|
+
* maps, via the supplied `resolve(table, property) => columnName`. Returns the list of mismatches
|
|
91
|
+
* (empty when the adapter is canonical) so a spec can `expect(assertDurableColumns(resolve)).toEqual([])`.
|
|
92
|
+
*
|
|
93
|
+
* Pass `expected = DURABLE_CANONICAL_COLUMNS` (default) for the snake_case contract, or a map of the
|
|
94
|
+
* property names to themselves to assert the camelCase ("preserve") naming.
|
|
95
|
+
*/
|
|
96
|
+
declare function assertDurableColumns(resolve: (table: string, property: string) => string | undefined, expected?: Record<string, Record<string, string>>): DurableColumnMismatch[];
|
|
97
|
+
/** The "preserve" (camelCase) expectation: every property maps to a column of the same name. */
|
|
98
|
+
declare function preserveColumnExpectation(): Record<string, Record<string, string>>;
|
|
99
|
+
|
|
12
100
|
/** A clock you control, for testing durable sleeps without real time. */
|
|
13
101
|
declare class MutableClock {
|
|
14
102
|
private current;
|
|
@@ -127,4 +215,4 @@ type HandleableTransport = Transport & {
|
|
|
127
215
|
*/
|
|
128
216
|
declare function assertTransportConformance(transport: HandleableTransport, idPrefix?: string): Promise<void>;
|
|
129
217
|
|
|
130
|
-
export { type HandleableTransport, MutableClock, type RunHistory, type StateStoreContext, type StateStoreFactory, StateStoreUnavailableError, type TestEngine, assertOutput, assertReplayable, assertRunStatus, assertStepAttempts, assertStepsRan, assertTransportConformance, createTestEngine, failOnce, failTimes, recordedSteps, runStateStoreContract };
|
|
218
|
+
export { DURABLE_CANONICAL_COLUMNS, type DurableColumnMap, type DurableColumnMismatch, type HandleableTransport, MutableClock, type RunHistory, type StateStoreContext, type StateStoreFactory, StateStoreUnavailableError, type TestEngine, assertDurableColumns, assertOutput, assertReplayable, assertRunStatus, assertStepAttempts, assertStepsRan, assertTransportConformance, createTestEngine, failOnce, failTimes, preserveColumnExpectation, recordedSteps, runStateStoreContract };
|
package/dist/index.js
CHANGED
|
@@ -48,6 +48,88 @@ async function assertStepAttempts(store, runId, name, attempts) {
|
|
|
48
48
|
}
|
|
49
49
|
__name(assertStepAttempts, "assertStepAttempts");
|
|
50
50
|
|
|
51
|
+
// src/durable-columns.ts
|
|
52
|
+
var DURABLE_CANONICAL_COLUMNS = {
|
|
53
|
+
durable_workflow_runs: {
|
|
54
|
+
id: "id",
|
|
55
|
+
workflow: "workflow",
|
|
56
|
+
workflowVersion: "workflow_version",
|
|
57
|
+
status: "status",
|
|
58
|
+
input: "input",
|
|
59
|
+
output: "output",
|
|
60
|
+
error: "error",
|
|
61
|
+
wakeAt: "wake_at",
|
|
62
|
+
lockedBy: "locked_by",
|
|
63
|
+
lockedUntil: "locked_until",
|
|
64
|
+
recoveryAttempts: "recovery_attempts",
|
|
65
|
+
tags: "tags",
|
|
66
|
+
searchAttributes: "search_attributes",
|
|
67
|
+
createdAt: "created_at",
|
|
68
|
+
updatedAt: "updated_at"
|
|
69
|
+
},
|
|
70
|
+
durable_step_checkpoints: {
|
|
71
|
+
runId: "run_id",
|
|
72
|
+
seq: "seq",
|
|
73
|
+
name: "name",
|
|
74
|
+
kind: "kind",
|
|
75
|
+
stepId: "step_id",
|
|
76
|
+
status: "status",
|
|
77
|
+
input: "input",
|
|
78
|
+
output: "output",
|
|
79
|
+
error: "error",
|
|
80
|
+
events: "events",
|
|
81
|
+
attempts: "attempts",
|
|
82
|
+
workerGroup: "worker_group",
|
|
83
|
+
wakeAt: "wake_at",
|
|
84
|
+
enqueuedAt: "enqueued_at",
|
|
85
|
+
startedAt: "started_at",
|
|
86
|
+
finishedAt: "finished_at"
|
|
87
|
+
},
|
|
88
|
+
durable_run_attributes: {
|
|
89
|
+
runId: "run_id",
|
|
90
|
+
key: "key",
|
|
91
|
+
strValue: "str_value",
|
|
92
|
+
numValue: "num_value"
|
|
93
|
+
},
|
|
94
|
+
durable_signal_waiters: {
|
|
95
|
+
token: "token",
|
|
96
|
+
runId: "run_id",
|
|
97
|
+
seq: "seq"
|
|
98
|
+
},
|
|
99
|
+
durable_buffered_signals: {
|
|
100
|
+
id: "id",
|
|
101
|
+
token: "token",
|
|
102
|
+
payload: "payload"
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
function assertDurableColumns(resolve, expected = DURABLE_CANONICAL_COLUMNS) {
|
|
106
|
+
const mismatches = [];
|
|
107
|
+
for (const [table, props] of Object.entries(expected)) {
|
|
108
|
+
for (const [property, column] of Object.entries(props)) {
|
|
109
|
+
const actual = resolve(table, property);
|
|
110
|
+
if (actual !== column) mismatches.push({
|
|
111
|
+
table,
|
|
112
|
+
property,
|
|
113
|
+
expected: column,
|
|
114
|
+
actual
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return mismatches;
|
|
119
|
+
}
|
|
120
|
+
__name(assertDurableColumns, "assertDurableColumns");
|
|
121
|
+
function preserveColumnExpectation() {
|
|
122
|
+
const out = {};
|
|
123
|
+
for (const [table, props] of Object.entries(DURABLE_CANONICAL_COLUMNS)) {
|
|
124
|
+
out[table] = Object.fromEntries(Object.keys(props).map((p) => [
|
|
125
|
+
p,
|
|
126
|
+
p
|
|
127
|
+
]));
|
|
128
|
+
}
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
131
|
+
__name(preserveColumnExpectation, "preserveColumnExpectation");
|
|
132
|
+
|
|
51
133
|
// src/harness.ts
|
|
52
134
|
import { InMemoryStateStore, InMemoryTransport, WorkflowEngine } from "@dudousxd/nestjs-durable-core";
|
|
53
135
|
var MutableClock = class {
|
|
@@ -5418,8 +5500,10 @@ async function assertTransportConformance(transport, idPrefix = "conf") {
|
|
|
5418
5500
|
}
|
|
5419
5501
|
__name(assertTransportConformance, "assertTransportConformance");
|
|
5420
5502
|
export {
|
|
5503
|
+
DURABLE_CANONICAL_COLUMNS,
|
|
5421
5504
|
MutableClock,
|
|
5422
5505
|
StateStoreUnavailableError,
|
|
5506
|
+
assertDurableColumns,
|
|
5423
5507
|
assertOutput,
|
|
5424
5508
|
assertReplayable,
|
|
5425
5509
|
assertRunStatus,
|
|
@@ -5429,6 +5513,7 @@ export {
|
|
|
5429
5513
|
createTestEngine,
|
|
5430
5514
|
failOnce,
|
|
5431
5515
|
failTimes,
|
|
5516
|
+
preserveColumnExpectation,
|
|
5432
5517
|
recordedSteps,
|
|
5433
5518
|
runStateStoreContract
|
|
5434
5519
|
};
|