@secondlayer/cli 5.6.5 → 5.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,41 +1,48 @@
1
1
  # @secondlayer/cli
2
2
 
3
- The Secondlayer CLI — one binary for dedicated Stacks indexing, real-time
4
- subgraphs, and per-tenant hosting lifecycle.
3
+ The Secondlayer CLI — one binary for Stacks indexing, real-time subgraphs,
4
+ subscriptions, and Clarity code generation.
5
5
 
6
6
  ```bash
7
7
  bun add -g @secondlayer/cli
8
8
  sl --version
9
9
  ```
10
10
 
11
- ## Beta Quickstart
11
+ ## Auth
12
12
 
13
- Use this path for a first hosted demo. The CLI stores your login session,
14
- binds the current directory to a project, provisions a dedicated tenant, then
15
- deploys and queries a subgraph through short-lived tenant credentials.
13
+ Two ways to authenticate:
14
+
15
+ - **Interactive (`sl login`)** — magic-link email → 6-digit code → session
16
+ written to `~/.secondlayer/session.json`. Used for day-to-day CLI work.
17
+ - **Machine / CI** — set `SL_SERVICE_KEY` to an API key created in the platform
18
+ console at https://secondlayer.tools/platform/api-keys. Keys are prefixed
19
+ `sk-sl_`.
16
20
 
17
21
  ```bash
18
- bun add -g @secondlayer/cli
22
+ # interactive
23
+ sl login
24
+
25
+ # machine / CI
26
+ export SL_SERVICE_KEY=sk-sl_xxxxxxxx
27
+ ```
28
+
29
+ During open beta, reads are public (no key needed). Writes — deploying or
30
+ managing subgraphs and subscriptions — require a session or an `sk-sl_` key.
19
31
 
32
+ ## Quickstart
33
+
34
+ ```bash
35
+ bun add -g @secondlayer/cli
20
36
  sl login
21
37
  sl project create my-app
22
38
  sl project use my-app
23
- sl instance create --plan launch
24
39
 
40
+ # scaffold + deploy a subgraph from a deployed contract
25
41
  sl subgraphs scaffold SP1234ABCD.my-contract -o subgraphs/my-contract.ts
26
42
  sl subgraphs deploy subgraphs/my-contract.ts --start-block <recent-block>
27
43
  sl subgraphs query my-contract <table> --sort _block_height --order desc
28
- sl subgraphs spec my-contract --format openapi -o openapi.json
29
- ```
30
-
31
- `sl subgraphs scaffold` writes the definition file, creates or updates
32
- `package.json`, and runs `bun install` by default so the generated import is
33
- deployable immediately. Pass `--no-install` to skip the install and run
34
- `bun install` manually in the output directory.
35
-
36
- Then wire a receiver:
37
44
 
38
- ```bash
45
+ # wire a webhook receiver
39
46
  sl create subscription my-hook \
40
47
  --runtime node \
41
48
  --subgraph my-contract \
@@ -43,129 +50,65 @@ sl create subscription my-hook \
43
50
  --url https://<receiver-host>/webhook
44
51
  ```
45
52
 
46
- ## Command surface
47
-
48
- ### Auth (top-level)
49
-
50
- | Command | What it does |
51
- |---|---|
52
- | `sl login` | Magic-link email → 6-digit code → writes session to `~/.secondlayer/session.json` |
53
- | `sl logout` | Revokes the session and clears the local file |
54
- | `sl whoami` | Prints account, active project, instance URL, plan, status |
53
+ `sl subgraphs scaffold` writes the definition file, creates/updates
54
+ `package.json`, and runs `bun install` (pass `--no-install` to skip).
55
55
 
56
- ### Project
56
+ ## Commands
57
57
 
58
- Projects are the unit that binds a working directory to a dedicated instance.
59
- Binding is **per-directory** — `.secondlayer/project` in cwd takes precedence
60
- over the global default at `~/.secondlayer/config.json:defaultProject`. The
61
- walk-up stops at `.git` (never crosses repos).
58
+ ### Auth & project
62
59
 
63
60
  | Command | What it does |
64
61
  |---|---|
