@secondlayer/subgraphs 3.21.0 → 3.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/src/index.d.ts +238 -17
  2. package/dist/src/index.js +389 -52
  3. package/dist/src/index.js.map +12 -11
  4. package/dist/src/runtime/block-processor.d.ts +111 -10
  5. package/dist/src/runtime/block-processor.js +263 -31
  6. package/dist/src/runtime/block-processor.js.map +9 -8
  7. package/dist/src/runtime/catchup.d.ts +111 -10
  8. package/dist/src/runtime/catchup.js +263 -31
  9. package/dist/src/runtime/catchup.js.map +9 -8
  10. package/dist/src/runtime/context.d.ts +111 -11
  11. package/dist/src/runtime/context.js +166 -12
  12. package/dist/src/runtime/context.js.map +7 -6
  13. package/dist/src/runtime/processor.js +272 -35
  14. package/dist/src/runtime/processor.js.map +10 -9
  15. package/dist/src/runtime/reindex.d.ts +111 -10
  16. package/dist/src/runtime/reindex.js +263 -31
  17. package/dist/src/runtime/reindex.js.map +9 -8
  18. package/dist/src/runtime/reorg.d.ts +111 -10
  19. package/dist/src/runtime/reorg.js +268 -31
  20. package/dist/src/runtime/reorg.js.map +10 -9
  21. package/dist/src/runtime/replay.d.ts +3 -3
  22. package/dist/src/runtime/replay.js +30 -6
  23. package/dist/src/runtime/replay.js.map +4 -4
  24. package/dist/src/runtime/runner.d.ts +191 -17
  25. package/dist/src/runtime/source-matcher.d.ts +68 -8
  26. package/dist/src/runtime/source-matcher.js +30 -6
  27. package/dist/src/runtime/source-matcher.js.map +3 -3
  28. package/dist/src/runtime/stats.d.ts +3 -3
  29. package/dist/src/schema/index.d.ts +114 -13
  30. package/dist/src/schema/index.js +133 -20
  31. package/dist/src/schema/index.js.map +5 -5
  32. package/dist/src/service.js +272 -35
  33. package/dist/src/service.js.map +10 -9
  34. package/dist/src/testing/index.d.ts +667 -0
  35. package/dist/src/testing/index.js +1463 -0
  36. package/dist/src/testing/index.js.map +17 -0
  37. package/dist/src/triggers/index.d.ts +57 -6
  38. package/dist/src/types.d.ts +112 -11
  39. package/dist/src/validate.d.ts +129 -11
  40. package/dist/src/validate.js +117 -18
  41. package/dist/src/validate.js.map +3 -3
  42. package/package.json +9 -3
@@ -1,4 +1,32 @@
1
- import { AbiContract } from "@secondlayer/stacks/clarity";
1
+ import { AbiContract as AbiContract2 } from "@secondlayer/stacks/clarity";
2
+ /**
3
+ * How long a read stays valid.
4
+ *
5
+ * - `per-block` (default): pinned to the block being processed, cached under
6
+ * its `index_block_hash`. Sound for any read-only function — reindexing the
7
+ * same block always returns the same value, and a reorg-replaced block has a
8
+ * different id so it can't inherit the orphaned answer.
9
+ * - `contract-constant`: the caller asserts the value cannot change for this
10
+ * contract and these args (SIP-010 `get-decimals`/`get-symbol`), so it is
11
+ * resolved ONCE instead of once per block. This is the mode that makes a
12
+ * backfill affordable — under `per-block` every block is a distinct key and
13
+ * therefore a distinct RPC. Declaring it on a value that does change pins the
14
+ * first answer forever, so it is opt-in and never inferred.
15
+ */
16
+ type ChainReadCacheMode = "per-block" | "contract-constant";
17
+ type ChainReadOptions = {
18
+ cache?: ChainReadCacheMode
19
+ };
20
+ /**
21
+ * `ChainReadClient` with the ABI generic erased. Structurally cheap, so the
22
+ * base `SubgraphContext` can carry it; `TypedSubgraphContext` uses the real
23
+ * one and handlers get full inference.
24
+ */
25
+ interface ErasedChainReadClient {
26
+ contract(contractId: string, abi: unknown, options?: ChainReadOptions): {
27
+ read: Record<string, (args?: Record<string, unknown>) => Promise<unknown>>
28
+ };
29
+ }
2
30
  /** Supported column types for subgraph schemas */
3
31
  type ColumnType = "text" | "uint" | "int" | "principal" | "boolean" | "timestamp" | "jsonb";
4
32
  /** Column definition in a subgraph table */
@@ -25,15 +53,24 @@ interface SubgraphRelation {
25
53
  /** Target column(s) the fields point at (a uniqueKeys entry on the target). */
26
54
  referencedColumns: string[];
27
55
  }
28
- /** Table definition within a subgraph schema */
56
+ /**
57
+ * Table definition within a subgraph schema.
58
+ *
59
+ * The array fields are `readonly` so a schema literal can be hoisted out of
60
+ * the `defineSubgraph()` call with `as const` (or {@link defineSchema}) and
61
+ * still typecheck — `as const` produces `readonly [readonly ["holder"]]`,
62
+ * which a mutable `string[][]` rejects. Without that, extracting a helper
63
+ * that takes `ctx` meant losing the entire typed surface, which is why the
64
+ * shipped starter reached for `ctx: any`.
65
+ */
29
66
  interface SubgraphTable {
30
67
  columns: Record<string, SubgraphColumn>;
31
68
  /** Composite indexes (each entry is an array of column names) */
32
- indexes?: string[][];
69
+ indexes?: readonly (readonly string[])[];
33
70
  /** Unique key constraints (each entry is an array of column names). Required for upsert. */
34
- uniqueKeys?: string[][];
71
+ uniqueKeys?: readonly (readonly string[])[];
35
72
  /** Foreign-key relations to other tables (for typed ORM joins). */
36
- relations?: SubgraphRelation[];
73
+ relations?: readonly SubgraphRelation[];
37
74
  }
38
75
  /** Subgraph schema — maps table names to table definitions */
39
76
  type SubgraphSchema = Record<string, SubgraphTable>;
