@nocobase/cli 2.2.0-alpha.4 → 2.2.0-alpha.6
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/assets/env-proxy/nginx/snippets/proxy-location.conf +1 -0
- package/dist/commands/app/start.js +4 -1
- package/dist/commands/install.js +53 -128
- package/dist/commands/proxy/caddy/generate.js +23 -15
- package/dist/commands/proxy/nginx/generate.js +23 -15
- package/dist/commands/revision/create.js +1 -1
- package/dist/commands/source/download.js +16 -12
- package/dist/lib/app-managed-resources.js +3 -2
- package/dist/lib/auth-store.js +68 -0
- package/dist/lib/cli-config.js +52 -1
- package/dist/lib/docker-image.js +94 -6
- package/dist/lib/env-config.js +5 -0
- package/dist/lib/env-proxy-config.js +48 -0
- package/dist/lib/env-proxy.js +29 -3
- package/dist/lib/proxy-caddy.js +53 -7
- package/dist/lib/proxy-nginx.js +53 -7
- package/package.json +2 -2
package/dist/lib/proxy-caddy.js
CHANGED
|
@@ -9,14 +9,17 @@
|
|
|
9
9
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
10
10
|
import path from 'node:path';
|
|
11
11
|
import { dockerContainerExists, dockerContainerIsRunning, startDockerContainer, stopDockerContainer, } from './app-runtime.js';
|
|
12
|
+
import { loadAuthConfig } from './auth-store.js';
|
|
12
13
|
import { CADDY_PROXY_DRIVER_OPTIONS, DEFAULT_CADDY_PROXY_DRIVER, getCliConfigValue, normalizeCaddyProxyDriver, resolveDockerContainerPrefix, setCliConfigValue, } from './cli-config.js';
|
|
13
14
|
import { resolveCliHomeRoot } from './cli-home.js';
|
|
14
15
|
import { applyEnvProxyAppEntryOptions, buildManualEnvProxyCaddyBundle, buildEnvProxyCaddyBundle, buildEnvProxyMainConfig, mapProxyPathFromCliRoot, resolveEnvProxyMainOutputPath, } from './env-proxy.js';
|
|
15
|
-
import {
|
|
16
|
+
import { normalizeEnvProxyConfig } from './env-proxy-config.js';
|
|
17
|
+
import { commandOutput, run } from './run-npm.js';
|
|
16
18
|
const DOCKER_CADDY_PROXY_CONTAINER_SUFFIX = 'caddy-proxy';
|
|
17
19
|
const DOCKER_CADDY_PROXY_IMAGE = 'caddy:latest';
|
|
18
20
|
const DOCKER_CADDY_PROXY_RUNTIME_ROOT = '/apps';
|
|
19
21
|
const DOCKER_CADDY_PROXY_CONF_DESTINATION = '/etc/caddy/Caddyfile';
|
|
22
|
+
const DEFAULT_DOCKER_CADDY_PROXY_PUBLISHED_PORTS = [80, 443];
|
|
20
23
|
async function readOptionalTextFile(filePath) {
|
|
21
24
|
try {
|
|
22
25
|
return await readFile(filePath, 'utf8');
|
|
@@ -171,11 +174,16 @@ async function reloadLocalCaddyProxy(runtimeContext) {
|
|
|
171
174
|
}
|
|
172
175
|
async function ensureDockerCaddyProxyContainer(runtimeContext) {
|
|
173
176
|
const containerName = await resolveCaddyProxyContainerName();
|
|
177
|
+
const mainConfigPath = await ensureCaddyProxyMainConfig(runtimeContext);
|
|
178
|
+
const publishedPorts = await resolveDockerCaddyPublishedPorts();
|
|
174
179
|
if (await dockerContainerExists(containerName)) {
|
|
175
|
-
|
|
180
|
+
if (await dockerCaddyProxyContainerMatchesPublishedPorts(containerName, publishedPorts)) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
await removeDockerCaddyProxyContainer(containerName);
|
|
176
184
|
}
|
|
177
185
|
const hostCliRoot = String(process.env.NB_CLI_ROOT ?? resolveCliHomeRoot()).trim() || resolveCliHomeRoot();
|
|
178
|
-
const
|
|
186
|
+
const dockerPortArgs = publishedPorts.flatMap((port) => ['-p', `${port}:${port}`]);
|
|
179
187
|
await run('docker', [
|
|
180
188
|
'run',
|
|
181
189
|
'-d',
|
|
@@ -183,8 +191,7 @@ async function ensureDockerCaddyProxyContainer(runtimeContext) {
|
|
|
183
191
|
containerName,
|
|
184
192
|
'--add-host',
|
|
185
193
|
'host.docker.internal:host-gateway',
|
|
186
|
-
|
|
187
|
-
'80:80',
|
|
194
|
+
...dockerPortArgs,
|
|
188
195
|
'-v',
|
|
189
196
|
`${hostCliRoot}:${DOCKER_CADDY_PROXY_RUNTIME_ROOT}`,
|
|
190
197
|
'-v',
|
|
@@ -195,14 +202,53 @@ async function ensureDockerCaddyProxyContainer(runtimeContext) {
|
|
|
195
202
|
stdio: 'ignore',
|
|
196
203
|
});
|
|
197
204
|
}
|
|
205
|
+
async function resolveDockerCaddyPublishedPorts() {
|
|
206
|
+
const config = await loadAuthConfig();
|
|
207
|
+
const ports = new Set(DEFAULT_DOCKER_CADDY_PROXY_PUBLISHED_PORTS);
|
|
208
|
+
for (const envConfig of Object.values(config.envs)) {
|
|
209
|
+
const port = normalizeEnvProxyConfig(envConfig.proxy)?.port;
|
|
210
|
+
if (port !== undefined) {
|
|
211
|
+
ports.add(port);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return Array.from(ports).sort((left, right) => left - right);
|
|
215
|
+
}
|
|
216
|
+
async function readDockerCaddyPublishedPorts(containerName) {
|
|
217
|
+
const output = await commandOutput('docker', ['inspect', '--format', '{{json .HostConfig.PortBindings}}', containerName], { errorName: 'docker inspect' });
|
|
218
|
+
const parsed = JSON.parse(output.trim() || '{}');
|
|
219
|
+
const ports = new Set();
|
|
220
|
+
for (const bindings of Object.values(parsed)) {
|
|
221
|
+
if (!Array.isArray(bindings)) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
for (const binding of bindings) {
|
|
225
|
+
const port = Number.parseInt(String(binding?.HostPort ?? '').trim(), 10);
|
|
226
|
+
if (Number.isInteger(port) && port > 0) {
|
|
227
|
+
ports.add(port);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return Array.from(ports).sort((left, right) => left - right);
|
|
232
|
+
}
|
|
233
|
+
async function dockerCaddyProxyContainerMatchesPublishedPorts(containerName, expectedPorts) {
|
|
234
|
+
const currentPorts = await readDockerCaddyPublishedPorts(containerName);
|
|
235
|
+
return currentPorts.length === expectedPorts.length && currentPorts.every((port, index) => port === expectedPorts[index]);
|
|
236
|
+
}
|
|
237
|
+
async function removeDockerCaddyProxyContainer(containerName) {
|
|
238
|
+
await run('docker', ['rm', '-f', containerName], {
|
|
239
|
+
errorName: 'docker rm',
|
|
240
|
+
stdio: 'ignore',
|
|
241
|
+
});
|
|
242
|
+
}
|
|
198
243
|
async function startDockerCaddyProxy(runtimeContext) {
|
|
199
244
|
const containerName = await resolveCaddyProxyContainerName();
|
|
200
245
|
await ensureCaddyProxyMainConfig(runtimeContext);
|
|
201
|
-
|
|
246
|
+
const existedBeforeEnsure = await dockerContainerExists(containerName);
|
|
247
|
+
await ensureDockerCaddyProxyContainer(runtimeContext);
|
|
248
|
+
if (existedBeforeEnsure && (await dockerContainerExists(containerName))) {
|
|
202
249
|
const state = await startDockerContainer(containerName, { stdio: 'ignore' });
|
|
203
250
|
return state === 'already-running' ? 'already-running' : 'started';
|
|
204
251
|
}
|
|
205
|
-
await ensureDockerCaddyProxyContainer(runtimeContext);
|
|
206
252
|
return 'started';
|
|
207
253
|
}
|
|
208
254
|
async function stopDockerCaddyProxy() {
|
package/dist/lib/proxy-nginx.js
CHANGED
|
@@ -9,14 +9,17 @@
|
|
|
9
9
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
10
10
|
import path from 'node:path';
|
|
11
11
|
import { dockerContainerExists, dockerContainerIsRunning, startDockerContainer, stopDockerContainer, } from './app-runtime.js';
|
|
12
|
+
import { loadAuthConfig } from './auth-store.js';
|
|
12
13
|
import { DEFAULT_NGINX_PROXY_DRIVER, getCliConfigValue, NGINX_PROXY_DRIVER_OPTIONS, normalizeNginxProxyDriver, resolveDockerContainerPrefix, setCliConfigValue, } from './cli-config.js';
|
|
13
14
|
import { resolveCliHomeRoot } from './cli-home.js';
|
|
14
15
|
import { applyEnvProxyAppEntryOptions, appConfigHasManagedNginxBlock, buildManualEnvProxyNginxBundle, buildEnvProxyMainConfig, buildEnvProxyNginxBundle, extractManagedNginxConfigBlock, installEnvProxyProvider, mapProxyPathFromCliRoot, reloadEnvProxyProvider, resolveEnvProxyMainOutputPath, replaceManagedNginxConfigBlock, syncEnvProxyNginxSnippets, } from './env-proxy.js';
|
|
15
|
-
import {
|
|
16
|
+
import { normalizeEnvProxyConfig } from './env-proxy-config.js';
|
|
17
|
+
import { commandOutput, run } from './run-npm.js';
|
|
16
18
|
const DOCKER_NGINX_PROXY_CONTAINER_SUFFIX = 'nginx-proxy';
|
|
17
19
|
const DOCKER_NGINX_PROXY_IMAGE = 'nginx:latest';
|
|
18
20
|
const DOCKER_NGINX_PROXY_RUNTIME_ROOT = '/apps';
|
|
19
21
|
const DOCKER_NGINX_PROXY_CONF_DESTINATION = '/etc/nginx/conf.d/default.conf';
|
|
22
|
+
const DEFAULT_DOCKER_NGINX_PROXY_PUBLISHED_PORTS = [80, 443];
|
|
20
23
|
async function readOptionalTextFile(filePath) {
|
|
21
24
|
try {
|
|
22
25
|
return await readFile(filePath, 'utf8');
|
|
@@ -231,11 +234,16 @@ async function reloadLocalNginxProxy(runtimeContext) {
|
|
|
231
234
|
}
|
|
232
235
|
async function ensureDockerNginxProxyContainer(runtimeContext) {
|
|
233
236
|
const containerName = await resolveNginxProxyContainerName();
|
|
237
|
+
const mainConfigPath = await ensureNginxProxyMainConfig(runtimeContext);
|
|
238
|
+
const publishedPorts = await resolveDockerNginxPublishedPorts();
|
|
234
239
|
if (await dockerContainerExists(containerName)) {
|
|
235
|
-
|
|
240
|
+
if (await dockerNginxProxyContainerMatchesPublishedPorts(containerName, publishedPorts)) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
await removeDockerNginxProxyContainer(containerName);
|
|
236
244
|
}
|
|
237
245
|
const hostCliRoot = String(process.env.NB_CLI_ROOT ?? resolveCliHomeRoot()).trim() || resolveCliHomeRoot();
|
|
238
|
-
const
|
|
246
|
+
const dockerPortArgs = publishedPorts.flatMap((port) => ['-p', `${port}:${port}`]);
|
|
239
247
|
await run('docker', [
|
|
240
248
|
'run',
|
|
241
249
|
'-d',
|
|
@@ -243,8 +251,7 @@ async function ensureDockerNginxProxyContainer(runtimeContext) {
|
|
|
243
251
|
containerName,
|
|
244
252
|
'--add-host',
|
|
245
253
|
'host.docker.internal:host-gateway',
|
|
246
|
-
|
|
247
|
-
'80:80',
|
|
254
|
+
...dockerPortArgs,
|
|
248
255
|
'-v',
|
|
249
256
|
`${hostCliRoot}:${DOCKER_NGINX_PROXY_RUNTIME_ROOT}`,
|
|
250
257
|
'-v',
|
|
@@ -255,14 +262,53 @@ async function ensureDockerNginxProxyContainer(runtimeContext) {
|
|
|
255
262
|
stdio: 'ignore',
|
|
256
263
|
});
|
|
257
264
|
}
|
|
265
|
+
async function resolveDockerNginxPublishedPorts() {
|
|
266
|
+
const config = await loadAuthConfig();
|
|
267
|
+
const ports = new Set(DEFAULT_DOCKER_NGINX_PROXY_PUBLISHED_PORTS);
|
|
268
|
+
for (const envConfig of Object.values(config.envs)) {
|
|
269
|
+
const port = normalizeEnvProxyConfig(envConfig.proxy)?.port;
|
|
270
|
+
if (port !== undefined) {
|
|
271
|
+
ports.add(port);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return Array.from(ports).sort((left, right) => left - right);
|
|
275
|
+
}
|
|
276
|
+
async function readDockerNginxPublishedPorts(containerName) {
|
|
277
|
+
const output = await commandOutput('docker', ['inspect', '--format', '{{json .HostConfig.PortBindings}}', containerName], { errorName: 'docker inspect' });
|
|
278
|
+
const parsed = JSON.parse(output.trim() || '{}');
|
|
279
|
+
const ports = new Set();
|
|
280
|
+
for (const bindings of Object.values(parsed)) {
|
|
281
|
+
if (!Array.isArray(bindings)) {
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
for (const binding of bindings) {
|
|
285
|
+
const port = Number.parseInt(String(binding?.HostPort ?? '').trim(), 10);
|
|
286
|
+
if (Number.isInteger(port) && port > 0) {
|
|
287
|
+
ports.add(port);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return Array.from(ports).sort((left, right) => left - right);
|
|
292
|
+
}
|
|
293
|
+
async function dockerNginxProxyContainerMatchesPublishedPorts(containerName, expectedPorts) {
|
|
294
|
+
const currentPorts = await readDockerNginxPublishedPorts(containerName);
|
|
295
|
+
return currentPorts.length === expectedPorts.length && currentPorts.every((port, index) => port === expectedPorts[index]);
|
|
296
|
+
}
|
|
297
|
+
async function removeDockerNginxProxyContainer(containerName) {
|
|
298
|
+
await run('docker', ['rm', '-f', containerName], {
|
|
299
|
+
errorName: 'docker rm',
|
|
300
|
+
stdio: 'ignore',
|
|
301
|
+
});
|
|
302
|
+
}
|
|
258
303
|
async function startDockerNginxProxy(runtimeContext) {
|
|
259
304
|
const containerName = await resolveNginxProxyContainerName();
|
|
260
305
|
await ensureNginxProxyMainConfig(runtimeContext);
|
|
261
|
-
|
|
306
|
+
const existedBeforeEnsure = await dockerContainerExists(containerName);
|
|
307
|
+
await ensureDockerNginxProxyContainer(runtimeContext);
|
|
308
|
+
if (existedBeforeEnsure && (await dockerContainerExists(containerName))) {
|
|
262
309
|
const state = await startDockerContainer(containerName, { stdio: 'ignore' });
|
|
263
310
|
return state === 'already-running' ? 'already-running' : 'started';
|
|
264
311
|
}
|
|
265
|
-
await ensureDockerNginxProxyContainer(runtimeContext);
|
|
266
312
|
return 'started';
|
|
267
313
|
}
|
|
268
314
|
async function stopDockerNginxProxy() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/cli",
|
|
3
|
-
"version": "2.2.0-alpha.
|
|
3
|
+
"version": "2.2.0-alpha.6",
|
|
4
4
|
"description": "NocoBase Command Line Tool",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/generated/command-registry.js",
|
|
@@ -144,5 +144,5 @@
|
|
|
144
144
|
"type": "git",
|
|
145
145
|
"url": "git+https://github.com/nocobase/nocobase.git"
|
|
146
146
|
},
|
|
147
|
-
"gitHead": "
|
|
147
|
+
"gitHead": "f55b252811f6af01d08cd3814171867b70c8ef7a"
|
|
148
148
|
}
|