@secondlayer/cli 3.6.1 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.js +106 -100
- package/dist/cli.js.map +28 -28
- package/dist/core/plugin-manager.js +3 -3
- package/dist/core/plugin-manager.js.map +4 -4
- package/dist/index.js +9 -9
- package/dist/index.js.map +5 -5
- package/dist/plugins/index.js +17 -16
- package/dist/plugins/index.js.map +11 -11
- package/package.json +6 -6
- package/templates/subscriptions/inngest/src/server.ts +1 -1
- package/templates/subscriptions/node/src/index.ts +3 -1
package/README.md
CHANGED
|
@@ -74,7 +74,7 @@ One instance per project. The platform API spawns a dedicated `sl-pg-{slug}`,
|
|
|
74
74
|
|
|
75
75
|
| Command | What it does |
|
|
76
76
|
|---|---|
|
|
77
|
-
| `sl instance create --plan <hobby\|launch\|
|
|
77
|
+
| `sl instance create --plan <hobby\|launch\|scale>` | Provision containers. Boxed reveal of `serviceKey` + `anonKey` (shown once). |
|
|
78
78
|
| `sl instance info` | Plan, status, resource usage |
|
|
79
79
|
| `sl instance resize --plan <...>` | Recreate containers with new CPU/memory (~30s downtime) |
|
|
80
80
|
| `sl instance suspend` / `resume` | Stop/start containers, volume preserved |
|
package/dist/cli.js
CHANGED
|
@@ -119,8 +119,8 @@ var biome = null;
|
|
|
119
119
|
var init_format = () => {};
|
|
120
120
|
|
|
121
121
|
// src/core/plugin-manager.ts
|
|
122
|
-
import { promises as fs } from "fs";
|
|
123
|
-
import path from "path";
|
|
122
|
+
import { promises as fs } from "node:fs";
|
|
123
|
+
import path from "node:path";
|
|
124
124
|
import { isValidAddress as _validateStacksAddress } from "@secondlayer/stacks";
|
|
125
125
|
import { getErrorMessage } from "@secondlayer/shared";
|
|
126
126
|
import { toCamelCase } from "@secondlayer/stacks/clarity";
|
|
@@ -2499,7 +2499,7 @@ async function readSession() {
|
|
|
2499
2499
|
}
|
|
2500
2500
|
async function writeSession(session) {
|
|
2501
2501
|
await mkdir(dirname(SESSION_PATH), { recursive: true });
|
|
2502
|
-
await writeFile(SESSION_PATH, JSON.stringify(session, null, 2)
|
|
2502
|
+
await writeFile(SESSION_PATH, `${JSON.stringify(session, null, 2)}
|
|
2503
2503
|
`, "utf8");
|
|
2504
2504
|
await chmod(SESSION_PATH, 384);
|
|
2505
2505
|
}
|
|
@@ -2659,7 +2659,7 @@ function migrateConfig(raw) {
|
|
|
2659
2659
|
network: old.nodeNetwork || "mainnet"
|
|
2660
2660
|
};
|
|
2661
2661
|
if (!migrated.node.installPath) {
|
|
2662
|
-
|
|
2662
|
+
migrated.node = undefined;
|
|
2663
2663
|
}
|
|
2664
2664
|
}
|
|
2665
2665
|
if (old.node && typeof old.node === "object") {
|
|
@@ -2709,13 +2709,13 @@ function applyEnvOverrides(config) {
|
|
|
2709
2709
|
}
|
|
2710
2710
|
if (process.env.SL_API_PORT) {
|
|
2711
2711
|
const port = Number.parseInt(process.env.SL_API_PORT, 10);
|
|
2712
|
-
if (!isNaN(port) && port > 0 && port <= 65535) {
|
|
2712
|
+
if (!Number.isNaN(port) && port > 0 && port <= 65535) {
|
|
2713
2713
|
result.ports = { ...result.ports, api: port };
|
|
2714
2714
|
}
|
|
2715
2715
|
}
|
|
2716
2716
|
if (process.env.SL_INDEXER_PORT) {
|
|
2717
2717
|
const port = Number.parseInt(process.env.SL_INDEXER_PORT, 10);
|
|
2718
|
-
if (!isNaN(port) && port > 0 && port <= 65535) {
|
|
2718
|
+
if (!Number.isNaN(port) && port > 0 && port <= 65535) {
|
|
2719
2719
|
result.ports = { ...result.ports, indexer: port };
|
|
2720
2720
|
}
|
|
2721
2721
|
}
|
|
@@ -2733,7 +2733,7 @@ async function configExists() {
|
|
|
2733
2733
|
async function saveConfig(config) {
|
|
2734
2734
|
const validated = ConfigSchema.parse(config);
|
|
2735
2735
|
await ensureConfigDir();
|
|
2736
|
-
await writeTextFile(CONFIG_PATH, JSON.stringify(validated, null, 2)
|
|
2736
|
+
await writeTextFile(CONFIG_PATH, `${JSON.stringify(validated, null, 2)}
|
|
2737
2737
|
`);
|
|
2738
2738
|
}
|
|
2739
2739
|
async function setConfigValue(key, value) {
|
|
@@ -2761,7 +2761,7 @@ function parseValue(value) {
|
|
|
2761
2761
|
if (value === "false")
|
|
2762
2762
|
return false;
|
|
2763
2763
|
const num = Number(value);
|
|
2764
|
-
if (!isNaN(num) && value.trim() !== "") {
|
|
2764
|
+
if (!Number.isNaN(num) && value.trim() !== "") {
|
|
2765
2765
|
return num;
|
|
2766
2766
|
}
|
|
2767
2767
|
return value;
|
|
@@ -2797,9 +2797,9 @@ async function requireLocalNetwork() {
|
|
|
2797
2797
|
console.error(`Error: 'sl local' commands require local mode.`);
|
|
2798
2798
|
console.error(` Current context: ${config.network} (hosted)`);
|
|
2799
2799
|
console.error("");
|
|
2800
|
-
console.error(
|
|
2800
|
+
console.error(" To check system status, use: sl status");
|
|
2801
2801
|
console.error("");
|
|
2802
|
-
console.error(
|
|
2802
|
+
console.error(" To switch to local mode: sl config set network local");
|
|
2803
2803
|
process.exit(1);
|
|
2804
2804
|
}
|
|
2805
2805
|
return config;
|
|
@@ -2884,7 +2884,7 @@ async function writeActiveProject(slug, cwd) {
|
|
|
2884
2884
|
const dir = join3(resolve(cwd), DIRNAME);
|
|
2885
2885
|
await mkdir3(dir, { recursive: true });
|
|
2886
2886
|
const file = join3(dir, FILENAME);
|
|
2887
|
-
await writeFile3(file, JSON.stringify({ slug }, null, 2)
|
|
2887
|
+
await writeFile3(file, `${JSON.stringify({ slug }, null, 2)}
|
|
2888
2888
|
`, "utf8");
|
|
2889
2889
|
return file;
|
|
2890
2890
|
}
|
|
@@ -5074,7 +5074,7 @@ async function loadDevState() {
|
|
|
5074
5074
|
}
|
|
5075
5075
|
async function saveDevState(state) {
|
|
5076
5076
|
await ensureDirs();
|
|
5077
|
-
await Bun.write(DEV_STATE_PATH, JSON.stringify(state, null, 2)
|
|
5077
|
+
await Bun.write(DEV_STATE_PATH, `${JSON.stringify(state, null, 2)}
|
|
5078
5078
|
`);
|
|
5079
5079
|
}
|
|
5080
5080
|
async function clearDevState() {
|
|
@@ -5271,30 +5271,31 @@ function normalizeAbi(abi) {
|
|
|
5271
5271
|
}
|
|
5272
5272
|
|
|
5273
5273
|
// src/parsers/clarity.ts
|
|
5274
|
-
import { promises as fs3 } from "fs";
|
|
5274
|
+
import { promises as fs3 } from "node:fs";
|
|
5275
5275
|
async function parseClarityFile(filePath) {
|
|
5276
5276
|
try {
|
|
5277
5277
|
const content = await fs3.readFile(filePath, "utf-8");
|
|
5278
5278
|
const result = parseClarityContent(content);
|
|
5279
5279
|
if (result.functions.length === 0) {
|
|
5280
|
-
console.warn(`⚠️ No functions found in ${filePath}.
|
|
5280
|
+
console.warn(`⚠️ No functions found in ${filePath}. For complex contracts, deploy first and use the contract address instead.`);
|
|
5281
5281
|
}
|
|
5282
5282
|
return result;
|
|
5283
5283
|
} catch (error2) {
|
|
5284
|
-
throw new Error(`Unable to parse ${filePath}.
|
|
5285
|
-
|
|
5284
|
+
throw new Error(`Unable to parse ${filePath}. For complex contracts, deploy first and use the contract address instead.
|
|
5285
|
+
Original error: ${error2}`);
|
|
5286
5286
|
}
|
|
5287
5287
|
}
|
|
5288
5288
|
function parseClarityContent(content) {
|
|
5289
5289
|
const functions = [];
|
|
5290
5290
|
const functionRegex = /\(define-(public|read-only|private)\s+\(([^)]+)\)([\s\S]*?)\)\s*$/gm;
|
|
5291
|
-
let match;
|
|
5292
|
-
while (
|
|
5291
|
+
let match = functionRegex.exec(content);
|
|
5292
|
+
while (match !== null) {
|
|
5293
5293
|
const [, access, signature, body] = match;
|
|
5294
5294
|
const func = parseFunctionSignature(signature, access, body);
|
|
5295
5295
|
if (func) {
|
|
5296
5296
|
functions.push(func);
|
|
5297
5297
|
}
|
|
5298
|
+
match = functionRegex.exec(content);
|
|
5298
5299
|
}
|
|
5299
5300
|
return { functions };
|
|
5300
5301
|
}
|
|
@@ -5320,8 +5321,8 @@ function parseFunctionSignature(signature, access, body) {
|
|
|
5320
5321
|
};
|
|
5321
5322
|
}
|
|
5322
5323
|
function parseType(typeStr) {
|
|
5323
|
-
|
|
5324
|
-
switch (
|
|
5324
|
+
const cleaned = typeStr.replace(/[()]/g, "").trim();
|
|
5325
|
+
switch (cleaned) {
|
|
5325
5326
|
case "uint":
|
|
5326
5327
|
case "uint128":
|
|
5327
5328
|
return "uint128";
|
|
@@ -5335,13 +5336,13 @@ function parseType(typeStr) {
|
|
|
5335
5336
|
case "trait_reference":
|
|
5336
5337
|
return "principal";
|
|
5337
5338
|
default:
|
|
5338
|
-
if (
|
|
5339
|
+
if (cleaned.startsWith("string-ascii")) {
|
|
5339
5340
|
return { "string-ascii": { length: 256 } };
|
|
5340
5341
|
}
|
|
5341
|
-
if (
|
|
5342
|
+
if (cleaned.startsWith("string-utf8")) {
|
|
5342
5343
|
return { "string-utf8": { length: 256 } };
|
|
5343
5344
|
}
|
|
5344
|
-
if (
|
|
5345
|
+
if (cleaned.startsWith("buff")) {
|
|
5345
5346
|
return { buff: { length: 32 } };
|
|
5346
5347
|
}
|
|
5347
5348
|
return "uint128";
|
|
@@ -13117,7 +13118,7 @@ async function validateNetworkConsistency(config) {
|
|
|
13117
13118
|
const envStr = result.stdout.toString();
|
|
13118
13119
|
const match = envStr.match(/STACKS_CHAIN_ID=(0x[0-9a-fA-F]+|\d+)/);
|
|
13119
13120
|
if (match) {
|
|
13120
|
-
const containerId = Number.parseInt(match[1], match[1]
|
|
13121
|
+
const containerId = Number.parseInt(match[1], match[1]?.startsWith("0x") ? 16 : 10);
|
|
13121
13122
|
if (containerId !== expected) {
|
|
13122
13123
|
issues.push(`Container STACKS_CHAIN_ID=${containerId} but config expects ${expected} (${network})`);
|
|
13123
13124
|
}
|
|
@@ -13131,7 +13132,7 @@ async function validateNetworkConsistency(config) {
|
|
|
13131
13132
|
const content = await envFile.text();
|
|
13132
13133
|
const match = content.match(/STACKS_CHAIN_ID=(0x[0-9a-fA-F]+|\d+)/);
|
|
13133
13134
|
if (match) {
|
|
13134
|
-
const fileId = Number.parseInt(match[1], match[1]
|
|
13135
|
+
const fileId = Number.parseInt(match[1], match[1]?.startsWith("0x") ? 16 : 10);
|
|
13135
13136
|
if (fileId !== expected) {
|
|
13136
13137
|
issues.push(`Node .env STACKS_CHAIN_ID=${fileId} but config expects ${expected} (${network})`);
|
|
13137
13138
|
}
|
|
@@ -13327,14 +13328,14 @@ function formatLogLine(line) {
|
|
|
13327
13328
|
function extractKeyInfo(message) {
|
|
13328
13329
|
if (message.includes("Advanced to new tip")) {
|
|
13329
13330
|
const hashMatch = message.match(/([a-f0-9]{64})/);
|
|
13330
|
-
const hash = hashMatch ? hashMatch[1]
|
|
13331
|
+
const hash = hashMatch ? `${hashMatch[1]?.slice(0, 16)}...` : "";
|
|
13331
13332
|
return `Advanced to new tip ${hash}`;
|
|
13332
13333
|
}
|
|
13333
13334
|
if (message.includes("Downloading")) {
|
|
13334
13335
|
return message.replace(/local::[^\s]+/, "").trim();
|
|
13335
13336
|
}
|
|
13336
13337
|
if (message.length > 120) {
|
|
13337
|
-
return message.slice(0, 117)
|
|
13338
|
+
return `${message.slice(0, 117)}...`;
|
|
13338
13339
|
}
|
|
13339
13340
|
return message;
|
|
13340
13341
|
}
|
|
@@ -13616,7 +13617,7 @@ async function runBackground(options2) {
|
|
|
13616
13617
|
if (databaseUrl) {
|
|
13617
13618
|
const reachable = await isDatabaseReachable(databaseUrl);
|
|
13618
13619
|
if (!reachable) {
|
|
13619
|
-
info(
|
|
13620
|
+
info("Configured DATABASE_URL not reachable, starting PostgreSQL container...");
|
|
13620
13621
|
databaseUrl = undefined;
|
|
13621
13622
|
}
|
|
13622
13623
|
}
|
|
@@ -13778,7 +13779,7 @@ async function runForeground(options2) {
|
|
|
13778
13779
|
if (databaseUrl) {
|
|
13779
13780
|
const reachable = await isDatabaseReachable(databaseUrl);
|
|
13780
13781
|
if (!reachable) {
|
|
13781
|
-
info(
|
|
13782
|
+
info("Configured DATABASE_URL not reachable, starting PostgreSQL container...");
|
|
13782
13783
|
databaseUrl = undefined;
|
|
13783
13784
|
}
|
|
13784
13785
|
}
|
|
@@ -13854,13 +13855,16 @@ function formatLogLine2(service, line) {
|
|
|
13854
13855
|
const [, timestamp, level, message] = match;
|
|
13855
13856
|
const dimTimestamp = dim(timestamp);
|
|
13856
13857
|
if (level === "ERROR") {
|
|
13857
|
-
return `${prefix} ${dimTimestamp} ${red(level
|
|
13858
|
-
}
|
|
13859
|
-
|
|
13860
|
-
|
|
13861
|
-
|
|
13862
|
-
|
|
13863
|
-
return `${prefix} ${dimTimestamp} ${
|
|
13858
|
+
return `${prefix} ${dimTimestamp} ${red(`${level}:`)} ${message}`;
|
|
13859
|
+
}
|
|
13860
|
+
if (level === "WARN") {
|
|
13861
|
+
return `${prefix} ${dimTimestamp} ${yellow(`${level}:`)} ${message}`;
|
|
13862
|
+
}
|
|
13863
|
+
if (level === "INFO") {
|
|
13864
|
+
return `${prefix} ${dimTimestamp} ${green(`${level}:`)} ${message}`;
|
|
13865
|
+
}
|
|
13866
|
+
if (level === "DEBUG") {
|
|
13867
|
+
return `${prefix} ${dimTimestamp} ${dim(`${level}:`)} ${dim(message)}`;
|
|
13864
13868
|
}
|
|
13865
13869
|
}
|
|
13866
13870
|
return `${prefix} ${line}`;
|
|
@@ -13888,7 +13892,7 @@ async function followLogs(services, initialLines) {
|
|
|
13888
13892
|
await showStaticLogs(services, initialLines);
|
|
13889
13893
|
const procs = [];
|
|
13890
13894
|
for (const [name, service] of services) {
|
|
13891
|
-
const proc = Bun.spawn(["tail", "-f", "-n", "0", service
|
|
13895
|
+
const proc = Bun.spawn(["tail", "-f", "-n", "0", service?.logFile], {
|
|
13892
13896
|
stdout: "pipe",
|
|
13893
13897
|
stderr: "pipe"
|
|
13894
13898
|
});
|
|
@@ -14103,7 +14107,7 @@ async function isContainerRunning(name) {
|
|
|
14103
14107
|
function printBanner() {
|
|
14104
14108
|
console.log("");
|
|
14105
14109
|
console.log(blue(" ╔═══════════════════════════════════════╗"));
|
|
14106
|
-
console.log(blue(" ║")
|
|
14110
|
+
console.log(`${blue(" ║")} Secondlayer Dev Server ${blue("║")}`);
|
|
14107
14111
|
console.log(blue(" ╚═══════════════════════════════════════╝"));
|
|
14108
14112
|
console.log("");
|
|
14109
14113
|
console.log(dim(" Starting services..."));
|
|
@@ -14112,21 +14116,21 @@ function printBanner() {
|
|
|
14112
14116
|
function printUrls(indexerPort, apiPort) {
|
|
14113
14117
|
console.log(dim(" ─────────────────────────────────────────"));
|
|
14114
14118
|
console.log("");
|
|
14115
|
-
console.log(
|
|
14119
|
+
console.log(` ${blue("API:")}`);
|
|
14116
14120
|
console.log(` List subgraphs: curl http://localhost:${apiPort}/api/subgraphs`);
|
|
14117
14121
|
console.log(` Health check: curl http://localhost:${apiPort}/health`);
|
|
14118
14122
|
console.log("");
|
|
14119
|
-
console.log(
|
|
14123
|
+
console.log(` ${blue("Indexer:")}`);
|
|
14120
14124
|
console.log(` Health check: curl http://localhost:${indexerPort}/health`);
|
|
14121
14125
|
console.log(` Send block: curl -X POST http://localhost:${indexerPort}/new_block -d @block.json`);
|
|
14122
14126
|
console.log("");
|
|
14123
|
-
console.log(
|
|
14127
|
+
console.log(` ${blue("Stacks Node Config:")}`);
|
|
14124
14128
|
console.log(dim(" Add to your Stacks node Config.toml:"));
|
|
14125
14129
|
console.log("");
|
|
14126
|
-
console.log(yellow(
|
|
14130
|
+
console.log(yellow(" [[events_observer]]"));
|
|
14127
14131
|
console.log(yellow(` endpoint = "host.docker.internal:${indexerPort}"`));
|
|
14128
14132
|
console.log(yellow(` events_keys = ["*"]`));
|
|
14129
|
-
console.log(yellow(
|
|
14133
|
+
console.log(yellow(" timeout_ms = 300_000"));
|
|
14130
14134
|
console.log("");
|
|
14131
14135
|
console.log(dim(" ─────────────────────────────────────────"));
|
|
14132
14136
|
}
|
|
@@ -14268,7 +14272,7 @@ async function runSetupWizard() {
|
|
|
14268
14272
|
default: "3700",
|
|
14269
14273
|
validate: (value) => {
|
|
14270
14274
|
const port = Number.parseInt(value);
|
|
14271
|
-
if (isNaN(port) || port < 1 || port > 65535) {
|
|
14275
|
+
if (Number.isNaN(port) || port < 1 || port > 65535) {
|
|
14272
14276
|
return "Invalid port number";
|
|
14273
14277
|
}
|
|
14274
14278
|
return true;
|
|
@@ -14301,9 +14305,9 @@ async function runSetupWizard() {
|
|
|
14301
14305
|
]));
|
|
14302
14306
|
console.log("");
|
|
14303
14307
|
console.log(dim("Next steps:"));
|
|
14304
|
-
console.log(
|
|
14305
|
-
console.log(
|
|
14306
|
-
console.log(
|
|
14308
|
+
console.log(` ${green("sl local node start")}${dim(" - Start the Stacks node")}`);
|
|
14309
|
+
console.log(` ${green("sl local node status")}${dim(" - Check sync progress")}`);
|
|
14310
|
+
console.log(` ${green("sl local node logs")}${dim(" - View logs")}`);
|
|
14307
14311
|
console.log("");
|
|
14308
14312
|
}
|
|
14309
14313
|
async function startNode(pathOverride, withIndexer) {
|
|
@@ -14349,13 +14353,13 @@ async function startNode(pathOverride, withIndexer) {
|
|
|
14349
14353
|
console.log("");
|
|
14350
14354
|
if (withIndexer) {
|
|
14351
14355
|
const port = config.ports?.indexer || 3700;
|
|
14352
|
-
console.log(dim(
|
|
14356
|
+
console.log(dim("Tip: Start indexer with: sl local start"));
|
|
14353
14357
|
console.log(dim(` Or manually: PORT=${port} bun run packages/indexer/src/index.ts`));
|
|
14354
14358
|
console.log("");
|
|
14355
14359
|
}
|
|
14356
14360
|
console.log(dim("Next steps:"));
|
|
14357
|
-
console.log(
|
|
14358
|
-
console.log(
|
|
14361
|
+
console.log(` ${green("sl local node status")}${dim(" - Check sync progress")}`);
|
|
14362
|
+
console.log(` ${green("sl local node logs -f")}${dim(" - Follow logs")}`);
|
|
14359
14363
|
console.log("");
|
|
14360
14364
|
}
|
|
14361
14365
|
async function stopNode(_pathOverride, force, _wait) {
|
|
@@ -14427,8 +14431,8 @@ async function restartNode(pathOverride, force, _wait) {
|
|
|
14427
14431
|
success("Node started!");
|
|
14428
14432
|
console.log("");
|
|
14429
14433
|
console.log(dim("Next steps:"));
|
|
14430
|
-
console.log(
|
|
14431
|
-
console.log(
|
|
14434
|
+
console.log(` ${green("sl local node status")}${dim(" - Check sync progress")}`);
|
|
14435
|
+
console.log(` ${green("sl local node logs -f")}${dim(" - Follow logs")}`);
|
|
14432
14436
|
console.log("");
|
|
14433
14437
|
}
|
|
14434
14438
|
async function showStatus(pathOverride, jsonOutput) {
|
|
@@ -14534,7 +14538,7 @@ async function showStatus(pathOverride, jsonOutput) {
|
|
|
14534
14538
|
if (config.node) {
|
|
14535
14539
|
console.log(blue("Indexer"));
|
|
14536
14540
|
console.log(` ${dim("-")} ${dim(`Not running (expected on port ${indexerPort})`)}`);
|
|
14537
|
-
console.log(dim(
|
|
14541
|
+
console.log(dim(" Start with: sl local start"));
|
|
14538
14542
|
console.log("");
|
|
14539
14543
|
}
|
|
14540
14544
|
}
|
|
@@ -20448,10 +20452,10 @@ function generateClarityConversion(argName, argType) {
|
|
|
20448
20452
|
})()`;
|
|
20449
20453
|
}
|
|
20450
20454
|
if (isAbiResponse(type)) {
|
|
20451
|
-
const okConversion = generateClarityConversion(
|
|
20455
|
+
const okConversion = generateClarityConversion("responseValue.ok", {
|
|
20452
20456
|
type: type.response.ok
|
|
20453
20457
|
});
|
|
20454
|
-
const errConversion = generateClarityConversion(
|
|
20458
|
+
const errConversion = generateClarityConversion("responseValue.err", {
|
|
20455
20459
|
type: type.response.error
|
|
20456
20460
|
});
|
|
20457
20461
|
return `(() => {
|
|
@@ -20890,12 +20894,12 @@ var init_contract = __esm(() => {
|
|
|
20890
20894
|
});
|
|
20891
20895
|
|
|
20892
20896
|
// src/utils/config.ts
|
|
20893
|
-
import { randomBytes } from "crypto";
|
|
20894
|
-
import { promises as fs4 } from "fs";
|
|
20895
|
-
import { createRequire as createRequire2 } from "module";
|
|
20896
|
-
import { tmpdir } from "os";
|
|
20897
|
-
import path2 from "path";
|
|
20898
|
-
import { pathToFileURL } from "url";
|
|
20897
|
+
import { randomBytes } from "node:crypto";
|
|
20898
|
+
import { promises as fs4 } from "node:fs";
|
|
20899
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
20900
|
+
import { tmpdir } from "node:os";
|
|
20901
|
+
import path2 from "node:path";
|
|
20902
|
+
import { pathToFileURL } from "node:url";
|
|
20899
20903
|
async function findConfigFile(cwd) {
|
|
20900
20904
|
for (const fileName of CONFIG_FILE_NAMES) {
|
|
20901
20905
|
const filePath = path2.join(cwd, fileName);
|
|
@@ -32053,8 +32057,8 @@ var init_execa = __esm(() => {
|
|
|
32053
32057
|
});
|
|
32054
32058
|
|
|
32055
32059
|
// src/utils/dependencies.ts
|
|
32056
|
-
import { promises as fs6 } from "fs";
|
|
32057
|
-
import path9 from "path";
|
|
32060
|
+
import { promises as fs6 } from "node:fs";
|
|
32061
|
+
import path9 from "node:path";
|
|
32058
32062
|
async function getPackageManager(targetDir) {
|
|
32059
32063
|
const packageManager = await detect2({ programmatic: true, cwd: targetDir });
|
|
32060
32064
|
if (packageManager === "yarn@berry")
|
|
@@ -32131,7 +32135,7 @@ __export(exports_generate, {
|
|
|
32131
32135
|
resolveContract: () => resolveContract,
|
|
32132
32136
|
generate: () => generate
|
|
32133
32137
|
});
|
|
32134
|
-
import path10 from "path";
|
|
32138
|
+
import path10 from "node:path";
|
|
32135
32139
|
import { getErrorMessage as getErrorMessage2 } from "@secondlayer/shared";
|
|
32136
32140
|
import { toCamelCase as toCamelCase8 } from "@secondlayer/stacks/clarity";
|
|
32137
32141
|
function isContractAddress(input6) {
|
|
@@ -32174,8 +32178,8 @@ async function buildConfigFromInputs(parsedInputs, outPath, apiKey, defaultAddre
|
|
|
32174
32178
|
const deployer = defaultAddress || DEFAULT_DEVNET_ADDRESS;
|
|
32175
32179
|
if (parsedInputs.files.length > 0 && !defaultAddress) {
|
|
32176
32180
|
console.warn(source_default3.yellow(`⚠️ Using placeholder address (${deployer}) for local contracts.
|
|
32177
|
-
|
|
32178
|
-
|
|
32181
|
+
Generated contract addresses won't match deployed addresses.
|
|
32182
|
+
Set defaultAddress in config or use deployed contract addresses.`));
|
|
32179
32183
|
}
|
|
32180
32184
|
for (const file of parsedInputs.files) {
|
|
32181
32185
|
const abi = await parseClarityFile(file);
|
|
@@ -32376,8 +32380,8 @@ var exports_init = {};
|
|
|
32376
32380
|
__export(exports_init, {
|
|
32377
32381
|
init: () => init2
|
|
32378
32382
|
});
|
|
32379
|
-
import { promises as fs7 } from "fs";
|
|
32380
|
-
import path11 from "path";
|
|
32383
|
+
import { promises as fs7 } from "node:fs";
|
|
32384
|
+
import path11 from "node:path";
|
|
32381
32385
|
async function init2() {
|
|
32382
32386
|
const configPath = path11.join(process.cwd(), "secondlayer.config.ts");
|
|
32383
32387
|
try {
|
|
@@ -32439,7 +32443,7 @@ var {
|
|
|
32439
32443
|
// package.json
|
|
32440
32444
|
var package_default = {
|
|
32441
32445
|
name: "@secondlayer/cli",
|
|
32442
|
-
version: "
|
|
32446
|
+
version: "4.0.1",
|
|
32443
32447
|
description: "CLI for subgraphs and blockchain indexing on Stacks",
|
|
32444
32448
|
type: "module",
|
|
32445
32449
|
bin: {
|
|
@@ -32481,11 +32485,11 @@ var package_default = {
|
|
|
32481
32485
|
license: "MIT",
|
|
32482
32486
|
dependencies: {
|
|
32483
32487
|
"@inquirer/prompts": "^8.2.0",
|
|
32484
|
-
"@secondlayer/bundler": "^0.3.
|
|
32485
|
-
"@secondlayer/sdk": "^3.3.
|
|
32486
|
-
"@secondlayer/shared": "^
|
|
32487
|
-
"@secondlayer/stacks": "^2.0.
|
|
32488
|
-
"@secondlayer/subgraphs": "^1.3.
|
|
32488
|
+
"@secondlayer/bundler": "^0.3.4",
|
|
32489
|
+
"@secondlayer/sdk": "^3.3.1",
|
|
32490
|
+
"@secondlayer/shared": "^5.2.0",
|
|
32491
|
+
"@secondlayer/stacks": "^2.0.1",
|
|
32492
|
+
"@secondlayer/subgraphs": "^1.3.3",
|
|
32489
32493
|
"@biomejs/js-api": "^0.7.0",
|
|
32490
32494
|
"@biomejs/wasm-nodejs": "^1.9.0",
|
|
32491
32495
|
esbuild: "^0.19.0",
|
|
@@ -32730,7 +32734,7 @@ async function findDockerComposeRoot(startPath) {
|
|
|
32730
32734
|
function getParentPath(path2) {
|
|
32731
32735
|
const parts = path2.split("/").filter(Boolean);
|
|
32732
32736
|
parts.pop();
|
|
32733
|
-
return
|
|
32737
|
+
return `/${parts.join("/")}`;
|
|
32734
32738
|
}
|
|
32735
32739
|
function detectNetworkFromContainer(container) {
|
|
32736
32740
|
const config = container.Config;
|
|
@@ -32746,7 +32750,7 @@ function detectNetworkFromContainer(container) {
|
|
|
32746
32750
|
}
|
|
32747
32751
|
}
|
|
32748
32752
|
if (config?.Labels) {
|
|
32749
|
-
const networkLabel = config.Labels
|
|
32753
|
+
const networkLabel = config.Labels.network || config.Labels["stacks.network"];
|
|
32750
32754
|
if (networkLabel === "testnet") {
|
|
32751
32755
|
return "testnet";
|
|
32752
32756
|
}
|
|
@@ -33352,7 +33356,7 @@ function printStatus(status) {
|
|
|
33352
33356
|
const filled = Math.round(pct / 100 * barWidth);
|
|
33353
33357
|
const empty = barWidth - filled;
|
|
33354
33358
|
const bar = `${"█".repeat(filled)}${"░".repeat(empty)}`;
|
|
33355
|
-
const pctStr = pct.toFixed(1)
|
|
33359
|
+
const pctStr = `${pct.toFixed(1)}%`;
|
|
33356
33360
|
const color = pct >= 99.9 ? green : pct >= 50 ? yellow : red;
|
|
33357
33361
|
console.log(` ${dim("chain:")} ${color(bar)} ${color(pctStr)} ${dim(`(tip: ${status.chainTip.toLocaleString()})`)}`);
|
|
33358
33362
|
}
|
|
@@ -34070,7 +34074,7 @@ async function showBlocks(limit, json) {
|
|
|
34070
34074
|
for (const row of rows) {
|
|
34071
34075
|
const time = new Date(row.timestamp * 1000).toLocaleTimeString();
|
|
34072
34076
|
const canonicalMark = row.canonical ? "" : yellow(" (reorg)");
|
|
34073
|
-
console.log(` ${row.height.toString().padEnd(10)}
|
|
34077
|
+
console.log(` ${row.height.toString().padEnd(10)}${`${row.hash.slice(0, 20)}... `.padEnd(24)}${time}${canonicalMark}`);
|
|
34074
34078
|
}
|
|
34075
34079
|
console.log("");
|
|
34076
34080
|
process.exit(0);
|
|
@@ -34102,7 +34106,7 @@ async function showTransactions(limit, json) {
|
|
|
34102
34106
|
for (const row of rows) {
|
|
34103
34107
|
const statusColor = row.status === "success" ? green : yellow;
|
|
34104
34108
|
const contractInfo = row.contract_id ? `${row.contract_id.split(".")[1] || row.contract_id}${row.function_name ? `::${row.function_name}` : ""}` : "-";
|
|
34105
|
-
console.log(` ${statusColor(row.block_height.toString().padEnd(8))}
|
|
34109
|
+
console.log(` ${statusColor(row.block_height.toString().padEnd(8))}${row.type.padEnd(18)}${`${row.sender.slice(0, 18)}... `.padEnd(20)}${contractInfo}`);
|
|
34106
34110
|
}
|
|
34107
34111
|
console.log("");
|
|
34108
34112
|
process.exit(0);
|
|
@@ -34271,7 +34275,7 @@ async function resyncDatabase(skipConfirm, backfill) {
|
|
|
34271
34275
|
const nodeInfo = await nodeClient.getInfo();
|
|
34272
34276
|
const tip = nodeInfo.stacks_tip_height;
|
|
34273
34277
|
info(`Node tip: block ${tip}. Fetching blocks 1 to ${tip}...`);
|
|
34274
|
-
console.log(dim(
|
|
34278
|
+
console.log(dim(`This may take a while. Run 'sl sync --from 1 --to ${tip}' if interrupted.`));
|
|
34275
34279
|
console.log("");
|
|
34276
34280
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), exports_config));
|
|
34277
34281
|
const config = await loadConfig2();
|
|
@@ -34465,7 +34469,7 @@ init_format();
|
|
|
34465
34469
|
async function generateSubgraphConsumer(subgraphName, detail) {
|
|
34466
34470
|
const tables = Object.entries(detail.tables);
|
|
34467
34471
|
const rowInterfaces = tables.map(([tableName, tableDef]) => {
|
|
34468
|
-
const typeName = toPascalCase(tableName)
|
|
34472
|
+
const typeName = `${toPascalCase(tableName)}Row`;
|
|
34469
34473
|
const fields = Object.entries(tableDef.columns).map(([colName, colMeta]) => {
|
|
34470
34474
|
const tsType = subgraphTypeToTS(colMeta.type);
|
|
34471
34475
|
const optional = colMeta.nullable ? "?" : "";
|
|
@@ -35463,7 +35467,7 @@ async function stackStart(options2) {
|
|
|
35463
35467
|
const args = [
|
|
35464
35468
|
"bun",
|
|
35465
35469
|
"run",
|
|
35466
|
-
import.meta.dir
|
|
35470
|
+
`${import.meta.dir}/../../bin/secondlayer.ts`,
|
|
35467
35471
|
"dev",
|
|
35468
35472
|
"start"
|
|
35469
35473
|
];
|
|
@@ -35493,7 +35497,7 @@ async function stackStop(options2) {
|
|
|
35493
35497
|
const proc = Bun.spawn([
|
|
35494
35498
|
"bun",
|
|
35495
35499
|
"run",
|
|
35496
|
-
import.meta.dir
|
|
35500
|
+
`${import.meta.dir}/../../bin/secondlayer.ts`,
|
|
35497
35501
|
"dev",
|
|
35498
35502
|
"stop"
|
|
35499
35503
|
], { stdin: "inherit", stdout: "inherit", stderr: "inherit" });
|
|
@@ -35853,7 +35857,7 @@ async function runLocalDoctor(jsonOutput) {
|
|
|
35853
35857
|
const lines = result.stdout.toString().trim().split(`
|
|
35854
35858
|
`);
|
|
35855
35859
|
if (lines.length >= 2) {
|
|
35856
|
-
const parts = lines[1]
|
|
35860
|
+
const parts = lines[1]?.split(/\s+/);
|
|
35857
35861
|
const used = parts[2];
|
|
35858
35862
|
const avail = parts[3];
|
|
35859
35863
|
const pct = parts[4];
|
|
@@ -36147,13 +36151,16 @@ function formatLogLine3(service, line) {
|
|
|
36147
36151
|
const [, timestamp, level, message] = match;
|
|
36148
36152
|
const dimTimestamp = dim(timestamp);
|
|
36149
36153
|
if (level === "ERROR") {
|
|
36150
|
-
return `${prefix} ${dimTimestamp} ${red(level
|
|
36151
|
-
}
|
|
36152
|
-
|
|
36153
|
-
|
|
36154
|
-
|
|
36155
|
-
|
|
36156
|
-
return `${prefix} ${dimTimestamp} ${
|
|
36154
|
+
return `${prefix} ${dimTimestamp} ${red(`${level}:`)} ${message}`;
|
|
36155
|
+
}
|
|
36156
|
+
if (level === "WARN") {
|
|
36157
|
+
return `${prefix} ${dimTimestamp} ${yellow(`${level}:`)} ${message}`;
|
|
36158
|
+
}
|
|
36159
|
+
if (level === "INFO") {
|
|
36160
|
+
return `${prefix} ${dimTimestamp} ${green(`${level}:`)} ${message}`;
|
|
36161
|
+
}
|
|
36162
|
+
if (level === "DEBUG") {
|
|
36163
|
+
return `${prefix} ${dimTimestamp} ${dim(`${level}:`)} ${dim(message)}`;
|
|
36157
36164
|
}
|
|
36158
36165
|
}
|
|
36159
36166
|
return `${prefix} ${line}`;
|
|
@@ -36295,12 +36302,12 @@ import { confirm as confirm5, input as input4, select as select4 } from "@inquir
|
|
|
36295
36302
|
var INSTANCE_CREATE_TIMEOUT_MS = 180000;
|
|
36296
36303
|
function registerInstanceCommand(program2) {
|
|
36297
36304
|
const instance = program2.command("instance").description("Manage your dedicated Secondlayer instance");
|
|
36298
|
-
instance.command("create").description("Provision a new dedicated instance for the active project").option("--plan <plan>", "Plan: hobby (free) | launch |
|
|
36305
|
+
instance.command("create").description("Provision a new dedicated instance for the active project").option("--plan <plan>", "Plan: hobby (free) | launch | scale", "hobby").action(async (opts) => {
|
|
36299
36306
|
guardOssMode();
|
|
36300
36307
|
const activeSlug = await requireActiveProject();
|
|
36301
36308
|
const plan = opts.plan;
|
|
36302
|
-
if (!["hobby", "launch", "
|
|
36303
|
-
error(`Invalid plan: ${plan} (expected hobby, launch,
|
|
36309
|
+
if (!["hobby", "launch", "scale"].includes(plan)) {
|
|
36310
|
+
error(`Invalid plan: ${plan} (expected hobby, launch, or scale)`);
|
|
36304
36311
|
process.exit(1);
|
|
36305
36312
|
}
|
|
36306
36313
|
const spinner = createSpinner("Provisioning your instance (~60s; safe to interrupt — instance will still be created; check `sl instance info`)");
|
|
@@ -36326,7 +36333,7 @@ function registerInstanceCommand(program2) {
|
|
|
36326
36333
|
guardOssMode();
|
|
36327
36334
|
await renderInstanceInfo();
|
|
36328
36335
|
});
|
|
36329
|
-
instance.command("resize").description("Change your instance plan (brief downtime)").option("--plan <plan>", "Target plan: hobby | launch |
|
|
36336
|
+
instance.command("resize").description("Change your instance plan (brief downtime)").option("--plan <plan>", "Target plan: hobby | launch | scale").option("--yes", "Skip confirm").action(async (opts) => {
|
|
36330
36337
|
guardOssMode();
|
|
36331
36338
|
let target = opts.plan;
|
|
36332
36339
|
if (!target) {
|
|
@@ -36335,16 +36342,15 @@ function registerInstanceCommand(program2) {
|
|
|
36335
36342
|
choices: [
|
|
36336
36343
|
{
|
|
36337
36344
|
value: "hobby",
|
|
36338
|
-
name: "Hobby — free (0.5 vCPU ·
|
|
36345
|
+
name: "Hobby — free (0.5 vCPU · 1 GB · 10 GB, auto-pause after 7d idle)"
|
|
36339
36346
|
},
|
|
36340
36347
|
{
|
|
36341
36348
|
value: "launch",
|
|
36342
|
-
name: "Launch — $99/mo (
|
|
36349
|
+
name: "Launch — $99/mo (2 vCPU · 6 GB · 100 GB)"
|
|
36343
36350
|
},
|
|
36344
|
-
{ value: "grow", name: "Grow — $249/mo (2 vCPU · 4 GB · 50 GB)" },
|
|
36345
36351
|
{
|
|
36346
36352
|
value: "scale",
|
|
36347
|
-
name: "Scale — $
|
|
36353
|
+
name: "Scale — $299/mo (8 vCPU · 24 GB · 500 GB)"
|
|
36348
36354
|
}
|
|
36349
36355
|
]
|
|
36350
36356
|
});
|
|
@@ -36797,5 +36803,5 @@ registerLocalCommand(program);
|
|
|
36797
36803
|
registerAccountCommand(program);
|
|
36798
36804
|
program.parse();
|
|
36799
36805
|
|
|
36800
|
-
//# debugId=
|
|
36806
|
+
//# debugId=89A6DFBE4B8EE7D064756E2164756E21
|
|
36801
36807
|
//# sourceMappingURL=cli.js.map
|