@0xobelisk/sui-cli 1.2.0-pre.21 → 1.2.0-pre.24

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xobelisk/sui-cli",
3
- "version": "1.2.0-pre.21",
3
+ "version": "1.2.0-pre.24",
4
4
  "description": "Tookit for interacting with move eps framework",
5
5
  "keywords": [
6
6
  "sui",
@@ -37,6 +37,7 @@
37
37
  "chalk": "^5.0.1",
38
38
  "child_process": "^1.0.2",
39
39
  "chokidar": "^3.5.3",
40
+ "cli-table3": "^0.6.5",
40
41
  "dotenv": "^16.0.3",
41
42
  "ejs": "^3.1.8",
42
43
  "execa": "^7.0.0",
@@ -50,8 +51,8 @@
50
51
  "yargs": "^17.7.1",
51
52
  "zod": "^3.22.3",
52
53
  "zod-validation-error": "^1.3.0",
53
- "@0xobelisk/sui-client": "1.2.0-pre.21",
54
- "@0xobelisk/sui-common": "1.2.0-pre.21"
54
+ "@0xobelisk/sui-client": "1.2.0-pre.24",
55
+ "@0xobelisk/sui-common": "1.2.0-pre.24"
55
56
  },
56
57
  "devDependencies": {
57
58
  "@types/ejs": "^3.1.1",
@@ -1,5 +1,5 @@
1
1
  import type { CommandModule } from 'yargs';
2
- import { execSync } from 'child_process';
2
+ import { execSync, exec } from 'child_process';
3
3
  import chalk from 'chalk';
4
4
  import { DubheConfig, loadConfig } from '@0xobelisk/sui-common';
5
5
  import { switchEnv, updateDubheDependency } from '../utils';
@@ -52,6 +52,7 @@ const commandModule: CommandModule<Options, Options> = {
52
52
  }`;
53
53
  const output = execSync(command, { encoding: 'utf-8' });
54
54
  console.log(output);
55
+ exec(`pnpm dubhe convert-json --config-path ${configPath}`)
55
56
  } catch (error: any) {
56
57
  console.error(chalk.red('Error executing sui move build:'));
57
58
  console.log(error.stdout);
@@ -1,90 +1,90 @@
1
- import type { CommandModule } from 'yargs';
2
- import { logError } from '../utils/errors';
3
- import { callHandler } from '../utils';
4
- import { loadConfig, DubheConfig } from '@0xobelisk/sui-common';
1
+ // import type { CommandModule } from 'yargs';
2
+ // import { logError } from '../utils/errors';
3
+ // import { callHandler } from '../utils';
4
+ // import { loadConfig, DubheConfig } from '@0xobelisk/sui-common';
5
5
 
6
- type Options = {
7
- network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
8
- module: string;
9
- function: string;
10
- 'config-path'?: string;
11
- 'package-id'?: string;
12
- 'metadata-path'?: string;
13
- params?: any[];
14
- };
6
+ // type Options = {
7
+ // network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
8
+ // module: string;
9
+ // function: string;
10
+ // 'config-path'?: string;
11
+ // 'package-id'?: string;
12
+ // 'metadata-path'?: string;
13
+ // params?: any[];
14
+ // };
15
15
 
16
- /**
17
- * CLI command for calling a function in a module
18
- */
19
- const commandModule: CommandModule<Options, Options> = {
20
- command: 'call',
16
+ // /**
17
+ // * CLI command for calling a function in a module
18
+ // */
19
+ // const commandModule: CommandModule<Options, Options> = {
20
+ // command: 'call',
21
21
 
22
- describe: 'Call a function in a module',
22
+ // describe: 'Call a function in a module',
23
23
 
24
- builder: {
25
- network: {
26
- type: 'string',
27
- choices: ['mainnet', 'testnet', 'devnet', 'localnet'],
28
- desc: 'Node network (mainnet/testnet/devnet/localnet)',
29
- default: 'localnet'
30
- },
31
- module: {
32
- type: 'string',
33
- desc: 'Module name',
34
- demandOption: true
35
- },
36
- function: {
37
- type: 'string',
38
- desc: 'Function name',
39
- demandOption: true
40
- },
41
- 'config-path': {
42
- type: 'string',
43
- default: 'dubhe.config.ts',
44
- desc: 'Configuration file path'
45
- },
46
- 'package-id': {
47
- type: 'string',
48
- desc: 'Package ID (optional)'
49
- },
50
- 'metadata-path': {
51
- type: 'string',
52
- desc: 'Path to metadata JSON file (optional)'
53
- },
54
- params: {
55
- type: 'array',
56
- desc: 'Params for the function',
57
- string: true
58
- }
59
- },
24
+ // builder: {
25
+ // network: {
26
+ // type: 'string',
27
+ // choices: ['mainnet', 'testnet', 'devnet', 'localnet'],
28
+ // desc: 'Node network (mainnet/testnet/devnet/localnet)',
29
+ // default: 'localnet'
30
+ // },
31
+ // module: {
32
+ // type: 'string',
33
+ // desc: 'Module name',
34
+ // demandOption: true
35
+ // },
36
+ // function: {
37
+ // type: 'string',
38
+ // desc: 'Function name',
39
+ // demandOption: true
40
+ // },
41
+ // 'config-path': {
42
+ // type: 'string',
43
+ // default: 'dubhe.config.ts',
44
+ // desc: 'Configuration file path'
45
+ // },
46
+ // 'package-id': {
47
+ // type: 'string',
48
+ // desc: 'Package ID (optional)'
49
+ // },
50
+ // 'metadata-path': {
51
+ // type: 'string',
52
+ // desc: 'Path to metadata JSON file (optional)'
53
+ // },
54
+ // params: {
55
+ // type: 'array',
56
+ // desc: 'Params for the function',
57
+ // string: true
58
+ // }
59
+ // },
60
60
 
61
- async handler({
62
- network,
63
- 'config-path': configPath,
64
- module: moduleName,
65
- function: funcName,
66
- 'package-id': packageId,
67
- 'metadata-path': metadataPath,
68
- params
69
- }) {
70
- try {
71
- const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
61
+ // async handler({
62
+ // network,
63
+ // 'config-path': configPath,
64
+ // module: moduleName,
65
+ // function: funcName,
66
+ // 'package-id': packageId,
67
+ // 'metadata-path': metadataPath,
68
+ // params
69
+ // }) {
70
+ // try {
71
+ // const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
72
72
 
73
- await callHandler({
74
- dubheConfig,
75
- moduleName,
76
- funcName,
77
- network,
78
- packageId,
79
- metadataFilePath: metadataPath,
80
- params
81
- });
82
- } catch (error: any) {
83
- logError(error);
84
- process.exit(1);
85
- }
86
- process.exit(0);
87
- }
88
- };
73
+ // await callHandler({
74
+ // dubheConfig,
75
+ // moduleName,
76
+ // funcName,
77
+ // network,
78
+ // packageId,
79
+ // metadataFilePath: metadataPath,
80
+ // params
81
+ // });
82
+ // } catch (error: any) {
83
+ // logError(error);
84
+ // process.exit(1);
85
+ // }
86
+ // process.exit(0);
87
+ // }
88
+ // };
89
89
 
90
- export default commandModule;
90
+ // export default commandModule;
@@ -0,0 +1,49 @@
1
+ import type { CommandModule } from 'yargs';
2
+ import chalk from 'chalk';
3
+ import { DubheConfig, loadConfig } from '@0xobelisk/sui-common';
4
+ import { generateConfigJson } from '../utils';
5
+ import fs from 'fs';
6
+
7
+ type Options = {
8
+ 'config-path': string;
9
+ 'output-path': string;
10
+ };
11
+
12
+ const commandModule: CommandModule<Options, Options> = {
13
+ command: 'convert-json',
14
+ describe: 'Convert JSON from Dubhe config to config.json',
15
+ builder(yargs) {
16
+ return yargs.options({
17
+ 'config-path': {
18
+ type: 'string',
19
+ default: 'dubhe.config.ts',
20
+ description: 'Options to pass to forge test'
21
+ },
22
+ 'output-path': {
23
+ type: 'string',
24
+ default: 'dubhe.config.json',
25
+ description: 'Output path for the config.json file'
26
+ }
27
+ });
28
+ },
29
+
30
+ async handler({
31
+ 'config-path': configPath,
32
+ 'output-path': outputPath
33
+ }) {
34
+ // Start an internal anvil process if no world address is provided
35
+ try {
36
+ console.log('šŸš€ Running convert json');
37
+ const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
38
+ const json = generateConfigJson(dubheConfig);
39
+ // write to file
40
+ fs.writeFileSync(outputPath, json);
41
+ } catch (error: any) {
42
+ console.error(chalk.red('Error executing convert json:'));
43
+ console.log(error.stdout);
44
+ process.exit(0);
45
+ }
46
+ }
47
+ };
48
+
49
+ export default commandModule;
@@ -0,0 +1,348 @@
1
+ import type { CommandModule } from 'yargs';
2
+ import chalk from 'chalk';
3
+ import { spawn } from 'child_process';
4
+ import { existsSync } from 'fs';
5
+ import { homedir } from 'os';
6
+ import { join } from 'path';
7
+ import Table from 'cli-table3';
8
+
9
+ // Check result type
10
+ interface CheckResult {
11
+ name: string;
12
+ status: 'success' | 'warning' | 'error';
13
+ message: string;
14
+ fixSuggestion?: string;
15
+ }
16
+
17
+ // Execute shell command and return output
18
+ async function execCommand(
19
+ command: string,
20
+ args: string[] = []
21
+ ): Promise<{ code: number; stdout: string; stderr: string }> {
22
+ return new Promise((resolve) => {
23
+ const child = spawn(command, args, { shell: true });
24
+ let stdout = '';
25
+ let stderr = '';
26
+
27
+ child.stdout?.on('data', (data) => {
28
+ stdout += data.toString();
29
+ });
30
+
31
+ child.stderr?.on('data', (data) => {
32
+ stderr += data.toString();
33
+ });
34
+
35
+ child.on('close', (code) => {
36
+ resolve({ code: code || 0, stdout, stderr });
37
+ });
38
+
39
+ child.on('error', () => {
40
+ resolve({ code: -1, stdout, stderr });
41
+ });
42
+ });
43
+ }
44
+
45
+ // Check if command is available in PATH
46
+ async function checkCommand(
47
+ command: string,
48
+ versionFlag: string = '--version'
49
+ ): Promise<CheckResult> {
50
+ try {
51
+ const result = await execCommand(command, [versionFlag]);
52
+ if (result.code === 0) {
53
+ const version = result.stdout.trim().split('\n')[0];
54
+ return {
55
+ name: command,
56
+ status: 'success',
57
+ message: `Installed ${version}`
58
+ };
59
+ } else {
60
+ return {
61
+ name: command,
62
+ status: 'error',
63
+ message: 'Not installed',
64
+ fixSuggestion: getInstallSuggestion(command)
65
+ };
66
+ }
67
+ } catch (error) {
68
+ return {
69
+ name: command,
70
+ status: 'error',
71
+ message: 'Not installed',
72
+ fixSuggestion: getInstallSuggestion(command)
73
+ };
74
+ }
75
+ }
76
+
77
+ // Get installation suggestions
78
+ function getInstallSuggestion(command: string): string {
79
+ const suggestions: Record<string, string> = {
80
+ docker: 'Visit https://docs.docker.com/get-docker/ to install Docker',
81
+ 'docker-compose': 'Visit https://docs.docker.com/compose/install/ to install Docker Compose',
82
+ sui: 'Visit https://docs.sui.io/guides/developer/getting-started/sui-install to install Sui CLI',
83
+ pnpm: 'Run: npm install -g pnpm',
84
+ node: 'Visit https://nodejs.org/ to download and install Node.js',
85
+ git: 'Visit https://git-scm.com/downloads to install Git'
86
+ };
87
+
88
+ return suggestions[command] || `Please install ${command}`;
89
+ }
90
+
91
+ // Check if file exists
92
+ function checkFileExists(filePath: string, description: string): CheckResult {
93
+ const exists = existsSync(filePath);
94
+ return {
95
+ name: description,
96
+ status: exists ? 'success' : 'warning',
97
+ message: exists ? 'Available' : 'Not found',
98
+ fixSuggestion: exists ? undefined : `Please create file: ${filePath}`
99
+ };
100
+ }
101
+
102
+ // Check Node.js version
103
+ async function checkNodeVersion(): Promise<CheckResult> {
104
+ try {
105
+ const result = await execCommand('node', ['--version']);
106
+ if (result.code === 0) {
107
+ const version = result.stdout.trim();
108
+ const versionNumber = parseFloat(version.replace('v', ''));
109
+
110
+ if (versionNumber >= 18) {
111
+ return {
112
+ name: 'Node.js version',
113
+ status: 'success',
114
+ message: `${version} (meets requirement >=18.0)`
115
+ };
116
+ } else {
117
+ return {
118
+ name: 'Node.js version',
119
+ status: 'warning',
120
+ message: `${version} (recommend upgrade to >=18.0)`,
121
+ fixSuggestion: 'Please upgrade Node.js to 18.0 or higher'
122
+ };
123
+ }
124
+ } else {
125
+ return {
126
+ name: 'Node.js version',
127
+ status: 'error',
128
+ message: 'Not installed',
129
+ fixSuggestion: 'Please install Node.js 18.0 or higher'
130
+ };
131
+ }
132
+ } catch (error) {
133
+ return {
134
+ name: 'Node.js version',
135
+ status: 'error',
136
+ message: 'Check failed',
137
+ fixSuggestion: 'Please install Node.js'
138
+ };
139
+ }
140
+ }
141
+
142
+ // Check Docker service status
143
+ async function checkDockerService(): Promise<CheckResult> {
144
+ try {
145
+ const result = await execCommand('docker', ['info']);
146
+ if (result.code === 0) {
147
+ return {
148
+ name: 'Docker service',
149
+ status: 'success',
150
+ message: 'Running'
151
+ };
152
+ } else {
153
+ return {
154
+ name: 'Docker service',
155
+ status: 'warning',
156
+ message: 'Not running',
157
+ fixSuggestion: 'Please start Docker service'
158
+ };
159
+ }
160
+ } catch (error) {
161
+ return {
162
+ name: 'Docker service',
163
+ status: 'error',
164
+ message: 'Check failed',
165
+ fixSuggestion: 'Please install and start Docker'
166
+ };
167
+ }
168
+ }
169
+
170
+ // Check NPM configuration
171
+ async function checkNpmConfig(): Promise<CheckResult> {
172
+ try {
173
+ const result = await execCommand('npm', ['config', 'get', 'registry']);
174
+ if (result.code === 0) {
175
+ const registry = result.stdout.trim();
176
+ return {
177
+ name: 'NPM configuration',
178
+ status: 'success',
179
+ message: `Configured (${registry})`
180
+ };
181
+ } else {
182
+ return {
183
+ name: 'NPM configuration',
184
+ status: 'warning',
185
+ message: 'Configuration issue',
186
+ fixSuggestion: 'Check NPM config: npm config list'
187
+ };
188
+ }
189
+ } catch (error) {
190
+ return {
191
+ name: 'NPM configuration',
192
+ status: 'warning',
193
+ message: 'Check failed',
194
+ fixSuggestion: 'Please install Node.js and NPM'
195
+ };
196
+ }
197
+ }
198
+
199
+ // Create table row data
200
+ function formatTableRow(result: CheckResult): string[] {
201
+ const statusIcon = {
202
+ success: chalk.green('āœ“'),
203
+ warning: chalk.yellow('!'),
204
+ error: chalk.red('āœ—')
205
+ };
206
+
207
+ const statusText = {
208
+ success: chalk.green('YES'),
209
+ warning: chalk.yellow('WARN'),
210
+ error: chalk.red('NO')
211
+ };
212
+
213
+ // Decide what content to display based on status
214
+ let fixContent = '';
215
+ if (result.status === 'success') {
216
+ fixContent = result.message;
217
+ } else {
218
+ fixContent = result.fixSuggestion || result.message;
219
+ }
220
+
221
+ return [result.name, `${statusIcon[result.status]} ${statusText[result.status]}`, fixContent];
222
+ }
223
+
224
+ // Main check function
225
+ async function runDoctorChecks() {
226
+ console.log(chalk.bold.blue('\nšŸ” Dubhe Doctor - Environment Check Tool\n'));
227
+ console.log(chalk.gray('Checking your development environment...\n'));
228
+
229
+ const results: CheckResult[] = [];
230
+
231
+ // Execute all checks
232
+ console.log('Running checks...\n');
233
+
234
+ // Required tools check
235
+ const nodeCheck = await checkNodeVersion();
236
+ results.push(nodeCheck);
237
+
238
+ const pnpmCheck = await checkCommand('pnpm');
239
+ results.push(pnpmCheck);
240
+
241
+ const gitCheck = await checkCommand('git');
242
+ results.push(gitCheck);
243
+
244
+ // Package manager configuration check
245
+ const npmConfigCheck = await checkNpmConfig();
246
+ // Treat npm config as optional, don't affect overall status
247
+ if (npmConfigCheck.status === 'error') {
248
+ npmConfigCheck.status = 'warning';
249
+ }
250
+ results.push(npmConfigCheck);
251
+
252
+ // Docker related checks
253
+ const dockerCheck = await checkCommand('docker');
254
+ results.push(dockerCheck);
255
+
256
+ let dockerServiceCheck: CheckResult | null = null;
257
+ if (dockerCheck.status === 'success') {
258
+ dockerServiceCheck = await checkDockerService();
259
+ results.push(dockerServiceCheck);
260
+ }
261
+
262
+ const dockerComposeCheck = await checkCommand('docker-compose');
263
+ results.push(dockerComposeCheck);
264
+
265
+ // Sui CLI check
266
+ const suiCheck = await checkCommand('sui');
267
+ results.push(suiCheck);
268
+
269
+ // Configuration files check
270
+ const gitConfigCheck = checkFileExists(join(homedir(), '.gitconfig'), 'Git configuration');
271
+ results.push(gitConfigCheck);
272
+
273
+ // Create and display table
274
+ const table = new Table({
275
+ head: [chalk.bold.cyan('Criteria'), chalk.bold.cyan('Result'), chalk.bold.cyan('Fix')],
276
+ colWidths: [25, 15, 50],
277
+ style: {
278
+ head: ['cyan'],
279
+ border: ['grey']
280
+ },
281
+ wordWrap: true
282
+ });
283
+
284
+ // Add table rows
285
+ results.forEach((result) => {
286
+ table.push(formatTableRow(result));
287
+ });
288
+
289
+ console.log(table.toString());
290
+
291
+ // Summarize results
292
+ const summary = {
293
+ success: results.filter((r) => r.status === 'success').length,
294
+ warning: results.filter((r) => r.status === 'warning').length,
295
+ error: results.filter((r) => r.status === 'error').length
296
+ };
297
+
298
+ console.log('\n' + chalk.bold('šŸ“Š Check Summary:'));
299
+ console.log(` ${chalk.green('āœ“ Passed:')} ${summary.success} items`);
300
+ console.log(` ${chalk.yellow('! Warning:')} ${summary.warning} items`);
301
+ console.log(` ${chalk.red('āœ— Error:')} ${summary.error} items`);
302
+
303
+ if (summary.error > 0) {
304
+ console.log(
305
+ chalk.red(
306
+ '\nāŒ Your environment has some issues, please fix them according to the suggestions above.'
307
+ )
308
+ );
309
+ process.exit(1);
310
+ } else if (summary.warning > 0) {
311
+ console.log(
312
+ chalk.yellow(
313
+ '\nāš ļø Your environment is basically ready, but it is recommended to fix warning items for a better development experience.'
314
+ )
315
+ );
316
+ } else {
317
+ console.log(chalk.green('\nāœ… Congratulations! Your development environment is fully ready!'));
318
+ }
319
+
320
+ console.log(
321
+ chalk.gray(
322
+ '\nšŸ’” Tip: For more help, visit https://docs.sui.io/ or https://github.com/0xobelisk/dubhe'
323
+ )
324
+ );
325
+ }
326
+
327
+ const commandModule: CommandModule = {
328
+ command: 'doctor',
329
+ describe: 'Check if local development environment is ready',
330
+ builder(yargs) {
331
+ return yargs.option('verbose', {
332
+ alias: 'v',
333
+ type: 'boolean',
334
+ description: 'Show verbose output',
335
+ default: false
336
+ });
337
+ },
338
+ async handler() {
339
+ try {
340
+ await runDoctorChecks();
341
+ } catch (error) {
342
+ console.error(chalk.red('Error occurred during check:'), error);
343
+ process.exit(1);
344
+ }
345
+ }
346
+ };
347
+
348
+ export default commandModule;
@@ -4,29 +4,29 @@ import localnode from './localnode';
4
4
  import faucet from './faucet';
5
5
  import schemagen from './schemagen';
6
6
  import publish from './publish';
7
- import upgrade from './upgrade';
8
7
  import test from './test';
9
8
  import build from './build';
10
9
  import hello from './hello';
11
10
  import generateKey from './generateKey';
12
11
  import checkBalance from './checkBalance';
13
12
  import configStore from './configStore';
14
- import query from './query';
15
- import call from './call';
16
13
  import watch from './watch';
17
14
  import wait from './wait';
18
15
  import switchEnv from './switchEnv';
19
16
  import info from './info';
17
+ import loadMetadata from './loadMetadata';
18
+ import doctor from './doctor';
19
+ import convertJson from './convertJson';
20
20
 
21
21
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Each command has different options
22
22
  export const commands: CommandModule<any, any>[] = [
23
23
  localnode,
24
24
  publish,
25
- call,
26
- query,
25
+ // call,
26
+ // query,
27
27
  faucet,
28
28
  schemagen,
29
- upgrade,
29
+ // upgrade,
30
30
  test,
31
31
  build,
32
32
  hello,
@@ -36,5 +36,8 @@ export const commands: CommandModule<any, any>[] = [
36
36
  watch,
37
37
  wait,
38
38
  switchEnv,
39
- info
39
+ info,
40
+ loadMetadata,
41
+ doctor,
42
+ convertJson
40
43
  ];