@clarigen/cli 3.1.0 → 3.2.0
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.cjs +80 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -146
- package/dist/index.d.ts +12 -146
- package/dist/index.js +78 -60
- package/dist/index.js.map +1 -1
- package/dist/run-cli.cjs +158 -78
- package/dist/run-cli.cjs.map +1 -1
- package/dist/run-cli.js +150 -70
- package/dist/run-cli.js.map +1 -1
- package/package.json +8 -8
package/dist/run-cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import { Cli, Builtins } from "clipanion";
|
|
|
7
7
|
import { Command as Command2, Option as Option2 } from "clipanion";
|
|
8
8
|
|
|
9
9
|
// src/config.ts
|
|
10
|
-
import {
|
|
10
|
+
import { type as type2 } from "arktype";
|
|
11
11
|
|
|
12
12
|
// src/logger.ts
|
|
13
13
|
import { pino } from "pino";
|
|
@@ -57,19 +57,27 @@ function sortContracts(contracts) {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
// src/clarinet-config.ts
|
|
60
|
-
import {
|
|
60
|
+
import { type } from "arktype";
|
|
61
61
|
import { readFile } from "fs/promises";
|
|
62
62
|
import { parse } from "@iarna/toml";
|
|
63
|
-
var
|
|
64
|
-
project:
|
|
65
|
-
requirements:
|
|
66
|
-
|
|
63
|
+
var ClarinetConfig = type({
|
|
64
|
+
project: type({
|
|
65
|
+
requirements: type({
|
|
66
|
+
contract_id: type("string").describe("Contract ID")
|
|
67
|
+
}).array().describe("Project requirements").optional(),
|
|
68
|
+
cache_location: type({
|
|
69
|
+
path: type("string").describe("Cache location path")
|
|
70
|
+
}).optional()
|
|
67
71
|
}),
|
|
68
|
-
contracts:
|
|
72
|
+
contracts: type({
|
|
73
|
+
"[string]": type({
|
|
74
|
+
path: type("string").describe("Contract path")
|
|
75
|
+
})
|
|
76
|
+
}).optional()
|
|
69
77
|
});
|
|
70
78
|
async function getClarinetConfig(path) {
|
|
71
79
|
const file = await readFile(path, "utf-8");
|
|
72
|
-
const config =
|
|
80
|
+
const config = ClarinetConfig.assert(parse(file));
|
|
73
81
|
return config;
|
|
74
82
|
}
|
|
75
83
|
|
|
@@ -78,23 +86,23 @@ import { dirname as dirname2, join, relative as relative2, resolve as resolve2 }
|
|
|
78
86
|
import { stringify, parse as parse2 } from "@iarna/toml";
|
|
79
87
|
import { readFile as readFile2 } from "fs/promises";
|
|
80
88
|
var CONFIG_FILE = "Clarigen.toml";
|
|
81
|
-
var typesSchema =
|
|
82
|
-
output:
|
|
83
|
-
outputs:
|
|
84
|
-
include_accounts:
|
|
85
|
-
after:
|
|
86
|
-
include_boot_contracts:
|
|
87
|
-
watch_folders:
|
|
89
|
+
var typesSchema = type2({
|
|
90
|
+
"output?": type2("string").describe("Path to the output file"),
|
|
91
|
+
"outputs?": type2("string[]").describe("Paths to the output files"),
|
|
92
|
+
"include_accounts?": type2("boolean").describe("Include accounts in the output"),
|
|
93
|
+
"after?": type2("string").describe("Script to run after the output is generated"),
|
|
94
|
+
"include_boot_contracts?": type2("boolean").describe("Include boot contracts in the output"),
|
|
95
|
+
"watch_folders?": type2("string[]").describe("Folders to watch for changes")
|
|
88
96
|
}).optional();
|
|
89
|
-
var
|
|
90
|
-
clarinet:
|
|
97
|
+
var ConfigFile = type2({
|
|
98
|
+
clarinet: type2("string").describe("Path to the Clarinet config file"),
|
|
91
99
|
["types" /* ESM */]: typesSchema,
|
|
92
100
|
["esm" /* ESM_OLD */]: typesSchema,
|
|
93
|
-
["docs" /* Docs */]:
|
|
94
|
-
output:
|
|
95
|
-
outputs:
|
|
96
|
-
exclude:
|
|
97
|
-
after:
|
|
101
|
+
["docs" /* Docs */]: type2({
|
|
102
|
+
"output?": type2("string").describe("Path to docs output folder. Defaults to ./docs"),
|
|
103
|
+
"outputs?": type2("string[]").describe("Paths to docs output folders"),
|
|
104
|
+
"exclude?": type2("string[]").describe("Contracts to exclude from docs generation"),
|
|
105
|
+
"after?": type2("string").describe("Script to run after docs are generated")
|
|
98
106
|
}).optional()
|
|
99
107
|
});
|
|
100
108
|
var defaultConfigFile = {
|
|
@@ -118,36 +126,36 @@ var Config = class {
|
|
|
118
126
|
const clarinet = await getClarinetConfig(resolve2(cwd ?? "", config.clarinet));
|
|
119
127
|
return new this(config, clarinet, cwd);
|
|
120
128
|
}
|
|
121
|
-
getOutputs(
|
|
129
|
+
getOutputs(type4) {
|
|
122
130
|
var _a, _b;
|
|
123
|
-
const singlePath = (_a = this.configFile[
|
|
124
|
-
const multiPath = ((_b = this.configFile[
|
|
131
|
+
const singlePath = (_a = this.configFile[type4]) == null ? void 0 : _a.output;
|
|
132
|
+
const multiPath = ((_b = this.configFile[type4]) == null ? void 0 : _b.outputs) || [];
|
|
125
133
|
if (singlePath !== void 0) return [singlePath];
|
|
126
134
|
return multiPath;
|
|
127
135
|
}
|
|
128
|
-
outputResolve(
|
|
129
|
-
const outputs = this.getOutputs(
|
|
130
|
-
if (!this.supports(
|
|
136
|
+
outputResolve(type4, filePath) {
|
|
137
|
+
const outputs = this.getOutputs(type4);
|
|
138
|
+
if (!this.supports(type4)) return null;
|
|
131
139
|
return outputs.map((path) => {
|
|
132
140
|
return resolve2(this.cwd, path, filePath || "");
|
|
133
141
|
});
|
|
134
142
|
}
|
|
135
|
-
async writeOutput(
|
|
136
|
-
const paths = this.outputResolve(
|
|
143
|
+
async writeOutput(type4, contents, filePath) {
|
|
144
|
+
const paths = this.outputResolve(type4, filePath);
|
|
137
145
|
if (paths === null) return null;
|
|
138
146
|
await Promise.all(
|
|
139
147
|
paths.map(async (path) => {
|
|
140
148
|
await writeFile(path, contents);
|
|
141
|
-
log.debug(`Generated ${
|
|
149
|
+
log.debug(`Generated ${type4} file at ${relative2(this.cwd, path)}`);
|
|
142
150
|
})
|
|
143
151
|
);
|
|
144
152
|
return paths;
|
|
145
153
|
}
|
|
146
|
-
supports(
|
|
147
|
-
return this.getOutputs(
|
|
154
|
+
supports(type4) {
|
|
155
|
+
return this.getOutputs(type4).length > 0;
|
|
148
156
|
}
|
|
149
|
-
type(
|
|
150
|
-
return this.configFile[
|
|
157
|
+
type(type4) {
|
|
158
|
+
return this.configFile[type4];
|
|
151
159
|
}
|
|
152
160
|
get esm() {
|
|
153
161
|
return this.configFile["types" /* ESM */];
|
|
@@ -173,16 +181,12 @@ async function getConfig(cwd) {
|
|
|
173
181
|
if (await fileExists(path)) {
|
|
174
182
|
const toml = await readFile2(path, "utf-8");
|
|
175
183
|
const parsedToml = parse2(toml);
|
|
176
|
-
const
|
|
177
|
-
if (
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
logger.error("Error parsing Clarigen.toml:");
|
|
181
|
-
parseResult.error.errors.forEach((e) => {
|
|
182
|
-
logger.error(`${e.path.join(".")}: ${e.message}`);
|
|
183
|
-
});
|
|
184
|
-
throw new Error("Error parsing Clarigen.toml");
|
|
184
|
+
const parsed = ConfigFile(parsedToml);
|
|
185
|
+
if (parsed instanceof type2.errors) {
|
|
186
|
+
logger.error(`Error parsing Clarigen config: ${parsed.summary}`);
|
|
187
|
+
throw new Error(`Error parsing Clarigen config: ${parsed.summary}`);
|
|
185
188
|
}
|
|
189
|
+
sessionConfig = parsed;
|
|
186
190
|
} else {
|
|
187
191
|
sessionConfig = defaultConfigFile;
|
|
188
192
|
}
|
|
@@ -191,7 +195,7 @@ async function getConfig(cwd) {
|
|
|
191
195
|
|
|
192
196
|
// src/commands/base-command.ts
|
|
193
197
|
import { Command, Option } from "clipanion";
|
|
194
|
-
import {
|
|
198
|
+
import { type as type3 } from "arktype";
|
|
195
199
|
var BaseCommand = class extends Command {
|
|
196
200
|
verbose = Option.Boolean("-v,--verbose", false, {
|
|
197
201
|
description: "Enable verbose logging"
|
|
@@ -203,8 +207,8 @@ var BaseCommand = class extends Command {
|
|
|
203
207
|
}
|
|
204
208
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
205
209
|
async catch(error) {
|
|
206
|
-
if (error instanceof
|
|
207
|
-
logger.error(
|
|
210
|
+
if (error instanceof type3.errors) {
|
|
211
|
+
logger.error("Your configuration file is invalid.", error.summary);
|
|
208
212
|
return;
|
|
209
213
|
}
|
|
210
214
|
logger.error(error);
|
|
@@ -291,9 +295,9 @@ var jsTypeFromAbiType = (val, isArgument = false) => {
|
|
|
291
295
|
return `${innerType} | null`;
|
|
292
296
|
} else if (isClarityAbiTuple(val)) {
|
|
293
297
|
const tupleDefs = [];
|
|
294
|
-
val.tuple.forEach(({ name, type }) => {
|
|
298
|
+
val.tuple.forEach(({ name, type: type4 }) => {
|
|
295
299
|
const camelName = toCamelCase2(name);
|
|
296
|
-
const innerType = jsTypeFromAbiType(
|
|
300
|
+
const innerType = jsTypeFromAbiType(type4, isArgument);
|
|
297
301
|
tupleDefs.push(`"${camelName}": ${innerType};`);
|
|
298
302
|
});
|
|
299
303
|
return `{
|
|
@@ -493,9 +497,9 @@ export const simnet = {
|
|
|
493
497
|
function encodeVariables(variables) {
|
|
494
498
|
return variables.map((v) => {
|
|
495
499
|
let varLine = `${encodeVariableName(v.name)}: `;
|
|
496
|
-
const
|
|
500
|
+
const type4 = jsTypeFromAbiType(v.type);
|
|
497
501
|
const varJSON = serialize(v);
|
|
498
|
-
varLine += `${varJSON} as TypedAbiVariable<${
|
|
502
|
+
varLine += `${varJSON} as TypedAbiVariable<${type4}>`;
|
|
499
503
|
return varLine;
|
|
500
504
|
});
|
|
501
505
|
}
|
|
@@ -532,6 +536,20 @@ function serializeArray(key, lines) {
|
|
|
532
536
|
}
|
|
533
537
|
|
|
534
538
|
// src/files/variables.ts
|
|
539
|
+
function clarityVersionForContract(contract) {
|
|
540
|
+
switch (contract.contract_interface.clarity_version) {
|
|
541
|
+
case "Clarity1":
|
|
542
|
+
return 1;
|
|
543
|
+
case "Clarity2":
|
|
544
|
+
return 2;
|
|
545
|
+
case "Clarity3":
|
|
546
|
+
return 3;
|
|
547
|
+
case "Clarity4":
|
|
548
|
+
return 4;
|
|
549
|
+
default:
|
|
550
|
+
return 3;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
535
553
|
function getVariablesV2(contract, simnet, verbose) {
|
|
536
554
|
const [deployer] = contract.contract_id.split(".");
|
|
537
555
|
const fakeId = `${getContractName3(contract.contract_id)}-vars`;
|
|
@@ -567,7 +585,7 @@ ${varFn}`;
|
|
|
567
585
|
fakeId,
|
|
568
586
|
fullSrc,
|
|
569
587
|
{
|
|
570
|
-
clarityVersion:
|
|
588
|
+
clarityVersion: clarityVersionForContract(contract)
|
|
571
589
|
},
|
|
572
590
|
deployer
|
|
573
591
|
);
|
|
@@ -633,7 +651,11 @@ async function getSession(config) {
|
|
|
633
651
|
}
|
|
634
652
|
return {
|
|
635
653
|
contract_id,
|
|
636
|
-
contract_interface
|
|
654
|
+
contract_interface: {
|
|
655
|
+
...contract_interface,
|
|
656
|
+
epoch: contract_interface.epoch,
|
|
657
|
+
clarity_version: contract_interface.clarity_version
|
|
658
|
+
},
|
|
637
659
|
source: source ?? ""
|
|
638
660
|
};
|
|
639
661
|
})
|
|
@@ -866,7 +888,7 @@ async function afterESM(config) {
|
|
|
866
888
|
|
|
867
889
|
// src/commands/default-command.ts
|
|
868
890
|
import chokidar from "chokidar";
|
|
869
|
-
import { dirname as dirname4, join as join3, relative as relative4 } from "path";
|
|
891
|
+
import { dirname as dirname4, join as join3, relative as relative4 } from "node:path";
|
|
870
892
|
async function generate(config) {
|
|
871
893
|
const session = await getSession(config);
|
|
872
894
|
const baseFile = generateBaseFile(session);
|
|
@@ -1039,8 +1061,8 @@ function clarityNameMatcher(line) {
|
|
|
1039
1061
|
return /[\w|\-|\?|\!]+/.exec(line);
|
|
1040
1062
|
}
|
|
1041
1063
|
function findItemNameFromLine(line) {
|
|
1042
|
-
const fnType = FN_TYPES.find((
|
|
1043
|
-
return line.startsWith(`(define-${
|
|
1064
|
+
const fnType = FN_TYPES.find((type4) => {
|
|
1065
|
+
return line.startsWith(`(define-${type4}`);
|
|
1044
1066
|
});
|
|
1045
1067
|
if (fnType) {
|
|
1046
1068
|
const prefix = `(define-${fnType} (`;
|
|
@@ -1053,13 +1075,13 @@ function findItemNameFromLine(line) {
|
|
|
1053
1075
|
}
|
|
1054
1076
|
return match[0];
|
|
1055
1077
|
}
|
|
1056
|
-
for (const
|
|
1057
|
-
const prefix = `(define-${
|
|
1078
|
+
for (const type4 of VAR_TYPES) {
|
|
1079
|
+
const prefix = `(define-${type4} `;
|
|
1058
1080
|
if (!line.startsWith(prefix)) continue;
|
|
1059
1081
|
const startString = line.slice(prefix.length);
|
|
1060
1082
|
const match = clarityNameMatcher(startString);
|
|
1061
1083
|
if (!match) {
|
|
1062
|
-
console.debug(`[claridocs]: Unable to determine ${
|
|
1084
|
+
console.debug(`[claridocs]: Unable to determine ${type4} name from line:
|
|
1063
1085
|
\`${line}\``);
|
|
1064
1086
|
return;
|
|
1065
1087
|
}
|
|
@@ -1331,8 +1353,8 @@ function generateReadme(session, excluded) {
|
|
|
1331
1353
|
contractLines.push(line);
|
|
1332
1354
|
});
|
|
1333
1355
|
const fileContents = `# Contracts
|
|
1334
|
-
|
|
1335
|
-
|
|
1356
|
+
|
|
1357
|
+
${contractLines.join("\n")}
|
|
1336
1358
|
`;
|
|
1337
1359
|
return fileContents;
|
|
1338
1360
|
}
|
|
@@ -1396,23 +1418,81 @@ output = "docs/"
|
|
|
1396
1418
|
}
|
|
1397
1419
|
|
|
1398
1420
|
// src/commands/docs-command.ts
|
|
1421
|
+
import { dirname as dirname5, join as join4, relative as relative6 } from "node:path";
|
|
1422
|
+
import chokidar2 from "chokidar";
|
|
1423
|
+
async function watch2(config, cwd) {
|
|
1424
|
+
return new Promise(async (resolve3, reject) => {
|
|
1425
|
+
var _a;
|
|
1426
|
+
const session = await getSession(config);
|
|
1427
|
+
try {
|
|
1428
|
+
await generateDocs({
|
|
1429
|
+
session,
|
|
1430
|
+
config
|
|
1431
|
+
});
|
|
1432
|
+
} catch (error) {
|
|
1433
|
+
logger.error({ error }, "Error generating types");
|
|
1434
|
+
}
|
|
1435
|
+
const clarinetFolder = dirname5(config.clarinetFile());
|
|
1436
|
+
const contractsFolder = join4(clarinetFolder, "/contracts/**/*.clar");
|
|
1437
|
+
const relativeFolder = relative6(cwd || process.cwd(), contractsFolder);
|
|
1438
|
+
const watchFolders = ((_a = config.esm) == null ? void 0 : _a.watch_folders) ?? [];
|
|
1439
|
+
watchFolders.push(relativeFolder);
|
|
1440
|
+
logger.info(`Watching for changes in ${watchFolders}`);
|
|
1441
|
+
const watcher = chokidar2.watch(watchFolders, { persistent: true, cwd: clarinetFolder });
|
|
1442
|
+
let running = false;
|
|
1443
|
+
let start = 0;
|
|
1444
|
+
const isVerbose = logger.level !== "info";
|
|
1445
|
+
watcher.on("change", async (path) => {
|
|
1446
|
+
if (!running) {
|
|
1447
|
+
start = Date.now();
|
|
1448
|
+
logger.info(`File ${path} has been changed. Generating types.`);
|
|
1449
|
+
running = true;
|
|
1450
|
+
const session2 = await getSession(config);
|
|
1451
|
+
void generateDocs({
|
|
1452
|
+
session: session2,
|
|
1453
|
+
config
|
|
1454
|
+
}).catch((e) => {
|
|
1455
|
+
logger.error({ error: e }, "Error generating types");
|
|
1456
|
+
}).then(() => {
|
|
1457
|
+
setTimeout(() => {
|
|
1458
|
+
process.stdout.moveCursor(0, -1);
|
|
1459
|
+
process.stdout.clearLine(1);
|
|
1460
|
+
const elapsed = Date.now() - start;
|
|
1461
|
+
logger.info(
|
|
1462
|
+
`Docs generated (${(elapsed / 1e3).toFixed(2)}s). Watching for changes...`
|
|
1463
|
+
);
|
|
1464
|
+
running = false;
|
|
1465
|
+
});
|
|
1466
|
+
});
|
|
1467
|
+
}
|
|
1468
|
+
});
|
|
1469
|
+
});
|
|
1470
|
+
}
|
|
1399
1471
|
var DocsCommand = class extends BaseCommand {
|
|
1400
1472
|
static paths = [["docs"]];
|
|
1401
1473
|
static usage = BaseCommand.Usage({
|
|
1402
1474
|
description: "Generate markdown documentation for your Clarity contracts"
|
|
1403
1475
|
});
|
|
1404
1476
|
cwd = Option4.String({ required: false });
|
|
1477
|
+
watch = Option4.Boolean("-w,--watch", {
|
|
1478
|
+
description: "Watch for changes and regenerate docs",
|
|
1479
|
+
required: false
|
|
1480
|
+
});
|
|
1405
1481
|
async execute() {
|
|
1406
1482
|
this.preexecute();
|
|
1407
1483
|
const config = await Config.load(this.cwd);
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1484
|
+
if (this.watch) {
|
|
1485
|
+
await watch2(config, this.cwd);
|
|
1486
|
+
} else {
|
|
1487
|
+
const session = await getSession(config);
|
|
1488
|
+
await generateDocs({
|
|
1489
|
+
session: {
|
|
1490
|
+
...session,
|
|
1491
|
+
variables: []
|
|
1492
|
+
},
|
|
1493
|
+
config
|
|
1494
|
+
});
|
|
1495
|
+
}
|
|
1416
1496
|
}
|
|
1417
1497
|
};
|
|
1418
1498
|
|
|
@@ -1477,7 +1557,7 @@ var InitConfigCommand = class extends BaseCommand {
|
|
|
1477
1557
|
};
|
|
1478
1558
|
|
|
1479
1559
|
// src/generated/version.ts
|
|
1480
|
-
var version = "3.
|
|
1560
|
+
var version = "3.2.0";
|
|
1481
1561
|
|
|
1482
1562
|
// src/run-cli.ts
|
|
1483
1563
|
var [node, script, ...args] = process.argv;
|