65
- | `sl project create [name]` | Scaffold a new project on the platform |
66
- | `sl project list` | List all projects for the account |
67
- | `sl project use <slug>` | Write `./.secondlayer/project` — binds cwd to that project |
68
- | `sl project current` | Prints the resolved slug + the file it was read from |
62
+ | `sl login` / `sl logout` | Start or revoke a session |
63
+ | `sl whoami` | Print account + active project |
64
+ | `sl project create [name]` | Create a project |
65
+ | `sl project list` | List projects |
66
+ | `sl project use <slug>` | Bind cwd to a project (writes `./.secondlayer/project`) |
67
+ | `sl project current` | Show resolved project + source file |
69
68
 
70
- ### Instance (dedicated hosting)
69
+ Project binding is per-directory: `.secondlayer/project` in cwd takes
70
+ precedence over `~/.secondlayer/config.json:defaultProject`. The walk-up stops
71
+ at `.git`.
71
72
 
72
- One instance per project. The platform API spawns a dedicated `sl-pg-{slug}`,
73
- `sl-api-{slug}`, and `sl-proc-{slug}` container set on the hosting side.
73
+ ### Subgraphs
74
74
 
75
75
  | Command | What it does |
76
76
  |---|---|
77
- | `sl instance create --plan <launch\|scale>` | Provision containers after trial/subscription activation. Boxed reveal of `serviceKey` + `anonKey` (shown once). |
78
- | `sl instance info` | Plan, status, resource usage |
79
- | `sl instance resize --plan <...>` | Recreate containers with new CPU/memory (~30s downtime) |
80
- | `sl instance suspend` / `resume` | Stop/start containers, volume preserved |
81
- | `sl instance keys rotate [--service\|--anon\|--both]` | Bump JWT gen, recreate API container, mint replacement key(s) |
82
- | `sl instance delete` | Typed-slug confirm, hard teardown |
83
- | `sl instance db` | Print `ssh -L` command + `DATABASE_URL` for tunneled Postgres access |
84
- | `sl instance db add-key <path>` | Upload an SSH pubkey to the bastion |
85
- | `sl instance db revoke-key` | Revoke your bastion access |
86
-
87
- ### Create (scaffolders)
88
-
89
- | Command | What it does |
90
- |---|---|
91
- | `sl create subscription <name> --runtime <inngest\|trigger\|cloudflare\|node> [--auth-token <token>] [--filter key=value]` | Scaffold a receiver project wired to a new subscription. Copies the runtime template into `./<name>/`, provisions through the active project/instance, supports scalar filters and bearer auth, and wires the signing secret so the dev server starts consuming events immediately. |
77
+ | `sl subgraphs new <name>` | Scaffold a definition file |
78
+ | `sl subgraphs scaffold <SP...::contract> [-o <path>] [--no-install]` | Generate a subgraph from a deployed contract |
79
+ | `sl subgraphs deploy <file> [--start-block <n>]` | Deploy; `--start-block` overrides the definition |
80
+ | `sl subgraphs dev <file>` | Watch + hot-redeploy |
81
+ | `sl subgraphs query <name> <table>` | Query a table with filters, sort, pagination |
82
+ | `sl subgraphs list` / `status <name>` / `gaps <name>` | Inspect deployments |
83
+ | `sl subgraphs spec <name> [--format openapi\|agent\|markdown]` | Export API docs for a deployed subgraph |
84
+ | `sl subgraphs inspect <file> [--format ...]` | Same docs from a local definition before deploy |
85
+ | `sl subgraphs deploy <file> --database-url <url>` | BYO: write the subgraph's rows to your own Postgres |
86
+ | `sl subgraphs codegen <file> --target prisma\|drizzle [-o <path>]` | Generate an ORM schema for the subgraph's tables (BYO DB) |
87
+ | `sl subgraphs client <name> -o <path>` | Generate a typed query client for a deployed subgraph (was `generate`) |
88
+ | `sl subgraphs reindex/backfill/stop/delete <name>` | Manage processing |
92
89
 
93
- ### Subscriptions (tenant-scoped)
90
+ ### Subscriptions
94
91
 
95
- `sl create subscription` is the receiver scaffolder. `sl subscriptions ...` is
96
- the operational surface for existing subscriptions. All commands resolve the
97
- active project/instance the same way as `sl subgraphs ...`; `SL_API_URL` and
98
- `SL_SERVICE_KEY` still bypass platform resolution for OSS or CI.
92
+ `sl create subscription` scaffolds a receiver project. `sl subscriptions ...`
93
+ manages existing ones.
99
94
 
100
95
  | Command | What it does |
101
96
  |---|---|
