@substrat-run/control-plane-api 0.156.0 → 0.159.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/api.d.ts.map +1 -1
- package/dist/api.js +15 -4
- package/dist/api.js.map +1 -1
- package/dist/cf-observability.d.ts +0 -5
- package/dist/cf-observability.d.ts.map +1 -1
- package/dist/cf-observability.js +3 -0
- package/dist/cf-observability.js.map +1 -1
- package/dist/email-intent.js +2 -2
- package/dist/email-intent.js.map +1 -1
- package/dist/observability.d.ts +2 -1
- package/dist/observability.d.ts.map +1 -1
- package/dist/observability.js +0 -15
- package/dist/observability.js.map +1 -1
- package/dist/platform-entry.generated.d.ts +1 -1
- package/dist/platform-entry.generated.d.ts.map +1 -1
- package/dist/platform-entry.generated.js +2 -2
- package/dist/platform-entry.generated.js.map +1 -1
- package/package.json +8 -8
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
export const PLATFORM_ENTRY_MODULE = 'substrat-platform-entry.js';
|
|
10
10
|
/** The import specifier the uploader replaces with `./<the bundle's entry>`. */
|
|
11
11
|
export const PLATFORM_ENTRY_PLACEHOLDER = '__SUBSTRAT_VERTICAL_ENTRY__';
|
|
12
|
-
/** The entry itself —
|
|
13
|
-
export const PLATFORM_ENTRY_SOURCE = "// substrat-platform-entry.ts\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\n// packages/contracts/dist/invocation-record.js\nvar INVOCATION_RECORD_HEADER = \"x-substrat-invocation-record\";\nvar REQUEST_ID_HEADER = \"x-substrat-request-id\";\nvar INVOCATION_RECORD_FIELD_MAX = 128;\nvar FIELDS = [\"operation\", \"problemCode\", \"principalKind\"];\nfunction encodeInvocationRecord(record2) {\n const params = new URLSearchParams();\n for (const key of FIELDS) {\n const v = record2[key];\n if (typeof v === \"string\" && v !== \"\")\n params.set(key, v.slice(0, INVOCATION_RECORD_FIELD_MAX));\n }\n const value = params.toString();\n return value === \"\" ? null : value;\n}\nvar FIELD_COVERAGE_HEADER = \"x-substrat-field-coverage\";\nfunction invocationLevelOf(status, threw, problemCode) {\n if (threw || status === null || status >= 500)\n return \"error\";\n if (status >= 400)\n return \"warn\";\n if (problemCode)\n return \"warn\";\n return \"info\";\n}\n\n// packages/contracts/dist/trace-sink.js\nvar TRACE_SINK_KEY = /* @__PURE__ */ Symbol.for(\"substrat.trace-sink\");\nvar STARTS_KEY = /* @__PURE__ */ Symbol.for(\"substrat.trace-starts\");\nfunction starts() {\n const slots = globalThis;\n return slots[STARTS_KEY] ??= /* @__PURE__ */ new Map();\n}\nfunction markTraceStart(invocationId, at = performance.now()) {\n const map = starts();\n if (!map.has(invocationId))\n map.set(invocationId, at);\n}\nfunction forgetTraceStart(invocationId) {\n starts().delete(invocationId);\n}\nfunction installedTraceSink() {\n return globalThis[TRACE_SINK_KEY];\n}\n\n// packages/kernel/dist/invocation-line.js\nfunction invocationLine(f) {\n const emitted = f.emitted;\n return {\n substrat: \"invocation\",\n ...f.kind ? { kind: f.kind } : {},\n tenantId: f.tenantId,\n scopeId: f.scopeId,\n vertical: f.vertical ?? null,\n surface: f.surface ?? null,\n method: f.method ?? null,\n path: f.path ?? null,\n status: f.status ?? null,\n threw: f.threw,\n durationMs: f.durationMs,\n invocationId: f.invocationId,\n level: f.level,\n operation: f.operation ?? null,\n problemCode: f.problemCode ?? null,\n principalKind: f.principalKind ?? null,\n eventCount: emitted ? emitted.total : null,\n eventTypes: emitted ? distinct(emitted.events.map((e) => e.type)) : [],\n entities: emitted && f.withEntities !== false ? distinct(emitted.events.map((e) => e.entity)) : [],\n versionId: f.versionId ?? null,\n ...f.outputFields ? { outputFields: f.outputFields, ...f.fieldCoverageId ? { fieldCoverageId: f.fieldCoverageId } : {} } : {},\n ...f.storeCalls && f.storeCalls.length > 0 ? { storeCalls: f.storeCalls } : {},\n ...f.storeCallsDropped ? { storeCallsDropped: f.storeCallsDropped } : {},\n ...f.outboundCalls && f.outboundCalls.length > 0 ? { outboundCalls: f.outboundCalls } : {},\n ...f.outboundCallsDropped ? { outboundCallsDropped: f.outboundCallsDropped } : {},\n ...f.parentInvocationId ? { parentInvocationId: f.parentInvocationId, ...f.parentScopeId ? { parentScopeId: f.parentScopeId } : {} } : {},\n ...f.async ?? {}\n };\n}\nvar STORE_CALL_LOG_CAP = 16;\nfunction tallyStoreCall(tally, call) {\n const calls = tally.storeCalls ?? (tally.storeCalls = []);\n if (calls.length < STORE_CALL_LOG_CAP) {\n calls.push({ binding: call.binding, operation: call.operation, outcome: call.outcome, durationMs: call.durationMs });\n } else {\n tally.storeCallsDropped = (tally.storeCallsDropped ?? 0) + 1;\n }\n}\nvar OUTBOUND_CALL_LOG_CAP = 16;\nfunction tallyOutboundCall(tally, call) {\n const calls = tally.outboundCalls ?? (tally.outboundCalls = []);\n if (calls.length < OUTBOUND_CALL_LOG_CAP) {\n calls.push({\n host: call.host,\n path: call.path,\n method: call.method,\n status: call.status,\n outcome: call.outcome,\n durationMs: call.durationMs,\n atMs: call.atMs,\n ...call.reason !== void 0 ? { reason: call.reason } : {}\n });\n } else {\n tally.outboundCallsDropped = (tally.outboundCallsDropped ?? 0) + 1;\n }\n}\nvar STORE_CALL_SINK_KEY = \"substrat.store-call-sink\";\nfunction distinct(values) {\n return [...new Set(values)];\n}\n\n// packages/kernel/dist/ulid.js\nvar B32 = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\nvar MAX_ULID_TIME = 2 ** 48 - 1;\nvar ULID_SHAPE = /^[0-9A-HJKMNP-TV-Z]{26}$/;\nvar unencodable = (t) => `not an encodable ULID instant: ${t} (want 0..${MAX_ULID_TIME})`;\nfunction encodeTime(time) {\n let ts = \"\";\n let t = time;\n for (let i = 0; i < 10; i++) {\n ts = B32[t % 32] + ts;\n t = Math.floor(t / 32);\n }\n return ts;\n}\nfunction createUlid() {\n let lastTime = -1;\n const lastRand = new Array(16).fill(0);\n function freshRandom() {\n const bytes = crypto.getRandomValues(new Uint8Array(16));\n for (let i = 0; i < 16; i++)\n lastRand[i] = bytes[i] % 32;\n }\n function incrementRandom() {\n for (let i = 15; i >= 0; i--) {\n if (lastRand[i] < 31) {\n lastRand[i]++;\n return true;\n }\n lastRand[i] = 0;\n }\n return false;\n }\n const mint = ((now = Date.now()) => {\n if (!Number.isSafeInteger(now))\n throw new RangeError(unencodable(now));\n let time = now;\n if (time <= lastTime) {\n time = lastTime;\n if (!incrementRandom()) {\n time = lastTime + 1;\n freshRandom();\n }\n } else {\n freshRandom();\n }\n if (time < 0 || time > MAX_ULID_TIME)\n throw new RangeError(unencodable(time));\n lastTime = time;\n let r = \"\";\n for (const d of lastRand)\n r += B32[d];\n return encodeTime(time) + r;\n });\n mint.seedFrom = (id) => {\n const time = ulidTime(id);\n if (time < lastTime)\n return;\n const rand = [];\n for (const ch of id.slice(10))\n rand.push(B32.indexOf(ch));\n if (time === lastTime) {\n let ahead = false;\n for (let i = 0; i < 16; i++) {\n if (rand[i] !== lastRand[i]) {\n ahead = rand[i] > lastRand[i];\n break;\n }\n }\n if (!ahead)\n return;\n }\n lastTime = time;\n for (let i = 0; i < 16; i++)\n lastRand[i] = rand[i];\n };\n return mint;\n}\nvar processUlid = createUlid();\nfunction ulid(now = Date.now()) {\n return processUlid(now);\n}\nfunction ulidTime(id) {\n if (!ULID_SHAPE.test(id))\n throw new Error(`not a ULID: ${id}`);\n let t = 0;\n for (const ch of id.slice(0, 10))\n t = t * 32 + B32.indexOf(ch);\n if (t > MAX_ULID_TIME)\n throw new Error(`not a ULID: ${id}`);\n return t;\n}\n\n// packages/vertical-host/src/outbound-calls.ts\nvar EGRESS_REFUSAL_HEADER = \"x-substrat-egress\";\nvar STORE_CALL_HOST = \"store.substrat.internal\";\nvar REDACTED = \"[redacted]\";\nvar PATH_MAX = 200;\nvar WORDS = /^[a-z]{1,16}(?:[-_][a-z]{1,16}){0,3}$/;\nvar WORDS_WITH_EXTENSION = /^[a-z]{1,16}(?:[-_][a-z]{1,16}){0,3}\\.[a-z][a-z0-9]{0,4}$/;\nvar SEGMENT_MAX = 40;\nvar SMALL_INTEGER = /^[0-9]{1,10}$/;\nvar VERSION = /^v[0-9]{1,3}(?:\\.[0-9]{1,3}){0,2}$/;\nfunction keepsSegment(segment) {\n if (segment.length > SEGMENT_MAX) return false;\n return segment === \"\" || WORDS.test(segment) || WORDS_WITH_EXTENSION.test(segment) || SMALL_INTEGER.test(segment) || VERSION.test(segment);\n}\nfunction redactOutboundPath(pathname) {\n const path = pathname.split(\"/\").map((segment) => keepsSegment(segment) ? segment : REDACTED).join(\"/\");\n return path.length > PATH_MAX ? `${path.slice(0, PATH_MAX)}…` : path;\n}\nvar ERROR_CLASS = /^[A-Z][A-Za-z]{0,30}(?:Error|Exception)$/;\nfunction errorName(e) {\n const name = e?.name;\n return typeof name === \"string\" && ERROR_CLASS.test(name) ? name : \"Error\";\n}\nfunction answeredOutcome(response) {\n if (response.status === 403 && response.headers?.get?.(EGRESS_REFUSAL_HEADER) === \"refused\") return \"refused\";\n return response.status >= 400 ? \"http-error\" : \"ok\";\n}\nfunction rejectedOutcome(e) {\n const name = errorName(e);\n if (name === \"TimeoutError\") return { outcome: \"timeout\" };\n if (name === \"AbortError\") return { outcome: \"aborted\" };\n return { outcome: \"failed\", reason: name };\n}\nvar SINCE = /* @__PURE__ */ Symbol.for(\"substrat.outbound-since\");\nfunction sinceMap() {\n const g = globalThis;\n return g[SINCE] ??= /* @__PURE__ */ new WeakMap();\n}\nfunction markRequestStart(recording, started) {\n try {\n sinceMap().set(recording, started);\n } catch {\n }\n}\nfunction destinationOf(input, init) {\n const fromRequest = typeof input === \"object\" && input !== null && !(input instanceof URL);\n const raw = fromRequest ? input.url : input;\n let url;\n try {\n url = new URL(String(raw));\n } catch {\n return null;\n }\n const initMethod = init?.method;\n const requestMethod = fromRequest ? input.method : void 0;\n const method = typeof initMethod === \"string\" ? initMethod : typeof requestMethod === \"string\" ? requestMethod : \"GET\";\n return { url, method: method.toUpperCase().slice(0, 16) };\n}\nfunction record(recording, destination, startedAt, end) {\n try {\n const call = {\n host: destination.url.host.toLowerCase(),\n path: redactOutboundPath(destination.url.pathname),\n method: destination.method,\n status: end.status,\n outcome: end.outcome,\n durationMs: Math.max(0, Date.now() - startedAt),\n atMs: Math.max(0, startedAt - (sinceMap().get(recording) ?? startedAt)),\n ...end.reason !== void 0 ? { reason: end.reason } : {}\n };\n tallyOutboundCall(recording, call);\n } catch {\n }\n}\nvar WRAPPED = /* @__PURE__ */ Symbol.for(\"substrat.outbound-fetch\");\nvar IN_CALL = /* @__PURE__ */ Symbol.for(\"substrat.outbound-fetch.in-call\");\nfunction recordingFetch(original, current) {\n const wrapped = function fetch(input, init) {\n const g = globalThis;\n if (g[IN_CALL] === true) return original.call(globalThis, input, init);\n let recording;\n let destination = null;\n try {\n recording = current();\n if (recording) destination = destinationOf(input, init);\n } catch {\n recording = void 0;\n }\n if (!recording || !destination || destination.url.hostname.toLowerCase() === STORE_CALL_HOST) {\n return original.call(globalThis, input, init);\n }\n const rec = recording;\n const dest = destination;\n const startedAt = Date.now();\n let pending;\n g[IN_CALL] = true;\n try {\n pending = original.call(globalThis, input, init);\n } finally {\n g[IN_CALL] = false;\n }\n return pending.then(\n (response) => {\n let status = null;\n let outcome = \"failed\";\n try {\n status = response.status;\n outcome = answeredOutcome(response);\n } catch {\n }\n record(rec, dest, startedAt, { status, outcome });\n return response;\n },\n (e) => {\n let end = { outcome: \"failed\", reason: \"Error\" };\n try {\n end = rejectedOutcome(e);\n } catch {\n }\n record(rec, dest, startedAt, { status: null, ...end });\n throw e;\n }\n );\n };\n Object.defineProperty(wrapped, WRAPPED, { value: true });\n return wrapped;\n}\nfunction installOutboundRecorder(current) {\n try {\n const g = globalThis;\n const existing = g.fetch;\n if (typeof existing !== \"function\" || existing[WRAPPED]) return;\n g.fetch = recordingFetch(existing, current);\n } catch {\n }\n}\n\n// packages/contracts/dist/wire-auth.js\nfunction secretMatches(presented, expected) {\n const given = presented ?? \"\";\n let diff = given.length ^ expected.length | (given.length === 0 ? 1 : 0);\n for (let i = 0; i < expected.length; i++) {\n diff |= (i < given.length ? given.charCodeAt(i) : 0) ^ expected.charCodeAt(i);\n }\n return diff === 0;\n}\n\n// packages/vertical-host/src/routed-node.ts\nvar ROUTED_ID = /^[0-9A-HJKMNP-TV-Z]{26}$/;\nvar RouterAssertionError = class extends Error {\n};\nfunction readRoutedNode(headers, options = {}) {\n const rawTenant = headers.get(\"x-substrat-tenant\");\n const rawScope = headers.get(\"x-substrat-scope\");\n if (!rawTenant && !rawScope) return null;\n const { expectedSecret, allowUnsigned = false } = options;\n if (expectedSecret) {\n if (!secretMatches(headers.get(\"x-substrat-router\"), expectedSecret)) {\n throw new RouterAssertionError(\"router assertion is not signed by a known router\");\n }\n } else if (!allowUnsigned) {\n throw new RouterAssertionError(\n \"router assertion cannot be verified: this worker has no ROUTER_SECRET configured\"\n );\n }\n if (!rawTenant || !rawScope) {\n throw new RouterAssertionError(\"router assertion is incomplete\");\n }\n if (!ROUTED_ID.test(rawTenant) || !ROUTED_ID.test(rawScope)) {\n throw new RouterAssertionError(\"router assertion carries a malformed id\");\n }\n return {\n tenantId: rawTenant,\n scopeId: rawScope,\n surface: headers.get(\"x-substrat-surface\") ?? \"app\",\n verticalSlug: headers.get(\"x-substrat-vertical\")\n };\n}\n\n// packages/vertical-host/src/invocation-log.ts\nfunction builtinAsyncLocalStorage() {\n try {\n const proc = globalThis.process;\n const mod = proc?.getBuiltinModule?.(\"node:async_hooks\");\n return typeof mod?.AsyncLocalStorage === \"function\" ? mod.AsyncLocalStorage : void 0;\n } catch {\n return void 0;\n }\n}\nfunction storeCallSlot(provided) {\n try {\n const g = globalThis;\n const key = Symbol.for(STORE_CALL_SINK_KEY);\n const existing = g[key];\n if (typeof existing?.run === \"function\" && typeof existing.current === \"function\") return existing;\n const Als = provided ?? builtinAsyncLocalStorage();\n if (!Als) return void 0;\n const storage = new Als();\n const slot = {\n current() {\n const tally = storage.getStore()?.tally;\n return tally ? (call) => tallyStoreCall(tally, call) : void 0;\n },\n invocationId: () => storage.getStore()?.invocationId,\n run: (tally, fn, invocationId) => storage.run({ tally, invocationId }, fn),\n recording: () => storage.getStore()?.tally\n };\n g[key] = slot;\n return slot;\n } catch {\n return void 0;\n }\n}\nfunction currentRecording() {\n const slot = globalThis[Symbol.for(STORE_CALL_SINK_KEY)];\n return typeof slot?.recording === \"function\" ? slot.recording() : void 0;\n}\nfunction runRecording(stamp, started, provided, fn) {\n const slot = storeCallSlot(provided);\n if (!slot) return fn();\n markRequestStart(stamp.record, started);\n installOutboundRecorder(currentRecording);\n return slot.run(stamp.record, fn, stamp.invocationId);\n}\nfunction versionIdOf(env) {\n const v = env?.SUBSTRAT_VERSION_ID;\n return typeof v === \"string\" && v.length > 0 ? v : null;\n}\nvar UPLOAD_LINK_LOG_SECRET_PREFIX = \"sbup_\";\nvar UPLOAD_LINK_SECRET_SEGMENT = /^(\\/api\\/attachment-uploads\\/[^/]+\\/[^/]+\\/)[^/]+/;\nvar SECRET_SHAPED_SEGMENT = new RegExp(`(^|/)${UPLOAD_LINK_LOG_SECRET_PREFIX}[^/]*`, \"g\");\nvar redactUploadLinkSecret = (pathname) => pathname.replace(UPLOAD_LINK_SECRET_SEGMENT, \"$1[redacted]\").replace(SECRET_SHAPED_SEGMENT, \"$1[redacted]\");\nfunction pathOf(url) {\n try {\n return redactUploadLinkSecret(new URL(url).pathname);\n } catch {\n return \"/\";\n }\n}\nvar STAMPS = /* @__PURE__ */ Symbol.for(\"substrat.invocation-stamp\");\nfunction stamps() {\n const g = globalThis;\n return g[STAMPS] ??= /* @__PURE__ */ new WeakMap();\n}\nfunction invocationStampOf(request) {\n return stamps().get(request);\n}\nfunction withRequestId(response, id) {\n const headers = response?.headers;\n try {\n headers?.set?.(REQUEST_ID_HEADER, id);\n return response;\n } catch {\n }\n try {\n const r = response;\n if (r.status === 101) return response;\n const copy = new Response(r.body, r);\n copy.headers.set(REQUEST_ID_HEADER, id);\n return copy;\n } catch {\n return response;\n }\n}\nfunction beginStamp(request, env, options) {\n const stamp = { invocationId: ulid(), record: {} };\n if (installedTraceSink()) markTraceStart(stamp.invocationId);\n const fieldCoverageId = armedFieldCoverageId(request.headers, env, options);\n if (fieldCoverageId) stamp.fieldCoverageId = fieldCoverageId;\n stamps().set(request, stamp);\n return stamp;\n}\nfunction armedFieldCoverageId(headers, env, options) {\n let id;\n try {\n id = headers.get(FIELD_COVERAGE_HEADER);\n } catch {\n return void 0;\n }\n if (id === null || !ROUTED_ID.test(id)) return void 0;\n return routedNodeOrNull(headers, env, options) !== null ? id : void 0;\n}\nfunction writeInvocationLine(stamp, done, options) {\n traceRequest(stamp, done);\n try {\n writeLineOrThrow(stamp, done, options);\n } catch (e) {\n try {\n console.log(JSON.stringify({ substrat: \"invocation-log-fault\", detail: String(e) }));\n } catch {\n }\n }\n}\nfunction traceRequest(stamp, done) {\n const sink = installedTraceSink();\n if (!sink) return;\n try {\n const { record: record2, invocationId } = stamp;\n const durationMs = Date.now() - done.started;\n const line = invocationLine({\n tenantId: \"\",\n scopeId: null,\n vertical: null,\n surface: null,\n method: done.request.method,\n path: pathOf(done.request.url),\n status: done.status,\n threw: done.threw,\n durationMs,\n invocationId,\n level: invocationLevelOf(done.status, done.threw, record2.problemCode),\n operation: record2.operation,\n problemCode: record2.problemCode,\n principalKind: record2.principalKind,\n ...record2.emitted ? { emitted: record2.emitted } : {},\n versionId: versionIdOf(done.env)\n });\n sink.head(invocationId, {\n startedAt: new Date(done.started).toISOString(),\n method: line.method,\n path: line.path,\n status: line.status,\n threw: line.threw,\n durationMs: line.durationMs,\n level: line.level,\n operation: line.operation,\n problemCode: line.problemCode,\n principalKind: line.principalKind,\n eventCount: line.eventCount,\n eventTypes: line.eventTypes,\n entities: line.entities,\n versionId: line.versionId,\n // Calls the record kept no room for: a truncated list must read as truncated.\n ...record2.outboundCallsDropped ? { stepsDropped: record2.outboundCallsDropped } : {}\n });\n for (const call of record2.outboundCalls ?? []) {\n sink.step(invocationId, {\n type: \"outbound\",\n atMs: call.atMs,\n durationMs: call.durationMs,\n host: call.host,\n path: call.path,\n method: call.method,\n status: call.status,\n outcome: call.outcome,\n ...call.reason ? { reason: call.reason } : {}\n });\n }\n sink.end(invocationId);\n forgetTraceStart(invocationId);\n } catch {\n }\n}\nfunction writeLineOrThrow(stamp, done, options) {\n const node = routedNodeOrNull(done.request.headers, done.env, options);\n if (!node) return;\n const { record: record2, invocationId } = stamp;\n const line = invocationLine({\n tenantId: node.tenantId,\n scopeId: node.scopeId,\n vertical: node.verticalSlug,\n surface: node.surface,\n method: done.request.method,\n path: pathOf(done.request.url),\n status: done.status,\n threw: done.threw,\n durationMs: Date.now() - done.started,\n invocationId,\n level: invocationLevelOf(done.status, done.threw, record2.problemCode),\n operation: record2.operation,\n problemCode: record2.problemCode,\n principalKind: record2.principalKind,\n ...record2.emitted ? { emitted: record2.emitted } : {},\n versionId: versionIdOf(done.env),\n ...record2.outputFields ? { outputFields: record2.outputFields } : {},\n ...stamp.fieldCoverageId ? { fieldCoverageId: stamp.fieldCoverageId } : {},\n ...record2.storeCalls && record2.storeCalls.length > 0 ? { storeCalls: record2.storeCalls } : {},\n ...record2.storeCallsDropped ? { storeCallsDropped: record2.storeCallsDropped } : {},\n ...record2.outboundCalls && record2.outboundCalls.length > 0 ? { outboundCalls: record2.outboundCalls } : {},\n ...record2.outboundCallsDropped ? { outboundCallsDropped: record2.outboundCallsDropped } : {}\n });\n console.log(JSON.stringify(line));\n}\nvar OTHER_HANDLERS = [\"scheduled\", \"queue\", \"email\", \"tail\", \"trace\", \"alarm\", \"test\"];\nfunction withInvocationLog(worker, options = {}) {\n const inner = worker?.fetch;\n if (typeof inner !== \"function\") return worker;\n const wrapped = {\n async fetch(request, env, ctx) {\n if (invocationStampOf(request)) return inner.call(worker, request, env, ctx);\n const started = Date.now();\n const stamp = beginStamp(request, env, options);\n let status = null;\n let threw = false;\n try {\n const response = withRequestId(\n await runRecording(stamp, started, options.asyncLocalStorage, () => inner.call(worker, request, env, ctx)),\n stamp.invocationId\n );\n status = response.status;\n handRecordToRouter(response, stamp.record, request, env, options);\n return response;\n } catch (e) {\n threw = true;\n throw e;\n } finally {\n writeInvocationLine(stamp, { request, env, status, threw, started }, options);\n }\n }\n };\n for (const name of OTHER_HANDLERS) {\n const h = worker[name];\n if (typeof h === \"function\") wrapped[name] = h.bind(worker);\n }\n return wrapped;\n}\nfunction handRecordToRouter(response, record2, request, env, options) {\n try {\n const value = encodeInvocationRecord(record2);\n if (value === null || !routedNodeOrNull(request.headers, env, options)) return;\n response.headers?.set?.(\n INVOCATION_RECORD_HEADER,\n value\n );\n } catch {\n }\n}\nfunction routedNodeOrNull(headers, env, options) {\n try {\n return readRoutedNode(headers, {\n expectedSecret: options.routerSecret?.(env),\n allowUnsigned: options.allowUnsigned?.(env) ?? false\n });\n } catch (e) {\n if (!(e instanceof RouterAssertionError)) console.log(JSON.stringify({ substrat: \"invocation-log-fault\", detail: String(e) }));\n return null;\n }\n}\n\n// substrat-platform-entry.ts\nimport * as vertical from \"__SUBSTRAT_VERTICAL_ENTRY__\";\nexport * from \"__SUBSTRAT_VERTICAL_ENTRY__\";\nvar substrat_platform_entry_default = withInvocationLog(vertical.default, {\n routerSecret: (env) => env.ROUTER_SECRET,\n allowUnsigned: (env) => env.ALLOW_DEV_NODE === \"true\",\n asyncLocalStorage: AsyncLocalStorage\n});\nexport {\n substrat_platform_entry_default as default\n};\n";
|
|
12
|
+
/** The entry itself — 24369 bytes of ESM. */
|
|
13
|
+
export const PLATFORM_ENTRY_SOURCE = "// substrat-platform-entry.ts\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\n// packages/contracts/dist/auth-diagnostics.js\nvar AUTH_CHECK_STAGES = [\"bearer\", \"session\", \"mcp-audience\", \"mcp-caller\"];\nvar AUTH_CHECK_OUTCOMES = [\"accepted\", \"refused\", \"absent\", \"error\"];\nvar AUTH_CHECK_REASONS = [\n \"verified\",\n \"session-invalid\",\n \"credential-missing\",\n \"discovery-failed\",\n \"key-resolution-failed\",\n \"token-expired\",\n \"token-not-active\",\n \"issuer-invalid\",\n \"audience-invalid\",\n \"claims-invalid\",\n \"signature-invalid\",\n \"token-invalid\",\n \"verification-failed\",\n \"subject-missing\",\n \"assertion-not-access-token\",\n \"delegation-refused\",\n \"token-not-for-app\",\n \"resource-mismatch\",\n \"caller-resolved\",\n \"caller-refused\",\n \"caller-error\"\n];\nvar AUTH_CHECK_CAP = 16;\nvar AUTH_DIAGNOSTICS_KEY = /* @__PURE__ */ Symbol.for(\"substrat.auth-diagnostics\");\nfunction authCheckOf(value) {\n if (!value || typeof value !== \"object\")\n return void 0;\n const v = value;\n if (!AUTH_CHECK_STAGES.includes(v.stage) || !AUTH_CHECK_OUTCOMES.includes(v.outcome) || !AUTH_CHECK_REASONS.includes(v.reason))\n return void 0;\n return { stage: v.stage, outcome: v.outcome, reason: v.reason };\n}\nfunction tallyAuthCheck(record2, value) {\n const check = authCheckOf(value);\n if (!check)\n return;\n const checks = record2.authChecks ??= [];\n if (checks.length < AUTH_CHECK_CAP)\n checks.push(check);\n else\n record2.authChecksDropped = (record2.authChecksDropped ?? 0) + 1;\n}\n\n// packages/contracts/dist/invocation-record.js\nvar INVOCATION_RECORD_HEADER = \"x-substrat-invocation-record\";\nvar REQUEST_ID_HEADER = \"x-substrat-request-id\";\nvar INVOCATION_RECORD_FIELD_MAX = 128;\nvar FIELDS = [\"operation\", \"problemCode\", \"principalKind\"];\nfunction encodeInvocationRecord(record2) {\n const params = new URLSearchParams();\n for (const key of FIELDS) {\n const v = record2[key];\n if (typeof v === \"string\" && v !== \"\")\n params.set(key, v.slice(0, INVOCATION_RECORD_FIELD_MAX));\n }\n const value = params.toString();\n return value === \"\" ? null : value;\n}\nvar FIELD_COVERAGE_HEADER = \"x-substrat-field-coverage\";\nfunction invocationLevelOf(status, threw, problemCode) {\n if (threw || status === null || status >= 500)\n return \"error\";\n if (status >= 400)\n return \"warn\";\n if (problemCode)\n return \"warn\";\n return \"info\";\n}\n\n// packages/contracts/dist/trace-sink.js\nvar TRACE_SINK_KEY = /* @__PURE__ */ Symbol.for(\"substrat.trace-sink\");\nvar STARTS_KEY = /* @__PURE__ */ Symbol.for(\"substrat.trace-starts\");\nfunction starts() {\n const slots = globalThis;\n return slots[STARTS_KEY] ??= /* @__PURE__ */ new Map();\n}\nfunction markTraceStart(invocationId, at = performance.now()) {\n const map = starts();\n if (!map.has(invocationId))\n map.set(invocationId, at);\n}\nfunction forgetTraceStart(invocationId) {\n starts().delete(invocationId);\n}\nfunction installedTraceSink() {\n return globalThis[TRACE_SINK_KEY];\n}\n\n// packages/kernel/dist/invocation-line.js\nfunction invocationLine(f) {\n const emitted = f.emitted;\n return {\n substrat: \"invocation\",\n ...f.kind ? { kind: f.kind } : {},\n tenantId: f.tenantId,\n scopeId: f.scopeId,\n vertical: f.vertical ?? null,\n surface: f.surface ?? null,\n method: f.method ?? null,\n path: f.path ?? null,\n status: f.status ?? null,\n threw: f.threw,\n durationMs: f.durationMs,\n invocationId: f.invocationId,\n level: f.level,\n operation: f.operation ?? null,\n problemCode: f.problemCode ?? null,\n principalKind: f.principalKind ?? null,\n eventCount: emitted ? emitted.total : null,\n eventTypes: emitted ? distinct(emitted.events.map((e) => e.type)) : [],\n entities: emitted && f.withEntities !== false ? distinct(emitted.events.map((e) => e.entity)) : [],\n versionId: f.versionId ?? null,\n ...f.outputFields ? { outputFields: f.outputFields, ...f.fieldCoverageId ? { fieldCoverageId: f.fieldCoverageId } : {} } : {},\n ...f.storeCalls && f.storeCalls.length > 0 ? { storeCalls: f.storeCalls } : {},\n ...f.storeCallsDropped ? { storeCallsDropped: f.storeCallsDropped } : {},\n ...f.outboundCalls && f.outboundCalls.length > 0 ? { outboundCalls: f.outboundCalls } : {},\n ...f.outboundCallsDropped ? { outboundCallsDropped: f.outboundCallsDropped } : {},\n ...f.authChecks?.length ? { authChecks: f.authChecks } : {},\n ...f.authChecksDropped ? { authChecksDropped: f.authChecksDropped } : {},\n ...f.parentInvocationId ? { parentInvocationId: f.parentInvocationId, ...f.parentScopeId ? { parentScopeId: f.parentScopeId } : {} } : {},\n ...f.async ?? {}\n };\n}\nvar STORE_CALL_LOG_CAP = 16;\nfunction tallyStoreCall(tally, call) {\n const calls = tally.storeCalls ?? (tally.storeCalls = []);\n if (calls.length < STORE_CALL_LOG_CAP) {\n calls.push({ binding: call.binding, operation: call.operation, outcome: call.outcome, durationMs: call.durationMs });\n } else {\n tally.storeCallsDropped = (tally.storeCallsDropped ?? 0) + 1;\n }\n}\nvar OUTBOUND_CALL_LOG_CAP = 16;\nfunction tallyOutboundCall(tally, call) {\n const calls = tally.outboundCalls ?? (tally.outboundCalls = []);\n if (calls.length < OUTBOUND_CALL_LOG_CAP) {\n calls.push({\n host: call.host,\n path: call.path,\n method: call.method,\n status: call.status,\n outcome: call.outcome,\n durationMs: call.durationMs,\n atMs: call.atMs,\n ...call.reason !== void 0 ? { reason: call.reason } : {}\n });\n } else {\n tally.outboundCallsDropped = (tally.outboundCallsDropped ?? 0) + 1;\n }\n}\nvar STORE_CALL_SINK_KEY = \"substrat.store-call-sink\";\nfunction distinct(values) {\n return [...new Set(values)];\n}\n\n// packages/kernel/dist/ulid.js\nvar B32 = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\nvar MAX_ULID_TIME = 2 ** 48 - 1;\nvar ULID_SHAPE = /^[0-9A-HJKMNP-TV-Z]{26}$/;\nvar unencodable = (t) => `not an encodable ULID instant: ${t} (want 0..${MAX_ULID_TIME})`;\nfunction encodeTime(time) {\n let ts = \"\";\n let t = time;\n for (let i = 0; i < 10; i++) {\n ts = B32[t % 32] + ts;\n t = Math.floor(t / 32);\n }\n return ts;\n}\nfunction createUlid() {\n let lastTime = -1;\n const lastRand = new Array(16).fill(0);\n function freshRandom() {\n const bytes = crypto.getRandomValues(new Uint8Array(16));\n for (let i = 0; i < 16; i++)\n lastRand[i] = bytes[i] % 32;\n }\n function incrementRandom() {\n for (let i = 15; i >= 0; i--) {\n if (lastRand[i] < 31) {\n lastRand[i]++;\n return true;\n }\n lastRand[i] = 0;\n }\n return false;\n }\n const mint = ((now = Date.now()) => {\n if (!Number.isSafeInteger(now))\n throw new RangeError(unencodable(now));\n let time = now;\n if (time <= lastTime) {\n time = lastTime;\n if (!incrementRandom()) {\n time = lastTime + 1;\n freshRandom();\n }\n } else {\n freshRandom();\n }\n if (time < 0 || time > MAX_ULID_TIME)\n throw new RangeError(unencodable(time));\n lastTime = time;\n let r = \"\";\n for (const d of lastRand)\n r += B32[d];\n return encodeTime(time) + r;\n });\n mint.seedFrom = (id) => {\n const time = ulidTime(id);\n if (time < lastTime)\n return;\n const rand = [];\n for (const ch of id.slice(10))\n rand.push(B32.indexOf(ch));\n if (time === lastTime) {\n let ahead = false;\n for (let i = 0; i < 16; i++) {\n if (rand[i] !== lastRand[i]) {\n ahead = rand[i] > lastRand[i];\n break;\n }\n }\n if (!ahead)\n return;\n }\n lastTime = time;\n for (let i = 0; i < 16; i++)\n lastRand[i] = rand[i];\n };\n return mint;\n}\nvar processUlid = createUlid();\nfunction ulid(now = Date.now()) {\n return processUlid(now);\n}\nfunction ulidTime(id) {\n if (!ULID_SHAPE.test(id))\n throw new Error(`not a ULID: ${id}`);\n let t = 0;\n for (const ch of id.slice(0, 10))\n t = t * 32 + B32.indexOf(ch);\n if (t > MAX_ULID_TIME)\n throw new Error(`not a ULID: ${id}`);\n return t;\n}\n\n// packages/vertical-host/src/outbound-calls.ts\nvar EGRESS_REFUSAL_HEADER = \"x-substrat-egress\";\nvar STORE_CALL_HOST = \"store.substrat.internal\";\nvar REDACTED = \"[redacted]\";\nvar PATH_MAX = 200;\nvar WORDS = /^[a-z]{1,16}(?:[-_][a-z]{1,16}){0,3}$/;\nvar WORDS_WITH_EXTENSION = /^[a-z]{1,16}(?:[-_][a-z]{1,16}){0,3}\\.[a-z][a-z0-9]{0,4}$/;\nvar SEGMENT_MAX = 40;\nvar SMALL_INTEGER = /^[0-9]{1,10}$/;\nvar VERSION = /^v[0-9]{1,3}(?:\\.[0-9]{1,3}){0,2}$/;\nfunction keepsSegment(segment) {\n if (segment.length > SEGMENT_MAX) return false;\n return segment === \"\" || WORDS.test(segment) || WORDS_WITH_EXTENSION.test(segment) || SMALL_INTEGER.test(segment) || VERSION.test(segment);\n}\nfunction redactOutboundPath(pathname) {\n const path = pathname.split(\"/\").map((segment) => keepsSegment(segment) ? segment : REDACTED).join(\"/\");\n return path.length > PATH_MAX ? `${path.slice(0, PATH_MAX)}…` : path;\n}\nvar ERROR_CLASS = /^[A-Z][A-Za-z]{0,30}(?:Error|Exception)$/;\nfunction errorName(e) {\n const name = e?.name;\n return typeof name === \"string\" && ERROR_CLASS.test(name) ? name : \"Error\";\n}\nfunction answeredOutcome(response) {\n if (response.status === 403 && response.headers?.get?.(EGRESS_REFUSAL_HEADER) === \"refused\") return \"refused\";\n return response.status >= 400 ? \"http-error\" : \"ok\";\n}\nfunction rejectedOutcome(e) {\n const name = errorName(e);\n if (name === \"TimeoutError\") return { outcome: \"timeout\" };\n if (name === \"AbortError\") return { outcome: \"aborted\" };\n return { outcome: \"failed\", reason: name };\n}\nvar SINCE = /* @__PURE__ */ Symbol.for(\"substrat.outbound-since\");\nfunction sinceMap() {\n const g = globalThis;\n return g[SINCE] ??= /* @__PURE__ */ new WeakMap();\n}\nfunction markRequestStart(recording, started) {\n try {\n sinceMap().set(recording, started);\n } catch {\n }\n}\nfunction destinationOf(input, init) {\n const fromRequest = typeof input === \"object\" && input !== null && !(input instanceof URL);\n const raw = fromRequest ? input.url : input;\n let url;\n try {\n url = new URL(String(raw));\n } catch {\n return null;\n }\n const initMethod = init?.method;\n const requestMethod = fromRequest ? input.method : void 0;\n const method = typeof initMethod === \"string\" ? initMethod : typeof requestMethod === \"string\" ? requestMethod : \"GET\";\n return { url, method: method.toUpperCase().slice(0, 16) };\n}\nfunction record(recording, destination, startedAt, end) {\n try {\n const call = {\n host: destination.url.host.toLowerCase(),\n path: redactOutboundPath(destination.url.pathname),\n method: destination.method,\n status: end.status,\n outcome: end.outcome,\n durationMs: Math.max(0, Date.now() - startedAt),\n atMs: Math.max(0, startedAt - (sinceMap().get(recording) ?? startedAt)),\n ...end.reason !== void 0 ? { reason: end.reason } : {}\n };\n tallyOutboundCall(recording, call);\n } catch {\n }\n}\nvar WRAPPED = /* @__PURE__ */ Symbol.for(\"substrat.outbound-fetch\");\nvar IN_CALL = /* @__PURE__ */ Symbol.for(\"substrat.outbound-fetch.in-call\");\nfunction recordingFetch(original, current) {\n const wrapped = function fetch(input, init) {\n const g = globalThis;\n if (g[IN_CALL] === true) return original.call(globalThis, input, init);\n let recording;\n let destination = null;\n try {\n recording = current();\n if (recording) destination = destinationOf(input, init);\n } catch {\n recording = void 0;\n }\n if (!recording || !destination || destination.url.hostname.toLowerCase() === STORE_CALL_HOST) {\n return original.call(globalThis, input, init);\n }\n const rec = recording;\n const dest = destination;\n const startedAt = Date.now();\n let pending;\n g[IN_CALL] = true;\n try {\n pending = original.call(globalThis, input, init);\n } finally {\n g[IN_CALL] = false;\n }\n return pending.then(\n (response) => {\n let status = null;\n let outcome = \"failed\";\n try {\n status = response.status;\n outcome = answeredOutcome(response);\n } catch {\n }\n record(rec, dest, startedAt, { status, outcome });\n return response;\n },\n (e) => {\n let end = { outcome: \"failed\", reason: \"Error\" };\n try {\n end = rejectedOutcome(e);\n } catch {\n }\n record(rec, dest, startedAt, { status: null, ...end });\n throw e;\n }\n );\n };\n Object.defineProperty(wrapped, WRAPPED, { value: true });\n return wrapped;\n}\nfunction installOutboundRecorder(current) {\n try {\n const g = globalThis;\n const existing = g.fetch;\n if (typeof existing !== \"function\" || existing[WRAPPED]) return;\n g.fetch = recordingFetch(existing, current);\n } catch {\n }\n}\n\n// packages/contracts/dist/wire-auth.js\nfunction secretMatches(presented, expected) {\n const given = presented ?? \"\";\n let diff = given.length ^ expected.length | (given.length === 0 ? 1 : 0);\n for (let i = 0; i < expected.length; i++) {\n diff |= (i < given.length ? given.charCodeAt(i) : 0) ^ expected.charCodeAt(i);\n }\n return diff === 0;\n}\n\n// packages/vertical-host/src/routed-node.ts\nvar ROUTED_ID = /^[0-9A-HJKMNP-TV-Z]{26}$/;\nvar RouterAssertionError = class extends Error {\n};\nfunction readRoutedNode(headers, options = {}) {\n const rawTenant = headers.get(\"x-substrat-tenant\");\n const rawScope = headers.get(\"x-substrat-scope\");\n if (!rawTenant && !rawScope) return null;\n const { expectedSecret, allowUnsigned = false } = options;\n if (expectedSecret) {\n if (!secretMatches(headers.get(\"x-substrat-router\"), expectedSecret)) {\n throw new RouterAssertionError(\"router assertion is not signed by a known router\");\n }\n } else if (!allowUnsigned) {\n throw new RouterAssertionError(\n \"router assertion cannot be verified: this worker has no ROUTER_SECRET configured\"\n );\n }\n if (!rawTenant || !rawScope) {\n throw new RouterAssertionError(\"router assertion is incomplete\");\n }\n if (!ROUTED_ID.test(rawTenant) || !ROUTED_ID.test(rawScope)) {\n throw new RouterAssertionError(\"router assertion carries a malformed id\");\n }\n return {\n tenantId: rawTenant,\n scopeId: rawScope,\n surface: headers.get(\"x-substrat-surface\") ?? \"app\",\n verticalSlug: headers.get(\"x-substrat-vertical\")\n };\n}\n\n// packages/vertical-host/src/invocation-log.ts\nfunction builtinAsyncLocalStorage() {\n try {\n const proc = globalThis.process;\n const mod = proc?.getBuiltinModule?.(\"node:async_hooks\");\n return typeof mod?.AsyncLocalStorage === \"function\" ? mod.AsyncLocalStorage : void 0;\n } catch {\n return void 0;\n }\n}\nfunction storeCallSlot(provided) {\n try {\n const g = globalThis;\n const key = Symbol.for(STORE_CALL_SINK_KEY);\n const existing = g[key];\n if (typeof existing?.run === \"function\" && typeof existing.current === \"function\") return existing;\n const Als = provided ?? builtinAsyncLocalStorage();\n if (!Als) return void 0;\n const storage = new Als();\n const slot = {\n current() {\n const tally = storage.getStore()?.tally;\n return tally ? (call) => tallyStoreCall(tally, call) : void 0;\n },\n invocationId: () => storage.getStore()?.invocationId,\n run: (tally, fn, invocationId) => storage.run({ tally, invocationId }, fn),\n recording: () => storage.getStore()?.tally\n };\n g[key] = slot;\n return slot;\n } catch {\n return void 0;\n }\n}\nfunction currentRecording() {\n const slot = globalThis[Symbol.for(STORE_CALL_SINK_KEY)];\n return typeof slot?.recording === \"function\" ? slot.recording() : void 0;\n}\nfunction runRecording(stamp, started, provided, fn) {\n const slot = storeCallSlot(provided);\n if (!slot) return fn();\n try {\n const authSink = {\n record(check) {\n const record2 = currentRecording();\n if (record2) tallyAuthCheck(record2, check);\n }\n };\n globalThis[AUTH_DIAGNOSTICS_KEY] = authSink;\n } catch {\n }\n markRequestStart(stamp.record, started);\n installOutboundRecorder(currentRecording);\n return slot.run(stamp.record, fn, stamp.invocationId);\n}\nfunction versionIdOf(env) {\n const v = env?.SUBSTRAT_VERSION_ID;\n return typeof v === \"string\" && v.length > 0 ? v : null;\n}\nvar UPLOAD_LINK_LOG_SECRET_PREFIX = \"sbup_\";\nvar UPLOAD_LINK_SECRET_SEGMENT = /^(\\/api\\/attachment-uploads\\/[^/]+\\/[^/]+\\/)[^/]+/;\nvar SECRET_SHAPED_SEGMENT = new RegExp(`(^|/)${UPLOAD_LINK_LOG_SECRET_PREFIX}[^/]*`, \"g\");\nvar redactUploadLinkSecret = (pathname) => pathname.replace(UPLOAD_LINK_SECRET_SEGMENT, \"$1[redacted]\").replace(SECRET_SHAPED_SEGMENT, \"$1[redacted]\");\nfunction pathOf(url) {\n try {\n return redactUploadLinkSecret(new URL(url).pathname);\n } catch {\n return \"/\";\n }\n}\nvar STAMPS = /* @__PURE__ */ Symbol.for(\"substrat.invocation-stamp\");\nfunction stamps() {\n const g = globalThis;\n return g[STAMPS] ??= /* @__PURE__ */ new WeakMap();\n}\nfunction invocationStampOf(request) {\n return stamps().get(request);\n}\nfunction withRequestId(response, id) {\n const headers = response?.headers;\n try {\n headers?.set?.(REQUEST_ID_HEADER, id);\n return response;\n } catch {\n }\n try {\n const r = response;\n if (r.status === 101) return response;\n const copy = new Response(r.body, r);\n copy.headers.set(REQUEST_ID_HEADER, id);\n return copy;\n } catch {\n return response;\n }\n}\nfunction beginStamp(request, env, options) {\n const stamp = { invocationId: ulid(), record: {} };\n if (installedTraceSink()) markTraceStart(stamp.invocationId);\n const fieldCoverageId = armedFieldCoverageId(request.headers, env, options);\n if (fieldCoverageId) stamp.fieldCoverageId = fieldCoverageId;\n stamps().set(request, stamp);\n return stamp;\n}\nfunction armedFieldCoverageId(headers, env, options) {\n let id;\n try {\n id = headers.get(FIELD_COVERAGE_HEADER);\n } catch {\n return void 0;\n }\n if (id === null || !ROUTED_ID.test(id)) return void 0;\n return routedNodeOrNull(headers, env, options) !== null ? id : void 0;\n}\nfunction writeInvocationLine(stamp, done, options) {\n traceRequest(stamp, done);\n try {\n writeLineOrThrow(stamp, done, options);\n } catch (e) {\n try {\n console.log(JSON.stringify({ substrat: \"invocation-log-fault\", detail: String(e) }));\n } catch {\n }\n }\n}\nfunction traceRequest(stamp, done) {\n const sink = installedTraceSink();\n if (!sink) return;\n try {\n const { record: record2, invocationId } = stamp;\n const durationMs = Date.now() - done.started;\n const line = invocationLine({\n tenantId: \"\",\n scopeId: null,\n vertical: null,\n surface: null,\n method: done.request.method,\n path: pathOf(done.request.url),\n status: done.status,\n threw: done.threw,\n durationMs,\n invocationId,\n level: invocationLevelOf(done.status, done.threw, record2.problemCode),\n operation: record2.operation,\n problemCode: record2.problemCode,\n principalKind: record2.principalKind,\n ...record2.emitted ? { emitted: record2.emitted } : {},\n versionId: versionIdOf(done.env)\n });\n sink.head(invocationId, {\n startedAt: new Date(done.started).toISOString(),\n method: line.method,\n path: line.path,\n status: line.status,\n threw: line.threw,\n durationMs: line.durationMs,\n level: line.level,\n operation: line.operation,\n problemCode: line.problemCode,\n principalKind: line.principalKind,\n eventCount: line.eventCount,\n eventTypes: line.eventTypes,\n entities: line.entities,\n versionId: line.versionId,\n // Calls the record kept no room for: a truncated list must read as truncated.\n ...record2.outboundCallsDropped ? { stepsDropped: record2.outboundCallsDropped } : {}\n });\n for (const call of record2.outboundCalls ?? []) {\n sink.step(invocationId, {\n type: \"outbound\",\n atMs: call.atMs,\n durationMs: call.durationMs,\n host: call.host,\n path: call.path,\n method: call.method,\n status: call.status,\n outcome: call.outcome,\n ...call.reason ? { reason: call.reason } : {}\n });\n }\n for (const check of record2.authChecks ?? []) {\n sink.step(invocationId, { type: \"log\", atMs: durationMs, level: check.outcome === \"refused\" || check.outcome === \"error\" ? \"warn\" : \"info\", message: `auth ${check.stage}: ${check.outcome} (${check.reason})` });\n }\n if (record2.authChecksDropped) sink.head(invocationId, { stepsDropped: record2.authChecksDropped });\n sink.end(invocationId);\n forgetTraceStart(invocationId);\n } catch {\n }\n}\nfunction writeLineOrThrow(stamp, done, options) {\n const node = routedNodeOrNull(done.request.headers, done.env, options);\n if (!node) return;\n const { record: record2, invocationId } = stamp;\n const line = invocationLine({\n tenantId: node.tenantId,\n scopeId: node.scopeId,\n vertical: node.verticalSlug,\n surface: node.surface,\n method: done.request.method,\n path: pathOf(done.request.url),\n status: done.status,\n threw: done.threw,\n durationMs: Date.now() - done.started,\n invocationId,\n level: invocationLevelOf(done.status, done.threw, record2.problemCode),\n operation: record2.operation,\n problemCode: record2.problemCode,\n principalKind: record2.principalKind,\n ...record2.emitted ? { emitted: record2.emitted } : {},\n versionId: versionIdOf(done.env),\n ...record2.outputFields ? { outputFields: record2.outputFields } : {},\n ...stamp.fieldCoverageId ? { fieldCoverageId: stamp.fieldCoverageId } : {},\n ...record2.storeCalls && record2.storeCalls.length > 0 ? { storeCalls: record2.storeCalls } : {},\n ...record2.storeCallsDropped ? { storeCallsDropped: record2.storeCallsDropped } : {},\n ...record2.outboundCalls && record2.outboundCalls.length > 0 ? { outboundCalls: record2.outboundCalls } : {},\n ...record2.outboundCallsDropped ? { outboundCallsDropped: record2.outboundCallsDropped } : {},\n ...record2.authChecks?.length ? { authChecks: record2.authChecks } : {},\n ...record2.authChecksDropped ? { authChecksDropped: record2.authChecksDropped } : {}\n });\n console.log(JSON.stringify(line));\n}\nvar OTHER_HANDLERS = [\"scheduled\", \"queue\", \"email\", \"tail\", \"trace\", \"alarm\", \"test\"];\nfunction withInvocationLog(worker, options = {}) {\n const inner = worker?.fetch;\n if (typeof inner !== \"function\") return worker;\n const wrapped = {\n async fetch(request, env, ctx) {\n if (invocationStampOf(request)) return inner.call(worker, request, env, ctx);\n const started = Date.now();\n const stamp = beginStamp(request, env, options);\n let status = null;\n let threw = false;\n try {\n const response = withRequestId(\n await runRecording(stamp, started, options.asyncLocalStorage, () => inner.call(worker, request, env, ctx)),\n stamp.invocationId\n );\n status = response.status;\n handRecordToRouter(response, stamp.record, request, env, options);\n return response;\n } catch (e) {\n threw = true;\n throw e;\n } finally {\n writeInvocationLine(stamp, { request, env, status, threw, started }, options);\n }\n }\n };\n for (const name of OTHER_HANDLERS) {\n const h = worker[name];\n if (typeof h === \"function\") wrapped[name] = h.bind(worker);\n }\n return wrapped;\n}\nfunction handRecordToRouter(response, record2, request, env, options) {\n try {\n const value = encodeInvocationRecord(record2);\n if (value === null || !routedNodeOrNull(request.headers, env, options)) return;\n response.headers?.set?.(\n INVOCATION_RECORD_HEADER,\n value\n );\n } catch {\n }\n}\nfunction routedNodeOrNull(headers, env, options) {\n try {\n return readRoutedNode(headers, {\n expectedSecret: options.routerSecret?.(env),\n allowUnsigned: options.allowUnsigned?.(env) ?? false\n });\n } catch (e) {\n if (!(e instanceof RouterAssertionError)) console.log(JSON.stringify({ substrat: \"invocation-log-fault\", detail: String(e) }));\n return null;\n }\n}\n\n// substrat-platform-entry.ts\nimport * as vertical from \"__SUBSTRAT_VERTICAL_ENTRY__\";\nexport * from \"__SUBSTRAT_VERTICAL_ENTRY__\";\nvar substrat_platform_entry_default = withInvocationLog(vertical.default, {\n routerSecret: (env) => env.ROUTER_SECRET,\n allowUnsigned: (env) => env.ALLOW_DEV_NODE === \"true\",\n asyncLocalStorage: AsyncLocalStorage\n});\nexport {\n substrat_platform_entry_default as default\n};\n";
|
|
14
14
|
/**
|
|
15
15
|
* #2245: the entry's `node:async_hooks` import, as it appears in `PLATFORM_ENTRY_SOURCE`, and
|
|
16
16
|
* the line the uploader puts in its place for a script that can have no `AsyncLocalStorage`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-entry.generated.js","sourceRoot":"","sources":["../src/platform-entry.generated.ts"],"names":[],"mappings":"AAAA,8KAA8K;AAC9K,sEAAsE;AAEtE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAElE,gFAAgF;AAChF,MAAM,CAAC,MAAM,0BAA0B,GAAG,6BAA6B,CAAC;AAExE,6CAA6C;AAC7C,MAAM,CAAC,MAAM,qBAAqB,GAAW,
|
|
1
|
+
{"version":3,"file":"platform-entry.generated.js","sourceRoot":"","sources":["../src/platform-entry.generated.ts"],"names":[],"mappings":"AAAA,8KAA8K;AAC9K,sEAAsE;AAEtE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAElE,gFAAgF;AAChF,MAAM,CAAC,MAAM,0BAA0B,GAAG,6BAA6B,CAAC;AAExE,6CAA6C;AAC7C,MAAM,CAAC,MAAM,qBAAqB,GAAW,kwxBAAkwxB,CAAC;AAEhzxB;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,yDAAyD,CAAC;AACnG,MAAM,CAAC,MAAM,2BAA2B,GAAG,sCAAsC,CAAC;AAElF;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,8BAA8B,CAAC;AAEtE,+CAA+C;AAC/C,MAAM,CAAC,MAAM,uBAAuB,GAAW,83VAA83V,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@substrat-run/control-plane-api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.159.0",
|
|
4
4
|
"description": "HTTP surface over HostAdmin — the audited control-plane transport (control-plane.md §4.5)",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"repository": {
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"hono": "^4.13.13",
|
|
30
|
-
"@substrat-run/contracts": "^0.
|
|
31
|
-
"@substrat-run/
|
|
30
|
+
"@substrat-run/contracts": "^0.159.0",
|
|
31
|
+
"@substrat-run/kernel": "^0.159.0",
|
|
32
32
|
"@substrat-run/psl": "^0.2.5",
|
|
33
|
-
"@substrat-run/
|
|
33
|
+
"@substrat-run/control-plane-client": "^0.3.10"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@hono/node-server": "^1.13.0",
|
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
"tsx": "^4.19.0",
|
|
44
44
|
"typescript": "^7.0.0",
|
|
45
45
|
"vitest": "^5.0.5",
|
|
46
|
-
"@substrat-run/
|
|
47
|
-
"@substrat-run/
|
|
48
|
-
"@substrat-run/vertical-host": "^0.
|
|
49
|
-
"@substrat-run/connector-planima": "^0.2.
|
|
46
|
+
"@substrat-run/adapter-sqlite": "^0.159.0",
|
|
47
|
+
"@substrat-run/connector-fortnox": "^0.4.61",
|
|
48
|
+
"@substrat-run/vertical-host": "^0.159.0",
|
|
49
|
+
"@substrat-run/connector-planima": "^0.2.56"
|
|
50
50
|
},
|
|
51
51
|
"publishConfig": {
|
|
52
52
|
"access": "public"
|