lan-low-code-cli 2.5.0 → 2.7.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.
- package/README.md +183 -0
- package/dist/api/flow.js +119 -0
- package/dist/api/formDefine.js +31 -1
- package/dist/api/operation.js +27 -0
- package/dist/api/template.js +76 -0
- package/dist/api/view.js +23 -0
- package/dist/commands/flow.js +755 -0
- package/dist/commands/form.js +181 -1
- package/dist/commands/operation.js +730 -0
- package/dist/commands/template.js +541 -0
- package/dist/generator/flow/compiler.js +397 -0
- package/dist/generator/flow/index.js +22 -0
- package/dist/generator/flow/layout.js +136 -0
- package/dist/generator/flow/schema-resolver.js +133 -0
- package/dist/generator/flow/schema.js +96 -0
- package/dist/generator/flow/types.js +10 -0
- package/dist/generator/flow/validate.js +129 -0
- package/dist/index.js +20 -1
- package/package.json +49 -49
- package/skills/lan-low-code-cli/SKILL.md +20 -5
- package/skills/lan-low-code-cli/SKILL.zh-CN.md +19 -4
- package/skills/lan-low-code-cli/references/cli-contract.md +167 -8
- package/skills/lan-low-code-cli/references/cli-contract.zh-CN.md +162 -7
- package/skills/lan-low-code-cli/references/mkxform-api.md +2652 -2652
- package/skills/lan-low-code-cli/references/operation-script-context.md +220 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 动作流节点元数据表
|
|
4
|
+
*
|
|
5
|
+
* 逐 case 翻译 `action-flow-ide/enter.tsx:217-336` 的 generateNodeData:
|
|
6
|
+
* IDE 保存时只挑每种 nodeType 的专属字段,其余字段丢弃。
|
|
7
|
+
* 必填规则来自 `configuration/nodes/utils.tsx:37-288` 与 `validate.ts:13-17`。
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.CONTEXT_KEYS = exports.FLOW_CODE_PATTERN = exports.NODE_ID_PATTERN = exports.KNOWN_START_WAYS = exports.MULTI_OUT_NODE_TYPES = exports.NODE_REQUIRED = exports.NODE_DEFAULTS = exports.NODE_FIELD_WHITELIST = void 0;
|
|
11
|
+
/** 节点专属字段白名单;未列出的 nodeType 视为未知类型(透传 config 并告警) */
|
|
12
|
+
exports.NODE_FIELD_WHITELIST = {
|
|
13
|
+
StartNode: ['startNodeDef'],
|
|
14
|
+
EndNode: ['outParamType', 'outParam', 'outputParamMapping'],
|
|
15
|
+
BranchNode: ['conditionType', 'flowWay', 'defaultTargetRef', 'ruleConfig', 'formulaConfig'],
|
|
16
|
+
LoopNode: ['loopDefine', 'subProcess'],
|
|
17
|
+
QueryLoopNode: [
|
|
18
|
+
'target', 'conditions', 'sortType', 'containsDeleted', 'executeTime',
|
|
19
|
+
'loopDefine', 'context_outputParam', 'limitTime',
|
|
20
|
+
],
|
|
21
|
+
FilterDataNode: ['bindNode', 'formula'],
|
|
22
|
+
MessageNode: [
|
|
23
|
+
'bindNode', 'subject', 'notifyType', 'todoType', 'messageTarget', 'messageLink',
|
|
24
|
+
'eventCode', 'codeValue', 'notifyCategoryCode', 'subjectType', 'templateCode',
|
|
25
|
+
'templateFields', 'grantPermission',
|
|
26
|
+
],
|
|
27
|
+
AddDataNode: ['bindNode', 'dataSourceVO', 'flow', 'commitType', 'fields', 'autoMatchField', 'fastExecute'],
|
|
28
|
+
DeleteDataNode: ['bindNode'],
|
|
29
|
+
QueryDataNode: ['target', 'conditions', 'sorts', 'resultType', 'maxSize', 'containsDeleted'],
|
|
30
|
+
UpdateDataNode: ['bindNode', 'fields', 'fastExecute'],
|
|
31
|
+
CreateKmReviewNode: ['bindNode', 'kmReviewTemplate', 'fdCreator', 'fdSubject', 'commitType', 'fields'],
|
|
32
|
+
AddOrUpdateNode: [
|
|
33
|
+
'bindNode', 'dataSourceVO', 'flow', 'commitType', 'fields', 'condition',
|
|
34
|
+
'autoMatchField', 'fastExecute',
|
|
35
|
+
],
|
|
36
|
+
AssignValueNode: ['assignValueRuleConfigs'],
|
|
37
|
+
TransformNode: ['outParamType', 'outParam', 'outputParamMapping'],
|
|
38
|
+
ExecuteNode: ['outParamType', 'executeCode', 'inputParamMapping'],
|
|
39
|
+
FlowBotsNode: ['outParamType', 'flowBotsCode', 'inputParamMapping'],
|
|
40
|
+
InterfaceNode: ['apiType', 'apiMethodPath', 'inputParamMapping'],
|
|
41
|
+
SubActionNode: ['outParam', 'outParamType', 'actionFlowCode', 'inputParamMapping'],
|
|
42
|
+
MessageEliminateNode: ['eliminateRange', 'eliminateType', 'eventCode', 'bindNode'],
|
|
43
|
+
QueryStatisticsNode: [
|
|
44
|
+
'nativeNodeType', 'resultType', 'target', 'conditions', 'sorts',
|
|
45
|
+
'columns', 'statisticsDimensions', 'statisticsItems',
|
|
46
|
+
],
|
|
47
|
+
DispatchNode: [],
|
|
48
|
+
};
|
|
49
|
+
/** 与 IDE 一致的缺省值(styleSheet.ts:404-445) */
|
|
50
|
+
exports.NODE_DEFAULTS = {
|
|
51
|
+
BranchNode: { conditionType: 'formula', flowWay: 'singleBranch' },
|
|
52
|
+
QueryDataNode: { resultType: 'single' },
|
|
53
|
+
LoopNode: { loopDefine: { type: 'LoopArray' } },
|
|
54
|
+
MessageNode: { grantPermission: true },
|
|
55
|
+
};
|
|
56
|
+
/** 发布前 IDE 强校验的必填字段(configuration/nodes/utils.tsx:37-288) */
|
|
57
|
+
exports.NODE_REQUIRED = {
|
|
58
|
+
AddDataNode: ['dataSourceVO', 'flow', 'fields'],
|
|
59
|
+
QueryDataNode: ['target'],
|
|
60
|
+
UpdateDataNode: ['bindNode'],
|
|
61
|
+
DeleteDataNode: ['bindNode'],
|
|
62
|
+
FilterDataNode: ['bindNode'],
|
|
63
|
+
BranchNode: ['conditionType', 'flowWay'],
|
|
64
|
+
SubActionNode: ['actionFlowCode'],
|
|
65
|
+
InterfaceNode: ['apiType', 'apiMethodPath'],
|
|
66
|
+
ExecuteNode: ['executeCode'],
|
|
67
|
+
QueryStatisticsNode: ['target'],
|
|
68
|
+
AddOrUpdateNode: ['dataSourceVO', 'flow', 'fields'],
|
|
69
|
+
LoopNode: ['loopDefine'],
|
|
70
|
+
AssignValueNode: ['assignValueRuleConfigs'],
|
|
71
|
+
CreateKmReviewNode: ['kmReviewTemplate', 'fdSubject'],
|
|
72
|
+
FlowBotsNode: ['flowBotsCode'],
|
|
73
|
+
MessageNode: ['subject', 'messageTarget'],
|
|
74
|
+
MessageEliminateNode: ['eliminateRange', 'eliminateType'],
|
|
75
|
+
};
|
|
76
|
+
/** 允许多条出边的节点(validateCommonVertex 的 getwayMap,另有 StartNode) */
|
|
77
|
+
exports.MULTI_OUT_NODE_TYPES = new Set(['BranchNode', 'parallelGateway', 'StartNode']);
|
|
78
|
+
exports.KNOWN_START_WAYS = [
|
|
79
|
+
'StartScheduledNode',
|
|
80
|
+
'StartDataNode',
|
|
81
|
+
'StartEventNode',
|
|
82
|
+
'StartActiveNode',
|
|
83
|
+
];
|
|
84
|
+
/** 节点编码 /^[0-9a-zA-Z_]{2,32}$/(configuration/nodes/utils.tsx:12-30) */
|
|
85
|
+
exports.NODE_ID_PATTERN = /^[0-9a-zA-Z_]{2,32}$/;
|
|
86
|
+
/** 动作流编码 /^[a-zA-Z0-9_]{1,30}$/(topbar/index.tsx:262-279) */
|
|
87
|
+
exports.FLOW_CODE_PATTERN = /^[a-zA-Z0-9_]{1,30}$/;
|
|
88
|
+
/** extraAttr 六个上下文键(enter.tsx:383-390) */
|
|
89
|
+
exports.CONTEXT_KEYS = [
|
|
90
|
+
'context_bindFormId',
|
|
91
|
+
'context_bindNode',
|
|
92
|
+
'context_nodeParam',
|
|
93
|
+
'context_isMulti',
|
|
94
|
+
'context_fdInParam',
|
|
95
|
+
'context_outputParam',
|
|
96
|
+
];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 动作流编译内核 · 类型定义
|
|
4
|
+
*
|
|
5
|
+
* 依据 `sys-modeling/src/components/action-flow-ide/enter.tsx:339-428`:
|
|
6
|
+
* `fdDesign` 是 JSON 字符串,顶层 `{ nodes, lines, processVar? }`;
|
|
7
|
+
* 节点为扁平结构:`drawAttr.bounds` + `extraAttr.context_*` + 各 nodeType 专属字段。
|
|
8
|
+
* IDE 回显时原样使用 x/y,不重算坐标,因此坐标必须由本内核生成。
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 动作流离线校验器
|
|
4
|
+
*
|
|
5
|
+
* 移植 IDE 发布前的 validate(true):连线数量、必填、编码格式、无环
|
|
6
|
+
* (enter.tsx:468-529、validate.ts:150-327、mxgraph/utils.tsx:1206-1258)。
|
|
7
|
+
* 目的是在发包之前把错误挡住——CLI 直接调 addPublish 会绕过 IDE 校验。
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.validateSpec = validateSpec;
|
|
11
|
+
exports.validateGraph = validateGraph;
|
|
12
|
+
exports.hasErrors = hasErrors;
|
|
13
|
+
const schema_1 = require("./schema");
|
|
14
|
+
const err = (code, message, nodeId) => ({
|
|
15
|
+
level: 'error', code, message, nodeId,
|
|
16
|
+
});
|
|
17
|
+
const warn = (code, message, nodeId) => ({
|
|
18
|
+
level: 'warn', code, message, nodeId,
|
|
19
|
+
});
|
|
20
|
+
/** 基础信息校验 */
|
|
21
|
+
function validateSpec(spec) {
|
|
22
|
+
const out = [];
|
|
23
|
+
if (!spec.name || !String(spec.name).trim())
|
|
24
|
+
out.push(err('SPEC_NAME_REQUIRED', '缺少流程名称 name'));
|
|
25
|
+
if (!spec.code || !schema_1.FLOW_CODE_PATTERN.test(spec.code)) {
|
|
26
|
+
out.push(err('SPEC_CODE_INVALID', `流程编码 code 必须匹配 /^[a-zA-Z0-9_]{1,30}$/:${spec.code ?? '(空)'}`));
|
|
27
|
+
}
|
|
28
|
+
const startWay = spec.startWay ?? 'StartActiveNode';
|
|
29
|
+
if (!schema_1.KNOWN_START_WAYS.includes(startWay)) {
|
|
30
|
+
out.push(err('SPEC_START_WAY_INVALID', `未知启动方式:${startWay}`));
|
|
31
|
+
}
|
|
32
|
+
if (!Array.isArray(spec.nodes))
|
|
33
|
+
out.push(err('SPEC_NODES_REQUIRED', '缺少 nodes 数组'));
|
|
34
|
+
if (!Array.isArray(spec.edges))
|
|
35
|
+
out.push(err('SPEC_EDGES_REQUIRED', '缺少 edges 数组'));
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
/** 开始节点按启动方式的必填项(configuration/nodes/utils.tsx:40-61、validate.ts:13-17) */
|
|
39
|
+
function validateStartNode(graph, spec, startWay) {
|
|
40
|
+
const out = [];
|
|
41
|
+
const start = graph.nodes.find((n) => n._isStart);
|
|
42
|
+
if (!start)
|
|
43
|
+
return out;
|
|
44
|
+
const provided = start.config?.startNodeDef;
|
|
45
|
+
const def = provided ?? spec.trigger ?? {};
|
|
46
|
+
const has = (k) => def[k] !== undefined && def[k] !== null && def[k] !== '';
|
|
47
|
+
if (startWay === 'StartScheduledNode' && !has('scheduledDef')) {
|
|
48
|
+
out.push(err('START_SCHEDULE_REQUIRED', '定时触发必须在 trigger 中提供 scheduledDef', start.id));
|
|
49
|
+
}
|
|
50
|
+
if (startWay === 'StartDataNode' && !has('target')) {
|
|
51
|
+
out.push(err('START_DATA_TARGET_REQUIRED', '数据监听必须在 trigger 中提供 target(触发表单)', start.id));
|
|
52
|
+
}
|
|
53
|
+
if (startWay === 'StartEventNode' && !has('eventCode')) {
|
|
54
|
+
out.push(err('START_EVENT_REQUIRED', '事件监听必须在 trigger 中提供 eventCode', start.id));
|
|
55
|
+
}
|
|
56
|
+
if (startWay === 'StartActiveNode') {
|
|
57
|
+
const runTypes = def.fdRunType;
|
|
58
|
+
const byFlags = def.operateTrigger === true || def.bpmTrigger === true || def.apiTrigger === true;
|
|
59
|
+
const byList = Array.isArray(runTypes) && runTypes.length > 0;
|
|
60
|
+
if (!byFlags && !byList) {
|
|
61
|
+
out.push(err('START_ACTIVE_TRIGGER_REQUIRED', '主动触发必须提供 trigger.fdRunType(operate / bpm / api 至少一项)或对应布尔开关', start.id));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
/** 图结构 + 节点必填校验 */
|
|
67
|
+
function validateGraph(graph, spec, startWay = 'StartActiveNode') {
|
|
68
|
+
const out = [];
|
|
69
|
+
const ids = new Set();
|
|
70
|
+
const byId = new Map(graph.nodes.map((n) => [n.id, n]));
|
|
71
|
+
for (const node of graph.nodes) {
|
|
72
|
+
if (!schema_1.NODE_ID_PATTERN.test(node.id)) {
|
|
73
|
+
out.push(err('NODE_ID_INVALID', `节点 id 必须匹配 /^[0-9a-zA-Z_]{2,32}$/:${node.id}`, node.id));
|
|
74
|
+
}
|
|
75
|
+
if (ids.has(node.id))
|
|
76
|
+
out.push(err('NODE_ID_DUPLICATE', `节点 id 重复:${node.id}`, node.id));
|
|
77
|
+
ids.add(node.id);
|
|
78
|
+
if (!schema_1.NODE_FIELD_WHITELIST[node.type]) {
|
|
79
|
+
out.push(warn('NODE_TYPE_UNKNOWN', `未知节点类型 ${node.type},config 将原样透传;请用 llc flow templates list 核对环境支持的节点`, node.id));
|
|
80
|
+
}
|
|
81
|
+
// 与编译器一致:默认值(如 BranchNode.conditionType / flowWay)也算已填
|
|
82
|
+
const config = { ...(schema_1.NODE_DEFAULTS[node.type] ?? {}), ...(node.config ?? {}) };
|
|
83
|
+
for (const field of schema_1.NODE_REQUIRED[node.type] ?? []) {
|
|
84
|
+
if (config[field] === undefined || config[field] === null || config[field] === '') {
|
|
85
|
+
out.push(err('NODE_FIELD_REQUIRED', `节点 ${node.id}(${node.type})缺少必填字段 ${field}`, node.id));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const inCount = new Map();
|
|
90
|
+
const outCount = new Map();
|
|
91
|
+
const seenEdge = new Set();
|
|
92
|
+
for (const edge of graph.edges) {
|
|
93
|
+
const key = `${edge.from}->${edge.to}`;
|
|
94
|
+
if (seenEdge.has(key)) {
|
|
95
|
+
out.push(err('EDGE_DUPLICATE', `重复连线:${key}(IDE 设置 setMultigraph(false))`));
|
|
96
|
+
}
|
|
97
|
+
seenEdge.add(key);
|
|
98
|
+
if (!byId.has(edge.from))
|
|
99
|
+
out.push(err('EDGE_SOURCE_MISSING', `连线起点不存在:${edge.from}`));
|
|
100
|
+
if (!byId.has(edge.to))
|
|
101
|
+
out.push(err('EDGE_TARGET_MISSING', `连线终点不存在:${edge.to}`));
|
|
102
|
+
if (edge.from === edge.to)
|
|
103
|
+
out.push(err('EDGE_SELF_LOOP', `禁止自连:${edge.from}`));
|
|
104
|
+
inCount.set(edge.to, (inCount.get(edge.to) ?? 0) + 1);
|
|
105
|
+
outCount.set(edge.from, (outCount.get(edge.from) ?? 0) + 1);
|
|
106
|
+
}
|
|
107
|
+
for (const node of graph.nodes) {
|
|
108
|
+
const incoming = inCount.get(node.id) ?? 0;
|
|
109
|
+
const outgoing = outCount.get(node.id) ?? 0;
|
|
110
|
+
if (node._isStart && incoming > 0)
|
|
111
|
+
out.push(err('START_HAS_IN_EDGE', '开始节点不能有入边', node.id));
|
|
112
|
+
if (node._isEnd && outgoing > 0)
|
|
113
|
+
out.push(err('END_HAS_OUT_EDGE', '结束节点不能有出边', node.id));
|
|
114
|
+
if (!node._isEnd && outgoing === 0) {
|
|
115
|
+
out.push(err('NODE_NO_OUT_EDGE', `节点 ${node.id} 没有出边`, node.id));
|
|
116
|
+
}
|
|
117
|
+
if (!node._isStart && incoming === 0) {
|
|
118
|
+
out.push(err('NODE_NO_IN_EDGE', `节点 ${node.id} 没有入边`, node.id));
|
|
119
|
+
}
|
|
120
|
+
if (outgoing > 1 && !schema_1.MULTI_OUT_NODE_TYPES.has(node.type)) {
|
|
121
|
+
out.push(err('NODE_MULTI_OUT_EDGE', `节点 ${node.id}(${node.type})有 ${outgoing} 条出边;仅 BranchNode / StartNode / parallelGateway 允许多出边`, node.id));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
out.push(...validateStartNode(graph, spec, startWay));
|
|
125
|
+
return out;
|
|
126
|
+
}
|
|
127
|
+
function hasErrors(diagnostics) {
|
|
128
|
+
return diagnostics.some((d) => d.level === 'error');
|
|
129
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -6,10 +6,13 @@ const app_1 = require("./commands/app");
|
|
|
6
6
|
const config_1 = require("./commands/config");
|
|
7
7
|
const control_1 = require("./commands/control");
|
|
8
8
|
const field_1 = require("./commands/field");
|
|
9
|
+
const flow_1 = require("./commands/flow");
|
|
9
10
|
const form_1 = require("./commands/form");
|
|
10
11
|
const locale_1 = require("./commands/locale");
|
|
12
|
+
const operation_1 = require("./commands/operation");
|
|
13
|
+
const template_1 = require("./commands/template");
|
|
11
14
|
const logger_1 = require("./utils/logger");
|
|
12
|
-
const VERSION = '2.
|
|
15
|
+
const VERSION = '2.7.0';
|
|
13
16
|
const program = new commander_1.Command();
|
|
14
17
|
exports.program = program;
|
|
15
18
|
program
|
|
@@ -34,6 +37,9 @@ program.hook('preAction', (thisCommand, actionCommand) => {
|
|
|
34
37
|
(0, app_1.registerAppCommand)(program);
|
|
35
38
|
(0, form_1.registerFormCommand)(program);
|
|
36
39
|
(0, field_1.registerFieldCommand)(program);
|
|
40
|
+
(0, operation_1.registerOperationCommand)(program);
|
|
41
|
+
(0, template_1.registerTemplateCommand)(program);
|
|
42
|
+
(0, flow_1.registerFlowCommand)(program);
|
|
37
43
|
(0, locale_1.registerLocaleCommand)(program);
|
|
38
44
|
(0, control_1.registerControlCommand)(program);
|
|
39
45
|
/**
|
|
@@ -106,6 +112,19 @@ ${logger_1.color.bold('常用查询')}
|
|
|
106
112
|
llc control list 环境可用控件(含高级控件;明细/分页为容器类)
|
|
107
113
|
llc locale list 环境提供了哪些语言译文
|
|
108
114
|
llc field library [--keyword 关键词] 字段库
|
|
115
|
+
llc operation list --form-id <fdId> 表单的业务操作(列表页/查看页按钮)
|
|
116
|
+
llc operation create --form-id <fdId> --name 打开帮助 --code openHelp --type link --url https://example.com
|
|
117
|
+
llc operation delete --id <operationId> --yes 删除业务操作(被引用时会拒绝)
|
|
118
|
+
llc operation attach --form-id <fdId> --operation-id <opId> 挂到列表视图(--target view 挂查看视图)
|
|
119
|
+
llc flow list --app-code <appCode> 应用下的动作流(只读)
|
|
120
|
+
llc flow get --id <flowId> --with-design 查看动作流并解析 fdDesign
|
|
121
|
+
llc flow spec --out flow.json 生成 Flow Spec 模板
|
|
122
|
+
llc flow validate --spec @flow.json 离线校验(图结构 / 必填 / 布局)
|
|
123
|
+
llc flow compile --spec @flow.json --json 编译出含编排布局的 fdDesign
|
|
124
|
+
llc flow apply --spec @flow.json --app-code <code> 预览提交体(追加 --yes 才写入)
|
|
125
|
+
llc flow diff --id <flowId> --spec @flow.json 对比本地与远端设计(忽略坐标)
|
|
126
|
+
llc flow script --id <flowId> 生成 flow_{fdCode} 按钮脚本
|
|
127
|
+
llc flow enable/disable/delete --id <flowId> 生命周期管理
|
|
109
128
|
|
|
110
129
|
${logger_1.color.gray('高级控件(desc / tags / mdm / association / mechnumber …)与普通控件同样写法:')}
|
|
111
130
|
llc form autofill --id <fdId> --apply --add-field "字段名:标题:控件类型"
|
package/package.json
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "lan-low-code-cli",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "lan-low-code cli:低代码表单引擎命令行工具(创建表单、获取可用字段、自动完善表单字段)",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"low-code",
|
|
7
|
-
"lan-low-code",
|
|
8
|
-
"llc",
|
|
9
|
-
"form",
|
|
10
|
-
"cli"
|
|
11
|
-
],
|
|
12
|
-
"license": "MIT",
|
|
13
|
-
"packageManager": "pnpm@10.26.2",
|
|
14
|
-
"bin": {
|
|
15
|
-
"llc": "bin/llc.js"
|
|
16
|
-
},
|
|
17
|
-
"main": "dist/index.js",
|
|
18
|
-
"scripts": {
|
|
19
|
-
"build": "tsc -p tsconfig.json",
|
|
20
|
-
"clean": "rimraf dist",
|
|
21
|
-
"rebuild": "pnpm run clean && pnpm run build",
|
|
22
|
-
"start": "pnpm run build && node bin/llc.js",
|
|
23
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
24
|
-
"prepare": "pnpm run build",
|
|
25
|
-
"bump": "node scripts/bump-version.js",
|
|
26
|
-
"bump:check": "node scripts/bump-version.js --check",
|
|
27
|
-
"pack": "node scripts/pack.js",
|
|
28
|
-
"pack:cli": "node scripts/pack.js --target cli",
|
|
29
|
-
"pack:skill": "node scripts/pack.js --target skill"
|
|
30
|
-
},
|
|
31
|
-
"dependencies": {
|
|
32
|
-
"commander": "^11.1.0"
|
|
33
|
-
},
|
|
34
|
-
"devDependencies": {
|
|
35
|
-
"@types/node": "^20.11.30",
|
|
36
|
-
"rimraf": "^5.0.5",
|
|
37
|
-
"typescript": "^5.4.5"
|
|
38
|
-
},
|
|
39
|
-
"engines": {
|
|
40
|
-
"node": ">=18",
|
|
41
|
-
"pnpm": ">=8"
|
|
42
|
-
},
|
|
43
|
-
"files": [
|
|
44
|
-
"bin",
|
|
45
|
-
"dist",
|
|
46
|
-
"skills",
|
|
47
|
-
"README.md"
|
|
48
|
-
]
|
|
49
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "lan-low-code-cli",
|
|
3
|
+
"version": "2.7.0",
|
|
4
|
+
"description": "lan-low-code cli:低代码表单引擎命令行工具(创建表单、获取可用字段、自动完善表单字段)",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"low-code",
|
|
7
|
+
"lan-low-code",
|
|
8
|
+
"llc",
|
|
9
|
+
"form",
|
|
10
|
+
"cli"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"packageManager": "pnpm@10.26.2",
|
|
14
|
+
"bin": {
|
|
15
|
+
"llc": "bin/llc.js"
|
|
16
|
+
},
|
|
17
|
+
"main": "dist/index.js",
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc -p tsconfig.json",
|
|
20
|
+
"clean": "rimraf dist",
|
|
21
|
+
"rebuild": "pnpm run clean && pnpm run build",
|
|
22
|
+
"start": "pnpm run build && node bin/llc.js",
|
|
23
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
24
|
+
"prepare": "pnpm run build",
|
|
25
|
+
"bump": "node scripts/bump-version.js",
|
|
26
|
+
"bump:check": "node scripts/bump-version.js --check",
|
|
27
|
+
"pack": "node scripts/pack.js",
|
|
28
|
+
"pack:cli": "node scripts/pack.js --target cli",
|
|
29
|
+
"pack:skill": "node scripts/pack.js --target skill"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"commander": "^11.1.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^20.11.30",
|
|
36
|
+
"rimraf": "^5.0.5",
|
|
37
|
+
"typescript": "^5.4.5"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18",
|
|
41
|
+
"pnpm": ">=8"
|
|
42
|
+
},
|
|
43
|
+
"files": [
|
|
44
|
+
"bin",
|
|
45
|
+
"dist",
|
|
46
|
+
"skills",
|
|
47
|
+
"README.md"
|
|
48
|
+
]
|
|
49
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lan-low-code-cli
|
|
3
|
-
version: 2.
|
|
3
|
+
version: 2.7.0
|
|
4
4
|
author: Pig George
|
|
5
5
|
description: Operate the Landray low-code form engine through the `llc` CLI. Use when the user asks to create, inspect, modify, publish, or delete low-code apps and forms; generate field configs; configure layouts (grid/tabs), field permissions, options, i18n, or control actions (onChange/onLoad); or run pre-publish validation. Also use for troubleshooting form loading/rendering errors.
|
|
6
6
|
tags:
|
|
@@ -41,11 +41,11 @@ Verify: `llc -v` should print the version.
|
|
|
41
41
|
### Version check before upgrading
|
|
42
42
|
|
|
43
43
|
Before upgrading (and whenever `llc -v` does not match this skill), compare the **major** version of the
|
|
44
|
-
installed CLI with this skill's frontmatter
|
|
44
|
+
installed CLI with the `version:` in this skill's frontmatter:
|
|
45
45
|
|
|
46
46
|
| CLI version vs skill | Action |
|
|
47
47
|
|---|---|
|
|
48
|
-
| Same major (`2.
|
|
48
|
+
| Same major (e.g. skill `2.x` → CLI `2.y`) | **Upgrade directly**: `npm i -g lan-low-code-cli@latest`. Non-major releases keep the flags in this skill valid. |
|
|
49
49
|
| CLI major is higher (`2.x` skill vs `3.x` CLI) | A **major** version has been crossed: **this skill may be out of date**. Do not assume its flags/fields still exist — tell the user the skill may be stale and update it (see **Self-update** below) before running write operations. |
|
|
50
50
|
| CLI major is lower | The CLI is older than the skill: upgrade the CLI first (`npm i -g lan-low-code-cli@latest`); never downgrade the skill. |
|
|
51
51
|
|
|
@@ -91,13 +91,28 @@ Always run `llc <command> --help` before inventing flags — the CLI is the sour
|
|
|
91
91
|
| Command | Purpose |
|
|
92
92
|
|---|---|
|
|
93
93
|
| `llc app list / create / forms / delete / delete-data` | business apps (`--code` allows letters/digits/hyphen only, **no underscore**) |
|
|
94
|
-
| `llc form create / list / get / publish / autofill / delete / delete-data` | form lifecycle |
|
|
94
|
+
| `llc form create / list / get / publish / autofill / delete / delete-data` | form lifecycle; `create --type category\|simpleCategory` builds a category form (no business fields; templates are created in the platform designer) |
|
|
95
95
|
| `llc field list / gen-key / library` | available fields |
|
|
96
|
+
| `llc operation list / get / create / update / delete / attach / detach` | form business operations (link, script, dialog), including attaching to list/view pages |
|
|
97
|
+
| `llc template list / create / add-fields / delete` | category-form templates: create/append/delete templates, porting fields/views/permissions from an existing form (auto category node, bypasses official init) |
|
|
98
|
+
| `llc flow spec / compile / validate` | **offline**: generate a Flow Spec, compile it into `fdDesign` with IDE-style layout, run offline validation |
|
|
99
|
+
| `llc flow list / get / category / logs / schema / templates` | **read-only** action-flow queries; `templates` extracts golden node skeletons (coordinates stripped) |
|
|
100
|
+
| `llc flow apply / diff / script / enable / disable / delete` | **write** action-flow lifecycle; `apply` previews by default and needs `--yes` + `--app-code` |
|
|
96
101
|
| `llc control list / show` | controls installed in the environment (basis for `--add-field` third segment) |
|
|
97
102
|
| `llc locale list` | languages with translations available (from control i18n resources) |
|
|
98
103
|
| `llc config set / show / clear` | global credentials and defaults |
|
|
99
104
|
|
|
100
105
|
> Full per-command options, spec-string syntax and exit codes: **§7 CLI contract**. When in doubt, `llc <command> --help` is authoritative.
|
|
106
|
+
>
|
|
107
|
+
> Runtime `context` of operation scripts (selected rows, list refresh, query, navigation, event bus,
|
|
108
|
+
> `window.MKXFORM`) is documented in [references/operation-script-context.md](references/operation-script-context.md) (Chinese).
|
|
109
|
+
>
|
|
110
|
+
> Action flows are **application-scoped** (`--app-code`, `fdAppCode`), not form-scoped. Always start with
|
|
111
|
+
> `llc flow spec --out flow.json` → `llc flow validate --spec @flow.json` → `llc flow compile --spec @flow.json --json`.
|
|
112
|
+
> `llc flow apply` **only previews** until `--yes` is added, and requires an explicit `--app-code`.
|
|
113
|
+
> `--layout ide` (default) reproduces the platform's branch arrangement; never hand-write `drawAttr.bounds`.
|
|
114
|
+
> Full Flow Spec syntax: **§10 of [references/cli-contract.md](references/cli-contract.md)**.
|
|
115
|
+
> Add `--resolve-schema` when publishing nodes that reference a data model (`sys-modeling#<fdId>`).
|
|
101
116
|
|
|
102
117
|
## 2. Core workflow
|
|
103
118
|
|
|
@@ -181,7 +196,7 @@ llc form autofill --id <fdId> --apply --publish \
|
|
|
181
196
|
is accepted), so an unsupported event saves fine but never fires. Confirm in this order: the designer's
|
|
182
197
|
"控件动作" event dropdown (authoritative) → `llc control show --element <pkg> --json`, i.e. event
|
|
183
198
|
declarations in `meta` if the package has any (not shown in human output) → the keys of
|
|
184
|
-
`controlAction.control['<table>.<uuid>']` on an existing form. See §
|
|
199
|
+
`controlAction.control['<table>.<uuid>']` on an existing form. See §8 of
|
|
185
200
|
[references/cli-contract.md](references/cli-contract.md).
|
|
186
201
|
- `source` is function **source code** (evaluated via
|
|
187
202
|
`new Function('MKXFORM', 'return (fn)')`); `@path` reads it from a file.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lan-low-code-cli
|
|
3
|
-
version: 2.
|
|
3
|
+
version: 2.7.0
|
|
4
4
|
author: Pig George
|
|
5
5
|
description: 通过 `llc` CLI 操作蓝凌低代码表单引擎。适用于:创建、查看、修改、发布或删除低代码应用与表单;生成字段配置;配置布局(栅格/页签)、字段权限、选项、多语言、控件动作(onChange/onLoad);或执行发布前校验、排查表单加载/渲染报错。
|
|
6
6
|
tags:
|
|
@@ -45,7 +45,7 @@ npm i -g lan-low-code-cli # 全局安装,获得 `llc` 命令
|
|
|
45
45
|
|
|
46
46
|
| CLI 版本 vs skill | 处理 |
|
|
47
47
|
|---|---|
|
|
48
|
-
|
|
|
48
|
+
| 同一大版本(如 skill `2.x` → CLI `2.y`) | **直接升级**:`npm i -g lan-low-code-cli@latest`。非大版本升级不影响本 skill 的参数与写法。 |
|
|
49
49
|
| CLI 大版本更高(skill `2.x` vs CLI `3.x`) | 已**跨大版本**:**本 skill 可能已过期**。不要假设其中的参数/字段仍然有效——告知用户 skill 可能过期,按下方**自更新**更新后再执行写操作。 |
|
|
50
50
|
| CLI 大版本更低 | CLI 比 skill 旧:先升级 CLI(`npm i -g lan-low-code-cli@latest`),不要把 skill 降级。 |
|
|
51
51
|
|
|
@@ -88,13 +88,28 @@ llc config set --base-url http://<host>/data --token <X-AUTH-TOKEN> # 一次
|
|
|
88
88
|
| 命令 | 用途 |
|
|
89
89
|
|---|---|
|
|
90
90
|
| `llc app list / create / forms / delete / delete-data` | 业务应用(`--code` 仅允许字母/数字/连字符,**不允许下划线**) |
|
|
91
|
-
| `llc form create / list / get / publish / autofill / delete / delete-data` |
|
|
91
|
+
| `llc form create / list / get / publish / autofill / delete / delete-data` | 表单生命周期;`create --type category\|simpleCategory` 建分类表单(无业务字段,模板需在平台设计器创建) |
|
|
92
92
|
| `llc field list / gen-key / library` | 可用字段 |
|
|
93
|
+
| `llc operation list / get / create / update / delete / attach / detach` | 表单业务操作(链接、脚本、对话框),含挂载到列表/查看视图 |
|
|
94
|
+
| `llc template list / create / add-fields / delete` | 分类表单模板:创建模板并把既有表单的字段/视图/权限移植进来,追加字段,或清理模板(自动建分类节点、跳过官方 init) |
|
|
95
|
+
| `llc flow spec / compile / validate` | **纯离线**:生成 Flow Spec、编译出符合 IDE 编排布局的 `fdDesign`、离线校验 |
|
|
96
|
+
| `llc flow list / get / category / logs / schema / templates` | **只读**查询动作流;`templates` 抽取 golden 节点骨架(已剥离坐标) |
|
|
97
|
+
| `llc flow apply / diff / script / enable / disable / delete` | **写入**动作流全生命周期;`apply` 默认预览,需 `--yes` + `--app-code` 才提交 |
|
|
93
98
|
| `llc control list / show` | 环境已安装控件(`--add-field` 第三段的取值依据) |
|
|
94
99
|
| `llc locale list` | 环境中有现成译文的语言(来自控件多语言资源) |
|
|
95
100
|
| `llc config set / show / clear` | 全局凭据与默认值 |
|
|
96
101
|
|
|
97
102
|
> 每个命令的完整参数、规格字符串语法与退出码见**第 7 节 CLI 契约**;不确定时以 `llc <命令> --help` 为准。
|
|
103
|
+
>
|
|
104
|
+
> 业务操作「脚本模式」的运行时 `context`(选中数据、刷新列表、查询、跳转、事件总线、`window.MKXFORM`)
|
|
105
|
+
> 见 [references/operation-script-context.md](references/operation-script-context.md)。
|
|
106
|
+
>
|
|
107
|
+
> 动作流是**应用级**对象(`--app-code` 即 `fdAppCode`),不是表单级。固定起手式:
|
|
108
|
+
> `llc flow spec --out flow.json` → `llc flow validate --spec @flow.json` → `llc flow compile --spec @flow.json --json`。
|
|
109
|
+
> `llc flow apply` **默认只预览**,必须追加 `--yes`,且必须显式给 `--app-code`。
|
|
110
|
+
> `--layout ide`(默认)复刻平台分支编排,不要手写 `drawAttr.bounds`。
|
|
111
|
+
> Flow Spec 完整语法见 [references/cli-contract.md](references/cli-contract.md) **第 10 节**。
|
|
112
|
+
> 节点引用数据模型(`sys-modeling#<fdId>`)时,发布请加 `--resolve-schema`。
|
|
98
113
|
|
|
99
114
|
## 2. 核心流程
|
|
100
115
|
|
|
@@ -174,7 +189,7 @@ llc form autofill --id <fdId> --apply --publish \
|
|
|
174
189
|
- **控件支持哪些事件**:CLI 不内置白名单、也不校验(只要求标识符),写错不会报错但不会触发。
|
|
175
190
|
按序确认:设计器「控件动作」事件下拉(权威)→ `llc control show --element <pkg> --json` 的 `meta`
|
|
176
191
|
(若包内声明了事件;人类可读输出不展示)→ 已有表单 `controlAction.control['<表名>.<uuid>']` 的键名。
|
|
177
|
-
详见 [references/cli-contract.zh-CN.md](references/cli-contract.zh-CN.md) 第
|
|
192
|
+
详见 [references/cli-contract.zh-CN.md](references/cli-contract.zh-CN.md) 第 8 节。
|
|
178
193
|
- `source` 是函数**源码**(运行时经 `new Function('MKXFORM', 'return (fn)')` 求值);
|
|
179
194
|
`@路径` 表示从文件读取。
|
|
180
195
|
- 落库位置:`fdConfig.attribute.formAttr.controlAction.control['<表名>.<uuid>'][<事件>]`。
|