@somewhere-tech/cli 0.29.1 → 0.30.1

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.
Files changed (45) hide show
  1. package/dist/commands/auth.js +50 -4
  2. package/dist/commands/auth.js.map +1 -1
  3. package/dist/commands/browser.js +115 -16
  4. package/dist/commands/browser.js.map +1 -1
  5. package/dist/commands/check.js +7 -0
  6. package/dist/commands/check.js.map +1 -1
  7. package/dist/commands/deploy.js +82 -6
  8. package/dist/commands/deploy.js.map +1 -1
  9. package/dist/commands/dev.js +64 -7
  10. package/dist/commands/dev.js.map +1 -1
  11. package/dist/commands/docs.js +139 -7
  12. package/dist/commands/docs.js.map +1 -1
  13. package/dist/commands/errors.js +29 -6
  14. package/dist/commands/errors.js.map +1 -1
  15. package/dist/commands/status.js +89 -4
  16. package/dist/commands/status.js.map +1 -1
  17. package/dist/lib/client.js +59 -4
  18. package/dist/lib/client.js.map +1 -1
  19. package/dist/lib/config.js +18 -0
  20. package/dist/lib/config.js.map +1 -1
  21. package/dist/lib/files.js +57 -6
  22. package/dist/lib/files.js.map +1 -1
  23. package/dist/lib/output.js +4 -2
  24. package/dist/lib/output.js.map +1 -1
  25. package/dist/lib/publish-surface.js +94 -0
  26. package/dist/lib/publish-surface.js.map +1 -0
  27. package/dist/local/browser-run.js +321 -0
  28. package/dist/local/browser-run.js.map +1 -0
  29. package/dist/local/chrome.js +320 -0
  30. package/dist/local/chrome.js.map +1 -0
  31. package/dist/local/compiler.js +67 -12
  32. package/dist/local/compiler.js.map +1 -1
  33. package/dist/local/runtime.js +72 -2
  34. package/dist/local/runtime.js.map +1 -1
  35. package/dist/local/telemetry-filter.js +120 -0
  36. package/dist/local/telemetry-filter.js.map +1 -0
  37. package/npm-shrinkwrap.json +2 -2
  38. package/package.json +2 -2
  39. package/runtime/VENDOR.json +4 -3
  40. package/runtime/browser-probes.mjs +6 -0
  41. package/runtime/compiler/VENDOR.json +40 -3
  42. package/runtime/compiler/compile-core.cjs +18 -0
  43. package/runtime/compiler/typed-functions.cjs +31 -1
  44. package/runtime/platform-context.mjs +241 -23
  45. package/runtime/sw-init.mjs +1 -1
@@ -1,4 +1,4 @@
1
- // VENDORED from worker/src/runtime/context.ts (PLATFORM_CONTEXT_JS) @ 3326a8d8
1
+ // VENDORED from worker/src/runtime/context.ts (PLATFORM_CONTEXT_JS) @ 1bf981dd
2
2
  // — the exact runtime deployed functions run against. Do not edit by hand;
3
3
  // re-sync with: node scripts/extract-runtime.mjs <monorepo>
4
4
  // ── Primordial freeze (tsk_327fe8a4, opinionated-not-greenfield) ───────────
