@secondlayer/shared 11.4.2 → 11.5.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/README.md +4 -4
- package/dist/src/archive/derived-stage-report.d.ts +2 -2
- package/dist/src/archive/derived-stage-report.js.map +1 -1
- package/dist/src/archive/instance-diagnosis.js +2 -2
- package/dist/src/archive/instance-diagnosis.js.map +2 -2
- package/dist/src/archive/range-digest.d.ts +25 -25
- package/dist/src/archive/semantic-digest-builder.d.ts +25 -25
- package/dist/src/archive/status.d.ts +32 -7
- package/dist/src/archive/status.js +20 -3
- package/dist/src/archive/status.js.map +3 -3
- package/dist/src/coverage/index.d.ts +25 -25
- package/dist/src/coverage/index.js.map +1 -1
- package/dist/src/crypto/secondlayer-webhook.d.ts +2 -2
- package/dist/src/crypto/secondlayer-webhook.js.map +1 -1
- package/dist/src/crypto/secrets.js.map +1 -1
- package/dist/src/db/index.d.ts +37 -37
- package/dist/src/db/index.js +4 -4
- package/dist/src/db/index.js.map +3 -3
- package/dist/src/db/queries/chain-reorgs.d.ts +25 -25
- package/dist/src/db/queries/chain-reorgs.js +4 -4
- package/dist/src/db/queries/chain-reorgs.js.map +3 -3
- package/dist/src/db/queries/contracts.d.ts +25 -25
- package/dist/src/db/queries/instance.d.ts +25 -25
- package/dist/src/db/queries/integrity.d.ts +25 -25
- package/dist/src/db/queries/subgraph-gaps.d.ts +25 -25
- package/dist/src/db/queries/subgraph-operations.d.ts +25 -25
- package/dist/src/db/queries/subgraphs.d.ts +25 -25
- package/dist/src/db/queries/subgraphs.js +4 -4
- package/dist/src/db/queries/subgraphs.js.map +3 -3
- package/dist/src/db/queries/sync-scope.d.ts +25 -25
- package/dist/src/db/queries/{subscriptions.d.ts → webhooks.d.ts} +58 -58
- package/dist/src/db/queries/{subscriptions.js → webhooks.js} +38 -38
- package/dist/src/db/queries/webhooks.js.map +13 -0
- package/dist/src/db/schema.d.ts +34 -34
- package/dist/src/index.d.ts +109 -107
- package/dist/src/index.js +51 -54
- package/dist/src/index.js.map +6 -6
- package/dist/src/leader.d.ts +4 -4
- package/dist/src/leader.js +3 -3
- package/dist/src/leader.js.map +3 -3
- package/dist/src/node/local-client.d.ts +25 -25
- package/dist/src/queue/listener.d.ts +2 -2
- package/dist/src/queue/listener.js.map +1 -1
- package/dist/src/runtime/index.js +2 -6
- package/dist/src/runtime/index.js.map +4 -4
- package/dist/src/schemas/index.d.ts +61 -61
- package/dist/src/schemas/index.js +48 -51
- package/dist/src/schemas/index.js.map +5 -5
- package/dist/src/schemas/subgraphs.d.ts +2 -2
- package/dist/src/schemas/subgraphs.js.map +1 -1
- package/dist/src/schemas/{subscriptions.d.ts → webhooks.d.ts} +63 -63
- package/dist/src/schemas/{subscriptions.js → webhooks.js} +49 -52
- package/dist/src/schemas/webhooks.js.map +10 -0
- package/migrations/0126_rename_subscriptions_to_webhooks.ts +96 -0
- package/migrations/0127_rename_webhook_catalog_names.ts +55 -0
- package/package.json +8 -8
- package/dist/src/db/queries/subscriptions.js.map +0 -13
- package/dist/src/schemas/subscriptions.js.map +0 -10
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/mode.ts", "../src/crypto/hmac.ts", "../src/crypto/secrets.ts", "../src/db/queries/webhooks.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Instance modes for the Secondlayer platform.\n *\n * - `oss`: self-hosted, single-tenant. No auth middleware, no platform routes\n * (projects, admin). Everything runs against a single `DATABASE_URL`.\n * Intended for `docker compose up`.\n *\n * - `platform`: the metered archive deployment. Magic-link auth, API keys,\n * accounts, credits, and metered `/v1` reads (Index + Streams + subgraphs)\n * against a single shared DB. No paid tier ladder — one metered `free`\n * tier plus first-party internal service credentials.\n */\n\nexport type InstanceMode = \"oss\" | \"platform\";\n\n/** What the operator wrote in the env — `archive` is the honest name for the\n * metered public-archive deployment and aliases `platform` behaviorally. */\nexport type DeclaredInstanceMode = InstanceMode | \"archive\";\n\nconst VALID_MODES: readonly DeclaredInstanceMode[] = [\n\t\"oss\",\n\t\"platform\",\n\t\"archive\",\n];\n\nfunction declaredMode(): DeclaredInstanceMode {\n\tconst raw = process.env.INSTANCE_MODE?.trim().toLowerCase();\n\tif (raw && (VALID_MODES as readonly string[]).includes(raw)) {\n\t\treturn raw as DeclaredInstanceMode;\n\t}\n\treturn \"oss\";\n}\n\n/**\n * Resolve the active instance mode from `process.env.INSTANCE_MODE`.\n * Defaults to `\"oss\"` — the safest default for self-hosters who deploy\n * without setting the variable. `archive` normalizes to `platform` here so\n * every behavioral branch stays a two-way choice; use\n * `getDeclaredInstanceMode()` for display surfaces.\n */\nexport function getInstanceMode(): InstanceMode {\n\tconst declared = declaredMode();\n\treturn declared === \"archive\" ? \"platform\" : declared;\n}\n\n/** The mode as declared in the env, for status/identity surfaces. */\nexport function getDeclaredInstanceMode(): DeclaredInstanceMode {\n\treturn declaredMode();\n}\n\n/**\n * True when public reads are credit-metered (the free window, retention, and\n * credits gates arm). Platform/archive deployments meter by default;\n * self-host never does unless the operator explicitly sets\n * `METERED_READS=true`. `METERED_READS=false` disarms a metered deployment.\n */\nexport function isMeteredReads(): boolean {\n\tconst override = process.env.METERED_READS?.trim().toLowerCase();\n\tif (override === \"true\") return true;\n\tif (override === \"false\") return false;\n\treturn getInstanceMode() === \"platform\";\n}\n\n/** True when the active mode is `\"platform\"` (shared multi-tenant). */\nexport function isPlatformMode(): boolean {\n\treturn getInstanceMode() === \"platform\";\n}\n\n/** True when the active mode is `\"oss\"` (self-hosted). */\nexport function isOssMode(): boolean {\n\treturn getInstanceMode() === \"oss\";\n}\n",
|
|
6
|
+
"import { createHmac, randomBytes } from \"node:crypto\";\n\n/**\n * Generate a random secret for delivery signing\n * Returns 32 bytes as a 64-character hex string\n */\nexport function generateSecret(): string {\n\treturn randomBytes(32).toString(\"hex\");\n}\n\n/**\n * Sign a payload with HMAC-SHA256\n * Returns the signature as a hex string\n */\nexport function signPayload(payload: string, secret: string): string {\n\tconst hmac = createHmac(\"sha256\", secret);\n\thmac.update(payload);\n\treturn hmac.digest(\"hex\");\n}\n\n/**\n * Verify an HMAC signature\n * Uses constant-time comparison to prevent timing attacks\n */\nexport function verifySignature(\n\tpayload: string,\n\tsignature: string,\n\tsecret: string,\n): boolean {\n\tconst expectedSignature = signPayload(payload, secret);\n\n\t// Constant-time comparison\n\tif (signature.length !== expectedSignature.length) {\n\t\treturn false;\n\t}\n\n\tlet result = 0;\n\tfor (let i = 0; i < signature.length; i++) {\n\t\tresult |= signature.charCodeAt(i) ^ expectedSignature.charCodeAt(i);\n\t}\n\n\treturn result === 0;\n}\n\n/**\n * Create a Stripe-style signature header\n * Format: t=timestamp,v1=signature\n */\nexport function createSignatureHeader(\n\tpayload: string,\n\tsecret: string,\n\ttimestamp?: number,\n): string {\n\tconst ts = timestamp ?? Math.floor(Date.now() / 1000);\n\tconst signedPayload = `${ts}.${payload}`;\n\tconst signature = signPayload(signedPayload, secret);\n\n\treturn `t=${ts},v1=${signature}`;\n}\n\n/**\n * Parse and verify a Stripe-style signature header\n * Returns true if valid, false otherwise\n */\nexport function verifySignatureHeader(\n\tpayload: string,\n\theader: string,\n\tsecret: string,\n\ttoleranceSeconds = 300, // 5 minutes\n): boolean {\n\t// Parse header\n\tconst parts = header.split(\",\");\n\tconst timestamp = parts.find((p) => p.startsWith(\"t=\"))?.slice(2);\n\tconst signature = parts.find((p) => p.startsWith(\"v1=\"))?.slice(3);\n\n\tif (!timestamp || !signature) {\n\t\treturn false;\n\t}\n\n\tconst ts = Number.parseInt(timestamp, 10);\n\tif (Number.isNaN(ts)) {\n\t\treturn false;\n\t}\n\n\t// Check timestamp is within tolerance\n\tconst now = Math.floor(Date.now() / 1000);\n\tif (Math.abs(now - ts) > toleranceSeconds) {\n\t\treturn false;\n\t}\n\n\t// Verify signature\n\tconst signedPayload = `${ts}.${payload}`;\n\treturn verifySignature(signedPayload, signature, secret);\n}\n",
|
|
7
|
+
"import { createCipheriv, createDecipheriv, randomBytes } from \"node:crypto\";\nimport {\n\tappendFileSync,\n\tcloseSync,\n\texistsSync,\n\topenSync,\n\treadFileSync,\n\tunlinkSync,\n} from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { getInstanceMode } from \"../mode.ts\";\n\n/**\n * AES-256-GCM symmetric envelope for encrypted secrets at rest (tenant keys,\n * webhook signing secrets, etc.).\n *\n * Ciphertext layout: `iv (12 bytes) || authTag (16 bytes) || ciphertext`\n *\n * The key comes from `SECONDLAYER_SECRETS_KEY` — 32 bytes hex. In OSS mode,\n * if the env var is unset on first use we autogenerate a key and persist it\n * to `.env.local` in the current working directory so subsequent restarts\n * pick it up without user intervention. Dedicated/platform modes throw —\n * those runtimes must provision the key explicitly.\n *\n * Rotation strategy: re-encrypt all rows with the new key and swap the env\n * var. Not zero-downtime, but acceptable at v2 scale. For real KMS (AWS\n * KMS, Vault, GCP KMS), wrap the same byte layout behind an\n * `EncryptSecret`/`DecryptSecret` interface and swap at startup.\n */\n\nconst KEY_ENV = \"SECONDLAYER_SECRETS_KEY\";\nconst IV_LEN = 12;\nconst TAG_LEN = 16;\n\nfunction readExistingKey(envPath: string): string | null {\n\tif (!existsSync(envPath)) return null;\n\tconst contents = readFileSync(envPath, \"utf8\");\n\tconst match = contents.match(/^SECONDLAYER_SECRETS_KEY=([a-fA-F0-9]{64})/m);\n\t// biome-ignore lint/style/noNonNullAssertion: value is non-null after preceding check or by construction; TS narrowing limitation\n\treturn match ? match[1]! : null;\n}\n\n/**\n * Atomic file lock via `openSync(..., \"wx\")` — O_CREAT | O_EXCL. If two\n * processes race on cold-compose start, exactly one creates the lock\n * file; the loser polls until the winner finishes writing `.env.local`,\n * then reads the winner's key. Stale locks (process crashed mid-write)\n * are cleaned after `STALE_LOCK_MS`.\n */\nconst STALE_LOCK_MS = 10_000;\nconst POLL_MS = 25;\n\nfunction bootstrapOssKey(): string {\n\tconst envPath = resolve(process.cwd(), \".env.local\");\n\n\t// Fast path — key already on disk from a prior run.\n\tconst existing = readExistingKey(envPath);\n\tif (existing) {\n\t\tprocess.env[KEY_ENV] = existing;\n\t\treturn existing;\n\t}\n\n\tconst lockPath = `${envPath}.secret-bootstrap.lock`;\n\tlet lockFd: number | null = null;\n\ttry {\n\t\tlockFd = openSync(lockPath, \"wx\", 0o600);\n\t} catch (err) {\n\t\tconst e = err as NodeJS.ErrnoException;\n\t\tif (e.code !== \"EEXIST\") throw err;\n\t}\n\n\tif (lockFd === null) {\n\t\t// Another process is bootstrapping. Poll for its result.\n\t\tconst deadline = Date.now() + STALE_LOCK_MS;\n\t\twhile (Date.now() < deadline) {\n\t\t\tconst key = readExistingKey(envPath);\n\t\t\tif (key) {\n\t\t\t\tprocess.env[KEY_ENV] = key;\n\t\t\t\treturn key;\n\t\t\t}\n\t\t\tBun.sleepSync(POLL_MS);\n\t\t}\n\t\t// Lock holder died mid-write — force-clean and retry once.\n\t\ttry {\n\t\t\tunlinkSync(lockPath);\n\t\t} catch {}\n\t\treturn bootstrapOssKey();\n\t}\n\n\ttry {\n\t\tconst hex = randomBytes(32).toString(\"hex\");\n\t\tconst line = `${existsSync(envPath) ? \"\\n\" : \"\"}${KEY_ENV}=${hex}\\n`;\n\t\tappendFileSync(envPath, line, { mode: 0o600 });\n\t\tprocess.env[KEY_ENV] = hex;\n\t\tconsole.log(\n\t\t\t`[secondlayer] generated ${KEY_ENV}; saved to ${envPath} (mode 0600)`,\n\t\t);\n\t\treturn hex;\n\t} finally {\n\t\tcloseSync(lockFd);\n\t\ttry {\n\t\t\tunlinkSync(lockPath);\n\t\t} catch {}\n\t}\n}\n\nfunction loadKey(): Buffer {\n\tlet hex = process.env[KEY_ENV];\n\tif (!hex) {\n\t\tif (getInstanceMode() === \"oss\") {\n\t\t\thex = bootstrapOssKey();\n\t\t} else {\n\t\t\tthrow new Error(\n\t\t\t\t`${KEY_ENV} not set. Generate one with: openssl rand -hex 32`,\n\t\t\t);\n\t\t}\n\t}\n\tconst key = Buffer.from(hex, \"hex\");\n\tif (key.length !== 32) {\n\t\tthrow new Error(`${KEY_ENV} must be 32 bytes hex (got ${key.length})`);\n\t}\n\treturn key;\n}\n\nlet _cachedKey: Buffer | null = null;\nfunction getKey(): Buffer {\n\tif (!_cachedKey) _cachedKey = loadKey();\n\treturn _cachedKey;\n}\n\n/**\n * Non-throwing check for whether a secrets key is currently resolvable —\n * same resolution order as {@link loadKey} (env var, then the OSS\n * `.env.local` fallback), but never bootstraps a new key (that would\n * generate+persist a key as a side effect of a mere existence check), never\n * throws, and never returns or logs the key itself. Used by callers that\n * need to fail loud on a missing key BEFORE attempting a decrypt (f072).\n */\nexport function secretsKeyAvailable(): boolean {\n\tif (process.env[KEY_ENV]) return true;\n\tif (getInstanceMode() === \"oss\") {\n\t\tconst envPath = resolve(process.cwd(), \".env.local\");\n\t\treturn readExistingKey(envPath) !== null;\n\t}\n\treturn false;\n}\n\nexport function encryptSecret(plaintext: string): Buffer {\n\tconst key = getKey();\n\tconst iv = randomBytes(IV_LEN);\n\tconst cipher = createCipheriv(\"aes-256-gcm\", key, iv);\n\tconst ciphertext = Buffer.concat([\n\t\tcipher.update(plaintext, \"utf8\"),\n\t\tcipher.final(),\n\t]);\n\tconst tag = cipher.getAuthTag();\n\treturn Buffer.concat([iv, tag, ciphertext]);\n}\n\nexport function decryptSecret(envelope: Buffer): string {\n\tconst key = getKey();\n\tconst iv = envelope.subarray(0, IV_LEN);\n\tconst tag = envelope.subarray(IV_LEN, IV_LEN + TAG_LEN);\n\tconst ciphertext = envelope.subarray(IV_LEN + TAG_LEN);\n\tconst decipher = createDecipheriv(\"aes-256-gcm\", key, iv);\n\tdecipher.setAuthTag(tag);\n\treturn decipher.update(ciphertext).toString(\"utf8\") + decipher.final(\"utf8\");\n}\n\n/** Generate a fresh 32-byte hex key suitable for `SECONDLAYER_SECRETS_KEY`. */\nexport function generateSecretsKey(): string {\n\treturn randomBytes(32).toString(\"hex\");\n}\n",
|
|
8
|
+
"import { type Kysely, sql } from \"kysely\";\nimport { generateSecret } from \"../../crypto/hmac.ts\";\nimport { decryptSecret, encryptSecret } from \"../../crypto/secrets.ts\";\nimport { isPlatformMode } from \"../../mode.ts\";\nimport type {\n\tDatabase,\n\tInsertWebhook,\n\tUpdateWebhook,\n\tWebhook,\n\tWebhookFormat,\n\tWebhookKind,\n\tWebhookRuntime,\n\tWebhookStatus,\n} from \"../types.ts\";\n\n/**\n * Webhook CRUD. `signing_secret_enc` is transparently encrypted via\n * `encryptSecret`/`decryptSecret`. Plaintext secrets only leave via the\n * return value of `create` (one-time display) and `rotateSecret`.\n */\n\nexport interface CreateWebhookInput {\n\taccountId: string;\n\tprojectId?: string | null;\n\tname: string;\n\t/** Defaults to \"subgraph\". Chain webhooks set kind=\"chain\" + triggers. */\n\tkind?: WebhookKind;\n\t/** Required for subgraph webhooks; omitted for chain. */\n\tsubgraphName?: string | null;\n\t/** Required for subgraph webhooks; omitted for chain. */\n\ttableName?: string | null;\n\t/** Chain-trigger filter array. Required for chain webhooks. */\n\ttriggers?: unknown;\n\tfilter?: unknown;\n\tformat?: WebhookFormat;\n\truntime?: WebhookRuntime | null;\n\turl: string;\n\tauthConfig?: unknown;\n\tmaxRetries?: number;\n\ttimeoutMs?: number;\n\tconcurrency?: number;\n}\n\nexport interface CreateWebhookResult {\n\twebhook: Webhook;\n\t/** Plaintext signing secret — surfaced once, never stored decrypted. */\n\tsigningSecret: string;\n}\n\nexport async function createWebhook(\n\tdb: Kysely<Database>,\n\tinput: CreateWebhookInput,\n): Promise<CreateWebhookResult> {\n\tconst signingSecret = generateSecret();\n\tconst kind: WebhookKind = input.kind ?? \"subgraph\";\n\tconst row: InsertWebhook = {\n\t\taccount_id: isPlatformMode() ? input.accountId : \"\",\n\t\tproject_id: input.projectId ?? null,\n\t\tname: input.name,\n\t\tstatus: \"active\",\n\t\tkind,\n\t\tsubgraph_name: input.subgraphName ?? null,\n\t\ttable_name: input.tableName ?? null,\n\t\ttriggers: kind === \"chain\" ? ((input.triggers ?? []) as unknown) : null,\n\t\tfilter: input.filter ?? {},\n\t\tformat: input.format ?? \"standard-webhooks\",\n\t\truntime: input.runtime ?? null,\n\t\turl: input.url,\n\t\tsigning_secret_enc: encryptSecret(signingSecret),\n\t\tauth_config: input.authConfig ?? {},\n\t\t...(input.maxRetries !== undefined\n\t\t\t? { max_retries: input.maxRetries }\n\t\t\t: {}),\n\t\t...(input.timeoutMs !== undefined ? { timeout_ms: input.timeoutMs } : {}),\n\t\t...(input.concurrency !== undefined\n\t\t\t? { concurrency: input.concurrency }\n\t\t\t: {}),\n\t};\n\tconst webhook = await db\n\t\t.insertInto(\"webhooks\")\n\t\t.values(row)\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\treturn { webhook, signingSecret };\n}\n\nexport async function listWebhooks(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\topts?: { limit?: number; offset?: number },\n): Promise<Webhook[]> {\n\tlet q = db.selectFrom(\"webhooks\").selectAll().orderBy(\"created_at\", \"desc\");\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\tif (opts?.limit !== undefined) q = q.limit(opts.limit);\n\tif (opts?.offset !== undefined) q = q.offset(opts.offset);\n\treturn q.execute();\n}\n\n/**\n * All active chain webhooks across every account — the input to the global\n * trigger evaluator (one loop serves them all). Subgraph webhooks are\n * excluded; they emit via the subgraph flush path.\n */\nexport async function listActiveChainWebhooks(\n\tdb: Kysely<Database>,\n): Promise<Webhook[]> {\n\treturn db\n\t\t.selectFrom(\"webhooks\")\n\t\t.selectAll()\n\t\t.where(\"kind\", \"=\", \"chain\")\n\t\t.where(\"status\", \"=\", \"active\")\n\t\t.execute();\n}\n\nexport async function getWebhook(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tid: string,\n): Promise<Webhook | null> {\n\tlet q = db.selectFrom(\"webhooks\").selectAll().where(\"id\", \"=\", id);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\treturn (await q.executeTakeFirst()) ?? null;\n}\n\nexport async function getWebhookByName(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tname: string,\n): Promise<Webhook | null> {\n\tlet q = db.selectFrom(\"webhooks\").selectAll().where(\"name\", \"=\", name);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\treturn (await q.executeTakeFirst()) ?? null;\n}\n\nexport interface UpdateWebhookInput {\n\tname?: string;\n\tfilter?: unknown;\n\tformat?: WebhookFormat;\n\truntime?: WebhookRuntime | null;\n\turl?: string;\n\tauthConfig?: unknown;\n\tmaxRetries?: number;\n\ttimeoutMs?: number;\n\tconcurrency?: number;\n}\n\nexport async function updateWebhook(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tid: string,\n\tpatch: UpdateWebhookInput,\n): Promise<Webhook | null> {\n\tconst update: UpdateWebhook = { updated_at: new Date() };\n\tif (patch.name !== undefined) update.name = patch.name;\n\tif (patch.filter !== undefined) update.filter = patch.filter;\n\tif (patch.format !== undefined) update.format = patch.format;\n\tif (patch.runtime !== undefined) update.runtime = patch.runtime;\n\tif (patch.url !== undefined) update.url = patch.url;\n\tif (patch.authConfig !== undefined) update.auth_config = patch.authConfig;\n\tif (patch.maxRetries !== undefined) update.max_retries = patch.maxRetries;\n\tif (patch.timeoutMs !== undefined) update.timeout_ms = patch.timeoutMs;\n\tif (patch.concurrency !== undefined) update.concurrency = patch.concurrency;\n\n\tlet q = db.updateTable(\"webhooks\").set(update).where(\"id\", \"=\", id);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\treturn (await q.returningAll().executeTakeFirst()) ?? null;\n}\n\nexport async function toggleWebhookStatus(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tid: string,\n\tstatus: WebhookStatus,\n): Promise<Webhook | null> {\n\tlet q = db\n\t\t.updateTable(\"webhooks\")\n\t\t.set({\n\t\t\tstatus,\n\t\t\tupdated_at: new Date(),\n\t\t\t...(status === \"active\"\n\t\t\t\t? {\n\t\t\t\t\t\tcircuit_failures: 0,\n\t\t\t\t\t\tcircuit_opened_at: null,\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t})\n\t\t.where(\"id\", \"=\", id);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\treturn (await q.returningAll().executeTakeFirst()) ?? null;\n}\n\nexport async function deleteWebhook(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tid: string,\n): Promise<boolean> {\n\tlet q = db.deleteFrom(\"webhooks\").where(\"id\", \"=\", id);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\tconst res = await q.executeTakeFirst();\n\treturn Number(res.numDeletedRows ?? 0) > 0;\n}\n\nexport interface RotateSecretResult {\n\twebhook: Webhook;\n\tsigningSecret: string;\n}\n\nexport async function rotateWebhookSecret(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tid: string,\n): Promise<RotateSecretResult | null> {\n\tconst signingSecret = generateSecret();\n\tlet q = db\n\t\t.updateTable(\"webhooks\")\n\t\t.set({\n\t\t\tsigning_secret_enc: encryptSecret(signingSecret),\n\t\t\tupdated_at: new Date(),\n\t\t})\n\t\t.where(\"id\", \"=\", id);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\tconst row = await q.returningAll().executeTakeFirst();\n\tif (!row) return null;\n\treturn { webhook: row, signingSecret };\n}\n\n/** Decrypt a webhook's signing secret for HMAC signing at emit time. */\nexport function getWebhookSigningSecret(webhook: Webhook): string {\n\treturn decryptSecret(webhook.signing_secret_enc);\n}\n\n/** Fire `webhooks:changed` notify so the emitter hot-reloads its cache. */\nexport async function notifyWebhooksChanged(\n\tdb: Kysely<Database>,\n\taccountId: string,\n): Promise<void> {\n\tawait sql`SELECT pg_notify('webhooks:changed', ${accountId})`.execute(db);\n}\n"
|
|
9
|
+
],
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "8CB695561D569ACB64756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|
package/dist/src/db/schema.d.ts
CHANGED
|
@@ -788,9 +788,9 @@ interface Database {
|
|
|
788
788
|
account_spend_caps: AccountSpendCapsTable;
|
|
789
789
|
account_credits: AccountCreditsTable;
|
|
790
790
|
hosted_meter_days: HostedMeterDaysTable;
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
791
|
+
webhooks: WebhooksTable;
|
|
792
|
+
webhook_outbox: WebhookOutboxTable;
|
|
793
|
+
webhook_deliveries: WebhookDeliveriesTable;
|
|
794
794
|
trigger_evaluator_state: TriggerEvaluatorStateTable;
|
|
795
795
|
decoded_events: DecodedEventsTable;
|
|
796
796
|
decoder_checkpoints: DecoderCheckpointsTable;
|
|
@@ -963,31 +963,31 @@ type SubgraphHealthSnapshot = Selectable<SubgraphHealthSnapshotsTable>;
|
|
|
963
963
|
type InsertSubgraphHealthSnapshot = Insertable<SubgraphHealthSnapshotsTable>;
|
|
964
964
|
type SubgraphGap = Selectable<SubgraphGapsTable>;
|
|
965
965
|
type InsertSubgraphGap = Insertable<SubgraphGapsTable>;
|
|
966
|
-
type
|
|
967
|
-
/** Polymorphic
|
|
966
|
+
type WebhookStatus = "active" | "paused" | "error";
|
|
967
|
+
/** Polymorphic webhook mode: `subgraph` reacts to processed table rows;
|
|
968
968
|
* `chain` reacts to raw chain events matched directly off the Index/Streams
|
|
969
969
|
* clock (no subgraph). See migration 0088. */
|
|
970
|
-
type
|
|
971
|
-
type
|
|
972
|
-
type
|
|
973
|
-
interface
|
|
970
|
+
type WebhookKind = "subgraph" | "chain";
|
|
971
|
+
type WebhookFormat = "standard-webhooks" | "inngest" | "trigger" | "cloudflare" | "cloudevents" | "raw";
|
|
972
|
+
type WebhookRuntime = "inngest" | "trigger" | "cloudflare" | "node";
|
|
973
|
+
interface WebhooksTable {
|
|
974
974
|
id: Generated<string>;
|
|
975
975
|
account_id: string;
|
|
976
976
|
project_id: string | null;
|
|
977
977
|
name: string;
|
|
978
|
-
status: ColumnType<
|
|
979
|
-
kind: ColumnType<
|
|
980
|
-
/** Null for chain
|
|
978
|
+
status: ColumnType<WebhookStatus, WebhookStatus | undefined, WebhookStatus>;
|
|
979
|
+
kind: ColumnType<WebhookKind, WebhookKind | undefined, WebhookKind>;
|
|
980
|
+
/** Null for chain webhooks (CHECK webhooks_kind_shape). */
|
|
981
981
|
subgraph_name: string | null;
|
|
982
|
-
/** Null for chain
|
|
982
|
+
/** Null for chain webhooks (CHECK webhooks_kind_shape). */
|
|
983
983
|
table_name: string | null;
|
|
984
984
|
/** Chain-trigger filter array (the `SubgraphFilter` shape, JSON). Null for
|
|
985
|
-
* subgraph
|
|
986
|
-
* import cycle; the Zod schema in schemas/
|
|
985
|
+
* subgraph webhooks. Typed loosely here to avoid a shared→subgraphs
|
|
986
|
+
* import cycle; the Zod schema in schemas/webhooks.ts owns the shape. */
|
|
987
987
|
triggers: unknown | null;
|
|
988
988
|
filter: Generated<unknown>;
|
|
989
|
-
format: ColumnType<
|
|
990
|
-
runtime:
|
|
989
|
+
format: ColumnType<WebhookFormat, WebhookFormat | undefined, WebhookFormat>;
|
|
990
|
+
runtime: WebhookRuntime | null;
|
|
991
991
|
url: string;
|
|
992
992
|
signing_secret_enc: Buffer;
|
|
993
993
|
auth_config: Generated<unknown>;
|
|
@@ -1002,17 +1002,17 @@ interface SubscriptionsTable {
|
|
|
1002
1002
|
created_at: Generated<Date>;
|
|
1003
1003
|
updated_at: Generated<Date>;
|
|
1004
1004
|
}
|
|
1005
|
-
type
|
|
1006
|
-
type
|
|
1007
|
-
type
|
|
1005
|
+
type Webhook = Selectable<WebhooksTable>;
|
|
1006
|
+
type InsertWebhook = Insertable<WebhooksTable>;
|
|
1007
|
+
type UpdateWebhook = Updateable<WebhooksTable>;
|
|
1008
1008
|
type OutboxStatus = "pending" | "delivered" | "dead";
|
|
1009
|
-
interface
|
|
1009
|
+
interface WebhookOutboxTable {
|
|
1010
1010
|
id: Generated<string>;
|
|
1011
|
-
|
|
1012
|
-
kind: ColumnType<
|
|
1013
|
-
/** Null for chain-
|
|
1011
|
+
webhook_id: string;
|
|
1012
|
+
kind: ColumnType<WebhookKind, WebhookKind | undefined, WebhookKind>;
|
|
1013
|
+
/** Null for chain-webhook rows. */
|
|
1014
1014
|
subgraph_name: string | null;
|
|
1015
|
-
/** Null for chain-
|
|
1015
|
+
/** Null for chain-webhook rows. */
|
|
1016
1016
|
table_name: string | null;
|
|
1017
1017
|
block_height: number | bigint;
|
|
1018
1018
|
tx_id: string | null;
|
|
@@ -1030,15 +1030,15 @@ interface SubscriptionOutboxTable {
|
|
|
1030
1030
|
locked_until: Date | null;
|
|
1031
1031
|
created_at: Generated<Date>;
|
|
1032
1032
|
}
|
|
1033
|
-
type
|
|
1034
|
-
type
|
|
1035
|
-
type
|
|
1036
|
-
interface
|
|
1033
|
+
type WebhookOutbox = Selectable<WebhookOutboxTable>;
|
|
1034
|
+
type InsertWebhookOutbox = Insertable<WebhookOutboxTable>;
|
|
1035
|
+
type UpdateWebhookOutbox = Updateable<WebhookOutboxTable>;
|
|
1036
|
+
interface WebhookDeliveriesTable {
|
|
1037
1037
|
id: Generated<string>;
|
|
1038
1038
|
/** Nullable after migration 0077 — outbox row may be cleaned up while
|
|
1039
1039
|
* delivery telemetry is retained. */
|
|
1040
1040
|
outbox_id: string | null;
|
|
1041
|
-
|
|
1041
|
+
webhook_id: string;
|
|
1042
1042
|
attempt: number;
|
|
1043
1043
|
status_code: number | null;
|
|
1044
1044
|
response_headers: unknown | null;
|
|
@@ -1047,10 +1047,10 @@ interface SubscriptionDeliveriesTable {
|
|
|
1047
1047
|
duration_ms: number | null;
|
|
1048
1048
|
dispatched_at: Generated<Date>;
|
|
1049
1049
|
}
|
|
1050
|
-
type
|
|
1051
|
-
type
|
|
1050
|
+
type WebhookDelivery = Selectable<WebhookDeliveriesTable>;
|
|
1051
|
+
type InsertWebhookDelivery = Insertable<WebhookDeliveriesTable>;
|
|
1052
1052
|
/** Single-row (id always TRUE) high-water mark for the chain-trigger evaluator.
|
|
1053
|
-
* One loop serves all chain
|
|
1053
|
+
* One loop serves all chain webhooks, so the cursor is global. */
|
|
1054
1054
|
interface TriggerEvaluatorStateTable {
|
|
1055
1055
|
id: Generated<boolean>;
|
|
1056
1056
|
last_processed_block: ColumnType<bigint, bigint | number | undefined, bigint | number>;
|
|
@@ -1060,4 +1060,4 @@ interface TriggerEvaluatorStateTable {
|
|
|
1060
1060
|
updated_at: Generated<Date>;
|
|
1061
1061
|
}
|
|
1062
1062
|
type TriggerEvaluatorState = Selectable<TriggerEvaluatorStateTable>;
|
|
1063
|
-
export { X402PaymentsTable, X402BalancesTable,
|
|
1063
|
+
export { X402PaymentsTable, X402BalancesTable, WebhooksTable, WebhookStatus, WebhookRuntime, WebhookOutboxTable, WebhookOutbox, WebhookKind, WebhookFormat, WebhookDelivery, WebhookDeliveriesTable, Webhook, UpdateWebhookOutbox, UpdateWebhook, UpdateTransaction, UpdateSubgraphOperation, UpdateSubgraph, UpdateIndexProgress, UpdateHostedMeterDay, UpdateEvent, UpdateContract, UpdateClaimToken, UpdateBlock, UpdateArchiveFetch, UpdateApiKey, UpdateAccountSpendCap, UpdateAccountCredits, TriggerEvaluatorStateTable, TriggerEvaluatorState, TransactionsTable, TransactionsArchiveTable, Transaction, SyncScopesTable, SubgraphsTable, SubgraphViolationsTable, SubgraphTableSnapshotsTable, SubgraphProcessingStatsTable, SubgraphOperationsTable, SubgraphOperationStatus, SubgraphOperationKind, SubgraphOperation, SubgraphHealthSnapshotsTable, SubgraphHealthSnapshot, SubgraphGapsTable, SubgraphGap, Subgraph, StageRunsTable, StageRegistryTable, StageKind, StageFailuresTable, StageBlockReceiptsTable, SessionsTable, Session, ServiceHeartbeatsTable, SbtcTokenEventsTable, SbtcTokenEventType, SbtcSupplySnapshotsTable, SbtcSettlementsTable, SbtcEventsTable, SbtcEventTopic, RunStatus, RetryState, RepairMode, ProcessedStripeEventsTable, Pox5EventsTable, Pox5EventTopic, Pox4SignersDailyTable, Pox4FunctionName, Pox4CyclesDailyTable, Pox4CallsTable, PlayProvisionsTable, PlayProvision, PendingForkBlocksTable, OutboxStatus, ObserverJournalTable, ObserverJournalStatus, NativeClock, MempoolTransactionsTable, MempoolTransaction, MagicLinksTable, MagicLink, InstancesTable, InsertWebhookOutbox, InsertWebhookDelivery, InsertWebhook, InsertTransaction, InsertSubgraphOperation, InsertSubgraphHealthSnapshot, InsertSubgraphGap, InsertSubgraph, InsertSession, InsertPlayProvision, InsertMempoolTransaction, InsertMagicLink, InsertIndexProgress, InsertHostedMeterDay, InsertEvent, InsertContract, InsertClaimToken, InsertBlock, InsertArchiveFetch, InsertApiKey, InsertAccountSpendCap, InsertAccountCredits, InsertAccount, IndexProgressTable, IndexProgress, HostedMeterDaysTable, HostedMeterDay, FailureUnit, FailureClass, EventsTable, EventsArchiveTable, Event, DecoderCheckpointsTable, DecodedEventsTable, DeadLetterEventsTable, Database, CoverageSegmentsTable, ContractsTable, Contract, ClaimTokensTable, ClaimToken, ChainReorgsTable, ChainReadCacheTable, BurnBlockRewardsTable, BurnBlockRewardSlotsTable, BnsNamespacesTable, BnsNamespaceEventsTable, BnsNamespaceEventStatus, BnsNamesTable, BnsNameEventsTable, BnsNameEventTopic, BnsMarketplaceEventsTable, BnsMarketplaceAction, BlocksTable, Block, ArchiveFetchesTable, ArchiveFetch, ApiKeysTable, ApiKey, AccountsTable, AccountSpendCapsTable, AccountSpendCap, AccountCreditsTable, AccountCredits, Account };
|