@nocobase/cli 2.1.0-alpha.16 → 2.1.0-alpha.18

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 (105) hide show
  1. package/LICENSE.txt +107 -0
  2. package/README.md +134 -63
  3. package/bin/run.cmd +3 -0
  4. package/bin/run.js +87 -0
  5. package/dist/commands/api/index.js +8 -0
  6. package/dist/commands/env/add.js +53 -0
  7. package/dist/commands/env/auth.js +36 -0
  8. package/dist/commands/env/index.js +27 -0
  9. package/dist/commands/env/list.js +31 -0
  10. package/dist/commands/env/remove.js +54 -0
  11. package/dist/commands/env/update.js +58 -0
  12. package/dist/commands/env/use.js +26 -0
  13. package/dist/commands/resource/create.js +15 -0
  14. package/dist/commands/resource/destroy.js +15 -0
  15. package/dist/commands/resource/get.js +15 -0
  16. package/dist/commands/resource/index.js +7 -0
  17. package/dist/commands/resource/list.js +16 -0
  18. package/dist/commands/resource/query.js +15 -0
  19. package/dist/commands/resource/update.js +15 -0
  20. package/dist/generated/command-registry.js +88 -0
  21. package/dist/lib/api-client.js +199 -0
  22. package/dist/lib/auth-store.js +155 -0
  23. package/dist/lib/bootstrap.js +349 -0
  24. package/dist/lib/build-config.js +10 -0
  25. package/dist/lib/cli-home.js +30 -0
  26. package/dist/lib/env-auth.js +405 -0
  27. package/dist/lib/generated-command.js +142 -0
  28. package/dist/lib/naming.js +70 -0
  29. package/dist/lib/openapi.js +254 -0
  30. package/dist/lib/post-processors.js +23 -0
  31. package/dist/lib/resource-command.js +335 -0
  32. package/dist/lib/resource-request.js +104 -0
  33. package/dist/lib/runtime-generator.js +408 -0
  34. package/dist/lib/runtime-store.js +56 -0
  35. package/dist/lib/ui.js +169 -0
  36. package/dist/post-processors/data-modeling.js +66 -0
  37. package/dist/post-processors/data-source-manager.js +114 -0
  38. package/dist/post-processors/index.js +19 -0
  39. package/nocobase-ctl.config.json +327 -0
  40. package/package.json +50 -25
  41. package/LICENSE +0 -201
  42. package/bin/index.js +0 -39
  43. package/nocobase.conf.tpl +0 -184
  44. package/src/cli.js +0 -28
  45. package/src/commands/benchmark.js +0 -73
  46. package/src/commands/build.js +0 -81
  47. package/src/commands/clean.js +0 -30
  48. package/src/commands/client.js +0 -168
  49. package/src/commands/create-nginx-conf.js +0 -53
  50. package/src/commands/create-plugin.js +0 -33
  51. package/src/commands/dev.js +0 -290
  52. package/src/commands/doc.js +0 -76
  53. package/src/commands/e2e.js +0 -265
  54. package/src/commands/global.js +0 -43
  55. package/src/commands/index.js +0 -45
  56. package/src/commands/instance-id.js +0 -47
  57. package/src/commands/locale/cronstrue.js +0 -122
  58. package/src/commands/locale/react-js-cron/en-US.json +0 -75
  59. package/src/commands/locale/react-js-cron/index.js +0 -17
  60. package/src/commands/locale/react-js-cron/zh-CN.json +0 -33
  61. package/src/commands/locale/react-js-cron/zh-TW.json +0 -33
  62. package/src/commands/locale.js +0 -81
  63. package/src/commands/p-test.js +0 -88
  64. package/src/commands/perf.js +0 -63
  65. package/src/commands/pkg.js +0 -321
  66. package/src/commands/pm2.js +0 -37
  67. package/src/commands/postinstall.js +0 -88
  68. package/src/commands/start.js +0 -148
  69. package/src/commands/tar.js +0 -36
  70. package/src/commands/test-coverage.js +0 -55
  71. package/src/commands/test.js +0 -107
  72. package/src/commands/umi.js +0 -33
  73. package/src/commands/update-deps.js +0 -72
  74. package/src/commands/upgrade.js +0 -47
  75. package/src/commands/view-license-key.js +0 -44
  76. package/src/index.js +0 -14
  77. package/src/license.js +0 -76
  78. package/src/logger.js +0 -75
  79. package/src/plugin-generator.js +0 -80
  80. package/src/util.js +0 -607
  81. package/templates/bundle-status.html +0 -338
  82. package/templates/create-app-package.json +0 -39
  83. package/templates/plugin/.npmignore.tpl +0 -2
  84. package/templates/plugin/README.md.tpl +0 -1
  85. package/templates/plugin/client-v2.d.ts +0 -2
  86. package/templates/plugin/client-v2.js +0 -1
  87. package/templates/plugin/client.d.ts +0 -2
  88. package/templates/plugin/client.js +0 -1
  89. package/templates/plugin/package.json.tpl +0 -12
  90. package/templates/plugin/server.d.ts +0 -2
  91. package/templates/plugin/server.js +0 -1
  92. package/templates/plugin/src/client/client.d.ts +0 -249
  93. package/templates/plugin/src/client/index.tsx.tpl +0 -1
  94. package/templates/plugin/src/client/locale.ts +0 -21
  95. package/templates/plugin/src/client/models/index.ts +0 -12
  96. package/templates/plugin/src/client/plugin.tsx.tpl +0 -10
  97. package/templates/plugin/src/client-v2/client.d.ts +0 -103
  98. package/templates/plugin/src/client-v2/index.tsx.tpl +0 -1
  99. package/templates/plugin/src/client-v2/plugin.tsx.tpl +0 -7
  100. package/templates/plugin/src/index.ts +0 -2
  101. package/templates/plugin/src/locale/en-US.json +0 -1
  102. package/templates/plugin/src/locale/zh-CN.json +0 -1
  103. package/templates/plugin/src/server/collections/.gitkeep +0 -0
  104. package/templates/plugin/src/server/index.ts.tpl +0 -1
  105. package/templates/plugin/src/server/plugin.ts.tpl +0 -19
