@secondlayer/cli 9.4.1 → 9.5.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/cli.js CHANGED
@@ -28687,6 +28687,40 @@ var init_filter_params = __esm(() => {
28687
28687
  ALL_OPERATOR_LABELS = [...FILTER_OPERATORS, ...QUERY_ONLY_OPERATORS].join(", ");
28688
28688
  });
28689
28689
 
28690
+ // src/lib/git-status.ts
28691
+ import { execFileSync } from "node:child_process";
28692
+ import { dirname as dirname3 } from "node:path";
28693
+ function runGit(args, cwd) {
28694
+ try {
28695
+ return execFileSync("git", args, {
28696
+ cwd,
28697
+ stdio: ["ignore", "pipe", "ignore"]
28698
+ }).toString().trim();
28699
+ } catch {
28700
+ return null;
28701
+ }
28702
+ }
28703
+ function inspectSourceGitState(absPath) {
28704
+ const cwd = dirname3(absPath);
28705
+ const insideWorkTree = runGit(["rev-parse", "--is-inside-work-tree"], cwd);
28706
+ if (insideWorkTree !== "true") {
28707
+ return { kind: "not-a-repo" };
28708
+ }
28709
+ const tracked = runGit(["ls-files", "--error-unmatch", absPath], cwd);
28710
+ if (tracked === null) {
28711
+ return { kind: "untracked" };
28712
+ }
28713
+ const status = runGit(["status", "--porcelain", "--", absPath], cwd);
28714
+ if (status === null) {
28715
+ return { kind: "not-a-repo" };
28716
+ }
28717
+ if (status.length > 0) {
28718
+ return { kind: "modified" };
28719
+ }
28720
+ return { kind: "clean" };
28721
+ }
28722
+ var init_git_status = () => {};
28723
+
28690
28724
  // src/commands/login.ts
28691
28725
  import { confirm as confirm2, input } from "@inquirer/prompts";
