@secondlayer/cli 0.3.5 → 0.3.7
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 +292 -163
- package/dist/cli.js.map +7 -5
- package/dist/index.js +273 -272
- package/dist/index.js.map +9 -8
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -15617,6 +15617,159 @@ var init_api = __esm(() => {
|
|
|
15617
15617
|
};
|
|
15618
15618
|
});
|
|
15619
15619
|
|
|
15620
|
+
// src/utils/abi-compat.ts
|
|
15621
|
+
function normalizeAccess(access) {
|
|
15622
|
+
if (access === "read_only")
|
|
15623
|
+
return "read-only";
|
|
15624
|
+
return access;
|
|
15625
|
+
}
|
|
15626
|
+
function normalizeType(type) {
|
|
15627
|
+
if (typeof type === "string") {
|
|
15628
|
+
switch (type) {
|
|
15629
|
+
case "uint128":
|
|
15630
|
+
case "int128":
|
|
15631
|
+
case "bool":
|
|
15632
|
+
case "principal":
|
|
15633
|
+
case "trait_reference":
|
|
15634
|
+
return type;
|
|
15635
|
+
default:
|
|
15636
|
+
return type;
|
|
15637
|
+
}
|
|
15638
|
+
}
|
|
15639
|
+
if (typeof type !== "object" || type === null) {
|
|
15640
|
+
return "uint128";
|
|
15641
|
+
}
|
|
15642
|
+
const typeObj = type;
|
|
15643
|
+
if ("buffer" in typeObj) {
|
|
15644
|
+
const buffer = typeObj.buffer;
|
|
15645
|
+
return {
|
|
15646
|
+
buff: {
|
|
15647
|
+
length: buffer?.length ?? 32
|
|
15648
|
+
}
|
|
15649
|
+
};
|
|
15650
|
+
}
|
|
15651
|
+
if ("buff" in typeObj) {
|
|
15652
|
+
const buff = typeObj.buff;
|
|
15653
|
+
return {
|
|
15654
|
+
buff: {
|
|
15655
|
+
length: buff?.length ?? 32
|
|
15656
|
+
}
|
|
15657
|
+
};
|
|
15658
|
+
}
|
|
15659
|
+
if ("string-ascii" in typeObj) {
|
|
15660
|
+
const strAscii = typeObj["string-ascii"];
|
|
15661
|
+
return {
|
|
15662
|
+
"string-ascii": {
|
|
15663
|
+
length: strAscii?.length ?? 256
|
|
15664
|
+
}
|
|
15665
|
+
};
|
|
15666
|
+
}
|
|
15667
|
+
if ("string-utf8" in typeObj) {
|
|
15668
|
+
const strUtf8 = typeObj["string-utf8"];
|
|
15669
|
+
return {
|
|
15670
|
+
"string-utf8": {
|
|
15671
|
+
length: strUtf8?.length ?? 256
|
|
15672
|
+
}
|
|
15673
|
+
};
|
|
15674
|
+
}
|
|
15675
|
+
if ("response" in typeObj) {
|
|
15676
|
+
const response2 = typeObj.response;
|
|
15677
|
+
return {
|
|
15678
|
+
response: {
|
|
15679
|
+
ok: normalizeType(response2?.ok ?? "bool"),
|
|
15680
|
+
error: normalizeType(response2?.error ?? "uint128")
|
|
15681
|
+
}
|
|
15682
|
+
};
|
|
15683
|
+
}
|
|
15684
|
+
if ("optional" in typeObj) {
|
|
15685
|
+
return {
|
|
15686
|
+
optional: normalizeType(typeObj.optional)
|
|
15687
|
+
};
|
|
15688
|
+
}
|
|
15689
|
+
if ("list" in typeObj) {
|
|
15690
|
+
const list = typeObj.list;
|
|
15691
|
+
return {
|
|
15692
|
+
list: {
|
|
15693
|
+
type: normalizeType(list?.type ?? "uint128"),
|
|
15694
|
+
length: list?.length ?? 100
|
|
15695
|
+
}
|
|
15696
|
+
};
|
|
15697
|
+
}
|
|
15698
|
+
if ("tuple" in typeObj) {
|
|
15699
|
+
const tuple = typeObj.tuple;
|
|
15700
|
+
return {
|
|
15701
|
+
tuple: tuple.map((field) => ({
|
|
15702
|
+
name: field.name,
|
|
15703
|
+
type: normalizeType(field.type)
|
|
15704
|
+
}))
|
|
15705
|
+
};
|
|
15706
|
+
}
|
|
15707
|
+
return "uint128";
|
|
15708
|
+
}
|
|
15709
|
+
function normalizeFunction(func) {
|
|
15710
|
+
const access = normalizeAccess(func.access);
|
|
15711
|
+
const args = func.args ?? [];
|
|
15712
|
+
const outputs = func.outputs;
|
|
15713
|
+
return {
|
|
15714
|
+
name: func.name,
|
|
15715
|
+
access,
|
|
15716
|
+
args: args.map((arg) => ({
|
|
15717
|
+
name: arg.name,
|
|
15718
|
+
type: normalizeType(arg.type)
|
|
15719
|
+
})),
|
|
15720
|
+
outputs: normalizeType(typeof outputs === "object" && outputs !== null && "type" in outputs ? outputs.type : outputs)
|
|
15721
|
+
};
|
|
15722
|
+
}
|
|
15723
|
+
function normalizeMap(map) {
|
|
15724
|
+
return {
|
|
15725
|
+
name: map.name,
|
|
15726
|
+
key: normalizeType(map.key),
|
|
15727
|
+
value: normalizeType(map.value)
|
|
15728
|
+
};
|
|
15729
|
+
}
|
|
15730
|
+
function normalizeVariable(variable) {
|
|
15731
|
+
return {
|
|
15732
|
+
name: variable.name,
|
|
15733
|
+
type: normalizeType(variable.type),
|
|
15734
|
+
access: variable.access
|
|
15735
|
+
};
|
|
15736
|
+
}
|
|
15737
|
+
function normalizeAbi(abi) {
|
|
15738
|
+
if (typeof abi !== "object" || abi === null) {
|
|
15739
|
+
return { functions: [] };
|
|
15740
|
+
}
|
|
15741
|
+
const abiObj = abi;
|
|
15742
|
+
const functions = [];
|
|
15743
|
+
const maps = [];
|
|
15744
|
+
const variables = [];
|
|
15745
|
+
if (Array.isArray(abiObj.functions)) {
|
|
15746
|
+
for (const func of abiObj.functions) {
|
|
15747
|
+
if (typeof func === "object" && func !== null) {
|
|
15748
|
+
functions.push(normalizeFunction(func));
|
|
15749
|
+
}
|
|
15750
|
+
}
|
|
15751
|
+
}
|
|
15752
|
+
if (Array.isArray(abiObj.maps)) {
|
|
15753
|
+
for (const map of abiObj.maps) {
|
|
15754
|
+
if (typeof map === "object" && map !== null) {
|
|
15755
|
+
maps.push(normalizeMap(map));
|
|
15756
|
+
}
|
|
15757
|
+
}
|
|
15758
|
+
}
|
|
15759
|
+
if (Array.isArray(abiObj.variables)) {
|
|
15760
|
+
for (const variable of abiObj.variables) {
|
|
15761
|
+
if (typeof variable === "object" && variable !== null) {
|
|
15762
|
+
variables.push(normalizeVariable(variable));
|
|
15763
|
+
}
|
|
15764
|
+
}
|
|
15765
|
+
}
|
|
15766
|
+
return {
|
|
15767
|
+
functions,
|
|
15768
|
+
maps: maps.length > 0 ? maps : undefined,
|
|
15769
|
+
variables: variables.length > 0 ? variables : undefined
|
|
15770
|
+
};
|
|
15771
|
+
}
|
|
15772
|
+
|
|
15620
15773
|
// src/parsers/clarity.ts
|
|
15621
15774
|
import { promises as fs3 } from "fs";
|
|
15622
15775
|
async function parseClarityFile(filePath) {
|
|
@@ -15703,116 +15856,91 @@ function inferReturnType(body) {
|
|
|
15703
15856
|
}
|
|
15704
15857
|
function parseApiResponse(apiResponse) {
|
|
15705
15858
|
try {
|
|
15706
|
-
|
|
15707
|
-
const maps = [];
|
|
15708
|
-
const variables = [];
|
|
15709
|
-
if (apiResponse.functions) {
|
|
15710
|
-
for (const func of apiResponse.functions) {
|
|
15711
|
-
const access = func.access === "read_only" ? "read-only" : func.access;
|
|
15712
|
-
functions.push({
|
|
15713
|
-
name: func.name,
|
|
15714
|
-
access,
|
|
15715
|
-
args: func.args.map((arg) => ({
|
|
15716
|
-
name: arg.name,
|
|
15717
|
-
type: convertApiType(arg.type)
|
|
15718
|
-
})),
|
|
15719
|
-
outputs: convertApiType(func.outputs.type)
|
|
15720
|
-
});
|
|
15721
|
-
}
|
|
15722
|
-
}
|
|
15723
|
-
if (apiResponse.maps) {
|
|
15724
|
-
for (const map of apiResponse.maps) {
|
|
15725
|
-
maps.push({
|
|
15726
|
-
name: map.name,
|
|
15727
|
-
key: convertApiType(map.key),
|
|
15728
|
-
value: convertApiType(map.value)
|
|
15729
|
-
});
|
|
15730
|
-
}
|
|
15731
|
-
}
|
|
15732
|
-
if (apiResponse.variables) {
|
|
15733
|
-
for (const variable of apiResponse.variables) {
|
|
15734
|
-
variables.push({
|
|
15735
|
-
name: variable.name,
|
|
15736
|
-
type: convertApiType(variable.type),
|
|
15737
|
-
access: variable.access
|
|
15738
|
-
});
|
|
15739
|
-
}
|
|
15740
|
-
}
|
|
15741
|
-
return {
|
|
15742
|
-
functions,
|
|
15743
|
-
maps: maps.length > 0 ? maps : undefined,
|
|
15744
|
-
variables: variables.length > 0 ? variables : undefined
|
|
15745
|
-
};
|
|
15859
|
+
return normalizeAbi(apiResponse);
|
|
15746
15860
|
} catch (error) {
|
|
15747
15861
|
throw new Error(`Failed to parse API response: ${error}`);
|
|
15748
15862
|
}
|
|
15749
15863
|
}
|
|
15750
|
-
|
|
15751
|
-
|
|
15752
|
-
|
|
15753
|
-
|
|
15754
|
-
|
|
15755
|
-
|
|
15756
|
-
|
|
15757
|
-
|
|
15758
|
-
|
|
15759
|
-
|
|
15760
|
-
|
|
15761
|
-
|
|
15864
|
+
var init_clarity = () => {};
|
|
15865
|
+
|
|
15866
|
+
// src/utils/type-mapping.ts
|
|
15867
|
+
import {
|
|
15868
|
+
toCamelCase,
|
|
15869
|
+
isClarityList,
|
|
15870
|
+
isClarityTuple,
|
|
15871
|
+
isClarityOptional,
|
|
15872
|
+
isClarityResponse,
|
|
15873
|
+
isClarityBuffer,
|
|
15874
|
+
isClarityStringAscii,
|
|
15875
|
+
isClarityStringUtf8
|
|
15876
|
+
} from "@secondlayer/clarity-types";
|
|
15877
|
+
function clarityTypeToTS(type) {
|
|
15878
|
+
if (typeof type === "string") {
|
|
15879
|
+
switch (type) {
|
|
15880
|
+
case "uint128":
|
|
15881
|
+
case "int128":
|
|
15882
|
+
return "bigint";
|
|
15883
|
+
case "bool":
|
|
15884
|
+
return "boolean";
|
|
15885
|
+
case "principal":
|
|
15886
|
+
case "trait_reference":
|
|
15887
|
+
return "string";
|
|
15888
|
+
default: {
|
|
15889
|
+
const typeStr = type;
|
|
15890
|
+
if (typeStr.includes("string") || typeStr.includes("ascii") || typeStr.includes("utf8")) {
|
|
15891
|
+
return "string";
|
|
15892
|
+
}
|
|
15893
|
+
if (typeStr.includes("buff")) {
|
|
15894
|
+
return "Uint8Array | string | { type: 'ascii' | 'utf8' | 'hex'; value: string }";
|
|
15895
|
+
}
|
|
15896
|
+
if (typeStr.includes("uint") || typeStr.includes("int")) {
|
|
15897
|
+
return "bigint";
|
|
15898
|
+
}
|
|
15899
|
+
return "any";
|
|
15762
15900
|
}
|
|
15763
|
-
}
|
|
15764
|
-
}
|
|
15765
|
-
if (apiType.optional) {
|
|
15766
|
-
return {
|
|
15767
|
-
optional: convertApiType(apiType.optional)
|
|
15768
|
-
};
|
|
15901
|
+
}
|
|
15769
15902
|
}
|
|
15770
|
-
if (
|
|
15771
|
-
return {
|
|
15772
|
-
list: {
|
|
15773
|
-
type: convertApiType(apiType.list.type),
|
|
15774
|
-
length: apiType.list.length || 100
|
|
15775
|
-
}
|
|
15776
|
-
};
|
|
15903
|
+
if (isClarityBuffer(type)) {
|
|
15904
|
+
return "Uint8Array | string | { type: 'ascii' | 'utf8' | 'hex'; value: string }";
|
|
15777
15905
|
}
|
|
15778
|
-
if (
|
|
15779
|
-
return
|
|
15780
|
-
tuple: apiType.tuple.map((field) => ({
|
|
15781
|
-
name: field.name,
|
|
15782
|
-
type: convertApiType(field.type)
|
|
15783
|
-
}))
|
|
15784
|
-
};
|
|
15906
|
+
if (isClarityStringAscii(type) || isClarityStringUtf8(type)) {
|
|
15907
|
+
return "string";
|
|
15785
15908
|
}
|
|
15786
|
-
if (
|
|
15787
|
-
|
|
15788
|
-
|
|
15789
|
-
|
|
15790
|
-
|
|
15791
|
-
}
|
|
15909
|
+
if (isClarityOptional(type)) {
|
|
15910
|
+
const innerType = clarityTypeToTS(type.optional);
|
|
15911
|
+
if (innerType.includes(" | ") && !innerType.startsWith("(")) {
|
|
15912
|
+
return `(${innerType}) | null`;
|
|
15913
|
+
}
|
|
15914
|
+
return `${innerType} | null`;
|
|
15792
15915
|
}
|
|
15793
|
-
if (
|
|
15794
|
-
|
|
15795
|
-
|
|
15796
|
-
|
|
15797
|
-
|
|
15798
|
-
}
|
|
15916
|
+
if (isClarityList(type)) {
|
|
15917
|
+
const innerType = clarityTypeToTS(type.list.type);
|
|
15918
|
+
if (innerType.includes(" | ") && !innerType.startsWith("(")) {
|
|
15919
|
+
return `(${innerType})[]`;
|
|
15920
|
+
}
|
|
15921
|
+
return `${innerType}[]`;
|
|
15799
15922
|
}
|
|
15800
|
-
if (
|
|
15801
|
-
|
|
15802
|
-
|
|
15803
|
-
length: apiType["string-utf8"].length || 256
|
|
15804
|
-
}
|
|
15805
|
-
};
|
|
15923
|
+
if (isClarityTuple(type)) {
|
|
15924
|
+
const fields = type.tuple.map((field) => `${toCamelCase(field.name)}: ${clarityTypeToTS(field.type)}`).join("; ");
|
|
15925
|
+
return `{ ${fields} }`;
|
|
15806
15926
|
}
|
|
15807
|
-
if (
|
|
15808
|
-
|
|
15927
|
+
if (isClarityResponse(type)) {
|
|
15928
|
+
const okType = clarityTypeToTS(type.response.ok);
|
|
15929
|
+
const errType = clarityTypeToTS(type.response.error);
|
|
15930
|
+
return `{ ok: ${okType} } | { err: ${errType} }`;
|
|
15809
15931
|
}
|
|
15810
|
-
return "
|
|
15932
|
+
return "any";
|
|
15811
15933
|
}
|
|
15812
|
-
|
|
15934
|
+
function getTypeForArg(arg) {
|
|
15935
|
+
return clarityTypeToTS(arg.type);
|
|
15936
|
+
}
|
|
15937
|
+
var init_type_mapping = () => {};
|
|
15813
15938
|
|
|
15814
15939
|
// src/generators/contract.ts
|
|
15815
15940
|
import { format } from "prettier";
|
|
15941
|
+
import {
|
|
15942
|
+
toCamelCase as toCamelCase2
|
|
15943
|
+
} from "@secondlayer/clarity-types";
|
|
15816
15944
|
function generateNetworkUtils() {
|
|
15817
15945
|
return `/**
|
|
15818
15946
|
* API URLs for different networks
|
|
@@ -15844,6 +15972,13 @@ function getApiUrl(
|
|
|
15844
15972
|
return API_URLS[network];
|
|
15845
15973
|
}`;
|
|
15846
15974
|
}
|
|
15975
|
+
function generateValidationUtils() {
|
|
15976
|
+
return `/**
|
|
15977
|
+
* Contract name validation regex
|
|
15978
|
+
* Must start with letter, contain only letters, numbers, and hyphens, max 128 chars
|
|
15979
|
+
*/
|
|
15980
|
+
const CONTRACT_NAME_REGEX = /^[a-zA-Z][a-zA-Z0-9\\-]{0,127}$/;`;
|
|
15981
|
+
}
|
|
15847
15982
|
async function generateContractInterface(contracts) {
|
|
15848
15983
|
const imports = `import { Cl, validateStacksAddress } from '@stacks/transactions'`;
|
|
15849
15984
|
const header = `/**
|
|
@@ -15852,6 +15987,7 @@ async function generateContractInterface(contracts) {
|
|
|
15852
15987
|
*
|
|
15853
15988
|
* @requires @stacks/transactions - Install with: npm install @stacks/transactions
|
|
15854
15989
|
*/`;
|
|
15990
|
+
const validationUtils = generateValidationUtils();
|
|
15855
15991
|
const networkUtils = generateNetworkUtils();
|
|
15856
15992
|
const contractsCode = contracts.map((contract) => generateContract(contract)).join(`
|
|
15857
15993
|
|
|
@@ -15860,6 +15996,8 @@ async function generateContractInterface(contracts) {
|
|
|
15860
15996
|
|
|
15861
15997
|
${header}
|
|
15862
15998
|
|
|
15999
|
+
${validationUtils}
|
|
16000
|
+
|
|
15863
16001
|
${networkUtils}
|
|
15864
16002
|
|
|
15865
16003
|
${contractsCode}`;
|
|
@@ -15900,7 +16038,7 @@ function generateAbiConstant(name, abi) {
|
|
|
15900
16038
|
return `export const ${name}Abi = ${abiJson} as const`;
|
|
15901
16039
|
}
|
|
15902
16040
|
function generateMethod(func, address, contractName) {
|
|
15903
|
-
const methodName =
|
|
16041
|
+
const methodName = toCamelCase2(func.name);
|
|
15904
16042
|
if (func.args.length === 0) {
|
|
15905
16043
|
return `${methodName}() {
|
|
15906
16044
|
return {
|
|
@@ -15913,7 +16051,7 @@ function generateMethod(func, address, contractName) {
|
|
|
15913
16051
|
}
|
|
15914
16052
|
if (func.args.length === 1) {
|
|
15915
16053
|
const originalArgName = func.args[0].name;
|
|
15916
|
-
const argName =
|
|
16054
|
+
const argName = toCamelCase2(originalArgName);
|
|
15917
16055
|
const argType = getTypeForArg(func.args[0]);
|
|
15918
16056
|
const clarityConversion = generateClarityConversion(argName, func.args[0]);
|
|
15919
16057
|
return `${methodName}(...args: [{ ${argName}: ${argType} }] | [${argType}]) {
|
|
@@ -15929,17 +16067,17 @@ function generateMethod(func, address, contractName) {
|
|
|
15929
16067
|
}
|
|
15930
16068
|
}`;
|
|
15931
16069
|
}
|
|
15932
|
-
const argsList = func.args.map((arg) =>
|
|
16070
|
+
const argsList = func.args.map((arg) => toCamelCase2(arg.name)).join(", ");
|
|
15933
16071
|
const argsTypes = func.args.map((arg) => {
|
|
15934
|
-
const camelName =
|
|
16072
|
+
const camelName = toCamelCase2(arg.name);
|
|
15935
16073
|
return `${camelName}: ${getTypeForArg(arg)}`;
|
|
15936
16074
|
}).join("; ");
|
|
15937
16075
|
const argsArray = func.args.map((arg) => {
|
|
15938
|
-
const argName =
|
|
16076
|
+
const argName = toCamelCase2(arg.name);
|
|
15939
16077
|
return generateClarityConversion(argName, arg);
|
|
15940
16078
|
}).join(", ");
|
|
15941
16079
|
const objectAccess = func.args.map((arg) => {
|
|
15942
|
-
const camelName =
|
|
16080
|
+
const camelName = toCamelCase2(arg.name);
|
|
15943
16081
|
return `args[0].${camelName}`;
|
|
15944
16082
|
}).join(", ");
|
|
15945
16083
|
const positionTypes = func.args.map((arg) => getTypeForArg(arg)).join(", ");
|
|
@@ -15956,50 +16094,6 @@ function generateMethod(func, address, contractName) {
|
|
|
15956
16094
|
}
|
|
15957
16095
|
}`;
|
|
15958
16096
|
}
|
|
15959
|
-
function getTypeForArg(arg) {
|
|
15960
|
-
const type = arg.type;
|
|
15961
|
-
if (typeof type === "string") {
|
|
15962
|
-
switch (type) {
|
|
15963
|
-
case "uint128":
|
|
15964
|
-
case "int128":
|
|
15965
|
-
return "bigint";
|
|
15966
|
-
case "bool":
|
|
15967
|
-
return "boolean";
|
|
15968
|
-
case "principal":
|
|
15969
|
-
case "trait_reference":
|
|
15970
|
-
return "string";
|
|
15971
|
-
default:
|
|
15972
|
-
return "any";
|
|
15973
|
-
}
|
|
15974
|
-
}
|
|
15975
|
-
if (type["string-ascii"] || type["string-utf8"]) {
|
|
15976
|
-
return "string";
|
|
15977
|
-
}
|
|
15978
|
-
if (type.buff) {
|
|
15979
|
-
return "Uint8Array | string | { type: 'ascii' | 'utf8' | 'hex'; value: string }";
|
|
15980
|
-
}
|
|
15981
|
-
if (type.optional) {
|
|
15982
|
-
const innerType = getTypeForArg({ type: type.optional });
|
|
15983
|
-
return `${innerType} | null`;
|
|
15984
|
-
}
|
|
15985
|
-
if (type.list) {
|
|
15986
|
-
const innerType = getTypeForArg({ type: type.list.type });
|
|
15987
|
-
return `${innerType}[]`;
|
|
15988
|
-
}
|
|
15989
|
-
if (type.tuple) {
|
|
15990
|
-
const fields = type.tuple.map((field) => `${toCamelCase(field.name)}: ${getTypeForArg({ type: field.type })}`).join("; ");
|
|
15991
|
-
return `{ ${fields} }`;
|
|
15992
|
-
}
|
|
15993
|
-
if (type.response) {
|
|
15994
|
-
const okType = getTypeForArg({ type: type.response.ok });
|
|
15995
|
-
const errType = getTypeForArg({ type: type.response.error });
|
|
15996
|
-
return `{ ok: ${okType} } | { err: ${errType} }`;
|
|
15997
|
-
}
|
|
15998
|
-
return "any";
|
|
15999
|
-
}
|
|
16000
|
-
function toCamelCase(str) {
|
|
16001
|
-
return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()).replace(/-([A-Z])/g, (_, letter) => letter).replace(/-(\d)/g, (_, digit) => digit).replace(/-/g, "");
|
|
16002
|
-
}
|
|
16003
16097
|
function generateClarityConversion(argName, argType) {
|
|
16004
16098
|
const type = argType.type;
|
|
16005
16099
|
if (typeof type === "string") {
|
|
@@ -16013,11 +16107,14 @@ function generateClarityConversion(argName, argType) {
|
|
|
16013
16107
|
case "principal":
|
|
16014
16108
|
case "trait_reference":
|
|
16015
16109
|
return `(() => {
|
|
16016
|
-
const [address, contractName] = ${argName}.split(".") as [string, string];
|
|
16110
|
+
const [address, contractName] = ${argName}.split(".") as [string, string | undefined];
|
|
16017
16111
|
if (!validateStacksAddress(address)) {
|
|
16018
16112
|
throw new Error("Invalid Stacks address format");
|
|
16019
16113
|
}
|
|
16020
|
-
if (
|
|
16114
|
+
if (contractName !== undefined) {
|
|
16115
|
+
if (!CONTRACT_NAME_REGEX.test(contractName)) {
|
|
16116
|
+
throw new Error("Invalid contract name format: must start with letter and contain only letters, numbers, and hyphens");
|
|
16117
|
+
}
|
|
16021
16118
|
return Cl.contractPrincipal(address, contractName);
|
|
16022
16119
|
}
|
|
16023
16120
|
return Cl.standardPrincipal(${argName});
|
|
@@ -16079,24 +16176,54 @@ function generateClarityConversion(argName, argType) {
|
|
|
16079
16176
|
const innerConversion = generateClarityConversion("item", {
|
|
16080
16177
|
type: type.list.type
|
|
16081
16178
|
});
|
|
16082
|
-
|
|
16179
|
+
const maxLength = type.list.length || 100;
|
|
16180
|
+
return `(() => {
|
|
16181
|
+
const listValue = ${argName};
|
|
16182
|
+
if (listValue.length > ${maxLength}) {
|
|
16183
|
+
throw new Error(\`List length \${listValue.length} exceeds max ${maxLength}\`);
|
|
16184
|
+
}
|
|
16185
|
+
return Cl.list(listValue.map(item => ${innerConversion}));
|
|
16186
|
+
})()`;
|
|
16083
16187
|
}
|
|
16084
16188
|
if (type.tuple) {
|
|
16189
|
+
const requiredFields = type.tuple.map((f) => f.name);
|
|
16190
|
+
const fieldNames = JSON.stringify(requiredFields);
|
|
16085
16191
|
const fields = type.tuple.map((field) => {
|
|
16086
|
-
const camelFieldName =
|
|
16087
|
-
const fieldConversion = generateClarityConversion(
|
|
16192
|
+
const camelFieldName = toCamelCase2(field.name);
|
|
16193
|
+
const fieldConversion = generateClarityConversion(`tupleValue.${camelFieldName}`, { type: field.type });
|
|
16088
16194
|
return `"${field.name}": ${fieldConversion}`;
|
|
16089
16195
|
}).join(", ");
|
|
16090
|
-
return `
|
|
16196
|
+
return `(() => {
|
|
16197
|
+
const tupleValue = ${argName};
|
|
16198
|
+
const requiredFields = ${fieldNames};
|
|
16199
|
+
for (const fieldName of requiredFields) {
|
|
16200
|
+
const camelName = fieldName.replace(/-([a-z])/g, (_: string, l: string) => l.toUpperCase());
|
|
16201
|
+
if (!(fieldName in tupleValue) && !(camelName in tupleValue)) {
|
|
16202
|
+
throw new Error(\`Missing tuple field: \${fieldName}\`);
|
|
16203
|
+
}
|
|
16204
|
+
}
|
|
16205
|
+
return Cl.tuple({ ${fields} });
|
|
16206
|
+
})()`;
|
|
16091
16207
|
}
|
|
16092
16208
|
if (type.response) {
|
|
16093
|
-
const okConversion = generateClarityConversion(
|
|
16209
|
+
const okConversion = generateClarityConversion(`responseValue.ok`, {
|
|
16094
16210
|
type: type.response.ok
|
|
16095
16211
|
});
|
|
16096
|
-
const errConversion = generateClarityConversion(
|
|
16212
|
+
const errConversion = generateClarityConversion(`responseValue.err`, {
|
|
16097
16213
|
type: type.response.error
|
|
16098
16214
|
});
|
|
16099
|
-
return `
|
|
16215
|
+
return `(() => {
|
|
16216
|
+
const responseValue = ${argName};
|
|
16217
|
+
const hasOk = 'ok' in responseValue;
|
|
16218
|
+
const hasErr = 'err' in responseValue;
|
|
16219
|
+
if (hasOk && !hasErr) {
|
|
16220
|
+
return Cl.ok(${okConversion});
|
|
16221
|
+
}
|
|
16222
|
+
if (hasErr && !hasOk) {
|
|
16223
|
+
return Cl.error(${errConversion});
|
|
16224
|
+
}
|
|
16225
|
+
throw new Error("Response must have exactly 'ok' or 'err' property");
|
|
16226
|
+
})()`;
|
|
16100
16227
|
}
|
|
16101
16228
|
return `${argName}`;
|
|
16102
16229
|
}
|
|
@@ -16105,7 +16232,7 @@ function generateMapsObject(maps, address, contractName) {
|
|
|
16105
16232
|
return "";
|
|
16106
16233
|
}
|
|
16107
16234
|
const mapMethods = maps.map((map) => {
|
|
16108
|
-
const methodName =
|
|
16235
|
+
const methodName = toCamelCase2(map.name);
|
|
16109
16236
|
const keyType = getTypeForArg({ type: map.key });
|
|
16110
16237
|
const valueType = getTypeForArg({ type: map.value });
|
|
16111
16238
|
const keyConversion = generateMapKeyConversion(map.key);
|
|
@@ -16159,7 +16286,7 @@ function generateVarsObject(variables, address, contractName) {
|
|
|
16159
16286
|
return "";
|
|
16160
16287
|
}
|
|
16161
16288
|
const varMethods = dataVars.map((variable) => {
|
|
16162
|
-
const methodName =
|
|
16289
|
+
const methodName = toCamelCase2(variable.name);
|
|
16163
16290
|
const valueType = getTypeForArg({ type: variable.type });
|
|
16164
16291
|
return `${methodName}: {
|
|
16165
16292
|
async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
|
|
@@ -16197,7 +16324,7 @@ function generateConstantsObject(variables, address, contractName) {
|
|
|
16197
16324
|
return "";
|
|
16198
16325
|
}
|
|
16199
16326
|
const constMethods = constants.map((constant) => {
|
|
16200
|
-
const methodName =
|
|
16327
|
+
const methodName = toCamelCase2(constant.name);
|
|
16201
16328
|
const valueType = getTypeForArg({ type: constant.type });
|
|
16202
16329
|
return `${methodName}: {
|
|
16203
16330
|
async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
|
|
@@ -16229,7 +16356,7 @@ function generateConstantsObject(variables, address, contractName) {
|
|
|
16229
16356
|
function generateMapKeyConversion(keyType) {
|
|
16230
16357
|
if (keyType.tuple) {
|
|
16231
16358
|
const fields = keyType.tuple.map((field) => {
|
|
16232
|
-
const camelFieldName =
|
|
16359
|
+
const camelFieldName = toCamelCase2(field.name);
|
|
16233
16360
|
const fieldConversion = generateClarityConversion(`key.${camelFieldName}`, { type: field.type });
|
|
16234
16361
|
return `"${field.name}": ${fieldConversion}`;
|
|
16235
16362
|
}).join(", ");
|
|
@@ -16237,7 +16364,9 @@ function generateMapKeyConversion(keyType) {
|
|
|
16237
16364
|
}
|
|
16238
16365
|
return generateClarityConversion("key", { type: keyType });
|
|
16239
16366
|
}
|
|
16240
|
-
var init_contract = () => {
|
|
16367
|
+
var init_contract = __esm(() => {
|
|
16368
|
+
init_type_mapping();
|
|
16369
|
+
});
|
|
16241
16370
|
|
|
16242
16371
|
// ../../node_modules/ansis/index.cjs
|
|
16243
16372
|
var require_ansis = __commonJS((exports, module) => {
|
|
@@ -27838,7 +27967,7 @@ function deriveContractName(filePath) {
|
|
|
27838
27967
|
const basename = path11.basename(filePath, ".clar");
|
|
27839
27968
|
return basename.replace(/[-_](.)/g, (_2, char) => char.toUpperCase()).replace(/^(.)/, (_2, char) => char.toLowerCase()).replace(/^\d/, "_$&");
|
|
27840
27969
|
}
|
|
27841
|
-
function
|
|
27970
|
+
function toCamelCase3(str) {
|
|
27842
27971
|
return str.replace(/[-_](.)/g, (_2, char) => char.toUpperCase()).replace(/^(.)/, (_2, char) => char.toLowerCase()).replace(/^\d/, "_$&");
|
|
27843
27972
|
}
|
|
27844
27973
|
async function buildConfigFromInputs(parsedInputs, outPath, apiKey) {
|
|
@@ -27860,7 +27989,7 @@ async function buildConfigFromInputs(parsedInputs, outPath, apiKey) {
|
|
|
27860
27989
|
const apiClient = new StacksApiClient(network, apiKey);
|
|
27861
27990
|
const contractInfo = await apiClient.getContractInfo(contractId);
|
|
27862
27991
|
const abi = parseApiResponse(contractInfo);
|
|
27863
|
-
const name =
|
|
27992
|
+
const name = toCamelCase3(contractName);
|
|
27864
27993
|
contracts.push({
|
|
27865
27994
|
name,
|
|
27866
27995
|
address: contractId,
|
|
@@ -28105,7 +28234,7 @@ var {
|
|
|
28105
28234
|
// package.json
|
|
28106
28235
|
var package_default = {
|
|
28107
28236
|
name: "@secondlayer/cli",
|
|
28108
|
-
version: "0.3.
|
|
28237
|
+
version: "0.3.7",
|
|
28109
28238
|
description: "CLI for generating type-safe contract interfaces for the Stacks blockchain",
|
|
28110
28239
|
type: "module",
|
|
28111
28240
|
bin: {
|
|
@@ -28144,7 +28273,7 @@ var package_default = {
|
|
|
28144
28273
|
author: "",
|
|
28145
28274
|
license: "MIT",
|
|
28146
28275
|
dependencies: {
|
|
28147
|
-
"@secondlayer/clarity-types": "^0.4.
|
|
28276
|
+
"@secondlayer/clarity-types": "^0.4.1",
|
|
28148
28277
|
"@stacks/transactions": "7.0.6",
|
|
28149
28278
|
esbuild: "^0.19.0",
|
|
28150
28279
|
prettier: "^3.1.0"
|
|
@@ -28181,5 +28310,5 @@ program.command("init").description("Initialize a new stacks.config.ts file").ac
|
|
|
28181
28310
|
});
|
|
28182
28311
|
program.parse();
|
|
28183
28312
|
|
|
28184
|
-
//# debugId=
|
|
28313
|
+
//# debugId=58D4865FBB414E7B64756E2164756E21
|
|
28185
28314
|
//# sourceMappingURL=cli.js.map
|