@@ -68,6 +105,45 @@ interface StxLockFilter {
68
105
  type TraitScope = {
69
106
  trait?: string
70
107
  };
108
+ /**
109
+ * Scope a source to a DYNAMIC address set discovered from another source's
110
+ * events, instead of a fixed contract list.
111
+ *
112
+ * The standard shape it unlocks: a router plus pools created after you
113
+ * deploy. `contractId` arrays cover a set you know at authoring time; a
114
+ * factory covers the set that grows. It is deliberately NOT tied to contract
115
+ * deployment — the address can come from any field of any event, so it also
116
+ * covers launchpad-minted tokens, DAO extension allowlists, and registry
117
+ * entries.
118
+ *
119
+ * ```ts
120
+ * sources: {
121
+ * registry: { type: "print_event", contractId: REGISTRY, topic: "pool-created" },
122
+ * swaps: {
123
+ * type: "print_event",
124
+ * topic: "swap",
125
+ * // every pool the registry has ever announced, including new ones
126
+ * factory: { from: "registry", field: "data.pool" },
127
+ * },
128
+ * }
129
+ * ```
130
+ *
131
+ * Two guarantees the runtime provides:
132
+ * - **Same-block ordering** — a contract discovered in block N receives its
133
+ * own block-N events. Discovery runs before matching, within the block.
134
+ * - **Reorg-scoped** — the discovered set is stamped with the block that
135
+ * revealed it and rolled back with everything else on a fork, so an address
136
+ * announced on an orphaned chain does not linger forever.
137
+ */
138
+ interface FactoryScope {
139
+ factory?: {
140
+ /** Source name whose events reveal the addresses. */
141
+ from: string
142
+ /** Dotted path to the address on that source's payload
143
+ * (e.g. `"data.pool"`, `"contractId"`, `"data.token.id"`). */
144
+ field: string
145
+ };
146
+ }
71
147
  /** FT event filters */
72
148
  interface FtTransferFilter extends TraitScope {
73
149
  type: "ft_transfer";
@@ -106,9 +182,19 @@ interface NftBurnFilter extends TraitScope {
106
182
  sender?: string;
107
183
  }
108
184
  /** Contract event filters */
109
- interface ContractCallFilter extends TraitScope {
185
+ interface ContractCallFilter extends TraitScope, FactoryScope {
110
186
  type: "contract_call";
111
- contractId?: string;
187
+ /**
188
+ * One contract id, or a SET of them (max 20) — the standard DeFi shape is
189
+ * a router plus N pools, which used to cost N near-identical sources and
190
+ * handlers, or the `"*"` catch-all that erases per-source typing. Payload
191
+ * types are identical per `type`, so one handler serves the set and
192
+ * `event.contractId` disambiguates.
193
+ *
194
+ * Supports `*` wildcards (e.g. `"SP1ABC….pool-*"`). Mutually exclusive
195
+ * with `trait`, which resolves its own set per block.
196
+ */
197
+ contractId?: string | readonly string[];
112
198
  functionName?: string;
113
199
  caller?: string;
114
200
  /**
@@ -117,7 +203,7 @@ interface ContractCallFilter extends TraitScope {
117
203
  * definition and used at runtime to decode args by name. Omit to keep
118
204
  * `event.args` as a positional `unknown[]`.
119
205
  */
120
- abi?: AbiContract;
206
+ abi?: AbiContract2;
121
207
  }
122
208
  interface ContractDeployFilter {
123
209
  type: "contract_deploy";
@@ -146,9 +232,11 @@ type PrintField = ColumnType | {
146
232
  } | {
147
233
  list: PrintField
148
234
  };
149
- interface PrintEventFilter extends TraitScope {
235
+ interface PrintEventFilter extends TraitScope, FactoryScope {
150
236
  type: "print_event";
151
- contractId?: string;
237
+ /** One contract id, or a set of them (max 20). Supports `*` wildcards.
238
+ * Mutually exclusive with `trait`. */
239
+ contractId?: string | readonly string[];
152
240
  topic?: string;
153
241
  /**
154
242
  * Per-topic field schema. When declared, the handler's `event` is a
@@ -186,8 +274,21 @@ interface SubgraphContext {
186
274
  hash: string
187
275
  timestamp: number
188
276
  burnBlockHeight: number
277
+ /** Nakamoto StacksBlockId, when the block row carries one. */
278
+ indexBlockHash?: string | null
189
279
  };
190
280
  tx: TxMeta;
281
+ /**
282
+ * Read-only contract calls pinned to this block. Cached, so the same
283
+ * (contract, function, args) is fetched once per block rather than once
284
+ * per event.
285
+ *
286
+ * Erased here on purpose: this interface is compared structurally wherever
287
+ * a subgraph definition is passed around, and carrying an ABI-generic
288
+ * method pushes those comparisons past TS's instantiation depth. Handlers
289
+ * receive `TypedSubgraphContext`, which exposes the fully typed version.
290
+ */
291
+ client: ErasedChainReadClient;
191
292
  insert(table: string, row: Record<string, unknown>): void;
192
293
  update(table: string, where: Record<string, unknown>, set: Record<string, unknown>): void;
193
294
  upsert(table: string, key: Record<string, unknown>, row: Record<string, unknown>): void;
@@ -272,10 +373,27 @@ declare const SubgraphColumnSchema: z.ZodType<SubgraphColumn>;
272
373
  declare const SubgraphTableSchema: z.ZodType<SubgraphTable>;
273
374
  declare const SubgraphSchemaSchema: z.ZodType<Record<string, SubgraphTable>>;
274
375
  declare const VALID_FILTER_TYPES: readonly ["stx_transfer", "stx_mint", "stx_burn", "stx_lock", "ft_transfer", "ft_mint", "ft_burn", "nft_transfer", "nft_mint", "nft_burn", "contract_call", "contract_deploy", "print_event"];
376
+ /**
377
+ * `trait` and `contractId` compose rather than conflict: the matcher ANDs
378
+ * them, so the pair means "contracts conforming to this trait, narrowed to
379
+ * these ids". (The Index READ API refuses the combination because its query
380
+ * planner picks one index path — that's an API constraint, not a semantic
381
+ * one, and subgraph sources are not bound by it.)
382
+ */
275
383
  declare const SubgraphFilterSchema: z.ZodType<SubgraphFilter>;
276
384
  declare const SubgraphDefinitionSchema: z.ZodType<SubgraphDefinition>;
277
385
  /**
278
386
  * Validates a subgraph definition, returning the parsed result or throwing on failure.
279
387
  */
280
388
  declare function validateSubgraphDefinition(def: unknown): SubgraphDefinition;
281
- export { validateSubgraphDefinition, VALID_FILTER_TYPES, SubgraphTableSchema, SubgraphSchemaSchema, SubgraphNameSchema, SubgraphFilterSchema, SubgraphDefinitionSchema, SubgraphColumnSchema, SqlIdentifierSchema, PrintFieldSchema, ColumnTypeSchema, AbiContractSchema };
389
+ /**
390
+ * Per-source-type field vocabulary, DERIVED from
391
+ * {@link SubgraphFilterSchema}. Agent-facing surfaces (the MCP filters
392
+ * reference) used to hand-maintain a parallel copy of this list; deriving it
393
+ * means adding a field to a filter can never leave the documentation behind.
394
+ */
395
+ declare function filterFieldsByType(): Array<{
396
+ type: string
397
+ fields: string[]
398
+ }>;
399
+ export { validateSubgraphDefinition, filterFieldsByType, VALID_FILTER_TYPES, SubgraphTableSchema, SubgraphSchemaSchema, SubgraphNameSchema, SubgraphFilterSchema, SubgraphDefinitionSchema, SubgraphColumnSchema, SqlIdentifierSchema, PrintFieldSchema, ColumnTypeSchema, AbiContractSchema };
@@ -86,24 +86,105 @@ var VALID_FILTER_TYPES = [
86
86
  "contract_deploy",
87
87
  "print_event"
88
88
  ];
89
- var SubgraphFilterSchema = z.object({
90
- type: z.enum(VALID_FILTER_TYPES),
91
- sender: z.string().optional(),
92
- recipient: z.string().optional(),
89
+ var contractIdField = z.union([
90
+ z.string(),
91
+ z.array(z.string()).min(1).max(20)
92
+ ]);
93
+ var traitScope = { trait: z.string().optional() };
94
+ var factoryScope = {
95
+ factory: z.object({ from: z.string().min(1), field: z.string().min(1) }).strict().optional()
96
+ };
97
+ var amountRange = {
93
98
  minAmount: z.bigint().optional(),
94
- maxAmount: z.bigint().optional(),
95
- assetIdentifier: z.string().optional(),
96
- contractId: z.string().optional(),
97
- functionName: z.string().optional(),
98
- caller: z.string().optional(),
99
- deployer: z.string().optional(),
100
- contractName: z.string().optional(),
101
- topic: z.string().optional(),
102
- lockedAddress: z.string().optional(),
103
- abi: AbiContractSchema.optional(),
104
- trait: z.string().optional(),
105
- prints: z.record(z.string(), z.record(z.string(), PrintFieldSchema)).optional()
106
- }).strict();
99
+ maxAmount: z.bigint().optional()
100
+ };
101
+ var SubgraphFilterUnion = z.discriminatedUnion("type", [
102
+ z.object({
103
+ type: z.literal("stx_transfer"),
104
+ sender: z.string().optional(),
105
+ recipient: z.string().optional(),
106
+ ...amountRange
107
+ }).strict(),
108
+ z.object({
109
+ type: z.literal("stx_mint"),
110
+ recipient: z.string().optional(),
111
+ minAmount: z.bigint().optional()
112
+ }).strict(),
113
+ z.object({
114
+ type: z.literal("stx_burn"),
115
+ sender: z.string().optional(),
116
+ minAmount: z.bigint().optional()
117
+ }).strict(),
118
+ z.object({
119
+ type: z.literal("stx_lock"),
120
+ lockedAddress: z.string().optional(),
121
+ minAmount: z.bigint().optional()
122
+ }).strict(),
123
+ z.object({
124
+ type: z.literal("ft_transfer"),
125
+ assetIdentifier: z.string().optional(),
126
+ sender: z.string().optional(),
127
+ recipient: z.string().optional(),
128
+ minAmount: z.bigint().optional(),
129
+ ...traitScope
130
+ }).strict(),
131
+ z.object({
132
+ type: z.literal("ft_mint"),
133
+ assetIdentifier: z.string().optional(),
134
+ recipient: z.string().optional(),
135
+ minAmount: z.bigint().optional(),
136
+ ...traitScope
137
+ }).strict(),
138
+ z.object({
139
+ type: z.literal("ft_burn"),
140
+ assetIdentifier: z.string().optional(),
141
+ sender: z.string().optional(),
142
+ minAmount: z.bigint().optional(),
143
+ ...traitScope
144
+ }).strict(),
145
+ z.object({
146
+ type: z.literal("nft_transfer"),
147
+ assetIdentifier: z.string().optional(),
148
+ sender: z.string().optional(),
149
+ recipient: z.string().optional(),
150
+ ...traitScope
151
+ }).strict(),
152
+ z.object({
153
+ type: z.literal("nft_mint"),
154
+ assetIdentifier: z.string().optional(),
155
+ recipient: z.string().optional(),
156
+ ...traitScope
157
+ }).strict(),
158
+ z.object({
159
+ type: z.literal("nft_burn"),
160
+ assetIdentifier: z.string().optional(),
161
+ sender: z.string().optional(),
162
+ ...traitScope
163
+ }).strict(),
164
+ z.object({
165
+ type: z.literal("contract_call"),
166
+ contractId: contractIdField.optional(),
167
+ functionName: z.string().optional(),
168
+ caller: z.string().optional(),
169
+ abi: AbiContractSchema.optional(),
170
+ ...traitScope,
171
+ ...factoryScope
172
+ }).strict(),
173
+ z.object({
174
+ type: z.literal("contract_deploy"),
175
+ deployer: z.string().optional(),
176
+ contractName: z.string().optional()
177
+ }).strict(),
178
+ z.object({
179
+ type: z.literal("print_event"),
180
+ contractId: contractIdField.optional(),
181
+ topic: z.string().optional(),
182
+ prints: z.record(z.string(), z.record(z.string(), PrintFieldSchema)).optional(),
183
+ ...traitScope,
184
+ ...factoryScope
185
+ }).strict()
186
+ ]);
187
+ var SubgraphFilterSchema = SubgraphFilterUnion;
107
188
  var SubgraphDefinitionSchema = z.object({
108
189
  name: SubgraphNameSchema,
109
190
  version: z.string().optional(),
@@ -117,8 +198,26 @@ var SubgraphDefinitionSchema = z.object({
117
198
  function validateSubgraphDefinition(def) {
118
199
  return SubgraphDefinitionSchema.parse(def);
119
200
  }
201
+ function filterFieldsByType() {
202
+ const options = SubgraphFilterUnion?._def?.options ?? [];
203
+ const out = [];
204
+ for (const option of options) {
205
+ const shape = option?.shape ?? option?._def?.shape;
206
+ if (!shape)
207
+ continue;
208
+ const literal = shape.type?._def?.values?.[0] ?? shape.type?._def?.value ?? undefined;
209
+ if (typeof literal !== "string")
210
+ continue;
211
+ out.push({
212
+ type: literal,
213
+ fields: Object.keys(shape).filter((k) => k !== "type")
214
+ });
215
+ }
216
+ return out;
217
+ }
120
218
  export {
121
219
  validateSubgraphDefinition,
220
+ filterFieldsByType,
122
221
  VALID_FILTER_TYPES,
123
222
  SubgraphTableSchema,
124
223
  SubgraphSchemaSchema,
@@ -132,5 +231,5 @@ export {
132
231
  AbiContractSchema
133
232
  };
134
233
 
135
- //# debugId=E99182101593A8B264756E2164756E21
234
+ //# debugId=BAF10EBE9E88C37664756E2164756E21
136
235
  //# sourceMappingURL=validate.js.map
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/validate.ts"],
4
4
  "sourcesContent": [
5
- "import { z } from \"zod\";\nimport type {\n\tColumnType,\n\tSubgraphColumn,\n\tSubgraphDefinition,\n\tSubgraphFilter,\n\tSubgraphTable,\n} from \"./types.ts\";\n\nexport const SubgraphNameSchema: z.ZodType<string> = z\n\t.string()\n\t.min(1)\n\t.max(63)\n\t.regex(\n\t\t/^[a-z][a-z0-9-]*$/,\n\t\t\"Must start with lowercase letter, contain only lowercase alphanumeric and hyphens\",\n\t);\n\n/**\n * A safe SQL identifier (table or column name). Mirrors the runtime guard in\n * runtime/context.ts (validateColumnName) so the schema validator can never\n * accept a name the runtime would reject — and closes the deploy-time DDL\n * injection path in schema/generator.ts, which interpolates these names raw.\n */\nexport const SqlIdentifierSchema: z.ZodType<string> = z\n\t.string()\n\t.min(1)\n\t.max(63) // Postgres truncates identifiers > 63 bytes; reject rather than collide.\n\t.regex(\n\t\t/^[a-z_][a-z0-9_]*$/i,\n\t\t\"Must be a valid SQL identifier: start with a letter or underscore, then letters/digits/underscores only\",\n\t);\n\nexport const ColumnTypeSchema: z.ZodType<ColumnType> = z.enum([\n\t\"text\",\n\t\"uint\",\n\t\"int\",\n\t\"principal\",\n\t\"boolean\",\n\t\"timestamp\",\n\t\"jsonb\",\n]);\n\n/**\n * One declared print field: a bare column type, or a composite (optional,\n * nested tuple, list). Recursive — real print payloads nest, and a vocabulary\n * that could only say `\"jsonb\"` is what let a flat-field declaration pass\n * while every event decoded to null.\n */\nexport const PrintFieldSchema: z.ZodType<unknown> = z.lazy(() =>\n\tz.union([\n\t\tColumnTypeSchema,\n\t\tz.object({ type: PrintFieldSchema, optional: z.literal(true) }),\n\t\tz.object({ tuple: z.record(z.string(), PrintFieldSchema) }),\n\t\tz.object({ list: PrintFieldSchema }),\n\t]),\n);\n\n/**\n * A Clarity ABI type: a primitive name, or one of the composite shapes.\n * Recursive, so nested tuples/lists/optionals are checked all the way down.\n */\nconst AbiTypeSchema: z.ZodType<unknown> = z.lazy(() =>\n\tz.union([\n\t\tz.string(),\n\t\tz.object({ buff: z.object({ length: z.number() }) }),\n\t\tz.object({ \"string-ascii\": z.object({ length: z.number() }) }),\n\t\tz.object({ \"string-utf8\": z.object({ length: z.number() }) }),\n\t\tz.object({ optional: AbiTypeSchema }),\n\t\tz.object({\n\t\t\tlist: z.object({ type: AbiTypeSchema, length: z.number() }),\n\t\t}),\n\t\tz.object({\n\t\t\ttuple: z.array(z.object({ name: z.string(), type: AbiTypeSchema })),\n\t\t}),\n\t\tz.object({\n\t\t\tresponse: z.object({ ok: AbiTypeSchema, error: AbiTypeSchema }),\n\t\t}),\n\t]),\n);\n\n/**\n * The canonical `AbiContract` shape, validated at deploy time.\n *\n * This used to be `z.record(z.string(), z.any())`, which accepted a raw\n * Hiro/Clarinet ABI (`read_only` access, `buffer` types, outputs wrapped as\n * `{ type: … }`) and let it through — the deploy succeeded and `event.input`\n * then mis-decoded at RUNTIME, per event, forever. Reject it here instead,\n * and name the fix: run it through `normalizeAbi` from\n * `@secondlayer/stacks/clarity`.\n */\nexport const AbiContractSchema: z.ZodType<unknown> = z.object({\n\tfunctions: z.array(\n\t\tz.object({\n\t\t\tname: z.string(),\n\t\t\taccess: z.enum([\"public\", \"read-only\", \"private\"], {\n\t\t\t\tmessage:\n\t\t\t\t\t\"ABI access must be public | read-only | private — a raw Hiro/Clarinet ABI uses `read_only`. Normalize it first: normalizeAbi() from @secondlayer/stacks/clarity.\",\n\t\t\t}),\n\t\t\targs: z.array(z.object({ name: z.string(), type: AbiTypeSchema })),\n\t\t\t// Canonical shape is a bare AbiType; raw ABIs wrap it as `{ type: … }`.\n\t\t\toutputs: AbiTypeSchema,\n\t\t}),\n\t),\n\tmaps: z.array(z.unknown()).optional(),\n\tvariables: z.array(z.unknown()).optional(),\n\tfungible_tokens: z.array(z.unknown()).optional(),\n\tnon_fungible_tokens: z.array(z.unknown()).optional(),\n\timplemented_traits: z.array(z.unknown()).optional(),\n\tdefined_traits: z.array(z.unknown()).optional(),\n});\n\nexport const SubgraphColumnSchema: z.ZodType<SubgraphColumn> = z.object({\n\ttype: ColumnTypeSchema,\n\tnullable: z.boolean().optional(),\n\tindexed: z.boolean().optional(),\n\tsearch: z.boolean().optional(),\n\tdefault: z.union([z.string(), z.number(), z.boolean()]).optional(),\n}) as z.ZodType<SubgraphColumn>;\n\nexport const SubgraphTableSchema: z.ZodType<SubgraphTable> = z.object({\n\tcolumns: z\n\t\t.record(SqlIdentifierSchema, SubgraphColumnSchema)\n\t\t.refine(\n\t\t\t(c) => Object.keys(c).length > 0,\n\t\t\t\"Table must have at least one column\",\n\t\t),\n\tindexes: z.array(z.array(SqlIdentifierSchema)).optional(),\n\tuniqueKeys: z.array(z.array(SqlIdentifierSchema)).optional(),\n\trelations: z\n\t\t.array(\n\t\t\tz.object({\n\t\t\t\tname: SqlIdentifierSchema,\n\t\t\t\treferences: SqlIdentifierSchema,\n\t\t\t\tfields: z.array(SqlIdentifierSchema).min(1),\n\t\t\t\treferencedColumns: z.array(SqlIdentifierSchema).min(1),\n\t\t\t}),\n\t\t)\n\t\t.optional(),\n}) as z.ZodType<SubgraphTable>;\n\nexport const SubgraphSchemaSchema: z.ZodType<Record<string, SubgraphTable>> = z\n\t.record(SqlIdentifierSchema, SubgraphTableSchema)\n\t.refine(\n\t\t(s) => Object.keys(s).length > 0,\n\t\t\"Schema must have at least one table\",\n\t) as z.ZodType<Record<string, SubgraphTable>>;\n\nexport const VALID_FILTER_TYPES = [\n\t\"stx_transfer\",\n\t\"stx_mint\",\n\t\"stx_burn\",\n\t\"stx_lock\",\n\t\"ft_transfer\",\n\t\"ft_mint\",\n\t\"ft_burn\",\n\t\"nft_transfer\",\n\t\"nft_mint\",\n\t\"nft_burn\",\n\t\"contract_call\",\n\t\"contract_deploy\",\n\t\"print_event\",\n] as const;\n\nexport const SubgraphFilterSchema: z.ZodType<SubgraphFilter> = z\n\t.object({\n\t\ttype: z.enum(VALID_FILTER_TYPES),\n\t\t// All optional fields across all filter types\n\t\tsender: z.string().optional(),\n\t\trecipient: z.string().optional(),\n\t\tminAmount: z.bigint().optional(),\n\t\tmaxAmount: z.bigint().optional(),\n\t\tassetIdentifier: z.string().optional(),\n\t\tcontractId: z.string().optional(),\n\t\tfunctionName: z.string().optional(),\n\t\tcaller: z.string().optional(),\n\t\tdeployer: z.string().optional(),\n\t\tcontractName: z.string().optional(),\n\t\ttopic: z.string().optional(),\n\t\tlockedAddress: z.string().optional(),\n\t\tabi: AbiContractSchema.optional(),\n\t\ttrait: z.string().optional(),\n\t\t// print_event per-topic field schema. Declaring it opts the source into\n\t\t// runtime payload validation (skip + log on mismatch).\n\t\tprints: z\n\t\t\t.record(z.string(), z.record(z.string(), PrintFieldSchema))\n\t\t\t.optional(),\n\t})\n\t.strict() as unknown as z.ZodType<SubgraphFilter>;\n\nexport const SubgraphDefinitionSchema: z.ZodType<SubgraphDefinition> = z.object(\n\t{\n\t\tname: SubgraphNameSchema,\n\t\tversion: z.string().optional(),\n\t\tdescription: z.string().optional(),\n\t\tstartBlock: z.number().int().nonnegative().optional(),\n\t\t// 'concurrent' = tip-first deploy: go live at tip immediately, fill\n\t\t// history via a background backfill. Only safe for order-tolerant\n\t\t// handlers (commutative or insert-only writes).\n\t\tbackfillMode: z.enum([\"blocking\", \"concurrent\"]).optional(),\n\t\tsources: z\n\t\t\t.record(z.string(), SubgraphFilterSchema)\n\t\t\t.refine(\n\t\t\t\t(s) => Object.keys(s).length > 0,\n\t\t\t\t\"Must have at least one source\",\n\t\t\t),\n\t\tschema: SubgraphSchemaSchema,\n\t\thandlers: z.record(z.string(), z.any()),\n\t},\n) as unknown as z.ZodType<SubgraphDefinition>;\n\n/**\n * Validates a subgraph definition, returning the parsed result or throwing on failure.\n */\nexport function validateSubgraphDefinition(def: unknown): SubgraphDefinition {\n\treturn SubgraphDefinitionSchema.parse(def);\n}\n"
5
+ "import { z } from \"zod\";\nimport type {\n\tColumnType,\n\tSubgraphColumn,\n\tSubgraphDefinition,\n\tSubgraphFilter,\n\tSubgraphTable,\n} from \"./types.ts\";\n\nexport const SubgraphNameSchema: z.ZodType<string> = z\n\t.string()\n\t.min(1)\n\t.max(63)\n\t.regex(\n\t\t/^[a-z][a-z0-9-]*$/,\n\t\t\"Must start with lowercase letter, contain only lowercase alphanumeric and hyphens\",\n\t);\n\n/**\n * A safe SQL identifier (table or column name). Mirrors the runtime guard in\n * runtime/context.ts (validateColumnName) so the schema validator can never\n * accept a name the runtime would reject — and closes the deploy-time DDL\n * injection path in schema/generator.ts, which interpolates these names raw.\n */\nexport const SqlIdentifierSchema: z.ZodType<string> = z\n\t.string()\n\t.min(1)\n\t.max(63) // Postgres truncates identifiers > 63 bytes; reject rather than collide.\n\t.regex(\n\t\t/^[a-z_][a-z0-9_]*$/i,\n\t\t\"Must be a valid SQL identifier: start with a letter or underscore, then letters/digits/underscores only\",\n\t);\n\nexport const ColumnTypeSchema: z.ZodType<ColumnType> = z.enum([\n\t\"text\",\n\t\"uint\",\n\t\"int\",\n\t\"principal\",\n\t\"boolean\",\n\t\"timestamp\",\n\t\"jsonb\",\n]);\n\n/**\n * One declared print field: a bare column type, or a composite (optional,\n * nested tuple, list). Recursive — real print payloads nest, and a vocabulary\n * that could only say `\"jsonb\"` is what let a flat-field declaration pass\n * while every event decoded to null.\n */\nexport const PrintFieldSchema: z.ZodType<unknown> = z.lazy(() =>\n\tz.union([\n\t\tColumnTypeSchema,\n\t\tz.object({ type: PrintFieldSchema, optional: z.literal(true) }),\n\t\tz.object({ tuple: z.record(z.string(), PrintFieldSchema) }),\n\t\tz.object({ list: PrintFieldSchema }),\n\t]),\n);\n\n/**\n * A Clarity ABI type: a primitive name, or one of the composite shapes.\n * Recursive, so nested tuples/lists/optionals are checked all the way down.\n */\nconst AbiTypeSchema: z.ZodType<unknown> = z.lazy(() =>\n\tz.union([\n\t\tz.string(),\n\t\tz.object({ buff: z.object({ length: z.number() }) }),\n\t\tz.object({ \"string-ascii\": z.object({ length: z.number() }) }),\n\t\tz.object({ \"string-utf8\": z.object({ length: z.number() }) }),\n\t\tz.object({ optional: AbiTypeSchema }),\n\t\tz.object({\n\t\t\tlist: z.object({ type: AbiTypeSchema, length: z.number() }),\n\t\t}),\n\t\tz.object({\n\t\t\ttuple: z.array(z.object({ name: z.string(), type: AbiTypeSchema })),\n\t\t}),\n\t\tz.object({\n\t\t\tresponse: z.object({ ok: AbiTypeSchema, error: AbiTypeSchema }),\n\t\t}),\n\t]),\n);\n\n/**\n * The canonical `AbiContract` shape, validated at deploy time.\n *\n * This used to be `z.record(z.string(), z.any())`, which accepted a raw\n * Hiro/Clarinet ABI (`read_only` access, `buffer` types, outputs wrapped as\n * `{ type: … }`) and let it through — the deploy succeeded and `event.input`\n * then mis-decoded at RUNTIME, per event, forever. Reject it here instead,\n * and name the fix: run it through `normalizeAbi` from\n * `@secondlayer/stacks/clarity`.\n */\nexport const AbiContractSchema: z.ZodType<unknown> = z.object({\n\tfunctions: z.array(\n\t\tz.object({\n\t\t\tname: z.string(),\n\t\t\taccess: z.enum([\"public\", \"read-only\", \"private\"], {\n\t\t\t\tmessage:\n\t\t\t\t\t\"ABI access must be public | read-only | private — a raw Hiro/Clarinet ABI uses `read_only`. Normalize it first: normalizeAbi() from @secondlayer/stacks/clarity.\",\n\t\t\t}),\n\t\t\targs: z.array(z.object({ name: z.string(), type: AbiTypeSchema })),\n\t\t\t// Canonical shape is a bare AbiType; raw ABIs wrap it as `{ type: … }`.\n\t\t\toutputs: AbiTypeSchema,\n\t\t}),\n\t),\n\tmaps: z.array(z.unknown()).optional(),\n\tvariables: z.array(z.unknown()).optional(),\n\tfungible_tokens: z.array(z.unknown()).optional(),\n\tnon_fungible_tokens: z.array(z.unknown()).optional(),\n\timplemented_traits: z.array(z.unknown()).optional(),\n\tdefined_traits: z.array(z.unknown()).optional(),\n});\n\nexport const SubgraphColumnSchema: z.ZodType<SubgraphColumn> = z.object({\n\ttype: ColumnTypeSchema,\n\tnullable: z.boolean().optional(),\n\tindexed: z.boolean().optional(),\n\tsearch: z.boolean().optional(),\n\tdefault: z.union([z.string(), z.number(), z.boolean()]).optional(),\n}) as z.ZodType<SubgraphColumn>;\n\nexport const SubgraphTableSchema: z.ZodType<SubgraphTable> = z.object({\n\tcolumns: z\n\t\t.record(SqlIdentifierSchema, SubgraphColumnSchema)\n\t\t.refine(\n\t\t\t(c) => Object.keys(c).length > 0,\n\t\t\t\"Table must have at least one column\",\n\t\t),\n\tindexes: z.array(z.array(SqlIdentifierSchema)).optional(),\n\tuniqueKeys: z.array(z.array(SqlIdentifierSchema)).optional(),\n\trelations: z\n\t\t.array(\n\t\t\tz.object({\n\t\t\t\tname: SqlIdentifierSchema,\n\t\t\t\treferences: SqlIdentifierSchema,\n\t\t\t\tfields: z.array(SqlIdentifierSchema).min(1),\n\t\t\t\treferencedColumns: z.array(SqlIdentifierSchema).min(1),\n\t\t\t}),\n\t\t)\n\t\t.optional(),\n}) as z.ZodType<SubgraphTable>;\n\nexport const SubgraphSchemaSchema: z.ZodType<Record<string, SubgraphTable>> = z\n\t.record(SqlIdentifierSchema, SubgraphTableSchema)\n\t.refine(\n\t\t(s) => Object.keys(s).length > 0,\n\t\t\"Schema must have at least one table\",\n\t) as z.ZodType<Record<string, SubgraphTable>>;\n\nexport const VALID_FILTER_TYPES = [\n\t\"stx_transfer\",\n\t\"stx_mint\",\n\t\"stx_burn\",\n\t\"stx_lock\",\n\t\"ft_transfer\",\n\t\"ft_mint\",\n\t\"ft_burn\",\n\t\"nft_transfer\",\n\t\"nft_mint\",\n\t\"nft_burn\",\n\t\"contract_call\",\n\t\"contract_deploy\",\n\t\"print_event\",\n] as const;\n\n/** A contract id, or a set of them (max 20, matching the Index API cap). */\nconst contractIdField = z.union([\n\tz.string(),\n\tz.array(z.string()).min(1).max(20),\n]);\n\n/** Fields shared by the trait-scopable filters. */\nconst traitScope = { trait: z.string().optional() };\n/** Dynamic address set discovered from another source's events. */\nconst factoryScope = {\n\tfactory: z\n\t\t.object({ from: z.string().min(1), field: z.string().min(1) })\n\t\t.strict()\n\t\t.optional(),\n};\nconst amountRange = {\n\tminAmount: z.bigint().optional(),\n\tmaxAmount: z.bigint().optional(),\n};\n\n/**\n * A REAL discriminated union — one member per source type, each `.strict()`\n * with only the fields that type actually supports.\n *\n * It used to be one flat object with every field optional, so\n * `{ type: \"contract_deploy\", assetIdentifier: \"SP…\", minAmount: 1n }`\n * validated clean at deploy and then matched nothing, forever. The runtime\n * union already knew better; only the validator didn't.\n */\nconst SubgraphFilterUnion = z.discriminatedUnion(\"type\", [\n\tz\n\t\t.object({\n\t\t\ttype: z.literal(\"stx_transfer\"),\n\t\t\tsender: z.string().optional(),\n\t\t\trecipient: z.string().optional(),\n\t\t\t...amountRange,\n\t\t})\n\t\t.strict(),\n\tz\n\t\t.object({\n\t\t\ttype: z.literal(\"stx_mint\"),\n\t\t\trecipient: z.string().optional(),\n\t\t\tminAmount: z.bigint().optional(),\n\t\t})\n\t\t.strict(),\n\tz\n\t\t.object({\n\t\t\ttype: z.literal(\"stx_burn\"),\n\t\t\tsender: z.string().optional(),\n\t\t\tminAmount: z.bigint().optional(),\n\t\t})\n\t\t.strict(),\n\tz\n\t\t.object({\n\t\t\ttype: z.literal(\"stx_lock\"),\n\t\t\tlockedAddress: z.string().optional(),\n\t\t\tminAmount: z.bigint().optional(),\n\t\t})\n\t\t.strict(),\n\tz\n\t\t.object({\n\t\t\ttype: z.literal(\"ft_transfer\"),\n\t\t\tassetIdentifier: z.string().optional(),\n\t\t\tsender: z.string().optional(),\n\t\t\trecipient: z.string().optional(),\n\t\t\tminAmount: z.bigint().optional(),\n\t\t\t...traitScope,\n\t\t})\n\t\t.strict(),\n\tz\n\t\t.object({\n\t\t\ttype: z.literal(\"ft_mint\"),\n\t\t\tassetIdentifier: z.string().optional(),\n\t\t\trecipient: z.string().optional(),\n\t\t\tminAmount: z.bigint().optional(),\n\t\t\t...traitScope,\n\t\t})\n\t\t.strict(),\n\tz\n\t\t.object({\n\t\t\ttype: z.literal(\"ft_burn\"),\n\t\t\tassetIdentifier: z.string().optional(),\n\t\t\tsender: z.string().optional(),\n\t\t\tminAmount: z.bigint().optional(),\n\t\t\t...traitScope,\n\t\t})\n\t\t.strict(),\n\tz\n\t\t.object({\n\t\t\ttype: z.literal(\"nft_transfer\"),\n\t\t\tassetIdentifier: z.string().optional(),\n\t\t\tsender: z.string().optional(),\n\t\t\trecipient: z.string().optional(),\n\t\t\t...traitScope,\n\t\t})\n\t\t.strict(),\n\tz\n\t\t.object({\n\t\t\ttype: z.literal(\"nft_mint\"),\n\t\t\tassetIdentifier: z.string().optional(),\n\t\t\trecipient: z.string().optional(),\n\t\t\t...traitScope,\n\t\t})\n\t\t.strict(),\n\tz\n\t\t.object({\n\t\t\ttype: z.literal(\"nft_burn\"),\n\t\t\tassetIdentifier: z.string().optional(),\n\t\t\tsender: z.string().optional(),\n\t\t\t...traitScope,\n\t\t})\n\t\t.strict(),\n\tz\n\t\t.object({\n\t\t\ttype: z.literal(\"contract_call\"),\n\t\t\tcontractId: contractIdField.optional(),\n\t\t\tfunctionName: z.string().optional(),\n\t\t\tcaller: z.string().optional(),\n\t\t\tabi: AbiContractSchema.optional(),\n\t\t\t...traitScope,\n\t\t\t...factoryScope,\n\t\t})\n\t\t.strict(),\n\tz\n\t\t.object({\n\t\t\ttype: z.literal(\"contract_deploy\"),\n\t\t\tdeployer: z.string().optional(),\n\t\t\tcontractName: z.string().optional(),\n\t\t})\n\t\t.strict(),\n\tz\n\t\t.object({\n\t\t\ttype: z.literal(\"print_event\"),\n\t\t\tcontractId: contractIdField.optional(),\n\t\t\ttopic: z.string().optional(),\n\t\t\tprints: z\n\t\t\t\t.record(z.string(), z.record(z.string(), PrintFieldSchema))\n\t\t\t\t.optional(),\n\t\t\t...traitScope,\n\t\t\t...factoryScope,\n\t\t})\n\t\t.strict(),\n]);\n\n/**\n * `trait` and `contractId` compose rather than conflict: the matcher ANDs\n * them, so the pair means \"contracts conforming to this trait, narrowed to\n * these ids\". (The Index READ API refuses the combination because its query\n * planner picks one index path — that's an API constraint, not a semantic\n * one, and subgraph sources are not bound by it.)\n */\nexport const SubgraphFilterSchema: z.ZodType<SubgraphFilter> =\n\tSubgraphFilterUnion as unknown as z.ZodType<SubgraphFilter>;\n\nexport const SubgraphDefinitionSchema: z.ZodType<SubgraphDefinition> = z.object(\n\t{\n\t\tname: SubgraphNameSchema,\n\t\tversion: z.string().optional(),\n\t\tdescription: z.string().optional(),\n\t\tstartBlock: z.number().int().nonnegative().optional(),\n\t\t// 'concurrent' = tip-first deploy: go live at tip immediately, fill\n\t\t// history via a background backfill. Only safe for order-tolerant\n\t\t// handlers (commutative or insert-only writes).\n\t\tbackfillMode: z.enum([\"blocking\", \"concurrent\"]).optional(),\n\t\tsources: z\n\t\t\t.record(z.string(), SubgraphFilterSchema)\n\t\t\t.refine(\n\t\t\t\t(s) => Object.keys(s).length > 0,\n\t\t\t\t\"Must have at least one source\",\n\t\t\t),\n\t\tschema: SubgraphSchemaSchema,\n\t\thandlers: z.record(z.string(), z.any()),\n\t},\n) as unknown as z.ZodType<SubgraphDefinition>;\n\n/**\n * Validates a subgraph definition, returning the parsed result or throwing on failure.\n */\nexport function validateSubgraphDefinition(def: unknown): SubgraphDefinition {\n\treturn SubgraphDefinitionSchema.parse(def);\n}\n\n/**\n * Per-source-type field vocabulary, DERIVED from\n * {@link SubgraphFilterSchema}. Agent-facing surfaces (the MCP filters\n * reference) used to hand-maintain a parallel copy of this list; deriving it\n * means adding a field to a filter can never leave the documentation behind.\n */\nexport function filterFieldsByType(): Array<{\n\ttype: string;\n\tfields: string[];\n}> {\n\t// Read the UNION directly (SubgraphFilterSchema wraps it in superRefine).\n\t// biome-ignore lint/suspicious/noExplicitAny: reading zod's internal option shapes\n\tconst options = (SubgraphFilterUnion as any)?._def?.options ?? [];\n\tconst out: Array<{ type: string; fields: string[] }> = [];\n\tfor (const option of options) {\n\t\t// `.superRefine()` wraps the union, so unwrap one level when present.\n\t\tconst shape = option?.shape ?? option?._def?.shape;\n\t\tif (!shape) continue;\n\t\tconst literal =\n\t\t\tshape.type?._def?.values?.[0] ?? shape.type?._def?.value ?? undefined;\n\t\tif (typeof literal !== \"string\") continue;\n\t\tout.push({\n\t\t\ttype: literal,\n\t\t\tfields: Object.keys(shape).filter((k) => k !== \"type\"),\n\t\t});\n\t}\n\treturn out;\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "E99182101593A8B264756E2164756E21",
7
+ "mappings": ";;;;AAAA;AASO,IAAM,qBAAwC,EACnD,OAAO,EACP,IAAI,CAAC,EACL,IAAI,EAAE,EACN,MACA,qBACA,mFACD;AAQM,IAAM,sBAAyC,EACpD,OAAO,EACP,IAAI,CAAC,EACL,IAAI,EAAE,EACN,MACA,uBACA,yGACD;AAEM,IAAM,mBAA0C,EAAE,KAAK;AAAA,EAC7D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAQM,IAAM,mBAAuC,EAAE,KAAK,MAC1D,EAAE,MAAM;AAAA,EACP;AAAA,EACA,EAAE,OAAO,EAAE,MAAM,kBAAkB,UAAU,EAAE,QAAQ,IAAI,EAAE,CAAC;AAAA,EAC9D,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,gBAAgB,EAAE,CAAC;AAAA,EAC1D,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AACpC,CAAC,CACF;AAMA,IAAM,gBAAoC,EAAE,KAAK,MAChD,EAAE,MAAM;AAAA,EACP,EAAE,OAAO;AAAA,EACT,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AAAA,EACnD,EAAE,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AAAA,EAC7D,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AAAA,EAC5D,EAAE,OAAO,EAAE,UAAU,cAAc,CAAC;AAAA,EACpC,EAAE,OAAO;AAAA,IACR,MAAM,EAAE,OAAO,EAAE,MAAM,eAAe,QAAQ,EAAE,OAAO,EAAE,CAAC;AAAA,EAC3D,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACR,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,cAAc,CAAC,CAAC;AAAA,EACnE,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACR,UAAU,EAAE,OAAO,EAAE,IAAI,eAAe,OAAO,cAAc,CAAC;AAAA,EAC/D,CAAC;AACF,CAAC,CACF;AAYO,IAAM,oBAAwC,EAAE,OAAO;AAAA,EAC7D,WAAW,EAAE,MACZ,EAAE,OAAO;AAAA,IACR,MAAM,EAAE,OAAO;AAAA,IACf,QAAQ,EAAE,KAAK,CAAC,UAAU,aAAa,SAAS,GAAG;AAAA,MAClD,SACC;AAAA,IACF,CAAC;AAAA,IACD,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,cAAc,CAAC,CAAC;AAAA,IAEjE,SAAS;AAAA,EACV,CAAC,CACF;AAAA,EACA,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACpC,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACzC,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EAC/C,qBAAqB,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACnD,oBAAoB,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EAClD,gBAAgB,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,SAAS;AAC/C,CAAC;AAEM,IAAM,uBAAkD,EAAE,OAAO;AAAA,EACvE,MAAM;AAAA,EACN,UAAU,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC/B,SAAS,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,QAAQ,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC7B,SAAS,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,SAAS;AAClE,CAAC;AAEM,IAAM,sBAAgD,EAAE,OAAO;AAAA,EACrE,SAAS,EACP,OAAO,qBAAqB,oBAAoB,EAChD,OACA,CAAC,MAAM,OAAO,KAAK,CAAC,EAAE,SAAS,GAC/B,qCACD;AAAA,EACD,SAAS,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC,EAAE,SAAS;AAAA,EACxD,YAAY,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC,EAAE,SAAS;AAAA,EAC3D,WAAW,EACT,MACA,EAAE,OAAO;AAAA,IACR,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,QAAQ,EAAE,MAAM,mBAAmB,EAAE,IAAI,CAAC;AAAA,IAC1C,mBAAmB,EAAE,MAAM,mBAAmB,EAAE,IAAI,CAAC;AAAA,EACtD,CAAC,CACF,EACC,SAAS;AACZ,CAAC;AAEM,IAAM,uBAAiE,EAC5E,OAAO,qBAAqB,mBAAmB,EAC/C,OACA,CAAC,MAAM,OAAO,KAAK,CAAC,EAAE,SAAS,GAC/B,qCACD;AAEM,IAAM,qBAAqB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAGA,IAAM,kBAAkB,EAAE,MAAM;AAAA,EAC/B,EAAE,OAAO;AAAA,EACT,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAClC,CAAC;AAGD,IAAM,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE;AAElD,IAAM,eAAe;AAAA,EACpB,SAAS,EACP,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,EAC5D,OAAO,EACP,SAAS;AACZ;AACA,IAAM,cAAc;AAAA,EACnB,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,WAAW,EAAE,OAAO,EAAE,SAAS;AAChC;AAWA,IAAM,sBAAsB,EAAE,mBAAmB,QAAQ;AAAA,EACxD,EACE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,cAAc;AAAA,IAC9B,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,OAC5B;AAAA,EACJ,CAAC,EACA,OAAO;AAAA,EACT,EACE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,UAAU;AAAA,IAC1B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,IAC/B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,CAAC,EACA,OAAO;AAAA,EACT,EACE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,UAAU;AAAA,IAC1B,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,CAAC,EACA,OAAO;AAAA,EACT,EACE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,UAAU;AAAA,IAC1B,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,IACnC,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,CAAC,EACA,OAAO;AAAA,EACT,EACE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,aAAa;AAAA,IAC7B,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,IACrC,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,IAC/B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,OAC5B;AAAA,EACJ,CAAC,EACA,OAAO;AAAA,EACT,EACE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,SAAS;AAAA,IACzB,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,IACrC,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,IAC/B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,OAC5B;AAAA,EACJ,CAAC,EACA,OAAO;AAAA,EACT,EACE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,SAAS;AAAA,IACzB,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,IACrC,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,OAC5B;AAAA,EACJ,CAAC,EACA,OAAO;AAAA,EACT,EACE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,cAAc;AAAA,IAC9B,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,IACrC,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,OAC5B;AAAA,EACJ,CAAC,EACA,OAAO;AAAA,EACT,EACE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,UAAU;AAAA,IAC1B,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,IACrC,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,OAC5B;AAAA,EACJ,CAAC,EACA,OAAO;AAAA,EACT,EACE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,UAAU;AAAA,IAC1B,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,IACrC,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,OACzB;AAAA,EACJ,CAAC,EACA,OAAO;AAAA,EACT,EACE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,eAAe;AAAA,IAC/B,YAAY,gBAAgB,SAAS;AAAA,IACrC,cAAc,EAAE,OAAO,EAAE,SAAS;AAAA,IAClC,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,KAAK,kBAAkB,SAAS;AAAA,OAC7B;AAAA,OACA;AAAA,EACJ,CAAC,EACA,OAAO;AAAA,EACT,EACE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,iBAAiB;AAAA,IACjC,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,IAC9B,cAAc,EAAE,OAAO,EAAE,SAAS;AAAA,EACnC,CAAC,EACA,OAAO;AAAA,EACT,EACE,OAAO;AAAA,IACP,MAAM,EAAE,QAAQ,aAAa;AAAA,IAC7B,YAAY,gBAAgB,SAAS;AAAA,IACrC,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC3B,QAAQ,EACN,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,EAAE,OAAO,GAAG,gBAAgB,CAAC,EACzD,SAAS;AAAA,OACR;AAAA,OACA;AAAA,EACJ,CAAC,EACA,OAAO;AACV,CAAC;AASM,IAAM,uBACZ;AAEM,IAAM,2BAA0D,EAAE,OACxE;AAAA,EACC,MAAM;AAAA,EACN,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAAA,EAIpD,cAAc,EAAE,KAAK,CAAC,YAAY,YAAY,CAAC,EAAE,SAAS;AAAA,EAC1D,SAAS,EACP,OAAO,EAAE,OAAO,GAAG,oBAAoB,EACvC,OACA,CAAC,MAAM,OAAO,KAAK,CAAC,EAAE,SAAS,GAC/B,+BACD;AAAA,EACD,QAAQ;AAAA,EACR,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,IAAI,CAAC;AACvC,CACD;AAKO,SAAS,0BAA0B,CAAC,KAAkC;AAAA,EAC5E,OAAO,yBAAyB,MAAM,GAAG;AAAA;AASnC,SAAS,kBAAkB,GAG/B;AAAA,EAGF,MAAM,UAAW,qBAA6B,MAAM,WAAW,CAAC;AAAA,EAChE,MAAM,MAAiD,CAAC;AAAA,EACxD,WAAW,UAAU,SAAS;AAAA,IAE7B,MAAM,QAAQ,QAAQ,SAAS,QAAQ,MAAM;AAAA,IAC7C,IAAI,CAAC;AAAA,MAAO;AAAA,IACZ,MAAM,UACL,MAAM,MAAM,MAAM,SAAS,MAAM,MAAM,MAAM,MAAM,SAAS;AAAA,IAC7D,IAAI,OAAO,YAAY;AAAA,MAAU;AAAA,IACjC,IAAI,KAAK;AAAA,MACR,MAAM;AAAA,MACN,QAAQ,OAAO,KAAK,KAAK,EAAE,OAAO,CAAC,MAAM,MAAM,MAAM;AAAA,IACtD,CAAC;AAAA,EACF;AAAA,EACA,OAAO;AAAA;",
8
+ "debugId": "BAF10EBE9E88C37664756E2164756E21",
9
9
  "names": []
10
10
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@secondlayer/subgraphs",
3
- "version": "3.21.0",
3
+ "version": "3.23.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -43,9 +43,15 @@
43
43
  "./runtime/emitter": {
44
44
  "types": "./dist/src/runtime/emitter.d.ts",
45
45
  "import": "./dist/src/runtime/emitter.js"
46
+ },
47
+ "./testing": {
48
+ "types": "./dist/src/testing/index.d.ts",
49
+ "import": "./dist/src/testing/index.js"
46
50
  }
47
51
  },
48
- "files": ["dist"],
52
+ "files": [
53
+ "dist"
54
+ ],
49
55
  "scripts": {
50
56
  "build": "bunup",
51
57
  "dev": "bunup --watch",
@@ -55,7 +61,7 @@
55
61
  },
56
62
  "dependencies": {
57
63
  "@secondlayer/shared": "^7.0.3",
58
- "@secondlayer/stacks": "^2.21.0",
64
+ "@secondlayer/stacks": "^2.22.0",
59
65
  "esbuild": "^0.27.4",
60
66
  "kysely": "0.28.17",
61
67
  "zod": "^4.3.6"