@nocobase/cli 2.2.0-test.15 → 2.2.0

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 (44) hide show
  1. package/dist/commands/api/resource/create.js +11 -2
  2. package/dist/commands/app/start.js +1 -21
  3. package/dist/commands/config/set.js +0 -1
  4. package/dist/commands/init.js +3 -120
  5. package/dist/commands/install.js +4 -121
  6. package/dist/commands/source/dev.js +1 -1
  7. package/dist/lib/api-client.js +7 -0
  8. package/dist/lib/auth-store.js +1 -3
  9. package/dist/lib/browser.js +29 -0
  10. package/dist/lib/cli-config.js +1 -20
  11. package/dist/lib/env-config.js +0 -3
  12. package/dist/lib/env-proxy.js +1 -65
  13. package/dist/lib/generated-command.js +81 -0
  14. package/dist/lib/managed-init-env.js +1 -6
  15. package/dist/lib/naming.js +9 -0
  16. package/dist/lib/plugin-import.js +30 -8
  17. package/dist/lib/resource-command.js +18 -2
  18. package/dist/lib/resource-request.js +8 -0
  19. package/dist/lib/run-npm.js +16 -17
  20. package/dist/lib/runtime-generator.js +28 -1
  21. package/dist/lib/ui.js +1 -28
  22. package/dist/locale/en-US.json +0 -154
  23. package/dist/locale/zh-CN.json +0 -154
  24. package/nocobase-ctl.config.json +111 -0
  25. package/package.json +3 -5
  26. package/dist/commands/portal/create.js +0 -105
  27. package/dist/commands/portal/deploy.js +0 -81
  28. package/dist/commands/portal/destroy.js +0 -104
  29. package/dist/commands/portal/dev.js +0 -71
  30. package/dist/commands/portal/index.js +0 -20
  31. package/dist/commands/portal/info.js +0 -82
  32. package/dist/commands/portal/list.js +0 -98
  33. package/dist/commands/portal/pull.js +0 -77
  34. package/dist/commands/portal/push.js +0 -79
  35. package/dist/lib/portal-command-env.js +0 -31
  36. package/dist/lib/portal-create.js +0 -488
  37. package/dist/lib/portal-deploy.js +0 -275
  38. package/dist/lib/portal-destroy.js +0 -100
  39. package/dist/lib/portal-dev.js +0 -79
  40. package/dist/lib/portal-env-files.js +0 -53
  41. package/dist/lib/portal-info.js +0 -31
  42. package/dist/lib/portal-list.js +0 -197
  43. package/dist/lib/portal-source.js +0 -416
  44. package/dist/lib/portal-template.js +0 -190
