@secondlayer/cli 1.10.0 → 1.11.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
@@ -2444,44 +2444,198 @@ var init_config = __esm(() => {
2444
2444
  };
2445
2445
  });
2446
2446
 
2447
- // src/lib/docker.ts
2448
- async function isDockerAvailable() {
2447
+ // src/lib/api-client.ts
2448
+ var exports_api_client = {};
2449
+ __export(exports_api_client, {
2450
+ updateStreamByName: () => updateStreamByName,
2451
+ updateStream: () => updateStream,
2452
+ updateAccountProfile: () => updateAccountProfile,
2453
+ unpublishSubgraphApi: () => unpublishSubgraphApi,
2454
+ stopSubgraphApi: () => stopSubgraphApi,
2455
+ rotateSecret: () => rotateSecret,
2456
+ resumeAllStreams: () => resumeAllStreams,
2457
+ resolveStreamId: () => resolveStreamId,
2458
+ reindexSubgraphApi: () => reindexSubgraphApi,
2459
+ querySubgraphTableCount: () => querySubgraphTableCount,
2460
+ querySubgraphTable: () => querySubgraphTable,
2461
+ publishSubgraphApi: () => publishSubgraphApi,
2462
+ pauseAllStreams: () => pauseAllStreams,
2463
+ listSubgraphsApi: () => listSubgraphsApi,
2464
+ listStreams: () => listStreams,
2465
+ handleApiError: () => handleApiError,
2466
+ getSubgraphGaps: () => getSubgraphGaps,
2467
+ getSubgraphApi: () => getSubgraphApi,
2468
+ getStream: () => getStream,
2469
+ getQueueStats: () => getQueueStats,
2470
+ getMarketplaceSubgraph: () => getMarketplaceSubgraph,
2471
+ getAccountProfile: () => getAccountProfile,
2472
+ forkMarketplaceSubgraph: () => forkMarketplaceSubgraph,
2473
+ enableStream: () => enableStream,
2474
+ disableStream: () => disableStream,
2475
+ deploySubgraphApi: () => deploySubgraphApi,
2476
+ deleteSubgraphApi: () => deleteSubgraphApi,
2477
+ deleteStream: () => deleteStream,
2478
+ createStream: () => createStream,
2479
+ browseMarketplace: () => browseMarketplace,
2480
+ backfillSubgraphApi: () => backfillSubgraphApi,
2481
+ authHeaders: () => authHeaders,
2482
+ assertOk: () => assertOk,
2483
+ ApiError: () => ApiError
2484
+ });
2485
+ import { SecondLayer } from "@secondlayer/sdk";
2486
+ import { ApiError } from "@secondlayer/sdk";
2487
+ async function assertOk(res) {
2488
+ if (res.ok)
2489
+ return;
2490
+ const body = await res.text();
2449
2491
  try {
2450
- const result = await Bun.$`docker info`.quiet().nothrow();
2451
- return result.exitCode === 0;
2452
- } catch {
2453
- return false;
2492
+ const parsed = JSON.parse(body);
2493
+ if (typeof parsed.error === "string" && parsed.error)
2494
+ throw new Error(parsed.error);
2495
+ } catch (e) {
2496
+ if (e instanceof Error && e.message !== body)
2497
+ throw e;
2454
2498
  }
2499
+ throw new Error(`HTTP ${res.status}`);
2455
2500
  }
2456
- async function requireDocker() {
2457
- const whichResult = await Bun.$`which docker`.quiet().nothrow();
2458
- if (whichResult.exitCode !== 0) {
2459
- throw new DockerNotAvailableError(`Docker is not installed.
2460
-
2461
- ` + `Install Docker:
2462
- ` + ` macOS: brew install --cask docker
2463
- ` + ` or download from https://docker.com/products/docker-desktop
2464
- ` + ` Linux: curl -fsSL https://get.docker.com | sh
2465
- `);
2466
- }
2467
- const available = await isDockerAvailable();
2468
- if (!available) {
2469
- throw new DockerNotAvailableError(`Docker daemon is not running.
2470
-
2471
- ` + `Start Docker:
2472
- ` + ` macOS: Open Docker Desktop or OrbStack
2473
- ` + ` Linux: sudo systemctl start docker
2474
- `);
2501
+ function handleApiError(err, action) {
2502
+ if (err instanceof ApiError && err.status === 401) {
2503
+ console.error("Error: Authentication required. Run: sl auth login");
2504
+ process.exit(1);
2475
2505
  }
2506
+ console.error(`Error: Failed to ${action}: ${err}`);
2507
+ process.exit(1);
2476
2508
  }
2477
- var DockerNotAvailableError;
2478
- var init_docker = __esm(() => {
2479
- DockerNotAvailableError = class DockerNotAvailableError extends Error {
2480
- constructor(message) {
2481
- super(message);
2482
- this.name = "DockerNotAvailableError";
2483
- }
2484
- };
2509
+ async function getClient() {
2510
+ const config = await loadConfig();
2511
+ const baseUrl = resolveApiUrl(config);
2512
+ return new SecondLayer({ baseUrl, apiKey: config.apiKey });
2513
+ }
2514
+ function authHeaders(config) {
2515
+ return SecondLayer.authHeaders(config.apiKey);
2516
+ }
2517
+ async function createStream(data) {
2518
+ return (await getClient()).streams.create(data);
2519
+ }
2520
+ async function updateStream(id, data) {
2521
+ return (await getClient()).streams.update(id, data);
2522
+ }
2523
+ async function updateStreamByName(name, data) {
2524
+ return (await getClient()).streams.updateByName(name, data);
2525
+ }
2526
+ async function listStreams(params) {
2527
+ return (await getClient()).streams.list(params);
2528
+ }
2529
+ async function resolveStreamId(partialId) {
2530
+ return (await getClient()).streams.resolveStreamId(partialId);
2531
+ }
2532
+ async function getStream(id) {
2533
+ return (await getClient()).streams.get(id);
2534
+ }
2535
+ async function deleteStream(id) {
2536
+ return (await getClient()).streams.delete(id);
2537
+ }
2538
+ async function enableStream(id) {
2539
+ return (await getClient()).streams.enable(id);
2540
+ }
2541
+ async function disableStream(id) {
2542
+ return (await getClient()).streams.disable(id);
2543
+ }
2544
+ async function rotateSecret(id) {
2545
+ return (await getClient()).streams.rotateSecret(id);
2546
+ }
2547
+ async function pauseAllStreams() {
2548
+ return (await getClient()).streams.pauseAll();
2549
+ }
2550
+ async function resumeAllStreams() {
2551
+ return (await getClient()).streams.resumeAll();
2552
+ }
2553
+ async function getQueueStats() {
2554
+ return (await getClient()).getQueueStats();
2555
+ }
2556
+ async function listSubgraphsApi() {
2557
+ return (await getClient()).subgraphs.list();
2558
+ }
2559
+ async function getSubgraphApi(name) {
2560
+ return (await getClient()).subgraphs.get(name);
2561
+ }
2562
+ async function reindexSubgraphApi(name, options) {
2563
+ return (await getClient()).subgraphs.reindex(name, options);
2564
+ }
2565
+ async function backfillSubgraphApi(name, options) {
2566
+ return (await getClient()).subgraphs.backfill(name, options);
2567
+ }
2568
+ async function stopSubgraphApi(name) {
2569
+ return (await getClient()).subgraphs.stop(name);
2570
+ }
2571
+ async function deleteSubgraphApi(name) {
2572
+ return (await getClient()).subgraphs.delete(name);
2573
+ }
2574
+ async function deploySubgraphApi(data) {
2575
+ return (await getClient()).subgraphs.deploy(data);
2576
+ }
2577
+ async function querySubgraphTable(name, table, params = {}) {
2578
+ return (await getClient()).subgraphs.queryTable(name, table, params);
2579
+ }
2580
+ async function querySubgraphTableCount(name, table, params = {}) {
2581
+ return (await getClient()).subgraphs.queryTableCount(name, table, params);
2582
+ }
2583
+ async function getSubgraphGaps(name, opts) {
2584
+ return (await getClient()).subgraphs.gaps(name, opts);
2585
+ }
2586
+ async function getAccountProfile() {
2587
+ const config = await loadConfig();
2588
+ const baseUrl = resolveApiUrl(config);
2589
+ const res = await fetch(`${baseUrl}/api/accounts/me`, {
2590
+ headers: authHeaders(config)
2591
+ });
2592
+ await assertOk(res);
2593
+ return res.json();
2594
+ }
2595
+ async function updateAccountProfile(data) {
2596
+ const config = await loadConfig();
2597
+ const baseUrl = resolveApiUrl(config);
2598
+ const res = await fetch(`${baseUrl}/api/accounts/me`, {
2599
+ method: "PATCH",
2600
+ headers: authHeaders(config),
2601
+ body: JSON.stringify(data)
2602
+ });
2603
+ await assertOk(res);
2604
+ return res.json();
2605
+ }
2606
+ async function browseMarketplace(opts = {}) {
2607
+ return (await getClient()).marketplace.browse(opts);
2608
+ }
2609
+ async function getMarketplaceSubgraph(name) {
2610
+ return (await getClient()).marketplace.get(name);
2611
+ }
2612
+ async function forkMarketplaceSubgraph(name, newName) {
2613
+ return (await getClient()).marketplace.fork(name, newName);
2614
+ }
2615
+ async function publishSubgraphApi(name, opts) {
2616
+ const config = await loadConfig();
2617
+ const baseUrl = resolveApiUrl(config);
2618
+ const res = await fetch(`${baseUrl}/api/subgraphs/${name}/publish`, {
2619
+ method: "POST",
2620
+ headers: authHeaders(config),
2621
+ body: JSON.stringify(opts ?? {})
2622
+ });
2623
+ await assertOk(res);
2624
+ return res.json();
2625
+ }
2626
+ async function unpublishSubgraphApi(name) {
2627
+ const config = await loadConfig();
2628
+ const baseUrl = resolveApiUrl(config);
2629
+ const res = await fetch(`${baseUrl}/api/subgraphs/${name}/unpublish`, {
2630
+ method: "POST",
2631
+ headers: authHeaders(config),
2632
+ body: JSON.stringify({})
2633
+ });
2634
+ await assertOk(res);
2635
+ return res.json();
2636
+ }
2637
+ var init_api_client = __esm(() => {
2638
+ init_config();
2485
2639
  });
2486
2640
 
2487
2641
  // src/lib/output.ts
@@ -2556,6 +2710,46 @@ var init_output = __esm(() => {
2556
2710
  };
2557
2711
  });
2558
2712
 
2713
+ // src/lib/docker.ts
2714
+ async function isDockerAvailable() {
2715
+ try {
2716
+ const result = await Bun.$`docker info`.quiet().nothrow();
2717
+ return result.exitCode === 0;
2718
+ } catch {
2719
+ return false;
2720
+ }
2721
+ }
2722
+ async function requireDocker() {
2723
+ const whichResult = await Bun.$`which docker`.quiet().nothrow();
2724
+ if (whichResult.exitCode !== 0) {
2725
+ throw new DockerNotAvailableError(`Docker is not installed.
2726
+
2727
+ ` + `Install Docker:
2728
+ ` + ` macOS: brew install --cask docker
2729
+ ` + ` or download from https://docker.com/products/docker-desktop
2730
+ ` + ` Linux: curl -fsSL https://get.docker.com | sh
2731
+ `);
2732
+ }
2733
+ const available = await isDockerAvailable();
2734
+ if (!available) {
2735
+ throw new DockerNotAvailableError(`Docker daemon is not running.
2736
+
2737
+ ` + `Start Docker:
2738
+ ` + ` macOS: Open Docker Desktop or OrbStack
2739
+ ` + ` Linux: sudo systemctl start docker
2740
+ `);
2741
+ }
2742
+ }
2743
+ var DockerNotAvailableError;
2744
+ var init_docker = __esm(() => {
2745
+ DockerNotAvailableError = class DockerNotAvailableError extends Error {
2746
+ constructor(message) {
2747
+ super(message);
2748
+ this.name = "DockerNotAvailableError";
2749
+ }
2750
+ };
2751
+ });
2752
+
2559
2753
  // ../../node_modules/postgres/src/query.js
2560
2754
  function cachedError(xs) {
2561
2755
  if (originCache.has(xs))
@@ -4546,142 +4740,6 @@ var init_src = __esm(() => {
4546
4740
  src_default = Postgres;
4547
4741
  });
4548
4742
 
4549
- // src/lib/api-client.ts
4550
- var exports_api_client = {};
4551
- __export(exports_api_client, {
4552
- updateStreamByName: () => updateStreamByName,
4553
- updateStream: () => updateStream,
4554
- stopSubgraphApi: () => stopSubgraphApi,
4555
- rotateSecret: () => rotateSecret,
4556
- resumeAllStreams: () => resumeAllStreams,
4557
- resolveStreamId: () => resolveStreamId,
4558
- reindexSubgraphApi: () => reindexSubgraphApi,
4559
- querySubgraphTableCount: () => querySubgraphTableCount,
4560
- querySubgraphTable: () => querySubgraphTable,
4561
- pauseAllStreams: () => pauseAllStreams,
4562
- listSubgraphsApi: () => listSubgraphsApi,
4563
- listStreams: () => listStreams,
4564
- handleApiError: () => handleApiError,
4565
- getSubgraphGaps: () => getSubgraphGaps,
4566
- getSubgraphApi: () => getSubgraphApi,
4567
- getStream: () => getStream,
4568
- getQueueStats: () => getQueueStats,
4569
- enableStream: () => enableStream,
4570
- disableStream: () => disableStream,
4571
- deploySubgraphApi: () => deploySubgraphApi,
4572
- deleteSubgraphApi: () => deleteSubgraphApi,
4573
- deleteStream: () => deleteStream,
4574
- createStream: () => createStream,
4575
- backfillSubgraphApi: () => backfillSubgraphApi,
4576
- authHeaders: () => authHeaders,
4577
- assertOk: () => assertOk,
4578
- ApiError: () => ApiError
4579
- });
4580
- import { SecondLayer } from "@secondlayer/sdk";
4581
- import { ApiError } from "@secondlayer/sdk";
4582
- async function assertOk(res) {
4583
- if (res.ok)
4584
- return;
4585
- const body = await res.text();
4586
- try {
4587
- const parsed = JSON.parse(body);
4588
- if (typeof parsed.error === "string" && parsed.error)
4589
- throw new Error(parsed.error);
4590
- } catch (e) {
4591
- if (e instanceof Error && e.message !== body)
4592
- throw e;
4593
- }
4594
- throw new Error(`HTTP ${res.status}`);
4595
- }
4596
- function handleApiError(err, action) {
4597
- if (err instanceof ApiError && err.status === 401) {
4598
- console.error("Error: Authentication required. Run: sl auth login");
4599
- process.exit(1);
4600
- }
4601
- console.error(`Error: Failed to ${action}: ${err}`);
4602
- process.exit(1);
4603
- }
4604
- async function getClient() {
4605
- const config = await loadConfig();
4606
- const baseUrl = resolveApiUrl(config);
4607
- return new SecondLayer({ baseUrl, apiKey: config.apiKey });
4608
- }
4609
- function authHeaders(config) {
4610
- return SecondLayer.authHeaders(config.apiKey);
4611
- }
4612
- async function createStream(data) {
4613
- return (await getClient()).streams.create(data);
4614
- }
4615
- async function updateStream(id, data) {
4616
- return (await getClient()).streams.update(id, data);
4617
- }
4618
- async function updateStreamByName(name, data) {
4619
- return (await getClient()).streams.updateByName(name, data);
4620
- }
4621
- async function listStreams(params) {
4622
- return (await getClient()).streams.list(params);
4623
- }
4624
- async function resolveStreamId(partialId) {
4625
- return (await getClient()).streams.resolveStreamId(partialId);
4626
- }
4627
- async function getStream(id) {
4628
- return (await getClient()).streams.get(id);
4629
- }
4630
- async function deleteStream(id) {
4631
- return (await getClient()).streams.delete(id);
4632
- }
4633
- async function enableStream(id) {
4634
- return (await getClient()).streams.enable(id);
4635
- }
4636
- async function disableStream(id) {
4637
- return (await getClient()).streams.disable(id);
4638
- }
4639
- async function rotateSecret(id) {
4640
- return (await getClient()).streams.rotateSecret(id);
4641
- }
4642
- async function pauseAllStreams() {
4643
- return (await getClient()).streams.pauseAll();
4644
- }
4645
- async function resumeAllStreams() {
4646
- return (await getClient()).streams.resumeAll();
4647
- }
4648
- async function getQueueStats() {
4649
- return (await getClient()).getQueueStats();
4650
- }
4651
- async function listSubgraphsApi() {
4652
- return (await getClient()).subgraphs.list();
4653
- }
4654
- async function getSubgraphApi(name) {
4655
- return (await getClient()).subgraphs.get(name);
4656
- }
4657
- async function reindexSubgraphApi(name, options) {
4658
- return (await getClient()).subgraphs.reindex(name, options);
4659
- }
4660
- async function backfillSubgraphApi(name, options) {
4661
- return (await getClient()).subgraphs.backfill(name, options);
4662
- }
4663
- async function stopSubgraphApi(name) {
4664
- return (await getClient()).subgraphs.stop(name);
4665
- }
4666
- async function deleteSubgraphApi(name) {
4667
- return (await getClient()).subgraphs.delete(name);
4668
- }
4669
- async function deploySubgraphApi(data) {
4670
- return (await getClient()).subgraphs.deploy(data);
4671
- }
4672
- async function querySubgraphTable(name, table, params = {}) {
4673
- return (await getClient()).subgraphs.queryTable(name, table, params);
4674
- }
4675
- async function querySubgraphTableCount(name, table, params = {}) {
4676
- return (await getClient()).subgraphs.queryTableCount(name, table, params);
4677
- }
4678
- async function getSubgraphGaps(name, opts) {
4679
- return (await getClient()).subgraphs.gaps(name, opts);
4680
- }
4681
- var init_api_client = __esm(() => {
4682
- init_config();
4683
- });
4684
-
4685
4743
  // src/lib/dev-state.ts
4686
4744
  var exports_dev_state = {};
4687
4745
  __export(exports_dev_state, {
@@ -19089,42 +19147,42 @@ var require_queue = __commonJS((exports, module) => {
19089
19147
  queue.drained = drained;
19090
19148
  return queue;
19091
19149
  function push(value) {
19092
- var p = new Promise(function(resolve7, reject) {
19150
+ var p = new Promise(function(resolve8, reject) {
19093
19151
  pushCb(value, function(err, result) {
19094
19152
  if (err) {
19095
19153
  reject(err);
19096
19154
  return;
19097
19155
  }
19098
- resolve7(result);
19156
+ resolve8(result);
19099
19157
  });
19100
19158
  });
19101
19159
  p.catch(noop5);
19102
19160
  return p;
19103
19161
  }
19104
19162
  function unshift(value) {
19105
- var p = new Promise(function(resolve7, reject) {
19163
+ var p = new Promise(function(resolve8, reject) {
19106
19164
  unshiftCb(value, function(err, result) {
19107
19165
  if (err) {
19108
19166
  reject(err);
19109
19167
  return;
19110
19168
  }
19111
- resolve7(result);
19169
+ resolve8(result);
19112
19170
  });
19113
19171
  });
19114
19172
  p.catch(noop5);
19115
19173
  return p;
19116
19174
  }
19117
19175
  function drained() {
19118
- var p = new Promise(function(resolve7) {
19176
+ var p = new Promise(function(resolve8) {
19119
19177
  process.nextTick(function() {
19120
19178
  if (queue.idle()) {
19121
- resolve7();
19179
+ resolve8();
19122
19180
  } else {
19123
19181
  var previousDrain = queue.drain;
19124
19182
  queue.drain = function() {
19125
19183
  if (typeof previousDrain === "function")
19126
19184
  previousDrain();
19127
- resolve7();
19185
+ resolve8();
19128
19186
  queue.drain = previousDrain;
19129
19187
  };
19130
19188
  }
@@ -19585,9 +19643,9 @@ var require_stream3 = __commonJS((exports) => {
19585
19643
  });
19586
19644
  }
19587
19645
  _getStat(filepath) {
19588
- return new Promise((resolve7, reject) => {
19646
+ return new Promise((resolve8, reject) => {
19589
19647
  this._stat(filepath, this._fsStatSettings, (error2, stats) => {
19590
- return error2 === null ? resolve7(stats) : reject(error2);
19648
+ return error2 === null ? resolve8(stats) : reject(error2);
19591
19649
  });
19592
19650
  });
19593
19651
  }
@@ -19609,10 +19667,10 @@ var require_async5 = __commonJS((exports) => {
19609
19667
  this._readerStream = new stream_1.default(this._settings);
19610
19668
  }
19611
19669
  dynamic(root, options2) {
19612
- return new Promise((resolve7, reject) => {
19670
+ return new Promise((resolve8, reject) => {
19613
19671
  this._walkAsync(root, options2, (error2, entries2) => {
19614
19672
  if (error2 === null) {
19615
- resolve7(entries2);
19673
+ resolve8(entries2);
19616
19674
  } else {
19617
19675
  reject(error2);
19618
19676
  }
@@ -19622,10 +19680,10 @@ var require_async5 = __commonJS((exports) => {
19622
19680
  async static(patterns, options2) {
19623
19681
  const entries2 = [];
19624
19682
  const stream2 = this._readerStream.static(patterns, options2);
19625
- return new Promise((resolve7, reject) => {
19683
+ return new Promise((resolve8, reject) => {
19626
19684
  stream2.once("error", reject);
19627
19685
  stream2.on("data", (entry) => entries2.push(entry));
19628
- stream2.once("end", () => resolve7(entries2));
19686
+ stream2.once("end", () => resolve8(entries2));
19629
19687
  });
19630
19688
  }
19631
19689
  }
@@ -20266,7 +20324,7 @@ import { promises as fs3 } from "fs";
20266
20324
  import path from "path";
20267
20325
  import { isValidAddress as _validateStacksAddress } from "@secondlayer/stacks";
20268
20326
  import { getErrorMessage } from "@secondlayer/shared";
20269
- import { toCamelCase as toCamelCase2 } from "@secondlayer/stacks/clarity";
20327
+ import { toCamelCase as toCamelCase3 } from "@secondlayer/stacks/clarity";
20270
20328
 
20271
20329
  class PluginManager {
20272
20330
  plugins = [];
@@ -20490,7 +20548,7 @@ ${JSON.stringify(content, null, 2)}`;
20490
20548
  }
20491
20549
  createUtils() {
20492
20550
  return {
20493
- toCamelCase: toCamelCase2,
20551
+ toCamelCase: toCamelCase3,
20494
20552
  toKebabCase: (str) => {
20495
20553
  return str.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
20496
20554
  },
@@ -20541,7 +20599,7 @@ import {
20541
20599
  isAbiStringAscii as isAbiStringAscii2,
20542
20600
  isAbiStringUtf8 as isAbiStringUtf82,
20543
20601
  isAbiTuple,
20544
- toCamelCase as toCamelCase3
20602
+ toCamelCase as toCamelCase4
20545
20603
  } from "@secondlayer/stacks/clarity";
20546
20604
  function generateClarityConversion(argName, argType) {
20547
20605
  const type = argType.type;
@@ -20632,7 +20690,7 @@ function generateClarityConversion(argName, argType) {
20632
20690
  const requiredFields = type.tuple.map((f) => f.name);
20633
20691
  const fieldNames = JSON.stringify(requiredFields);
20634
20692
  const fields = type.tuple.map((field) => {
20635
- const camelFieldName = toCamelCase3(field.name);
20693
+ const camelFieldName = toCamelCase4(field.name);
20636
20694
  const fieldConversion = generateClarityConversion(`tupleValue.${camelFieldName}`, { type: field.type });
20637
20695
  return `"${field.name}": ${fieldConversion}`;
20638
20696
  }).join(", ");
@@ -20681,7 +20739,7 @@ import {
20681
20739
  isAbiStringAscii as isAbiStringAscii3,
20682
20740
  isAbiStringUtf8 as isAbiStringUtf83,
20683
20741
  isAbiTuple as isAbiTuple2,
20684
- toCamelCase as toCamelCase4
20742
+ toCamelCase as toCamelCase5
20685
20743
  } from "@secondlayer/stacks/clarity";
20686
20744
  function clarityTypeToTS(type) {
20687
20745
  if (typeof type === "string") {
@@ -20733,7 +20791,7 @@ function clarityTypeToTS(type) {
20733
20791
  return `${innerType}[]`;
20734
20792
  }
20735
20793
  if (isAbiTuple2(type)) {
20736
- const fields = type.tuple.map((field) => `${toCamelCase4(field.name)}: ${clarityTypeToTS(field.type)}`).join("; ");
20794
+ const fields = type.tuple.map((field) => `${toCamelCase5(field.name)}: ${clarityTypeToTS(field.type)}`).join("; ");
20737
20795
  return `{ ${fields} }`;
20738
20796
  }
20739
20797
  if (isAbiResponse2(type)) {
@@ -20751,12 +20809,12 @@ var init_type_mapping = () => {};
20751
20809
  // src/utils/generator-helpers.ts
20752
20810
  import {
20753
20811
  isAbiTuple as isAbiTuple3,
20754
- toCamelCase as toCamelCase5
20812
+ toCamelCase as toCamelCase6
20755
20813
  } from "@secondlayer/stacks/clarity";
20756
20814
  function generateMapKeyConversion(keyType) {
20757
20815
  if (isAbiTuple3(keyType)) {
20758
20816
  const fields = keyType.tuple.map((field) => {
20759
- const camelFieldName = toCamelCase5(field.name);
20817
+ const camelFieldName = toCamelCase6(field.name);
20760
20818
  const fieldConversion = generateClarityConversion(`key.${camelFieldName}`, { type: field.type });
20761
20819
  return `"${field.name}": ${fieldConversion}`;
20762
20820
  }).join(", ");
@@ -20771,7 +20829,7 @@ var init_generator_helpers = __esm(() => {
20771
20829
 
20772
20830
  // src/generators/contract.ts
20773
20831
  import {
20774
- toCamelCase as toCamelCase6
20832
+ toCamelCase as toCamelCase7
20775
20833
  } from "@secondlayer/stacks/clarity";
20776
20834
  function generateNetworkUtils() {
20777
20835
  return `/**
@@ -20863,7 +20921,7 @@ function generateAbiConstant(name, abi) {
20863
20921
  return `export const ${name}Abi = ${abiJson} as const`;
20864
20922
  }
20865
20923
  function generateMethod(func, address, contractName) {
20866
- const methodName = toCamelCase6(func.name);
20924
+ const methodName = toCamelCase7(func.name);
20867
20925
  if (func.args.length === 0) {
20868
20926
  return `${methodName}() {
20869
20927
  return {
@@ -20876,7 +20934,7 @@ function generateMethod(func, address, contractName) {
20876
20934
  }
20877
20935
  if (func.args.length === 1) {
20878
20936
  const originalArgName = func.args[0].name;
20879
- const argName = toCamelCase6(originalArgName);
20937
+ const argName = toCamelCase7(originalArgName);
20880
20938
  const argType = getTypeForArg(func.args[0]);
20881
20939
  const clarityConversion = generateClarityConversion(argName, func.args[0]);
20882
20940
  return `${methodName}(...args: [{ ${argName}: ${argType} }] | [${argType}]) {
@@ -20892,17 +20950,17 @@ function generateMethod(func, address, contractName) {
20892
20950
  }
20893
20951
  }`;
20894
20952
  }
20895
- const argsList = func.args.map((arg) => toCamelCase6(arg.name)).join(", ");
20953
+ const argsList = func.args.map((arg) => toCamelCase7(arg.name)).join(", ");
20896
20954
  const argsTypes = func.args.map((arg) => {
20897
- const camelName = toCamelCase6(arg.name);
20955
+ const camelName = toCamelCase7(arg.name);
20898
20956
  return `${camelName}: ${getTypeForArg(arg)}`;
20899
20957
  }).join("; ");
20900
20958
  const argsArray = func.args.map((arg) => {
20901
- const argName = toCamelCase6(arg.name);
20959
+ const argName = toCamelCase7(arg.name);
20902
20960
  return generateClarityConversion(argName, arg);
20903
20961
  }).join(", ");
20904
20962
  const objectAccess = func.args.map((arg) => {
20905
- const camelName = toCamelCase6(arg.name);
20963
+ const camelName = toCamelCase7(arg.name);
20906
20964
  return `args[0].${camelName}`;
20907
20965
  }).join(", ");
20908
20966
  const positionTypes = func.args.map((arg) => getTypeForArg(arg)).join(", ");
@@ -20924,7 +20982,7 @@ function generateMapsObject(maps, address, contractName) {
20924
20982
  return "";
20925
20983
  }
20926
20984
  const mapMethods = maps.map((map) => {
20927
- const methodName = toCamelCase6(map.name);
20985
+ const methodName = toCamelCase7(map.name);
20928
20986
  const keyType = getTypeForArg({ type: map.key });
20929
20987
  const valueType = getTypeForArg({ type: map.value });
20930
20988
  const keyConversion = generateMapKeyConversion(map.key);
@@ -20985,7 +21043,7 @@ function generateVarsObject(variables, address, contractName) {
20985
21043
  return "";
20986
21044
  }
20987
21045
  const varMethods = dataVars.map((variable) => {
20988
- const methodName = toCamelCase6(variable.name);
21046
+ const methodName = toCamelCase7(variable.name);
20989
21047
  const valueType = getTypeForArg({ type: variable.type });
20990
21048
  return `${methodName}: {
20991
21049
  async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
@@ -21030,7 +21088,7 @@ function generateConstantsObject(variables, address, contractName) {
21030
21088
  return "";
21031
21089
  }
21032
21090
  const constMethods = constants.map((constant) => {
21033
- const methodName = toCamelCase6(constant.name);
21091
+ const methodName = toCamelCase7(constant.name);
21034
21092
  const valueType = getTypeForArg({ type: constant.type });
21035
21093
  return `${methodName}: {
21036
21094
  async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
@@ -22090,11 +22148,11 @@ var init_commands = __esm(() => {
22090
22148
  });
22091
22149
 
22092
22150
  // ../../node_modules/@antfu/ni/dist/shared/ni.B5qNAuoI.mjs
22093
- import path3, { join as join7, dirname as dirname6, resolve as resolve7 } from "node:path";
22151
+ import path3, { join as join7, dirname as dirname6, resolve as resolve8 } from "node:path";
22094
22152
  import process$1 from "node:process";
22095
22153
  import require$$0 from "readline";
22096
22154
  import require$$2 from "events";
22097
- import fs5, { promises, existsSync as existsSync2 } from "node:fs";
22155
+ import fs5, { promises, existsSync as existsSync3 } from "node:fs";
22098
22156
  import require$$0$1 from "os";
22099
22157
  import require$$1 from "tty";
22100
22158
  import os4 from "node:os";
@@ -26239,12 +26297,12 @@ var require_isexe = __commonJS((exports, module) => {
26239
26297
  if (typeof Promise !== "function") {
26240
26298
  throw new TypeError("callback not provided");
26241
26299
  }
26242
- return new Promise(function(resolve8, reject) {
26300
+ return new Promise(function(resolve9, reject) {
26243
26301
  isexe(path4, options3 || {}, function(er, is2) {
26244
26302
  if (er) {
26245
26303
  reject(er);
26246
26304
  } else {
26247
- resolve8(is2);
26305
+ resolve9(is2);
26248
26306
  }
26249
26307
  });
26250
26308
  });
@@ -26306,27 +26364,27 @@ var require_which = __commonJS((exports, module) => {
26306
26364
  opt = {};
26307
26365
  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
26308
26366
  const found = [];
26309
- const step = (i2) => new Promise((resolve8, reject) => {
26367
+ const step = (i2) => new Promise((resolve9, reject) => {
26310
26368
  if (i2 === pathEnv.length)
26311
- return opt.all && found.length ? resolve8(found) : reject(getNotFoundError(cmd));
26369
+ return opt.all && found.length ? resolve9(found) : reject(getNotFoundError(cmd));
26312
26370
  const ppRaw = pathEnv[i2];
26313
26371
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
26314
26372
  const pCmd = path4.join(pathPart, cmd);
26315
26373
  const p2 = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
26316
- resolve8(subStep(p2, i2, 0));
26374
+ resolve9(subStep(p2, i2, 0));
26317
26375
  });
26318
- const subStep = (p2, i2, ii) => new Promise((resolve8, reject) => {
26376
+ const subStep = (p2, i2, ii) => new Promise((resolve9, reject) => {
26319
26377
  if (ii === pathExt.length)
26320
- return resolve8(step(i2 + 1));
26378
+ return resolve9(step(i2 + 1));
26321
26379
  const ext = pathExt[ii];
26322
26380
  isexe(p2 + ext, { pathExt: pathExtExe }, (er, is2) => {
26323
26381
  if (!er && is2) {
26324
26382
  if (opt.all)
26325
26383
  found.push(p2 + ext);
26326
26384
  else
26327
- return resolve8(p2 + ext);
26385
+ return resolve9(p2 + ext);
26328
26386
  }
26329
- return resolve8(subStep(p2, i2, ii + 1));
26387
+ return resolve9(subStep(p2, i2, ii + 1));
26330
26388
  });
26331
26389
  });
26332
26390
  return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
@@ -27264,8 +27322,8 @@ var init_validation = __esm(() => {
27264
27322
  // ../../node_modules/execa/lib/utils/deferred.js
27265
27323
  var createDeferred = () => {
27266
27324
  const methods = {};
27267
- const promise = new Promise((resolve8, reject) => {
27268
- Object.assign(methods, { resolve: resolve8, reject });
27325
+ const promise = new Promise((resolve9, reject) => {
27326
+ Object.assign(methods, { resolve: resolve9, reject });
27269
27327
  });
27270
27328
  return Object.assign(promise, methods);
27271
27329
  };
@@ -31608,10 +31666,10 @@ var initializeConcurrentStreams = () => ({
31608
31666
  const promises2 = weakMap.get(stream2);
31609
31667
  const promise = createDeferred();
31610
31668
  promises2.push(promise);
31611
- const resolve8 = promise.resolve.bind(promise);
31612
- return { resolve: resolve8, promises: promises2 };
31613
- }, waitForConcurrentStreams = async ({ resolve: resolve8, promises: promises2 }, subprocess) => {
31614
- resolve8();
31669
+ const resolve9 = promise.resolve.bind(promise);
31670
+ return { resolve: resolve9, promises: promises2 };
31671
+ }, waitForConcurrentStreams = async ({ resolve: resolve9, promises: promises2 }, subprocess) => {
31672
+ resolve9();
31615
31673
  const [isSubprocessExit] = await Promise.race([
31616
31674
  Promise.allSettled([true, subprocess]),
31617
31675
  Promise.all([false, ...promises2])
@@ -32314,7 +32372,7 @@ __export(exports_generate, {
32314
32372
  });
32315
32373
  import path10 from "path";
32316
32374
  import { getErrorMessage as getErrorMessage2 } from "@secondlayer/shared";
32317
- import { toCamelCase as toCamelCase7 } from "@secondlayer/stacks/clarity";
32375
+ import { toCamelCase as toCamelCase8 } from "@secondlayer/stacks/clarity";
32318
32376
  function isContractAddress(input4) {
32319
32377
  const contractIdPattern = /^(SP|ST|SM|SN)[A-Z0-9]{38,}\.[a-zA-Z][a-zA-Z0-9-]*$/;
32320
32378
  return contractIdPattern.test(input4);
@@ -32375,7 +32433,7 @@ async function buildConfigFromInputs(parsedInputs, outPath, apiKey, defaultAddre
32375
32433
  const apiClient = new StacksApiClient(network, apiKey);
32376
32434
  const contractInfo = await apiClient.getContractInfo(contractId);
32377
32435
  const abi = parseApiResponse(contractInfo);
32378
- const name = toCamelCase7(contractName);
32436
+ const name = toCamelCase8(contractName);
32379
32437
  contracts.push({
32380
32438
  name,
32381
32439
  address: contractId,
@@ -32620,7 +32678,7 @@ var {
32620
32678
  // package.json
32621
32679
  var package_default = {
32622
32680
  name: "@secondlayer/cli",
32623
- version: "1.10.0",
32681
+ version: "1.11.0",
32624
32682
  description: "CLI for streams, subgraphs, and real-time blockchain indexing on Stacks",
32625
32683
  type: "module",
32626
32684
  bin: {
@@ -32661,10 +32719,11 @@ var package_default = {
32661
32719
  license: "MIT",
32662
32720
  dependencies: {
32663
32721
  "@inquirer/prompts": "^8.2.0",
32664
- "@secondlayer/sdk": "^0.9.0",
32665
- "@secondlayer/shared": "^0.10.0",
32722
+ "@secondlayer/sdk": "^0.10.0",
32723
+ "@secondlayer/shared": "^0.10.1",
32666
32724
  "@secondlayer/stacks": "^0.2.2",
32667
- "@secondlayer/subgraphs": "^0.8.0",
32725
+ "@secondlayer/subgraphs": "^0.9.0",
32726
+ "@secondlayer/workflows": "^0.0.1",
32668
32727
  "@biomejs/js-api": "^0.7.0",
32669
32728
  "@biomejs/wasm-nodejs": "^1.9.0",
32670
32729
  esbuild: "^0.19.0",
@@ -32685,6 +32744,52 @@ var package_default = {
32685
32744
  }
32686
32745
  };
32687
32746
 
32747
+ // src/commands/account.ts
32748
+ init_api_client();
32749
+ init_output();
32750
+ function registerAccountCommand(program2) {
32751
+ const account = program2.command("account").description("Manage your account profile");
32752
+ account.command("profile").description("View or update your public profile").option("--name <name>", "Set display name").option("--bio <bio>", "Set bio").option("--slug <slug>", "Set public URL slug").option("--json", "Output as JSON").action(async (options) => {
32753
+ try {
32754
+ const hasUpdates = options.name || options.bio || options.slug;
32755
+ if (hasUpdates) {
32756
+ const data = {};
32757
+ if (options.name)
32758
+ data.display_name = options.name;
32759
+ if (options.bio)
32760
+ data.bio = options.bio;
32761
+ if (options.slug)
32762
+ data.slug = options.slug;
32763
+ const updated = await updateAccountProfile(data);
32764
+ if (options.json) {
32765
+ console.log(JSON.stringify(updated, null, 2));
32766
+ return;
32767
+ }
32768
+ success("Profile updated");
32769
+ console.log(formatKeyValue([
32770
+ ["Display Name", updated.displayName ?? dim("—")],
32771
+ ["Bio", updated.bio ?? dim("—")],
32772
+ ["Slug", updated.slug ?? dim("—")]
32773
+ ]));
32774
+ return;
32775
+ }
32776
+ const profile = await getAccountProfile();
32777
+ if (options.json) {
32778
+ console.log(JSON.stringify(profile, null, 2));
32779
+ return;
32780
+ }
32781
+ console.log(formatKeyValue([
32782
+ ["Email", profile.email],
32783
+ ["Plan", profile.plan],
32784
+ ["Display Name", profile.displayName ?? dim("—")],
32785
+ ["Bio", profile.bio ?? dim("—")],
32786
+ ["Slug", profile.slug ?? dim("—")]
32787
+ ]));
32788
+ } catch (err) {
32789
+ handleApiError(err, "manage profile");
32790
+ }
32791
+ });
32792
+ }
32688
32793
  // src/commands/config.ts
32689
32794
  init_config();
32690
32795
 
@@ -35226,6 +35331,9 @@ function mapType(abiType, nullable) {
35226
35331
  }
35227
35332
 
35228
35333
  // src/generators/subgraph-scaffold.ts
35334
+ function toCamelCase(str) {
35335
+ return str.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
35336
+ }
35229
35337
  async function generateSubgraphScaffold(input2) {
35230
35338
  const { contractId, functions } = input2;
35231
35339
  const contractParts = contractId.split(".");
@@ -35235,6 +35343,12 @@ async function generateSubgraphScaffold(input2) {
35235
35343
  if (publicFunctions.length === 0) {
35236
35344
  throw new Error(`No public functions found in ${contractId}`);
35237
35345
  }
35346
+ const sourceEntries = publicFunctions.map((fn) => {
35347
+ const sourceName = toCamelCase(fn.name);
35348
+ return ` ${sourceName}: { type: 'contract_call', contractId: '${contractId}', functionName: '${fn.name}' }`;
35349
+ });
35350
+ const sourcesBlock = sourceEntries.join(`,
35351
+ `);
35238
35352
  const tables = publicFunctions.map((fn) => {
35239
35353
  const columns = fn.args.map((arg) => {
35240
35354
  const mapped = clarityTypeToSubgraphColumn(arg.type);
@@ -35251,14 +35365,15 @@ ${columns || " _placeholder: { type: 'text' }"}
35251
35365
  });
35252
35366
  const schemaBlock = tables.join(`,
35253
35367
  `);
35254
- const handlerKeys = publicFunctions.map((fn) => {
35255
- return ` '${contractId}::${fn.name}': async (event, ctx) => {
35368
+ const handlerEntries = publicFunctions.map((fn) => {
35369
+ const sourceName = toCamelCase(fn.name);
35370
+ return ` ${sourceName}: async (event, ctx) => {
35256
35371
  // TODO: implement ${fn.name} handler
35257
35372
  // event.args contains the function arguments
35258
35373
  // ctx.insert('${fn.name.replace(/-/g, "_")}', { ... })
35259
35374
  }`;
35260
35375
  });
35261
- const handlersBlock = handlerKeys.join(`,
35376
+ const handlersBlock = handlerEntries.join(`,
35262
35377
 
35263
35378
  `);
35264
35379
  const code = `
@@ -35266,7 +35381,9 @@ import { defineSubgraph } from '@secondlayer/subgraphs';
35266
35381
 
35267
35382
  export default defineSubgraph({
35268
35383
  name: '${subgraphName}',
35269
- sources: [{ contract: '${contractId}' }],
35384
+ sources: {
35385
+ ${sourcesBlock}
35386
+ },
35270
35387
  schema: {
35271
35388
  ${schemaBlock}
35272
35389
  },
@@ -35279,12 +35396,12 @@ ${handlersBlock}
35279
35396
  }
35280
35397
 
35281
35398
  // src/utils/case-conversion.ts
35282
- import { toCamelCase } from "@secondlayer/stacks/clarity";
35399
+ import { toCamelCase as toCamelCase2 } from "@secondlayer/stacks/clarity";
35283
35400
  function capitalize(str) {
35284
35401
  return str.charAt(0).toUpperCase() + str.slice(1);
35285
35402
  }
35286
35403
  function toPascalCase(str) {
35287
- return capitalize(toCamelCase(str));
35404
+ return capitalize(toCamelCase2(str));
35288
35405
  }
35289
35406
 
35290
35407
  // src/generators/subgraphs.ts
@@ -35378,15 +35495,19 @@ export default defineSubgraph({
35378
35495
  description: "TODO: describe what this subgraph tracks",
35379
35496
 
35380
35497
  // Sources define what blockchain data this subgraph processes.
35381
- // Each source filters transactions/events by contract, type, function, or event.
35382
- // Examples:
35383
- // { contract: "SP000...::my-contract" } — all txs to a contract
35384
- // { contract: "SP000...::my-contract", event: "transfer" } — specific event
35385
- // { type: "stx_transfer", minAmount: 1000000n } — STX transfers >= 1 STX
35386
- // { contract: "*.pox-*" } — wildcard contract match
35387
- sources: [
35388
- { contract: "SP000000000000000000002Q6VF78.pox-4" },
35389
- ],
35498
+ // Each source is named the name becomes the handler key.
35499
+ //
35500
+ // Filter types:
35501
+ // { type: "ft_transfer", assetIdentifier: "SP...token::token-name" }
35502
+ // { type: "ft_mint", assetIdentifier: "SP...token::token-name" }
35503
+ // { type: "contract_call", contractId: "SP...contract", functionName: "swap" }
35504
+ // { type: "contract_deploy" }
35505
+ // { type: "print_event", contractId: "SP...contract", topic: "my-event" }
35506
+ // { type: "stx_transfer", minAmount: 1000000n }
35507
+ // { type: "nft_transfer", assetIdentifier: "SP...nft::nft-name" }
35508
+ sources: {
35509
+ handler: { type: "contract_call", contractId: "SP000000000000000000002Q6VF78.pox-4" },
35510
+ },
35390
35511
 
35391
35512
  // Schema defines the tables this subgraph creates.
35392
35513
  // Each table gets auto-columns: _id, _block_height, _tx_id, _created_at.
@@ -35398,20 +35519,18 @@ export default defineSubgraph({
35398
35519
  amount: { type: "uint" },
35399
35520
  memo: { type: "text", nullable: true },
35400
35521
  },
35401
- // Optional composite indexes
35402
- // indexes: [["sender", "amount"]],
35403
35522
  },
35404
35523
  },
35405
35524
 
35406
- // Handlers process matched events and write to your tables via the context.
35407
- // Keys match source patterns (use sourceKey format), or "*" as catch-all.
35408
- // Context methods: ctx.insert(), ctx.update(), ctx.delete()
35525
+ // Handlers process matched events. Keys must match source names.
35526
+ // Context: ctx.insert(), ctx.update(), ctx.upsert(), ctx.patch(),
35527
+ // ctx.patchOrInsert(), ctx.findOne(), ctx.findMany()
35409
35528
  handlers: {
35410
- "*": async (event, ctx) => {
35411
- await ctx.insert("data", {
35412
- sender: event.sender ?? event.tx?.sender,
35529
+ handler: (event, ctx) => {
35530
+ ctx.insert("data", {
35531
+ sender: ctx.tx.sender,
35413
35532
  amount: event.amount ?? 0,
35414
- memo: event.memo ?? null,
35533
+ memo: null,
35415
35534
  });
35416
35535
  },
35417
35536
  },
@@ -35520,12 +35639,11 @@ Stopped watching.`);
35520
35639
  write: false
35521
35640
  });
35522
35641
  const handlerCode = new TextDecoder().decode(buildResult.outputFiles[0].contents);
35523
- const { sourceKey } = await import("@secondlayer/subgraphs");
35524
35642
  const result = await deploySubgraphApi({
35525
35643
  name: def.name,
35526
35644
  version: def.version,
35527
35645
  description: def.description,
35528
- sources: def.sources.map(sourceKey),
35646
+ sources: def.sources,
35529
35647
  schema: def.schema,
35530
35648
  handlerCode,
35531
35649
  reindex: options2.reindex
@@ -35781,6 +35899,37 @@ ${rows.length} row(s)`));
35781
35899
  handleApiError(err, "delete subgraph");
35782
35900
  }
35783
35901
  });
35902
+ subgraphs.command("publish <name>").description("Publish a subgraph to the marketplace").option("--tags <tags>", "Tags (comma-separated, max 5)").option("--description <desc>", "Public description (max 500 chars)").option("--json", "Output as JSON").action(async (name, options2) => {
35903
+ try {
35904
+ const opts = {};
35905
+ if (options2.tags) {
35906
+ opts.tags = options2.tags.split(",").map((t) => t.trim());
35907
+ }
35908
+ if (options2.description) {
35909
+ opts.description = options2.description;
35910
+ }
35911
+ const result = await publishSubgraphApi(name, opts);
35912
+ if (options2.json) {
35913
+ console.log(JSON.stringify(result, null, 2));
35914
+ return;
35915
+ }
35916
+ success(result.message);
35917
+ } catch (err) {
35918
+ handleApiError(err, "publish subgraph");
35919
+ }
35920
+ });
35921
+ subgraphs.command("unpublish <name>").description("Remove a subgraph from the marketplace").option("--json", "Output as JSON").action(async (name, options2) => {
35922
+ try {
35923
+ const result = await unpublishSubgraphApi(name);
35924
+ if (options2.json) {
35925
+ console.log(JSON.stringify(result, null, 2));
35926
+ return;
35927
+ }
35928
+ success(result.message);
35929
+ } catch (err) {
35930
+ handleApiError(err, "unpublish subgraph");
35931
+ }
35932
+ });
35784
35933
  subgraphs.command("scaffold <contractAddress>").description("Scaffold a defineSubgraph() file from a contract ABI").option("-o, --output <path>", "Output file path (required)").option("--api-key <key>", "Hiro API key").action(async (contractAddress, options2) => {
35785
35934
  try {
35786
35935
  if (!options2.output) {
@@ -36951,6 +37100,87 @@ function formatDeliverySummary2(jsonStr) {
36951
37100
  return null;
36952
37101
  }
36953
37102
  }
37103
+ // src/commands/marketplace.ts
37104
+ init_api_client();
37105
+ init_output();
37106
+ function registerMarketplaceCommand(program2) {
37107
+ const marketplace = program2.command("marketplace").alias("mp").description("Browse the public subgraph marketplace");
37108
+ marketplace.command("browse").description("List public subgraphs").option("--tags <tags>", "Filter by tags (comma-separated)").option("--search <query>", "Search by name or description").option("--sort <field>", "Sort by: recent, popular, name", "recent").option("--limit <n>", "Max results", "20").option("--json", "Output as JSON").action(async (options2) => {
37109
+ try {
37110
+ const result = await browseMarketplace({
37111
+ tags: options2.tags ? options2.tags.split(",").map((t) => t.trim()) : undefined,
37112
+ search: options2.search,
37113
+ sort: options2.sort,
37114
+ limit: Number.parseInt(options2.limit ?? "20", 10)
37115
+ });
37116
+ if (options2.json) {
37117
+ console.log(JSON.stringify(result, null, 2));
37118
+ return;
37119
+ }
37120
+ if (result.data.length === 0) {
37121
+ console.log(dim("No public subgraphs found"));
37122
+ return;
37123
+ }
37124
+ const rows = result.data.map((s) => [
37125
+ s.name,
37126
+ s.creator?.displayName ?? s.creator?.slug ?? dim("—"),
37127
+ (s.tags ?? []).join(", ") || dim("—"),
37128
+ s.status
37129
+ ]);
37130
+ console.log(formatTable(["Name", "Creator", "Tags", "Status"], rows));
37131
+ console.log(dim(`
37132
+ ${result.meta.total} subgraph(s) total`));
37133
+ } catch (err) {
37134
+ handleApiError(err, "browse marketplace");
37135
+ }
37136
+ });
37137
+ marketplace.command("view <name>").description("View a public subgraph's details").option("--json", "Output as JSON").action(async (name, options2) => {
37138
+ try {
37139
+ const detail = await getMarketplaceSubgraph(name);
37140
+ if (options2.json) {
37141
+ console.log(JSON.stringify(detail, null, 2));
37142
+ return;
37143
+ }
37144
+ console.log(formatKeyValue([
37145
+ ["Name", detail.name],
37146
+ ["Description", detail.description ?? dim("—")],
37147
+ ["Creator", detail.creator?.displayName ?? detail.creator?.slug ?? dim("—")],
37148
+ ["Status", detail.status],
37149
+ ["Version", detail.version],
37150
+ ["Tags", (detail.tags ?? []).join(", ") || dim("—")],
37151
+ ["Tables", detail.tables?.join(", ") ?? dim("—")],
37152
+ ["Start Block", String(detail.startBlock)],
37153
+ ["Last Processed", String(detail.lastProcessedBlock)],
37154
+ ["Queries (7d)", String(detail.usage?.totalQueries7d ?? 0)],
37155
+ ["Queries (30d)", String(detail.usage?.totalQueries30d ?? 0)],
37156
+ ["Created", detail.createdAt]
37157
+ ]));
37158
+ if (detail.tableSchemas) {
37159
+ console.log(dim(`
37160
+ Endpoints:`));
37161
+ for (const [table, schema] of Object.entries(detail.tableSchemas)) {
37162
+ console.log(` ${cyan(table)} — ${schema.rowCount} rows — ${schema.endpoint}`);
37163
+ }
37164
+ }
37165
+ } catch (err) {
37166
+ handleApiError(err, "view subgraph");
37167
+ }
37168
+ });
37169
+ marketplace.command("fork <name>").description("Fork a public subgraph into your account").option("--name <newName>", "Name for the forked subgraph").option("--json", "Output as JSON").action(async (name, options2) => {
37170
+ try {
37171
+ const result = await forkMarketplaceSubgraph(name, options2.name);
37172
+ if (options2.json) {
37173
+ console.log(JSON.stringify(result, null, 2));
37174
+ return;
37175
+ }
37176
+ success(`Forked ${result.forkedFrom} as ${result.name}`);
37177
+ console.log(dim(`Subgraph ID: ${result.subgraphId}`));
37178
+ console.log(dim("Indexing will start automatically from the source's start block."));
37179
+ } catch (err) {
37180
+ handleApiError(err, "fork subgraph");
37181
+ }
37182
+ });
37183
+ }
36954
37184
  // src/commands/whoami.ts
36955
37185
  init_api_client();
36956
37186
  init_config();
@@ -36987,9 +37217,180 @@ function registerWhoamiCommand(program2) {
36987
37217
  }
36988
37218
  });
36989
37219
  }
37220
+ // src/commands/workflows.ts
37221
+ init_output();
37222
+ import { existsSync as existsSync2 } from "node:fs";
37223
+ import { resolve as resolve7 } from "node:path";
37224
+ import { SecondLayer as SecondLayer2 } from "@secondlayer/sdk";
37225
+ function getClient2() {
37226
+ const apiKey = process.env.SECONDLAYER_API_KEY;
37227
+ if (!apiKey) {
37228
+ error("SECONDLAYER_API_KEY required. Run: sl auth login");
37229
+ process.exit(1);
37230
+ }
37231
+ return new SecondLayer2({ apiKey });
37232
+ }
37233
+ function registerWorkflowsCommand(program2) {
37234
+ const workflows = program2.command("workflows").description("Manage workflows");
37235
+ workflows.command("deploy <file>").description("Validate and deploy a workflow definition file").action(async (file) => {
37236
+ try {
37237
+ const absPath = resolve7(file);
37238
+ if (!existsSync2(absPath)) {
37239
+ error(`File not found: ${absPath}`);
37240
+ process.exit(1);
37241
+ }
37242
+ info(`Loading workflow from ${absPath}`);
37243
+ const mod = await import(absPath);
37244
+ const def = mod.default ?? mod;
37245
+ const { validateWorkflowDefinition } = await import("@secondlayer/workflows/validate");
37246
+ const result = validateWorkflowDefinition(def);
37247
+ success(`Workflow "${result.name}" is valid`);
37248
+ info(`Trigger: ${result.trigger.type}`);
37249
+ if (result.retries) {
37250
+ info(`Retries: maxAttempts=${result.retries.maxAttempts ?? "default"}`);
37251
+ }
37252
+ if (result.timeout) {
37253
+ info(`Timeout: ${result.timeout}ms`);
37254
+ }
37255
+ } catch (err) {
37256
+ error(`Failed to validate workflow: ${err}`);
37257
+ process.exit(1);
37258
+ }
37259
+ });
37260
+ workflows.command("list").alias("ls").description("List all workflows").option("--json", "Output as JSON").action(async (options2) => {
37261
+ try {
37262
+ const { workflows: items } = await getClient2().workflows.list();
37263
+ if (options2.json) {
37264
+ console.log(JSON.stringify(items, null, 2));
37265
+ return;
37266
+ }
37267
+ if (items.length === 0) {
37268
+ console.log("No workflows deployed");
37269
+ return;
37270
+ }
37271
+ const rows = items.map((w) => {
37272
+ const statusColor = w.status === "active" ? green : yellow;
37273
+ return [
37274
+ w.name,
37275
+ statusColor(w.status),
37276
+ w.triggerType,
37277
+ w.createdAt
37278
+ ];
37279
+ });
37280
+ console.log(formatTable(["Name", "Status", "Trigger", "Created"], rows));
37281
+ console.log(dim(`
37282
+ ${items.length} workflow(s) total`));
37283
+ } catch (err) {
37284
+ error(`Failed to list workflows: ${err}`);
37285
+ process.exit(1);
37286
+ }
37287
+ });
37288
+ workflows.command("get <name>").description("Get workflow details").option("--json", "Output as JSON").action(async (name, options2) => {
37289
+ try {
37290
+ const detail = await getClient2().workflows.get(name);
37291
+ if (options2.json) {
37292
+ console.log(JSON.stringify(detail, null, 2));
37293
+ return;
37294
+ }
37295
+ console.log(formatKeyValue([
37296
+ ["Name", detail.name],
37297
+ ["Status", detail.status],
37298
+ ["Trigger", detail.triggerType],
37299
+ ["Total Runs", String(detail.totalRuns)],
37300
+ ["Last Run", detail.lastRunAt ?? "never"],
37301
+ ["Timeout", detail.timeout ? `${detail.timeout}ms` : "default"],
37302
+ ["Created", detail.createdAt],
37303
+ ["Updated", detail.updatedAt]
37304
+ ]));
37305
+ } catch (err) {
37306
+ error(`Failed to get workflow: ${err}`);
37307
+ process.exit(1);
37308
+ }
37309
+ });
37310
+ workflows.command("trigger <name>").description("Trigger a workflow run").option("--input <json>", "Input JSON string").action(async (name, options2) => {
37311
+ try {
37312
+ const input4 = options2.input ? JSON.parse(options2.input) : undefined;
37313
+ const result = await getClient2().workflows.trigger(name, input4);
37314
+ success(`Triggered workflow "${name}"`);
37315
+ info(`Run ID: ${result.runId}`);
37316
+ } catch (err) {
37317
+ error(`Failed to trigger workflow: ${err}`);
37318
+ process.exit(1);
37319
+ }
37320
+ });
37321
+ workflows.command("runs <name>").description("List runs for a workflow").option("--status <status>", "Filter by status").option("--limit <n>", "Max runs to return", "20").option("--json", "Output as JSON").action(async (name, options2) => {
37322
+ try {
37323
+ const { runs } = await getClient2().workflows.listRuns(name, {
37324
+ status: options2.status,
37325
+ limit: options2.limit ? Number.parseInt(options2.limit, 10) : undefined
37326
+ });
37327
+ if (options2.json) {
37328
+ console.log(JSON.stringify(runs, null, 2));
37329
+ return;
37330
+ }
37331
+ if (runs.length === 0) {
37332
+ console.log("No runs found");
37333
+ return;
37334
+ }
37335
+ const rows = runs.map((r) => {
37336
+ const statusColor = r.status === "completed" ? green : r.status === "failed" ? (s) => `\x1B[31m${s}\x1B[0m` : yellow;
37337
+ return [
37338
+ r.id.slice(0, 8),
37339
+ statusColor(r.status),
37340
+ `${r.duration}ms`,
37341
+ String(r.aiTokensUsed),
37342
+ r.triggeredAt
37343
+ ];
37344
+ });
37345
+ console.log(formatTable(["ID", "Status", "Duration", "AI Tokens", "Triggered"], rows));
37346
+ console.log(dim(`
37347
+ ${runs.length} run(s)`));
37348
+ } catch (err) {
37349
+ error(`Failed to list runs: ${err}`);
37350
+ process.exit(1);
37351
+ }
37352
+ });
37353
+ workflows.command("pause <name>").description("Pause a workflow").action(async (name) => {
37354
+ try {
37355
+ await getClient2().workflows.pause(name);
37356
+ success(`Paused workflow "${name}"`);
37357
+ } catch (err) {
37358
+ error(`Failed to pause workflow: ${err}`);
37359
+ process.exit(1);
37360
+ }
37361
+ });
37362
+ workflows.command("resume <name>").description("Resume a paused workflow").action(async (name) => {
37363
+ try {
37364
+ await getClient2().workflows.resume(name);
37365
+ success(`Resumed workflow "${name}"`);
37366
+ } catch (err) {
37367
+ error(`Failed to resume workflow: ${err}`);
37368
+ process.exit(1);
37369
+ }
37370
+ });
37371
+ workflows.command("delete <name>").description("Delete a workflow").option("-y, --yes", "Skip confirmation").action(async (name, options2) => {
37372
+ try {
37373
+ if (!options2.yes) {
37374
+ const { confirm: confirm7 } = await import("@inquirer/prompts");
37375
+ const ok = await confirm7({
37376
+ message: `Delete workflow "${name}"? This cannot be undone.`
37377
+ });
37378
+ if (!ok) {
37379
+ info("Cancelled");
37380
+ return;
37381
+ }
37382
+ }
37383
+ await getClient2().workflows.delete(name);
37384
+ success(`Deleted workflow "${name}"`);
37385
+ } catch (err) {
37386
+ error(`Failed to delete workflow: ${err}`);
37387
+ process.exit(1);
37388
+ }
37389
+ });
37390
+ }
36990
37391
  // src/cli.ts
36991
37392
  var { version } = package_default;
36992
- program.name("secondlayer").alias("sl").description("SecondLayer CLI — streams, subgraphs, and real-time indexing for Stacks").version(version).option("--network <network>", "Override network (local, testnet, mainnet)");
37393
+ program.name("secondlayer").alias("sl").description("SecondLayer CLI — streams, subgraphs, workflows, and real-time indexing for Stacks").version(version).option("--network <network>", "Override network (local, testnet, mainnet)");
36993
37394
  program.hook("preAction", (thisCommand) => {
36994
37395
  const net3 = thisCommand.opts().network;
36995
37396
  if (net3)
@@ -37012,8 +37413,11 @@ program.command("init").description("Initialize a new secondlayer.config.ts file
37012
37413
  });
37013
37414
  registerStreamsCommand(program);
37014
37415
  registerSubgraphsCommand(program);
37416
+ registerWorkflowsCommand(program);
37417
+ registerMarketplaceCommand(program);
37015
37418
  registerStatusCommand(program);
37016
37419
  registerLocalCommand(program);
37420
+ registerAccountCommand(program);
37017
37421
  registerStackCommand(program);
37018
37422
  registerDbCommand(program);
37019
37423
  registerSyncCommand(program);
@@ -37025,5 +37429,5 @@ registerWhoamiCommand(program);
37025
37429
  registerReceiverCommand(program);
37026
37430
  program.parse();
37027
37431
 
37028
- //# debugId=2406566DC849ADA464756E2164756E21
37432
+ //# debugId=48CCB0723E8C164C64756E2164756E21
37029
37433
  //# sourceMappingURL=cli.js.map