@secondlayer/shared 11.20.0 → 11.22.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.
Files changed (43) hide show
  1. package/dist/src/archive/range-digest.d.ts +65 -0
  2. package/dist/src/archive/semantic-digest-builder.d.ts +65 -0
  3. package/dist/src/classify/index.d.ts +83 -0
  4. package/dist/src/classify/index.js +464 -0
  5. package/dist/src/classify/index.js.map +18 -0
  6. package/dist/src/coverage/index.d.ts +65 -0
  7. package/dist/src/db/index.d.ts +72 -1
  8. package/dist/src/db/index.js +3 -1
  9. package/dist/src/db/index.js.map +3 -3
  10. package/dist/src/db/queries/chain-reorgs.d.ts +65 -0
  11. package/dist/src/db/queries/chain-reorgs.js +3 -1
  12. package/dist/src/db/queries/chain-reorgs.js.map +3 -3
  13. package/dist/src/db/queries/contracts.d.ts +65 -0
  14. package/dist/src/db/queries/instance.d.ts +65 -0
  15. package/dist/src/db/queries/integrity.d.ts +65 -0
  16. package/dist/src/db/queries/subgraph-gaps.d.ts +65 -0
  17. package/dist/src/db/queries/subgraph-operations.d.ts +65 -0
  18. package/dist/src/db/queries/subgraphs.d.ts +69 -0
  19. package/dist/src/db/queries/subgraphs.js +10 -2
  20. package/dist/src/db/queries/subgraphs.js.map +4 -4
  21. package/dist/src/db/queries/sync-scope.d.ts +65 -0
  22. package/dist/src/db/queries/webhooks.d.ts +65 -0
  23. package/dist/src/db/schema.d.ts +70 -1
  24. package/dist/src/error-envelope.d.ts +48 -0
  25. package/dist/src/error-envelope.js +76 -0
  26. package/dist/src/error-envelope.js.map +10 -0
  27. package/dist/src/index.d.ts +288 -208
  28. package/dist/src/index.js +6 -1
  29. package/dist/src/index.js.map +5 -5
  30. package/dist/src/node/local-client.d.ts +65 -0
  31. package/dist/src/queue/listener.js +3 -1
  32. package/dist/src/queue/listener.js.map +3 -3
  33. package/dist/src/schemas/index.d.ts +30 -1
  34. package/dist/src/schemas/index.js.map +2 -2
  35. package/dist/src/schemas/subgraphs.d.ts +30 -1
  36. package/dist/src/schemas/subgraphs.js.map +2 -2
  37. package/dist/src/subgraphs/spec.d.ts +27 -0
  38. package/dist/src/subgraphs/spec.js +4 -1
  39. package/dist/src/subgraphs/spec.js.map +3 -3
  40. package/migrations/0155_api_failed_requests.ts +37 -0
  41. package/migrations/0156_feedback_tickets.ts +47 -0
  42. package/migrations/0157_subgraph_pin_verification.ts +35 -0
  43. package/package.json +17 -1
@@ -18,6 +18,27 @@ type FailureClass = (typeof FAILURE_CLASSES)[number];
18
18
  declare const RETRY_STATES: readonly ["open", "retrying", "halted", "resolved"];
19
19
  type RetryState = (typeof RETRY_STATES)[number];
20
20
  type BootstrapSource = "archive" | "genesis" | "import";