102
- | `sl subscriptions list` | List subscriptions with status, target table, format, and last success |
103
- | `sl subscriptions get <id\|name>` | Show full config, filter, retry/circuit state |
104
- | `sl subscriptions update <id\|name> --url <url> [--auth-token <token>] [--filter key.gte=value]` | Patch URL, bearer auth, filter, format, runtime, retry, timeout, concurrency |
97
+ | `sl create subscription <name> --runtime <inngest\|trigger\|cloudflare\|node> [--auth-token <token>] [--filter key=value]` | Scaffold a receiver wired to a new subscription |
98
+ | `sl subscriptions list` / `get <id\|name>` | List or show config + delivery state |
99
+ | `sl subscriptions update <id\|name> --url <url> [--filter key.gte=value]` | Patch URL, filter, format, retry, etc. |
105
100
  | `sl subscriptions pause/resume <id\|name>` | Stop or restart delivery |
106
- | `sl subscriptions rotate-secret <id\|name>` | Rotate signing secret and print the new value once |
107
- | `sl subscriptions deliveries <id\|name>` | Last 100 delivery attempts |
108
- | `sl subscriptions dead <id\|name>` | Dead-letter rows |
101
+ | `sl subscriptions rotate-secret <id\|name>` | Rotate signing secret (printed once) |
102
+ | `sl subscriptions deliveries/dead <id\|name>` | Recent attempts / dead-letter rows |
109
103
  | `sl subscriptions requeue <id\|name> <outboxId>` | Requeue one dead-letter row |
110
- | `sl subscriptions replay <id\|name> --from-block <n> --to-block <n>` | Enqueue historical rows from a block range |
111
- | `sl subscriptions doctor <id\|name>` | Config, circuit state, recent delivery health, linked subgraph gaps, next-step hints |
112
- | `sl subscriptions test <id\|name> --signing-secret <secret> [--post]` | Build a signed Standard Webhooks fixture from the latest row or a synthetic row |
104
+ | `sl subscriptions replay <id\|name> --from-block <n> --to-block <n>` | Enqueue a historical block range |
105
+ | `sl subscriptions doctor/test <id\|name>` | Health check / signed fixture |
113
106
 
114
107
  Read/action commands support `--json`. Destructive commands prompt unless
115
- `--yes` is passed. CLI filters are schema-aware: unknown tables, unknown
116
- columns, unsupported operators, and non-scalar columns are rejected before the
117
- API call; the server repeats the same validation as the source of truth.
108
+ `--yes`. Filters are schema-aware: unknown tables/columns, bad operators, and
109
+ non-scalar columns are rejected before the API call.
118
110
 
119
- ### Subgraphs (tenant-scoped)
120
-
121
- All tenant-scoped commands auto-mint a 5-minute ephemeral service JWT per
122
- invocation. No long-lived key on disk.
123
-
124
- | Command | What it does |
125
- |---|---|
126
- | `sl subgraphs new <name>` | Scaffold a subgraph definition file |
127
- | `sl subgraphs deploy <file> [--start-block <n>]` | Deploy to the active instance; `--start-block` overrides the definition start block for that deploy |
128
- | `sl subgraphs dev <file>` | Watch + hot-redeploy |
129
- | `sl subgraphs list` | List deployed subgraphs |
130
- | `sl subgraphs status <name>` | Indexing progress, row counts, gaps |
131
- | `sl subgraphs query <name> <table>` | Query a subgraph table with filters, sort, pagination |
132
- | `sl subgraphs spec <name> [--format openapi\|agent\|markdown] [-o <path>] [--server <url>]` | Export generated API docs for a deployed subgraph |
133
- | `sl subgraphs inspect <file> [--format openapi\|agent\|markdown] [-o <path>] [--server <url>]` | Generate API docs from a local `defineSubgraph()` file before deploy |
134
- | `sl subgraphs reindex <name>` | Drop + re-process from the tip backwards |
135
- | `sl subgraphs backfill <name>` | Fill a specific block range |
136
- | `sl subgraphs stop <name>` | Pause processing |
137
- | `sl subgraphs gaps <name>` | List missing block ranges |
138
- | `sl subgraphs delete <name>` | Drop the subgraph + its schema |
139
- | `sl subgraphs scaffold <SP...::contract> [-o <path>] [--no-install]` | Generate a starter subgraph from a deployed contract, write/amend `package.json`, and install dependencies unless skipped |
140
- | `sl subgraphs generate <name>` | Regenerate TS types for an existing subgraph |
141
-
142
- #### Subgraph API specs
143
-
144
- Use `spec` when the subgraph is already deployed to the active project
145
- instance. Use `inspect` when you want the same documentation contract from a
146
- local TypeScript definition before deploy.
147
-
148
- ```bash
149
- # Deployed subgraph docs from the active project instance
150
- sl subgraphs spec token-transfers --format openapi -o openapi.json
151
- sl subgraphs spec token-transfers --format agent
152
- sl subgraphs spec token-transfers --format markdown -o API.md
153
-
154
- # Local pre-deploy docs from a defineSubgraph() file
155
- sl subgraphs inspect subgraphs/token-transfers.ts --format agent
156
- sl subgraphs inspect subgraphs/token-transfers.ts --format openapi \
157
- --server https://<your-slug>.secondlayer.tools
158
- ```
159
-
160
- Formats:
161
-
162
- | Format | Use |
163
- |---|---|
164
- | `openapi` | OpenAPI 3.1 JSON for docs tooling, client generators, and API catalogs |
165
- | `agent` | Compact JSON schema for agents that need table, column, filter, and endpoint context |
166
- | `markdown` | Human-readable API reference for docs pages or repository docs |
167
-
168
- ### Local dev + OSS
111
+ ### Local dev & OSS
169
112
 
