@secondlayer/cli 3.5.5 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/dist/cli.js +181 -17
- package/dist/cli.js.map +4 -4
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -27,6 +27,11 @@ sl subgraphs deploy subgraphs/my-contract.ts --start-block <recent-block>
|
|
|
27
27
|
sl subgraphs query my-contract <table> --sort _block_height --order desc
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
`sl subgraphs scaffold` writes the definition file, creates or updates
|
|
31
|
+
`package.json`, and runs `bun install` by default so the generated import is
|
|
32
|
+
deployable immediately. Pass `--no-install` to skip the install and run
|
|
33
|
+
`bun install` manually in the output directory.
|
|
34
|
+
|
|
30
35
|
Then wire a receiver:
|
|
31
36
|
|
|
32
37
|
```bash
|
|
@@ -128,7 +133,7 @@ invocation. No long-lived key on disk.
|
|
|
128
133
|
| `sl subgraphs stop <name>` | Pause processing |
|
|
129
134
|
| `sl subgraphs gaps <name>` | List missing block ranges |
|
|
130
135
|
| `sl subgraphs delete <name>` | Drop the subgraph + its schema |
|
|
131
|
-
| `sl subgraphs scaffold <SP...::contract
|
|
136
|
+
| `sl subgraphs scaffold <SP...::contract> [-o <path>] [--no-install]` | Generate a starter subgraph from a deployed contract, write/amend `package.json`, and install dependencies unless skipped |
|
|
132
137
|
| `sl subgraphs generate <name>` | Regenerate TS types for an existing subgraph |
|
|
133
138
|
|
|
134
139
|
### Local dev + OSS
|
package/dist/cli.js
CHANGED
|
@@ -26406,7 +26406,7 @@ var require_cross_spawn = __commonJS((exports, module) => {
|
|
|
26406
26406
|
var cp = __require("child_process");
|
|
26407
26407
|
var parse2 = require_parse3();
|
|
26408
26408
|
var enoent = require_enoent();
|
|
26409
|
-
function
|
|
26409
|
+
function spawn2(command, args, options3) {
|
|
26410
26410
|
const parsed = parse2(command, args, options3);
|
|
26411
26411
|
const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
|
|
26412
26412
|
enoent.hookChildProcess(spawned, parsed);
|
|
@@ -26418,8 +26418,8 @@ var require_cross_spawn = __commonJS((exports, module) => {
|
|
|
26418
26418
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
26419
26419
|
return result;
|
|
26420
26420
|
}
|
|
26421
|
-
module.exports =
|
|
26422
|
-
module.exports.spawn =
|
|
26421
|
+
module.exports = spawn2;
|
|
26422
|
+
module.exports.spawn = spawn2;
|
|
26423
26423
|
module.exports.sync = spawnSync;
|
|
26424
26424
|
module.exports._parse = parse2;
|
|
26425
26425
|
module.exports._enoent = enoent;
|
|
@@ -31750,7 +31750,7 @@ var init_promise = __esm(() => {
|
|
|
31750
31750
|
|
|
31751
31751
|
// ../../node_modules/execa/lib/methods/main-async.js
|
|
31752
31752
|
import { setMaxListeners } from "node:events";
|
|
31753
|
-
import { spawn } from "node:child_process";
|
|
31753
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
31754
31754
|
var execaCoreAsync = (rawFile, rawArguments, rawOptions, createNested) => {
|
|
31755
31755
|
const { file, commandArguments, command, escapedCommand, startTime, verboseInfo, options: options3, fileDescriptors } = handleAsyncArguments(rawFile, rawArguments, rawOptions);
|
|
31756
31756
|
const { subprocess, promise } = spawnSubprocessAsync({
|
|
@@ -31795,7 +31795,7 @@ var execaCoreAsync = (rawFile, rawArguments, rawOptions, createNested) => {
|
|
|
31795
31795
|
}, spawnSubprocessAsync = ({ file, commandArguments, options: options3, startTime, verboseInfo, command, escapedCommand, fileDescriptors }) => {
|
|
31796
31796
|
let subprocess;
|
|
31797
31797
|
try {
|
|
31798
|
-
subprocess =
|
|
31798
|
+
subprocess = spawn2(...concatenateShell(file, commandArguments, options3));
|
|
31799
31799
|
} catch (error2) {
|
|
31800
31800
|
return handleEarlyError({
|
|
31801
31801
|
error: error2,
|
|
@@ -32439,7 +32439,7 @@ var {
|
|
|
32439
32439
|
// package.json
|
|
32440
32440
|
var package_default = {
|
|
32441
32441
|
name: "@secondlayer/cli",
|
|
32442
|
-
version: "3.
|
|
32442
|
+
version: "3.6.0",
|
|
32443
32443
|
description: "CLI for subgraphs and blockchain indexing on Stacks",
|
|
32444
32444
|
type: "module",
|
|
32445
32445
|
bin: {
|
|
@@ -32482,8 +32482,8 @@ var package_default = {
|
|
|
32482
32482
|
dependencies: {
|
|
32483
32483
|
"@inquirer/prompts": "^8.2.0",
|
|
32484
32484
|
"@secondlayer/bundler": "^0.3.2",
|
|
32485
|
-
"@secondlayer/sdk": "^3.
|
|
32486
|
-
"@secondlayer/shared": "^4.
|
|
32485
|
+
"@secondlayer/sdk": "^3.3.0",
|
|
32486
|
+
"@secondlayer/shared": "^4.4.0",
|
|
32487
32487
|
"@secondlayer/stacks": "^2.0.0",
|
|
32488
32488
|
"@secondlayer/subgraphs": "^1.3.2",
|
|
32489
32489
|
"@biomejs/js-api": "^0.7.0",
|
|
@@ -32555,6 +32555,15 @@ async function listSubgraphsApi() {
|
|
|
32555
32555
|
async function getSubgraphApi(name) {
|
|
32556
32556
|
return (await getTenantClient()).subgraphs.get(name);
|
|
32557
32557
|
}
|
|
32558
|
+
async function getSubgraphOpenApi(name, options) {
|
|
32559
|
+
return (await getTenantClient()).subgraphs.openapi(name, options);
|
|
32560
|
+
}
|
|
32561
|
+
async function getSubgraphAgentSchema(name, options) {
|
|
32562
|
+
return (await getTenantClient()).subgraphs.schema(name, options);
|
|
32563
|
+
}
|
|
32564
|
+
async function getSubgraphMarkdown(name, options) {
|
|
32565
|
+
return (await getTenantClient()).subgraphs.markdown(name, options);
|
|
32566
|
+
}
|
|
32558
32567
|
async function reindexSubgraphApi(name, options) {
|
|
32559
32568
|
return (await getTenantClient()).subgraphs.reindex(name, options);
|
|
32560
32569
|
}
|
|
@@ -34315,6 +34324,7 @@ async function resyncDatabase(skipConfirm, backfill) {
|
|
|
34315
34324
|
}
|
|
34316
34325
|
}
|
|
34317
34326
|
// src/commands/subgraphs.ts
|
|
34327
|
+
import { spawn } from "node:child_process";
|
|
34318
34328
|
import {
|
|
34319
34329
|
existsSync as existsSync3,
|
|
34320
34330
|
mkdirSync as mkdirSync2,
|
|
@@ -34598,6 +34608,91 @@ function parseStartBlockOption(value) {
|
|
|
34598
34608
|
}
|
|
34599
34609
|
return parsed;
|
|
34600
34610
|
}
|
|
34611
|
+
function parseSubgraphSpecFormat(value) {
|
|
34612
|
+
const format = value ?? "openapi";
|
|
34613
|
+
if (format === "openapi" || format === "agent" || format === "markdown") {
|
|
34614
|
+
return format;
|
|
34615
|
+
}
|
|
34616
|
+
throw new Error("--format must be one of: openapi, agent, markdown");
|
|
34617
|
+
}
|
|
34618
|
+
function formatSubgraphSpecOutput(spec, format) {
|
|
34619
|
+
if (typeof spec === "string")
|
|
34620
|
+
return spec;
|
|
34621
|
+
if (format === "markdown")
|
|
34622
|
+
return String(spec);
|
|
34623
|
+
return `${JSON.stringify(spec, null, 2)}
|
|
34624
|
+
`;
|
|
34625
|
+
}
|
|
34626
|
+
async function writeOrPrintSubgraphSpec(spec, format, output) {
|
|
34627
|
+
const text = formatSubgraphSpecOutput(spec, format);
|
|
34628
|
+
if (!output) {
|
|
34629
|
+
process.stdout.write(text);
|
|
34630
|
+
return;
|
|
34631
|
+
}
|
|
34632
|
+
const outPath = resolve3(output);
|
|
34633
|
+
const dir = resolve3(outPath, "..");
|
|
34634
|
+
if (!existsSync3(dir))
|
|
34635
|
+
mkdirSync2(dir, { recursive: true });
|
|
34636
|
+
await writeTextFile(outPath, text);
|
|
34637
|
+
success(`Created ${outPath}`);
|
|
34638
|
+
}
|
|
34639
|
+
function createLocalSubgraphDetail(input2) {
|
|
34640
|
+
const tables = {};
|
|
34641
|
+
for (const [tableName, rawTable] of Object.entries(input2.schema)) {
|
|
34642
|
+
const table = rawTable;
|
|
34643
|
+
const columns = {};
|
|
34644
|
+
for (const [columnName, column] of Object.entries(table.columns ?? {})) {
|
|
34645
|
+
columns[columnName] = {
|
|
34646
|
+
type: column.type ?? "text",
|
|
34647
|
+
...column.nullable && { nullable: true },
|
|
34648
|
+
...column.indexed && { indexed: true },
|
|
34649
|
+
...column.search && { searchable: true },
|
|
34650
|
+
...column.default !== undefined && { default: column.default }
|
|
34651
|
+
};
|
|
34652
|
+
}
|
|
34653
|
+
columns._id = { type: "serial" };
|
|
34654
|
+
columns._block_height = { type: "bigint" };
|
|
34655
|
+
columns._tx_id = { type: "text" };
|
|
34656
|
+
columns._created_at = { type: "timestamp" };
|
|
34657
|
+
tables[tableName] = {
|
|
34658
|
+
endpoint: `/subgraphs/${input2.name}/${tableName}`,
|
|
34659
|
+
columns,
|
|
34660
|
+
rowCount: 0,
|
|
34661
|
+
example: `/subgraphs/${input2.name}/${tableName}?_sort=_block_height&_order=desc&_limit=10`,
|
|
34662
|
+
...table.indexes && { indexes: table.indexes },
|
|
34663
|
+
...table.uniqueKeys && { uniqueKeys: table.uniqueKeys }
|
|
34664
|
+
};
|
|
34665
|
+
}
|
|
34666
|
+
return {
|
|
34667
|
+
name: input2.name,
|
|
34668
|
+
version: input2.version ?? "0.0.0",
|
|
34669
|
+
schemaHash: input2.schemaHash,
|
|
34670
|
+
status: "local",
|
|
34671
|
+
lastProcessedBlock: 0,
|
|
34672
|
+
...input2.description && { description: input2.description },
|
|
34673
|
+
sources: input2.sources,
|
|
34674
|
+
health: {
|
|
34675
|
+
totalProcessed: 0,
|
|
34676
|
+
totalErrors: 0,
|
|
34677
|
+
errorRate: 0,
|
|
34678
|
+
lastError: null,
|
|
34679
|
+
lastErrorAt: null
|
|
34680
|
+
},
|
|
34681
|
+
sync: {
|
|
34682
|
+
status: "synced",
|
|
34683
|
+
startBlock: 0,
|
|
34684
|
+
lastProcessedBlock: 0,
|
|
34685
|
+
chainTip: 0,
|
|
34686
|
+
blocksRemaining: 0,
|
|
34687
|
+
progress: 1,
|
|
34688
|
+
gaps: { count: 0, totalMissingBlocks: 0, ranges: [] },
|
|
34689
|
+
integrity: "complete"
|
|
34690
|
+
},
|
|
34691
|
+
tables,
|
|
34692
|
+
createdAt: new Date(0).toISOString(),
|
|
34693
|
+
updatedAt: new Date(0).toISOString()
|
|
34694
|
+
};
|
|
34695
|
+
}
|
|
34601
34696
|
function readCliSubgraphsDependency() {
|
|
34602
34697
|
const here = dirname4(fileURLToPath2(import.meta.url));
|
|
34603
34698
|
const candidates = [
|
|
@@ -34638,15 +34733,24 @@ function ensureScaffoldPackageJson(dir) {
|
|
|
34638
34733
|
`, "utf8");
|
|
34639
34734
|
}
|
|
34640
34735
|
async function runBunInstall(dir) {
|
|
34641
|
-
|
|
34642
|
-
|
|
34643
|
-
|
|
34644
|
-
|
|
34736
|
+
await new Promise((resolvePromise, reject) => {
|
|
34737
|
+
const proc = spawn("bun", ["install"], {
|
|
34738
|
+
cwd: dir,
|
|
34739
|
+
stdio: "inherit"
|
|
34740
|
+
});
|
|
34741
|
+
proc.on("error", reject);
|
|
34742
|
+
proc.on("close", (exitCode, signal) => {
|
|
34743
|
+
if (exitCode === 0) {
|
|
34744
|
+
resolvePromise();
|
|
34745
|
+
return;
|
|
34746
|
+
}
|
|
34747
|
+
if (exitCode !== null) {
|
|
34748
|
+
reject(new Error(`bun install exited with code ${exitCode}`));
|
|
34749
|
+
return;
|
|
34750
|
+
}
|
|
34751
|
+
reject(new Error(`bun install exited with signal ${signal}`));
|
|
34752
|
+
});
|
|
34645
34753
|
});
|
|
34646
|
-
const exitCode = await proc.exited;
|
|
34647
|
-
if (exitCode !== 0) {
|
|
34648
|
-
throw new Error(`bun install exited with code ${exitCode}`);
|
|
34649
|
-
}
|
|
34650
34754
|
}
|
|
34651
34755
|
async function installScaffoldDependencies(dir, options2 = {}) {
|
|
34652
34756
|
if (options2.install === false)
|
|
@@ -34993,6 +35097,66 @@ Table endpoints:`));
|
|
|
34993
35097
|
handleApiError(err, "get subgraph status");
|
|
34994
35098
|
}
|
|
34995
35099
|
});
|
|
35100
|
+
subgraphs.command("spec <name>").description("Output API documentation for a deployed subgraph").option("--format <format>", "Output format: openapi, agent, markdown", "openapi").option("-o, --output <path>", "Write output to a file").option("--server <url>", "Override the server URL in generated docs").action(async (name, options2) => {
|
|
35101
|
+
try {
|
|
35102
|
+
const format = parseSubgraphSpecFormat(options2.format);
|
|
35103
|
+
const specOptions = options2.server ? { serverUrl: options2.server } : undefined;
|
|
35104
|
+
const spec = format === "openapi" ? await getSubgraphOpenApi(name, specOptions) : format === "agent" ? await getSubgraphAgentSchema(name, specOptions) : await getSubgraphMarkdown(name, specOptions);
|
|
35105
|
+
await writeOrPrintSubgraphSpec(spec, format, options2.output);
|
|
35106
|
+
} catch (err) {
|
|
35107
|
+
if (err instanceof Error && err.message.startsWith("--format")) {
|
|
35108
|
+
error(err.message);
|
|
35109
|
+
process.exit(1);
|
|
35110
|
+
}
|
|
35111
|
+
handleApiError(err, "generate subgraph spec");
|
|
35112
|
+
}
|
|
35113
|
+
});
|
|
35114
|
+
subgraphs.command("inspect <file>").description("Output API documentation for a local subgraph file").option("--format <format>", "Output format: openapi, agent, markdown", "agent").option("-o, --output <path>", "Write output to a file").option("--server <url>", "Override the server URL in generated docs").action(async (file, options2) => {
|
|
35115
|
+
try {
|
|
35116
|
+
const format = parseSubgraphSpecFormat(options2.format);
|
|
35117
|
+
const absPath = resolve3(file);
|
|
35118
|
+
if (!existsSync3(absPath)) {
|
|
35119
|
+
error(`File not found: ${absPath}`);
|
|
35120
|
+
process.exit(1);
|
|
35121
|
+
}
|
|
35122
|
+
const { readFile: readFile4 } = await import("node:fs/promises");
|
|
35123
|
+
const { bundleSubgraphCode } = await import("@secondlayer/bundler");
|
|
35124
|
+
const { generateSubgraphSQL } = await import("@secondlayer/subgraphs");
|
|
35125
|
+
const {
|
|
35126
|
+
generateSubgraphAgentSchema,
|
|
35127
|
+
generateSubgraphMarkdown,
|
|
35128
|
+
generateSubgraphOpenApi
|
|
35129
|
+
} = await import("@secondlayer/shared/subgraphs/spec");
|
|
35130
|
+
const source = await readFile4(absPath, "utf8");
|
|
35131
|
+
const bundled = await bundleSubgraphCode(source);
|
|
35132
|
+
const { hash } = generateSubgraphSQL({
|
|
35133
|
+
name: bundled.name,
|
|
35134
|
+
version: bundled.version,
|
|
35135
|
+
description: bundled.description,
|
|
35136
|
+
sources: bundled.sources,
|
|
35137
|
+
schema: bundled.schema,
|
|
35138
|
+
handlers: {}
|
|
35139
|
+
});
|
|
35140
|
+
const detail = createLocalSubgraphDetail({
|
|
35141
|
+
name: bundled.name,
|
|
35142
|
+
version: bundled.version,
|
|
35143
|
+
description: bundled.description,
|
|
35144
|
+
sources: bundled.sources,
|
|
35145
|
+
schema: bundled.schema,
|
|
35146
|
+
schemaHash: hash
|
|
35147
|
+
});
|
|
35148
|
+
const specOptions = options2.server ? { serverUrl: options2.server } : undefined;
|
|
35149
|
+
const spec = format === "openapi" ? generateSubgraphOpenApi(detail, specOptions) : format === "agent" ? generateSubgraphAgentSchema(detail, specOptions) : generateSubgraphMarkdown(detail, specOptions);
|
|
35150
|
+
await writeOrPrintSubgraphSpec(spec, format, options2.output);
|
|
35151
|
+
} catch (err) {
|
|
35152
|
+
if (err instanceof Error && err.message.startsWith("--format")) {
|
|
35153
|
+
error(err.message);
|
|
35154
|
+
process.exit(1);
|
|
35155
|
+
}
|
|
35156
|
+
error(`Failed to inspect subgraph: ${err}`);
|
|
35157
|
+
process.exit(1);
|
|
35158
|
+
}
|
|
35159
|
+
});
|
|
34996
35160
|
subgraphs.command("reindex <name>").description("Reindex a subgraph from historical blocks").option("--from <block>", "Start block height").option("--to <block>", "End block height").action(async (name, options2) => {
|
|
34997
35161
|
try {
|
|
34998
35162
|
info(`Reindexing subgraph "${name}"...`);
|
|
@@ -36628,5 +36792,5 @@ registerLocalCommand(program);
|
|
|
36628
36792
|
registerAccountCommand(program);
|
|
36629
36793
|
program.parse();
|
|
36630
36794
|
|
|
36631
|
-
//# debugId=
|
|
36795
|
+
//# debugId=9B4F6BACEC00400164756E2164756E21
|
|
36632
36796
|
//# sourceMappingURL=cli.js.map
|