@clarigen/cli 0.2.4 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,20 +7,7 @@ Most of the time, you'll only need to run `clarigen` to automatically build your
7
7
  # Usage
8
8
 
9
9
  <!-- commands -->
10
- * [`clarigen `](#clarigen-)
11
10
 
12
- ## `clarigen `
13
-
14
- Generate project files
15
-
16
- ```
17
- USAGE
18
- $ clarigen
19
-
20
- OPTIONS
21
- -h, --help show CLI help
22
- -w, --watch Watch for changes to your contracts
23
- ```
24
11
  <!-- commandsstop -->
25
12
 
26
13
  ## Development
package/bin/run CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
+ /* eslint-disable @typescript-eslint/no-var-requires */
2
3
 
3
- require('../dist')
4
+ require('@oclif/command')
4
5
  .run()
5
6
  .then(require('@oclif/command/flush'))
6
7
  .catch(require('@oclif/errors/handle'));
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getClarinetAccounts = exports.getContractsFromClarinet = exports.getClarinetConfig = exports.getClarinetDevConfig = void 0;
4
+ const j_toml_1 = require("@ltd/j-toml");
5
+ const path_1 = require("path");
6
+ const promises_1 = require("fs/promises");
7
+ const wallet_sdk_1 = require("@stacks/wallet-sdk");
8
+ async function getClarinetDevConfig(folder) {
9
+ const baseConfigPath = path_1.resolve(folder, 'settings', 'Devnet.toml');
10
+ const configContents = await promises_1.readFile(baseConfigPath, { encoding: 'utf-8' });
11
+ const config = j_toml_1.parse(configContents, 1.0, '\n', true, {
12
+ longer: true,
13
+ });
14
+ return config;
15
+ }
16
+ exports.getClarinetDevConfig = getClarinetDevConfig;
17
+ async function getClarinetConfig(folder) {
18
+ const baseConfigPath = path_1.resolve(folder, 'Clarinet.toml');
19
+ const configContents = await promises_1.readFile(baseConfigPath, { encoding: 'utf-8' });
20
+ const config = j_toml_1.parse(configContents, 1.0, '\n', true);
21
+ return config;
22
+ }
23
+ exports.getClarinetConfig = getClarinetConfig;
24
+ async function getContractsFromClarinet(folder, accounts) {
25
+ const clarinetConfig = await getClarinetConfig(folder);
26
+ const deployerAddress = accounts.deployer.address;
27
+ const contracts = Object.entries(clarinetConfig.contracts).map(([contractName, info]) => {
28
+ const file = info.path.replace(/^contracts\//, '');
29
+ return {
30
+ file,
31
+ address: deployerAddress,
32
+ };
33
+ });
34
+ return contracts;
35
+ }
36
+ exports.getContractsFromClarinet = getContractsFromClarinet;
37
+ async function getClarinetAccounts(folder) {
38
+ const devConfig = await getClarinetDevConfig(folder);
39
+ const accountEntries = await Promise.all(Object.entries(devConfig.accounts).map(async ([key, info]) => {
40
+ const wallet = await wallet_sdk_1.generateWallet({
41
+ secretKey: info.mnemonic,
42
+ password: 'password',
43
+ });
44
+ const [account] = wallet.accounts;
45
+ const address = wallet_sdk_1.getStxAddress({ account });
46
+ return [
47
+ key,
48
+ {
49
+ ...info,
50
+ address,
51
+ },
52
+ ];
53
+ }));
54
+ const accounts = Object.fromEntries(accountEntries);
55
+ return accounts;
56
+ }
57
+ exports.getClarinetAccounts = getClarinetAccounts;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Contract = void 0;
4
+ const command_1 = require("@oclif/command");
5
+ const utils_1 = require("../utils");
6
+ class Contract extends command_1.Command {
7
+ async run() {
8
+ const { argv, flags } = this.parse(Contract);
9
+ const [contractFile] = argv;
10
+ await utils_1.generateFilesForContract({
11
+ contractFile,
12
+ outputFolder: flags.output,
13
+ });
14
+ }
15
+ }
16
+ exports.Contract = Contract;
17
+ Contract.description = `Generate files for a single contract`;
18
+ Contract.strict = true;
19
+ Contract.hidden = true;
20
+ Contract.flags = {
21
+ help: command_1.flags.help({ char: 'h' }),
22
+ output: command_1.flags.string({
23
+ char: 'o',
24
+ description: 'Output destination folder',
25
+ default: 'clarion',
26
+ }),
27
+ };
28
+ Contract.args = [
29
+ {
30
+ name: 'contract',
31
+ description: 'The file path for your contract',
32
+ },
33
+ ];
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Generate = void 0;
4
+ const command_1 = require("@oclif/command");
5
+ const utils_1 = require("../utils");
6
+ const config_1 = require("../config");
7
+ const chokidar_1 = require("chokidar");
8
+ const path_1 = require("path");
9
+ const chalk_1 = require("chalk");
10
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
11
+ const ora = require('ora');
12
+ class Generate extends command_1.Command {
13
+ async run() {
14
+ const { flags } = this.parse(Generate);
15
+ const cwd = process.cwd();
16
+ if (flags.watch) {
17
+ const spinner = ora('Generating files').start();
18
+ const { contractsDir } = await config_1.getConfigFile(cwd);
19
+ const watcher = chokidar_1.watch([contractsDir], {
20
+ cwd,
21
+ });
22
+ try {
23
+ await utils_1.generateProject(cwd);
24
+ spinner.succeed(`Finished generating files. Watching for changes.`);
25
+ }
26
+ catch (error) {
27
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
28
+ spinner.fail(`Error generating files.\n${error.message}`);
29
+ }
30
+ watcher.on('change', async (path) => {
31
+ const file = path_1.basename(path);
32
+ spinner.clear();
33
+ spinner.start(`Change detected for ${chalk_1.green(file)}, generating.`);
34
+ try {
35
+ await utils_1.generateProject(cwd);
36
+ spinner.succeed(`Finished generating files for ${chalk_1.green(file)}. Watching for changes.`);
37
+ }
38
+ catch (error) {
39
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
40
+ const msg = error.message;
41
+ spinner.fail(`Error after saving ${chalk_1.red(file)}.\n${msg}`);
42
+ }
43
+ });
44
+ process.on('SIGINT', async () => {
45
+ await watcher.close();
46
+ process.exit();
47
+ });
48
+ }
49
+ else {
50
+ await utils_1.generateProject(cwd);
51
+ }
52
+ }
53
+ }
54
+ exports.Generate = Generate;
55
+ Generate.description = `Generate project files`;
56
+ Generate.strict = true;
57
+ Generate.hidden = false;
58
+ Generate.flags = {
59
+ help: command_1.flags.help({ char: 'h' }),
60
+ watch: command_1.flags.boolean({
61
+ char: 'w',
62
+ description: 'Watch for changes to your contracts',
63
+ }),
64
+ };
65
+ Generate.args = [];
package/dist/config.js ADDED
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getConfigFile = void 0;
4
+ const path_1 = require("path");
5
+ const promises_1 = require("fs/promises");
6
+ const clarinet_config_1 = require("./clarinet-config");
7
+ async function getConfigFile(rootPath) {
8
+ const fullPath = path_1.resolve(rootPath, 'clarigen.config.json');
9
+ const configContents = await promises_1.readFile(fullPath, { encoding: 'utf-8' });
10
+ const configFile = JSON.parse(configContents);
11
+ if (!configFile.outputDir)
12
+ throw new Error('Config file missing "outputDir"');
13
+ if ('clarinet' in configFile) {
14
+ const clarinetPath = path_1.resolve(rootPath, configFile.clarinet);
15
+ const accounts = await clarinet_config_1.getClarinetAccounts(clarinetPath);
16
+ const contracts = await clarinet_config_1.getContractsFromClarinet(clarinetPath, accounts);
17
+ const contractsDir = path_1.relative(process.cwd(), path_1.join(configFile.clarinet, 'contracts'));
18
+ return {
19
+ ...configFile,
20
+ contracts,
21
+ contractsDir,
22
+ accounts,
23
+ };
24
+ }
25
+ if (!configFile.contracts)
26
+ throw new Error('Config file missing "contracts"');
27
+ if (!configFile.contractsDir)
28
+ throw new Error('Config file missing "contractDir"');
29
+ return configFile;
30
+ }
31
+ exports.getConfigFile = getConfigFile;
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeTypes = exports.jsTypeFromAbiType = exports.cvFromType = void 0;
4
+ const transactions_1 = require("@stacks/transactions");
5
+ const core_1 = require("@clarigen/core");
6
+ const cvFromType = (val) => {
7
+ if (transactions_1.isClarityAbiPrimitive(val)) {
8
+ if (val === 'uint128') {
9
+ return 'ClarityTypes.UIntCV';
10
+ }
11
+ else if (val === 'int128') {
12
+ return 'ClarityTypes.IntCV';
13
+ }
14
+ else if (val === 'bool') {
15
+ return 'ClarityTypes.BooleanCV';
16
+ }
17
+ else if (val === 'principal') {
18
+ return 'ClarityTypes.PrincipalCV';
19
+ }
20
+ else if (val === 'none') {
21
+ return 'ClarityTypes.NoneCV';
22
+ }
23
+ else {
24
+ throw new Error(`Unexpected Clarity ABI type primitive: ${JSON.stringify(val)}`);
25
+ }
26
+ }
27
+ else if (transactions_1.isClarityAbiBuffer(val)) {
28
+ return 'ClarityTypes.BufferCV';
29
+ }
30
+ else if (transactions_1.isClarityAbiResponse(val)) {
31
+ return 'ClarityTypes.ResponseCV';
32
+ }
33
+ else if (transactions_1.isClarityAbiOptional(val)) {
34
+ return 'ClarityTypes.OptionalCV';
35
+ }
36
+ else if (transactions_1.isClarityAbiTuple(val)) {
37
+ return 'ClarityTypes.TupleCV';
38
+ }
39
+ else if (transactions_1.isClarityAbiList(val)) {
40
+ return 'ClarityTypes.ListCV';
41
+ }
42
+ else if (transactions_1.isClarityAbiStringAscii(val)) {
43
+ return 'ClarityTypes.StringAsciiCV';
44
+ }
45
+ else if (transactions_1.isClarityAbiStringUtf8(val)) {
46
+ return 'ClarityTypes.StringUtf8CV';
47
+ }
48
+ else {
49
+ throw new Error(`Unexpected Clarity ABI type: ${JSON.stringify(val)}`);
50
+ }
51
+ };
52
+ exports.cvFromType = cvFromType;
53
+ const jsTypeFromAbiType = (val, isArgument = false) => {
54
+ if (transactions_1.isClarityAbiPrimitive(val)) {
55
+ if (val === 'uint128') {
56
+ if (isArgument)
57
+ return 'number | bigint';
58
+ return 'bigint';
59
+ }
60
+ else if (val === 'int128') {
61
+ if (isArgument)
62
+ return 'number | bigint';
63
+ return 'bigint';
64
+ }
65
+ else if (val === 'bool') {
66
+ return 'boolean';
67
+ }
68
+ else if (val === 'principal') {
69
+ return 'string';
70
+ }
71
+ else if (val === 'none') {
72
+ return 'null';
73
+ }
74
+ else if (val === 'trait_reference') {
75
+ return 'string';
76
+ }
77
+ else {
78
+ throw new Error(`Unexpected Clarity ABI type primitive: ${JSON.stringify(val)}`);
79
+ }
80
+ }
81
+ else if (transactions_1.isClarityAbiBuffer(val)) {
82
+ return 'Buffer';
83
+ }
84
+ else if (transactions_1.isClarityAbiResponse(val)) {
85
+ const ok = exports.jsTypeFromAbiType(val.response.ok);
86
+ const err = exports.jsTypeFromAbiType(val.response.error);
87
+ return `ClarityTypes.Response<${ok}, ${err}>`;
88
+ }
89
+ else if (transactions_1.isClarityAbiOptional(val)) {
90
+ const innerType = exports.jsTypeFromAbiType(val.optional);
91
+ return `${innerType} | null`;
92
+ }
93
+ else if (transactions_1.isClarityAbiTuple(val)) {
94
+ const tupleDefs = [];
95
+ val.tuple.forEach(({ name, type }) => {
96
+ const innerType = exports.jsTypeFromAbiType(type);
97
+ tupleDefs.push(`"${name}": ${innerType}`);
98
+ });
99
+ return `{
100
+ ${tupleDefs.join(';\n ')}
101
+ }`;
102
+ }
103
+ else if (transactions_1.isClarityAbiList(val)) {
104
+ const innerType = exports.jsTypeFromAbiType(val.list.type);
105
+ return `${innerType}[]`;
106
+ }
107
+ else if (transactions_1.isClarityAbiStringAscii(val)) {
108
+ return 'string';
109
+ }
110
+ else if (transactions_1.isClarityAbiStringUtf8(val)) {
111
+ return 'string';
112
+ }
113
+ else if (val === 'trait_reference') {
114
+ return 'string';
115
+ }
116
+ else {
117
+ throw new Error(`Unexpected Clarity ABI type: ${JSON.stringify(val)}`);
118
+ }
119
+ };
120
+ exports.jsTypeFromAbiType = jsTypeFromAbiType;
121
+ const makeTypes = (abi) => {
122
+ let typings = '';
123
+ abi.functions.forEach((func, index) => {
124
+ if (func.access === 'private')
125
+ return;
126
+ let functionLine = `${core_1.toCamelCase(func.name)}: `;
127
+ const args = func.args.map((arg) => {
128
+ return `${core_1.toCamelCase(arg.name)}: ${exports.jsTypeFromAbiType(arg.type, true)}`;
129
+ });
130
+ functionLine += `(${args.join(', ')}) => `;
131
+ if (func.access === 'public') {
132
+ const { type } = func.outputs;
133
+ if (!transactions_1.isClarityAbiResponse(type))
134
+ throw new Error('Expected response type for public function');
135
+ functionLine += 'Transaction';
136
+ const ok = exports.jsTypeFromAbiType(type.response.ok);
137
+ const err = exports.jsTypeFromAbiType(type.response.error);
138
+ functionLine += `<${ok}, ${err}>;`;
139
+ }
140
+ else {
141
+ const jsType = exports.jsTypeFromAbiType(func.outputs.type);
142
+ functionLine += `Promise<${jsType}>;`;
143
+ // const { type } = func.outputs;
144
+ // if (isClarityAbiResponse(type)) {
145
+ // const ok = jsTypeFromAbiType(type.response.ok);
146
+ // const err = jsTypeFromAbiType(type.response.error);
147
+ // functionLine += `Promise<ClarityTypes.Response<${ok}, ${err}>>;`;
148
+ // } else {
149
+ // const jsType = jsTypeFromAbiType(func.outputs.type);
150
+ // functionLine += `Promise<${jsType}>;`;
151
+ // }
152
+ }
153
+ typings += `${index === 0 ? '' : '\n'} ${functionLine}`;
154
+ });
155
+ return typings;
156
+ };
157
+ exports.makeTypes = makeTypes;
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateProjectIndexFile = exports.generateTypesFile = exports.generateIndexFile = exports.generateInterfaceFile = exports.generateInterface = void 0;
4
+ const native_bin_1 = require("@clarigen/native-bin");
5
+ const core_1 = require("@clarigen/core");
6
+ const declaration_1 = require("./declaration");
7
+ const path_1 = require("path");
8
+ const generateInterface = async ({ provider: _provider, contractFile, contractAddress = 'S1G2081040G2081040G2081040G208105NK8PE5', }) => {
9
+ const provider = _provider || (await native_bin_1.createClarityBin());
10
+ const contractName = core_1.getContractNameFromPath(contractFile);
11
+ const receipt = await provider.runCommand([
12
+ 'launch',
13
+ `${contractAddress}.${contractName}`,
14
+ contractFile,
15
+ provider.dbFilePath,
16
+ '--output_analysis',
17
+ '--costs',
18
+ '--assets',
19
+ ]);
20
+ if (receipt.stderr &&
21
+ !receipt.stderr.includes('Used unimplemented cost function')) {
22
+ throw new Error(`Error on ${contractFile}:
23
+ ${receipt.stderr}
24
+ `);
25
+ }
26
+ const output = JSON.parse(receipt.stdout);
27
+ if (output.error) {
28
+ const { initialization } = output.error;
29
+ if (initialization?.includes('\nNear:\n')) {
30
+ const [error, trace] = initialization.split('\nNear:\n');
31
+ let startLine = '';
32
+ const matcher = /start_line: (\d+),/;
33
+ const matches = matcher.exec(trace);
34
+ if (matches)
35
+ startLine = matches[1];
36
+ throw new Error(`Error on ${contractFile}:
37
+ ${error}
38
+ ${startLine ? `Near line ${startLine}` : ''}
39
+ Raw trace:
40
+ ${trace}
41
+ `);
42
+ }
43
+ throw new Error(`Error on ${contractFile}:
44
+ ${JSON.stringify(output.error, null, 2)}
45
+ `);
46
+ }
47
+ const abi = output.analysis;
48
+ return abi;
49
+ };
50
+ exports.generateInterface = generateInterface;
51
+ const generateInterfaceFile = ({ contractFile, abi, }) => {
52
+ const contractName = core_1.getContractNameFromPath(contractFile);
53
+ const variableName = core_1.toCamelCase(contractName, true);
54
+ const abiString = JSON.stringify(abi, null, 2);
55
+ const fileContents = `import { ClarityAbi } from '@clarigen/core';
56
+
57
+ // prettier-ignore
58
+ export const ${variableName}Interface: ClarityAbi = ${abiString};
59
+ `;
60
+ return fileContents;
61
+ };
62
+ exports.generateInterfaceFile = generateInterfaceFile;
63
+ const generateIndexFile = ({ contractFile, address, }) => {
64
+ const contractName = core_1.getContractNameFromPath(contractFile);
65
+ const contractTitle = core_1.toCamelCase(contractName, true);
66
+ const varName = core_1.toCamelCase(contractName);
67
+ const contractType = `${contractTitle}Contract`;
68
+ const fileContents = `import { proxy, BaseProvider, Contract } from '@clarigen/core';
69
+ import type { ${contractType} } from './types';
70
+ import { ${contractTitle}Interface } from './abi';
71
+ export type { ${contractType} } from './types';
72
+
73
+ export const ${varName}Contract = (provider: BaseProvider) => {
74
+ const contract = proxy<${contractType}>(${contractTitle}Interface, provider);
75
+ return contract;
76
+ };
77
+
78
+ export const ${varName}Info: Contract<${contractType}> = {
79
+ contract: ${varName}Contract,
80
+ address: '${address}',
81
+ contractFile: '${contractFile}',
82
+ };
83
+ `;
84
+ return fileContents;
85
+ };
86
+ exports.generateIndexFile = generateIndexFile;
87
+ const generateTypesFile = (abi, contractName) => {
88
+ const name = core_1.toCamelCase(contractName, true);
89
+ const typings = declaration_1.makeTypes(abi);
90
+ const fileContents = `import { ClarityTypes, Transaction } from '@clarigen/core';
91
+
92
+ // prettier-ignore
93
+ export interface ${name}Contract {
94
+ ${typings}
95
+ }
96
+ `;
97
+ return fileContents;
98
+ };
99
+ exports.generateTypesFile = generateTypesFile;
100
+ const generateProjectIndexFile = (config) => {
101
+ const imports = [];
102
+ const exports = [];
103
+ const contractMap = [];
104
+ let accounts = '';
105
+ if ('accounts' in config) {
106
+ const accountLines = Object.keys(config.accounts).map((key) => {
107
+ const account = config.accounts[key];
108
+ return `"${key}": {
109
+ mnemonic: "${account.mnemonic}",
110
+ balance: ${account.balance.toString()}n,
111
+ address: "${account.address}",
112
+ },`;
113
+ });
114
+ accounts = `\n\n// prettier-ignore
115
+ export const accounts = {
116
+ ${accountLines.join('\n ')}
117
+ };`;
118
+ }
119
+ config.contracts.forEach((contract) => {
120
+ const contractName = core_1.getContractNameFromPath(contract.file);
121
+ const contractVar = core_1.toCamelCase(contractName);
122
+ const contractInfo = `${contractVar}Info`;
123
+ const contractInterface = `${core_1.toCamelCase(contractName, true)}Contract`;
124
+ const dirName = path_1.dirname(contract.file);
125
+ const importPath = `'./${path_1.join(dirName || '.', contractName)}'`;
126
+ const _import = `import { ${contractInfo} } from ${importPath};`;
127
+ imports.push(_import);
128
+ const _export = `export type { ${contractInterface} } from ${importPath};`;
129
+ exports.push(_export);
130
+ const map = `${contractVar}: ${contractInfo},`;
131
+ contractMap.push(map);
132
+ });
133
+ const file = `${imports.join('\n')}
134
+ ${exports.join('\n')}
135
+
136
+ export const contracts = {
137
+ ${contractMap.join('\n ')}
138
+ };${accounts}
139
+ `;
140
+ return file;
141
+ };
142
+ exports.generateProjectIndexFile = generateProjectIndexFile;
package/dist/index.js CHANGED
@@ -1,8 +1,19 @@
1
-
2
- 'use strict'
3
-
4
- if (process.env.NODE_ENV === 'production') {
5
- module.exports = require('./cli.cjs.production.min.js')
6
- } else {
7
- module.exports = require('./cli.cjs.development.js')
8
- }
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.run = void 0;
14
+ var command_1 = require("@oclif/command");
15
+ Object.defineProperty(exports, "run", { enumerable: true, get: function () { return command_1.run; } });
16
+ __exportStar(require("./config"), exports);
17
+ __exportStar(require("./generate/declaration"), exports);
18
+ __exportStar(require("./generate/files"), exports);
19
+ __exportStar(require("./commands"), exports);
package/dist/start.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const errors_1 = require("@oclif/errors");
7
+ const flush_1 = __importDefault(require("@oclif/command/flush"));
8
+ const index_1 = require("./index");
9
+ index_1.run().then(flush_1.default, errors_1.handle);
package/dist/utils.js ADDED
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateProject = exports.generateFilesForContract = void 0;
4
+ const files_1 = require("./generate/files");
5
+ const core_1 = require("@clarigen/core");
6
+ const native_bin_1 = require("@clarigen/native-bin");
7
+ const path_1 = require("path");
8
+ const promises_1 = require("fs/promises");
9
+ const config_1 = require("./config");
10
+ const generateFilesForContract = async ({ contractFile: _contractFile, outputFolder, provider, contractAddress, dirName, }) => {
11
+ const contractFile = path_1.resolve(process.cwd(), _contractFile);
12
+ const contractName = core_1.getContractNameFromPath(contractFile);
13
+ const abi = await files_1.generateInterface({
14
+ contractFile,
15
+ provider,
16
+ contractAddress,
17
+ });
18
+ const typesFile = files_1.generateTypesFile(abi, contractName);
19
+ if (!contractAddress && process.env.NODE_ENV !== 'test') {
20
+ console.warn('Please provide an address with every contract.');
21
+ }
22
+ const indexFile = files_1.generateIndexFile({
23
+ contractFile: path_1.relative(process.cwd(), contractFile),
24
+ address: contractAddress || '',
25
+ });
26
+ const abiFile = files_1.generateInterfaceFile({ contractFile, abi });
27
+ const baseDir = outputFolder || path_1.resolve(process.cwd(), `tmp/${contractName}`);
28
+ const outputPath = path_1.resolve(baseDir, dirName || '.', contractName);
29
+ await promises_1.mkdir(outputPath, { recursive: true });
30
+ await promises_1.writeFile(path_1.resolve(outputPath, 'abi.ts'), abiFile);
31
+ await promises_1.writeFile(path_1.resolve(outputPath, 'index.ts'), indexFile);
32
+ await promises_1.writeFile(path_1.resolve(outputPath, 'types.ts'), typesFile);
33
+ };
34
+ exports.generateFilesForContract = generateFilesForContract;
35
+ const generateProject = async (projectPath) => {
36
+ const configFile = await config_1.getConfigFile(projectPath);
37
+ const { contractsDir, outputDir, contracts } = configFile;
38
+ const outputFolder = path_1.resolve(projectPath, outputDir);
39
+ const provider = await native_bin_1.createClarityBin();
40
+ // this needs to be serial
41
+ for (const contract of contracts) {
42
+ const contractFile = path_1.resolve(projectPath, contractsDir, contract.file);
43
+ const dirName = path_1.dirname(contract.file);
44
+ await exports.generateFilesForContract({
45
+ contractFile,
46
+ outputFolder: outputFolder,
47
+ provider,
48
+ contractAddress: contract.address,
49
+ dirName,
50
+ });
51
+ }
52
+ const indexFile = files_1.generateProjectIndexFile(configFile);
53
+ const indexPath = path_1.resolve(outputFolder, 'index.ts');
54
+ await promises_1.writeFile(indexPath, indexFile);
55
+ };
56
+ exports.generateProject = generateProject;
package/package.json CHANGED
@@ -2,13 +2,13 @@
2
2
  "name": "@clarigen/cli",
3
3
  "description": "A CLI for generating a Typescript interface for a Clarity contract.",
4
4
  "author": "Hank Stoever",
5
- "version": "0.2.4",
5
+ "version": "0.3.1",
6
6
  "license": "MIT",
7
7
  "main": "dist/index.js",
8
8
  "files": [
9
9
  "dist",
10
10
  "src",
11
- "/oclif.manifest.json"
11
+ "oclif.manifest.json"
12
12
  ],
13
13
  "engines": {
14
14
  "node": ">=10"
@@ -18,10 +18,11 @@
18
18
  "start": "ts-node-script src/start.ts",
19
19
  "compile": "ncc build src/index.ts --no-source-map-register -e @oclif/command -e @oclif/errors",
20
20
  "build-single-file": "yarn compile && oclif-dev readme",
21
- "build": "tsdx build && oclif-dev readme",
21
+ "build": "rm -rf dist && tsc -b",
22
22
  "test": "tsdx test",
23
23
  "lint": "tsdx lint",
24
- "typecheck": "tsc --noEmit"
24
+ "typecheck": "tsc --noEmit",
25
+ "prepublishOnly": "yarn build"
25
26
  },
26
27
  "bin": {
27
28
  "clarigen": "./bin/run"
@@ -37,25 +38,26 @@
37
38
  "trailingComma": "es5"
38
39
  },
39
40
  "devDependencies": {
40
- "@oclif/config": "^1.17.0",
41
41
  "@oclif/dev-cli": "^1.26.0",
42
42
  "@oclif/errors": "^1.3.4",
43
43
  "@vercel/ncc": "0.27.0",
44
- "chokidar": "3.5.1",
45
44
  "oclif": "^1.16.1",
46
45
  "ts-node": "^9.1.1"
47
46
  },
48
47
  "dependencies": {
49
- "@clarigen/core": "0.2.3",
50
- "@clarigen/native-bin": "0.2.3",
48
+ "@clarigen/core": "0.3.1",
49
+ "@clarigen/native-bin": "0.3.1",
51
50
  "@ltd/j-toml": "1.12.2",
52
51
  "@oclif/command": "^1.8.0",
52
+ "@oclif/config": "^1.17.0",
53
+ "@oclif/plugin-help": "3.2.3",
53
54
  "@stacks/wallet-sdk": "1.0.0-wallet-sdk.4",
54
55
  "chalk": "4.1.0",
56
+ "chokidar": "3.5.1",
55
57
  "ora": "5.4.0"
56
58
  },
57
59
  "publishConfig": {
58
60
  "access": "public"
59
61
  },
60
- "gitHead": "d5f5f508ece8cd70b88d23f4b27643c0ba990997"
62
+ "gitHead": "7fa176bead2d770807bbb77d86aae5f5d7543e2b"
61
63
  }