@mcp-b/do-runtime 0.3.5 → 0.4.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/CHANGELOG.md +17 -0
- package/README.md +4 -1
- package/dist/backends/node-sqlite.js +2 -1
- package/dist/backends/node-sqlite.js.map +1 -1
- package/dist/backends/sqlite-wasm.js +2 -1
- package/dist/backends/sqlite-wasm.js.map +1 -1
- package/dist/chunks/{sqlite-DFg92Tgt.js → sqlite-migrations-DsWmLP_B.js} +55 -3
- package/dist/chunks/sqlite-migrations-DsWmLP_B.js.map +1 -0
- package/dist/gate.js +30 -6
- package/dist/gate.js.map +1 -1
- package/dist/index.js +276 -45
- package/dist/index.js.map +1 -1
- package/dist/server/alarm-scheduler.js +2 -1
- package/dist/server/alarm-scheduler.js.map +1 -1
- package/dist/src/api/sql.d.ts +15 -3
- package/dist/src/gate.d.ts +4 -0
- package/dist/src/util/sqlite-migrations.d.ts +72 -0
- package/package.json +3 -1
- package/dist/chunks/sqlite-DFg92Tgt.js.map +0 -1
package/dist/gate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate.js","names":[],"sources":["../src/gate.ts"],"sourcesContent":["/* @do-runtime-gated */\n\nimport {\n tryCurrentContinuation,\n tryCurrentIoContext,\n type IoContext,\n} from \"./io/io-context\";\n\ntype Publication = {\n readonly publish: () => Promise<void>;\n readonly reject: (exception: unknown) => void;\n};\n\ntype Outcome<T> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly exception: unknown };\n\nconst TRANSFORMED_AWAIT = Symbol(\"@mcp-b/do-runtime/transformed-await\");\nconst warnedUngatedAwaits = new Set<string>();\n\ntype TransformedAwait<T> = {\n readonly [TRANSFORMED_AWAIT]: true;\n readonly context: IoContext;\n readonly outcome: Outcome<T>;\n};\n\nfunction isThenable(value: unknown): value is PromiseLike<unknown> {\n return (\n (typeof value === \"object\" && value !== null) ||\n typeof value === \"function\"\n ) && typeof Reflect.get(value, \"then\") === \"function\";\n}\n\n/** Re-enter the actor that owns this transformed await; fail open outside actors. */\nexport function __gate<T>(value: T): T | Promise<Awaited<T>> {\n const context = tryCurrentIoContext();\n if (!isThenable(value) && context === undefined) return value;\n if (context === undefined) return value;\n return resumeWithContext(context, Promise.resolve(value));\n}\n\n/** Capture an actor await without publishing its context before the continuation runs. */\nexport function __gateAwait<T>(\n value: T,\n developmentSource?: string,\n): T | Promise<TransformedAwait<Awaited<T>>> {\n const context = tryCurrentIoContext();\n if (context === undefined) {\n if (developmentSource !== undefined && !warnedUngatedAwaits.has(developmentSource)) {\n warnedUngatedAwaits.add(developmentSource);\n console.warn(\n `do-runtime: transformed await in ${developmentSource} ran without an actor input lock; ` +\n \"an earlier await or entry path is not gated\",\n );\n }\n return value;\n }\n return resumeAwaitWithContext(context, Promise.resolve(value));\n}\n\n/** Restore the captured actor at the first instruction after a transformed await. */\nexport function __resumeAwait<T>(value: T | TransformedAwait<T>): T {\n if (!isTransformedAwait(value)) return value as T;\n\n value.context.restoreContinuation();\n if (value.outcome.ok) return value.outcome.value;\n throw value.outcome.exception;\n}\n\nfunction isTransformedAwait<T>(value: T | TransformedAwait<T>): value is TransformedAwait<T> {\n return Reflect.get(Object(value), TRANSFORMED_AWAIT) === true;\n}\n\nfunction publishOutcome<T, Result>(\n context: IoContext,\n promise: Promise<T>,\n finish: (outcome: Outcome<T>) => Result,\n): Promise<Result> {\n return new Promise<Result>((resolve, reject) => {\n const publish = context.makeTransformReentryCallback((outcome: Outcome<T>) => {\n if (tryCurrentContinuation() !== undefined) {\n schedulePublication({ publish: () => publish(outcome), reject });\n return;\n }\n resolve(finish(outcome));\n });\n void promise.then(\n (value) => {\n schedulePublication({ publish: () => publish({ ok: true, value }), reject });\n },\n (exception: unknown) => {\n schedulePublication({ publish: () => publish({ ok: false, exception }), reject });\n },\n );\n });\n}\n\nfunction resumeAwaitWithContext<T>(\n context: IoContext,\n promise: Promise<T>,\n): Promise<TransformedAwait<T>> {\n return publishOutcome(context, promise, (outcome) => ({\n [TRANSFORMED_AWAIT]: true,\n context,\n outcome,\n }));\n}\n\nfunction resumeWithContext<T>(context: IoContext, promise: Promise<T>): Promise<T> {\n return publishOutcome(context, promise, (outcome) => {\n context.restoreContinuation();\n if (outcome.ok) return outcome.value;\n throw outcome.exception;\n });\n}\n\n/**\n * Resolve one transformed await per task, inside a fresh actor slice. Admission\n * attempts are independent so a blocked actor cannot stall the actor that will\n * unblock it. The task boundary keeps each continuation ambient isolated.\n */\nfunction schedulePublication(publication: Publication): void {\n const channel = new MessageChannel();\n channel.port1.onmessage = () => {\n channel.port1.close();\n channel.port2.close();\n\n void publication.publish().catch((exception: unknown) => {\n publication.reject(exception);\n });\n };\n channel.port2.postMessage(undefined);\n}\n\nfunction iteratorFor<T>(iterable: AsyncIterable<T> | Iterable<T>): AsyncIterator<T> | Iterator<T> {\n const subject = Object(iterable);\n const asyncIterator: unknown = Reflect.get(subject, Symbol.asyncIterator);\n if (typeof asyncIterator === \"function\") return Reflect.apply(asyncIterator, iterable, []);\n const iterator: unknown = Reflect.get(subject, Symbol.iterator);\n if (typeof iterator === \"function\") return Reflect.apply(iterator, iterable, []);\n throw new TypeError(\"value is not async iterable or iterable\");\n}\n\nfunction gatedIterator<T>(iterable: AsyncIterable<T> | Iterable<T>): AsyncIterator<T> {\n const iterator = iteratorFor(iterable);\n\n function invoke(methodName: \"next\" | \"return\" | \"throw\", args: unknown[]): Promise<IteratorResult<T>> {\n const method: unknown = Reflect.get(iterator, methodName);\n if (typeof method === \"function\") {\n return Promise.resolve(__gate(Reflect.apply(method, iterator, args)));\n }\n if (methodName === \"throw\") return Promise.reject(args[0]);\n return Promise.resolve({ done: true, value: args[0] });\n }\n\n return {\n next: (...args: [] | [unknown]) => invoke(\"next\", args),\n return: (value?: unknown) => invoke(\"return\", [value]),\n throw: (exception?: unknown) => invoke(\"throw\", [exception]),\n };\n}\n\n/** Gate every operation used by `for await`, including early return and throw. */\nexport function __gateAsyncIterable<T, IterableType extends AsyncIterable<T> | Iterable<T>>(\n iterable: IterableType,\n): IterableType;\nexport function __gateAsyncIterable<T>(\n iterable: AsyncIterable<T> | Iterable<T>,\n): AsyncIterable<T> | Iterable<T> {\n const wrapper: AsyncIterable<T> = {\n [Symbol.asyncIterator]: () => gatedIterator(iterable),\n };\n if ((typeof iterable !== \"object\" || iterable === null) && typeof iterable !== \"function\") {\n return wrapper;\n }\n return new Proxy(iterable, {\n get(target, property, receiver): unknown {\n if (property === Symbol.asyncIterator) return wrapper[Symbol.asyncIterator];\n return Reflect.get(target, property, receiver);\n },\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"gate.js","names":[],"sources":["../src/gate.ts"],"sourcesContent":["/* @do-runtime-gated */\n\nimport {\n atCheckpointEnd,\n tryCurrentContinuation,\n tryCurrentIoContext,\n type IoContext,\n} from \"./io/io-context\";\n\ntype Publication = {\n readonly publish: () => Promise<void>;\n readonly reject: (exception: unknown) => void;\n};\n\ntype Outcome<T> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly exception: unknown };\n\nconst TRANSFORMED_AWAIT = Symbol(\"@mcp-b/do-runtime/transformed-await\");\n/**\n * Own the gap between publishing an await result and its `__resumeAwait` call.\n * This is deliberately separate from the current-continuation ambient: a\n * reservation serializes publishers but must never make its actor look current.\n * See §2.3 and decision 8.\n */\nconst CURRENT_PUBLICATION = Symbol.for(\"@mcp-b/do-runtime/current-await-publication\");\nconst warnedUngatedAwaits = new Set<string>();\n\ntype PublicationReservation = {\n readonly context: IoContext;\n};\n\ntype TransformedAwait<T> = {\n readonly [TRANSFORMED_AWAIT]: true;\n readonly context: IoContext;\n readonly outcome: Outcome<T>;\n readonly reservation: PublicationReservation;\n};\n\nfunction isThenable(value: unknown): value is PromiseLike<unknown> {\n return (\n (typeof value === \"object\" && value !== null) ||\n typeof value === \"function\"\n ) && typeof Reflect.get(value, \"then\") === \"function\";\n}\n\n/** Re-enter the actor that owns this transformed await; fail open outside actors. */\nexport function __gate<T>(value: T): T | Promise<Awaited<T>> {\n const context = tryCurrentIoContext();\n if (!isThenable(value) && context === undefined) return value;\n if (context === undefined) return value;\n return resumeWithContext(context, Promise.resolve(value));\n}\n\n/** Capture an actor await without publishing its context before the continuation runs. */\nexport function __gateAwait<T>(\n value: T,\n developmentSource?: string,\n): T | Promise<TransformedAwait<Awaited<T>>> {\n const context = tryCurrentIoContext();\n if (context === undefined) {\n if (developmentSource !== undefined && !warnedUngatedAwaits.has(developmentSource)) {\n warnedUngatedAwaits.add(developmentSource);\n console.warn(\n `do-runtime: transformed await in ${developmentSource} ran without an actor input lock; ` +\n \"an earlier await or entry path is not gated\",\n );\n }\n return value;\n }\n return resumeAwaitWithContext(context, Promise.resolve(value));\n}\n\n/** Restore the captured actor at the first instruction after a transformed await. */\nexport function __resumeAwait<T>(value: T | TransformedAwait<T>): T {\n if (!isTransformedAwait(value)) return value as T;\n\n clearPublication(value.reservation);\n value.context.restoreContinuation();\n if (value.outcome.ok) return value.outcome.value;\n throw value.outcome.exception;\n}\n\nfunction isTransformedAwait<T>(value: T | TransformedAwait<T>): value is TransformedAwait<T> {\n return Reflect.get(Object(value), TRANSFORMED_AWAIT) === true;\n}\n\nfunction currentPublication(): PublicationReservation | undefined {\n return Reflect.get(globalThis, CURRENT_PUBLICATION) as PublicationReservation | undefined;\n}\n\nfunction reservePublication(context: IoContext): PublicationReservation | undefined {\n if (tryCurrentContinuation() !== undefined || currentPublication() !== undefined) return undefined;\n const reservation = { context };\n Reflect.set(globalThis, CURRENT_PUBLICATION, reservation);\n atCheckpointEnd(() => clearPublication(reservation));\n return reservation;\n}\n\nfunction clearPublication(reservation: PublicationReservation): void {\n if (currentPublication() === reservation) {\n Reflect.deleteProperty(globalThis, CURRENT_PUBLICATION);\n }\n}\n\nfunction publishOutcome<T, Result>(\n context: IoContext,\n promise: Promise<T>,\n finish: (outcome: Outcome<T>, reservation: PublicationReservation) => Result,\n): Promise<Result> {\n return new Promise<Result>((resolve, reject) => {\n const publish = context.makeTransformReentryCallback((outcome: Outcome<T>) => {\n const reservation = reservePublication(context);\n if (reservation === undefined) {\n schedulePublication({ publish: () => publish(outcome), reject });\n return;\n }\n resolve(finish(outcome, reservation));\n });\n void promise.then(\n (value) => {\n schedulePublication({ publish: () => publish({ ok: true, value }), reject });\n },\n (exception: unknown) => {\n schedulePublication({ publish: () => publish({ ok: false, exception }), reject });\n },\n );\n });\n}\n\nfunction resumeAwaitWithContext<T>(\n context: IoContext,\n promise: Promise<T>,\n): Promise<TransformedAwait<T>> {\n return publishOutcome(context, promise, (outcome, reservation) => ({\n [TRANSFORMED_AWAIT]: true,\n context,\n outcome,\n reservation,\n }));\n}\n\nfunction resumeWithContext<T>(context: IoContext, promise: Promise<T>): Promise<T> {\n return publishOutcome(context, promise, (outcome, reservation) => {\n clearPublication(reservation);\n context.restoreContinuation();\n if (outcome.ok) return outcome.value;\n throw outcome.exception;\n });\n}\n\n/**\n * Resolve one transformed await per task, inside a fresh actor slice. Admission\n * attempts are independent so a blocked actor cannot stall the actor that will\n * unblock it. The task boundary keeps each continuation ambient isolated.\n */\nfunction schedulePublication(publication: Publication): void {\n const channel = new MessageChannel();\n channel.port1.onmessage = () => {\n channel.port1.close();\n channel.port2.close();\n\n void publication.publish().catch((exception: unknown) => {\n publication.reject(exception);\n });\n };\n channel.port2.postMessage(undefined);\n}\n\nfunction iteratorFor<T>(iterable: AsyncIterable<T> | Iterable<T>): AsyncIterator<T> | Iterator<T> {\n const subject = Object(iterable);\n const asyncIterator: unknown = Reflect.get(subject, Symbol.asyncIterator);\n if (typeof asyncIterator === \"function\") return Reflect.apply(asyncIterator, iterable, []);\n const iterator: unknown = Reflect.get(subject, Symbol.iterator);\n if (typeof iterator === \"function\") return Reflect.apply(iterator, iterable, []);\n throw new TypeError(\"value is not async iterable or iterable\");\n}\n\nfunction gatedIterator<T>(iterable: AsyncIterable<T> | Iterable<T>): AsyncIterator<T> {\n const iterator = iteratorFor(iterable);\n\n function invoke(methodName: \"next\" | \"return\" | \"throw\", args: unknown[]): Promise<IteratorResult<T>> {\n const method: unknown = Reflect.get(iterator, methodName);\n if (typeof method === \"function\") {\n return Promise.resolve(__gate(Reflect.apply(method, iterator, args)));\n }\n if (methodName === \"throw\") return Promise.reject(args[0]);\n return Promise.resolve({ done: true, value: args[0] });\n }\n\n return {\n next: (...args: [] | [unknown]) => invoke(\"next\", args),\n return: (value?: unknown) => invoke(\"return\", [value]),\n throw: (exception?: unknown) => invoke(\"throw\", [exception]),\n };\n}\n\n/** Gate every operation used by `for await`, including early return and throw. */\nexport function __gateAsyncIterable<T, IterableType extends AsyncIterable<T> | Iterable<T>>(\n iterable: IterableType,\n): IterableType;\nexport function __gateAsyncIterable<T>(\n iterable: AsyncIterable<T> | Iterable<T>,\n): AsyncIterable<T> | Iterable<T> {\n const wrapper: AsyncIterable<T> = {\n [Symbol.asyncIterator]: () => gatedIterator(iterable),\n };\n if ((typeof iterable !== \"object\" || iterable === null) && typeof iterable !== \"function\") {\n return wrapper;\n }\n return new Proxy(iterable, {\n get(target, property, receiver): unknown {\n if (property === Symbol.asyncIterator) return wrapper[Symbol.asyncIterator];\n return Reflect.get(target, property, receiver);\n },\n });\n}\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as hasUserErrorDetail, c as setUserErrorDetail, d as tryCurrentSlice, f as CanceledError, i as captureGateStack, m as OutputGate, n as IoContext, o as isExceptionFromInputGateBroken, p as InputGate, r as atCheckpointEnd, s as requireInputLock, t as BrokenActorError, u as tryCurrentIoContext } from "./chunks/io-context-RmmjNtwm.js";
|
|
2
2
|
import { RpcTarget as RpcTarget$1 } from "./cloudflare-workers.js";
|
|
3
|
-
import { a as
|
|
3
|
+
import { a as SqliteDatabase, c as getText, l as hasCurrentSqliteTable, o as getBlob, s as getInt64, t as ensureRuntimeStorageVersion, u as isNull } from "./chunks/sqlite-migrations-DsWmLP_B.js";
|
|
4
4
|
import { ALARM_RETRY_MAX_TRIES, ALARM_RETRY_START_SECONDS, AlarmScheduler, RETRY_BACKOFF_MAX, RETRY_JITTER_FACTOR, alarmRetryDelayMs } from "./server/alarm-scheduler.js";
|
|
5
5
|
import { deserialize, serialize } from "@ungap/structured-clone";
|
|
6
6
|
import { RpcTarget, newMessagePortRpcSession } from "capnweb";
|
|
@@ -1119,6 +1119,247 @@ function refuseTransactionControl(statement) {
|
|
|
1119
1119
|
if (TRANSACTION_CONTROL.test(code)) SqlStorageRegulator.allowTransactions();
|
|
1120
1120
|
}
|
|
1121
1121
|
/**
|
|
1122
|
+
* ← the message a `SQLITE_DENY` from the authorizer surfaces to JavaScript,
|
|
1123
|
+
* byte-identical so a caller matching on it ports unchanged.
|
|
1124
|
+
*/
|
|
1125
|
+
var SQL_NOT_AUTHORIZED_MESSAGE = "not authorized: SQLITE_AUTH";
|
|
1126
|
+
/** Comments are never code. String literals STAY: pragma arguments may be quoted. */
|
|
1127
|
+
var NOT_COMMENT = /--[^\n]*|\/\*[\s\S]*?\*\//g;
|
|
1128
|
+
/** Cheap pre-test; `PRAGMA` and the `pragma_` functions both contain it. */
|
|
1129
|
+
var PRAGMA_HINT = /pragma/i;
|
|
1130
|
+
/** `PRAGMA [schema.]name`, then `= value`, `(argument)`, or nothing. */
|
|
1131
|
+
var PRAGMA_STATEMENT = /^\s*PRAGMA\s+(?:[A-Za-z_][A-Za-z0-9_$]*\s*\.\s*)?([A-Za-z_][A-Za-z0-9_$]*)(?:\s*=\s*([\s\S]+?)|\s*\(\s*([\s\S]*?)\s*\))?\s*;?\s*$/i;
|
|
1132
|
+
/**
|
|
1133
|
+
* ← `ALLOWED_PRAGMAS` and `PragmaSignature` (`util/sqlite.c++:525-563`),
|
|
1134
|
+
* verbatim. `table_list`, `table_info`, and `table_xinfo` are special-cased
|
|
1135
|
+
* ahead of the table in the authorizer, exactly as upstream's `SQLITE_PRAGMA`
|
|
1136
|
+
* case does (`util/sqlite.c++:1194-1273`).
|
|
1137
|
+
*/
|
|
1138
|
+
var ALLOWED_PRAGMAS = /* @__PURE__ */ new Map([
|
|
1139
|
+
["data_version", "NO_ARG"],
|
|
1140
|
+
["case_sensitive_like", "BOOLEAN"],
|
|
1141
|
+
["foreign_keys", "BOOLEAN"],
|
|
1142
|
+
["defer_foreign_keys", "BOOLEAN"],
|
|
1143
|
+
["ignore_check_constraints", "BOOLEAN"],
|
|
1144
|
+
["legacy_alter_table", "BOOLEAN"],
|
|
1145
|
+
["recursive_triggers", "BOOLEAN"],
|
|
1146
|
+
["reverse_unordered_selects", "BOOLEAN"],
|
|
1147
|
+
["foreign_key_check", "OPTIONAL_OBJECT_NAME"],
|
|
1148
|
+
["foreign_key_list", "OBJECT_NAME"],
|
|
1149
|
+
["index_info", "OBJECT_NAME"],
|
|
1150
|
+
["index_list", "OBJECT_NAME"],
|
|
1151
|
+
["index_xinfo", "OBJECT_NAME"],
|
|
1152
|
+
["quick_check", "NULL_NUMBER_OR_OBJECT_NAME"],
|
|
1153
|
+
["optimize", "NULL_OR_NUMBER"]
|
|
1154
|
+
]);
|
|
1155
|
+
/** Upstream compares the eight literal forms as PREFIXES, case-insensitively. */
|
|
1156
|
+
var BOOLEAN_PRAGMA_VALUE = /^(?:true|false|yes|no|on|off|1|0)/i;
|
|
1157
|
+
/**
|
|
1158
|
+
* The pragmas SQLite ships (https://www.sqlite.org/pragma.html), so a
|
|
1159
|
+
* `pragma_X` identifier can be told apart: `X` here means the table-valued
|
|
1160
|
+
* pragma function and follows the allowlist; any other `pragma_`-prefixed
|
|
1161
|
+
* identifier is an ordinary application name, which upstream's authorizer
|
|
1162
|
+
* distinguishes by resolution and the conformance suite pins.
|
|
1163
|
+
*/
|
|
1164
|
+
var SQLITE_PRAGMA_NAMES = /* @__PURE__ */ new Set([
|
|
1165
|
+
"analysis_limit",
|
|
1166
|
+
"application_id",
|
|
1167
|
+
"auto_vacuum",
|
|
1168
|
+
"automatic_index",
|
|
1169
|
+
"busy_timeout",
|
|
1170
|
+
"cache_size",
|
|
1171
|
+
"cache_spill",
|
|
1172
|
+
"case_sensitive_like",
|
|
1173
|
+
"cell_size_check",
|
|
1174
|
+
"checkpoint_fullfsync",
|
|
1175
|
+
"collation_list",
|
|
1176
|
+
"compile_options",
|
|
1177
|
+
"data_version",
|
|
1178
|
+
"database_list",
|
|
1179
|
+
"defer_foreign_keys",
|
|
1180
|
+
"encoding",
|
|
1181
|
+
"foreign_key_check",
|
|
1182
|
+
"foreign_key_list",
|
|
1183
|
+
"foreign_keys",
|
|
1184
|
+
"freelist_count",
|
|
1185
|
+
"full_column_names",
|
|
1186
|
+
"fullfsync",
|
|
1187
|
+
"function_list",
|
|
1188
|
+
"hard_heap_limit",
|
|
1189
|
+
"ignore_check_constraints",
|
|
1190
|
+
"incremental_vacuum",
|
|
1191
|
+
"index_info",
|
|
1192
|
+
"index_list",
|
|
1193
|
+
"index_xinfo",
|
|
1194
|
+
"integrity_check",
|
|
1195
|
+
"journal_mode",
|
|
1196
|
+
"journal_size_limit",
|
|
1197
|
+
"legacy_alter_table",
|
|
1198
|
+
"legacy_file_format",
|
|
1199
|
+
"locking_mode",
|
|
1200
|
+
"max_page_count",
|
|
1201
|
+
"mmap_size",
|
|
1202
|
+
"module_list",
|
|
1203
|
+
"optimize",
|
|
1204
|
+
"page_count",
|
|
1205
|
+
"page_size",
|
|
1206
|
+
"pragma_list",
|
|
1207
|
+
"query_only",
|
|
1208
|
+
"quick_check",
|
|
1209
|
+
"read_uncommitted",
|
|
1210
|
+
"recursive_triggers",
|
|
1211
|
+
"reverse_unordered_selects",
|
|
1212
|
+
"schema_version",
|
|
1213
|
+
"secure_delete",
|
|
1214
|
+
"short_column_names",
|
|
1215
|
+
"shrink_memory",
|
|
1216
|
+
"soft_heap_limit",
|
|
1217
|
+
"synchronous",
|
|
1218
|
+
"table_info",
|
|
1219
|
+
"table_list",
|
|
1220
|
+
"table_xinfo",
|
|
1221
|
+
"temp_store",
|
|
1222
|
+
"threads",
|
|
1223
|
+
"trusted_schema",
|
|
1224
|
+
"user_version",
|
|
1225
|
+
"wal_autocheckpoint",
|
|
1226
|
+
"wal_checkpoint",
|
|
1227
|
+
"writable_schema"
|
|
1228
|
+
]);
|
|
1229
|
+
/** kj's `tryParseAs` is decimal; keep the same acceptance. */
|
|
1230
|
+
var DECIMAL = /^[+-]?\d+$/;
|
|
1231
|
+
/** One layer of SQL quoting off a pragma argument, any of the four forms. */
|
|
1232
|
+
function unquoted(argument) {
|
|
1233
|
+
const first = argument[0];
|
|
1234
|
+
const last = argument[argument.length - 1];
|
|
1235
|
+
if (argument.length >= 2) {
|
|
1236
|
+
if ((first === "'" || first === "\"" || first === "`") && last === first) return argument.slice(1, -1);
|
|
1237
|
+
if (first === "[" && last === "]") return argument.slice(1, -1);
|
|
1238
|
+
}
|
|
1239
|
+
return argument;
|
|
1240
|
+
}
|
|
1241
|
+
/** ← the `SQLITE_PRAGMA` authorizer case (`util/sqlite.c++:1194-1273`), whole. */
|
|
1242
|
+
function isAllowedPragma(name, argument) {
|
|
1243
|
+
const pragma = name.toLowerCase();
|
|
1244
|
+
if (pragma === "table_list") return true;
|
|
1245
|
+
if (pragma === "table_info" || pragma === "table_xinfo") {
|
|
1246
|
+
if (argument === void 0) return false;
|
|
1247
|
+
return SqlStorageRegulator.isAllowedName(unquoted(argument));
|
|
1248
|
+
}
|
|
1249
|
+
const signature = ALLOWED_PRAGMAS.get(pragma);
|
|
1250
|
+
if (signature === void 0) return false;
|
|
1251
|
+
switch (signature) {
|
|
1252
|
+
case "NO_ARG": return argument === void 0;
|
|
1253
|
+
case "BOOLEAN": return argument === void 0 || BOOLEAN_PRAGMA_VALUE.test(unquoted(argument));
|
|
1254
|
+
case "OBJECT_NAME": return argument !== void 0 && SqlStorageRegulator.isAllowedName(unquoted(argument));
|
|
1255
|
+
case "OPTIONAL_OBJECT_NAME": return argument === void 0 || SqlStorageRegulator.isAllowedName(unquoted(argument));
|
|
1256
|
+
case "NULL_OR_NUMBER": return argument === void 0 || DECIMAL.test(argument);
|
|
1257
|
+
case "NULL_NUMBER_OR_OBJECT_NAME": return argument === void 0 || DECIMAL.test(argument) || SqlStorageRegulator.isAllowedName(unquoted(argument));
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
/**
|
|
1261
|
+
* The text-level stand-in for the authorizer's `SQLITE_PRAGMA` case, against
|
|
1262
|
+
* one SQLite-decided statement boundary. Load-bearing beyond fidelity:
|
|
1263
|
+
* `user_version` is where runtime storage versioning keeps its per-file stamp
|
|
1264
|
+
* (`util/sqlite-migrations.ts`), and `writable_schema` would let application
|
|
1265
|
+
* SQL rewrite `sqlite_master` out from under the `_cf_` reservation.
|
|
1266
|
+
*
|
|
1267
|
+
* The `pragma_` table-valued functions reach the same authorizer path
|
|
1268
|
+
* upstream, so they follow the same allowlist here — by pragma NAME only. An
|
|
1269
|
+
* argument the text cannot see (a string literal or a binding) goes unchecked
|
|
1270
|
+
* where upstream's authorizer sees the resolved value; a `_cf_` name smuggled
|
|
1271
|
+
* that way reads schema whose shape is public source anyway, while identifier
|
|
1272
|
+
* arguments stay covered by `requireAllowedNames`. The README divergence row
|
|
1273
|
+
* records this.
|
|
1274
|
+
*/
|
|
1275
|
+
function requireAllowedPragmas(statement) {
|
|
1276
|
+
if (!PRAGMA_HINT.test(statement)) return;
|
|
1277
|
+
const code = statement.replace(NOT_COMMENT, " ");
|
|
1278
|
+
const direct = code.match(PRAGMA_STATEMENT);
|
|
1279
|
+
if (direct !== null) {
|
|
1280
|
+
const [, name = "", assigned, called] = direct;
|
|
1281
|
+
const argument = (assigned ?? called)?.trim();
|
|
1282
|
+
if (!isAllowedPragma(name, argument === "" ? void 0 : argument)) throw new Error(SQL_NOT_AUTHORIZED_MESSAGE);
|
|
1283
|
+
return;
|
|
1284
|
+
}
|
|
1285
|
+
if (/^\s*PRAGMA\b/i.test(code)) throw new Error(SQL_NOT_AUTHORIZED_MESSAGE);
|
|
1286
|
+
const literalFree = code.replace(NOT_CODE, " ");
|
|
1287
|
+
for (const [token] of literalFree.matchAll(IDENTIFIER)) {
|
|
1288
|
+
if (token.length <= 7 || token.slice(0, 7).toLowerCase() !== "pragma_") continue;
|
|
1289
|
+
const name = token.slice(7).toLowerCase();
|
|
1290
|
+
if (!SQLITE_PRAGMA_NAMES.has(name)) continue;
|
|
1291
|
+
if (name !== "table_list" && name !== "table_info" && name !== "table_xinfo" && !ALLOWED_PRAGMAS.has(name)) throw new Error(SQL_NOT_AUTHORIZED_MESSAGE);
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
/** Everything the untrusted path refuses at one statement boundary. */
|
|
1295
|
+
function regulateUntrustedStatement(statement) {
|
|
1296
|
+
refuseTransactionControl(statement);
|
|
1297
|
+
requireAllowedPragmas(statement);
|
|
1298
|
+
}
|
|
1299
|
+
/** ← `JSG_INHERIT_INTRINSIC(v8::kIteratorPrototype)` (`jsg/iterator.h:1044`). */
|
|
1300
|
+
var IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()));
|
|
1301
|
+
/**
|
|
1302
|
+
* ← the `JSG_ITERATOR` types (`jsg/iterator.h:1036-1050`): `next` and
|
|
1303
|
+
* self-iterability on `%IteratorPrototype%` — which is what carries the ES
|
|
1304
|
+
* iterator helpers; `raw().toArray()` is what Drizzle's durable-sqlite driver
|
|
1305
|
+
* calls — and NOTHING else. No `return`, no `throw` (only the async variant
|
|
1306
|
+
* registers `return_`, `:1069-1085`), so `IteratorClose` after a `break`, a
|
|
1307
|
+
* partial destructuring, or a `take()` is a no-op and a retained iterator
|
|
1308
|
+
* resumes. Results are `JSG_STRUCT(done, value)` in that key order
|
|
1309
|
+
* (`jsg/iterator.h:706-710`).
|
|
1310
|
+
*/
|
|
1311
|
+
var RawIterator = class {
|
|
1312
|
+
#pull;
|
|
1313
|
+
constructor(pull) {
|
|
1314
|
+
this.#pull = pull;
|
|
1315
|
+
}
|
|
1316
|
+
next() {
|
|
1317
|
+
const raw = this.#pull();
|
|
1318
|
+
if (raw === void 0) return {
|
|
1319
|
+
done: true,
|
|
1320
|
+
value: void 0
|
|
1321
|
+
};
|
|
1322
|
+
return {
|
|
1323
|
+
done: false,
|
|
1324
|
+
value: asRawRow([...raw])
|
|
1325
|
+
};
|
|
1326
|
+
}
|
|
1327
|
+
[Symbol.iterator]() {
|
|
1328
|
+
return this;
|
|
1329
|
+
}
|
|
1330
|
+
};
|
|
1331
|
+
Object.setPrototypeOf(RawIterator.prototype, IteratorPrototype);
|
|
1332
|
+
Object.defineProperty(RawIterator.prototype, Symbol.toStringTag, {
|
|
1333
|
+
value: "RawIterator",
|
|
1334
|
+
configurable: true
|
|
1335
|
+
});
|
|
1336
|
+
/** ← `RowIterator`, shaped exactly as `RawIterator` above. */
|
|
1337
|
+
var RowIterator = class {
|
|
1338
|
+
#pull;
|
|
1339
|
+
constructor(pull) {
|
|
1340
|
+
this.#pull = pull;
|
|
1341
|
+
}
|
|
1342
|
+
next() {
|
|
1343
|
+
const row = this.#pull();
|
|
1344
|
+
if (row === void 0) return {
|
|
1345
|
+
done: true,
|
|
1346
|
+
value: void 0
|
|
1347
|
+
};
|
|
1348
|
+
return {
|
|
1349
|
+
done: false,
|
|
1350
|
+
value: row
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
1353
|
+
[Symbol.iterator]() {
|
|
1354
|
+
return this;
|
|
1355
|
+
}
|
|
1356
|
+
};
|
|
1357
|
+
Object.setPrototypeOf(RowIterator.prototype, IteratorPrototype);
|
|
1358
|
+
Object.defineProperty(RowIterator.prototype, Symbol.toStringTag, {
|
|
1359
|
+
value: "RowIterator",
|
|
1360
|
+
configurable: true
|
|
1361
|
+
});
|
|
1362
|
+
/**
|
|
1122
1363
|
* ← `SqlStorage::Cursor`.
|
|
1123
1364
|
*
|
|
1124
1365
|
* `rowsRead` is the one counter that is not upstream's. Upstream reads
|
|
@@ -1130,20 +1371,30 @@ function refuseTransactionControl(statement) {
|
|
|
1130
1371
|
* undercounts any query that scans more rows than it returns.
|
|
1131
1372
|
*/
|
|
1132
1373
|
var Cursor = class {
|
|
1133
|
-
columnNames;
|
|
1374
|
+
#columnNames;
|
|
1134
1375
|
#rawRows;
|
|
1135
1376
|
#rowsWritten;
|
|
1136
1377
|
#position = 0;
|
|
1137
1378
|
constructor(state) {
|
|
1138
1379
|
if (state === void 0) throw new Error(CURSOR_NOT_CONSTRUCTIBLE_MESSAGE);
|
|
1139
|
-
this
|
|
1380
|
+
this.#columnNames = state.columnNames;
|
|
1140
1381
|
this.#rawRows = state.rawRows;
|
|
1141
1382
|
this.#rowsWritten = state.rowsWritten;
|
|
1142
1383
|
}
|
|
1384
|
+
/**
|
|
1385
|
+
* ← `JSG_READONLY_PROTOTYPE_PROPERTY(columnNames)` (`sql.h:210`): a
|
|
1386
|
+
* prototype accessor, not an own field, so a cursor JSON-stringifies to `{}`.
|
|
1387
|
+
*/
|
|
1388
|
+
get columnNames() {
|
|
1389
|
+
return this.#columnNames;
|
|
1390
|
+
}
|
|
1143
1391
|
/** ← `Cursor::next`, whose `RowIterator::Next` is this exact shape. */
|
|
1144
1392
|
next() {
|
|
1145
1393
|
const row = this.#nextRow();
|
|
1146
|
-
if (row === void 0) return {
|
|
1394
|
+
if (row === void 0) return {
|
|
1395
|
+
done: true,
|
|
1396
|
+
value: void 0
|
|
1397
|
+
};
|
|
1147
1398
|
return {
|
|
1148
1399
|
done: false,
|
|
1149
1400
|
value: row
|
|
@@ -1168,45 +1419,16 @@ var Cursor = class {
|
|
|
1168
1419
|
}
|
|
1169
1420
|
return row;
|
|
1170
1421
|
}
|
|
1171
|
-
/**
|
|
1422
|
+
/**
|
|
1423
|
+
* ← `Cursor::raw`, which shares this cursor's position rather than
|
|
1424
|
+
* restarting. The iterator's shape is `RawIterator`'s whole doc comment.
|
|
1425
|
+
*/
|
|
1172
1426
|
raw() {
|
|
1173
|
-
|
|
1174
|
-
[Symbol.iterator]() {
|
|
1175
|
-
return iterator;
|
|
1176
|
-
},
|
|
1177
|
-
next: () => {
|
|
1178
|
-
const raw = this.#nextRaw();
|
|
1179
|
-
if (raw === void 0) return {
|
|
1180
|
-
done: true,
|
|
1181
|
-
value: void 0
|
|
1182
|
-
};
|
|
1183
|
-
return {
|
|
1184
|
-
done: false,
|
|
1185
|
-
value: asRawRow([...raw])
|
|
1186
|
-
};
|
|
1187
|
-
}
|
|
1188
|
-
};
|
|
1189
|
-
return iterator;
|
|
1427
|
+
return new RawIterator(() => this.#nextRaw());
|
|
1190
1428
|
}
|
|
1191
|
-
/** ← `JSG_ITERABLE(rows)
|
|
1429
|
+
/** ← `JSG_ITERABLE(rows)`, yielding through the same shared position. */
|
|
1192
1430
|
[Symbol.iterator]() {
|
|
1193
|
-
|
|
1194
|
-
[Symbol.iterator]() {
|
|
1195
|
-
return iterator;
|
|
1196
|
-
},
|
|
1197
|
-
next: () => {
|
|
1198
|
-
const row = this.#nextRow();
|
|
1199
|
-
if (row === void 0) return {
|
|
1200
|
-
done: true,
|
|
1201
|
-
value: void 0
|
|
1202
|
-
};
|
|
1203
|
-
return {
|
|
1204
|
-
done: false,
|
|
1205
|
-
value: row
|
|
1206
|
-
};
|
|
1207
|
-
}
|
|
1208
|
-
};
|
|
1209
|
-
return iterator;
|
|
1431
|
+
return new RowIterator(() => this.#nextRow());
|
|
1210
1432
|
}
|
|
1211
1433
|
get rowsRead() {
|
|
1212
1434
|
return this.#position;
|
|
@@ -1226,12 +1448,17 @@ var Cursor = class {
|
|
|
1226
1448
|
const raw = this.#nextRaw();
|
|
1227
1449
|
if (raw === void 0) return void 0;
|
|
1228
1450
|
const row = {};
|
|
1229
|
-
this
|
|
1451
|
+
this.#columnNames.forEach((name, index) => {
|
|
1230
1452
|
row[name] = raw[index] ?? null;
|
|
1231
1453
|
});
|
|
1232
1454
|
return asRow(row);
|
|
1233
1455
|
}
|
|
1234
1456
|
};
|
|
1457
|
+
/** ← the jsg resource-type tag every workerd API object carries (`resource.h`). */
|
|
1458
|
+
Object.defineProperty(Cursor.prototype, Symbol.toStringTag, {
|
|
1459
|
+
value: "Cursor",
|
|
1460
|
+
configurable: true
|
|
1461
|
+
});
|
|
1235
1462
|
/**
|
|
1236
1463
|
* ← `SqlStorage::Statement`, which upstream describes as "supported only for
|
|
1237
1464
|
* backwards compatibility ... it is actually just a wrapper around `exec()`".
|
|
@@ -1261,7 +1488,7 @@ var SqlStorage = class {
|
|
|
1261
1488
|
const db = this.#owner.getSqliteDb();
|
|
1262
1489
|
const sqlBindings = bindings.map(toSqlBindingValue);
|
|
1263
1490
|
requireAllowedNames(query);
|
|
1264
|
-
const result = db.run({ regulate:
|
|
1491
|
+
const result = db.run({ regulate: regulateUntrustedStatement }, query, ...sqlBindings);
|
|
1265
1492
|
return new Cursor({
|
|
1266
1493
|
columnNames: [...result.columnNames],
|
|
1267
1494
|
rawRows: result.rawRows.map((row) => row.map(toSqlStorageValue)),
|
|
@@ -1294,7 +1521,7 @@ var SqlStorage = class {
|
|
|
1294
1521
|
ingest(query) {
|
|
1295
1522
|
requireInputLock(this.#ctx, "sql.ingest()");
|
|
1296
1523
|
requireAllowedNames(query);
|
|
1297
|
-
return this.#owner.getSqliteDb().ingest(query,
|
|
1524
|
+
return this.#owner.getSqliteDb().ingest(query, regulateUntrustedStatement);
|
|
1298
1525
|
}
|
|
1299
1526
|
/** ← `SqlStorage::setMaxPageCountForTest`, which is what its name says. */
|
|
1300
1527
|
setMaxPageCountForTest(count) {
|
|
@@ -5827,9 +6054,13 @@ var ActorContainerImpl = class {
|
|
|
5827
6054
|
* `state`.
|
|
5828
6055
|
*/
|
|
5829
6056
|
async function createActorContainer(options) {
|
|
5830
|
-
const
|
|
6057
|
+
const actorDb = await options.ports.sql.open(ACTOR_DATABASE_NAME);
|
|
6058
|
+
ensureRuntimeStorageVersion(actorDb, ACTOR_DATABASE_NAME);
|
|
6059
|
+
const db = new SqliteDatabase(actorDb);
|
|
5831
6060
|
if (options.facet !== void 0) return new ActorContainerImpl(options, db, void 0, options.facet.tree);
|
|
5832
|
-
const
|
|
6061
|
+
const facetDb = await options.ports.sql.open(FACET_DATABASE_NAME);
|
|
6062
|
+
ensureRuntimeStorageVersion(facetDb, FACET_DATABASE_NAME);
|
|
6063
|
+
const tree = new ActorTree(facetDb, options.ports.facets);
|
|
5833
6064
|
return new ActorContainerImpl(options, db, tree, tree);
|
|
5834
6065
|
}
|
|
5835
6066
|
//#endregion
|