@clarigen/cli 1.0.0-next.18 → 1.0.0-next.21
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/abi-types.ts.txt +119 -0
- package/dist/commands/index.js +750 -74
- package/dist/index.js +774 -87
- package/package.json +19 -21
- package/src/clarinet-config.ts +11 -8
- package/src/commands/index.ts +28 -23
- package/src/config.ts +7 -3
- package/src/generate/declaration.ts +3 -3
- package/src/generate/files.ts +0 -49
- package/src/generate/single.ts +12 -6
- package/src/utils.ts +0 -1
- package/dist/commands/index.d.ts +0 -16
- package/dist/commands/index.mjs +0 -92
- package/dist/index.d.ts +0 -64
- package/dist/index.mjs +0 -105
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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": "1.0.0-next.
|
|
5
|
+
"version": "1.0.0-next.21",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"main": "./dist/index.js",
|
|
@@ -14,19 +14,6 @@
|
|
|
14
14
|
"engines": {
|
|
15
15
|
"node": ">=10"
|
|
16
16
|
},
|
|
17
|
-
"scripts": {
|
|
18
|
-
"start": "tsup-node --watch",
|
|
19
|
-
"dev": "tsup-node --watch",
|
|
20
|
-
"build": "shx rm -rf ./dist && tsup-node src/index.ts src/commands/index.ts --splitting false",
|
|
21
|
-
"compile": "ncc build src/index.ts --no-source-map-register -e @oclif/command -e @oclif/errors",
|
|
22
|
-
"build-single-file": "yarn compile && oclif-dev readme",
|
|
23
|
-
"test": "jest",
|
|
24
|
-
"lint": "eslint \"src/**/*.{ts,tsx}\" && prettier --check src/**/*.ts",
|
|
25
|
-
"typecheck": "tsc --noEmit -p tsconfig-test.json",
|
|
26
|
-
"prepublishOnly": "yarn build",
|
|
27
|
-
"demo": "yarn build && node bin/run",
|
|
28
|
-
"publish:dev": "yalc publish --push"
|
|
29
|
-
},
|
|
30
17
|
"bin": {
|
|
31
18
|
"clarigen": "./bin/run"
|
|
32
19
|
},
|
|
@@ -50,9 +37,9 @@
|
|
|
50
37
|
"ts-node": "^9.1.1"
|
|
51
38
|
},
|
|
52
39
|
"dependencies": {
|
|
53
|
-
"@clarigen/
|
|
54
|
-
"@clarigen/
|
|
55
|
-
"@clarigen/
|
|
40
|
+
"@clarigen/core": "1.0.0-next.21",
|
|
41
|
+
"@clarigen/native-bin": "1.0.0-next.21",
|
|
42
|
+
"@clarigen/claridocs": "1.0.0-next.21",
|
|
56
43
|
"@ltd/j-toml": "1.12.2",
|
|
57
44
|
"@oclif/command": "^1.8.0",
|
|
58
45
|
"@oclif/config": "^1.17.0",
|
|
@@ -62,11 +49,22 @@
|
|
|
62
49
|
"micro-stacks": "^0.2.0",
|
|
63
50
|
"ora": "5.4.0",
|
|
64
51
|
"prettier": "2.6.2",
|
|
65
|
-
"
|
|
66
|
-
"
|
|
52
|
+
"toposort": "2.0.2",
|
|
53
|
+
"reserved-words": "0.1.2"
|
|
67
54
|
},
|
|
68
55
|
"publishConfig": {
|
|
69
56
|
"access": "public"
|
|
70
57
|
},
|
|
71
|
-
"
|
|
72
|
-
|
|
58
|
+
"scripts": {
|
|
59
|
+
"start": "tsup-node --watch",
|
|
60
|
+
"dev": "tsup-node --watch",
|
|
61
|
+
"build": "shx rm -rf ./dist && tsup-node",
|
|
62
|
+
"compile": "ncc build src/index.ts --no-source-map-register -e @oclif/command -e @oclif/errors",
|
|
63
|
+
"build-single-file": "compile && oclif-dev readme",
|
|
64
|
+
"test": "jest",
|
|
65
|
+
"lint": "eslint \"src/**/*.{ts,tsx}\" && prettier --check src/**/*.ts",
|
|
66
|
+
"typecheck": "tsc --noEmit -p tsconfig-test.json",
|
|
67
|
+
"demo": "pnpm build && node bin/run",
|
|
68
|
+
"publish:dev": "yalc publish --push"
|
|
69
|
+
}
|
|
70
|
+
}
|
package/src/clarinet-config.ts
CHANGED
|
@@ -29,9 +29,9 @@ export async function getClarinetDevConfig(
|
|
|
29
29
|
): Promise<ClarinetDevConfig> {
|
|
30
30
|
const baseConfigPath = resolve(folder, 'settings', 'Devnet.toml');
|
|
31
31
|
const configContents = await readFile(baseConfigPath, { encoding: 'utf-8' });
|
|
32
|
-
const config =
|
|
32
|
+
const config = parse(configContents, 1.0, '\n', true, {
|
|
33
33
|
longer: true,
|
|
34
|
-
}) as unknown
|
|
34
|
+
}) as unknown as ClarinetDevConfig;
|
|
35
35
|
return config;
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -46,6 +46,10 @@ export interface ClarinetContracts {
|
|
|
46
46
|
|
|
47
47
|
export interface ClarinetConfig {
|
|
48
48
|
contracts: ClarinetContracts;
|
|
49
|
+
clarigen?: {
|
|
50
|
+
output_dir?: string;
|
|
51
|
+
docs?: string;
|
|
52
|
+
};
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
export const CLARINET_SETTINGS = [
|
|
@@ -57,20 +61,19 @@ export const CLARINET_SETTINGS = [
|
|
|
57
61
|
export async function getClarinetConfig(folder: string) {
|
|
58
62
|
const baseConfigPath = resolve(folder, 'Clarinet.toml');
|
|
59
63
|
const configContents = await readFile(baseConfigPath, { encoding: 'utf-8' });
|
|
60
|
-
const config =
|
|
64
|
+
const config = parse(
|
|
61
65
|
configContents,
|
|
62
66
|
1.0,
|
|
63
67
|
'\n',
|
|
64
68
|
true
|
|
65
|
-
) as unknown
|
|
69
|
+
) as unknown as ClarinetConfig;
|
|
66
70
|
return config;
|
|
67
71
|
}
|
|
68
72
|
|
|
69
|
-
export
|
|
70
|
-
|
|
73
|
+
export function getContractsFromClarinet(
|
|
74
|
+
clarinetConfig: ClarinetConfig,
|
|
71
75
|
accounts: ClarinetAccounts
|
|
72
|
-
):
|
|
73
|
-
const clarinetConfig = await getClarinetConfig(folder);
|
|
76
|
+
): ConfigContract[] {
|
|
74
77
|
const deployerAddress = accounts.deployer.address;
|
|
75
78
|
const sortedContracts = sortClarinetContracts(clarinetConfig.contracts);
|
|
76
79
|
const contracts: ConfigContract[] = sortedContracts.map((contractName) => {
|
package/src/commands/index.ts
CHANGED
|
@@ -4,8 +4,7 @@ import { getProjectConfig } from '../config';
|
|
|
4
4
|
import { watch } from 'chokidar';
|
|
5
5
|
import { basename } from 'path';
|
|
6
6
|
import { red, green } from 'chalk';
|
|
7
|
-
|
|
8
|
-
const ora = require('ora');
|
|
7
|
+
import ora from 'ora';
|
|
9
8
|
|
|
10
9
|
export class Generate extends Command {
|
|
11
10
|
static description = `Generate project files`;
|
|
@@ -36,29 +35,35 @@ export class Generate extends Command {
|
|
|
36
35
|
await generateProject(cwd);
|
|
37
36
|
spinner.succeed(`Finished generating files. Watching for changes.`);
|
|
38
37
|
} catch (error) {
|
|
39
|
-
// eslint-disable-next-line @typescript-eslint/no-
|
|
40
|
-
spinner.fail(`Error generating files.\n${(error
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
39
|
+
spinner.fail(`Error generating files.\n${String(error.message)}`);
|
|
41
40
|
}
|
|
42
|
-
watcher.on('change',
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
41
|
+
watcher.on('change', (path) => {
|
|
42
|
+
const cb = async () => {
|
|
43
|
+
const file = basename(path);
|
|
44
|
+
spinner.clear();
|
|
45
|
+
spinner.start(`Change detected for ${green(file)}, generating.`);
|
|
46
|
+
try {
|
|
47
|
+
await generateProject(cwd);
|
|
48
|
+
spinner.succeed(
|
|
49
|
+
`Finished generating files for ${green(
|
|
50
|
+
file
|
|
51
|
+
)}. Watching for changes.`
|
|
52
|
+
);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
55
|
+
const msg = error.message as string;
|
|
56
|
+
spinner.fail(`Error after saving ${red(file)}.\n${msg}`);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
void cb();
|
|
58
60
|
});
|
|
59
|
-
process.on('SIGINT',
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
process.on('SIGINT', () => {
|
|
62
|
+
async function cb() {
|
|
63
|
+
await watcher.close();
|
|
64
|
+
process.exit();
|
|
65
|
+
}
|
|
66
|
+
void cb();
|
|
62
67
|
});
|
|
63
68
|
} else {
|
|
64
69
|
await generateProject(cwd);
|
package/src/config.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { constants } from 'fs';
|
|
|
4
4
|
import {
|
|
5
5
|
ClarinetAccounts,
|
|
6
6
|
getClarinetAccounts,
|
|
7
|
+
getClarinetConfig,
|
|
7
8
|
getContractsFromClarinet,
|
|
8
9
|
} from './clarinet-config';
|
|
9
10
|
|
|
@@ -62,18 +63,21 @@ export async function getConfigFile(
|
|
|
62
63
|
|
|
63
64
|
export async function getProjectConfig(rootPath: string): Promise<ConfigFile> {
|
|
64
65
|
const configFile = await getConfigFile(rootPath);
|
|
65
|
-
const clarinetPath = resolve(rootPath, configFile.clarinet
|
|
66
|
+
const clarinetPath = resolve(rootPath, configFile.clarinet);
|
|
67
|
+
const clarinet = await getClarinetConfig(clarinetPath);
|
|
66
68
|
const accounts = await getClarinetAccounts(clarinetPath);
|
|
67
|
-
const contracts =
|
|
69
|
+
const contracts = getContractsFromClarinet(clarinet, accounts);
|
|
68
70
|
const contractsDir = relative(
|
|
69
71
|
process.cwd(),
|
|
70
72
|
join(configFile.clarinet, 'contracts')
|
|
71
73
|
);
|
|
72
74
|
return {
|
|
73
75
|
...configFile,
|
|
76
|
+
outputDir: clarinet.clarigen?.output_dir || configFile.outputDir,
|
|
77
|
+
docs: clarinet.clarigen?.docs || configFile.docs,
|
|
74
78
|
contracts,
|
|
75
79
|
contractsDir,
|
|
76
80
|
accounts,
|
|
77
|
-
clarinet: configFile.clarinet
|
|
81
|
+
clarinet: configFile.clarinet,
|
|
78
82
|
};
|
|
79
83
|
}
|
|
@@ -39,8 +39,8 @@ export const jsTypeFromAbiType = (
|
|
|
39
39
|
} else if (isClarityAbiBuffer(val)) {
|
|
40
40
|
return 'Uint8Array';
|
|
41
41
|
} else if (isClarityAbiResponse(val)) {
|
|
42
|
-
const ok
|
|
43
|
-
const err
|
|
42
|
+
const ok = jsTypeFromAbiType(val.response.ok);
|
|
43
|
+
const err = jsTypeFromAbiType(val.response.error);
|
|
44
44
|
return `Response<${ok}, ${err}>`;
|
|
45
45
|
} else if (isClarityAbiOptional(val)) {
|
|
46
46
|
const innerType = jsTypeFromAbiType(val.optional);
|
|
@@ -55,7 +55,7 @@ export const jsTypeFromAbiType = (
|
|
|
55
55
|
${tupleDefs.join(';\n ')}
|
|
56
56
|
}`;
|
|
57
57
|
} else if (isClarityAbiList(val)) {
|
|
58
|
-
const innerType
|
|
58
|
+
const innerType = jsTypeFromAbiType(val.list.type);
|
|
59
59
|
return `${innerType}[]`;
|
|
60
60
|
} else if (isClarityAbiStringAscii(val)) {
|
|
61
61
|
return 'string';
|
package/src/generate/files.ts
CHANGED
|
@@ -4,55 +4,6 @@ import { ConfigContract, ConfigFile } from '../config';
|
|
|
4
4
|
import { dirname, resolve, join } from 'path';
|
|
5
5
|
import { makePureTypes } from '..';
|
|
6
6
|
|
|
7
|
-
export const generateInterface = async ({
|
|
8
|
-
provider,
|
|
9
|
-
contractFile,
|
|
10
|
-
contractAddress,
|
|
11
|
-
contractName,
|
|
12
|
-
}: {
|
|
13
|
-
contractFile: string;
|
|
14
|
-
provider: NativeClarityBinProvider;
|
|
15
|
-
contractAddress: string;
|
|
16
|
-
contractName: string;
|
|
17
|
-
}): Promise<ClarityAbi> => {
|
|
18
|
-
const receipt = await provider.runCommand([
|
|
19
|
-
'launch',
|
|
20
|
-
`${contractAddress}.${contractName}`,
|
|
21
|
-
contractFile,
|
|
22
|
-
provider.dbFilePath,
|
|
23
|
-
'--output_analysis',
|
|
24
|
-
'--costs',
|
|
25
|
-
'--assets',
|
|
26
|
-
]);
|
|
27
|
-
if (hasStdErr(receipt.stderr)) {
|
|
28
|
-
throw new Error(`Error on ${contractFile}:
|
|
29
|
-
${receipt.stderr}
|
|
30
|
-
`);
|
|
31
|
-
}
|
|
32
|
-
const output = JSON.parse(receipt.stdout);
|
|
33
|
-
if (output.error) {
|
|
34
|
-
const { initialization } = output.error;
|
|
35
|
-
if (initialization?.includes('\nNear:\n')) {
|
|
36
|
-
const [error, trace] = initialization.split('\nNear:\n');
|
|
37
|
-
let startLine = '';
|
|
38
|
-
const matcher = /start_line: (\d+),/;
|
|
39
|
-
const matches = matcher.exec(trace);
|
|
40
|
-
if (matches) startLine = matches[1];
|
|
41
|
-
throw new Error(`Error on ${contractFile}:
|
|
42
|
-
${error}
|
|
43
|
-
${startLine ? `Near line ${startLine}` : ''}
|
|
44
|
-
Raw trace:
|
|
45
|
-
${trace}
|
|
46
|
-
`);
|
|
47
|
-
}
|
|
48
|
-
throw new Error(`Error on ${contractFile}:
|
|
49
|
-
${JSON.stringify(output.error, null, 2)}
|
|
50
|
-
`);
|
|
51
|
-
}
|
|
52
|
-
const abi = output.analysis;
|
|
53
|
-
return abi;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
7
|
export const generateInterfaceFile = ({
|
|
57
8
|
contractName,
|
|
58
9
|
abi,
|
package/src/generate/single.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { toCamelCase } from '@clarigen/core';
|
|
|
2
2
|
import type { ConfigFile } from '../config';
|
|
3
3
|
import { getArgName, jsTypeFromAbiType } from './declaration';
|
|
4
4
|
import type { ContractMeta } from '../utils';
|
|
5
|
-
import { resolveConfig, format } from 'prettier';
|
|
6
5
|
import { relative, resolve } from 'path';
|
|
7
6
|
import { readFile } from 'fs/promises';
|
|
8
7
|
import { inspect } from 'util';
|
|
@@ -27,7 +26,7 @@ export function generateContractMeta(contract: ContractMeta) {
|
|
|
27
26
|
const variableLines = contract.variables.map((v) => {
|
|
28
27
|
let varLine = `${toCamelCase(v.name)}: `;
|
|
29
28
|
const type = jsTypeFromAbiType(v.type);
|
|
30
|
-
const varJSON =
|
|
29
|
+
const varJSON = serialize(v);
|
|
31
30
|
varLine += `${varJSON} as TypedAbiVariable<${type}>`;
|
|
32
31
|
return varLine;
|
|
33
32
|
});
|
|
@@ -79,7 +78,7 @@ export async function generateSingleFile(
|
|
|
79
78
|
const file = `
|
|
80
79
|
${types}
|
|
81
80
|
|
|
82
|
-
export const contracts
|
|
81
|
+
export const contracts = {
|
|
83
82
|
${contractDefs.join(',\n')}
|
|
84
83
|
} as const;
|
|
85
84
|
|
|
@@ -111,8 +110,14 @@ Uint8Array.prototype[inspect.custom] = function (this: Uint8Array) {
|
|
|
111
110
|
return `Uint8Array.from([${this.join(',')}])`;
|
|
112
111
|
};
|
|
113
112
|
|
|
114
|
-
function serialize(obj: any) {
|
|
115
|
-
return inspect(obj,
|
|
113
|
+
export function serialize(obj: any) {
|
|
114
|
+
return inspect(obj, {
|
|
115
|
+
showHidden: false,
|
|
116
|
+
maxArrayLength: null,
|
|
117
|
+
maxStringLength: null,
|
|
118
|
+
depth: null,
|
|
119
|
+
colors: false,
|
|
120
|
+
});
|
|
116
121
|
}
|
|
117
122
|
|
|
118
123
|
function serializeLines(key: string, lines: string[]) {
|
|
@@ -122,7 +127,8 @@ function serializeLines(key: string, lines: string[]) {
|
|
|
122
127
|
}
|
|
123
128
|
|
|
124
129
|
export async function getSingleTypes() {
|
|
125
|
-
|
|
130
|
+
// 🤔 weird stuff with tsup shims
|
|
131
|
+
const typesPath = resolve(__dirname, '../../dist/abi-types.ts.txt');
|
|
126
132
|
const typesFile = await readFile(typesPath, { encoding: 'utf-8' });
|
|
127
133
|
return typesFile;
|
|
128
134
|
}
|
package/src/utils.ts
CHANGED
package/dist/commands/index.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import * as _oclif_parser_lib_flags from '@oclif/parser/lib/flags';
|
|
2
|
-
import { Command } from '@oclif/command';
|
|
3
|
-
|
|
4
|
-
declare class Generate extends Command {
|
|
5
|
-
static description: string;
|
|
6
|
-
static strict: boolean;
|
|
7
|
-
static hidden: boolean;
|
|
8
|
-
static flags: {
|
|
9
|
-
help: _oclif_parser_lib_flags.IBooleanFlag<void>;
|
|
10
|
-
watch: _oclif_parser_lib_flags.IBooleanFlag<boolean>;
|
|
11
|
-
};
|
|
12
|
-
static args: any[];
|
|
13
|
-
run(): Promise<void>;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export { Generate };
|
package/dist/commands/index.mjs
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
var lt=Object.defineProperty,pt=Object.defineProperties;var ft=Object.getOwnPropertyDescriptors;var N=Object.getOwnPropertySymbols;var R=Object.prototype.hasOwnProperty,B=Object.prototype.propertyIsEnumerable;var M=(t,r,e)=>r in t?lt(t,r,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[r]=e,C=(t,r)=>{for(var e in r||(r={}))R.call(r,e)&&M(t,e,r[e]);if(N)for(var e of N(r))B.call(r,e)&&M(t,e,r[e]);return t},x=(t,r)=>pt(t,ft(r));var mt=(t=>typeof require!="undefined"?require:typeof Proxy!="undefined"?new Proxy(t,{get:(r,e)=>(typeof require!="undefined"?require:r)[e]}):t)(function(t){if(typeof require!="undefined")return require.apply(this,arguments);throw new Error('Dynamic require of "'+t+'" is not supported')});var j=(t,r)=>{var e={};for(var n in t)R.call(t,n)&&r.indexOf(n)<0&&(e[n]=t[n]);if(t!=null&&N)for(var n of N(t))r.indexOf(n)<0&&B.call(t,n)&&(e[n]=t[n]);return e};import{fileURLToPath as ut}from"url";import gt from"path";var Ct=()=>ut(import.meta.url),yt=()=>gt.dirname(Ct()),u=yt();import{Command as be,flags as st}from"@oclif/command";import{hasStdErr as rr}from"@clarigen/native-bin";import{toCamelCase as F}from"@clarigen/core";import{dirname as Bt,join as Jt}from"path";import{run as Qe}from"@oclif/command";import{resolve as H,join as Ft,relative as Tt}from"path";import{readFile as vt,access as Pt}from"fs/promises";import{constants as Nt}from"fs";import{parse as J}from"@ltd/j-toml";import{resolve as U}from"path";import{readFile as W}from"fs/promises";import{generateWallet as dt,getStxAddressFromAccount as $t}from"micro-stacks/wallet-sdk";import{array as bt}from"toposort";import{StacksNetworkVersion as xt}from"micro-stacks/crypto";async function wt(t){let r=U(t,"settings","Devnet.toml"),e=await W(r,{encoding:"utf-8"});return J(e,1,`
|
|
2
|
-
`,!0,{longer:!0})}async function At(t){let r=U(t,"Clarinet.toml"),e=await W(r,{encoding:"utf-8"});return J(e,1,`
|
|
3
|
-
`,!0)}async function z(t,r){let e=await At(t),n=r.deployer.address;return ht(e.contracts).map(a=>({file:e.contracts[a].path.replace(/^contracts\//,""),address:n,name:a}))}function ht(t){let r=[],e=[];return Object.entries(t).forEach(([o,i])=>{e.push(o),i.depends_on.forEach(a=>r.push([o,a]))}),bt(e,r).reverse()}async function K(t){let r=await wt(t),e=await Promise.all(Object.entries(r.accounts).map(async([o,i])=>{let a=await dt(i.mnemonic,"password"),[s]=a.accounts,l=$t(s,xt.testnetP2PKH);return[o,x(C({},i),{address:l})]}));return Object.fromEntries(e)}var q={outputDir:"src/clarigen",clarinet:"."};function jt(t){return H(t,"clarigen.config.json")}async function Et(t){try{return await Pt(t,Nt.R_OK),!0}catch{return!1}}async function It(t){let r=jt(t);if(await Et(r)){let n=await vt(r,{encoding:"utf-8"}),o=JSON.parse(n);return C(C({},q),o)}return q}async function E(t){let r=await It(t),e=H(t,r.clarinet||"."),n=await K(e),o=await z(e,n),i=Tt(process.cwd(),Ft(r.clarinet,"contracts"));return x(C({},r),{contracts:o,contractsDir:i,accounts:n,clarinet:r.clarinet||"."})}import{isClarityAbiBuffer as kt,isClarityAbiList as St,isClarityAbiOptional as Dt,isClarityAbiPrimitive as Vt,isClarityAbiResponse as Q,isClarityAbiStringAscii as Ot,isClarityAbiStringUtf8 as Lt,isClarityAbiTuple as _t}from"micro-stacks/transactions";import{toCamelCase as S}from"@clarigen/core";import{check as Mt}from"reserved-words";var f=(t,r=!1)=>{if(Vt(t)){if(t==="uint128")return r?"number | bigint":"bigint";if(t==="int128")return r?"number | bigint":"bigint";if(t==="bool")return"boolean";if(t==="principal")return"string";if(t==="none")return"null";if(t==="trait_reference")return"string";throw new Error(`Unexpected Clarity ABI type primitive: ${JSON.stringify(t)}`)}else{if(kt(t))return"Uint8Array";if(Q(t)){let e=f(t.response.ok),n=f(t.response.error);return`Response<${e}, ${n}>`}else{if(Dt(t))return`${f(t.optional)} | null`;if(_t(t)){let e=[];return t.tuple.forEach(({name:n,type:o})=>{let i=f(o);e.push(`"${n}": ${i}`)}),`{
|
|
4
|
-
${e.join(`;
|
|
5
|
-
`)}
|
|
6
|
-
}`}else{if(St(t))return`${f(t.list.type)}[]`;if(Ot(t))return"string";if(Lt(t))return"string";if(t==="trait_reference")return"string";throw new Error(`Unexpected Clarity ABI type: ${JSON.stringify(t)}`)}}}};function D(t){let r=S(t);return`${Mt(r,6)?"_":""}${r}`}var Rt={public:"Public",read_only:"ReadOnly",private:"Private"};function X(t){let r="";return t.functions.forEach((e,n)=>{let o=`${S(e.name)}: `;if(o+=`(${e.args.map(s=>`${D(s.name)}: ${f(s.type,!0)}`).join(", ")}) => `,o+=`ContractCalls.${Rt[e.access]}<`,e.access==="public"){let{type:s}=e.outputs;if(!Q(s))throw new Error("Expected response type for public function");let l=f(s.response.ok),p=f(s.response.error);o+=`${l}, ${p}>;`}else o+=`${f(e.outputs.type)}>;`;r+=`${n===0?"":`
|
|
7
|
-
`} ${o}`}),t.maps.forEach(e=>{let n=`${S(e.name)}: `,o=f(e.key,!0),i=`key: ${o}`,a=f(e.value);n+=`(${i}) => ContractCalls.Map<${o}, ${a}>;`,r+=`
|
|
8
|
-
${n}`}),r}var Y=({contractName:t,abi:r})=>{let e=F(t,!0),s=r,{clarity_version:n}=s,o=j(s,["clarity_version"]),i=JSON.stringify(o,null,2);return`import { ClarityAbi } from '@clarigen/core';
|
|
9
|
-
|
|
10
|
-
// prettier-ignore
|
|
11
|
-
export const ${e}Interface: ClarityAbi = ${i};
|
|
12
|
-
`},Z=({contractFile:t,contractAddress:r,contractName:e})=>{let n=F(e,!0),o=F(e),i=`${n}Contract`,a=`${n}Interface`;return`import { pureProxy, Contract } from '@clarigen/core';
|
|
13
|
-
import type { ${i} } from './types';
|
|
14
|
-
import { ${a} } from './abi';
|
|
15
|
-
export type { ${i} } from './types';
|
|
16
|
-
|
|
17
|
-
export function ${o}Contract(contractAddress: string, contractName: string) {
|
|
18
|
-
return pureProxy<${i}>({
|
|
19
|
-
abi: ${a},
|
|
20
|
-
contractAddress,
|
|
21
|
-
contractName,
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export const ${o}Info: Contract<${i}> = {
|
|
26
|
-
contract: ${o}Contract,
|
|
27
|
-
address: '${r}',
|
|
28
|
-
contractFile: '${t}',
|
|
29
|
-
name: '${e}',
|
|
30
|
-
abi: ${a},
|
|
31
|
-
};
|
|
32
|
-
`},G=(t,r)=>{let e=F(r,!0),n=X(t);return`import { Response, ContractCalls } from '@clarigen/core';
|
|
33
|
-
|
|
34
|
-
// prettier-ignore
|
|
35
|
-
export interface ${e}Contract {
|
|
36
|
-
${n}
|
|
37
|
-
}
|
|
38
|
-
`},tt=t=>{let r=["import type { ContractInstances } from '@clarigen/core';"],e=[],n=[],o="";"accounts"in t&&(o=`
|
|
39
|
-
|
|
40
|
-
// prettier-ignore
|
|
41
|
-
export const accounts = {
|
|
42
|
-
${Object.keys(t.accounts).map(l=>{let p=t.accounts[l];return`"${l}": {
|
|
43
|
-
mnemonic: "${p.mnemonic}",
|
|
44
|
-
balance: ${p.balance.toString()}n,
|
|
45
|
-
address: "${p.address}",
|
|
46
|
-
},`}).join(`
|
|
47
|
-
`)}
|
|
48
|
-
};`),t.contracts.forEach(s=>{let l=s.name,p=F(l),b=`${p}Info`,w=`${F(l,!0)}Contract`,g=Bt(s.file),d=`'./${Jt(g||".",l)}'`,c=`import { ${b} } from ${d};`;r.push(c);let m=`export type { ${w} } from ${d};`;e.push(m);let h=`${p}: ${b},`;n.push(h)});let i=`
|
|
49
|
-
export type Contracts = ContractInstances<typeof contracts>;
|
|
50
|
-
`;return`${r.join(`
|
|
51
|
-
`)}
|
|
52
|
-
${e.join(`
|
|
53
|
-
`)}
|
|
54
|
-
${i}
|
|
55
|
-
export const contracts = {
|
|
56
|
-
${n.join(`
|
|
57
|
-
`)}
|
|
58
|
-
};${o}
|
|
59
|
-
`};import{createClarityBin as ue,deployContract as ge}from"@clarigen/native-bin";import{resolve as $,relative as Ce,dirname as ye}from"path";import{mkdir as de}from"fs/promises";import{createContractDocInfo as Ut,generateMarkdown as Wt}from"@clarigen/claridocs";import{mkdir as zt,readFile as Kt,writeFile as et}from"fs/promises";import{relative as qt,resolve as V}from"path";async function rt({contractFile:t,contractName:r,docsPath:e,abi:n,dirName:o}){let i=await Kt(t,{encoding:"utf-8"}),a=Ut({contractSrc:i,abi:n}),s=V(process.cwd(),e,o||"."),l=V(s,`${r}.md`),p=Wt({contract:a,contractFile:qt(s,t),contractName:r,abi:n});await zt(s,{recursive:!0}),await et(l,p)}async function nt(t){if(!t.docs)return;let e=`# Contracts
|
|
60
|
-
|
|
61
|
-
${t.contracts.map(o=>{let i=o.file.replace(".clar",".md");return`- [\`${o.name}\`](${i})`}).join(`
|
|
62
|
-
`)}
|
|
63
|
-
`,n=V(process.cwd(),t.docs,"README.md");await et(n,e)}import{toCamelCase as v}from"@clarigen/core";import{relative as Ht,resolve as Qt}from"path";import{readFile as Xt}from"fs/promises";import{inspect as O}from"util";function Yt(t){let{abi:r}=t,e=[],d=r,{functions:n,variables:o,maps:i}=d,a=j(d,["functions","variables","maps"]);n.forEach(c=>{let m=`${v(c.name)}: `,P=`[${c.args.map(_=>`${D(_.name)}: ${f(_.type,!0)}`).join(", ")}]`;m+=JSON.stringify(c);let ct=f(c.outputs.type);m+=` as TypedAbiFunction<${P}, ${ct}>`,e.push(m)});let s=t.variables.map(c=>{let m=`${v(c.name)}: `,h=f(c.type);return m+=`${O(c,!1,null,!1)} as TypedAbiVariable<${h}>`,m}),p=t.variables.filter(c=>c.access==="constant").map(c=>`"${v(c.name)}": ${Gt(c.defaultValue)}`),b=i.map(c=>{let m=`${v(c.name)}: `,h=f(c.key),P=f(c.value);return m+=JSON.stringify(c),m+=` as TypedAbiMap<${h}, ${P}>`,m}),w=JSON.stringify(a),g=Ht(process.cwd(),t.contractFile);return`{
|
|
64
|
-
${I("functions",e)}
|
|
65
|
-
${I("variables",s)}
|
|
66
|
-
${I("maps",b)}
|
|
67
|
-
${I("constants",p)}
|
|
68
|
-
${w.slice(1,-1)},
|
|
69
|
-
contractName: '${t.contractName}',
|
|
70
|
-
contractFile: '${g}',
|
|
71
|
-
}`}async function ot(t,r){let e=r.map(a=>{let s=Yt(a);return`${v(a.contractName)}: ${s}`}),n=await te(),o=Zt(t);return`
|
|
72
|
-
${n}
|
|
73
|
-
|
|
74
|
-
export const contracts: Record<string, TypedAbi> = {
|
|
75
|
-
${e.join(`,
|
|
76
|
-
`)}
|
|
77
|
-
} as const;
|
|
78
|
-
|
|
79
|
-
${o}
|
|
80
|
-
`}function Zt(t){let r="";return"accounts"in t&&(r=`export const accounts = {
|
|
81
|
-
${Object.keys(t.accounts).map(n=>{let o=t.accounts[n];return`"${n}": {
|
|
82
|
-
mnemonic: "${o.mnemonic}",
|
|
83
|
-
balance: ${o.balance.toString()}n,
|
|
84
|
-
address: "${o.address}",
|
|
85
|
-
},`}).join(`
|
|
86
|
-
`)}
|
|
87
|
-
} as const;`),r}Uint8Array.prototype[O.custom]=function(){return`Uint8Array.from([${this.join(",")}])`};function Gt(t){return O(t,!1,null,!1)}function I(t,r){return`"${t}": {
|
|
88
|
-
${r.join(`,
|
|
89
|
-
`)}
|
|
90
|
-
},`}async function te(){let t=Qt(u,"../../../core/src/abi-types.ts");return await Xt(t,{encoding:"utf-8"})}import{writeFile as ee}from"fs/promises";import{basename as re}from"path";import{resolveConfig as ne,format as oe}from"prettier";var ie={printWidth:80,semi:!0,singleQuote:!0,trailingComma:"es5"};async function se(){try{let t=await ne(process.cwd());if(t)return t}catch{}return ie}async function ae(t,r){try{let e=re(r),n=await se();return oe(t,x(C({},n),{filepath:e}))}catch{}return t}async function T(t,r){let e=await ae(r,t);await ee(t,e)}import{cvToValue as ce}from"@clarigen/core";import{evalRaw as le}from"@clarigen/native-bin";import{hexToCV as pe}from"micro-stacks/clarity";async function it({abi:t,contractIdentifier:r,provider:e}){let n=t.variables.map(i=>fe({variable:i,provider:e,contractIdentifier:r}));return await Promise.all(n)}async function fe({contractIdentifier:t,variable:r,provider:e}){let n=me(r),o=await le({contractAddress:t,code:n,provider:e}),i=pe(o.output_serialized),a=ce(i,!0);return x(C({},r),{defaultValue:a})}function me(t){let{access:r}=t;return r==="variable"?`(var-get ${t.name})`:t.name}var $e=async({contractFile:t,outputFolder:r,provider:e,contractAddress:n,dirName:o,contractName:i,docsPath:a})=>{let s=$(process.cwd(),t),l=`${n}.${i}`,p=await ge({contractIdentifier:l,contractFilePath:s,provider:e}),b=await it({abi:p,contractIdentifier:l,provider:e}),w=G(p,i),g=Z({contractFile:Ce(process.cwd(),s),contractAddress:n,contractName:i}),d=Y({contractName:i,abi:p});typeof a<"u"&&await rt({contractFile:s,contractName:i,abi:p,docsPath:a,dirName:o});let c=$(r,o||".",i);return await de(c,{recursive:!0}),await T($(c,"abi.ts"),d),await T($(c,"index.ts"),g),await T($(c,"types.ts"),w),{abi:p,contractFile:s,contractName:i,dirName:o,contractAddress:n,variables:b}},k=async t=>{let r=await E(t),{contractsDir:e,outputDir:n,contracts:o}=r,i=$(t,n),a=await ue(),s=[];for(let g of o){let d=$(t,e,g.file),c=ye(g.file),m=await $e({contractFile:d,outputFolder:i,provider:a,contractAddress:g.address,dirName:c,contractName:g.name,docsPath:r.docs});s.push(m)}let l=tt(r);await nt(r);let p=$(i,"index.ts");await T(p,l);let b=await ot(r,s),w=$(i,"single.ts");await T(w,b)};import{watch as xe}from"chokidar";import{basename as we}from"path";import{red as Ae,green as at}from"chalk";var he=mt("ora"),L=class extends be{async run(){let{flags:r}=this.parse(L),e=process.cwd();if(r.watch){let n=he("Generating files").start(),{contractsDir:o}=await E(e),i=xe([o],{cwd:e});try{await k(e),n.succeed("Finished generating files. Watching for changes.")}catch(a){n.fail(`Error generating files.
|
|
91
|
-
${a.message}`)}i.on("change",async a=>{let s=we(a);n.clear(),n.start(`Change detected for ${at(s)}, generating.`);try{await k(e),n.succeed(`Finished generating files for ${at(s)}. Watching for changes.`)}catch(l){let p=l.message;n.fail(`Error after saving ${Ae(s)}.
|
|
92
|
-
${p}`)}}),process.on("SIGINT",async()=>{await i.close(),process.exit()})}else await k(e)}},A=L;A.description="Generate project files",A.strict=!0,A.hidden=!1,A.flags={help:st.help({char:"h"}),watch:st.boolean({char:"w",description:"Watch for changes to your contracts"})},A.args=[];export{A as Generate};
|
package/dist/index.d.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
export { run } from '@oclif/command';
|
|
2
|
-
import { ClarityAbiType } from 'micro-stacks/clarity';
|
|
3
|
-
import { ClarityAbi } from '@clarigen/core';
|
|
4
|
-
import { NativeClarityBinProvider } from '@clarigen/native-bin';
|
|
5
|
-
export { Generate } from './commands/index.js';
|
|
6
|
-
import '@oclif/parser/lib/flags';
|
|
7
|
-
|
|
8
|
-
interface ClarinetConfigAccount {
|
|
9
|
-
mnemonic: string;
|
|
10
|
-
balance: bigint;
|
|
11
|
-
}
|
|
12
|
-
interface ClarinetAccount extends ClarinetConfigAccount {
|
|
13
|
-
address: string;
|
|
14
|
-
}
|
|
15
|
-
interface ClarinetAccounts {
|
|
16
|
-
deployer: ClarinetAccount;
|
|
17
|
-
[name: string]: ClarinetAccount;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
interface ConfigContract {
|
|
21
|
-
address: string;
|
|
22
|
-
file: string;
|
|
23
|
-
name: string;
|
|
24
|
-
}
|
|
25
|
-
interface ConfigFileContents {
|
|
26
|
-
outputDir: string;
|
|
27
|
-
clarinet: string;
|
|
28
|
-
docs?: string;
|
|
29
|
-
}
|
|
30
|
-
interface ConfigFile extends ConfigFileContents {
|
|
31
|
-
contractsDir: string;
|
|
32
|
-
contracts: ConfigContract[];
|
|
33
|
-
accounts: ClarinetAccounts;
|
|
34
|
-
clarinet: string;
|
|
35
|
-
}
|
|
36
|
-
declare const defaultConfigFile: ConfigFileContents;
|
|
37
|
-
declare function configFilePath(rootPath: string): string;
|
|
38
|
-
declare function configFileExists(configPath: string): Promise<boolean>;
|
|
39
|
-
declare function getConfigFile(rootPath: string): Promise<ConfigFileContents>;
|
|
40
|
-
declare function getProjectConfig(rootPath: string): Promise<ConfigFile>;
|
|
41
|
-
|
|
42
|
-
declare const jsTypeFromAbiType: (val: ClarityAbiType, isArgument?: boolean) => string;
|
|
43
|
-
declare function getArgName(name: string): string;
|
|
44
|
-
declare function makePureTypes(abi: ClarityAbi): string;
|
|
45
|
-
|
|
46
|
-
declare const generateInterface: ({ provider, contractFile, contractAddress, contractName, }: {
|
|
47
|
-
contractFile: string;
|
|
48
|
-
provider: NativeClarityBinProvider;
|
|
49
|
-
contractAddress: string;
|
|
50
|
-
contractName: string;
|
|
51
|
-
}) => Promise<ClarityAbi>;
|
|
52
|
-
declare const generateInterfaceFile: ({ contractName, abi, }: {
|
|
53
|
-
contractName: string;
|
|
54
|
-
abi: ClarityAbi;
|
|
55
|
-
}) => string;
|
|
56
|
-
declare const generateIndexFile: ({ contractFile, contractAddress, contractName, }: {
|
|
57
|
-
contractFile: string;
|
|
58
|
-
contractAddress: string;
|
|
59
|
-
contractName: string;
|
|
60
|
-
}) => string;
|
|
61
|
-
declare const generateTypesFile: (abi: ClarityAbi, contractName: string) => string;
|
|
62
|
-
declare const generateProjectIndexFile: (config: ConfigFile) => string;
|
|
63
|
-
|
|
64
|
-
export { ConfigContract, ConfigFile, ConfigFileContents, configFileExists, configFilePath, defaultConfigFile, generateIndexFile, generateInterface, generateInterfaceFile, generateProjectIndexFile, generateTypesFile, getArgName, getConfigFile, getProjectConfig, jsTypeFromAbiType, makePureTypes };
|