@secondlayer/cli 10.4.0 → 11.0.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 +95 -454
- package/dist/cli.js.map +10 -14
- package/package.json +6 -6
package/dist/cli.js
CHANGED
|
@@ -2772,118 +2772,6 @@ var init_output = __esm(() => {
|
|
|
2772
2772
|
ANSI_ESCAPE_PATTERN = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
|
|
2773
2773
|
});
|
|
2774
2774
|
|
|
2775
|
-
// src/lib/api-client.ts
|
|
2776
|
-
import { ApiError, SecondLayer } from "@secondlayer/sdk";
|
|
2777
|
-
function nextStepHint(status) {
|
|
2778
|
-
if (status === undefined)
|
|
2779
|
-
return;
|
|
2780
|
-
if (status === 403)
|
|
2781
|
-
return "You may not have access — check your active project with `secondlayer whoami`.";
|
|
2782
|
-
if (status === 404)
|
|
2783
|
-
return "Check the name/slug — run the matching `list` command to see what exists.";
|
|
2784
|
-
if (status === 400 || status === 422)
|
|
2785
|
-
return "Check the command arguments and flags — see `--help` for the expected format.";
|
|
2786
|
-
if (status === 429)
|
|
2787
|
-
return "Rate limited — wait a moment and retry.";
|
|
2788
|
-
if (status >= 500)
|
|
2789
|
-
return "Server error — retry shortly, or check `secondlayer status`.";
|
|
2790
|
-
return;
|
|
2791
|
-
}
|
|
2792
|
-
function handleApiError(err, action) {
|
|
2793
|
-
const status = err instanceof ApiError || err instanceof CliHttpError ? err.status : undefined;
|
|
2794
|
-
if (err instanceof CliHttpError && err.code === "SESSION_EXPIRED" || status === 401) {
|
|
2795
|
-
printError("Authentication required.", {
|
|
2796
|
-
hint: isOssMode() ? "Set SL_API_KEY / INSTANCE_TOKEN from `secondlayer init`." : "Run `secondlayer login` to re-authenticate."
|
|
2797
|
-
});
|
|
2798
|
-
process.exit(1);
|
|
2799
|
-
}
|
|
2800
|
-
const detail = err instanceof Error ? err.message : String(err);
|
|
2801
|
-
printError(`Failed to ${action}: ${detail}`, { hint: nextStepHint(status) });
|
|
2802
|
-
process.exit(1);
|
|
2803
|
-
}
|
|
2804
|
-
function withErrorHandling(fn, options) {
|
|
2805
|
-
return async (...args) => {
|
|
2806
|
-
try {
|
|
2807
|
-
await fn(...args);
|
|
2808
|
-
} catch (err) {
|
|
2809
|
-
if (options?.onError) {
|
|
2810
|
-
options.onError(err);
|
|
2811
|
-
} else {
|
|
2812
|
-
handleApiError(err, options?.action ?? "execute command");
|
|
2813
|
-
}
|
|
2814
|
-
}
|
|
2815
|
-
};
|
|
2816
|
-
}
|
|
2817
|
-
async function getPlatformClient() {
|
|
2818
|
-
const { apiUrl, ephemeralKey } = await resolveAuth();
|
|
2819
|
-
return new SecondLayer({ baseUrl: apiUrl, apiKey: ephemeralKey });
|
|
2820
|
-
}
|
|
2821
|
-
async function listSubgraphsApi() {
|
|
2822
|
-
return (await getPlatformClient()).subgraphs.list();
|
|
2823
|
-
}
|
|
2824
|
-
async function getSubgraphApi(name) {
|
|
2825
|
-
return (await getPlatformClient()).subgraphs.get(name);
|
|
2826
|
-
}
|
|
2827
|
-
async function getSubgraphOpenApi(name, options) {
|
|
2828
|
-
return (await getPlatformClient()).subgraphs.openapi(name, options);
|
|
2829
|
-
}
|
|
2830
|
-
async function getSubgraphAgentSchema(name, options) {
|
|
2831
|
-
return (await getPlatformClient()).subgraphs.schema(name, options);
|
|
2832
|
-
}
|
|
2833
|
-
async function getSubgraphMarkdown(name, options) {
|
|
2834
|
-
return (await getPlatformClient()).subgraphs.markdown(name, options);
|
|
2835
|
-
}
|
|
2836
|
-
async function reindexSubgraphApi(name) {
|
|
2837
|
-
return (await getPlatformClient()).subgraphs.reindex(name);
|
|
2838
|
-
}
|
|
2839
|
-
async function backfillSubgraphApi(name, options) {
|
|
2840
|
-
return (await getPlatformClient()).subgraphs.backfill(name, options);
|
|
2841
|
-
}
|
|
2842
|
-
async function stopSubgraphApi(name) {
|
|
2843
|
-
return (await getPlatformClient()).subgraphs.stop(name);
|
|
2844
|
-
}
|
|
2845
|
-
async function deleteSubgraphApi(name, options) {
|
|
2846
|
-
return (await getPlatformClient()).subgraphs.delete(name, options);
|
|
2847
|
-
}
|
|
2848
|
-
async function deploySubgraphApi(data) {
|
|
2849
|
-
return (await getPlatformClient()).subgraphs.deploy(data);
|
|
2850
|
-
}
|
|
2851
|
-
async function publishSubgraphApi(name) {
|
|
2852
|
-
return (await getPlatformClient()).subgraphs.publish(name);
|
|
2853
|
-
}
|
|
2854
|
-
async function unpublishSubgraphApi(name) {
|
|
2855
|
-
return (await getPlatformClient()).subgraphs.unpublish(name);
|
|
2856
|
-
}
|
|
2857
|
-
async function querySubgraphTable(name, table, params = {}) {
|
|
2858
|
-
return (await getPlatformClient()).subgraphs.queryTable(name, table, params);
|
|
2859
|
-
}
|
|
2860
|
-
async function querySubgraphTableCount(name, table, params = {}) {
|
|
2861
|
-
return (await getPlatformClient()).subgraphs.queryTableCount(name, table, params);
|
|
2862
|
-
}
|
|
2863
|
-
async function getSubgraphGaps(name, opts) {
|
|
2864
|
-
return (await getPlatformClient()).subgraphs.gaps(name, opts);
|
|
2865
|
-
}
|
|
2866
|
-
async function getContractPrintSchema(contractId) {
|
|
2867
|
-
let client;
|
|
2868
|
-
try {
|
|
2869
|
-
client = await getPlatformClient();
|
|
2870
|
-
} catch {
|
|
2871
|
-
client = new SecondLayer({ baseUrl: resolveApiUrl() });
|
|
2872
|
-
}
|
|
2873
|
-
return client.index.printSchema(contractId);
|
|
2874
|
-
}
|
|
2875
|
-
async function getAccountProfile() {
|
|
2876
|
-
return httpPlatform("/api/accounts/me");
|
|
2877
|
-
}
|
|
2878
|
-
async function updateAccountProfile(data) {
|
|
2879
|
-
return httpPlatform("/api/accounts/me", { method: "PATCH", body: data });
|
|
2880
|
-
}
|
|
2881
|
-
var init_api_client = __esm(() => {
|
|
2882
|
-
init_http();
|
|
2883
|
-
init_output();
|
|
2884
|
-
init_resolve_auth();
|
|
2885
|
-
});
|
|
2886
|
-
|
|
2887
2775
|
// ../../node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
2888
2776
|
function assembleStyles() {
|
|
2889
2777
|
const codes = new Map;
|
|
@@ -28400,6 +28288,93 @@ var init_subgraphs = __esm(() => {
|
|
|
28400
28288
|
init_format();
|
|
28401
28289
|
});
|
|
28402
28290
|
|
|
28291
|
+
// src/lib/api-client.ts
|
|
28292
|
+
import { ApiError, SecondLayer } from "@secondlayer/sdk";
|
|
28293
|
+
function nextStepHint(status) {
|
|
28294
|
+
if (status === undefined)
|
|
28295
|
+
return;
|
|
28296
|
+
if (status === 403)
|
|
28297
|
+
return "You may not have access — check your active project with `secondlayer whoami`.";
|
|
28298
|
+
if (status === 404)
|
|
28299
|
+
return "Check the name/slug — run the matching `list` command to see what exists.";
|
|
28300
|
+
if (status === 400 || status === 422)
|
|
28301
|
+
return "Check the command arguments and flags — see `--help` for the expected format.";
|
|
28302
|
+
if (status === 429)
|
|
28303
|
+
return "Rate limited — wait a moment and retry.";
|
|
28304
|
+
if (status >= 500)
|
|
28305
|
+
return "Server error — retry shortly, or check `secondlayer status`.";
|
|
28306
|
+
return;
|
|
28307
|
+
}
|
|
28308
|
+
function handleApiError(err, action2) {
|
|
28309
|
+
const status = err instanceof ApiError || err instanceof CliHttpError ? err.status : undefined;
|
|
28310
|
+
if (err instanceof CliHttpError && err.code === "SESSION_EXPIRED" || status === 401) {
|
|
28311
|
+
printError("Authentication required.", {
|
|
28312
|
+
hint: isOssMode() ? "Set SL_API_KEY / INSTANCE_TOKEN from `secondlayer init`." : "Run `secondlayer login` to re-authenticate."
|
|
28313
|
+
});
|
|
28314
|
+
process.exit(1);
|
|
28315
|
+
}
|
|
28316
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
28317
|
+
printError(`Failed to ${action2}: ${detail}`, { hint: nextStepHint(status) });
|
|
28318
|
+
process.exit(1);
|
|
28319
|
+
}
|
|
28320
|
+
async function getPlatformClient() {
|
|
28321
|
+
const { apiUrl, ephemeralKey } = await resolveAuth();
|
|
28322
|
+
return new SecondLayer({ baseUrl: apiUrl, apiKey: ephemeralKey });
|
|
28323
|
+
}
|
|
28324
|
+
async function listSubgraphsApi() {
|
|
28325
|
+
return (await getPlatformClient()).subgraphs.list();
|
|
28326
|
+
}
|
|
28327
|
+
async function getSubgraphApi(name) {
|
|
28328
|
+
return (await getPlatformClient()).subgraphs.get(name);
|
|
28329
|
+
}
|
|
28330
|
+
async function getSubgraphOpenApi(name, options3) {
|
|
28331
|
+
return (await getPlatformClient()).subgraphs.openapi(name, options3);
|
|
28332
|
+
}
|
|
28333
|
+
async function getSubgraphAgentSchema(name, options3) {
|
|
28334
|
+
return (await getPlatformClient()).subgraphs.schema(name, options3);
|
|
28335
|
+
}
|
|
28336
|
+
async function getSubgraphMarkdown(name, options3) {
|
|
28337
|
+
return (await getPlatformClient()).subgraphs.markdown(name, options3);
|
|
28338
|
+
}
|
|
28339
|
+
async function reindexSubgraphApi(name) {
|
|
28340
|
+
return (await getPlatformClient()).subgraphs.reindex(name);
|
|
28341
|
+
}
|
|
28342
|
+
async function backfillSubgraphApi(name, options3) {
|
|
28343
|
+
return (await getPlatformClient()).subgraphs.backfill(name, options3);
|
|
28344
|
+
}
|
|
28345
|
+
async function stopSubgraphApi(name) {
|
|
28346
|
+
return (await getPlatformClient()).subgraphs.stop(name);
|
|
28347
|
+
}
|
|
28348
|
+
async function deleteSubgraphApi(name, options3) {
|
|
28349
|
+
return (await getPlatformClient()).subgraphs.delete(name, options3);
|
|
28350
|
+
}
|
|
28351
|
+
async function deploySubgraphApi(data) {
|
|
28352
|
+
return (await getPlatformClient()).subgraphs.deploy(data);
|
|
28353
|
+
}
|
|
28354
|
+
async function querySubgraphTable(name, table, params = {}) {
|
|
28355
|
+
return (await getPlatformClient()).subgraphs.queryTable(name, table, params);
|
|
28356
|
+
}
|
|
28357
|
+
async function querySubgraphTableCount(name, table, params = {}) {
|
|
28358
|
+
return (await getPlatformClient()).subgraphs.queryTableCount(name, table, params);
|
|
28359
|
+
}
|
|
28360
|
+
async function getSubgraphGaps(name, opts) {
|
|
28361
|
+
return (await getPlatformClient()).subgraphs.gaps(name, opts);
|
|
28362
|
+
}
|
|
28363
|
+
async function getContractPrintSchema(contractId) {
|
|
28364
|
+
let client;
|
|
28365
|
+
try {
|
|
28366
|
+
client = await getPlatformClient();
|
|
28367
|
+
} catch {
|
|
28368
|
+
client = new SecondLayer({ baseUrl: resolveApiUrl() });
|
|
28369
|
+
}
|
|
28370
|
+
return client.index.printSchema(contractId);
|
|
28371
|
+
}
|
|
28372
|
+
var init_api_client = __esm(() => {
|
|
28373
|
+
init_http();
|
|
28374
|
+
init_output();
|
|
28375
|
+
init_resolve_auth();
|
|
28376
|
+
});
|
|
28377
|
+
|
|
28403
28378
|
// src/lib/fs.ts
|
|
28404
28379
|
import { mkdir as mkdir2, readFile as readFile2, stat, unlink, writeFile as writeFile2 } from "node:fs/promises";
|
|
28405
28380
|
async function readJsonFile(path11) {
|
|
@@ -29587,7 +29562,6 @@ import {
|
|
|
29587
29562
|
generatePrintPayloadTypes,
|
|
29588
29563
|
generatePrintSchemaSubgraph
|
|
29589
29564
|
} from "@secondlayer/scaffold";
|
|
29590
|
-
import { ByoBreakingChangeError } from "@secondlayer/sdk";
|
|
29591
29565
|
import { TRAIT_STANDARDS } from "@secondlayer/stacks/clarity";
|
|
29592
29566
|
async function loadSubgraphWithDepCheck(absPath) {
|
|
29593
29567
|
try {
|
|
@@ -29940,27 +29914,6 @@ ${dim("Columns")}`);
|
|
|
29940
29914
|
const deployTarget = context.bundled ? "tenant API" : "local database";
|
|
29941
29915
|
info(`Dry run only. No ${deployTarget} changes were made.`);
|
|
29942
29916
|
}
|
|
29943
|
-
function printByoBreakingPlan(details) {
|
|
29944
|
-
error("Refusing breaking schema change on BYO subgraph (no data dropped).");
|
|
29945
|
-
console.log(`
|
|
29946
|
-
Breaking changes:`);
|
|
29947
|
-
for (const r2 of details.reasons)
|
|
29948
|
-
console.log(` ${red("✗")} ${r2}`);
|
|
29949
|
-
console.log(`
|
|
29950
|
-
To rebuild manually, run on YOUR database:`);
|
|
29951
|
-
console.log(` ${details.plan.dropStatement}`);
|
|
29952
|
-
console.log(` ${details.plan.statements.join(`;
|
|
29953
|
-
`)}`);
|
|
29954
|
-
console.log(`
|
|
29955
|
-
Grant (first deploy only):`);
|
|
29956
|
-
for (const line of details.plan.grantScript.split(`
|
|
29957
|
-
`)) {
|
|
29958
|
-
console.log(` ${dim(line)}`);
|
|
29959
|
-
}
|
|
29960
|
-
console.log(`
|
|
29961
|
-
${yellow("This DROPS all rows in that schema, then rebuilds it. Re-deploy after.")}`);
|
|
29962
|
-
console.log(dim("(--force destructive rebuild not yet supported — manual DROP required.)"));
|
|
29963
|
-
}
|
|
29964
29917
|
function formatDuration(seconds2) {
|
|
29965
29918
|
if (seconds2 < 90)
|
|
29966
29919
|
return `${Math.max(1, Math.round(seconds2))}s`;
|
|
@@ -30140,7 +30093,7 @@ Stopped watching.`);
|
|
|
30140
30093
|
});
|
|
30141
30094
|
await new Promise(() => {});
|
|
30142
30095
|
});
|
|
30143
|
-
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("--
|
|
30096
|
+
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("--strict", "Run `tsc --noEmit` against the handler before deploy (slower; catches TS type errors)").addOption(new Option("--visibility <visibility>", "Hosted only. Public/private namespace.").hideHelp()).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) => {
|
|
30144
30097
|
try {
|
|
30145
30098
|
const absPath = resolve3(file);
|
|
30146
30099
|
if (!options3.dryRun) {
|
|
@@ -30173,15 +30126,6 @@ Stopped watching.`);
|
|
|
30173
30126
|
}
|
|
30174
30127
|
const dryRun = options3.dryRun;
|
|
30175
30128
|
const visibility = parseVisibilityOption(options3.visibility);
|
|
30176
|
-
if (visibility === "public" && options3.databaseUrl && !options3.yes) {
|
|
30177
|
-
const confirmed = await confirm3({
|
|
30178
|
-
message: "⚠ Public BYO subgraph: anonymous reads will query YOUR database. Continue?"
|
|
30179
|
-
});
|
|
30180
|
-
if (!confirmed) {
|
|
30181
|
-
info("Aborted.");
|
|
30182
|
-
process.exit(0);
|
|
30183
|
-
}
|
|
30184
|
-
}
|
|
30185
30129
|
const startBlock = parseStartBlockOption(options3.startBlock);
|
|
30186
30130
|
if (startBlock !== undefined) {
|
|
30187
30131
|
warn(`--start-block ${startBlock} overrides the definition's startBlock for this deploy.`);
|
|
@@ -30246,9 +30190,6 @@ Stopped watching.`);
|
|
|
30246
30190
|
}
|
|
30247
30191
|
}
|
|
30248
30192
|
}
|
|
30249
|
-
if (options3.databaseUrl) {
|
|
30250
|
-
info("BYO data plane: schema + rows will live in your database. The server verifies the connection before deploying.");
|
|
30251
|
-
}
|
|
30252
30193
|
const result = await deploySubgraphApi({
|
|
30253
30194
|
name: effectiveDef.name,
|
|
30254
30195
|
version: undefined,
|
|
@@ -30258,12 +30199,8 @@ Stopped watching.`);
|
|
|
30258
30199
|
handlerCode,
|
|
30259
30200
|
sourceCode: source,
|
|
30260
30201
|
...deployStartBlock !== undefined ? { startBlock: deployStartBlock } : {},
|
|
30261
|
-
...options3.databaseUrl ? { databaseUrl: options3.databaseUrl } : {},
|
|
30262
30202
|
...visibility ? { visibility } : {}
|
|
30263
30203
|
});
|
|
30264
|
-
if (result.start_block_clamped) {
|
|
30265
|
-
info(` Free tier indexes forward from deploy (start block ${result.start_block}) — upgrade for genesis backfill.`);
|
|
30266
|
-
}
|
|
30267
30204
|
for (const w2 of result.warnings ?? [])
|
|
30268
30205
|
warn(w2);
|
|
30269
30206
|
const printDeployFooter = async () => {
|
|
@@ -30276,7 +30213,6 @@ Stopped watching.`);
|
|
|
30276
30213
|
info(` Share: ${apiUrl}/v1/subgraphs/${effectiveDef.name} (public — no key needed)`);
|
|
30277
30214
|
} else if (firstTable) {
|
|
30278
30215
|
info(` REST: ${apiUrl}/api/subgraphs/${effectiveDef.name}/${firstTable}`);
|
|
30279
|
-
info(` Publish: secondlayer subgraphs publish ${effectiveDef.name} (open anon /v1 reads)`);
|
|
30280
30216
|
}
|
|
30281
30217
|
if (result.reindexStarted) {
|
|
30282
30218
|
const denom = result.estimatedEvents != null ? ` ~${result.estimatedEvents.toLocaleString()} events —` : "";
|
|
@@ -30356,14 +30292,6 @@ Stopped watching.`);
|
|
|
30356
30292
|
await closeDb();
|
|
30357
30293
|
}
|
|
30358
30294
|
} catch (err) {
|
|
30359
|
-
if (err instanceof ByoBreakingChangeError) {
|
|
30360
|
-
printByoBreakingPlan(err.details);
|
|
30361
|
-
process.exit(1);
|
|
30362
|
-
}
|
|
30363
|
-
if (err && typeof err === "object" && err.code === "BYO_BREAKING_CHANGE" && err.details) {
|
|
30364
|
-
printByoBreakingPlan(err.details);
|
|
30365
|
-
process.exit(1);
|
|
30366
|
-
}
|
|
30367
30295
|
error(`Failed to deploy subgraph: ${err}`);
|
|
30368
30296
|
process.exit(1);
|
|
30369
30297
|
}
|
|
@@ -30700,33 +30628,6 @@ ${rows.length} row(s)`));
|
|
|
30700
30628
|
handleApiError(err, "delete subgraph");
|
|
30701
30629
|
}
|
|
30702
30630
|
});
|
|
30703
|
-
subgraphs.command("publish <name>", { hidden: true }).description("Make a subgraph publicly readable on /v1/subgraphs/<name> (claims the name globally, no key needed to read)").action(async (name) => {
|
|
30704
|
-
try {
|
|
30705
|
-
await requireAuth();
|
|
30706
|
-
const result = await publishSubgraphApi(name);
|
|
30707
|
-
success(`Subgraph "${name}" is now public`);
|
|
30708
|
-
try {
|
|
30709
|
-
const { apiUrl } = await resolveAuth();
|
|
30710
|
-
info(` Share: ${apiUrl}${result.url} (no key needed)`);
|
|
30711
|
-
} catch {}
|
|
30712
|
-
} catch (err) {
|
|
30713
|
-
const status = err?.status;
|
|
30714
|
-
if (status === 409) {
|
|
30715
|
-
error(`Public name "${name}" is already taken by another account. Rename the subgraph (redeploy under a new name) or keep it private.`);
|
|
30716
|
-
process.exit(1);
|
|
30717
|
-
}
|
|
30718
|
-
handleApiError(err, "publish subgraph");
|
|
30719
|
-
}
|
|
30720
|
-
});
|
|
30721
|
-
subgraphs.command("unpublish <name>", { hidden: true }).description("Make a subgraph private again — reads require your API key, the public name claim is released").action(async (name) => {
|
|
30722
|
-
try {
|
|
30723
|
-
await requireAuth();
|
|
30724
|
-
await unpublishSubgraphApi(name);
|
|
30725
|
-
success(`Subgraph "${name}" is now private (reads need your key)`);
|
|
30726
|
-
} catch (err) {
|
|
30727
|
-
handleApiError(err, "unpublish subgraph");
|
|
30728
|
-
}
|
|
30729
|
-
});
|
|
30730
30631
|
subgraphs.command("scaffold [contractAddress]").description("Scaffold a defineSubgraph() file from a contract or trait").option("-o, --output <path>", "Output file path (required)").option("-k, --api-key <key>", "Stacks node API key for direct RPC URLs").option("--functions <names>", "Comma-separated public functions to index as typed contract_call tables").option("--trait <std>", "Scaffold a trait-scoped source (sip-009|sip-010|sip-013) — no contract needed").option("--no-install", "Skip bun install after writing package.json").addHelpText("after", `
|
|
30731
30632
|
Examples:
|
|
30732
30633
|
$ secondlayer subgraphs scaffold SP3D6PV2ACBPEKYJTCMH7HEN02KP87QSP8KTEH335.megapont-ape-club-nft -o subgraphs/apes.ts
|
|
@@ -34789,7 +34690,7 @@ init_esm();
|
|
|
34789
34690
|
// package.json
|
|
34790
34691
|
var package_default = {
|
|
34791
34692
|
name: "@secondlayer/cli",
|
|
34792
|
-
version: "
|
|
34693
|
+
version: "11.0.0",
|
|
34793
34694
|
repository: {
|
|
34794
34695
|
type: "git",
|
|
34795
34696
|
url: "git+https://github.com/ryanwaits/secondlayer.git",
|
|
@@ -34830,12 +34731,12 @@ var package_default = {
|
|
|
34830
34731
|
"@biomejs/wasm-nodejs": "^1.9.0",
|
|
34831
34732
|
"@dsnp/parquetjs": "^1.8.8",
|
|
34832
34733
|
"@inquirer/prompts": "^8.2.0",
|
|
34833
|
-
"@secondlayer/bundler": "^0.5.
|
|
34834
|
-
"@secondlayer/scaffold": "^1.5.
|
|
34835
|
-
"@secondlayer/sdk": "^
|
|
34836
|
-
"@secondlayer/shared": "^
|
|
34734
|
+
"@secondlayer/bundler": "^0.5.1",
|
|
34735
|
+
"@secondlayer/scaffold": "^1.5.3",
|
|
34736
|
+
"@secondlayer/sdk": "^7.0.0",
|
|
34737
|
+
"@secondlayer/shared": "^8.0.0",
|
|
34837
34738
|
"@secondlayer/stacks": "^3.3.1",
|
|
34838
|
-
"@secondlayer/subgraphs": "^
|
|
34739
|
+
"@secondlayer/subgraphs": "^4.0.0",
|
|
34839
34740
|
esbuild: "^0.27.4",
|
|
34840
34741
|
"smol-toml": "^1.6.1",
|
|
34841
34742
|
zod: "^4.3.6"
|
|
@@ -34855,134 +34756,6 @@ var package_default = {
|
|
|
34855
34756
|
}
|
|
34856
34757
|
};
|
|
34857
34758
|
|
|
34858
|
-
// src/commands/account.ts
|
|
34859
|
-
init_api_client();
|
|
34860
|
-
init_output();
|
|
34861
|
-
|
|
34862
|
-
// src/commands/billing.ts
|
|
34863
|
-
init_http();
|
|
34864
|
-
init_output();
|
|
34865
|
-
async function runBillingStatus(json) {
|
|
34866
|
-
let res;
|
|
34867
|
-
try {
|
|
34868
|
-
res = await httpPlatform("/api/billing/status");
|
|
34869
|
-
} catch (err) {
|
|
34870
|
-
if (err instanceof CliHttpError) {
|
|
34871
|
-
error(err.message);
|
|
34872
|
-
process.exit(1);
|
|
34873
|
-
}
|
|
34874
|
-
throw err;
|
|
34875
|
-
}
|
|
34876
|
-
output({ json, data: res, human: () => renderBillingStatus(res) });
|
|
34877
|
-
}
|
|
34878
|
-
function addBillingCommand(parent) {
|
|
34879
|
-
parent.command("billing").description("Show archive credit balance (hidden; use secondlayer credits)").option("--json", "Output as JSON").action((options) => runBillingStatus(options.json));
|
|
34880
|
-
}
|
|
34881
|
-
function renderBillingStatus(res) {
|
|
34882
|
-
if (!res.subscription) {
|
|
34883
|
-
console.log(formatKeyValue([
|
|
34884
|
-
["Credits", dim("secondlayer credits balance")],
|
|
34885
|
-
[
|
|
34886
|
-
"Buy",
|
|
34887
|
-
dim("secondlayer credits buy --email you@example.com --pack 25")
|
|
34888
|
-
]
|
|
34889
|
-
]));
|
|
34890
|
-
return;
|
|
34891
|
-
}
|
|
34892
|
-
const rows = [];
|
|
34893
|
-
rows.push(["Plan", res.plan]);
|
|
34894
|
-
rows.push([
|
|
34895
|
-
"Customer",
|
|
34896
|
-
res.stripeCustomerId ?? dim("(none — no subscription yet)")
|
|
34897
|
-
]);
|
|
34898
|
-
const sub = res.subscription;
|
|
34899
|
-
rows.push(["Subscription", `${sub.id} (${sub.status})`]);
|
|
34900
|
-
if (sub.tier)
|
|
34901
|
-
rows.push(["Tier", sub.tier]);
|
|
34902
|
-
if (sub.amountCents !== null && sub.interval) {
|
|
34903
|
-
const dollars = (sub.amountCents / 100).toFixed(2);
|
|
34904
|
-
rows.push(["Price", `$${dollars} / ${sub.interval}`]);
|
|
34905
|
-
}
|
|
34906
|
-
if (sub.trialEnd) {
|
|
34907
|
-
const days = Math.max(0, Math.round((new Date(sub.trialEnd).getTime() - Date.now()) / 86400000));
|
|
34908
|
-
rows.push([
|
|
34909
|
-
"Trial ends",
|
|
34910
|
-
`${formatDate(sub.trialEnd)} (${days}d remaining)`
|
|
34911
|
-
]);
|
|
34912
|
-
}
|
|
34913
|
-
if (sub.currentPeriodEnd) {
|
|
34914
|
-
rows.push(["Renews", formatDate(sub.currentPeriodEnd)]);
|
|
34915
|
-
}
|
|
34916
|
-
if (sub.cancelAtPeriodEnd) {
|
|
34917
|
-
rows.push(["Cancels at period end", "yes"]);
|
|
34918
|
-
}
|
|
34919
|
-
if (sub.discount) {
|
|
34920
|
-
const off = sub.discount.percentOff !== null ? `${sub.discount.percentOff}% off` : sub.discount.amountOff !== null ? `$${(sub.discount.amountOff / 100).toFixed(2)} off` : "discount";
|
|
34921
|
-
const label = sub.discount.code ? `${sub.discount.code} (${sub.discount.name ?? "coupon"})` : sub.discount.name ?? "applied";
|
|
34922
|
-
rows.push(["Discount", `${label} — ${off}, ${sub.discount.duration}`]);
|
|
34923
|
-
}
|
|
34924
|
-
console.log(formatKeyValue(rows));
|
|
34925
|
-
}
|
|
34926
|
-
function formatDate(iso) {
|
|
34927
|
-
return new Date(iso).toISOString().slice(0, 10);
|
|
34928
|
-
}
|
|
34929
|
-
|
|
34930
|
-
// src/commands/account.ts
|
|
34931
|
-
async function showProfile(json) {
|
|
34932
|
-
const profile = await getAccountProfile();
|
|
34933
|
-
output({
|
|
34934
|
-
json,
|
|
34935
|
-
data: profile,
|
|
34936
|
-
human: () => console.log(formatKeyValue([
|
|
34937
|
-
["Email", profile.email],
|
|
34938
|
-
["Plan", profile.plan],
|
|
34939
|
-
["Display Name", profile.displayName ?? dim("—")],
|
|
34940
|
-
["Bio", profile.bio ?? dim("—")],
|
|
34941
|
-
["Slug", profile.slug ?? dim("—")],
|
|
34942
|
-
[
|
|
34943
|
-
"Notify on reindex complete",
|
|
34944
|
-
profile.notifyReindexComplete ? "on" : "off"
|
|
34945
|
-
]
|
|
34946
|
-
]))
|
|
34947
|
-
});
|
|
34948
|
-
}
|
|
34949
|
-
async function applyProfileUpdate(options, getOptionValueSource) {
|
|
34950
|
-
const data = {};
|
|
34951
|
-
if (options.name)
|
|
34952
|
-
data.display_name = options.name;
|
|
34953
|
-
if (options.bio)
|
|
34954
|
-
data.bio = options.bio;
|
|
34955
|
-
if (options.slug)
|
|
34956
|
-
data.slug = options.slug;
|
|
34957
|
-
if (getOptionValueSource("notifyReindexComplete") === "cli") {
|
|
34958
|
-
data.notify_reindex_complete = options.notifyReindexComplete;
|
|
34959
|
-
}
|
|
34960
|
-
const updated = await updateAccountProfile(data);
|
|
34961
|
-
output({
|
|
34962
|
-
json: options.json,
|
|
34963
|
-
data: updated,
|
|
34964
|
-
human: () => {
|
|
34965
|
-
success("Profile updated");
|
|
34966
|
-
console.log(formatKeyValue([
|
|
34967
|
-
["Display Name", updated.displayName ?? dim("—")],
|
|
34968
|
-
["Bio", updated.bio ?? dim("—")],
|
|
34969
|
-
["Slug", updated.slug ?? dim("—")],
|
|
34970
|
-
[
|
|
34971
|
-
"Notify on reindex complete",
|
|
34972
|
-
updated.notifyReindexComplete ? "on" : "off"
|
|
34973
|
-
]
|
|
34974
|
-
]));
|
|
34975
|
-
}
|
|
34976
|
-
});
|
|
34977
|
-
}
|
|
34978
|
-
function registerAccountCommand(program2) {
|
|
34979
|
-
const account = program2.command("account", { hidden: true }).description("Manage your account profile");
|
|
34980
|
-
addBillingCommand(account);
|
|
34981
|
-
account.command("get").description("Show your account profile").option("--json", "Output as JSON").action(withErrorHandling(async (options) => showProfile(options.json), { action: "show profile" }));
|
|
34982
|
-
account.command("update").description("Update your public profile").option("--name <name>", "Set display name").option("--bio <bio>", "Set bio").option("--slug <slug>", "Set public URL slug").option("--notify-reindex-complete", "Email me when a subgraph reindex finishes").option("--no-notify-reindex-complete", "Don't email me when a subgraph reindex finishes").option("--json", "Output as JSON").action(withErrorHandling(async (options, command) => applyProfileUpdate(options, (key) => command.getOptionValueSource(key)), {
|
|
34983
|
-
action: "update profile"
|
|
34984
|
-
}));
|
|
34985
|
-
}
|
|
34986
34759
|
// src/commands/credits.ts
|
|
34987
34760
|
init_http();
|
|
34988
34761
|
init_output();
|
|
@@ -37409,46 +37182,6 @@ Examples:
|
|
|
37409
37182
|
// src/commands/index.ts
|
|
37410
37183
|
init_index_api();
|
|
37411
37184
|
|
|
37412
|
-
// src/commands/keys.ts
|
|
37413
|
-
init_output();
|
|
37414
|
-
init_resolve_auth();
|
|
37415
|
-
import { SecondLayer as SecondLayer4 } from "@secondlayer/sdk";
|
|
37416
|
-
function registerKeysCommand(program2) {
|
|
37417
|
-
const keys = program2.command("keys", { hidden: true }).description("Manage API keys");
|
|
37418
|
-
keys.command("create").description("Mint a scoped streams/index read key (requires an account-level key)").option("--product <product>", "Key scope: streams or index", "streams").option("--name <name>", "Optional label for the key").option("--json", "Print the full response as JSON").action(async (o3) => {
|
|
37419
|
-
if (o3.product && o3.product !== "streams" && o3.product !== "index") {
|
|
37420
|
-
error("--product must be 'streams' or 'index'");
|
|
37421
|
-
process.exit(1);
|
|
37422
|
-
}
|
|
37423
|
-
const apiKey = resolveEnvKey();
|
|
37424
|
-
if (!apiKey) {
|
|
37425
|
-
error("No API key set. Export SL_API_KEY with an account-level key (issue one at https://www.secondlayer.tools/platform/api-keys).");
|
|
37426
|
-
process.exit(1);
|
|
37427
|
-
}
|
|
37428
|
-
try {
|
|
37429
|
-
const sl = new SecondLayer4({
|
|
37430
|
-
baseUrl: resolveApiUrl(),
|
|
37431
|
-
apiKey
|
|
37432
|
-
});
|
|
37433
|
-
const minted = await sl.apiKeys.create({
|
|
37434
|
-
product: o3.product === "index" ? "index" : "streams",
|
|
37435
|
-
name: o3.name
|
|
37436
|
-
});
|
|
37437
|
-
output({
|
|
37438
|
-
json: o3.json,
|
|
37439
|
-
data: minted,
|
|
37440
|
-
human: () => {
|
|
37441
|
-
success(`Created ${minted.product} key (${minted.prefix}…)`);
|
|
37442
|
-
note("This key is shown once — store it now:");
|
|
37443
|
-
writeData(minted.key);
|
|
37444
|
-
}
|
|
37445
|
-
});
|
|
37446
|
-
} catch (err) {
|
|
37447
|
-
error(err instanceof Error ? err.message : String(err));
|
|
37448
|
-
process.exit(1);
|
|
37449
|
-
}
|
|
37450
|
-
});
|
|
37451
|
-
}
|
|
37452
37185
|
// src/commands/doctor.ts
|
|
37453
37186
|
init_config2();
|
|
37454
37187
|
|
|
@@ -38662,14 +38395,6 @@ async function readActiveProject(cwd, globalDefault) {
|
|
|
38662
38395
|
}
|
|
38663
38396
|
return null;
|
|
38664
38397
|
}
|
|
38665
|
-
async function writeActiveProject(slug, cwd) {
|
|
38666
|
-
const dir = join13(resolve11(cwd), DIRNAME);
|
|
38667
|
-
await mkdir4(dir, { recursive: true });
|
|
38668
|
-
const file = join13(dir, FILENAME);
|
|
38669
|
-
await writeFile4(file, `${JSON.stringify({ slug }, null, 2)}
|
|
38670
|
-
`, "utf8");
|
|
38671
|
-
return file;
|
|
38672
|
-
}
|
|
38673
38398
|
|
|
38674
38399
|
// src/commands/whoami.ts
|
|
38675
38400
|
init_resolve_auth();
|
|
@@ -38699,7 +38424,6 @@ function registerWhoamiCommand(program2) {
|
|
|
38699
38424
|
json: options3.json,
|
|
38700
38425
|
data: {
|
|
38701
38426
|
email: account.email,
|
|
38702
|
-
plan: account.plan,
|
|
38703
38427
|
apiUrl: auth.apiUrl,
|
|
38704
38428
|
authSource,
|
|
38705
38429
|
project: active ? { slug: active.slug, source: active.resolvedFrom } : null
|
|
@@ -38707,7 +38431,6 @@ function registerWhoamiCommand(program2) {
|
|
|
38707
38431
|
human: () => {
|
|
38708
38432
|
const rows = [];
|
|
38709
38433
|
rows.push(["Email", account.email]);
|
|
38710
|
-
rows.push(["Plan", account.plan]);
|
|
38711
38434
|
rows.push(["API URL", auth.apiUrl]);
|
|
38712
38435
|
rows.push(["Auth", dim(authSource)]);
|
|
38713
38436
|
if (active) {
|
|
@@ -38750,85 +38473,6 @@ function registerLogoutCommand(program2) {
|
|
|
38750
38473
|
success("Logged out.");
|
|
38751
38474
|
});
|
|
38752
38475
|
}
|
|
38753
|
-
// src/commands/project.ts
|
|
38754
|
-
init_config2();
|
|
38755
|
-
init_http();
|
|
38756
|
-
init_output();
|
|
38757
|
-
function registerProjectCommand(program2) {
|
|
38758
|
-
const project = program2.command("projects", { hidden: true }).alias("project").description("Manage your Secondlayer project");
|
|
38759
|
-
project.command("list").alias("ls").description("List projects in your account").option("--json", "Output as JSON").action(async (options3) => {
|
|
38760
|
-
try {
|
|
38761
|
-
const res = await httpPlatform("/api/projects");
|
|
38762
|
-
const active = await readActiveProject(process.cwd(), (await loadConfig2()).defaultProject);
|
|
38763
|
-
output({
|
|
38764
|
-
json: options3.json,
|
|
38765
|
-
data: { projects: res.projects, active: active?.slug ?? null },
|
|
38766
|
-
human: () => {
|
|
38767
|
-
if (res.projects.length === 0) {
|
|
38768
|
-
info("No project found.");
|
|
38769
|
-
return;
|
|
38770
|
-
}
|
|
38771
|
-
const rows = res.projects.map((p2) => [
|
|
38772
|
-
p2.slug === active?.slug ? `* ${p2.slug}` : ` ${p2.slug}`,
|
|
38773
|
-
p2.name,
|
|
38774
|
-
p2.network,
|
|
38775
|
-
new Date(p2.createdAt).toLocaleDateString()
|
|
38776
|
-
]);
|
|
38777
|
-
console.log(formatTable(["", "Name", "Network", "Created"], rows));
|
|
38778
|
-
if (active) {
|
|
38779
|
-
console.log(dim(`Active: ${active.slug} (from ${active.resolvedFrom})`));
|
|
38780
|
-
}
|
|
38781
|
-
}
|
|
38782
|
-
});
|
|
38783
|
-
} catch (err) {
|
|
38784
|
-
handleProjectError(err);
|
|
38785
|
-
}
|
|
38786
|
-
});
|
|
38787
|
-
project.command("use <slug>").description("Bind this directory to a project (writes ./.secondlayer/project)").action(async (slug) => {
|
|
38788
|
-
try {
|
|
38789
|
-
await httpPlatform(`/api/projects/${encodeURIComponent(slug)}`);
|
|
38790
|
-
} catch (err) {
|
|
38791
|
-
if (err instanceof CliHttpError && err.status === 404) {
|
|
38792
|
-
error(`Project "${slug}" not found — run 'secondlayer project list' to see available projects`);
|
|
38793
|
-
process.exit(1);
|
|
38794
|
-
}
|
|
38795
|
-
handleProjectError(err);
|
|
38796
|
-
}
|
|
38797
|
-
const path11 = await writeActiveProject(slug, process.cwd());
|
|
38798
|
-
success(`Bound to project "${slug}"`);
|
|
38799
|
-
info(dim(`Written to ${path11}`));
|
|
38800
|
-
info(dim("Tip: add `.secondlayer/` to .gitignore — it's account-personal."));
|
|
38801
|
-
});
|
|
38802
|
-
project.command("get").description("Show the active project for this directory").option("--json", "Output as JSON").action(async (options3) => {
|
|
38803
|
-
const config = await loadConfig2();
|
|
38804
|
-
const active = await readActiveProject(process.cwd(), config.defaultProject);
|
|
38805
|
-
output({
|
|
38806
|
-
json: options3.json,
|
|
38807
|
-
data: active ? { slug: active.slug, source: active.resolvedFrom } : null,
|
|
38808
|
-
human: () => {
|
|
38809
|
-
if (!active) {
|
|
38810
|
-
info("No active project.");
|
|
38811
|
-
info(dim("Run 'secondlayer project use <slug>' to bind this directory."));
|
|
38812
|
-
return;
|
|
38813
|
-
}
|
|
38814
|
-
console.log(active.slug);
|
|
38815
|
-
console.log(dim(`(from ${active.resolvedFrom})`));
|
|
38816
|
-
}
|
|
38817
|
-
});
|
|
38818
|
-
});
|
|
38819
|
-
}
|
|
38820
|
-
function handleProjectError(err) {
|
|
38821
|
-
if (err instanceof CliHttpError) {
|
|
38822
|
-
if (err.code === "SESSION_EXPIRED") {
|
|
38823
|
-
error("Session expired. Run: secondlayer login");
|
|
38824
|
-
process.exit(1);
|
|
38825
|
-
}
|
|
38826
|
-
error(err.message);
|
|
38827
|
-
process.exit(1);
|
|
38828
|
-
}
|
|
38829
|
-
error(err instanceof Error ? err.message : String(err));
|
|
38830
|
-
process.exit(1);
|
|
38831
|
-
}
|
|
38832
38476
|
// src/commands/verify.ts
|
|
38833
38477
|
import {
|
|
38834
38478
|
compareRangeDigests,
|
|
@@ -39969,7 +39613,6 @@ registerSubscriptionsCommand(program);
|
|
|
39969
39613
|
registerStreamsCommand(program);
|
|
39970
39614
|
registerIndexCommand(program);
|
|
39971
39615
|
program.commandsGroup("Project & codegen:");
|
|
39972
|
-
registerProjectCommand(program);
|
|
39973
39616
|
registerCodegenCommand(program);
|
|
39974
39617
|
var configureGenerate = (cmd) => cmd.option("-c, --config <path>", "Path to config file").option("-o, --output <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) => {
|
|
39975
39618
|
const { deprecatedCodegenNotice: deprecatedCodegenNotice2 } = await Promise.resolve().then(() => (init_codegen(), exports_codegen));
|
|
@@ -39996,9 +39639,7 @@ registerVerifyCommand(program);
|
|
|
39996
39639
|
registerRepairCommand(program);
|
|
39997
39640
|
program.commandsGroup("Account:");
|
|
39998
39641
|
registerCreditsCommand(program);
|
|
39999
|
-
registerAccountCommand(program);
|
|
40000
|
-
registerKeysCommand(program);
|
|
40001
39642
|
program.parse();
|
|
40002
39643
|
|
|
40003
|
-
//# debugId=
|
|
39644
|
+
//# debugId=3107CF5F3E1F73F364756E2164756E21
|
|
40004
39645
|
//# sourceMappingURL=cli.js.map
|