@better-sol/cli 0.1.0-alpha.11 → 0.1.0-alpha.12
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/index.js +71 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -388,13 +388,11 @@ function collectAccounts(source, program, rawStructZCs) {
|
|
|
388
388
|
const firstArg = call.arguments[0];
|
|
389
389
|
if (firstArg === void 0 || !isObjectExpression(firstArg)) continue;
|
|
390
390
|
const fields = parseFields(source, firstArg);
|
|
391
|
-
const
|
|
392
|
-
if (chainText.includes(".pda(")) throw new Error(".pda() was renamed to .derive(). Use .derive((seed) => ['literal', seed.fieldName]).");
|
|
393
|
-
if (chainText.includes(".seeds(")) throw new Error(".seeds() was removed. Use .derive((seed) => ['literal', seed.fieldName]).");
|
|
394
|
-
const zeroCopy = chainText.includes(".zeroCopy");
|
|
391
|
+
const zeroCopy = hasChainMethod(source, decl.init, "zeroCopy");
|
|
395
392
|
if (zeroCopy) validateZeroCopyFields(name, fields, rawStructZCs);
|
|
396
|
-
const
|
|
397
|
-
const
|
|
393
|
+
const deriveCall = findChainCall(source, decl.init, "derive");
|
|
394
|
+
const seeds = deriveCall !== void 0 ? parseSeedsFromAst(source, deriveCall) : [];
|
|
395
|
+
const hasOneFields = parseHasOneFieldsFromAst(source, decl.init);
|
|
398
396
|
accounts.push({
|
|
399
397
|
name,
|
|
400
398
|
fields,
|
|
@@ -578,6 +576,17 @@ function resolveConstraint(source, prop, accountName, rawAccounts) {
|
|
|
578
576
|
};
|
|
579
577
|
}
|
|
580
578
|
case "remaining": {
|
|
579
|
+
const argNode = init.arguments[0];
|
|
580
|
+
if (argNode !== void 0 && isIdentifier(argNode)) {
|
|
581
|
+
if (argNode.name === "tokenAccount" || argNode.name.includes("TokenAccount") || argNode.name.includes("tokenAccount")) return {
|
|
582
|
+
kind: "remaining",
|
|
583
|
+
itemType: "tokenAccount"
|
|
584
|
+
};
|
|
585
|
+
if (argNode.name === "signer" || argNode.name.includes("Signer")) return {
|
|
586
|
+
kind: "remaining",
|
|
587
|
+
itemType: "signer"
|
|
588
|
+
};
|
|
589
|
+
}
|
|
581
590
|
const argText = getCallArgText(source, init, 0) ?? "";
|
|
582
591
|
if (argText.includes("tokenAccount")) return {
|
|
583
592
|
kind: "remaining",
|
|
@@ -704,50 +713,73 @@ function tryResolvePrimitive(name) {
|
|
|
704
713
|
"bytes"
|
|
705
714
|
].includes(name) ? name : void 0;
|
|
706
715
|
}
|
|
707
|
-
function
|
|
708
|
-
|
|
709
|
-
|
|
716
|
+
function hasChainMethod(source, node, methodName) {
|
|
717
|
+
return findChainCall(source, node, methodName) !== void 0;
|
|
718
|
+
}
|
|
719
|
+
function findChainCall(source, node, methodName) {
|
|
720
|
+
let current = node;
|
|
721
|
+
while (current !== void 0) {
|
|
722
|
+
if (!isCallExpression(current)) break;
|
|
723
|
+
if (isMemberExpression(current.callee)) {
|
|
724
|
+
if (getMemberPropertyName(source, current.callee) === methodName) return current;
|
|
725
|
+
current = current.callee.object;
|
|
726
|
+
} else break;
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
function parseSeedsFromAst(source, deriveCall) {
|
|
730
|
+
const firstArg = deriveCall.arguments[0];
|
|
731
|
+
if (firstArg === void 0 || !isArrowFunctionExpression(firstArg)) return [];
|
|
732
|
+
const body = unwrapParenthesized(firstArg.body);
|
|
733
|
+
if (!isArrayExpression(body)) return [];
|
|
710
734
|
const seeds = [];
|
|
711
|
-
const
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
const singleQuotedLiteral = match[2];
|
|
716
|
-
const doubleQuotedLiteral = match[3];
|
|
717
|
-
if (field !== void 0) seeds.push({
|
|
718
|
-
kind: "field",
|
|
719
|
-
fieldName: field
|
|
720
|
-
});
|
|
721
|
-
else if (singleQuotedLiteral !== void 0 && singleQuotedLiteral !== "") seeds.push(parseLiteralSeed(singleQuotedLiteral));
|
|
722
|
-
else if (doubleQuotedLiteral !== void 0 && doubleQuotedLiteral !== "") seeds.push(parseLiteralSeed(doubleQuotedLiteral));
|
|
735
|
+
for (const element of body.elements) {
|
|
736
|
+
if (element === void 0 || element === null || isSpreadElement(element)) continue;
|
|
737
|
+
const seed = parseSingleSeed(source, element);
|
|
738
|
+
if (seed !== void 0) seeds.push(seed);
|
|
723
739
|
}
|
|
724
740
|
return seeds;
|
|
725
741
|
}
|
|
742
|
+
function parseSingleSeed(source, node) {
|
|
743
|
+
if (isStringLiteral(node)) return parseLiteralSeed(node.value);
|
|
744
|
+
if (isTemplateLiteral(node) && node.quasis.length === 1) {
|
|
745
|
+
const quasi = node.quasis[0];
|
|
746
|
+
if (quasi !== void 0) return parseLiteralSeed(quasi.value.cooked ?? quasi.value.raw);
|
|
747
|
+
}
|
|
748
|
+
if (isMemberExpression(node)) {
|
|
749
|
+
const property = getMemberPropertyName(source, node);
|
|
750
|
+
if (property !== void 0) return {
|
|
751
|
+
kind: "field",
|
|
752
|
+
fieldName: property
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
if (isCallExpression(node) && isMemberExpression(node.callee)) {
|
|
756
|
+
const property = getMemberPropertyName(source, node.callee);
|
|
757
|
+
if (property !== void 0) return {
|
|
758
|
+
kind: "field",
|
|
759
|
+
fieldName: property
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
}
|
|
726
763
|
function parseLiteralSeed(value) {
|
|
727
|
-
if (/^\{[A-Za-z_$][\w$]*\}$/.test(value)) throw new Error(`Dynamic PDA seed template '${value}' is not supported. Store the value as an account field and reference it with seed.${value.slice(1, -1)}.`);
|
|
728
764
|
return {
|
|
729
765
|
kind: "literal",
|
|
730
766
|
value
|
|
731
767
|
};
|
|
732
768
|
}
|
|
733
|
-
function
|
|
769
|
+
function parseHasOneFieldsFromAst(source, node) {
|
|
734
770
|
const fields = [];
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
for (let index = argsStart; index < chainText.length; index += 1) {
|
|
746
|
-
const char = chainText[index];
|
|
747
|
-
if (char === "(") depth += 1;
|
|
748
|
-
else if (char === ")") depth -= 1;
|
|
749
|
-
if (depth === 0) return chainText.slice(argsStart, index);
|
|
771
|
+
let current = node;
|
|
772
|
+
while (current !== void 0) {
|
|
773
|
+
if (!isCallExpression(current)) break;
|
|
774
|
+
if (isMemberExpression(current.callee)) {
|
|
775
|
+
if (getMemberPropertyName(source, current.callee) === "hasOne") {
|
|
776
|
+
const arg = current.arguments[0];
|
|
777
|
+
if (isStringLiteral(arg)) fields.push(arg.value);
|
|
778
|
+
}
|
|
779
|
+
current = current.callee.object;
|
|
780
|
+
} else break;
|
|
750
781
|
}
|
|
782
|
+
return fields;
|
|
751
783
|
}
|
|
752
784
|
function validateZeroCopyFields(accountName, fields, structs) {
|
|
753
785
|
for (const field of fields) try {
|
|
@@ -69328,7 +69360,7 @@ async function gitCommit() {
|
|
|
69328
69360
|
//#endregion
|
|
69329
69361
|
//#region src/index.ts
|
|
69330
69362
|
const cli = new Command();
|
|
69331
|
-
cli.name("better-sol").description("Write Solana programs in TypeScript. Run with npx @better-sol/cli@alpha").version("0.1.0-alpha.
|
|
69363
|
+
cli.name("better-sol").description("Write Solana programs in TypeScript. Run with npx @better-sol/cli@alpha").version("0.1.0-alpha.12");
|
|
69332
69364
|
cli.command("init").description("Initialize a better-sol project").option("--force", "overwrite existing files", false).option("--skip-install", "skip installing dependencies", false).action((options) => run(() => init(options)));
|
|
69333
69365
|
cli.command("create").description("Create a new better-sol program").argument("[name]", "program name").option("--dir <dir>", "program directory", "programs").option("--force", "overwrite existing files", false).action((name, options) => run(() => create(name, options)));
|
|
69334
69366
|
cli.command("login").description("Save your compiler API key").argument("[apiKey]", "compiler API key").action((apiKey) => run(() => login(apiKey)));
|