@secondlayer/shared 11.7.1 → 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 +2 -3
- 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 +2 -3
- 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 +1 -2
- 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 +18 -19
- package/dist/src/db/index.js +40 -55
- package/dist/src/db/index.js.map +5 -5
- 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 +1 -2
- package/dist/src/db/queries/chain-reorgs.js +27 -42
- package/dist/src/db/queries/chain-reorgs.js.map +5 -5
- package/dist/src/db/queries/contracts.d.ts +1 -2
- 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 +1 -2
- 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 +1 -2
- package/dist/src/db/queries/integrity.js +5 -21
- package/dist/src/db/queries/integrity.js.map +2 -2
- package/dist/src/db/queries/subgraph-gaps.d.ts +1 -2
- 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 +1 -2
- 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 +2 -14
- package/dist/src/db/queries/subgraphs.js +15 -37
- package/dist/src/db/queries/subgraphs.js.map +5 -5
- package/dist/src/db/queries/sync-scope.d.ts +1 -2
- 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 +1 -2
- 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 +1 -2
- 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 +136 -149
- package/dist/src/index.js +259 -313
- package/dist/src/index.js.map +12 -12
- 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 +1 -2
- 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/0136_drop_subgraph_visibility.ts +34 -0
- package/package.json +1 -1
|
@@ -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/db/queries/sync-scope.ts
|
|
18
2
|
var SYNC_START_HEIGHT_ENV = "SECONDLAYER_SYNC_START_HEIGHT";
|
|
19
3
|
|
|
@@ -104,13 +88,13 @@ async function resolveSyncScope(db, network) {
|
|
|
104
88
|
};
|
|
105
89
|
}
|
|
106
90
|
export {
|
|
107
|
-
|
|
108
|
-
syncStartHeightFromEnv,
|
|
109
|
-
resolveSyncScope,
|
|
110
|
-
getSyncScope,
|
|
91
|
+
InvalidSyncStartHeightError,
|
|
111
92
|
SYNC_START_HEIGHT_ENV,
|
|
112
|
-
|
|
93
|
+
getSyncScope,
|
|
94
|
+
resolveSyncScope,
|
|
95
|
+
syncStartHeightFromEnv,
|
|
96
|
+
upsertSyncScope
|
|
113
97
|
};
|
|
114
98
|
|
|
115
|
-
//# debugId=
|
|
99
|
+
//# debugId=0BAF9C1F28590E5C64756E2164756E21
|
|
116
100
|
//# sourceMappingURL=sync-scope.js.map
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import type { Kysely } from \"kysely\";\nimport type { BootstrapSource, SyncScope } from \"../../coverage/evaluate.ts\";\nimport type { Database } from \"../types.ts\";\n\n/**\n * The instance's declared sync scope.\n *\n * An instance that starts at height N is not an instance missing the first N\n * blocks — but nothing in the schema said so, so every consumer had to guess\n * from `MIN(height)`. `sync_scopes` records the declaration; this module is the\n * only place that reads it, and it always answers in the `SyncScope` shape the\n * coverage evaluator consumes.\n *\n * `resolveSyncScope` never fails on an instance that predates the table: with\n * no row it derives a scope from what the database already shows, so an\n * existing install keeps working without a backfill dance.\n */\n\n/**\n * Declares a forward-only instance: history below this height is deliberately\n * absent, not lost. Read only when no `sync_scopes` row exists — a recorded\n * scope always wins, because it is the one an operator committed to.\n */\nexport const SYNC_START_HEIGHT_ENV = \"SECONDLAYER_SYNC_START_HEIGHT\";\n\nexport class InvalidSyncStartHeightError extends Error {\n\treadonly name = \"InvalidSyncStartHeightError\";\n\tconstructor(readonly value: string) {\n\t\tsuper(\n\t\t\t`${SYNC_START_HEIGHT_ENV} must be a non-negative integer (got ${value})`,\n\t\t);\n\t}\n}\n\n/**\n * Throws rather than ignoring a malformed value: a typo'd start height that\n * silently falls back to genesis would report a real forward-only instance as\n * an 8M-block gap, which is the exact confusion this table exists to end.\n */\nexport function syncStartHeightFromEnv(\n\tenv: NodeJS.ProcessEnv = process.env,\n): number | null {\n\tconst raw = env[SYNC_START_HEIGHT_ENV];\n\tif (raw === undefined || raw.trim() === \"\") return null;\n\tconst height = Number(raw.trim());\n\tif (!Number.isInteger(height) || height < 0) {\n\t\tthrow new InvalidSyncStartHeightError(raw);\n\t}\n\treturn height;\n}\n\nfunction toScope(row: {\n\tnetwork: string;\n\tstart_height: number | string;\n\ttarget_height: number | string | null;\n\tbootstrap_source: BootstrapSource;\n\tbootstrap_manifest_digest: string | null;\n\tgenesis_hash: string | null;\n}): SyncScope {\n\treturn {\n\t\tnetwork: row.network,\n\t\tstart_height: Number(row.start_height),\n\t\ttarget_height:\n\t\t\trow.target_height === null ? null : Number(row.target_height),\n\t\tbootstrap: {\n\t\t\tsource: row.bootstrap_source,\n\t\t\tmanifest_digest: row.bootstrap_manifest_digest,\n\t\t\tgenesis_hash: row.genesis_hash,\n\t\t},\n\t};\n}\n\nexport async function getSyncScope(\n\tdb: Kysely<Database>,\n\tnetwork: string,\n): Promise<SyncScope | null> {\n\tconst row = await db\n\t\t.selectFrom(\"sync_scopes\")\n\t\t.select([\n\t\t\t\"network\",\n\t\t\t\"start_height\",\n\t\t\t\"target_height\",\n\t\t\t\"bootstrap_source\",\n\t\t\t\"bootstrap_manifest_digest\",\n\t\t\t\"genesis_hash\",\n\t\t])\n\t\t.where(\"network\", \"=\", network)\n\t\t.executeTakeFirst();\n\treturn row ? toScope(row) : null;\n}\n\n/**\n * Record (or restate) the scope for a network. Bootstrap and re-bootstrap are\n * the writers; the upsert is idempotent so re-running a restore over the same\n * archive does not fork the declaration.\n */\nexport async function upsertSyncScope(\n\tdb: Kysely<Database>,\n\tscope: SyncScope,\n): Promise<SyncScope> {\n\tconst row = await db\n\t\t.insertInto(\"sync_scopes\")\n\t\t.values({\n\t\t\tnetwork: scope.network,\n\t\t\tstart_height: scope.start_height,\n\t\t\ttarget_height: scope.target_height,\n\t\t\tbootstrap_source: scope.bootstrap.source,\n\t\t\tbootstrap_manifest_digest: scope.bootstrap.manifest_digest,\n\t\t\tgenesis_hash: scope.bootstrap.genesis_hash,\n\t\t})\n\t\t.onConflict((oc) =>\n\t\t\toc.column(\"network\").doUpdateSet({\n\t\t\t\tstart_height: scope.start_height,\n\t\t\t\ttarget_height: scope.target_height,\n\t\t\t\tbootstrap_source: scope.bootstrap.source,\n\t\t\t\tbootstrap_manifest_digest: scope.bootstrap.manifest_digest,\n\t\t\t\tgenesis_hash: scope.bootstrap.genesis_hash,\n\t\t\t\tupdated_at: new Date(),\n\t\t\t}),\n\t\t)\n\t\t.returning([\n\t\t\t\"network\",\n\t\t\t\"start_height\",\n\t\t\t\"target_height\",\n\t\t\t\"bootstrap_source\",\n\t\t\t\"bootstrap_manifest_digest\",\n\t\t\t\"genesis_hash\",\n\t\t])\n\t\t.executeTakeFirstOrThrow();\n\treturn toScope(row);\n}\n\n/**\n * The persisted scope, or one derived from the database when none was ever\n * recorded.\n *\n * The derivation is deliberately conservative: it claims only what the data\n * already shows (the lowest canonical block, the genesis hash if genesis is\n * present) and never invents provenance — an instance whose history starts\n * above genesis with no recorded bootstrap is an `import`, not an archive\n * restore we can vouch for.\n */\nexport async function resolveSyncScope(\n\tdb: Kysely<Database>,\n\tnetwork: string,\n): Promise<SyncScope> {\n\tconst persisted = await getSyncScope(db, network);\n\tif (persisted) return persisted;\n\n\tconst declaredStart = syncStartHeightFromEnv();\n\tconst lowest = await db\n\t\t.selectFrom(\"blocks\")\n\t\t.select(({ fn }) => fn.min(\"height\").as(\"min\"))\n\t\t.where(\"canonical\", \"=\", true)\n\t\t.executeTakeFirst();\n\tconst lowestStored =\n\t\tlowest?.min === null || lowest?.min === undefined\n\t\t\t? null\n\t\t\t: Number(lowest.min);\n\tconst startHeight = declaredStart ?? lowestStored ?? 0;\n\n\tconst genesis =\n\t\tstartHeight === 0\n\t\t\t? await db\n\t\t\t\t\t.selectFrom(\"blocks\")\n\t\t\t\t\t.select(\"hash\")\n\t\t\t\t\t.where(\"canonical\", \"=\", true)\n\t\t\t\t\t.where(\"height\", \"=\", 0)\n\t\t\t\t\t.executeTakeFirst()\n\t\t\t: undefined;\n\n\treturn {\n\t\tnetwork,\n\t\tstart_height: startHeight,\n\t\ttarget_height: null,\n\t\tbootstrap: {\n\t\t\tsource: startHeight === 0 ? \"genesis\" : \"import\",\n\t\t\tmanifest_digest: null,\n\t\t\tgenesis_hash: genesis?.hash ?? null,\n\t\t},\n\t};\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "0BAF9C1F28590E5C64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -153,7 +153,6 @@ interface SubgraphsTable {
|
|
|
153
153
|
handler_code: string | null;
|
|
154
154
|
source_code: string | null;
|
|
155
155
|
project_id: string | null;
|
|
156
|
-
visibility: Generated<string>;
|
|
157
156
|
/** Paid (wallet-ghost) deploys expire unless renewed or claimed; NULL = no expiry. */
|
|
158
157
|
expires_at: Date | null;
|
|
159
158
|
/** (event type, contract) probe pairs persisted at deploy for weight classification. */
|
|
@@ -1004,4 +1003,4 @@ declare function rotateWebhookSecret(db: Kysely<Database>, accountId: string, id
|
|
|
1004
1003
|
declare function getWebhookSigningSecret(webhook: Webhook): string;
|
|
1005
1004
|
/** Fire `webhooks:changed` notify so the emitter hot-reloads its cache. */
|
|
1006
1005
|
declare function notifyWebhooksChanged(db: Kysely<Database>, accountId: string): Promise<void>;
|
|
1007
|
-
export {
|
|
1006
|
+
export { CreateWebhookInput, CreateWebhookResult, RotateSecretResult, UpdateWebhookInput, createWebhook, deleteWebhook, getWebhook, getWebhookByName, getWebhookSigningSecret, listActiveChainWebhooks, listWebhooks, notifyWebhooksChanged, rotateWebhookSecret, toggleWebhookStatus, updateWebhook };
|
|
@@ -14,49 +14,17 @@ var __export = (target, all) => {
|
|
|
14
14
|
});
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
// src/
|
|
18
|
-
|
|
19
|
-
"oss",
|
|
20
|
-
"platform",
|
|
21
|
-
"archive"
|
|
22
|
-
];
|
|
23
|
-
function declaredMode() {
|
|
24
|
-
const raw = process.env.INSTANCE_MODE?.trim().toLowerCase();
|
|
25
|
-
if (raw && VALID_MODES.includes(raw)) {
|
|
26
|
-
return raw;
|
|
27
|
-
}
|
|
28
|
-
return "oss";
|
|
29
|
-
}
|
|
30
|
-
function getInstanceMode() {
|
|
31
|
-
const declared = declaredMode();
|
|
32
|
-
return declared === "archive" ? "platform" : declared;
|
|
33
|
-
}
|
|
34
|
-
function getDeclaredInstanceMode() {
|
|
35
|
-
return declaredMode();
|
|
36
|
-
}
|
|
37
|
-
function isMeteredReads() {
|
|
38
|
-
const override = process.env.METERED_READS?.trim().toLowerCase();
|
|
39
|
-
if (override === "true")
|
|
40
|
-
return true;
|
|
41
|
-
if (override === "false")
|
|
42
|
-
return false;
|
|
43
|
-
return getInstanceMode() === "platform";
|
|
44
|
-
}
|
|
45
|
-
function isPlatformMode() {
|
|
46
|
-
return getInstanceMode() === "platform";
|
|
47
|
-
}
|
|
48
|
-
function isOssMode() {
|
|
49
|
-
return getInstanceMode() === "oss";
|
|
50
|
-
}
|
|
17
|
+
// src/db/queries/webhooks.ts
|
|
18
|
+
import { sql } from "kysely";
|
|
51
19
|
|
|
52
20
|
// src/crypto/hmac.ts
|
|
53
21
|
var exports_hmac = {};
|
|
54
22
|
__export(exports_hmac, {
|
|
55
|
-
|
|
56
|
-
verifySignature: () => verifySignature,
|
|
57
|
-
signPayload: () => signPayload,
|
|
23
|
+
createSignatureHeader: () => createSignatureHeader,
|
|
58
24
|
generateSecret: () => generateSecret,
|
|
59
|
-
|
|
25
|
+
signPayload: () => signPayload,
|
|
26
|
+
verifySignature: () => verifySignature,
|
|
27
|
+
verifySignatureHeader: () => verifySignatureHeader
|
|
60
28
|
});
|
|
61
29
|
import { createHmac, randomBytes } from "node:crypto";
|
|
62
30
|
function generateSecret() {
|
|
@@ -114,6 +82,43 @@ import {
|
|
|
114
82
|
unlinkSync
|
|
115
83
|
} from "node:fs";
|
|
116
84
|
import { resolve } from "node:path";
|
|
85
|
+
|
|
86
|
+
// src/mode.ts
|
|
87
|
+
var VALID_MODES = [
|
|
88
|
+
"oss",
|
|
89
|
+
"platform",
|
|
90
|
+
"archive"
|
|
91
|
+
];
|
|
92
|
+
function declaredMode() {
|
|
93
|
+
const raw = process.env.INSTANCE_MODE?.trim().toLowerCase();
|
|
94
|
+
if (raw && VALID_MODES.includes(raw)) {
|
|
95
|
+
return raw;
|
|
96
|
+
}
|
|
97
|
+
return "oss";
|
|
98
|
+
}
|
|
99
|
+
function getInstanceMode() {
|
|
100
|
+
const declared = declaredMode();
|
|
101
|
+
return declared === "archive" ? "platform" : declared;
|
|
102
|
+
}
|
|
103
|
+
function getDeclaredInstanceMode() {
|
|
104
|
+
return declaredMode();
|
|
105
|
+
}
|
|
106
|
+
function isMeteredReads() {
|
|
107
|
+
const override = process.env.METERED_READS?.trim().toLowerCase();
|
|
108
|
+
if (override === "true")
|
|
109
|
+
return true;
|
|
110
|
+
if (override === "false")
|
|
111
|
+
return false;
|
|
112
|
+
return getInstanceMode() === "platform";
|
|
113
|
+
}
|
|
114
|
+
function isPlatformMode() {
|
|
115
|
+
return getInstanceMode() === "platform";
|
|
116
|
+
}
|
|
117
|
+
function isOssMode() {
|
|
118
|
+
return getInstanceMode() === "oss";
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/crypto/secrets.ts
|
|
117
122
|
var KEY_ENV = "SECONDLAYER_SECRETS_KEY";
|
|
118
123
|
var IV_LEN = 12;
|
|
119
124
|
var TAG_LEN = 16;
|
|
@@ -228,7 +233,6 @@ function generateSecretsKey() {
|
|
|
228
233
|
}
|
|
229
234
|
|
|
230
235
|
// src/db/queries/webhooks.ts
|
|
231
|
-
import { sql } from "kysely";
|
|
232
236
|
async function createWebhook(db, input) {
|
|
233
237
|
const signingSecret = generateSecret();
|
|
234
238
|
const kind = input.kind ?? "subgraph";
|
|
@@ -344,18 +348,18 @@ async function notifyWebhooksChanged(db, accountId) {
|
|
|
344
348
|
await sql`SELECT pg_notify('webhooks:changed', ${accountId})`.execute(db);
|
|
345
349
|
}
|
|
346
350
|
export {
|
|
347
|
-
|
|
348
|
-
toggleWebhookStatus,
|
|
349
|
-
rotateWebhookSecret,
|
|
350
|
-
notifyWebhooksChanged,
|
|
351
|
-
listWebhooks,
|
|
352
|
-
listActiveChainWebhooks,
|
|
353
|
-
getWebhookSigningSecret,
|
|
354
|
-
getWebhookByName,
|
|
355
|
-
getWebhook,
|
|
351
|
+
createWebhook,
|
|
356
352
|
deleteWebhook,
|
|
357
|
-
|
|
353
|
+
getWebhook,
|
|
354
|
+
getWebhookByName,
|
|
355
|
+
getWebhookSigningSecret,
|
|
356
|
+
listActiveChainWebhooks,
|
|
357
|
+
listWebhooks,
|
|
358
|
+
notifyWebhooksChanged,
|
|
359
|
+
rotateWebhookSecret,
|
|
360
|
+
toggleWebhookStatus,
|
|
361
|
+
updateWebhook
|
|
358
362
|
};
|
|
359
363
|
|
|
360
|
-
//# debugId=
|
|
364
|
+
//# debugId=0300624A605962A764756E2164756E21
|
|
361
365
|
//# sourceMappingURL=webhooks.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/
|
|
3
|
+
"sources": ["../src/db/queries/webhooks.ts", "../src/crypto/hmac.ts", "../src/crypto/secrets.ts", "../src/mode.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"
|
|
5
|
+
"import { type Kysely, sql } from \"kysely\";\nimport { generateSecret } from \"../../crypto/hmac.ts\";\nimport { decryptSecret, encryptSecret } from \"../../crypto/secrets.ts\";\nimport { isPlatformMode } from \"../../mode.ts\";\nimport type {\n\tDatabase,\n\tInsertWebhook,\n\tUpdateWebhook,\n\tWebhook,\n\tWebhookFormat,\n\tWebhookKind,\n\tWebhookRuntime,\n\tWebhookStatus,\n} from \"../types.ts\";\n\n/**\n * Webhook CRUD. `signing_secret_enc` is transparently encrypted via\n * `encryptSecret`/`decryptSecret`. Plaintext secrets only leave via the\n * return value of `create` (one-time display) and `rotateSecret`.\n */\n\nexport interface CreateWebhookInput {\n\taccountId: string;\n\tprojectId?: string | null;\n\tname: string;\n\t/** Defaults to \"subgraph\". Chain webhooks set kind=\"chain\" + triggers. */\n\tkind?: WebhookKind;\n\t/** Required for subgraph webhooks; omitted for chain. */\n\tsubgraphName?: string | null;\n\t/** Required for subgraph webhooks; omitted for chain. */\n\ttableName?: string | null;\n\t/** Chain-trigger filter array. Required for chain webhooks. */\n\ttriggers?: unknown;\n\tfilter?: unknown;\n\tformat?: WebhookFormat;\n\truntime?: WebhookRuntime | null;\n\turl: string;\n\tauthConfig?: unknown;\n\tmaxRetries?: number;\n\ttimeoutMs?: number;\n\tconcurrency?: number;\n}\n\nexport interface CreateWebhookResult {\n\twebhook: Webhook;\n\t/** Plaintext signing secret — surfaced once, never stored decrypted. */\n\tsigningSecret: string;\n}\n\nexport async function createWebhook(\n\tdb: Kysely<Database>,\n\tinput: CreateWebhookInput,\n): Promise<CreateWebhookResult> {\n\tconst signingSecret = generateSecret();\n\tconst kind: WebhookKind = input.kind ?? \"subgraph\";\n\tconst row: InsertWebhook = {\n\t\taccount_id: isPlatformMode() ? input.accountId : \"\",\n\t\tproject_id: input.projectId ?? null,\n\t\tname: input.name,\n\t\tstatus: \"active\",\n\t\tkind,\n\t\tsubgraph_name: input.subgraphName ?? null,\n\t\ttable_name: input.tableName ?? null,\n\t\ttriggers: kind === \"chain\" ? ((input.triggers ?? []) as unknown) : null,\n\t\tfilter: input.filter ?? {},\n\t\tformat: input.format ?? \"standard-webhooks\",\n\t\truntime: input.runtime ?? null,\n\t\turl: input.url,\n\t\tsigning_secret_enc: encryptSecret(signingSecret),\n\t\tauth_config: input.authConfig ?? {},\n\t\t...(input.maxRetries !== undefined\n\t\t\t? { max_retries: input.maxRetries }\n\t\t\t: {}),\n\t\t...(input.timeoutMs !== undefined ? { timeout_ms: input.timeoutMs } : {}),\n\t\t...(input.concurrency !== undefined\n\t\t\t? { concurrency: input.concurrency }\n\t\t\t: {}),\n\t};\n\tconst webhook = await db\n\t\t.insertInto(\"webhooks\")\n\t\t.values(row)\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\treturn { webhook, signingSecret };\n}\n\nexport async function listWebhooks(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\topts?: { limit?: number; offset?: number },\n): Promise<Webhook[]> {\n\tlet q = db.selectFrom(\"webhooks\").selectAll().orderBy(\"created_at\", \"desc\");\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\tif (opts?.limit !== undefined) q = q.limit(opts.limit);\n\tif (opts?.offset !== undefined) q = q.offset(opts.offset);\n\treturn q.execute();\n}\n\n/**\n * All active chain webhooks across every account — the input to the global\n * trigger evaluator (one loop serves them all). Subgraph webhooks are\n * excluded; they emit via the subgraph flush path.\n */\nexport async function listActiveChainWebhooks(\n\tdb: Kysely<Database>,\n): Promise<Webhook[]> {\n\treturn db\n\t\t.selectFrom(\"webhooks\")\n\t\t.selectAll()\n\t\t.where(\"kind\", \"=\", \"chain\")\n\t\t.where(\"status\", \"=\", \"active\")\n\t\t.execute();\n}\n\nexport async function getWebhook(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tid: string,\n): Promise<Webhook | null> {\n\tlet q = db.selectFrom(\"webhooks\").selectAll().where(\"id\", \"=\", id);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\treturn (await q.executeTakeFirst()) ?? null;\n}\n\nexport async function getWebhookByName(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tname: string,\n): Promise<Webhook | null> {\n\tlet q = db.selectFrom(\"webhooks\").selectAll().where(\"name\", \"=\", name);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\treturn (await q.executeTakeFirst()) ?? null;\n}\n\nexport interface UpdateWebhookInput {\n\tname?: string;\n\tfilter?: unknown;\n\tformat?: WebhookFormat;\n\truntime?: WebhookRuntime | null;\n\turl?: string;\n\tauthConfig?: unknown;\n\tmaxRetries?: number;\n\ttimeoutMs?: number;\n\tconcurrency?: number;\n}\n\nexport async function updateWebhook(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tid: string,\n\tpatch: UpdateWebhookInput,\n): Promise<Webhook | null> {\n\tconst update: UpdateWebhook = { updated_at: new Date() };\n\tif (patch.name !== undefined) update.name = patch.name;\n\tif (patch.filter !== undefined) update.filter = patch.filter;\n\tif (patch.format !== undefined) update.format = patch.format;\n\tif (patch.runtime !== undefined) update.runtime = patch.runtime;\n\tif (patch.url !== undefined) update.url = patch.url;\n\tif (patch.authConfig !== undefined) update.auth_config = patch.authConfig;\n\tif (patch.maxRetries !== undefined) update.max_retries = patch.maxRetries;\n\tif (patch.timeoutMs !== undefined) update.timeout_ms = patch.timeoutMs;\n\tif (patch.concurrency !== undefined) update.concurrency = patch.concurrency;\n\n\tlet q = db.updateTable(\"webhooks\").set(update).where(\"id\", \"=\", id);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\treturn (await q.returningAll().executeTakeFirst()) ?? null;\n}\n\nexport async function toggleWebhookStatus(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tid: string,\n\tstatus: WebhookStatus,\n): Promise<Webhook | null> {\n\tlet q = db\n\t\t.updateTable(\"webhooks\")\n\t\t.set({\n\t\t\tstatus,\n\t\t\tupdated_at: new Date(),\n\t\t\t...(status === \"active\"\n\t\t\t\t? {\n\t\t\t\t\t\tcircuit_failures: 0,\n\t\t\t\t\t\tcircuit_opened_at: null,\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t})\n\t\t.where(\"id\", \"=\", id);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\treturn (await q.returningAll().executeTakeFirst()) ?? null;\n}\n\nexport async function deleteWebhook(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tid: string,\n): Promise<boolean> {\n\tlet q = db.deleteFrom(\"webhooks\").where(\"id\", \"=\", id);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\tconst res = await q.executeTakeFirst();\n\treturn Number(res.numDeletedRows ?? 0) > 0;\n}\n\nexport interface RotateSecretResult {\n\twebhook: Webhook;\n\tsigningSecret: string;\n}\n\nexport async function rotateWebhookSecret(\n\tdb: Kysely<Database>,\n\taccountId: string,\n\tid: string,\n): Promise<RotateSecretResult | null> {\n\tconst signingSecret = generateSecret();\n\tlet q = db\n\t\t.updateTable(\"webhooks\")\n\t\t.set({\n\t\t\tsigning_secret_enc: encryptSecret(signingSecret),\n\t\t\tupdated_at: new Date(),\n\t\t})\n\t\t.where(\"id\", \"=\", id);\n\tif (isPlatformMode()) q = q.where(\"account_id\", \"=\", accountId);\n\tconst row = await q.returningAll().executeTakeFirst();\n\tif (!row) return null;\n\treturn { webhook: row, signingSecret };\n}\n\n/** Decrypt a webhook's signing secret for HMAC signing at emit time. */\nexport function getWebhookSigningSecret(webhook: Webhook): string {\n\treturn decryptSecret(webhook.signing_secret_enc);\n}\n\n/** Fire `webhooks:changed` notify so the emitter hot-reloads its cache. */\nexport async function notifyWebhooksChanged(\n\tdb: Kysely<Database>,\n\taccountId: string,\n): Promise<void> {\n\tawait sql`SELECT pg_notify('webhooks:changed', ${accountId})`.execute(db);\n}\n",
|
|
6
6
|
"import { createHmac, randomBytes } from \"node:crypto\";\n\n/**\n * Generate a random secret for delivery signing\n * Returns 32 bytes as a 64-character hex string\n */\nexport function generateSecret(): string {\n\treturn randomBytes(32).toString(\"hex\");\n}\n\n/**\n * Sign a payload with HMAC-SHA256\n * Returns the signature as a hex string\n */\nexport function signPayload(payload: string, secret: string): string {\n\tconst hmac = createHmac(\"sha256\", secret);\n\thmac.update(payload);\n\treturn hmac.digest(\"hex\");\n}\n\n/**\n * Verify an HMAC signature\n * Uses constant-time comparison to prevent timing attacks\n */\nexport function verifySignature(\n\tpayload: string,\n\tsignature: string,\n\tsecret: string,\n): boolean {\n\tconst expectedSignature = signPayload(payload, secret);\n\n\t// Constant-time comparison\n\tif (signature.length !== expectedSignature.length) {\n\t\treturn false;\n\t}\n\n\tlet result = 0;\n\tfor (let i = 0; i < signature.length; i++) {\n\t\tresult |= signature.charCodeAt(i) ^ expectedSignature.charCodeAt(i);\n\t}\n\n\treturn result === 0;\n}\n\n/**\n * Create a Stripe-style signature header\n * Format: t=timestamp,v1=signature\n */\nexport function createSignatureHeader(\n\tpayload: string,\n\tsecret: string,\n\ttimestamp?: number,\n): string {\n\tconst ts = timestamp ?? Math.floor(Date.now() / 1000);\n\tconst signedPayload = `${ts}.${payload}`;\n\tconst signature = signPayload(signedPayload, secret);\n\n\treturn `t=${ts},v1=${signature}`;\n}\n\n/**\n * Parse and verify a Stripe-style signature header\n * Returns true if valid, false otherwise\n */\nexport function verifySignatureHeader(\n\tpayload: string,\n\theader: string,\n\tsecret: string,\n\ttoleranceSeconds = 300, // 5 minutes\n): boolean {\n\t// Parse header\n\tconst parts = header.split(\",\");\n\tconst timestamp = parts.find((p) => p.startsWith(\"t=\"))?.slice(2);\n\tconst signature = parts.find((p) => p.startsWith(\"v1=\"))?.slice(3);\n\n\tif (!timestamp || !signature) {\n\t\treturn false;\n\t}\n\n\tconst ts = Number.parseInt(timestamp, 10);\n\tif (Number.isNaN(ts)) {\n\t\treturn false;\n\t}\n\n\t// Check timestamp is within tolerance\n\tconst now = Math.floor(Date.now() / 1000);\n\tif (Math.abs(now - ts) > toleranceSeconds) {\n\t\treturn false;\n\t}\n\n\t// Verify signature\n\tconst signedPayload = `${ts}.${payload}`;\n\treturn verifySignature(signedPayload, signature, secret);\n}\n",
|
|
7
7
|
"import { createCipheriv, createDecipheriv, randomBytes } from \"node:crypto\";\nimport {\n\tappendFileSync,\n\tcloseSync,\n\texistsSync,\n\topenSync,\n\treadFileSync,\n\tunlinkSync,\n} from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { getInstanceMode } from \"../mode.ts\";\n\n/**\n * AES-256-GCM symmetric envelope for encrypted secrets at rest (tenant keys,\n * webhook signing secrets, etc.).\n *\n * Ciphertext layout: `iv (12 bytes) || authTag (16 bytes) || ciphertext`\n *\n * The key comes from `SECONDLAYER_SECRETS_KEY` — 32 bytes hex. In OSS mode,\n * if the env var is unset on first use we autogenerate a key and persist it\n * to `.env.local` in the current working directory so subsequent restarts\n * pick it up without user intervention. Dedicated/platform modes throw —\n * those runtimes must provision the key explicitly.\n *\n * Rotation strategy: re-encrypt all rows with the new key and swap the env\n * var. Not zero-downtime, but acceptable at v2 scale. For real KMS (AWS\n * KMS, Vault, GCP KMS), wrap the same byte layout behind an\n * `EncryptSecret`/`DecryptSecret` interface and swap at startup.\n */\n\nconst KEY_ENV = \"SECONDLAYER_SECRETS_KEY\";\nconst IV_LEN = 12;\nconst TAG_LEN = 16;\n\nfunction readExistingKey(envPath: string): string | null {\n\tif (!existsSync(envPath)) return null;\n\tconst contents = readFileSync(envPath, \"utf8\");\n\tconst match = contents.match(/^SECONDLAYER_SECRETS_KEY=([a-fA-F0-9]{64})/m);\n\t// biome-ignore lint/style/noNonNullAssertion: value is non-null after preceding check or by construction; TS narrowing limitation\n\treturn match ? match[1]! : null;\n}\n\n/**\n * Atomic file lock via `openSync(..., \"wx\")` — O_CREAT | O_EXCL. If two\n * processes race on cold-compose start, exactly one creates the lock\n * file; the loser polls until the winner finishes writing `.env.local`,\n * then reads the winner's key. Stale locks (process crashed mid-write)\n * are cleaned after `STALE_LOCK_MS`.\n */\nconst STALE_LOCK_MS = 10_000;\nconst POLL_MS = 25;\n\nfunction bootstrapOssKey(): string {\n\tconst envPath = resolve(process.cwd(), \".env.local\");\n\n\t// Fast path — key already on disk from a prior run.\n\tconst existing = readExistingKey(envPath);\n\tif (existing) {\n\t\tprocess.env[KEY_ENV] = existing;\n\t\treturn existing;\n\t}\n\n\tconst lockPath = `${envPath}.secret-bootstrap.lock`;\n\tlet lockFd: number | null = null;\n\ttry {\n\t\tlockFd = openSync(lockPath, \"wx\", 0o600);\n\t} catch (err) {\n\t\tconst e = err as NodeJS.ErrnoException;\n\t\tif (e.code !== \"EEXIST\") throw err;\n\t}\n\n\tif (lockFd === null) {\n\t\t// Another process is bootstrapping. Poll for its result.\n\t\tconst deadline = Date.now() + STALE_LOCK_MS;\n\t\twhile (Date.now() < deadline) {\n\t\t\tconst key = readExistingKey(envPath);\n\t\t\tif (key) {\n\t\t\t\tprocess.env[KEY_ENV] = key;\n\t\t\t\treturn key;\n\t\t\t}\n\t\t\tBun.sleepSync(POLL_MS);\n\t\t}\n\t\t// Lock holder died mid-write — force-clean and retry once.\n\t\ttry {\n\t\t\tunlinkSync(lockPath);\n\t\t} catch {}\n\t\treturn bootstrapOssKey();\n\t}\n\n\ttry {\n\t\tconst hex = randomBytes(32).toString(\"hex\");\n\t\tconst line = `${existsSync(envPath) ? \"\\n\" : \"\"}${KEY_ENV}=${hex}\\n`;\n\t\tappendFileSync(envPath, line, { mode: 0o600 });\n\t\tprocess.env[KEY_ENV] = hex;\n\t\tconsole.log(\n\t\t\t`[secondlayer] generated ${KEY_ENV}; saved to ${envPath} (mode 0600)`,\n\t\t);\n\t\treturn hex;\n\t} finally {\n\t\tcloseSync(lockFd);\n\t\ttry {\n\t\t\tunlinkSync(lockPath);\n\t\t} catch {}\n\t}\n}\n\nfunction loadKey(): Buffer {\n\tlet hex = process.env[KEY_ENV];\n\tif (!hex) {\n\t\tif (getInstanceMode() === \"oss\") {\n\t\t\thex = bootstrapOssKey();\n\t\t} else {\n\t\t\tthrow new Error(\n\t\t\t\t`${KEY_ENV} not set. Generate one with: openssl rand -hex 32`,\n\t\t\t);\n\t\t}\n\t}\n\tconst key = Buffer.from(hex, \"hex\");\n\tif (key.length !== 32) {\n\t\tthrow new Error(`${KEY_ENV} must be 32 bytes hex (got ${key.length})`);\n\t}\n\treturn key;\n}\n\nlet _cachedKey: Buffer | null = null;\nfunction getKey(): Buffer {\n\tif (!_cachedKey) _cachedKey = loadKey();\n\treturn _cachedKey;\n}\n\n/**\n * Non-throwing check for whether a secrets key is currently resolvable —\n * same resolution order as {@link loadKey} (env var, then the OSS\n * `.env.local` fallback), but never bootstraps a new key (that would\n * generate+persist a key as a side effect of a mere existence check), never\n * throws, and never returns or logs the key itself. Used by callers that\n * need to fail loud on a missing key BEFORE attempting a decrypt (f072).\n */\nexport function secretsKeyAvailable(): boolean {\n\tif (process.env[KEY_ENV]) return true;\n\tif (getInstanceMode() === \"oss\") {\n\t\tconst envPath = resolve(process.cwd(), \".env.local\");\n\t\treturn readExistingKey(envPath) !== null;\n\t}\n\treturn false;\n}\n\nexport function encryptSecret(plaintext: string): Buffer {\n\tconst key = getKey();\n\tconst iv = randomBytes(IV_LEN);\n\tconst cipher = createCipheriv(\"aes-256-gcm\", key, iv);\n\tconst ciphertext = Buffer.concat([\n\t\tcipher.update(plaintext, \"utf8\"),\n\t\tcipher.final(),\n\t]);\n\tconst tag = cipher.getAuthTag();\n\treturn Buffer.concat([iv, tag, ciphertext]);\n}\n\nexport function decryptSecret(envelope: Buffer): string {\n\tconst key = getKey();\n\tconst iv = envelope.subarray(0, IV_LEN);\n\tconst tag = envelope.subarray(IV_LEN, IV_LEN + TAG_LEN);\n\tconst ciphertext = envelope.subarray(IV_LEN + TAG_LEN);\n\tconst decipher = createDecipheriv(\"aes-256-gcm\", key, iv);\n\tdecipher.setAuthTag(tag);\n\treturn decipher.update(ciphertext).toString(\"utf8\") + decipher.final(\"utf8\");\n}\n\n/** Generate a fresh 32-byte hex key suitable for `SECONDLAYER_SECRETS_KEY`. */\nexport function generateSecretsKey(): string {\n\treturn randomBytes(32).toString(\"hex\");\n}\n",
|
|
8
|
-
"
|
|
8
|
+
"/**\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"
|
|
9
9
|
],
|
|
10
|
-
"mappings": ";;;;;;;;;;;;;;;;;
|
|
11
|
-
"debugId": "
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "0300624A605962A764756E2164756E21",
|
|
12
12
|
"names": []
|
|
13
13
|
}
|
package/dist/src/db/schema.d.ts
CHANGED
|
@@ -152,7 +152,6 @@ interface SubgraphsTable {
|
|
|
152
152
|
handler_code: string | null;
|
|
153
153
|
source_code: string | null;
|
|
154
154
|
project_id: string | null;
|
|
155
|
-
visibility: Generated<string>;
|
|
156
155
|
/** Paid (wallet-ghost) deploys expire unless renewed or claimed; NULL = no expiry. */
|
|
157
156
|
expires_at: Date | null;
|
|
158
157
|
/** (event type, contract) probe pairs persisted at deploy for weight classification. */
|
|
@@ -995,4 +994,4 @@ interface WaitlistSignupsTable {
|
|
|
995
994
|
type Waitlist = Selectable<WaitlistsTable>;
|
|
996
995
|
type WaitlistSignup = Selectable<WaitlistSignupsTable>;
|
|
997
996
|
type InsertWaitlistSignup = Insertable<WaitlistSignupsTable>;
|
|
998
|
-
export {
|
|
997
|
+
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, DeadLetterEventsTable, DecodedEventsTable, DecoderCheckpointsTable, Event, EventsArchiveTable, EventsTable, FailureClass, FailureUnit, 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, NativeClock, ObserverJournalStatus, ObserverJournalTable, OutboxStatus, PendingForkBlocksTable, Pox4CallsTable, Pox4FunctionName, Pox5EventTopic, Pox5EventsTable, ProcessedStripeEventsTable, RepairMode, RetryState, RunStatus, 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, 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 };
|
package/dist/src/env.d.ts
CHANGED
|
@@ -52,4 +52,4 @@ declare function isPox5DecoderEnabled(env?: EnvMap): boolean;
|
|
|
52
52
|
declare function isSbtcDecoderEnabled(env?: EnvMap): boolean;
|
|
53
53
|
/** Default OFF. Opt in with `BNS_DECODER_ENABLED=true`. */
|
|
54
54
|
declare function isBnsDecoderEnabled(env?: EnvMap): boolean;
|
|
55
|
-
export {
|
|
55
|
+
export { Env, envSchema, getEnv, isBnsDecoderEnabled, isPox4DecoderEnabled, isPox5DecoderEnabled, isProductionEnv, isSbtcDecoderEnabled };
|
package/dist/src/env.js
CHANGED
|
@@ -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/env.ts
|
|
18
2
|
import { z } from "zod";
|
|
19
3
|
var networksSchema = z.string().transform((val) => {
|
|
@@ -73,14 +57,14 @@ function isBnsDecoderEnabled(env = process.env) {
|
|
|
73
57
|
return env.BNS_DECODER_ENABLED === "true";
|
|
74
58
|
}
|
|
75
59
|
export {
|
|
76
|
-
|
|
77
|
-
isProductionEnv,
|
|
78
|
-
isPox5DecoderEnabled,
|
|
79
|
-
isPox4DecoderEnabled,
|
|
80
|
-
isBnsDecoderEnabled,
|
|
60
|
+
envSchema,
|
|
81
61
|
getEnv,
|
|
82
|
-
|
|
62
|
+
isBnsDecoderEnabled,
|
|
63
|
+
isPox4DecoderEnabled,
|
|
64
|
+
isPox5DecoderEnabled,
|
|
65
|
+
isProductionEnv,
|
|
66
|
+
isSbtcDecoderEnabled
|
|
83
67
|
};
|
|
84
68
|
|
|
85
|
-
//# debugId=
|
|
69
|
+
//# debugId=09269FBBCC4C7B6B64756E2164756E21
|
|
86
70
|
//# sourceMappingURL=env.js.map
|
package/dist/src/env.js.map
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import { z } from \"zod\";\n\n// Parse comma-separated networks\nconst networksSchema = z.string().transform((val) => {\n\tconst networks = val\n\t\t.split(\",\")\n\t\t.map((n) => n.trim())\n\t\t.filter(Boolean);\n\tconst valid = [\"mainnet\", \"testnet\"];\n\tfor (const n of networks) {\n\t\tif (!valid.includes(n)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid network: ${n}. Must be one of: ${valid.join(\", \")}`,\n\t\t\t);\n\t\t}\n\t}\n\treturn networks as (\"mainnet\" | \"testnet\")[];\n});\n\ninterface EnvSchemaOutput {\n\tDATABASE_URL?: string;\n\t/**\n\t * Shared indexer DB (blocks/txs/events). Falls back to DATABASE_URL.\n\t * Set this alongside TARGET_DATABASE_URL to enable dual-DB mode.\n\t */\n\tSOURCE_DATABASE_URL?: string;\n\t/**\n\t * Tenant DB (subgraph schemas + subgraphs table). Falls back to DATABASE_URL.\n\t * Set this alongside SOURCE_DATABASE_URL to enable dual-DB mode.\n\t */\n\tTARGET_DATABASE_URL?: string;\n\tNETWORK?: \"mainnet\" | \"testnet\";\n\tNETWORKS?: (\"mainnet\" | \"testnet\")[];\n\tLOG_LEVEL: \"debug\" | \"info\" | \"warn\" | \"error\";\n\tNODE_ENV: \"development\" | \"production\" | \"test\";\n}\n\n// Cast needed: z.preprocess / z.default create different _input vs _output types\n// that z.ZodType<T> can't represent without explicit input type param\nconst envSchema: z.ZodType<EnvSchemaOutput> = z.object({\n\tDATABASE_URL: z.preprocess(\n\t\t(val) => (typeof val === \"string\" && val.length === 0 ? undefined : val),\n\t\tz.string().url().optional(),\n\t),\n\tSOURCE_DATABASE_URL: z.preprocess(\n\t\t(val) => (typeof val === \"string\" && val.length === 0 ? undefined : val),\n\t\tz.string().url().optional(),\n\t),\n\tTARGET_DATABASE_URL: z.preprocess(\n\t\t(val) => (typeof val === \"string\" && val.length === 0 ? undefined : val),\n\t\tz.string().url().optional(),\n\t),\n\tNETWORK: z.enum([\"mainnet\", \"testnet\"]).optional(),\n\tNETWORKS: networksSchema.optional(),\n\tLOG_LEVEL: z.enum([\"debug\", \"info\", \"warn\", \"error\"]).default(\"info\"),\n\tNODE_ENV: z\n\t\t.enum([\"development\", \"production\", \"test\"])\n\t\t.default(\"development\"),\n}) as unknown as z.ZodType<EnvSchemaOutput>;\n\nexport type Env = EnvSchemaOutput & {\n\tenabledNetworks: (\"mainnet\" | \"testnet\")[];\n};\n\nlet cachedEnv: Env | null = null;\n\nexport function getEnv(): Env {\n\tif (cachedEnv) {\n\t\treturn cachedEnv;\n\t}\n\n\tconst result = envSchema.safeParse(process.env);\n\n\tif (!result.success) {\n\t\tconsole.error(\"❌ Invalid environment configuration:\");\n\t\tconsole.error(z.treeifyError(result.error));\n\t\tthrow new Error(\"Invalid environment configuration\");\n\t}\n\n\t// Compute enabled networks from NETWORKS or NETWORK\n\tlet enabledNetworks: (\"mainnet\" | \"testnet\")[];\n\tif (result.data.NETWORKS && result.data.NETWORKS.length > 0) {\n\t\tenabledNetworks = result.data.NETWORKS;\n\t} else if (result.data.NETWORK) {\n\t\tenabledNetworks = [result.data.NETWORK];\n\t} else {\n\t\tenabledNetworks = [\"mainnet\"]; // Default\n\t}\n\n\tcachedEnv = { ...result.data, enabledNetworks };\n\treturn cachedEnv;\n}\n\n/**\n * True when `NODE_ENV=production`, read at RUNTIME — the single source of truth\n * for prod-vs-dev branching in this package.\n *\n * Why a helper instead of inlining `process.env.NODE_ENV === \"production\"`:\n * bunup/esbuild constant-folds the dot-access `process.env.NODE_ENV` to its\n * BUILD-time value. `@secondlayer/shared` is consumed by other services as its\n * built `dist`, so an inlined check freezes to a literal in the shipped bundle\n * (e.g. `const isProd = false`) and silently ignores the container's real\n * NODE_ENV. The bracket access below is NOT folded, so it stays a runtime read.\n * Route every prod check through here so the footgun lives in exactly one place.\n */\nexport function isProductionEnv(): boolean {\n\t// biome-ignore lint/complexity/useLiteralKeys: bracket access is deliberate — dot-access gets constant-folded by the bundler, freezing this to a build-time literal in the shipped dist.\n\treturn process.env[\"NODE_ENV\"] === \"production\";\n}\n\ntype EnvMap = NodeJS.ProcessEnv;\n\n/**\n * PoX-4 stacking decoder is ON by default — `/v1/index/stacking` is part of the\n * public surface, so the decoder that fills `pox4_calls` runs unless explicitly\n * opted out with `POX4_DECODER_ENABLED=false` (mirrors the sBTC decoder policy).\n */\nexport function isPox4DecoderEnabled(env: EnvMap = process.env): boolean {\n\treturn env.POX4_DECODER_ENABLED !== \"false\";\n}\n\n/**\n * PoX-5 print-event decoder is ON by default (mirrors pox-4/sBTC policy).\n * No activation gating needed: pox-5 events cannot exist before the Epoch 4.0\n * hard fork (Bitcoin block 960,230), so pre-activation the decoder idles at\n * tip. Opt out with `POX5_DECODER_ENABLED=false`.\n */\nexport function isPox5DecoderEnabled(env: EnvMap = process.env): boolean {\n\treturn env.POX5_DECODER_ENABLED !== \"false\";\n}\n\n/** Default ON. Opt out with `SBTC_DECODER_ENABLED=false`. */\nexport function isSbtcDecoderEnabled(env: EnvMap = process.env): boolean {\n\treturn env.SBTC_DECODER_ENABLED !== \"false\";\n}\n\n/** Default OFF. Opt in with `BNS_DECODER_ENABLED=true`. */\nexport function isBnsDecoderEnabled(env: EnvMap = process.env): boolean {\n\treturn env.BNS_DECODER_ENABLED === \"true\";\n}\n\n// Export for testing\nexport { envSchema };\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";AAAA;AAGA,IAAM,iBAAiB,EAAE,OAAO,EAAE,UAAU,CAAC,QAAQ;AAAA,EACpD,MAAM,WAAW,IACf,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO;AAAA,EAChB,MAAM,QAAQ,CAAC,WAAW,SAAS;AAAA,EACnC,WAAW,KAAK,UAAU;AAAA,IACzB,IAAI,CAAC,MAAM,SAAS,CAAC,GAAG;AAAA,MACvB,MAAM,IAAI,MACT,oBAAoB,sBAAsB,MAAM,KAAK,IAAI,GAC1D;AAAA,IACD;AAAA,EACD;AAAA,EACA,OAAO;AAAA,CACP;AAsBD,IAAM,YAAwC,EAAE,OAAO;AAAA,EACtD,cAAc,EAAE,WACf,CAAC,QAAS,OAAO,QAAQ,YAAY,IAAI,WAAW,IAAI,YAAY,KACpE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,CAC3B;AAAA,EACA,qBAAqB,EAAE,WACtB,CAAC,QAAS,OAAO,QAAQ,YAAY,IAAI,WAAW,IAAI,YAAY,KACpE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,CAC3B;AAAA,EACA,qBAAqB,EAAE,WACtB,CAAC,QAAS,OAAO,QAAQ,YAAY,IAAI,WAAW,IAAI,YAAY,KACpE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,CAC3B;AAAA,EACA,SAAS,EAAE,KAAK,CAAC,WAAW,SAAS,CAAC,EAAE,SAAS;AAAA,EACjD,UAAU,eAAe,SAAS;AAAA,EAClC,WAAW,EAAE,KAAK,CAAC,SAAS,QAAQ,QAAQ,OAAO,CAAC,EAAE,QAAQ,MAAM;AAAA,EACpE,UAAU,EACR,KAAK,CAAC,eAAe,cAAc,MAAM,CAAC,EAC1C,QAAQ,aAAa;AACxB,CAAC;AAMD,IAAI,YAAwB;AAErB,SAAS,MAAM,GAAQ;AAAA,EAC7B,IAAI,WAAW;AAAA,IACd,OAAO;AAAA,EACR;AAAA,EAEA,MAAM,SAAS,UAAU,UAAU,QAAQ,GAAG;AAAA,EAE9C,IAAI,CAAC,OAAO,SAAS;AAAA,IACpB,QAAQ,MAAM,sCAAsC;AAAA,IACpD,QAAQ,MAAM,EAAE,aAAa,OAAO,KAAK,CAAC;AAAA,IAC1C,MAAM,IAAI,MAAM,mCAAmC;AAAA,EACpD;AAAA,EAGA,IAAI;AAAA,EACJ,IAAI,OAAO,KAAK,YAAY,OAAO,KAAK,SAAS,SAAS,GAAG;AAAA,IAC5D,kBAAkB,OAAO,KAAK;AAAA,EAC/B,EAAO,SAAI,OAAO,KAAK,SAAS;AAAA,IAC/B,kBAAkB,CAAC,OAAO,KAAK,OAAO;AAAA,EACvC,EAAO;AAAA,IACN,kBAAkB,CAAC,SAAS;AAAA;AAAA,EAG7B,YAAY,KAAK,OAAO,MAAM,gBAAgB;AAAA,EAC9C,OAAO;AAAA;AAeD,SAAS,eAAe,GAAY;AAAA,EAE1C,OAAO,QAAQ,IAAI,gBAAgB;AAAA;AAU7B,SAAS,oBAAoB,CAAC,MAAc,QAAQ,KAAc;AAAA,EACxE,OAAO,IAAI,yBAAyB;AAAA;AAS9B,SAAS,oBAAoB,CAAC,MAAc,QAAQ,KAAc;AAAA,EACxE,OAAO,IAAI,yBAAyB;AAAA;AAI9B,SAAS,oBAAoB,CAAC,MAAc,QAAQ,KAAc;AAAA,EACxE,OAAO,IAAI,yBAAyB;AAAA;AAI9B,SAAS,mBAAmB,CAAC,MAAc,QAAQ,KAAc;AAAA,EACvE,OAAO,IAAI,wBAAwB;AAAA;",
|
|
8
|
+
"debugId": "09269FBBCC4C7B6B64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/src/errors.d.ts
CHANGED
|
@@ -77,4 +77,4 @@ declare class TenantSuspendedError extends SecondLayerError {
|
|
|
77
77
|
* (avoids cross-bundle instanceof failures from bunup class duplication). */
|
|
78
78
|
declare const CODE_TO_STATUS: Record<string, 400 | 401 | 402 | 403 | 404 | 409 | 415 | 422 | 423 | 429 | 503>;
|
|
79
79
|
declare function getErrorMessage(err: unknown): string;
|
|
80
|
-
export {
|
|
80
|
+
export { AuthenticationError, AuthorizationError, CODE_TO_STATUS, DatabaseError, ErrorCode, ErrorCodes, ForbiddenError, KeyRotatedError, NotFoundError, PaymentRequiredError, RateLimitError, SecondLayerError, TenantSuspendedError, ValidationError, VersionConflictError, getErrorMessage };
|
package/dist/src/errors.js
CHANGED
|
@@ -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/errors.ts
|
|
18
2
|
var ErrorCodes = {
|
|
19
3
|
VALIDATION_ERROR: "VALIDATION_ERROR",
|
|
@@ -145,22 +129,22 @@ function getErrorMessage(err) {
|
|
|
145
129
|
return err instanceof Error ? err.message : String(err);
|
|
146
130
|
}
|
|
147
131
|
export {
|
|
148
|
-
|
|
149
|
-
VersionConflictError,
|
|
150
|
-
ValidationError,
|
|
151
|
-
TenantSuspendedError,
|
|
152
|
-
SecondLayerError,
|
|
153
|
-
RateLimitError,
|
|
154
|
-
PaymentRequiredError,
|
|
155
|
-
NotFoundError,
|
|
156
|
-
KeyRotatedError,
|
|
157
|
-
ForbiddenError,
|
|
158
|
-
ErrorCodes,
|
|
159
|
-
DatabaseError,
|
|
160
|
-
CODE_TO_STATUS,
|
|
132
|
+
AuthenticationError,
|
|
161
133
|
AuthorizationError,
|
|
162
|
-
|
|
134
|
+
CODE_TO_STATUS,
|
|
135
|
+
DatabaseError,
|
|
136
|
+
ErrorCodes,
|
|
137
|
+
ForbiddenError,
|
|
138
|
+
KeyRotatedError,
|
|
139
|
+
NotFoundError,
|
|
140
|
+
PaymentRequiredError,
|
|
141
|
+
RateLimitError,
|
|
142
|
+
SecondLayerError,
|
|
143
|
+
TenantSuspendedError,
|
|
144
|
+
ValidationError,
|
|
145
|
+
VersionConflictError,
|
|
146
|
+
getErrorMessage
|
|
163
147
|
};
|
|
164
148
|
|
|
165
|
-
//# debugId=
|
|
149
|
+
//# debugId=342CE76CCD6FF26D64756E2164756E21
|
|
166
150
|
//# sourceMappingURL=errors.js.map
|
package/dist/src/errors.js.map
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"export const ErrorCodes = {\n\tVALIDATION_ERROR: \"VALIDATION_ERROR\",\n\tDATABASE_ERROR: \"DATABASE_ERROR\",\n\tAUTHENTICATION_ERROR: \"AUTHENTICATION_ERROR\",\n\tAUTHORIZATION_ERROR: \"AUTHORIZATION_ERROR\",\n\tRATE_LIMIT_ERROR: \"RATE_LIMIT_ERROR\",\n\tPAYMENT_REQUIRED: \"PAYMENT_REQUIRED\",\n\tFORBIDDEN: \"FORBIDDEN\",\n\tVERSION_CONFLICT: \"VERSION_CONFLICT\",\n\tNOT_FOUND: \"NOT_FOUND\",\n\t// Tenant lifecycle (CLI surfaces these verbatim)\n\tKEY_ROTATED: \"KEY_ROTATED\",\n\tTENANT_SUSPENDED: \"TENANT_SUSPENDED\",\n\tNO_TENANT_FOR_PROJECT: \"NO_TENANT_FOR_PROJECT\",\n\tINSTANCE_EXISTS: \"INSTANCE_EXISTS\",\n} as const;\n\nexport type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];\n\n/** Base error class for all Secondlayer errors. */\nexport class SecondLayerError extends Error {\n\tpublic code: ErrorCode;\n\tpublic override cause?: unknown;\n\t/** Optional structured payload merged into the HTTP error body (machine-readable hints). */\n\tpublic details?: Record<string, unknown>;\n\n\tconstructor(\n\t\tcode: ErrorCode,\n\t\tmessage: string,\n\t\tcause?: unknown,\n\t\tdetails?: Record<string, unknown>,\n\t) {\n\t\tsuper(message);\n\t\tthis.code = code;\n\t\tthis.cause = cause;\n\t\tthis.details = details;\n\t\tthis.name = this.constructor.name;\n\t\tError.captureStackTrace?.(this, this.constructor);\n\t}\n\n\ttoJSON(): {\n\t\tname: string;\n\t\tcode: string;\n\t\tmessage: string;\n\t\tstack: string | undefined;\n\t\tcause: unknown;\n\t\tdetails: Record<string, unknown> | undefined;\n\t} {\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\tcode: this.code,\n\t\t\tmessage: this.message,\n\t\t\tstack: this.stack,\n\t\t\tcause: this.cause,\n\t\t\tdetails: this.details,\n\t\t};\n\t}\n}\n\nexport class NotFoundError extends SecondLayerError {\n\tconstructor(message: string) {\n\t\tsuper(\"NOT_FOUND\", message);\n\t}\n}\n\nexport class ValidationError extends SecondLayerError {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(\"VALIDATION_ERROR\", message, cause);\n\t}\n}\n\nexport class DatabaseError extends SecondLayerError {\n\tconstructor(message: string, cause?: unknown) {\n\t\tsuper(\"DATABASE_ERROR\", message, cause);\n\t}\n}\n\nexport class AuthenticationError extends SecondLayerError {\n\t/** `details` is merged into the HTTP body — use it to carry the recovery\n\t * hint (which credential, where it comes from) instead of a bare \"invalid\n\t * key\" the caller cannot act on. */\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(\"AUTHENTICATION_ERROR\", message, undefined, details);\n\t}\n}\n\nexport class AuthorizationError extends SecondLayerError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(\"AUTHORIZATION_ERROR\", message, undefined, details);\n\t}\n}\n\nexport class RateLimitError extends SecondLayerError {\n\tconstructor(message: string) {\n\t\tsuper(\"RATE_LIMIT_ERROR\", message);\n\t}\n}\n\n/**\n * HTTP 402. Carries the x402 challenge (or a retry-later reason) in `details` so\n * the global error handler emits it in the body. The wire `PAYMENT-REQUIRED`\n * header is set separately by the x402 middleware on the challenge path.\n */\nexport class PaymentRequiredError extends SecondLayerError {\n\tconstructor(message: string, details?: Record<string, unknown>) {\n\t\tsuper(\"PAYMENT_REQUIRED\", message, undefined, details);\n\t}\n}\n\nexport class ForbiddenError extends SecondLayerError {\n\tconstructor(message = \"Forbidden\") {\n\t\tsuper(\"FORBIDDEN\", message);\n\t}\n}\n\nexport class VersionConflictError extends SecondLayerError {\n\tpublic currentVersion: string;\n\tpublic expectedVersion: string;\n\n\tconstructor(currentVersion: string, expectedVersion: string) {\n\t\tsuper(\n\t\t\t\"VERSION_CONFLICT\",\n\t\t\t`Version conflict: expected ${expectedVersion}, current ${currentVersion}`,\n\t\t);\n\t\tthis.currentVersion = currentVersion;\n\t\tthis.expectedVersion = expectedVersion;\n\t}\n}\n\nexport class KeyRotatedError extends SecondLayerError {\n\tconstructor(message = \"Token has been rotated\") {\n\t\tsuper(\"KEY_ROTATED\", message);\n\t}\n}\n\nexport class TenantSuspendedError extends SecondLayerError {\n\tconstructor(message = \"Instance is suspended\") {\n\t\tsuper(\"TENANT_SUSPENDED\", message);\n\t}\n}\n\n/** Error code → HTTP status. Used by API middleware for code-based matching\n * (avoids cross-bundle instanceof failures from bunup class duplication). */\n// String literal map — codes don't have to be in the central ErrorCode\n// enum (route-local error classes can supply any code; we just map the\n// HTTP status here). This keeps cross-bundle instanceof failures out of\n// the equation.\nexport const CODE_TO_STATUS: Record<\n\tstring,\n\t400 | 401 | 402 | 403 | 404 | 409 | 415 | 422 | 423 | 429 | 503\n> = {\n\t// The chain plane has no data yet — a fresh self-host install before the\n\t// first block lands. Retryable, and not the operator's mistake, so it is a\n\t// 503 with a name rather than an opaque 500.\n\tCHAIN_DATA_UNAVAILABLE: 503,\n\tAUTHENTICATION_ERROR: 401,\n\tAUTHORIZATION_ERROR: 403,\n\tPAYMENT_REQUIRED: 402,\n\tRATE_LIMIT_ERROR: 429,\n\tFORBIDDEN: 403,\n\tNOT_FOUND: 404,\n\tVALIDATION_ERROR: 400,\n\tKEY_ROTATED: 401,\n\tTENANT_SUSPENDED: 423,\n\tNO_TENANT_FOR_PROJECT: 404,\n\tINSTANCE_EXISTS: 409,\n\tSUBGRAPH_NOT_FOUND: 404,\n\tGHOST_KEY_READ_ONLY: 403,\n\t// A write that did not declare `Content-Type: application/json`. Shaped\n\t// like something a browser could have forged cross-origin without a CORS\n\t// preflight — see the API's `middleware/csrf.ts`.\n\tUNSUPPORTED_MEDIA_TYPE: 415,\n} as const;\n\nexport function getErrorMessage(err: unknown): string {\n\treturn err instanceof Error ? err.message : String(err);\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "342CE76CCD6FF26D64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/src/index-http.d.ts
CHANGED
|
@@ -168,4 +168,4 @@ declare class IndexHttpClient {
|
|
|
168
168
|
}
|
|
169
169
|
/** Decoder + subgraph processor client. One env contract; omits bearer when no key. */
|
|
170
170
|
declare function createInternalIndexHttpClient(): IndexHttpClient;
|
|
171
|
-
export {
|
|
171
|
+
export { IndexBlockRow, IndexEventRow, IndexHttpClient, IndexHttpOptions, IndexTransactionRow, StreamsReorgRow, createInternalIndexHttpClient };
|