@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/index.js
CHANGED
|
@@ -318,6 +318,83 @@ import { initSimnet } from "@hirosystems/clarinet-sdk";
|
|
|
318
318
|
|
|
319
319
|
// src/generators/contract.ts
|
|
320
320
|
import { format } from "prettier";
|
|
321
|
+
import {
|
|
322
|
+
toCamelCase as toCamelCase2
|
|
323
|
+
} from "@secondlayer/clarity-types";
|
|
324
|
+
|
|
325
|
+
// src/utils/type-mapping.ts
|
|
326
|
+
import {
|
|
327
|
+
toCamelCase,
|
|
328
|
+
isClarityList,
|
|
329
|
+
isClarityTuple,
|
|
330
|
+
isClarityOptional,
|
|
331
|
+
isClarityResponse,
|
|
332
|
+
isClarityBuffer,
|
|
333
|
+
isClarityStringAscii,
|
|
334
|
+
isClarityStringUtf8
|
|
335
|
+
} from "@secondlayer/clarity-types";
|
|
336
|
+
function clarityTypeToTS(type) {
|
|
337
|
+
if (typeof type === "string") {
|
|
338
|
+
switch (type) {
|
|
339
|
+
case "uint128":
|
|
340
|
+
case "int128":
|
|
341
|
+
return "bigint";
|
|
342
|
+
case "bool":
|
|
343
|
+
return "boolean";
|
|
344
|
+
case "principal":
|
|
345
|
+
case "trait_reference":
|
|
346
|
+
return "string";
|
|
347
|
+
default: {
|
|
348
|
+
const typeStr = type;
|
|
349
|
+
if (typeStr.includes("string") || typeStr.includes("ascii") || typeStr.includes("utf8")) {
|
|
350
|
+
return "string";
|
|
351
|
+
}
|
|
352
|
+
if (typeStr.includes("buff")) {
|
|
353
|
+
return "Uint8Array | string | { type: 'ascii' | 'utf8' | 'hex'; value: string }";
|
|
354
|
+
}
|
|
355
|
+
if (typeStr.includes("uint") || typeStr.includes("int")) {
|
|
356
|
+
return "bigint";
|
|
357
|
+
}
|
|
358
|
+
return "any";
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if (isClarityBuffer(type)) {
|
|
363
|
+
return "Uint8Array | string | { type: 'ascii' | 'utf8' | 'hex'; value: string }";
|
|
364
|
+
}
|
|
365
|
+
if (isClarityStringAscii(type) || isClarityStringUtf8(type)) {
|
|
366
|
+
return "string";
|
|
367
|
+
}
|
|
368
|
+
if (isClarityOptional(type)) {
|
|
369
|
+
const innerType = clarityTypeToTS(type.optional);
|
|
370
|
+
if (innerType.includes(" | ") && !innerType.startsWith("(")) {
|
|
371
|
+
return `(${innerType}) | null`;
|
|
372
|
+
}
|
|
373
|
+
return `${innerType} | null`;
|
|
374
|
+
}
|
|
375
|
+
if (isClarityList(type)) {
|
|
376
|
+
const innerType = clarityTypeToTS(type.list.type);
|
|
377
|
+
if (innerType.includes(" | ") && !innerType.startsWith("(")) {
|
|
378
|
+
return `(${innerType})[]`;
|
|
379
|
+
}
|
|
380
|
+
return `${innerType}[]`;
|
|
381
|
+
}
|
|
382
|
+
if (isClarityTuple(type)) {
|
|
383
|
+
const fields = type.tuple.map((field) => `${toCamelCase(field.name)}: ${clarityTypeToTS(field.type)}`).join("; ");
|
|
384
|
+
return `{ ${fields} }`;
|
|
385
|
+
}
|
|
386
|
+
if (isClarityResponse(type)) {
|
|
387
|
+
const okType = clarityTypeToTS(type.response.ok);
|
|
388
|
+
const errType = clarityTypeToTS(type.response.error);
|
|
389
|
+
return `{ ok: ${okType} } | { err: ${errType} }`;
|
|
390
|
+
}
|
|
391
|
+
return "any";
|
|
392
|
+
}
|
|
393
|
+
function getTypeForArg(arg) {
|
|
394
|
+
return clarityTypeToTS(arg.type);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// src/generators/contract.ts
|
|
321
398
|
function generateNetworkUtils() {
|
|
322
399
|
return `/**
|
|
323
400
|
* API URLs for different networks
|
|
@@ -349,6 +426,13 @@ function getApiUrl(
|
|
|
349
426
|
return API_URLS[network];
|
|
350
427
|
}`;
|
|
351
428
|
}
|
|
429
|
+
function generateValidationUtils() {
|
|
430
|
+
return `/**
|
|
431
|
+
* Contract name validation regex
|
|
432
|
+
* Must start with letter, contain only letters, numbers, and hyphens, max 128 chars
|
|
433
|
+
*/
|
|
434
|
+
const CONTRACT_NAME_REGEX = /^[a-zA-Z][a-zA-Z0-9\\-]{0,127}$/;`;
|
|
435
|
+
}
|
|
352
436
|
async function generateContractInterface(contracts) {
|
|
353
437
|
const imports = `import { Cl, validateStacksAddress } from '@stacks/transactions'`;
|
|
354
438
|
const header = `/**
|
|
@@ -357,6 +441,7 @@ async function generateContractInterface(contracts) {
|
|
|
357
441
|
*
|
|
358
442
|
* @requires @stacks/transactions - Install with: npm install @stacks/transactions
|
|
359
443
|
*/`;
|
|
444
|
+
const validationUtils = generateValidationUtils();
|
|
360
445
|
const networkUtils = generateNetworkUtils();
|
|
361
446
|
const contractsCode = contracts.map((contract) => generateContract(contract)).join(`
|
|
362
447
|
|
|
@@ -365,6 +450,8 @@ async function generateContractInterface(contracts) {
|
|
|
365
450
|
|
|
366
451
|
${header}
|
|
367
452
|
|
|
453
|
+
${validationUtils}
|
|
454
|
+
|
|
368
455
|
${networkUtils}
|
|
369
456
|
|
|
370
457
|
${contractsCode}`;
|
|
@@ -405,7 +492,7 @@ function generateAbiConstant(name, abi) {
|
|
|
405
492
|
return `export const ${name}Abi = ${abiJson} as const`;
|
|
406
493
|
}
|
|
407
494
|
function generateMethod(func, address, contractName) {
|
|
408
|
-
const methodName =
|
|
495
|
+
const methodName = toCamelCase2(func.name);
|
|
409
496
|
if (func.args.length === 0) {
|
|
410
497
|
return `${methodName}() {
|
|
411
498
|
return {
|
|
@@ -418,7 +505,7 @@ function generateMethod(func, address, contractName) {
|
|
|
418
505
|
}
|
|
419
506
|
if (func.args.length === 1) {
|
|
420
507
|
const originalArgName = func.args[0].name;
|
|
421
|
-
const argName =
|
|
508
|
+
const argName = toCamelCase2(originalArgName);
|
|
422
509
|
const argType = getTypeForArg(func.args[0]);
|
|
423
510
|
const clarityConversion = generateClarityConversion(argName, func.args[0]);
|
|
424
511
|
return `${methodName}(...args: [{ ${argName}: ${argType} }] | [${argType}]) {
|
|
@@ -434,17 +521,17 @@ function generateMethod(func, address, contractName) {
|
|
|
434
521
|
}
|
|
435
522
|
}`;
|
|
436
523
|
}
|
|
437
|
-
const argsList = func.args.map((arg) =>
|
|
524
|
+
const argsList = func.args.map((arg) => toCamelCase2(arg.name)).join(", ");
|
|
438
525
|
const argsTypes = func.args.map((arg) => {
|
|
439
|
-
const camelName =
|
|
526
|
+
const camelName = toCamelCase2(arg.name);
|
|
440
527
|
return `${camelName}: ${getTypeForArg(arg)}`;
|
|
441
528
|
}).join("; ");
|
|
442
529
|
const argsArray = func.args.map((arg) => {
|
|
443
|
-
const argName =
|
|
530
|
+
const argName = toCamelCase2(arg.name);
|
|
444
531
|
return generateClarityConversion(argName, arg);
|
|
445
532
|
}).join(", ");
|
|
446
533
|
const objectAccess = func.args.map((arg) => {
|
|
447
|
-
const camelName =
|
|
534
|
+
const camelName = toCamelCase2(arg.name);
|
|
448
535
|
return `args[0].${camelName}`;
|
|
449
536
|
}).join(", ");
|
|
450
537
|
const positionTypes = func.args.map((arg) => getTypeForArg(arg)).join(", ");
|
|
@@ -461,50 +548,6 @@ function generateMethod(func, address, contractName) {
|
|
|
461
548
|
}
|
|
462
549
|
}`;
|
|
463
550
|
}
|
|
464
|
-
function getTypeForArg(arg) {
|
|
465
|
-
const type = arg.type;
|
|
466
|
-
if (typeof type === "string") {
|
|
467
|
-
switch (type) {
|
|
468
|
-
case "uint128":
|
|
469
|
-
case "int128":
|
|
470
|
-
return "bigint";
|
|
471
|
-
case "bool":
|
|
472
|
-
return "boolean";
|
|
473
|
-
case "principal":
|
|
474
|
-
case "trait_reference":
|
|
475
|
-
return "string";
|
|
476
|
-
default:
|
|
477
|
-
return "any";
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
if (type["string-ascii"] || type["string-utf8"]) {
|
|
481
|
-
return "string";
|
|
482
|
-
}
|
|
483
|
-
if (type.buff) {
|
|
484
|
-
return "Uint8Array | string | { type: 'ascii' | 'utf8' | 'hex'; value: string }";
|
|
485
|
-
}
|
|
486
|
-
if (type.optional) {
|
|
487
|
-
const innerType = getTypeForArg({ type: type.optional });
|
|
488
|
-
return `${innerType} | null`;
|
|
489
|
-
}
|
|
490
|
-
if (type.list) {
|
|
491
|
-
const innerType = getTypeForArg({ type: type.list.type });
|
|
492
|
-
return `${innerType}[]`;
|
|
493
|
-
}
|
|
494
|
-
if (type.tuple) {
|
|
495
|
-
const fields = type.tuple.map((field) => `${toCamelCase(field.name)}: ${getTypeForArg({ type: field.type })}`).join("; ");
|
|
496
|
-
return `{ ${fields} }`;
|
|
497
|
-
}
|
|
498
|
-
if (type.response) {
|
|
499
|
-
const okType = getTypeForArg({ type: type.response.ok });
|
|
500
|
-
const errType = getTypeForArg({ type: type.response.error });
|
|
501
|
-
return `{ ok: ${okType} } | { err: ${errType} }`;
|
|
502
|
-
}
|
|
503
|
-
return "any";
|
|
504
|
-
}
|
|
505
|
-
function toCamelCase(str) {
|
|
506
|
-
return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()).replace(/-([A-Z])/g, (_, letter) => letter).replace(/-(\d)/g, (_, digit) => digit).replace(/-/g, "");
|
|
507
|
-
}
|
|
508
551
|
function generateClarityConversion(argName, argType) {
|
|
509
552
|
const type = argType.type;
|
|
510
553
|
if (typeof type === "string") {
|
|
@@ -518,11 +561,14 @@ function generateClarityConversion(argName, argType) {
|
|
|
518
561
|
case "principal":
|
|
519
562
|
case "trait_reference":
|
|
520
563
|
return `(() => {
|
|
521
|
-
const [address, contractName] = ${argName}.split(".") as [string, string];
|
|
564
|
+
const [address, contractName] = ${argName}.split(".") as [string, string | undefined];
|
|
522
565
|
if (!validateStacksAddress(address)) {
|
|
523
566
|
throw new Error("Invalid Stacks address format");
|
|
524
567
|
}
|
|
525
|
-
if (
|
|
568
|
+
if (contractName !== undefined) {
|
|
569
|
+
if (!CONTRACT_NAME_REGEX.test(contractName)) {
|
|
570
|
+
throw new Error("Invalid contract name format: must start with letter and contain only letters, numbers, and hyphens");
|
|
571
|
+
}
|
|
526
572
|
return Cl.contractPrincipal(address, contractName);
|
|
527
573
|
}
|
|
528
574
|
return Cl.standardPrincipal(${argName});
|
|
@@ -584,24 +630,54 @@ function generateClarityConversion(argName, argType) {
|
|
|
584
630
|
const innerConversion = generateClarityConversion("item", {
|
|
585
631
|
type: type.list.type
|
|
586
632
|
});
|
|
587
|
-
|
|
633
|
+
const maxLength = type.list.length || 100;
|
|
634
|
+
return `(() => {
|
|
635
|
+
const listValue = ${argName};
|
|
636
|
+
if (listValue.length > ${maxLength}) {
|
|
637
|
+
throw new Error(\`List length \${listValue.length} exceeds max ${maxLength}\`);
|
|
638
|
+
}
|
|
639
|
+
return Cl.list(listValue.map(item => ${innerConversion}));
|
|
640
|
+
})()`;
|
|
588
641
|
}
|
|
589
642
|
if (type.tuple) {
|
|
643
|
+
const requiredFields = type.tuple.map((f) => f.name);
|
|
644
|
+
const fieldNames = JSON.stringify(requiredFields);
|
|
590
645
|
const fields = type.tuple.map((field) => {
|
|
591
|
-
const camelFieldName =
|
|
592
|
-
const fieldConversion = generateClarityConversion(
|
|
646
|
+
const camelFieldName = toCamelCase2(field.name);
|
|
647
|
+
const fieldConversion = generateClarityConversion(`tupleValue.${camelFieldName}`, { type: field.type });
|
|
593
648
|
return `"${field.name}": ${fieldConversion}`;
|
|
594
649
|
}).join(", ");
|
|
595
|
-
return `
|
|
650
|
+
return `(() => {
|
|
651
|
+
const tupleValue = ${argName};
|
|
652
|
+
const requiredFields = ${fieldNames};
|
|
653
|
+
for (const fieldName of requiredFields) {
|
|
654
|
+
const camelName = fieldName.replace(/-([a-z])/g, (_: string, l: string) => l.toUpperCase());
|
|
655
|
+
if (!(fieldName in tupleValue) && !(camelName in tupleValue)) {
|
|
656
|
+
throw new Error(\`Missing tuple field: \${fieldName}\`);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
return Cl.tuple({ ${fields} });
|
|
660
|
+
})()`;
|
|
596
661
|
}
|
|
597
662
|
if (type.response) {
|
|
598
|
-
const okConversion = generateClarityConversion(
|
|
663
|
+
const okConversion = generateClarityConversion(`responseValue.ok`, {
|
|
599
664
|
type: type.response.ok
|
|
600
665
|
});
|
|
601
|
-
const errConversion = generateClarityConversion(
|
|
666
|
+
const errConversion = generateClarityConversion(`responseValue.err`, {
|
|
602
667
|
type: type.response.error
|
|
603
668
|
});
|
|
604
|
-
return `
|
|
669
|
+
return `(() => {
|
|
670
|
+
const responseValue = ${argName};
|
|
671
|
+
const hasOk = 'ok' in responseValue;
|
|
672
|
+
const hasErr = 'err' in responseValue;
|
|
673
|
+
if (hasOk && !hasErr) {
|
|
674
|
+
return Cl.ok(${okConversion});
|
|
675
|
+
}
|
|
676
|
+
if (hasErr && !hasOk) {
|
|
677
|
+
return Cl.error(${errConversion});
|
|
678
|
+
}
|
|
679
|
+
throw new Error("Response must have exactly 'ok' or 'err' property");
|
|
680
|
+
})()`;
|
|
605
681
|
}
|
|
606
682
|
return `${argName}`;
|
|
607
683
|
}
|
|
@@ -610,7 +686,7 @@ function generateMapsObject(maps, address, contractName) {
|
|
|
610
686
|
return "";
|
|
611
687
|
}
|
|
612
688
|
const mapMethods = maps.map((map) => {
|
|
613
|
-
const methodName =
|
|
689
|
+
const methodName = toCamelCase2(map.name);
|
|
614
690
|
const keyType = getTypeForArg({ type: map.key });
|
|
615
691
|
const valueType = getTypeForArg({ type: map.value });
|
|
616
692
|
const keyConversion = generateMapKeyConversion(map.key);
|
|
@@ -664,7 +740,7 @@ function generateVarsObject(variables, address, contractName) {
|
|
|
664
740
|
return "";
|
|
665
741
|
}
|
|
666
742
|
const varMethods = dataVars.map((variable) => {
|
|
667
|
-
const methodName =
|
|
743
|
+
const methodName = toCamelCase2(variable.name);
|
|
668
744
|
const valueType = getTypeForArg({ type: variable.type });
|
|
669
745
|
return `${methodName}: {
|
|
670
746
|
async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
|
|
@@ -702,7 +778,7 @@ function generateConstantsObject(variables, address, contractName) {
|
|
|
702
778
|
return "";
|
|
703
779
|
}
|
|
704
780
|
const constMethods = constants.map((constant) => {
|
|
705
|
-
const methodName =
|
|
781
|
+
const methodName = toCamelCase2(constant.name);
|
|
706
782
|
const valueType = getTypeForArg({ type: constant.type });
|
|
707
783
|
return `${methodName}: {
|
|
708
784
|
async get(options?: { network?: 'mainnet' | 'testnet' | 'devnet' }): Promise<${valueType}> {
|
|
@@ -734,7 +810,7 @@ function generateConstantsObject(variables, address, contractName) {
|
|
|
734
810
|
function generateMapKeyConversion(keyType) {
|
|
735
811
|
if (keyType.tuple) {
|
|
736
812
|
const fields = keyType.tuple.map((field) => {
|
|
737
|
-
const camelFieldName =
|
|
813
|
+
const camelFieldName = toCamelCase2(field.name);
|
|
738
814
|
const fieldConversion = generateClarityConversion(`key.${camelFieldName}`, { type: field.type });
|
|
739
815
|
return `"${field.name}": ${fieldConversion}`;
|
|
740
816
|
}).join(", ");
|
|
@@ -744,11 +820,11 @@ function generateMapKeyConversion(keyType) {
|
|
|
744
820
|
}
|
|
745
821
|
|
|
746
822
|
// src/plugins/clarinet/index.ts
|
|
747
|
-
function
|
|
823
|
+
function toCamelCase3(str) {
|
|
748
824
|
return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()).replace(/-([A-Z])/g, (_, letter) => letter).replace(/-(\d)/g, (_, digit) => digit).replace(/-/g, "").replace(/^\d/, "_$&");
|
|
749
825
|
}
|
|
750
826
|
function sanitizeContractName(name) {
|
|
751
|
-
return
|
|
827
|
+
return toCamelCase3(name);
|
|
752
828
|
}
|
|
753
829
|
async function isUserDefinedContract(contractId, manifestPath) {
|
|
754
830
|
const [address, contractName] = contractId.split(".");
|
|
@@ -858,56 +934,13 @@ async function hasClarinetProject(path2 = "./Clarinet.toml") {
|
|
|
858
934
|
}
|
|
859
935
|
}
|
|
860
936
|
// src/plugins/actions/generators.ts
|
|
861
|
-
|
|
862
|
-
return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()).replace(/-([A-Z])/g, (_, letter) => letter).replace(/-(\d)/g, (_, digit) => digit).replace(/-/g, "").replace(/^\d/, "_$&");
|
|
863
|
-
}
|
|
864
|
-
function getTypeForArg2(arg) {
|
|
865
|
-
const type = arg.type;
|
|
866
|
-
if (typeof type === "string") {
|
|
867
|
-
switch (type) {
|
|
868
|
-
case "uint128":
|
|
869
|
-
case "int128":
|
|
870
|
-
return "bigint";
|
|
871
|
-
case "bool":
|
|
872
|
-
return "boolean";
|
|
873
|
-
case "principal":
|
|
874
|
-
case "trait_reference":
|
|
875
|
-
return "string";
|
|
876
|
-
default:
|
|
877
|
-
return "any";
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
if (type["string-ascii"] || type["string-utf8"]) {
|
|
881
|
-
return "string";
|
|
882
|
-
}
|
|
883
|
-
if (type.buff) {
|
|
884
|
-
return "Uint8Array | string | { type: 'ascii' | 'utf8' | 'hex'; value: string }";
|
|
885
|
-
}
|
|
886
|
-
if (type.optional) {
|
|
887
|
-
const innerType = getTypeForArg2({ type: type.optional });
|
|
888
|
-
return `${innerType} | null`;
|
|
889
|
-
}
|
|
890
|
-
if (type.list) {
|
|
891
|
-
const innerType = getTypeForArg2({ type: type.list.type });
|
|
892
|
-
return `${innerType}[]`;
|
|
893
|
-
}
|
|
894
|
-
if (type.tuple) {
|
|
895
|
-
const fields = type.tuple.map((field) => `${toCamelCase3(field.name)}: ${getTypeForArg2({ type: field.type })}`).join("; ");
|
|
896
|
-
return `{ ${fields} }`;
|
|
897
|
-
}
|
|
898
|
-
if (type.response) {
|
|
899
|
-
const okType = getTypeForArg2({ type: type.response.ok });
|
|
900
|
-
const errType = getTypeForArg2({ type: type.response.error });
|
|
901
|
-
return `{ ok: ${okType} } | { err: ${errType} }`;
|
|
902
|
-
}
|
|
903
|
-
return "any";
|
|
904
|
-
}
|
|
937
|
+
import { toCamelCase as toCamelCase4 } from "@secondlayer/clarity-types";
|
|
905
938
|
function generateArgsSignature(args) {
|
|
906
939
|
if (args.length === 0)
|
|
907
940
|
return "";
|
|
908
941
|
const argsTypes = args.map((arg) => {
|
|
909
|
-
const camelName =
|
|
910
|
-
return `${camelName}: ${
|
|
942
|
+
const camelName = toCamelCase4(arg.name);
|
|
943
|
+
return `${camelName}: ${getTypeForArg(arg)}`;
|
|
911
944
|
}).join("; ");
|
|
912
945
|
return `args: { ${argsTypes} }, `;
|
|
913
946
|
}
|
|
@@ -915,7 +948,7 @@ function generateClarityArgs(args, _contractName) {
|
|
|
915
948
|
if (args.length === 0)
|
|
916
949
|
return "";
|
|
917
950
|
return args.map((arg) => {
|
|
918
|
-
const argName = `args.${
|
|
951
|
+
const argName = `args.${toCamelCase4(arg.name)}`;
|
|
919
952
|
return generateClarityConversion2(argName, arg);
|
|
920
953
|
}).join(", ");
|
|
921
954
|
}
|
|
@@ -932,11 +965,14 @@ function generateClarityConversion2(argName, argType) {
|
|
|
932
965
|
case "principal":
|
|
933
966
|
case "trait_reference":
|
|
934
967
|
return `(() => {
|
|
935
|
-
const [address, contractName] = ${argName}.split(".") as [string, string];
|
|
968
|
+
const [address, contractName] = ${argName}.split(".") as [string, string | undefined];
|
|
936
969
|
if (!validateStacksAddress(address)) {
|
|
937
970
|
throw new Error("Invalid Stacks address format");
|
|
938
971
|
}
|
|
939
|
-
if (
|
|
972
|
+
if (contractName !== undefined) {
|
|
973
|
+
if (!CONTRACT_NAME_REGEX.test(contractName)) {
|
|
974
|
+
throw new Error("Invalid contract name format: must start with letter and contain only letters, numbers, and hyphens");
|
|
975
|
+
}
|
|
940
976
|
return Cl.contractPrincipal(address, contractName);
|
|
941
977
|
}
|
|
942
978
|
return Cl.standardPrincipal(${argName});
|
|
@@ -992,24 +1028,54 @@ function generateClarityConversion2(argName, argType) {
|
|
|
992
1028
|
const innerConversion = generateClarityConversion2("item", {
|
|
993
1029
|
type: type.list.type
|
|
994
1030
|
});
|
|
995
|
-
|
|
1031
|
+
const maxLength = type.list.length || 100;
|
|
1032
|
+
return `(() => {
|
|
1033
|
+
const listValue = ${argName};
|
|
1034
|
+
if (listValue.length > ${maxLength}) {
|
|
1035
|
+
throw new Error(\`List length \${listValue.length} exceeds max ${maxLength}\`);
|
|
1036
|
+
}
|
|
1037
|
+
return Cl.list(listValue.map(item => ${innerConversion}));
|
|
1038
|
+
})()`;
|
|
996
1039
|
}
|
|
997
1040
|
if (type.tuple) {
|
|
1041
|
+
const requiredFields = type.tuple.map((f) => f.name);
|
|
1042
|
+
const fieldNames = JSON.stringify(requiredFields);
|
|
998
1043
|
const fields = type.tuple.map((field) => {
|
|
999
|
-
const camelFieldName =
|
|
1000
|
-
const fieldConversion = generateClarityConversion2(
|
|
1044
|
+
const camelFieldName = toCamelCase4(field.name);
|
|
1045
|
+
const fieldConversion = generateClarityConversion2(`tupleValue.${camelFieldName}`, { type: field.type });
|
|
1001
1046
|
return `"${field.name}": ${fieldConversion}`;
|
|
1002
1047
|
}).join(", ");
|
|
1003
|
-
return `
|
|
1048
|
+
return `(() => {
|
|
1049
|
+
const tupleValue = ${argName};
|
|
1050
|
+
const requiredFields = ${fieldNames};
|
|
1051
|
+
for (const fieldName of requiredFields) {
|
|
1052
|
+
const camelName = fieldName.replace(/-([a-z])/g, (_: string, l: string) => l.toUpperCase());
|
|
1053
|
+
if (!(fieldName in tupleValue) && !(camelName in tupleValue)) {
|
|
1054
|
+
throw new Error(\`Missing tuple field: \${fieldName}\`);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
return Cl.tuple({ ${fields} });
|
|
1058
|
+
})()`;
|
|
1004
1059
|
}
|
|
1005
1060
|
if (type.response) {
|
|
1006
|
-
const okConversion = generateClarityConversion2(
|
|
1061
|
+
const okConversion = generateClarityConversion2(`responseValue.ok`, {
|
|
1007
1062
|
type: type.response.ok
|
|
1008
1063
|
});
|
|
1009
|
-
const errConversion = generateClarityConversion2(
|
|
1064
|
+
const errConversion = generateClarityConversion2(`responseValue.err`, {
|
|
1010
1065
|
type: type.response.error
|
|
1011
1066
|
});
|
|
1012
|
-
return `
|
|
1067
|
+
return `(() => {
|
|
1068
|
+
const responseValue = ${argName};
|
|
1069
|
+
const hasOk = 'ok' in responseValue;
|
|
1070
|
+
const hasErr = 'err' in responseValue;
|
|
1071
|
+
if (hasOk && !hasErr) {
|
|
1072
|
+
return Cl.ok(${okConversion});
|
|
1073
|
+
}
|
|
1074
|
+
if (hasErr && !hasOk) {
|
|
1075
|
+
return Cl.error(${errConversion});
|
|
1076
|
+
}
|
|
1077
|
+
throw new Error("Response must have exactly 'ok' or 'err' property");
|
|
1078
|
+
})()`;
|
|
1013
1079
|
}
|
|
1014
1080
|
return `${argName}`;
|
|
1015
1081
|
}
|
|
@@ -1033,7 +1099,7 @@ function generateReadHelpers(contract, options) {
|
|
|
1033
1099
|
return "";
|
|
1034
1100
|
}
|
|
1035
1101
|
const helpers = filteredFunctions.map((func) => {
|
|
1036
|
-
const methodName =
|
|
1102
|
+
const methodName = toCamelCase4(func.name);
|
|
1037
1103
|
const argsSignature = generateArgsSignature(func.args);
|
|
1038
1104
|
const clarityArgs = generateClarityArgs(func.args, name);
|
|
1039
1105
|
return `async ${methodName}(${argsSignature}options?: {
|
|
@@ -1076,7 +1142,7 @@ function generateWriteHelpers(contract, options) {
|
|
|
1076
1142
|
return "";
|
|
1077
1143
|
}
|
|
1078
1144
|
const helpers = filteredFunctions.map((func) => {
|
|
1079
|
-
const methodName =
|
|
1145
|
+
const methodName = toCamelCase4(func.name);
|
|
1080
1146
|
const argsSignature = generateArgsSignature(func.args);
|
|
1081
1147
|
const clarityArgs = generateClarityArgs(func.args, name);
|
|
1082
1148
|
return `async ${methodName}(${argsSignature}options: {
|
|
@@ -2124,38 +2190,36 @@ function generateGenericHook(hookName) {
|
|
|
2124
2190
|
import { format as format4 } from "prettier";
|
|
2125
2191
|
|
|
2126
2192
|
// src/plugins/react/generators/utils.ts
|
|
2127
|
-
|
|
2128
|
-
return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
2129
|
-
}
|
|
2193
|
+
import { toCamelCase as toCamelCase5 } from "@secondlayer/clarity-types";
|
|
2130
2194
|
function capitalize(str) {
|
|
2131
2195
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
2132
2196
|
}
|
|
2133
2197
|
function generateHookArgsSignature(args) {
|
|
2134
2198
|
if (args.length === 0)
|
|
2135
2199
|
return "";
|
|
2136
|
-
const argsList = args.map((arg) => `${
|
|
2200
|
+
const argsList = args.map((arg) => `${toCamelCase5(arg.name)}: ${clarityTypeToTS(arg.type)}`).join(", ");
|
|
2137
2201
|
return `${argsList}`;
|
|
2138
2202
|
}
|
|
2139
2203
|
function generateArgsType(args) {
|
|
2140
2204
|
if (args.length === 0)
|
|
2141
2205
|
return "void";
|
|
2142
|
-
const argsList = args.map((arg) => `${
|
|
2206
|
+
const argsList = args.map((arg) => `${toCamelCase5(arg.name)}: ${clarityTypeToTS(arg.type)}`).join("; ");
|
|
2143
2207
|
return `{ ${argsList} }`;
|
|
2144
2208
|
}
|
|
2145
2209
|
function generateQueryKeyArgs(args) {
|
|
2146
2210
|
if (args.length === 0)
|
|
2147
2211
|
return "";
|
|
2148
|
-
return args.map((arg) =>
|
|
2212
|
+
return args.map((arg) => toCamelCase5(arg.name)).join(", ");
|
|
2149
2213
|
}
|
|
2150
2214
|
function generateFunctionCallArgs(args) {
|
|
2151
2215
|
if (args.length === 0)
|
|
2152
2216
|
return "";
|
|
2153
|
-
return args.map((arg) =>
|
|
2217
|
+
return args.map((arg) => toCamelCase5(arg.name)).join(", ");
|
|
2154
2218
|
}
|
|
2155
2219
|
function generateEnabledCondition(args) {
|
|
2156
2220
|
return args.map((arg) => {
|
|
2157
|
-
const camelName =
|
|
2158
|
-
const type =
|
|
2221
|
+
const camelName = toCamelCase5(arg.name);
|
|
2222
|
+
const type = clarityTypeToTS(arg.type);
|
|
2159
2223
|
if (type === "string")
|
|
2160
2224
|
return `!!${camelName}`;
|
|
2161
2225
|
if (type === "bigint")
|
|
@@ -2163,62 +2227,10 @@ function generateEnabledCondition(args) {
|
|
|
2163
2227
|
return `${camelName} !== undefined`;
|
|
2164
2228
|
}).join(" && ");
|
|
2165
2229
|
}
|
|
2166
|
-
function mapClarityTypeToTS(clarityType) {
|
|
2167
|
-
if (typeof clarityType !== "string") {
|
|
2168
|
-
if (clarityType?.uint || clarityType?.int)
|
|
2169
|
-
return "bigint";
|
|
2170
|
-
if (clarityType?.principal)
|
|
2171
|
-
return "string";
|
|
2172
|
-
if (clarityType?.bool)
|
|
2173
|
-
return "boolean";
|
|
2174
|
-
if (clarityType?.string || clarityType?.ascii)
|
|
2175
|
-
return "string";
|
|
2176
|
-
if (clarityType?.["string-ascii"] || clarityType?.["string-utf8"])
|
|
2177
|
-
return "string";
|
|
2178
|
-
if (clarityType?.buff)
|
|
2179
|
-
return "Uint8Array";
|
|
2180
|
-
if (clarityType?.optional) {
|
|
2181
|
-
const innerType = mapClarityTypeToTS(clarityType.optional);
|
|
2182
|
-
return `${innerType} | null`;
|
|
2183
|
-
}
|
|
2184
|
-
if (clarityType?.response) {
|
|
2185
|
-
const okType = mapClarityTypeToTS(clarityType.response.ok);
|
|
2186
|
-
const errType = mapClarityTypeToTS(clarityType.response.error);
|
|
2187
|
-
return `{ ok: ${okType} } | { err: ${errType} }`;
|
|
2188
|
-
}
|
|
2189
|
-
if (clarityType?.tuple) {
|
|
2190
|
-
const fields = clarityType.tuple.map((field) => `${toCamelCase4(field.name)}: ${mapClarityTypeToTS(field.type)}`).join("; ");
|
|
2191
|
-
return `{ ${fields} }`;
|
|
2192
|
-
}
|
|
2193
|
-
if (clarityType?.list) {
|
|
2194
|
-
const innerType = mapClarityTypeToTS(clarityType.list.type);
|
|
2195
|
-
if (innerType.includes(" | ")) {
|
|
2196
|
-
return `(${innerType})[]`;
|
|
2197
|
-
}
|
|
2198
|
-
return `${innerType}[]`;
|
|
2199
|
-
}
|
|
2200
|
-
return "any";
|
|
2201
|
-
}
|
|
2202
|
-
if (clarityType.includes("uint") || clarityType.includes("int"))
|
|
2203
|
-
return "bigint";
|
|
2204
|
-
if (clarityType.includes("principal"))
|
|
2205
|
-
return "string";
|
|
2206
|
-
if (clarityType.includes("bool"))
|
|
2207
|
-
return "boolean";
|
|
2208
|
-
if (clarityType.includes("string") || clarityType.includes("ascii"))
|
|
2209
|
-
return "string";
|
|
2210
|
-
if (clarityType.includes("buff"))
|
|
2211
|
-
return "Uint8Array";
|
|
2212
|
-
if (clarityType.includes("optional")) {
|
|
2213
|
-
const innerType = clarityType.replace(/optional\s*/, "").trim();
|
|
2214
|
-
return `${mapClarityTypeToTS(innerType)} | null`;
|
|
2215
|
-
}
|
|
2216
|
-
return "any";
|
|
2217
|
-
}
|
|
2218
2230
|
function generateObjectArgs(args) {
|
|
2219
2231
|
if (args.length === 0)
|
|
2220
2232
|
return "";
|
|
2221
|
-
return args.map((arg) => `${arg.name}: ${
|
|
2233
|
+
return args.map((arg) => `${arg.name}: ${toCamelCase5(arg.name)}`).join(", ");
|
|
2222
2234
|
}
|
|
2223
2235
|
|
|
2224
2236
|
// src/plugins/react/generators/contract.ts
|
|
@@ -2258,21 +2270,21 @@ function generateContractHookMethods(contract, excludeList) {
|
|
|
2258
2270
|
const readOnlyFunctions = functions.filter((f) => f.access === "read_only" || f.access === "read-only");
|
|
2259
2271
|
const publicFunctions = functions.filter((f) => f.access === "public");
|
|
2260
2272
|
const readHooks = readOnlyFunctions.map((func) => {
|
|
2261
|
-
const hookName = `use${capitalize(name)}${capitalize(
|
|
2273
|
+
const hookName = `use${capitalize(name)}${capitalize(toCamelCase5(func.name))}`;
|
|
2262
2274
|
if (excludeList.includes(hookName)) {
|
|
2263
2275
|
return null;
|
|
2264
2276
|
}
|
|
2265
2277
|
return generateReadHook(func, name);
|
|
2266
2278
|
}).filter(Boolean);
|
|
2267
2279
|
const writeHooks = publicFunctions.map((func) => {
|
|
2268
|
-
const hookName = `use${capitalize(name)}${capitalize(
|
|
2280
|
+
const hookName = `use${capitalize(name)}${capitalize(toCamelCase5(func.name))}`;
|
|
2269
2281
|
if (excludeList.includes(hookName)) {
|
|
2270
2282
|
return null;
|
|
2271
2283
|
}
|
|
2272
2284
|
return generateWriteHook(func, name);
|
|
2273
2285
|
}).filter(Boolean);
|
|
2274
2286
|
const mapHooks = maps.map((map) => {
|
|
2275
|
-
const hookName = `use${capitalize(name)}${capitalize(
|
|
2287
|
+
const hookName = `use${capitalize(name)}${capitalize(toCamelCase5(map.name))}`;
|
|
2276
2288
|
if (excludeList.includes(hookName)) {
|
|
2277
2289
|
return null;
|
|
2278
2290
|
}
|
|
@@ -2280,7 +2292,7 @@ function generateContractHookMethods(contract, excludeList) {
|
|
|
2280
2292
|
}).filter(Boolean);
|
|
2281
2293
|
const dataVars = variables.filter((v) => v.access === "variable");
|
|
2282
2294
|
const varHooks = dataVars.map((variable) => {
|
|
2283
|
-
const hookName = `use${capitalize(name)}${capitalize(
|
|
2295
|
+
const hookName = `use${capitalize(name)}${capitalize(toCamelCase5(variable.name))}`;
|
|
2284
2296
|
if (excludeList.includes(hookName)) {
|
|
2285
2297
|
return null;
|
|
2286
2298
|
}
|
|
@@ -2288,7 +2300,7 @@ function generateContractHookMethods(contract, excludeList) {
|
|
|
2288
2300
|
}).filter(Boolean);
|
|
2289
2301
|
const constants = variables.filter((v) => v.access === "constant");
|
|
2290
2302
|
const constantHooks = constants.map((constant) => {
|
|
2291
|
-
const hookName = `use${capitalize(name)}${capitalize(
|
|
2303
|
+
const hookName = `use${capitalize(name)}${capitalize(toCamelCase5(constant.name))}`;
|
|
2292
2304
|
if (excludeList.includes(hookName)) {
|
|
2293
2305
|
return null;
|
|
2294
2306
|
}
|
|
@@ -2303,16 +2315,16 @@ function generateContractHookMethods(contract, excludeList) {
|
|
|
2303
2315
|
`);
|
|
2304
2316
|
}
|
|
2305
2317
|
function generateReadHook(func, contractName) {
|
|
2306
|
-
const hookName = `use${capitalize(contractName)}${capitalize(
|
|
2318
|
+
const hookName = `use${capitalize(contractName)}${capitalize(toCamelCase5(func.name))}`;
|
|
2307
2319
|
const argsSignature = generateHookArgsSignature(func.args);
|
|
2308
2320
|
const enabledParam = func.args.length > 0 ? ", options?: { enabled?: boolean }" : "options?: { enabled?: boolean }";
|
|
2309
|
-
const returnType =
|
|
2321
|
+
const returnType = clarityTypeToTS(func.outputs);
|
|
2310
2322
|
return `export function ${hookName}(${argsSignature}${enabledParam}) {
|
|
2311
2323
|
const config = useStacksConfig()
|
|
2312
2324
|
|
|
2313
2325
|
return useQuery<${returnType}>({
|
|
2314
2326
|
queryKey: ['${func.name}', ${contractName}.address, ${generateQueryKeyArgs(func.args)}],
|
|
2315
|
-
queryFn: () => ${contractName}.read.${
|
|
2327
|
+
queryFn: () => ${contractName}.read.${toCamelCase5(func.name)}(${generateFunctionCallArgs(func.args) ? `{ ${generateObjectArgs(func.args)} }, ` : ""}{
|
|
2316
2328
|
network: config.network,
|
|
2317
2329
|
senderAddress: config.senderAddress || 'SP000000000000000000002Q6VF78'
|
|
2318
2330
|
}),
|
|
@@ -2322,7 +2334,7 @@ function generateReadHook(func, contractName) {
|
|
|
2322
2334
|
}`;
|
|
2323
2335
|
}
|
|
2324
2336
|
function generateWriteHook(func, contractName) {
|
|
2325
|
-
const hookName = `use${capitalize(contractName)}${capitalize(
|
|
2337
|
+
const hookName = `use${capitalize(contractName)}${capitalize(toCamelCase5(func.name))}`;
|
|
2326
2338
|
const argsType = generateArgsType(func.args);
|
|
2327
2339
|
return `export function ${hookName}() {
|
|
2328
2340
|
const config = useStacksConfig()
|
|
@@ -2339,7 +2351,7 @@ function generateWriteHook(func, contractName) {
|
|
|
2339
2351
|
};
|
|
2340
2352
|
}) => {
|
|
2341
2353
|
const { args, options = {} } = params
|
|
2342
|
-
const contractCallData = ${contractName}.${
|
|
2354
|
+
const contractCallData = ${contractName}.${toCamelCase5(func.name)}(args)
|
|
2343
2355
|
const { contractAddress, contractName: name, functionName, functionArgs } = contractCallData
|
|
2344
2356
|
const network = config.network || 'mainnet'
|
|
2345
2357
|
const contract = \`\${contractAddress}.\${name}\`
|
|
@@ -2389,7 +2401,7 @@ function generateWriteHook(func, contractName) {
|
|
|
2389
2401
|
}
|
|
2390
2402
|
})
|
|
2391
2403
|
|
|
2392
|
-
const ${
|
|
2404
|
+
const ${toCamelCase5(func.name)} = useCallback(async (
|
|
2393
2405
|
args: ${argsType},
|
|
2394
2406
|
options?: {
|
|
2395
2407
|
postConditions?: PostCondition[];
|
|
@@ -2402,7 +2414,7 @@ function generateWriteHook(func, contractName) {
|
|
|
2402
2414
|
}, [mutation])
|
|
2403
2415
|
|
|
2404
2416
|
return {
|
|
2405
|
-
${
|
|
2417
|
+
${toCamelCase5(func.name)},
|
|
2406
2418
|
// Expose mutation state
|
|
2407
2419
|
isPending: mutation.isPending,
|
|
2408
2420
|
isError: mutation.isError,
|
|
@@ -2414,46 +2426,46 @@ function generateWriteHook(func, contractName) {
|
|
|
2414
2426
|
}`;
|
|
2415
2427
|
}
|
|
2416
2428
|
function generateMapHook(map, contractVarName, _address, _contractName) {
|
|
2417
|
-
const hookName = `use${capitalize(contractVarName)}${capitalize(
|
|
2418
|
-
const keyType =
|
|
2419
|
-
const valueType =
|
|
2429
|
+
const hookName = `use${capitalize(contractVarName)}${capitalize(toCamelCase5(map.name))}`;
|
|
2430
|
+
const keyType = clarityTypeToTS(map.key);
|
|
2431
|
+
const valueType = clarityTypeToTS(map.value);
|
|
2420
2432
|
return `export function ${hookName}(key: ${keyType}, options?: { enabled?: boolean }) {
|
|
2421
2433
|
const config = useStacksConfig()
|
|
2422
2434
|
|
|
2423
2435
|
return useQuery<${valueType} | null>({
|
|
2424
2436
|
queryKey: ['${contractVarName}', '${map.name}', 'map', key, config.network],
|
|
2425
2437
|
queryFn: async () => {
|
|
2426
|
-
return ${contractVarName}.maps.${
|
|
2438
|
+
return ${contractVarName}.maps.${toCamelCase5(map.name)}.get(key, { network: config.network })
|
|
2427
2439
|
},
|
|
2428
2440
|
enabled: options?.enabled ?? true
|
|
2429
2441
|
})
|
|
2430
2442
|
}`;
|
|
2431
2443
|
}
|
|
2432
2444
|
function generateVarHook(variable, contractVarName, _address, _contractName) {
|
|
2433
|
-
const hookName = `use${capitalize(contractVarName)}${capitalize(
|
|
2434
|
-
const valueType =
|
|
2445
|
+
const hookName = `use${capitalize(contractVarName)}${capitalize(toCamelCase5(variable.name))}`;
|
|
2446
|
+
const valueType = clarityTypeToTS(variable.type);
|
|
2435
2447
|
return `export function ${hookName}(options?: { enabled?: boolean }) {
|
|
2436
2448
|
const config = useStacksConfig()
|
|
2437
2449
|
|
|
2438
2450
|
return useQuery<${valueType}>({
|
|
2439
2451
|
queryKey: ['${contractVarName}', '${variable.name}', 'var', config.network],
|
|
2440
2452
|
queryFn: async () => {
|
|
2441
|
-
return ${contractVarName}.vars.${
|
|
2453
|
+
return ${contractVarName}.vars.${toCamelCase5(variable.name)}.get({ network: config.network })
|
|
2442
2454
|
},
|
|
2443
2455
|
enabled: options?.enabled ?? true
|
|
2444
2456
|
})
|
|
2445
2457
|
}`;
|
|
2446
2458
|
}
|
|
2447
2459
|
function generateConstantHook(constant, contractVarName, _address, _contractName) {
|
|
2448
|
-
const hookName = `use${capitalize(contractVarName)}${capitalize(
|
|
2449
|
-
const valueType =
|
|
2460
|
+
const hookName = `use${capitalize(contractVarName)}${capitalize(toCamelCase5(constant.name))}`;
|
|
2461
|
+
const valueType = clarityTypeToTS(constant.type);
|
|
2450
2462
|
return `export function ${hookName}(options?: { enabled?: boolean }) {
|
|
2451
2463
|
const config = useStacksConfig()
|
|
2452
2464
|
|
|
2453
2465
|
return useQuery<${valueType}>({
|
|
2454
2466
|
queryKey: ['${contractVarName}', '${constant.name}', 'constant', config.network],
|
|
2455
2467
|
queryFn: async () => {
|
|
2456
|
-
return ${contractVarName}.constants.${
|
|
2468
|
+
return ${contractVarName}.constants.${toCamelCase5(constant.name)}.get({ network: config.network })
|
|
2457
2469
|
},
|
|
2458
2470
|
enabled: options?.enabled ?? true,
|
|
2459
2471
|
staleTime: Infinity // Constants never change
|
|
@@ -2500,60 +2512,19 @@ var react = (options = {}) => {
|
|
|
2500
2512
|
};
|
|
2501
2513
|
};
|
|
2502
2514
|
// src/plugins/testing/generators.ts
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
}
|
|
2515
|
+
import {
|
|
2516
|
+
toCamelCase as toCamelCase6
|
|
2517
|
+
} from "@secondlayer/clarity-types";
|
|
2506
2518
|
function toPascalCase(str) {
|
|
2507
|
-
const camel =
|
|
2519
|
+
const camel = toCamelCase6(str);
|
|
2508
2520
|
return camel.charAt(0).toUpperCase() + camel.slice(1);
|
|
2509
2521
|
}
|
|
2510
|
-
function getTypeForArg3(arg) {
|
|
2511
|
-
const type = arg.type;
|
|
2512
|
-
if (typeof type === "string") {
|
|
2513
|
-
switch (type) {
|
|
2514
|
-
case "uint128":
|
|
2515
|
-
case "int128":
|
|
2516
|
-
return "bigint";
|
|
2517
|
-
case "bool":
|
|
2518
|
-
return "boolean";
|
|
2519
|
-
case "principal":
|
|
2520
|
-
case "trait_reference":
|
|
2521
|
-
return "string";
|
|
2522
|
-
default:
|
|
2523
|
-
return "any";
|
|
2524
|
-
}
|
|
2525
|
-
}
|
|
2526
|
-
if (type["string-ascii"] || type["string-utf8"]) {
|
|
2527
|
-
return "string";
|
|
2528
|
-
}
|
|
2529
|
-
if (type.buff) {
|
|
2530
|
-
return "Uint8Array | string | { type: 'ascii' | 'utf8' | 'hex'; value: string }";
|
|
2531
|
-
}
|
|
2532
|
-
if (type.optional) {
|
|
2533
|
-
const innerType = getTypeForArg3({ type: type.optional });
|
|
2534
|
-
return `${innerType} | null`;
|
|
2535
|
-
}
|
|
2536
|
-
if (type.list) {
|
|
2537
|
-
const innerType = getTypeForArg3({ type: type.list.type });
|
|
2538
|
-
return `${innerType}[]`;
|
|
2539
|
-
}
|
|
2540
|
-
if (type.tuple) {
|
|
2541
|
-
const fields = type.tuple.map((field) => `${toCamelCase5(field.name)}: ${getTypeForArg3({ type: field.type })}`).join("; ");
|
|
2542
|
-
return `{ ${fields} }`;
|
|
2543
|
-
}
|
|
2544
|
-
if (type.response) {
|
|
2545
|
-
const okType = getTypeForArg3({ type: type.response.ok });
|
|
2546
|
-
const errType = getTypeForArg3({ type: type.response.error });
|
|
2547
|
-
return `{ ok: ${okType} } | { err: ${errType} }`;
|
|
2548
|
-
}
|
|
2549
|
-
return "any";
|
|
2550
|
-
}
|
|
2551
2522
|
function generateArgsSignature2(args) {
|
|
2552
2523
|
if (args.length === 0)
|
|
2553
2524
|
return "";
|
|
2554
2525
|
const argsTypes = args.map((arg) => {
|
|
2555
|
-
const camelName =
|
|
2556
|
-
return `${camelName}: ${
|
|
2526
|
+
const camelName = toCamelCase6(arg.name);
|
|
2527
|
+
return `${camelName}: ${getTypeForArg(arg)}`;
|
|
2557
2528
|
}).join("; ");
|
|
2558
2529
|
return `args: { ${argsTypes} }, `;
|
|
2559
2530
|
}
|
|
@@ -2628,24 +2599,54 @@ function generateClarityConversion3(argName, argType) {
|
|
|
2628
2599
|
const innerConversion = generateClarityConversion3("item", {
|
|
2629
2600
|
type: type.list.type
|
|
2630
2601
|
});
|
|
2631
|
-
|
|
2602
|
+
const maxLength = type.list.length || 100;
|
|
2603
|
+
return `(() => {
|
|
2604
|
+
const listValue = ${argName};
|
|
2605
|
+
if (listValue.length > ${maxLength}) {
|
|
2606
|
+
throw new Error(\`List length \${listValue.length} exceeds max ${maxLength}\`);
|
|
2607
|
+
}
|
|
2608
|
+
return Cl.list(listValue.map(item => ${innerConversion}));
|
|
2609
|
+
})()`;
|
|
2632
2610
|
}
|
|
2633
2611
|
if (type.tuple) {
|
|
2612
|
+
const requiredFields = type.tuple.map((f) => f.name);
|
|
2613
|
+
const fieldNames = JSON.stringify(requiredFields);
|
|
2634
2614
|
const fields = type.tuple.map((field) => {
|
|
2635
|
-
const camelFieldName =
|
|
2636
|
-
const fieldConversion = generateClarityConversion3(
|
|
2615
|
+
const camelFieldName = toCamelCase6(field.name);
|
|
2616
|
+
const fieldConversion = generateClarityConversion3(`tupleValue.${camelFieldName}`, { type: field.type });
|
|
2637
2617
|
return `"${field.name}": ${fieldConversion}`;
|
|
2638
2618
|
}).join(", ");
|
|
2639
|
-
return `
|
|
2619
|
+
return `(() => {
|
|
2620
|
+
const tupleValue = ${argName};
|
|
2621
|
+
const requiredFields = ${fieldNames};
|
|
2622
|
+
for (const fieldName of requiredFields) {
|
|
2623
|
+
const camelName = fieldName.replace(/-([a-z])/g, (_: string, l: string) => l.toUpperCase());
|
|
2624
|
+
if (!(fieldName in tupleValue) && !(camelName in tupleValue)) {
|
|
2625
|
+
throw new Error(\`Missing tuple field: \${fieldName}\`);
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
return Cl.tuple({ ${fields} });
|
|
2629
|
+
})()`;
|
|
2640
2630
|
}
|
|
2641
2631
|
if (type.response) {
|
|
2642
|
-
const okConversion = generateClarityConversion3(
|
|
2632
|
+
const okConversion = generateClarityConversion3(`responseValue.ok`, {
|
|
2643
2633
|
type: type.response.ok
|
|
2644
2634
|
});
|
|
2645
|
-
const errConversion = generateClarityConversion3(
|
|
2635
|
+
const errConversion = generateClarityConversion3(`responseValue.err`, {
|
|
2646
2636
|
type: type.response.error
|
|
2647
2637
|
});
|
|
2648
|
-
return `
|
|
2638
|
+
return `(() => {
|
|
2639
|
+
const responseValue = ${argName};
|
|
2640
|
+
const hasOk = 'ok' in responseValue;
|
|
2641
|
+
const hasErr = 'err' in responseValue;
|
|
2642
|
+
if (hasOk && !hasErr) {
|
|
2643
|
+
return Cl.ok(${okConversion});
|
|
2644
|
+
}
|
|
2645
|
+
if (hasErr && !hasOk) {
|
|
2646
|
+
return Cl.error(${errConversion});
|
|
2647
|
+
}
|
|
2648
|
+
throw new Error("Response must have exactly 'ok' or 'err' property");
|
|
2649
|
+
})()`;
|
|
2649
2650
|
}
|
|
2650
2651
|
return `${argName}`;
|
|
2651
2652
|
}
|
|
@@ -2653,12 +2654,12 @@ function generateClarityArgs2(args) {
|
|
|
2653
2654
|
if (args.length === 0)
|
|
2654
2655
|
return "";
|
|
2655
2656
|
return args.map((arg) => {
|
|
2656
|
-
const argName = `args.${
|
|
2657
|
+
const argName = `args.${toCamelCase6(arg.name)}`;
|
|
2657
2658
|
return generateClarityConversion3(argName, arg);
|
|
2658
2659
|
}).join(", ");
|
|
2659
2660
|
}
|
|
2660
2661
|
function generatePublicFunction(func, contractId) {
|
|
2661
|
-
const methodName =
|
|
2662
|
+
const methodName = toCamelCase6(func.name);
|
|
2662
2663
|
const argsSignature = generateArgsSignature2(func.args);
|
|
2663
2664
|
const clarityArgs = generateClarityArgs2(func.args);
|
|
2664
2665
|
return `${methodName}: (${argsSignature}caller: string) => {
|
|
@@ -2672,7 +2673,7 @@ function generatePublicFunction(func, contractId) {
|
|
|
2672
2673
|
}`;
|
|
2673
2674
|
}
|
|
2674
2675
|
function generateReadOnlyFunction(func, contractId) {
|
|
2675
|
-
const methodName =
|
|
2676
|
+
const methodName = toCamelCase6(func.name);
|
|
2676
2677
|
const argsSignature = generateArgsSignature2(func.args);
|
|
2677
2678
|
const clarityArgs = generateClarityArgs2(func.args);
|
|
2678
2679
|
const hasArgs = func.args.length > 0;
|
|
@@ -2687,7 +2688,7 @@ function generateReadOnlyFunction(func, contractId) {
|
|
|
2687
2688
|
}`;
|
|
2688
2689
|
}
|
|
2689
2690
|
function generatePrivateFunction(func, contractId) {
|
|
2690
|
-
const methodName =
|
|
2691
|
+
const methodName = toCamelCase6(func.name);
|
|
2691
2692
|
const argsSignature = generateArgsSignature2(func.args);
|
|
2692
2693
|
const clarityArgs = generateClarityArgs2(func.args);
|
|
2693
2694
|
return `${methodName}: (${argsSignature}caller: string) => {
|
|
@@ -2701,22 +2702,22 @@ function generatePrivateFunction(func, contractId) {
|
|
|
2701
2702
|
}`;
|
|
2702
2703
|
}
|
|
2703
2704
|
function generateDataVarHelper(variable, contractId) {
|
|
2704
|
-
const methodName =
|
|
2705
|
+
const methodName = toCamelCase6(variable.name);
|
|
2705
2706
|
return `${methodName}: () => {
|
|
2706
2707
|
return simnet.getDataVar('${contractId}', '${variable.name}');
|
|
2707
2708
|
}`;
|
|
2708
2709
|
}
|
|
2709
2710
|
function getMapKeyType(keyType) {
|
|
2710
2711
|
if (keyType.tuple) {
|
|
2711
|
-
const fields = keyType.tuple.map((field) => `${
|
|
2712
|
+
const fields = keyType.tuple.map((field) => `${toCamelCase6(field.name)}: ${getTypeForArg({ type: field.type })}`).join("; ");
|
|
2712
2713
|
return `{ ${fields} }`;
|
|
2713
2714
|
}
|
|
2714
|
-
return
|
|
2715
|
+
return getTypeForArg({ type: keyType });
|
|
2715
2716
|
}
|
|
2716
2717
|
function generateMapKeyConversion2(keyType) {
|
|
2717
2718
|
if (keyType.tuple) {
|
|
2718
2719
|
const fields = keyType.tuple.map((field) => {
|
|
2719
|
-
const camelFieldName =
|
|
2720
|
+
const camelFieldName = toCamelCase6(field.name);
|
|
2720
2721
|
const fieldConversion = generateClarityConversion3(`key.${camelFieldName}`, { type: field.type });
|
|
2721
2722
|
return `"${field.name}": ${fieldConversion}`;
|
|
2722
2723
|
}).join(", ");
|
|
@@ -2725,7 +2726,7 @@ function generateMapKeyConversion2(keyType) {
|
|
|
2725
2726
|
return generateClarityConversion3("key", { type: keyType });
|
|
2726
2727
|
}
|
|
2727
2728
|
function generateMapEntryHelper(map, contractId) {
|
|
2728
|
-
const methodName =
|
|
2729
|
+
const methodName = toCamelCase6(map.name);
|
|
2729
2730
|
const keyType = getMapKeyType(map.key);
|
|
2730
2731
|
const keyConversion = generateMapKeyConversion2(map.key);
|
|
2731
2732
|
return `${methodName}: (key: ${keyType}) => {
|
|
@@ -2795,7 +2796,7 @@ function generateContractHelper(contract, options) {
|
|
|
2795
2796
|
}
|
|
2796
2797
|
function generateGetContracts(contracts) {
|
|
2797
2798
|
const contractEntries = contracts.map((contract) => {
|
|
2798
|
-
const camelName =
|
|
2799
|
+
const camelName = toCamelCase6(contract.name);
|
|
2799
2800
|
const pascalName = toPascalCase(contract.name);
|
|
2800
2801
|
return `${camelName}: get${pascalName}(simnet)`;
|
|
2801
2802
|
}).join(`,
|
|
@@ -2923,5 +2924,5 @@ export {
|
|
|
2923
2924
|
PluginManager
|
|
2924
2925
|
};
|
|
2925
2926
|
|
|
2926
|
-
//# debugId=
|
|
2927
|
+
//# debugId=7C8745101A6FCC2D64756E2164756E21
|
|
2927
2928
|
//# sourceMappingURL=index.js.map
|