28692
28726
  function sessionExpiry() {
@@ -29274,7 +29308,7 @@ __export(exports_subgraph_test, {
29274
29308
  });
29275
29309
  import { createHash } from "node:crypto";
29276
29310
  import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
29277
- import { dirname as dirname3, resolve as resolve2 } from "node:path";
29311
+ import { dirname as dirname4, resolve as resolve2 } from "node:path";
29278
29312
  import { Index } from "@secondlayer/sdk";
29279
29313
  import {
29280
29314
  DECODED_EVENT_TYPES
@@ -29400,7 +29434,7 @@ async function runSubgraphTest(file, options3) {
29400
29434
  events
29401
29435
  };
29402
29436
  const path11 = cassettePath(bundled.name);
29403
- mkdirSync(dirname3(path11), { recursive: true });
29437
+ mkdirSync(dirname4(path11), { recursive: true });
29404
29438
  writeFileSync2(path11, `${JSON.stringify(cassette, (_k, v2) => typeof v2 === "bigint" ? `${v2}n` : v2, 2)}
29405
29439
  `);
29406
29440
  info(`Recorded cassette → ${path11}`);
@@ -29510,7 +29544,7 @@ import {
29510
29544
  watch,
29511
29545
  writeFileSync as writeFileSync3
29512
29546
  } from "node:fs";
29513
- import { basename, dirname as dirname4, extname, join as join4, resolve as resolve3 } from "node:path";
29547
+ import { basename, dirname as dirname5, extname, join as join4, resolve as resolve3 } from "node:path";
29514
29548
  import { fileURLToPath as fileURLToPath3 } from "node:url";
29515
29549
  import { confirm as confirm3 } from "@inquirer/prompts";
29516
29550
  import {
@@ -29645,7 +29679,7 @@ async function runPayloadsCodegen(file, output2) {
29645
29679
  process.exit(1);
29646
29680
  }
29647
29681
  const out = generatePrintPayloadTypes({ sources });
29648
- const outPath = resolve3(output2 ?? join4(dirname4(absPath), `${basename(absPath, extname(absPath))}.payloads.d.ts`));
29682
+ const outPath = resolve3(output2 ?? join4(dirname5(absPath), `${basename(absPath, extname(absPath))}.payloads.d.ts`));
29649
29683
  await writeTextFile(outPath, out);
29650
29684
  success(`Wrote print payload types to ${outPath}`);
29651
29685
  }
@@ -29764,7 +29798,7 @@ function createLocalSubgraphDetail(input2) {
29764
29798
  };
29765
29799
  }
29766
29800
  function readCliSubgraphsDependency() {
29767
- const here = dirname4(fileURLToPath3(import.meta.url));
29801
+ const here = dirname5(fileURLToPath3(import.meta.url));
29768
29802
  const candidates = [
29769
29803
  resolve3(here, "..", "..", "package.json"),
29770
29804
  resolve3(here, "..", "package.json")
@@ -30070,9 +30104,33 @@ Stopped watching.`);
30070
30104
  });
30071
30105
  await new Promise(() => {});
30072
30106
  });
30073
- subgraphs.command("deploy <file>").alias("update").description("Deploy a subgraph definition file (alias: update — deploy is create-or-update)").option("--start-block <n>", "Override the subgraph definition startBlock for this deploy").option("--tip-first", "Go live at chain tip immediately; history backfills in the background (requires order-tolerant handlers — commutative or insert-only writes)").option("--dry-run", "Validate and preview deploy without writing changes").option("-y, --yes", "Skip the reindex confirmation prompt").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)").option("--visibility <visibility>", "Read visibility: public (anon /v1 reads, global name claim) or private (your key only). Defaults: managed → public, BYO → private.").action(async (file, options3) => {
30107
+ subgraphs.command("deploy <file>").alias("update").description("Deploy a subgraph definition file (alias: update — deploy is create-or-update)").option("--start-block <n>", "Override the subgraph definition startBlock for this deploy").option("--tip-first", "Go live at chain tip immediately; history backfills in the background (requires order-tolerant handlers — commutative or insert-only writes)").option("--dry-run", "Validate and preview deploy without writing changes").option("-y, --yes", "Skip the reindex confirmation prompt").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)").option("--visibility <visibility>", "Read visibility: public (anon /v1 reads, global name claim) or private (your key only). Defaults: managed → public, BYO → private.").option("--allow-uncommitted", "Deploy even though the source file is not committed to git (the deployed definition will exist only in the database)").action(async (file, options3) => {
30074
30108
  try {
30075
30109
  const absPath = resolve3(file);
30110
+ if (!options3.dryRun) {
30111
+ if (options3.allowUncommitted) {
30112
+ info("--allow-uncommitted: skipping the git commit check for the source file.");
30113
+ } else {
30114
+ const gitState = inspectSourceGitState(absPath);
30115
+ if (gitState.kind === "untracked" || gitState.kind === "modified") {
30116
+ const reason = gitState.kind === "untracked" ? "not tracked by git" : "modified with uncommitted changes";
30117
+ const message = `${file} is ${reason}. If you deploy it, the only copy of this definition will be a row in the database — this has already caused two production recoveries.`;
30118
+ if (process.stdout.isTTY) {
30119
+ warn(message);
30120
+ const confirmed = await confirm3({
30121
+ message: "Deploy anyway?"
30122
+ });
30123
+ if (!confirmed) {
30124
+ info("Aborted.");
30125
+ process.exit(0);
30126
+ }
30127
+ } else {
30128
+ error(`${message} Commit it, or pass --allow-uncommitted.`);
30129
+ process.exit(1);
30130
+ }
30131
+ }
30132
+ }
30133
+ }
30076
30134
  const config = await loadConfig2();
30077
30135
  if (config.network !== "local") {
30078
30136
  await requireAuth();
@@ -30793,6 +30851,7 @@ var init_subgraphs2 = __esm(() => {
30793
30851
  init_config2();
30794
30852
  init_filter_params();
30795
30853
  init_fs();
30854
+ init_git_status();
30796
30855
  init_output();
30797
30856
  init_require_auth();
30798
30857
  init_resolve_auth();
@@ -33560,10 +33619,10 @@ var init_manager = __esm(() => {
33560
33619
  });
33561
33620
 
33562
33621
  // src/services/indexer.ts
33563
- import { dirname as dirname9, resolve as resolve6 } from "node:path";
33622
+ import { dirname as dirname10, resolve as resolve6 } from "node:path";
33564
33623
  async function startIndexer(options3) {
33565
33624
  const port = options3.port ?? 3700;
33566
- const rootDir = dirname9(dirname9(dirname9(dirname9(import.meta.dir))));
33625
+ const rootDir = dirname10(dirname10(dirname10(dirname10(import.meta.dir))));
33567
33626
  const indexerPath = resolve6(rootDir, "packages/indexer/src/index.ts");
33568
33627
  await serviceManager.start(SERVICE_NAME, ["bun", "run", "--watch", indexerPath], {
33569
33628
  port,
@@ -33580,9 +33639,9 @@ var init_indexer = __esm(() => {
33580
33639
  });
33581
33640
 
33582
33641
  // src/services/worker.ts
33583
- import { dirname as dirname10, resolve as resolve7 } from "node:path";
33642
+ import { dirname as dirname11, resolve as resolve7 } from "node:path";
33584
33643
  async function startWorker(options3) {
33585
- const rootDir = dirname10(dirname10(dirname10(dirname10(import.meta.dir))));
33644
+ const rootDir = dirname11(dirname11(dirname11(dirname11(import.meta.dir))));
33586
33645
  const workerPath = resolve7(rootDir, "packages/worker/src/index.ts");
33587
33646
  await serviceManager.start(SERVICE_NAME2, ["bun", "run", "--watch", workerPath], {
33588
33647
  onStdout: options3.onLog,
@@ -33595,10 +33654,10 @@ var init_worker = __esm(() => {
33595
33654
  });
33596
33655
 
33597
33656
  // src/services/api.ts
33598
- import { dirname as dirname11, resolve as resolve8 } from "node:path";
33657
+ import { dirname as dirname12, resolve as resolve8 } from "node:path";
33599
33658
  async function startApi(options3) {
33600
33659
  const port = options3.port ?? 3800;
33601
- const rootDir = dirname11(dirname11(dirname11(dirname11(import.meta.dir))));
33660
+ const rootDir = dirname12(dirname12(dirname12(dirname12(import.meta.dir))));
33602
33661
  const apiPath = resolve8(rootDir, "packages/api/src/index.ts");
33603
33662
  await serviceManager.start(SERVICE_NAME3, ["bun", "run", "--watch", apiPath], {
33604
33663
  port,
@@ -33615,9 +33674,9 @@ var init_api2 = __esm(() => {
33615
33674
  });
33616
33675
 
33617
33676
  // src/services/subgraph-processor.ts
33618
- import { dirname as dirname12, resolve as resolve9 } from "node:path";
33677
+ import { dirname as dirname13, resolve as resolve9 } from "node:path";
33619
33678
  async function startSubgraphProcessor(options3) {
33620
- const rootDir = dirname12(dirname12(dirname12(dirname12(import.meta.dir))));
33679
+ const rootDir = dirname13(dirname13(dirname13(dirname13(import.meta.dir))));
33621
33680
  const servicePath = resolve9(rootDir, "packages/subgraphs/src/service.ts");
33622
33681
  await serviceManager.start(SERVICE_NAME4, ["bun", "run", "--watch", servicePath], {
33623
33682
  env: {
@@ -33653,7 +33712,7 @@ __export(exports_dev_impl, {
33653
33712
  isDevAlreadyRunning: () => isDevAlreadyRunning
33654
33713
  });
33655
33714
  import { mkdirSync as mkdirSync5 } from "node:fs";
33656
- import { dirname as dirname13, join as join11, resolve as resolve10 } from "node:path";
33715
+ import { dirname as dirname14, join as join11, resolve as resolve10 } from "node:path";
33657
33716
  async function isDevAlreadyRunning() {
33658
33717
  if (await isDevRunning()) {
33659
33718
  const running = await getRunningServices();
@@ -33731,7 +33790,7 @@ async function runBackground(options3) {
33731
33790
  startedAt: new Date().toISOString()
33732
33791
  };
33733
33792
  try {
33734
- const packagesDir = dirname13(dirname13(dirname13(dirname13(import.meta.dir))));
33793
+ const packagesDir = dirname14(dirname14(dirname14(dirname14(import.meta.dir))));
33735
33794
  const env2 = { DATABASE_URL: databaseUrl, DEV_MODE: "true" };
33736
33795
  const apiLogFile = getLogFile("api");
33737
33796
  const apiProc = Bun.spawn(["bun", "run", resolve10(packagesDir, "packages/api/src/index.ts")], {
@@ -34081,7 +34140,7 @@ async function restartDev() {
34081
34140
  await clearDevState();
34082
34141
  await clearLogs();
34083
34142
  const config = await loadConfig2();
34084
- const packagesDir = dirname13(dirname13(dirname13(dirname13(import.meta.dir))));
34143
+ const packagesDir = dirname14(dirname14(dirname14(dirname14(import.meta.dir))));
34085
34144
  const env2 = state.env;
34086
34145
  const newState = {
34087
34146
  services: {},
@@ -34278,7 +34337,7 @@ async function ensureDevPostgres(dataDir) {
34278
34337
  throw new Error("PostgreSQL failed to start");
34279
34338
  }
34280
34339
  async function runMigrations(databaseUrl) {
34281
- const packagesDir = dirname13(dirname13(dirname13(dirname13(import.meta.dir))));
34340
+ const packagesDir = dirname14(dirname14(dirname14(dirname14(import.meta.dir))));
34282
34341
  const migrateScript = resolve10(packagesDir, "packages/shared/src/db/migrate.ts");
34283
34342
  const result = await Bun.$`DATABASE_URL=${databaseUrl} bun run ${migrateScript}`.quiet().nothrow();
34284
34343
  if (result.exitCode !== 0) {
@@ -34762,7 +34821,7 @@ var {
34762
34821
  // package.json
34763
34822
  var package_default = {
34764
34823
  name: "@secondlayer/cli",
34765
- version: "9.4.1",
34824
+ version: "9.5.0",
34766
34825
  repository: {
34767
34826
  type: "git",
34768
34827
  url: "git+https://github.com/ryanwaits/secondlayer.git",
@@ -35507,7 +35566,7 @@ import {
35507
35566
  statSync as statSync2,
35508
35567
  writeFileSync as writeFileSync4
35509
35568
  } from "node:fs";
35510
- import { dirname as dirname5, join as join6, relative, resolve as resolve5 } from "node:path";
35569
+ import { dirname as dirname6, join as join6, relative, resolve as resolve5 } from "node:path";
35511
35570
  import { fileURLToPath as fileURLToPath4 } from "node:url";
35512
35571
  import { input as input2, select as select3 } from "@inquirer/prompts";
35513
35572
  import { SecondLayer as SecondLayer3 } from "@secondlayer/sdk";
@@ -35522,7 +35581,7 @@ var FORMAT_BY_RUNTIME = {
35522
35581
  node: "standard-webhooks"
35523
35582
  };
35524
35583
  function templatesRoot() {
35525
- const here = dirname5(fileURLToPath4(import.meta.url));
35584
+ const here = dirname6(fileURLToPath4(import.meta.url));
35526
35585
  const candidateDist = resolve5(here, "..", "templates", "subscriptions");
35527
35586
  if (existsSync4(candidateDist))
35528
35587
  return candidateDist;
@@ -36466,7 +36525,7 @@ POST result (client-side, not logged):`));
36466
36525
  // src/commands/devnet.ts
36467
36526
  import { spawnSync as spawnSync2 } from "node:child_process";
36468
36527
  import { existsSync as existsSync6, mkdirSync as mkdirSync4, writeFileSync as writeFileSync6 } from "node:fs";
36469
- import { dirname as dirname7, join as join8 } from "node:path";
36528
+ import { dirname as dirname8, join as join8 } from "node:path";
36470
36529
 
36471
36530
  // src/lib/devnet-compose.ts
36472
36531
  var DEFAULT_IMAGE_OWNER = "ryanwaits";
@@ -36609,7 +36668,7 @@ volumes:
36609
36668
 
36610
36669
  // src/lib/devnet-config.ts
36611
36670
  import { existsSync as existsSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
36612
- import { dirname as dirname6, join as join7, parse as parsePath } from "node:path";
36671
+ import { dirname as dirname7, join as join7, parse as parsePath } from "node:path";
36613
36672
  import { parse as parseToml } from "smol-toml";
36614
36673
  var DEFAULT_INDEXER_OBSERVER = "host.docker.internal:3700";
36615
36674
  function findClarinetProject(startDir) {
@@ -36620,7 +36679,7 @@ function findClarinetProject(startDir) {
36620
36679
  return dir;
36621
36680
  if (dir === root)
36622
36681
  return null;
36623
- dir = dirname6(dir);
36682
+ dir = dirname7(dir);
36624
36683
  }
36625
36684
  }
36626
36685
  function ensureEventObserver(devnetTomlPath, endpoint = DEFAULT_INDEXER_OBSERVER) {
@@ -36724,7 +36783,7 @@ function resolveProject(explicit) {
36724
36783
  async function connect(options3) {
36725
36784
  const project = resolveProject(options3.project);
36726
36785
  const devnetToml = join8(project, "settings", "Devnet.toml");
36727
- mkdirSync4(dirname7(devnetToml), { recursive: true });
36786
+ mkdirSync4(dirname8(devnetToml), { recursive: true });
36728
36787
  const result = ensureEventObserver(devnetToml, DEFAULT_INDEXER_OBSERVER);
36729
36788
  console.log(`${green("✓")} found Clarinet.toml`);
36730
36789
  if (result.status === "present") {
@@ -36734,7 +36793,7 @@ async function connect(options3) {
36734
36793
  console.log(dim(` + stacks_node_events_observers = ["${DEFAULT_INDEXER_OBSERVER}"]`));
36735
36794
  }
36736
36795
  const composePath = join8(project, COMPOSE_REL);
36737
- mkdirSync4(dirname7(composePath), { recursive: true });
36796
+ mkdirSync4(dirname8(composePath), { recursive: true });
36738
36797
  writeFileSync6(composePath, buildDevnetCompose({ owner: options3.owner, imageTag: options3.imageTag }));
36739
36798
  console.log(`${green("✓")} wrote ${COMPOSE_REL}`);
36740
36799
  if (!options3.up) {
@@ -36904,7 +36963,7 @@ init_subgraphs2();
36904
36963
  init_output();
36905
36964
  init_resolve_auth();
36906
36965
  import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
36907
- import { dirname as dirname8, join as join9 } from "node:path";
36966
+ import { dirname as dirname9, join as join9 } from "node:path";
36908
36967
  import { createStreamsClient } from "@secondlayer/sdk";
36909
36968
  import { STREAMS_EVENT_TYPES } from "@secondlayer/shared";
36910
36969
  var DEFAULT_BASE_URL3 = "https://api.secondlayer.tools";
@@ -37081,7 +37140,7 @@ Examples:
37081
37140
  for (const file of files) {
37082
37141
  const bytes = await dumps.download(file);
37083
37142
  const dest = join9(options3.to, file.path);
37084
- await mkdir3(dirname8(dest), { recursive: true });
37143
+ await mkdir3(dirname9(dest), { recursive: true });
37085
37144
  await writeFile3(dest, bytes);
37086
37145
  process.stderr.write(`# ${file.path} (${file.row_count} rows, ${bytes.byteLength} bytes)
37087
37146
  `);
@@ -38370,7 +38429,7 @@ init_output();
38370
38429
  import { existsSync as existsSync7 } from "node:fs";
38371
38430
  import { mkdir as mkdir4, readFile as readFile3, writeFile as writeFile4 } from "node:fs/promises";
38372
38431
  import { homedir as homedir5 } from "node:os";
38373
- import { dirname as dirname14, join as join12, parse as parsePath2, resolve as resolve11 } from "node:path";
38432
+ import { dirname as dirname15, join as join12, parse as parsePath2, resolve as resolve11 } from "node:path";
38374
38433
  import { z as z4 } from "zod";
38375
38434
  var ProjectFileSchema = z4.object({
38376
38435
  slug: z4.string().min(1)
@@ -38394,7 +38453,7 @@ async function readActiveProject(cwd, globalDefault) {
38394
38453
  break;
38395
38454
  if (dir === home2 || dir === fsRoot)
38396
38455
  break;
38397
- const parent = dirname14(dir);
38456
+ const parent = dirname15(dir);
38398
38457
  if (parent === dir)
38399
38458
  break;
38400
38459
  dir = parent;
@@ -38632,5 +38691,5 @@ registerAccountCommand(program);
38632
38691
  registerKeysCommand(program);
38633
38692
  program.parse();
38634
38693
 
38635
- //# debugId=3FA001BD14F850B364756E2164756E21
38694
+ //# debugId=032000CD6BC64C8E64756E2164756E21
38636
38695
  //# sourceMappingURL=cli.js.map