@@ -128,9 +128,13 @@ function __sw_initTrace(request) {
128
128
  traceId: inbound ? inbound.traceId : __sw_randHex(16),
129
129
  spanId: __sw_randHex(8),
130
130
  parentSpanId: inbound ? inbound.parentSpanId : null,
131
- // A function has no sampling policy of its own: it honors an inbound
132
- // decision and otherwise records. The platform is the single place the
133
- // 1-in-N rate is configured, and it applies that rate to its own spans.
131
+ // A function has no sampling policy of its own. An inbound decision to
132
+ // DROP is honored; otherwise this is "no opinion", not "store this" --
133
+ // the platform applies TRACE_SAMPLE_RATE deterministically on the trace
134
+ // id, both on its own hops and when these spans are posted to
135
+ // /v1/traces, so the whole chain is kept or dropped together
136
+ // (tsk_07a7465a). Before that this true was load-bearing and exempted
137
+ // every runtime-originated request from sampling entirely.
134
138
  sampled: inbound ? inbound.sampled : true,
135
139
  tracestate: __sw_traceHeader(request, 'tracestate', 512),
136
140
  baggage: __sw_traceHeader(request, 'baggage', 8192),
@@ -1069,6 +1073,24 @@ function buildPlatformContext(env, request, runtimeFetch = fetch, outboundFetch
1069
1073
  err.__sw_expose = true;
1070
1074
  return err;
1071
1075
  }
1076
+ // A PLAN answer, not a connection failure. The platform refuses the
1077
+ // local loop's database calls on a plan without the local-dev database
1078
+ // entitlement, and its message already names the plans, this account's
1079
+ // plan, and that deploying is unaffected. Surfacing it verbatim is the
1080
+ // whole fix: this used to fall through to connectionNotReady below,
1081
+ // whose copy tells the developer to redeploy the function — a
1082
+ // remediation that has never changed this answer (tsk_4df056ea).
1083
+ function planGateError(body) {
1084
+ const code = body && (body.error || body.code);
1085
+ if (code !== 'LOCAL_DEV_DB_NOT_ENABLED' && code !== 'CLOUD_DEV_NOT_ENABLED') return null;
1086
+ const err = new Error((body && body.message) ||
1087
+ 'This plan does not include reaching the project database from `somewhere dev`. `somewhere deploy` publishes on every plan.');
1088
+ err.code = code;
1089
+ err.status = 403;
1090
+ err.retryable = false;
1091
+ err.__sw_expose = true;
1092
+ return err;
1093
+ }
1072
1094
  function connectionNotReady(operation, response, body) {
1073
1095
  const upstreamCode = body && (body.error || body.code);
1074
1096
  if (response.status !== 401 && response.status !== 403) return null;
@@ -1095,6 +1117,8 @@ function buildPlatformContext(env, request, runtimeFetch = fetch, outboundFetch
1095
1117
  try { j = txt ? JSON.parse(txt) : null; } catch (_) { j = null; }
1096
1118
  const managedErr = managedCapabilityError(j);
1097
1119
  if (managedErr) throw managedErr;
1120
+ const planErr = planGateError(j);
1121
+ if (planErr) throw planErr;
1098
1122
  const responseCode = j && (j.error || j.code);
1099
1123
  const isolationCode = draftExecution && responseCode === 'DRAFT_DB_NOT_ISOLATED'
1100
1124
  ? 'DRAFT_DB_NOT_ISOLATED'
@@ -1181,6 +1205,8 @@ function buildPlatformContext(env, request, runtimeFetch = fetch, outboundFetch
1181
1205
  if (!r.ok || !j || j.ok === false) {
1182
1206
  const managedErr = managedCapabilityError(j);
1183
1207
  if (managedErr) throw managedErr;
1208
+ const planErr = planGateError(j);
1209
+ if (planErr) throw planErr;
1184
1210
  const connectionErr = connectionNotReady('batch', r, j);
1185
1211
  if (connectionErr) throw connectionErr;
1186
1212
  const sizeErr = responseSizeError(r, j, 'The database rejected this batch because an input exceeded a size limit.');
@@ -2728,6 +2754,20 @@ function buildPlatformContext(env, request, runtimeFetch = fetch, outboundFetch
2728
2754
  }
2729
2755
  return v; // unknown declared type: fail open on typing, never on transport
2730
2756
  }
2757
+ // Refuse BEFORE the write a whole number the database cannot store as one
2758
+ // (tsk_daf4d6d2). Whole numbers are kept as 64-bit values; anything past
2759
+ // that range is stored as an approximate decimal and can never be read
2760
+ // back exactly, so it must be refused up front rather than discovered
2761
+ // after the row has already landed. A column declared as a decimal
2762
+ // ('number') is exempt: large decimals are legitimate there.
2763
+ function __sw_structAssertStorableWholeNumber(verb, table, column, v, col) {
2764
+ if (typeof v !== 'number' || !Number.isInteger(v)) return;
2765
+ if (col && col.t === 'number') return;
2766
+ if (v < 9223372036854775808 && v >= -9223372036854775808) return;
2767
+ __sw_structThrowSchema('DATABASE_VALUE_TOO_LARGE',
2768
+ 'sw.db.' + verb + ' on "' + table + '": the value for "' + column + '" is outside the range of whole numbers this database stores ' +
2769
+ '(-9223372036854775808 to 9223372036854775807). Keep the value inside that range, or store it as text.');
2770
+ }
2731
2771
  function __sw_structAssertKnownColumn(verb, table, shape, ownerColumn, name, where) {
2732
2772
  if (ownerColumn && __sw_lower(name) === __sw_lower(ownerColumn)) return;
2733
2773
  if (__sw_structFindDeclaredColumn(shape, name)) return;
@@ -2749,6 +2789,7 @@ function buildPlatformContext(env, request, runtimeFetch = fetch, outboundFetch
2749
2789
  if (v !== null && typeof v === 'object') {
2750
2790
  __sw_structThrow('sw.db.' + verb + ' value for "' + ir.values[i].column + '": values must be a string, number, boolean, or null (got object).');
2751
2791
  }
2792
+ __sw_structAssertStorableWholeNumber(verb, table, ir.values[i].column, v, null);
2752
2793
  }
2753
2794
  return;
2754
2795
  }
@@ -2761,6 +2802,7 @@ function buildPlatformContext(env, request, runtimeFetch = fetch, outboundFetch
2761
2802
  for (let i = 0; i < ir.values.length; i++) {
2762
2803
  __sw_structAssertKnownColumn(verb, table, shape, null, ir.values[i].column, verb === 'update' ? 'set' : 'values');
2763
2804
  const col = __sw_structFindDeclaredColumn(shape, ir.values[i].column);
2805
+ __sw_structAssertStorableWholeNumber(verb, table, ir.values[i].column, ir.values[i].value, col);
2764
2806
  ir.values[i].value = __sw_structCheckWriteValue(verb, table, col, ir.values[i].value);
2765
2807
  }
2766
2808
  }
@@ -2902,8 +2944,19 @@ function buildPlatformContext(env, request, runtimeFetch = fetch, outboundFetch
2902
2944
  __sw_structThrow403('TABLE_INTENT_INVALID',
2903
2945
  'sw.db.' + verb + ' on "' + table + '": the table is declared user-owned but its ownership column is missing. Repair the scope declaration (sw.db.scope / db_scope_set), then redeploy.');
2904
2946
  }
2947
+ // Name the file AND the step that applies it (tsk_883e3ede). The old
2948
+ // message pointed only at sw.db.scope / db_scope_set, so a developer
2949
+ // who had already declared the table in db/schema.ts and was running
2950
+ // local dev read it as "your schema file does not count" and
2951
+ // abandoned the managed API for raw SQL. db/schema.ts is applied on a
2952
+ // production deploy only — never from local dev, a preview, or a dry
2953
+ // run — so "declared but not yet deployed" is the single most likely
2954
+ // reason to be reading this, and the message has to say so.
2905
2955
  __sw_structThrow403('TABLE_INTENT_REQUIRED',
2906
- 'sw.db.' + verb + ' on "' + table + '": this table has no declared intent, so the platform cannot prove how to access it safely. Declare it user-owned (sw.db.scope / db_scope_set) to scope it to the signed-in user, or shared for intentional cross-user access — or use raw sw.db.query(sql, params) for manual access.');
2956
+ 'sw.db.' + verb + ' on "' + table + '": this table has no declared intent, so the platform cannot prove how to access it safely. ' +
2957
+ 'Declare it in db/schema.ts — table({ ... }, { scope: owner() }) for per-user rows, shared() for intentional cross-user access, serverOnly() for trusted server access — then run `somewhere deploy`, which is the step that applies db/schema.ts. ' +
2958
+ 'Already declared it there? It needs that one production deploy: local dev, previews and dry runs do not apply the schema file, so the table still reads as undeclared here. ' +
2959
+ 'Not using a schema file? sw.db.scope / db_scope_set declares a table immediately. For manual access, use raw sw.db.query(sql, params).');
2907
2960
  }
2908
2961
  if (asServer === true) {
2909
2962
  // Trusted server code reading cross-user, explicitly. No principal
@@ -2986,12 +3039,83 @@ function buildPlatformContext(env, request, runtimeFetch = fetch, outboundFetch
2986
3039
  }
2987
3040
  }
2988
3041
 
2989
- // THE renderer: a pure function of (IR, principalId). Identifiers are
2990
- // validated + double-quoted; every value including LIMIT/OFFSET is a
3042
+ // ── Whole-number fidelity on the affected-row RETURNING read (tsk_daf4d6d2) ──
3043
+ // The database stores whole numbers as 64-bit values; a JavaScript number
3044
+ // is only exact to 9007199254740991. On a READ the platform recovers the
3045
+ // exact value by re-running the SELECT with a cast-to-text projection
3046
+ // (db-result-fidelity.ts). A WRITE cannot be re-run, so the same guard has
3047
+ // to be INSIDE the statement: the platform composes the RETURNING list
3048
+ // itself and casts any out-of-range whole number to text there, so the
3049
+ // affected row comes back exactly as the read path would return it.
3050
+ // Before this, a write whose affected row held a 64-bit id COMMITTED and
3051
+ // THEN threw DATABASE_VALUE_TOO_LARGE from the read-back — a successful
3052
+ // write reported as a failure, and no structured update to such a row was
3053
+ // possible even when it did not touch that column.
3054
+ //
3055
+ // Column names come from the declared schema when the table is managed
3056
+ // (free) and otherwise from ONE table-shape read, cached for this request.
3057
+ // If the shape cannot be read, or carries a name this builder would not
3058
+ // quote, the statement keeps its long-standing RETURNING * (rule 9: the
3059
+ // fidelity guard must never turn a working write into a failing one).
3060
+ const __sw_returningShapeCache = new Map();
3061
+
3062
+ // The column list RETURNING must project, or null to keep RETURNING *.
3063
+ async function __sw_structReturningColumns(label, table) {
3064
+ const key = __sw_lower(table);
3065
+ if (__sw_returningShapeCache.has(key)) return __sw_returningShapeCache.get(key);
3066
+ let cols = null;
3067
+ const shape = __sw_structManagedShape(table);
3068
+ if (shape) {
3069
+ cols = [];
3070
+ for (let i = 0; i < shape.columns.length; i++) {
3071
+ cols.push({ n: shape.columns[i].n, guard: shape.columns[i].t === 'integer' });
3072
+ }
3073
+ const ownerColumn = __sw_structResolveOwnerColumn(table);
3074
+ if (ownerColumn) {
3075
+ let present = false;
3076
+ for (let i = 0; i < cols.length; i++) if (cols[i].n === __sw_lower(ownerColumn)) present = true;
3077
+ if (!present) cols.push({ n: __sw_lower(ownerColumn), guard: false });
3078
+ }
3079
+ } else if (!__sw_quotableColumnName(table)) {
3080
+ // Unreachable through the builder (the renderer quotes and validates
3081
+ // the table first), and the only place a table name is spelled into
3082
+ // SQL text rather than bound, so it is checked here on its own.
3083
+ cols = null;
3084
+ } else {
3085
+ // hidden = 1 is a virtual table's hidden column, which SELECT * and
3086
+ // RETURNING * both omit; generated columns (2/3) are included by both.
3087
+ const shapeSql = "SELECT name, type, hidden FROM pragma_table_xinfo('" + table + "')";
3088
+ try {
3089
+ const r = await __sw_execOne(label, DB, shapeSql, []);
3090
+ const rows = (r && r.results) || [];
3091
+ const out = [];
3092
+ for (let i = 0; i < rows.length; i++) {
3093
+ const row = rows[i];
3094
+ if (!row || typeof row !== 'object') { out.length = 0; break; }
3095
+ if (Number(row.hidden) === 1) continue;
3096
+ out.push({ n: row.name, guard: __sw_integerCapableAffinity(row.type) });
3097
+ }
3098
+ cols = out.length > 0 ? out : null;
3099
+ } catch (_) {
3100
+ cols = null;
3101
+ }
3102
+ }
3103
+ if (cols) {
3104
+ for (let i = 0; i < cols.length; i++) {
3105
+ if (!__sw_quotableColumnName(cols[i].n)) { cols = null; break; }
3106
+ }
3107
+ }
3108
+ __sw_returningShapeCache.set(key, cols);
3109
+ return cols;
3110
+ }
3111
+
3112
+ // THE renderer: a pure function of (IR, principalId, returning). Identifiers
3113
+ // are validated + double-quoted; every value — including LIMIT/OFFSET — is a
2991
3114
  // bound ?. For 'user' scope it appends "ownerColumn" = ? (and, for
2992
3115
  // INSERT, adds the owner column + value itself). The owner predicate is
2993
- // NEVER in ir.where; the renderer owns it.
2994
- function __sw_renderIR(ir, principalId) {
3116
+ // NEVER in ir.where; the renderer owns it. The 'returning' argument is the
3117
+ // write-path column list resolved above (null keeps RETURNING *).
3118
+ function __sw_renderIR(ir, principalId, returning) {
2995
3119
  // Only the 'project' table arm is renderable today. The IR reserves a
2996
3120
  // 'primitive' arm for future platform primitives (users/calendar/inbox/
2997
3121
  // files) that arrive pre-scoped — but the runtime must REJECT it
@@ -3132,7 +3256,7 @@ function buildPlatformContext(env, request, runtimeFetch = fetch, outboundFetch
3132
3256
  existsSql += ' AND ' + q(m.mg[i]) + ' = ?';
3133
3257
  params.push(gv);
3134
3258
  }
3135
- sql = 'INSERT INTO ' + tableSql + ' (' + colList + ') SELECT ' + placeholders + ' WHERE EXISTS (' + existsSql + ') RETURNING *';
3259
+ sql = 'INSERT INTO ' + tableSql + ' (' + colList + ') SELECT ' + placeholders + ' WHERE EXISTS (' + existsSql + ')' + __sw_returningSql(returning);
3136
3260
  return { sql: sql, params: params };
3137
3261
  }
3138
3262
  sql = 'INSERT INTO ' + tableSql + ' (' + allCols.map(q).join(', ') + ') VALUES (' + allCols.map(function () { return '?'; }).join(', ') + ')';
@@ -3151,13 +3275,13 @@ function buildPlatformContext(env, request, runtimeFetch = fetch, outboundFetch
3151
3275
  sql += ' ON CONFLICT DO UPDATE SET ' + sets.join(', ');
3152
3276
  if (ir.scope.mode === 'user') { sql += ' WHERE ' + q(ir.scope.ownerColumn) + ' = ?'; params.push(principalId); }
3153
3277
  }
3154
- sql += ' RETURNING *';
3278
+ sql += __sw_returningSql(returning);
3155
3279
  } else if (ir.kind === 'update') {
3156
3280
  if (ir.values.length === 0) __sw_structThrow('sw.db.update requires a non-empty set.');
3157
3281
  const assigns = ir.values.map(function (e) { params.push(e.value); return q(e.column) + ' = ?'; });
3158
- sql = 'UPDATE ' + tableSql + ' SET ' + assigns.join(', ') + whereSql() + ' RETURNING *';
3282
+ sql = 'UPDATE ' + tableSql + ' SET ' + assigns.join(', ') + whereSql() + __sw_returningSql(returning);
3159
3283
  } else {
3160
- sql = 'DELETE FROM ' + tableSql + whereSql() + ' RETURNING *';
3284
+ sql = 'DELETE FROM ' + tableSql + whereSql() + __sw_returningSql(returning);
3161
3285
  }
3162
3286
  return { sql: sql, params: params };
3163
3287
  }
@@ -3380,11 +3504,22 @@ function buildPlatformContext(env, request, runtimeFetch = fetch, outboundFetch
3380
3504
  const __sw_t0 = Date.now();
3381
3505
  let rendered;
3382
3506
  try {
3383
- rendered = __sw_renderIR(ir, principalId);
3507
+ rendered = __sw_renderIR(ir, principalId, null);
3384
3508
  } catch (err) {
3385
3509
  __sw_emitQueryEvent(ir, Date.now() - __sw_t0, 0, false, err && err.code);
3386
3510
  throw err;
3387
3511
  }
3512
+ // Writes project their affected row through a fidelity-guarded
3513
+ // RETURNING list (tsk_daf4d6d2). Resolved AFTER the render above so a
3514
+ // rejected call still reaches zero transport, and re-rendered rather
3515
+ // than patched — the renderer is a pure function, so the second pass
3516
+ // produces the same statement with the guarded projection and the
3517
+ // identical bound params. Reads never take this path: same call, same
3518
+ // SQL, same params as before.
3519
+ if (ir.kind === 'insert' || ir.kind === 'update' || ir.kind === 'delete') {
3520
+ const returning = await __sw_structReturningColumns(label, ir.table.name);
3521
+ if (returning) rendered = __sw_renderIR(ir, principalId, returning);
3522
+ }
3388
3523
  let r;
3389
3524
  const liveReadFingerprint = ir.kind === 'select' ? __sw_structFingerprint(ir) : null;
3390
3525
  const liveReadDeclared = !!liveReadFingerprint && LIVE_MANIFEST.liveViews.some(function (view) {
@@ -3945,6 +4080,30 @@ function buildPlatformContext(env, request, runtimeFetch = fetch, outboundFetch
3945
4080
  return err;
3946
4081
  }
3947
4082
 
4083
+ // The same failure on a statement that has ALREADY RUN. Saying so is the
4084
+ // whole point: a caller that reads 'failed' off a committed INSERT retries
4085
+ // it and writes the row twice (tsk_daf4d6d2). Raw SQL is run exactly as
4086
+ // written, so the platform cannot add the cast for the caller here — the
4087
+ // composed writers (sw.db.insert / update / remove) do it themselves.
4088
+ function __sw_exactIntegerWriteError(column) {
4089
+ const err = new Error(
4090
+ 'The statement ran and its changes were applied, but the row it returned holds an integer outside ' +
4091
+ "JavaScript's exact number range in column " + JSON.stringify(String(column)) + ', which cannot be read ' +
4092
+ 'back exactly afterwards. Do not retry the statement. Select the column as CAST(' +
4093
+ __sw_quoteResultColumn(column) + ' AS TEXT) in the RETURNING list, or write through sw.db.insert / ' +
4094
+ 'sw.db.update / sw.db.remove, which compose that cast for you.'
4095
+ );
4096
+ err.code = 'DATABASE_VALUE_TOO_LARGE';
4097
+ err.status = 400;
4098
+ err.__sw_expose = true;
4099
+ return err;
4100
+ }
4101
+
4102
+ function __sw_dbStatementApplied(sql) {
4103
+ const kind = __sw_dbStatementKind(sql);
4104
+ return kind === 'INSERT' || kind === 'UPDATE' || kind === 'DELETE' || kind === 'REPLACE';
4105
+ }
4106
+
3948
4107
  // THE result-row decoding chokepoint for every sw.db transport and shape:
3949
4108
  // native binding, REST fallback, raw query, structured query, and batch
3950
4109
  // statement results all pass here before customer code can observe them.
@@ -3956,7 +4115,11 @@ function buildPlatformContext(env, request, runtimeFetch = fetch, outboundFetch
3956
4115
  async function __sw_decodeDbResult(database, sql, params, result) {
3957
4116
  const unsafeColumn = __sw_unsafeIntegerResultColumn(result);
3958
4117
  if (!unsafeColumn) return result;
3959
- if (__sw_dbStatementKind(sql) !== 'SELECT') throw __sw_exactIntegerReadError(unsafeColumn);
4118
+ if (__sw_dbStatementKind(sql) !== 'SELECT') {
4119
+ throw __sw_dbStatementApplied(sql)
4120
+ ? __sw_exactIntegerWriteError(unsafeColumn)
4121
+ : __sw_exactIntegerReadError(unsafeColumn);
4122
+ }
3960
4123
 
3961
4124
  const first = result.results && result.results[0];
3962
4125
  if (!first || typeof first !== 'object' || __sw_arrayIsArray(first)) {
@@ -3980,6 +4143,38 @@ function buildPlatformContext(env, request, runtimeFetch = fetch, outboundFetch
3980
4143
  return exact;
3981
4144
  }
3982
4145
 
4146
+ // SQLite column affinity, from the declared type. Only INTEGER, NUMERIC
4147
+ // and BLOB/none affinity can hold a whole number out of exact range —
4148
+ // TEXT affinity stores it as text and REAL affinity as a decimal, neither
4149
+ // of which the read path ever flags. Guarding only these keeps the
4150
+ // composed RETURNING list short on wide tables.
4151
+ function __sw_integerCapableAffinity(declaredType) {
4152
+ const t = __sw_lower(String(declaredType == null ? '' : declaredType));
4153
+ if (t.indexOf('int') !== -1) return true;
4154
+ if (t.indexOf('char') !== -1 || t.indexOf('clob') !== -1 || t.indexOf('text') !== -1) return false;
4155
+ if (t === '' || t.indexOf('blob') !== -1) return true;
4156
+ if (t.indexOf('real') !== -1 || t.indexOf('floa') !== -1 || t.indexOf('doub') !== -1) return false;
4157
+ return true;
4158
+ }
4159
+
4160
+ function __sw_quotableColumnName(name) {
4161
+ return typeof name === 'string' && name.length > 0 && name.length <= 64 &&
4162
+ __sw_reMatch(__SW_STRUCT_IDENT_RE, name);
4163
+ }
4164
+
4165
+ function __sw_returningSql(cols) {
4166
+ if (!cols || cols.length === 0) return ' RETURNING *';
4167
+ const parts = [];
4168
+ for (let i = 0; i < cols.length; i++) {
4169
+ const name = __sw_structQuote(cols[i].n);
4170
+ parts.push(cols[i].guard
4171
+ ? 'CASE WHEN typeof(' + name + ") = 'integer' AND (" + name + ' > 9007199254740991 OR ' +
4172
+ name + ' < -9007199254740991) THEN CAST(' + name + ' AS TEXT) ELSE ' + name + ' END AS ' + name
4173
+ : name);
4174
+ }
4175
+ return ' RETURNING ' + parts.join(', ');
4176
+ }
4177
+
3983
4178
  function __sw_execOne(label, database, sql, params) {
3984
4179
  return __sw_timedExec(label, sql, async function () {
3985
4180
  const result = await __sw_prepOn(database, sql, params).all();
@@ -6617,20 +6812,43 @@ function buildPlatformContext(env, request, runtimeFetch = fetch, outboundFetch
6617
6812
  // resolver; there is no parallel derivation.
6618
6813
  __sw_authResolveRequest = __sw_resolveRequestUser;
6619
6814
  __sw_authVerifyPrincipal = __sw_resolveRequestUser;
6620
- // Ambient visitor identity (tsk_99bec0b4). sw.db's owner() resolver calls
6621
- // this ONLY when there is no verified user AND the project's baked
6622
- // owner-identity mode is 'visitor'. It reads __Host-sw_anon_id from the FROZEN
6623
- // auth snapshot (the same source verified identity is derived from, so
6624
- // customer code cannot spoof or downgrade it), validates the format, and
6625
- // otherwise mints a fresh id AND queues the Set-Cookie itself — there is
6626
- // no caller Response to attach it to on the structured path. Never throws.
6815
+ // Ambient visitor identity (tsk_99bec0b4; made reachable by tsk_11f8f791).
6816
+ // sw.db's owner() resolver calls this ONLY when there is no verified user
6817
+ // AND the project's baked owner-identity mode is 'visitor'. It reads
6818
+ // __Host-sw_anon_id from the FROZEN auth snapshot (the same source verified
6819
+ // identity is derived from, so customer code cannot spoof or downgrade it),
6820
+ // validates the format, and otherwise mints a fresh id AND queues the
6821
+ // Set-Cookie itself — there is no caller Response to attach it to on the
6822
+ // structured path. Never throws.
6823
+ //
6824
+ // What binds the owner predicate, exactly (the security claim):
6825
+ // - ONE channel. The value is read from the __Host-sw_anon_id cookie on the
6826
+ // frozen snapshot and nowhere else — no header, query param, body field,
6827
+ // or sw.db argument can name a visitor. An id offered through any other
6828
+ // channel is not read, so the request is simply a visitor with no cookie
6829
+ // and the platform mints its own.
6830
+ // - NEVER over a verified user. The caller reaches this only when identity
6831
+ // resolution found no verified principal, so a cookie cannot downgrade or
6832
+ // impersonate a signed-in user.
6833
+ // - The anon_ prefix is mandatory, which is what keeps the visitor
6834
+ // namespace disjoint from the app-user namespace: an id shaped like an
6835
+ // app user's (a uuid) fails the test and is discarded, so a visitor
6836
+ // cannot address a signed-in user's rows by naming their id.
6837
+ // - Bounded (tsk_11f8f791): a conforming id is 37 chars; anything past 64
6838
+ // is not ours and is discarded rather than written into an owner column.
6839
+ // - Anything that fails the test is IGNORED, never repaired and never used:
6840
+ // the platform mints a fresh id, so a malformed or hostile cookie yields
6841
+ // a brand-new empty visitor, never a partial or borrowed one.
6842
+ // The conforming value itself is a bearer credential with the same standing
6843
+ // as a session cookie — HttpOnly, Secure, __Host-, 122 bits of entropy —
6844
+ // and is stated as such in the docs. Holding it IS being that visitor.
6627
6845
  __sw_resolveVisitorIdentity = function () {
6628
6846
  let id = null;
6629
6847
  try {
6630
6848
  const ch = __sw_authSnapshotRequest.headers.get('cookie');
6631
6849
  __sw_expireLegacyAuthCookiesIfPresent(ch, request && request.url);
6632
6850
  const existing = __sw_readCookie(ch, '__Host-sw_anon_id');
6633
- if (existing && /^anon_[a-zA-Z0-9_-]{8,}$/.test(existing)) id = existing;
6851
+ if (existing && /^anon_[a-zA-Z0-9_-]{8,64}$/.test(existing)) id = existing;
6634
6852
  } catch (_) { /* fall through and mint */ }
6635
6853
  if (!id) {
6636
6854
  id = 'anon_' + crypto.randomUUID().replace(/-/g, '');
@@ -1,4 +1,4 @@
1
- // VENDORED from worker/src/utils/function-bundle.ts (SW_INIT_JS) @ 3326a8d8
1
+ // VENDORED from worker/src/utils/function-bundle.ts (SW_INIT_JS) @ 1bf981dd
2
2
  // — the exact runtime deployed functions run against. Do not edit by hand;
3
3
  // re-sync with: node scripts/extract-runtime.mjs <monorepo>
4
4
  // Generated by somewhere.tech deploy pipeline. Sets up the global