@secondlayer/shared 11.7.1 → 11.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/dist/src/archive/copy-loader.d.ts +1 -1
  2. package/dist/src/archive/copy-loader.js +4 -20
  3. package/dist/src/archive/copy-loader.js.map +2 -2
  4. package/dist/src/archive/derived-stage-report.d.ts +1 -1
  5. package/dist/src/archive/derived-stage-report.js +3 -19
  6. package/dist/src/archive/derived-stage-report.js.map +2 -2
  7. package/dist/src/archive/disk-guard.d.ts +1 -1
  8. package/dist/src/archive/disk-guard.js +3 -19
  9. package/dist/src/archive/disk-guard.js.map +2 -2
  10. package/dist/src/archive/instance-diagnosis.d.ts +1 -1
  11. package/dist/src/archive/instance-diagnosis.js +6 -22
  12. package/dist/src/archive/instance-diagnosis.js.map +2 -2
  13. package/dist/src/archive/key-registry.d.ts +1 -1
  14. package/dist/src/archive/key-registry.js +12 -12
  15. package/dist/src/archive/key-registry.js.map +1 -1
  16. package/dist/src/archive/per-height-digest.d.ts +1 -1
  17. package/dist/src/archive/per-height-digest.js +3 -17
  18. package/dist/src/archive/per-height-digest.js.map +5 -5
  19. package/dist/src/archive/progress.d.ts +1 -1
  20. package/dist/src/archive/progress.js +4 -20
  21. package/dist/src/archive/progress.js.map +2 -2
  22. package/dist/src/archive/range-digest.d.ts +28 -3
  23. package/dist/src/archive/range-digest.js +4 -20
  24. package/dist/src/archive/range-digest.js.map +2 -2
  25. package/dist/src/archive/reference.d.ts +1 -1
  26. package/dist/src/archive/reference.js +14 -12
  27. package/dist/src/archive/reference.js.map +5 -5
  28. package/dist/src/archive/root-key.d.ts +1 -1
  29. package/dist/src/archive/root-key.js +3 -19
  30. package/dist/src/archive/root-key.js.map +2 -2
  31. package/dist/src/archive/semantic-digest-builder.d.ts +28 -3
  32. package/dist/src/archive/semantic-digest-builder.js +5 -19
  33. package/dist/src/archive/semantic-digest-builder.js.map +5 -5
  34. package/dist/src/archive/semantic-digest.d.ts +1 -1
  35. package/dist/src/archive/semantic-digest.js +4 -20
  36. package/dist/src/archive/semantic-digest.js.map +2 -2
  37. package/dist/src/archive/status.d.ts +1 -1
  38. package/dist/src/archive/status.js +4 -20
  39. package/dist/src/archive/status.js.map +2 -2
  40. package/dist/src/coverage/index.d.ts +27 -2
  41. package/dist/src/coverage/index.js +80 -96
  42. package/dist/src/coverage/index.js.map +2 -2
  43. package/dist/src/crypto/ed25519.d.ts +1 -1
  44. package/dist/src/crypto/ed25519.js +13 -13
  45. package/dist/src/crypto/ed25519.js.map +1 -1
  46. package/dist/src/crypto/hmac.d.ts +1 -1
  47. package/dist/src/crypto/hmac.js +9 -9
  48. package/dist/src/crypto/hmac.js.map +1 -1
  49. package/dist/src/crypto/secondlayer-webhook.d.ts +1 -1
  50. package/dist/src/crypto/secondlayer-webhook.js +14 -14
  51. package/dist/src/crypto/secondlayer-webhook.js.map +2 -2
  52. package/dist/src/crypto/secrets.d.ts +1 -1
  53. package/dist/src/crypto/secrets.js +15 -29
  54. package/dist/src/crypto/secrets.js.map +5 -5
  55. package/dist/src/crypto/standard-webhooks.d.ts +1 -1
  56. package/dist/src/crypto/standard-webhooks.js +3 -19
  57. package/dist/src/crypto/standard-webhooks.js.map +2 -2
  58. package/dist/src/db/index.d.ts +48 -19
  59. package/dist/src/db/index.js +41 -55
  60. package/dist/src/db/index.js.map +6 -6
  61. package/dist/src/db/jsonb.d.ts +1 -1
  62. package/dist/src/db/jsonb.js +3 -19
  63. package/dist/src/db/jsonb.js.map +2 -2
  64. package/dist/src/db/queries/chain-reorgs.d.ts +27 -2
  65. package/dist/src/db/queries/chain-reorgs.js +28 -42
  66. package/dist/src/db/queries/chain-reorgs.js.map +6 -6
  67. package/dist/src/db/queries/contracts.d.ts +27 -2
  68. package/dist/src/db/queries/contracts.js +9 -23
  69. package/dist/src/db/queries/contracts.js.map +5 -5
  70. package/dist/src/db/queries/instance.d.ts +27 -2
  71. package/dist/src/db/queries/instance.js +7 -23
  72. package/dist/src/db/queries/instance.js.map +2 -2
  73. package/dist/src/db/queries/integrity.d.ts +27 -2
  74. package/dist/src/db/queries/integrity.js +5 -21
  75. package/dist/src/db/queries/integrity.js.map +2 -2
  76. package/dist/src/db/queries/subgraph-gaps.d.ts +27 -2
  77. package/dist/src/db/queries/subgraph-gaps.js +5 -21
  78. package/dist/src/db/queries/subgraph-gaps.js.map +2 -2
  79. package/dist/src/db/queries/subgraph-operations.d.ts +27 -2
  80. package/dist/src/db/queries/subgraph-operations.js +17 -33
  81. package/dist/src/db/queries/subgraph-operations.js.map +2 -2
  82. package/dist/src/db/queries/subgraphs.d.ts +28 -14
  83. package/dist/src/db/queries/subgraphs.js +15 -37
  84. package/dist/src/db/queries/subgraphs.js.map +5 -5
  85. package/dist/src/db/queries/sync-scope.d.ts +27 -2
  86. package/dist/src/db/queries/sync-scope.js +6 -22
  87. package/dist/src/db/queries/sync-scope.js.map +2 -2
  88. package/dist/src/db/queries/webhooks.d.ts +27 -2
  89. package/dist/src/db/queries/webhooks.js +54 -50
  90. package/dist/src/db/queries/webhooks.js.map +5 -5
  91. package/dist/src/db/schema.d.ts +30 -2
  92. package/dist/src/env.d.ts +1 -1
  93. package/dist/src/env.js +7 -23
  94. package/dist/src/env.js.map +2 -2
  95. package/dist/src/errors.d.ts +4 -4
  96. package/dist/src/errors.js +15 -31
  97. package/dist/src/errors.js.map +3 -3
  98. package/dist/src/index-http.d.ts +1 -1
  99. package/dist/src/index-http.js +4 -20
  100. package/dist/src/index-http.js.map +3 -3
  101. package/dist/src/index-internal-auth.d.ts +4 -7
  102. package/dist/src/index-internal-auth.js +8 -24
  103. package/dist/src/index-internal-auth.js.map +3 -3
  104. package/dist/src/index.d.ts +176 -152
  105. package/dist/src/index.js +305 -317
  106. package/dist/src/index.js.map +15 -15
  107. package/dist/src/leader.d.ts +1 -1
  108. package/dist/src/leader.js +7 -21
  109. package/dist/src/leader.js.map +5 -5
  110. package/dist/src/logger.js +1 -17
  111. package/dist/src/logger.js.map +2 -2
  112. package/dist/src/mode.d.ts +1 -1
  113. package/dist/src/mode.js +5 -21
  114. package/dist/src/mode.js.map +2 -2
  115. package/dist/src/node/archive-client.d.ts +1 -1
  116. package/dist/src/node/archive-client.js +9 -23
  117. package/dist/src/node/archive-client.js.map +5 -5
  118. package/dist/src/node/client.d.ts +1 -1
  119. package/dist/src/node/client.js +4 -18
  120. package/dist/src/node/client.js.map +5 -5
  121. package/dist/src/node/consensus.d.ts +1 -1
  122. package/dist/src/node/consensus.js +5 -21
  123. package/dist/src/node/consensus.js.map +2 -2
  124. package/dist/src/node/hiro-client.d.ts +1 -1
  125. package/dist/src/node/hiro-client.js +1 -17
  126. package/dist/src/node/hiro-client.js.map +2 -2
  127. package/dist/src/node/hiro-pg-client.js +1 -17
  128. package/dist/src/node/hiro-pg-client.js.map +2 -2
  129. package/dist/src/node/local-client.d.ts +27 -2
  130. package/dist/src/node/local-client.js +3 -19
  131. package/dist/src/node/local-client.js.map +2 -2
  132. package/dist/src/node/nakamoto.d.ts +1 -1
  133. package/dist/src/node/nakamoto.js +12 -28
  134. package/dist/src/node/nakamoto.js.map +2 -2
  135. package/dist/src/queue/listener.d.ts +1 -1
  136. package/dist/src/queue/listener.js +4 -20
  137. package/dist/src/queue/listener.js.map +2 -2
  138. package/dist/src/runtime/index.d.ts +1 -1
  139. package/dist/src/runtime/index.js +51 -67
  140. package/dist/src/runtime/index.js.map +2 -2
  141. package/dist/src/schemas/index.d.ts +8 -4
  142. package/dist/src/schemas/index.js +64 -41
  143. package/dist/src/schemas/index.js.map +4 -4
  144. package/dist/src/schemas/subgraphs.d.ts +1 -4
  145. package/dist/src/schemas/subgraphs.js +1 -18
  146. package/dist/src/schemas/subgraphs.js.map +3 -3
  147. package/dist/src/schemas/webhooks.d.ts +19 -1
  148. package/dist/src/schemas/webhooks.js +70 -41
  149. package/dist/src/schemas/webhooks.js.map +3 -3
  150. package/dist/src/streams-bulk-manifest.d.ts +1 -1
  151. package/dist/src/streams-bulk-manifest.js +9 -9
  152. package/dist/src/streams-bulk-manifest.js.map +1 -1
  153. package/dist/src/streams-rows/index.d.ts +1 -1
  154. package/dist/src/streams-rows/index.js +32 -48
  155. package/dist/src/streams-rows/index.js.map +2 -2
  156. package/dist/src/subgraphs/spec.d.ts +1 -11
  157. package/dist/src/subgraphs/spec.js +27 -93
  158. package/dist/src/subgraphs/spec.js.map +3 -3
  159. package/dist/src/types.d.ts +1 -1
  160. package/migrations/0136_drop_subgraph_visibility.ts +34 -0
  161. package/migrations/0137_webhook_outbox_last_error.ts +27 -0
  162. package/migrations/0138_usage_ledger.ts +46 -0
  163. package/package.json +1 -1
