@nocobase/cli 0.15.0-alpha.2 → 0.15.0-alpha.4

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/bin/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  const dotenv = require('dotenv');
4
4
  const { resolve } = require('path');
5
- const { existsSync } = require('fs');
5
+ const fs = require('fs');
6
6
  const chalk = require('chalk');
7
7
  const { genTsConfigPaths } = require('../src/util');
8
8
 
@@ -25,11 +25,26 @@ const env = {
25
25
  };
26
26
 
27
27
  if (!process.env.APP_ENV_PATH && process.argv[2] && process.argv[2] === 'test') {
28
- if (existsSync(resolve(process.cwd(), '.env.test'))) {
28
+ if (fs.existsSync(resolve(process.cwd(), '.env.test'))) {
29
29
  process.env.APP_ENV_PATH = '.env.test';
30
30
  }
31
31
  }
32
32
 
33
+ if (process.argv[2] === 'e2e') {
34
+ // 用于存放 playwright 自动生成的相关的文件
35
+ if (!fs.existsSync('playwright')) {
36
+ fs.mkdirSync('playwright');
37
+ }
38
+ if (!fs.existsSync('.env.e2e') && fs.existsSync('.env.e2e.example')) {
39
+ const env = fs.readFileSync('.env.e2e.example');
40
+ fs.writeFileSync('.env.e2e', env);
41
+ }
42
+ if (!fs.existsSync('.env.e2e')) {
43
+ throw new Error('Please create .env.e2e file first!');
44
+ }
45
+ process.env.APP_ENV_PATH = '.env.e2e';
46
+ }
47
+
33
48
  genTsConfigPaths();
34
49
 
35
50
  dotenv.config({
@@ -42,6 +57,10 @@ for (const key in env) {
42
57
  }
43
58
  }
44
59
 
60
+ if (process.argv[2] === 'e2e' && !process.env.APP_BASE_URL) {
61
+ process.env.APP_BASE_URL = `http://127.0.0.1:${process.env.APP_PORT}`;
62
+ }
63
+
45
64
  if (require('semver').satisfies(process.version, '<16')) {
46
65
  console.error(chalk.red('[nocobase cli]: Node.js version must be >= 16'));
47
66
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/cli",
3
- "version": "0.15.0-alpha.2",
3
+ "version": "0.15.0-alpha.4",
4
4
  "description": "",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./src/index.js",
@@ -8,7 +8,7 @@
8
8
  "nocobase": "./bin/index.js"
9
9
  },
10
10
  "dependencies": {
11
- "@nocobase/app": "0.15.0-alpha.2",
11
+ "@nocobase/app": "0.15.0-alpha.4",
12
12
  "@types/fs-extra": "^11.0.1",
13
13
  "@umijs/utils": "3.5.20",
14
14
  "chalk": "^4.1.1",
@@ -23,12 +23,12 @@
23
23
  "tsx": "^3.12.7"
24
24
  },
25
25
  "devDependencies": {
26
- "@nocobase/devtools": "0.15.0-alpha.2"
26
+ "@nocobase/devtools": "0.15.0-alpha.4"
27
27
  },
28
28
  "repository": {
29
29
  "type": "git",
30
30
  "url": "git+https://github.com/nocobase/nocobase.git",
31
31
  "directory": "packages/core/cli"
32
32
  },
33
- "gitHead": "2504887cf82935200bf546b28adf2872cab3e452"
33
+ "gitHead": "380045c660ea0432f3e8fd7cf01c3cfe7275db34"
34
34
  }
@@ -0,0 +1,199 @@
1
+ const { Command } = require('commander');
2
+ const { run, isPortReachable } = require('../util');
3
+ const { execSync } = require('node:child_process');
4
+ const axios = require('axios');
5
+
6
+ /**
7
+ * 检查服务是否启动成功
8
+ */
9
+ const checkServer = async (duration = 1000, max = 60 * 10) => {
10
+ return new Promise((resolve, reject) => {
11
+ let count = 0;
12
+ const timer = setInterval(async () => {
13
+ if (count++ > max) {
14
+ clearInterval(timer);
15
+ return reject(new Error('Server start timeout.'));
16
+ }
17
+
18
+ // if (!(await checkPort(PORT))) {
19
+ // return;
20
+ // }
21
+
22
+ const url = `${process.env.APP_BASE_URL}/api/__health_check`;
23
+ // console.log('url', url);
24
+
25
+ axios
26
+ .get(url)
27
+ .then((response) => {
28
+ if (response.status === 200) {
29
+ clearInterval(timer);
30
+ resolve(true);
31
+ }
32
+ })
33
+ .catch((error) => {
34
+ console.error('Request error:', error.message);
35
+ });
36
+ }, duration);
37
+ });
38
+ };
39
+
40
+ /**
41
+ * 检查 UI 是否启动成功
42
+ * @param duration
43
+ */
44
+ const checkUI = async (duration = 1000, max = 60 * 10) => {
45
+ return new Promise((resolve, reject) => {
46
+ let count = 0;
47
+ const timer = setInterval(async () => {
48
+ if (count++ > max) {
49
+ clearInterval(timer);
50
+ return reject(new Error('UI start timeout.'));
51
+ }
52
+
53
+ axios
54
+ .get(`${process.env.APP_BASE_URL}/__umi/api/bundle-status`)
55
+ .then((response) => {
56
+ if (response.data === 'ok') {
57
+ clearInterval(timer);
58
+ resolve(true);
59
+ return;
60
+ }
61
+ if (response.data.bundleStatus.done) {
62
+ clearInterval(timer);
63
+ resolve(true);
64
+ }
65
+ })
66
+ .catch((error) => {
67
+ console.error('Request error:', error.message);
68
+ });
69
+ }, duration);
70
+ });
71
+ };
72
+
73
+ async function appReady() {
74
+ console.log('check server...');
75
+ await checkServer();
76
+ console.log('server is ready, check UI...');
77
+ await checkUI();
78
+ console.log('UI is ready.');
79
+ }
80
+
81
+ async function runApp(options = {}) {
82
+ console.log('installing...');
83
+ await run('nocobase', ['install', '-f']);
84
+ if (await isPortReachable(process.env.APP_PORT)) {
85
+ console.log('app started');
86
+ return;
87
+ }
88
+ console.log('starting...');
89
+ run('nocobase', [process.env.APP_ENV === 'production' ? 'start' : 'dev'], options);
90
+ }
91
+
92
+ const commonConfig = {
93
+ stdio: 'inherit',
94
+ };
95
+
96
+ const runCodegenSync = () => {
97
+ try {
98
+ execSync(
99
+ `npx playwright codegen --load-storage=playwright/.auth/codegen.auth.json ${process.env.APP_BASE_URL} --save-storage=playwright/.auth/codegen.auth.json`,
100
+ commonConfig,
101
+ );
102
+ } catch (err) {
103
+ if (err.message.includes('auth.json')) {
104
+ execSync(
105
+ `npx playwright codegen ${process.env.APP_BASE_URL} --save-storage=playwright/.auth/codegen.auth.json`,
106
+ commonConfig,
107
+ );
108
+ } else {
109
+ console.error(err);
110
+ }
111
+ }
112
+ };
113
+
114
+ const filterArgv = () => {
115
+ const arr = process.argv.slice(4);
116
+ const argv = [];
117
+ for (let index = 0; index < arr.length; index++) {
118
+ const element = arr[index];
119
+ if (element === '--url') {
120
+ index++;
121
+ continue;
122
+ }
123
+ if (element.startsWith('--url=')) {
124
+ continue;
125
+ }
126
+ if (element === '--skip-reporter') {
127
+ continue;
128
+ }
129
+ argv.push(element);
130
+ }
131
+ return argv;
132
+ };
133
+
134
+ /**
135
+ *
136
+ * @param {Command} cli
137
+ */
138
+ module.exports = (cli) => {
139
+ const e2e = cli.command('e2e').hook('preAction', () => {
140
+ if (process.env.APP_BASE_URL) {
141
+ process.env.APP_BASE_URL = process.env.APP_BASE_URL.replace('localhost', '127.0.0.1');
142
+ console.log('APP_BASE_URL:', process.env.APP_BASE_URL);
143
+ }
144
+ });
145
+ e2e
146
+ .command('test')
147
+ .allowUnknownOption()
148
+ .option('--url [url]')
149
+ .option('--skip-reporter')
150
+ .action(async (options) => {
151
+ if (options.skipReporter) {
152
+ process.env.PLAYWRIGHT_SKIP_REPORTER = true;
153
+ }
154
+ if (options.url) {
155
+ process.env.APP_BASE_URL = options.url.replace('localhost', '127.0.0.1');
156
+ } else {
157
+ await runApp({
158
+ stdio: 'ignore',
159
+ });
160
+ }
161
+ await appReady();
162
+ await run('npx', ['playwright', 'test', ...filterArgv()]);
163
+ process.exit();
164
+ });
165
+
166
+ e2e
167
+ .command('codegen')
168
+ .allowUnknownOption()
169
+ .option('--url [url]')
170
+ .action(async (options) => {
171
+ if (options.url) {
172
+ process.env.APP_BASE_URL = options.url.replace('localhost', '127.0.0.1');
173
+ } else {
174
+ await runApp({
175
+ stdio: 'ignore',
176
+ });
177
+ }
178
+ await appReady();
179
+ runCodegenSync();
180
+ });
181
+
182
+ e2e
183
+ .command('start-app')
184
+ .option('--production')
185
+ .option('--port [port]')
186
+ .action(async (options) => {
187
+ if (options.production) {
188
+ process.env.APP_ENV = 'production';
189
+ }
190
+ if (options.port) {
191
+ process.env.APP_PORT = options.port;
192
+ }
193
+ runApp();
194
+ });
195
+
196
+ e2e.command('reinstall-app').action(async (options) => {
197
+ await run('nocobase', ['install', '-f'], options);
198
+ });
199
+ };
@@ -13,6 +13,7 @@ module.exports = (cli) => {
13
13
  require('./dev')(cli);
14
14
  require('./start')(cli);
15
15
  require('./test')(cli);
16
+ require('./e2e')(cli);
16
17
  require('./clean')(cli);
17
18
  require('./doc')(cli);
18
19
  require('./umi')(cli);