@secondlayer/cli 1.4.1 → 1.5.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/dist/cli.js +172 -164
- package/dist/cli.js.map +14 -13
- package/dist/index.d.ts +6 -1
- package/dist/index.js +81 -104
- package/dist/index.js.map +8 -7
- package/dist/plugin-manager.d.ts +6 -1
- package/dist/plugin-manager.js +29 -52
- package/dist/plugin-manager.js.map +4 -4
- package/package.json +5 -5
package/dist/cli.js
CHANGED
|
@@ -2202,8 +2202,8 @@ function migrateConfig(raw) {
|
|
|
2202
2202
|
if (typeof old.apiKey === "string") {
|
|
2203
2203
|
migrated.apiKey = old.apiKey;
|
|
2204
2204
|
}
|
|
2205
|
-
if (typeof old.sessionToken === "string") {
|
|
2206
|
-
|
|
2205
|
+
if (typeof old.sessionToken === "string" && !migrated.apiKey) {
|
|
2206
|
+
console.warn("Warning: config contains sessionToken but no apiKey. Run `sl auth login` to re-authenticate.");
|
|
2207
2207
|
}
|
|
2208
2208
|
if (typeof old.apiUrl === "string" && old.apiUrl !== "http://localhost:3800") {
|
|
2209
2209
|
migrated.apiUrl = old.apiUrl;
|
|
@@ -2268,9 +2268,6 @@ function applyEnvOverrides(config) {
|
|
|
2268
2268
|
if (process.env.SECONDLAYER_API_KEY) {
|
|
2269
2269
|
result.apiKey = process.env.SECONDLAYER_API_KEY;
|
|
2270
2270
|
}
|
|
2271
|
-
if (process.env.SECONDLAYER_SESSION_TOKEN) {
|
|
2272
|
-
result.sessionToken = process.env.SECONDLAYER_SESSION_TOKEN;
|
|
2273
|
-
}
|
|
2274
2271
|
if (process.env.SL_DATA_DIR) {
|
|
2275
2272
|
result.dataDir = process.env.SL_DATA_DIR;
|
|
2276
2273
|
}
|
|
@@ -2406,7 +2403,6 @@ var init_config = __esm(() => {
|
|
|
2406
2403
|
network: NetworkSchema.default("mainnet"),
|
|
2407
2404
|
apiUrl: z.string().url().optional(),
|
|
2408
2405
|
apiKey: z.string().optional(),
|
|
2409
|
-
sessionToken: z.string().optional(),
|
|
2410
2406
|
dataDir: z.string().default("~/.secondlayer/data"),
|
|
2411
2407
|
defaultWebhookUrl: z.string().url().optional(),
|
|
2412
2408
|
node: NodeSchema.optional(),
|
|
@@ -4550,10 +4546,25 @@ __export(exports_api_client, {
|
|
|
4550
4546
|
deleteStream: () => deleteStream,
|
|
4551
4547
|
createStream: () => createStream,
|
|
4552
4548
|
authHeaders: () => authHeaders,
|
|
4549
|
+
assertOk: () => assertOk,
|
|
4553
4550
|
ApiError: () => ApiError
|
|
4554
4551
|
});
|
|
4555
4552
|
import { SecondLayer } from "@secondlayer/sdk";
|
|
4556
4553
|
import { ApiError } from "@secondlayer/sdk";
|
|
4554
|
+
async function assertOk(res) {
|
|
4555
|
+
if (res.ok)
|
|
4556
|
+
return;
|
|
4557
|
+
const body = await res.text();
|
|
4558
|
+
try {
|
|
4559
|
+
const parsed = JSON.parse(body);
|
|
4560
|
+
if (typeof parsed.error === "string" && parsed.error)
|
|
4561
|
+
throw new Error(parsed.error);
|
|
4562
|
+
} catch (e) {
|
|
4563
|
+
if (e instanceof Error && e.message !== body)
|
|
4564
|
+
throw e;
|
|
4565
|
+
}
|
|
4566
|
+
throw new Error(`HTTP ${res.status}`);
|
|
4567
|
+
}
|
|
4557
4568
|
function handleApiError(err, action) {
|
|
4558
4569
|
if (err instanceof ApiError && err.status === 401) {
|
|
4559
4570
|
console.error("Error: Authentication required. Run: sl auth login");
|
|
@@ -4565,10 +4576,10 @@ function handleApiError(err, action) {
|
|
|
4565
4576
|
async function getClient() {
|
|
4566
4577
|
const config = await loadConfig();
|
|
4567
4578
|
const baseUrl = resolveApiUrl(config);
|
|
4568
|
-
return new SecondLayer({ baseUrl, apiKey: config.
|
|
4579
|
+
return new SecondLayer({ baseUrl, apiKey: config.apiKey });
|
|
4569
4580
|
}
|
|
4570
4581
|
function authHeaders(config) {
|
|
4571
|
-
return SecondLayer.authHeaders(config.
|
|
4582
|
+
return SecondLayer.authHeaders(config.apiKey);
|
|
4572
4583
|
}
|
|
4573
4584
|
async function createStream(data) {
|
|
4574
4585
|
return (await getClient()).streams.create(data);
|
|
@@ -20157,6 +20168,8 @@ function isDirectFileContract(c) {
|
|
|
20157
20168
|
import { promises as fs3 } from "fs";
|
|
20158
20169
|
import path from "path";
|
|
20159
20170
|
import { isValidAddress as _validateStacksAddress } from "@secondlayer/stacks";
|
|
20171
|
+
import { getErrorMessage } from "@secondlayer/shared";
|
|
20172
|
+
import { toCamelCase as toCamelCase2 } from "@secondlayer/stacks/clarity";
|
|
20160
20173
|
|
|
20161
20174
|
class PluginManager {
|
|
20162
20175
|
plugins = [];
|
|
@@ -20199,12 +20212,11 @@ class PluginManager {
|
|
|
20199
20212
|
success: true
|
|
20200
20213
|
});
|
|
20201
20214
|
} catch (error2) {
|
|
20202
|
-
const err = error2;
|
|
20203
20215
|
this.recordHookResult(plugin.name, "transformConfig", {
|
|
20204
20216
|
success: false,
|
|
20205
|
-
error:
|
|
20217
|
+
error: error2 instanceof Error ? error2 : new Error(getErrorMessage(error2))
|
|
20206
20218
|
});
|
|
20207
|
-
throw new Error(`Plugin "${plugin.name}" failed during config transformation: ${
|
|
20219
|
+
throw new Error(`Plugin "${plugin.name}" failed during config transformation: ${getErrorMessage(error2)}`);
|
|
20208
20220
|
}
|
|
20209
20221
|
}
|
|
20210
20222
|
}
|
|
@@ -20218,31 +20230,11 @@ class PluginManager {
|
|
|
20218
20230
|
const processedContracts = [];
|
|
20219
20231
|
for (let contract of contracts) {
|
|
20220
20232
|
if (isClarinetContract(contract) && contract.abi) {
|
|
20221
|
-
|
|
20222
|
-
const parsed = parseContractId(address);
|
|
20223
|
-
const processed = {
|
|
20224
|
-
name: contract.name || parsed.contractName,
|
|
20225
|
-
address: parsed.address,
|
|
20226
|
-
contractName: parsed.contractName,
|
|
20227
|
-
abi: contract.abi,
|
|
20228
|
-
source: "local",
|
|
20229
|
-
metadata: { source: "clarinet" }
|
|
20230
|
-
};
|
|
20231
|
-
processedContracts.push(processed);
|
|
20233
|
+
processedContracts.push(this.contractToProcessed(contract, "clarinet"));
|
|
20232
20234
|
continue;
|
|
20233
20235
|
}
|
|
20234
20236
|
if (isDirectFileContract(contract) && contract.abi) {
|
|
20235
|
-
|
|
20236
|
-
const parsed = parseContractId(address);
|
|
20237
|
-
const processed = {
|
|
20238
|
-
name: contract.name || parsed.contractName,
|
|
20239
|
-
address: parsed.address,
|
|
20240
|
-
contractName: parsed.contractName,
|
|
20241
|
-
abi: contract.abi,
|
|
20242
|
-
source: "local",
|
|
20243
|
-
metadata: { source: "direct" }
|
|
20244
|
-
};
|
|
20245
|
-
processedContracts.push(processed);
|
|
20237
|
+
processedContracts.push(this.contractToProcessed(contract, "direct"));
|
|
20246
20238
|
continue;
|
|
20247
20239
|
}
|
|
20248
20240
|
for (const plugin of this.plugins) {
|
|
@@ -20254,27 +20246,16 @@ class PluginManager {
|
|
|
20254
20246
|
success: true
|
|
20255
20247
|
});
|
|
20256
20248
|
} catch (error2) {
|
|
20257
|
-
const err = error2;
|
|
20258
20249
|
this.recordHookResult(plugin.name, "transformContract", {
|
|
20259
20250
|
success: false,
|
|
20260
|
-
error:
|
|
20251
|
+
error: error2 instanceof Error ? error2 : new Error(getErrorMessage(error2))
|
|
20261
20252
|
});
|
|
20262
|
-
this.logger.warn(`Plugin "${plugin.name}" failed to transform contract: ${
|
|
20253
|
+
this.logger.warn(`Plugin "${plugin.name}" failed to transform contract: ${getErrorMessage(error2)}`);
|
|
20263
20254
|
}
|
|
20264
20255
|
}
|
|
20265
20256
|
}
|
|
20266
20257
|
if (contract.abi) {
|
|
20267
|
-
|
|
20268
|
-
const parsed = parseContractId(addressStr);
|
|
20269
|
-
const processed = {
|
|
20270
|
-
name: contract.name || parsed.contractName || "unknown",
|
|
20271
|
-
address: parsed.address || "unknown",
|
|
20272
|
-
contractName: parsed.contractName || contract.name || "unknown",
|
|
20273
|
-
abi: contract.abi,
|
|
20274
|
-
source: "api",
|
|
20275
|
-
metadata: contract.metadata
|
|
20276
|
-
};
|
|
20277
|
-
processedContracts.push(processed);
|
|
20258
|
+
processedContracts.push(this.contractToProcessed(contract, "api"));
|
|
20278
20259
|
}
|
|
20279
20260
|
}
|
|
20280
20261
|
return processedContracts;
|
|
@@ -20290,12 +20271,11 @@ class PluginManager {
|
|
|
20290
20271
|
success: true
|
|
20291
20272
|
});
|
|
20292
20273
|
} catch (error2) {
|
|
20293
|
-
const err = error2;
|
|
20294
20274
|
this.recordHookResult(plugin.name, hookName, {
|
|
20295
20275
|
success: false,
|
|
20296
|
-
error:
|
|
20276
|
+
error: error2 instanceof Error ? error2 : new Error(getErrorMessage(error2))
|
|
20297
20277
|
});
|
|
20298
|
-
this.logger.error(`Plugin "${plugin.name}" failed during ${hookName}: ${
|
|
20278
|
+
this.logger.error(`Plugin "${plugin.name}" failed during ${hookName}: ${getErrorMessage(error2)}`);
|
|
20299
20279
|
}
|
|
20300
20280
|
}
|
|
20301
20281
|
}
|
|
@@ -20335,12 +20315,11 @@ class PluginManager {
|
|
|
20335
20315
|
success: true
|
|
20336
20316
|
});
|
|
20337
20317
|
} catch (error2) {
|
|
20338
|
-
const err = error2;
|
|
20339
20318
|
this.recordHookResult(plugin.name, "transformOutput", {
|
|
20340
20319
|
success: false,
|
|
20341
|
-
error:
|
|
20320
|
+
error: error2 instanceof Error ? error2 : new Error(getErrorMessage(error2))
|
|
20342
20321
|
});
|
|
20343
|
-
this.logger.warn(`Plugin "${plugin.name}" failed to transform output: ${
|
|
20322
|
+
this.logger.warn(`Plugin "${plugin.name}" failed to transform output: ${getErrorMessage(error2)}`);
|
|
20344
20323
|
}
|
|
20345
20324
|
}
|
|
20346
20325
|
}
|
|
@@ -20358,15 +20337,26 @@ class PluginManager {
|
|
|
20358
20337
|
await this.utils.ensureDir(path.dirname(resolvedPath));
|
|
20359
20338
|
await this.utils.writeFile(resolvedPath, output.content);
|
|
20360
20339
|
} catch (error2) {
|
|
20361
|
-
|
|
20362
|
-
|
|
20363
|
-
throw err;
|
|
20340
|
+
this.logger.error(`Failed to write ${output.path}: ${getErrorMessage(error2)}`);
|
|
20341
|
+
throw error2;
|
|
20364
20342
|
}
|
|
20365
20343
|
}
|
|
20366
20344
|
}
|
|
20367
20345
|
getExecutionResults() {
|
|
20368
20346
|
return new Map(this.executionContext.results);
|
|
20369
20347
|
}
|
|
20348
|
+
contractToProcessed(contract, source) {
|
|
20349
|
+
const address = typeof contract.address === "string" ? contract.address : "";
|
|
20350
|
+
const parsed = parseContractId(address);
|
|
20351
|
+
return {
|
|
20352
|
+
name: contract.name || parsed.contractName || "unknown",
|
|
20353
|
+
address: parsed.address || "unknown",
|
|
20354
|
+
contractName: parsed.contractName || contract.name || "unknown",
|
|
20355
|
+
abi: contract.abi,
|
|
20356
|
+
source: source === "api" ? "api" : "local",
|
|
20357
|
+
metadata: contract.metadata ?? { source }
|
|
20358
|
+
};
|
|
20359
|
+
}
|
|
20370
20360
|
augmentOutput(outputs, outputKey, contractName, content) {
|
|
20371
20361
|
const existing = outputs.get(outputKey);
|
|
20372
20362
|
if (!existing) {
|
|
@@ -20403,9 +20393,7 @@ ${JSON.stringify(content, null, 2)}`;
|
|
|
20403
20393
|
}
|
|
20404
20394
|
createUtils() {
|
|
20405
20395
|
return {
|
|
20406
|
-
toCamelCase:
|
|
20407
|
-
return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
20408
|
-
},
|
|
20396
|
+
toCamelCase: toCamelCase2,
|
|
20409
20397
|
toKebabCase: (str) => {
|
|
20410
20398
|
return str.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
|
|
20411
20399
|
},
|
|
@@ -20554,7 +20542,7 @@ var init_config2 = __esm(() => {
|
|
|
20554
20542
|
|
|
20555
20543
|
// src/utils/type-mapping.ts
|
|
20556
20544
|
import {
|
|
20557
|
-
toCamelCase,
|
|
20545
|
+
toCamelCase as toCamelCase3,
|
|
20558
20546
|
isAbiList,
|
|
20559
20547
|
isAbiTuple,
|
|
20560
20548
|
isAbiOptional as isAbiOptional2,
|
|
@@ -20613,7 +20601,7 @@ function clarityTypeToTS(type) {
|
|
|
20613
20601
|
return `${innerType}[]`;
|
|
20614
20602
|
}
|
|
20615
20603
|
if (isAbiTuple(type)) {
|
|
20616
|
-
const fields = type.tuple.map((field) => `${
|
|
20604
|
+
const fields = type.tuple.map((field) => `${toCamelCase3(field.name)}: ${clarityTypeToTS(field.type)}`).join("; ");
|
|
20617
20605
|
return `{ ${fields} }`;
|
|
20618
20606
|
}
|
|
20619
20607
|
if (isAbiResponse(type)) {
|
|
@@ -20630,7 +20618,7 @@ var init_type_mapping = () => {};
|
|
|
20630
20618
|
|
|
20631
20619
|
// src/utils/clarity-conversion.ts
|
|
20632
20620
|
import {
|
|
20633
|
-
toCamelCase as
|
|
20621
|
+
toCamelCase as toCamelCase4,
|
|
20634
20622
|
isAbiStringAscii as isAbiStringAscii3,
|
|
20635
20623
|
isAbiStringUtf8 as isAbiStringUtf83,
|
|
20636
20624
|
isAbiBuffer as isAbiBuffer3,
|
|
@@ -20728,7 +20716,7 @@ function generateClarityConversion(argName, argType) {
|
|
|
20728
20716
|
const requiredFields = type.tuple.map((f) => f.name);
|
|
20729
20717
|
const fieldNames = JSON.stringify(requiredFields);
|
|
20730
20718
|
const fields = type.tuple.map((field) => {
|
|
20731
|
-
const camelFieldName =
|
|
20719
|
+
const camelFieldName = toCamelCase4(field.name);
|
|
20732
20720
|
const fieldConversion = generateClarityConversion(`tupleValue.${camelFieldName}`, { type: field.type });
|
|
20733
20721
|
return `"${field.name}": ${fieldConversion}`;
|
|
20734
20722
|
}).join(", ");
|
|
@@ -20769,11 +20757,11 @@ function generateClarityConversion(argName, argType) {
|
|
|
20769
20757
|
var init_clarity_conversion = () => {};
|
|
20770
20758
|
|
|
20771
20759
|
// src/utils/generator-helpers.ts
|
|
20772
|
-
import { toCamelCase as
|
|
20760
|
+
import { toCamelCase as toCamelCase5, isAbiTuple as isAbiTuple3 } from "@secondlayer/stacks/clarity";
|
|
20773
20761
|
function generateMapKeyConversion(keyType) {
|
|
20774
20762
|
if (isAbiTuple3(keyType)) {
|
|
20775
20763
|
const fields = keyType.tuple.map((field) => {
|
|
20776
|
-
const camelFieldName =
|
|
20764
|
+
const camelFieldName = toCamelCase5(field.name);
|
|
20777
20765
|
const fieldConversion = generateClarityConversion(`key.${camelFieldName}`, { type: field.type });
|
|
20778
20766
|
return `"${field.name}": ${fieldConversion}`;
|
|
20779
20767
|
}).join(", ");
|
|
@@ -20788,7 +20776,7 @@ var init_generator_helpers = __esm(() => {
|
|
|
20788
20776
|
|
|
20789
20777
|
// src/generators/contract.ts
|
|
20790
20778
|
import {
|
|
20791
|
-
toCamelCase as
|
|
20779
|
+
toCamelCase as toCamelCase6
|
|
20792
20780
|
} from "@secondlayer/stacks/clarity";
|
|
20793
20781
|
function generateNetworkUtils() {
|
|
20794
20782
|
return `/**
|
|
@@ -20880,7 +20868,7 @@ function generateAbiConstant(name, abi) {
|
|
|
20880
20868
|
return `export const ${name}Abi = ${abiJson} as const`;
|
|
20881
20869
|
}
|
|
20882
20870
|
function generateMethod(func, address, contractName) {
|
|
20883
|
-
const methodName =
|
|
20871
|
+
const methodName = toCamelCase6(func.name);
|
|
20884
20872
|
if (func.args.length === 0) {
|
|
20885
20873
|
return `${methodName}() {
|
|
20886
20874
|
return {
|
|
@@ -20893,7 +20881,7 @@ function generateMethod(func, address, contractName) {
|
|
|
20893
20881
|
}
|
|
20894
20882
|
if (func.args.length === 1) {
|
|
20895
20883
|
const originalArgName = func.args[0].name;
|
|
20896
|
-
const argName =
|
|
20884
|
+
const argName = toCamelCase6(originalArgName);
|
|
20897
20885
|
const argType = getTypeForArg(func.args[0]);
|
|
20898
20886
|
const clarityConversion = generateClarityConversion(argName, func.args[0]);
|
|
20899
20887
|
return `${methodName}(...args: [{ ${argName}: ${argType} }] | [${argType}]) {
|
|
@@ -20909,17 +20897,17 @@ function generateMethod(func, address, contractName) {
|
|
|
20909
20897
|
}
|
|
20910
20898
|
}`;
|
|
20911
20899
|
}
|
|
20912
|
-
const argsList = func.args.map((arg) =>
|
|
20900
|
+
const argsList = func.args.map((arg) => toCamelCase6(arg.name)).join(", ");
|
|
20913
20901
|
const argsTypes = func.args.map((arg) => {
|
|
20914
|
-
const camelName =
|
|
20902
|
+
const camelName = toCamelCase6(arg.name);
|
|
20915
20903
|
return `${camelName}: ${getTypeForArg(arg)}`;
|
|
20916
20904
|
}).join("; ");
|
|
20917
20905
|
const argsArray = func.args.map((arg) => {
|
|
20918
|
-
const argName =
|
|
20906
|
+
const argName = toCamelCase6(arg.name);
|
|
20919
20907
|
return generateClarityConversion(argName, arg);
|
|
20920
20908
|
}).join(", ");
|
|
20921
20909
|
const objectAccess = func.args.map((arg) => {
|
|
20922
|
-
const camelName =
|
|
20910
|
+
const camelName = toCamelCase6(arg.name);
|
|
20923
20911
|
return `args[0].${camelName}`;
|
|
20924
20912
|
}).join(", ");
|
|
20925
20913
|
const positionTypes = func.args.map((arg) => getTypeForArg(arg)).join(", ");
|
|
@@ -20941,7 +20929,7 @@ function generateMapsObject(maps, address, contractName) {
|
|
|
20941
20929
|
return "";
|
|
20942
20930
|
}
|
|
20943
20931
|
const mapMethods = maps.map((map) => {
|
|
20944
|
-
const methodName =
|
|
20932
|
+
const methodName = toCamelCase6(map.name);
|
|
20945
20933
|
const keyType = getTypeForArg({ type: map.key });
|
|
20946
20934
|
const valueType = getTypeForArg({ type: map.value });
|
|
20947
20935
|
const keyConversion = generateMapKeyConversion(map.key);
|
|
@@ -21002,7 +20990,7 @@ function generateVarsObject(variables, address, contractName) {
|
|
|
21002
20990
|
return "";
|
|
21003
20991
|
}
|
|
21004
20992
|
const varMethods = dataVars.map((variable) => {
|
|
21005
|
-
const methodName =
|
|
20993
|
+
const methodName = toCamelCase6(variable.name);
|
|
21006
20994
|
const valueType = getTypeForArg({ type: variable.type });
|
|
21007
20995
|
return `${methodName}: {
|
|
21008
20996
|
async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
|
|
@@ -21047,7 +21035,7 @@ function generateConstantsObject(variables, address, contractName) {
|
|
|
21047
21035
|
return "";
|
|
21048
21036
|
}
|
|
21049
21037
|
const constMethods = constants.map((constant) => {
|
|
21050
|
-
const methodName =
|
|
21038
|
+
const methodName = toCamelCase6(constant.name);
|
|
21051
21039
|
const valueType = getTypeForArg({ type: constant.type });
|
|
21052
21040
|
return `${methodName}: {
|
|
21053
21041
|
async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
|
|
@@ -32648,7 +32636,8 @@ __export(exports_generate, {
|
|
|
32648
32636
|
generate: () => generate
|
|
32649
32637
|
});
|
|
32650
32638
|
import path11 from "path";
|
|
32651
|
-
import { toCamelCase as
|
|
32639
|
+
import { toCamelCase as toCamelCase7 } from "@secondlayer/stacks/clarity";
|
|
32640
|
+
import { getErrorMessage as getErrorMessage2 } from "@secondlayer/shared";
|
|
32652
32641
|
function isContractAddress(input4) {
|
|
32653
32642
|
const contractIdPattern = /^(SP|ST|SM|SN)[A-Z0-9]{38,}\.[a-zA-Z][a-zA-Z0-9-]*$/;
|
|
32654
32643
|
return contractIdPattern.test(input4);
|
|
@@ -32709,7 +32698,7 @@ async function buildConfigFromInputs(parsedInputs, outPath, apiKey, defaultAddre
|
|
|
32709
32698
|
const apiClient = new StacksApiClient(network, apiKey);
|
|
32710
32699
|
const contractInfo = await apiClient.getContractInfo(contractId);
|
|
32711
32700
|
const abi = parseApiResponse(contractInfo);
|
|
32712
|
-
const name =
|
|
32701
|
+
const name = toCamelCase7(contractName);
|
|
32713
32702
|
contracts.push({
|
|
32714
32703
|
name,
|
|
32715
32704
|
address: contractId,
|
|
@@ -32717,7 +32706,7 @@ async function buildConfigFromInputs(parsedInputs, outPath, apiKey, defaultAddre
|
|
|
32717
32706
|
_directFile: true
|
|
32718
32707
|
});
|
|
32719
32708
|
} catch (error2) {
|
|
32720
|
-
throw new Error(`Failed to fetch contract ${contractId}: ${error2
|
|
32709
|
+
throw new Error(`Failed to fetch contract ${contractId}: ${getErrorMessage2(error2)}`);
|
|
32721
32710
|
}
|
|
32722
32711
|
}
|
|
32723
32712
|
return {
|
|
@@ -32799,8 +32788,8 @@ To get started:`);
|
|
|
32799
32788
|
} catch (error2) {
|
|
32800
32789
|
console.error(source_default3.red("✗ Generation failed"));
|
|
32801
32790
|
console.error(source_default3.red(`
|
|
32802
|
-
${error2
|
|
32803
|
-
if (process.env.DEBUG) {
|
|
32791
|
+
${getErrorMessage2(error2)}`));
|
|
32792
|
+
if (process.env.DEBUG && error2 instanceof Error) {
|
|
32804
32793
|
console.error(error2.stack);
|
|
32805
32794
|
}
|
|
32806
32795
|
process.exit(1);
|
|
@@ -32867,7 +32856,7 @@ async function resolveContracts(source, defaultNetwork, apiKey, apiUrl) {
|
|
|
32867
32856
|
source: "api"
|
|
32868
32857
|
});
|
|
32869
32858
|
} catch (error2) {
|
|
32870
|
-
console.warn(`Warning: Failed to resolve contract for ${network}: ${error2
|
|
32859
|
+
console.warn(`Warning: Failed to resolve contract for ${network}: ${getErrorMessage2(error2)}`);
|
|
32871
32860
|
}
|
|
32872
32861
|
}
|
|
32873
32862
|
return resolvedContracts;
|
|
@@ -32954,7 +32943,7 @@ var {
|
|
|
32954
32943
|
// package.json
|
|
32955
32944
|
var package_default = {
|
|
32956
32945
|
name: "@secondlayer/cli",
|
|
32957
|
-
version: "1.
|
|
32946
|
+
version: "1.5.1",
|
|
32958
32947
|
description: "CLI for streams, views, and real-time blockchain indexing on Stacks",
|
|
32959
32948
|
type: "module",
|
|
32960
32949
|
bin: {
|
|
@@ -32995,10 +32984,10 @@ var package_default = {
|
|
|
32995
32984
|
license: "MIT",
|
|
32996
32985
|
dependencies: {
|
|
32997
32986
|
"@inquirer/prompts": "^8.2.0",
|
|
32998
|
-
"@secondlayer/sdk": "^0.
|
|
32999
|
-
"@secondlayer/shared": "^0.
|
|
33000
|
-
"@secondlayer/stacks": "^0.
|
|
33001
|
-
"@secondlayer/views": "^0.
|
|
32987
|
+
"@secondlayer/sdk": "^0.5.0",
|
|
32988
|
+
"@secondlayer/shared": "^0.4.0",
|
|
32989
|
+
"@secondlayer/stacks": "^0.2.0",
|
|
32990
|
+
"@secondlayer/views": "^0.3.0",
|
|
33002
32991
|
"@biomejs/js-api": "^0.7.0",
|
|
33003
32992
|
"@biomejs/wasm-nodejs": "^1.9.0",
|
|
33004
32993
|
esbuild: "^0.19.0",
|
|
@@ -33387,6 +33376,7 @@ async function validateDatabaseConnection(url) {
|
|
|
33387
33376
|
}
|
|
33388
33377
|
// src/commands/setup.ts
|
|
33389
33378
|
init_output();
|
|
33379
|
+
init_api_client();
|
|
33390
33380
|
import { select as select2, input, confirm } from "@inquirer/prompts";
|
|
33391
33381
|
init_config();
|
|
33392
33382
|
var STREAMS_DIR = "streams";
|
|
@@ -33639,13 +33629,10 @@ async function hostedLogin(config) {
|
|
|
33639
33629
|
headers: { "Content-Type": "application/json" },
|
|
33640
33630
|
body: JSON.stringify({ email })
|
|
33641
33631
|
});
|
|
33642
|
-
|
|
33643
|
-
|
|
33644
|
-
|
|
33645
|
-
|
|
33646
|
-
msg = JSON.parse(body).error || msg;
|
|
33647
|
-
} catch {}
|
|
33648
|
-
error(`Failed to send magic link: ${msg}`);
|
|
33632
|
+
try {
|
|
33633
|
+
await assertOk(mlRes);
|
|
33634
|
+
} catch (e) {
|
|
33635
|
+
error(`Failed to send magic link: ${e instanceof Error ? e.message : e}`);
|
|
33649
33636
|
return false;
|
|
33650
33637
|
}
|
|
33651
33638
|
info("Check your email for a login token.");
|
|
@@ -33658,18 +33645,41 @@ async function hostedLogin(config) {
|
|
|
33658
33645
|
headers: { "Content-Type": "application/json" },
|
|
33659
33646
|
body: JSON.stringify({ token: token.trim() })
|
|
33660
33647
|
});
|
|
33661
|
-
|
|
33662
|
-
|
|
33663
|
-
|
|
33664
|
-
|
|
33665
|
-
msg = JSON.parse(body).error || msg;
|
|
33666
|
-
} catch {}
|
|
33667
|
-
error(`Verification failed: ${msg}`);
|
|
33648
|
+
try {
|
|
33649
|
+
await assertOk(verifyRes);
|
|
33650
|
+
} catch (e) {
|
|
33651
|
+
error(`Verification failed: ${e instanceof Error ? e.message : e}`);
|
|
33668
33652
|
return false;
|
|
33669
33653
|
}
|
|
33670
33654
|
const result = await verifyRes.json();
|
|
33671
|
-
|
|
33655
|
+
const { hostname } = await import("node:os");
|
|
33656
|
+
const sessionHeaders = { Authorization: `Bearer ${result.sessionToken}`, "Content-Type": "application/json" };
|
|
33657
|
+
const keyName = `cli-${hostname().toLowerCase()}`;
|
|
33658
|
+
const listRes = await fetch(`${apiUrl}/api/keys`, { headers: sessionHeaders });
|
|
33659
|
+
if (listRes.ok) {
|
|
33660
|
+
const { keys } = await listRes.json();
|
|
33661
|
+
const existing = keys.find((k) => k.name === keyName && k.status === "active");
|
|
33662
|
+
if (existing) {
|
|
33663
|
+
await fetch(`${apiUrl}/api/keys/${existing.id}`, { method: "DELETE", headers: sessionHeaders });
|
|
33664
|
+
}
|
|
33665
|
+
}
|
|
33666
|
+
const createRes = await fetch(`${apiUrl}/api/keys`, {
|
|
33667
|
+
method: "POST",
|
|
33668
|
+
headers: sessionHeaders,
|
|
33669
|
+
body: JSON.stringify({ name: keyName })
|
|
33670
|
+
});
|
|
33671
|
+
try {
|
|
33672
|
+
await assertOk(createRes);
|
|
33673
|
+
} catch (e) {
|
|
33674
|
+
error(`Failed to create API key: ${e instanceof Error ? e.message : e}`);
|
|
33675
|
+
return false;
|
|
33676
|
+
}
|
|
33677
|
+
const { key } = await createRes.json();
|
|
33678
|
+
config.apiKey = key;
|
|
33672
33679
|
await saveConfig(config);
|
|
33680
|
+
try {
|
|
33681
|
+
await fetch(`${apiUrl}/api/auth/logout`, { method: "POST", headers: sessionHeaders });
|
|
33682
|
+
} catch {}
|
|
33673
33683
|
const account = result.account;
|
|
33674
33684
|
console.log();
|
|
33675
33685
|
success(`Authenticated as ${account.email}!`);
|
|
@@ -35610,6 +35620,17 @@ ${handlersBlock}
|
|
|
35610
35620
|
|
|
35611
35621
|
// src/generators/views.ts
|
|
35612
35622
|
init_format();
|
|
35623
|
+
|
|
35624
|
+
// src/utils/case-conversion.ts
|
|
35625
|
+
import { toCamelCase } from "@secondlayer/stacks/clarity";
|
|
35626
|
+
function capitalize(str) {
|
|
35627
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
35628
|
+
}
|
|
35629
|
+
function toPascalCase(str) {
|
|
35630
|
+
return capitalize(toCamelCase(str));
|
|
35631
|
+
}
|
|
35632
|
+
|
|
35633
|
+
// src/generators/views.ts
|
|
35613
35634
|
async function generateViewConsumer(viewName, detail) {
|
|
35614
35635
|
const tables = Object.entries(detail.tables);
|
|
35615
35636
|
const rowInterfaces = tables.map(([tableName, tableDef]) => {
|
|
@@ -35662,9 +35683,6 @@ export function createClient(options?: { apiKey?: string; baseUrl?: string }): C
|
|
|
35662
35683
|
`.trimStart();
|
|
35663
35684
|
return formatCode(code);
|
|
35664
35685
|
}
|
|
35665
|
-
function toPascalCase(str) {
|
|
35666
|
-
return str.split(/[-_]/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
35667
|
-
}
|
|
35668
35686
|
function viewTypeToTS(type) {
|
|
35669
35687
|
switch (type) {
|
|
35670
35688
|
case "uint":
|
|
@@ -36564,6 +36582,7 @@ async function runLocalDoctor(jsonOutput) {
|
|
|
36564
36582
|
init_config();
|
|
36565
36583
|
init_api_client();
|
|
36566
36584
|
init_output();
|
|
36585
|
+
import { hostname } from "node:os";
|
|
36567
36586
|
import { input as input2 } from "@inquirer/prompts";
|
|
36568
36587
|
function registerAuthCommand(program2) {
|
|
36569
36588
|
const auth = program2.command("auth").description("Manage authentication and API keys");
|
|
@@ -36584,14 +36603,7 @@ function registerAuthCommand(program2) {
|
|
|
36584
36603
|
headers: { "Content-Type": "application/json" },
|
|
36585
36604
|
body: JSON.stringify({ email })
|
|
36586
36605
|
});
|
|
36587
|
-
|
|
36588
|
-
const body = await mlRes.text();
|
|
36589
|
-
let msg = `HTTP ${mlRes.status}`;
|
|
36590
|
-
try {
|
|
36591
|
-
msg = JSON.parse(body).error || msg;
|
|
36592
|
-
} catch {}
|
|
36593
|
-
throw new Error(msg);
|
|
36594
|
-
}
|
|
36606
|
+
await assertOk(mlRes);
|
|
36595
36607
|
console.log(dim("Check your email for a login token."));
|
|
36596
36608
|
const token = await input2({
|
|
36597
36609
|
message: "Token:",
|
|
@@ -36602,19 +36614,32 @@ function registerAuthCommand(program2) {
|
|
|
36602
36614
|
headers: { "Content-Type": "application/json" },
|
|
36603
36615
|
body: JSON.stringify({ token: token.trim() })
|
|
36604
36616
|
});
|
|
36605
|
-
|
|
36606
|
-
const body = await verifyRes.text();
|
|
36607
|
-
let msg = `HTTP ${verifyRes.status}`;
|
|
36608
|
-
try {
|
|
36609
|
-
msg = JSON.parse(body).error || msg;
|
|
36610
|
-
} catch {}
|
|
36611
|
-
throw new Error(msg);
|
|
36612
|
-
}
|
|
36617
|
+
await assertOk(verifyRes);
|
|
36613
36618
|
const result = await verifyRes.json();
|
|
36614
|
-
|
|
36619
|
+
const sessionHeaders = { Authorization: `Bearer ${result.sessionToken}`, "Content-Type": "application/json" };
|
|
36620
|
+
const keyName = `cli-${hostname().toLowerCase()}`;
|
|
36621
|
+
const listRes = await fetch(`${apiUrl}/api/keys`, { headers: sessionHeaders });
|
|
36622
|
+
if (listRes.ok) {
|
|
36623
|
+
const { keys: keys2 } = await listRes.json();
|
|
36624
|
+
const existing = keys2.find((k) => k.name === keyName && k.status === "active");
|
|
36625
|
+
if (existing) {
|
|
36626
|
+
await fetch(`${apiUrl}/api/keys/${existing.id}`, { method: "DELETE", headers: sessionHeaders });
|
|
36627
|
+
}
|
|
36628
|
+
}
|
|
36629
|
+
const createRes = await fetch(`${apiUrl}/api/keys`, {
|
|
36630
|
+
method: "POST",
|
|
36631
|
+
headers: sessionHeaders,
|
|
36632
|
+
body: JSON.stringify({ name: keyName })
|
|
36633
|
+
});
|
|
36634
|
+
await assertOk(createRes);
|
|
36635
|
+
const { key, prefix } = await createRes.json();
|
|
36636
|
+
config.apiKey = key;
|
|
36615
36637
|
await saveConfig(config);
|
|
36638
|
+
try {
|
|
36639
|
+
await fetch(`${apiUrl}/api/auth/logout`, { method: "POST", headers: sessionHeaders });
|
|
36640
|
+
} catch {}
|
|
36616
36641
|
success(`Authenticated as ${result.account.email}`);
|
|
36617
|
-
console.log(dim(`
|
|
36642
|
+
console.log(dim(`Key: ${prefix}...`));
|
|
36618
36643
|
console.log(dim(`Network: ${config.network}`));
|
|
36619
36644
|
console.log(dim(`API: ${apiUrl}`));
|
|
36620
36645
|
} catch (err) {
|
|
@@ -36622,37 +36647,41 @@ function registerAuthCommand(program2) {
|
|
|
36622
36647
|
process.exit(1);
|
|
36623
36648
|
}
|
|
36624
36649
|
});
|
|
36625
|
-
auth.command("logout").description("Revoke
|
|
36650
|
+
auth.command("logout").description("Revoke API key and remove from config").action(async () => {
|
|
36626
36651
|
const config = await loadConfig();
|
|
36627
36652
|
const apiUrl = resolveApiUrl(config);
|
|
36628
|
-
if (!config.
|
|
36653
|
+
if (!config.apiKey) {
|
|
36629
36654
|
error("Not logged in.");
|
|
36630
36655
|
process.exit(1);
|
|
36631
36656
|
}
|
|
36632
36657
|
try {
|
|
36633
|
-
|
|
36634
|
-
|
|
36635
|
-
|
|
36636
|
-
|
|
36658
|
+
const headers = authHeaders(config);
|
|
36659
|
+
const listRes = await fetch(`${apiUrl}/api/keys`, { headers });
|
|
36660
|
+
if (listRes.ok) {
|
|
36661
|
+
const { keys: keys2 } = await listRes.json();
|
|
36662
|
+
const currentPrefix = config.apiKey.slice(0, 14);
|
|
36663
|
+
const match = keys2.find((k) => currentPrefix.startsWith(k.prefix));
|
|
36664
|
+
if (match) {
|
|
36665
|
+
await fetch(`${apiUrl}/api/keys/${match.id}`, { method: "DELETE", headers });
|
|
36666
|
+
}
|
|
36667
|
+
}
|
|
36637
36668
|
} catch {}
|
|
36638
|
-
delete config.
|
|
36669
|
+
delete config.apiKey;
|
|
36639
36670
|
await saveConfig(config);
|
|
36640
|
-
success("Logged out.
|
|
36671
|
+
success("Logged out. API key revoked.");
|
|
36641
36672
|
});
|
|
36642
36673
|
auth.command("status").description("Show current auth status").action(async () => {
|
|
36643
36674
|
const config = await loadConfig();
|
|
36644
36675
|
const apiUrl = resolveApiUrl(config);
|
|
36645
|
-
const token = config.sessionToken ?? config.apiKey;
|
|
36646
36676
|
const pairs = [
|
|
36647
36677
|
["Network", config.network],
|
|
36648
36678
|
["API", apiUrl || "(not configured)"],
|
|
36649
|
-
["Session", config.sessionToken ? config.sessionToken.slice(0, 14) + "..." : "(none)"],
|
|
36650
36679
|
["API Key", config.apiKey ? config.apiKey.slice(0, 14) + "..." : "(none)"]
|
|
36651
36680
|
];
|
|
36652
|
-
if (
|
|
36681
|
+
if (config.apiKey && apiUrl) {
|
|
36653
36682
|
try {
|
|
36654
36683
|
const res = await fetch(`${apiUrl}/api/accounts/me`, {
|
|
36655
|
-
headers:
|
|
36684
|
+
headers: authHeaders(config)
|
|
36656
36685
|
});
|
|
36657
36686
|
if (res.ok) {
|
|
36658
36687
|
const data = await res.json();
|
|
@@ -36696,14 +36725,7 @@ function registerAuthCommand(program2) {
|
|
|
36696
36725
|
headers,
|
|
36697
36726
|
body: JSON.stringify({ name: options2.name })
|
|
36698
36727
|
});
|
|
36699
|
-
|
|
36700
|
-
const body = await res.text();
|
|
36701
|
-
let msg = `HTTP ${res.status}`;
|
|
36702
|
-
try {
|
|
36703
|
-
msg = JSON.parse(body).error || msg;
|
|
36704
|
-
} catch {}
|
|
36705
|
-
throw new Error(msg);
|
|
36706
|
-
}
|
|
36728
|
+
await assertOk(res);
|
|
36707
36729
|
const { key, prefix } = await res.json();
|
|
36708
36730
|
success(`Created API key: ${prefix}...`);
|
|
36709
36731
|
console.log();
|
|
@@ -36737,24 +36759,18 @@ function registerAuthCommand(program2) {
|
|
|
36737
36759
|
method: "DELETE",
|
|
36738
36760
|
headers
|
|
36739
36761
|
});
|
|
36740
|
-
|
|
36741
|
-
const body = await res.text();
|
|
36742
|
-
let msg = `HTTP ${res.status}`;
|
|
36743
|
-
try {
|
|
36744
|
-
msg = JSON.parse(body).error || msg;
|
|
36745
|
-
} catch {}
|
|
36746
|
-
throw new Error(msg);
|
|
36747
|
-
}
|
|
36762
|
+
await assertOk(res);
|
|
36748
36763
|
success(`Revoked key ${idOrPrefix}`);
|
|
36749
36764
|
} catch (err) {
|
|
36750
36765
|
error(`Failed to revoke key: ${err}`);
|
|
36751
36766
|
process.exit(1);
|
|
36752
36767
|
}
|
|
36753
36768
|
});
|
|
36754
|
-
|
|
36769
|
+
const defaultKeyName = `cli-${hostname().toLowerCase()}`;
|
|
36770
|
+
keys.command("rotate").description("Revoke current API key and create a new one").option("--name <name>", "Name for the new API key", defaultKeyName).action(async (options2) => {
|
|
36755
36771
|
await rotateKey(options2);
|
|
36756
36772
|
});
|
|
36757
|
-
auth.command("rotate").description("Revoke current API key and create a new one").option("--name <name>", "Name for the new API key",
|
|
36773
|
+
auth.command("rotate").description("Revoke current API key and create a new one").option("--name <name>", "Name for the new API key", defaultKeyName).action(async (options2) => {
|
|
36758
36774
|
await rotateKey(options2);
|
|
36759
36775
|
});
|
|
36760
36776
|
}
|
|
@@ -36762,7 +36778,7 @@ async function rotateKey(options2) {
|
|
|
36762
36778
|
const config = await loadConfig();
|
|
36763
36779
|
const apiUrl = resolveApiUrl(config);
|
|
36764
36780
|
const headers = authHeaders(config);
|
|
36765
|
-
if (!config.
|
|
36781
|
+
if (!config.apiKey) {
|
|
36766
36782
|
error("Not logged in. Run `sl auth login` first.");
|
|
36767
36783
|
process.exit(1);
|
|
36768
36784
|
}
|
|
@@ -36787,14 +36803,7 @@ async function rotateKey(options2) {
|
|
|
36787
36803
|
headers: { ...headers, "Content-Type": "application/json" },
|
|
36788
36804
|
body: JSON.stringify({ name: options2.name })
|
|
36789
36805
|
});
|
|
36790
|
-
|
|
36791
|
-
const body = await createRes.text();
|
|
36792
|
-
let msg = `HTTP ${createRes.status}`;
|
|
36793
|
-
try {
|
|
36794
|
-
msg = JSON.parse(body).error || msg;
|
|
36795
|
-
} catch {}
|
|
36796
|
-
throw new Error(msg);
|
|
36797
|
-
}
|
|
36806
|
+
await assertOk(createRes);
|
|
36798
36807
|
const { key, prefix } = await createRes.json();
|
|
36799
36808
|
config.apiKey = key;
|
|
36800
36809
|
await saveConfig(config);
|
|
@@ -37098,8 +37107,7 @@ function registerWhoamiCommand(program2) {
|
|
|
37098
37107
|
program2.command("whoami").description("Show current authenticated account").action(async () => {
|
|
37099
37108
|
const config = await loadConfig();
|
|
37100
37109
|
const apiUrl = resolveApiUrl(config);
|
|
37101
|
-
|
|
37102
|
-
if (!token) {
|
|
37110
|
+
if (!config.apiKey) {
|
|
37103
37111
|
error("Not authenticated. Run: sl auth login");
|
|
37104
37112
|
process.exit(1);
|
|
37105
37113
|
}
|
|
@@ -37165,5 +37173,5 @@ registerWhoamiCommand(program);
|
|
|
37165
37173
|
registerWebhookCommand(program);
|
|
37166
37174
|
program.parse();
|
|
37167
37175
|
|
|
37168
|
-
//# debugId=
|
|
37176
|
+
//# debugId=623C283AFFA2A54D64756E2164756E21
|
|
37169
37177
|
//# sourceMappingURL=cli.js.map
|