@secondlayer/shared 11.7.0 → 11.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/archive/copy-loader.d.ts +1 -1
- package/dist/src/archive/copy-loader.js +4 -20
- package/dist/src/archive/copy-loader.js.map +2 -2
- package/dist/src/archive/derived-stage-report.d.ts +1 -1
- package/dist/src/archive/derived-stage-report.js +3 -19
- package/dist/src/archive/derived-stage-report.js.map +2 -2
- package/dist/src/archive/disk-guard.d.ts +1 -1
- package/dist/src/archive/disk-guard.js +3 -19
- package/dist/src/archive/disk-guard.js.map +2 -2
- package/dist/src/archive/instance-diagnosis.d.ts +1 -1
- package/dist/src/archive/instance-diagnosis.js +6 -22
- package/dist/src/archive/instance-diagnosis.js.map +2 -2
- package/dist/src/archive/key-registry.d.ts +1 -1
- package/dist/src/archive/key-registry.js +12 -12
- package/dist/src/archive/key-registry.js.map +1 -1
- package/dist/src/archive/per-height-digest.d.ts +1 -1
- package/dist/src/archive/per-height-digest.js +3 -17
- package/dist/src/archive/per-height-digest.js.map +5 -5
- package/dist/src/archive/progress.d.ts +1 -1
- package/dist/src/archive/progress.js +4 -20
- package/dist/src/archive/progress.js.map +2 -2
- package/dist/src/archive/range-digest.d.ts +25 -30
- package/dist/src/archive/range-digest.js +4 -20
- package/dist/src/archive/range-digest.js.map +2 -2
- package/dist/src/archive/reference.d.ts +1 -1
- package/dist/src/archive/reference.js +14 -12
- package/dist/src/archive/reference.js.map +5 -5
- package/dist/src/archive/root-key.d.ts +1 -1
- package/dist/src/archive/root-key.js +3 -19
- package/dist/src/archive/root-key.js.map +2 -2
- package/dist/src/archive/semantic-digest-builder.d.ts +25 -30
- package/dist/src/archive/semantic-digest-builder.js +5 -19
- package/dist/src/archive/semantic-digest-builder.js.map +5 -5
- package/dist/src/archive/semantic-digest.d.ts +1 -1
- package/dist/src/archive/semantic-digest.js +4 -20
- package/dist/src/archive/semantic-digest.js.map +2 -2
- package/dist/src/archive/status.d.ts +1 -1
- package/dist/src/archive/status.js +4 -20
- package/dist/src/archive/status.js.map +2 -2
- package/dist/src/coverage/index.d.ts +24 -29
- package/dist/src/coverage/index.js +80 -96
- package/dist/src/coverage/index.js.map +2 -2
- package/dist/src/crypto/ed25519.d.ts +1 -1
- package/dist/src/crypto/ed25519.js +13 -13
- package/dist/src/crypto/ed25519.js.map +1 -1
- package/dist/src/crypto/hmac.d.ts +1 -1
- package/dist/src/crypto/hmac.js +9 -9
- package/dist/src/crypto/hmac.js.map +1 -1
- package/dist/src/crypto/secondlayer-webhook.d.ts +1 -1
- package/dist/src/crypto/secondlayer-webhook.js +14 -14
- package/dist/src/crypto/secondlayer-webhook.js.map +2 -2
- package/dist/src/crypto/secrets.d.ts +1 -1
- package/dist/src/crypto/secrets.js +15 -29
- package/dist/src/crypto/secrets.js.map +5 -5
- package/dist/src/crypto/standard-webhooks.d.ts +1 -1
- package/dist/src/crypto/standard-webhooks.js +3 -19
- package/dist/src/crypto/standard-webhooks.js.map +2 -2
- package/dist/src/db/index.d.ts +46 -57
- package/dist/src/db/index.js +42 -58
- package/dist/src/db/index.js.map +6 -6
- package/dist/src/db/jsonb.d.ts +1 -1
- package/dist/src/db/jsonb.js +3 -19
- package/dist/src/db/jsonb.js.map +2 -2
- package/dist/src/db/queries/chain-reorgs.d.ts +24 -29
- package/dist/src/db/queries/chain-reorgs.js +29 -45
- package/dist/src/db/queries/chain-reorgs.js.map +6 -6
- package/dist/src/db/queries/contracts.d.ts +24 -29
- package/dist/src/db/queries/contracts.js +9 -23
- package/dist/src/db/queries/contracts.js.map +5 -5
- package/dist/src/db/queries/instance.d.ts +24 -29
- package/dist/src/db/queries/instance.js +7 -23
- package/dist/src/db/queries/instance.js.map +2 -2
- package/dist/src/db/queries/integrity.d.ts +25 -30
- package/dist/src/db/queries/integrity.js +8 -23
- package/dist/src/db/queries/integrity.js.map +3 -3
- package/dist/src/db/queries/subgraph-gaps.d.ts +24 -29
- package/dist/src/db/queries/subgraph-gaps.js +5 -21
- package/dist/src/db/queries/subgraph-gaps.js.map +2 -2
- package/dist/src/db/queries/subgraph-operations.d.ts +24 -29
- package/dist/src/db/queries/subgraph-operations.js +17 -33
- package/dist/src/db/queries/subgraph-operations.js.map +2 -2
- package/dist/src/db/queries/subgraphs.d.ts +23 -44
- package/dist/src/db/queries/subgraphs.js +15 -46
- package/dist/src/db/queries/subgraphs.js.map +5 -5
- package/dist/src/db/queries/sync-scope.d.ts +24 -29
- package/dist/src/db/queries/sync-scope.js +6 -22
- package/dist/src/db/queries/sync-scope.js.map +2 -2
- package/dist/src/db/queries/webhooks.d.ts +24 -29
- package/dist/src/db/queries/webhooks.js +54 -50
- package/dist/src/db/queries/webhooks.js.map +5 -5
- package/dist/src/db/schema.d.ts +27 -37
- package/dist/src/env.d.ts +1 -1
- package/dist/src/env.js +7 -23
- package/dist/src/env.js.map +2 -2
- package/dist/src/errors.d.ts +1 -1
- package/dist/src/errors.js +15 -31
- package/dist/src/errors.js.map +2 -2
- package/dist/src/index-http.d.ts +1 -1
- package/dist/src/index-http.js +3 -19
- package/dist/src/index-http.js.map +2 -2
- package/dist/src/index-internal-auth.d.ts +1 -1
- package/dist/src/index-internal-auth.js +7 -23
- package/dist/src/index-internal-auth.js.map +2 -2
- package/dist/src/index.d.ts +164 -187
- package/dist/src/index.js +261 -316
- package/dist/src/index.js.map +13 -13
- package/dist/src/leader.d.ts +1 -1
- package/dist/src/leader.js +7 -21
- package/dist/src/leader.js.map +5 -5
- package/dist/src/logger.js +1 -17
- package/dist/src/logger.js.map +2 -2
- package/dist/src/mode.d.ts +1 -1
- package/dist/src/mode.js +5 -21
- package/dist/src/mode.js.map +2 -2
- package/dist/src/node/archive-client.d.ts +1 -1
- package/dist/src/node/archive-client.js +9 -23
- package/dist/src/node/archive-client.js.map +5 -5
- package/dist/src/node/client.d.ts +1 -1
- package/dist/src/node/client.js +4 -18
- package/dist/src/node/client.js.map +5 -5
- package/dist/src/node/consensus.d.ts +1 -1
- package/dist/src/node/consensus.js +5 -21
- package/dist/src/node/consensus.js.map +2 -2
- package/dist/src/node/hiro-client.d.ts +1 -1
- package/dist/src/node/hiro-client.js +1 -17
- package/dist/src/node/hiro-client.js.map +2 -2
- package/dist/src/node/hiro-pg-client.js +1 -17
- package/dist/src/node/hiro-pg-client.js.map +2 -2
- package/dist/src/node/local-client.d.ts +24 -29
- package/dist/src/node/local-client.js +3 -19
- package/dist/src/node/local-client.js.map +2 -2
- package/dist/src/node/nakamoto.d.ts +1 -1
- package/dist/src/node/nakamoto.js +12 -28
- package/dist/src/node/nakamoto.js.map +2 -2
- package/dist/src/queue/listener.d.ts +1 -1
- package/dist/src/queue/listener.js +4 -20
- package/dist/src/queue/listener.js.map +2 -2
- package/dist/src/runtime/index.d.ts +1 -1
- package/dist/src/runtime/index.js +51 -67
- package/dist/src/runtime/index.js.map +2 -2
- package/dist/src/schemas/index.d.ts +1 -4
- package/dist/src/schemas/index.js +19 -37
- package/dist/src/schemas/index.js.map +3 -3
- package/dist/src/schemas/subgraphs.d.ts +1 -4
- package/dist/src/schemas/subgraphs.js +1 -18
- package/dist/src/schemas/subgraphs.js.map +3 -3
- package/dist/src/schemas/webhooks.d.ts +1 -1
- package/dist/src/schemas/webhooks.js +21 -37
- package/dist/src/schemas/webhooks.js.map +2 -2
- package/dist/src/streams-bulk-manifest.d.ts +1 -1
- package/dist/src/streams-bulk-manifest.js +9 -9
- package/dist/src/streams-bulk-manifest.js.map +1 -1
- package/dist/src/streams-rows/index.d.ts +1 -1
- package/dist/src/streams-rows/index.js +32 -48
- package/dist/src/streams-rows/index.js.map +2 -2
- package/dist/src/subgraphs/spec.d.ts +1 -11
- package/dist/src/subgraphs/spec.js +27 -93
- package/dist/src/subgraphs/spec.js.map +3 -3
- package/dist/src/types.d.ts +1 -1
- package/migrations/0134_waitlists.ts +64 -0
- package/migrations/0135_drop_hosted_play_and_meters.ts +58 -0
- package/migrations/0136_drop_subgraph_visibility.ts +34 -0
- package/package.json +1 -1
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
177
|
-
generateSecretsKey,
|
|
162
|
+
decryptSecret,
|
|
178
163
|
encryptSecret,
|
|
179
|
-
|
|
164
|
+
generateSecretsKey,
|
|
165
|
+
secretsKeyAvailable
|
|
180
166
|
};
|
|
181
167
|
|
|
182
|
-
//# debugId=
|
|
168
|
+
//# debugId=38F3B263F0011FBC64756E2164756E21
|
|
183
169
|
//# sourceMappingURL=secrets.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/
|
|
3
|
+
"sources": ["../src/crypto/secrets.ts", "../src/mode.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n *
|
|
6
|
-
"
|
|
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": "
|
|
9
|
-
"debugId": "
|
|
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 {
|
|
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
|
-
|
|
73
|
-
|
|
56
|
+
sign,
|
|
57
|
+
verify
|
|
74
58
|
};
|
|
75
59
|
|
|
76
|
-
//# debugId=
|
|
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": "
|
|
8
|
-
"debugId": "
|
|
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
|
}
|
package/dist/src/db/index.d.ts
CHANGED
|
@@ -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. */
|
|
@@ -302,21 +284,6 @@ interface MagicLinksTable {
|
|
|
302
284
|
failed_attempts: Generated<number>;
|
|
303
285
|
created_at: Generated<Date>;
|
|
304
286
|
}
|
|
305
|
-
/** One-shot hashed tokens that attach a play ghost to an email at claim. */
|
|
306
|
-
interface ClaimTokensTable {
|
|
307
|
-
id: Generated<string>;
|
|
308
|
-
account_id: string;
|
|
309
|
-
token_hash: string;
|
|
310
|
-
created_at: Generated<Date>;
|
|
311
|
-
expires_at: Date;
|
|
312
|
-
used_at: Date | null;
|
|
313
|
-
}
|
|
314
|
-
/** 3 play provisions per IP per UTC day. PK (ip_hash, day); `count` caps at 3. */
|
|
315
|
-
interface PlayProvisionsTable {
|
|
316
|
-
ip_hash: string;
|
|
317
|
-
day: string;
|
|
318
|
-
count: Generated<number>;
|
|
319
|
-
}
|
|
320
287
|
interface SubgraphProcessingStatsTable {
|
|
321
288
|
id: Generated<string>;
|
|
322
289
|
subgraph_name: string;
|
|
@@ -778,8 +745,6 @@ interface Database {
|
|
|
778
745
|
accounts: AccountsTable;
|
|
779
746
|
sessions: SessionsTable;
|
|
780
747
|
magic_links: MagicLinksTable;
|
|
781
|
-
claim_tokens: ClaimTokensTable;
|
|
782
|
-
play_provisions: PlayProvisionsTable;
|
|
783
748
|
subgraph_health_snapshots: SubgraphHealthSnapshotsTable;
|
|
784
749
|
subgraph_processing_stats: SubgraphProcessingStatsTable;
|
|
785
750
|
subgraph_gaps: SubgraphGapsTable;
|
|
@@ -788,7 +753,6 @@ interface Database {
|
|
|
788
753
|
processed_stripe_events: ProcessedStripeEventsTable;
|
|
789
754
|
account_spend_caps: AccountSpendCapsTable;
|
|
790
755
|
account_credits: AccountCreditsTable;
|
|
791
|
-
hosted_meter_days: HostedMeterDaysTable;
|
|
792
756
|
webhooks: WebhooksTable;
|
|
793
757
|
webhook_outbox: WebhookOutboxTable;
|
|
794
758
|
webhook_deliveries: WebhookDeliveriesTable;
|
|
@@ -819,6 +783,8 @@ interface Database {
|
|
|
819
783
|
coverage_segments: CoverageSegmentsTable;
|
|
820
784
|
stage_failures: StageFailuresTable;
|
|
821
785
|
archive_fetches: ArchiveFetchesTable;
|
|
786
|
+
waitlists: WaitlistsTable;
|
|
787
|
+
waitlist_signups: WaitlistSignupsTable;
|
|
822
788
|
}
|
|
823
789
|
interface ServiceHeartbeatsTable {
|
|
824
790
|
name: string;
|
|
@@ -853,18 +819,6 @@ interface AccountCreditsTable {
|
|
|
853
819
|
type AccountCredits = Selectable<AccountCreditsTable>;
|
|
854
820
|
type InsertAccountCredits = Insertable<AccountCreditsTable>;
|
|
855
821
|
type UpdateAccountCredits = Updateable<AccountCreditsTable>;
|
|
856
|
-
/** Daily idempotency ledger for hosted subgraph running + storage meters. */
|
|
857
|
-
interface HostedMeterDaysTable {
|
|
858
|
-
day: string;
|
|
859
|
-
account_id: string;
|
|
860
|
-
subgraph_name: string;
|
|
861
|
-
kind: string;
|
|
862
|
-
usd_micros: string | number | bigint;
|
|
863
|
-
billed_at: Generated<Date>;
|
|
864
|
-
}
|
|
865
|
-
type HostedMeterDay = Selectable<HostedMeterDaysTable>;
|
|
866
|
-
type InsertHostedMeterDay = Insertable<HostedMeterDaysTable>;
|
|
867
|
-
type UpdateHostedMeterDay = Updateable<HostedMeterDaysTable>;
|
|
868
822
|
/**
|
|
869
823
|
* Archive fetch charge log (design-f089 gate). Append-only: one row per
|
|
870
824
|
* priced attempt to fetch a partition object. `usd_micros` is 0 for
|
|
@@ -915,11 +869,6 @@ type Account = Selectable<AccountsTable>;
|
|
|
915
869
|
type InsertAccount = Insertable<AccountsTable>;
|
|
916
870
|
type MagicLink = Selectable<MagicLinksTable>;
|
|
917
871
|
type InsertMagicLink = Insertable<MagicLinksTable>;
|
|
918
|
-
type ClaimToken = Selectable<ClaimTokensTable>;
|
|
919
|
-
type InsertClaimToken = Insertable<ClaimTokensTable>;
|
|
920
|
-
type UpdateClaimToken = Updateable<ClaimTokensTable>;
|
|
921
|
-
type PlayProvision = Selectable<PlayProvisionsTable>;
|
|
922
|
-
type InsertPlayProvision = Insertable<PlayProvisionsTable>;
|
|
923
872
|
type Session = Selectable<SessionsTable>;
|
|
924
873
|
type InsertSession = Insertable<SessionsTable>;
|
|
925
874
|
type SubgraphHealthSnapshot = Selectable<SubgraphHealthSnapshotsTable>;
|
|
@@ -1023,6 +972,30 @@ interface TriggerEvaluatorStateTable {
|
|
|
1023
972
|
updated_at: Generated<Date>;
|
|
1024
973
|
}
|
|
1025
974
|
type TriggerEvaluatorState = Selectable<TriggerEvaluatorStateTable>;
|
|
975
|
+
/** A public waitlist page: what it is for and whether it takes signups. */
|
|
976
|
+
interface WaitlistsTable {
|
|
977
|
+
slug: string;
|
|
978
|
+
title: string;
|
|
979
|
+
description: string;
|
|
980
|
+
url: string;
|
|
981
|
+
opened_at: Generated<Date>;
|
|
982
|
+
/** Null while the list is open. */
|
|
983
|
+
closed_at: Date | null;
|
|
984
|
+
}
|
|
985
|
+
/**
|
|
986
|
+
* One signup per (list, contact, token). `answers` holds the list's own
|
|
987
|
+
* questions, validated per list by the API before insert.
|
|
988
|
+
*/
|
|
989
|
+
interface WaitlistSignupsTable {
|
|
990
|
+
id: Generated<string>;
|
|
991
|
+
list: string;
|
|
992
|
+
contact: string;
|
|
993
|
+
answers: Record<string, unknown>;
|
|
994
|
+
created_at: Generated<Date>;
|
|
995
|
+
}
|
|
996
|
+
type Waitlist = Selectable<WaitlistsTable>;
|
|
997
|
+
type WaitlistSignup = Selectable<WaitlistSignupsTable>;
|
|
998
|
+
type InsertWaitlistSignup = Insertable<WaitlistSignupsTable>;
|
|
1026
999
|
import { sql } from "kysely";
|
|
1027
1000
|
import { Selectable as Selectable2 } from "kysely";
|
|
1028
1001
|
/** Widen a single scalar to its driver-accurate read shape. */
|
|
@@ -1856,6 +1829,23 @@ declare const SOURCE_READ_PKS: {
|
|
|
1856
1829
|
readonly events: readonly ["tx_id", "event_index"]
|
|
1857
1830
|
readonly chain_reorgs: null
|
|
1858
1831
|
};
|
|
1832
|
+
import { RawBuilder } from "kysely";
|
|
1833
|
+
/**
|
|
1834
|
+
* Safely encode a JS value as a JSONB literal for Kysely inserts/updates.
|
|
1835
|
+
* Kysely + postgres.js double-encodes JSON when using parameterized queries
|
|
1836
|
+
* with ::jsonb casts. This uses sql.raw to inline a properly escaped literal.
|
|
1837
|
+
*
|
|
1838
|
+
* Generic parameter lets callers set the RawBuilder's output type so they
|
|
1839
|
+
* don't need to cast at the insert site. Default is `unknown` — widen at
|
|
1840
|
+
* the call site when the column type is narrower, e.g. `jsonb<MyShape>(...)`.
|
|
1841
|
+
*/
|
|
1842
|
+
declare function jsonb<T = unknown>(value: T): RawBuilder<T>;
|
|
1843
|
+
/**
|
|
1844
|
+
* Safely parse a JSONB value from the database.
|
|
1845
|
+
* Handles double-encoded strings where postgres.js returns a JSON string
|
|
1846
|
+
* instead of a parsed object.
|
|
1847
|
+
*/
|
|
1848
|
+
declare function parseJsonb<T = unknown>(value: unknown): T;
|
|
1859
1849
|
/**
|
|
1860
1850
|
* Per-migration DB-plane gating for the source/target split.
|
|
1861
1851
|
*
|
|
@@ -1946,8 +1936,6 @@ declare const TABLE_TO_DB: {
|
|
|
1946
1936
|
api_keys: string
|
|
1947
1937
|
sessions: string
|
|
1948
1938
|
magic_links: string
|
|
1949
|
-
claim_tokens: string
|
|
1950
|
-
play_provisions: string
|
|
1951
1939
|
account_spend_caps: string
|
|
1952
1940
|
processed_stripe_events: string
|
|
1953
1941
|
webhooks: string
|
|
@@ -1961,8 +1949,9 @@ declare const TABLE_TO_DB: {
|
|
|
1961
1949
|
subgraph_violations: string
|
|
1962
1950
|
subgraph_processing_stats: string
|
|
1963
1951
|
account_credits: string
|
|
1964
|
-
hosted_meter_days: string
|
|
1965
1952
|
archive_fetches: string
|
|
1953
|
+
waitlists: string
|
|
1954
|
+
waitlist_signups: string
|
|
1966
1955
|
service_heartbeats: string
|
|
1967
1956
|
};
|
|
1968
1957
|
/** OSS: one application URL. SOURCE_/TARGET_ are hosted split only. */
|
|
@@ -2034,4 +2023,4 @@ declare function getRawClient(role?: "source" | "target"): ReturnType<typeof pos
|
|
|
2034
2023
|
declare function getRawClientFor(url: string): ReturnType<typeof postgres>;
|
|
2035
2024
|
/** Close all DB connection pools. Call in CLI commands to allow process exit. */
|
|
2036
2025
|
declare function closeDb(): Promise<void>;
|
|
2037
|
-
export {
|
|
2026
|
+
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, 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, UpdateVmEvent, UpdateWebhook, UpdateWebhookOutbox, 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 };
|
package/dist/src/db/index.js
CHANGED
|
@@ -1,18 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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) {
|
|
@@ -774,8 +759,6 @@ var TABLE_TO_DB = {
|
|
|
774
759
|
api_keys: "target",
|
|
775
760
|
sessions: "target",
|
|
776
761
|
magic_links: "target",
|
|
777
|
-
claim_tokens: "target",
|
|
778
|
-
play_provisions: "target",
|
|
779
762
|
account_spend_caps: "target",
|
|
780
763
|
processed_stripe_events: "target",
|
|
781
764
|
webhooks: "target",
|
|
@@ -789,8 +772,9 @@ var TABLE_TO_DB = {
|
|
|
789
772
|
subgraph_violations: "target",
|
|
790
773
|
subgraph_processing_stats: "target",
|
|
791
774
|
account_credits: "target",
|
|
792
|
-
hosted_meter_days: "target",
|
|
793
775
|
archive_fetches: "target",
|
|
776
|
+
waitlists: "target",
|
|
777
|
+
waitlist_signups: "target",
|
|
794
778
|
service_heartbeats: "both"
|
|
795
779
|
};
|
|
796
780
|
|
|
@@ -971,27 +955,27 @@ async function closeDb() {
|
|
|
971
955
|
pools.clear();
|
|
972
956
|
}
|
|
973
957
|
export {
|
|
974
|
-
|
|
975
|
-
setMigrationRole,
|
|
976
|
-
parseJsonb,
|
|
977
|
-
onControlPlane,
|
|
978
|
-
onChainPlane,
|
|
979
|
-
jsonb,
|
|
980
|
-
getTargetDb,
|
|
981
|
-
getSourceDb,
|
|
982
|
-
getRawClientFor,
|
|
983
|
-
getRawClient,
|
|
984
|
-
getMigrationRole,
|
|
985
|
-
getDbSplitStatus,
|
|
986
|
-
getDb,
|
|
987
|
-
closeDb,
|
|
988
|
-
assertDbSplit,
|
|
989
|
-
applicationDatabaseUrl,
|
|
990
|
-
TABLE_TO_DB,
|
|
991
|
-
SOURCE_READ_TYPES,
|
|
958
|
+
SOURCE_READ_COLUMNS,
|
|
992
959
|
SOURCE_READ_PKS,
|
|
993
|
-
|
|
960
|
+
SOURCE_READ_TYPES,
|
|
961
|
+
TABLE_TO_DB,
|
|
962
|
+
applicationDatabaseUrl,
|
|
963
|
+
assertDbSplit,
|
|
964
|
+
closeDb,
|
|
965
|
+
getDb,
|
|
966
|
+
getDbSplitStatus,
|
|
967
|
+
getMigrationRole,
|
|
968
|
+
getRawClient,
|
|
969
|
+
getRawClientFor,
|
|
970
|
+
getSourceDb,
|
|
971
|
+
getTargetDb,
|
|
972
|
+
jsonb,
|
|
973
|
+
onChainPlane,
|
|
974
|
+
onControlPlane,
|
|
975
|
+
parseJsonb,
|
|
976
|
+
setMigrationRole,
|
|
977
|
+
sql2 as sql
|
|
994
978
|
};
|
|
995
979
|
|
|
996
|
-
//# debugId=
|
|
980
|
+
//# debugId=09CA90EE67C5AC1164756E2164756E21
|
|
997
981
|
//# sourceMappingURL=index.js.map
|