@secondlayer/cli 9.1.0 → 9.2.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 +381 -167
- package/dist/cli.js.map +6 -5
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -28919,6 +28919,12 @@ 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
|
+
*
|
|
28922
28928
|
* Query examples once deployed:
|
|
28923
28929
|
* GET /v1/subgraphs/${name}/balances?_search=SP1...
|
|
28924
28930
|
* GET /v1/subgraphs/${name}/balances?holder=SP1...
|
|
@@ -28941,49 +28947,33 @@ export default defineSubgraph({
|
|
|
28941
28947
|
holder: { type: "principal", indexed: true, search: true },
|
|
28942
28948
|
amount: { type: "uint" },
|
|
28943
28949
|
},
|
|
28950
|
+
// increment() upserts on this key.
|
|
28944
28951
|
uniqueKeys: [["asset_identifier", "holder"]],
|
|
28945
28952
|
},
|
|
28946
28953
|
},
|
|
28947
28954
|
|
|
28948
28955
|
handlers: {
|
|
28949
|
-
transfer:
|
|
28956
|
+
transfer: (event, ctx) => {
|
|
28950
28957
|
const amount = BigInt(event.amount ?? 0);
|
|
28951
28958
|
if (event.sender) {
|
|
28952
|
-
|
|
28959
|
+
ctx.increment("balances", { asset_identifier: event.assetIdentifier, holder: event.sender }, { amount: -amount });
|
|
28953
28960
|
}
|
|
28954
28961
|
if (event.recipient) {
|
|
28955
|
-
|
|
28962
|
+
ctx.increment("balances", { asset_identifier: event.assetIdentifier, holder: event.recipient }, { amount });
|
|
28956
28963
|
}
|
|
28957
28964
|
},
|
|
28958
|
-
mint:
|
|
28965
|
+
mint: (event, ctx) => {
|
|
28959
28966
|
if (event.recipient) {
|
|
28960
|
-
|
|
28967
|
+
ctx.increment("balances", { asset_identifier: event.assetIdentifier, holder: event.recipient }, { amount: BigInt(event.amount ?? 0) });
|
|
28961
28968
|
}
|
|
28962
28969
|
},
|
|
28963
|
-
burn:
|
|
28970
|
+
burn: (event, ctx) => {
|
|
28964
28971
|
if (event.sender) {
|
|
28965
|
-
|
|
28972
|
+
ctx.increment("balances", { asset_identifier: event.assetIdentifier, holder: event.sender }, { amount: -BigInt(event.amount ?? 0) });
|
|
28966
28973
|
}
|
|
28967
28974
|
},
|
|
28968
28975
|
},
|
|
28969
28976
|
});
|
|
28970
|
-
|
|
28971
|
-
async function adjust(
|
|
28972
|
-
// biome-ignore lint/suspicious/noExplicitAny: subgraph runtime ctx shape
|
|
28973
|
-
ctx: any,
|
|
28974
|
-
assetIdentifier: string,
|
|
28975
|
-
holder: string,
|
|
28976
|
-
delta: bigint,
|
|
28977
|
-
): Promise<void> {
|
|
28978
|
-
const existing = await ctx.findOne("balances", { asset_identifier: assetIdentifier, holder });
|
|
28979
|
-
const current = existing ? BigInt(existing.amount) : 0n;
|
|
28980
|
-
const next = current + delta;
|
|
28981
|
-
await ctx.upsert(
|
|
28982
|
-
"balances",
|
|
28983
|
-
{ asset_identifier: assetIdentifier, holder },
|
|
28984
|
-
{ asset_identifier: assetIdentifier, holder, amount: next },
|
|
28985
|
-
);
|
|
28986
|
-
}
|
|
28987
28977
|
`;
|
|
28988
28978
|
}
|
|
28989
28979
|
function sbtcFlows(name) {
|
|
@@ -29206,6 +29196,223 @@ function deriveBaseUrl(apiUrl) {
|
|
|
29206
29196
|
}
|
|
29207
29197
|
}
|
|
29208
29198
|
|
|
29199
|
+
// src/commands/subgraph-test.ts
|
|
29200
|
+
var exports_subgraph_test = {};
|
|
29201
|
+
__export(exports_subgraph_test, {
|
|
29202
|
+
runSubgraphTest: () => runSubgraphTest
|
|
29203
|
+
});
|
|
29204
|
+
import { createHash } from "node:crypto";
|
|
29205
|
+
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
29206
|
+
import { dirname as dirname3, resolve as resolve2 } from "node:path";
|
|
29207
|
+
import { Index } from "@secondlayer/sdk";
|
|
29208
|
+
function filterHashOf(sources) {
|
|
29209
|
+
const stable = JSON.stringify(Object.fromEntries(Object.entries(sources).sort(([a4], [b2]) => a4.localeCompare(b2))), (_k, v2) => typeof v2 === "bigint" ? `${v2}n` : v2);
|
|
29210
|
+
return createHash("sha256").update(stable).digest("hex").slice(0, 16);
|
|
29211
|
+
}
|
|
29212
|
+
function cassettePath(name) {
|
|
29213
|
+
return resolve2(CASSETTE_DIR, `${name}.json`);
|
|
29214
|
+
}
|
|
29215
|
+
function loadCassette(name, filterHash) {
|
|
29216
|
+
const path11 = cassettePath(name);
|
|
29217
|
+
if (!existsSync2(path11))
|
|
29218
|
+
return null;
|
|
29219
|
+
let parsed;
|
|
29220
|
+
try {
|
|
29221
|
+
parsed = JSON.parse(readFileSync3(path11, "utf8"));
|
|
29222
|
+
} catch {
|
|
29223
|
+
return { stale: "unreadable" };
|
|
29224
|
+
}
|
|
29225
|
+
if (parsed.decoderVersion !== DECODER_VERSION) {
|
|
29226
|
+
return { stale: `recorded by decoder v${parsed.decoderVersion}` };
|
|
29227
|
+
}
|
|
29228
|
+
if (parsed.filterHash !== filterHash) {
|
|
29229
|
+
return { stale: "sources changed since it was recorded" };
|
|
29230
|
+
}
|
|
29231
|
+
return parsed;
|
|
29232
|
+
}
|
|
29233
|
+
function eventTypeFor(filter) {
|
|
29234
|
+
if (filter.type === "print_event")
|
|
29235
|
+
return "print";
|
|
29236
|
+
if (filter.type === "contract_call" || filter.type === "contract_deploy") {
|
|
29237
|
+
return null;
|
|
29238
|
+
}
|
|
29239
|
+
return filter.type;
|
|
29240
|
+
}
|
|
29241
|
+
async function runSubgraphTest(file, options3) {
|
|
29242
|
+
const absPath = resolve2(file);
|
|
29243
|
+
if (!existsSync2(absPath)) {
|
|
29244
|
+
error(`File not found: ${absPath}`);
|
|
29245
|
+
process.exit(1);
|
|
29246
|
+
}
|
|
29247
|
+
const { readFile: readFile3 } = await import("node:fs/promises");
|
|
29248
|
+
const { bundleSubgraphCode } = await import("@secondlayer/bundler");
|
|
29249
|
+
const { createTestContext, buildEvent } = await import("@secondlayer/subgraphs/testing");
|
|
29250
|
+
const source = await readFile3(absPath, "utf8");
|
|
29251
|
+
const bundled = await bundleSubgraphCode(source);
|
|
29252
|
+
const sources = bundled.sources ?? {};
|
|
29253
|
+
const filterHash = filterHashOf(sources);
|
|
29254
|
+
const mod = await import(`${absPath}?t=${Date.now()}`);
|
|
29255
|
+
const def = mod.default;
|
|
29256
|
+
if (!def?.handlers || !def.schema) {
|
|
29257
|
+
error("File must default-export a defineSubgraph() definition with handlers and schema.");
|
|
29258
|
+
process.exit(1);
|
|
29259
|
+
}
|
|
29260
|
+
const cached = loadCassette(bundled.name, filterHash);
|
|
29261
|
+
if (cached && "stale" in cached) {
|
|
29262
|
+
warn(`Cassette discarded (${cached.stale}) — re-recording.`);
|
|
29263
|
+
}
|
|
29264
|
+
const usable = cached && !("stale" in cached) ? cached : null;
|
|
29265
|
+
let events;
|
|
29266
|
+
let fromHeight;
|
|
29267
|
+
let toHeight;
|
|
29268
|
+
if (usable && options3.offline !== false && !options3.from) {
|
|
29269
|
+
info(`Replaying cassette: blocks ${usable.fromHeight}–${usable.toHeight}, recorded ${usable.recordedAt}`);
|
|
29270
|
+
events = usable.events;
|
|
29271
|
+
fromHeight = usable.fromHeight;
|
|
29272
|
+
toHeight = usable.toHeight;
|
|
29273
|
+
} else {
|
|
29274
|
+
if (options3.offline) {
|
|
29275
|
+
error("No usable cassette for --offline. Record one first: sl subgraphs test <file> --from <h> --to <h>");
|
|
29276
|
+
process.exit(1);
|
|
29277
|
+
}
|
|
29278
|
+
if (!options3.from) {
|
|
29279
|
+
error("--from <height> is required for the first run (Index reads are metered). Later runs replay the cassette.");
|
|
29280
|
+
process.exit(1);
|
|
29281
|
+
}
|
|
29282
|
+
fromHeight = Number(options3.from);
|
|
29283
|
+
toHeight = options3.to ? Number(options3.to) : fromHeight + 100;
|
|
29284
|
+
if (!Number.isInteger(fromHeight) || !Number.isInteger(toHeight)) {
|
|
29285
|
+
error("--from/--to must be integers.");
|
|
29286
|
+
process.exit(1);
|
|
29287
|
+
}
|
|
29288
|
+
const limit = options3.limit ? Number(options3.limit) : 500;
|
|
29289
|
+
const index = new Index;
|
|
29290
|
+
events = {};
|
|
29291
|
+
for (const [name, filter] of Object.entries(sources)) {
|
|
29292
|
+
const eventType = eventTypeFor(filter);
|
|
29293
|
+
if (eventType === null) {
|
|
29294
|
+
warn(`source "${name}" (${filter.type}) is not readable from index.events — skipped.`);
|
|
29295
|
+
continue;
|
|
29296
|
+
}
|
|
29297
|
+
info(`Fetching ${name} (${eventType}) blocks ${fromHeight}–${toHeight}…`);
|
|
29298
|
+
try {
|
|
29299
|
+
const envelope = await index.events.list({
|
|
29300
|
+
eventType,
|
|
29301
|
+
...filter.contractId ? {
|
|
29302
|
+
contractId: Array.isArray(filter.contractId) ? filter.contractId : filter.contractId
|
|
29303
|
+
} : {},
|
|
29304
|
+
fromHeight,
|
|
29305
|
+
toHeight,
|
|
29306
|
+
limit
|
|
29307
|
+
});
|
|
29308
|
+
events[name] = envelope.events;
|
|
29309
|
+
} catch (err) {
|
|
29310
|
+
const e2 = err;
|
|
29311
|
+
if (e2?.status === 402) {
|
|
29312
|
+
const details = e2.body?.details;
|
|
29313
|
+
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."}`);
|
|
29314
|
+
process.exit(1);
|
|
29315
|
+
}
|
|
29316
|
+
throw err;
|
|
29317
|
+
}
|
|
29318
|
+
}
|
|
29319
|
+
if (options3.record !== false) {
|
|
29320
|
+
const cassette = {
|
|
29321
|
+
decoderVersion: DECODER_VERSION,
|
|
29322
|
+
filterHash,
|
|
29323
|
+
subgraph: bundled.name,
|
|
29324
|
+
fromHeight,
|
|
29325
|
+
toHeight,
|
|
29326
|
+
recordedAt: new Date().toISOString(),
|
|
29327
|
+
events
|
|
29328
|
+
};
|
|
29329
|
+
const path11 = cassettePath(bundled.name);
|
|
29330
|
+
mkdirSync(dirname3(path11), { recursive: true });
|
|
29331
|
+
writeFileSync2(path11, `${JSON.stringify(cassette, (_k, v2) => typeof v2 === "bigint" ? `${v2}n` : v2, 2)}
|
|
29332
|
+
`);
|
|
29333
|
+
info(`Recorded cassette → ${path11}`);
|
|
29334
|
+
}
|
|
29335
|
+
}
|
|
29336
|
+
const ctx = createTestContext(def.schema);
|
|
29337
|
+
let applied = 0;
|
|
29338
|
+
let failed = 0;
|
|
29339
|
+
const failures = [];
|
|
29340
|
+
for (const [name, rows] of Object.entries(events)) {
|
|
29341
|
+
const handler = def.handlers[name] ?? def.handlers["*"];
|
|
29342
|
+
if (typeof handler !== "function") {
|
|
29343
|
+
warn(`source "${name}": no handler — skipped.`);
|
|
29344
|
+
continue;
|
|
29345
|
+
}
|
|
29346
|
+
const filter = sources[name];
|
|
29347
|
+
for (const row of rows) {
|
|
29348
|
+
const payload = toHandlerPayload(filter, row);
|
|
29349
|
+
if (filter?.type === "print_event" && filter.topic && payload.topic !== filter.topic) {
|
|
29350
|
+
continue;
|
|
29351
|
+
}
|
|
29352
|
+
try {
|
|
29353
|
+
await handler(buildEvent(filter, payload), ctx);
|
|
29354
|
+
applied++;
|
|
29355
|
+
} catch (err) {
|
|
29356
|
+
failed++;
|
|
29357
|
+
if (failures.length < 5) {
|
|
29358
|
+
failures.push(` ${name} @ ${row.cursor}: ${err instanceof Error ? err.message : String(err)}`);
|
|
29359
|
+
}
|
|
29360
|
+
}
|
|
29361
|
+
}
|
|
29362
|
+
}
|
|
29363
|
+
info("");
|
|
29364
|
+
const tables = Object.keys(def.schema);
|
|
29365
|
+
let totalRows = 0;
|
|
29366
|
+
for (const table of tables) {
|
|
29367
|
+
const rows = await ctx.rows(table);
|
|
29368
|
+
totalRows += rows.length;
|
|
29369
|
+
info(` ${table.padEnd(24)} ${String(rows.length).padStart(6)} rows`);
|
|
29370
|
+
const sample = rows[0];
|
|
29371
|
+
if (sample) {
|
|
29372
|
+
const preview = Object.entries(sample).filter(([k2]) => !k2.startsWith("_")).slice(0, 4).map(([k2, v2]) => `${k2}=${String(v2).slice(0, 24)}`).join(" ");
|
|
29373
|
+
info(` ${"".padEnd(24)} ${preview}`);
|
|
29374
|
+
}
|
|
29375
|
+
}
|
|
29376
|
+
info("");
|
|
29377
|
+
if (failed > 0) {
|
|
29378
|
+
warn(`${failed} handler error${failed === 1 ? "" : "s"}:`);
|
|
29379
|
+
for (const f2 of failures)
|
|
29380
|
+
warn(f2);
|
|
29381
|
+
}
|
|
29382
|
+
const fetched = Object.values(events).reduce((n3, r2) => n3 + r2.length, 0);
|
|
29383
|
+
if (fetched === 0) {
|
|
29384
|
+
warn(`No events matched these sources in blocks ${fromHeight}–${toHeight}. Widen the range (--to) or check the source filters.`);
|
|
29385
|
+
return;
|
|
29386
|
+
}
|
|
29387
|
+
if (totalRows === 0) {
|
|
29388
|
+
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.`);
|
|
29389
|
+
process.exit(1);
|
|
29390
|
+
}
|
|
29391
|
+
success(`${applied} event${applied === 1 ? "" : "s"} → ${totalRows} row${totalRows === 1 ? "" : "s"} across ${tables.length} table${tables.length === 1 ? "" : "s"} (blocks ${fromHeight}–${toHeight})`);
|
|
29392
|
+
}
|
|
29393
|
+
function toHandlerPayload(_filter, row) {
|
|
29394
|
+
if (row.event_type === "print") {
|
|
29395
|
+
const payload = row.payload;
|
|
29396
|
+
return {
|
|
29397
|
+
contractId: row.contract_id ?? "",
|
|
29398
|
+
topic: payload?.topic ?? "",
|
|
29399
|
+
data: payload?.value ?? {}
|
|
29400
|
+
};
|
|
29401
|
+
}
|
|
29402
|
+
const r2 = row;
|
|
29403
|
+
return {
|
|
29404
|
+
...r2.sender !== undefined ? { sender: r2.sender } : {},
|
|
29405
|
+
...r2.recipient !== undefined ? { recipient: r2.recipient } : {},
|
|
29406
|
+
...r2.amount !== undefined ? { amount: BigInt(String(r2.amount)) } : {},
|
|
29407
|
+
...r2.asset_identifier !== undefined ? { assetIdentifier: r2.asset_identifier } : {},
|
|
29408
|
+
...r2.value !== undefined ? { tokenId: r2.value } : {}
|
|
29409
|
+
};
|
|
29410
|
+
}
|
|
29411
|
+
var CASSETTE_DIR = "cassettes", DECODER_VERSION = 1;
|
|
29412
|
+
var init_subgraph_test = __esm(() => {
|
|
29413
|
+
init_output();
|
|
29414
|
+
});
|
|
29415
|
+
|
|
29209
29416
|
// src/commands/subgraphs.ts
|
|
29210
29417
|
var exports_subgraphs = {};
|
|
29211
29418
|
__export(exports_subgraphs, {
|
|
@@ -29224,13 +29431,13 @@ __export(exports_subgraphs, {
|
|
|
29224
29431
|
});
|
|
29225
29432
|
import { spawn as spawn2 } from "node:child_process";
|
|
29226
29433
|
import {
|
|
29227
|
-
existsSync as
|
|
29228
|
-
mkdirSync,
|
|
29229
|
-
readFileSync as
|
|
29434
|
+
existsSync as existsSync3,
|
|
29435
|
+
mkdirSync as mkdirSync2,
|
|
29436
|
+
readFileSync as readFileSync4,
|
|
29230
29437
|
watch,
|
|
29231
|
-
writeFileSync as
|
|
29438
|
+
writeFileSync as writeFileSync3
|
|
29232
29439
|
} from "node:fs";
|
|
29233
|
-
import { basename, dirname as
|
|
29440
|
+
import { basename, dirname as dirname4, extname, join as join4, resolve as resolve3 } from "node:path";
|
|
29234
29441
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
29235
29442
|
import { confirm as confirm3 } from "@inquirer/prompts";
|
|
29236
29443
|
import {
|
|
@@ -29319,8 +29526,8 @@ function ormFlagsConflictingWithPayloads(getOptionValueSource) {
|
|
|
29319
29526
|
return Object.entries(ORM_ONLY_CODEGEN_FLAGS).filter(([key]) => getOptionValueSource(key) === "cli").map(([, flag]) => flag);
|
|
29320
29527
|
}
|
|
29321
29528
|
async function runPayloadsCodegen(file, output2) {
|
|
29322
|
-
const absPath =
|
|
29323
|
-
if (!
|
|
29529
|
+
const absPath = resolve3(file);
|
|
29530
|
+
if (!existsSync3(absPath)) {
|
|
29324
29531
|
error(`File not found: ${absPath}`);
|
|
29325
29532
|
process.exit(1);
|
|
29326
29533
|
}
|
|
@@ -29365,7 +29572,7 @@ async function runPayloadsCodegen(file, output2) {
|
|
|
29365
29572
|
process.exit(1);
|
|
29366
29573
|
}
|
|
29367
29574
|
const out = generatePrintPayloadTypes({ sources });
|
|
29368
|
-
const outPath =
|
|
29575
|
+
const outPath = resolve3(output2 ?? join4(dirname4(absPath), `${basename(absPath, extname(absPath))}.payloads.d.ts`));
|
|
29369
29576
|
await writeTextFile(outPath, out);
|
|
29370
29577
|
success(`Wrote print payload types to ${outPath}`);
|
|
29371
29578
|
}
|
|
@@ -29390,10 +29597,10 @@ async function writeOrPrintSubgraphSpec(spec, format2, output2) {
|
|
|
29390
29597
|
process.stdout.write(text2);
|
|
29391
29598
|
return;
|
|
29392
29599
|
}
|
|
29393
|
-
const outPath =
|
|
29394
|
-
const dir =
|
|
29395
|
-
if (!
|
|
29396
|
-
|
|
29600
|
+
const outPath = resolve3(output2);
|
|
29601
|
+
const dir = resolve3(outPath, "..");
|
|
29602
|
+
if (!existsSync3(dir))
|
|
29603
|
+
mkdirSync2(dir, { recursive: true });
|
|
29397
29604
|
await writeTextFile(outPath, text2);
|
|
29398
29605
|
success(`Created ${outPath}`);
|
|
29399
29606
|
}
|
|
@@ -29484,15 +29691,15 @@ function createLocalSubgraphDetail(input2) {
|
|
|
29484
29691
|
};
|
|
29485
29692
|
}
|
|
29486
29693
|
function readCliSubgraphsDependency() {
|
|
29487
|
-
const here =
|
|
29694
|
+
const here = dirname4(fileURLToPath3(import.meta.url));
|
|
29488
29695
|
const candidates = [
|
|
29489
|
-
|
|
29490
|
-
|
|
29696
|
+
resolve3(here, "..", "..", "package.json"),
|
|
29697
|
+
resolve3(here, "..", "package.json")
|
|
29491
29698
|
];
|
|
29492
29699
|
for (const candidate of candidates) {
|
|
29493
|
-
if (!
|
|
29700
|
+
if (!existsSync3(candidate))
|
|
29494
29701
|
continue;
|
|
29495
|
-
const pkg = JSON.parse(
|
|
29702
|
+
const pkg = JSON.parse(readFileSync4(candidate, "utf8"));
|
|
29496
29703
|
const dep = pkg.dependencies?.["@secondlayer/subgraphs"];
|
|
29497
29704
|
if (dep)
|
|
29498
29705
|
return dep;
|
|
@@ -29502,8 +29709,8 @@ function readCliSubgraphsDependency() {
|
|
|
29502
29709
|
function ensureScaffoldPackageJson(dir) {
|
|
29503
29710
|
const packagePath = join4(dir, "package.json");
|
|
29504
29711
|
const subgraphsDep = readCliSubgraphsDependency();
|
|
29505
|
-
if (!
|
|
29506
|
-
|
|
29712
|
+
if (!existsSync3(packagePath)) {
|
|
29713
|
+
writeFileSync3(packagePath, `${JSON.stringify({
|
|
29507
29714
|
type: "module",
|
|
29508
29715
|
dependencies: {
|
|
29509
29716
|
"@secondlayer/subgraphs": subgraphsDep
|
|
@@ -29512,14 +29719,14 @@ function ensureScaffoldPackageJson(dir) {
|
|
|
29512
29719
|
`, "utf8");
|
|
29513
29720
|
return;
|
|
29514
29721
|
}
|
|
29515
|
-
const pkg = JSON.parse(
|
|
29722
|
+
const pkg = JSON.parse(readFileSync4(packagePath, "utf8"));
|
|
29516
29723
|
if (pkg.dependencies?.["@secondlayer/subgraphs"])
|
|
29517
29724
|
return;
|
|
29518
29725
|
pkg.dependencies = {
|
|
29519
29726
|
...pkg.dependencies ?? {},
|
|
29520
29727
|
"@secondlayer/subgraphs": subgraphsDep
|
|
29521
29728
|
};
|
|
29522
|
-
|
|
29729
|
+
writeFileSync3(packagePath, `${JSON.stringify(pkg, null, 2)}
|
|
29523
29730
|
`, "utf8");
|
|
29524
29731
|
}
|
|
29525
29732
|
async function runBunInstall(dir) {
|
|
@@ -29687,9 +29894,9 @@ ${SUBGRAPH_TEMPLATE_SLUGS.map((s2) => ` ${s2.padEnd(20)} ${SUBGRAPH_TEMPLATE_DE
|
|
|
29687
29894
|
`)}`);
|
|
29688
29895
|
process.exit(1);
|
|
29689
29896
|
}
|
|
29690
|
-
const dir =
|
|
29691
|
-
const filePath =
|
|
29692
|
-
if (
|
|
29897
|
+
const dir = resolve3("subgraphs");
|
|
29898
|
+
const filePath = resolve3(dir, `${name}.ts`);
|
|
29899
|
+
if (existsSync3(filePath)) {
|
|
29693
29900
|
error(`File already exists: ${filePath}`);
|
|
29694
29901
|
process.exit(1);
|
|
29695
29902
|
}
|
|
@@ -29717,8 +29924,8 @@ Check the contract id, and that the contract has emitted print events (schemas a
|
|
|
29717
29924
|
} else {
|
|
29718
29925
|
content = generateSubgraphTemplate(name, slug);
|
|
29719
29926
|
}
|
|
29720
|
-
if (!
|
|
29721
|
-
|
|
29927
|
+
if (!existsSync3(dir)) {
|
|
29928
|
+
mkdirSync2(dir, { recursive: true });
|
|
29722
29929
|
}
|
|
29723
29930
|
await writeTextFile(filePath, content);
|
|
29724
29931
|
success(`Created ${filePath}`);
|
|
@@ -29731,8 +29938,8 @@ Check the contract id, and that the contract has emitted print events (schemas a
|
|
|
29731
29938
|
});
|
|
29732
29939
|
subgraphs.command("dev <file>").description("Watch a subgraph file and auto-redeploy on change").action(async (file) => {
|
|
29733
29940
|
await requireLocalNetwork();
|
|
29734
|
-
const absPath =
|
|
29735
|
-
if (!
|
|
29941
|
+
const absPath = resolve3(file);
|
|
29942
|
+
if (!existsSync3(absPath)) {
|
|
29736
29943
|
error(`File not found: ${absPath}`);
|
|
29737
29944
|
process.exit(1);
|
|
29738
29945
|
}
|
|
@@ -29792,7 +29999,7 @@ Stopped watching.`);
|
|
|
29792
29999
|
});
|
|
29793
30000
|
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
30001
|
try {
|
|
29795
|
-
const absPath =
|
|
30002
|
+
const absPath = resolve3(file);
|
|
29796
30003
|
const config = await loadConfig2();
|
|
29797
30004
|
if (config.network !== "local") {
|
|
29798
30005
|
await requireAuth();
|
|
@@ -30093,8 +30300,8 @@ Synced — exiting watch.`));
|
|
|
30093
30300
|
try {
|
|
30094
30301
|
const format2 = parseSubgraphSpecFormat(options3.format);
|
|
30095
30302
|
const specOptions = options3.server ? { serverUrl: options3.server } : undefined;
|
|
30096
|
-
const absPath =
|
|
30097
|
-
if (nameOrFile.endsWith(".ts") && !
|
|
30303
|
+
const absPath = resolve3(nameOrFile);
|
|
30304
|
+
if (nameOrFile.endsWith(".ts") && !existsSync3(absPath)) {
|
|
30098
30305
|
error(`File not found: ${absPath}`);
|
|
30099
30306
|
process.exit(1);
|
|
30100
30307
|
}
|
|
@@ -30113,6 +30320,13 @@ Synced — exiting watch.`));
|
|
|
30113
30320
|
deprecatedCodegenNotice("sl subgraphs codegen", options3.payloads ? "sl codegen prints" : "sl codegen subgraph");
|
|
30114
30321
|
await runSubgraphSchemaCodegen(file, options3, (key) => command.getOptionValueSource(key));
|
|
30115
30322
|
});
|
|
30323
|
+
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", `
|
|
30324
|
+
Examples:
|
|
30325
|
+
$ sl subgraphs test subgraphs/bns-names.ts --from 167484 --to 167600
|
|
30326
|
+
$ sl subgraphs test subgraphs/bns-names.ts --offline`).action(async (file, options3) => {
|
|
30327
|
+
const { runSubgraphTest: runSubgraphTest2 } = await Promise.resolve().then(() => (init_subgraph_test(), exports_subgraph_test));
|
|
30328
|
+
await runSubgraphTest2(file, options3);
|
|
30329
|
+
});
|
|
30116
30330
|
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
30331
|
Examples:
|
|
30118
30332
|
$ sl subgraphs reindex my-graph -y
|
|
@@ -30372,7 +30586,7 @@ Examples:
|
|
|
30372
30586
|
error("a <contractAddress> is required (or use --trait)");
|
|
30373
30587
|
process.exit(1);
|
|
30374
30588
|
}
|
|
30375
|
-
const outPath =
|
|
30589
|
+
const outPath = resolve3(options3.output);
|
|
30376
30590
|
let content;
|
|
30377
30591
|
if (trait) {
|
|
30378
30592
|
info(`Generating trait-scoped scaffold for ${trait}...`);
|
|
@@ -30392,9 +30606,9 @@ Examples:
|
|
|
30392
30606
|
functions: options3.functions?.split(",").map((f2) => f2.trim()).filter(Boolean)
|
|
30393
30607
|
});
|
|
30394
30608
|
}
|
|
30395
|
-
const dir =
|
|
30396
|
-
if (!
|
|
30397
|
-
|
|
30609
|
+
const dir = resolve3(outPath, "..");
|
|
30610
|
+
if (!existsSync3(dir))
|
|
30611
|
+
mkdirSync2(dir, { recursive: true });
|
|
30398
30612
|
await writeTextFile(outPath, content);
|
|
30399
30613
|
ensureScaffoldPackageJson(dir);
|
|
30400
30614
|
success(`Created ${outPath}`);
|
|
@@ -30427,14 +30641,14 @@ async function runSubgraphClientCodegen(subgraphName, options3) {
|
|
|
30427
30641
|
error("--output <path> is required");
|
|
30428
30642
|
process.exit(1);
|
|
30429
30643
|
}
|
|
30430
|
-
const outPath =
|
|
30644
|
+
const outPath = resolve3(options3.output);
|
|
30431
30645
|
info(`Fetching subgraph metadata for "${subgraphName}"...`);
|
|
30432
30646
|
const subgraphDetail = await getSubgraphApi(subgraphName);
|
|
30433
30647
|
info("Generating typed client...");
|
|
30434
30648
|
const content = await generateSubgraphConsumer(subgraphName, subgraphDetail);
|
|
30435
|
-
const dir =
|
|
30436
|
-
if (!
|
|
30437
|
-
|
|
30649
|
+
const dir = resolve3(outPath, "..");
|
|
30650
|
+
if (!existsSync3(dir))
|
|
30651
|
+
mkdirSync2(dir, { recursive: true });
|
|
30438
30652
|
await writeTextFile(outPath, content);
|
|
30439
30653
|
success(`Created ${outPath}`);
|
|
30440
30654
|
} catch (err) {
|
|
@@ -30457,8 +30671,8 @@ async function runSubgraphSchemaCodegen(file, options3, optionSource, defaultTar
|
|
|
30457
30671
|
error(`Unsupported --target "${target}" (supported: prisma, drizzle, kysely).`);
|
|
30458
30672
|
process.exit(1);
|
|
30459
30673
|
}
|
|
30460
|
-
const absPath =
|
|
30461
|
-
if (!
|
|
30674
|
+
const absPath = resolve3(file);
|
|
30675
|
+
if (!existsSync3(absPath)) {
|
|
30462
30676
|
error(`File not found: ${absPath}`);
|
|
30463
30677
|
process.exit(1);
|
|
30464
30678
|
}
|
|
@@ -30485,7 +30699,7 @@ async function runSubgraphSchemaCodegen(file, options3, optionSource, defaultTar
|
|
|
30485
30699
|
modelsOnly: options3.modelsOnly
|
|
30486
30700
|
});
|
|
30487
30701
|
if (options3.output) {
|
|
30488
|
-
await writeTextFile(
|
|
30702
|
+
await writeTextFile(resolve3(options3.output), out);
|
|
30489
30703
|
success(`Wrote ${target} schema to ${options3.output}`);
|
|
30490
30704
|
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
30705
|
info(`Next: ${next}`);
|
|
@@ -30527,10 +30741,10 @@ __export(exports_index_api, {
|
|
|
30527
30741
|
runIndexCodegen: () => runIndexCodegen,
|
|
30528
30742
|
registerIndexCommand: () => registerIndexCommand
|
|
30529
30743
|
});
|
|
30530
|
-
import { resolve as
|
|
30531
|
-
import { Index } from "@secondlayer/sdk";
|
|
30744
|
+
import { resolve as resolve4 } from "node:path";
|
|
30745
|
+
import { Index as Index2 } from "@secondlayer/sdk";
|
|
30532
30746
|
function client() {
|
|
30533
|
-
return new
|
|
30747
|
+
return new Index2({
|
|
30534
30748
|
baseUrl: process.env.SL_API_URL ?? DEFAULT_BASE_URL,
|
|
30535
30749
|
apiKey: resolveEnvKey()
|
|
30536
30750
|
});
|
|
@@ -30719,7 +30933,7 @@ async function runIndexCodegen(o3) {
|
|
|
30719
30933
|
datasourceEnv: o3.env
|
|
30720
30934
|
});
|
|
30721
30935
|
if (o3.output) {
|
|
30722
|
-
await writeTextFile(
|
|
30936
|
+
await writeTextFile(resolve4(o3.output), out);
|
|
30723
30937
|
success(`Wrote ${target} Index schema to ${o3.output}`);
|
|
30724
30938
|
} else {
|
|
30725
30939
|
process.stdout.write(out);
|
|
@@ -30831,9 +31045,9 @@ var init_query = __esm(() => {
|
|
|
30831
31045
|
CLOSE = {};
|
|
30832
31046
|
Query = class Query extends Promise {
|
|
30833
31047
|
constructor(strings, args, handler, canceller, options3 = {}) {
|
|
30834
|
-
let
|
|
31048
|
+
let resolve5, reject;
|
|
30835
31049
|
super((a4, b2) => {
|
|
30836
|
-
|
|
31050
|
+
resolve5 = a4;
|
|
30837
31051
|
reject = b2;
|
|
30838
31052
|
});
|
|
30839
31053
|
this.tagged = Array.isArray(strings.raw);
|
|
@@ -30844,7 +31058,7 @@ var init_query = __esm(() => {
|
|
|
30844
31058
|
this.options = options3;
|
|
30845
31059
|
this.state = null;
|
|
30846
31060
|
this.statement = null;
|
|
30847
|
-
this.resolve = (x2) => (this.active = false,
|
|
31061
|
+
this.resolve = (x2) => (this.active = false, resolve5(x2));
|
|
30848
31062
|
this.reject = (x2) => (this.active = false, reject(x2));
|
|
30849
31063
|
this.active = false;
|
|
30850
31064
|
this.cancelled = null;
|
|
@@ -30892,12 +31106,12 @@ var init_query = __esm(() => {
|
|
|
30892
31106
|
if (this.executed && !this.active)
|
|
30893
31107
|
return { done: true };
|
|
30894
31108
|
prev && prev();
|
|
30895
|
-
const promise = new Promise((
|
|
31109
|
+
const promise = new Promise((resolve5, reject) => {
|
|
30896
31110
|
this.cursorFn = (value) => {
|
|
30897
|
-
|
|
31111
|
+
resolve5({ value, done: false });
|
|
30898
31112
|
return new Promise((r2) => prev = r2);
|
|
30899
31113
|
};
|
|
30900
|
-
this.resolve = () => (this.active = false,
|
|
31114
|
+
this.resolve = () => (this.active = false, resolve5({ done: true }));
|
|
30901
31115
|
this.reject = (x2) => (this.active = false, reject(x2));
|
|
30902
31116
|
});
|
|
30903
31117
|
this.execute();
|
|
@@ -31451,12 +31665,12 @@ function Connection(options3, queues = {}, { onopen = noop4, onend = noop4, oncl
|
|
|
31451
31665
|
x2.on("drain", drain);
|
|
31452
31666
|
return x2;
|
|
31453
31667
|
}
|
|
31454
|
-
async function cancel({ pid, secret },
|
|
31668
|
+
async function cancel({ pid, secret }, resolve5, reject) {
|
|
31455
31669
|
try {
|
|
31456
31670
|
cancelMessage = bytes_default().i32(16).i32(80877102).i32(pid).i32(secret).end(16);
|
|
31457
31671
|
await connect();
|
|
31458
31672
|
socket.once("error", reject);
|
|
31459
|
-
socket.once("close",
|
|
31673
|
+
socket.once("close", resolve5);
|
|
31460
31674
|
} catch (error3) {
|
|
31461
31675
|
reject(error3);
|
|
31462
31676
|
}
|
|
@@ -32329,7 +32543,7 @@ var noop5 = () => {};
|
|
|
32329
32543
|
// ../../node_modules/postgres/src/large.js
|
|
32330
32544
|
import Stream2 from "stream";
|
|
32331
32545
|
function largeObject(sql, oid, mode = 131072 | 262144) {
|
|
32332
|
-
return new Promise(async (
|
|
32546
|
+
return new Promise(async (resolve5, reject) => {
|
|
32333
32547
|
await sql.begin(async (sql2) => {
|
|
32334
32548
|
let finish;
|
|
32335
32549
|
!oid && ([{ oid }] = await sql2`select lo_creat(-1) as oid`);
|
|
@@ -32355,7 +32569,7 @@ function largeObject(sql, oid, mode = 131072 | 262144) {
|
|
|
32355
32569
|
) seek
|
|
32356
32570
|
`
|
|
32357
32571
|
};
|
|
32358
|
-
|
|
32572
|
+
resolve5(lo);
|
|
32359
32573
|
return new Promise(async (r2) => finish = r2);
|
|
32360
32574
|
async function readable2({
|
|
32361
32575
|
highWaterMark = 2048 * 8,
|
|
@@ -32515,8 +32729,8 @@ function Postgres(a4, b3) {
|
|
|
32515
32729
|
}
|
|
32516
32730
|
async function reserve() {
|
|
32517
32731
|
const queue = queue_default();
|
|
32518
|
-
const c4 = open.length ? open.shift() : await new Promise((
|
|
32519
|
-
const query = { reserve:
|
|
32732
|
+
const c4 = open.length ? open.shift() : await new Promise((resolve5, reject) => {
|
|
32733
|
+
const query = { reserve: resolve5, reject };
|
|
32520
32734
|
queries.push(query);
|
|
32521
32735
|
closed.length && connect(closed.shift(), query);
|
|
32522
32736
|
});
|
|
@@ -32553,9 +32767,9 @@ function Postgres(a4, b3) {
|
|
|
32553
32767
|
let uncaughtError, result;
|
|
32554
32768
|
name && await sql2`savepoint ${sql2(name)}`;
|
|
32555
32769
|
try {
|
|
32556
|
-
result = await new Promise((
|
|
32770
|
+
result = await new Promise((resolve5, reject) => {
|
|
32557
32771
|
const x2 = fn2(sql2);
|
|
32558
|
-
Promise.resolve(Array.isArray(x2) ? Promise.all(x2) : x2).then(
|
|
32772
|
+
Promise.resolve(Array.isArray(x2) ? Promise.all(x2) : x2).then(resolve5, reject);
|
|
32559
32773
|
});
|
|
32560
32774
|
if (uncaughtError)
|
|
32561
32775
|
throw uncaughtError;
|
|
@@ -32612,8 +32826,8 @@ function Postgres(a4, b3) {
|
|
|
32612
32826
|
return c4.execute(query) ? move(c4, busy) : move(c4, full);
|
|
32613
32827
|
}
|
|
32614
32828
|
function cancel(query) {
|
|
32615
|
-
return new Promise((
|
|
32616
|
-
query.state ? query.active ? connection_default(options3).cancel(query.state,
|
|
32829
|
+
return new Promise((resolve5, reject) => {
|
|
32830
|
+
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
32831
|
});
|
|
32618
32832
|
}
|
|
32619
32833
|
async function end({ timeout = null } = {}) {
|
|
@@ -32629,11 +32843,11 @@ function Postgres(a4, b3) {
|
|
|
32629
32843
|
async function close() {
|
|
32630
32844
|
await Promise.all(connections.map((c4) => c4.end()));
|
|
32631
32845
|
}
|
|
32632
|
-
async function destroy(
|
|
32846
|
+
async function destroy(resolve5) {
|
|
32633
32847
|
await Promise.all(connections.map((c4) => c4.terminate()));
|
|
32634
32848
|
while (queries.length)
|
|
32635
32849
|
queries.shift().reject(Errors.connection("CONNECTION_DESTROYED", options3));
|
|
32636
|
-
|
|
32850
|
+
resolve5();
|
|
32637
32851
|
}
|
|
32638
32852
|
function connect(c4, query) {
|
|
32639
32853
|
move(c4, connecting);
|
|
@@ -33273,11 +33487,11 @@ var init_manager = __esm(() => {
|
|
|
33273
33487
|
});
|
|
33274
33488
|
|
|
33275
33489
|
// src/services/indexer.ts
|
|
33276
|
-
import { dirname as
|
|
33490
|
+
import { dirname as dirname9, resolve as resolve6 } from "node:path";
|
|
33277
33491
|
async function startIndexer(options3) {
|
|
33278
33492
|
const port = options3.port ?? 3700;
|
|
33279
|
-
const rootDir =
|
|
33280
|
-
const indexerPath =
|
|
33493
|
+
const rootDir = dirname9(dirname9(dirname9(dirname9(import.meta.dir))));
|
|
33494
|
+
const indexerPath = resolve6(rootDir, "packages/indexer/src/index.ts");
|
|
33281
33495
|
await serviceManager.start(SERVICE_NAME, ["bun", "run", "--watch", indexerPath], {
|
|
33282
33496
|
port,
|
|
33283
33497
|
env: {
|
|
@@ -33293,10 +33507,10 @@ var init_indexer = __esm(() => {
|
|
|
33293
33507
|
});
|
|
33294
33508
|
|
|
33295
33509
|
// src/services/worker.ts
|
|
33296
|
-
import { dirname as
|
|
33510
|
+
import { dirname as dirname10, resolve as resolve7 } from "node:path";
|
|
33297
33511
|
async function startWorker(options3) {
|
|
33298
|
-
const rootDir =
|
|
33299
|
-
const workerPath =
|
|
33512
|
+
const rootDir = dirname10(dirname10(dirname10(dirname10(import.meta.dir))));
|
|
33513
|
+
const workerPath = resolve7(rootDir, "packages/worker/src/index.ts");
|
|
33300
33514
|
await serviceManager.start(SERVICE_NAME2, ["bun", "run", "--watch", workerPath], {
|
|
33301
33515
|
onStdout: options3.onLog,
|
|
33302
33516
|
onStderr: options3.onLog
|
|
@@ -33308,11 +33522,11 @@ var init_worker = __esm(() => {
|
|
|
33308
33522
|
});
|
|
33309
33523
|
|
|
33310
33524
|
// src/services/api.ts
|
|
33311
|
-
import { dirname as
|
|
33525
|
+
import { dirname as dirname11, resolve as resolve8 } from "node:path";
|
|
33312
33526
|
async function startApi(options3) {
|
|
33313
33527
|
const port = options3.port ?? 3800;
|
|
33314
|
-
const rootDir =
|
|
33315
|
-
const apiPath =
|
|
33528
|
+
const rootDir = dirname11(dirname11(dirname11(dirname11(import.meta.dir))));
|
|
33529
|
+
const apiPath = resolve8(rootDir, "packages/api/src/index.ts");
|
|
33316
33530
|
await serviceManager.start(SERVICE_NAME3, ["bun", "run", "--watch", apiPath], {
|
|
33317
33531
|
port,
|
|
33318
33532
|
env: {
|
|
@@ -33328,10 +33542,10 @@ var init_api2 = __esm(() => {
|
|
|
33328
33542
|
});
|
|
33329
33543
|
|
|
33330
33544
|
// src/services/subgraph-processor.ts
|
|
33331
|
-
import { dirname as
|
|
33545
|
+
import { dirname as dirname12, resolve as resolve9 } from "node:path";
|
|
33332
33546
|
async function startSubgraphProcessor(options3) {
|
|
33333
|
-
const rootDir =
|
|
33334
|
-
const servicePath =
|
|
33547
|
+
const rootDir = dirname12(dirname12(dirname12(dirname12(import.meta.dir))));
|
|
33548
|
+
const servicePath = resolve9(rootDir, "packages/subgraphs/src/service.ts");
|
|
33335
33549
|
await serviceManager.start(SERVICE_NAME4, ["bun", "run", "--watch", servicePath], {
|
|
33336
33550
|
env: {
|
|
33337
33551
|
SUBGRAPH_CONCURRENCY: String(options3.concurrency ?? 5)
|
|
@@ -33365,8 +33579,8 @@ __export(exports_dev_impl, {
|
|
|
33365
33579
|
restartDev: () => restartDev,
|
|
33366
33580
|
isDevAlreadyRunning: () => isDevAlreadyRunning
|
|
33367
33581
|
});
|
|
33368
|
-
import { mkdirSync as
|
|
33369
|
-
import { dirname as
|
|
33582
|
+
import { mkdirSync as mkdirSync5 } from "node:fs";
|
|
33583
|
+
import { dirname as dirname13, join as join11, resolve as resolve10 } from "node:path";
|
|
33370
33584
|
async function isDevAlreadyRunning() {
|
|
33371
33585
|
if (await isDevRunning()) {
|
|
33372
33586
|
const running = await getRunningServices();
|
|
@@ -33444,10 +33658,10 @@ async function runBackground(options3) {
|
|
|
33444
33658
|
startedAt: new Date().toISOString()
|
|
33445
33659
|
};
|
|
33446
33660
|
try {
|
|
33447
|
-
const packagesDir =
|
|
33661
|
+
const packagesDir = dirname13(dirname13(dirname13(dirname13(import.meta.dir))));
|
|
33448
33662
|
const env2 = { DATABASE_URL: databaseUrl, DEV_MODE: "true" };
|
|
33449
33663
|
const apiLogFile = getLogFile("api");
|
|
33450
|
-
const apiProc = Bun.spawn(["bun", "run",
|
|
33664
|
+
const apiProc = Bun.spawn(["bun", "run", resolve10(packagesDir, "packages/api/src/index.ts")], {
|
|
33451
33665
|
env: { ...process.env, ...env2, PORT: String(apiPort) },
|
|
33452
33666
|
stdout: Bun.file(apiLogFile),
|
|
33453
33667
|
stderr: Bun.file(apiLogFile)
|
|
@@ -33460,7 +33674,7 @@ async function runBackground(options3) {
|
|
|
33460
33674
|
};
|
|
33461
33675
|
console.log(green(" ✓ API"), dim(`http://localhost:${apiPort}`));
|
|
33462
33676
|
const indexerLogFile = getLogFile("indexer");
|
|
33463
|
-
const indexerProc = Bun.spawn(["bun", "run",
|
|
33677
|
+
const indexerProc = Bun.spawn(["bun", "run", resolve10(packagesDir, "packages/indexer/src/index.ts")], {
|
|
33464
33678
|
env: { ...process.env, ...env2, PORT: String(indexerPort) },
|
|
33465
33679
|
stdout: Bun.file(indexerLogFile),
|
|
33466
33680
|
stderr: Bun.file(indexerLogFile)
|
|
@@ -33474,7 +33688,7 @@ async function runBackground(options3) {
|
|
|
33474
33688
|
console.log(green(" ✓ Indexer"), dim(`http://localhost:${indexerPort}`));
|
|
33475
33689
|
if (options3.worker) {
|
|
33476
33690
|
const workerLogFile = getLogFile("worker");
|
|
33477
|
-
const workerProc = Bun.spawn(["bun", "run",
|
|
33691
|
+
const workerProc = Bun.spawn(["bun", "run", resolve10(packagesDir, "packages/worker/src/index.ts")], {
|
|
33478
33692
|
env: { ...process.env, ...env2 },
|
|
33479
33693
|
stdout: Bun.file(workerLogFile),
|
|
33480
33694
|
stderr: Bun.file(workerLogFile)
|
|
@@ -33492,7 +33706,7 @@ async function runBackground(options3) {
|
|
|
33492
33706
|
const subgraphsProc = Bun.spawn([
|
|
33493
33707
|
"bun",
|
|
33494
33708
|
"run",
|
|
33495
|
-
|
|
33709
|
+
resolve10(packagesDir, "packages/subgraphs/src/service.ts")
|
|
33496
33710
|
], {
|
|
33497
33711
|
env: { ...process.env, ...env2 },
|
|
33498
33712
|
stdout: Bun.file(subgraphsLogFile),
|
|
@@ -33794,7 +34008,7 @@ async function restartDev() {
|
|
|
33794
34008
|
await clearDevState();
|
|
33795
34009
|
await clearLogs();
|
|
33796
34010
|
const config = await loadConfig2();
|
|
33797
|
-
const packagesDir =
|
|
34011
|
+
const packagesDir = dirname13(dirname13(dirname13(dirname13(import.meta.dir))));
|
|
33798
34012
|
const env2 = state.env;
|
|
33799
34013
|
const newState = {
|
|
33800
34014
|
services: {},
|
|
@@ -33804,7 +34018,7 @@ async function restartDev() {
|
|
|
33804
34018
|
};
|
|
33805
34019
|
const apiPort = config.ports.api;
|
|
33806
34020
|
const apiLogFile = getLogFile("api");
|
|
33807
|
-
const apiProc = Bun.spawn(["bun", "run",
|
|
34021
|
+
const apiProc = Bun.spawn(["bun", "run", resolve10(packagesDir, "packages/api/src/index.ts")], {
|
|
33808
34022
|
env: { ...process.env, ...env2, PORT: String(apiPort) },
|
|
33809
34023
|
stdout: Bun.file(apiLogFile),
|
|
33810
34024
|
stderr: Bun.file(apiLogFile)
|
|
@@ -33818,7 +34032,7 @@ async function restartDev() {
|
|
|
33818
34032
|
console.log(green(" ✓ API"), dim(`http://localhost:${apiPort}`));
|
|
33819
34033
|
const indexerPort = config.ports.indexer;
|
|
33820
34034
|
const indexerLogFile = getLogFile("indexer");
|
|
33821
|
-
const indexerProc = Bun.spawn(["bun", "run",
|
|
34035
|
+
const indexerProc = Bun.spawn(["bun", "run", resolve10(packagesDir, "packages/indexer/src/index.ts")], {
|
|
33822
34036
|
env: { ...process.env, ...env2, PORT: String(indexerPort) },
|
|
33823
34037
|
stdout: Bun.file(indexerLogFile),
|
|
33824
34038
|
stderr: Bun.file(indexerLogFile)
|
|
@@ -33832,7 +34046,7 @@ async function restartDev() {
|
|
|
33832
34046
|
console.log(green(" ✓ Indexer"), dim(`http://localhost:${indexerPort}`));
|
|
33833
34047
|
if (state.services.worker) {
|
|
33834
34048
|
const workerLogFile = getLogFile("worker");
|
|
33835
|
-
const workerProc = Bun.spawn(["bun", "run",
|
|
34049
|
+
const workerProc = Bun.spawn(["bun", "run", resolve10(packagesDir, "packages/worker/src/index.ts")], {
|
|
33836
34050
|
env: { ...process.env, ...env2 },
|
|
33837
34051
|
stdout: Bun.file(workerLogFile),
|
|
33838
34052
|
stderr: Bun.file(workerLogFile)
|
|
@@ -33847,7 +34061,7 @@ async function restartDev() {
|
|
|
33847
34061
|
}
|
|
33848
34062
|
if (state.services.subgraphs) {
|
|
33849
34063
|
const subgraphsLogFile = getLogFile("subgraphs");
|
|
33850
|
-
const subgraphsProc = Bun.spawn(["bun", "run",
|
|
34064
|
+
const subgraphsProc = Bun.spawn(["bun", "run", resolve10(packagesDir, "packages/subgraphs/src/service.ts")], {
|
|
33851
34065
|
env: { ...process.env, ...env2 },
|
|
33852
34066
|
stdout: Bun.file(subgraphsLogFile),
|
|
33853
34067
|
stderr: Bun.file(subgraphsLogFile)
|
|
@@ -33976,7 +34190,7 @@ async function ensureDevPostgres(dataDir) {
|
|
|
33976
34190
|
return false;
|
|
33977
34191
|
}
|
|
33978
34192
|
const pgDataDir = join11(dataDir, "postgres");
|
|
33979
|
-
|
|
34193
|
+
mkdirSync5(pgDataDir, { recursive: true });
|
|
33980
34194
|
const stopped = await Bun.$`docker ps -aq -f name=secondlayer-dev-postgres`.quiet().nothrow();
|
|
33981
34195
|
if (stopped.stdout.toString().trim()) {
|
|
33982
34196
|
await Bun.$`docker rm secondlayer-dev-postgres`.quiet().nothrow();
|
|
@@ -33991,8 +34205,8 @@ async function ensureDevPostgres(dataDir) {
|
|
|
33991
34205
|
throw new Error("PostgreSQL failed to start");
|
|
33992
34206
|
}
|
|
33993
34207
|
async function runMigrations(databaseUrl) {
|
|
33994
|
-
const packagesDir =
|
|
33995
|
-
const migrateScript =
|
|
34208
|
+
const packagesDir = dirname13(dirname13(dirname13(dirname13(import.meta.dir))));
|
|
34209
|
+
const migrateScript = resolve10(packagesDir, "packages/shared/src/db/migrate.ts");
|
|
33996
34210
|
const result = await Bun.$`DATABASE_URL=${databaseUrl} bun run ${migrateScript}`.quiet().nothrow();
|
|
33997
34211
|
if (result.exitCode !== 0) {
|
|
33998
34212
|
throw new Error(`Migration failed: ${result.stderr.toString()}`);
|
|
@@ -34475,7 +34689,7 @@ var {
|
|
|
34475
34689
|
// package.json
|
|
34476
34690
|
var package_default = {
|
|
34477
34691
|
name: "@secondlayer/cli",
|
|
34478
|
-
version: "9.
|
|
34692
|
+
version: "9.2.0",
|
|
34479
34693
|
repository: {
|
|
34480
34694
|
type: "git",
|
|
34481
34695
|
url: "git+https://github.com/ryanwaits/secondlayer.git",
|
|
@@ -34517,8 +34731,8 @@ var package_default = {
|
|
|
34517
34731
|
"@secondlayer/scaffold": "^1.5.0",
|
|
34518
34732
|
"@secondlayer/sdk": "^6.36.0",
|
|
34519
34733
|
"@secondlayer/shared": "^7.0.3",
|
|
34520
|
-
"@secondlayer/stacks": "^2.21.
|
|
34521
|
-
"@secondlayer/subgraphs": "^3.
|
|
34734
|
+
"@secondlayer/stacks": "^2.21.1",
|
|
34735
|
+
"@secondlayer/subgraphs": "^3.22.0",
|
|
34522
34736
|
"@biomejs/js-api": "^0.7.0",
|
|
34523
34737
|
"@biomejs/wasm-nodejs": "^1.9.0",
|
|
34524
34738
|
esbuild: "^0.27.4",
|
|
@@ -35213,14 +35427,14 @@ init_output();
|
|
|
35213
35427
|
init_resolve_auth();
|
|
35214
35428
|
import {
|
|
35215
35429
|
copyFileSync,
|
|
35216
|
-
existsSync as
|
|
35217
|
-
mkdirSync as
|
|
35218
|
-
readFileSync as
|
|
35430
|
+
existsSync as existsSync4,
|
|
35431
|
+
mkdirSync as mkdirSync3,
|
|
35432
|
+
readFileSync as readFileSync5,
|
|
35219
35433
|
readdirSync,
|
|
35220
35434
|
statSync as statSync2,
|
|
35221
|
-
writeFileSync as
|
|
35435
|
+
writeFileSync as writeFileSync4
|
|
35222
35436
|
} from "node:fs";
|
|
35223
|
-
import { dirname as
|
|
35437
|
+
import { dirname as dirname5, join as join6, relative, resolve as resolve5 } from "node:path";
|
|
35224
35438
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
35225
35439
|
import { input as input2, select as select3 } from "@inquirer/prompts";
|
|
35226
35440
|
import { SecondLayer as SecondLayer3 } from "@secondlayer/sdk";
|
|
@@ -35235,17 +35449,17 @@ var FORMAT_BY_RUNTIME = {
|
|
|
35235
35449
|
node: "standard-webhooks"
|
|
35236
35450
|
};
|
|
35237
35451
|
function templatesRoot() {
|
|
35238
|
-
const here =
|
|
35239
|
-
const candidateDist =
|
|
35240
|
-
if (
|
|
35452
|
+
const here = dirname5(fileURLToPath4(import.meta.url));
|
|
35453
|
+
const candidateDist = resolve5(here, "..", "templates", "subscriptions");
|
|
35454
|
+
if (existsSync4(candidateDist))
|
|
35241
35455
|
return candidateDist;
|
|
35242
|
-
return
|
|
35456
|
+
return resolve5(here, "..", "..", "templates", "subscriptions");
|
|
35243
35457
|
}
|
|
35244
35458
|
function copyTemplate(src2, dest, vars) {
|
|
35245
|
-
if (!
|
|
35459
|
+
if (!existsSync4(src2)) {
|
|
35246
35460
|
throw new Error(`template dir missing: ${src2}`);
|
|
35247
35461
|
}
|
|
35248
|
-
|
|
35462
|
+
mkdirSync3(dest, { recursive: true });
|
|
35249
35463
|
const entries2 = readdirSync(src2);
|
|
35250
35464
|
for (const entry of entries2) {
|
|
35251
35465
|
const from = join6(src2, entry);
|
|
@@ -35254,9 +35468,9 @@ function copyTemplate(src2, dest, vars) {
|
|
|
35254
35468
|
if (st.isDirectory()) {
|
|
35255
35469
|
copyTemplate(from, to, vars);
|
|
35256
35470
|
} else {
|
|
35257
|
-
const raw =
|
|
35471
|
+
const raw = readFileSync5(from, "utf8");
|
|
35258
35472
|
const rendered = raw.replace(/\{\{([A-Z_]+)\}\}/g, (match, key) => vars[key] ?? match);
|
|
35259
|
-
|
|
35473
|
+
writeFileSync4(to, rendered);
|
|
35260
35474
|
}
|
|
35261
35475
|
}
|
|
35262
35476
|
}
|
|
@@ -35265,7 +35479,7 @@ function parseTriggersInput(opts) {
|
|
|
35265
35479
|
if (opts.triggersFile) {
|
|
35266
35480
|
let parsed;
|
|
35267
35481
|
try {
|
|
35268
|
-
parsed = JSON.parse(
|
|
35482
|
+
parsed = JSON.parse(readFileSync5(opts.triggersFile, "utf8"));
|
|
35269
35483
|
} catch (err) {
|
|
35270
35484
|
throw new Error(`Could not read/parse --triggers-file ${opts.triggersFile}: ${err instanceof Error ? err.message : String(err)}`);
|
|
35271
35485
|
}
|
|
@@ -35350,9 +35564,9 @@ async function createSubscription(name, opts) {
|
|
|
35350
35564
|
}
|
|
35351
35565
|
}
|
|
35352
35566
|
const eventName = `${subgraph}.${table}.created`;
|
|
35353
|
-
const targetDir =
|
|
35567
|
+
const targetDir = resolve5(process.cwd(), name);
|
|
35354
35568
|
if (!opts.scaffold === false) {
|
|
35355
|
-
if (
|
|
35569
|
+
if (existsSync4(targetDir)) {
|
|
35356
35570
|
error(`Directory already exists: ${relative(process.cwd(), targetDir)}`);
|
|
35357
35571
|
process.exit(1);
|
|
35358
35572
|
}
|
|
@@ -35403,15 +35617,15 @@ async function createSubscription(name, opts) {
|
|
|
35403
35617
|
if (signingSecret && !opts.scaffold === false) {
|
|
35404
35618
|
const envTarget = join6(targetDir, ".env");
|
|
35405
35619
|
const envExample = join6(targetDir, ".env.example");
|
|
35406
|
-
if (
|
|
35620
|
+
if (existsSync4(envExample) && !existsSync4(envTarget)) {
|
|
35407
35621
|
copyFileSync(envExample, envTarget);
|
|
35408
35622
|
}
|
|
35409
|
-
if (!
|
|
35410
|
-
|
|
35623
|
+
if (!existsSync4(envTarget)) {
|
|
35624
|
+
writeFileSync4(envTarget, `SIGNING_SECRET=${signingSecret}
|
|
35411
35625
|
`);
|
|
35412
35626
|
} else {
|
|
35413
|
-
const cur =
|
|
35414
|
-
|
|
35627
|
+
const cur = readFileSync5(envTarget, "utf8");
|
|
35628
|
+
writeFileSync4(envTarget, cur.match(/^SIGNING_SECRET=/m) ? cur.replace(/^SIGNING_SECRET=.*/m, `SIGNING_SECRET=${signingSecret}`) : `${cur}
|
|
35415
35629
|
SIGNING_SECRET=${signingSecret}
|
|
35416
35630
|
`);
|
|
35417
35631
|
}
|
|
@@ -36178,8 +36392,8 @@ POST result (client-side, not logged):`));
|
|
|
36178
36392
|
}
|
|
36179
36393
|
// src/commands/devnet.ts
|
|
36180
36394
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
36181
|
-
import { existsSync as
|
|
36182
|
-
import { dirname as
|
|
36395
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync4, writeFileSync as writeFileSync6 } from "node:fs";
|
|
36396
|
+
import { dirname as dirname7, join as join8 } from "node:path";
|
|
36183
36397
|
|
|
36184
36398
|
// src/lib/devnet-compose.ts
|
|
36185
36399
|
var DEFAULT_IMAGE_OWNER = "ryanwaits";
|
|
@@ -36321,24 +36535,24 @@ volumes:
|
|
|
36321
36535
|
}
|
|
36322
36536
|
|
|
36323
36537
|
// src/lib/devnet-config.ts
|
|
36324
|
-
import { existsSync as
|
|
36325
|
-
import { dirname as
|
|
36538
|
+
import { existsSync as existsSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "node:fs";
|
|
36539
|
+
import { dirname as dirname6, join as join7, parse as parsePath } from "node:path";
|
|
36326
36540
|
import { parse as parseToml } from "smol-toml";
|
|
36327
36541
|
var DEFAULT_INDEXER_OBSERVER = "host.docker.internal:3700";
|
|
36328
36542
|
function findClarinetProject(startDir) {
|
|
36329
36543
|
let dir = startDir;
|
|
36330
36544
|
const { root } = parsePath(dir);
|
|
36331
36545
|
while (true) {
|
|
36332
|
-
if (
|
|
36546
|
+
if (existsSync5(join7(dir, "Clarinet.toml")))
|
|
36333
36547
|
return dir;
|
|
36334
36548
|
if (dir === root)
|
|
36335
36549
|
return null;
|
|
36336
|
-
dir =
|
|
36550
|
+
dir = dirname6(dir);
|
|
36337
36551
|
}
|
|
36338
36552
|
}
|
|
36339
36553
|
function ensureEventObserver(devnetTomlPath, endpoint = DEFAULT_INDEXER_OBSERVER) {
|
|
36340
|
-
const exists =
|
|
36341
|
-
const original = exists ?
|
|
36554
|
+
const exists = existsSync5(devnetTomlPath);
|
|
36555
|
+
const original = exists ? readFileSync6(devnetTomlPath, "utf8") : "";
|
|
36342
36556
|
if (original.trim()) {
|
|
36343
36557
|
const parsed = parseToml(original);
|
|
36344
36558
|
const observers = parsed.devnet?.stacks_node_events_observers;
|
|
@@ -36352,7 +36566,7 @@ function ensureEventObserver(devnetTomlPath, endpoint = DEFAULT_INDEXER_OBSERVER
|
|
|
36352
36566
|
const at = (arrayStart.index ?? 0) + arrayStart[0].length;
|
|
36353
36567
|
const next = original.slice(at).trimStart().startsWith("]") ? entry : `${entry}, `;
|
|
36354
36568
|
const patched = original.slice(0, at) + next + original.slice(at);
|
|
36355
|
-
|
|
36569
|
+
writeFileSync5(devnetTomlPath, patched);
|
|
36356
36570
|
return { status: "added" };
|
|
36357
36571
|
}
|
|
36358
36572
|
const header = original.match(/^\[devnet\]\s*$/m);
|
|
@@ -36360,7 +36574,7 @@ function ensureEventObserver(devnetTomlPath, endpoint = DEFAULT_INDEXER_OBSERVER
|
|
|
36360
36574
|
const at = (header.index ?? 0) + header[0].length;
|
|
36361
36575
|
const patched = `${original.slice(0, at)}
|
|
36362
36576
|
stacks_node_events_observers = [${entry}]${original.slice(at)}`;
|
|
36363
|
-
|
|
36577
|
+
writeFileSync5(devnetTomlPath, patched);
|
|
36364
36578
|
return { status: "added" };
|
|
36365
36579
|
}
|
|
36366
36580
|
const prefix = original && !original.endsWith(`
|
|
@@ -36370,7 +36584,7 @@ stacks_node_events_observers = [${entry}]${original.slice(at)}`;
|
|
|
36370
36584
|
` : ""}[devnet]
|
|
36371
36585
|
stacks_node_events_observers = [${entry}]
|
|
36372
36586
|
`;
|
|
36373
|
-
|
|
36587
|
+
writeFileSync5(devnetTomlPath, block);
|
|
36374
36588
|
return { status: exists ? "added" : "created" };
|
|
36375
36589
|
}
|
|
36376
36590
|
|
|
@@ -36420,7 +36634,7 @@ function registerDevnetCommand(program2) {
|
|
|
36420
36634
|
}
|
|
36421
36635
|
function resolveProject(explicit) {
|
|
36422
36636
|
if (explicit) {
|
|
36423
|
-
if (!
|
|
36637
|
+
if (!existsSync6(join8(explicit, "Clarinet.toml"))) {
|
|
36424
36638
|
error(`No Clarinet.toml in ${explicit}`);
|
|
36425
36639
|
process.exit(1);
|
|
36426
36640
|
}
|
|
@@ -36437,7 +36651,7 @@ function resolveProject(explicit) {
|
|
|
36437
36651
|
async function connect(options3) {
|
|
36438
36652
|
const project = resolveProject(options3.project);
|
|
36439
36653
|
const devnetToml = join8(project, "settings", "Devnet.toml");
|
|
36440
|
-
|
|
36654
|
+
mkdirSync4(dirname7(devnetToml), { recursive: true });
|
|
36441
36655
|
const result = ensureEventObserver(devnetToml, DEFAULT_INDEXER_OBSERVER);
|
|
36442
36656
|
console.log(`${green("✓")} found Clarinet.toml`);
|
|
36443
36657
|
if (result.status === "present") {
|
|
@@ -36447,8 +36661,8 @@ async function connect(options3) {
|
|
|
36447
36661
|
console.log(dim(` + stacks_node_events_observers = ["${DEFAULT_INDEXER_OBSERVER}"]`));
|
|
36448
36662
|
}
|
|
36449
36663
|
const composePath = join8(project, COMPOSE_REL);
|
|
36450
|
-
|
|
36451
|
-
|
|
36664
|
+
mkdirSync4(dirname7(composePath), { recursive: true });
|
|
36665
|
+
writeFileSync6(composePath, buildDevnetCompose({ owner: options3.owner, imageTag: options3.imageTag }));
|
|
36452
36666
|
console.log(`${green("✓")} wrote ${COMPOSE_REL}`);
|
|
36453
36667
|
if (!options3.up) {
|
|
36454
36668
|
console.log(dim(`
|
|
@@ -36477,7 +36691,7 @@ Stop with: sl devnet down`));
|
|
|
36477
36691
|
async function down(options3) {
|
|
36478
36692
|
const project = resolveProject(options3.project);
|
|
36479
36693
|
const composePath = join8(project, COMPOSE_REL);
|
|
36480
|
-
if (!
|
|
36694
|
+
if (!existsSync6(composePath)) {
|
|
36481
36695
|
error(`No ${COMPOSE_REL} in ${project} — nothing to stop. Run \`sl devnet connect\` first.`);
|
|
36482
36696
|
process.exit(1);
|
|
36483
36697
|
}
|
|
@@ -36492,7 +36706,7 @@ async function down(options3) {
|
|
|
36492
36706
|
async function logs(service, options3) {
|
|
36493
36707
|
const project = resolveProject(options3.project);
|
|
36494
36708
|
const composePath = join8(project, COMPOSE_REL);
|
|
36495
|
-
if (!
|
|
36709
|
+
if (!existsSync6(composePath)) {
|
|
36496
36710
|
error(`No ${COMPOSE_REL} in ${project} — run \`sl devnet connect\` first.`);
|
|
36497
36711
|
process.exit(1);
|
|
36498
36712
|
}
|
|
@@ -36617,7 +36831,7 @@ init_subgraphs2();
|
|
|
36617
36831
|
init_output();
|
|
36618
36832
|
init_resolve_auth();
|
|
36619
36833
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
|
|
36620
|
-
import { dirname as
|
|
36834
|
+
import { dirname as dirname8, join as join9 } from "node:path";
|
|
36621
36835
|
import { createStreamsClient } from "@secondlayer/sdk";
|
|
36622
36836
|
import { STREAMS_EVENT_TYPES } from "@secondlayer/shared";
|
|
36623
36837
|
var DEFAULT_BASE_URL3 = "https://api.secondlayer.tools";
|
|
@@ -36794,7 +37008,7 @@ Examples:
|
|
|
36794
37008
|
for (const file of files) {
|
|
36795
37009
|
const bytes = await dumps.download(file);
|
|
36796
37010
|
const dest = join9(options3.to, file.path);
|
|
36797
|
-
await mkdir3(
|
|
37011
|
+
await mkdir3(dirname8(dest), { recursive: true });
|
|
36798
37012
|
await writeFile3(dest, bytes);
|
|
36799
37013
|
process.stderr.write(`# ${file.path} (${file.row_count} rows, ${bytes.byteLength} bytes)
|
|
36800
37014
|
`);
|
|
@@ -38080,10 +38294,10 @@ init_http();
|
|
|
38080
38294
|
init_output();
|
|
38081
38295
|
|
|
38082
38296
|
// src/lib/project-file.ts
|
|
38083
|
-
import { existsSync as
|
|
38297
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
38084
38298
|
import { mkdir as mkdir4, readFile as readFile3, writeFile as writeFile4 } from "node:fs/promises";
|
|
38085
38299
|
import { homedir as homedir5 } from "node:os";
|
|
38086
|
-
import { dirname as
|
|
38300
|
+
import { dirname as dirname14, join as join12, parse as parsePath2, resolve as resolve11 } from "node:path";
|
|
38087
38301
|
import { z as z4 } from "zod";
|
|
38088
38302
|
var ProjectFileSchema = z4.object({
|
|
38089
38303
|
slug: z4.string().min(1)
|
|
@@ -38091,23 +38305,23 @@ var ProjectFileSchema = z4.object({
|
|
|
38091
38305
|
var FILENAME = "project";
|
|
38092
38306
|
var DIRNAME = ".secondlayer";
|
|
38093
38307
|
async function readActiveProject(cwd, globalDefault) {
|
|
38094
|
-
let dir =
|
|
38095
|
-
const home2 =
|
|
38308
|
+
let dir = resolve11(cwd);
|
|
38309
|
+
const home2 = resolve11(homedir5());
|
|
38096
38310
|
const fsRoot = parsePath2(dir).root;
|
|
38097
38311
|
while (true) {
|
|
38098
38312
|
const candidate = join12(dir, DIRNAME, FILENAME);
|
|
38099
|
-
if (
|
|
38313
|
+
if (existsSync7(candidate)) {
|
|
38100
38314
|
try {
|
|
38101
38315
|
const raw = await readFile3(candidate, "utf8");
|
|
38102
38316
|
const parsed = ProjectFileSchema.parse(JSON.parse(raw));
|
|
38103
38317
|
return { slug: parsed.slug, resolvedFrom: candidate };
|
|
38104
38318
|
} catch {}
|
|
38105
38319
|
}
|
|
38106
|
-
if (
|
|
38320
|
+
if (existsSync7(join12(dir, ".git")))
|
|
38107
38321
|
break;
|
|
38108
38322
|
if (dir === home2 || dir === fsRoot)
|
|
38109
38323
|
break;
|
|
38110
|
-
const parent =
|
|
38324
|
+
const parent = dirname14(dir);
|
|
38111
38325
|
if (parent === dir)
|
|
38112
38326
|
break;
|
|
38113
38327
|
dir = parent;
|
|
@@ -38121,7 +38335,7 @@ async function readActiveProject(cwd, globalDefault) {
|
|
|
38121
38335
|
return null;
|
|
38122
38336
|
}
|
|
38123
38337
|
async function writeActiveProject(slug, cwd) {
|
|
38124
|
-
const dir = join12(
|
|
38338
|
+
const dir = join12(resolve11(cwd), DIRNAME);
|
|
38125
38339
|
await mkdir4(dir, { recursive: true });
|
|
38126
38340
|
const file = join12(dir, FILENAME);
|
|
38127
38341
|
await writeFile4(file, `${JSON.stringify({ slug }, null, 2)}
|
|
@@ -38345,5 +38559,5 @@ registerAccountCommand(program);
|
|
|
38345
38559
|
registerKeysCommand(program);
|
|
38346
38560
|
program.parse();
|
|
38347
38561
|
|
|
38348
|
-
//# debugId=
|
|
38562
|
+
//# debugId=FAEADBDE13DF788264756E2164756E21
|
|
38349
38563
|
//# sourceMappingURL=cli.js.map
|