openxiangda 1.0.94 → 1.0.96
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/lib/cli.js +53 -2
- package/lib/design-gates.js +99 -3
- package/package.json +1 -1
package/lib/cli.js
CHANGED
|
@@ -24,7 +24,9 @@ const { assertCanInitializeWorkspace, initWorkspace } = require('./workspace-ini
|
|
|
24
24
|
const { bootstrapWorkspace } = require('./workspace-bootstrap');
|
|
25
25
|
const {
|
|
26
26
|
getDesignGates,
|
|
27
|
+
getDesignTopicCatalog,
|
|
27
28
|
getResourceExplain,
|
|
29
|
+
renderDesignHelp,
|
|
28
30
|
renderDesignGatesText,
|
|
29
31
|
renderDesignTemplate,
|
|
30
32
|
renderResourceExplain,
|
|
@@ -49,6 +51,9 @@ const RUNTIME_UPLOAD_CONCURRENCY = 3;
|
|
|
49
51
|
|
|
50
52
|
async function main(argv) {
|
|
51
53
|
const [command, ...rest] = argv;
|
|
54
|
+
if (command === 'version' || command === '--version' || command === '-v') {
|
|
55
|
+
return version(rest);
|
|
56
|
+
}
|
|
52
57
|
if (!command || command === 'help' || command === '--help' || command === '-h') {
|
|
53
58
|
printHelp();
|
|
54
59
|
return;
|
|
@@ -91,6 +96,7 @@ function printHelp() {
|
|
|
91
96
|
print(`OpenXiangda CLI
|
|
92
97
|
|
|
93
98
|
Usage:
|
|
99
|
+
openxiangda version [--json]
|
|
94
100
|
openxiangda login <platform-url> [--profile name]
|
|
95
101
|
openxiangda update check|install [--json] [--registry https://registry.npmjs.org]
|
|
96
102
|
openxiangda platform add <name> <platform-url>
|
|
@@ -153,6 +159,7 @@ Usage:
|
|
|
153
159
|
|
|
154
160
|
OpenXiangda 使用普通用户登录 token,不需要 AK/SK。
|
|
155
161
|
表单页、流程表单页和代码页的主链路是 sy-lowcode-app-workspace + openxiangda workspace publish。
|
|
162
|
+
新 React SPA 公开访问使用 public-access 命令和 src/resources/public-access;settings public-access 仅用于旧表单公开设置兼容/修复。
|
|
156
163
|
JS_CODE V2 使用 trusted_node;AI 源码必须写在 src/js-code-nodes/<scriptCode>/index.ts,代码自动化源码写在 src/automations/<resourceCode>/index.ts。definition-json 中的 sourceFile.localPath 会在 validate/create/publish 时先 TS 校验、再构建并上传为快照。`);
|
|
157
164
|
}
|
|
158
165
|
|
|
@@ -233,6 +240,17 @@ function wantsSubcommandHelp(subcommand, flags) {
|
|
|
233
240
|
);
|
|
234
241
|
}
|
|
235
242
|
|
|
243
|
+
async function version(args) {
|
|
244
|
+
const { flags } = parseArgs(args);
|
|
245
|
+
const result = {
|
|
246
|
+
name: NPM_PACKAGE_NAME,
|
|
247
|
+
version: CURRENT_VERSION,
|
|
248
|
+
updateCheckCommand: 'openxiangda update check --json',
|
|
249
|
+
};
|
|
250
|
+
if (flags.json) return writeJson(result);
|
|
251
|
+
print(CURRENT_VERSION);
|
|
252
|
+
}
|
|
253
|
+
|
|
236
254
|
async function update(args) {
|
|
237
255
|
const requestedSubcommand = args[0] && !args[0].startsWith('--') ? args[0] : 'check';
|
|
238
256
|
const parsedArgs = requestedSubcommand === args[0] ? args.slice(1) : args;
|
|
@@ -435,7 +453,8 @@ async function design(args) {
|
|
|
435
453
|
const { flags, positional } = parseArgs(rest);
|
|
436
454
|
const topic = flags.topic || positional[0];
|
|
437
455
|
if (wantsSubcommandHelp(subcommand, flags)) {
|
|
438
|
-
|
|
456
|
+
if (flags.json) return writeJson(getDesignTopicCatalog());
|
|
457
|
+
print(renderDesignHelp());
|
|
439
458
|
return;
|
|
440
459
|
}
|
|
441
460
|
|
|
@@ -466,7 +485,7 @@ async function doctor(args) {
|
|
|
466
485
|
return;
|
|
467
486
|
}
|
|
468
487
|
const config = loadConfig();
|
|
469
|
-
const profileName = flags
|
|
488
|
+
const profileName = resolveDoctorProfileName(config, flags);
|
|
470
489
|
const result = {
|
|
471
490
|
cli: {
|
|
472
491
|
version: CURRENT_VERSION,
|
|
@@ -561,6 +580,24 @@ async function doctor(args) {
|
|
|
561
580
|
printDoctorReport(result);
|
|
562
581
|
}
|
|
563
582
|
|
|
583
|
+
function resolveDoctorProfileName(config, flags) {
|
|
584
|
+
if (flags.profile) return flags.profile;
|
|
585
|
+
const state = loadProjectState();
|
|
586
|
+
const boundEntries = Object.entries(state.profiles || {}).filter(([, bound]) => bound?.appType);
|
|
587
|
+
const requestedAppType = flags['app-type'];
|
|
588
|
+
if (requestedAppType) {
|
|
589
|
+
const matched = boundEntries.find(([, bound]) => bound.appType === requestedAppType);
|
|
590
|
+
if (matched) return matched[0];
|
|
591
|
+
}
|
|
592
|
+
if (config.currentProfile && state.profiles?.[config.currentProfile]?.appType) {
|
|
593
|
+
return config.currentProfile;
|
|
594
|
+
}
|
|
595
|
+
if (boundEntries.length === 1) {
|
|
596
|
+
return boundEntries[0][0];
|
|
597
|
+
}
|
|
598
|
+
return config.currentProfile;
|
|
599
|
+
}
|
|
600
|
+
|
|
564
601
|
function printDoctorReport(result) {
|
|
565
602
|
const lines = [
|
|
566
603
|
`OpenXiangda doctor v${result.cli.version}`,
|
|
@@ -3998,7 +4035,9 @@ async function commands(args) {
|
|
|
3998
4035
|
const { flags } = parseArgs(args);
|
|
3999
4036
|
const manifest = {
|
|
4000
4037
|
name: 'openxiangda',
|
|
4038
|
+
version: CURRENT_VERSION,
|
|
4001
4039
|
commands: [
|
|
4040
|
+
'version [--json]',
|
|
4002
4041
|
'login <platform-url> [--profile name]',
|
|
4003
4042
|
'update check|install',
|
|
4004
4043
|
'platform add|list|use|remove',
|
|
@@ -4025,10 +4064,19 @@ async function commands(args) {
|
|
|
4025
4064
|
'permission form-group-list|form-group-create|form-group-update|form-group-delete|form-group-bind|form-summary|menu-permissions',
|
|
4026
4065
|
'settings get|save|indexes|indexes-save|data-management|data-management-save|public-access|public-access-save|public-access-delete',
|
|
4027
4066
|
'resource validate|plan|publish|pull|typegen|explain',
|
|
4067
|
+
'runtime deploy|releases|activate',
|
|
4028
4068
|
'inspect app|form|workflow|automation|permissions',
|
|
4029
4069
|
'feedback preview|submit',
|
|
4030
4070
|
'skill install|status|bootstrap',
|
|
4031
4071
|
],
|
|
4072
|
+
designTopics: getDesignTopicCatalog(),
|
|
4073
|
+
resourceNotes: [
|
|
4074
|
+
'For formal multi-resource development, prefer src/resources/** + openxiangda resource validate|plan|publish.',
|
|
4075
|
+
'Use first-class route/public-access/auth-config/function/connector/notification/data-view/menu/permission commands for discovery, diagnosis, dry-run, and small live fixes.',
|
|
4076
|
+
'public-access is the new React SPA public policy resource for /view/:appType/public/* routes.',
|
|
4077
|
+
'settings public-access is legacy form public-access compatibility/repair and should not be used for new React SPA apps.',
|
|
4078
|
+
'Direct live mutation commands should use --dry-run first and --write-manifest when the repository should remain source of truth.',
|
|
4079
|
+
],
|
|
4032
4080
|
};
|
|
4033
4081
|
if (flags.json) return writeJson(manifest);
|
|
4034
4082
|
print(JSON.stringify(manifest, null, 2));
|
|
@@ -5047,6 +5095,9 @@ function validateWorkspaceResources(manifest) {
|
|
|
5047
5095
|
const errors = [];
|
|
5048
5096
|
const warnings = [];
|
|
5049
5097
|
const counts = {};
|
|
5098
|
+
if (!fs.existsSync(manifest.baseDir)) {
|
|
5099
|
+
warnings.push('未发现 src/resources;多资源正式开发请在该目录声明资源,或使用一等 CLI 子命令进行只读诊断/小步维护');
|
|
5100
|
+
}
|
|
5050
5101
|
for (const spec of RESOURCE_SPECS) {
|
|
5051
5102
|
const items = manifest[spec.key] || [];
|
|
5052
5103
|
counts[spec.key] = items.length;
|
package/lib/design-gates.js
CHANGED
|
@@ -219,19 +219,112 @@ const DESIGN_GATE_TOPICS = [
|
|
|
219
219
|
},
|
|
220
220
|
];
|
|
221
221
|
|
|
222
|
+
const DESIGN_GATE_TOPIC_ALIASES = {
|
|
223
|
+
app: 'new-app',
|
|
224
|
+
application: 'new-app',
|
|
225
|
+
dashboard: 'complex-page',
|
|
226
|
+
page: 'complex-page',
|
|
227
|
+
pages: 'complex-page',
|
|
228
|
+
login: 'auth',
|
|
229
|
+
register: 'auth',
|
|
230
|
+
registration: 'auth',
|
|
231
|
+
sso: 'auth',
|
|
232
|
+
public: 'public-access',
|
|
233
|
+
guest: 'public-access',
|
|
234
|
+
visitor: 'public-access',
|
|
235
|
+
visitors: 'public-access',
|
|
236
|
+
permission: 'permissions',
|
|
237
|
+
role: 'permissions',
|
|
238
|
+
roles: 'permissions',
|
|
239
|
+
workflow: 'workflow-automation',
|
|
240
|
+
automation: 'workflow-automation',
|
|
241
|
+
function: 'workflow-automation',
|
|
242
|
+
functions: 'workflow-automation',
|
|
243
|
+
'app-function': 'workflow-automation',
|
|
244
|
+
js_code: 'workflow-automation',
|
|
245
|
+
jscode: 'workflow-automation',
|
|
246
|
+
connector: 'connector-notification',
|
|
247
|
+
connectors: 'connector-notification',
|
|
248
|
+
notification: 'connector-notification',
|
|
249
|
+
notifications: 'connector-notification',
|
|
250
|
+
integration: 'connector-notification',
|
|
251
|
+
integrations: 'connector-notification',
|
|
252
|
+
webhook: 'connector-notification',
|
|
253
|
+
resource: 'resource-maintenance',
|
|
254
|
+
resources: 'resource-maintenance',
|
|
255
|
+
maintenance: 'resource-maintenance',
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
function resolveTopicSelection(topicCode) {
|
|
259
|
+
if (!topicCode || topicCode === 'all') {
|
|
260
|
+
return { requested: ['all'], wanted: null, unknown: [] };
|
|
261
|
+
}
|
|
262
|
+
const knownCodes = new Set(DESIGN_GATE_TOPICS.map(topic => topic.code));
|
|
263
|
+
const requested = String(topicCode)
|
|
264
|
+
.split(/[,/|+\s]+/)
|
|
265
|
+
.map(item => item.trim())
|
|
266
|
+
.filter(Boolean);
|
|
267
|
+
const wanted = new Set();
|
|
268
|
+
const unknown = [];
|
|
269
|
+
for (const item of requested) {
|
|
270
|
+
const normalized = item.toLowerCase();
|
|
271
|
+
const code = DESIGN_GATE_TOPIC_ALIASES[normalized] || normalized;
|
|
272
|
+
if (knownCodes.has(code)) {
|
|
273
|
+
wanted.add(code);
|
|
274
|
+
} else {
|
|
275
|
+
unknown.push(item);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return { requested, wanted, unknown };
|
|
279
|
+
}
|
|
280
|
+
|
|
222
281
|
function selectTopics(topicCode) {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
return DESIGN_GATE_TOPICS.filter(topic => wanted.has(topic.code));
|
|
282
|
+
const selection = resolveTopicSelection(topicCode);
|
|
283
|
+
if (!selection.wanted) return DESIGN_GATE_TOPICS;
|
|
284
|
+
return DESIGN_GATE_TOPICS.filter(topic => selection.wanted.has(topic.code));
|
|
226
285
|
}
|
|
227
286
|
|
|
228
287
|
function getDesignGates(topicCode) {
|
|
288
|
+
const selection = resolveTopicSelection(topicCode);
|
|
229
289
|
return {
|
|
230
290
|
hardRule: DESIGN_GATE_HARD_RULE,
|
|
291
|
+
requestedTopics: selection.requested,
|
|
292
|
+
unknownTopics: selection.unknown,
|
|
231
293
|
topics: selectTopics(topicCode),
|
|
232
294
|
};
|
|
233
295
|
}
|
|
234
296
|
|
|
297
|
+
function getDesignTopicCatalog() {
|
|
298
|
+
return {
|
|
299
|
+
hardRule: DESIGN_GATE_HARD_RULE,
|
|
300
|
+
topics: DESIGN_GATE_TOPICS.map(topic => ({
|
|
301
|
+
code: topic.code,
|
|
302
|
+
title: topic.title,
|
|
303
|
+
triggers: topic.triggers,
|
|
304
|
+
})),
|
|
305
|
+
aliases: DESIGN_GATE_TOPIC_ALIASES,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function renderDesignHelp() {
|
|
310
|
+
const catalog = getDesignTopicCatalog();
|
|
311
|
+
const lines = [
|
|
312
|
+
'用法: openxiangda design gates|template [--topic code[,code...]] [--json]',
|
|
313
|
+
'',
|
|
314
|
+
catalog.hardRule,
|
|
315
|
+
'',
|
|
316
|
+
'Topics:',
|
|
317
|
+
];
|
|
318
|
+
for (const topic of catalog.topics) {
|
|
319
|
+
lines.push(`- ${topic.code}: ${topic.title} (${topic.triggers.join('、')})`);
|
|
320
|
+
}
|
|
321
|
+
lines.push('', 'Aliases:');
|
|
322
|
+
for (const [alias, code] of Object.entries(catalog.aliases).sort()) {
|
|
323
|
+
lines.push(`- ${alias} -> ${code}`);
|
|
324
|
+
}
|
|
325
|
+
return lines.join('\n');
|
|
326
|
+
}
|
|
327
|
+
|
|
235
328
|
function renderDesignGatesText(topicCode) {
|
|
236
329
|
const gates = getDesignGates(topicCode);
|
|
237
330
|
const lines = [gates.hardRule, ''];
|
|
@@ -441,8 +534,11 @@ function renderResourceExplain(type) {
|
|
|
441
534
|
module.exports = {
|
|
442
535
|
DESIGN_GATE_HARD_RULE,
|
|
443
536
|
DESIGN_GATE_TOPICS,
|
|
537
|
+
DESIGN_GATE_TOPIC_ALIASES,
|
|
444
538
|
getDesignGates,
|
|
539
|
+
getDesignTopicCatalog,
|
|
445
540
|
getResourceExplain,
|
|
541
|
+
renderDesignHelp,
|
|
446
542
|
renderDesignGatesText,
|
|
447
543
|
renderDesignTemplate,
|
|
448
544
|
renderResourceExplain,
|