170
113
  | Command | What it does |
171
114
  |---|---|
@@ -178,10 +121,9 @@ Formats:
178
121
 
179
122
  | Command | What it does |
180
123
  |---|---|
181
- | `sl generate [files...]` (aliases: `gen`, `codegen`) | Generate TS interfaces from Clarity contracts |
124
+ | `sl generate [files...]` (alias `gen`) | Generate TS interfaces from Clarity contracts |
182
125
  | `sl init` | Scaffold `secondlayer.config.ts` |
183
- | `sl doctor` | Session + project + instance reachability check |
184
- | `sl status` | Platform/instance health |
126
+ | `sl doctor` / `sl status` | Reachability + health checks |
185
127
  | `sl account profile` | Update display name / bio / slug |
186
128
  | `sl config show/set/reset/clear` | Inspect or reset local config |
187
129
 
@@ -189,46 +131,29 @@ Formats:
189
131
 
190
132
  | Var | Purpose |
191
133
  |---|---|
192
- | `SL_API_URL` | Bypass platform resolution — point at an OSS or internal API directly |
193
- | `SL_SERVICE_KEY` | Service key when using env-var bypass |
134
+ | `SL_SERVICE_KEY` | An `sk-sl_` API key (or session token) for machine/CI use; bypasses platform resolution. `SECONDLAYER_API_KEY` is a deprecated alias |
135
+ | `SL_API_URL` | Point at an OSS or internal API directly, bypassing the platform |
194
136
  | `SL_PLATFORM_API_URL` | Override the platform API base (default `https://api.secondlayer.tools`) |
195
- | `STACKS_NETWORK` | Override via `--network <local\|testnet\|mainnet>` |
137
+ | `STACKS_NETWORK` | Default network (also via `--network <local\|testnet\|mainnet>`) |
196
138
  | `HIRO_API_KEY` | Used by `sl generate` for remote contract fetches |
197
139
 
198
- ## Error codes
199
-
200
- Every tenant-scoped failure surfaces a typed code and an action hint:
201
-
202
- | Code | CLI hint |
203
- |---|---|
204
- | `SESSION_EXPIRED` | `Session expired. Run: sl login` |
205
- | `TENANT_SUSPENDED` | `Instance is suspended. Run: sl instance resume` |
206
- | `NO_ACTIVE_PROJECT` | `No project selected. Run: sl project use <slug>` |
207
- | `NO_TENANT_FOR_PROJECT` | `Project has no instance. Run: sl instance create --plan launch` |
208
- | `KEY_ROTATED` | Handled transparently — `http.ts` re-mints and retries once |
209
-
210
140
  ## Code generation (`sl generate`)
211
141
 
212
- Generate type-safe interfaces, functions, and optional React hooks from
213
- Clarity contracts — works against local `.clar` files, deployed contracts
214
- (network inferred from address prefix), or glob patterns.
142
+ Generate type-safe interfaces, functions, and optional React hooks from Clarity
143
+ contracts — local `.clar` files, deployed contracts (network inferred from
144
+ address prefix), or globs.
215
145
 