@@ -1,33 +0,0 @@
1
- {
2
- "everyText": "每",
3
- "emptyMonths": "每月",
4
- "emptyMonthDays": "每日(月)",
5
- "emptyMonthDaysShort": "每日",
6
- "emptyWeekDays": "每天(周)",
7
- "emptyWeekDaysShort": "每天(周)",
8
- "emptyHours": "每小时",
9
- "emptyMinutes": "每分钟",
10
- "emptyMinutesForHourPeriod": "每",
11
- "yearOption": "年",
12
- "monthOption": "月",
13
- "weekOption": "周",
14
- "dayOption": "天",
15
- "hourOption": "小时",
16
- "minuteOption": "分钟",
17
- "rebootOption": "重启",
18
- "prefixPeriod": "每",
19
- "prefixMonths": "的",
20
- "prefixMonthDays": "的",
21
- "prefixWeekDays": "的",
22
- "prefixWeekDaysForMonthAndYearPeriod": "或者",
23
- "prefixHours": "的",
24
- "prefixMinutes": ":",
25
- "prefixMinutesForHourPeriod": "的",
26
- "suffixMinutesForHourPeriod": "分钟",
27
- "errorInvalidCron": "不符合 cron 规则的表达式",
28
- "clearButtonText": "清空",
29
- "weekDays": ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
30
- "months": ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
31
- "altWeekDays": ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
32
- "altMonths": ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"]
33
- }
@@ -1,33 +0,0 @@
1
- {
2
- "everyText": "每",
3
- "emptyMonths": "每月",
4
- "emptyMonthDays": "每日(月)",
5
- "emptyMonthDaysShort": "每日",
6
- "emptyWeekDays": "每天(週)",
7
- "emptyWeekDaysShort": "每天(週)",
8
- "emptyHours": "每小時",
9
- "emptyMinutes": "每分鐘",
10
- "emptyMinutesForHourPeriod": "每",
11
- "yearOption": "年",
12
- "monthOption": "月",
13
- "weekOption": "週",
14
- "dayOption": "天",
15
- "hourOption": "小時",
16
- "minuteOption": "分鐘",
17
- "rebootOption": "重啟",
18
- "prefixPeriod": "每",
19
- "prefixMonths": "的",
20
- "prefixMonthDays": "的",
21
- "prefixWeekDays": "的",
22
- "prefixWeekDaysForMonthAndYearPeriod": "或者",
23
- "prefixHours": "的",
24
- "prefixMinutes": ":",
25
- "prefixMinutesForHourPeriod": "的",
26
- "suffixMinutesForHourPeriod": "分鐘",
27
- "errorInvalidCron": "不符合 cron 規則的表示式",
28
- "clearButtonText": "清空",
29
- "weekDays": ["週日", "週一", "週二", "週三", "週四", "週五", "週六"],
30
- "months": ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
31
- "altWeekDays": ["週日", "週一", "週二", "週三", "週四", "週五", "週六"],
32
- "altMonths": ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"]
33
- }
@@ -1,81 +0,0 @@
1
- /**
2
- * This file is part of the NocoBase (R) project.
3
- * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
- * Authors: NocoBase Team.
5
- *
6
- * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
- * For more information, please refer to: https://www.nocobase.com/agreement.
8
- */
9
-
10
- const { Command } = require('commander');
11
- const fg = require('fast-glob');
12
- const fs = require('fs-extra');
13
- const path = require('path');
14
- const _ = require('lodash');
15
- const deepmerge = require('deepmerge');
16
- const { getCronstrueLocale } = require('./locale/cronstrue');
17
- const { getReactJsCron } = require('./locale/react-js-cron');
18
-
19
- function sortJSON(json) {
20
- if (Array.isArray(json)) {
21
- return json.map(sortJSON);
22
- } else if (typeof json === 'object' && json !== null) {
23
- const sortedKeys = Object.keys(json).sort();
24
- const sortedObject = {};
25
- sortedKeys.forEach((key) => {
26
- sortedObject[key] = sortJSON(json[key]);
27
- });
28
- return sortedObject;
29
- }
30
- return json;
31
- }
32
-
33
- /**
34
- *
35
- * @param {Command} cli
36
- */
37
- module.exports = (cli) => {
38
- const locale = cli.command('locale');
39
- locale.command('generate').action(async (options) => {
40
- const cwd = path.resolve(process.cwd(), 'node_modules', '@nocobase');
41
- const files = await fg('./*/src/locale/*.json', {
42
- cwd,
43
- });
44
- let locales = {};
45
- await fs.mkdirp(path.resolve(process.cwd(), 'storage/locales'));
46
- for (const file of files) {
47
- const locale = path.basename(file, '.json');
48
- const pkg = path.basename(path.dirname(path.dirname(path.dirname(file))));
49
- _.set(locales, [locale.replace(/_/g, '-'), `@nocobase/${pkg}`], await fs.readJSON(path.resolve(cwd, file)));
50
- if (locale.includes('_')) {
51
- await fs.rename(
52
- path.resolve(cwd, file),
53
- path.resolve(cwd, path.dirname(file), `${locale.replace(/_/g, '-')}.json`),
54
- );
55
- }
56
- }
57
- const zhCN = locales['zh-CN'];
58
- const enUS = locales['en-US'];
59
- for (const key1 in zhCN) {
60
- for (const key2 in zhCN[key1]) {
61
- if (!_.get(enUS, [key1, key2])) {
62
- _.set(enUS, [key1, key2], key2);
63
- }
64
- }
65
- }
66
- for (const locale of Object.keys(locales)) {
67
- locales[locale] = deepmerge(enUS, locales[locale]);
68
- locales[locale]['cronstrue'] = getCronstrueLocale(locale);
69
- locales[locale]['react-js-cron'] = getReactJsCron(locale);
70
- }
71
- locales = sortJSON(locales);
72
- for (const locale of Object.keys(locales)) {
73
- await fs.writeFile(
74
- path.resolve(process.cwd(), 'storage/locales', `${locale}.json`),
75
- JSON.stringify(sortJSON(locales[locale]), null, 2),
76
- );
77
- }
78
- });
79
-
80
- locale.command('sync').action(async (options) => {});
81
- };
@@ -1,88 +0,0 @@
1
- /**
2
- * This file is part of the NocoBase (R) project.
3
- * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
- * Authors: NocoBase Team.
5
- *
6
- * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
- * For more information, please refer to: https://www.nocobase.com/agreement.
8
- */
9
-
10
- const execa = require('execa');
11
- const { resolve } = require('path');
12
- const pAll = require('p-all');
13
- const dotenv = require('dotenv');
14
- const fs = require('fs');
15
- const glob = require('glob');
16
- const _ = require('lodash');
17
-
18
- let ENV_FILE = resolve(process.cwd(), '.env.e2e');
19
-
20
- if (!fs.existsSync(ENV_FILE)) {
21
- ENV_FILE = resolve(process.cwd(), '.env.e2e.example');
22
- }
23
-
24
- const data = fs.readFileSync(ENV_FILE, 'utf-8');
25
- const config = {
26
- ...dotenv.parse(data),
27
- ...process.env,
28
- };
29
-
30
- async function runApp(dir, index = 0) {
31
- // 一个进程需要占用两个端口? (一个是应用端口,一个是 socket 端口)
32
- index = index * 2;
33
- const { Client } = require('pg');
34
- const database = `nocobase${index}`;
35
- const client = new Client({
36
- host: config['DB_HOST'],
37
- port: Number(config['DB_PORT']),
38
- user: config['DB_USER'],
39
- password: config['DB_PASSWORD'],
40
- database: 'postgres',
41
- });
42
- await client.connect();
43
- await client.query(`DROP DATABASE IF EXISTS "${database}"`);
44
- await client.query(`CREATE DATABASE "${database}";`);
45
- await client.end();
46
- return execa('yarn', ['nocobase', 'e2e', 'test', dir], {
47
- shell: true,
48
- stdio: 'inherit',
49
- env: {
50
- ...config,
51
- CI: process.env.CI,
52
- __E2E__: true,
53
- APP_BASE_URL: undefined,
54
- LOGGER_LEVEL: 'error',
55
- APP_ENV: 'production',
56
- APP_PORT: 20000 + index,
57
- DB_DATABASE: `nocobase${index}`,
58
- SOCKET_PATH: `storage/e2e/gateway-e2e-${index}.sock`,
59
- PM2_HOME: resolve(process.cwd(), `storage/e2e/.pm2-${index}`),
60
- PLAYWRIGHT_AUTH_FILE: resolve(process.cwd(), `storage/playwright/.auth/admin-${index}.json`),
61
- E2E_JOB_ID: index,
62
- },
63
- });
64
- }
65
-
66
- exports.pTest = async (options) => {
67
- const dir = resolve(process.cwd(), 'storage/e2e');
68
-
69
- if (!fs.existsSync(dir)) {
70
- fs.mkdirSync(dir, { recursive: true });
71
- }
72
-
73
- const files = glob.sync(options.match, {
74
- ignore: options.ignore,
75
- root: process.cwd(),
76
- });
77
-
78
- const commands = splitArrayIntoParts(_.shuffle(files), options.concurrency || 4).map((v, i) => {
79
- return () => runApp(v.join(' '), i);
80
- });
81
-
82
- await pAll(commands, { concurrency: 4, stopOnError: false, ...options });
83
- };
84
-
85
- function splitArrayIntoParts(array, parts) {
86
- let chunkSize = Math.ceil(array.length / parts);
87
- return _.chunk(array, chunkSize);
88
- }
@@ -1,63 +0,0 @@
1
- /**
2
- * This file is part of the NocoBase (R) project.
3
- * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
- * Authors: NocoBase Team.
5
- *
6
- * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
- * For more information, please refer to: https://www.nocobase.com/agreement.
8
- */
9
-
10
- const path = require('path');
11
- const fs = require('fs');
12
- // const init = require('@nocobase/server/__perf__/init');
13
- const { Command } = require('commander');
14
- const dotenv = require('dotenv');
15
- const { run } = require('../util');
16
-
17
- /**
18
- * Performance testing command
19
- * @param {Command} cli
20
- */
21
- module.exports = (cli) => {
22
- const perf = cli.command('perf');
23
- perf
24
- .command('init')
25
- .arguments('<file>')
26
- .description('Initialize performance testing app')
27
- .action(async (file, options) => {
28
- if (!file) {
29
- throw new Error('Please provide the path to the init script');
30
- }
31
- const f = path.isAbsolute(file) ? file : path.join(process.cwd(), file);
32
- if (!fs.statSync(file).isFile()) {
33
- throw new Error(`Init script file not found: ${file}`);
34
- }
35
- // const envFile = fs.existsSync(path.resolve(process.cwd(), '.env.test')) ? '.env.test' : '.env';
36
- // const cliArgs = ['--max_old_space_size=4096'];
37
- await run(`tsx`, [f]);
38
- });
39
- perf
40
- .command('run')
41
- .arguments('<file>')
42
- .description('Run performance testing script')
43
- .option('-e, --env-file <env>', 'Environment file to load', '.env.perf')
44
- .allowUnknownOption(true)
45
- .action(async (file, options, command) => {
46
- const f = path.isAbsolute(file) ? file : path.join(process.cwd(), file);
47
- if (!fs.statSync(f).isFile()) {
48
- throw new Error(`Performance testing script file not found: ${f}`);
49
- }
50
- if (options.envFile) {
51
- const envFilePath = path.resolve(process.cwd(), options.envFile);
52
- if (fs.statSync(envFilePath).isFile()) {
53
- dotenv.config({ path: envFilePath, override: true });
54
- }
55
- }
56
- if (!process.env.TARGET_ORIGIN) {
57
- throw new Error('Please set TARGET_ORIGIN in environment variables or in .env.perf file');
58
- }
59
- const args = command.args.filter((arg) => arg !== file);
60
- await run(`k6`, ['run', f, ...(args.length ? ['--', ...args] : [])]);
61
- });
62
- return perf;
63
- };
@@ -1,321 +0,0 @@
1
- /**
2
- * This file is part of the NocoBase (R) project.
3
- * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
- * Authors: NocoBase Team.
5
- *
6
- * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
- * For more information, please refer to: https://www.nocobase.com/agreement.
8
- */
9
-
10
- const { Command } = require('commander');
11
- const axios = require('axios');
12
- const fs = require('fs-extra');
13
- const zlib = require('zlib');
14
- const tar = require('tar');
15
- const path = require('path');
16
- const { createStoragePluginsSymlink } = require('@nocobase/utils/plugin-symlink');
17
- const { getAccessKeyPair, showLicenseInfo, LicenseKeyError } = require('../license');
18
- const { logger } = require('../logger');
19
-
20
- class Package {
21
- data;
22
- constructor(packageName, packageManager) {
23
- this.packageName = packageName;
24
- this.packageManager = packageManager;
25
- this.outputDir = path.resolve(process.cwd(), `storage/plugins/${this.packageName}`);
26
- }
27
-
28
- get token() {
29
- return this.packageManager.getToken();
30
- }
31
-
32
- url(path) {
33
- return this.packageManager.url(path);
34
- }
35
-
36
- async mkdir() {
37
- if (await fs.exists(this.outputDir)) {
38
- await fs.rm(this.outputDir, { recursive: true, force: true });
39
- }
40
- await fs.mkdirp(this.outputDir);
41
- }
42
-
43
- async getInfo() {
44
- try {
45
- const res = await axios.get(this.url(this.packageName), {
46
- headers: {
47
- Authorization: `Bearer ${this.token}`,
48
- },
49
- responseType: 'json',
50
- });
51
- this.data = res.data;
52
- } catch (error) {
53
- return;
54
- }
55
- }
56
-
57
- getTarball(version = 'latest') {
58
- if (this.data.versions[version]) {
59
- return [version, this.data.versions[version].dist.tarball];
60
- }
61
-
62
- const keys = version.split('.');
63
- const length = keys.length;
64
-
65
- if (version.includes('rc')) {
66
- version = version.split('-').shift();
67
- }
68
-
69
- if (length === 5) {
70
- keys.pop();
71
- version = keys.join('.');
72
- }
73
-
74
- if (version === 'latest') {
75
- version = this.data['dist-tags']['latest'];
76
- } else if (version === 'next') {
77
- version = this.data['dist-tags']['next'];
78
- }
79
-
80
- if (!this.data.versions[version]) {
81
- logger.error(`Download failed: ${this.packageName}@${version} package does not exist`);
82
- }
83
-
84
- return [version, this.data.versions[version].dist.tarball];
85
- }
86
-
87
- async isDevPackage() {
88
- let file = path.resolve(process.cwd(), 'packages/plugins', this.packageName, 'package.json');
89
- if (await fs.exists(file)) {
90
- return true;
91
- }
92
- file = path.resolve(process.cwd(), 'packages/pro-plugins', this.packageName, 'package.json');
93
- if (await fs.exists(file)) {
94
- return true;
95
- }
96
- return false;
97
- }
98
-
99
- async isDepPackage() {
100
- const pkg1 = path.resolve(process.cwd(), 'node_modules', this.packageName, 'package.json');
101
- const pkg2 = path.resolve(process.cwd(), process.env.PLUGIN_STORAGE_PATH, this.packageName, 'package.json');
102
- if ((await fs.exists(pkg1)) && (await fs.exists(pkg2))) {
103
- const readPath1 = fs.realpathSync(pkg1);
104
- const readPath2 = fs.realpathSync(pkg2);
105
- if (readPath1 !== readPath2) {
106
- return true;
107
- }
108
- }
109
- return false;
110
- }
111
-
112
- async isDownloaded(version) {
113
- const packageFile = path.resolve(process.env.PLUGIN_STORAGE_PATH, this.packageName, 'package.json');
114
- if (await fs.exists(packageFile)) {
115
- const json = await fs.readJson(packageFile);
116
- if (json.version === version) {
117
- return true;
118
- }
119
- }
120
- return false;
121
- }
122
-
123
- async download(options = {}) {
124
- if (await this.isDevPackage()) {
125
- logger.info(`Skipped: ${this.packageName} is dev package`);
126
- return;
127
- }
128
- if (await this.isDepPackage()) {
129
- logger.info(`Skipped: ${this.packageName} is dependency package`);
130
- return;
131
- }
132
- if (await this.isDownloaded(options.version)) {
133
- return;
134
- }
135
- await this.getInfo();
136
- if (!this.data) {
137
- logger.error(`Download failed: ${this.packageName} package does not exist`);
138
- return;
139
- }
140
- try {
141
- const [version, url] = this.getTarball(options.version);
142
- if (await this.isDownloaded(version)) {
143
- return;
144
- }
145
- const response = await axios({
146
- url,
147
- responseType: 'stream',
148
- method: 'GET',
149
- headers: {
150
- Authorization: `Bearer ${this.token}`,
151
- },
152
- });
153
- await this.mkdir();
154
- await new Promise((resolve, reject) => {
155
- response.data
156
- .pipe(zlib.createGunzip()) // 解压 gzip
157
- .pipe(tar.extract({ cwd: this.outputDir, strip: 1 })) // 解压 tar
158
- .on('finish', resolve)
159
- .on('error', reject);
160
- });
161
- logger.info(`Downloaded: ${this.packageName}@${version}`);
162
- } catch (error) {
163
- if (error?.response?.data && typeof error?.response?.data?.pipe === 'function') {
164
- let errorMessageBuffer = '';
165
- error.response.data.on?.('data', (chunk) => {
166
- errorMessageBuffer += chunk.toString('utf8'); // 收集错误信息
167
- });
168
- error.response.data.on?.('end', () => {
169
- if (error.response.status === 403) {
170
- logger.error('You do not have permission to download this package version.');
171
- }
172
- });
173
- }
174
- logger.error(`Download failed: ${this.packageName}`);
175
- }
176
- }
177
- }
178
-
179
- class PackageManager {
180
- token;
181
- baseURL;
182
-
183
- constructor({ baseURL }) {
184
- this.baseURL = baseURL;
185
- }
186
-
187
- getToken() {
188
- return this.token;
189
- }
190
-
191
- getBaseURL() {
192
- return this.baseURL;
193
- }
194
-
195
- url(path) {
196
- return this.baseURL + path;
197
- }
198
-
199
- async login(credentials) {
200
- try {
201
- const res1 = await axios.post(`${this.baseURL}-/verdaccio/sec/login`, credentials, {
202
- responseType: 'json',
203
- });
204
- this.token = res1.data.token;
205
- logger.info('Login success');
206
- } catch (error) {
207
- if (error?.response?.data?.error === 'license not valid') {
208
- showLicenseInfo(LicenseKeyError.notValid);
209
- }
210
- logger.error(`Login failed: ${this.baseURL}`);
211
- logger.error(error?.message, { error });
212
- }
213
- }
214
-
215
- getPackage(packageName) {
216
- return new Package(packageName, this);
217
- }
218
-
219
- async getProPackages() {
220
- const res = await axios.get(this.url('pro-packages'), {
221
- headers: {
222
- Authorization: `Bearer ${this.token}`,
223
- },
224
- responseType: 'json',
225
- });
226
- return {
227
- licensed_plugins: res.data?.data || [],
228
- commercial_plugins: res.data?.meta?.commercial_plugins || [],
229
- };
230
- }
231
-
232
- async getPackages() {
233
- const pkgs = await this.getProPackages();
234
-
235
- if (Array.isArray(pkgs)) {
236
- return {
237
- commercial_plugins: pkgs,
238
- licensed_plugins: pkgs,
239
- };
240
- }
241
- return pkgs;
242
- }
243
-
244
- async removePackage(packageName) {
245
- const dir = path.resolve(process.env.PLUGIN_STORAGE_PATH, packageName);
246
- const r = await fs.exists(dir);
247
- if (r) {
248
- logger.info(`Removed: ${packageName}`);
249
- await fs.rm(dir, { force: true, recursive: true });
250
- }
251
- }
252
-
253
- async download(options = {}) {
254
- const { version } = options;
255
- if (!this.token) {
256
- return;
257
- }
258
- const { commercial_plugins, licensed_plugins } = await this.getPackages();
259
- for (const pkg of commercial_plugins) {
260
- if (!licensed_plugins.includes(pkg)) {
261
- await this.removePackage(pkg);
262
- }
263
- }
264
- logger.info(`Download plugins...`);
265
- for (const pkg of licensed_plugins) {
266
- await this.getPackage(pkg).download({ version });
267
- }
268
- logger.info('Download plugins done');
269
- }
270
- }
271
-
272
- /**
273
- *
274
- * @param {Command} cli
275
- */
276
- module.exports = (cli) => {
277
- const pkg = cli.command('pkg');
278
- pkg
279
- .command('download-pro')
280
- .option('-V, --version [version]')
281
- .action(async () => {
282
- const {
283
- NOCOBASE_PKG_URL = 'https://pkg.nocobase.com/',
284
- NOCOBASE_PKG_USERNAME,
285
- NOCOBASE_PKG_PASSWORD,
286
- DISABLE_PKG_DOWNLOAD,
287
- } = process.env;
288
- if (DISABLE_PKG_DOWNLOAD === 'true') {
289
- logger.info('Package download is disabled.');
290
- return;
291
- }
292
- let accessKeyId;
293
- let accessKeySecret;
294
- try {
295
- ({ accessKeyId, accessKeySecret } = await getAccessKeyPair());
296
- } catch (e) {
297
- // logger.error('Get AccessKey Pair error', e);
298
- return;
299
- }
300
- if (NOCOBASE_PKG_USERNAME && NOCOBASE_PKG_PASSWORD && !accessKeyId && !accessKeySecret) {
301
- logger.warn(
302
- 'NOCOBASE_PKG_USERNAME and NOCOBASE_PKG_PASSWORD will be deprecated in future versions. Please log in to NocoBase Service and refer to the documentation to learn how to install and upgrade commercial plugins.\n',
303
- );
304
- }
305
- if (!(NOCOBASE_PKG_USERNAME && NOCOBASE_PKG_PASSWORD) && !(accessKeyId && accessKeySecret)) {
306
- return;
307
- }
308
- const credentials = accessKeyId
309
- ? { username: accessKeyId, password: accessKeySecret }
310
- : { username: NOCOBASE_PKG_USERNAME, password: NOCOBASE_PKG_PASSWORD };
311
- const pm = new PackageManager({ baseURL: NOCOBASE_PKG_URL });
312
- await pm.login(credentials);
313
- const file = path.resolve(__dirname, '../../package.json');
314
- const json = await fs.readJson(file);
315
- await pm.download({ version: json.version });
316
- await createStoragePluginsSymlink();
317
- });
318
- pkg.command('export-all').action(async () => {
319
- logger.info('Todo...');
320
- });
321
- };
@@ -1,37 +0,0 @@
1
- /**
2
- * This file is part of the NocoBase (R) project.
3
- * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
- * Authors: NocoBase Team.
5
- *
6
- * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
- * For more information, please refer to: https://www.nocobase.com/agreement.
8
- */
9
-
10
- const chalk = require('chalk');
11
- const { Command } = require('commander');
12
- const { run, isDev } = require('../util');
13
-
14
- /**
15
- *
16
- * @param {Command} cli
17
- */
18
- module.exports = (cli) => {
19
- cli
20
- .command('pm2')
21
- .allowUnknownOption()
22
- .action(() => {
23
- run('pm2', process.argv.slice(3));
24
- });
25
- cli
26
- .command('pm2-restart')
27
- .allowUnknownOption()
28
- .action(() => {
29
- run('pm2', ['restart', 'all']);
30
- });
31
- cli
32
- .command('pm2-stop')
33
- .allowUnknownOption()
34
- .action(() => {
35
- run('pm2', ['kill']);
36
- });
37
- };