@@ -1,18 +1,14 @@
1
- import { createRequire } from "node:module";
2
- var __defProp = Object.defineProperty;
3
- var __returnValue = (v) => v;
4
- function __exportSetter(name, newValue) {
5
- this[name] = __returnValue.bind(null, newValue);
6
- }
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, {
10
- get: all[name],
11
- enumerable: true,
12
- configurable: true,
13
- set: __exportSetter.bind(all, name)
14
- });
15
- };
1
+ // src/crypto/secrets.ts
2
+ import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
3
+ import {
4
+ appendFileSync,
5
+ closeSync,
6
+ existsSync,
7
+ openSync,
8
+ readFileSync,
9
+ unlinkSync
10
+ } from "node:fs";
11
+ import { resolve } from "node:path";
16
12
 
17
13
  // src/mode.ts
18
14
  var VALID_MODES = [
@@ -50,16 +46,6 @@ function isOssMode() {
50
46
  }
51
47
 
52
48
  // src/crypto/secrets.ts
53
- import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
54
- import {
55
- appendFileSync,
56
- closeSync,
57
- existsSync,
58
- openSync,
59
- readFileSync,
60
- unlinkSync
61
- } from "node:fs";
62
- import { resolve } from "node:path";
63
49
  var KEY_ENV = "SECONDLAYER_SECRETS_KEY";
64
50
  var IV_LEN = 12;
65
51
  var TAG_LEN = 16;
@@ -173,11 +159,11 @@ function generateSecretsKey() {
173
159
  return randomBytes(32).toString("hex");
174
160
  }
175
161
  export {
176
- secretsKeyAvailable,
177
- generateSecretsKey,
162
+ decryptSecret,
178
163
  encryptSecret,
179
- decryptSecret
164
+ generateSecretsKey,
165
+ secretsKeyAvailable
180
166
  };
181
167
 
182
- //# debugId=8E49B42A8C43DF1864756E2164756E21
168
+ //# debugId=38F3B263F0011FBC64756E2164756E21
183
169
  //# sourceMappingURL=secrets.js.map
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/mode.ts", "../src/crypto/secrets.ts"],
3
+ "sources": ["../src/crypto/secrets.ts", "../src/mode.ts"],
4
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 { 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"
5
+ "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",
6
+ "/**\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"
7
7
  ],
8
- "mappings": "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",
9
- "debugId": "8E49B42A8C43DF1864756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "38F3B263F0011FBC64756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -30,4 +30,4 @@ interface VerifyOptions {
30
30
  nowSeconds?: number;
31
31
  }
32
32
  declare function verify(body: string, headers: StandardWebhooksHeaders | Record<string, string | string[] | undefined>, secret: string, opts?: VerifyOptions): boolean;
33
- export { verify, sign, VerifyOptions, StandardWebhooksHeaders, SignOptions };
33
+ export { SignOptions, StandardWebhooksHeaders, VerifyOptions, sign, verify };
@@ -1,19 +1,3 @@
1
- import { createRequire } from "node:module";
2
- var __defProp = Object.defineProperty;
3
- var __returnValue = (v) => v;
4
- function __exportSetter(name, newValue) {
5
- this[name] = __returnValue.bind(null, newValue);
6
- }
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, {
10
- get: all[name],
11
- enumerable: true,
12
- configurable: true,
13
- set: __exportSetter.bind(all, name)
14
- });
15
- };
16
-
17
1
  // src/crypto/standard-webhooks.ts