216
146
  ```bash
217
- # Local .clar files
218
147
  sl generate ./contracts/token.clar -o ./src/generated.ts
219
-
220
- # Deployed contracts (SP/SM → mainnet, ST/SN → testnet)
221
148
  sl generate SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.alex-vault -o ./src/generated.ts
222
-
223
- # Glob
224
149
  sl generate "./contracts/*.clar" -o ./src/generated.ts
225
150
  ```
226
151
 
227
- Config-driven mode:
152
+ Config-driven:
228
153
 
229
154
  ```bash
230
- sl init # creates secondlayer.config.ts
231
- sl generate # regenerates from the config
155
+ sl init # creates secondlayer.config.ts
156
+ sl generate # regenerates from the config
232
157
  ```
233
158
 
234
159
  ```typescript
@@ -242,20 +167,15 @@ export default defineConfig({
242
167
  })
243
168
  ```
244
169
 
245
- ### Plugins
246
-
247
170
  | Plugin | What it adds |
248
171
  |---|---|
249
172
  | `clarinet()` | Parse local Clarinet project |
250
- | `actions()` | `read.*` + `write.*` helpers on each contract |
251
- | `react()` | Typed React Query hooks (`useTokenTransfer`, `useTokenBalance`, etc.) |
173
+ | `actions()` | `read.*` + `write.*` helpers per contract |
174
+ | `react()` | Typed React Query hooks |
252
175
  | `testing()` | Clarinet SDK test helpers |
253
176
 
254
- ### Usage examples
255
-
256
177
  ```typescript
257
178
  import { token } from "./generated/contracts"
258
- import { makeContractCall, fetchCallReadOnlyFunction } from "@stacks/transactions"
259
179
 
260
180
  // Works with @stacks/transactions directly:
261
181
  await makeContractCall({
@@ -263,26 +183,15 @@ await makeContractCall({
263
183
  network: "mainnet",
264
184
  })
265
185
 
266
- // With actions() plugin — read/write helpers:
186
+ // With actions() — read/write helpers + maps/vars/constants:
267
187
  const balance = await token.read.getBalance({ account: "SP..." })
268
188
  await token.write.transfer({ amount: 100n, recipient: "SP..." })
269
-
270
- // Maps / vars / constants:
271
189
  const supply = await token.vars.totalSupply.get()
272
- const bal = await token.maps.balances.get("SP...")
273
- const max = await token.constants.maxSupply.get()
274
190
  ```
275
191
 
276
- ```typescript
277
- // With react() plugin:
278
- import { useTokenTransfer, useTokenBalance } from "./generated/hooks"
279
-
280
- function App() {
281
- const { transfer, isRequestPending } = useTokenTransfer()
282
- const { data: balance } = useTokenBalance("SP...")
283
- // ...
284
- }
285
- ```
192
+ ## Docs
193
+
194
+ Full reference: https://secondlayer.tools/docs
286
195
 
287
196
  ## License
288
197
 
