@substrat-run/kernel 0.128.0 → 0.130.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 +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/invocation-log.d.ts +27 -0
- package/dist/invocation-log.d.ts.map +1 -1
- package/dist/invocation-log.js +1 -0
- package/dist/invocation-log.js.map +1 -1
- package/dist/lifecycle-flow.d.ts.map +1 -1
- package/dist/lifecycle-flow.js +17 -0
- package/dist/lifecycle-flow.js.map +1 -1
- package/dist/refusals.d.ts +38 -0
- package/dist/refusals.d.ts.map +1 -0
- package/dist/refusals.js +73 -0
- package/dist/refusals.js.map +1 -0
- package/dist/spine-guard.d.ts +12 -6
- package/dist/spine-guard.d.ts.map +1 -1
- package/dist/spine-guard.js +32 -129
- package/dist/spine-guard.js.map +1 -1
- package/dist/spine-restore.d.ts +70 -11
- package/dist/spine-restore.d.ts.map +1 -1
- package/dist/spine-restore.js +100 -16
- package/dist/spine-restore.js.map +1 -1
- package/dist/system-switch-record.d.ts +8 -0
- package/dist/system-switch-record.d.ts.map +1 -1
- package/dist/system-switch-record.js +11 -1
- package/dist/system-switch-record.js.map +1 -1
- package/package.json +2 -2
package/dist/spine-guard.js
CHANGED
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
* What is refused: a statement whose write TARGET is a `_substrat_*` table —
|
|
19
19
|
* `INSERT`/`REPLACE INTO`, `UPDATE`, `DELETE FROM`, `DROP`, `ALTER`, `CREATE` — and
|
|
20
20
|
* the second table a statement can reach past the one it names first: `CREATE
|
|
21
|
-
* TRIGGER … ON`, `CREATE INDEX … ON`, `ALTER TABLE … RENAME TO
|
|
21
|
+
* TRIGGER … ON`, `CREATE INDEX … ON`, `ALTER TABLE … RENAME TO`, and a `REFERENCES` clause
|
|
22
|
+
* naming the spine (`assertNoSpineReference`, #1898).
|
|
22
23
|
* What is allowed, deliberately: every read of the spine, including one that feeds
|
|
23
24
|
* a write — `INSERT INTO my_timeline SELECT … FROM _substrat_events` is the
|
|
24
25
|
* projection pattern CLAUDE.md explicitly blesses, and only the target is judged.
|
|
@@ -27,20 +28,13 @@
|
|
|
27
28
|
* runtime refuses them outright, and widening this guard to cover them would make
|
|
28
29
|
* it a second read-only console rather than a rule about forging.
|
|
29
30
|
*
|
|
30
|
-
* The scan
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* (`main._substrat_tuples`) merge into one token, and every part is checked.
|
|
31
|
+
* The scan is `tokenizeSql` from `@substrat-run/contracts`, the one reading of the grammar
|
|
32
|
+
* the dump checks share: comments and string literals skipped, quoted identifiers kept as
|
|
33
|
+
* tokens, dotted names merged into one, and every part of one checked.
|
|
34
34
|
* Multiple statements in one string are walked in full: the DO's `sql.exec` accepts
|
|
35
35
|
* them, so a forge chained after a legitimate write must not slip past.
|
|
36
36
|
*/
|
|
37
|
-
import { substratError } from '@substrat-run/contracts';
|
|
38
|
-
/**
|
|
39
|
-
* The platform spine's table prefix — the same one `isSystemTable` groups on, and the one a
|
|
40
|
-
* restore builds from the kernel's DDL (`isSpineTable`, #1883). Compared lowercased: SQLite
|
|
41
|
-
* matches table names without regard to case, so `_SUBSTRAT_TUPLES` is the tuples table.
|
|
42
|
-
*/
|
|
43
|
-
export const SPINE_PREFIX = '_substrat';
|
|
37
|
+
import { namesSpineTable, referencedTablesIn, substratError, tokenizeSql } from '@substrat-run/contracts';
|
|
44
38
|
/**
|
|
45
39
|
* Tokens that may stand between a write verb and the table it names. The first
|
|
46
40
|
* following token that is NOT one of these (or that is quoted) is the target.
|
|
@@ -66,120 +60,6 @@ const MODIFIERS = {
|
|
|
66
60
|
'exists',
|
|
67
61
|
]),
|
|
68
62
|
};
|
|
69
|
-
function tokenize(sql) {
|
|
70
|
-
const tokens = [];
|
|
71
|
-
const n = sql.length;
|
|
72
|
-
let i = 0;
|
|
73
|
-
// Set when the previous token ended on a `.`, so `main . tbl` folds into one name.
|
|
74
|
-
let continues = false;
|
|
75
|
-
const push = (text, quoted) => {
|
|
76
|
-
const prev = tokens[tokens.length - 1];
|
|
77
|
-
if (continues && prev) {
|
|
78
|
-
tokens[tokens.length - 1] = { text: `${prev.text}.${text}`, quoted: prev.quoted || quoted };
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
tokens.push({ text, quoted });
|
|
82
|
-
}
|
|
83
|
-
// Look ahead for the dot that joins this name to the next part. SQLite treats a
|
|
84
|
-
// COMMENT as whitespace, so `main /* … */ . _substrat_tuples` is one qualified
|
|
85
|
-
// name — skipping only spaces here would record `main` as the target and miss it.
|
|
86
|
-
let j = i;
|
|
87
|
-
for (;;) {
|
|
88
|
-
if (j < n && /\s/.test(sql[j])) {
|
|
89
|
-
j += 1;
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
if (sql[j] === '-' && sql[j + 1] === '-') {
|
|
93
|
-
while (j < n && sql[j] !== '\n')
|
|
94
|
-
j += 1;
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
if (sql[j] === '/' && sql[j + 1] === '*') {
|
|
98
|
-
j += 2;
|
|
99
|
-
while (j < n && !(sql[j] === '*' && sql[j + 1] === '/'))
|
|
100
|
-
j += 1;
|
|
101
|
-
j += 2;
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
if (sql[j] === '.') {
|
|
107
|
-
continues = true;
|
|
108
|
-
i = j + 1;
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
continues = false;
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
while (i < n) {
|
|
115
|
-
const c = sql[i];
|
|
116
|
-
const c2 = sql[i + 1];
|
|
117
|
-
if (c === '-' && c2 === '-') {
|
|
118
|
-
while (i < n && sql[i] !== '\n')
|
|
119
|
-
i += 1;
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
if (c === '/' && c2 === '*') {
|
|
123
|
-
i += 2;
|
|
124
|
-
while (i < n && !(sql[i] === '*' && sql[i + 1] === '/'))
|
|
125
|
-
i += 1;
|
|
126
|
-
i += 2;
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
if (c === "'" || c === '"' || c === '`') {
|
|
130
|
-
// A quoted identifier, or a string literal SQLite would still accept as one
|
|
131
|
-
// in a table position. The closing quote doubles to escape itself.
|
|
132
|
-
i += 1;
|
|
133
|
-
let text = '';
|
|
134
|
-
while (i < n) {
|
|
135
|
-
if (sql[i] === c) {
|
|
136
|
-
if (sql[i + 1] === c) {
|
|
137
|
-
text += c;
|
|
138
|
-
i += 2;
|
|
139
|
-
continue;
|
|
140
|
-
}
|
|
141
|
-
i += 1;
|
|
142
|
-
break;
|
|
143
|
-
}
|
|
144
|
-
text += sql[i];
|
|
145
|
-
i += 1;
|
|
146
|
-
}
|
|
147
|
-
push(text, true);
|
|
148
|
-
continue;
|
|
149
|
-
}
|
|
150
|
-
if (c === '[') {
|
|
151
|
-
i += 1;
|
|
152
|
-
let text = '';
|
|
153
|
-
while (i < n && sql[i] !== ']') {
|
|
154
|
-
text += sql[i];
|
|
155
|
-
i += 1;
|
|
156
|
-
}
|
|
157
|
-
i += 1;
|
|
158
|
-
push(text, true);
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
if (/[A-Za-z_]/.test(c)) {
|
|
162
|
-
let j = i;
|
|
163
|
-
while (j < n && /[A-Za-z0-9_$]/.test(sql[j]))
|
|
164
|
-
j += 1;
|
|
165
|
-
const text = sql.slice(i, j);
|
|
166
|
-
i = j;
|
|
167
|
-
push(text, false);
|
|
168
|
-
continue;
|
|
169
|
-
}
|
|
170
|
-
// Whitespace does not break a dotted name (`main . tbl` is one); anything else does.
|
|
171
|
-
if (!/\s/.test(c))
|
|
172
|
-
continues = false;
|
|
173
|
-
i += 1;
|
|
174
|
-
}
|
|
175
|
-
return tokens;
|
|
176
|
-
}
|
|
177
|
-
/** True when any part of a (possibly dotted, possibly quoted) name is spine. */
|
|
178
|
-
function namesSpine(token) {
|
|
179
|
-
return token.text
|
|
180
|
-
.split('.')
|
|
181
|
-
.some((part) => part.toLowerCase().startsWith(SPINE_PREFIX));
|
|
182
|
-
}
|
|
183
63
|
/**
|
|
184
64
|
* A SECOND table a statement can reach, past the one it names first.
|
|
185
65
|
*
|
|
@@ -194,7 +74,7 @@ const SECOND_TARGET = { create: 'on', alter: 'to' };
|
|
|
194
74
|
/** The first token at or after `from` that names the spine, following this verb's grammar. */
|
|
195
75
|
function spineTargetFrom(tokens, from, verb) {
|
|
196
76
|
const first = tokens[from];
|
|
197
|
-
if (first &&
|
|
77
|
+
if (first && namesSpineTable(first.text))
|
|
198
78
|
return first;
|
|
199
79
|
const keyword = SECOND_TARGET[verb];
|
|
200
80
|
if (!keyword)
|
|
@@ -203,7 +83,7 @@ function spineTargetFrom(tokens, from, verb) {
|
|
|
203
83
|
if (tokens[k].quoted || tokens[k].text.toLowerCase() !== keyword)
|
|
204
84
|
continue;
|
|
205
85
|
const after = tokens[k + 1];
|
|
206
|
-
return after &&
|
|
86
|
+
return after && namesSpineTable(after.text) ? after : undefined;
|
|
207
87
|
}
|
|
208
88
|
return undefined;
|
|
209
89
|
}
|
|
@@ -215,7 +95,7 @@ function spineTargetFrom(tokens, from, verb) {
|
|
|
215
95
|
* the table so the author sees which line to delete.
|
|
216
96
|
*/
|
|
217
97
|
export function assertNoSpineWrite(sql) {
|
|
218
|
-
const tokens =
|
|
98
|
+
const tokens = tokenizeSql(sql);
|
|
219
99
|
for (let i = 0; i < tokens.length; i += 1) {
|
|
220
100
|
const token = tokens[i];
|
|
221
101
|
if (token.quoted)
|
|
@@ -234,6 +114,29 @@ export function assertNoSpineWrite(sql) {
|
|
|
234
114
|
throw substratError('forbidden', `ctx.sql cannot write the platform spine: ${verb.toUpperCase()} on '${target.text}'. ` +
|
|
235
115
|
'Reads are fine; writes go through ctx.emit / ctx.link / ctx.grant.', { reason: 'spine_write' });
|
|
236
116
|
}
|
|
117
|
+
refuseSpineReference(referencedTablesIn(tokens), 'ctx.sql');
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Refuse a statement whose `REFERENCES` clause names a `_substrat_*` table (#1898), for the
|
|
121
|
+
* same reason `CREATE TRIGGER … ON` is refused above: the spine's rows become the parent of a
|
|
122
|
+
* module's, and with foreign keys enforced the kernel's own writes to that table (a revoke, a
|
|
123
|
+
* restore's re-point, an outbox prune) then fail on the module's rows. That denies the spine
|
|
124
|
+
* rather than forging it. `what` names the SQL's source in the message.
|
|
125
|
+
*
|
|
126
|
+
* `ctx.sql` passes through here (`assertNoSpineWrite`), and so does every migration a scope
|
|
127
|
+
* applies, which reaches the database on the kernel's own handle rather than through
|
|
128
|
+
* `ctx.sql`. A dump's replayed DDL is held to the same rule by `assertReplayableDump`.
|
|
129
|
+
*/
|
|
130
|
+
export function assertNoSpineReference(sql, what) {
|
|
131
|
+
refuseSpineReference(referencedTablesIn(tokenizeSql(sql)), what);
|
|
132
|
+
}
|
|
133
|
+
/** The refusal itself, over a statement's `REFERENCES` targets. */
|
|
134
|
+
function refuseSpineReference(referenced, what) {
|
|
135
|
+
const target = referenced.find(namesSpineTable);
|
|
136
|
+
if (target === undefined)
|
|
137
|
+
return;
|
|
138
|
+
throw substratError('forbidden', `${what} cannot declare a foreign key to the platform spine: REFERENCES '${target}'. ` +
|
|
139
|
+
'A module table may reference its own tables; spine rows are reached through the kernel, never as a parent.', { reason: 'spine_write' });
|
|
237
140
|
}
|
|
238
141
|
/**
|
|
239
142
|
* Wrap a module-facing `ScopedSql` so every statement passes `assertNoSpineWrite`
|
package/dist/spine-guard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spine-guard.js","sourceRoot":"","sources":["../src/spine-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"spine-guard.js","sourceRoot":"","sources":["../src/spine-guard.ts"],"names":[],"mappings":"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"}
|
package/dist/spine-restore.d.ts
CHANGED
|
@@ -23,7 +23,10 @@
|
|
|
23
23
|
* - a spine table the kernel does not build is refused (`assertSpineTablesBuilt`), every such
|
|
24
24
|
* table named at once.
|
|
25
25
|
*
|
|
26
|
-
*
|
|
26
|
+
* In a scope, tables outside the spine keep the dump's own DDL: a vertical's schema is the
|
|
27
|
+
* dump's to say. A directory has no vertical tables, so there every table is built by the
|
|
28
|
+
* host and loaded by these same rules, and a table it does not build is refused
|
|
29
|
+
* (`assertDirectoryTablesBuilt`, #1912).
|
|
27
30
|
*/
|
|
28
31
|
/**
|
|
29
32
|
* A kernel-owned table, which a restore builds from the kernel's DDL rather than the dump's.
|
|
@@ -41,14 +44,28 @@ export declare function isSpineTable(name: string): boolean;
|
|
|
41
44
|
* tables (`_substrat_roles`, `_substrat_tenant_tuples`, …) that a node scope keeps in its
|
|
42
45
|
* directory instead. Loading one anyway would mean dropping its rows, which a restore does not
|
|
43
46
|
* do silently.
|
|
47
|
+
*
|
|
48
|
+
* Every `_substrat*` name is judged, the search index's namespace included (`namesSpineTable`,
|
|
49
|
+
* not `isSpineTable`): a scope restore has skipped its index tables before this, since it
|
|
50
|
+
* rebuilds them. A directory restore judges every table instead (`assertDirectoryTablesBuilt`).
|
|
44
51
|
*/
|
|
45
52
|
export declare function assertSpineTablesBuilt(names: readonly string[], columnsOf: KernelColumnsOf): void;
|
|
46
53
|
/** A table's columns as the kernel built it here, or `undefined` when it built no such table. */
|
|
47
54
|
export type KernelColumnsOf = (name: string) => readonly string[] | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Refuse a directory dump carrying any table the directory does not build, spine or not, naming
|
|
57
|
+
* every one of them (#1912). A directory holds only the platform's own tables, so there is no
|
|
58
|
+
* vertical table whose DDL the dump could have a say in: an extra table would keep the dump's
|
|
59
|
+
* DDL, and with it whatever that declares, such as a `REFERENCES tenants` that fails the
|
|
60
|
+
* delete of a referenced row. `loadDirectoryDump` calls it first, where `assertSpineTablesBuilt`
|
|
61
|
+
* is in a scope restore, with the same `columnsOf`.
|
|
62
|
+
*/
|
|
63
|
+
export declare function assertDirectoryTablesBuilt(names: readonly string[], columnsOf: KernelColumnsOf): void;
|
|
48
64
|
/**
|
|
49
65
|
* The `INSERT` that loads one dumped table's rows, one row of positional parameters per
|
|
50
66
|
* execution, in the dump's column order: `spineRowsInsert` for a spine table, and the dump's
|
|
51
|
-
* own columns for a vertical one.
|
|
67
|
+
* own columns for a vertical one. A directory builds every table, so it calls
|
|
68
|
+
* `spineRowsInsert` directly. The names are quoted as given: the loader has already passed
|
|
52
69
|
* the dump through `assertReplayableDump`.
|
|
53
70
|
*/
|
|
54
71
|
export declare function dumpRowsInsert(table: {
|
|
@@ -56,22 +73,24 @@ export declare function dumpRowsInsert(table: {
|
|
|
56
73
|
columns: readonly string[];
|
|
57
74
|
}, columnsOf: KernelColumnsOf): string;
|
|
58
75
|
/**
|
|
59
|
-
* The statements that add to a
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
76
|
+
* The statements that add to a table the host built (a spine table, or any directory table,
|
|
77
|
+
* #1912) each column the dump carries and the host's table does not, as a plain untyped column:
|
|
78
|
+
* `ADD COLUMN "<name>"`, lowercased, and nothing after it, so it has no type, collation,
|
|
79
|
+
* constraint or default. Run after `assertSpineTablesBuilt` / `assertDirectoryTablesBuilt` and
|
|
80
|
+
* before the table's rows go in, inside the load's transaction. The names are the dump's, which
|
|
81
|
+
* `assertReplayableDump` has already held to the identifier rule. Empty for a table the host
|
|
82
|
+
* did not build, which those have refused.
|
|
65
83
|
*/
|
|
66
84
|
export declare function spineColumnAdditions(table: {
|
|
67
85
|
name: string;
|
|
68
86
|
columns: readonly string[];
|
|
69
87
|
}, kernelColumns: readonly string[] | undefined): string[];
|
|
70
88
|
/**
|
|
71
|
-
* The `INSERT` that loads one dumped
|
|
89
|
+
* The `INSERT` that loads one dumped table's rows into the table the host built: a spine table,
|
|
90
|
+
* or any directory table (#1912).
|
|
72
91
|
*
|
|
73
|
-
* `kernelColumns` is the
|
|
74
|
-
* `spineColumnAdditions`, or `undefined` when the
|
|
92
|
+
* `kernelColumns` is the built table's column list as the loader reads it back after
|
|
93
|
+
* `spineColumnAdditions`, or `undefined` when the host built no such table. Either refusal
|
|
75
94
|
* below is a backstop the loader's order makes unreachable, and throws `validation_failed`
|
|
76
95
|
* inside the load's transaction, so the target keeps what it held.
|
|
77
96
|
*/
|
|
@@ -79,4 +98,44 @@ export declare function spineRowsInsert(table: {
|
|
|
79
98
|
name: string;
|
|
80
99
|
columns: readonly string[];
|
|
81
100
|
}, kernelColumns: readonly string[] | undefined): string;
|
|
101
|
+
/**
|
|
102
|
+
* The naming columns a scope row from before the directory left NULL, filled with the defaults
|
|
103
|
+
* `resolveScopeRecord` applies: a ULID lowercases into a valid slug, so the placeholder is unique
|
|
104
|
+
* by construction. Run by both adapters' schema pass on every start, and by a directory restore
|
|
105
|
+
* after its rows are in, inside its transaction (#1912). One statement per entry, since a
|
|
106
|
+
* Durable Object's `exec` and better-sqlite3's `prepare` each take one.
|
|
107
|
+
*/
|
|
108
|
+
export declare const LEGACY_SCOPE_ROWS_BACKFILL: readonly string[];
|
|
109
|
+
/**
|
|
110
|
+
* Load a directory dump's rows into the tables the host has just built from its own schema
|
|
111
|
+
* (#1912): the one sequence both adapters' directory restores run, inside their transaction,
|
|
112
|
+
* after dropping the old directory and running the schema pass.
|
|
113
|
+
*
|
|
114
|
+
* 1. refuse a table the directory does not build (`assertDirectoryTablesBuilt`), and one that
|
|
115
|
+
* would pass `maxColumns` once the dump's unknown columns join this code's own;
|
|
116
|
+
* 2. add each column the dump carries and this code does not know, bare and lowercased, and
|
|
117
|
+
* refuse one named for the rowid (`spineColumnAdditions`);
|
|
118
|
+
* 3. insert every row by column name, against the columns read back after step 2
|
|
119
|
+
* (`spineRowsInsert`);
|
|
120
|
+
* 4. fill a pre-directory scope row's naming columns (`LEGACY_SCOPE_ROWS_BACKFILL`);
|
|
121
|
+
* 5. backfill the schedule switch's record from the dump's own admin log, when the dump
|
|
122
|
+
* predates it (#1674). One that carried it keeps its rows and is never backfilled over.
|
|
123
|
+
*
|
|
124
|
+
* A throw anywhere is the caller's transaction rolling back, so the directory keeps what it held.
|
|
125
|
+
*/
|
|
126
|
+
export declare function loadDirectoryDump(tables: readonly {
|
|
127
|
+
name: string;
|
|
128
|
+
columns: readonly string[];
|
|
129
|
+
rows: readonly (readonly unknown[])[];
|
|
130
|
+
}[], host: {
|
|
131
|
+
columnsOf: KernelColumnsOf;
|
|
132
|
+
exec: (sql: string) => void;
|
|
133
|
+
insert: (sql: string, rows: readonly (readonly unknown[])[]) => void;
|
|
134
|
+
/**
|
|
135
|
+
* The most columns a table here may hold: a Durable Object's cap. `assertReplayableDump`
|
|
136
|
+
* holds the dump's own column list to it, but a table grows by this code's columns plus the
|
|
137
|
+
* dump's unknown ones, which can pass it while each list alone does not.
|
|
138
|
+
*/
|
|
139
|
+
maxColumns?: number;
|
|
140
|
+
}): void;
|
|
82
141
|
//# sourceMappingURL=spine-restore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spine-restore.d.ts","sourceRoot":"","sources":["../src/spine-restore.ts"],"names":[],"mappings":"AAKA
|
|
1
|
+
{"version":3,"file":"spine-restore.d.ts","sourceRoot":"","sources":["../src/spine-restore.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIlD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,eAAe,GAAG,IAAI,CAGjG;AAED,iGAAiG;AACjG,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;AAE9E;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,eAAe,GAAG,IAAI,CAUrG;AAmBD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,EAAE,SAAS,EAAE,eAAe,GAAG,MAAM,CAEtH;AASD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,EACnD,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAC3C,MAAM,EAAE,CAmBV;AAKD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,EACnD,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAC3C,MAAM,CAyBR;AAED;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EAIvD,CAAC;AAsBF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,CAAA;CAAE,EAAE,EACtG,IAAI,EAAE;IACJ,SAAS,EAAE,eAAe,CAAC;IAC3B,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,SAAS,OAAO,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IACrE;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GACA,IAAI,CASN"}
|
package/dist/spine-restore.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { substratError } from '@substrat-run/contracts';
|
|
1
|
+
import { SPINE_PREFIX, namesSpineTable, substratError } from '@substrat-run/contracts';
|
|
2
2
|
import { SCHEDULE_STATE_KIND_OF_OP } from './platform-sweep.js';
|
|
3
3
|
import { isSearchIndexTable } from './search-index.js';
|
|
4
|
-
import {
|
|
4
|
+
import { SYSTEM_SWITCHES_BACKFILL_SQL, dumpCarriesSystemSwitches } from './system-switch-record.js';
|
|
5
5
|
/**
|
|
6
6
|
* How a restore, fork or carry loads a dump's `_substrat_*` spine tables (#1883). One
|
|
7
7
|
* definition for both adapters' loaders, so the DO and the pure host build the same tables
|
|
@@ -27,7 +27,10 @@ import { SPINE_PREFIX } from './spine-guard.js';
|
|
|
27
27
|
* - a spine table the kernel does not build is refused (`assertSpineTablesBuilt`), every such
|
|
28
28
|
* table named at once.
|
|
29
29
|
*
|
|
30
|
-
*
|
|
30
|
+
* In a scope, tables outside the spine keep the dump's own DDL: a vertical's schema is the
|
|
31
|
+
* dump's to say. A directory has no vertical tables, so there every table is built by the
|
|
32
|
+
* host and loaded by these same rules, and a table it does not build is refused
|
|
33
|
+
* (`assertDirectoryTablesBuilt`, #1912).
|
|
31
34
|
*/
|
|
32
35
|
/**
|
|
33
36
|
* A kernel-owned table, which a restore builds from the kernel's DDL rather than the dump's.
|
|
@@ -49,12 +52,32 @@ export function isSpineTable(name) {
|
|
|
49
52
|
* tables (`_substrat_roles`, `_substrat_tenant_tuples`, …) that a node scope keeps in its
|
|
50
53
|
* directory instead. Loading one anyway would mean dropping its rows, which a restore does not
|
|
51
54
|
* do silently.
|
|
55
|
+
*
|
|
56
|
+
* Every `_substrat*` name is judged, the search index's namespace included (`namesSpineTable`,
|
|
57
|
+
* not `isSpineTable`): a scope restore has skipped its index tables before this, since it
|
|
58
|
+
* rebuilds them. A directory restore judges every table instead (`assertDirectoryTablesBuilt`).
|
|
52
59
|
*/
|
|
53
60
|
export function assertSpineTablesBuilt(names, columnsOf) {
|
|
54
|
-
const missing = names.filter((n) =>
|
|
61
|
+
const missing = names.filter((n) => namesSpineTable(n) && columnsOf(n) === undefined);
|
|
55
62
|
if (missing.length > 0)
|
|
56
63
|
throw unbuiltSpineTables(missing);
|
|
57
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Refuse a directory dump carrying any table the directory does not build, spine or not, naming
|
|
67
|
+
* every one of them (#1912). A directory holds only the platform's own tables, so there is no
|
|
68
|
+
* vertical table whose DDL the dump could have a say in: an extra table would keep the dump's
|
|
69
|
+
* DDL, and with it whatever that declares, such as a `REFERENCES tenants` that fails the
|
|
70
|
+
* delete of a referenced row. `loadDirectoryDump` calls it first, where `assertSpineTablesBuilt`
|
|
71
|
+
* is in a scope restore, with the same `columnsOf`.
|
|
72
|
+
*/
|
|
73
|
+
export function assertDirectoryTablesBuilt(names, columnsOf) {
|
|
74
|
+
const missing = names.filter((n) => columnsOf(n) === undefined);
|
|
75
|
+
if (missing.length > 0) {
|
|
76
|
+
throw substratError('validation_failed', `restore refused: the dump carries table(s) this directory does not build: ${missing.join(', ')}. ` +
|
|
77
|
+
'A directory holds only the platform\'s own tables, each built by this code, and a table it does not ' +
|
|
78
|
+
'build would keep the dump\'s own schema. Nothing was changed.');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
58
81
|
const unbuiltSpineTables = (names) => substratError('validation_failed', `restore refused: the dump carries spine table(s) this host's kernel does not build: ${names.join(', ')}. ` +
|
|
59
82
|
'It was exported by a different kind of host (a Durable Object scope holds spine tables a node scope ' +
|
|
60
83
|
'keeps in its directory) or by a newer kernel, and its rows would have nowhere to go. Nothing was changed.');
|
|
@@ -69,7 +92,8 @@ const DERIVED_COLUMNS = {
|
|
|
69
92
|
/**
|
|
70
93
|
* The `INSERT` that loads one dumped table's rows, one row of positional parameters per
|
|
71
94
|
* execution, in the dump's column order: `spineRowsInsert` for a spine table, and the dump's
|
|
72
|
-
* own columns for a vertical one.
|
|
95
|
+
* own columns for a vertical one. A directory builds every table, so it calls
|
|
96
|
+
* `spineRowsInsert` directly. The names are quoted as given: the loader has already passed
|
|
73
97
|
* the dump through `assertReplayableDump`.
|
|
74
98
|
*/
|
|
75
99
|
export function dumpRowsInsert(table, columnsOf) {
|
|
@@ -80,12 +104,13 @@ const plainInsert = (table) => `INSERT INTO "${table.name}" (${table.columns.map
|
|
|
80
104
|
/** Column names as SQLite resolves them, without case. */
|
|
81
105
|
const lowered = (columns) => new Set(columns.map((c) => c.toLowerCase()));
|
|
82
106
|
/**
|
|
83
|
-
* The statements that add to a
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
107
|
+
* The statements that add to a table the host built (a spine table, or any directory table,
|
|
108
|
+
* #1912) each column the dump carries and the host's table does not, as a plain untyped column:
|
|
109
|
+
* `ADD COLUMN "<name>"`, lowercased, and nothing after it, so it has no type, collation,
|
|
110
|
+
* constraint or default. Run after `assertSpineTablesBuilt` / `assertDirectoryTablesBuilt` and
|
|
111
|
+
* before the table's rows go in, inside the load's transaction. The names are the dump's, which
|
|
112
|
+
* `assertReplayableDump` has already held to the identifier rule. Empty for a table the host
|
|
113
|
+
* did not build, which those have refused.
|
|
89
114
|
*/
|
|
90
115
|
export function spineColumnAdditions(table, kernelColumns) {
|
|
91
116
|
if (kernelColumns === undefined)
|
|
@@ -94,7 +119,8 @@ export function spineColumnAdditions(table, kernelColumns) {
|
|
|
94
119
|
const unknown = table.columns.filter((c) => !known.has(c.toLowerCase()));
|
|
95
120
|
// A real column named for the rowid shadows SQLite's alias. On the outbox, `rowid` is the mark
|
|
96
121
|
// the #1705 and #1746 since-queries read (`OUTBOX_MARK_SQL`), so a dump's value would silence
|
|
97
|
-
// them from then on, and survive every later export.
|
|
122
|
+
// them from then on, and survive every later export. A directory table is held to the same
|
|
123
|
+
// rule: whatever reads its rowid, now or later, reads the dump's value instead.
|
|
98
124
|
const aliased = unknown.filter((c) => ROWID_ALIASES.has(c.toLowerCase()));
|
|
99
125
|
if (aliased.length > 0) {
|
|
100
126
|
throw substratError('validation_failed', `restore refused: the dump's ${table.name} has column(s) named for SQLite's rowid: ${aliased.join(', ')}. ` +
|
|
@@ -107,15 +133,16 @@ export function spineColumnAdditions(table, kernelColumns) {
|
|
|
107
133
|
/** The names SQLite resolves to a table's rowid, unless a real column takes one. */
|
|
108
134
|
const ROWID_ALIASES = new Set(['rowid', 'oid', '_rowid_']);
|
|
109
135
|
/**
|
|
110
|
-
* The `INSERT` that loads one dumped
|
|
136
|
+
* The `INSERT` that loads one dumped table's rows into the table the host built: a spine table,
|
|
137
|
+
* or any directory table (#1912).
|
|
111
138
|
*
|
|
112
|
-
* `kernelColumns` is the
|
|
113
|
-
* `spineColumnAdditions`, or `undefined` when the
|
|
139
|
+
* `kernelColumns` is the built table's column list as the loader reads it back after
|
|
140
|
+
* `spineColumnAdditions`, or `undefined` when the host built no such table. Either refusal
|
|
114
141
|
* below is a backstop the loader's order makes unreachable, and throws `validation_failed`
|
|
115
142
|
* inside the load's transaction, so the target keeps what it held.
|
|
116
143
|
*/
|
|
117
144
|
export function spineRowsInsert(table, kernelColumns) {
|
|
118
|
-
// `assertSpineTablesBuilt` has refused this already, naming every such table.
|
|
145
|
+
// `assertSpineTablesBuilt` / `assertDirectoryTablesBuilt` has refused this already, naming every such table.
|
|
119
146
|
if (kernelColumns === undefined)
|
|
120
147
|
throw unbuiltSpineTables([table.name]);
|
|
121
148
|
const known = lowered(kernelColumns);
|
|
@@ -135,4 +162,61 @@ export function spineRowsInsert(table, kernelColumns) {
|
|
|
135
162
|
return (`INSERT INTO "${table.name}" (${[...quoted, ...derived.map(([c]) => `"${c}"`)].join(', ')}) ` +
|
|
136
163
|
`SELECT ${[...quoted, ...derived.map(([, expr]) => expr)].join(', ')} FROM (SELECT ${row})`);
|
|
137
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* The naming columns a scope row from before the directory left NULL, filled with the defaults
|
|
167
|
+
* `resolveScopeRecord` applies: a ULID lowercases into a valid slug, so the placeholder is unique
|
|
168
|
+
* by construction. Run by both adapters' schema pass on every start, and by a directory restore
|
|
169
|
+
* after its rows are in, inside its transaction (#1912). One statement per entry, since a
|
|
170
|
+
* Durable Object's `exec` and better-sqlite3's `prepare` each take one.
|
|
171
|
+
*/
|
|
172
|
+
export const LEGACY_SCOPE_ROWS_BACKFILL = [
|
|
173
|
+
'UPDATE scopes SET slug = lower(scope_id) WHERE slug IS NULL',
|
|
174
|
+
"UPDATE scopes SET kind = 'scope' WHERE kind IS NULL",
|
|
175
|
+
'UPDATE scopes SET name = slug WHERE name IS NULL',
|
|
176
|
+
];
|
|
177
|
+
/** Refuse a table whose built columns plus the dump's unknown ones would pass `max`. */
|
|
178
|
+
function assertWithinColumnCap(tables, columnsOf, max) {
|
|
179
|
+
for (const t of tables) {
|
|
180
|
+
const built = columnsOf(t.name) ?? [];
|
|
181
|
+
const known = lowered(built);
|
|
182
|
+
const width = built.length + new Set(t.columns.map((c) => c.toLowerCase()).filter((c) => !known.has(c))).size;
|
|
183
|
+
if (width > max) {
|
|
184
|
+
throw substratError('validation_failed', `restore refused: the dump's ${t.name} would hold ${width} columns once the ones this code does not ` +
|
|
185
|
+
`know are added to its own, and a table here holds at most ${max}. Nothing was changed.`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Load a directory dump's rows into the tables the host has just built from its own schema
|
|
191
|
+
* (#1912): the one sequence both adapters' directory restores run, inside their transaction,
|
|
192
|
+
* after dropping the old directory and running the schema pass.
|
|
193
|
+
*
|
|
194
|
+
* 1. refuse a table the directory does not build (`assertDirectoryTablesBuilt`), and one that
|
|
195
|
+
* would pass `maxColumns` once the dump's unknown columns join this code's own;
|
|
196
|
+
* 2. add each column the dump carries and this code does not know, bare and lowercased, and
|
|
197
|
+
* refuse one named for the rowid (`spineColumnAdditions`);
|
|
198
|
+
* 3. insert every row by column name, against the columns read back after step 2
|
|
199
|
+
* (`spineRowsInsert`);
|
|
200
|
+
* 4. fill a pre-directory scope row's naming columns (`LEGACY_SCOPE_ROWS_BACKFILL`);
|
|
201
|
+
* 5. backfill the schedule switch's record from the dump's own admin log, when the dump
|
|
202
|
+
* predates it (#1674). One that carried it keeps its rows and is never backfilled over.
|
|
203
|
+
*
|
|
204
|
+
* A throw anywhere is the caller's transaction rolling back, so the directory keeps what it held.
|
|
205
|
+
*/
|
|
206
|
+
export function loadDirectoryDump(tables, host) {
|
|
207
|
+
assertDirectoryTablesBuilt(tables.map((t) => t.name), host.columnsOf);
|
|
208
|
+
if (host.maxColumns !== undefined)
|
|
209
|
+
assertWithinColumnCap(tables, host.columnsOf, host.maxColumns);
|
|
210
|
+
for (const t of tables)
|
|
211
|
+
for (const alter of spineColumnAdditions(t, host.columnsOf(t.name)))
|
|
212
|
+
host.exec(alter);
|
|
213
|
+
for (const t of tables) {
|
|
214
|
+
if (t.rows.length > 0)
|
|
215
|
+
host.insert(spineRowsInsert(t, host.columnsOf(t.name)), t.rows);
|
|
216
|
+
}
|
|
217
|
+
for (const stmt of LEGACY_SCOPE_ROWS_BACKFILL)
|
|
218
|
+
host.exec(stmt);
|
|
219
|
+
if (!dumpCarriesSystemSwitches(tables.map((t) => t.name)))
|
|
220
|
+
host.exec(SYSTEM_SWITCHES_BACKFILL_SQL);
|
|
221
|
+
}
|
|
138
222
|
//# sourceMappingURL=spine-restore.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spine-restore.js","sourceRoot":"","sources":["../src/spine-restore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"spine-restore.js","sourceRoot":"","sources":["../src/spine-restore.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
*/
|
|
27
27
|
import type { ListPage } from '@substrat-run/contracts';
|
|
28
28
|
import type { SwitchSql, SwitchedOff, SystemScheduleState } from './system-switch.js';
|
|
29
|
+
/** The record's table name, as the DDL below spells it. */
|
|
30
|
+
export declare const SYSTEM_SWITCHES_TABLE = "_substrat_system_switches";
|
|
29
31
|
/**
|
|
30
32
|
* The table. Interpolated into both adapters' directory DDL, so `lint:spine-ddl` sees the
|
|
31
33
|
* one spelling on each side. No CHECK on `position`: the drift gate does not compare
|
|
@@ -51,6 +53,12 @@ export declare const SYSTEM_SWITCHES_DDL = "\n CREATE TABLE IF NOT EXISTS _subs
|
|
|
51
53
|
* The adapters run it only on the construction that creates the table, so it runs once.
|
|
52
54
|
*/
|
|
53
55
|
export declare const SYSTEM_SWITCHES_BACKFILL_SQL = "\n WITH applied AS (\n SELECT DISTINCT action, json_extract(after, '$.operationId') AS operation_id\n FROM _substrat_admin_log\n WHERE action IN ('revokeFromSystem', 'restoreToSystem')\n AND json_extract(after, '$.phase') = 'applied'\n ),\n intents AS (\n SELECT i.id AS id, i.tenant_id AS tenant_id, i.scope_id AS scope_id,\n json_extract(i.after, '$.moduleId') AS module_id,\n CASE i.action WHEN 'revokeFromSystem' THEN 'off' ELSE 'on' END AS position,\n i.actor AS actor,\n json_extract(i.after, '$.reason') AS reason,\n json_extract(i.after, '$.operationId') AS operation_id,\n i.at AS at\n FROM _substrat_admin_log i\n JOIN applied a\n ON a.action = i.action AND a.operation_id = json_extract(i.after, '$.operationId')\n WHERE i.action IN ('revokeFromSystem', 'restoreToSystem')\n AND i.tenant_id IS NOT NULL AND i.scope_id IS NOT NULL\n AND json_extract(i.after, '$.phase') = 'intent'\n AND json_extract(i.after, '$.moduleId') IS NOT NULL\n AND json_extract(i.after, '$.reason') IS NOT NULL\n ),\n ranked AS (\n SELECT *,\n ROW_NUMBER() OVER (PARTITION BY tenant_id, scope_id, module_id ORDER BY id DESC) AS latest,\n MAX(position = 'off') OVER (PARTITION BY tenant_id, scope_id, module_id) AS ever_off\n FROM intents\n )\n INSERT OR IGNORE INTO _substrat_system_switches\n (tenant_id, scope_id, module_id, position, actor, reason, operation_id, switched_at)\n SELECT tenant_id, scope_id, module_id, position, actor, reason, operation_id, at\n FROM ranked\n WHERE latest = 1 AND ever_off = 1\n";
|
|
56
|
+
/**
|
|
57
|
+
* Does a dump carry the record table? A directory restore builds the table either way, and
|
|
58
|
+
* backfills it from the dump's own admin log only when the dump did not (#1898). Compared
|
|
59
|
+
* without case, as SQLite resolves a table name.
|
|
60
|
+
*/
|
|
61
|
+
export declare function dumpCarriesSystemSwitches(names: readonly string[]): boolean;
|
|
54
62
|
/** "Does the record table exist yet?" — asked BEFORE the DDL, so the backfill runs once. */
|
|
55
63
|
export declare function systemSwitchesTableExists(db: SwitchSql): boolean;
|
|
56
64
|
/** One record row as the directory holds it, with the scope's binding joined on. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-switch-record.d.ts","sourceRoot":"","sources":["../src/system-switch-record.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"system-switch-record.d.ts","sourceRoot":"","sources":["../src/system-switch-record.ts"],"names":[],"mappings":"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"}
|