@nocobase/cli 2.2.0-beta.8 → 2.2.0-test.15
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/app.conf.tpl +23 -0
- package/assets/env-proxy/nginx/nocobase.conf.tpl +5 -0
- package/assets/env-proxy/nginx/snippets/dist-location.conf +5 -0
- package/assets/env-proxy/nginx/snippets/gzip.conf +17 -0
- package/assets/env-proxy/nginx/snippets/log-format-http.conf +13 -0
- package/assets/env-proxy/nginx/snippets/maps-http.conf +14 -0
- package/assets/env-proxy/nginx/snippets/mime-types.conf +98 -0
- package/assets/env-proxy/nginx/snippets/proxy-location.conf +18 -0
- package/assets/env-proxy/nginx/snippets/spa-location.conf +6 -0
- package/assets/env-proxy/nginx/snippets/uploads-location.conf +24 -0
- package/dist/commands/app/start.js +25 -2
- package/dist/commands/config/set.js +1 -0
- package/dist/commands/env/info.js +11 -1
- package/dist/commands/init.js +131 -4
- package/dist/commands/install.js +179 -131
- package/dist/commands/portal/create.js +105 -0
- package/dist/commands/portal/deploy.js +81 -0
- package/dist/commands/portal/destroy.js +104 -0
- package/dist/commands/portal/dev.js +71 -0
- package/dist/commands/portal/index.js +20 -0
- package/dist/commands/portal/info.js +82 -0
- package/dist/commands/portal/list.js +98 -0
- package/dist/commands/portal/pull.js +77 -0
- package/dist/commands/portal/push.js +79 -0
- package/dist/commands/proxy/caddy/generate.js +93 -7
- package/dist/commands/proxy/nginx/generate.js +98 -7
- package/dist/commands/revision/create.js +1 -1
- package/dist/commands/source/dev.js +1 -1
- package/dist/commands/source/download.js +18 -14
- package/dist/lib/app-managed-resources.js +3 -2
- package/dist/lib/auth-store.js +71 -1
- package/dist/lib/cli-config.js +74 -2
- package/dist/lib/docker-image.js +94 -6
- package/dist/lib/env-config.js +8 -0
- package/dist/lib/env-proxy-config.js +48 -0
- package/dist/lib/env-proxy.js +266 -61
- package/dist/lib/managed-init-env.js +6 -1
- package/dist/lib/portal-command-env.js +31 -0
- package/dist/lib/portal-create.js +488 -0
- package/dist/lib/portal-deploy.js +275 -0
- package/dist/lib/portal-destroy.js +100 -0
- package/dist/lib/portal-dev.js +79 -0
- package/dist/lib/portal-env-files.js +53 -0
- package/dist/lib/portal-info.js +31 -0
- package/dist/lib/portal-list.js +197 -0
- package/dist/lib/portal-source.js +416 -0
- package/dist/lib/portal-template.js +190 -0
- package/dist/lib/prompt-catalog-terminal.js +32 -19
- package/dist/lib/prompt-web-ui.js +13 -2
- package/dist/lib/proxy-caddy.js +77 -9
- package/dist/lib/proxy-nginx.js +71 -11
- package/dist/lib/run-npm.js +17 -16
- package/dist/lib/ui.js +28 -1
- package/dist/locale/en-US.json +192 -38
- package/dist/locale/zh-CN.json +192 -38
- package/package.json +6 -3
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Rendered by `nb env proxy`.
|
|
2
|
+
# Context:
|
|
3
|
+
# publicBasePath={{publicBasePath}}
|
|
4
|
+
# apiBasePath={{apiBasePath}}
|
|
5
|
+
# wsPath={{wsPath}}
|
|
6
|
+
# v2PublicPath={{v2PublicPath}}
|
|
7
|
+
# backendUrl={{backendUrl}}
|
|
8
|
+
# snippetsDir={{snippetsDir}}
|
|
9
|
+
# uploadsDir={{uploadsDir}}
|
|
10
|
+
# distRootDir={{distRootDir}}
|
|
11
|
+
# entryDir={{entryDir}}
|
|
12
|
+
# publicDir={{publicDir}}
|
|
13
|
+
|
|
14
|
+
server {
|
|
15
|
+
listen 80;
|
|
16
|
+
server_name _;
|
|
17
|
+
|
|
18
|
+
# Add custom directives or locations above the managed block as needed.
|
|
19
|
+
|
|
20
|
+
{{managedConfigBlock}}
|
|
21
|
+
|
|
22
|
+
# Add custom directives or locations below the managed block as needed.
|
|
23
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
gzip on;
|
|
2
|
+
gzip_types
|
|
3
|
+
text/plain
|
|
4
|
+
text/css
|
|
5
|
+
text/xml
|
|
6
|
+
text/markdown
|
|
7
|
+
text/javascript
|
|
8
|
+
application/javascript
|
|
9
|
+
application/json
|
|
10
|
+
application/manifest+json
|
|
11
|
+
application/atom+xml
|
|
12
|
+
application/rss+xml
|
|
13
|
+
application/xml
|
|
14
|
+
application/xml+rss
|
|
15
|
+
application/xhtml+xml
|
|
16
|
+
application/wasm
|
|
17
|
+
image/svg+xml;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
log_format apm '"$time_local" client=$remote_addr '
|
|
2
|
+
'method=$request_method request="$request" '
|
|
3
|
+
'request_length=$request_length '
|
|
4
|
+
'status=$status bytes_sent=$bytes_sent '
|
|
5
|
+
'body_bytes_sent=$body_bytes_sent '
|
|
6
|
+
'referer=$http_referer '
|
|
7
|
+
'user_agent="$http_user_agent" '
|
|
8
|
+
'upstream_addr=$upstream_addr '
|
|
9
|
+
'upstream_status=$upstream_status '
|
|
10
|
+
'request_time=$request_time '
|
|
11
|
+
'upstream_response_time=$upstream_response_time '
|
|
12
|
+
'upstream_connect_time=$upstream_connect_time '
|
|
13
|
+
'upstream_header_time=$upstream_header_time';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
map $http_upgrade $connection_upgrade {
|
|
2
|
+
default upgrade;
|
|
3
|
+
"" close;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
map $http_x_forwarded_proto $upstream_x_forwarded_proto {
|
|
7
|
+
default $http_x_forwarded_proto;
|
|
8
|
+
"" $scheme;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
map $http_host $final_host {
|
|
12
|
+
default $http_host;
|
|
13
|
+
"" $host;
|
|
14
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
types {
|
|
2
|
+
text/html html htm shtml;
|
|
3
|
+
text/css css;
|
|
4
|
+
text/xml xml;
|
|
5
|
+
image/gif gif;
|
|
6
|
+
image/jpeg jpeg jpg;
|
|
7
|
+
application/javascript js mjs;
|
|
8
|
+
application/atom+xml atom;
|
|
9
|
+
application/rss+xml rss;
|
|
10
|
+
|
|
11
|
+
text/mathml mml;
|
|
12
|
+
text/plain txt;
|
|
13
|
+
text/vnd.sun.j2me.app-descriptor jad;
|
|
14
|
+
text/vnd.wap.wml wml;
|
|
15
|
+
text/x-component htc;
|
|
16
|
+
|
|
17
|
+
image/avif avif;
|
|
18
|
+
image/png png;
|
|
19
|
+
image/svg+xml svg svgz;
|
|
20
|
+
image/tiff tif tiff;
|
|
21
|
+
image/vnd.wap.wbmp wbmp;
|
|
22
|
+
image/webp webp;
|
|
23
|
+
image/x-icon ico;
|
|
24
|
+
image/x-jng jng;
|
|
25
|
+
image/x-ms-bmp bmp;
|
|
26
|
+
|
|
27
|
+
font/woff woff;
|
|
28
|
+
font/woff2 woff2;
|
|
29
|
+
|
|
30
|
+
application/java-archive jar war ear;
|
|
31
|
+
application/json json;
|
|
32
|
+
application/mac-binhex40 hqx;
|
|
33
|
+
application/msword doc;
|
|
34
|
+
application/pdf pdf;
|
|
35
|
+
application/postscript ps eps ai;
|
|
36
|
+
application/rtf rtf;
|
|
37
|
+
application/vnd.apple.mpegurl m3u8;
|
|
38
|
+
application/vnd.google-earth.kml+xml kml;
|
|
39
|
+
application/vnd.google-earth.kmz kmz;
|
|
40
|
+
application/vnd.ms-excel xls;
|
|
41
|
+
application/vnd.ms-fontobject eot;
|
|
42
|
+
application/vnd.ms-powerpoint ppt;
|
|
43
|
+
application/vnd.oasis.opendocument.graphics odg;
|
|
44
|
+
application/vnd.oasis.opendocument.presentation odp;
|
|
45
|
+
application/vnd.oasis.opendocument.spreadsheet ods;
|
|
46
|
+
application/vnd.oasis.opendocument.text odt;
|
|
47
|
+
application/vnd.openxmlformats-officedocument.presentationml.presentation
|
|
48
|
+
pptx;
|
|
49
|
+
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
|
50
|
+
xlsx;
|
|
51
|
+
application/vnd.openxmlformats-officedocument.wordprocessingml.document
|
|
52
|
+
docx;
|
|
53
|
+
application/vnd.wap.wmlc wmlc;
|
|
54
|
+
application/wasm wasm;
|
|
55
|
+
application/x-7z-compressed 7z;
|
|
56
|
+
application/x-cocoa cco;
|
|
57
|
+
application/x-java-archive-diff jardiff;
|
|
58
|
+
application/x-java-jnlp-file jnlp;
|
|
59
|
+
application/x-makeself run;
|
|
60
|
+
application/x-perl pl pm;
|
|
61
|
+
application/x-pilot prc pdb;
|
|
62
|
+
application/x-rar-compressed rar;
|
|
63
|
+
application/x-redhat-package-manager rpm;
|
|
64
|
+
application/x-sea sea;
|
|
65
|
+
application/x-shockwave-flash swf;
|
|
66
|
+
application/x-stuffit sit;
|
|
67
|
+
application/x-tcl tcl tk;
|
|
68
|
+
application/x-x509-ca-cert der pem crt;
|
|
69
|
+
application/x-xpinstall xpi;
|
|
70
|
+
application/xhtml+xml xhtml;
|
|
71
|
+
application/xspf+xml xspf;
|
|
72
|
+
application/zip zip;
|
|
73
|
+
|
|
74
|
+
application/octet-stream bin exe dll;
|
|
75
|
+
application/octet-stream deb;
|
|
76
|
+
application/octet-stream dmg;
|
|
77
|
+
application/octet-stream iso img;
|
|
78
|
+
application/octet-stream msi msp msm;
|
|
79
|
+
|
|
80
|
+
audio/midi mid midi kar;
|
|
81
|
+
audio/mpeg mp3;
|
|
82
|
+
audio/ogg ogg;
|
|
83
|
+
audio/x-m4a m4a;
|
|
84
|
+
audio/x-realaudio ra;
|
|
85
|
+
|
|
86
|
+
video/3gpp 3gpp 3gp;
|
|
87
|
+
video/mp2t ts;
|
|
88
|
+
video/mp4 mp4;
|
|
89
|
+
video/mpeg mpeg mpg;
|
|
90
|
+
video/quicktime mov;
|
|
91
|
+
video/webm webm;
|
|
92
|
+
video/x-flv flv;
|
|
93
|
+
video/x-m4v m4v;
|
|
94
|
+
video/x-mng mng;
|
|
95
|
+
video/x-ms-asf asx asf;
|
|
96
|
+
video/x-ms-wmv wmv;
|
|
97
|
+
video/x-msvideo avi;
|
|
98
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
proxy_http_version 1.1;
|
|
2
|
+
|
|
3
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
4
|
+
proxy_set_header Connection $connection_upgrade;
|
|
5
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
6
|
+
proxy_set_header X-Forwarded-Proto $upstream_x_forwarded_proto;
|
|
7
|
+
proxy_set_header Host $final_host;
|
|
8
|
+
proxy_set_header Referer $http_referer;
|
|
9
|
+
proxy_set_header User-Agent $http_user_agent;
|
|
10
|
+
|
|
11
|
+
add_header Cache-Control "no-cache, no-store" always;
|
|
12
|
+
proxy_cache_bypass $http_upgrade;
|
|
13
|
+
|
|
14
|
+
proxy_connect_timeout 600;
|
|
15
|
+
proxy_send_timeout 600;
|
|
16
|
+
proxy_read_timeout 600;
|
|
17
|
+
send_timeout 600;
|
|
18
|
+
proxy_buffering off;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
add_header Cache-Control "public" always;
|
|
2
|
+
add_header Content-Security-Policy "sandbox" always;
|
|
3
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
4
|
+
|
|
5
|
+
access_log off;
|
|
6
|
+
autoindex off;
|
|
7
|
+
|
|
8
|
+
# Force potentially renderable uploaded files to download.
|
|
9
|
+
location ~* \.(?:htm|html|pdf|svg|svgz|xht|xhtml|xml|xsl|xslt)$ {
|
|
10
|
+
add_header Cache-Control "public" always;
|
|
11
|
+
add_header Content-Security-Policy "sandbox" always;
|
|
12
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
13
|
+
add_header Content-Disposition "attachment" always;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
# Let Markdown files render as plain Markdown text.
|
|
17
|
+
location ~* \.md$ {
|
|
18
|
+
default_type text/markdown;
|
|
19
|
+
|
|
20
|
+
add_header Cache-Control "public" always;
|
|
21
|
+
add_header Content-Security-Policy "sandbox" always;
|
|
22
|
+
add_header X-Content-Type-Options "nosniff" always;
|
|
23
|
+
add_header Content-Disposition "inline" always;
|
|
24
|
+
}
|
|
@@ -14,6 +14,7 @@ import { AppHealthCheckError, formatAppUrl, isAppReady, resolveManagedAppApiBase
|
|
|
14
14
|
import { ensureBuiltinDbReady, ensureLocalPostinstall, ensureSavedLocalSource, recreateSavedDockerApp, } from '../../lib/app-managed-resources.js';
|
|
15
15
|
import { clearEnvRootSetup, getEnv, upsertEnv } from '../../lib/auth-store.js';
|
|
16
16
|
import { buildInitAppEnvVarsFromConfig, isPreparedSetupState } from '../../lib/managed-init-env.js';
|
|
17
|
+
import { prepareInitialPortalTemplate } from '../../lib/portal-template.js';
|
|
17
18
|
import { resolveAppUrlFromApiBaseUrl } from '../env/shared.js';
|
|
18
19
|
import { readManagedRuntimeEnvValues } from '../../lib/managed-env-file.js';
|
|
19
20
|
import { run } from '../../lib/run-npm.js';
|
|
@@ -37,6 +38,9 @@ function buildLicenseSyncArgv(envName, options) {
|
|
|
37
38
|
}
|
|
38
39
|
function resolveHookCommand(value) {
|
|
39
40
|
const text = String(value ?? '').trim();
|
|
41
|
+
if (text === 'init') {
|
|
42
|
+
return text;
|
|
43
|
+
}
|
|
40
44
|
if (text === 'app:restart' || text === 'app:upgrade') {
|
|
41
45
|
return text;
|
|
42
46
|
}
|
|
@@ -178,6 +182,19 @@ async function finalizePreparedEnv(envName) {
|
|
|
178
182
|
setupState: 'installed',
|
|
179
183
|
});
|
|
180
184
|
}
|
|
185
|
+
async function prepareInitialPortalForRuntime(runtime, verbose) {
|
|
186
|
+
await prepareInitialPortalTemplate({
|
|
187
|
+
developmentMode: runtime.env.config?.developmentMode,
|
|
188
|
+
portalName: runtime.env.config?.portalName,
|
|
189
|
+
portalTemplate: runtime.env.config?.portalTemplate,
|
|
190
|
+
npmRegistry: runtime.env.config?.npmRegistry,
|
|
191
|
+
storagePath: runtime.env.storagePath || runtime.env.config?.storagePath,
|
|
192
|
+
verbose,
|
|
193
|
+
onStartTask: startTask,
|
|
194
|
+
onSucceedTask: succeedTask,
|
|
195
|
+
onFailTask: failTask,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
181
198
|
export default class AppStart extends Command {
|
|
182
199
|
static hidden = false;
|
|
183
200
|
static description = 'Start NocoBase for the selected env. When applicable, the CLI synchronizes licensed commercial plugins first, then prepares and starts the app or recreates the saved Docker container.';
|
|
@@ -225,7 +242,7 @@ export default class AppStart extends Command {
|
|
|
225
242
|
}),
|
|
226
243
|
'hook-command': Flags.string({
|
|
227
244
|
hidden: true,
|
|
228
|
-
options: ['app:start', 'app:restart', 'app:upgrade'],
|
|
245
|
+
options: ['init', 'app:start', 'app:restart', 'app:upgrade'],
|
|
229
246
|
}),
|
|
230
247
|
};
|
|
231
248
|
async run() {
|
|
@@ -246,7 +263,7 @@ export default class AppStart extends Command {
|
|
|
246
263
|
}
|
|
247
264
|
const daemonFlagWasProvided = argvHasToken(this.argv, ['--daemon', '--no-daemon']);
|
|
248
265
|
const runtime = await resolveManagedAppRuntime(requestedEnv);
|
|
249
|
-
const preparedInitEnvVars = buildInitAppEnvVarsFromConfig(runtime?.env.config);
|
|
266
|
+
const preparedInitEnvVars = buildInitAppEnvVarsFromConfig(runtime?.env.config, { includePortal: false });
|
|
250
267
|
const isPreparedEnv = isPreparedSetupState(runtime?.env.config?.setupState);
|
|
251
268
|
const hookCommand = resolveHookCommand(flags['hook-command']);
|
|
252
269
|
const hookPhase = resolveAppStartHookPhase({
|
|
@@ -319,6 +336,9 @@ export default class AppStart extends Command {
|
|
|
319
336
|
command: hookCommand,
|
|
320
337
|
});
|
|
321
338
|
}
|
|
339
|
+
if (isPreparedEnv) {
|
|
340
|
+
await prepareInitialPortalForRuntime(runtime, flags.verbose);
|
|
341
|
+
}
|
|
322
342
|
await recreateSavedDockerApp(runtime, {
|
|
323
343
|
initEnvVars: isPreparedEnv ? preparedInitEnvVars : undefined,
|
|
324
344
|
verbose: flags.verbose,
|
|
@@ -467,6 +487,9 @@ export default class AppStart extends Command {
|
|
|
467
487
|
command: hookCommand,
|
|
468
488
|
});
|
|
469
489
|
}
|
|
490
|
+
if (isPreparedEnv) {
|
|
491
|
+
await prepareInitialPortalForRuntime(runtime, flags.verbose);
|
|
492
|
+
}
|
|
470
493
|
await runLocalNocoBaseCommand(runtime, npmArgs, {
|
|
471
494
|
env: startEnv,
|
|
472
495
|
stdio: commandStdio,
|
|
@@ -14,6 +14,7 @@ export default class ConfigSet extends Command {
|
|
|
14
14
|
static description = 'Set a CLI configuration value for a supported configuration key.';
|
|
15
15
|
static examples = [
|
|
16
16
|
'<%= config.bin %> <%= command.id %> locale zh-CN',
|
|
17
|
+
'<%= config.bin %> <%= command.id %> default-portal-template git@github.com:nocobase/admin-starter.git',
|
|
17
18
|
'<%= config.bin %> <%= command.id %> update.policy prompt',
|
|
18
19
|
'<%= config.bin %> <%= command.id %> docker.network nocobase',
|
|
19
20
|
'<%= config.bin %> <%= command.id %> docker.container-prefix nb',
|
|
@@ -170,8 +170,13 @@ export default class EnvInfo extends Command {
|
|
|
170
170
|
'auth.accessToken': authGroup.accessToken,
|
|
171
171
|
'auth.refreshToken': authGroup.refreshToken,
|
|
172
172
|
};
|
|
173
|
+
const envGroup = {
|
|
174
|
+
name: runtime.envName,
|
|
175
|
+
kind: runtime.kind,
|
|
176
|
+
};
|
|
173
177
|
const output = {
|
|
174
178
|
ok: true,
|
|
179
|
+
name: runtime.envName,
|
|
175
180
|
env: runtime.envName,
|
|
176
181
|
kind: runtime.kind,
|
|
177
182
|
app: serializeGroup(appGroup),
|
|
@@ -197,6 +202,11 @@ export default class EnvInfo extends Command {
|
|
|
197
202
|
this.log(JSON.stringify(output, null, 2));
|
|
198
203
|
return;
|
|
199
204
|
}
|
|
200
|
-
this.log([
|
|
205
|
+
this.log([
|
|
206
|
+
createGroupTable('Env', envGroup),
|
|
207
|
+
createGroupTable('App', appGroup),
|
|
208
|
+
createGroupTable('DB', dbGroup),
|
|
209
|
+
createGroupTable('API', apiGroup),
|
|
210
|
+
].join('\n\n'));
|
|
201
211
|
}
|
|
202
212
|
}
|
package/dist/commands/init.js
CHANGED
|
@@ -16,7 +16,8 @@ import { getEnv, upsertEnv } from "../lib/auth-store.js";
|
|
|
16
16
|
import { runPromptCatalog, } from "../lib/prompt-catalog.js";
|
|
17
17
|
import { applyCliLocale, localeText, translateCli } from "../lib/cli-locale.js";
|
|
18
18
|
import { resolveConfiguredEnvPath, resolveDefaultConfigScope, resolveEnvRelativePath } from '../lib/cli-home.js';
|
|
19
|
-
import { resolveDefaultApiHost, resolveDefaultUiHost } from '../lib/cli-config.js';
|
|
19
|
+
import { getCliConfigValue, resolveDefaultApiHost, resolveDefaultUiHost } from '../lib/cli-config.js';
|
|
20
|
+
import { resolveOfficialDockerRegistry } from '../lib/docker-image.js';
|
|
20
21
|
import { areConfiguredPathsEquivalent, deriveConfiguredSourcePath, deriveConfiguredStoragePath, inferConfiguredAppPathFromLegacyConfig, } from '../lib/env-paths.js';
|
|
21
22
|
import { formatMissingManagedAppEnvMessage } from '../lib/app-runtime.js';
|
|
22
23
|
import { runPromptCatalogWebUI } from "../lib/prompt-web-ui.js";
|
|
@@ -31,8 +32,12 @@ import EnvAdd from "./env/add.js";
|
|
|
31
32
|
import Install, { defaultDbPortForDialect } from "./install.js";
|
|
32
33
|
const DEFAULT_INIT_API_BASE_URL = 'http://localhost:13000/api';
|
|
33
34
|
const DEFAULT_INIT_APP_NAME = 'local';
|
|
35
|
+
const DEFAULT_INIT_DEVELOPMENT_MODE = 'no-code';
|
|
36
|
+
const DEFAULT_INIT_PORTAL_NAME = 'admin';
|
|
37
|
+
const DEFAULT_INIT_PORTAL_TEMPLATE = 'git@github.com:nocobase/admin-starter.git';
|
|
34
38
|
const DOWNLOAD_OUTPUT_DIR_PROMPT = Download.prompts.outputDir;
|
|
35
39
|
const INIT_SETUP_MODES = ['install-new', 'manage-local', 'connect-remote'];
|
|
40
|
+
const INIT_DEVELOPMENT_MODES = ['no-code', 'vibe-coding'];
|
|
36
41
|
const INIT_ENV_ADD_FLAG_NAMES = [
|
|
37
42
|
'locale',
|
|
38
43
|
'default-api-base-url',
|
|
@@ -79,6 +84,9 @@ function isInstallNewSetupMode(values) {
|
|
|
79
84
|
function isInstallLikeSetupMode(values) {
|
|
80
85
|
return !isRemoteSetupMode(values);
|
|
81
86
|
}
|
|
87
|
+
function isVibeCodingMode(values) {
|
|
88
|
+
return String(values.developmentMode ?? DEFAULT_INIT_DEVELOPMENT_MODE).trim() === 'vibe-coding';
|
|
89
|
+
}
|
|
82
90
|
function remoteConnectionOnly(def) {
|
|
83
91
|
return withExtraHidden(def, (values) => !isRemoteSetupMode(values));
|
|
84
92
|
}
|
|
@@ -386,6 +394,43 @@ Prompt modes:
|
|
|
386
394
|
devDependencies: installLikeDownloadExecutionOnly(Download.prompts.devDependencies),
|
|
387
395
|
build: installLikeDownloadExecutionOnly(Download.prompts.build),
|
|
388
396
|
buildDts: installLikeDownloadExecutionOnly(Download.prompts.buildDts),
|
|
397
|
+
developmentMode: installNewOnly({
|
|
398
|
+
type: 'select',
|
|
399
|
+
variant: 'radio',
|
|
400
|
+
message: initText('prompts.developmentMode.message'),
|
|
401
|
+
options: [
|
|
402
|
+
{
|
|
403
|
+
value: 'no-code',
|
|
404
|
+
label: initText('prompts.developmentMode.noCodeLabel'),
|
|
405
|
+
hint: initText('prompts.developmentMode.noCodeHint'),
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
value: 'vibe-coding',
|
|
409
|
+
label: initText('prompts.developmentMode.vibeCodingLabel'),
|
|
410
|
+
hint: initText('prompts.developmentMode.vibeCodingHint'),
|
|
411
|
+
},
|
|
412
|
+
],
|
|
413
|
+
initialValue: DEFAULT_INIT_DEVELOPMENT_MODE,
|
|
414
|
+
yesInitialValue: DEFAULT_INIT_DEVELOPMENT_MODE,
|
|
415
|
+
required: true,
|
|
416
|
+
}),
|
|
417
|
+
portalName: installNewOnly({
|
|
418
|
+
type: 'text',
|
|
419
|
+
message: initText('prompts.portalName.message'),
|
|
420
|
+
placeholder: DEFAULT_INIT_PORTAL_NAME,
|
|
421
|
+
initialValue: DEFAULT_INIT_PORTAL_NAME,
|
|
422
|
+
yesInitialValue: DEFAULT_INIT_PORTAL_NAME,
|
|
423
|
+
hidden: (values) => !isVibeCodingMode(values),
|
|
424
|
+
required: true,
|
|
425
|
+
}),
|
|
426
|
+
portalTemplate: installNewOnly({
|
|
427
|
+
type: 'text',
|
|
428
|
+
message: initText('prompts.portalTemplate.message'),
|
|
429
|
+
placeholder: DEFAULT_INIT_PORTAL_TEMPLATE,
|
|
430
|
+
yesInitialValue: DEFAULT_INIT_PORTAL_TEMPLATE,
|
|
431
|
+
hidden: (values) => !isVibeCodingMode(values),
|
|
432
|
+
required: true,
|
|
433
|
+
}),
|
|
389
434
|
dbDialect: installLikeOnly(Install.dbPrompts.dbDialect),
|
|
390
435
|
builtinDb: installLikeOnly(Install.dbPrompts.builtinDb),
|
|
391
436
|
builtinDbImage: installLikeOnly(Install.dbPrompts.builtinDbImage),
|
|
@@ -411,6 +456,13 @@ Prompt modes:
|
|
|
411
456
|
...Init.prompts,
|
|
412
457
|
installApiBaseUrl: createInstallConnectionApiBaseUrlPrompt(options.defaultApiHost),
|
|
413
458
|
};
|
|
459
|
+
const defaultPortalTemplate = String(options.defaultPortalTemplate ?? '').trim();
|
|
460
|
+
if (defaultPortalTemplate) {
|
|
461
|
+
prompts.portalTemplate = {
|
|
462
|
+
...prompts.portalTemplate,
|
|
463
|
+
yesInitialValue: defaultPortalTemplate,
|
|
464
|
+
};
|
|
465
|
+
}
|
|
414
466
|
if (flags['skip-auth']) {
|
|
415
467
|
const accessTokenPrompt = {
|
|
416
468
|
...EnvAdd.prompts.accessToken,
|
|
@@ -460,6 +512,16 @@ Prompt modes:
|
|
|
460
512
|
description: 'Setup mode: install a new app, manage a local app by reusing its database, or connect a remote app',
|
|
461
513
|
options: [...INIT_SETUP_MODES],
|
|
462
514
|
}),
|
|
515
|
+
'development-mode': Flags.string({
|
|
516
|
+
description: 'Initial development mode: no-code or vibe-coding',
|
|
517
|
+
options: [...INIT_DEVELOPMENT_MODES],
|
|
518
|
+
}),
|
|
519
|
+
'portal-name': Flags.string({
|
|
520
|
+
description: 'Initial portal name when --development-mode vibe-coding is used',
|
|
521
|
+
}),
|
|
522
|
+
'portal-template': Flags.string({
|
|
523
|
+
description: 'Initial portal template Git URL or local path when --development-mode vibe-coding is used',
|
|
524
|
+
}),
|
|
463
525
|
ui: Flags.boolean({
|
|
464
526
|
description: 'Open the guided setup flow in a local browser form (not valid with --yes)',
|
|
465
527
|
default: false,
|
|
@@ -577,7 +639,8 @@ Prompt modes:
|
|
|
577
639
|
const dynamicInitialValues = await Init.buildDynamicInitialValuesForInstall(normalizedFlags, presetValues);
|
|
578
640
|
const defaultUiHost = await resolveDefaultUiHost();
|
|
579
641
|
const defaultApiHost = await resolveDefaultApiHost();
|
|
580
|
-
const
|
|
642
|
+
const defaultPortalTemplate = String(dynamicInitialValues.portalTemplate ?? '').trim();
|
|
643
|
+
const promptCatalog = this.buildPromptCatalog(normalizedFlags, { defaultApiHost, defaultPortalTemplate });
|
|
581
644
|
if (useBrowserUi) {
|
|
582
645
|
presetValues = await runPromptCatalogWebUI({
|
|
583
646
|
stages: Init.buildWebUiStages(promptCatalog),
|
|
@@ -606,6 +669,7 @@ Prompt modes:
|
|
|
606
669
|
? { setupMode: normalizeInitSetupMode(presetValues.hasNocobase) }
|
|
607
670
|
: {}),
|
|
608
671
|
},
|
|
672
|
+
yesInitialValues: pickKeys(dynamicInitialValues, ['portalTemplate']),
|
|
609
673
|
values: presetValues,
|
|
610
674
|
yes: normalizedFlags.yes || useBrowserUi || !interactive,
|
|
611
675
|
hooks: {
|
|
@@ -678,7 +742,9 @@ Prompt modes:
|
|
|
678
742
|
}
|
|
679
743
|
static async buildDynamicInitialValuesForInstall(flags, presetValues) {
|
|
680
744
|
const out = {};
|
|
681
|
-
|
|
745
|
+
const shouldResolveAppInitialValues = !Object.prototype.hasOwnProperty.call(presetValues, 'appPort') ||
|
|
746
|
+
!Object.prototype.hasOwnProperty.call(presetValues, 'portalTemplate');
|
|
747
|
+
if (shouldResolveAppInitialValues) {
|
|
682
748
|
const appInitialValues = await Install.buildAppPromptInitialValues({
|
|
683
749
|
envName: String(presetValues.appName ?? '').trim(),
|
|
684
750
|
flags: {
|
|
@@ -686,17 +752,31 @@ Prompt modes:
|
|
|
686
752
|
'app-path': flags['app-path'] ?? '',
|
|
687
753
|
'app-root-path': flags['app-root-path'] ?? '',
|
|
688
754
|
'storage-path': flags['storage-path'] ?? '',
|
|
755
|
+
'portal-template': flags['portal-template'] ??
|
|
756
|
+
(Object.prototype.hasOwnProperty.call(presetValues, 'portalTemplate')
|
|
757
|
+
? String(presetValues.portalTemplate ?? '')
|
|
758
|
+
: undefined),
|
|
689
759
|
},
|
|
690
760
|
warnOnPortFallback: false,
|
|
691
761
|
});
|
|
692
|
-
if (appInitialValues.appPort !== undefined) {
|
|
762
|
+
if (appInitialValues.appPort !== undefined && !Object.prototype.hasOwnProperty.call(presetValues, 'appPort')) {
|
|
693
763
|
out.appPort = appInitialValues.appPort;
|
|
694
764
|
}
|
|
765
|
+
if (appInitialValues.portalTemplate !== undefined &&
|
|
766
|
+
!Object.prototype.hasOwnProperty.call(presetValues, 'portalTemplate')) {
|
|
767
|
+
out.portalTemplate = appInitialValues.portalTemplate;
|
|
768
|
+
}
|
|
695
769
|
}
|
|
696
770
|
const downloadSeed = { ...presetValues };
|
|
697
771
|
if (flags.yes && !Object.prototype.hasOwnProperty.call(downloadSeed, 'source')) {
|
|
698
772
|
downloadSeed.source = 'docker';
|
|
699
773
|
}
|
|
774
|
+
const builtinDbImageRegistry = String(presetValues.dockerRegistry ?? '').trim() ||
|
|
775
|
+
resolveOfficialDockerRegistry(await getCliConfigValue('nb-image-registry'));
|
|
776
|
+
if (!Object.prototype.hasOwnProperty.call(presetValues, 'dockerRegistry')) {
|
|
777
|
+
out.dockerRegistry = builtinDbImageRegistry;
|
|
778
|
+
}
|
|
779
|
+
out.builtinDbImageRegistry = builtinDbImageRegistry;
|
|
700
780
|
const dbInitial = await Install.buildDbPromptInitialValues({
|
|
701
781
|
flags,
|
|
702
782
|
downloadResults: downloadSeed,
|
|
@@ -704,6 +784,9 @@ Prompt modes:
|
|
|
704
784
|
warnOnPortFallback: false,
|
|
705
785
|
});
|
|
706
786
|
for (const [key, value] of Object.entries(dbInitial)) {
|
|
787
|
+
if (key === 'builtinDbImage') {
|
|
788
|
+
continue;
|
|
789
|
+
}
|
|
707
790
|
if (!Object.prototype.hasOwnProperty.call(presetValues, key)) {
|
|
708
791
|
out[key] = value;
|
|
709
792
|
}
|
|
@@ -761,6 +844,13 @@ Prompt modes:
|
|
|
761
844
|
buildDts: c.buildDts,
|
|
762
845
|
},
|
|
763
846
|
},
|
|
847
|
+
{
|
|
848
|
+
sectionTitle: initText('webUi.developmentMode.title'),
|
|
849
|
+
sectionDescription: initText('webUi.developmentMode.description'),
|
|
850
|
+
catalog: {
|
|
851
|
+
developmentMode: c.developmentMode,
|
|
852
|
+
},
|
|
853
|
+
},
|
|
764
854
|
{
|
|
765
855
|
sectionTitle: initText('webUi.configureDatabase.title'),
|
|
766
856
|
sectionDescription: initText('webUi.configureDatabase.description'),
|
|
@@ -861,6 +951,15 @@ Prompt modes:
|
|
|
861
951
|
if (flags['app-public-path'] !== undefined && String(flags['app-public-path']).trim() !== '') {
|
|
862
952
|
preset.appPublicPath = String(flags['app-public-path']).trim();
|
|
863
953
|
}
|
|
954
|
+
if (flags['development-mode'] !== undefined && String(flags['development-mode']).trim() !== '') {
|
|
955
|
+
preset.developmentMode = String(flags['development-mode']).trim();
|
|
956
|
+
}
|
|
957
|
+
if (flags['portal-name'] !== undefined && String(flags['portal-name']).trim() !== '') {
|
|
958
|
+
preset.portalName = String(flags['portal-name']).trim();
|
|
959
|
+
}
|
|
960
|
+
if (flags['portal-template'] !== undefined && String(flags['portal-template']).trim() !== '') {
|
|
961
|
+
preset.portalTemplate = String(flags['portal-template']).trim();
|
|
962
|
+
}
|
|
864
963
|
if (flags['root-username'] !== undefined) {
|
|
865
964
|
preset.rootUsername = String(flags['root-username'] ?? '').trim();
|
|
866
965
|
}
|
|
@@ -998,6 +1097,9 @@ Prompt modes:
|
|
|
998
1097
|
const existingEnv = await getEnv(envName, { scope: resolveDefaultConfigScope() });
|
|
999
1098
|
const appPort = String(results.appPort ?? '').trim();
|
|
1000
1099
|
const appPublicPath = String(results.appPublicPath ?? '').trim();
|
|
1100
|
+
const developmentMode = String(results.developmentMode ?? '').trim();
|
|
1101
|
+
const portalName = String(results.portalName ?? '').trim();
|
|
1102
|
+
const portalTemplate = String(results.portalTemplate ?? '').trim();
|
|
1001
1103
|
const source = String(results.source ?? '').trim();
|
|
1002
1104
|
const version = resolveInitDownloadVersion(results);
|
|
1003
1105
|
const dockerRegistry = String(results.dockerRegistry ?? '').trim();
|
|
@@ -1070,6 +1172,9 @@ Prompt modes:
|
|
|
1070
1172
|
...(storagePath && !areConfiguredPathsEquivalent(storagePath, derivedStoragePath) ? { storagePath } : {}),
|
|
1071
1173
|
...(appPort ? { appPort } : {}),
|
|
1072
1174
|
...(appPublicPath ? { appPublicPath } : {}),
|
|
1175
|
+
...(developmentMode && developmentMode !== DEFAULT_INIT_DEVELOPMENT_MODE ? { developmentMode } : {}),
|
|
1176
|
+
...(portalName ? { portalName } : {}),
|
|
1177
|
+
...(portalTemplate ? { portalTemplate } : {}),
|
|
1073
1178
|
...(appKey ? { appKey } : {}),
|
|
1074
1179
|
...(timeZone ? { timezone: timeZone } : {}),
|
|
1075
1180
|
...(!skipDownload && results.devDependencies !== undefined
|
|
@@ -1194,6 +1299,18 @@ Prompt modes:
|
|
|
1194
1299
|
if (appPublicPath) {
|
|
1195
1300
|
argv.push('--app-public-path', appPublicPath);
|
|
1196
1301
|
}
|
|
1302
|
+
const developmentMode = String(results.developmentMode ?? '').trim();
|
|
1303
|
+
if (developmentMode && developmentMode !== DEFAULT_INIT_DEVELOPMENT_MODE) {
|
|
1304
|
+
argv.push('--development-mode', developmentMode);
|
|
1305
|
+
}
|
|
1306
|
+
const portalName = String(results.portalName ?? '').trim();
|
|
1307
|
+
if (portalName) {
|
|
1308
|
+
argv.push('--portal-name', portalName);
|
|
1309
|
+
}
|
|
1310
|
+
const portalTemplate = String(results.portalTemplate ?? '').trim();
|
|
1311
|
+
if (portalTemplate) {
|
|
1312
|
+
argv.push('--portal-template', portalTemplate);
|
|
1313
|
+
}
|
|
1197
1314
|
if (flags.force) {
|
|
1198
1315
|
argv.push('--force');
|
|
1199
1316
|
}
|
|
@@ -1391,6 +1508,16 @@ Prompt modes:
|
|
|
1391
1508
|
delete normalized.rootPassword;
|
|
1392
1509
|
delete normalized.rootNickname;
|
|
1393
1510
|
}
|
|
1511
|
+
const developmentMode = normalizeConnectionString(normalized.developmentMode) || DEFAULT_INIT_DEVELOPMENT_MODE;
|
|
1512
|
+
normalized.developmentMode = developmentMode;
|
|
1513
|
+
if (developmentMode === 'vibe-coding') {
|
|
1514
|
+
normalized.portalName = normalizeConnectionString(normalized.portalName) || DEFAULT_INIT_PORTAL_NAME;
|
|
1515
|
+
normalized.portalTemplate = normalizeConnectionString(normalized.portalTemplate);
|
|
1516
|
+
}
|
|
1517
|
+
else {
|
|
1518
|
+
delete normalized.portalName;
|
|
1519
|
+
delete normalized.portalTemplate;
|
|
1520
|
+
}
|
|
1394
1521
|
delete normalized.installApiBaseUrl;
|
|
1395
1522
|
delete normalized.installAuthType;
|
|
1396
1523
|
delete normalized.installUsername;
|