package/dist/cli.js CHANGED
@@ -32321,7 +32321,7 @@ var {
32321
32321
  // package.json
32322
32322
  var package_default = {
32323
32323
  name: "@secondlayer/cli",
32324
- version: "5.6.5",
32324
+ version: "5.7.0",
32325
32325
  repository: {
32326
32326
  type: "git",
32327
32327
  url: "git+https://github.com/ryanwaits/secondlayer.git",
@@ -32371,9 +32371,9 @@ var package_default = {
32371
32371
  "@inquirer/prompts": "^8.2.0",
32372
32372
  "@secondlayer/bundler": "^0.3.7",
32373
32373
  "@secondlayer/sdk": "^5.0.0",
32374
- "@secondlayer/shared": "^6.4.5",
32375
- "@secondlayer/stacks": "^2.2.1",
32376
- "@secondlayer/subgraphs": "^3.2.1",
32374
+ "@secondlayer/shared": "^6.9.0",
32375
+ "@secondlayer/stacks": "^2.3.0",
32376
+ "@secondlayer/subgraphs": "^3.3.0",
32377
32377
  "@biomejs/js-api": "^0.7.0",
32378
32378
  "@biomejs/wasm-nodejs": "^1.9.0",
32379
32379
  esbuild: "^0.19.0",
@@ -32591,17 +32591,20 @@ function registerBillingCommand(program2) {
32591
32591
  }
32592
32592
  throw err;
32593
32593
  }
32594
+ if (!res.subscription) {
32595
+ console.log(formatKeyValue([
32596
+ ["Plan", "Free during open beta"],
32597
+ ["Cost", dim("$0 — no limits, no charges")],
32598
+ ["Paid plans", dim("coming after beta")]
32599
+ ]));
32600
+ return;
32601
+ }
32594
32602
  const rows = [];
32595
32603
  rows.push(["Plan", res.plan]);
32596
32604
  rows.push([
32597
32605
  "Customer",
32598
32606
  res.stripeCustomerId ?? dim("(none — no subscription yet)")
32599
32607
  ]);
32600
- if (!res.subscription) {
32601
- rows.push(["Subscription", dim("(none)")]);
32602
- console.log(formatKeyValue(rows));
32603
- return;
32604
- }
32605
32608
  const sub = res.subscription;
32606
32609
  rows.push(["Subscription", `${sub.id} (${sub.status})`]);
32607
32610
  if (sub.tier)
@@ -35472,7 +35475,7 @@ Stopped watching.`);
35472
35475
  });
35473
35476
  await new Promise(() => {});
35474
35477
  });
35475
- subgraphs.command("deploy <file>").description("Deploy a subgraph definition file").option("--start-block <n>", "Override the subgraph definition startBlock for this deploy").option("--dry-run", "Validate and preview deploy without writing changes").option("--preview", "Alias for --dry-run").option("--force", "Skip confirmation prompt for reindex operations").option("--strict", "Run `tsc --noEmit` against the handler before deploy (slower; catches TS type errors)").action(async (file, options2) => {
35478
+ subgraphs.command("deploy <file>").description("Deploy a subgraph definition file").option("--start-block <n>", "Override the subgraph definition startBlock for this deploy").option("--dry-run", "Validate and preview deploy without writing changes").option("--preview", "Alias for --dry-run").option("--force", "Skip confirmation prompt for reindex operations").option("--database-url <url>", "BYO data plane: write the subgraph's schema/rows to your own Postgres. With --dry-run, prints the DDL + grant script and verifies the connection.").option("--strict", "Run `tsc --noEmit` against the handler before deploy (slower; catches TS type errors)").action(async (file, options2) => {
35476
35479
  try {
35477
35480
  const absPath = resolve2(file);
35478
35481
  const config = await loadConfig();
@@ -35515,6 +35518,9 @@ Stopped watching.`);
35515
35518
  return;
35516
35519
  }
35517
35520
  const deployStartBlock = startBlock ?? effectiveDef.startBlock;
35521
+ if (options2.databaseUrl) {
35522
+ info("BYO data plane: schema + rows will live in your database. The server verifies the connection before deploying.");
35523
+ }
35518
35524
  const result = await deploySubgraphApi({
35519
35525
  name: effectiveDef.name,
35520
35526
  version: undefined,
@@ -35523,7 +35529,8 @@ Stopped watching.`);
35523
35529
  schema: effectiveDef.schema,
35524
35530
  handlerCode,
35525
35531
  sourceCode: source,
35526
- ...deployStartBlock !== undefined ? { startBlock: deployStartBlock } : {}
35532
+ ...deployStartBlock !== undefined ? { startBlock: deployStartBlock } : {},
35533
+ ...options2.databaseUrl ? { databaseUrl: options2.databaseUrl } : {}
35527
35534
  });
35528
35535
  const printDeployFooter = async () => {
35529
35536
  try {
@@ -35769,6 +35776,48 @@ Synced — exiting watch.`));
35769
35776
  process.exit(1);
35770
35777
  }
35771
35778
  });
