@blocklet/cli 1.16.33 → 1.16.34-beta-20241120-080738-bbbe036c

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.
Files changed (87) hide show
  1. package/README.md +32 -25
  2. package/bin/blocklet.js +292 -1
  3. package/config.example.yml +33 -0
  4. package/lib/arcblock.js +53 -0
  5. package/lib/commands/blocklet/add.js +124 -0
  6. package/lib/commands/blocklet/assets/git-ignore +28 -0
  7. package/lib/commands/blocklet/assets/index.html +9 -0
  8. package/lib/commands/blocklet/assets/index.js +14 -0
  9. package/lib/commands/blocklet/assets/logo.png +0 -0
  10. package/lib/commands/blocklet/bundle/bundle.js +184 -0
  11. package/lib/commands/blocklet/bundle/bundlers/blocklet.js +138 -0
  12. package/lib/commands/blocklet/bundle/bundlers/changelog.js +100 -0
  13. package/lib/commands/blocklet/bundle/bundlers/logo.js +56 -0
  14. package/lib/commands/blocklet/bundle/bundlers/markdown.js +241 -0
  15. package/lib/commands/blocklet/bundle/bundlers/preference.js +50 -0
  16. package/lib/commands/blocklet/bundle/bundlers/readme.js +43 -0
  17. package/lib/commands/blocklet/bundle/bundlers/screenshots.js +94 -0
  18. package/lib/commands/blocklet/bundle/bundlers/simple.js +70 -0
  19. package/lib/commands/blocklet/bundle/compact/bundle-compact-file.js +48 -0
  20. package/lib/commands/blocklet/bundle/compact/bundle-merge-extra.js +66 -0
  21. package/lib/commands/blocklet/bundle/compact/default-external.js +5 -0
  22. package/lib/commands/blocklet/bundle/compact/index.js +88 -0
  23. package/lib/commands/blocklet/bundle/index.js +139 -0
  24. package/lib/commands/blocklet/bundle/pack.js +8 -0
  25. package/lib/commands/blocklet/bundle/parse-external-dependencies.js +97 -0
  26. package/lib/commands/blocklet/bundle/simple/index.js +62 -0
  27. package/lib/commands/blocklet/bundle/zip/archive.js +35 -0
  28. package/lib/commands/blocklet/bundle/zip/dependencies.js +333 -0
  29. package/lib/commands/blocklet/bundle/zip/index.js +165 -0
  30. package/lib/commands/blocklet/bundle/zip/main.js +124 -0
  31. package/lib/commands/blocklet/bundle/zip/node.js +59 -0
  32. package/lib/commands/blocklet/bundle/zip/resolve.js +93 -0
  33. package/lib/commands/blocklet/cleanup.js +52 -0
  34. package/lib/commands/blocklet/config.js +108 -0
  35. package/lib/commands/blocklet/connect.js +87 -0
  36. package/lib/commands/blocklet/create.js +38 -0
  37. package/lib/commands/blocklet/deploy.js +435 -0
  38. package/lib/commands/blocklet/dev.js +1000 -0
  39. package/lib/commands/blocklet/document.js +39 -0
  40. package/lib/commands/blocklet/exec.js +106 -0
  41. package/lib/commands/blocklet/init.js +300 -0
  42. package/lib/commands/blocklet/meta.js +22 -0
  43. package/lib/commands/blocklet/remove.js +35 -0
  44. package/lib/commands/blocklet/test.js +201 -0
  45. package/lib/commands/blocklet/upload.js +105 -0
  46. package/lib/commands/blocklet/version.js +81 -0
  47. package/lib/commands/server/cleanup.js +32 -0
  48. package/lib/commands/server/command.js +131 -0
  49. package/lib/commands/server/info.js +92 -0
  50. package/lib/commands/server/init.js +433 -0
  51. package/lib/commands/server/logs.js +99 -0
  52. package/lib/commands/server/rescue.js +71 -0
  53. package/lib/commands/server/start.js +821 -0
  54. package/lib/commands/server/status.js +107 -0
  55. package/lib/commands/server/stop.js +163 -0
  56. package/lib/commands/server/upgrade.js +123 -0
  57. package/lib/constant.js +21 -2
  58. package/lib/debug.js +20 -0
  59. package/lib/manager/config.js +122 -0
  60. package/lib/manager/deploy.js +75 -0
  61. package/lib/manager/index.js +23 -0
  62. package/lib/manager/process.js +47 -0
  63. package/lib/node.js +214 -0
  64. package/lib/port.js +19 -0
  65. package/lib/postinstall.js +3 -0
  66. package/lib/process/daemon.js +196 -0
  67. package/lib/process/service.js +86 -0
  68. package/lib/ui.js +137 -0
  69. package/lib/util/blocklet/config.js +78 -0
  70. package/lib/util/blocklet/env.js +172 -0
  71. package/lib/util/blocklet/meta.js +36 -0
  72. package/lib/util/blocklet/payment.js +88 -0
  73. package/lib/util/blocklet/sign.js +21 -0
  74. package/lib/util/blocklet/tar.js +119 -0
  75. package/lib/util/convert-to-nosources-sourcemap.js +37 -0
  76. package/lib/util/docker-status-log.js +17 -0
  77. package/lib/util/exit-when-server-stopped.js +44 -0
  78. package/lib/util/get-cli-binary-name.js +8 -0
  79. package/lib/util/get-download-bundle-step.js +36 -0
  80. package/lib/util/get-service-instance-number.js +12 -0
  81. package/lib/util/index.js +626 -0
  82. package/lib/util/print-error.js +11 -0
  83. package/lib/util/print.js +9 -0
  84. package/lib/util/what-uri.js +40 -0
  85. package/package.json +123 -27
  86. package/lib/run.d.ts +0 -2
  87. package/lib/run.js +0 -73
