@fabrika/db 0.9.0-cloudflare.1 → 0.9.0-cloudflare.2
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/package.json +4 -4
- package/src/testing-shared.ts +47 -5
- package/types/src/testing-shared.d.ts +10 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fabrika/db",
|
|
3
|
-
"version": "0.9.0-cloudflare.
|
|
3
|
+
"version": "0.9.0-cloudflare.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -92,9 +92,9 @@
|
|
|
92
92
|
"test": "bun test"
|
|
93
93
|
},
|
|
94
94
|
"dependencies": {
|
|
95
|
-
"@fabrika/auth-core": "0.9.0-cloudflare.
|
|
96
|
-
"@fabrika/platform": "0.9.0-cloudflare.
|
|
97
|
-
"@fabrika/platform-node": "0.9.0-cloudflare.
|
|
95
|
+
"@fabrika/auth-core": "0.9.0-cloudflare.2",
|
|
96
|
+
"@fabrika/platform": "0.9.0-cloudflare.2",
|
|
97
|
+
"@fabrika/platform-node": "0.9.0-cloudflare.2",
|
|
98
98
|
"kysely": "0.29.6",
|
|
99
99
|
"kysely-postgres-js": "5.0.1",
|
|
100
100
|
"zod": "^3.25.76"
|
package/src/testing-shared.ts
CHANGED
|
@@ -83,6 +83,11 @@ export interface IsolationWorlds {
|
|
|
83
83
|
readonly dimension: string
|
|
84
84
|
readonly own: WorldRow
|
|
85
85
|
readonly other: WorldRow
|
|
86
|
+
/**
|
|
87
|
+
* Deletes both rows of the table and every row that refers to them, however deep; the containers stay. A case whose
|
|
88
|
+
* rows hold pinned values removes them, so the next case can pin the same values again under a unique index.
|
|
89
|
+
*/
|
|
90
|
+
readonly remove: () => Promise<void>
|
|
86
91
|
}
|
|
87
92
|
|
|
88
93
|
/** What a test kit seeds through, over its migrated schema. */
|
|
@@ -90,9 +95,17 @@ export interface TestSeeding {
|
|
|
90
95
|
/**
|
|
91
96
|
* Seeds one row of `table` in each of two fresh chains, with every container row a table owns. `values` (column →
|
|
92
97
|
* value) are written into both rows of `table`: the state an endpoint's precondition needs. A text column keeps its
|
|
93
|
-
* marker, so a seed of one, or of a column that places the row, throws.
|
|
98
|
+
* marker, so a seed of one, or of a column that places the row, throws. `pins` (column → value) give a text column of
|
|
99
|
+
* `table` a known value instead of its marker: the value in the own row, and `<value>-other` in the other row, which
|
|
100
|
+
* counts among the other row's markers, so a leak of it is still found. A pin of a column that places the row, or of
|
|
101
|
+
* no text column, throws.
|
|
94
102
|
*/
|
|
95
|
-
seedWorlds<DB, P>(
|
|
103
|
+
seedWorlds<DB, P>(
|
|
104
|
+
tables: Tables<DB, P>,
|
|
105
|
+
table: string,
|
|
106
|
+
values?: Readonly<Record<string, SampleValue>>,
|
|
107
|
+
pins?: Readonly<Record<string, string>>,
|
|
108
|
+
): Promise<IsolationWorlds>
|
|
96
109
|
/**
|
|
97
110
|
* Seeds one row of the application table `table`: its key, version and creator stamped, `values` (column → value)
|
|
98
111
|
* as given, a text column too, every other column sampled. A value for a stamped column or a file column throws.
|
|
@@ -525,7 +538,17 @@ export function testSeeding(backend: SeedingBackend): TestSeeding {
|
|
|
525
538
|
return { key, ...seeded }
|
|
526
539
|
}
|
|
527
540
|
|
|
528
|
-
|
|
541
|
+
/** The value a pin gives the row of `world`: as written in the own row, distinct in the other. */
|
|
542
|
+
const pinnedValue = (value: string, world: string): string => (world === 'own' ? value : `${value}-${world}`)
|
|
543
|
+
|
|
544
|
+
async function seedWorld(
|
|
545
|
+
models: TableModels,
|
|
546
|
+
model: TableModel,
|
|
547
|
+
world: string,
|
|
548
|
+
seed: Readonly<Record<string, SampleValue>>,
|
|
549
|
+
pins: Readonly<Record<string, string>>,
|
|
550
|
+
inserted: InsertedRow[],
|
|
551
|
+
): Promise<WorldRow> {
|
|
529
552
|
const markers: string[] = []
|
|
530
553
|
const values = new Map<string, string>()
|
|
531
554
|
const links: readonly Container[] = model.chain
|
|
@@ -562,7 +585,20 @@ export function testSeeding(backend: SeedingBackend): TestSeeding {
|
|
|
562
585
|
}
|
|
563
586
|
assigned.set(name, value)
|
|
564
587
|
}
|
|
588
|
+
for (const [name, value] of Object.entries(pins)) {
|
|
589
|
+
const column = columnOf(model.name, name)
|
|
590
|
+
if (assigned.has(name)) {
|
|
591
|
+
throw new Error(`${model.name}.${name} places the row in its scope or is seeded; a pin gives a text column of the row's own state a known value`)
|
|
592
|
+
}
|
|
593
|
+
if (!(await holdsMarker(model, model.name, column))) {
|
|
594
|
+
throw new Error(`${model.name}.${name} holds no text marker; a pin gives a text column a known value, a seed every other column`)
|
|
595
|
+
}
|
|
596
|
+
const pinned = pinnedValue(value, world)
|
|
597
|
+
assigned.set(name, pinned)
|
|
598
|
+
markers.push(pinned)
|
|
599
|
+
}
|
|
565
600
|
const { row } = await insert(models, model.name, assigned, markers)
|
|
601
|
+
inserted.push({ table: model.name, match: new Map([[scope.key, key]]) })
|
|
566
602
|
const updates: Record<string, SampleValue> = {}
|
|
567
603
|
for (const name of namesOf(model.update)) {
|
|
568
604
|
updates[name] = row.get(name) ?? await updateSample(model.name, name)
|
|
@@ -586,10 +622,16 @@ export function testSeeding(backend: SeedingBackend): TestSeeding {
|
|
|
586
622
|
}
|
|
587
623
|
|
|
588
624
|
return {
|
|
589
|
-
async seedWorlds(tables, table, values = {}) {
|
|
625
|
+
async seedWorlds(tables, table, values = {}, pins = {}) {
|
|
590
626
|
const { models, model } = scopedModel(tables, table)
|
|
591
627
|
const dimension = grantDimension(models, model)
|
|
592
|
-
|
|
628
|
+
const inserted: InsertedRow[] = []
|
|
629
|
+
return {
|
|
630
|
+
dimension,
|
|
631
|
+
own: await seedWorld(models, model, 'own', values, pins, inserted),
|
|
632
|
+
other: await seedWorld(models, model, 'other', values, pins, inserted),
|
|
633
|
+
remove: () => backend.remove(inserted),
|
|
634
|
+
}
|
|
593
635
|
},
|
|
594
636
|
async seedRow(tables, table, values = {}) {
|
|
595
637
|
const { models, model } = scopedModel(tables, table)
|
|
@@ -69,15 +69,23 @@ export interface IsolationWorlds {
|
|
|
69
69
|
readonly dimension: string;
|
|
70
70
|
readonly own: WorldRow;
|
|
71
71
|
readonly other: WorldRow;
|
|
72
|
+
/**
|
|
73
|
+
* Deletes both rows of the table and every row that refers to them, however deep; the containers stay. A case whose
|
|
74
|
+
* rows hold pinned values removes them, so the next case can pin the same values again under a unique index.
|
|
75
|
+
*/
|
|
76
|
+
readonly remove: () => Promise<void>;
|
|
72
77
|
}
|
|
73
78
|
/** What a test kit seeds through, over its migrated schema. */
|
|
74
79
|
export interface TestSeeding {
|
|
75
80
|
/**
|
|
76
81
|
* Seeds one row of `table` in each of two fresh chains, with every container row a table owns. `values` (column →
|
|
77
82
|
* value) are written into both rows of `table`: the state an endpoint's precondition needs. A text column keeps its
|
|
78
|
-
* marker, so a seed of one, or of a column that places the row, throws.
|
|
83
|
+
* marker, so a seed of one, or of a column that places the row, throws. `pins` (column → value) give a text column of
|
|
84
|
+
* `table` a known value instead of its marker: the value in the own row, and `<value>-other` in the other row, which
|
|
85
|
+
* counts among the other row's markers, so a leak of it is still found. A pin of a column that places the row, or of
|
|
86
|
+
* no text column, throws.
|
|
79
87
|
*/
|
|
80
|
-
seedWorlds<DB, P>(tables: Tables<DB, P>, table: string, values?: Readonly<Record<string, SampleValue>>): Promise<IsolationWorlds>;
|
|
88
|
+
seedWorlds<DB, P>(tables: Tables<DB, P>, table: string, values?: Readonly<Record<string, SampleValue>>, pins?: Readonly<Record<string, string>>): Promise<IsolationWorlds>;
|
|
81
89
|
/**
|
|
82
90
|
* Seeds one row of the application table `table`: its key, version and creator stamped, `values` (column → value)
|
|
83
91
|
* as given, a text column too, every other column sampled. A value for a stamped column or a file column throws.
|