@secondlayer/cli 9.1.0 → 9.3.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 +451 -177
- package/dist/cli.js.map +6 -5
- package/package.json +15 -5
package/dist/cli.js
CHANGED
|
@@ -28910,7 +28910,7 @@ export default defineSubgraph({
|
|
|
28910
28910
|
`;
|
|
28911
28911
|
}
|
|
28912
28912
|
function sip010Balances(name) {
|
|
28913
|
-
return `import { defineSubgraph } from "@secondlayer/subgraphs";
|
|
28913
|
+
return `import { defineSchema, defineSubgraph, readContractAt, type TypedSubgraphContext } from "@secondlayer/subgraphs";
|
|
28914
28914
|
|
|
28915
28915
|
/**
|
|
28916
28916
|
* Track SIP-010 token balances per (asset_identifier, holder).
|
|
@@ -28919,10 +28919,59 @@ function sip010Balances(name) {
|
|
|
28919
28919
|
* token by adding \`assetIdentifier: "SP...token::token-name"\` to each
|
|
28920
28920
|
* source filter.
|
|
28921
28921
|
*
|
|
28922
|
+
* Balances are moved with \`ctx.increment\`, which applies a DELTA in one
|
|
28923
|
+
* atomic statement. That matters: a read-modify-write (findOne → compute →
|
|
28924
|
+
* upsert) loses concurrent updates to the same row, and it is not replay-safe
|
|
28925
|
+
* under \`backfillMode: "concurrent"\`. Deltas commute, so order doesn't
|
|
28926
|
+
* matter and a reorg rewind reverses cleanly via the journal.
|
|
28927
|
+
*
|
|
28928
|
+
* Token metadata (decimals/symbol) comes from the token contract itself via
|
|
28929
|
+
* \`readContractAt\`, so \`amount\` stops being a bare integer nobody can
|
|
28930
|
+
* render. The read is pinned to the block being processed — a handler stays a
|
|
28931
|
+
* pure function of its block — and \`cache: "contract-constant"\` says these
|
|
28932
|
+
* two values can never change for a given token, so each is fetched ONCE
|
|
28933
|
+
* instead of once per block.
|
|
28934
|
+
*
|
|
28922
28935
|
* Query examples once deployed:
|
|
28923
28936
|
* GET /v1/subgraphs/${name}/balances?_search=SP1...
|
|
28924
28937
|
* GET /v1/subgraphs/${name}/balances?holder=SP1...
|
|
28938
|
+
* GET /v1/subgraphs/${name}/tokens
|
|
28925
28939
|
*/
|
|
28940
|
+
|
|
28941
|
+
/** The two SIP-010 read-only functions this subgraph calls. */
|
|
28942
|
+
const SIP010_ABI = {
|
|
28943
|
+
functions: [
|
|
28944
|
+
{ name: "get-decimals", access: "read-only", args: [], outputs: { response: { ok: "uint128", error: "uint128" } } },
|
|
28945
|
+
{ name: "get-symbol", access: "read-only", args: [], outputs: { response: { ok: { "string-ascii": { length: 32 } }, error: "uint128" } } },
|
|
28946
|
+
],
|
|
28947
|
+
} as const;
|
|
28948
|
+
|
|
28949
|
+
/** Tokens already labelled in this process — metadata is immutable, so one
|
|
28950
|
+
* resolution per token is enough even across a backfill. */
|
|
28951
|
+
const labelled = new Set<string>();
|
|
28952
|
+
|
|
28953
|
+
// Hoisted so the helper below can be typed against it.
|
|
28954
|
+
const schema = defineSchema({
|
|
28955
|
+
balances: {
|
|
28956
|
+
columns: {
|
|
28957
|
+
asset_identifier: { type: "text", indexed: true, search: true },
|
|
28958
|
+
holder: { type: "principal", indexed: true, search: true },
|
|
28959
|
+
amount: { type: "uint" },
|
|
28960
|
+
},
|
|
28961
|
+
// increment() upserts on this key.
|
|
28962
|
+
uniqueKeys: [["asset_identifier", "holder"]],
|
|
28963
|
+
},
|
|
28964
|
+
tokens: {
|
|
28965
|
+
columns: {
|
|
28966
|
+
asset_identifier: { type: "text", indexed: true },
|
|
28967
|
+
contract_id: { type: "text" },
|
|
28968
|
+
symbol: { type: "text" },
|
|
28969
|
+
decimals: { type: "uint" },
|
|
28970
|
+
},
|
|
28971
|
+
uniqueKeys: [["asset_identifier"]],
|
|
28972
|
+
},
|
|
28973
|
+
});
|
|
28974
|
+
|
|
28926
28975
|
export default defineSubgraph({
|
|
28927
28976
|
name: "${name}",
|
|
28928
28977
|
version: "1.0.0",
|
|
@@ -28934,55 +28983,46 @@ export default defineSubgraph({
|
|
|
28934
28983
|
burn: { type: "ft_burn" },
|
|
28935
28984
|
},
|
|
28936
28985
|
|
|
28937
|
-
schema
|
|
28938
|
-
balances: {
|
|
28939
|
-
columns: {
|
|
28940
|
-
asset_identifier: { type: "text", indexed: true, search: true },
|
|
28941
|
-
holder: { type: "principal", indexed: true, search: true },
|
|
28942
|
-
amount: { type: "uint" },
|
|
28943
|
-
},
|
|
28944
|
-
uniqueKeys: [["asset_identifier", "holder"]],
|
|
28945
|
-
},
|
|
28946
|
-
},
|
|
28986
|
+
schema,
|
|
28947
28987
|
|
|
28948
28988
|
handlers: {
|
|
28949
28989
|
transfer: async (event, ctx) => {
|
|
28990
|
+
await labelToken(event.assetIdentifier, ctx);
|
|
28950
28991
|
const amount = BigInt(event.amount ?? 0);
|
|
28951
28992
|
if (event.sender) {
|
|
28952
|
-
|
|
28993
|
+
ctx.increment("balances", { asset_identifier: event.assetIdentifier, holder: event.sender }, { amount: -amount });
|
|
28953
28994
|
}
|
|
28954
28995
|
if (event.recipient) {
|
|
28955
|
-
|
|
28996
|
+
ctx.increment("balances", { asset_identifier: event.assetIdentifier, holder: event.recipient }, { amount });
|
|
28956
28997
|
}
|
|
28957
28998
|
},
|
|
28958
|
-
mint:
|
|
28999
|
+
mint: (event, ctx) => {
|
|
28959
29000
|
if (event.recipient) {
|
|
28960
|
-
|
|
29001
|
+
ctx.increment("balances", { asset_identifier: event.assetIdentifier, holder: event.recipient }, { amount: BigInt(event.amount ?? 0) });
|
|
28961
29002
|
}
|
|
28962
29003
|
},
|
|
28963
|
-
burn:
|
|
29004
|
+
burn: (event, ctx) => {
|
|
28964
29005
|
if (event.sender) {
|
|
28965
|
-
|
|
29006
|
+
ctx.increment("balances", { asset_identifier: event.assetIdentifier, holder: event.sender }, { amount: -BigInt(event.amount ?? 0) });
|
|
28966
29007
|
}
|
|
28967
29008
|
},
|
|
28968
29009
|
},
|
|
28969
29010
|
});
|
|
28970
29011
|
|
|
28971
|
-
|
|
28972
|
-
|
|
28973
|
-
|
|
28974
|
-
|
|
28975
|
-
|
|
28976
|
-
|
|
28977
|
-
)
|
|
28978
|
-
const
|
|
28979
|
-
const
|
|
28980
|
-
const
|
|
28981
|
-
|
|
28982
|
-
|
|
28983
|
-
|
|
28984
|
-
|
|
28985
|
-
);
|
|
29012
|
+
/** Resolve a token's symbol + decimals from its contract, once. */
|
|
29013
|
+
async function labelToken(
|
|
29014
|
+
assetIdentifier: string | undefined,
|
|
29015
|
+
ctx: TypedSubgraphContext<typeof schema>,
|
|
29016
|
+
) {
|
|
29017
|
+
if (!assetIdentifier || labelled.has(assetIdentifier)) return;
|
|
29018
|
+
labelled.add(assetIdentifier);
|
|
29019
|
+
const contractId = assetIdentifier.split("::")[0];
|
|
29020
|
+
const token = readContractAt(ctx, contractId, SIP010_ABI, { cache: "contract-constant" });
|
|
29021
|
+
const [decimals, symbol] = await Promise.all([
|
|
29022
|
+
token.read.getDecimals({}),
|
|
29023
|
+
token.read.getSymbol({}),
|
|
29024
|
+
]);
|
|
29025
|
+
ctx.upsert("tokens", { asset_identifier: assetIdentifier }, { asset_identifier: assetIdentifier, contract_id: contractId, symbol, decimals });
|
|
28986
29026
|
}
|
|
28987
29027
|
`;
|
|
28988
29028
|
}
|
|
@@ -29206,6 +29246,223 @@ function deriveBaseUrl(apiUrl) {
|
|
|
29206
29246
|
}
|
|
29207
29247
|
}
|
|
29208
29248
|
|
|
29249
|
+
// src/commands/subgraph-test.ts
|
|
29250
|
+
var exports_subgraph_test = {};
|
|
29251
|
+
__export(exports_subgraph_test, {
|
|
29252
|
+
runSubgraphTest: () => runSubgraphTest
|
|
29253
|
+
});
|
|
29254
|
+
import { createHash } from "node:crypto";
|
|
29255
|
+
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
29256
|
+
import { dirname as dirname3, resolve as resolve2 } from "node:path";
|
|
29257
|
+
import { Index } from "@secondlayer/sdk";
|
|
29258
|
+
function filterHashOf(sources) {
|
|
29259
|
+
const stable = JSON.stringify(Object.fromEntries(Object.entries(sources).sort(([a4], [b2]) => a4.localeCompare(b2))), (_k, v2) => typeof v2 === "bigint" ? `${v2}n` : v2);
|
|
29260
|
+
return createHash("sha256").update(stable).digest("hex").slice(0, 16);
|
|
29261
|
+
}
|
|
29262
|
+
function cassettePath(name) {
|
|
29263
|
+
return resolve2(CASSETTE_DIR, `${name}.json`);
|
|
29264
|
+
}
|
|
29265
|
+
function loadCassette(name, filterHash) {
|
|
29266
|
+
const path11 = cassettePath(name);
|
|
29267
|
+
if (!existsSync2(path11))
|
|
29268
|
+
return null;
|
|
29269
|
+
let parsed;
|
|
29270
|
+
try {
|
|
29271
|
+
parsed = JSON.parse(readFileSync3(path11, "utf8"));
|
|
29272
|
+
} catch {
|
|
29273
|
+
return { stale: "unreadable" };
|
|
29274
|
+
}
|
|
29275
|
+
if (parsed.decoderVersion !== DECODER_VERSION) {
|
|
29276
|
+
return { stale: `recorded by decoder v${parsed.decoderVersion}` };
|
|
29277
|
+
}
|
|
29278
|
+
if (parsed.filterHash !== filterHash) {
|
|
29279
|
+
return { stale: "sources changed since it was recorded" };
|
|
29280
|
+
}
|
|
29281
|
+
return parsed;
|
|
29282
|
+
}
|
|
29283
|
+
function eventTypeFor(filter) {
|
|
29284
|
+
if (filter.type === "print_event")
|
|
29285
|
+
return "print";
|
|
29286
|
+
if (filter.type === "contract_call" || filter.type === "contract_deploy") {
|
|
29287
|
+
return null;
|
|
29288
|
+
}
|
|
29289
|
+
return filter.type;
|
|
29290
|
+
}
|
|
29291
|
+
async function runSubgraphTest(file, options3) {
|
|
29292
|
+
const absPath = resolve2(file);
|
|
29293
|
+
if (!existsSync2(absPath)) {
|
|
29294
|
+
error(`File not found: ${absPath}`);
|
|
29295
|
+
process.exit(1);
|
|
29296
|
+
}
|
|
29297
|
+
const { readFile: readFile3 } = await import("node:fs/promises");
|
|
29298
|
+
const { bundleSubgraphCode } = await import("@secondlayer/bundler");
|
|
29299
|
+
const { createTestContext, buildEvent } = await import("@secondlayer/subgraphs/testing");
|
|
29300
|
+
const source = await readFile3(absPath, "utf8");
|
|
29301
|
+
const bundled = await bundleSubgraphCode(source);
|
|
29302
|
+
const sources = bundled.sources ?? {};
|
|
29303
|
+
const filterHash = filterHashOf(sources);
|
|
29304
|
+
const mod = await import(`${absPath}?t=${Date.now()}`);
|
|
29305
|
+
const def = mod.default;
|
|
29306
|
+
if (!def?.handlers || !def.schema) {
|
|
29307
|
+
error("File must default-export a defineSubgraph() definition with handlers and schema.");
|
|
29308
|
+
process.exit(1);
|
|
29309
|
+
}
|
|
29310
|
+
const cached = loadCassette(bundled.name, filterHash);
|
|
29311
|
+
if (cached && "stale" in cached) {
|
|
29312
|
+
warn(`Cassette discarded (${cached.stale}) — re-recording.`);
|
|
29313
|
+
}
|
|
29314
|
+
const usable = cached && !("stale" in cached) ? cached : null;
|
|
29315
|
+
let events;
|
|
29316
|
+
let fromHeight;
|
|
29317
|
+
let toHeight;
|
|
29318
|
+
if (usable && options3.offline !== false && !options3.from) {
|
|
29319
|
+
info(`Replaying cassette: blocks ${usable.fromHeight}–${usable.toHeight}, recorded ${usable.recordedAt}`);
|
|
29320
|
+
events = usable.events;
|
|
29321
|
+
fromHeight = usable.fromHeight;
|
|
29322
|
+
toHeight = usable.toHeight;
|
|
29323
|
+
} else {
|
|
29324
|
+
if (options3.offline) {
|
|
29325
|
+
error("No usable cassette for --offline. Record one first: sl subgraphs test <file> --from <h> --to <h>");
|
|
29326
|
+
process.exit(1);
|
|
29327
|
+
}
|
|
29328
|
+
if (!options3.from) {
|
|
29329
|
+
error("--from <height> is required for the first run (Index reads are metered). Later runs replay the cassette.");
|
|
29330
|
+
process.exit(1);
|
|
29331
|
+
}
|
|
29332
|
+
fromHeight = Number(options3.from);
|
|
29333
|
+
toHeight = options3.to ? Number(options3.to) : fromHeight + 100;
|
|
29334
|
+
if (!Number.isInteger(fromHeight) || !Number.isInteger(toHeight)) {
|
|
29335
|
+
error("--from/--to must be integers.");
|
|
29336
|
+
process.exit(1);
|
|
29337
|
+
}
|
|
29338
|
+
const limit = options3.limit ? Number(options3.limit) : 500;
|
|
29339
|
+
const index = new Index;
|
|
29340
|
+
events = {};
|
|
29341
|
+
for (const [name, filter] of Object.entries(sources)) {
|
|
29342
|
+
const eventType = eventTypeFor(filter);
|
|
29343
|
+
if (eventType === null) {
|
|
29344
|
+
warn(`source "${name}" (${filter.type}) is not readable from index.events — skipped.`);
|
|
29345
|
+
continue;
|
|
29346
|
+
}
|
|
29347
|
+
info(`Fetching ${name} (${eventType}) blocks ${fromHeight}–${toHeight}…`);
|
|
29348
|
+
try {
|
|
29349
|
+
const envelope = await index.events.list({
|
|
29350
|
+
eventType,
|
|
29351
|
+
...filter.contractId ? {
|
|
29352
|
+
contractId: Array.isArray(filter.contractId) ? filter.contractId : filter.contractId
|
|
29353
|
+
} : {},
|
|
29354
|
+
fromHeight,
|
|
29355
|
+
toHeight,
|
|
29356
|
+
limit
|
|
29357
|
+
});
|
|
29358
|
+
events[name] = envelope.events;
|
|
29359
|
+
} catch (err) {
|
|
29360
|
+
const e2 = err;
|
|
29361
|
+
if (e2?.status === 402) {
|
|
29362
|
+
const details = e2.body?.details;
|
|
29363
|
+
error(`Blocks ${fromHeight}–${toHeight} are below the free read window.${details?.oldest_seekable_height ? ` Try --from ${details.oldest_seekable_height}, or add a paid API key (SL_API_KEY) to test against older history.` : " Add a paid API key (SL_API_KEY) to test against older history."}`);
|
|
29364
|
+
process.exit(1);
|
|
29365
|
+
}
|
|
29366
|
+
throw err;
|
|
29367
|
+
}
|
|
29368
|
+
}
|
|
29369
|
+
if (options3.record !== false) {
|
|
29370
|
+
const cassette = {
|
|
29371
|
+
decoderVersion: DECODER_VERSION,
|
|
29372
|
+
filterHash,
|
|
29373
|
+
subgraph: bundled.name,
|
|
29374
|
+
fromHeight,
|
|
29375
|
+
toHeight,
|
|
29376
|
+
recordedAt: new Date().toISOString(),
|
|
29377
|
+
events
|
|
29378
|
+
};
|
|
29379
|
+
const path11 = cassettePath(bundled.name);
|
|
29380
|
+
mkdirSync(dirname3(path11), { recursive: true });
|
|
29381
|
+
writeFileSync2(path11, `${JSON.stringify(cassette, (_k, v2) => typeof v2 === "bigint" ? `${v2}n` : v2, 2)}
|
|
29382
|
+
`);
|
|
29383
|
+
info(`Recorded cassette → ${path11}`);
|
|
29384
|
+
}
|
|
29385
|
+
}
|
|
29386
|
+
const ctx = createTestContext(def.schema);
|
|
29387
|
+
let applied = 0;
|
|
29388
|
+
let failed = 0;
|
|
29389
|
+
const failures = [];
|
|
29390
|
+
for (const [name, rows] of Object.entries(events)) {
|
|
29391
|
+
const handler = def.handlers[name] ?? def.handlers["*"];
|
|
29392
|
+
if (typeof handler !== "function") {
|
|
29393
|
+
warn(`source "${name}": no handler — skipped.`);
|
|
29394
|
+
continue;
|
|
29395
|
+
}
|
|
29396
|
+
const filter = sources[name];
|
|
29397
|
+
for (const row of rows) {
|
|
29398
|
+
const payload = toHandlerPayload(filter, row);
|
|
29399
|
+
if (filter?.type === "print_event" && filter.topic && payload.topic !== filter.topic) {
|
|
29400
|
+
continue;
|
|
29401
|
+
}
|
|
29402
|
+
try {
|
|
29403
|
+
await handler(buildEvent(filter, payload), ctx);
|
|
29404
|
+
applied++;
|
|
29405
|
+
} catch (err) {
|
|
29406
|
+
failed++;
|
|
29407
|
+
if (failures.length < 5) {
|
|
29408
|
+
failures.push(` ${name} @ ${row.cursor}: ${err instanceof Error ? err.message : String(err)}`);
|
|
29409
|
+
}
|
|
29410
|
+
}
|
|
29411
|
+
}
|
|
29412
|
+
}
|
|
29413
|
+
info("");
|
|
29414
|
+
const tables = Object.keys(def.schema);
|
|
29415
|
+
let totalRows = 0;
|
|
29416
|
+
for (const table of tables) {
|
|
29417
|
+
const rows = await ctx.rows(table);
|
|
29418
|
+
totalRows += rows.length;
|
|
29419
|
+
info(` ${table.padEnd(24)} ${String(rows.length).padStart(6)} rows`);
|
|
29420
|
+
const sample = rows[0];
|
|
29421
|
+
if (sample) {
|
|
29422
|
+
const preview = Object.entries(sample).filter(([k2]) => !k2.startsWith("_")).slice(0, 4).map(([k2, v2]) => `${k2}=${String(v2).slice(0, 24)}`).join(" ");
|
|
29423
|
+
info(` ${"".padEnd(24)} ${preview}`);
|
|
29424
|
+
}
|
|
29425
|
+
}
|
|
29426
|
+
info("");
|
|
29427
|
+
if (failed > 0) {
|
|
29428
|
+
warn(`${failed} handler error${failed === 1 ? "" : "s"}:`);
|
|
29429
|
+
for (const f2 of failures)
|
|
29430
|
+
warn(f2);
|
|
29431
|
+
}
|
|
29432
|
+
const fetched = Object.values(events).reduce((n3, r2) => n3 + r2.length, 0);
|
|
29433
|
+
if (fetched === 0) {
|
|
29434
|
+
warn(`No events matched these sources in blocks ${fromHeight}–${toHeight}. Widen the range (--to) or check the source filters.`);
|
|
29435
|
+
return;
|
|
29436
|
+
}
|
|
29437
|
+
if (totalRows === 0) {
|
|
29438
|
+
error(`${applied} event${applied === 1 ? "" : "s"} applied, but NO rows were written — the shape of the field-mapping bug that shipped a 0-row subgraph. Check your handler's field names against the payload.`);
|
|
29439
|
+
process.exit(1);
|
|
29440
|
+
}
|
|
29441
|
+
success(`${applied} event${applied === 1 ? "" : "s"} → ${totalRows} row${totalRows === 1 ? "" : "s"} across ${tables.length} table${tables.length === 1 ? "" : "s"} (blocks ${fromHeight}–${toHeight})`);
|
|
29442
|
+
}
|
|
29443
|
+
function toHandlerPayload(_filter, row) {
|
|
29444
|
+
if (row.event_type === "print") {
|
|
29445
|
+
const payload = row.payload;
|
|
29446
|
+
return {
|
|
29447
|
+
contractId: row.contract_id ?? "",
|
|
29448
|
+
topic: payload?.topic ?? "",
|
|
29449
|
+
data: payload?.value ?? {}
|
|
29450
|
+
};
|
|
29451
|
+
}
|
|
29452
|
+
const r2 = row;
|
|
29453
|
+
return {
|
|
29454
|
+
...r2.sender !== undefined ? { sender: r2.sender } : {},
|
|
29455
|
+
...r2.recipient !== undefined ? { recipient: r2.recipient } : {},
|
|
29456
|
+
...r2.amount !== undefined ? { amount: BigInt(String(r2.amount)) } : {},
|
|
29457
|
+
...r2.asset_identifier !== undefined ? { assetIdentifier: r2.asset_identifier } : {},
|
|
29458
|
+
...r2.value !== undefined ? { tokenId: r2.value } : {}
|
|
29459
|
+
};
|
|
29460
|
+
}
|
|
29461
|
+
var CASSETTE_DIR = "cassettes", DECODER_VERSION = 1;
|
|
29462
|
+
var init_subgraph_test = __esm(() => {
|
|
29463
|
+
init_output();
|
|
29464
|
+
});
|
|
29465
|
+
|
|
29209
29466
|
// src/commands/subgraphs.ts
|
|
29210
29467
|
var exports_subgraphs = {};
|
|
29211
29468
|
__export(exports_subgraphs, {
|
|
@@ -29224,13 +29481,13 @@ __export(exports_subgraphs, {
|
|
|
29224
29481
|
});
|
|
29225
29482
|
import { spawn as spawn2 } from "node:child_process";
|
|
29226
29483
|
import {
|
|
29227
|
-
existsSync as
|
|
29228
|
-
mkdirSync,
|
|
29229
|
-
readFileSync as
|
|
29484
|
+
existsSync as existsSync3,
|
|
29485
|
+
mkdirSync as mkdirSync2,
|
|
29486
|
+
readFileSync as readFileSync4,
|
|
29230
29487
|
watch,
|
|
29231
|
-
writeFileSync as
|
|
29488
|
+
writeFileSync as writeFileSync3
|
|
29232
29489
|
} from "node:fs";
|
|
29233
|
-
import { basename, dirname as
|
|
29490
|
+
import { basename, dirname as dirname4, extname, join as join4, resolve as resolve3 } from "node:path";
|
|
29234
29491
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
29235
29492
|
import { confirm as confirm3 } from "@inquirer/prompts";
|
|
29236
29493
|
import {
|
|
@@ -29319,8 +29576,8 @@ function ormFlagsConflictingWithPayloads(getOptionValueSource) {
|
|
|
29319
29576
|
return Object.entries(ORM_ONLY_CODEGEN_FLAGS).filter(([key]) => getOptionValueSource(key) === "cli").map(([, flag]) => flag);
|
|
29320
29577
|
}
|
|
29321
29578
|
async function runPayloadsCodegen(file, output2) {
|
|
29322
|
-
const absPath =
|
|
29323
|
-
if (!
|
|
29579
|
+
const absPath = resolve3(file);
|
|
29580
|
+
if (!existsSync3(absPath)) {
|
|
29324
29581
|
error(`File not found: ${absPath}`);
|
|
29325
29582
|
process.exit(1);
|
|
29326
29583
|
}
|
|
@@ -29365,7 +29622,7 @@ async function runPayloadsCodegen(file, output2) {
|
|
|
29365
29622
|
process.exit(1);
|
|
29366
29623
|
}
|
|
29367
29624
|
const out = generatePrintPayloadTypes({ sources });
|
|
29368
|
-
const outPath =
|
|
29625
|
+
const outPath = resolve3(output2 ?? join4(dirname4(absPath), `${basename(absPath, extname(absPath))}.payloads.d.ts`));
|
|
29369
29626
|
await writeTextFile(outPath, out);
|
|
29370
29627
|
success(`Wrote print payload types to ${outPath}`);
|
|
29371
29628
|
}
|
|
@@ -29390,10 +29647,10 @@ async function writeOrPrintSubgraphSpec(spec, format2, output2) {
|
|
|
29390
29647
|
process.stdout.write(text2);
|
|
29391
29648
|
return;
|
|
29392
29649
|
}
|
|
29393
|
-
const outPath =
|
|
29394
|
-
const dir =
|
|
29395
|
-
if (!
|
|
29396
|
-
|
|
29650
|
+
const outPath = resolve3(output2);
|
|
29651
|
+
const dir = resolve3(outPath, "..");
|
|
29652
|
+
if (!existsSync3(dir))
|
|
29653
|
+
mkdirSync2(dir, { recursive: true });
|
|
29397
29654
|
await writeTextFile(outPath, text2);
|
|
29398
29655
|
success(`Created ${outPath}`);
|
|
29399
29656
|
}
|
|
@@ -29484,15 +29741,15 @@ function createLocalSubgraphDetail(input2) {
|
|
|
29484
29741
|
};
|
|
29485
29742
|
}
|
|
29486
29743
|
function readCliSubgraphsDependency() {
|
|
29487
|
-
const here =
|
|
29744
|
+
const here = dirname4(fileURLToPath3(import.meta.url));
|
|
29488
29745
|
const candidates = [
|
|
29489
|
-
|
|
29490
|
-
|
|
29746
|
+
resolve3(here, "..", "..", "package.json"),
|
|
29747
|
+
resolve3(here, "..", "package.json")
|
|
29491
29748
|
];
|
|
29492
29749
|
for (const candidate of candidates) {
|
|
29493
|
-
if (!
|
|
29750
|
+
if (!existsSync3(candidate))
|
|
29494
29751
|
continue;
|
|
29495
|
-
const pkg = JSON.parse(
|
|
29752
|
+
const pkg = JSON.parse(readFileSync4(candidate, "utf8"));
|
|
29496
29753
|
const dep = pkg.dependencies?.["@secondlayer/subgraphs"];
|
|
29497
29754
|
if (dep)
|
|
29498
29755
|
return dep;
|
|
@@ -29502,8 +29759,8 @@ function readCliSubgraphsDependency() {
|
|
|
29502
29759
|
function ensureScaffoldPackageJson(dir) {
|
|
29503
29760
|
const packagePath = join4(dir, "package.json");
|
|
29504
29761
|
const subgraphsDep = readCliSubgraphsDependency();
|
|
29505
|
-
if (!
|
|
29506
|
-
|
|
29762
|
+
if (!existsSync3(packagePath)) {
|
|
29763
|
+
writeFileSync3(packagePath, `${JSON.stringify({
|
|
29507
29764
|
type: "module",
|
|
29508
29765
|
dependencies: {
|
|
29509
29766
|
"@secondlayer/subgraphs": subgraphsDep
|
|
@@ -29512,14 +29769,14 @@ function ensureScaffoldPackageJson(dir) {
|
|
|
29512
29769
|
`, "utf8");
|
|
29513
29770
|
return;
|
|
29514
29771
|
}
|
|
29515
|
-
const pkg = JSON.parse(
|
|
29772
|
+
const pkg = JSON.parse(readFileSync4(packagePath, "utf8"));
|
|
29516
29773
|
if (pkg.dependencies?.["@secondlayer/subgraphs"])
|
|
29517
29774
|
return;
|
|
29518
29775
|
pkg.dependencies = {
|
|
29519
29776
|
...pkg.dependencies ?? {},
|
|
29520
29777
|
"@secondlayer/subgraphs": subgraphsDep
|
|
29521
29778
|
};
|
|
29522
|
-
|
|
29779
|
+
writeFileSync3(packagePath, `${JSON.stringify(pkg, null, 2)}
|
|
29523
29780
|
`, "utf8");
|
|
29524
29781
|
}
|
|
29525
29782
|
async function runBunInstall(dir) {
|
|
@@ -29687,9 +29944,9 @@ ${SUBGRAPH_TEMPLATE_SLUGS.map((s2) => ` ${s2.padEnd(20)} ${SUBGRAPH_TEMPLATE_DE
|
|
|
29687
29944
|
`)}`);
|
|
29688
29945
|
process.exit(1);
|
|
29689
29946
|
}
|
|
29690
|
-
const dir =
|
|
29691
|
-
const filePath =
|
|
29692
|
-
if (
|
|
29947
|
+
const dir = resolve3("subgraphs");
|
|
29948
|
+
const filePath = resolve3(dir, `${name}.ts`);
|
|
29949
|
+
if (existsSync3(filePath)) {
|
|
29693
29950
|
error(`File already exists: ${filePath}`);
|
|
29694
29951
|
process.exit(1);
|
|
29695
29952
|
}
|
|
@@ -29717,8 +29974,8 @@ Check the contract id, and that the contract has emitted print events (schemas a
|
|
|
29717
29974
|
} else {
|
|
29718
29975
|
content = generateSubgraphTemplate(name, slug);
|
|
29719
29976
|
}
|
|
29720
|
-
if (!
|
|
29721
|
-
|
|
29977
|
+
if (!existsSync3(dir)) {
|
|
29978
|
+
mkdirSync2(dir, { recursive: true });
|
|
29722
29979
|
}
|
|
29723
29980
|
await writeTextFile(filePath, content);
|
|
29724
29981
|
success(`Created ${filePath}`);
|
|
@@ -29731,8 +29988,8 @@ Check the contract id, and that the contract has emitted print events (schemas a
|
|
|
29731
29988
|
});
|
|
29732
29989
|
subgraphs.command("dev <file>").description("Watch a subgraph file and auto-redeploy on change").action(async (file) => {
|
|
29733
29990
|
await requireLocalNetwork();
|
|
29734
|
-
const absPath =
|
|
29735
|
-
if (!
|
|
29991
|
+
const absPath = resolve3(file);
|
|
29992
|
+
if (!existsSync3(absPath)) {
|
|
29736
29993
|
error(`File not found: ${absPath}`);
|
|
29737
29994
|
process.exit(1);
|
|
29738
29995
|
}
|
|
@@ -29792,7 +30049,7 @@ Stopped watching.`);
|
|
|
29792
30049
|
});
|
|
29793
30050
|
subgraphs.command("deploy <file>").alias("update").description("Deploy a subgraph definition file (alias: update — deploy is create-or-update)").option("--start-block <n>", "Override the subgraph definition startBlock for this deploy").option("--tip-first", "Go live at chain tip immediately; history backfills in the background (requires order-tolerant handlers — commutative or insert-only writes)").option("--dry-run", "Validate and preview deploy without writing changes").option("-y, --yes", "Skip the reindex confirmation prompt").option("--database-url <url>", "BYO data plane: write the subgraph's schema/rows to your own Postgres. With --dry-run, prints the DDL + grant script and verifies the connection.").option("--strict", "Run `tsc --noEmit` against the handler before deploy (slower; catches TS type errors)").option("--visibility <visibility>", "Read visibility: public (anon /v1 reads, global name claim) or private (your key only). Defaults: managed → public, BYO → private.").action(async (file, options3) => {
|
|
29794
30051
|
try {
|
|
29795
|
-
const absPath =
|
|
30052
|
+
const absPath = resolve3(file);
|
|
29796
30053
|
const config = await loadConfig2();
|
|
29797
30054
|
if (config.network !== "local") {
|
|
29798
30055
|
await requireAuth();
|
|
@@ -30093,8 +30350,8 @@ Synced — exiting watch.`));
|
|
|
30093
30350
|
try {
|
|
30094
30351
|
const format2 = parseSubgraphSpecFormat(options3.format);
|
|
30095
30352
|
const specOptions = options3.server ? { serverUrl: options3.server } : undefined;
|
|
30096
|
-
const absPath =
|
|
30097
|
-
if (nameOrFile.endsWith(".ts") && !
|
|
30353
|
+
const absPath = resolve3(nameOrFile);
|
|
30354
|
+
if (nameOrFile.endsWith(".ts") && !existsSync3(absPath)) {
|
|
30098
30355
|
error(`File not found: ${absPath}`);
|
|
30099
30356
|
process.exit(1);
|
|
30100
30357
|
}
|
|
@@ -30113,6 +30370,13 @@ Synced — exiting watch.`));
|
|
|
30113
30370
|
deprecatedCodegenNotice("sl subgraphs codegen", options3.payloads ? "sl codegen prints" : "sl codegen subgraph");
|
|
30114
30371
|
await runSubgraphSchemaCodegen(file, options3, (key) => command.getOptionValueSource(key));
|
|
30115
30372
|
});
|
|
30373
|
+
subgraphs.command("test <file>").description("Run a subgraph's handlers against real chain data without deploying").option("--from <height>", "Start block height (required on first run)").option("--to <height>", "End block height (defaults to --from + 100)").option("--offline", "Replay the recorded cassette; never hit the network").option("--no-record", "Don't write a cassette").option("--limit <n>", "Max events per source", "500").addHelpText("after", `
|
|
30374
|
+
Examples:
|
|
30375
|
+
$ sl subgraphs test subgraphs/bns-names.ts --from 167484 --to 167600
|
|
30376
|
+
$ sl subgraphs test subgraphs/bns-names.ts --offline`).action(async (file, options3) => {
|
|
30377
|
+
const { runSubgraphTest: runSubgraphTest2 } = await Promise.resolve().then(() => (init_subgraph_test(), exports_subgraph_test));
|
|
30378
|
+
await runSubgraphTest2(file, options3);
|
|
30379
|
+
});
|
|
30116
30380
|
subgraphs.command("reindex <name>").description("Reindex a subgraph from historical blocks (drops + reprocesses)").option("--from-block <n>", "Start block height").option("--to-block <n>", "End block height").option("-y, --yes", "Skip confirmation").addHelpText("after", `
|
|
30117
30381
|
Examples:
|
|
30118
30382
|
$ sl subgraphs reindex my-graph -y
|
|
@@ -30372,7 +30636,7 @@ Examples:
|
|
|
30372
30636
|
error("a <contractAddress> is required (or use --trait)");
|
|
30373
30637
|
process.exit(1);
|
|
30374
30638
|
}
|
|
30375
|
-
const outPath =
|
|
30639
|
+
const outPath = resolve3(options3.output);
|
|
30376
30640
|
let content;
|
|
30377
30641
|
if (trait) {
|
|
30378
30642
|
info(`Generating trait-scoped scaffold for ${trait}...`);
|
|
@@ -30392,9 +30656,9 @@ Examples:
|
|
|
30392
30656
|
functions: options3.functions?.split(",").map((f2) => f2.trim()).filter(Boolean)
|
|
30393
30657
|
});
|
|
30394
30658
|
}
|
|
30395
|
-
const dir =
|
|
30396
|
-
if (!
|
|
30397
|
-
|
|
30659
|
+
const dir = resolve3(outPath, "..");
|
|
30660
|
+
if (!existsSync3(dir))
|
|
30661
|
+
mkdirSync2(dir, { recursive: true });
|
|
30398
30662
|
await writeTextFile(outPath, content);
|
|
30399
30663
|
ensureScaffoldPackageJson(dir);
|
|
30400
30664
|
success(`Created ${outPath}`);
|
|
@@ -30427,14 +30691,14 @@ async function runSubgraphClientCodegen(subgraphName, options3) {
|
|
|
30427
30691
|
error("--output <path> is required");
|
|
30428
30692
|
process.exit(1);
|
|
30429
30693
|
}
|
|
30430
|
-
const outPath =
|
|
30694
|
+
const outPath = resolve3(options3.output);
|
|
30431
30695
|
info(`Fetching subgraph metadata for "${subgraphName}"...`);
|
|
30432
30696
|
const subgraphDetail = await getSubgraphApi(subgraphName);
|
|
30433
30697
|
info("Generating typed client...");
|
|
30434
30698
|
const content = await generateSubgraphConsumer(subgraphName, subgraphDetail);
|
|
30435
|
-
const dir =
|
|
30436
|
-
if (!
|
|
30437
|
-
|
|
30699
|
+
const dir = resolve3(outPath, "..");
|
|
30700
|
+
if (!existsSync3(dir))
|
|
30701
|
+
mkdirSync2(dir, { recursive: true });
|
|
30438
30702
|
await writeTextFile(outPath, content);
|
|
30439
30703
|
success(`Created ${outPath}`);
|
|
30440
30704
|
} catch (err) {
|
|
@@ -30457,8 +30721,8 @@ async function runSubgraphSchemaCodegen(file, options3, optionSource, defaultTar
|
|
|
30457
30721
|
error(`Unsupported --target "${target}" (supported: prisma, drizzle, kysely).`);
|
|
30458
30722
|
process.exit(1);
|
|
30459
30723
|
}
|
|
30460
|
-
const absPath =
|
|
30461
|
-
if (!
|
|
30724
|
+
const absPath = resolve3(file);
|
|
30725
|
+
if (!existsSync3(absPath)) {
|
|
30462
30726
|
error(`File not found: ${absPath}`);
|
|
30463
30727
|
process.exit(1);
|
|
30464
30728
|
}
|
|
@@ -30485,7 +30749,7 @@ async function runSubgraphSchemaCodegen(file, options3, optionSource, defaultTar
|
|
|
30485
30749
|
modelsOnly: options3.modelsOnly
|
|
30486
30750
|
});
|
|
30487
30751
|
if (options3.output) {
|
|
30488
|
-
await writeTextFile(
|
|
30752
|
+
await writeTextFile(resolve3(options3.output), out);
|
|
30489
30753
|
success(`Wrote ${target} schema to ${options3.output}`);
|
|
30490
30754
|
const next = target === "prisma" ? "point its datasource at your BYO database, then `prisma generate`." : target === "drizzle" ? "point your Drizzle connection at your BYO database (treat tables read-only)." : "import the `DB` type into `new Kysely<DB>()` against your BYO database.";
|
|
30491
30755
|
info(`Next: ${next}`);
|
|
@@ -30527,10 +30791,10 @@ __export(exports_index_api, {
|
|
|
30527
30791
|
runIndexCodegen: () => runIndexCodegen,
|
|
30528
30792
|
registerIndexCommand: () => registerIndexCommand
|
|
30529
30793
|
});
|
|
30530
|
-
import { resolve as
|
|
30531
|
-
import { Index } from "@secondlayer/sdk";
|
|
30794
|
+
import { resolve as resolve4 } from "node:path";
|
|
30795
|
+
import { Index as Index2 } from "@secondlayer/sdk";
|
|
30532
30796
|
function client() {
|
|
30533
|
-
return new
|
|
30797
|
+
return new Index2({
|
|
30534
30798
|
baseUrl: process.env.SL_API_URL ?? DEFAULT_BASE_URL,
|
|
30535
30799
|
apiKey: resolveEnvKey()
|
|
30536
30800
|
});
|
|
@@ -30719,7 +30983,7 @@ async function runIndexCodegen(o3) {
|
|
|
30719
30983
|
datasourceEnv: o3.env
|
|
30720
30984
|
});
|
|
30721
30985
|
if (o3.output) {
|
|
30722
|
-
await writeTextFile(
|
|
30986
|
+
await writeTextFile(resolve4(o3.output), out);
|
|
30723
30987
|
success(`Wrote ${target} Index schema to ${o3.output}`);
|
|
30724
30988
|
} else {
|
|
30725
30989
|
process.stdout.write(out);
|
|
@@ -30831,9 +31095,9 @@ var init_query = __esm(() => {
|
|
|
30831
31095
|
CLOSE = {};
|
|
30832
31096
|
Query = class Query extends Promise {
|
|
30833
31097
|
constructor(strings, args, handler, canceller, options3 = {}) {
|
|
30834
|
-
let
|
|
31098
|
+
let resolve5, reject;
|
|
30835
31099
|
super((a4, b2) => {
|
|
30836
|
-
|
|
31100
|
+
resolve5 = a4;
|
|
30837
31101
|
reject = b2;
|
|
30838
31102
|
});
|
|
30839
31103
|
this.tagged = Array.isArray(strings.raw);
|
|
@@ -30844,7 +31108,7 @@ var init_query = __esm(() => {
|
|
|
30844
31108
|
this.options = options3;
|
|
30845
31109
|
this.state = null;
|
|
30846
31110
|
this.statement = null;
|
|
30847
|
-
this.resolve = (x2) => (this.active = false,
|
|
31111
|
+
this.resolve = (x2) => (this.active = false, resolve5(x2));
|
|
30848
31112
|
this.reject = (x2) => (this.active = false, reject(x2));
|
|
30849
31113
|
this.active = false;
|
|
30850
31114
|
this.cancelled = null;
|
|
@@ -30892,12 +31156,12 @@ var init_query = __esm(() => {
|
|
|
30892
31156
|
if (this.executed && !this.active)
|
|
30893
31157
|
return { done: true };
|
|
30894
31158
|
prev && prev();
|
|
30895
|
-
const promise = new Promise((
|
|
31159
|
+
const promise = new Promise((resolve5, reject) => {
|
|
30896
31160
|
this.cursorFn = (value) => {
|
|
30897
|
-
|
|
31161
|
+
resolve5({ value, done: false });
|
|
30898
31162
|
return new Promise((r2) => prev = r2);
|
|
30899
31163
|
};
|
|
30900
|
-
this.resolve = () => (this.active = false,
|
|
31164
|
+
this.resolve = () => (this.active = false, resolve5({ done: true }));
|
|
30901
31165
|
this.reject = (x2) => (this.active = false, reject(x2));
|
|
30902
31166
|
});
|
|
30903
31167
|
this.execute();
|
|
@@ -31451,12 +31715,12 @@ function Connection(options3, queues = {}, { onopen = noop4, onend = noop4, oncl
|
|
|
31451
31715
|
x2.on("drain", drain);
|
|
31452
31716
|
return x2;
|
|
31453
31717
|
}
|
|
31454
|
-
async function cancel({ pid, secret },
|
|
31718
|
+
async function cancel({ pid, secret }, resolve5, reject) {
|
|
31455
31719
|
try {
|
|
31456
31720
|
cancelMessage = bytes_default().i32(16).i32(80877102).i32(pid).i32(secret).end(16);
|
|
31457
31721
|
await connect();
|
|
31458
31722
|
socket.once("error", reject);
|
|
31459
|
-
socket.once("close",
|
|
31723
|
+
socket.once("close", resolve5);
|
|
31460
31724
|
} catch (error3) {
|
|
31461
31725
|
reject(error3);
|
|
31462
31726
|
}
|
|
@@ -32329,7 +32593,7 @@ var noop5 = () => {};
|
|
|
32329
32593
|
// ../../node_modules/postgres/src/large.js
|
|
32330
32594
|
import Stream2 from "stream";
|
|
32331
32595
|
function largeObject(sql, oid, mode = 131072 | 262144) {
|
|
32332
|
-
return new Promise(async (
|
|
32596
|
+
return new Promise(async (resolve5, reject) => {
|
|
32333
32597
|
await sql.begin(async (sql2) => {
|
|
32334
32598
|
let finish;
|
|
32335
32599
|
!oid && ([{ oid }] = await sql2`select lo_creat(-1) as oid`);
|
|
@@ -32355,7 +32619,7 @@ function largeObject(sql, oid, mode = 131072 | 262144) {
|
|
|
32355
32619
|
) seek
|
|
32356
32620
|
`
|
|
32357
32621
|
};
|
|
32358
|
-
|
|
32622
|
+
resolve5(lo);
|
|
32359
32623
|
return new Promise(async (r2) => finish = r2);
|
|
32360
32624
|
async function readable2({
|
|
32361
32625
|
highWaterMark = 2048 * 8,
|
|
@@ -32515,8 +32779,8 @@ function Postgres(a4, b3) {
|
|
|
32515
32779
|
}
|
|
32516
32780
|
async function reserve() {
|
|
32517
32781
|
const queue = queue_default();
|
|
32518
|
-
const c4 = open.length ? open.shift() : await new Promise((
|
|
32519
|
-
const query = { reserve:
|
|
32782
|
+
const c4 = open.length ? open.shift() : await new Promise((resolve5, reject) => {
|
|
32783
|
+
const query = { reserve: resolve5, reject };
|
|
32520
32784
|
queries.push(query);
|
|
32521
32785
|
closed.length && connect(closed.shift(), query);
|
|
32522
32786
|
});
|
|
@@ -32553,9 +32817,9 @@ function Postgres(a4, b3) {
|
|
|
32553
32817
|
let uncaughtError, result;
|
|
32554
32818
|
name && await sql2`savepoint ${sql2(name)}`;
|
|
32555
32819
|
try {
|
|
32556
|
-
result = await new Promise((
|
|
32820
|
+
result = await new Promise((resolve5, reject) => {
|
|
32557
32821
|
const x2 = fn2(sql2);
|
|
32558
|
-
Promise.resolve(Array.isArray(x2) ? Promise.all(x2) : x2).then(
|
|
32822
|
+
Promise.resolve(Array.isArray(x2) ? Promise.all(x2) : x2).then(resolve5, reject);
|
|
32559
32823
|
});
|
|
32560
32824
|
if (uncaughtError)
|
|
32561
32825
|
throw uncaughtError;
|
|
@@ -32612,8 +32876,8 @@ function Postgres(a4, b3) {
|
|
|
32612
32876
|
return c4.execute(query) ? move(c4, busy) : move(c4, full);
|
|
32613
32877
|
}
|
|
32614
32878
|
function cancel(query) {
|
|
32615
|
-
return new Promise((
|
|
32616
|
-
query.state ? query.active ? connection_default(options3).cancel(query.state,
|
|
32879
|
+
return new Promise((resolve5, reject) => {
|
|
32880
|
+
query.state ? query.active ? connection_default(options3).cancel(query.state, resolve5, reject) : query.cancelled = { resolve: resolve5, reject } : (queries.remove(query), query.cancelled = true, query.reject(Errors.generic("57014", "canceling statement due to user request")), resolve5());
|
|
32617
32881
|
});
|
|
32618
32882
|
}
|
|
32619
32883
|
async function end({ timeout = null } = {}) {
|
|
@@ -32629,11 +32893,11 @@ function Postgres(a4, b3) {
|
|
|
32629
32893
|
async function close() {
|
|
32630
32894
|
await Promise.all(connections.map((c4) => c4.end()));
|
|
32631
32895
|
}
|
|
32632
|
-
async function destroy(
|
|
32896
|
+
async function destroy(resolve5) {
|
|
32633
32897
|
await Promise.all(connections.map((c4) => c4.terminate()));
|
|
32634
32898
|
while (queries.length)
|
|
32635
32899
|
queries.shift().reject(Errors.connection("CONNECTION_DESTROYED", options3));
|
|
32636
|
-
|
|
32900
|
+
resolve5();
|
|
32637
32901
|
}
|
|
32638
32902
|
function connect(c4, query) {
|
|
32639
32903
|
move(c4, connecting);
|
|
@@ -33273,11 +33537,11 @@ var init_manager = __esm(() => {
|
|
|
33273
33537
|
});
|
|
33274
33538
|
|
|
33275
33539
|
// src/services/indexer.ts
|
|
33276
|
-
import { dirname as
|
|
33540
|
+
import { dirname as dirname9, resolve as resolve6 } from "node:path";
|
|
33277
33541
|
async function startIndexer(options3) {
|
|
33278
33542
|
const port = options3.port ?? 3700;
|
|
33279
|
-
const rootDir =
|
|
33280
|
-
const indexerPath =
|
|
33543
|
+
const rootDir = dirname9(dirname9(dirname9(dirname9(import.meta.dir))));
|
|
33544
|
+
const indexerPath = resolve6(rootDir, "packages/indexer/src/index.ts");
|
|
33281
33545
|
await serviceManager.start(SERVICE_NAME, ["bun", "run", "--watch", indexerPath], {
|
|
33282
33546
|
port,
|
|
33283
33547
|
env: {
|
|
@@ -33293,10 +33557,10 @@ var init_indexer = __esm(() => {
|
|
|
33293
33557
|
});
|
|
33294
33558
|
|
|
33295
33559
|
// src/services/worker.ts
|
|
33296
|
-
import { dirname as
|
|
33560
|
+
import { dirname as dirname10, resolve as resolve7 } from "node:path";
|
|
33297
33561
|
async function startWorker(options3) {
|
|
33298
|
-
const rootDir =
|
|
33299
|
-
const workerPath =
|
|
33562
|
+
const rootDir = dirname10(dirname10(dirname10(dirname10(import.meta.dir))));
|
|
33563
|
+
const workerPath = resolve7(rootDir, "packages/worker/src/index.ts");
|
|
33300
33564
|
await serviceManager.start(SERVICE_NAME2, ["bun", "run", "--watch", workerPath], {
|
|
33301
33565
|
onStdout: options3.onLog,
|
|
33302
33566
|
onStderr: options3.onLog
|
|
@@ -33308,11 +33572,11 @@ var init_worker = __esm(() => {
|
|
|
33308
33572
|
});
|
|
33309
33573
|
|
|
33310
33574
|
// src/services/api.ts
|
|
33311
|
-
import { dirname as
|
|
33575
|
+
import { dirname as dirname11, resolve as resolve8 } from "node:path";
|
|
33312
33576
|
async function startApi(options3) {
|
|
33313
33577
|
const port = options3.port ?? 3800;
|
|
33314
|
-
const rootDir =
|
|
33315
|
-
const apiPath =
|
|
33578
|
+
const rootDir = dirname11(dirname11(dirname11(dirname11(import.meta.dir))));
|
|
33579
|
+
const apiPath = resolve8(rootDir, "packages/api/src/index.ts");
|
|
33316
33580
|
await serviceManager.start(SERVICE_NAME3, ["bun", "run", "--watch", apiPath], {
|
|
33317
33581
|
port,
|
|
33318
33582
|
env: {
|
|
@@ -33328,10 +33592,10 @@ var init_api2 = __esm(() => {
|
|
|
33328
33592
|
});
|
|
33329
33593
|
|
|
33330
33594
|
// src/services/subgraph-processor.ts
|
|
33331
|
-
import { dirname as
|
|
33595
|
+
import { dirname as dirname12, resolve as resolve9 } from "node:path";
|
|
33332
33596
|
async function startSubgraphProcessor(options3) {
|
|
33333
|
-
const rootDir =
|
|
33334
|
-
const servicePath =
|
|
33597
|
+
const rootDir = dirname12(dirname12(dirname12(dirname12(import.meta.dir))));
|
|
33598
|
+
const servicePath = resolve9(rootDir, "packages/subgraphs/src/service.ts");
|
|
33335
33599
|
await serviceManager.start(SERVICE_NAME4, ["bun", "run", "--watch", servicePath], {
|
|
33336
33600
|
env: {
|
|
33337
33601
|
SUBGRAPH_CONCURRENCY: String(options3.concurrency ?? 5)
|
|
@@ -33365,8 +33629,8 @@ __export(exports_dev_impl, {
|
|
|
33365
33629
|
restartDev: () => restartDev,
|
|
33366
33630
|
isDevAlreadyRunning: () => isDevAlreadyRunning
|
|
33367
33631
|
});
|
|
33368
|
-
import { mkdirSync as
|
|
33369
|
-
import { dirname as
|
|
33632
|
+
import { mkdirSync as mkdirSync5 } from "node:fs";
|
|
33633
|
+
import { dirname as dirname13, join as join11, resolve as resolve10 } from "node:path";
|
|
33370
33634
|
async function isDevAlreadyRunning() {
|
|
33371
33635
|
if (await isDevRunning()) {
|
|
33372
33636
|
const running = await getRunningServices();
|
|
@@ -33444,10 +33708,10 @@ async function runBackground(options3) {
|
|
|
33444
33708
|
startedAt: new Date().toISOString()
|
|
33445
33709
|
};
|
|
33446
33710
|
try {
|
|
33447
|
-
const packagesDir =
|
|
33711
|
+
const packagesDir = dirname13(dirname13(dirname13(dirname13(import.meta.dir))));
|
|
33448
33712
|
const env2 = { DATABASE_URL: databaseUrl, DEV_MODE: "true" };
|
|
33449
33713
|
const apiLogFile = getLogFile("api");
|
|
33450
|
-
const apiProc = Bun.spawn(["bun", "run",
|
|
33714
|
+
const apiProc = Bun.spawn(["bun", "run", resolve10(packagesDir, "packages/api/src/index.ts")], {
|
|
33451
33715
|
env: { ...process.env, ...env2, PORT: String(apiPort) },
|
|
33452
33716
|
stdout: Bun.file(apiLogFile),
|
|
33453
33717
|
stderr: Bun.file(apiLogFile)
|
|
@@ -33460,7 +33724,7 @@ async function runBackground(options3) {
|
|
|
33460
33724
|
};
|
|
33461
33725
|
console.log(green(" ✓ API"), dim(`http://localhost:${apiPort}`));
|
|
33462
33726
|
const indexerLogFile = getLogFile("indexer");
|
|
33463
|
-
const indexerProc = Bun.spawn(["bun", "run",
|
|
33727
|
+
const indexerProc = Bun.spawn(["bun", "run", resolve10(packagesDir, "packages/indexer/src/index.ts")], {
|
|
33464
33728
|
env: { ...process.env, ...env2, PORT: String(indexerPort) },
|
|
33465
33729
|
stdout: Bun.file(indexerLogFile),
|
|
33466
33730
|
stderr: Bun.file(indexerLogFile)
|
|
@@ -33474,7 +33738,7 @@ async function runBackground(options3) {
|
|
|
33474
33738
|
console.log(green(" ✓ Indexer"), dim(`http://localhost:${indexerPort}`));
|
|
33475
33739
|
if (options3.worker) {
|
|
33476
33740
|
const workerLogFile = getLogFile("worker");
|
|
33477
|
-
const workerProc = Bun.spawn(["bun", "run",
|
|
33741
|
+
const workerProc = Bun.spawn(["bun", "run", resolve10(packagesDir, "packages/worker/src/index.ts")], {
|
|
33478
33742
|
env: { ...process.env, ...env2 },
|
|
33479
33743
|
stdout: Bun.file(workerLogFile),
|
|
33480
33744
|
stderr: Bun.file(workerLogFile)
|
|
@@ -33492,7 +33756,7 @@ async function runBackground(options3) {
|
|
|
33492
33756
|
const subgraphsProc = Bun.spawn([
|
|
33493
33757
|
"bun",
|
|
33494
33758
|
"run",
|
|
33495
|
-
|
|
33759
|
+
resolve10(packagesDir, "packages/subgraphs/src/service.ts")
|
|
33496
33760
|
], {
|
|
33497
33761
|
env: { ...process.env, ...env2 },
|
|
33498
33762
|
stdout: Bun.file(subgraphsLogFile),
|
|
@@ -33794,7 +34058,7 @@ async function restartDev() {
|
|
|
33794
34058
|
await clearDevState();
|
|
33795
34059
|
await clearLogs();
|
|
33796
34060
|
const config = await loadConfig2();
|
|
33797
|
-
const packagesDir =
|
|
34061
|
+
const packagesDir = dirname13(dirname13(dirname13(dirname13(import.meta.dir))));
|
|
33798
34062
|
const env2 = state.env;
|
|
33799
34063
|
const newState = {
|
|
33800
34064
|
services: {},
|
|
@@ -33804,7 +34068,7 @@ async function restartDev() {
|
|
|
33804
34068
|
};
|
|
33805
34069
|
const apiPort = config.ports.api;
|
|
33806
34070
|
const apiLogFile = getLogFile("api");
|
|
33807
|
-
const apiProc = Bun.spawn(["bun", "run",
|
|
34071
|
+
const apiProc = Bun.spawn(["bun", "run", resolve10(packagesDir, "packages/api/src/index.ts")], {
|
|
33808
34072
|
env: { ...process.env, ...env2, PORT: String(apiPort) },
|
|
33809
34073
|
stdout: Bun.file(apiLogFile),
|
|
33810
34074
|
stderr: Bun.file(apiLogFile)
|
|
@@ -33818,7 +34082,7 @@ async function restartDev() {
|
|
|
33818
34082
|
console.log(green(" ✓ API"), dim(`http://localhost:${apiPort}`));
|
|
33819
34083
|
const indexerPort = config.ports.indexer;
|
|
33820
34084
|
const indexerLogFile = getLogFile("indexer");
|
|
33821
|
-
const indexerProc = Bun.spawn(["bun", "run",
|
|
34085
|
+
const indexerProc = Bun.spawn(["bun", "run", resolve10(packagesDir, "packages/indexer/src/index.ts")], {
|
|
33822
34086
|
env: { ...process.env, ...env2, PORT: String(indexerPort) },
|
|
33823
34087
|
stdout: Bun.file(indexerLogFile),
|
|
33824
34088
|
stderr: Bun.file(indexerLogFile)
|
|
@@ -33832,7 +34096,7 @@ async function restartDev() {
|
|
|
33832
34096
|
console.log(green(" ✓ Indexer"), dim(`http://localhost:${indexerPort}`));
|
|
33833
34097
|
if (state.services.worker) {
|
|
33834
34098
|
const workerLogFile = getLogFile("worker");
|
|
33835
|
-
const workerProc = Bun.spawn(["bun", "run",
|
|
34099
|
+
const workerProc = Bun.spawn(["bun", "run", resolve10(packagesDir, "packages/worker/src/index.ts")], {
|
|
33836
34100
|
env: { ...process.env, ...env2 },
|
|
33837
34101
|
stdout: Bun.file(workerLogFile),
|
|
33838
34102
|
stderr: Bun.file(workerLogFile)
|
|
@@ -33847,7 +34111,7 @@ async function restartDev() {
|
|
|
33847
34111
|
}
|
|
33848
34112
|
if (state.services.subgraphs) {
|
|
33849
34113
|
const subgraphsLogFile = getLogFile("subgraphs");
|
|
33850
|
-
const subgraphsProc = Bun.spawn(["bun", "run",
|
|
34114
|
+
const subgraphsProc = Bun.spawn(["bun", "run", resolve10(packagesDir, "packages/subgraphs/src/service.ts")], {
|
|
33851
34115
|
env: { ...process.env, ...env2 },
|
|
33852
34116
|
stdout: Bun.file(subgraphsLogFile),
|
|
33853
34117
|
stderr: Bun.file(subgraphsLogFile)
|
|
@@ -33976,7 +34240,7 @@ async function ensureDevPostgres(dataDir) {
|
|
|
33976
34240
|
return false;
|
|
33977
34241
|
}
|
|
33978
34242
|
const pgDataDir = join11(dataDir, "postgres");
|
|
33979
|
-
|
|
34243
|
+
mkdirSync5(pgDataDir, { recursive: true });
|
|
33980
34244
|
const stopped = await Bun.$`docker ps -aq -f name=secondlayer-dev-postgres`.quiet().nothrow();
|
|
33981
34245
|
if (stopped.stdout.toString().trim()) {
|
|
33982
34246
|
await Bun.$`docker rm secondlayer-dev-postgres`.quiet().nothrow();
|
|
@@ -33991,8 +34255,8 @@ async function ensureDevPostgres(dataDir) {
|
|
|
33991
34255
|
throw new Error("PostgreSQL failed to start");
|
|
33992
34256
|
}
|
|
33993
34257
|
async function runMigrations(databaseUrl) {
|
|
33994
|
-
const packagesDir =
|
|
33995
|
-
const migrateScript =
|
|
34258
|
+
const packagesDir = dirname13(dirname13(dirname13(dirname13(import.meta.dir))));
|
|
34259
|
+
const migrateScript = resolve10(packagesDir, "packages/shared/src/db/migrate.ts");
|
|
33996
34260
|
const result = await Bun.$`DATABASE_URL=${databaseUrl} bun run ${migrateScript}`.quiet().nothrow();
|
|
33997
34261
|
if (result.exitCode !== 0) {
|
|
33998
34262
|
throw new Error(`Migration failed: ${result.stderr.toString()}`);
|
|
@@ -34475,7 +34739,7 @@ var {
|
|
|
34475
34739
|
// package.json
|
|
34476
34740
|
var package_default = {
|
|
34477
34741
|
name: "@secondlayer/cli",
|
|
34478
|
-
version: "9.
|
|
34742
|
+
version: "9.3.0",
|
|
34479
34743
|
repository: {
|
|
34480
34744
|
type: "git",
|
|
34481
34745
|
url: "git+https://github.com/ryanwaits/secondlayer.git",
|
|
@@ -34500,7 +34764,11 @@ var package_default = {
|
|
|
34500
34764
|
import: "./dist/plugins/index.js"
|
|
34501
34765
|
}
|
|
34502
34766
|
},
|
|
34503
|
-
files: [
|
|
34767
|
+
files: [
|
|
34768
|
+
"dist",
|
|
34769
|
+
"templates",
|
|
34770
|
+
"README.md"
|
|
34771
|
+
],
|
|
34504
34772
|
scripts: {
|
|
34505
34773
|
build: "bunup",
|
|
34506
34774
|
dev: "bunup --watch",
|
|
@@ -34508,7 +34776,13 @@ var package_default = {
|
|
|
34508
34776
|
typecheck: "tsc --noEmit",
|
|
34509
34777
|
prepublishOnly: "bun run build"
|
|
34510
34778
|
},
|
|
34511
|
-
keywords: [
|
|
34779
|
+
keywords: [
|
|
34780
|
+
"stacks",
|
|
34781
|
+
"clarity",
|
|
34782
|
+
"blockchain",
|
|
34783
|
+
"smart-contracts",
|
|
34784
|
+
"cli"
|
|
34785
|
+
],
|
|
34512
34786
|
author: "",
|
|
34513
34787
|
license: "MIT",
|
|
34514
34788
|
dependencies: {
|
|
@@ -34517,8 +34791,8 @@ var package_default = {
|
|
|
34517
34791
|
"@secondlayer/scaffold": "^1.5.0",
|
|
34518
34792
|
"@secondlayer/sdk": "^6.36.0",
|
|
34519
34793
|
"@secondlayer/shared": "^7.0.3",
|
|
34520
|
-
"@secondlayer/stacks": "^2.
|
|
34521
|
-
"@secondlayer/subgraphs": "^3.
|
|
34794
|
+
"@secondlayer/stacks": "^2.22.0",
|
|
34795
|
+
"@secondlayer/subgraphs": "^3.23.0",
|
|
34522
34796
|
"@biomejs/js-api": "^0.7.0",
|
|
34523
34797
|
"@biomejs/wasm-nodejs": "^1.9.0",
|
|
34524
34798
|
esbuild: "^0.27.4",
|
|
@@ -35213,14 +35487,14 @@ init_output();
|
|
|
35213
35487
|
init_resolve_auth();
|
|
35214
35488
|
import {
|
|
35215
35489
|
copyFileSync,
|
|
35216
|
-
existsSync as
|
|
35217
|
-
mkdirSync as
|
|
35218
|
-
readFileSync as
|
|
35490
|
+
existsSync as existsSync4,
|
|
35491
|
+
mkdirSync as mkdirSync3,
|
|
35492
|
+
readFileSync as readFileSync5,
|
|
35219
35493
|
readdirSync,
|
|
35220
35494
|
statSync as statSync2,
|
|
35221
|
-
writeFileSync as
|
|
35495
|
+
writeFileSync as writeFileSync4
|
|
35222
35496
|
} from "node:fs";
|
|
35223
|
-
import { dirname as
|
|
35497
|
+
import { dirname as dirname5, join as join6, relative, resolve as resolve5 } from "node:path";
|
|
35224
35498
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
35225
35499
|
import { input as input2, select as select3 } from "@inquirer/prompts";
|
|
35226
35500
|
import { SecondLayer as SecondLayer3 } from "@secondlayer/sdk";
|
|
@@ -35235,17 +35509,17 @@ var FORMAT_BY_RUNTIME = {
|
|
|
35235
35509
|
node: "standard-webhooks"
|
|
35236
35510
|
};
|
|
35237
35511
|
function templatesRoot() {
|
|
35238
|
-
const here =
|
|
35239
|
-
const candidateDist =
|
|
35240
|
-
if (
|
|
35512
|
+
const here = dirname5(fileURLToPath4(import.meta.url));
|
|
35513
|
+
const candidateDist = resolve5(here, "..", "templates", "subscriptions");
|
|
35514
|
+
if (existsSync4(candidateDist))
|
|
35241
35515
|
return candidateDist;
|
|
35242
|
-
return
|
|
35516
|
+
return resolve5(here, "..", "..", "templates", "subscriptions");
|
|
35243
35517
|
}
|
|
35244
35518
|
function copyTemplate(src2, dest, vars) {
|
|
35245
|
-
if (!
|
|
35519
|
+
if (!existsSync4(src2)) {
|
|
35246
35520
|
throw new Error(`template dir missing: ${src2}`);
|
|
35247
35521
|
}
|
|
35248
|
-
|
|
35522
|
+
mkdirSync3(dest, { recursive: true });
|
|
35249
35523
|
const entries2 = readdirSync(src2);
|
|
35250
35524
|
for (const entry of entries2) {
|
|
35251
35525
|
const from = join6(src2, entry);
|
|
@@ -35254,9 +35528,9 @@ function copyTemplate(src2, dest, vars) {
|
|
|
35254
35528
|
if (st.isDirectory()) {
|
|
35255
35529
|
copyTemplate(from, to, vars);
|
|
35256
35530
|
} else {
|
|
35257
|
-
const raw =
|
|
35531
|
+
const raw = readFileSync5(from, "utf8");
|
|
35258
35532
|
const rendered = raw.replace(/\{\{([A-Z_]+)\}\}/g, (match, key) => vars[key] ?? match);
|
|
35259
|
-
|
|
35533
|
+
writeFileSync4(to, rendered);
|
|
35260
35534
|
}
|
|
35261
35535
|
}
|
|
35262
35536
|
}
|
|
@@ -35265,7 +35539,7 @@ function parseTriggersInput(opts) {
|
|
|
35265
35539
|
if (opts.triggersFile) {
|
|
35266
35540
|
let parsed;
|
|
35267
35541
|
try {
|
|
35268
|
-
parsed = JSON.parse(
|
|
35542
|
+
parsed = JSON.parse(readFileSync5(opts.triggersFile, "utf8"));
|
|
35269
35543
|
} catch (err) {
|
|
35270
35544
|
throw new Error(`Could not read/parse --triggers-file ${opts.triggersFile}: ${err instanceof Error ? err.message : String(err)}`);
|
|
35271
35545
|
}
|
|
@@ -35350,9 +35624,9 @@ async function createSubscription(name, opts) {
|
|
|
35350
35624
|
}
|
|
35351
35625
|
}
|
|
35352
35626
|
const eventName = `${subgraph}.${table}.created`;
|
|
35353
|
-
const targetDir =
|
|
35627
|
+
const targetDir = resolve5(process.cwd(), name);
|
|
35354
35628
|
if (!opts.scaffold === false) {
|
|
35355
|
-
if (
|
|
35629
|
+
if (existsSync4(targetDir)) {
|
|
35356
35630
|
error(`Directory already exists: ${relative(process.cwd(), targetDir)}`);
|
|
35357
35631
|
process.exit(1);
|
|
35358
35632
|
}
|
|
@@ -35403,15 +35677,15 @@ async function createSubscription(name, opts) {
|
|
|
35403
35677
|
if (signingSecret && !opts.scaffold === false) {
|
|
35404
35678
|
const envTarget = join6(targetDir, ".env");
|
|
35405
35679
|
const envExample = join6(targetDir, ".env.example");
|
|
35406
|
-
if (
|
|
35680
|
+
if (existsSync4(envExample) && !existsSync4(envTarget)) {
|
|
35407
35681
|
copyFileSync(envExample, envTarget);
|
|
35408
35682
|
}
|
|
35409
|
-
if (!
|
|
35410
|
-
|
|
35683
|
+
if (!existsSync4(envTarget)) {
|
|
35684
|
+
writeFileSync4(envTarget, `SIGNING_SECRET=${signingSecret}
|
|
35411
35685
|
`);
|
|
35412
35686
|
} else {
|
|
35413
|
-
const cur =
|
|
35414
|
-
|
|
35687
|
+
const cur = readFileSync5(envTarget, "utf8");
|
|
35688
|
+
writeFileSync4(envTarget, cur.match(/^SIGNING_SECRET=/m) ? cur.replace(/^SIGNING_SECRET=.*/m, `SIGNING_SECRET=${signingSecret}`) : `${cur}
|
|
35415
35689
|
SIGNING_SECRET=${signingSecret}
|
|
35416
35690
|
`);
|
|
35417
35691
|
}
|
|
@@ -36178,8 +36452,8 @@ POST result (client-side, not logged):`));
|
|
|
36178
36452
|
}
|
|
36179
36453
|
// src/commands/devnet.ts
|
|
36180
36454
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
36181
|
-
import { existsSync as
|
|
36182
|
-
import { dirname as
|
|
36455
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync4, writeFileSync as writeFileSync6 } from "node:fs";
|
|
36456
|
+
import { dirname as dirname7, join as join8 } from "node:path";
|
|
36183
36457
|
|
|
36184
36458
|
// src/lib/devnet-compose.ts
|
|
36185
36459
|
var DEFAULT_IMAGE_OWNER = "ryanwaits";
|
|
@@ -36321,24 +36595,24 @@ volumes:
|
|
|
36321
36595
|
}
|
|
36322
36596
|
|
|
36323
36597
|
// src/lib/devnet-config.ts
|
|
36324
|
-
import { existsSync as
|
|
36325
|
-
import { dirname as
|
|
36598
|
+
import { existsSync as existsSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
|
|
36599
|
+
import { dirname as dirname6, join as join7, parse as parsePath } from "node:path";
|
|
36326
36600
|
import { parse as parseToml } from "smol-toml";
|
|
36327
36601
|
var DEFAULT_INDEXER_OBSERVER = "host.docker.internal:3700";
|
|
36328
36602
|
function findClarinetProject(startDir) {
|
|
36329
36603
|
let dir = startDir;
|
|
36330
36604
|
const { root } = parsePath(dir);
|
|
36331
36605
|
while (true) {
|
|
36332
|
-
if (
|
|
36606
|
+
if (existsSync5(join7(dir, "Clarinet.toml")))
|
|
36333
36607
|
return dir;
|
|
36334
36608
|
if (dir === root)
|
|
36335
36609
|
return null;
|
|
36336
|
-
dir =
|
|
36610
|
+
dir = dirname6(dir);
|
|
36337
36611
|
}
|
|
36338
36612
|
}
|
|
36339
36613
|
function ensureEventObserver(devnetTomlPath, endpoint = DEFAULT_INDEXER_OBSERVER) {
|
|
36340
|
-
const exists =
|
|
36341
|
-
const original = exists ?
|
|
36614
|
+
const exists = existsSync5(devnetTomlPath);
|
|
36615
|
+
const original = exists ? readFileSync6(devnetTomlPath, "utf8") : "";
|
|
36342
36616
|
if (original.trim()) {
|
|
36343
36617
|
const parsed = parseToml(original);
|
|
36344
36618
|
const observers = parsed.devnet?.stacks_node_events_observers;
|
|
@@ -36352,7 +36626,7 @@ function ensureEventObserver(devnetTomlPath, endpoint = DEFAULT_INDEXER_OBSERVER
|
|
|
36352
36626
|
const at = (arrayStart.index ?? 0) + arrayStart[0].length;
|
|
36353
36627
|
const next = original.slice(at).trimStart().startsWith("]") ? entry : `${entry}, `;
|
|
36354
36628
|
const patched = original.slice(0, at) + next + original.slice(at);
|
|
36355
|
-
|
|
36629
|
+
writeFileSync5(devnetTomlPath, patched);
|
|
36356
36630
|
return { status: "added" };
|
|
36357
36631
|
}
|
|
36358
36632
|
const header = original.match(/^\[devnet\]\s*$/m);
|
|
@@ -36360,7 +36634,7 @@ function ensureEventObserver(devnetTomlPath, endpoint = DEFAULT_INDEXER_OBSERVER
|
|
|
36360
36634
|
const at = (header.index ?? 0) + header[0].length;
|
|
36361
36635
|
const patched = `${original.slice(0, at)}
|
|
36362
36636
|
stacks_node_events_observers = [${entry}]${original.slice(at)}`;
|
|
36363
|
-
|
|
36637
|
+
writeFileSync5(devnetTomlPath, patched);
|
|
36364
36638
|
return { status: "added" };
|
|
36365
36639
|
}
|
|
36366
36640
|
const prefix = original && !original.endsWith(`
|
|
@@ -36370,7 +36644,7 @@ stacks_node_events_observers = [${entry}]${original.slice(at)}`;
|
|
|
36370
36644
|
` : ""}[devnet]
|
|
36371
36645
|
stacks_node_events_observers = [${entry}]
|
|
36372
36646
|
`;
|
|
36373
|
-
|
|
36647
|
+
writeFileSync5(devnetTomlPath, block);
|
|
36374
36648
|
return { status: exists ? "added" : "created" };
|
|
36375
36649
|
}
|
|
36376
36650
|
|
|
@@ -36420,7 +36694,7 @@ function registerDevnetCommand(program2) {
|
|
|
36420
36694
|
}
|
|
36421
36695
|
function resolveProject(explicit) {
|
|
36422
36696
|
if (explicit) {
|
|
36423
|
-
if (!
|
|
36697
|
+
if (!existsSync6(join8(explicit, "Clarinet.toml"))) {
|
|
36424
36698
|
error(`No Clarinet.toml in ${explicit}`);
|
|
36425
36699
|
process.exit(1);
|
|
36426
36700
|
}
|
|
@@ -36437,7 +36711,7 @@ function resolveProject(explicit) {
|
|
|
36437
36711
|
async function connect(options3) {
|
|
36438
36712
|
const project = resolveProject(options3.project);
|
|
36439
36713
|
const devnetToml = join8(project, "settings", "Devnet.toml");
|
|
36440
|
-
|
|
36714
|
+
mkdirSync4(dirname7(devnetToml), { recursive: true });
|
|
36441
36715
|
const result = ensureEventObserver(devnetToml, DEFAULT_INDEXER_OBSERVER);
|
|
36442
36716
|
console.log(`${green("✓")} found Clarinet.toml`);
|
|
36443
36717
|
if (result.status === "present") {
|
|
@@ -36447,8 +36721,8 @@ async function connect(options3) {
|
|
|
36447
36721
|
console.log(dim(` + stacks_node_events_observers = ["${DEFAULT_INDEXER_OBSERVER}"]`));
|
|
36448
36722
|
}
|
|
36449
36723
|
const composePath = join8(project, COMPOSE_REL);
|
|
36450
|
-
|
|
36451
|
-
|
|
36724
|
+
mkdirSync4(dirname7(composePath), { recursive: true });
|
|
36725
|
+
writeFileSync6(composePath, buildDevnetCompose({ owner: options3.owner, imageTag: options3.imageTag }));
|
|
36452
36726
|
console.log(`${green("✓")} wrote ${COMPOSE_REL}`);
|
|
36453
36727
|
if (!options3.up) {
|
|
36454
36728
|
console.log(dim(`
|
|
@@ -36477,7 +36751,7 @@ Stop with: sl devnet down`));
|
|
|
36477
36751
|
async function down(options3) {
|
|
36478
36752
|
const project = resolveProject(options3.project);
|
|
36479
36753
|
const composePath = join8(project, COMPOSE_REL);
|
|
36480
|
-
if (!
|
|
36754
|
+
if (!existsSync6(composePath)) {
|
|
36481
36755
|
error(`No ${COMPOSE_REL} in ${project} — nothing to stop. Run \`sl devnet connect\` first.`);
|
|
36482
36756
|
process.exit(1);
|
|
36483
36757
|
}
|
|
@@ -36492,7 +36766,7 @@ async function down(options3) {
|
|
|
36492
36766
|
async function logs(service, options3) {
|
|
36493
36767
|
const project = resolveProject(options3.project);
|
|
36494
36768
|
const composePath = join8(project, COMPOSE_REL);
|
|
36495
|
-
if (!
|
|
36769
|
+
if (!existsSync6(composePath)) {
|
|
36496
36770
|
error(`No ${COMPOSE_REL} in ${project} — run \`sl devnet connect\` first.`);
|
|
36497
36771
|
process.exit(1);
|
|
36498
36772
|
}
|
|
@@ -36617,7 +36891,7 @@ init_subgraphs2();
|
|
|
36617
36891
|
init_output();
|
|
36618
36892
|
init_resolve_auth();
|
|
36619
36893
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
|
|
36620
|
-
import { dirname as
|
|
36894
|
+
import { dirname as dirname8, join as join9 } from "node:path";
|
|
36621
36895
|
import { createStreamsClient } from "@secondlayer/sdk";
|
|
36622
36896
|
import { STREAMS_EVENT_TYPES } from "@secondlayer/shared";
|
|
36623
36897
|
var DEFAULT_BASE_URL3 = "https://api.secondlayer.tools";
|
|
@@ -36794,7 +37068,7 @@ Examples:
|
|
|
36794
37068
|
for (const file of files) {
|
|
36795
37069
|
const bytes = await dumps.download(file);
|
|
36796
37070
|
const dest = join9(options3.to, file.path);
|
|
36797
|
-
await mkdir3(
|
|
37071
|
+
await mkdir3(dirname8(dest), { recursive: true });
|
|
36798
37072
|
await writeFile3(dest, bytes);
|
|
36799
37073
|
process.stderr.write(`# ${file.path} (${file.row_count} rows, ${bytes.byteLength} bytes)
|
|
36800
37074
|
`);
|
|
@@ -38080,10 +38354,10 @@ init_http();
|
|
|
38080
38354
|
init_output();
|
|
38081
38355
|
|
|
38082
38356
|
// src/lib/project-file.ts
|
|
38083
|
-
import { existsSync as
|
|
38357
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
38084
38358
|
import { mkdir as mkdir4, readFile as readFile3, writeFile as writeFile4 } from "node:fs/promises";
|
|
38085
38359
|
import { homedir as homedir5 } from "node:os";
|
|
38086
|
-
import { dirname as
|
|
38360
|
+
import { dirname as dirname14, join as join12, parse as parsePath2, resolve as resolve11 } from "node:path";
|
|
38087
38361
|
import { z as z4 } from "zod";
|
|
38088
38362
|
var ProjectFileSchema = z4.object({
|
|
38089
38363
|
slug: z4.string().min(1)
|
|
@@ -38091,23 +38365,23 @@ var ProjectFileSchema = z4.object({
|
|
|
38091
38365
|
var FILENAME = "project";
|
|
38092
38366
|
var DIRNAME = ".secondlayer";
|
|
38093
38367
|
async function readActiveProject(cwd, globalDefault) {
|
|
38094
|
-
let dir =
|
|
38095
|
-
const home2 =
|
|
38368
|
+
let dir = resolve11(cwd);
|
|
38369
|
+
const home2 = resolve11(homedir5());
|
|
38096
38370
|
const fsRoot = parsePath2(dir).root;
|
|
38097
38371
|
while (true) {
|
|
38098
38372
|
const candidate = join12(dir, DIRNAME, FILENAME);
|
|
38099
|
-
if (
|
|
38373
|
+
if (existsSync7(candidate)) {
|
|
38100
38374
|
try {
|
|
38101
38375
|
const raw = await readFile3(candidate, "utf8");
|
|
38102
38376
|
const parsed = ProjectFileSchema.parse(JSON.parse(raw));
|
|
38103
38377
|
return { slug: parsed.slug, resolvedFrom: candidate };
|
|
38104
38378
|
} catch {}
|
|
38105
38379
|
}
|
|
38106
|
-
if (
|
|
38380
|
+
if (existsSync7(join12(dir, ".git")))
|
|
38107
38381
|
break;
|
|
38108
38382
|
if (dir === home2 || dir === fsRoot)
|
|
38109
38383
|
break;
|
|
38110
|
-
const parent =
|
|
38384
|
+
const parent = dirname14(dir);
|
|
38111
38385
|
if (parent === dir)
|
|
38112
38386
|
break;
|
|
38113
38387
|
dir = parent;
|
|
@@ -38121,7 +38395,7 @@ async function readActiveProject(cwd, globalDefault) {
|
|
|
38121
38395
|
return null;
|
|
38122
38396
|
}
|
|
38123
38397
|
async function writeActiveProject(slug, cwd) {
|
|
38124
|
-
const dir = join12(
|
|
38398
|
+
const dir = join12(resolve11(cwd), DIRNAME);
|
|
38125
38399
|
await mkdir4(dir, { recursive: true });
|
|
38126
38400
|
const file = join12(dir, FILENAME);
|
|
38127
38401
|
await writeFile4(file, `${JSON.stringify({ slug }, null, 2)}
|
|
@@ -38345,5 +38619,5 @@ registerAccountCommand(program);
|
|
|
38345
38619
|
registerKeysCommand(program);
|
|
38346
38620
|
program.parse();
|
|
38347
38621
|
|
|
38348
|
-
//# debugId=
|
|
38622
|
+
//# debugId=083CEA7A9489EF8064756E2164756E21
|
|
38349
38623
|
//# sourceMappingURL=cli.js.map
|