@@ -0,0 +1,93 @@
1
+ /* eslint-disable no-use-before-define */
2
+ /* eslint-disable func-names */
3
+ const { version: nodeVersion } = require('process');
4
+
5
+ const findUp = require('find-up');
6
+ const pathExists = require('path-exists');
7
+ const resolve = require('resolve');
8
+ const { lt: ltVersion } = require('semver');
9
+
10
+ // Find the path to a module's `package.json`
11
+ // We need to use `resolve` instead of `require.resolve()` because:
12
+ // - it is async
13
+ // - it preserves symlinks:
14
+ // - this is important because if a file does a `require('./symlink')`, we
15
+ // need to bundle the symlink and its target, not only the target
16
+ // - `path.resolve()` cannot be used for relative|absolute file paths
17
+ // because it does not resolve ommitted file extension,
18
+ // e.g. `require('./file')` instead of `require('./file.js')`
19
+ // - the CLI flag `--preserve-symlinks` can be used with Node.js, but it
20
+ // cannot be set runtime
21
+ // However it does not give helpful error messages.
22
+ // https://github.com/browserify/resolve/issues/223
23
+ // So, on errors, we fallback to `require.resolve()`
24
+ const resolvePackage = async function (moduleName, basedir) {
25
+ try {
26
+ return await resolvePathPreserveSymlinks(`${moduleName}/package.json`, basedir);
27
+ } catch (error) {
28
+ if (ltVersion(nodeVersion, REQUEST_RESOLVE_MIN_VERSION)) {
29
+ throw error;
30
+ }
31
+
32
+ try {
33
+ return resolvePathFollowSymlinks(`${moduleName}/package.json`, basedir);
34
+ } catch (err) {
35
+ const packagePath = resolvePackageFallback(moduleName, basedir);
36
+ if (packagePath === undefined) {
37
+ throw err;
38
+ }
39
+ return packagePath;
40
+ }
41
+ }
42
+ };
43
+
44
+ // TODO: remove after dropping support for Node <8.9.0
45
+ // `require.resolve()` option `paths` was introduced in Node 8.9.0
46
+ const REQUEST_RESOLVE_MIN_VERSION = '8.9.0';
47
+
48
+ // We need to use `new Promise()` due to a bug with `utils.promisify()` on
49
+ // `resolve`:
50
+ // https://github.com/browserify/resolve/issues/151#issuecomment-368210310
51
+ const resolvePathPreserveSymlinks = function (path, basedir) {
52
+ return new Promise((success, reject) => {
53
+ resolve(path, { basedir, preserveSymlinks: true }, (error, resolvedLocation) => {
54
+ if (error) {
55
+ return reject(error);
56
+ }
57
+
58
+ return success(resolvedLocation);
59
+ });
60
+ });
61
+ };
62
+
63
+ const resolvePathFollowSymlinks = function (path, basedir) {
64
+ return require.resolve(path, { paths: [basedir] });
65
+ };
66
+
67
+ // `require.resolve()` on a module's specific file (like `package.json`)
68
+ // can be forbidden by the package author by using an `exports` field in
69
+ // their `package.json`. We need this fallback.
70
+ // It looks for the first directory up from a package's `main` file that:
71
+ // - is named like the package
72
+ // - has a `package.json`
73
+ // Theoritically, this might not the root `package.json`, but this is very
74
+ // unlikely, and we don't have any better alternative.
75
+ const resolvePackageFallback = function (moduleName, basedir) {
76
+ const mainFilePath = resolvePathFollowSymlinks(moduleName, basedir);
77
+ return findUp(isPackageDir.bind(null, moduleName), { cwd: mainFilePath, type: 'directory' });
78
+ };
79
+
80
+ const isPackageDir = async function (moduleName, dir) {
81
+ // Need to use `endsWith()` to take into account `@scope/package`.
82
+ // Backslashes need to be converted for Windows.
83
+ if (!dir.replace(BACKSLASH_REGEXP, '/').endsWith(moduleName) || !(await pathExists(`${dir}/package.json`))) {
84
+ return;
85
+ }
86
+
87
+ // eslint-disable-next-line consistent-return
88
+ return dir;
89
+ };
90
+
91
+ const BACKSLASH_REGEXP = /\\/g;
92
+
93
+ module.exports = { resolvePackage, resolvePathPreserveSymlinks };
@@ -0,0 +1,52 @@
1
+ const { BLOCKLET_CONFIGURABLE_KEY } = require('@blocklet/constant');
2
+ const { isValid: isValidDid, toAddress } = require('@arcblock/did');
3
+ const { printSuccess, printError } = require('../../util');
4
+ const { getNode } = require('../../node');
5
+
6
+ exports.run = async ({ target, appDid }) => {
7
+ if (!appDid) {
8
+ printError('Please provide `--app-did` when cleanup cache or backup');
9
+ process.exit(1);
10
+ }
11
+ if (isValidDid(appDid) === false) {
12
+ printError(`appDid is not valid: ${appDid}`);
13
+ process.exit(1);
14
+ }
15
+
16
+ // eslint-disable-next-line
17
+ appDid = toAddress(appDid);
18
+
19
+ const { node } = await getNode({ dir: process.cwd() });
20
+ node.onReady(async () => {
21
+ const blocklet = await node.getBlocklet({ did: appDid });
22
+ if (!blocklet) {
23
+ printError(`Blocklet ${appDid} not found`);
24
+ process.exit(1);
25
+ }
26
+
27
+ if (target === 'cache') {
28
+ const removed = await node.clearCache({ pattern: null, teamDid: appDid });
29
+ printSuccess(`Cache for app ${appDid} cleared: ${removed.join(',')}`);
30
+ process.exit(0);
31
+ }
32
+
33
+ if (target === 'backup') {
34
+ await node.configBlocklet({
35
+ did: appDid,
36
+ configs: [
37
+ {
38
+ key: BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_BACKUP_ENDPOINT,
39
+ value: '',
40
+ },
41
+ ],
42
+ });
43
+ await node.updateAutoBackup({ did: appDid, autoBackup: { enabled: false } });
44
+
45
+ printSuccess(`Blocklet ${appDid} auto-backup disabled`);
46
+ process.exit(0);
47
+ }
48
+
49
+ printError(`Unknown cleanup target: ${target}`);
50
+ process.exit(1);
51
+ });
52
+ };
@@ -0,0 +1,108 @@
1
+ const chalk = require('chalk');
2
+ const $get = require('lodash/get');
3
+ const { fromSecretKey } = require('@ocap/wallet');
4
+ const { isValid } = require('@arcblock/did');
5
+
6
+ const Config = require('../../util/blocklet/config');
7
+ const { print, printSuccess, printError } = require('../../util');
8
+
9
+ const getConfig = (profile) => {
10
+ return new Config({ configFile: process.env.ABT_NODE_CONFIG_FILE, section: profile === 'default' ? '' : profile });
11
+ };
12
+
13
+ const getProfile = (command) => $get(command, 'parent._optionValues.profile') || $get(command, '_optionValues.profile');
14
+
15
+ const whiteList = ['store', 'accessToken', 'registry', 'developerDid', 'name', 'email'];
16
+
17
+ function validate(key, value) {
18
+ const validatorMap = {
19
+ store: (v) => {
20
+ // 校验是否为合法的url地址(必须是 http 或 https 协议),例如:https://store.blocklet.dev/
21
+ if (/^((https?):\/\/)[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?$/.test(v)) {
22
+ return true;
23
+ }
24
+ print('Invalid store url:', v);
25
+ return false;
26
+ },
27
+ // TODO: remove this in the future
28
+ registry(...args) {
29
+ return validatorMap.store(...args);
30
+ },
31
+ accessToken: (v) => {
32
+ try {
33
+ fromSecretKey(v);
34
+ } catch {
35
+ print('Invalid access token:', v);
36
+ return false;
37
+ }
38
+ return true;
39
+ },
40
+ developerDid: (v) => {
41
+ try {
42
+ return isValid(v);
43
+ } catch {
44
+ return false;
45
+ }
46
+ },
47
+ };
48
+ const fn = validatorMap[key] || (() => true);
49
+ return fn(value);
50
+ }
51
+
52
+ function set(key, value, options, command) {
53
+ if (whiteList.includes(key)) {
54
+ if (validate(key, value)) {
55
+ getConfig(getProfile(command)).set(key, value);
56
+ printSuccess(`Config ${key} successfully`);
57
+ process.exit(0);
58
+ } else {
59
+ printError(`Unexpected config value ${value} for ${key}`);
60
+ process.exit(1);
61
+ }
62
+ } else {
63
+ printError(`Support config keys are: ${whiteList.join(', ')}`);
64
+ process.exit(1);
65
+ }
66
+ }
67
+
68
+ function get(key, options, command) {
69
+ print(Config.stringify(getConfig(getProfile(command)).get(key)));
70
+ process.exit(0);
71
+ }
72
+
73
+ function list(options, command) {
74
+ const profile = getProfile(command);
75
+ const config = getConfig(profile).get();
76
+ if (config) {
77
+ print(Config.stringify(config));
78
+ } else {
79
+ print(`No config found for profile ${chalk.cyan(profile)}`);
80
+ }
81
+ process.exit(0);
82
+ }
83
+
84
+ function unset(key, options, command) {
85
+ getConfig(getProfile(command)).unset(key);
86
+ print(`Delete config ${key} successfully`);
87
+ process.exit(0);
88
+ }
89
+
90
+ module.exports = {
91
+ set,
92
+ get,
93
+ list,
94
+ del: unset,
95
+ delete: unset,
96
+
97
+ run: (command, options) => {
98
+ const [key, value] = options.args;
99
+
100
+ if (typeof key === 'undefined') {
101
+ list(key, command);
102
+ } else if (typeof value !== 'undefined') {
103
+ set(key, value, command);
104
+ } else {
105
+ get(key, command);
106
+ }
107
+ },
108
+ };
@@ -0,0 +1,87 @@
1
+ /* eslint-disable global-require */
2
+ const chalk = require('chalk');
3
+ const { createConnect } = require('@blocklet/store');
4
+ const { getStoreUrl } = require('@abtnode/core/lib/util/store');
5
+ const isUndefined = require('lodash/isUndefined');
6
+ const open = require('open');
7
+ const validUrl = require('valid-url');
8
+ const inquirer = require('inquirer');
9
+ const { printError, printInfo, printSuccess, getCLIBinaryName } = require('../../util');
10
+ const Config = require('../../util/blocklet/config');
11
+ const { wrapSpinner } = require('../../ui');
12
+
13
+ /**
14
+ *
15
+ * @description 确认是否要覆盖之前填写的store url,回车或输入y直接覆盖,输入其他字符就不覆盖
16
+ * @see https://www.npmjs.com/package/inquirer
17
+ * @see https://github.com/SBoudrias/Inquirer.js/blob/0053e3f5694a4f75c4901512ab87e8906d1d7896/packages/inquirer/examples/pizza.js
18
+ * @default false
19
+ * @return {boolean}
20
+ */
21
+ async function confirmOverwriteStoreUrl() {
22
+ const { isRewriteStore } = await inquirer.prompt([
23
+ {
24
+ name: 'isRewriteStore',
25
+ type: 'confirm',
26
+ default: false,
27
+ message: 'The store url has been set, do you need to overwrite it?',
28
+ },
29
+ ]);
30
+
31
+ return isRewriteStore;
32
+ }
33
+
34
+ const run = async (store, { profile }) => {
35
+ // 校验是否为合法的url地址(必须是 http 或 https 协议),例如:https://store.blocklet.dev/
36
+ if (!validUrl.isWebUri(store)) {
37
+ printError('Invalid store url:', store);
38
+ process.exit(1);
39
+ }
40
+
41
+ try {
42
+ const storeUrl = await getStoreUrl(store);
43
+
44
+ // 读取配置
45
+ const config = new Config({
46
+ configFile: process.env.ABT_NODE_CONFIG_FILE,
47
+ section: profile === 'default' ? '' : profile,
48
+ });
49
+
50
+ const oldStoreUrl = config.get('store');
51
+ // 配置过store url,前后两次配置不一样,且选择不覆盖配置时,退出程序
52
+ if (!isUndefined(oldStoreUrl) && oldStoreUrl !== storeUrl && !(await confirmOverwriteStoreUrl())) {
53
+ process.exit(0);
54
+ }
55
+
56
+ const fetchData = await createConnect({
57
+ connectUrl: storeUrl,
58
+ connectAction: 'connect-cli',
59
+ enableEncrypt: true,
60
+ wrapSpinner,
61
+ openPage: open,
62
+ prettyUrl: (url) => chalk.cyan(url),
63
+ });
64
+ const { secretKey, developerDid, name, email } = fetchData;
65
+ config.set('store', storeUrl);
66
+ config.set('accessToken', secretKey);
67
+ config.set('developerDid', developerDid);
68
+ config.set('name', name);
69
+ config.set('email', email);
70
+
71
+ printSuccess(`Successfully connected, and now you are ready to upload blocklets to ${storeUrl}`);
72
+ printInfo(
73
+ `${chalk.cyan('Tips:')} Use the following command to view the configuration: ${chalk.cyan(
74
+ `${getCLIBinaryName()} config list ${profile === 'default' ? '' : `--profile ${profile}`}`
75
+ )}`
76
+ );
77
+ } catch (err) {
78
+ console.error(err);
79
+ printInfo(
80
+ `You can use the command ${chalk.cyan(`${getCLIBinaryName()} connect`)} to try to reconnect to the blocklet store`
81
+ );
82
+ process.exit(1);
83
+ }
84
+ process.exit(0);
85
+ };
86
+
87
+ exports.run = run;
@@ -0,0 +1,38 @@
1
+ const childProcess = require('child_process');
2
+ const chalk = require('chalk');
3
+
4
+ const { printInfo, print, printWarning } = require('../../util');
5
+
6
+ exports.run = (name, options = {}) => {
7
+ // eslint-disable-next-line no-param-reassign
8
+ name = name ? name.trim() : '';
9
+ let createCommand;
10
+ // must use latest version, otherwise npx will use cache version
11
+ if (name) {
12
+ createCommand = `npx create-blocklet@latest ${name}`;
13
+ } else {
14
+ createCommand = 'npx create-blocklet@latest';
15
+ }
16
+ if (options.did) {
17
+ createCommand += ` --did=${options.did}`;
18
+ }
19
+
20
+ try {
21
+ childProcess.execSync(createCommand, { stdio: 'inherit' });
22
+ process.exit(0);
23
+ } catch (error) {
24
+ console.error(error);
25
+
26
+ print('');
27
+ printWarning(`This is a problem related to ${chalk.cyan('npx')}.`);
28
+ print(` You can directly try to execute ${chalk.cyan(createCommand)} to create blocklet. \n`);
29
+
30
+ printInfo(
31
+ `You can also execute ${chalk.cyan('npm install -g create-blocklet')} and execute ${chalk.cyan(
32
+ createCommand.replace('npx ', '').replace('@latest', '')
33
+ )}`
34
+ );
35
+
36
+ process.exit(error.status);
37
+ }
38
+ };