21
+ /**
22
+ * How far a subgraph's rows can be checked without trusting the server,
23
+ * derived from its sources and a scan of its handler. Never configured.
24
+ *
25
+ * - `state`: every input is a named state write, provable from block headers.
26
+ * Handlers run in the deterministic realm. A deployed `state` subgraph is
27
+ * verifiable: one with any reason is refused at deploy.
28
+ * - `events`: an input (events, prints, tx results, `ctx.client`) needs
29
+ * re-execution proofs, which are not served yet.
30
+ * - `none`: a source can never be proven as written (trait scope, tip-first
31
+ * backfill).
32
+ */
33
+ interface SubgraphVerification {
34
+ level: "state" | "events" | "none";
35
+ /** What stands between the subgraph and checkable rows, e.g.
36
+ * `print_event source "swaps" needs event proofs` or
37
+ * `subgraph.ts:41:12 Date: wall-clock time differs per run`. */
38
+ reasons: string[];
39
+ /** What stays unproven even at this level, e.g. tx attribution of writes. */
40
+ unproven: string[];
41
+ }
21
42
  interface BlocksTable {
22
43
  height: number;
23
44
  hash: string;
@@ -178,6 +199,11 @@ interface SubgraphsTable {
178
199
  expires_at: Date | null;
179
200
  /** (event type, contract) probe pairs persisted at deploy for weight classification. */
180
201
  sparse_probe_targets: unknown | null;
202
+ /** sha256 over everything that shapes rows (schema, handler bundle,
203
+ * startBlock, network, runtime). NULL for unbundled or older deploys. */
204
+ pin: string | null;
205
+ /** Level derived at deploy. NULL (older deploys) = not verifiable. */
206
+ verification: SubgraphVerification | null;
181
207
  created_at: Generated<Date>;
182
208
  updated_at: Generated<Date>;
183
209
  }
@@ -846,6 +872,8 @@ interface Database {
846
872
  sentinel_accounts: SentinelAccountsTable;
847
873
  waitlists: WaitlistsTable;
848
874
  waitlist_signups: WaitlistSignupsTable;
875
+ api_failed_requests: ApiFailedRequestsTable;
876
+ feedback_tickets: FeedbackTicketsTable;
849
877
  }
850
878
  interface ServiceHeartbeatsTable {
851
879
  name: string;
@@ -1119,7 +1147,48 @@ interface WaitlistSignupsTable {
1119
1147
  answers: Record<string, unknown>;
1120
1148
  created_at: Generated<Date>;
1121
1149
  }
1150
+ /**
1151
+ * 24h hosted record of a failed API request, keyed by `request_id` and
1152
+ * scoped to the account that made it. `query` is redacted before insert.
1153
+ */
1154
+ interface ApiFailedRequestsTable {
1155
+ request_id: string;
1156
+ account_id: string;
1157
+ method: string;
1158
+ path: string;
1159
+ status: number;
1160
+ code: string;
1161
+ message: Generated<string>;
1162
+ query: Record<string, unknown>;
1163
+ origin: string | null;
1164
+ created_at: Generated<Date>;
1165
+ }
1166
+ type ApiFailedRequest = Selectable<ApiFailedRequestsTable>;
1167
+ type InsertApiFailedRequest = Insertable<ApiFailedRequestsTable>;
1168
+ /**
1169
+ * Hosted problem report. `attempted` is the server's own copy of the failed
1170
+ * request (never caller-supplied); `status` starts `new` until classified.
1171
+ */
1172
+ interface FeedbackTicketsTable {
1173
+ id: Generated<string>;
1174
+ account_id: string;
1175
+ idempotency_key: string | null;
1176
+ request_id: string | null;
1177
+ intent: string;
1178
+ expected: Record<string, unknown> | null;
1179
+ kind_hint: string | null;
1180
+ evidence: Record<string, unknown> | null;
1181
+ attempted: Record<string, unknown> | null;
1182
+ origin: string;
1183
+ status: Generated<"new" | "classified">;
1184
+ route: string | null;
1185
+ classification: Record<string, unknown> | null;
1186
+ classified_at: Date | null;
1187
+ created_at: Generated<Date>;
1188
+ }
1189
+ type FeedbackTicket = Selectable<FeedbackTicketsTable>;
1190
+ type InsertFeedbackTicket = Insertable<FeedbackTicketsTable>;
1122
1191
  type Waitlist = Selectable<WaitlistsTable>;
1123
1192
  type WaitlistSignup = Selectable<WaitlistSignupsTable>;
1124
1193
  type InsertWaitlistSignup = Insertable<WaitlistSignupsTable>;
1125
- export { Account, AccountBalanceAlerts, AccountBalanceAlertsTable, AccountCredits, AccountCreditsTable, AccountSpendCap, AccountSpendCapsTable, AccountsTable, ApiKey, ApiKeysTable, ArchiveFetch, ArchiveFetchesTable, Block, BlocksTable, BnsMarketplaceAction, BnsMarketplaceEventsTable, BnsNameEventTopic, BnsNameEventsTable, BnsNamesTable, BnsNamespaceEventStatus, BnsNamespaceEventsTable, BnsNamespacesTable, BurnBlockRewardSlotsTable, BurnBlockRewardsTable, ChainReadCacheTable, ChainReorgsTable, Contract, ContractsTable, CoverageSegmentsTable, Database, DeadLetterEventsTable, DecodedEventsTable, DecoderCheckpointsTable, Event, EventsArchiveTable, EventsTable, FailureClass, FailureUnit, IndexProgress, IndexProgressTable, InsertAccount, InsertAccountBalanceAlerts, InsertAccountCredits, InsertAccountSpendCap, InsertApiKey, InsertArchiveFetch, InsertBlock, InsertContract, InsertEvent, InsertIndexProgress, InsertMagicLink, InsertMempoolTransaction, InsertSession, InsertStateWrite, InsertSubgraph, InsertSubgraphGap, InsertSubgraphHealthSnapshot, InsertSubgraphOperation, InsertTransaction, InsertUsageLedgerRow, InsertVmEvent, InsertWaitlistSignup, InsertWebhook, InsertWebhookDelivery, InsertWebhookOutbox, InstancesTable, MagicLink, MagicLinksTable, MempoolTransaction, MempoolTransactionsTable, NativeClock, ObserverJournalStatus, ObserverJournalTable, OutboxStatus, PendingForkBlocksTable, Pox4CallsTable, Pox4FunctionName, Pox5CycleSignersTable, Pox5CyclesTable, Pox5EventTopic, Pox5EventsTable, ProcessedStripeEventsTable, RepairMode, RetryState, RunStatus, SbtcEventTopic, SbtcEventsTable, SbtcSettlementsTable, SbtcTokenEventType, SbtcTokenEventsTable, SentinelAccount, SentinelAccountsTable, ServiceHeartbeatsTable, Session, SessionsTable, StageBlockReceiptsTable, StageFailuresTable, StageKind, StageRegistryTable, StageRunsTable, StateWrite, StateWritesArchiveTable, StateWritesTable, Subgraph, SubgraphGap, SubgraphGapsTable, SubgraphHealthSnapshot, SubgraphHealthSnapshotsTable, SubgraphOperation, SubgraphOperationKind, SubgraphOperationStatus, SubgraphOperationsTable, SubgraphProcessingStatsTable, SubgraphViolationsTable, SubgraphsTable, SyncScopesTable, Transaction, TransactionsArchiveTable, TransactionsTable, TriggerEvaluatorState, TriggerEvaluatorStateTable, UpdateAccountBalanceAlerts, UpdateAccountCredits, UpdateAccountSpendCap, UpdateApiKey, UpdateArchiveFetch, UpdateBlock, UpdateContract, UpdateEvent, UpdateIndexProgress, UpdateSubgraph, UpdateSubgraphOperation, UpdateTransaction, UpdateUsageLedgerRow, UpdateVmEvent, UpdateWebhook, UpdateWebhookOutbox, UsageLedgerRow, UsageLedgerTable, VmEvent, VmEventsArchiveTable, VmEventsTable, Waitlist, WaitlistSignup, WaitlistSignupsTable, WaitlistsTable, Webhook, WebhookDeliveriesTable, WebhookDelivery, WebhookFormat, WebhookKind, WebhookOutbox, WebhookOutboxTable, WebhookRuntime, WebhookStatus, WebhooksTable };
1194
+ export { Account, AccountBalanceAlerts, AccountBalanceAlertsTable, AccountCredits, AccountCreditsTable, AccountSpendCap, AccountSpendCapsTable, AccountsTable, ApiFailedRequest, ApiFailedRequestsTable, ApiKey, ApiKeysTable, ArchiveFetch, ArchiveFetchesTable, Block, BlocksTable, BnsMarketplaceAction, BnsMarketplaceEventsTable, BnsNameEventTopic, BnsNameEventsTable, BnsNamesTable, BnsNamespaceEventStatus, BnsNamespaceEventsTable, BnsNamespacesTable, BurnBlockRewardSlotsTable, BurnBlockRewardsTable, ChainReadCacheTable, ChainReorgsTable, Contract, ContractsTable, CoverageSegmentsTable, Database, DeadLetterEventsTable, DecodedEventsTable, DecoderCheckpointsTable, Event, EventsArchiveTable, EventsTable, FailureClass, FailureUnit, FeedbackTicket, FeedbackTicketsTable, IndexProgress, IndexProgressTable, InsertAccount, InsertAccountBalanceAlerts, InsertAccountCredits, InsertAccountSpendCap, InsertApiFailedRequest, InsertApiKey, InsertArchiveFetch, InsertBlock, InsertContract, InsertEvent, InsertFeedbackTicket, InsertIndexProgress, InsertMagicLink, InsertMempoolTransaction, InsertSession, InsertStateWrite, InsertSubgraph, InsertSubgraphGap, InsertSubgraphHealthSnapshot, InsertSubgraphOperation, InsertTransaction, InsertUsageLedgerRow, InsertVmEvent, InsertWaitlistSignup, InsertWebhook, InsertWebhookDelivery, InsertWebhookOutbox, InstancesTable, MagicLink, MagicLinksTable, MempoolTransaction, MempoolTransactionsTable, NativeClock, ObserverJournalStatus, ObserverJournalTable, OutboxStatus, PendingForkBlocksTable, Pox4CallsTable, Pox4FunctionName, Pox5CycleSignersTable, Pox5CyclesTable, Pox5EventTopic, Pox5EventsTable, ProcessedStripeEventsTable, RepairMode, RetryState, RunStatus, SbtcEventTopic, SbtcEventsTable, SbtcSettlementsTable, SbtcTokenEventType, SbtcTokenEventsTable, SentinelAccount, SentinelAccountsTable, ServiceHeartbeatsTable, Session, SessionsTable, StageBlockReceiptsTable, StageFailuresTable, StageKind, StageRegistryTable, StageRunsTable, StateWrite, StateWritesArchiveTable, StateWritesTable, Subgraph, SubgraphGap, SubgraphGapsTable, SubgraphHealthSnapshot, SubgraphHealthSnapshotsTable, SubgraphOperation, SubgraphOperationKind, SubgraphOperationStatus, SubgraphOperationsTable, SubgraphProcessingStatsTable, SubgraphViolationsTable, SubgraphsTable, SyncScopesTable, Transaction, TransactionsArchiveTable, TransactionsTable, TriggerEvaluatorState, TriggerEvaluatorStateTable, UpdateAccountBalanceAlerts, UpdateAccountCredits, UpdateAccountSpendCap, UpdateApiKey, UpdateArchiveFetch, UpdateBlock, UpdateContract, UpdateEvent, UpdateIndexProgress, UpdateSubgraph, UpdateSubgraphOperation, UpdateTransaction, UpdateUsageLedgerRow, UpdateVmEvent, UpdateWebhook, UpdateWebhookOutbox, UsageLedgerRow, UsageLedgerTable, VmEvent, VmEventsArchiveTable, VmEventsTable, Waitlist, WaitlistSignup, WaitlistSignupsTable, WaitlistsTable, Webhook, WebhookDeliveriesTable, WebhookDelivery, WebhookFormat, WebhookKind, WebhookOutbox, WebhookOutboxTable, WebhookRuntime, WebhookStatus, WebhooksTable };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Pure, dependency-free pieces of the API error envelope: request ids,
3
+ * default codes by status, feedback pointers and query redaction. Shared by
4
+ * the API middleware and the workload gateway so both emit the same shape.
5
+ */
6
+ /** Default `code` for an error body that set none, keyed by HTTP status. */
7
+ declare const DEFAULT_CODE_BY_STATUS: Record<number, string>;
8
+ /** Where to report a gap: a path on hosted, the issue tracker on self-host. */
9
+ declare const FEEDBACK_URL: {
10
+ readonly platform: "/v1/feedback"
11
+ readonly oss: "https://github.com/ryanwaits/secondlayer/issues/new"
12
+ };
13
+ /** One hosted failed-request record (account-scoped, kept 24h). */
14
+ type FailedRequestRecord = {
15
+ request_id: string
16
+ account_id: string
17
+ method: string
18
+ path: string
19
+ status: number
20
+ code: string
21
+ message: string
22
+ query: Record<string, unknown>
23
+ origin: string | null
24
+ };
25
+ /** Incoming `X-Request-Id` values matching this are reused. */
26
+ declare const REQUEST_ID_PATTERN: RegExp;
27
+ /** `req_` plus 24 lowercase hex chars. */
28
+ declare function newRequestId(): string;
29
+ /**
30
+ * Query params safe to store: sensitive keys dropped, values capped at 200
31
+ * chars, and a `{ _truncated, keys }` stub when the result is over 2048 chars.
32
+ */
33
+ declare function redactQuery(params: URLSearchParams): Record<string, unknown>;
34
+ /**
35
+ * Additive error body: `request_id` always set, `code` only when absent or
36
+ * not a string, `feedback` only when absent (or always with
37
+ * `overrideFeedback`). Returns null when `body` is not an object carrying an
38
+ * `error` key, so callers leave such responses alone.
39
+ */
40
+ declare function augmentErrorBody(body: unknown, opts: {
41
+ status: number
42
+ requestId: string
43
+ feedbackUrl: string
44
+ overrideFeedback?: boolean
45
+ }): Record<string, unknown> | null;
46
+ /** `x-sl-origin` header reduced to a known value, else null. */
47
+ declare function normalizeOrigin(header: string | undefined): string | null;
48
+ export { DEFAULT_CODE_BY_STATUS, FEEDBACK_URL, FailedRequestRecord, REQUEST_ID_PATTERN, augmentErrorBody, newRequestId, normalizeOrigin, redactQuery };
@@ -0,0 +1,76 @@
1
+ // src/error-envelope.ts
2
+ var DEFAULT_CODE_BY_STATUS = {
3
+ 400: "VALIDATION_ERROR",
4
+ 401: "AUTHENTICATION_ERROR",
5
+ 402: "PAYMENT_REQUIRED",
6
+ 403: "FORBIDDEN",
7
+ 404: "NOT_FOUND",
8
+ 409: "CONFLICT",
9
+ 410: "GONE",
10
+ 415: "UNSUPPORTED_MEDIA_TYPE",
11
+ 422: "VALIDATION_ERROR",
12
+ 429: "RATE_LIMIT_ERROR",
13
+ 500: "INTERNAL_ERROR",
14
+ 502: "UPSTREAM_ERROR",
15
+ 503: "SERVICE_UNAVAILABLE"
16
+ };
17
+ var FEEDBACK_URL = {
18
+ platform: "/v1/feedback",
19
+ oss: "https://github.com/ryanwaits/secondlayer/issues/new"
20
+ };
21
+ var REQUEST_ID_PATTERN = /^[A-Za-z0-9._-]{8,64}$/;
22
+ function newRequestId() {
23
+ const bytes = crypto.getRandomValues(new Uint8Array(12));
24
+ let hex = "";
25
+ for (const b of bytes)
26
+ hex += b.toString(16).padStart(2, "0");
27
+ return `req_${hex}`;
28
+ }
29
+ var SENSITIVE_KEY = /token|key|secret|signature|password|auth/i;
30
+ var MAX_VALUE_CHARS = 200;
31
+ var MAX_QUERY_JSON_CHARS = 2048;
32
+ function redactQuery(params) {
33
+ const out = {};
34
+ for (const [key, value] of params) {
35
+ if (SENSITIVE_KEY.test(key))
36
+ continue;
37
+ out[key] = value.slice(0, MAX_VALUE_CHARS);
38
+ }
39
+ if (JSON.stringify(out).length > MAX_QUERY_JSON_CHARS) {
40
+ return { _truncated: true, keys: Object.keys(out) };
41
+ }
42
+ return out;
43
+ }
44
+ function augmentErrorBody(body, opts) {
45
+ if (typeof body !== "object" || body === null || Array.isArray(body)) {
46
+ return null;
47
+ }
48
+ if (!("error" in body))
49
+ return null;
50
+ const src = body;
51
+ const next = { ...src, request_id: opts.requestId };
52
+ if (typeof src.code !== "string") {
53
+ next.code = DEFAULT_CODE_BY_STATUS[opts.status] ?? "HTTP_ERROR";
54
+ }
55
+ if (opts.overrideFeedback || src.feedback === undefined) {
56
+ next.feedback = { url: opts.feedbackUrl };
57
+ }
58
+ return next;
59
+ }
60
+ var KNOWN_ORIGINS = ["cli", "mcp", "session"];
61
+ function normalizeOrigin(header) {
62
+ const v = header?.toLowerCase();
63
+ return v !== undefined && KNOWN_ORIGINS.includes(v) ? v : null;
64
+ }
65
+ export {
66
+ DEFAULT_CODE_BY_STATUS,
67
+ FEEDBACK_URL,
68
+ REQUEST_ID_PATTERN,
69
+ augmentErrorBody,
70
+ newRequestId,
71
+ normalizeOrigin,
72
+ redactQuery
73
+ };
74
+
75
+ //# debugId=5A36C709A44A1A2864756E2164756E21
76
+ //# sourceMappingURL=error-envelope.js.map
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/error-envelope.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Pure, dependency-free pieces of the API error envelope: request ids,\n * default codes by status, feedback pointers and query redaction. Shared by\n * the API middleware and the workload gateway so both emit the same shape.\n */\n\n/** Default `code` for an error body that set none, keyed by HTTP status. */\nexport const DEFAULT_CODE_BY_STATUS: Record<number, string> = {\n\t400: \"VALIDATION_ERROR\",\n\t401: \"AUTHENTICATION_ERROR\",\n\t402: \"PAYMENT_REQUIRED\",\n\t403: \"FORBIDDEN\",\n\t404: \"NOT_FOUND\",\n\t409: \"CONFLICT\",\n\t410: \"GONE\",\n\t415: \"UNSUPPORTED_MEDIA_TYPE\",\n\t422: \"VALIDATION_ERROR\",\n\t429: \"RATE_LIMIT_ERROR\",\n\t500: \"INTERNAL_ERROR\",\n\t502: \"UPSTREAM_ERROR\",\n\t503: \"SERVICE_UNAVAILABLE\",\n};\n\n/** Where to report a gap: a path on hosted, the issue tracker on self-host. */\nexport const FEEDBACK_URL = {\n\tplatform: \"/v1/feedback\",\n\toss: \"https://github.com/ryanwaits/secondlayer/issues/new\",\n} as const;\n\n/** One hosted failed-request record (account-scoped, kept 24h). */\nexport type FailedRequestRecord = {\n\trequest_id: string;\n\taccount_id: string;\n\tmethod: string;\n\tpath: string;\n\tstatus: number;\n\tcode: string;\n\tmessage: string;\n\tquery: Record<string, unknown>;\n\torigin: string | null;\n};\n\n/** Incoming `X-Request-Id` values matching this are reused. */\nexport const REQUEST_ID_PATTERN: RegExp = /^[A-Za-z0-9._-]{8,64}$/;\n\n/** `req_` plus 24 lowercase hex chars. */\nexport function newRequestId(): string {\n\tconst bytes = crypto.getRandomValues(new Uint8Array(12));\n\tlet hex = \"\";\n\tfor (const b of bytes) hex += b.toString(16).padStart(2, \"0\");\n\treturn `req_${hex}`;\n}\n\nconst SENSITIVE_KEY = /token|key|secret|signature|password|auth/i;\nconst MAX_VALUE_CHARS = 200;\nconst MAX_QUERY_JSON_CHARS = 2048;\n\n/**\n * Query params safe to store: sensitive keys dropped, values capped at 200\n * chars, and a `{ _truncated, keys }` stub when the result is over 2048 chars.\n */\nexport function redactQuery(params: URLSearchParams): Record<string, unknown> {\n\tconst out: Record<string, unknown> = {};\n\tfor (const [key, value] of params) {\n\t\tif (SENSITIVE_KEY.test(key)) continue;\n\t\tout[key] = value.slice(0, MAX_VALUE_CHARS);\n\t}\n\tif (JSON.stringify(out).length > MAX_QUERY_JSON_CHARS) {\n\t\treturn { _truncated: true, keys: Object.keys(out) };\n\t}\n\treturn out;\n}\n\n/**\n * Additive error body: `request_id` always set, `code` only when absent or\n * not a string, `feedback` only when absent (or always with\n * `overrideFeedback`). Returns null when `body` is not an object carrying an\n * `error` key, so callers leave such responses alone.\n */\nexport function augmentErrorBody(\n\tbody: unknown,\n\topts: {\n\t\tstatus: number;\n\t\trequestId: string;\n\t\tfeedbackUrl: string;\n\t\toverrideFeedback?: boolean;\n\t},\n): Record<string, unknown> | null {\n\tif (typeof body !== \"object\" || body === null || Array.isArray(body)) {\n\t\treturn null;\n\t}\n\tif (!(\"error\" in body)) return null;\n\tconst src = body as Record<string, unknown>;\n\tconst next: Record<string, unknown> = { ...src, request_id: opts.requestId };\n\tif (typeof src.code !== \"string\") {\n\t\tnext.code = DEFAULT_CODE_BY_STATUS[opts.status] ?? \"HTTP_ERROR\";\n\t}\n\tif (opts.overrideFeedback || src.feedback === undefined) {\n\t\tnext.feedback = { url: opts.feedbackUrl };\n\t}\n\treturn next;\n}\n\nconst KNOWN_ORIGINS = [\"cli\", \"mcp\", \"session\"];\n\n/** `x-sl-origin` header reduced to a known value, else null. */\nexport function normalizeOrigin(header: string | undefined): string | null {\n\tconst v = header?.toLowerCase();\n\treturn v !== undefined && KNOWN_ORIGINS.includes(v) ? v : null;\n}\n"
6
+ ],
7
+ "mappings": ";AAOO,IAAM,yBAAiD;AAAA,EAC7D,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACN;AAGO,IAAM,eAAe;AAAA,EAC3B,UAAU;AAAA,EACV,KAAK;AACN;AAgBO,IAAM,qBAA6B;AAGnC,SAAS,YAAY,GAAW;AAAA,EACtC,MAAM,QAAQ,OAAO,gBAAgB,IAAI,WAAW,EAAE,CAAC;AAAA,EACvD,IAAI,MAAM;AAAA,EACV,WAAW,KAAK;AAAA,IAAO,OAAO,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAAA,EAC5D,OAAO,OAAO;AAAA;AAGf,IAAM,gBAAgB;AACtB,IAAM,kBAAkB;AACxB,IAAM,uBAAuB;AAMtB,SAAS,WAAW,CAAC,QAAkD;AAAA,EAC7E,MAAM,MAA+B,CAAC;AAAA,EACtC,YAAY,KAAK,UAAU,QAAQ;AAAA,IAClC,IAAI,cAAc,KAAK,GAAG;AAAA,MAAG;AAAA,IAC7B,IAAI,OAAO,MAAM,MAAM,GAAG,eAAe;AAAA,EAC1C;AAAA,EACA,IAAI,KAAK,UAAU,GAAG,EAAE,SAAS,sBAAsB;AAAA,IACtD,OAAO,EAAE,YAAY,MAAM,MAAM,OAAO,KAAK,GAAG,EAAE;AAAA,EACnD;AAAA,EACA,OAAO;AAAA;AASD,SAAS,gBAAgB,CAC/B,MACA,MAMiC;AAAA,EACjC,IAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,MAAM,QAAQ,IAAI,GAAG;AAAA,IACrE,OAAO;AAAA,EACR;AAAA,EACA,IAAI,EAAE,WAAW;AAAA,IAAO,OAAO;AAAA,EAC/B,MAAM,MAAM;AAAA,EACZ,MAAM,OAAgC,KAAK,KAAK,YAAY,KAAK,UAAU;AAAA,EAC3E,IAAI,OAAO,IAAI,SAAS,UAAU;AAAA,IACjC,KAAK,OAAO,uBAAuB,KAAK,WAAW;AAAA,EACpD;AAAA,EACA,IAAI,KAAK,oBAAoB,IAAI,aAAa,WAAW;AAAA,IACxD,KAAK,WAAW,EAAE,KAAK,KAAK,YAAY;AAAA,EACzC;AAAA,EACA,OAAO;AAAA;AAGR,IAAM,gBAAgB,CAAC,OAAO,OAAO,SAAS;AAGvC,SAAS,eAAe,CAAC,QAA2C;AAAA,EAC1E,MAAM,IAAI,QAAQ,YAAY;AAAA,EAC9B,OAAO,MAAM,aAAa,cAAc,SAAS,CAAC,IAAI,IAAI;AAAA;",
8
+ "debugId": "5A36C709A44A1A2864756E2164756E21",
9
+ "names": []
10
+ }