@secondlayer/cli 8.12.0 → 8.14.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 +125 -11
- package/dist/cli.js.map +7 -7
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -31811,7 +31811,7 @@ var {
|
|
|
31811
31811
|
// package.json
|
|
31812
31812
|
var package_default = {
|
|
31813
31813
|
name: "@secondlayer/cli",
|
|
31814
|
-
version: "8.
|
|
31814
|
+
version: "8.14.0",
|
|
31815
31815
|
repository: {
|
|
31816
31816
|
type: "git",
|
|
31817
31817
|
url: "git+https://github.com/ryanwaits/secondlayer.git",
|
|
@@ -31862,9 +31862,9 @@ var package_default = {
|
|
|
31862
31862
|
"@secondlayer/bundler": "^0.3.7",
|
|
31863
31863
|
"@secondlayer/scaffold": "^1.3.0",
|
|
31864
31864
|
"@secondlayer/sdk": "^6.23.1",
|
|
31865
|
-
"@secondlayer/shared": "^6.
|
|
31865
|
+
"@secondlayer/shared": "^6.40.0",
|
|
31866
31866
|
"@secondlayer/stacks": "^2.5.1",
|
|
31867
|
-
"@secondlayer/subgraphs": "^3.
|
|
31867
|
+
"@secondlayer/subgraphs": "^3.19.0",
|
|
31868
31868
|
"@biomejs/js-api": "^0.7.0",
|
|
31869
31869
|
"@biomejs/wasm-nodejs": "^1.9.0",
|
|
31870
31870
|
esbuild: "^0.19.0",
|
|
@@ -32137,11 +32137,15 @@ async function showProfile(json) {
|
|
|
32137
32137
|
["Plan", profile.plan],
|
|
32138
32138
|
["Display Name", profile.displayName ?? dim("—")],
|
|
32139
32139
|
["Bio", profile.bio ?? dim("—")],
|
|
32140
|
-
["Slug", profile.slug ?? dim("—")]
|
|
32140
|
+
["Slug", profile.slug ?? dim("—")],
|
|
32141
|
+
[
|
|
32142
|
+
"Notify on reindex complete",
|
|
32143
|
+
profile.notifyReindexComplete ? "on" : "off"
|
|
32144
|
+
]
|
|
32141
32145
|
]))
|
|
32142
32146
|
});
|
|
32143
32147
|
}
|
|
32144
|
-
async function applyProfileUpdate(options) {
|
|
32148
|
+
async function applyProfileUpdate(options, getOptionValueSource) {
|
|
32145
32149
|
const data = {};
|
|
32146
32150
|
if (options.name)
|
|
32147
32151
|
data.display_name = options.name;
|
|
@@ -32149,6 +32153,9 @@ async function applyProfileUpdate(options) {
|
|
|
32149
32153
|
data.bio = options.bio;
|
|
32150
32154
|
if (options.slug)
|
|
32151
32155
|
data.slug = options.slug;
|
|
32156
|
+
if (getOptionValueSource("notifyReindexComplete") === "cli") {
|
|
32157
|
+
data.notify_reindex_complete = options.notifyReindexComplete;
|
|
32158
|
+
}
|
|
32152
32159
|
const updated = await updateAccountProfile(data);
|
|
32153
32160
|
output({
|
|
32154
32161
|
json: options.json,
|
|
@@ -32158,7 +32165,11 @@ async function applyProfileUpdate(options) {
|
|
|
32158
32165
|
console.log(formatKeyValue([
|
|
32159
32166
|
["Display Name", updated.displayName ?? dim("—")],
|
|
32160
32167
|
["Bio", updated.bio ?? dim("—")],
|
|
32161
|
-
["Slug", updated.slug ?? dim("—")]
|
|
32168
|
+
["Slug", updated.slug ?? dim("—")],
|
|
32169
|
+
[
|
|
32170
|
+
"Notify on reindex complete",
|
|
32171
|
+
updated.notifyReindexComplete ? "on" : "off"
|
|
32172
|
+
]
|
|
32162
32173
|
]));
|
|
32163
32174
|
}
|
|
32164
32175
|
});
|
|
@@ -32167,7 +32178,7 @@ function registerAccountCommand(program2) {
|
|
|
32167
32178
|
const account = program2.command("account").description("Manage your account profile");
|
|
32168
32179
|
addBillingCommand(account);
|
|
32169
32180
|
account.command("get").description("Show your account profile").option("--json", "Output as JSON").action(withErrorHandling(async (options) => showProfile(options.json), { action: "show profile" }));
|
|
32170
|
-
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("--json", "Output as JSON").action(withErrorHandling(async (options) => applyProfileUpdate(options), {
|
|
32181
|
+
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)), {
|
|
32171
32182
|
action: "update profile"
|
|
32172
32183
|
}));
|
|
32173
32184
|
}
|
|
@@ -32786,6 +32797,9 @@ import { dirname as dirname2, join as join4, relative, resolve } from "node:path
|
|
|
32786
32797
|
import { fileURLToPath } from "node:url";
|
|
32787
32798
|
import { input, select as select2 } from "@inquirer/prompts";
|
|
32788
32799
|
import { SecondLayer as SecondLayer3 } from "@secondlayer/sdk";
|
|
32800
|
+
import {
|
|
32801
|
+
ChainTriggerSchema
|
|
32802
|
+
} from "@secondlayer/shared/schemas/subscriptions";
|
|
32789
32803
|
init_output();
|
|
32790
32804
|
init_resolve_auth();
|
|
32791
32805
|
|
|
@@ -32838,6 +32852,38 @@ function copyTemplate(src, dest, vars) {
|
|
|
32838
32852
|
}
|
|
32839
32853
|
}
|
|
32840
32854
|
}
|
|
32855
|
+
function parseTriggersInput(opts) {
|
|
32856
|
+
const raw = [];
|
|
32857
|
+
if (opts.triggersFile) {
|
|
32858
|
+
let parsed;
|
|
32859
|
+
try {
|
|
32860
|
+
parsed = JSON.parse(readFileSync(opts.triggersFile, "utf8"));
|
|
32861
|
+
} catch (err) {
|
|
32862
|
+
throw new Error(`Could not read/parse --triggers-file ${opts.triggersFile}: ${err instanceof Error ? err.message : String(err)}`);
|
|
32863
|
+
}
|
|
32864
|
+
if (!Array.isArray(parsed)) {
|
|
32865
|
+
throw new Error("--triggers-file must contain a JSON array of triggers");
|
|
32866
|
+
}
|
|
32867
|
+
raw.push(...parsed);
|
|
32868
|
+
}
|
|
32869
|
+
for (const value of opts.trigger ?? []) {
|
|
32870
|
+
try {
|
|
32871
|
+
raw.push(JSON.parse(value));
|
|
32872
|
+
} catch {
|
|
32873
|
+
throw new Error(`--trigger is not valid JSON: ${value}`);
|
|
32874
|
+
}
|
|
32875
|
+
}
|
|
32876
|
+
if (raw.length === 0) {
|
|
32877
|
+
throw new Error("Provide at least one --trigger or --triggers-file");
|
|
32878
|
+
}
|
|
32879
|
+
return raw.map((entry, i) => {
|
|
32880
|
+
const result = ChainTriggerSchema.safeParse(entry);
|
|
32881
|
+
if (!result.success) {
|
|
32882
|
+
throw new Error(`Invalid trigger at index ${i}: ${result.error.issues[0]?.message ?? "validation failed"}`);
|
|
32883
|
+
}
|
|
32884
|
+
return result.data;
|
|
32885
|
+
});
|
|
32886
|
+
}
|
|
32841
32887
|
async function promptFor(_name, opts) {
|
|
32842
32888
|
const runtime = opts.runtime ?? await select2({
|
|
32843
32889
|
message: "Runtime?",
|
|
@@ -32988,15 +33034,75 @@ SIGNING_SECRET=${signingSecret}
|
|
|
32988
33034
|
success(`Done. Next:
|
|
32989
33035
|
${dashboardLine}${pausedLine}${runHint}`);
|
|
32990
33036
|
}
|
|
33037
|
+
async function createChainSubscription(name, opts) {
|
|
33038
|
+
for (const [flag, value] of [
|
|
33039
|
+
["--subgraph", opts.subgraph],
|
|
33040
|
+
["--table", opts.table],
|
|
33041
|
+
["--runtime", opts.runtime]
|
|
33042
|
+
]) {
|
|
33043
|
+
if (value !== undefined) {
|
|
33044
|
+
error(`${flag} is not valid with --trigger/--triggers-file (chain mode)`);
|
|
33045
|
+
process.exit(1);
|
|
33046
|
+
}
|
|
33047
|
+
}
|
|
33048
|
+
if (!opts.url) {
|
|
33049
|
+
error("--url is required when creating a chain subscription");
|
|
33050
|
+
process.exit(1);
|
|
33051
|
+
}
|
|
33052
|
+
let triggers;
|
|
33053
|
+
let authConfig;
|
|
33054
|
+
try {
|
|
33055
|
+
triggers = parseTriggersInput(opts);
|
|
33056
|
+
authConfig = buildSubscriptionAuthConfig(opts.authToken);
|
|
33057
|
+
} catch (err) {
|
|
33058
|
+
error(err instanceof Error ? err.message : String(err));
|
|
33059
|
+
process.exit(1);
|
|
33060
|
+
}
|
|
33061
|
+
const sl = await getSubscriptionClient();
|
|
33062
|
+
let subscriptionId;
|
|
33063
|
+
let signingSecret;
|
|
33064
|
+
try {
|
|
33065
|
+
const res = await sl.subscriptions.create({
|
|
33066
|
+
name,
|
|
33067
|
+
url: opts.url,
|
|
33068
|
+
triggers,
|
|
33069
|
+
format: opts.format ?? "standard-webhooks",
|
|
33070
|
+
...authConfig ? { authConfig } : {}
|
|
33071
|
+
});
|
|
33072
|
+
subscriptionId = res.subscription.id;
|
|
33073
|
+
signingSecret = res.signingSecret;
|
|
33074
|
+
success(`Chain subscription provisioned: ${blue(subscriptionId)}`);
|
|
33075
|
+
} catch (err) {
|
|
33076
|
+
error(`Subscription provisioning failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
33077
|
+
process.exit(1);
|
|
33078
|
+
}
|
|
33079
|
+
info(`Signing secret (store securely): ${signingSecret}`);
|
|
33080
|
+
let dashboardLine = "";
|
|
33081
|
+
try {
|
|
33082
|
+
const { apiUrl } = await resolveAuth();
|
|
33083
|
+
const base = deriveBaseUrl(apiUrl);
|
|
33084
|
+
dashboardLine = `Dashboard: ${base}/platform/subscriptions/${subscriptionId}
|
|
33085
|
+
`;
|
|
33086
|
+
} catch {}
|
|
33087
|
+
console.log();
|
|
33088
|
+
success(`Done. Next:
|
|
33089
|
+
${dashboardLine}View deliveries:
|
|
33090
|
+
sl subscriptions get ${name}`);
|
|
33091
|
+
}
|
|
32991
33092
|
async function getSubscriptionClient() {
|
|
32992
33093
|
const { apiUrl, ephemeralKey } = await resolveAuth();
|
|
32993
33094
|
return new SecondLayer3({ baseUrl: apiUrl, apiKey: ephemeralKey });
|
|
32994
33095
|
}
|
|
32995
33096
|
function addSubscriptionScaffold(parent, commandSpec, opts) {
|
|
32996
|
-
parent.command(commandSpec).description(opts.description).option("-r, --runtime <runtime>", "inngest | trigger | cloudflare | node").option("-s, --subgraph <name>", "Subgraph to subscribe to").option("-t, --table <name>", "Table to subscribe to").option("-u, --url <url>", "Webhook URL").option("--auth-token <token>", "Bearer token for receiver API auth").option("--filter <kv...>", "Filter as key=value (supports .eq/.neq/.gt/.gte/.lt/.lte suffixes)").option("--skip-api", "Copy template only, don't call the API").option("--no-scaffold", "Skip the local runtime template directory (webhook-only setups)").addHelpText("after", `
|
|
33097
|
+
parent.command(commandSpec).description(opts.description).option("-r, --runtime <runtime>", "inngest | trigger | cloudflare | node").option("-s, --subgraph <name>", "Subgraph to subscribe to").option("-t, --table <name>", "Table to subscribe to").option("-u, --url <url>", "Webhook URL").option("--auth-token <token>", "Bearer token for receiver API auth").option("--filter <kv...>", "Filter as key=value (supports .eq/.neq/.gt/.gte/.lt/.lte suffixes)").option("--trigger <json...>", `Chain-subscription trigger as JSON (repeatable), e.g. '{"type":"sbtc_deposit"}'`).option("--triggers-file <path>", "Chain-subscription triggers as a JSON array file").option("--format <format>", "Chain mode delivery format (default standard-webhooks)").option("--skip-api", "Copy template only, don't call the API").option("--no-scaffold", "Skip the local runtime template directory (webhook-only setups)").addHelpText("after", `
|
|
32997
33098
|
Examples:
|
|
32998
33099
|
$ ${opts.examplePrefix} my-sub -s my-graph -t transfers -u https://example.com/webhook
|
|
32999
|
-
$ ${opts.examplePrefix} my-sub -s my-graph -t balances -r inngest --filter amount.gte=1000
|
|
33100
|
+
$ ${opts.examplePrefix} my-sub -s my-graph -t balances -r inngest --filter amount.gte=1000
|
|
33101
|
+
$ ${opts.examplePrefix} my-hook -u https://example.com/webhook --trigger '{"type":"sbtc_deposit"}'`).action(async (name, options) => {
|
|
33102
|
+
if (options.trigger?.length || options.triggersFile) {
|
|
33103
|
+
await createChainSubscription(name, options);
|
|
33104
|
+
return;
|
|
33105
|
+
}
|
|
33000
33106
|
await createSubscription(name, options);
|
|
33001
33107
|
});
|
|
33002
33108
|
}
|
|
@@ -33561,6 +33667,9 @@ Examples:
|
|
|
33561
33667
|
}
|
|
33562
33668
|
const client = await getSubscriptionClient();
|
|
33563
33669
|
const { id, detail } = await resolveSubscriptionRef(client, idOrName);
|
|
33670
|
+
if (detail.triggers?.some((t) => t.type === "sbtc_withdrawal_swept_confirmed")) {
|
|
33671
|
+
warn("sbtc_withdrawal_swept_confirmed triggers are forward-only and not replayed; only on-Stacks sBTC and chain triggers emit over this range.");
|
|
33672
|
+
}
|
|
33564
33673
|
const ok = await confirmOrExit(`Replay ${detail.name} from block ${fromBlock} to ${toBlock}?`, options.yes);
|
|
33565
33674
|
if (!ok)
|
|
33566
33675
|
return;
|
|
@@ -35290,8 +35399,9 @@ function formatSubgraphSync(sync) {
|
|
|
35290
35399
|
};
|
|
35291
35400
|
}
|
|
35292
35401
|
const range = processedBlocks !== undefined && totalBlocks !== undefined ? `${processedBlocks} / ${totalBlocks} blocks` : `${sync.lastProcessedBlock} / ${targetBlock}`;
|
|
35402
|
+
const eta = sync.etaSeconds != null ? ` · est ${formatDuration(sync.etaSeconds)}` : "";
|
|
35293
35403
|
return {
|
|
35294
|
-
line: `reindexing — ${progress} (${range}, target #${targetBlock})`,
|
|
35404
|
+
line: `reindexing — ${progress} (${range}, target #${targetBlock})${eta}`,
|
|
35295
35405
|
remainingLabel: "Reindex Remaining",
|
|
35296
35406
|
remaining: String(sync.blocksRemaining)
|
|
35297
35407
|
};
|
|
@@ -35517,6 +35627,10 @@ Stopped watching.`);
|
|
|
35517
35627
|
info(` REST: ${apiUrl}/api/subgraphs/${effectiveDef.name}/${firstTable}`);
|
|
35518
35628
|
info(` Publish: sl subgraphs publish ${effectiveDef.name} (open anon /v1 reads)`);
|
|
35519
35629
|
}
|
|
35630
|
+
if (result.reindexStarted) {
|
|
35631
|
+
const denom = result.estimatedEvents != null ? ` ~${result.estimatedEvents.toLocaleString()} events —` : "";
|
|
35632
|
+
info(` Reindex: ${denom} started in the background — check status in ~30s for an ETA`);
|
|
35633
|
+
}
|
|
35520
35634
|
info(` Watch: sl subgraphs status ${effectiveDef.name}`);
|
|
35521
35635
|
if (firstTable) {
|
|
35522
35636
|
info(` Webhook: sl subscriptions create ${effectiveDef.name}-hook --subgraph ${effectiveDef.name} --table ${firstTable} --url <your-endpoint>`);
|
|
@@ -38022,5 +38136,5 @@ registerAccountCommand(program);
|
|
|
38022
38136
|
registerKeysCommand(program);
|
|
38023
38137
|
program.parse();
|
|
38024
38138
|
|
|
38025
|
-
//# debugId=
|
|
38139
|
+
//# debugId=7477A77F4D7194B764756E2164756E21
|
|
38026
38140
|
//# sourceMappingURL=cli.js.map
|