35779
+ subgraphs.command("codegen <file>").description("Generate an ORM schema (Prisma or Drizzle) for a subgraph's tables — point it at your BYO database").option("--target <orm>", "ORM target: prisma | drizzle", "prisma").option("--schema <name>", "Postgres schema name (defaults to subgraph_<name>)").option("--env <var>", "datasource url env var", "DATABASE_URL").option("--models-only", "Emit only Prisma models (compose via prismaSchemaFolder)").option("-o, --output <path>", "Write to a file (defaults to stdout)").action(async (file, options2) => {
35780
+ try {
35781
+ const target = options2.target ?? "prisma";
35782
+ if (target !== "prisma" && target !== "drizzle") {
35783
+ error(`Unsupported --target "${target}" (supported: prisma, drizzle). For Kysely, run kysely-codegen against your database.`);
35784
+ process.exit(1);
35785
+ }
35786
+ const absPath = resolve2(file);
35787
+ if (!existsSync2(absPath)) {
35788
+ error(`File not found: ${absPath}`);
35789
+ process.exit(1);
35790
+ }
35791
+ const { readFile: readFile3 } = await import("node:fs/promises");
35792
+ const { bundleSubgraphCode } = await import("@secondlayer/bundler");
35793
+ const { generatePrismaSchema, generateDrizzleSchema } = await import("@secondlayer/subgraphs");
35794
+ const source = await readFile3(absPath, "utf8");
35795
+ const bundled = await bundleSubgraphCode(source);
35796
+ const def = {
35797
+ name: bundled.name,
35798
+ version: bundled.version,
35799
+ description: bundled.description,
35800
+ sources: bundled.sources,
35801
+ schema: bundled.schema,
35802
+ handlers: {}
35803
+ };
35804
+ const out = target === "drizzle" ? generateDrizzleSchema(def, { schemaName: options2.schema }) : generatePrismaSchema(def, {
35805
+ schemaName: options2.schema,
35806
+ datasourceEnv: options2.env,
35807
+ modelsOnly: options2.modelsOnly
35808
+ });
35809
+ if (options2.output) {
35810
+ await writeTextFile(resolve2(options2.output), out);
35811
+ success(`Wrote ${target} schema to ${options2.output}`);
35812
+ info("Next: point its datasource at your BYO database, then `prisma generate`.");
35813
+ } else {
35814
+ process.stdout.write(out);
35815
+ }
35816
+ } catch (err) {
35817
+ error(`Failed to generate schema: ${err}`);
35818
+ process.exit(1);
35819
+ }
35820
+ });
35772
35821
  subgraphs.command("reindex <name>").description("Reindex a subgraph from historical blocks (drops + reprocesses)").option("--from <block>", "Start block height").option("--to <block>", "End block height").option("-y, --yes", "Skip confirmation").action(async (name, options2) => {
35773
35822
  try {
35774
35823
  const fromBlock = options2.from ? Number.parseInt(options2.from, 10) : undefined;
@@ -36004,7 +36053,7 @@ ${rows.length} row(s)`));
36004
36053
  process.exit(1);
36005
36054
  }
36006
36055
  });
36007
- subgraphs.command("generate <subgraphName>").description("Generate a typed client for a deployed subgraph").option("-o, --output <path>", "Output file path (required)").action(async (subgraphName, options2) => {
36056
+ subgraphs.command("client <subgraphName>").alias("generate").description("Generate a typed query client for a deployed subgraph").option("-o, --output <path>", "Output file path (required)").action(async (subgraphName, options2) => {
36008
36057
  try {
36009
36058
  if (!options2.output) {
36010
36059
  error("--output <path> is required");
@@ -37200,7 +37249,7 @@ Quickstart:
37200
37249
  $ sl subgraphs deploy subgraphs/my-watcher.ts
37201
37250
  $ sl subgraphs status my-watcher
37202
37251
  `);
37203
- program.command("generate [files...]").aliases(["gen", "codegen"]).description("Generate TypeScript interfaces from Clarity contracts").option("-c, --config <path>", "Path to config file").option("-o, --out <path>", "Output file path (required when using direct files)").option("-k, --api-key <key>", "Stacks node API key for direct RPC URLs").option("-w, --watch", "Watch for changes").action(async (files, options3) => {
37252
+ program.command("generate [files...]").aliases(["gen"]).description("Generate TypeScript interfaces from Clarity contracts").option("-c, --config <path>", "Path to config file").option("-o, --out <path>", "Output file path (required when using direct files)").option("-k, --api-key <key>", "Stacks node API key for direct RPC URLs").option("-w, --watch", "Watch for changes").action(async (files, options3) => {
37204
37253
  const { generate: generate2 } = await Promise.resolve().then(() => (init_generate(), exports_generate));
37205
37254
  await generate2(files, options3);
37206
37255
  });
@@ -37226,5 +37275,5 @@ registerAccountCommand(program);
37226
37275
  registerBillingCommand(program);
37227
37276
  program.parse();
37228
37277
 
37229
- //# debugId=181F89519FDA8D4E64756E2164756E21
37278
+ //# debugId=74377287407FCAB564756E2164756E21
37230
37279
  //# sourceMappingURL=cli.js.map