18
2
  import { createHmac, randomUUID } from "node:crypto";
19
3
  function secretToKey(secret) {
@@ -69,9 +53,9 @@ function verify(body, headers, secret, opts = {}) {
69
53
  return false;
70
54
  }
71
55
  export {
72
- verify,
73
- sign
56
+ sign,
57
+ verify
74
58
  };
75
59
 
76
- //# debugId=AE46F7E38D913C0D64756E2164756E21
60
+ //# debugId=654C7AE2023504E464756E2164756E21
77
61
  //# sourceMappingURL=standard-webhooks.js.map
@@ -4,7 +4,7 @@
4
4
  "sourcesContent": [
5
5
  "import { createHmac, randomUUID } from \"node:crypto\";\n\n/**\n * Standard Webhooks signing helpers — https://standardwebhooks.com\n *\n * Produces the three headers that every Standard Webhooks receiver expects:\n * webhook-id — UUID identifying the delivery (used for dedup)\n * webhook-timestamp — unix seconds, receiver rejects if skew > tolerance\n * webhook-signature — space-separated list of `vN,<base64-hmac>` tuples\n *\n * The signed content is `{id}.{timestamp}.{body}`. The HMAC key is the raw\n * bytes of the secret. If the secret is a `whsec_`-prefixed base64 string\n * (the Svix convention) we base64-decode after stripping the prefix;\n * otherwise we use the UTF-8 bytes directly.\n */\n\nexport interface StandardWebhooksHeaders {\n\t\"webhook-id\": string;\n\t\"webhook-timestamp\": string;\n\t\"webhook-signature\": string;\n}\n\nexport interface SignOptions {\n\t/** Override the delivery id. Defaults to a random UUID v4. */\n\tid?: string;\n\t/** Override the timestamp (unix seconds). Defaults to `Date.now()`. */\n\ttimestampSeconds?: number;\n}\n\nfunction secretToKey(secret: string): Buffer {\n\tif (secret.startsWith(\"whsec_\")) {\n\t\treturn Buffer.from(secret.slice(\"whsec_\".length), \"base64\");\n\t}\n\treturn Buffer.from(secret, \"utf8\");\n}\n\nexport function sign(\n\tbody: string,\n\tsecret: string,\n\topts: SignOptions = {},\n): StandardWebhooksHeaders {\n\tconst id = opts.id ?? randomUUID();\n\tconst timestamp = String(\n\t\topts.timestampSeconds ?? Math.floor(Date.now() / 1000),\n\t);\n\tconst toSign = `${id}.${timestamp}.${body}`;\n\tconst key = secretToKey(secret);\n\tconst signature = createHmac(\"sha256\", key).update(toSign).digest(\"base64\");\n\treturn {\n\t\t\"webhook-id\": id,\n\t\t\"webhook-timestamp\": timestamp,\n\t\t\"webhook-signature\": `v1,${signature}`,\n\t};\n}\n\nexport interface VerifyOptions {\n\t/** Max clock skew in seconds. Default 5 minutes per spec. */\n\ttoleranceSeconds?: number;\n\t/** Current time in unix seconds. Injectable for testing. */\n\tnowSeconds?: number;\n}\n\nexport function verify(\n\tbody: string,\n\theaders:\n\t\t| StandardWebhooksHeaders\n\t\t| Record<string, string | string[] | undefined>,\n\tsecret: string,\n\topts: VerifyOptions = {},\n): boolean {\n\tconst pick = (k: string) => {\n\t\tconst v = (headers as Record<string, unknown>)[k];\n\t\treturn typeof v === \"string\" ? v : undefined;\n\t};\n\tconst id = pick(\"webhook-id\");\n\tconst timestamp = pick(\"webhook-timestamp\");\n\tconst sigHeader = pick(\"webhook-signature\");\n\tif (!id || !timestamp || !sigHeader) return false;\n\n\tconst ts = Number.parseInt(timestamp, 10);\n\tif (!Number.isFinite(ts)) return false;\n\tconst tolerance = opts.toleranceSeconds ?? 5 * 60;\n\tconst now = opts.nowSeconds ?? Math.floor(Date.now() / 1000);\n\tif (Math.abs(now - ts) > tolerance) return false;\n\n\tconst key = secretToKey(secret);\n\tconst expected = createHmac(\"sha256\", key)\n\t\t.update(`${id}.${timestamp}.${body}`)\n\t\t.digest(\"base64\");\n\n\t// webhook-signature can carry multiple versions: \"v1,abc v1a,def\"\n\tfor (const part of sigHeader.split(\" \")) {\n\t\tconst [version, sig] = part.split(\",\", 2);\n\t\tif (version !== \"v1\" || !sig) continue;\n\t\tif (sig.length !== expected.length) continue;\n\t\tlet diff = 0;\n\t\tfor (let i = 0; i < sig.length; i++) {\n\t\t\tdiff |= sig.charCodeAt(i) ^ expected.charCodeAt(i);\n\t\t}\n\t\tif (diff === 0) return true;\n\t}\n\treturn false;\n}\n"
6
6
  ],
7
- "mappings": ";;;;;;;;;;;;;;;;;AAAA;AA6BA,SAAS,WAAW,CAAC,QAAwB;AAAA,EAC5C,IAAI,OAAO,WAAW,QAAQ,GAAG;AAAA,IAChC,OAAO,OAAO,KAAK,OAAO,MAAM,SAAS,MAAM,GAAG,QAAQ;AAAA,EAC3D;AAAA,EACA,OAAO,OAAO,KAAK,QAAQ,MAAM;AAAA;AAG3B,SAAS,IAAI,CACnB,MACA,QACA,OAAoB,CAAC,GACK;AAAA,EAC1B,MAAM,KAAK,KAAK,MAAM,WAAW;AAAA,EACjC,MAAM,YAAY,OACjB,KAAK,oBAAoB,KAAK,MAAM,KAAK,IAAI,IAAI,IAAI,CACtD;AAAA,EACA,MAAM,SAAS,GAAG,MAAM,aAAa;AAAA,EACrC,MAAM,MAAM,YAAY,MAAM;AAAA,EAC9B,MAAM,YAAY,WAAW,UAAU,GAAG,EAAE,OAAO,MAAM,EAAE,OAAO,QAAQ;AAAA,EAC1E,OAAO;AAAA,IACN,cAAc;AAAA,IACd,qBAAqB;AAAA,IACrB,qBAAqB,MAAM;AAAA,EAC5B;AAAA;AAUM,SAAS,MAAM,CACrB,MACA,SAGA,QACA,OAAsB,CAAC,GACb;AAAA,EACV,MAAM,OAAO,CAAC,MAAc;AAAA,IAC3B,MAAM,IAAK,QAAoC;AAAA,IAC/C,OAAO,OAAO,MAAM,WAAW,IAAI;AAAA;AAAA,EAEpC,MAAM,KAAK,KAAK,YAAY;AAAA,EAC5B,MAAM,YAAY,KAAK,mBAAmB;AAAA,EAC1C,MAAM,YAAY,KAAK,mBAAmB;AAAA,EAC1C,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;AAAA,IAAW,OAAO;AAAA,EAE5C,MAAM,KAAK,OAAO,SAAS,WAAW,EAAE;AAAA,EACxC,IAAI,CAAC,OAAO,SAAS,EAAE;AAAA,IAAG,OAAO;AAAA,EACjC,MAAM,YAAY,KAAK,oBAAoB,IAAI;AAAA,EAC/C,MAAM,MAAM,KAAK,cAAc,KAAK,MAAM,KAAK,IAAI,IAAI,IAAI;AAAA,EAC3D,IAAI,KAAK,IAAI,MAAM,EAAE,IAAI;AAAA,IAAW,OAAO;AAAA,EAE3C,MAAM,MAAM,YAAY,MAAM;AAAA,EAC9B,MAAM,WAAW,WAAW,UAAU,GAAG,EACvC,OAAO,GAAG,MAAM,aAAa,MAAM,EACnC,OAAO,QAAQ;AAAA,EAGjB,WAAW,QAAQ,UAAU,MAAM,GAAG,GAAG;AAAA,IACxC,OAAO,SAAS,OAAO,KAAK,MAAM,KAAK,CAAC;AAAA,IACxC,IAAI,YAAY,QAAQ,CAAC;AAAA,MAAK;AAAA,IAC9B,IAAI,IAAI,WAAW,SAAS;AAAA,MAAQ;AAAA,IACpC,IAAI,OAAO;AAAA,IACX,SAAS,IAAI,EAAG,IAAI,IAAI,QAAQ,KAAK;AAAA,MACpC,QAAQ,IAAI,WAAW,CAAC,IAAI,SAAS,WAAW,CAAC;AAAA,IAClD;AAAA,IACA,IAAI,SAAS;AAAA,MAAG,OAAO;AAAA,EACxB;AAAA,EACA,OAAO;AAAA;",
8
- "debugId": "AE46F7E38D913C0D64756E2164756E21",
7
+ "mappings": ";AAAA;AA6BA,SAAS,WAAW,CAAC,QAAwB;AAAA,EAC5C,IAAI,OAAO,WAAW,QAAQ,GAAG;AAAA,IAChC,OAAO,OAAO,KAAK,OAAO,MAAM,SAAS,MAAM,GAAG,QAAQ;AAAA,EAC3D;AAAA,EACA,OAAO,OAAO,KAAK,QAAQ,MAAM;AAAA;AAG3B,SAAS,IAAI,CACnB,MACA,QACA,OAAoB,CAAC,GACK;AAAA,EAC1B,MAAM,KAAK,KAAK,MAAM,WAAW;AAAA,EACjC,MAAM,YAAY,OACjB,KAAK,oBAAoB,KAAK,MAAM,KAAK,IAAI,IAAI,IAAI,CACtD;AAAA,EACA,MAAM,SAAS,GAAG,MAAM,aAAa;AAAA,EACrC,MAAM,MAAM,YAAY,MAAM;AAAA,EAC9B,MAAM,YAAY,WAAW,UAAU,GAAG,EAAE,OAAO,MAAM,EAAE,OAAO,QAAQ;AAAA,EAC1E,OAAO;AAAA,IACN,cAAc;AAAA,IACd,qBAAqB;AAAA,IACrB,qBAAqB,MAAM;AAAA,EAC5B;AAAA;AAUM,SAAS,MAAM,CACrB,MACA,SAGA,QACA,OAAsB,CAAC,GACb;AAAA,EACV,MAAM,OAAO,CAAC,MAAc;AAAA,IAC3B,MAAM,IAAK,QAAoC;AAAA,IAC/C,OAAO,OAAO,MAAM,WAAW,IAAI;AAAA;AAAA,EAEpC,MAAM,KAAK,KAAK,YAAY;AAAA,EAC5B,MAAM,YAAY,KAAK,mBAAmB;AAAA,EAC1C,MAAM,YAAY,KAAK,mBAAmB;AAAA,EAC1C,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;AAAA,IAAW,OAAO;AAAA,EAE5C,MAAM,KAAK,OAAO,SAAS,WAAW,EAAE;AAAA,EACxC,IAAI,CAAC,OAAO,SAAS,EAAE;AAAA,IAAG,OAAO;AAAA,EACjC,MAAM,YAAY,KAAK,oBAAoB,IAAI;AAAA,EAC/C,MAAM,MAAM,KAAK,cAAc,KAAK,MAAM,KAAK,IAAI,IAAI,IAAI;AAAA,EAC3D,IAAI,KAAK,IAAI,MAAM,EAAE,IAAI;AAAA,IAAW,OAAO;AAAA,EAE3C,MAAM,MAAM,YAAY,MAAM;AAAA,EAC9B,MAAM,WAAW,WAAW,UAAU,GAAG,EACvC,OAAO,GAAG,MAAM,aAAa,MAAM,EACnC,OAAO,QAAQ;AAAA,EAGjB,WAAW,QAAQ,UAAU,MAAM,GAAG,GAAG;AAAA,IACxC,OAAO,SAAS,OAAO,KAAK,MAAM,KAAK,CAAC;AAAA,IACxC,IAAI,YAAY,QAAQ,CAAC;AAAA,MAAK;AAAA,IAC9B,IAAI,IAAI,WAAW,SAAS;AAAA,MAAQ;AAAA,IACpC,IAAI,OAAO;AAAA,IACX,SAAS,IAAI,EAAG,IAAI,IAAI,QAAQ,KAAK;AAAA,MACpC,QAAQ,IAAI,WAAW,CAAC,IAAI,SAAS,WAAW,CAAC;AAAA,IAClD;AAAA,IACA,IAAI,SAAS;AAAA,MAAG,OAAO;AAAA,EACxB;AAAA,EACA,OAAO;AAAA;",
8
+ "debugId": "654C7AE2023504E464756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,20 +1,3 @@
1
- import { RawBuilder } from "kysely";
2
- /**
3
- * Safely encode a JS value as a JSONB literal for Kysely inserts/updates.
4
- * Kysely + postgres.js double-encodes JSON when using parameterized queries
5
- * with ::jsonb casts. This uses sql.raw to inline a properly escaped literal.
6
- *
7
- * Generic parameter lets callers set the RawBuilder's output type so they
8
- * don't need to cast at the insert site. Default is `unknown` — widen at
9
- * the call site when the column type is narrower, e.g. `jsonb<MyShape>(...)`.
10
- */
11
- declare function jsonb<T = unknown>(value: T): RawBuilder<T>;
12
- /**
13
- * Safely parse a JSONB value from the database.
14
- * Handles double-encoded strings where postgres.js returns a JSON string
15
- * instead of a parsed object.
16
- */
17
- declare function parseJsonb<T = unknown>(value: unknown): T;
18
1
  import { Kysely } from "kysely";
19
2
  import postgres from "postgres";
20
3
  import { ColumnType, Generated, Insertable, Selectable, Updateable } from "kysely";
@@ -171,7 +154,6 @@ interface SubgraphsTable {
171
154
  handler_code: string | null;
172
155
  source_code: string | null;
173
156
  project_id: string | null;
174
- visibility: Generated<string>;
175
157
  /** Paid (wallet-ghost) deploys expire unless renewed or claimed; NULL = no expiry. */
176
158
  expires_at: Date | null;
177
159
  /** (event type, contract) probe pairs persisted at deploy for weight classification. */
@@ -801,6 +783,7 @@ interface Database {
801
783
  coverage_segments: CoverageSegmentsTable;
802
784
  stage_failures: StageFailuresTable;
803
785
  archive_fetches: ArchiveFetchesTable;
786
+ usage_ledger: UsageLedgerTable;
804
787
  waitlists: WaitlistsTable;
805
788
  waitlist_signups: WaitlistSignupsTable;
806
789
  }
@@ -854,6 +837,30 @@ interface ArchiveFetchesTable {
854
837
  type ArchiveFetch = Selectable<ArchiveFetchesTable>;
855
838
  type InsertArchiveFetch = Insertable<ArchiveFetchesTable>;
856
839
  type UpdateArchiveFetch = Updateable<ArchiveFetchesTable>;
840
+ /**
841
+ * One metered ledger for every billable unit (archive partitions, hosted
842
+ * Index/Streams rows, and future hosted-stack meters). Append-only, written
843
+ * only by `meter()`. `idempotency_key` is UNIQUE so a retried submission
844
+ * no-ops instead of double-charging. `debited` is false when the balance
845
+ * (or a spend cap) refused the charge — the row still exists so the gap is
846
+ * visible, never silently dropped. `usd_micros` is negative for a Stripe
847
+ * top-up (`unit: "topup"`).
848
+ */
849
+ interface UsageLedgerTable {
850
+ id: Generated<string>;
851
+ account_id: string;
852
+ unit: string;
853
+ quantity: string | number | bigint;
854
+ usd_micros: string | number | bigint;
855
+ debited: Generated<boolean>;
856
+ source: string;
857
+ idempotency_key: string;
858
+ occurred_at: Generated<Date>;
859
+ recorded_at: Generated<Date>;
860
+ }
861
+ type UsageLedgerRow = Selectable<UsageLedgerTable>;
862
+ type InsertUsageLedgerRow = Insertable<UsageLedgerTable>;
863
+ type UpdateUsageLedgerRow = Updateable<UsageLedgerTable>;
857
864
  type Block = Selectable<BlocksTable>;
858
865
  type InsertBlock = Insertable<BlocksTable>;
859
866
  type UpdateBlock = Updateable<BlocksTable>;
@@ -958,6 +965,10 @@ interface WebhookOutboxTable {
958
965
  failed_at: Date | null;
959
966
  locked_by: string | null;
960
967
  locked_until: Date | null;
968
+ /** Set when a reorg marks an in-flight row `dead` instead of retrying it
969
+ * into an orphaned fork. Null otherwise — delivery failures track their
970
+ * history on `webhooks.last_error`, not per-row. */
971
+ last_error: string | null;
961
972
  created_at: Generated<Date>;
962
973
  }
963
974
  type WebhookOutbox = Selectable<WebhookOutboxTable>;
@@ -1847,6 +1858,23 @@ declare const SOURCE_READ_PKS: {
1847
1858
  readonly events: readonly ["tx_id", "event_index"]
1848
1859
  readonly chain_reorgs: null
1849
1860
  };
1861
+ import { RawBuilder } from "kysely";
1862
+ /**
1863
+ * Safely encode a JS value as a JSONB literal for Kysely inserts/updates.
1864
+ * Kysely + postgres.js double-encodes JSON when using parameterized queries
1865
+ * with ::jsonb casts. This uses sql.raw to inline a properly escaped literal.
1866
+ *
1867
+ * Generic parameter lets callers set the RawBuilder's output type so they
1868
+ * don't need to cast at the insert site. Default is `unknown` — widen at
1869
+ * the call site when the column type is narrower, e.g. `jsonb<MyShape>(...)`.
1870
+ */
1871
+ declare function jsonb<T = unknown>(value: T): RawBuilder<T>;
1872
+ /**
1873
+ * Safely parse a JSONB value from the database.
1874
+ * Handles double-encoded strings where postgres.js returns a JSON string
1875
+ * instead of a parsed object.
1876
+ */
1877
+ declare function parseJsonb<T = unknown>(value: unknown): T;
1850
1878
  /**
1851
1879
  * Per-migration DB-plane gating for the source/target split.
1852
1880
  *
@@ -1951,6 +1979,7 @@ declare const TABLE_TO_DB: {
1951
1979
  subgraph_processing_stats: string
1952
1980
  account_credits: string
1953
1981
  archive_fetches: string
1982
+ usage_ledger: string
1954
1983
  waitlists: string
1955
1984
  waitlist_signups: string
1956
1985
  service_heartbeats: string
@@ -2024,4 +2053,4 @@ declare function getRawClient(role?: "source" | "target"): ReturnType<typeof pos
2024
2053
  declare function getRawClientFor(url: string): ReturnType<typeof postgres>;
2025
2054
  /** Close all DB connection pools. Call in CLI commands to allow process exit. */
2026
2055
  declare function closeDb(): Promise<void>;
2027
- export { sql, setMigrationRole, parseJsonb, onControlPlane, onChainPlane, jsonb, getTargetDb, getSourceDb, getRawClientFor, getRawClient, getMigrationRole, getDbSplitStatus, getDb, closeDb, assertDbSplit, applicationDatabaseUrl, WebhooksTable, WebhookStatus, WebhookRuntime, WebhookOutboxTable, WebhookOutbox, WebhookKind, WebhookFormat, WebhookDelivery, WebhookDeliveriesTable, Webhook, WaitlistsTable, WaitlistSignupsTable, WaitlistSignup, Waitlist, VmEventsTable, VmEventsArchiveTable, VmEvent, UpdateWebhookOutbox, UpdateWebhook, UpdateVmEvent, UpdateTransaction, UpdateSubgraphOperation, UpdateSubgraph, UpdateIndexProgress, UpdateEvent, UpdateContract, UpdateBlock, UpdateArchiveFetch, UpdateApiKey, UpdateAccountSpendCap, UpdateAccountCredits, TriggerEvaluatorStateTable, TriggerEvaluatorState, TransactionsTable, TransactionsArchiveTable, Transaction, TABLE_TO_DB, SyncScopesTable, SubgraphsTable, SubgraphViolationsTable, SubgraphProcessingStatsTable, SubgraphOperationsTable, SubgraphOperationStatus, SubgraphOperationKind, SubgraphOperation, SubgraphHealthSnapshotsTable, SubgraphHealthSnapshot, SubgraphGapsTable, SubgraphGap, Subgraph, StageRunsTable, StageRegistryTable, StageKind, StageFailuresTable, StageBlockReceiptsTable, SessionsTable, Session, ServiceHeartbeatsTable, SbtcTokenEventsTable, SbtcTokenEventType, SbtcSettlementsTable, SbtcEventsTable, SbtcEventTopic, SOURCE_READ_TYPES, SOURCE_READ_PKS, SOURCE_READ_COLUMNS, RunStatus, RetryState, RepairMode, ProcessedStripeEventsTable, Pox5EventsTable, Pox5EventTopic, Pox4FunctionName, Pox4CallsTable, PendingForkBlocksTable, OutboxStatus, ObserverJournalTable, ObserverJournalStatus, NumericAsText, NativeClock, MigrationRole, MempoolTransactionsTable, MempoolTransaction, MagicLinksTable, MagicLink, InstancesTable, InsertWebhookOutbox, InsertWebhookDelivery, InsertWebhook, InsertWaitlistSignup, InsertVmEvent, InsertTransaction, InsertSubgraphOperation, InsertSubgraphHealthSnapshot, InsertSubgraphGap, InsertSubgraph, InsertSession, InsertMempoolTransaction, InsertMagicLink, InsertIndexProgress, InsertEvent, InsertContract, InsertBlock, InsertArchiveFetch, InsertApiKey, InsertAccountSpendCap, InsertAccountCredits, InsertAccount, IndexProgressTable, IndexProgress, IndexPrimaryKey, IndexColumnType, IndexColumn, FailureUnit, FailureClass, EventsTable, EventsArchiveTable, Event, DecoderCheckpointsTable, DecodedEventsTable, DeadLetterEventsTable, DbSplitStatus, DbReadRow, DbPlane, Database, CoverageSegmentsTable, ContractsTable, Contract, ChainReorgsTable, ChainReadCacheTable, BurnBlockRewardsTable, BurnBlockRewardSlotsTable, BnsNamespacesTable, BnsNamespaceEventsTable, BnsNamespaceEventStatus, BnsNamesTable, BnsNameEventsTable, BnsNameEventTopic, BnsMarketplaceEventsTable, BnsMarketplaceAction, BlocksTable, Block, ArchiveFetchesTable, ArchiveFetch, ApiKeysTable, ApiKey, AccountsTable, AccountSpendCapsTable, AccountSpendCap, AccountCreditsTable, AccountCredits, Account };
2056
+ export { Account, 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, DbPlane, DbReadRow, DbSplitStatus, DeadLetterEventsTable, DecodedEventsTable, DecoderCheckpointsTable, Event, EventsArchiveTable, EventsTable, FailureClass, FailureUnit, IndexColumn, IndexColumnType, IndexPrimaryKey, IndexProgress, IndexProgressTable, InsertAccount, InsertAccountCredits, InsertAccountSpendCap, InsertApiKey, InsertArchiveFetch, InsertBlock, InsertContract, InsertEvent, InsertIndexProgress, InsertMagicLink, InsertMempoolTransaction, InsertSession, InsertSubgraph, InsertSubgraphGap, InsertSubgraphHealthSnapshot, InsertSubgraphOperation, InsertTransaction, InsertUsageLedgerRow, InsertVmEvent, InsertWaitlistSignup, InsertWebhook, InsertWebhookDelivery, InsertWebhookOutbox, InstancesTable, MagicLink, MagicLinksTable, MempoolTransaction, MempoolTransactionsTable, MigrationRole, NativeClock, NumericAsText, ObserverJournalStatus, ObserverJournalTable, OutboxStatus, PendingForkBlocksTable, Pox4CallsTable, Pox4FunctionName, Pox5EventTopic, Pox5EventsTable, ProcessedStripeEventsTable, RepairMode, RetryState, RunStatus, SOURCE_READ_COLUMNS, SOURCE_READ_PKS, SOURCE_READ_TYPES, SbtcEventTopic, SbtcEventsTable, SbtcSettlementsTable, SbtcTokenEventType, SbtcTokenEventsTable, ServiceHeartbeatsTable, Session, SessionsTable, StageBlockReceiptsTable, StageFailuresTable, StageKind, StageRegistryTable, StageRunsTable, Subgraph, SubgraphGap, SubgraphGapsTable, SubgraphHealthSnapshot, SubgraphHealthSnapshotsTable, SubgraphOperation, SubgraphOperationKind, SubgraphOperationStatus, SubgraphOperationsTable, SubgraphProcessingStatsTable, SubgraphViolationsTable, SubgraphsTable, SyncScopesTable, TABLE_TO_DB, Transaction, TransactionsArchiveTable, TransactionsTable, TriggerEvaluatorState, TriggerEvaluatorStateTable, 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, applicationDatabaseUrl, assertDbSplit, closeDb, getDb, getDbSplitStatus, getMigrationRole, getRawClient, getRawClientFor, getSourceDb, getTargetDb, jsonb, onChainPlane, onControlPlane, parseJsonb, setMigrationRole, sql };
@@ -1,18 +1,7 @@
1
- import { createRequire } from "node:module";
2
- var __defProp = Object.defineProperty;
3
- var __returnValue = (v) => v;
4
- function __exportSetter(name, newValue) {
5
- this[name] = __returnValue.bind(null, newValue);
6
- }
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, {
10
- get: all[name],
11
- enumerable: true,
12
- configurable: true,
13
- set: __exportSetter.bind(all, name)
14
- });
15
- };
1
+ // src/db/index.ts
2
+ import { Kysely } from "kysely";
3
+ import { PostgresJSDialect } from "kysely-postgres-js";
4
+ import postgres from "postgres";
16
5
 
17
6
  // src/env.ts
18
7
  import { z } from "zod";
@@ -179,27 +168,7 @@ function isOssMode() {
179
168
  return getInstanceMode() === "oss";
180
169
  }
181
170
 
182
- // src/db/jsonb.ts
183
- import { sql } from "kysely";
184
- function jsonb(value) {
185
- const escaped = JSON.stringify(value, (_k, v) => typeof v === "bigint" ? v.toString() : v).replace(/'/g, "''");
186
- return sql`${sql.raw(`'${escaped}'::jsonb`)}`;
187
- }
188
- function parseJsonb(value) {
189
- if (typeof value === "string") {
190
- try {
191
- return JSON.parse(value);
192
- } catch {
193
- return value;
194
- }
195
- }
196
- return value ?? {};
197
- }
198
-
199
171
  // src/db/index.ts
200
- import { Kysely } from "kysely";
201
- import { PostgresJSDialect } from "kysely-postgres-js";
202
- import postgres from "postgres";
203
172
  import { sql as sql2 } from "kysely";
204
173
 
205
174
  // src/db/source-read-columns.ts
@@ -716,6 +685,22 @@ var SOURCE_READ_PKS = {
716
685
  events: ["tx_id", "event_index"],
717
686
  chain_reorgs: null
718
687
  };
688
+ // src/db/jsonb.ts
689
+ import { sql } from "kysely";
690
+ function jsonb(value) {
691
+ const escaped = JSON.stringify(value, (_k, v) => typeof v === "bigint" ? v.toString() : v).replace(/'/g, "''");
692
+ return sql`${sql.raw(`'${escaped}'::jsonb`)}`;
693
+ }
694
+ function parseJsonb(value) {
695
+ if (typeof value === "string") {
696
+ try {
697
+ return JSON.parse(value);
698
+ } catch {
699
+ return value;
700
+ }
701
+ }
702
+ return value ?? {};
703
+ }
719
704
  // src/db/migration-role.ts
720
705
  var currentRole = "both";
721
706
  function setMigrationRole(role) {
@@ -788,6 +773,7 @@ var TABLE_TO_DB = {
788
773
  subgraph_processing_stats: "target",
789
774
  account_credits: "target",
790
775
  archive_fetches: "target",
776
+ usage_ledger: "target",
791
777
  waitlists: "target",
792
778
  waitlist_signups: "target",
793
779
  service_heartbeats: "both"
@@ -970,27 +956,27 @@ async function closeDb() {
970
956
  pools.clear();
971
957
  }
972
958
  export {
973
- sql2 as sql,
974
- setMigrationRole,
975
- parseJsonb,
976
- onControlPlane,
977
- onChainPlane,
978
- jsonb,
979
- getTargetDb,
980
- getSourceDb,
981
- getRawClientFor,
982
- getRawClient,
983
- getMigrationRole,
984
- getDbSplitStatus,
985
- getDb,
986
- closeDb,
987
- assertDbSplit,
988
- applicationDatabaseUrl,
989
- TABLE_TO_DB,
990
- SOURCE_READ_TYPES,
959
+ SOURCE_READ_COLUMNS,
991
960
  SOURCE_READ_PKS,
992
- SOURCE_READ_COLUMNS
961
+ SOURCE_READ_TYPES,
962
+ TABLE_TO_DB,
963
+ applicationDatabaseUrl,
964
+ assertDbSplit,
965
+ closeDb,
966
+ getDb,
967
+ getDbSplitStatus,
968
+ getMigrationRole,
969
+ getRawClient,
970
+ getRawClientFor,
971
+ getSourceDb,
972
+ getTargetDb,
973
+ jsonb,
974
+ onChainPlane,
975
+ onControlPlane,
976
+ parseJsonb,
977
+ setMigrationRole,
978
+ sql2 as sql
993
979
  };
994
980
 
995
- //# debugId=9B89E15CFB7142D864756E2164756E21
981
+ //# debugId=47CB5F5A1643B5DD64756E2164756E21
996
982
  //# sourceMappingURL=index.js.map