@@ -1,190 +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
- import { cp, mkdir, mkdtemp, rm, stat } from 'node:fs/promises';
10
- import os from 'node:os';
11
- import path from 'node:path';
12
- import { fileURLToPath } from 'node:url';
13
- import { buildPortalCommandEnv } from './portal-command-env.js';
14
- import { resolvePortalTemplate } from './portal-create.js';
15
- import { run } from './run-npm.js';
16
- const DEFAULT_PORTAL_APP_NAME = 'main';
17
- const DEFAULT_PORTAL_NAME = 'admin';
18
- const PORTAL_CLIENT_PREFIX = 'x';
19
- function trimValue(value) {
20
- return String(value ?? '').trim();
21
- }
22
- function normalizePortalName(value) {
23
- const segment = String(value || '')
24
- .trim()
25
- .replace(/^\/+|\/+$/g, '');
26
- return segment || DEFAULT_PORTAL_NAME;
27
- }
28
- function normalizePortalAppName(value) {
29
- const segment = String(value || '')
30
- .trim()
31
- .replace(/^\/+|\/+$/g, '');
32
- return segment || DEFAULT_PORTAL_APP_NAME;
33
- }
34
- function validatePortalSegment(kind, value) {
35
- if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(value)) {
36
- throw new Error(`Invalid ${kind} "${value}". Use letters, numbers, underscores, or hyphens, and start with a letter or number.`);
37
- }
38
- }
39
- async function pathExists(filePath) {
40
- try {
41
- await stat(filePath);
42
- return true;
43
- }
44
- catch {
45
- return false;
46
- }
47
- }
48
- function resolveLocalTemplatePath(templateSource) {
49
- if (templateSource.startsWith('file://')) {
50
- return fileURLToPath(templateSource);
51
- }
52
- return templateSource;
53
- }
54
- function isGitTemplateSource(templateSource) {
55
- return (templateSource.startsWith('git@') ||
56
- templateSource.startsWith('git+') ||
57
- /^https?:\/\//i.test(templateSource) ||
58
- templateSource.endsWith('.git'));
59
- }
60
- async function getLocalTemplateDir(templateSource) {
61
- let localPath;
62
- try {
63
- localPath = resolveLocalTemplatePath(templateSource);
64
- }
65
- catch {
66
- return undefined;
67
- }
68
- let result;
69
- try {
70
- result = await stat(localPath);
71
- }
72
- catch {
73
- return undefined;
74
- }
75
- if (!result.isDirectory()) {
76
- throw new Error(`Portal template "${templateSource}" is invalid: expected a directory.`);
77
- }
78
- return localPath;
79
- }
80
- async function resolveInitialPortalTemplate(params) {
81
- const localTemplateDir = await getLocalTemplateDir(params.templateSource);
82
- if (localTemplateDir) {
83
- return {
84
- dir: localTemplateDir,
85
- source: params.templateSource,
86
- type: 'local',
87
- };
88
- }
89
- if (!isGitTemplateSource(params.templateSource)) {
90
- return resolvePortalTemplate(params.templateSource, {
91
- npmRegistry: params.npmRegistry,
92
- runCommand: params.runCommand,
93
- });
94
- }
95
- await params.runCommand('git', ['clone', '--depth', '1', params.templateSource, params.tempDir], {
96
- errorName: 'git clone',
97
- stdio: params.verbose ? 'inherit' : 'ignore',
98
- });
99
- return {
100
- dir: params.tempDir,
101
- source: params.templateSource,
102
- type: 'local',
103
- };
104
- }
105
- async function copyTemplate(sourceDir, targetDir) {
106
- await mkdir(path.dirname(targetDir), { recursive: true });
107
- await cp(sourceDir, targetDir, {
108
- recursive: true,
109
- filter: (source) => !source.split(path.sep).includes('.git'),
110
- });
111
- }
112
- async function buildPortalHtml(params) {
113
- const stdio = params.verbose ? 'inherit' : 'ignore';
114
- await params.runCommand('yarn', ['build:html'], {
115
- cwd: params.portalDir,
116
- env: buildPortalCommandEnv({
117
- NOCOBASE_API_URL: '/api',
118
- NOCOBASE_PORTAL_BASE: `/${PORTAL_CLIENT_PREFIX}/${params.portalName}/`,
119
- }),
120
- envMode: 'replace',
121
- errorName: 'yarn build:html',
122
- stdio,
123
- });
124
- }
125
- export async function prepareInitialPortalTemplate(options) {
126
- const developmentMode = trimValue(options.developmentMode);
127
- if (developmentMode !== 'vibe-coding') {
128
- return { prepared: false, skippedReason: 'no-code' };
129
- }
130
- const storagePath = trimValue(options.storagePath);
131
- if (!storagePath) {
132
- throw new Error('Cannot prepare an initial Portal template without a storage path.');
133
- }
134
- const templateUrl = trimValue(options.portalTemplate);
135
- if (!templateUrl) {
136
- throw new Error('Initial Portal template is required when development mode is "vibe-coding".');
137
- }
138
- const appName = normalizePortalAppName(options.appName);
139
- const portalName = normalizePortalName(options.portalName);
140
- validatePortalSegment('portal app name', appName);
141
- validatePortalSegment('Portal name', portalName);
142
- const portalDir = path.join(storagePath, 'portals', appName, portalName);
143
- if (await pathExists(portalDir)) {
144
- if (await pathExists(path.join(portalDir, 'dist', 'index.html'))) {
145
- return { prepared: false, skippedReason: 'already-prepared' };
146
- }
147
- await rm(portalDir, { recursive: true, force: true });
148
- }
149
- options.onStartTask?.(`Preparing Portal "${portalName}" from template...`);
150
- const runCommand = options.runCommand ?? run;
151
- const tempDir = await mkdtemp(path.join(os.tmpdir(), 'nocobase-portal-template-'));
152
- let cleanupPortalDir = false;
153
- let template;
154
- try {
155
- template = await resolveInitialPortalTemplate({
156
- templateSource: templateUrl,
157
- tempDir,
158
- npmRegistry: options.npmRegistry,
159
- verbose: options.verbose,
160
- runCommand,
161
- });
162
- const templateDir = template.dir;
163
- if (!(await pathExists(path.join(templateDir, 'package.json')))) {
164
- throw new Error(`Portal template "${templateUrl}" is invalid: package.json is missing.`);
165
- }
166
- cleanupPortalDir = true;
167
- await copyTemplate(templateDir, portalDir);
168
- await rm(path.join(portalDir, 'node_modules'), { recursive: true, force: true });
169
- await buildPortalHtml({
170
- portalDir,
171
- portalName,
172
- verbose: options.verbose,
173
- runCommand,
174
- });
175
- cleanupPortalDir = false;
176
- options.onSucceedTask?.(`Portal "${portalName}" is ready.`);
177
- return { prepared: true };
178
- }
179
- catch (error) {
180
- if (cleanupPortalDir) {
181
- await rm(portalDir, { recursive: true, force: true });
182
- }
183
- options.onFailTask?.(`Failed to prepare Portal "${portalName}".`);
184
- throw error;
185
- }
186
- finally {
187
- await rm(tempDir, { recursive: true, force: true });
188
- await template?.cleanup?.();
189
- }
190
- }