@dazitech/cli 3.0.1 → 3.0.3
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 +2 -2
- package/dist/clis/dazi-app.js +90 -9
- package/dist/clis/dazi-flow.js +2395 -1680
- package/dist/clis/dazi-onto.js +82 -15
- package/dist/clis/dazi.js +216 -50
- package/dist/docs/flow/ai-workflow-playbook.md +9 -8
- package/dist/docs/flow/flow-project-guide.md +41 -29
- package/dist/docs/flow/flows-guide.md +23 -16
- package/dist/docs/flow/local-files-spec.md +3 -3
- package/dist/docs/flow/node-code-guide.md +7 -7
- package/dist/docs/flow/run-guide.md +3 -3
- package/dist/docs/flow/variables-guide.md +4 -4
- package/dist/docs/guides/cli-invocation.md +3 -2
- package/dist/docs/guides/cli-reference.md +3 -1
- package/dist/docs/guides/flow-consistency-checklist.md +3 -3
- package/dist/docs/guides/quickstart.md +1 -1
- package/dist/docs/guides/troubleshooting.md +12 -11
- package/dist/docs/index.json +1 -1
- package/dist/examples/index.json +1 -1
- package/dist/prompts/index.json +94 -16
- package/package.json +1 -1
package/dist/clis/dazi-flow.js
CHANGED
|
@@ -6,9 +6,16 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __esm = (fn, res) => function __init() {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
};
|
|
9
12
|
var __commonJS = (cb, mod) => function __require() {
|
|
10
13
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
11
14
|
};
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
12
19
|
var __copyProps = (to, from, except, desc) => {
|
|
13
20
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
21
|
for (let key of __getOwnPropNames(from))
|
|
@@ -25,6 +32,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
32
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
33
|
mod
|
|
27
34
|
));
|
|
35
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
36
|
|
|
29
37
|
// node_modules/.pnpm/commander@12.1.0/node_modules/commander/lib/error.js
|
|
30
38
|
var require_error = __commonJS({
|
|
@@ -959,8 +967,8 @@ var require_command = __commonJS({
|
|
|
959
967
|
"node_modules/.pnpm/commander@12.1.0/node_modules/commander/lib/command.js"(exports2) {
|
|
960
968
|
var EventEmitter = require("node:events").EventEmitter;
|
|
961
969
|
var childProcess = require("node:child_process");
|
|
962
|
-
var
|
|
963
|
-
var
|
|
970
|
+
var path19 = require("node:path");
|
|
971
|
+
var fs16 = require("node:fs");
|
|
964
972
|
var process2 = require("node:process");
|
|
965
973
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
966
974
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -1892,11 +1900,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1892
1900
|
let launchWithNode = false;
|
|
1893
1901
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1894
1902
|
function findFile(baseDir, baseName) {
|
|
1895
|
-
const localBin =
|
|
1896
|
-
if (
|
|
1897
|
-
if (sourceExt.includes(
|
|
1903
|
+
const localBin = path19.resolve(baseDir, baseName);
|
|
1904
|
+
if (fs16.existsSync(localBin)) return localBin;
|
|
1905
|
+
if (sourceExt.includes(path19.extname(baseName))) return void 0;
|
|
1898
1906
|
const foundExt = sourceExt.find(
|
|
1899
|
-
(ext) =>
|
|
1907
|
+
(ext) => fs16.existsSync(`${localBin}${ext}`)
|
|
1900
1908
|
);
|
|
1901
1909
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
1902
1910
|
return void 0;
|
|
@@ -1908,21 +1916,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1908
1916
|
if (this._scriptPath) {
|
|
1909
1917
|
let resolvedScriptPath;
|
|
1910
1918
|
try {
|
|
1911
|
-
resolvedScriptPath =
|
|
1919
|
+
resolvedScriptPath = fs16.realpathSync(this._scriptPath);
|
|
1912
1920
|
} catch (err) {
|
|
1913
1921
|
resolvedScriptPath = this._scriptPath;
|
|
1914
1922
|
}
|
|
1915
|
-
executableDir =
|
|
1916
|
-
|
|
1923
|
+
executableDir = path19.resolve(
|
|
1924
|
+
path19.dirname(resolvedScriptPath),
|
|
1917
1925
|
executableDir
|
|
1918
1926
|
);
|
|
1919
1927
|
}
|
|
1920
1928
|
if (executableDir) {
|
|
1921
1929
|
let localFile = findFile(executableDir, executableFile);
|
|
1922
1930
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
1923
|
-
const legacyName =
|
|
1931
|
+
const legacyName = path19.basename(
|
|
1924
1932
|
this._scriptPath,
|
|
1925
|
-
|
|
1933
|
+
path19.extname(this._scriptPath)
|
|
1926
1934
|
);
|
|
1927
1935
|
if (legacyName !== this._name) {
|
|
1928
1936
|
localFile = findFile(
|
|
@@ -1933,7 +1941,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1933
1941
|
}
|
|
1934
1942
|
executableFile = localFile || executableFile;
|
|
1935
1943
|
}
|
|
1936
|
-
launchWithNode = sourceExt.includes(
|
|
1944
|
+
launchWithNode = sourceExt.includes(path19.extname(executableFile));
|
|
1937
1945
|
let proc;
|
|
1938
1946
|
if (process2.platform !== "win32") {
|
|
1939
1947
|
if (launchWithNode) {
|
|
@@ -2773,7 +2781,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2773
2781
|
* @return {Command}
|
|
2774
2782
|
*/
|
|
2775
2783
|
nameFromFilename(filename) {
|
|
2776
|
-
this._name =
|
|
2784
|
+
this._name = path19.basename(filename, path19.extname(filename));
|
|
2777
2785
|
return this;
|
|
2778
2786
|
}
|
|
2779
2787
|
/**
|
|
@@ -2787,9 +2795,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2787
2795
|
* @param {string} [path]
|
|
2788
2796
|
* @return {(string|null|Command)}
|
|
2789
2797
|
*/
|
|
2790
|
-
executableDir(
|
|
2791
|
-
if (
|
|
2792
|
-
this._executableDir =
|
|
2798
|
+
executableDir(path20) {
|
|
2799
|
+
if (path20 === void 0) return this._executableDir;
|
|
2800
|
+
this._executableDir = path20;
|
|
2793
2801
|
return this;
|
|
2794
2802
|
}
|
|
2795
2803
|
/**
|
|
@@ -3019,1482 +3027,2371 @@ var require_commander = __commonJS({
|
|
|
3019
3027
|
}
|
|
3020
3028
|
});
|
|
3021
3029
|
|
|
3022
|
-
//
|
|
3023
|
-
var
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3030
|
+
// src/shared/flowNodeCatalog.ts
|
|
3031
|
+
var flowNodeCatalog_exports = {};
|
|
3032
|
+
__export(flowNodeCatalog_exports, {
|
|
3033
|
+
FLOW_NODE_CATALOG: () => FLOW_NODE_CATALOG,
|
|
3034
|
+
FLOW_NODE_CATALOG_DESIGNER: () => FLOW_NODE_CATALOG_DESIGNER,
|
|
3035
|
+
allFlowNodeTypes: () => allFlowNodeTypes,
|
|
3036
|
+
buildFlowNodeCatalogQuickStartSection: () => buildFlowNodeCatalogQuickStartSection,
|
|
3037
|
+
flowNodeByType: () => flowNodeByType
|
|
3038
|
+
});
|
|
3039
|
+
function allFlowNodeTypes() {
|
|
3040
|
+
return FLOW_NODE_CATALOG.flatMap((g) => g.items);
|
|
3041
|
+
}
|
|
3042
|
+
function flowNodeByType(type) {
|
|
3043
|
+
return allFlowNodeTypes().find((n) => n.type === type);
|
|
3044
|
+
}
|
|
3045
|
+
function buildFlowNodeCatalogQuickStartSection(detailLink) {
|
|
3046
|
+
const lines = [
|
|
3047
|
+
"## \u53EF\u7528\u6D41\u7A0B\u8282\u70B9\uFF08`data.type`\uFF09",
|
|
3048
|
+
"",
|
|
3049
|
+
"> \u753B\u5E03\u8282\u70B9 **`type` \u6052\u4E3A `custom`**\uFF0C\u4E1A\u52A1\u7C7B\u578B\u5728 **`data.type`**\u3002\u65B0\u5EFA\uFF1A`flow node new --type <\u4E0B\u8868 type>`\u3002",
|
|
3050
|
+
"> **\u7981\u6B62**\u7F16\u9020\u672A\u5728\u4E0B\u8868\u4E2D\u7684 type\u3002",
|
|
3051
|
+
""
|
|
3052
|
+
];
|
|
3053
|
+
for (const { group, items } of FLOW_NODE_CATALOG) {
|
|
3054
|
+
lines.push(`### ${group}`, "");
|
|
3055
|
+
lines.push("| type | \u540D\u79F0 | \u4EE3\u7801 | \u7528\u9014 | \u53D8\u91CF |");
|
|
3056
|
+
lines.push("|------|------|:----:|------|------|");
|
|
3057
|
+
for (const n of items) {
|
|
3058
|
+
const code = n.hasCode ? n.codeFile ?? "code.*" : "\u2014";
|
|
3059
|
+
const vars = [n.consumes ? `\u5165:${shortVar(n.consumes)}` : "", n.produces ? `\u51FA:${shortVar(n.produces)}` : ""].filter(Boolean).join(" \xB7 ") || "\u2014";
|
|
3060
|
+
lines.push(`| \`${n.type}\` | ${n.label} | ${code} | ${n.summary} | ${vars} |`);
|
|
3061
|
+
}
|
|
3062
|
+
lines.push("");
|
|
3063
|
+
}
|
|
3064
|
+
lines.push(
|
|
3065
|
+
"**\u9009\u578B\u63D0\u793A**",
|
|
3066
|
+
"",
|
|
3067
|
+
"- **Excel\uFF08\u6709 `managed_file_id` / `file_id`\uFF09\u2192 \u4F18\u5148 `excel-python`**\uFF0C\u52FF\u7528 `file-source`\uFF08\u4E0D\u89E3\u6790 Excel\uFF09",
|
|
3068
|
+
"- \u4EC5\u6781\u7B80\u5355\u5355 Sheet\u3001\u96F6\u4EE3\u7801\u65F6\u624D\u7528 `excel-import`\uFF1B\u591A Sheet / \u590D\u6742\u8868\u5934 / \u4E0D\u786E\u5B9A\u7ED3\u6784 \u2192 `excel-python`",
|
|
3069
|
+
"- **`excel-python`**\uFF1A\u753B\u5E03\u914D **`managed_file_id`\uFF08UUID\uFF09**\uFF1B`code.py` \u7528 **`excel_source_path`**\uFF0C\u7981\u6B62\u5199\u6587\u4EF6\u540D/\u672C\u5730\u8DEF\u5F84",
|
|
3070
|
+
"- \u975E Excel \u539F\u59CB\u6587\u4EF6 \u2192 `file-source`\uFF1B\u8BFB\u5916\u90E8\u5E93 \u2192 `database-source`\uFF1B\u8BFB\u6570\u636E\u7A7A\u95F4 \u2192 `dataspace-source`",
|
|
3071
|
+
"- \u5185\u5B58\u52A0\u5DE5 \u2192 `sql-query` / `python-script`\uFF1B\u5206\u652F \u2192 `condition`\uFF08\u51FA\u8FB9 `true`/`false`\uFF09",
|
|
3072
|
+
"- \u5199\u5916\u90E8\u5E93 \u2192 `database-sink`\uFF1B\u5199\u6570\u636E\u7A7A\u95F4 \u2192 `dataspace-sink`",
|
|
3073
|
+
""
|
|
3074
|
+
);
|
|
3075
|
+
if (detailLink) {
|
|
3076
|
+
lines.push(`\u5404\u8282\u70B9\u914D\u7F6E\u4E0E\u793A\u4F8B \u2192 [flows-guide \xA7\u6D41\u7A0B\u8282\u70B9\u7EC4\u4EF6](${detailLink}#\u6D41\u7A0B\u8282\u70B9\u7EC4\u4EF6)\u3002`, "");
|
|
3077
|
+
} else {
|
|
3078
|
+
lines.push("\u5404\u8282\u70B9\u914D\u7F6E\u4E0E\u793A\u4F8B \u2192 \u5E2E\u52A9\u6587\u6863 **flow/flows-guide** \xA7\u6D41\u7A0B\u8282\u70B9\u7EC4\u4EF6\u3002", "");
|
|
3079
|
+
}
|
|
3080
|
+
return lines;
|
|
3081
|
+
}
|
|
3082
|
+
function shortVar(s) {
|
|
3083
|
+
return s.replace(/`/g, "").slice(0, 40);
|
|
3084
|
+
}
|
|
3085
|
+
var FLOW_NODE_CATALOG, FLOW_NODE_CATALOG_DESIGNER;
|
|
3086
|
+
var init_flowNodeCatalog = __esm({
|
|
3087
|
+
"src/shared/flowNodeCatalog.ts"() {
|
|
3088
|
+
"use strict";
|
|
3089
|
+
FLOW_NODE_CATALOG = [
|
|
3090
|
+
{
|
|
3091
|
+
group: "\u6D41\u7A0B\u63A7\u5236",
|
|
3092
|
+
items: [
|
|
3093
|
+
{
|
|
3094
|
+
type: "condition",
|
|
3095
|
+
label: "\u6761\u4EF6\u5224\u65AD",
|
|
3096
|
+
hasCode: true,
|
|
3097
|
+
codeFile: "code.py",
|
|
3098
|
+
summary: "\u5BF9\u4E0A\u6E38\u8868\u6C42\u5E03\u5C14\u8868\u8FBE\u5F0F\uFF0C\u8D70 True/False \u5206\u652F",
|
|
3099
|
+
consumes: "\u5165\u8FB9\u4E0A\u6E38\u8868 \u2192 \u8FD0\u884C\u65F6\u6CE8\u5165 `df`",
|
|
3100
|
+
produces: "\u65E0\u65B0\u8868\u53D8\u91CF\uFF08\u4EC5\u8DEF\u7531\uFF09",
|
|
3101
|
+
keyConfig: ["label", "pythonCode\uFF08\u4EE3\u7801\u5728 code.py\uFF09"]
|
|
3102
|
+
},
|
|
3103
|
+
{
|
|
3104
|
+
type: "delay",
|
|
3105
|
+
label: "\u5EF6\u65F6\u7B49\u5F85",
|
|
3106
|
+
hasCode: false,
|
|
3107
|
+
summary: "\u6682\u505C\u6307\u5B9A\u79D2\u6570\u540E\u7EE7\u7EED\u4E0B\u6E38",
|
|
3108
|
+
keyConfig: ["delaySeconds \u6216 delay\uFF08\u79D2\uFF09"]
|
|
3109
|
+
}
|
|
3110
|
+
]
|
|
3111
|
+
},
|
|
3112
|
+
{
|
|
3113
|
+
group: "\u6570\u636E\u5904\u7406",
|
|
3114
|
+
items: [
|
|
3115
|
+
{
|
|
3116
|
+
type: "file-source",
|
|
3117
|
+
label: "\u6587\u4EF6\u8F93\u5165",
|
|
3118
|
+
hasCode: false,
|
|
3119
|
+
summary: "\u975E Excel \u539F\u59CB\u6587\u4EF6\u900F\u4F20\uFF08.xlsx/.xls \u52FF\u7528\uFF0C\u6539 excel-python\uFF09",
|
|
3120
|
+
produces: "`output_variable_name`",
|
|
3121
|
+
keyConfig: ["file_id / managed_file_id", "output_variable_name"]
|
|
3122
|
+
},
|
|
3123
|
+
{
|
|
3124
|
+
type: "excel-import",
|
|
3125
|
+
label: "Excel \u5BFC\u5165",
|
|
3126
|
+
hasCode: false,
|
|
3127
|
+
summary: "\u4EC5\u6781\u7B80\u5355\u5355 Sheet \u96F6\u4EE3\u7801\uFF1B\u6709 file_id \u7684 Excel \u9ED8\u8BA4\u4ECD\u7528 excel-python",
|
|
3128
|
+
produces: "`output_variable_name`",
|
|
3129
|
+
keyConfig: ["file_id / source_excel_id", "sheetName\uFF08\u53EF\u9009\uFF09", "output_variable_name"]
|
|
3130
|
+
},
|
|
3131
|
+
{
|
|
3132
|
+
type: "excel-python",
|
|
3133
|
+
label: "Excel \u5F00\u53D1",
|
|
3134
|
+
hasCode: true,
|
|
3135
|
+
codeFile: "code.py",
|
|
3136
|
+
summary: "\u591A Sheet / \u590D\u6742\u8868\u5934\uFF1APython \u89E3\u6790 Excel\uFF08\u753B\u5E03\u914D managed_file_id\uFF0C\u4EE3\u7801\u7528 excel_source_path\uFF09",
|
|
3137
|
+
produces: "`set_table_output(\u4E0E output_variable_name \u540C\u540D, df)`",
|
|
3138
|
+
keyConfig: ["managed_file_id\uFF08UUID\uFF0C\u975E\u6587\u4EF6\u540D\uFF09", "output_variable_name"]
|
|
3139
|
+
},
|
|
3140
|
+
{
|
|
3141
|
+
type: "sql-query",
|
|
3142
|
+
label: "SQL \u67E5\u8BE2",
|
|
3143
|
+
hasCode: true,
|
|
3144
|
+
codeFile: "code.sql",
|
|
3145
|
+
summary: "DuckDB \u5185\u5B58 SQL\uFF0C\u4E0A\u6E38\u53D8\u91CF\u540D\u4F5C\u8868\u540D",
|
|
3146
|
+
consumes: "\u4E0A\u6E38 `output_variable_name` \u4F5C SQL \u8868\u540D",
|
|
3147
|
+
produces: "`output_variable_name`",
|
|
3148
|
+
keyConfig: ["output_variable_name"]
|
|
3149
|
+
},
|
|
3150
|
+
{
|
|
3151
|
+
type: "python-script",
|
|
3152
|
+
label: "Python \u811A\u672C",
|
|
3153
|
+
hasCode: true,
|
|
3154
|
+
codeFile: "code.py",
|
|
3155
|
+
summary: "pandas \u8F6C\u6362\uFF1B\u6700\u5E38\u7528\u52A0\u5DE5\u8282\u70B9",
|
|
3156
|
+
consumes: '`get_variable("\u4E0A\u6E38\u53D8\u91CF\u540D")` \u6216\u5165\u8FB9 `df`',
|
|
3157
|
+
produces: "`result_df` \u2192 `output_variable_name`",
|
|
3158
|
+
keyConfig: ["output_variable_name"]
|
|
3159
|
+
},
|
|
3160
|
+
{
|
|
3161
|
+
type: "database-source",
|
|
3162
|
+
label: "\u6570\u636E\u5E93\u8BFB\u53D6",
|
|
3163
|
+
hasCode: true,
|
|
3164
|
+
codeFile: "code.sql",
|
|
3165
|
+
summary: "\u4ECE\u5916\u90E8\u6570\u636E\u5E93\uFF08connectionId\uFF09\u53EA\u8BFB\u67E5\u8BE2",
|
|
3166
|
+
produces: "`output_variable_name`",
|
|
3167
|
+
keyConfig: ["connectionId", "output_variable_name"]
|
|
3168
|
+
},
|
|
3169
|
+
{
|
|
3170
|
+
type: "database-sink",
|
|
3171
|
+
label: "\u6570\u636E\u5E93\u5199\u5165",
|
|
3172
|
+
hasCode: false,
|
|
3173
|
+
summary: "\u5C06\u8868\u53D8\u91CF\u5199\u5165\u5916\u90E8\u6570\u636E\u5E93\u8868",
|
|
3174
|
+
consumes: "`input_variable_name` \u6216\u5165\u8FB9 Parquet",
|
|
3175
|
+
keyConfig: ["connectionId", "tableName", "mode", "input_variable_name"]
|
|
3176
|
+
},
|
|
3177
|
+
{
|
|
3178
|
+
type: "dataspace-source",
|
|
3179
|
+
label: "\u6570\u636E\u7A7A\u95F4\u8BFB\u53D6",
|
|
3180
|
+
hasCode: true,
|
|
3181
|
+
codeFile: "code.sql",
|
|
3182
|
+
summary: "\u4ECE\u642D\u5B50\u6570\u636E\u7A7A\u95F4\uFF08spaceId\uFF09\u53EA\u8BFB SQL",
|
|
3183
|
+
produces: "`output_variable_name`",
|
|
3184
|
+
keyConfig: ["spaceId", "output_variable_name", "limit\uFF08\u53EF\u9009\uFF09"]
|
|
3185
|
+
},
|
|
3186
|
+
{
|
|
3187
|
+
type: "dataspace-sink",
|
|
3188
|
+
label: "\u6570\u636E\u7A7A\u95F4\u5199\u5165",
|
|
3189
|
+
hasCode: false,
|
|
3190
|
+
summary: "\u5C06\u8868\u53D8\u91CF\u5199\u5165\u6570\u636E\u7A7A\u95F4\u8868",
|
|
3191
|
+
consumes: "`input_variable_name` \u6216\u5165\u8FB9 Parquet",
|
|
3192
|
+
keyConfig: ["spaceId", "tableName", "input_variable_name", "syncMetadata\uFF08\u53EF\u9009\uFF09"]
|
|
3193
|
+
},
|
|
3194
|
+
{
|
|
3195
|
+
type: "data-quality-check",
|
|
3196
|
+
label: "\u6570\u636E\u8D28\u91CF\u68C0\u67E5",
|
|
3197
|
+
hasCode: true,
|
|
3198
|
+
codeFile: "code.py",
|
|
3199
|
+
summary: "\u8D28\u68C0\u89C4\u5219\u6216\u81EA\u5B9A\u4E49 Python\uFF08dqPythonCode\uFF09",
|
|
3200
|
+
consumes: "\u4E0A\u6E38\u8868 / `get_variable`",
|
|
3201
|
+
produces: "\u8D28\u68C0\u62A5\u544A\u53D8\u91CF\uFF08\u4F9D\u914D\u7F6E\uFF09",
|
|
3202
|
+
keyConfig: ["output_variable_name", "qualityConfig", "dqPythonCode\uFF08\u4F18\u5148\u4E8E\u89C4\u5219\uFF09"]
|
|
3203
|
+
},
|
|
3204
|
+
{
|
|
3205
|
+
type: "folder-resource-import",
|
|
3206
|
+
label: "\u6587\u4EF6\u5939\u8D44\u6E90\u5BFC\u5165",
|
|
3207
|
+
hasCode: false,
|
|
3208
|
+
summary: "\u4ECE\u6587\u4EF6\u5939\u8D44\u6E90\u6279\u91CF\u5BFC\u5165\u6587\u4EF6",
|
|
3209
|
+
produces: "`output_variable_name`",
|
|
3210
|
+
keyConfig: ["folderId", "resourceId", "pageSize", "output_variable_name"]
|
|
3211
|
+
},
|
|
3212
|
+
{
|
|
3213
|
+
type: "folder-resource-register",
|
|
3214
|
+
label: "\u8D44\u6E90\u6CE8\u518C",
|
|
3215
|
+
hasCode: false,
|
|
3216
|
+
summary: "\u5C06\u5BFC\u5165\u7ED3\u679C\u6CE8\u518C\u5230\u8FDE\u63A5/\u8D44\u6E90\u76EE\u5F55",
|
|
3217
|
+
keyConfig: ["connectionName", "targetFolderId"]
|
|
3218
|
+
}
|
|
3219
|
+
]
|
|
3220
|
+
}
|
|
3221
|
+
];
|
|
3222
|
+
FLOW_NODE_CATALOG_DESIGNER = FLOW_NODE_CATALOG.map((g) => ({
|
|
3223
|
+
group: g.group,
|
|
3224
|
+
items: g.items.map(({ type, label, hasCode }) => ({
|
|
3225
|
+
type,
|
|
3226
|
+
label,
|
|
3227
|
+
...hasCode ? { code: true } : {}
|
|
3228
|
+
}))
|
|
3229
|
+
}));
|
|
3230
|
+
}
|
|
3231
|
+
});
|
|
3042
3232
|
|
|
3043
|
-
//
|
|
3044
|
-
var
|
|
3045
|
-
|
|
3046
|
-
|
|
3233
|
+
// src/shared/flowCliText.ts
|
|
3234
|
+
var flowCliText_exports = {};
|
|
3235
|
+
__export(flowCliText_exports, {
|
|
3236
|
+
DAZI_CLI: () => DAZI_CLI,
|
|
3237
|
+
DAZI_PS1: () => DAZI_PS1,
|
|
3238
|
+
mdDaziCmd: () => mdDaziCmd,
|
|
3239
|
+
mdFlowCmd: () => mdFlowCmd,
|
|
3240
|
+
normalizeCliExampleLine: () => normalizeCliExampleLine,
|
|
3241
|
+
psDaziLine: () => psDaziLine,
|
|
3242
|
+
psFlowBlock: () => psFlowBlock,
|
|
3243
|
+
psFlowLine: () => psFlowLine
|
|
3244
|
+
});
|
|
3245
|
+
function psFlowLine(subcommand) {
|
|
3246
|
+
return `${DAZI_CLI} flow ${subcommand}`;
|
|
3247
|
+
}
|
|
3248
|
+
function psDaziLine(args) {
|
|
3249
|
+
return `${DAZI_CLI} ${args}`;
|
|
3250
|
+
}
|
|
3251
|
+
function mdFlowCmd(subcommand) {
|
|
3252
|
+
return `\`${DAZI_CLI} flow ${subcommand}\``;
|
|
3253
|
+
}
|
|
3254
|
+
function mdDaziCmd(args) {
|
|
3255
|
+
return `\`${DAZI_CLI} ${args}\``;
|
|
3256
|
+
}
|
|
3257
|
+
function normalizeCliExampleLine(line) {
|
|
3258
|
+
return line.replace(/\.\\+scripts\\+dazi\.ps1\s+/g, `${DAZI_CLI} `).replace(/\.\/scripts\/dazi\.ps1\s+/g, `${DAZI_CLI} `);
|
|
3259
|
+
}
|
|
3260
|
+
function psFlowBlock(lines) {
|
|
3261
|
+
return ["```powershell", ...lines.map(normalizeCliExampleLine), "```"].join("\n");
|
|
3262
|
+
}
|
|
3263
|
+
var DAZI_CLI, DAZI_PS1;
|
|
3264
|
+
var init_flowCliText = __esm({
|
|
3265
|
+
"src/shared/flowCliText.ts"() {
|
|
3266
|
+
"use strict";
|
|
3267
|
+
DAZI_CLI = "dazi";
|
|
3268
|
+
DAZI_PS1 = DAZI_CLI;
|
|
3269
|
+
}
|
|
3270
|
+
});
|
|
3047
3271
|
|
|
3048
|
-
//
|
|
3049
|
-
var
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3272
|
+
// src/shared/flowWorkspaceAudit.ts
|
|
3273
|
+
var flowWorkspaceAudit_exports = {};
|
|
3274
|
+
__export(flowWorkspaceAudit_exports, {
|
|
3275
|
+
auditFlowWorkspace: () => auditFlowWorkspace,
|
|
3276
|
+
buildFlowConsistencyMarkdown: () => buildFlowConsistencyMarkdown,
|
|
3277
|
+
repairFlowMeta: () => repairFlowMeta
|
|
3278
|
+
});
|
|
3279
|
+
function sha12(text) {
|
|
3280
|
+
return import_crypto2.default.createHash("sha1").update(text, "utf8").digest("hex");
|
|
3281
|
+
}
|
|
3282
|
+
function resolveNodeType2(node) {
|
|
3283
|
+
if (node.type === "custom") {
|
|
3284
|
+
return String(node.data?.type ?? "custom");
|
|
3055
3285
|
}
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3286
|
+
return String(node.type ?? "custom");
|
|
3287
|
+
}
|
|
3288
|
+
function codeLanguageForNodeType2(nodeType) {
|
|
3289
|
+
if (["python-script", "excel-python", "condition", "data-quality-check"].includes(nodeType)) {
|
|
3290
|
+
return "python";
|
|
3061
3291
|
}
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
constructor(message, status) {
|
|
3065
|
-
super(message, "ERR_NETWORK", 3);
|
|
3066
|
-
this.status = status;
|
|
3067
|
-
this.name = "NetworkError";
|
|
3292
|
+
if (["database-source", "dataspace-source", "sql-query"].includes(nodeType)) {
|
|
3293
|
+
return "sql";
|
|
3068
3294
|
}
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
// cli/shared/src/auth.js
|
|
3072
|
-
function authFilePath() {
|
|
3073
|
-
return import_path.default.join(import_os.default.homedir(), ".dazi", "auth.json");
|
|
3295
|
+
return void 0;
|
|
3074
3296
|
}
|
|
3075
|
-
function
|
|
3076
|
-
|
|
3077
|
-
if (
|
|
3078
|
-
|
|
3297
|
+
function codeFileExt2(language) {
|
|
3298
|
+
if (language === "python") return "py";
|
|
3299
|
+
if (language === "sql") return "sql";
|
|
3300
|
+
return "txt";
|
|
3301
|
+
}
|
|
3302
|
+
function sanitizeName2(name) {
|
|
3303
|
+
const cleaned = (name || "").replace(/[<>:"/\\|?*\x00-\x1f]/g, "_").trim().replace(/\s+/g, "_");
|
|
3304
|
+
return cleaned || "node";
|
|
3305
|
+
}
|
|
3306
|
+
function readFlowJson2(flowDir) {
|
|
3307
|
+
const raw = JSON.parse(import_fs6.default.readFileSync(import_path7.default.join(flowDir, FLOW_JSON2), "utf8"));
|
|
3308
|
+
return {
|
|
3309
|
+
nodes: Array.isArray(raw.nodes) ? raw.nodes : [],
|
|
3310
|
+
edges: Array.isArray(raw.edges) ? raw.edges : []
|
|
3311
|
+
};
|
|
3312
|
+
}
|
|
3313
|
+
function readMeta2(flowDir) {
|
|
3314
|
+
const p = import_path7.default.join(flowDir, FLOW_META_JSON2);
|
|
3315
|
+
if (!import_fs6.default.existsSync(p)) return void 0;
|
|
3079
3316
|
try {
|
|
3080
|
-
return JSON.parse(
|
|
3317
|
+
return JSON.parse(import_fs6.default.readFileSync(p, "utf8"));
|
|
3081
3318
|
} catch {
|
|
3082
|
-
|
|
3319
|
+
return void 0;
|
|
3083
3320
|
}
|
|
3084
3321
|
}
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
const
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
Authorization: `Bearer ${auth.token}`,
|
|
3093
|
-
...opts.headers
|
|
3094
|
-
};
|
|
3095
|
-
const res = await fetch(url, {
|
|
3096
|
-
method: opts.method ?? "GET",
|
|
3097
|
-
headers,
|
|
3098
|
-
body: opts.body != null ? JSON.stringify(opts.body) : void 0
|
|
3099
|
-
});
|
|
3100
|
-
if (!res.ok) {
|
|
3101
|
-
let msg = `HTTP ${res.status} ${res.statusText}`;
|
|
3322
|
+
function isCodeNodeType(nodeType) {
|
|
3323
|
+
return Boolean(NODE_TYPE_CODE_DATA_KEY2[nodeType]);
|
|
3324
|
+
}
|
|
3325
|
+
function listNodeDirs(flowDir) {
|
|
3326
|
+
const nodesRoot = import_path7.default.join(flowDir, NODES_DIR2);
|
|
3327
|
+
if (!import_fs6.default.existsSync(nodesRoot)) return [];
|
|
3328
|
+
return import_fs6.default.readdirSync(nodesRoot).filter((n) => {
|
|
3102
3329
|
try {
|
|
3103
|
-
|
|
3104
|
-
if (j.message)
|
|
3105
|
-
msg = j.message;
|
|
3330
|
+
return import_fs6.default.statSync(import_path7.default.join(nodesRoot, n)).isDirectory();
|
|
3106
3331
|
} catch {
|
|
3332
|
+
return false;
|
|
3107
3333
|
}
|
|
3108
|
-
|
|
3109
|
-
}
|
|
3110
|
-
return res.json();
|
|
3111
|
-
}
|
|
3112
|
-
|
|
3113
|
-
// cli/shared/src/output.js
|
|
3114
|
-
function printJsonSummary(summary) {
|
|
3115
|
-
console.log(`__JSON_SUMMARY__${JSON.stringify(summary)}`);
|
|
3116
|
-
}
|
|
3117
|
-
function ok(data) {
|
|
3118
|
-
printJsonSummary({ ok: true, data });
|
|
3334
|
+
});
|
|
3119
3335
|
}
|
|
3120
|
-
function
|
|
3121
|
-
|
|
3336
|
+
function findCodeFileInDir(dirAbs) {
|
|
3337
|
+
if (!import_fs6.default.existsSync(dirAbs)) return void 0;
|
|
3338
|
+
for (const f of import_fs6.default.readdirSync(dirAbs)) {
|
|
3339
|
+
if (/^code\.(py|sql|txt)$/i.test(f)) return f;
|
|
3340
|
+
}
|
|
3341
|
+
return void 0;
|
|
3122
3342
|
}
|
|
3123
|
-
function
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3343
|
+
function findDirForUuid(flowDir, uuid) {
|
|
3344
|
+
const nodesRoot = import_path7.default.join(flowDir, NODES_DIR2);
|
|
3345
|
+
for (const dirName of listNodeDirs(flowDir)) {
|
|
3346
|
+
const infoPath = import_path7.default.join(nodesRoot, dirName, NODE_INFO_JSON2);
|
|
3347
|
+
if (import_fs6.default.existsSync(infoPath)) {
|
|
3348
|
+
try {
|
|
3349
|
+
const info = JSON.parse(import_fs6.default.readFileSync(infoPath, "utf8"));
|
|
3350
|
+
if (String(info.node_uuid ?? "") === uuid) return import_path7.default.posix.join(NODES_DIR2, dirName);
|
|
3351
|
+
} catch {
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3131
3354
|
}
|
|
3132
|
-
|
|
3355
|
+
return void 0;
|
|
3133
3356
|
}
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3357
|
+
function auditFlowWorkspace(flowDir) {
|
|
3358
|
+
const warnings = [];
|
|
3359
|
+
const doc = readFlowJson2(flowDir);
|
|
3360
|
+
const meta = readMeta2(flowDir) ?? { nodes: {} };
|
|
3361
|
+
const canvasNodeCount = doc.nodes.length;
|
|
3362
|
+
let canvasCodeNodeCount = 0;
|
|
3363
|
+
const missingInMeta = [];
|
|
3364
|
+
const missingCodeFiles = [];
|
|
3365
|
+
const flowUuids = /* @__PURE__ */ new Set();
|
|
3366
|
+
for (const node of doc.nodes) {
|
|
3367
|
+
const uuid = String(node.node_uuid ?? "").trim();
|
|
3368
|
+
if (!uuid) continue;
|
|
3369
|
+
flowUuids.add(uuid);
|
|
3370
|
+
const nodeType = resolveNodeType2(node);
|
|
3371
|
+
if (!isCodeNodeType(nodeType)) continue;
|
|
3372
|
+
canvasCodeNodeCount++;
|
|
3373
|
+
const label = String(node.data?.label ?? node.id ?? "");
|
|
3374
|
+
const m = meta.nodes[uuid];
|
|
3375
|
+
if (!m?.dir || !m.codeFile) {
|
|
3376
|
+
missingInMeta.push({ uuid, nodeId: String(node.id ?? ""), nodeType, label });
|
|
3377
|
+
continue;
|
|
3378
|
+
}
|
|
3379
|
+
const codePath = import_path7.default.join(flowDir, m.dir, m.codeFile);
|
|
3380
|
+
if (!import_fs6.default.existsSync(codePath)) {
|
|
3381
|
+
missingCodeFiles.push({ uuid, dir: m.dir, codeFile: m.codeFile });
|
|
3382
|
+
}
|
|
3383
|
+
}
|
|
3384
|
+
const orphanInMeta = Object.keys(meta.nodes).filter((u) => !flowUuids.has(u));
|
|
3385
|
+
let metaCodeIndexedCount = 0;
|
|
3386
|
+
for (const m of Object.values(meta.nodes)) {
|
|
3387
|
+
if (m.dir && m.codeFile) metaCodeIndexedCount++;
|
|
3388
|
+
}
|
|
3389
|
+
const unindexedDirs = [];
|
|
3390
|
+
for (const dirName of listNodeDirs(flowDir)) {
|
|
3391
|
+
const dirAbs = import_path7.default.join(flowDir, NODES_DIR2, dirName);
|
|
3392
|
+
if (!findCodeFileInDir(dirAbs)) continue;
|
|
3393
|
+
const rel = import_path7.default.posix.join(NODES_DIR2, dirName);
|
|
3394
|
+
const indexed = Object.values(meta.nodes).some((m) => m.dir?.replace(/\\/g, "/") === rel);
|
|
3395
|
+
if (!indexed) unindexedDirs.push(rel);
|
|
3396
|
+
}
|
|
3397
|
+
if (canvasCodeNodeCount !== metaCodeIndexedCount) {
|
|
3398
|
+
warnings.push(
|
|
3399
|
+
`\u753B\u5E03\u4EE3\u7801\u8282\u70B9 ${canvasCodeNodeCount} \u4E2A\uFF0Cmeta \u5DF2\u7D22\u5F15 ${metaCodeIndexedCount} \u4E2A\uFF08\u4E0D\u4E00\u81F4\u4F1A\u5BFC\u81F4 node push / \u8BBE\u8BA1\u5668\u6253\u5F00\u4EE3\u7801\u5931\u8D25\uFF09`
|
|
3400
|
+
);
|
|
3401
|
+
}
|
|
3402
|
+
if (missingInMeta.length) {
|
|
3403
|
+
warnings.push("\u90E8\u5206 flow.json \u4EE3\u7801\u8282\u70B9\u672A\u5199\u5165 flow.meta.json\uFF0C\u8BF7\u6267\u884C project repair-meta");
|
|
3404
|
+
}
|
|
3405
|
+
if (unindexedDirs.length) {
|
|
3406
|
+
warnings.push(`\u5B58\u5728\u672A\u7D22\u5F15\u7684\u8282\u70B9\u76EE\u5F55\uFF1A${unindexedDirs.join(", ")}`);
|
|
3407
|
+
}
|
|
3408
|
+
const ok3 = missingInMeta.length === 0 && orphanInMeta.length === 0 && missingCodeFiles.length === 0 && unindexedDirs.length === 0 && canvasCodeNodeCount === metaCodeIndexedCount;
|
|
3409
|
+
return {
|
|
3410
|
+
ok: ok3,
|
|
3411
|
+
canvasNodeCount,
|
|
3412
|
+
canvasCodeNodeCount,
|
|
3413
|
+
metaIndexedCount: Object.keys(meta.nodes).length,
|
|
3414
|
+
metaCodeIndexedCount,
|
|
3415
|
+
missingInMeta,
|
|
3416
|
+
orphanInMeta,
|
|
3417
|
+
missingCodeFiles,
|
|
3418
|
+
unindexedDirs,
|
|
3419
|
+
warnings
|
|
3154
3420
|
};
|
|
3155
3421
|
}
|
|
3422
|
+
function writeNodeInfo(flowDir, node, uuid, nodeType, relDir, codeFile, language, strippedData) {
|
|
3423
|
+
const abs = import_path7.default.join(flowDir, relDir);
|
|
3424
|
+
import_fs6.default.writeFileSync(
|
|
3425
|
+
import_path7.default.join(abs, NODE_INFO_JSON2),
|
|
3426
|
+
JSON.stringify(
|
|
3427
|
+
{
|
|
3428
|
+
_readonly: `\u6B64\u6587\u4EF6\u7531 dazi-flow \u751F\u6210\uFF0C\u4EC5\u4F9B\u67E5\u770B\uFF1B\u7F16\u8F91\u4EE3\u7801\u8BF7\u6539 ${codeFile}\uFF0C\u914D\u7F6E\u6539 flow.json`,
|
|
3429
|
+
node_uuid: uuid,
|
|
3430
|
+
nodeId: String(node.id ?? ""),
|
|
3431
|
+
nodeType,
|
|
3432
|
+
label: String(node.data?.label ?? ""),
|
|
3433
|
+
codeFile,
|
|
3434
|
+
codeLanguage: language,
|
|
3435
|
+
position: node.position,
|
|
3436
|
+
data: strippedData
|
|
3437
|
+
},
|
|
3438
|
+
null,
|
|
3439
|
+
2
|
|
3440
|
+
),
|
|
3441
|
+
"utf8"
|
|
3442
|
+
);
|
|
3443
|
+
}
|
|
3444
|
+
function repairFlowMeta(flowDir) {
|
|
3445
|
+
const warnings = [];
|
|
3446
|
+
const repairedUuids = [];
|
|
3447
|
+
const wroteNodeInfo = [];
|
|
3448
|
+
const doc = readFlowJson2(flowDir);
|
|
3449
|
+
const meta = readMeta2(flowDir) ?? { flowId: null, flowName: import_path7.default.basename(flowDir), nodes: {} };
|
|
3450
|
+
if (!meta.nodes) meta.nodes = {};
|
|
3451
|
+
const usedDirNames = new Set(
|
|
3452
|
+
Object.values(meta.nodes).map((m) => m.dir?.split("/").pop()).filter(Boolean)
|
|
3453
|
+
);
|
|
3454
|
+
for (const node of doc.nodes) {
|
|
3455
|
+
const uuid = String(node.node_uuid ?? "").trim();
|
|
3456
|
+
if (!uuid) continue;
|
|
3457
|
+
const nodeType = resolveNodeType2(node);
|
|
3458
|
+
const codeKey = NODE_TYPE_CODE_DATA_KEY2[nodeType];
|
|
3459
|
+
const semanticId = String(node.id ?? "");
|
|
3460
|
+
const label = String(node.data?.label ?? semanticId ?? nodeType);
|
|
3461
|
+
let entry = meta.nodes[uuid];
|
|
3462
|
+
if (!entry) {
|
|
3463
|
+
entry = { nodeId: semanticId, nodeType };
|
|
3464
|
+
meta.nodes[uuid] = entry;
|
|
3465
|
+
repairedUuids.push(uuid);
|
|
3466
|
+
} else {
|
|
3467
|
+
entry.nodeId = semanticId || entry.nodeId;
|
|
3468
|
+
entry.nodeType = nodeType;
|
|
3469
|
+
}
|
|
3470
|
+
if (!codeKey) continue;
|
|
3471
|
+
let relDir = entry.dir?.replace(/\\/g, "/");
|
|
3472
|
+
if (relDir && findCodeFileInDir(import_path7.default.join(flowDir, relDir))) {
|
|
3473
|
+
} else {
|
|
3474
|
+
relDir = findDirForUuid(flowDir, uuid);
|
|
3475
|
+
}
|
|
3476
|
+
if (!relDir) {
|
|
3477
|
+
const byLabel = import_path7.default.posix.join(NODES_DIR2, sanitizeName2(label));
|
|
3478
|
+
if (import_fs6.default.existsSync(import_path7.default.join(flowDir, byLabel)) && findCodeFileInDir(import_path7.default.join(flowDir, byLabel))) {
|
|
3479
|
+
relDir = byLabel;
|
|
3480
|
+
}
|
|
3481
|
+
}
|
|
3482
|
+
if (!relDir) {
|
|
3483
|
+
let dirName = sanitizeName2(label);
|
|
3484
|
+
if (usedDirNames.has(dirName)) dirName = `${dirName}_${uuid.slice(0, 6)}`;
|
|
3485
|
+
usedDirNames.add(dirName);
|
|
3486
|
+
relDir = import_path7.default.posix.join(NODES_DIR2, dirName);
|
|
3487
|
+
import_fs6.default.mkdirSync(import_path7.default.join(flowDir, relDir), { recursive: true });
|
|
3488
|
+
const lang = codeLanguageForNodeType2(nodeType);
|
|
3489
|
+
const codeFile2 = `code.${codeFileExt2(lang)}`;
|
|
3490
|
+
const template = nodeType === "excel-python" ? "# -*- coding: utf-8 -*-\n# Excel \u8282\u70B9\uFF1A\u753B\u5E03\u914D\u7F6E managed_file_id\uFF1B\u4EE3\u7801\u4F7F\u7528 excel_source_path\n" : lang === "sql" ? "-- \u8282\u70B9 SQL\nSELECT 1;\n" : "# -*- coding: utf-8 -*-\n";
|
|
3491
|
+
if (!findCodeFileInDir(import_path7.default.join(flowDir, relDir))) {
|
|
3492
|
+
import_fs6.default.writeFileSync(import_path7.default.join(flowDir, relDir, codeFile2), template, "utf8");
|
|
3493
|
+
warnings.push(`\u5DF2\u4E3A ${uuid} \u521B\u5EFA\u7A7A\u4EE3\u7801\u6A21\u677F ${relDir}/${codeFile2}`);
|
|
3494
|
+
}
|
|
3495
|
+
}
|
|
3496
|
+
const dirAbs = import_path7.default.join(flowDir, relDir);
|
|
3497
|
+
const codeFile = findCodeFileInDir(dirAbs);
|
|
3498
|
+
if (!codeFile) {
|
|
3499
|
+
warnings.push(`\u8282\u70B9 ${uuid} \u76EE\u5F55 ${relDir} \u65E0 code.*\uFF0C\u8DF3\u8FC7\u4EE3\u7801\u7D22\u5F15`);
|
|
3500
|
+
continue;
|
|
3501
|
+
}
|
|
3502
|
+
const language = codeLanguageForNodeType2(nodeType);
|
|
3503
|
+
const code = import_fs6.default.readFileSync(import_path7.default.join(dirAbs, codeFile), "utf8");
|
|
3504
|
+
entry.dir = relDir;
|
|
3505
|
+
entry.codeFile = codeFile;
|
|
3506
|
+
entry.codeLanguage = language;
|
|
3507
|
+
entry.codeHash = sha12(code);
|
|
3508
|
+
const strippedData = { ...node.data ?? {} };
|
|
3509
|
+
delete strippedData[codeKey];
|
|
3510
|
+
const infoPath = import_path7.default.join(dirAbs, NODE_INFO_JSON2);
|
|
3511
|
+
if (!import_fs6.default.existsSync(infoPath)) {
|
|
3512
|
+
writeNodeInfo(flowDir, node, uuid, nodeType, relDir, codeFile, language, strippedData);
|
|
3513
|
+
wroteNodeInfo.push(relDir);
|
|
3514
|
+
}
|
|
3515
|
+
if (!repairedUuids.includes(uuid)) repairedUuids.push(uuid);
|
|
3516
|
+
}
|
|
3517
|
+
meta.graphFingerprint = "sha1:" + sha12(JSON.stringify({ nodes: doc.nodes, edges: doc.edges }));
|
|
3518
|
+
import_fs6.default.writeFileSync(import_path7.default.join(flowDir, FLOW_META_JSON2), JSON.stringify(meta, null, 2), "utf8");
|
|
3519
|
+
const okAfter = auditFlowWorkspace(flowDir).ok;
|
|
3520
|
+
return {
|
|
3521
|
+
ok: okAfter,
|
|
3522
|
+
repairedUuids: [...new Set(repairedUuids)],
|
|
3523
|
+
wroteNodeInfo,
|
|
3524
|
+
warnings
|
|
3525
|
+
};
|
|
3526
|
+
}
|
|
3527
|
+
function buildFlowConsistencyMarkdown(audit, localFilesSpecLink = "../../\u8D44\u6E90/docs/flow/local-files-spec.md") {
|
|
3528
|
+
const lines = [
|
|
3529
|
+
"## \u672C\u5730\u6587\u4EF6\u4E00\u81F4\u6027",
|
|
3530
|
+
"",
|
|
3531
|
+
"| \u6307\u6807 | \u6570\u91CF |",
|
|
3532
|
+
"|------|------|",
|
|
3533
|
+
`| \u753B\u5E03\u8282\u70B9\uFF08flow.json\uFF09 | ${audit.canvasNodeCount} |`,
|
|
3534
|
+
`| \u753B\u5E03\u4EE3\u7801\u8282\u70B9\uFF08flow.json\uFF09 | ${audit.canvasCodeNodeCount} |`,
|
|
3535
|
+
`| meta \u5DF2\u767B\u8BB0\u8282\u70B9 | ${audit.metaIndexedCount} |`,
|
|
3536
|
+
`| meta \u5DF2\u7D22\u5F15\u4EE3\u7801\uFF08dir+codeFile\uFF09 | ${audit.metaCodeIndexedCount} |`,
|
|
3537
|
+
""
|
|
3538
|
+
];
|
|
3539
|
+
if (audit.ok) {
|
|
3540
|
+
lines.push("\u2705 **flow.json / flow.meta.json / \u8282\u70B9/ \u4E00\u81F4**\u3002\u8BBE\u8BA1\u5668\u53EF\u6B63\u5E38\u300C\u6253\u5F00\u4EE3\u7801\u300D\uFF0C`node push` \u53EF\u8BC6\u522B\u810F\u8282\u70B9\u3002", "");
|
|
3541
|
+
} else {
|
|
3542
|
+
lines.push("\u26A0\uFE0F **\u76EE\u5F55\u4E0D\u4E00\u81F4**\uFF08\u4F1A\u5BFC\u81F4\u8BBE\u8BA1\u5668\u627E\u4E0D\u5230\u4EE3\u7801\u3001\u6216 `node push` \u8DF3\u8FC7\uFF09\uFF1A", "");
|
|
3543
|
+
if (audit.missingInMeta.length) {
|
|
3544
|
+
lines.push("| uuid | \u8282\u70B9 | \u7C7B\u578B |");
|
|
3545
|
+
lines.push("|------|------|------|");
|
|
3546
|
+
for (const m of audit.missingInMeta) {
|
|
3547
|
+
lines.push(`| \`${m.uuid.slice(0, 8)}\u2026\` | ${m.label || m.nodeId} | ${m.nodeType} |`);
|
|
3548
|
+
}
|
|
3549
|
+
lines.push("");
|
|
3550
|
+
}
|
|
3551
|
+
if (audit.unindexedDirs.length) {
|
|
3552
|
+
lines.push(`- \u672A\u7D22\u5F15\u76EE\u5F55\uFF1A${audit.unindexedDirs.map((d) => `\`${d}\``).join(" ")}`);
|
|
3553
|
+
}
|
|
3554
|
+
if (audit.orphanInMeta.length) {
|
|
3555
|
+
lines.push(`- meta \u591A\u4F59 uuid\uFF1A${audit.orphanInMeta.length} \u4E2A\uFF08flow.json \u4E2D\u5DF2\u4E0D\u5B58\u5728\uFF09`);
|
|
3556
|
+
}
|
|
3557
|
+
for (const w of audit.warnings) lines.push(`- ${w}`);
|
|
3558
|
+
lines.push(
|
|
3559
|
+
"",
|
|
3560
|
+
"\u4FEE\u590D\uFF08\u5728\u6D41\u7A0B\u76EE\u5F55\uFF09\uFF1A",
|
|
3561
|
+
"",
|
|
3562
|
+
"```powershell",
|
|
3563
|
+
"dazi flow project repair-meta --dir .",
|
|
3564
|
+
"dazi flow project doctor --dir .",
|
|
3565
|
+
"```",
|
|
3566
|
+
"",
|
|
3567
|
+
`\u8BE6\u89C1 [\u6D41\u7A0B\u672C\u5730\u6587\u4EF6\u89C4\u8303](${localFilesSpecLink})\u3002`,
|
|
3568
|
+
""
|
|
3569
|
+
);
|
|
3570
|
+
}
|
|
3571
|
+
lines.push(
|
|
3572
|
+
"## \u53D8\u66F4\u63D0\u4EA4\u547D\u4EE4\u77E9\u9635",
|
|
3573
|
+
"",
|
|
3574
|
+
"| \u6539\u4E86\u4EC0\u4E48 | \u547D\u4EE4 |",
|
|
3575
|
+
"|----------|------|",
|
|
3576
|
+
"| `managed_file_id`\u3001`output_variable_name`\u3001\u8FDE\u7EBF\u3001\u589E\u5220\u8282\u70B9 | `dazi flow project push --dir . --canvas` |",
|
|
3577
|
+
"| `\u8282\u70B9/<\u540D>/code.py` \u6216 `code.sql` | `dazi flow node push --node <uuid> --dir .` |",
|
|
3578
|
+
'| **\u65B0\u589E\u4EE3\u7801\u8282\u70B9** | `dazi flow node new --type <type> --dir . --label "<\u540D>"` \u2192 \u6539\u914D\u7F6E \u2192 `push --canvas` \u2192 \u5199 code \u2192 `node push` |',
|
|
3579
|
+
"",
|
|
3580
|
+
"> \u7981\u6B62\u53EA\u6539 `flow.json` \u800C\u4E0D\u66F4\u65B0 `flow.meta.json`\uFF08\u987B `node new` / `pull` / `repair-meta`\uFF09\u3002",
|
|
3581
|
+
""
|
|
3582
|
+
);
|
|
3583
|
+
return lines;
|
|
3584
|
+
}
|
|
3585
|
+
var import_crypto2, import_fs6, import_path7, NODES_DIR2, FLOW_JSON2, FLOW_META_JSON2, NODE_INFO_JSON2, NODE_TYPE_CODE_DATA_KEY2;
|
|
3586
|
+
var init_flowWorkspaceAudit = __esm({
|
|
3587
|
+
"src/shared/flowWorkspaceAudit.ts"() {
|
|
3588
|
+
"use strict";
|
|
3589
|
+
import_crypto2 = __toESM(require("crypto"));
|
|
3590
|
+
import_fs6 = __toESM(require("fs"));
|
|
3591
|
+
import_path7 = __toESM(require("path"));
|
|
3592
|
+
NODES_DIR2 = "\u8282\u70B9";
|
|
3593
|
+
FLOW_JSON2 = "flow.json";
|
|
3594
|
+
FLOW_META_JSON2 = "flow.meta.json";
|
|
3595
|
+
NODE_INFO_JSON2 = "node.info.json";
|
|
3596
|
+
NODE_TYPE_CODE_DATA_KEY2 = {
|
|
3597
|
+
"database-source": "sql",
|
|
3598
|
+
"dataspace-source": "sql",
|
|
3599
|
+
"python-script": "pythonCode",
|
|
3600
|
+
"excel-python": "pythonCode",
|
|
3601
|
+
"sql-query": "sql",
|
|
3602
|
+
condition: "pythonCode",
|
|
3603
|
+
"data-quality-check": "dqPythonCode"
|
|
3604
|
+
};
|
|
3605
|
+
}
|
|
3606
|
+
});
|
|
3156
3607
|
|
|
3157
|
-
//
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3608
|
+
// src/shared/flowScaffoldDocs.js
|
|
3609
|
+
var require_flowScaffoldDocs = __commonJS({
|
|
3610
|
+
"src/shared/flowScaffoldDocs.js"(exports2) {
|
|
3611
|
+
"use strict";
|
|
3612
|
+
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
3613
|
+
return mod && mod.__esModule ? mod : { "default": mod };
|
|
3614
|
+
};
|
|
3615
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3616
|
+
exports2.writeScaffoldIfAllowed = exports2.buildFlowProjectReadmeHelpSection = exports2.removeLegacyFlowDirScaffoldReadme = exports2.resolveFlowRootFromFlowDir = exports2.removeLegacyFlowRootQuickStart = exports2.resolveFlowDirQuickStartPath = exports2.writeFlowDirQuickStartScaffold = exports2.removeLegacyFlowDirQuickStartFiles = exports2.buildFlowDirReadmeMarkdown = exports2.buildFlowDirQuickStartMarkdown = exports2.buildFlowsDirReadmeMarkdown = exports2.buildFlowQuickStartMarkdown = exports2.buildFlowRootReadmeMarkdown = exports2.isLegacyFlowScaffoldFile = exports2.isFlowScaffoldFile = exports2.flowDirQuickStartFilename = exports2.sanitizeFlowNameForFilename = exports2.FLOW_DIR_QUICKSTART_FILENAME = exports2.LEGACY_FLOW_DIR_QUICKSTART_FILENAME = exports2.LEGACY_FLOW_ROOT_QUICKSTART_FILENAME = exports2.FLOW_ROOT_README_FILENAME = exports2.flowDocsRel = void 0;
|
|
3617
|
+
var path_1 = __importDefault(require("path"));
|
|
3618
|
+
var flowNodeCatalog_1 = (init_flowNodeCatalog(), __toCommonJS(flowNodeCatalog_exports));
|
|
3619
|
+
var flowCliText_1 = (init_flowCliText(), __toCommonJS(flowCliText_exports));
|
|
3620
|
+
var flowWorkspaceAudit_1 = (init_flowWorkspaceAudit(), __toCommonJS(flowWorkspaceAudit_exports));
|
|
3621
|
+
var DEPTH = {
|
|
3622
|
+
"project-root": 2,
|
|
3623
|
+
"flows-dir": 3,
|
|
3624
|
+
"flow-dir": 4
|
|
3625
|
+
};
|
|
3626
|
+
function flowDocsRel(anchor, docPath) {
|
|
3627
|
+
const prefix = "../".repeat(DEPTH[anchor]);
|
|
3628
|
+
return `${prefix}\u8D44\u6E90/docs/${docPath}`;
|
|
3629
|
+
}
|
|
3630
|
+
exports2.flowDocsRel = flowDocsRel;
|
|
3631
|
+
var SCAFFOLD_MARKER = "<!-- dazi-flow-scaffold -->";
|
|
3632
|
+
exports2.FLOW_ROOT_README_FILENAME = "README.md";
|
|
3633
|
+
exports2.LEGACY_FLOW_ROOT_QUICKSTART_FILENAME = "\u5FEB\u901F\u542F\u52A8.md";
|
|
3634
|
+
exports2.LEGACY_FLOW_DIR_QUICKSTART_FILENAME = "\u5FEB\u901F\u542F\u52A8.md";
|
|
3635
|
+
exports2.FLOW_DIR_QUICKSTART_FILENAME = exports2.LEGACY_FLOW_DIR_QUICKSTART_FILENAME;
|
|
3636
|
+
function sanitizeFlowNameForFilename(flowName) {
|
|
3637
|
+
const safe = flowName.trim().replace(/[\\/:*?"<>|]/g, "_").replace(/\s+/g, "_").replace(/_+/g, "_").replace(/^\.+/, "").slice(0, 80);
|
|
3638
|
+
return safe || "flow";
|
|
3639
|
+
}
|
|
3640
|
+
exports2.sanitizeFlowNameForFilename = sanitizeFlowNameForFilename;
|
|
3641
|
+
function flowDirQuickStartFilename(flowName) {
|
|
3642
|
+
return `\u5FEB\u901F\u542F\u52A8_${sanitizeFlowNameForFilename(flowName)}.md`;
|
|
3643
|
+
}
|
|
3644
|
+
exports2.flowDirQuickStartFilename = flowDirQuickStartFilename;
|
|
3645
|
+
function isFlowScaffoldFile(content) {
|
|
3646
|
+
return content.includes(SCAFFOLD_MARKER);
|
|
3647
|
+
}
|
|
3648
|
+
exports2.isFlowScaffoldFile = isFlowScaffoldFile;
|
|
3649
|
+
function isLegacyFlowScaffoldFile(content) {
|
|
3650
|
+
if (isFlowScaffoldFile(content))
|
|
3651
|
+
return false;
|
|
3652
|
+
return content.includes("dazi-flow project pull") || content.includes("dazi-flow node push") || content.includes("\u89C1 \xA7335") || content.includes("# \u6D41\u7A0B") && content.includes("dazi-flow project pull");
|
|
3653
|
+
}
|
|
3654
|
+
exports2.isLegacyFlowScaffoldFile = isLegacyFlowScaffoldFile;
|
|
3655
|
+
function buildDocsTable(anchor) {
|
|
3656
|
+
const rows = [
|
|
3657
|
+
["Flow \u6587\u6863\u7D22\u5F15\uFF08\u4ECE\u8FD9\u91CC\u5F00\u59CB\uFF09", "flow/flows-guide.md"],
|
|
3658
|
+
["\u6570\u636E\u6D41\u7A0B\u9879\u76EE\u5F00\u53D1\u6307\u5357", "flow/flow-project-guide.md"],
|
|
3659
|
+
["\u6D41\u7A0B\u53D8\u91CF\u7CFB\u7EDF\u6307\u5357", "flow/variables-guide.md"],
|
|
3660
|
+
["\u8282\u70B9\u4EE3\u7801\u7F16\u5199\u6307\u5357\uFF08\u542B SQL/Python \u793A\u4F8B\uFF09", "flow/node-code-guide.md"],
|
|
3661
|
+
["Flow \u8FD0\u884C\u4E0E\u6D4B\u8BD5", "flow/run-guide.md"],
|
|
3662
|
+
["\u6570\u636E\u6E90\u4E0E connectionId", "flow/source-guide.md"],
|
|
3663
|
+
["**\u6D41\u7A0B\u672C\u5730\u6587\u4EF6\u89C4\u8303\uFF08AI \u5FC5\u8BFB\uFF09**", "flow/local-files-spec.md"],
|
|
3664
|
+
["\u6D41\u7A0B AI \u5DE5\u4F5C\u624B\u518C", "flow/ai-workflow-playbook.md"],
|
|
3665
|
+
["CLI \u8C03\u7528\u7EA6\u5B9A\uFF08`dazi` / `dazi.ps1`\uFF09", "guides/cli-invocation.md"]
|
|
3666
|
+
];
|
|
3667
|
+
return [
|
|
3668
|
+
"## \u5E2E\u52A9\u6587\u6863",
|
|
3669
|
+
"",
|
|
3670
|
+
"\u5DE5\u4F5C\u533A\u6587\u6863\u4F4D\u4E8E **`\u8D44\u6E90/docs/`**\uFF08\u6269\u5C55\u4FA7\u680F **\u5E2E\u52A9 \u2192 \u4E0B\u8F7D\u6240\u6709\u6587\u6863**\uFF0C\u6216\u5728\u5DE5\u4F5C\u533A\u6839\u6267\u884C `dazi docs sync`\uFF09\uFF1A",
|
|
3671
|
+
"",
|
|
3672
|
+
"| \u6587\u6863 | \u94FE\u63A5 |",
|
|
3673
|
+
"|------|------|",
|
|
3674
|
+
...rows.map(([title, p]) => `| ${title} | [${p.split("/").pop()}](${flowDocsRel(anchor, p)}) |`),
|
|
3675
|
+
"",
|
|
3676
|
+
"\u7EC8\u7AEF\u6253\u5F00\u6587\u6863\uFF08**dazi-work \u6839**\u6216\u5DF2 `cd` \u5230\u6D41\u7A0B\u76EE\u5F55\uFF09\uFF1A",
|
|
3677
|
+
"",
|
|
3678
|
+
"```powershell",
|
|
3679
|
+
(0, flowCliText_1.psDaziLine)("docs open flow/flow-project-guide"),
|
|
3680
|
+
(0, flowCliText_1.psDaziLine)("docs open flow/variables-guide"),
|
|
3681
|
+
(0, flowCliText_1.psDaziLine)("docs open flow/node-code-guide"),
|
|
3682
|
+
(0, flowCliText_1.psDaziLine)("docs open flow/flows-guide"),
|
|
3683
|
+
"```",
|
|
3684
|
+
"",
|
|
3685
|
+
"**\u4EE3\u7801\u793A\u4F8B**\uFF1A\u53D8\u91CF\u8BFB\u5199\u3001`python-script` / `sql-query` \u6A21\u677F\u89C1 [\u8282\u70B9\u4EE3\u7801\u7F16\u5199\u6307\u5357](" + flowDocsRel(anchor, "flow/node-code-guide.md") + ") \u4E0E [\u6D41\u7A0B\u53D8\u91CF\u7CFB\u7EDF\u6307\u5357](" + flowDocsRel(anchor, "flow/variables-guide.md") + ")\u3002",
|
|
3686
|
+
""
|
|
3687
|
+
];
|
|
3688
|
+
}
|
|
3689
|
+
function psPath(p) {
|
|
3690
|
+
return p.replace(/\//g, "\\");
|
|
3691
|
+
}
|
|
3692
|
+
function buildFlowDirRelPath(projectFolder, flowName) {
|
|
3693
|
+
const folder = projectFolder ?? "<\u4E1A\u52A1\u9879\u76EE\u540D>";
|
|
3694
|
+
return `\u9879\u76EE/${folder}/\u6D41\u7A0B/flows/${flowName}`;
|
|
3695
|
+
}
|
|
3696
|
+
function buildFlowCliDirSection(opts) {
|
|
3697
|
+
const relPs = psPath(buildFlowDirRelPath(opts.projectFolder, opts.flowName));
|
|
3698
|
+
const absDir = opts.flowDir ? psPath(path_1.default.resolve(opts.flowDir)) : `D:\\path\\to\\dazi-work\\${relPs}`;
|
|
3699
|
+
return [
|
|
3700
|
+
"## CLI \u8C03\u7528\u7EA6\u5B9A\uFF08\u5FC5\u8BFB\uFF09",
|
|
3701
|
+
"",
|
|
3702
|
+
"> **`--dir` \u5FC5\u987B\u6307\u5411\u542B `flow.json` \u7684\u6D41\u7A0B\u76EE\u5F55**\uFF08\u5373\u672C\u76EE\u5F55\uFF09\u3002",
|
|
3703
|
+
"> **\u7981\u6B62**\u5728 `dazi-work` **\u5DE5\u4F5C\u533A\u6839**\u6267\u884C `dazi flow project status/push/pull ... --dir .`",
|
|
3704
|
+
"> \uFF08\u6839\u76EE\u5F55\u53EF\u80FD\u6B8B\u7559\u9519\u8BEF\u7684 `flow.meta.json`\uFF0C\u6216 Agent \u8BEF\u8BFB\u5176\u4ED6\u6D41\u7A0B\u7684 meta\uFF0C\u5BFC\u81F4 **flowId \u4E0E\u6D41\u7A0B\u540D\u4E0D\u4E00\u81F4**\uFF09\u3002",
|
|
3705
|
+
"",
|
|
3706
|
+
"### \u63A8\u8350\uFF1A\u7EDD\u5BF9\u8DEF\u5F84\uFF08Trae / Agent \u9996\u9009\uFF09",
|
|
3707
|
+
"",
|
|
3708
|
+
"\u4E0D\u4F9D\u8D56\u7EC8\u7AEF\u5F53\u524D\u76EE\u5F55\uFF0C\u907F\u514D `cd` \u5230\u9519\u8BEF\u6D41\u7A0B\uFF1A",
|
|
3709
|
+
"",
|
|
3710
|
+
"```powershell",
|
|
3711
|
+
(0, flowCliText_1.psFlowLine)(`project status --dir "${absDir}"`),
|
|
3712
|
+
(0, flowCliText_1.psFlowLine)(`project pull --flow ${opts.flowId} --dir "${absDir}"`),
|
|
3713
|
+
(0, flowCliText_1.psFlowLine)(`project push --dir "${absDir}" --canvas`),
|
|
3714
|
+
(0, flowCliText_1.psFlowLine)(`run node-exec --node <node_uuid> --dir "${absDir}"`),
|
|
3715
|
+
(0, flowCliText_1.psFlowLine)(`run flow-exec --dir "${absDir}" --type debug`),
|
|
3716
|
+
(0, flowCliText_1.psFlowLine)(`variable sync --dir "${absDir}"`),
|
|
3717
|
+
"```",
|
|
3718
|
+
"",
|
|
3719
|
+
"### \u53EF\u9009\uFF1A\u5148 cd \u518D `--dir .`",
|
|
3720
|
+
"",
|
|
3721
|
+
"\u4EC5\u5F53\u7EC8\u7AEF **\u5DF2\u786E\u8BA4** \u5728\u5F53\u524D\u6D41\u7A0B\u76EE\u5F55\u65F6\uFF1A",
|
|
3722
|
+
"",
|
|
3723
|
+
"```powershell",
|
|
3724
|
+
`cd "${absDir}"`,
|
|
3725
|
+
(0, flowCliText_1.psFlowLine)("project status --dir ."),
|
|
3726
|
+
(0, flowCliText_1.psFlowLine)(`project pull --flow ${opts.flowId} --dir .`),
|
|
3727
|
+
"```",
|
|
3728
|
+
"",
|
|
3729
|
+
"**\u81EA\u68C0**\uFF1A`status` \u8F93\u51FA\u987B\u540C\u65F6\u5339\u914D\u672C\u9875 **flowId** \u4E0E **\u6D41\u7A0B\u540D**\uFF1B\u82E5\u51FA\u73B0\u5176\u4ED6\u6D41\u7A0B\u540D\uFF0C\u8BF4\u660E `--dir` \u6216 `cd` \u9519\u8BEF\u3002",
|
|
3730
|
+
""
|
|
3731
|
+
];
|
|
3732
|
+
}
|
|
3733
|
+
function cliPrefix() {
|
|
3734
|
+
return `\`${flowCliText_1.DAZI_CLI} flow\`\uFF08\u5168\u5C40 CLI\uFF1B\`--dir\` \u6307\u5411 **\u6D41\u7A0B\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84**\uFF1B\u672A\u88C5\u5168\u5C40\u65F6\u53EF\u7528 \`.scriptsdazi.ps1 flow\`\uFF09`;
|
|
3735
|
+
}
|
|
3736
|
+
function buildFlowRootReadmeMarkdown2(opts) {
|
|
3737
|
+
const folder = opts.projectFolder;
|
|
3738
|
+
return [
|
|
3739
|
+
SCAFFOLD_MARKER,
|
|
3740
|
+
"# \u6D41\u7A0B",
|
|
3741
|
+
"",
|
|
3742
|
+
`\u672C\u76EE\u5F55\u4E3A\u4E1A\u52A1\u9879\u76EE **\`${folder}\`** \u7684\u6570\u636E\u6D41\u7A0B\u5DE5\u4F5C\u533A\u3002`,
|
|
3743
|
+
"",
|
|
3744
|
+
"## 1. \u76EE\u5F55\u7ED3\u6784",
|
|
3745
|
+
"",
|
|
3746
|
+
"| \u8DEF\u5F84 | \u8BF4\u660E |",
|
|
3747
|
+
"|------|------|",
|
|
3748
|
+
"| `\u89C4\u5212/` | \u6D41\u7A0B\u8BBE\u8BA1\u6587\u6863\uFF08\u6570\u636E\u6E90\u3001\u62D3\u6251\u8349\u6848\u7B49\uFF09 |",
|
|
3749
|
+
"| `flows/` | \u5404\u6D41\u7A0B\u5B9E\u4F8B\u76EE\u5F55\uFF08`flow.json`\u3001`\u8282\u70B9/`\u3001`\u53D8\u91CF/`\uFF09 |",
|
|
3750
|
+
"",
|
|
3751
|
+
"\u5355\u4E2A\u6D41\u7A0B\u4F4D\u4E8E `flows/<\u6D41\u7A0B\u540D>/`\uFF1A",
|
|
3752
|
+
"",
|
|
3753
|
+
"| \u8DEF\u5F84 | \u8BF4\u660E |",
|
|
3754
|
+
"|------|------|",
|
|
3755
|
+
"| `flow.json` | \u753B\u5E03\u771F\u7406\u6E90\uFF08\u8282\u70B9\u914D\u7F6E + \u8FDE\u7EBF\uFF0C\u4EE3\u7801\u5DF2\u5265\u79BB\uFF09 |",
|
|
3756
|
+
"| `flow.meta.json` | flowId\u3001node_uuid \u6620\u5C04\uFF08CLI \u7EF4\u62A4\uFF0C\u52FF\u624B\u6539\uFF09 |",
|
|
3757
|
+
"| `\u8282\u70B9/<\u540D>/code.*` | SQL / Python \u8282\u70B9\u4EE3\u7801 |",
|
|
3758
|
+
"| `\u53D8\u91CF/<\u540D>.json` | \u8C03\u8BD5 Run \u53D8\u91CF\u9884\u89C8\uFF08\u53EA\u8BFB\uFF0Cpull/sync \u751F\u6210\uFF09 |",
|
|
3759
|
+
"| `_run/` | \u6D4B\u8BD5/\u8FD0\u884C\u4EA7\u7269\uFF08`*.last-error.md` \u7B49\uFF09 |",
|
|
3760
|
+
"",
|
|
3761
|
+
"> \u6D41\u7A0B**\u4E0D\u7ED1\u5B9A\u6570\u636E\u7A7A\u95F4**\uFF1B`connectionId` \u4EC5\u4E3A\u6570\u636E\u5E93\u8282\u70B9\u7684\u914D\u7F6E\u5B57\u6BB5\u3002",
|
|
3762
|
+
"",
|
|
3763
|
+
"## 2. \u65B0\u5EFA / \u62C9\u53D6\u6D41\u7A0B",
|
|
3764
|
+
"",
|
|
3765
|
+
"\u8D44\u6E90\u7BA1\u7406\u5668\uFF08\u63A8\u8350 **\u8868\u5355**\uFF09\uFF1A",
|
|
3766
|
+
"",
|
|
3767
|
+
"| \u64CD\u4F5C | \u83DC\u5355 |",
|
|
3768
|
+
"|------|------|",
|
|
3769
|
+
"| \u65B0\u5EFA\u6D41\u7A0B | \u53F3\u952E **`\u6D41\u7A0B/flows/`**\uFF08\u6216\u5176\u5B50\u76EE\u5F55\uFF09\u2192 **\u65B0\u5EFA\u6D41\u7A0B** |",
|
|
3770
|
+
"| \u62C9\u53D6\u5E73\u53F0\u6D41\u7A0B | \u53F3\u952E **`\u6D41\u7A0B/flows/`**\uFF08\u6216\u5176\u5B50\u76EE\u5F55\uFF09\u2192 **\u62C9\u53D6\u5E73\u53F0\u6D41\u7A0B** |",
|
|
3771
|
+
"",
|
|
3772
|
+
"\u62C9\u53D6\u8868\u5355\u53EF\u4ECE\u5E73\u53F0 Flow \u5217\u8868\u9009\u62E9\uFF0C\u6216\u624B\u52A8\u586B\u5199 Flow ID\uFF1B\u65B0\u5EFA\u8868\u5355\u586B\u5199\u540D\u79F0\u4E0E\u8BF4\u660E\u540E\u81EA\u52A8\u521B\u5EFA\u5E76\u62C9\u53D6\u3002",
|
|
3773
|
+
"",
|
|
3774
|
+
"> **\u7981\u6B62**\u5728 `dazi-work` \u5DE5\u4F5C\u533A\u6839\u5BF9\u6D41\u7A0B\u547D\u4EE4\u4F7F\u7528 `--dir .`\uFF1B`--dir` \u987B\u6307\u5411 `flows/<\u6D41\u7A0B\u540D>/`\uFF08\u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84\uFF09\u3002",
|
|
3775
|
+
"",
|
|
3776
|
+
"\u547D\u4EE4\u884C\uFF08`--dir` \u4F7F\u7528\u7EDD\u5BF9\u8DEF\u5F84\u6216\u76F8\u5BF9 `dazi-work` \u6839\uFF09\uFF1A",
|
|
3777
|
+
"",
|
|
3778
|
+
"```powershell",
|
|
3779
|
+
(0, flowCliText_1.psFlowLine)('project pull --flow <flowId> --dir "D:\\path\\to\\dazi-work\\\u9879\u76EE\\' + folder + '\\\u6D41\u7A0B\\flows\\<\u6D41\u7A0B\u540D>"'),
|
|
3780
|
+
"```",
|
|
3781
|
+
"",
|
|
3782
|
+
"\u62C9\u53D6\u540E\u6BCF\u4E2A\u6D41\u7A0B\u76EE\u5F55\u4F1A\u751F\u6210 **`\u5FEB\u901F\u542F\u52A8_<\u6D41\u7A0B\u540D>.md`**\uFF08\u542B flowId \u4E0E\u672C\u6D41\u7A0B\u5E38\u7528\u547D\u4EE4\uFF0C\u4FBF\u4E8E @ \u9644\u52A0\u7ED9 AI\uFF09\u3002",
|
|
3783
|
+
"",
|
|
3784
|
+
"## 3. \u5F00\u53D1\u4E0E\u63D0\u4EA4",
|
|
3785
|
+
"",
|
|
3786
|
+
"1. \u7F16\u8F91 `\u8282\u70B9/<\u540D>/code.sql` \u6216 `code.py`",
|
|
3787
|
+
"2. \u53F3\u952E **\u6D4B\u8BD5\u8FD0\u884C\u8282\u70B9** \u6216 `flow run node-exec --node <uuid>`",
|
|
3788
|
+
"3. \u53F3\u952E **\u63D0\u4EA4\u8282\u70B9** / **\u63D0\u4EA4\u6D41\u7A0B** \u6216 `flow node push` / `flow project push --canvas`",
|
|
3789
|
+
"4. \u67E5\u770B\u8868\u53D8\u91CF\uFF1A\u8BBE\u8BA1\u5668 **output_variable_name** \u65C1 \u{1F4CA}\uFF0C\u6216 `flow variable pull --name <\u540D>`",
|
|
3790
|
+
"",
|
|
3791
|
+
"\u547D\u4EE4\u524D\u7F00\uFF1A" + cliPrefix(),
|
|
3792
|
+
"",
|
|
3793
|
+
"## 4. \u63A8\u8350\u5F00\u53D1\u5FAA\u73AF",
|
|
3794
|
+
"",
|
|
3795
|
+
"\u8BE6\u89C1 [\u6570\u636E\u6D41\u7A0B\u9879\u76EE\u5F00\u53D1\u6307\u5357](" + flowDocsRel("project-root", "flow/flow-project-guide.md") + ") \xA74\u3002",
|
|
3796
|
+
"",
|
|
3797
|
+
"## 5. AI \u63D0\u793A\u8BCD\u63A8\u8350",
|
|
3798
|
+
"",
|
|
3799
|
+
"| \u573A\u666F | \u63D0\u793A\u8BCD ID |",
|
|
3800
|
+
"|------|-----------|",
|
|
3801
|
+
"| \u8BBE\u8BA1/\u65B0\u589E\u6D41\u7A0B | `flow/flow-design` |",
|
|
3802
|
+
"| **\u8FD0\u884C\u5931\u8D25\u3001\u81EA\u4E3B\u6539\u9519** | **`flow/run-fix-loop`**\uFF08\u2B50 \u9996\u9009\uFF09 |",
|
|
3803
|
+
"| \u5206\u6790\u7528\u6237\u7C98\u8D34\u7684\u9519\u8BEF | `flow/run-debug` |",
|
|
3804
|
+
"",
|
|
3805
|
+
"\u4FA7\u680F **\u5E2E\u52A9 \u2192 \u{1F916} \u63D0\u793A\u8BCD** \u4E2D \u2B50 \u4E3A\u6D41\u7A0B\u63A8\u8350\u3002\u53F3\u952E **`flow.json`** \u2192 **\u6253\u5F00 AI \u6539\u9519\u63D0\u793A\u8BCD**\u3002",
|
|
3806
|
+
"\u7ED9 AI \u7684\u4EFB\u52A1\u793A\u4F8B\uFF1A\u300C\u6539 XX \u8282\u70B9\uFF0C\u81EA\u5DF1\u8DD1\u6D4B\u8BD5\uFF0C\u5931\u8D25\u6309 last-error \u6539\u5230\u901A\u8FC7\u518D push\u300D\u3002",
|
|
3807
|
+
"",
|
|
3808
|
+
...buildDocsTable("project-root")
|
|
3809
|
+
].join("\n");
|
|
3810
|
+
}
|
|
3811
|
+
exports2.buildFlowRootReadmeMarkdown = buildFlowRootReadmeMarkdown2;
|
|
3812
|
+
function buildFlowQuickStartMarkdown(opts) {
|
|
3813
|
+
return buildFlowRootReadmeMarkdown2(opts);
|
|
3814
|
+
}
|
|
3815
|
+
exports2.buildFlowQuickStartMarkdown = buildFlowQuickStartMarkdown;
|
|
3816
|
+
function buildFlowsDirReadmeMarkdown2(opts) {
|
|
3817
|
+
return [
|
|
3818
|
+
SCAFFOLD_MARKER,
|
|
3819
|
+
"# flows",
|
|
3820
|
+
"",
|
|
3821
|
+
"\u6BCF\u4E2A\u5B50\u76EE\u5F55\u662F\u4E00\u4E2A\u6D41\u7A0B\u5B9E\u4F8B\uFF08\u542B `flow.json`\u3001`flow.meta.json`\uFF09\u3002",
|
|
3822
|
+
"",
|
|
3823
|
+
"## \u64CD\u4F5C",
|
|
3824
|
+
"",
|
|
3825
|
+
"| \u64CD\u4F5C | \u65B9\u5F0F |",
|
|
3826
|
+
"|------|------|",
|
|
3827
|
+
"| \u65B0\u5EFA\u6D41\u7A0B | \u53F3\u952E\u672C\u76EE\u5F55 \u2192 **\u65B0\u5EFA\u6D41\u7A0B**\uFF08\u8868\u5355\uFF1A\u540D\u79F0\u3001\u8BF4\u660E\u3001\u8DEF\u5F84\u9884\u89C8\uFF09 |",
|
|
3828
|
+
"| \u62C9\u53D6\u5E73\u53F0\u6D41\u7A0B | \u53F3\u952E \u2192 **\u62C9\u53D6\u5E73\u53F0\u6D41\u7A0B**\uFF08\u8868\u5355\uFF1A\u5E73\u53F0\u5217\u8868 / Flow ID\u3001\u672C\u5730\u76EE\u5F55\u540D\uFF09 |",
|
|
3829
|
+
"| \u6253\u5F00\u8BBE\u8BA1\u5668 | \u53F3\u952E `flow.json` \u2192 **\u6253\u5F00\u6D41\u7A0B\u8BBE\u8BA1\u5668** |",
|
|
3830
|
+
"",
|
|
3831
|
+
"> **\u7981\u6B62**\u5728 `dazi-work` \u6839\u6267\u884C `project status/push/pull --dir .`\u3002",
|
|
3832
|
+
"",
|
|
3833
|
+
"```powershell",
|
|
3834
|
+
"# \u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84",
|
|
3835
|
+
(0, flowCliText_1.psFlowLine)(`project pull --flow <id> --dir "D:\\path\\to\\dazi-work\\\u9879\u76EE\\${opts.projectFolder}\\\u6D41\u7A0B\\flows\\<\u6D41\u7A0B\u540D>"`),
|
|
3836
|
+
"```",
|
|
3837
|
+
"",
|
|
3838
|
+
"\u62C9\u53D6\u5B8C\u6210\u540E\u8BF7\u9605\u8BFB\u5404\u6D41\u7A0B\u5B50\u76EE\u5F55\u4E0B\u7684 **`\u5FEB\u901F\u542F\u52A8_<\u6D41\u7A0B\u540D>.md`**\u3002",
|
|
3839
|
+
"",
|
|
3840
|
+
...buildDocsTable("flows-dir")
|
|
3841
|
+
].join("\n");
|
|
3842
|
+
}
|
|
3843
|
+
exports2.buildFlowsDirReadmeMarkdown = buildFlowsDirReadmeMarkdown2;
|
|
3844
|
+
function buildFlowDirQuickStartMarkdown2(opts) {
|
|
3845
|
+
const name = opts.flowName;
|
|
3846
|
+
const relDir = buildFlowDirRelPath(opts.projectFolder, name);
|
|
3847
|
+
let audit;
|
|
3848
|
+
if (opts.flowDir) {
|
|
3849
|
+
try {
|
|
3850
|
+
audit = (0, flowWorkspaceAudit_1.auditFlowWorkspace)(opts.flowDir);
|
|
3851
|
+
} catch {
|
|
3852
|
+
}
|
|
3172
3853
|
}
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3854
|
+
const canvasN = audit?.canvasNodeCount ?? opts.nodeCount;
|
|
3855
|
+
const codeN = audit?.canvasCodeNodeCount ?? opts.codeNodeCount;
|
|
3856
|
+
const metaCodeN = audit?.metaCodeIndexedCount;
|
|
3857
|
+
const statsParts = [];
|
|
3858
|
+
if (canvasN != null) {
|
|
3859
|
+
let line = `
|
|
3860
|
+
| \u753B\u5E03\u8282\u70B9\uFF08flow.json\uFF09 | ${canvasN}`;
|
|
3861
|
+
if (codeN != null)
|
|
3862
|
+
line += `\uFF0C\u5176\u4E2D\u4EE3\u7801\u8282\u70B9 ${codeN}`;
|
|
3863
|
+
line += " |";
|
|
3864
|
+
statsParts.push(line);
|
|
3865
|
+
}
|
|
3866
|
+
if (metaCodeN != null && codeN != null && metaCodeN !== codeN) {
|
|
3867
|
+
statsParts.push(`
|
|
3868
|
+
| meta \u5DF2\u7D22\u5F15\u4EE3\u7801 | ${metaCodeN} \u26A0\uFE0F \u4E0E\u753B\u5E03\u4E0D\u4E00\u81F4 |`);
|
|
3869
|
+
} else if (metaCodeN != null) {
|
|
3870
|
+
statsParts.push(`
|
|
3871
|
+
| meta \u5DF2\u7D22\u5F15\u4EE3\u7801 | ${metaCodeN} |`);
|
|
3872
|
+
}
|
|
3873
|
+
const pulled = opts.pulledAt ? `
|
|
3874
|
+
| \u4E0A\u6B21\u62C9\u53D6 | ${opts.pulledAt} |` : "";
|
|
3875
|
+
const consistencySection = audit ? (0, flowWorkspaceAudit_1.buildFlowConsistencyMarkdown)(audit, flowDocsRel("flow-dir", "flow/local-files-spec.md")) : [];
|
|
3876
|
+
return [
|
|
3877
|
+
SCAFFOLD_MARKER,
|
|
3878
|
+
"# \u5FEB\u901F\u542F\u52A8",
|
|
3879
|
+
"",
|
|
3880
|
+
`**\u6D41\u7A0B**\uFF1A${name} \xB7 \u5E73\u53F0 flowId \`${opts.flowId}\``,
|
|
3881
|
+
"",
|
|
3882
|
+
"## \u6D41\u7A0B\u4FE1\u606F",
|
|
3883
|
+
"",
|
|
3884
|
+
"| \u5B57\u6BB5 | \u503C |",
|
|
3885
|
+
"|------|-----|",
|
|
3886
|
+
`| flowId | \`${opts.flowId}\` |`,
|
|
3887
|
+
`| \u672C\u5730\u76EE\u5F55 | \`${relDir}/\` |${statsParts.join("")}${pulled}`,
|
|
3888
|
+
"",
|
|
3889
|
+
...consistencySection,
|
|
3890
|
+
...buildFlowCliDirSection({
|
|
3891
|
+
flowDir: opts.flowDir,
|
|
3892
|
+
projectFolder: opts.projectFolder,
|
|
3893
|
+
flowName: name,
|
|
3894
|
+
flowId: opts.flowId
|
|
3895
|
+
}),
|
|
3896
|
+
"## \u5E38\u7528\u547D\u4EE4\u901F\u67E5",
|
|
3897
|
+
"",
|
|
3898
|
+
"\u9700\u5DF2\u5B89\u88C5\u5168\u5C40 CLI\uFF08`pnpm add -g @dazitech/cli`\uFF09\u6216\u672A\u88C5\u65F6\u7528 `.scriptsdazi.ps1 flow`\uFF1A",
|
|
3899
|
+
"",
|
|
3900
|
+
"```powershell",
|
|
3901
|
+
"# \u5C06 <FLOW_DIR> \u66FF\u6362\u4E3A\u4E0A\u4E00\u8282\u7EDD\u5BF9\u8DEF\u5F84",
|
|
3902
|
+
(0, flowCliText_1.psFlowLine)('project status --dir "<FLOW_DIR>"'),
|
|
3903
|
+
(0, flowCliText_1.psFlowLine)(`project pull --flow ${opts.flowId} --dir "<FLOW_DIR>"`),
|
|
3904
|
+
(0, flowCliText_1.psFlowLine)('project push --dir "<FLOW_DIR>" --canvas'),
|
|
3905
|
+
(0, flowCliText_1.psFlowLine)('run node-exec --node <node_uuid> --dir "<FLOW_DIR>"'),
|
|
3906
|
+
(0, flowCliText_1.psFlowLine)('run flow-exec --dir "<FLOW_DIR>" --type debug'),
|
|
3907
|
+
(0, flowCliText_1.psFlowLine)('variable sync --dir "<FLOW_DIR>"'),
|
|
3908
|
+
"```",
|
|
3909
|
+
"",
|
|
3910
|
+
...(0, flowNodeCatalog_1.buildFlowNodeCatalogQuickStartSection)(flowDocsRel("flow-dir", "flow/flows-guide.md")),
|
|
3911
|
+
"## AI \u4FEE\u6539\u73B0\u6709\u6D41\u7A0B\uFF08\u5355\u6587\u4EF6\u5165\u53E3\uFF09",
|
|
3912
|
+
"",
|
|
3913
|
+
"> \u63A8\u8350\u53EA\u628A\u672C\u6587\u4EF6\u9644\u52A0\u7ED9 AI\uFF1B\u82E5\u4FE1\u606F\u4E0D\u8DB3\uFF0C\u518D\u6309\u9700\u6253\u5F00\u300C\u5E2E\u52A9\u6587\u6863\u300D\u4E2D\u7684\u4E13\u9898\u3002",
|
|
3914
|
+
"",
|
|
3915
|
+
"### \u573A\u666F A\uFF1A\u65B0\u589E\u8282\u70B9\uFF08\u5DF2\u6709\u6D41\u7A0B\u7EE7\u7EED\u6539\uFF09",
|
|
3916
|
+
"",
|
|
3917
|
+
"1. \u5148\u8BFB `flow.json` \u4E0E `flow.meta.json`\uFF0C\u6267\u884C `dazi flow project doctor --dir .`",
|
|
3918
|
+
`2. **\u5FC5\u987B**\u7528 CLI \u65B0\u5EFA\u8282\u70B9\uFF08\u7981\u6B62\u624B\u6413 uuid\uFF09\uFF1A${(0, flowCliText_1.mdFlowCmd)('node new --type <node_type> --dir . --label "<\u8282\u70B9\u540D>"')}`,
|
|
3919
|
+
"3. \u5728 `flow.json` \u91CC\u8865 `nodes/edges`\uFF08\u9075\u5B88\u951A\u70B9\uFF1A`sourceHandle` \u4EC5 `r/b/true/false`\uFF0C`targetHandle` \u4EC5 `l/t`\uFF09",
|
|
3920
|
+
"4. \u7F16\u8F91 `\u8282\u70B9/<\u540D>/code.sql|py`\uFF08`node new` \u4F1A\u521B\u5EFA\u76EE\u5F55\u4E0E meta \u7D22\u5F15\uFF09",
|
|
3921
|
+
`5. \u5355\u8282\u70B9\u6D4B\u8BD5\uFF1A${(0, flowCliText_1.mdFlowCmd)("run node-exec --node <node_uuid> --dir .")}`,
|
|
3922
|
+
`6. \u63D0\u4EA4\u753B\u5E03\uFF08\u542B\u8FDE\u7EBF/\u914D\u7F6E\uFF09\uFF1A${(0, flowCliText_1.mdFlowCmd)("project push --dir . --canvas")}`,
|
|
3923
|
+
"",
|
|
3924
|
+
"### \u573A\u666F B\uFF1A\u4EC5\u6539\u8282\u70B9\u4EE3\u7801",
|
|
3925
|
+
"",
|
|
3926
|
+
"1. \u7F16\u8F91 `\u8282\u70B9/<\u540D>/code.sql|py`\uFF08\u4E0D\u8981\u628A\u6B63\u6587\u5199\u56DE `flow.json`\uFF09",
|
|
3927
|
+
`2. \u8FD0\u884C\u8282\u70B9\uFF1A${(0, flowCliText_1.mdFlowCmd)("run node-exec --node <node_uuid> --dir .")}`,
|
|
3928
|
+
`3. \u63D0\u4EA4\u4EE3\u7801\uFF1A${(0, flowCliText_1.mdFlowCmd)("node push --node <node_uuid> --dir .")}`,
|
|
3929
|
+
"",
|
|
3930
|
+
"### \u573A\u666F C\uFF1A\u753B\u5E03\u548C\u4EE3\u7801\u4E0D\u540C\u6B65",
|
|
3931
|
+
"",
|
|
3932
|
+
`1. \u5148 ${(0, flowCliText_1.mdFlowCmd)("project status --dir .")} \u770B\u672C\u5730\u810F\u6539\u52A8`,
|
|
3933
|
+
`2. \u82E5\u6539\u4E86\u62D3\u6251/\u8FDE\u7EBF/\u914D\u7F6E\uFF1A\u6267\u884C ${(0, flowCliText_1.mdFlowCmd)("project push --dir . --canvas")}`,
|
|
3934
|
+
`3. \u82E5\u53EA\u6539\u4E86\u4EE3\u7801\uFF1A\u6267\u884C ${(0, flowCliText_1.mdFlowCmd)("node push --node <node_uuid> --dir .")}`,
|
|
3935
|
+
`4. \u5FC5\u8981\u65F6\u91CD\u65B0\u62C9\u53D6\u6821\u5BF9\uFF1A${(0, flowCliText_1.mdFlowCmd)(`project pull --flow ${opts.flowId} --dir .`)}`,
|
|
3936
|
+
"",
|
|
3937
|
+
"## AI \u81EA\u68C0\u6E05\u5355\uFF08\u63D0\u4EA4\u524D\uFF09",
|
|
3938
|
+
"",
|
|
3939
|
+
`- \u547D\u4EE4\u524D\u7F00\u662F\u5426\u7EDF\u4E00\u4E3A ${(0, flowCliText_1.mdFlowCmd)("...")}\uFF08\u800C\u4E0D\u662F\u88F8 \`dazi-flow\`\uFF09`,
|
|
3940
|
+
"- `flow.json` \u662F\u5426\u53EA\u627F\u8F7D\u753B\u5E03\u62D3\u6251\u4E0E\u8282\u70B9\u914D\u7F6E\uFF08\u4E0D\u5D4C\u5165\u5927\u6BB5 SQL/Python\uFF09",
|
|
3941
|
+
"- `code.*` \u662F\u5426\u4E0E\u8282\u70B9\u4E1A\u52A1\u7C7B\u578B\u4E00\u81F4\uFF08SQL \u8282\u70B9 `code.sql`\uFF0CPython \u8282\u70B9 `code.py`\uFF09",
|
|
3942
|
+
"- \u6761\u4EF6\u8282\u70B9\u51FA\u8FB9\u662F\u5426\u4EC5\u4F7F\u7528 `true/false`\uFF0C\u672A\u8BEF\u7528 `r/b`",
|
|
3943
|
+
"- \u82E5\u6539\u52A8\u753B\u5E03\uFF0C\u662F\u5426\u6267\u884C\u4E86 `flow project push --canvas`",
|
|
3944
|
+
"",
|
|
3945
|
+
"## \u5E38\u89C1\u9519\u8BEF\u4E0E\u4FEE\u590D",
|
|
3946
|
+
"",
|
|
3947
|
+
"| \u73B0\u8C61 | \u5E38\u89C1\u539F\u56E0 | \u4FEE\u590D |",
|
|
3948
|
+
"|------|----------|------|",
|
|
3949
|
+
`| \u547D\u4EE4\u627E\u4E0D\u5230 | \u672A\u88C5\u5168\u5C40 CLI \u6216\u4E0D\u5728 dazi-work | \`pnpm add -g @dazitech/cli\` \u6216 ${(0, flowCliText_1.mdFlowCmd)("...")} / \`.scriptsdazi.ps1 flow ...\` |`,
|
|
3950
|
+
"| \u8282\u70B9\u6D4B\u8BD5\u62A5\u4E0A\u6E38\u53D8\u91CF\u4E0D\u5B58\u5728 | \u672A\u5148\u8FD0\u884C\u4E0A\u6E38\u8282\u70B9\u4EA7\u51FA\u53D8\u91CF | \u5148\u8DD1\u4E0A\u6E38\uFF0C\u6216\u6574\u6D41\u7A0B `flow run flow-exec --type debug` \u540E\u518D\u6D4B |",
|
|
3951
|
+
"| excel-python \u627E\u4E0D\u5230\u6587\u4EF6 | code.py \u5199\u4E86\u6587\u4EF6\u540D/\u672C\u5730\u8DEF\u5F84 | \u753B\u5E03\u914D `managed_file_id`\uFF08UUID\uFF09\uFF1B\u4EE3\u7801\u7528 `excel_source_path` |",
|
|
3952
|
+
"| Excel \u7528\u4E86 file-source | file-source \u4E0D\u89E3\u6790 xlsx | \u6539\u4E3A **`excel-python`** + `managed_file_id` |",
|
|
3953
|
+
"| excel-python \u65E0\u4E3B\u8F93\u51FA | \u672A `set_table_output` \u6216\u540D\u79F0\u4E0E `output_variable_name` \u4E0D\u4E00\u81F4 | \u89C1 node-code-guide \xA75 |",
|
|
3954
|
+
"| \u753B\u5E03\u663E\u793A\u5BF9\u4F46\u5E73\u53F0\u4E0D\u751F\u6548 | \u53EA push \u4E86\u4EE3\u7801\uFF0C\u672A push \u753B\u5E03 | \u6267\u884C `flow project push --dir . --canvas` |",
|
|
3955
|
+
"| \u4EE3\u7801\u6539\u4E86\u4F46\u5E73\u53F0\u8FD8\u662F\u65E7\u4EE3\u7801 | \u6539\u4E86\u672C\u5730 `code.*` \u4F46\u672A node push | \u6267\u884C `flow node push --node <node_uuid> --dir .` |",
|
|
3956
|
+
"| **flowId \u4E0E\u5FEB\u901F\u542F\u52A8\u4E0D\u4E00\u81F4** | \u5728 **dazi-work \u6839**\u6216**\u9519\u8BEF\u6D41\u7A0B\u76EE\u5F55**\u6267\u884C `--dir .` | \u6539\u7528\u4E0A\u6587 **\u7EDD\u5BF9\u8DEF\u5F84**\uFF1B`status` \u987B\u5339\u914D\u672C\u9875 flowId/\u6D41\u7A0B\u540D |",
|
|
3957
|
+
"",
|
|
3958
|
+
"## AI \u81EA\u4E3B\u8FD0\u884C\u4E0E\u6539\u9519\u95ED\u73AF\uFF08Agent \u5FC5\u8BFB\uFF09",
|
|
3959
|
+
"",
|
|
3960
|
+
"> **\u6269\u5C55/\u83DC\u5355\u4E0D\u4F1A\u81EA\u52A8\u6539\u4EE3\u7801**\uFF08\u5E73\u53F0 D6\uFF09\uFF1B\u7528\u6237\u59D4\u6258\u4F60\u6539\u6D41\u7A0B\u65F6\uFF0C\u4F60**\u5FC5\u987B\u4E3B\u52A8**\u6267\u884C\u300C\u6539 \u2192 \u8DD1 \u2192 \u8BFB\u9519 \u2192 \u518D\u6539 \u2192 \u518D\u8DD1\u300D\uFF0C\u76F4\u5230\u901A\u8FC7\u6216\u8FBE\u5230\u91CD\u8BD5\u4E0A\u9650\u3002",
|
|
3961
|
+
"",
|
|
3962
|
+
"### \u9519\u8BEF\u843D\u5728\u54EA\u91CC\uFF08\u8DD1\u5B8C\u5FC5\u67E5\uFF09",
|
|
3963
|
+
"",
|
|
3964
|
+
"| \u8FD0\u884C\u65B9\u5F0F | \u5931\u8D25\u65F6\u8BFB | \u6210\u529F/\u6B65\u9AA4\u6458\u8981 |",
|
|
3965
|
+
"|----------|----------|---------------|",
|
|
3966
|
+
"| \u5355\u8282\u70B9 `run node-exec` | `_run/<\u8282\u70B9\u540D>.last-error.md` | \u65E0 error \u6587\u4EF6\u5373\u901A\u8FC7 |",
|
|
3967
|
+
"| \u6574\u6D41\u7A0B `run flow-exec` | `_run/flow.last-error.md` | `_run/flow.last-run.md`\uFF08\u6B65\u9AA4+\u65E5\u5FD7\uFF09 |",
|
|
3968
|
+
"",
|
|
3969
|
+
"CLI \u5E26 `--json` \u65F6\uFF1A\u770B\u8FD4\u56DE `success: false` \u6216 `errorFile` \u5B57\u6BB5\uFF0C**\u518D\u6253\u5F00\u5BF9\u5E94 md \u6587\u4EF6**\uFF0C\u4E0D\u8981\u53EA\u770B\u7EC8\u7AEF\u4E00\u884C\u62A5\u9519\u3002",
|
|
3970
|
+
"",
|
|
3971
|
+
"### \u6807\u51C6\u6539\u9519\u5FAA\u73AF\uFF08\u9ED8\u8BA4\u6700\u591A 3 \u8F6E\uFF09",
|
|
3972
|
+
"",
|
|
3973
|
+
"1. **\u5B9A\u4F4D**\uFF1A\u8BFB `flow.json` + \u76EE\u6807 `\u8282\u70B9/<\u540D>/code.*` + `flow.meta.json`\uFF08\u53D6 `node_uuid`\uFF09",
|
|
3974
|
+
"2. **\u4FEE\u6539**\uFF1A\u53EA\u6539\u5FC5\u8981\u6587\u4EF6\uFF08\u4EE3\u7801 \u2192 `code.*`\uFF1B\u8FDE\u7EBF/\u914D\u7F6E \u2192 `flow.json`\uFF09",
|
|
3975
|
+
"3. **\u9A8C\u8BC1**\uFF08\u5148\u5C0F\u540E\u5927\uFF09\uFF1A",
|
|
3976
|
+
` - \u5355\u8282\u70B9\uFF1A${(0, flowCliText_1.mdFlowCmd)("run node-exec --node <node_uuid> --dir .")}`,
|
|
3977
|
+
` - \u6574\u6D41\u7A0B\uFF1A${(0, flowCliText_1.mdFlowCmd)("run flow-exec --dir . --type debug")}`,
|
|
3978
|
+
"4. **\u5224\u9519**\uFF1A\u9000\u51FA\u7801\u975E 0 / JSON `success:false` \u2192 \u6253\u5F00 `_run/*.last-error.md`\uFF0C\u6309\u5176\u4E2D**\u9519\u8BEF\u5206\u7C7B**\u4E0E traceback \u4FEE\u590D",
|
|
3979
|
+
"5. **\u91CD\u8BD5**\uFF1A\u56DE\u5230\u6B65\u9AA4 2\uFF1B\u82E5 3 \u8F6E\u4ECD\u5931\u8D25\uFF0C\u6C47\u603B\u5DF2\u5C1D\u8BD5\u4FEE\u590D\u70B9\u5E76\u8BF7\u6C42\u7528\u6237\u4ECB\u5165",
|
|
3980
|
+
"6. **\u63D0\u4EA4**\uFF08\u4EC5\u901A\u8FC7\u540E\uFF09\uFF1A\u4EE3\u7801 `node push`\uFF1B\u753B\u5E03 `project push --canvas`",
|
|
3981
|
+
"",
|
|
3982
|
+
"### \u5E38\u89C1\u5931\u8D25 \u2192 \u4F18\u5148\u52A8\u4F5C",
|
|
3983
|
+
"",
|
|
3984
|
+
"| last-error \u5206\u7C7B | \u4F18\u5148\u68C0\u67E5 |",
|
|
3985
|
+
"|-----------------|----------|",
|
|
3986
|
+
"| \u7F3A\u4E0A\u6E38\u53D8\u91CF | \u5148\u8DD1\u4E0A\u6E38\u8282\u70B9\u6216\u6574\u6D41\u7A0B debug\uFF0C\u518D `variable pull` \u770B schema |",
|
|
3987
|
+
"| \u914D\u7F6E\u7F3A\u5931 | `flow.json` \u8BE5\u8282\u70B9 `data`\uFF08connectionId / output_variable_name \u7B49\uFF09 |",
|
|
3988
|
+
"| \u4EE3\u7801\u9519\u8BEF | `code.*` \u4E0E traceback\uFF1B\u6539\u540E\u53EA `node push` |",
|
|
3989
|
+
"| \u8FDE\u63A5/\u6570\u636E\u6E90 | connectionId / spaceId \u662F\u5426\u6709\u6548 |",
|
|
3990
|
+
"",
|
|
3991
|
+
"### Agent \u7981\u6B62\u9879",
|
|
3992
|
+
"",
|
|
3993
|
+
"- **\u7981\u6B62**\u672A\u5B9E\u9645\u8FD0\u884C\u5C31\u58F0\u79F0\u300C\u5DF2\u4FEE\u590D/\u5DF2\u901A\u8FC7\u300D",
|
|
3994
|
+
"- **\u7981\u6B62**\u4E0D\u8BFB `_run/*.last-error.md` \u5C31\u731C\u6D4B\u539F\u56E0",
|
|
3995
|
+
"- **\u7981\u6B62**\u4FEE\u590D\u540E\u8DF3\u8FC7\u9A8C\u8BC1\u76F4\u63A5 `push`",
|
|
3996
|
+
"- **\u7981\u6B62**\u628A SQL/Python \u6B63\u6587\u5199\u56DE `flow.json`",
|
|
3997
|
+
"",
|
|
3998
|
+
"\u4FA7\u680F\u63D0\u793A\u8BCD\u53EF\u9009\u7528 **`flow/run-fix-loop`**\uFF08\u81EA\u4E3B\u6539\u9519\u4E13\u7528\uFF09\u3002",
|
|
3999
|
+
"",
|
|
4000
|
+
"\u6269\u5C55\uFF1A\u53F3\u952E **`flow.json`** / **\u8282\u70B9/** / **`code.*`** \u53EF\u6D4B\u8BD5\u3001\u63D0\u4EA4\u3001\u6253\u5F00\u8BBE\u8BA1\u5668\u3002",
|
|
4001
|
+
"",
|
|
4002
|
+
"## \u7F16\u5199\u8282\u70B9\u4EE3\u7801",
|
|
4003
|
+
"",
|
|
4004
|
+
"- **SQL \u8282\u70B9**\uFF08`sql-query` / `database-source`\uFF09\uFF1A\u7F16\u8F91 `\u8282\u70B9/<\u540D>/code.sql`\uFF1B`sql-query` \u4E2D\u7528 **\u4E0A\u6E38\u53D8\u91CF\u540D\u4F5C\u8868\u540D**\uFF08`FROM \u4E0A\u6E38\u53D8\u91CF\u540D`\uFF09",
|
|
4005
|
+
'- **Python \u8282\u70B9**\uFF08`python-script`\uFF09\uFF1A\u7F16\u8F91 `code.py`\uFF1B\u5355\u8282\u70B9\u6D4B\u8BD5\u7528 **`get_variable("\u4E0A\u6E38\u53D8\u91CF\u540D")`**\uFF0C\u8F93\u51FA\u8D4B\u503C **`result_df`**',
|
|
4006
|
+
"- **`excel-python`\uFF08Excel \u9ED8\u8BA4\u9996\u9009\uFF09**\uFF1A",
|
|
4007
|
+
" - \u6709 **`managed_file_id` \u7684 Excel \u2192 \u4F18\u5148 `excel-python`**\uFF0C**\u52FF\u7528 `file-source`**\uFF08file-source \u4E0D\u89E3\u6790 Excel\uFF09",
|
|
4008
|
+
" - **\u753B\u5E03**\u914D **`managed_file_id`**\uFF08UUID\uFF09\uFF1B**`code.py` \u53EA\u7528 `excel_source_path`**",
|
|
4009
|
+
' - \u4E3B\u8F93\u51FA **`set_table_output("<\u4E0E output_variable_name \u540C\u540D>", df)`**',
|
|
4010
|
+
" - \u5B8C\u6574\u793A\u4F8B \u2192 [node-code-guide \xA75](" + flowDocsRel("flow-dir", "flow/node-code-guide.md") + "#5-excel-pythonexcel-\u5F00\u53D1--\u9ED8\u8BA4\u9996\u9009)",
|
|
4011
|
+
"- \u53D8\u91CF\u7EA6\u5B9A\u4E0E\u5B8C\u6574\u793A\u4F8B \u2192 [\u6D41\u7A0B\u53D8\u91CF\u7CFB\u7EDF\u6307\u5357](" + flowDocsRel("flow-dir", "flow/variables-guide.md") + ") \xB7 [\u8282\u70B9\u4EE3\u7801\u7F16\u5199\u6307\u5357](" + flowDocsRel("flow-dir", "flow/node-code-guide.md") + ")",
|
|
4012
|
+
"",
|
|
4013
|
+
...buildDocsTable("flow-dir")
|
|
4014
|
+
].join("\n");
|
|
4015
|
+
}
|
|
4016
|
+
exports2.buildFlowDirQuickStartMarkdown = buildFlowDirQuickStartMarkdown2;
|
|
4017
|
+
function buildFlowDirReadmeMarkdown(opts) {
|
|
4018
|
+
return buildFlowDirQuickStartMarkdown2(opts);
|
|
4019
|
+
}
|
|
4020
|
+
exports2.buildFlowDirReadmeMarkdown = buildFlowDirReadmeMarkdown;
|
|
4021
|
+
function removeLegacyFlowDirQuickStartFiles(flowDir, currentFilename, fsImpl) {
|
|
4022
|
+
const legacy = path_1.default.join(flowDir, exports2.LEGACY_FLOW_DIR_QUICKSTART_FILENAME);
|
|
4023
|
+
if (fsImpl.existsSync(legacy)) {
|
|
4024
|
+
try {
|
|
4025
|
+
if (isFlowScaffoldFile(fsImpl.readFileSync(legacy, "utf8"))) {
|
|
4026
|
+
fsImpl.unlinkSync(legacy);
|
|
4027
|
+
}
|
|
4028
|
+
} catch {
|
|
4029
|
+
}
|
|
4030
|
+
}
|
|
4031
|
+
for (const entry of fsImpl.readdirSync(flowDir)) {
|
|
4032
|
+
if (entry === currentFilename)
|
|
4033
|
+
continue;
|
|
4034
|
+
if (!/^快速启动_.+\.md$/.test(entry))
|
|
4035
|
+
continue;
|
|
4036
|
+
const full = path_1.default.join(flowDir, entry);
|
|
4037
|
+
try {
|
|
4038
|
+
if (isFlowScaffoldFile(fsImpl.readFileSync(full, "utf8"))) {
|
|
4039
|
+
fsImpl.unlinkSync(full);
|
|
4040
|
+
}
|
|
4041
|
+
} catch {
|
|
4042
|
+
}
|
|
4043
|
+
}
|
|
4044
|
+
}
|
|
4045
|
+
exports2.removeLegacyFlowDirQuickStartFiles = removeLegacyFlowDirQuickStartFiles;
|
|
4046
|
+
function writeFlowDirQuickStartScaffold2(flowDir, flowName, content, fsImpl) {
|
|
4047
|
+
const filename = flowDirQuickStartFilename(flowName);
|
|
4048
|
+
writeScaffoldIfAllowed2(path_1.default.join(flowDir, filename), content, fsImpl);
|
|
4049
|
+
removeLegacyFlowDirQuickStartFiles(flowDir, filename, fsImpl);
|
|
4050
|
+
return filename;
|
|
4051
|
+
}
|
|
4052
|
+
exports2.writeFlowDirQuickStartScaffold = writeFlowDirQuickStartScaffold2;
|
|
4053
|
+
function resolveFlowDirQuickStartPath(flowDir, fsImpl) {
|
|
4054
|
+
let flowName;
|
|
4055
|
+
const metaPath = path_1.default.join(flowDir, "flow.meta.json");
|
|
4056
|
+
if (fsImpl.existsSync(metaPath)) {
|
|
4057
|
+
try {
|
|
4058
|
+
const meta = JSON.parse(fsImpl.readFileSync(metaPath, "utf8"));
|
|
4059
|
+
flowName = meta.flowName?.trim() || void 0;
|
|
4060
|
+
} catch {
|
|
4061
|
+
}
|
|
4062
|
+
}
|
|
4063
|
+
if (!flowName)
|
|
4064
|
+
flowName = path_1.default.basename(flowDir);
|
|
4065
|
+
const preferred = path_1.default.join(flowDir, flowDirQuickStartFilename(flowName));
|
|
4066
|
+
if (fsImpl.existsSync(preferred))
|
|
4067
|
+
return preferred;
|
|
4068
|
+
const legacy = path_1.default.join(flowDir, exports2.LEGACY_FLOW_DIR_QUICKSTART_FILENAME);
|
|
4069
|
+
if (fsImpl.existsSync(legacy))
|
|
4070
|
+
return legacy;
|
|
4071
|
+
const candidates = fsImpl.readdirSync(flowDir).filter((f) => /^快速启动_.+\.md$/.test(f));
|
|
4072
|
+
if (!candidates.length)
|
|
4073
|
+
return null;
|
|
4074
|
+
if (candidates.length === 1)
|
|
4075
|
+
return path_1.default.join(flowDir, candidates[0]);
|
|
4076
|
+
if (fsImpl.statSync) {
|
|
4077
|
+
candidates.sort((a, b) => fsImpl.statSync(path_1.default.join(flowDir, b)).mtimeMs - fsImpl.statSync(path_1.default.join(flowDir, a)).mtimeMs);
|
|
4078
|
+
}
|
|
4079
|
+
return path_1.default.join(flowDir, candidates[0]);
|
|
4080
|
+
}
|
|
4081
|
+
exports2.resolveFlowDirQuickStartPath = resolveFlowDirQuickStartPath;
|
|
4082
|
+
function removeLegacyFlowRootQuickStart2(flowRoot, fsImpl) {
|
|
4083
|
+
const legacy = path_1.default.join(flowRoot, exports2.LEGACY_FLOW_ROOT_QUICKSTART_FILENAME);
|
|
4084
|
+
if (!fsImpl.existsSync(legacy))
|
|
3176
4085
|
return;
|
|
4086
|
+
try {
|
|
4087
|
+
if (isFlowScaffoldFile(fsImpl.readFileSync(legacy, "utf8"))) {
|
|
4088
|
+
fsImpl.unlinkSync(legacy);
|
|
4089
|
+
}
|
|
4090
|
+
} catch {
|
|
3177
4091
|
}
|
|
3178
|
-
|
|
3179
|
-
|
|
4092
|
+
}
|
|
4093
|
+
exports2.removeLegacyFlowRootQuickStart = removeLegacyFlowRootQuickStart2;
|
|
4094
|
+
function resolveFlowRootFromFlowDir2(flowDir) {
|
|
4095
|
+
const flowsDir = path_1.default.dirname(flowDir);
|
|
4096
|
+
if (path_1.default.basename(flowsDir) === "flows") {
|
|
4097
|
+
return path_1.default.dirname(flowsDir);
|
|
3180
4098
|
}
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
4099
|
+
if (path_1.default.basename(flowsDir) === "\u6D41\u7A0B") {
|
|
4100
|
+
return flowsDir;
|
|
4101
|
+
}
|
|
4102
|
+
return void 0;
|
|
3184
4103
|
}
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
4104
|
+
exports2.resolveFlowRootFromFlowDir = resolveFlowRootFromFlowDir2;
|
|
4105
|
+
function removeLegacyFlowDirScaffoldReadme2(flowDir, fsImpl) {
|
|
4106
|
+
const legacy = path_1.default.join(flowDir, "README.md");
|
|
4107
|
+
if (!fsImpl.existsSync(legacy))
|
|
4108
|
+
return;
|
|
4109
|
+
try {
|
|
4110
|
+
if (isFlowScaffoldFile(fsImpl.readFileSync(legacy, "utf8"))) {
|
|
4111
|
+
fsImpl.unlinkSync(legacy);
|
|
4112
|
+
}
|
|
4113
|
+
} catch {
|
|
4114
|
+
}
|
|
3193
4115
|
}
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
4116
|
+
exports2.removeLegacyFlowDirScaffoldReadme = removeLegacyFlowDirScaffoldReadme2;
|
|
4117
|
+
function buildFlowProjectReadmeHelpSection() {
|
|
4118
|
+
return [
|
|
4119
|
+
"",
|
|
4120
|
+
"## \u5FEB\u901F\u5165\u95E8",
|
|
4121
|
+
"",
|
|
4122
|
+
"- \u9605\u8BFB\u672C\u76EE\u5F55 [README.md](./README.md)",
|
|
4123
|
+
"- \u6D41\u7A0B\u4E13\u9898\u6587\u6863\uFF1A[\u8D44\u6E90/docs/flow/flows-guide.md](" + flowDocsRel("project-root", "flow/flows-guide.md") + ")",
|
|
4124
|
+
""
|
|
4125
|
+
];
|
|
4126
|
+
}
|
|
4127
|
+
exports2.buildFlowProjectReadmeHelpSection = buildFlowProjectReadmeHelpSection;
|
|
4128
|
+
function writeScaffoldIfAllowed2(filePath, content, fsImpl, opts) {
|
|
4129
|
+
if (fsImpl.existsSync(filePath)) {
|
|
4130
|
+
const existing = fsImpl.readFileSync(filePath, "utf8");
|
|
4131
|
+
if (!isFlowScaffoldFile(existing)) {
|
|
4132
|
+
if (!(opts?.upgradeLegacy && isLegacyFlowScaffoldFile(existing)))
|
|
4133
|
+
return false;
|
|
4134
|
+
}
|
|
3202
4135
|
}
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
4136
|
+
fsImpl.writeFileSync(filePath, content, "utf8");
|
|
4137
|
+
return true;
|
|
4138
|
+
}
|
|
4139
|
+
exports2.writeScaffoldIfAllowed = writeScaffoldIfAllowed2;
|
|
4140
|
+
}
|
|
4141
|
+
});
|
|
4142
|
+
|
|
4143
|
+
// src/shared/flowWorkspaceAudit.js
|
|
4144
|
+
var require_flowWorkspaceAudit = __commonJS({
|
|
4145
|
+
"src/shared/flowWorkspaceAudit.js"(exports2) {
|
|
4146
|
+
"use strict";
|
|
4147
|
+
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
4148
|
+
return mod && mod.__esModule ? mod : { "default": mod };
|
|
4149
|
+
};
|
|
4150
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
4151
|
+
exports2.buildFlowConsistencyMarkdown = exports2.repairFlowMeta = exports2.auditFlowWorkspace = void 0;
|
|
4152
|
+
var crypto_1 = __importDefault(require("crypto"));
|
|
4153
|
+
var fs_1 = __importDefault(require("fs"));
|
|
4154
|
+
var path_1 = __importDefault(require("path"));
|
|
4155
|
+
var NODES_DIR3 = "\u8282\u70B9";
|
|
4156
|
+
var FLOW_JSON3 = "flow.json";
|
|
4157
|
+
var FLOW_META_JSON3 = "flow.meta.json";
|
|
4158
|
+
var NODE_INFO_JSON3 = "node.info.json";
|
|
4159
|
+
var NODE_TYPE_CODE_DATA_KEY3 = {
|
|
4160
|
+
"database-source": "sql",
|
|
4161
|
+
"dataspace-source": "sql",
|
|
4162
|
+
"python-script": "pythonCode",
|
|
4163
|
+
"excel-python": "pythonCode",
|
|
4164
|
+
"sql-query": "sql",
|
|
4165
|
+
condition: "pythonCode",
|
|
4166
|
+
"data-quality-check": "dqPythonCode"
|
|
4167
|
+
};
|
|
4168
|
+
function sha13(text) {
|
|
4169
|
+
return crypto_1.default.createHash("sha1").update(text, "utf8").digest("hex");
|
|
4170
|
+
}
|
|
4171
|
+
function resolveNodeType3(node) {
|
|
4172
|
+
if (node.type === "custom") {
|
|
4173
|
+
return String(node.data?.type ?? "custom");
|
|
3208
4174
|
}
|
|
3209
|
-
|
|
3210
|
-
} catch (err) {
|
|
3211
|
-
handleError(err);
|
|
4175
|
+
return String(node.type ?? "custom");
|
|
3212
4176
|
}
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
let result;
|
|
3217
|
-
if (opts.file) {
|
|
3218
|
-
const body = JSON.parse(import_fs2.default.readFileSync(import_path3.default.resolve(opts.file), "utf-8"));
|
|
3219
|
-
result = await apiRequest(`/api/data-pipelines/v1/flows/compile-plan`, { method: "POST", body });
|
|
3220
|
-
} else {
|
|
3221
|
-
result = await apiRequest(`/api/data-pipelines/v1/flows/${flowId}/validate`, { method: "POST" });
|
|
4177
|
+
function codeLanguageForNodeType3(nodeType) {
|
|
4178
|
+
if (["python-script", "excel-python", "condition", "data-quality-check"].includes(nodeType)) {
|
|
4179
|
+
return "python";
|
|
3222
4180
|
}
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
4181
|
+
if (["database-source", "dataspace-source", "sql-query"].includes(nodeType)) {
|
|
4182
|
+
return "sql";
|
|
4183
|
+
}
|
|
4184
|
+
return void 0;
|
|
3227
4185
|
}
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
4186
|
+
function codeFileExt3(language) {
|
|
4187
|
+
if (language === "python")
|
|
4188
|
+
return "py";
|
|
4189
|
+
if (language === "sql")
|
|
4190
|
+
return "sql";
|
|
4191
|
+
return "txt";
|
|
4192
|
+
}
|
|
4193
|
+
function sanitizeName3(name) {
|
|
4194
|
+
const cleaned = (name || "").replace(/[<>:"/\\|?*\x00-\x1f]/g, "_").trim().replace(/\s+/g, "_");
|
|
4195
|
+
return cleaned || "node";
|
|
4196
|
+
}
|
|
4197
|
+
function readFlowJson3(flowDir) {
|
|
4198
|
+
const raw = JSON.parse(fs_1.default.readFileSync(path_1.default.join(flowDir, FLOW_JSON3), "utf8"));
|
|
4199
|
+
return {
|
|
4200
|
+
nodes: Array.isArray(raw.nodes) ? raw.nodes : [],
|
|
4201
|
+
edges: Array.isArray(raw.edges) ? raw.edges : []
|
|
4202
|
+
};
|
|
4203
|
+
}
|
|
4204
|
+
function readMeta3(flowDir) {
|
|
4205
|
+
const p = path_1.default.join(flowDir, FLOW_META_JSON3);
|
|
4206
|
+
if (!fs_1.default.existsSync(p))
|
|
4207
|
+
return void 0;
|
|
4208
|
+
try {
|
|
4209
|
+
return JSON.parse(fs_1.default.readFileSync(p, "utf8"));
|
|
4210
|
+
} catch {
|
|
4211
|
+
return void 0;
|
|
3239
4212
|
}
|
|
3240
|
-
const flow = await apiRequest(`/api/data-pipelines/v1/flows/${flowId}`, { method: "PUT", body: patch });
|
|
3241
|
-
console.log(`\u2705 Flow ${flowId} \u5DF2\u66F4\u65B0`);
|
|
3242
|
-
ok({ flow });
|
|
3243
|
-
} catch (err) {
|
|
3244
|
-
handleError(err);
|
|
3245
4213
|
}
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
nodeCmd.command("get <flowId> <nodeId>").description("\u67E5\u770B Flow \u8282\u70B9\u8BE6\u60C5").option("--json", "\u8F93\u51FA JSON").action(async (flowId, nodeId, opts) => {
|
|
3249
|
-
try {
|
|
3250
|
-
const node = await apiRequest(`/api/data-pipelines/v1/flows/${flowId}/flow-nodes/${nodeId}`);
|
|
3251
|
-
console.log(JSON.stringify(node, null, 2));
|
|
3252
|
-
ok({ node });
|
|
3253
|
-
} catch (err) {
|
|
3254
|
-
handleError(err);
|
|
4214
|
+
function isCodeNodeType2(nodeType) {
|
|
4215
|
+
return Boolean(NODE_TYPE_CODE_DATA_KEY3[nodeType]);
|
|
3255
4216
|
}
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
4217
|
+
function listNodeDirs2(flowDir) {
|
|
4218
|
+
const nodesRoot = path_1.default.join(flowDir, NODES_DIR3);
|
|
4219
|
+
if (!fs_1.default.existsSync(nodesRoot))
|
|
4220
|
+
return [];
|
|
4221
|
+
return fs_1.default.readdirSync(nodesRoot).filter((n) => {
|
|
4222
|
+
try {
|
|
4223
|
+
return fs_1.default.statSync(path_1.default.join(nodesRoot, n)).isDirectory();
|
|
4224
|
+
} catch {
|
|
4225
|
+
return false;
|
|
4226
|
+
}
|
|
4227
|
+
});
|
|
4228
|
+
}
|
|
4229
|
+
function findCodeFileInDir2(dirAbs) {
|
|
4230
|
+
if (!fs_1.default.existsSync(dirAbs))
|
|
4231
|
+
return void 0;
|
|
4232
|
+
for (const f of fs_1.default.readdirSync(dirAbs)) {
|
|
4233
|
+
if (/^code\.(py|sql|txt)$/i.test(f))
|
|
4234
|
+
return f;
|
|
4235
|
+
}
|
|
4236
|
+
return void 0;
|
|
4237
|
+
}
|
|
4238
|
+
function findDirForUuid2(flowDir, uuid) {
|
|
4239
|
+
const nodesRoot = path_1.default.join(flowDir, NODES_DIR3);
|
|
4240
|
+
for (const dirName of listNodeDirs2(flowDir)) {
|
|
4241
|
+
const infoPath = path_1.default.join(nodesRoot, dirName, NODE_INFO_JSON3);
|
|
4242
|
+
if (fs_1.default.existsSync(infoPath)) {
|
|
4243
|
+
try {
|
|
4244
|
+
const info = JSON.parse(fs_1.default.readFileSync(infoPath, "utf8"));
|
|
4245
|
+
if (String(info.node_uuid ?? "") === uuid)
|
|
4246
|
+
return path_1.default.posix.join(NODES_DIR3, dirName);
|
|
4247
|
+
} catch {
|
|
4248
|
+
}
|
|
4249
|
+
}
|
|
3267
4250
|
}
|
|
3268
|
-
|
|
3269
|
-
`/api/data-pipelines/v1/flows/${flowId}/flow-nodes/${nodeId}`,
|
|
3270
|
-
{ method: "PATCH", body: patch }
|
|
3271
|
-
);
|
|
3272
|
-
console.log(`\u2705 \u8282\u70B9 ${nodeId} \u5DF2\u66F4\u65B0`);
|
|
3273
|
-
ok({ node });
|
|
3274
|
-
} catch (err) {
|
|
3275
|
-
handleError(err);
|
|
4251
|
+
return void 0;
|
|
3276
4252
|
}
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
const
|
|
3282
|
-
|
|
3283
|
-
const
|
|
3284
|
-
|
|
3285
|
-
|
|
4253
|
+
function auditFlowWorkspace3(flowDir) {
|
|
4254
|
+
const warnings = [];
|
|
4255
|
+
const doc = readFlowJson3(flowDir);
|
|
4256
|
+
const meta = readMeta3(flowDir) ?? { nodes: {} };
|
|
4257
|
+
const canvasNodeCount = doc.nodes.length;
|
|
4258
|
+
let canvasCodeNodeCount = 0;
|
|
4259
|
+
const missingInMeta = [];
|
|
4260
|
+
const missingCodeFiles = [];
|
|
4261
|
+
const flowUuids = /* @__PURE__ */ new Set();
|
|
4262
|
+
for (const node of doc.nodes) {
|
|
4263
|
+
const uuid = String(node.node_uuid ?? "").trim();
|
|
4264
|
+
if (!uuid)
|
|
4265
|
+
continue;
|
|
4266
|
+
flowUuids.add(uuid);
|
|
4267
|
+
const nodeType = resolveNodeType3(node);
|
|
4268
|
+
if (!isCodeNodeType2(nodeType))
|
|
4269
|
+
continue;
|
|
4270
|
+
canvasCodeNodeCount++;
|
|
4271
|
+
const label = String(node.data?.label ?? node.id ?? "");
|
|
4272
|
+
const m = meta.nodes[uuid];
|
|
4273
|
+
if (!m?.dir || !m.codeFile) {
|
|
4274
|
+
missingInMeta.push({ uuid, nodeId: String(node.id ?? ""), nodeType, label });
|
|
4275
|
+
continue;
|
|
4276
|
+
}
|
|
4277
|
+
const codePath = path_1.default.join(flowDir, m.dir, m.codeFile);
|
|
4278
|
+
if (!fs_1.default.existsSync(codePath)) {
|
|
4279
|
+
missingCodeFiles.push({ uuid, dir: m.dir, codeFile: m.codeFile });
|
|
4280
|
+
}
|
|
3286
4281
|
}
|
|
3287
|
-
const
|
|
3288
|
-
|
|
3289
|
-
|
|
4282
|
+
const orphanInMeta = Object.keys(meta.nodes).filter((u) => !flowUuids.has(u));
|
|
4283
|
+
let metaCodeIndexedCount = 0;
|
|
4284
|
+
for (const m of Object.values(meta.nodes)) {
|
|
4285
|
+
if (m.dir && m.codeFile)
|
|
4286
|
+
metaCodeIndexedCount++;
|
|
3290
4287
|
}
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
4288
|
+
const unindexedDirs = [];
|
|
4289
|
+
for (const dirName of listNodeDirs2(flowDir)) {
|
|
4290
|
+
const dirAbs = path_1.default.join(flowDir, NODES_DIR3, dirName);
|
|
4291
|
+
if (!findCodeFileInDir2(dirAbs))
|
|
4292
|
+
continue;
|
|
4293
|
+
const rel = path_1.default.posix.join(NODES_DIR3, dirName);
|
|
4294
|
+
const indexed = Object.values(meta.nodes).some((m) => m.dir?.replace(/\\/g, "/") === rel);
|
|
4295
|
+
if (!indexed)
|
|
4296
|
+
unindexedDirs.push(rel);
|
|
4297
|
+
}
|
|
4298
|
+
if (canvasCodeNodeCount !== metaCodeIndexedCount) {
|
|
4299
|
+
warnings.push(`\u753B\u5E03\u4EE3\u7801\u8282\u70B9 ${canvasCodeNodeCount} \u4E2A\uFF0Cmeta \u5DF2\u7D22\u5F15 ${metaCodeIndexedCount} \u4E2A\uFF08\u4E0D\u4E00\u81F4\u4F1A\u5BFC\u81F4 node push / \u8BBE\u8BA1\u5668\u6253\u5F00\u4EE3\u7801\u5931\u8D25\uFF09`);
|
|
4300
|
+
}
|
|
4301
|
+
if (missingInMeta.length) {
|
|
4302
|
+
warnings.push("\u90E8\u5206 flow.json \u4EE3\u7801\u8282\u70B9\u672A\u5199\u5165 flow.meta.json\uFF0C\u8BF7\u6267\u884C project repair-meta");
|
|
4303
|
+
}
|
|
4304
|
+
if (unindexedDirs.length) {
|
|
4305
|
+
warnings.push(`\u5B58\u5728\u672A\u7D22\u5F15\u7684\u8282\u70B9\u76EE\u5F55\uFF1A${unindexedDirs.join(", ")}`);
|
|
4306
|
+
}
|
|
4307
|
+
const ok3 = missingInMeta.length === 0 && orphanInMeta.length === 0 && missingCodeFiles.length === 0 && unindexedDirs.length === 0 && canvasCodeNodeCount === metaCodeIndexedCount;
|
|
4308
|
+
return {
|
|
4309
|
+
ok: ok3,
|
|
4310
|
+
canvasNodeCount,
|
|
4311
|
+
canvasCodeNodeCount,
|
|
4312
|
+
metaIndexedCount: Object.keys(meta.nodes).length,
|
|
4313
|
+
metaCodeIndexedCount,
|
|
4314
|
+
missingInMeta,
|
|
4315
|
+
orphanInMeta,
|
|
4316
|
+
missingCodeFiles,
|
|
4317
|
+
unindexedDirs,
|
|
4318
|
+
warnings
|
|
4319
|
+
};
|
|
3295
4320
|
}
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
};
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
}
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
}
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
const
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
}
|
|
3396
|
-
usedDirNames.add(dirName);
|
|
3397
|
-
const nodeDirAbs = import_path4.default.join(nodesDir, dirName);
|
|
3398
|
-
import_fs3.default.mkdirSync(nodeDirAbs, { recursive: true });
|
|
3399
|
-
const codeFile = `code.${ext}`;
|
|
3400
|
-
import_fs3.default.writeFileSync(import_path4.default.join(nodeDirAbs, codeFile), codeBody, "utf8");
|
|
3401
|
-
import_fs3.default.writeFileSync(
|
|
3402
|
-
import_path4.default.join(nodeDirAbs, NODE_INFO_JSON),
|
|
3403
|
-
JSON.stringify(
|
|
3404
|
-
{
|
|
3405
|
-
_readonly: "\u6B64\u6587\u4EF6\u7531 dazi-flow \u751F\u6210\uFF0C\u4EC5\u4F9B\u67E5\u770B\uFF1B\u7F16\u8F91\u4EE3\u7801\u8BF7\u6539 " + codeFile + "\uFF0C\u914D\u7F6E\u6539 flow.json",
|
|
3406
|
-
node_uuid: nodeUuid,
|
|
3407
|
-
nodeId: semanticId,
|
|
3408
|
-
nodeType,
|
|
3409
|
-
label,
|
|
3410
|
-
codeFile,
|
|
3411
|
-
codeLanguage: language,
|
|
3412
|
-
position: node.position,
|
|
3413
|
-
data: stripped.data
|
|
3414
|
-
},
|
|
3415
|
-
null,
|
|
3416
|
-
2
|
|
3417
|
-
),
|
|
3418
|
-
"utf8"
|
|
3419
|
-
);
|
|
3420
|
-
meta.dir = import_path4.default.posix.join(NODES_DIR, dirName);
|
|
3421
|
-
meta.codeFile = codeFile;
|
|
3422
|
-
meta.codeLanguage = language;
|
|
3423
|
-
meta.codeHash = sha1(codeBody);
|
|
4321
|
+
exports2.auditFlowWorkspace = auditFlowWorkspace3;
|
|
4322
|
+
function writeNodeInfo2(flowDir, node, uuid, nodeType, relDir, codeFile, language, strippedData) {
|
|
4323
|
+
const abs = path_1.default.join(flowDir, relDir);
|
|
4324
|
+
fs_1.default.writeFileSync(path_1.default.join(abs, NODE_INFO_JSON3), JSON.stringify({
|
|
4325
|
+
_readonly: `\u6B64\u6587\u4EF6\u7531 dazi-flow \u751F\u6210\uFF0C\u4EC5\u4F9B\u67E5\u770B\uFF1B\u7F16\u8F91\u4EE3\u7801\u8BF7\u6539 ${codeFile}\uFF0C\u914D\u7F6E\u6539 flow.json`,
|
|
4326
|
+
node_uuid: uuid,
|
|
4327
|
+
nodeId: String(node.id ?? ""),
|
|
4328
|
+
nodeType,
|
|
4329
|
+
label: String(node.data?.label ?? ""),
|
|
4330
|
+
codeFile,
|
|
4331
|
+
codeLanguage: language,
|
|
4332
|
+
position: node.position,
|
|
4333
|
+
data: strippedData
|
|
4334
|
+
}, null, 2), "utf8");
|
|
4335
|
+
}
|
|
4336
|
+
function repairFlowMeta3(flowDir) {
|
|
4337
|
+
const warnings = [];
|
|
4338
|
+
const repairedUuids = [];
|
|
4339
|
+
const wroteNodeInfo = [];
|
|
4340
|
+
const doc = readFlowJson3(flowDir);
|
|
4341
|
+
const meta = readMeta3(flowDir) ?? { flowId: null, flowName: path_1.default.basename(flowDir), nodes: {} };
|
|
4342
|
+
if (!meta.nodes)
|
|
4343
|
+
meta.nodes = {};
|
|
4344
|
+
const usedDirNames = new Set(Object.values(meta.nodes).map((m) => m.dir?.split("/").pop()).filter(Boolean));
|
|
4345
|
+
for (const node of doc.nodes) {
|
|
4346
|
+
const uuid = String(node.node_uuid ?? "").trim();
|
|
4347
|
+
if (!uuid)
|
|
4348
|
+
continue;
|
|
4349
|
+
const nodeType = resolveNodeType3(node);
|
|
4350
|
+
const codeKey = NODE_TYPE_CODE_DATA_KEY3[nodeType];
|
|
4351
|
+
const semanticId = String(node.id ?? "");
|
|
4352
|
+
const label = String(node.data?.label ?? semanticId ?? nodeType);
|
|
4353
|
+
let entry = meta.nodes[uuid];
|
|
4354
|
+
if (!entry) {
|
|
4355
|
+
entry = { nodeId: semanticId, nodeType };
|
|
4356
|
+
meta.nodes[uuid] = entry;
|
|
4357
|
+
repairedUuids.push(uuid);
|
|
4358
|
+
} else {
|
|
4359
|
+
entry.nodeId = semanticId || entry.nodeId;
|
|
4360
|
+
entry.nodeType = nodeType;
|
|
4361
|
+
}
|
|
4362
|
+
if (!codeKey)
|
|
4363
|
+
continue;
|
|
4364
|
+
let relDir = entry.dir?.replace(/\\/g, "/");
|
|
4365
|
+
if (relDir && findCodeFileInDir2(path_1.default.join(flowDir, relDir))) {
|
|
4366
|
+
} else {
|
|
4367
|
+
relDir = findDirForUuid2(flowDir, uuid);
|
|
4368
|
+
}
|
|
4369
|
+
if (!relDir) {
|
|
4370
|
+
const byLabel = path_1.default.posix.join(NODES_DIR3, sanitizeName3(label));
|
|
4371
|
+
if (fs_1.default.existsSync(path_1.default.join(flowDir, byLabel)) && findCodeFileInDir2(path_1.default.join(flowDir, byLabel))) {
|
|
4372
|
+
relDir = byLabel;
|
|
4373
|
+
}
|
|
4374
|
+
}
|
|
4375
|
+
if (!relDir) {
|
|
4376
|
+
let dirName = sanitizeName3(label);
|
|
4377
|
+
if (usedDirNames.has(dirName))
|
|
4378
|
+
dirName = `${dirName}_${uuid.slice(0, 6)}`;
|
|
4379
|
+
usedDirNames.add(dirName);
|
|
4380
|
+
relDir = path_1.default.posix.join(NODES_DIR3, dirName);
|
|
4381
|
+
fs_1.default.mkdirSync(path_1.default.join(flowDir, relDir), { recursive: true });
|
|
4382
|
+
const lang = codeLanguageForNodeType3(nodeType);
|
|
4383
|
+
const codeFile2 = `code.${codeFileExt3(lang)}`;
|
|
4384
|
+
const template = nodeType === "excel-python" ? "# -*- coding: utf-8 -*-\n# Excel \u8282\u70B9\uFF1A\u753B\u5E03\u914D\u7F6E managed_file_id\uFF1B\u4EE3\u7801\u4F7F\u7528 excel_source_path\n" : lang === "sql" ? "-- \u8282\u70B9 SQL\nSELECT 1;\n" : "# -*- coding: utf-8 -*-\n";
|
|
4385
|
+
if (!findCodeFileInDir2(path_1.default.join(flowDir, relDir))) {
|
|
4386
|
+
fs_1.default.writeFileSync(path_1.default.join(flowDir, relDir, codeFile2), template, "utf8");
|
|
4387
|
+
warnings.push(`\u5DF2\u4E3A ${uuid} \u521B\u5EFA\u7A7A\u4EE3\u7801\u6A21\u677F ${relDir}/${codeFile2}`);
|
|
4388
|
+
}
|
|
4389
|
+
}
|
|
4390
|
+
const dirAbs = path_1.default.join(flowDir, relDir);
|
|
4391
|
+
const codeFile = findCodeFileInDir2(dirAbs);
|
|
4392
|
+
if (!codeFile) {
|
|
4393
|
+
warnings.push(`\u8282\u70B9 ${uuid} \u76EE\u5F55 ${relDir} \u65E0 code.*\uFF0C\u8DF3\u8FC7\u4EE3\u7801\u7D22\u5F15`);
|
|
4394
|
+
continue;
|
|
4395
|
+
}
|
|
4396
|
+
const language = codeLanguageForNodeType3(nodeType);
|
|
4397
|
+
const code = fs_1.default.readFileSync(path_1.default.join(dirAbs, codeFile), "utf8");
|
|
4398
|
+
entry.dir = relDir;
|
|
4399
|
+
entry.codeFile = codeFile;
|
|
4400
|
+
entry.codeLanguage = language;
|
|
4401
|
+
entry.codeHash = sha13(code);
|
|
4402
|
+
const strippedData = { ...node.data ?? {} };
|
|
4403
|
+
delete strippedData[codeKey];
|
|
4404
|
+
const infoPath = path_1.default.join(dirAbs, NODE_INFO_JSON3);
|
|
4405
|
+
if (!fs_1.default.existsSync(infoPath)) {
|
|
4406
|
+
writeNodeInfo2(flowDir, node, uuid, nodeType, relDir, codeFile, language, strippedData);
|
|
4407
|
+
wroteNodeInfo.push(relDir);
|
|
4408
|
+
}
|
|
4409
|
+
if (!repairedUuids.includes(uuid))
|
|
4410
|
+
repairedUuids.push(uuid);
|
|
4411
|
+
}
|
|
4412
|
+
meta.graphFingerprint = "sha1:" + sha13(JSON.stringify({ nodes: doc.nodes, edges: doc.edges }));
|
|
4413
|
+
fs_1.default.writeFileSync(path_1.default.join(flowDir, FLOW_META_JSON3), JSON.stringify(meta, null, 2), "utf8");
|
|
4414
|
+
const okAfter = auditFlowWorkspace3(flowDir).ok;
|
|
4415
|
+
return {
|
|
4416
|
+
ok: okAfter,
|
|
4417
|
+
repairedUuids: [...new Set(repairedUuids)],
|
|
4418
|
+
wroteNodeInfo,
|
|
4419
|
+
warnings
|
|
4420
|
+
};
|
|
3424
4421
|
}
|
|
3425
|
-
|
|
3426
|
-
|
|
4422
|
+
exports2.repairFlowMeta = repairFlowMeta3;
|
|
4423
|
+
function buildFlowConsistencyMarkdown2(audit, localFilesSpecLink = "../../\u8D44\u6E90/docs/flow/local-files-spec.md") {
|
|
4424
|
+
const lines = [
|
|
4425
|
+
"## \u672C\u5730\u6587\u4EF6\u4E00\u81F4\u6027",
|
|
4426
|
+
"",
|
|
4427
|
+
"| \u6307\u6807 | \u6570\u91CF |",
|
|
4428
|
+
"|------|------|",
|
|
4429
|
+
`| \u753B\u5E03\u8282\u70B9\uFF08flow.json\uFF09 | ${audit.canvasNodeCount} |`,
|
|
4430
|
+
`| \u753B\u5E03\u4EE3\u7801\u8282\u70B9\uFF08flow.json\uFF09 | ${audit.canvasCodeNodeCount} |`,
|
|
4431
|
+
`| meta \u5DF2\u767B\u8BB0\u8282\u70B9 | ${audit.metaIndexedCount} |`,
|
|
4432
|
+
`| meta \u5DF2\u7D22\u5F15\u4EE3\u7801\uFF08dir+codeFile\uFF09 | ${audit.metaCodeIndexedCount} |`,
|
|
4433
|
+
""
|
|
4434
|
+
];
|
|
4435
|
+
if (audit.ok) {
|
|
4436
|
+
lines.push("\u2705 **flow.json / flow.meta.json / \u8282\u70B9/ \u4E00\u81F4**\u3002\u8BBE\u8BA1\u5668\u53EF\u6B63\u5E38\u300C\u6253\u5F00\u4EE3\u7801\u300D\uFF0C`node push` \u53EF\u8BC6\u522B\u810F\u8282\u70B9\u3002", "");
|
|
4437
|
+
} else {
|
|
4438
|
+
lines.push("\u26A0\uFE0F **\u76EE\u5F55\u4E0D\u4E00\u81F4**\uFF08\u4F1A\u5BFC\u81F4\u8BBE\u8BA1\u5668\u627E\u4E0D\u5230\u4EE3\u7801\u3001\u6216 `node push` \u8DF3\u8FC7\uFF09\uFF1A", "");
|
|
4439
|
+
if (audit.missingInMeta.length) {
|
|
4440
|
+
lines.push("| uuid | \u8282\u70B9 | \u7C7B\u578B |");
|
|
4441
|
+
lines.push("|------|------|------|");
|
|
4442
|
+
for (const m of audit.missingInMeta) {
|
|
4443
|
+
lines.push(`| \`${m.uuid.slice(0, 8)}\u2026\` | ${m.label || m.nodeId} | ${m.nodeType} |`);
|
|
4444
|
+
}
|
|
4445
|
+
lines.push("");
|
|
4446
|
+
}
|
|
4447
|
+
if (audit.unindexedDirs.length) {
|
|
4448
|
+
lines.push(`- \u672A\u7D22\u5F15\u76EE\u5F55\uFF1A${audit.unindexedDirs.map((d) => `\`${d}\``).join(" ")}`);
|
|
4449
|
+
}
|
|
4450
|
+
if (audit.orphanInMeta.length) {
|
|
4451
|
+
lines.push(`- meta \u591A\u4F59 uuid\uFF1A${audit.orphanInMeta.length} \u4E2A\uFF08flow.json \u4E2D\u5DF2\u4E0D\u5B58\u5728\uFF09`);
|
|
4452
|
+
}
|
|
4453
|
+
for (const w of audit.warnings)
|
|
4454
|
+
lines.push(`- ${w}`);
|
|
4455
|
+
lines.push("", "\u4FEE\u590D\uFF08\u5728\u6D41\u7A0B\u76EE\u5F55\uFF09\uFF1A", "", "```powershell", "dazi flow project repair-meta --dir .", "dazi flow project doctor --dir .", "```", "", `\u8BE6\u89C1 [\u6D41\u7A0B\u672C\u5730\u6587\u4EF6\u89C4\u8303](${localFilesSpecLink})\u3002`, "");
|
|
4456
|
+
}
|
|
4457
|
+
lines.push("## \u53D8\u66F4\u63D0\u4EA4\u547D\u4EE4\u77E9\u9635", "", "| \u6539\u4E86\u4EC0\u4E48 | \u547D\u4EE4 |", "|----------|------|", "| `managed_file_id`\u3001`output_variable_name`\u3001\u8FDE\u7EBF\u3001\u589E\u5220\u8282\u70B9 | `dazi flow project push --dir . --canvas` |", "| `\u8282\u70B9/<\u540D>/code.py` \u6216 `code.sql` | `dazi flow node push --node <uuid> --dir .` |", '| **\u65B0\u589E\u4EE3\u7801\u8282\u70B9** | `dazi flow node new --type <type> --dir . --label "<\u540D>"` \u2192 \u6539\u914D\u7F6E \u2192 `push --canvas` \u2192 \u5199 code \u2192 `node push` |', "", "> \u7981\u6B62\u53EA\u6539 `flow.json` \u800C\u4E0D\u66F4\u65B0 `flow.meta.json`\uFF08\u987B `node new` / `pull` / `repair-meta`\uFF09\u3002", "");
|
|
4458
|
+
return lines;
|
|
3427
4459
|
}
|
|
3428
|
-
|
|
4460
|
+
exports2.buildFlowConsistencyMarkdown = buildFlowConsistencyMarkdown2;
|
|
3429
4461
|
}
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
function
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
const codeKey = NODE_TYPE_CODE_DATA_KEY[nodeMeta.nodeType];
|
|
3458
|
-
if (!codeKey) continue;
|
|
3459
|
-
const code = readNodeCode(flowDir, nodeMeta);
|
|
3460
|
-
if (code != null) {
|
|
3461
|
-
node.data = { ...node.data ?? {}, [codeKey]: code };
|
|
4462
|
+
});
|
|
4463
|
+
|
|
4464
|
+
// src/shared/flowDirResolve.js
|
|
4465
|
+
var require_flowDirResolve = __commonJS({
|
|
4466
|
+
"src/shared/flowDirResolve.js"(exports2) {
|
|
4467
|
+
"use strict";
|
|
4468
|
+
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
4469
|
+
return mod && mod.__esModule ? mod : { "default": mod };
|
|
4470
|
+
};
|
|
4471
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
4472
|
+
exports2.resolveFlowDir = exports2.resolveFlowDirForCli = exports2.findFlowDirForPath = exports2.inferBusinessProjectFolder = exports2.FLOW_META_JSON = exports2.FLOW_JSON = void 0;
|
|
4473
|
+
var fs_1 = __importDefault(require("fs"));
|
|
4474
|
+
var path_1 = __importDefault(require("path"));
|
|
4475
|
+
exports2.FLOW_JSON = "flow.json";
|
|
4476
|
+
exports2.FLOW_META_JSON = "flow.meta.json";
|
|
4477
|
+
function inferBusinessProjectFolder2(flowDir) {
|
|
4478
|
+
const norm = path_1.default.resolve(flowDir).replace(/\\/g, "/");
|
|
4479
|
+
let m = norm.match(/(?:^|\/)项目\/([^/]+)\/流程\/flows\/[^/]+(?:\/|$)/);
|
|
4480
|
+
if (m)
|
|
4481
|
+
return m[1];
|
|
4482
|
+
m = norm.match(/(?:^|\/)项目\/([^/]+)\/流程\/([^/]+)(?:\/|$)/);
|
|
4483
|
+
if (m && m[2] !== "flows" && m[2] !== "\u89C4\u5212")
|
|
4484
|
+
return m[1];
|
|
4485
|
+
m = norm.match(/(?:^|\/)项目\/(flow_[^/]+)\/流程(?:\/|$)/);
|
|
4486
|
+
if (m)
|
|
4487
|
+
return m[1];
|
|
4488
|
+
return void 0;
|
|
3462
4489
|
}
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
4490
|
+
exports2.inferBusinessProjectFolder = inferBusinessProjectFolder2;
|
|
4491
|
+
function findFlowDirForPath(target) {
|
|
4492
|
+
let cur = path_1.default.resolve(target);
|
|
4493
|
+
if (fs_1.default.existsSync(cur)) {
|
|
4494
|
+
try {
|
|
4495
|
+
if (fs_1.default.statSync(cur).isFile())
|
|
4496
|
+
cur = path_1.default.dirname(cur);
|
|
4497
|
+
} catch {
|
|
4498
|
+
return void 0;
|
|
4499
|
+
}
|
|
4500
|
+
}
|
|
4501
|
+
for (let i = 0; i < 8 && cur; i++) {
|
|
4502
|
+
if (fs_1.default.existsSync(path_1.default.join(cur, exports2.FLOW_JSON)))
|
|
4503
|
+
return cur;
|
|
4504
|
+
const parent = path_1.default.dirname(cur);
|
|
4505
|
+
if (parent === cur)
|
|
4506
|
+
break;
|
|
4507
|
+
cur = parent;
|
|
4508
|
+
}
|
|
4509
|
+
return void 0;
|
|
4510
|
+
}
|
|
4511
|
+
exports2.findFlowDirForPath = findFlowDirForPath;
|
|
4512
|
+
function isWorkspaceRootCandidate(dir) {
|
|
4513
|
+
return fs_1.default.existsSync(path_1.default.join(dir, "\u9879\u76EE")) || fs_1.default.existsSync(path_1.default.join(dir, "scripts", "dazi.ps1"));
|
|
3474
4514
|
}
|
|
4515
|
+
function resolveFlowDirForCli(dir) {
|
|
4516
|
+
const requested = path_1.default.resolve(dir ?? process.cwd());
|
|
4517
|
+
const warnings = [];
|
|
4518
|
+
if (fs_1.default.existsSync(path_1.default.join(requested, exports2.FLOW_JSON))) {
|
|
4519
|
+
return { flowDir: requested, resolvedFromParent: false, warnings };
|
|
4520
|
+
}
|
|
4521
|
+
const found = findFlowDirForPath(requested);
|
|
4522
|
+
if (found) {
|
|
4523
|
+
if (found !== requested) {
|
|
4524
|
+
warnings.push(`--dir \u672A\u76F4\u63A5\u6307\u5411\u6D41\u7A0B\u76EE\u5F55\uFF0C\u5DF2\u5411\u4E0A\u89E3\u6790\u4E3A: ${found}`);
|
|
4525
|
+
}
|
|
4526
|
+
return { flowDir: found, resolvedFromParent: found !== requested, warnings };
|
|
4527
|
+
}
|
|
4528
|
+
const hasMetaOnly = fs_1.default.existsSync(path_1.default.join(requested, exports2.FLOW_META_JSON)) && !fs_1.default.existsSync(path_1.default.join(requested, exports2.FLOW_JSON));
|
|
4529
|
+
if (hasMetaOnly || isWorkspaceRootCandidate(requested) && !fs_1.default.existsSync(path_1.default.join(requested, exports2.FLOW_JSON))) {
|
|
4530
|
+
return {
|
|
4531
|
+
flowDir: requested,
|
|
4532
|
+
resolvedFromParent: false,
|
|
4533
|
+
warnings,
|
|
4534
|
+
error: "\u5F53\u524D\u76EE\u5F55\u4E0D\u662F\u6D41\u7A0B\u76EE\u5F55\uFF08\u7F3A\u5C11 flow.json\uFF09\u3002\u8BF7\u4F7F\u7528 --dir \u6307\u5411 \u9879\u76EE/<\u4E1A\u52A1\u540D>/\u6D41\u7A0B/flows/<\u6D41\u7A0B\u540D> \u7684\u7EDD\u5BF9\u8DEF\u5F84\uFF1B\u7981\u6B62\u5728 dazi-work \u5DE5\u4F5C\u533A\u6839\u6267\u884C project status/push/pull --dir ."
|
|
4535
|
+
};
|
|
4536
|
+
}
|
|
4537
|
+
return {
|
|
4538
|
+
flowDir: requested,
|
|
4539
|
+
resolvedFromParent: false,
|
|
4540
|
+
warnings,
|
|
4541
|
+
error: `\u76EE\u5F55\u7F3A\u5C11 flow.json: ${requested}\u3002\u8BF7 --dir \u6307\u5411\u542B flow.json \u7684\u6D41\u7A0B\u76EE\u5F55\uFF08\u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84\uFF09\u3002`
|
|
4542
|
+
};
|
|
4543
|
+
}
|
|
4544
|
+
exports2.resolveFlowDirForCli = resolveFlowDirForCli;
|
|
4545
|
+
function resolveFlowDir5(dir, opts) {
|
|
4546
|
+
const result = resolveFlowDirForCli(dir);
|
|
4547
|
+
if (!opts?.json) {
|
|
4548
|
+
for (const w of result.warnings)
|
|
4549
|
+
console.warn(`\u26A0\uFE0F ${w}`);
|
|
4550
|
+
}
|
|
4551
|
+
if (result.error) {
|
|
4552
|
+
console.error(`\u9519\u8BEF: ${result.error}`);
|
|
4553
|
+
process.exit(1);
|
|
4554
|
+
}
|
|
4555
|
+
return result.flowDir;
|
|
4556
|
+
}
|
|
4557
|
+
exports2.resolveFlowDir = resolveFlowDir5;
|
|
3475
4558
|
}
|
|
3476
|
-
|
|
3477
|
-
}
|
|
4559
|
+
});
|
|
3478
4560
|
|
|
3479
|
-
//
|
|
3480
|
-
var
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
if (!opts.force && baseHash && remoteHash !== baseHash) {
|
|
3495
|
-
return { uuid, status: "conflict", version: remote.version };
|
|
3496
|
-
}
|
|
3497
|
-
if (opts.dryRun) return { uuid, status: "dry-run", version: remote.version };
|
|
3498
|
-
const updated = await apiRequest(`${FLOW_API}/${flowId}/flow-nodes/${uuid}`, {
|
|
3499
|
-
method: "PATCH",
|
|
3500
|
-
body: { code_body: localCode, expected_version: opts.force ? void 0 : remote.version },
|
|
3501
|
-
label: `\u63D0\u4EA4\u8282\u70B9\u4EE3\u7801 (nodeId=${nodeLabel}, uuid=${uuid})`
|
|
3502
|
-
});
|
|
3503
|
-
nodeMeta.codeHash = sha1(localCode);
|
|
3504
|
-
nodeMeta.codeVersion = updated.version;
|
|
3505
|
-
return { uuid, status: "pushed", version: updated.version };
|
|
3506
|
-
}
|
|
3507
|
-
async function pullCodeNode(flowId, flowDir, meta, uuid) {
|
|
3508
|
-
const nodeMeta = meta.nodes[uuid];
|
|
3509
|
-
if (!nodeMeta?.dir || !nodeMeta.codeFile) {
|
|
3510
|
-
throw new Error(`\u8282\u70B9 ${uuid} \u4E0D\u662F\u4EE3\u7801\u8282\u70B9\u6216\u7F3A\u5C11\u672C\u5730\u6620\u5C04`);
|
|
4561
|
+
// src/shared/managedFilesTypes.js
|
|
4562
|
+
var require_managedFilesTypes = __commonJS({
|
|
4563
|
+
"src/shared/managedFilesTypes.js"(exports2) {
|
|
4564
|
+
"use strict";
|
|
4565
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
4566
|
+
exports2.MANAGED_BUNDLE_FILES = exports2.MANAGED_FS_API = exports2.MANAGED_FILES_API = void 0;
|
|
4567
|
+
exports2.MANAGED_FILES_API = "/api/data-pipelines/v1/managed-files";
|
|
4568
|
+
exports2.MANAGED_FS_API = "/api/data-pipelines/v1/managed-fs";
|
|
4569
|
+
exports2.MANAGED_BUNDLE_FILES = {
|
|
4570
|
+
manifest: "\u6587\u4EF6\u4FE1\u606F.json",
|
|
4571
|
+
originalPrefix: "\u539F\u6587\u4EF6",
|
|
4572
|
+
nativeDigest: "\u539F\u751F\u89E3\u6790.md",
|
|
4573
|
+
aiStructure: "\u8868\u7ED3\u6784.json",
|
|
4574
|
+
reportLayout: "\u62A5\u8868\u5E03\u5C40.json"
|
|
4575
|
+
};
|
|
3511
4576
|
}
|
|
3512
|
-
|
|
3513
|
-
label: `\u62C9\u53D6\u8282\u70B9\u4EE3\u7801 (uuid=${uuid})`
|
|
3514
|
-
});
|
|
3515
|
-
const code = remote.code_body ?? "";
|
|
3516
|
-
const target = import_path5.default.join(flowDir, nodeMeta.dir, nodeMeta.codeFile);
|
|
3517
|
-
import_fs4.default.mkdirSync(import_path5.default.dirname(target), { recursive: true });
|
|
3518
|
-
import_fs4.default.writeFileSync(target, code, "utf8");
|
|
3519
|
-
nodeMeta.codeHash = sha1(code);
|
|
3520
|
-
nodeMeta.codeVersion = remote.version;
|
|
3521
|
-
return { uuid, version: remote.version };
|
|
3522
|
-
}
|
|
3523
|
-
async function pushCanvasDocument(flowId, document) {
|
|
3524
|
-
const nodeCount = document.nodes?.length ?? 0;
|
|
3525
|
-
const edgeCount = document.edges?.length ?? 0;
|
|
3526
|
-
await apiRequest(`${FLOW_API}/${flowId}`, {
|
|
3527
|
-
method: "PUT",
|
|
3528
|
-
body: { data: document },
|
|
3529
|
-
label: `\u63D0\u4EA4\u753B\u5E03 flow.json (flowId=${flowId}, nodes=${nodeCount}, edges=${edgeCount})`
|
|
3530
|
-
});
|
|
3531
|
-
}
|
|
4577
|
+
});
|
|
3532
4578
|
|
|
3533
|
-
//
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
4579
|
+
// src/shared/managedFilesBundle.js
|
|
4580
|
+
var require_managedFilesBundle = __commonJS({
|
|
4581
|
+
"src/shared/managedFilesBundle.js"(exports2) {
|
|
4582
|
+
"use strict";
|
|
4583
|
+
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
4584
|
+
return mod && mod.__esModule ? mod : { "default": mod };
|
|
4585
|
+
};
|
|
4586
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
4587
|
+
exports2.findManagedFileInBrowse = exports2.pullManagedFileBundle = exports2.isExcelManagedFile = exports2.describeManagedFileLocalState = exports2.isManagedFilePulledLocally = exports2.managedFileLocalDir = exports2.managedFileLocalFolderName = void 0;
|
|
4588
|
+
var fs_1 = __importDefault(require("fs"));
|
|
4589
|
+
var path_1 = __importDefault(require("path"));
|
|
4590
|
+
var managedFilesTypes_js_1 = require_managedFilesTypes();
|
|
4591
|
+
function apiBase(auth) {
|
|
4592
|
+
return auth.serverUrl.replace(/\/$/, "");
|
|
4593
|
+
}
|
|
4594
|
+
function sanitizeDirPart(raw) {
|
|
4595
|
+
return raw.trim().replace(/\s+/g, "_").replace(/[<>:"|?*/\\]/g, "_").slice(0, 80) || "file";
|
|
4596
|
+
}
|
|
4597
|
+
function managedFileLocalFolderName(meta) {
|
|
4598
|
+
const base = sanitizeDirPart(meta.display_name ?? meta.file_id);
|
|
4599
|
+
const shortId = meta.file_id.slice(0, 8);
|
|
4600
|
+
return `${base}_${shortId}`;
|
|
4601
|
+
}
|
|
4602
|
+
exports2.managedFileLocalFolderName = managedFileLocalFolderName;
|
|
4603
|
+
function managedFileLocalDir(filesRoot, meta) {
|
|
4604
|
+
return path_1.default.join(filesRoot, managedFileLocalFolderName(meta));
|
|
4605
|
+
}
|
|
4606
|
+
exports2.managedFileLocalDir = managedFileLocalDir;
|
|
4607
|
+
function isManagedFilePulledLocally(filesRoot, meta) {
|
|
4608
|
+
return fs_1.default.existsSync(path_1.default.join(managedFileLocalDir(filesRoot, meta), managedFilesTypes_js_1.MANAGED_BUNDLE_FILES.manifest));
|
|
4609
|
+
}
|
|
4610
|
+
exports2.isManagedFilePulledLocally = isManagedFilePulledLocally;
|
|
4611
|
+
function describeManagedFileLocalState(wsRoot, meta, filesSubdir = "files") {
|
|
4612
|
+
if (!wsRoot || !meta.file_id)
|
|
4613
|
+
return void 0;
|
|
4614
|
+
const filesRoot = path_1.default.join(wsRoot, "\u8D44\u6E90", filesSubdir);
|
|
4615
|
+
if (isManagedFilePulledLocally(filesRoot, meta))
|
|
4616
|
+
return "\u5DF2\u62C9\u53D6";
|
|
4617
|
+
return void 0;
|
|
4618
|
+
}
|
|
4619
|
+
exports2.describeManagedFileLocalState = describeManagedFileLocalState;
|
|
4620
|
+
function isExcelManagedFile(meta) {
|
|
4621
|
+
const ext = (meta.file_ext ?? path_1.default.extname(meta.display_name ?? "")).toLowerCase();
|
|
4622
|
+
if (ext === ".xlsx" || ext === ".xls")
|
|
4623
|
+
return true;
|
|
4624
|
+
const mime = (meta.mime_type ?? "").toLowerCase();
|
|
4625
|
+
return mime.includes("spreadsheet") || mime.endsWith(".sheet");
|
|
4626
|
+
}
|
|
4627
|
+
exports2.isExcelManagedFile = isExcelManagedFile;
|
|
4628
|
+
async function fetchJson(auth, urlPath, method = "GET") {
|
|
4629
|
+
const res = await fetch(`${apiBase(auth)}${urlPath}`, {
|
|
4630
|
+
method,
|
|
4631
|
+
headers: {
|
|
4632
|
+
Authorization: `Bearer ${auth.token}`,
|
|
4633
|
+
Accept: "application/json",
|
|
4634
|
+
...method === "POST" ? { "Content-Type": "application/json" } : {}
|
|
4635
|
+
}
|
|
4636
|
+
});
|
|
4637
|
+
if (!res.ok) {
|
|
4638
|
+
const text = await res.text().catch(() => "");
|
|
4639
|
+
throw new Error(`HTTP ${res.status}: ${text || res.statusText}`);
|
|
3551
4640
|
}
|
|
3552
|
-
|
|
3553
|
-
} catch (err) {
|
|
3554
|
-
handleError(err);
|
|
4641
|
+
return res.json();
|
|
3555
4642
|
}
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
console.error(`\u9519\u8BEF: \u627E\u4E0D\u5230 ${file}\uFF0C\u8BF7\u5148\u8FD0\u884C snapshot pull`);
|
|
3564
|
-
process.exit(1);
|
|
4643
|
+
async function downloadBinary(auth, urlPath, destPath) {
|
|
4644
|
+
const res = await fetch(`${apiBase(auth)}${urlPath}`, {
|
|
4645
|
+
headers: { Authorization: `Bearer ${auth.token}` }
|
|
4646
|
+
});
|
|
4647
|
+
if (!res.ok) {
|
|
4648
|
+
const text = await res.text().catch(() => "");
|
|
4649
|
+
throw new Error(`\u4E0B\u8F7D\u5931\u8D25 HTTP ${res.status}: ${text || res.statusText}`);
|
|
3565
4650
|
}
|
|
3566
|
-
const
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
4651
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
4652
|
+
fs_1.default.mkdirSync(path_1.default.dirname(destPath), { recursive: true });
|
|
4653
|
+
fs_1.default.writeFileSync(destPath, buf);
|
|
4654
|
+
}
|
|
4655
|
+
async function resolveNativeDigest(auth, fileId, parseIfMissing) {
|
|
4656
|
+
if (!parseIfMissing) {
|
|
4657
|
+
try {
|
|
4658
|
+
return await fetchJson(auth, `${managedFilesTypes_js_1.MANAGED_FILES_API}/${encodeURIComponent(fileId)}/excel-native-digest`);
|
|
4659
|
+
} catch {
|
|
4660
|
+
return null;
|
|
4661
|
+
}
|
|
4662
|
+
}
|
|
4663
|
+
try {
|
|
4664
|
+
let resp = await fetchJson(auth, `${managedFilesTypes_js_1.MANAGED_FILES_API}/${encodeURIComponent(fileId)}/excel-native-digest`);
|
|
4665
|
+
if (resp.markdown)
|
|
4666
|
+
return resp;
|
|
4667
|
+
} catch {
|
|
4668
|
+
}
|
|
4669
|
+
try {
|
|
4670
|
+
return await fetchJson(auth, `${managedFilesTypes_js_1.MANAGED_FILES_API}/${encodeURIComponent(fileId)}/excel-native-parse`, "POST");
|
|
4671
|
+
} catch {
|
|
4672
|
+
return null;
|
|
3573
4673
|
}
|
|
3574
|
-
const doc = extractDocument(snapshot);
|
|
3575
|
-
await pushCanvasDocument(opts.flow, doc);
|
|
3576
|
-
console.log(`\u2705 \u56FE\u5FEB\u7167\u5DF2\u63A8\u9001`);
|
|
3577
|
-
ok({ flowId: opts.flow, nodeCount: doc.nodes.length, edgeCount: doc.edges.length });
|
|
3578
|
-
} catch (err) {
|
|
3579
|
-
handleError(err);
|
|
3580
4674
|
}
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
}
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
var import_path10 = __toESM(require("path"), 1);
|
|
3587
|
-
var import_fs8 = __toESM(require("fs"), 1);
|
|
3588
|
-
|
|
3589
|
-
// src/shared/flowScaffoldDocs.ts
|
|
3590
|
-
var import_path8 = __toESM(require("path"));
|
|
3591
|
-
|
|
3592
|
-
// src/shared/flowNodeCatalog.ts
|
|
3593
|
-
var FLOW_NODE_CATALOG = [
|
|
3594
|
-
{
|
|
3595
|
-
group: "\u6D41\u7A0B\u63A7\u5236",
|
|
3596
|
-
items: [
|
|
3597
|
-
{
|
|
3598
|
-
type: "condition",
|
|
3599
|
-
label: "\u6761\u4EF6\u5224\u65AD",
|
|
3600
|
-
hasCode: true,
|
|
3601
|
-
codeFile: "code.py",
|
|
3602
|
-
summary: "\u5BF9\u4E0A\u6E38\u8868\u6C42\u5E03\u5C14\u8868\u8FBE\u5F0F\uFF0C\u8D70 True/False \u5206\u652F",
|
|
3603
|
-
consumes: "\u5165\u8FB9\u4E0A\u6E38\u8868 \u2192 \u8FD0\u884C\u65F6\u6CE8\u5165 `df`",
|
|
3604
|
-
produces: "\u65E0\u65B0\u8868\u53D8\u91CF\uFF08\u4EC5\u8DEF\u7531\uFF09",
|
|
3605
|
-
keyConfig: ["label", "pythonCode\uFF08\u4EE3\u7801\u5728 code.py\uFF09"]
|
|
3606
|
-
},
|
|
3607
|
-
{
|
|
3608
|
-
type: "delay",
|
|
3609
|
-
label: "\u5EF6\u65F6\u7B49\u5F85",
|
|
3610
|
-
hasCode: false,
|
|
3611
|
-
summary: "\u6682\u505C\u6307\u5B9A\u79D2\u6570\u540E\u7EE7\u7EED\u4E0B\u6E38",
|
|
3612
|
-
keyConfig: ["delaySeconds \u6216 delay\uFF08\u79D2\uFF09"]
|
|
3613
|
-
}
|
|
3614
|
-
]
|
|
3615
|
-
},
|
|
3616
|
-
{
|
|
3617
|
-
group: "\u6570\u636E\u5904\u7406",
|
|
3618
|
-
items: [
|
|
3619
|
-
{
|
|
3620
|
-
type: "file-source",
|
|
3621
|
-
label: "\u6587\u4EF6\u8F93\u5165",
|
|
3622
|
-
hasCode: false,
|
|
3623
|
-
summary: "\u975E Excel \u539F\u59CB\u6587\u4EF6\u900F\u4F20\uFF08.xlsx/.xls \u52FF\u7528\uFF0C\u6539 excel-python\uFF09",
|
|
3624
|
-
produces: "`output_variable_name`",
|
|
3625
|
-
keyConfig: ["file_id / managed_file_id", "output_variable_name"]
|
|
3626
|
-
},
|
|
3627
|
-
{
|
|
3628
|
-
type: "excel-import",
|
|
3629
|
-
label: "Excel \u5BFC\u5165",
|
|
3630
|
-
hasCode: false,
|
|
3631
|
-
summary: "\u4EC5\u6781\u7B80\u5355\u5355 Sheet \u96F6\u4EE3\u7801\uFF1B\u6709 file_id \u7684 Excel \u9ED8\u8BA4\u4ECD\u7528 excel-python",
|
|
3632
|
-
produces: "`output_variable_name`",
|
|
3633
|
-
keyConfig: ["file_id / source_excel_id", "sheetName\uFF08\u53EF\u9009\uFF09", "output_variable_name"]
|
|
3634
|
-
},
|
|
3635
|
-
{
|
|
3636
|
-
type: "excel-python",
|
|
3637
|
-
label: "Excel \u5F00\u53D1",
|
|
3638
|
-
hasCode: true,
|
|
3639
|
-
codeFile: "code.py",
|
|
3640
|
-
summary: "\u591A Sheet / \u590D\u6742\u8868\u5934\uFF1APython \u89E3\u6790 Excel\uFF08\u753B\u5E03\u914D managed_file_id\uFF0C\u4EE3\u7801\u7528 excel_source_path\uFF09",
|
|
3641
|
-
produces: "`set_table_output(\u4E0E output_variable_name \u540C\u540D, df)`",
|
|
3642
|
-
keyConfig: ["managed_file_id\uFF08UUID\uFF0C\u975E\u6587\u4EF6\u540D\uFF09", "output_variable_name"]
|
|
3643
|
-
},
|
|
3644
|
-
{
|
|
3645
|
-
type: "sql-query",
|
|
3646
|
-
label: "SQL \u67E5\u8BE2",
|
|
3647
|
-
hasCode: true,
|
|
3648
|
-
codeFile: "code.sql",
|
|
3649
|
-
summary: "DuckDB \u5185\u5B58 SQL\uFF0C\u4E0A\u6E38\u53D8\u91CF\u540D\u4F5C\u8868\u540D",
|
|
3650
|
-
consumes: "\u4E0A\u6E38 `output_variable_name` \u4F5C SQL \u8868\u540D",
|
|
3651
|
-
produces: "`output_variable_name`",
|
|
3652
|
-
keyConfig: ["output_variable_name"]
|
|
3653
|
-
},
|
|
3654
|
-
{
|
|
3655
|
-
type: "python-script",
|
|
3656
|
-
label: "Python \u811A\u672C",
|
|
3657
|
-
hasCode: true,
|
|
3658
|
-
codeFile: "code.py",
|
|
3659
|
-
summary: "pandas \u8F6C\u6362\uFF1B\u6700\u5E38\u7528\u52A0\u5DE5\u8282\u70B9",
|
|
3660
|
-
consumes: '`get_variable("\u4E0A\u6E38\u53D8\u91CF\u540D")` \u6216\u5165\u8FB9 `df`',
|
|
3661
|
-
produces: "`result_df` \u2192 `output_variable_name`",
|
|
3662
|
-
keyConfig: ["output_variable_name"]
|
|
3663
|
-
},
|
|
3664
|
-
{
|
|
3665
|
-
type: "database-source",
|
|
3666
|
-
label: "\u6570\u636E\u5E93\u8BFB\u53D6",
|
|
3667
|
-
hasCode: true,
|
|
3668
|
-
codeFile: "code.sql",
|
|
3669
|
-
summary: "\u4ECE\u5916\u90E8\u6570\u636E\u5E93\uFF08connectionId\uFF09\u53EA\u8BFB\u67E5\u8BE2",
|
|
3670
|
-
produces: "`output_variable_name`",
|
|
3671
|
-
keyConfig: ["connectionId", "output_variable_name"]
|
|
3672
|
-
},
|
|
3673
|
-
{
|
|
3674
|
-
type: "database-sink",
|
|
3675
|
-
label: "\u6570\u636E\u5E93\u5199\u5165",
|
|
3676
|
-
hasCode: false,
|
|
3677
|
-
summary: "\u5C06\u8868\u53D8\u91CF\u5199\u5165\u5916\u90E8\u6570\u636E\u5E93\u8868",
|
|
3678
|
-
consumes: "`input_variable_name` \u6216\u5165\u8FB9 Parquet",
|
|
3679
|
-
keyConfig: ["connectionId", "tableName", "mode", "input_variable_name"]
|
|
3680
|
-
},
|
|
3681
|
-
{
|
|
3682
|
-
type: "dataspace-source",
|
|
3683
|
-
label: "\u6570\u636E\u7A7A\u95F4\u8BFB\u53D6",
|
|
3684
|
-
hasCode: true,
|
|
3685
|
-
codeFile: "code.sql",
|
|
3686
|
-
summary: "\u4ECE\u642D\u5B50\u6570\u636E\u7A7A\u95F4\uFF08spaceId\uFF09\u53EA\u8BFB SQL",
|
|
3687
|
-
produces: "`output_variable_name`",
|
|
3688
|
-
keyConfig: ["spaceId", "output_variable_name", "limit\uFF08\u53EF\u9009\uFF09"]
|
|
3689
|
-
},
|
|
3690
|
-
{
|
|
3691
|
-
type: "dataspace-sink",
|
|
3692
|
-
label: "\u6570\u636E\u7A7A\u95F4\u5199\u5165",
|
|
3693
|
-
hasCode: false,
|
|
3694
|
-
summary: "\u5C06\u8868\u53D8\u91CF\u5199\u5165\u6570\u636E\u7A7A\u95F4\u8868",
|
|
3695
|
-
consumes: "`input_variable_name` \u6216\u5165\u8FB9 Parquet",
|
|
3696
|
-
keyConfig: ["spaceId", "tableName", "input_variable_name", "syncMetadata\uFF08\u53EF\u9009\uFF09"]
|
|
3697
|
-
},
|
|
3698
|
-
{
|
|
3699
|
-
type: "data-quality-check",
|
|
3700
|
-
label: "\u6570\u636E\u8D28\u91CF\u68C0\u67E5",
|
|
3701
|
-
hasCode: true,
|
|
3702
|
-
codeFile: "code.py",
|
|
3703
|
-
summary: "\u8D28\u68C0\u89C4\u5219\u6216\u81EA\u5B9A\u4E49 Python\uFF08dqPythonCode\uFF09",
|
|
3704
|
-
consumes: "\u4E0A\u6E38\u8868 / `get_variable`",
|
|
3705
|
-
produces: "\u8D28\u68C0\u62A5\u544A\u53D8\u91CF\uFF08\u4F9D\u914D\u7F6E\uFF09",
|
|
3706
|
-
keyConfig: ["output_variable_name", "qualityConfig", "dqPythonCode\uFF08\u4F18\u5148\u4E8E\u89C4\u5219\uFF09"]
|
|
3707
|
-
},
|
|
3708
|
-
{
|
|
3709
|
-
type: "folder-resource-import",
|
|
3710
|
-
label: "\u6587\u4EF6\u5939\u8D44\u6E90\u5BFC\u5165",
|
|
3711
|
-
hasCode: false,
|
|
3712
|
-
summary: "\u4ECE\u6587\u4EF6\u5939\u8D44\u6E90\u6279\u91CF\u5BFC\u5165\u6587\u4EF6",
|
|
3713
|
-
produces: "`output_variable_name`",
|
|
3714
|
-
keyConfig: ["folderId", "resourceId", "pageSize", "output_variable_name"]
|
|
3715
|
-
},
|
|
3716
|
-
{
|
|
3717
|
-
type: "folder-resource-register",
|
|
3718
|
-
label: "\u8D44\u6E90\u6CE8\u518C",
|
|
3719
|
-
hasCode: false,
|
|
3720
|
-
summary: "\u5C06\u5BFC\u5165\u7ED3\u679C\u6CE8\u518C\u5230\u8FDE\u63A5/\u8D44\u6E90\u76EE\u5F55",
|
|
3721
|
-
keyConfig: ["connectionName", "targetFolderId"]
|
|
4675
|
+
async function resolveAiStructure(auth, fileId) {
|
|
4676
|
+
try {
|
|
4677
|
+
return await fetchJson(auth, `${managedFilesTypes_js_1.MANAGED_FILES_API}/${encodeURIComponent(fileId)}/excel-ai-structure`);
|
|
4678
|
+
} catch {
|
|
4679
|
+
return null;
|
|
3722
4680
|
}
|
|
3723
|
-
]
|
|
3724
|
-
}
|
|
3725
|
-
];
|
|
3726
|
-
var FLOW_NODE_CATALOG_DESIGNER = FLOW_NODE_CATALOG.map((g) => ({
|
|
3727
|
-
group: g.group,
|
|
3728
|
-
items: g.items.map(({ type, label, hasCode }) => ({
|
|
3729
|
-
type,
|
|
3730
|
-
label,
|
|
3731
|
-
...hasCode ? { code: true } : {}
|
|
3732
|
-
}))
|
|
3733
|
-
}));
|
|
3734
|
-
function buildFlowNodeCatalogQuickStartSection(detailLink) {
|
|
3735
|
-
const lines = [
|
|
3736
|
-
"## \u53EF\u7528\u6D41\u7A0B\u8282\u70B9\uFF08`data.type`\uFF09",
|
|
3737
|
-
"",
|
|
3738
|
-
"> \u753B\u5E03\u8282\u70B9 **`type` \u6052\u4E3A `custom`**\uFF0C\u4E1A\u52A1\u7C7B\u578B\u5728 **`data.type`**\u3002\u65B0\u5EFA\uFF1A`flow node new --type <\u4E0B\u8868 type>`\u3002",
|
|
3739
|
-
"> **\u7981\u6B62**\u7F16\u9020\u672A\u5728\u4E0B\u8868\u4E2D\u7684 type\u3002",
|
|
3740
|
-
""
|
|
3741
|
-
];
|
|
3742
|
-
for (const { group, items } of FLOW_NODE_CATALOG) {
|
|
3743
|
-
lines.push(`### ${group}`, "");
|
|
3744
|
-
lines.push("| type | \u540D\u79F0 | \u4EE3\u7801 | \u7528\u9014 | \u53D8\u91CF |");
|
|
3745
|
-
lines.push("|------|------|:----:|------|------|");
|
|
3746
|
-
for (const n of items) {
|
|
3747
|
-
const code = n.hasCode ? n.codeFile ?? "code.*" : "\u2014";
|
|
3748
|
-
const vars = [n.consumes ? `\u5165:${shortVar(n.consumes)}` : "", n.produces ? `\u51FA:${shortVar(n.produces)}` : ""].filter(Boolean).join(" \xB7 ") || "\u2014";
|
|
3749
|
-
lines.push(`| \`${n.type}\` | ${n.label} | ${code} | ${n.summary} | ${vars} |`);
|
|
3750
4681
|
}
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
4682
|
+
async function resolveReportLayout(auth, fileId) {
|
|
4683
|
+
try {
|
|
4684
|
+
return await fetchJson(auth, `${managedFilesTypes_js_1.MANAGED_FILES_API}/${encodeURIComponent(fileId)}/excel-report-layout`);
|
|
4685
|
+
} catch {
|
|
4686
|
+
return null;
|
|
4687
|
+
}
|
|
4688
|
+
}
|
|
4689
|
+
async function pullManagedFileBundle2(opts) {
|
|
4690
|
+
const { auth, meta } = opts;
|
|
4691
|
+
const fileId = meta.file_id?.trim();
|
|
4692
|
+
if (!fileId)
|
|
4693
|
+
throw new Error("\u7F3A\u5C11 file_id\uFF0C\u4EC5\u652F\u6301\u5DF2\u767B\u8BB0\u6587\u4EF6");
|
|
4694
|
+
const dir = managedFileLocalDir(opts.filesRootDir, meta);
|
|
4695
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
4696
|
+
const written = [];
|
|
4697
|
+
const notes = [];
|
|
4698
|
+
const pulledAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4699
|
+
const ext = (meta.file_ext && meta.file_ext.startsWith(".") ? meta.file_ext : meta.file_ext ? `.${meta.file_ext}` : "") || path_1.default.extname(meta.display_name ?? meta.stored_filename ?? "") || "";
|
|
4700
|
+
const originalName = `${managedFilesTypes_js_1.MANAGED_BUNDLE_FILES.originalPrefix}${ext || ""}`;
|
|
4701
|
+
const originalPath = path_1.default.join(dir, originalName);
|
|
4702
|
+
await downloadBinary(auth, `${managedFilesTypes_js_1.MANAGED_FILES_API}/${encodeURIComponent(fileId)}/content`, originalPath);
|
|
4703
|
+
written.push(originalName);
|
|
4704
|
+
if (isExcelManagedFile(meta)) {
|
|
4705
|
+
const digest = await resolveNativeDigest(auth, fileId, opts.parseNativeIfMissing !== false);
|
|
4706
|
+
if (digest?.markdown) {
|
|
4707
|
+
fs_1.default.writeFileSync(path_1.default.join(dir, managedFilesTypes_js_1.MANAGED_BUNDLE_FILES.nativeDigest), digest.markdown, "utf8");
|
|
4708
|
+
written.push(managedFilesTypes_js_1.MANAGED_BUNDLE_FILES.nativeDigest);
|
|
4709
|
+
} else {
|
|
4710
|
+
notes.push("\u539F\u751F\u89E3\u6790\u672A\u751F\u6210\uFF1A\u8BF7\u5728\u5E73\u53F0\u300C\u6587\u4EF6\u4E0A\u4F20\u7BA1\u7406\u300D\u4E2D\u5BF9 Excel \u6267\u884C\u300C\u539F\u751F\u89E3\u6790\u300D\u540E\u91CD\u8BD5\u62C9\u53D6");
|
|
4711
|
+
}
|
|
4712
|
+
const structureResp = await resolveAiStructure(auth, fileId);
|
|
4713
|
+
if (structureResp?.structure) {
|
|
4714
|
+
fs_1.default.writeFileSync(path_1.default.join(dir, managedFilesTypes_js_1.MANAGED_BUNDLE_FILES.aiStructure), JSON.stringify(structureResp.structure, null, 2), "utf8");
|
|
4715
|
+
written.push(managedFilesTypes_js_1.MANAGED_BUNDLE_FILES.aiStructure);
|
|
4716
|
+
} else {
|
|
4717
|
+
notes.push("\u8868\u7ED3\u6784\u672A\u751F\u6210\uFF1A\u8BF7\u5148\u5728\u5E73\u53F0\u5B8C\u6210\u300C\u539F\u751F\u89E3\u6790\u300D\u4E0E\u300CAI \u8868\u7ED3\u6784\u300D\u540E\u518D\u62C9\u53D6\uFF0C\u6216\u4EC5\u4F7F\u7528\u539F\u751F\u89E3\u6790.md \u4EA4\u7ED9 AI");
|
|
4718
|
+
}
|
|
4719
|
+
const layoutResp = await resolveReportLayout(auth, fileId);
|
|
4720
|
+
if (layoutResp?.layout) {
|
|
4721
|
+
fs_1.default.writeFileSync(path_1.default.join(dir, managedFilesTypes_js_1.MANAGED_BUNDLE_FILES.reportLayout), JSON.stringify(layoutResp.layout, null, 2), "utf8");
|
|
4722
|
+
written.push(managedFilesTypes_js_1.MANAGED_BUNDLE_FILES.reportLayout);
|
|
4723
|
+
} else {
|
|
4724
|
+
notes.push("\u62A5\u8868\u5E03\u5C40\u672A\u751F\u6210\uFF1A\u8BF7\u5728\u5E73\u53F0\u300C\u62A5\u8868\u5E03\u5C40\u300D\u9875\u7B7E\u6267\u884C\u89C4\u5219\u89E3\u6790\u6216 AI \u62A5\u8868\u5E03\u5C40\u540E\u518D\u62C9\u53D6");
|
|
4725
|
+
}
|
|
4726
|
+
} else {
|
|
4727
|
+
notes.push("\u975E Excel \u6587\u4EF6\uFF1A\u4EC5\u62C9\u53D6\u539F\u6587\u4EF6\u4E0E\u6587\u4EF6\u4FE1\u606F\uFF08\u65E0\u539F\u751F\u89E3\u6790/\u8868\u7ED3\u6784\uFF09");
|
|
4728
|
+
}
|
|
4729
|
+
const manifest = {
|
|
4730
|
+
pulledAt,
|
|
4731
|
+
file_id: fileId,
|
|
4732
|
+
display_name: meta.display_name,
|
|
4733
|
+
relative_dir: meta.relative_dir,
|
|
4734
|
+
localDir: dir,
|
|
4735
|
+
files: written,
|
|
4736
|
+
notes: notes.length ? notes : void 0
|
|
4737
|
+
};
|
|
4738
|
+
manifest.files = [...written, managedFilesTypes_js_1.MANAGED_BUNDLE_FILES.manifest];
|
|
4739
|
+
fs_1.default.writeFileSync(path_1.default.join(dir, managedFilesTypes_js_1.MANAGED_BUNDLE_FILES.manifest), JSON.stringify({ ...meta, ...manifest }, null, 2), "utf8");
|
|
4740
|
+
return { dir, manifest };
|
|
4741
|
+
}
|
|
4742
|
+
exports2.pullManagedFileBundle = pullManagedFileBundle2;
|
|
4743
|
+
function findManagedFileInBrowse2(items, fileId) {
|
|
4744
|
+
return items.find((i) => i.file_id === fileId);
|
|
4745
|
+
}
|
|
4746
|
+
exports2.findManagedFileInBrowse = findManagedFileInBrowse2;
|
|
3768
4747
|
}
|
|
3769
|
-
|
|
3770
|
-
}
|
|
3771
|
-
function shortVar(s) {
|
|
3772
|
-
return s.replace(/`/g, "").slice(0, 40);
|
|
3773
|
-
}
|
|
4748
|
+
});
|
|
3774
4749
|
|
|
3775
|
-
//
|
|
3776
|
-
var
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
4750
|
+
// node_modules/.pnpm/commander@12.1.0/node_modules/commander/esm.mjs
|
|
4751
|
+
var import_index = __toESM(require_commander(), 1);
|
|
4752
|
+
var {
|
|
4753
|
+
program,
|
|
4754
|
+
createCommand,
|
|
4755
|
+
createArgument,
|
|
4756
|
+
createOption,
|
|
4757
|
+
CommanderError,
|
|
4758
|
+
InvalidArgumentError,
|
|
4759
|
+
InvalidOptionArgumentError,
|
|
4760
|
+
// deprecated old name
|
|
4761
|
+
Command,
|
|
4762
|
+
Argument,
|
|
4763
|
+
Option,
|
|
4764
|
+
Help
|
|
4765
|
+
} = import_index.default;
|
|
3786
4766
|
|
|
3787
|
-
// src/
|
|
3788
|
-
var
|
|
3789
|
-
var
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
var
|
|
3793
|
-
var
|
|
3794
|
-
var
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
4767
|
+
// cli/dazi-flow/src/commands/flows.ts
|
|
4768
|
+
var import_path3 = __toESM(require("path"), 1);
|
|
4769
|
+
var import_fs2 = __toESM(require("fs"), 1);
|
|
4770
|
+
|
|
4771
|
+
// cli/shared/src/auth.js
|
|
4772
|
+
var import_os = __toESM(require("os"), 1);
|
|
4773
|
+
var import_path = __toESM(require("path"), 1);
|
|
4774
|
+
var import_fs = __toESM(require("fs"), 1);
|
|
4775
|
+
|
|
4776
|
+
// cli/shared/src/errors.js
|
|
4777
|
+
var DaziError = class extends Error {
|
|
4778
|
+
constructor(message, code = "ERR_DAZI", exitCode = 1) {
|
|
4779
|
+
super(message);
|
|
4780
|
+
this.code = code;
|
|
4781
|
+
this.exitCode = exitCode;
|
|
4782
|
+
this.name = "DaziError";
|
|
4783
|
+
}
|
|
3803
4784
|
};
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
if (node.type === "custom") {
|
|
3809
|
-
return String(node.data?.type ?? "custom");
|
|
4785
|
+
var AuthError = class extends DaziError {
|
|
4786
|
+
constructor(message = "\u672A\u767B\u5F55\uFF0C\u8BF7\u5148\u8FD0\u884C: dazi auth login") {
|
|
4787
|
+
super(message, "ERR_AUTH", 2);
|
|
4788
|
+
this.name = "AuthError";
|
|
3810
4789
|
}
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
4790
|
+
};
|
|
4791
|
+
var NetworkError = class extends DaziError {
|
|
4792
|
+
constructor(message, status, request) {
|
|
4793
|
+
super(message, "ERR_NETWORK", 3);
|
|
4794
|
+
this.status = status;
|
|
4795
|
+
this.request = request;
|
|
4796
|
+
this.name = "NetworkError";
|
|
3816
4797
|
}
|
|
3817
|
-
|
|
3818
|
-
|
|
4798
|
+
/** 多行人类可读详情,写入 stderr / OutputChannel */
|
|
4799
|
+
formatDetailLines() {
|
|
4800
|
+
const lines = [`\u9519\u8BEF: ${this.message}`];
|
|
4801
|
+
const r = this.request;
|
|
4802
|
+
if (!r)
|
|
4803
|
+
return lines;
|
|
4804
|
+
if (r.label)
|
|
4805
|
+
lines.push(`\u6B65\u9AA4: ${r.label}`);
|
|
4806
|
+
lines.push(`\u8BF7\u6C42: ${r.method} ${r.path}`);
|
|
4807
|
+
lines.push(`\u5B8C\u6574 URL: ${r.url}`);
|
|
4808
|
+
lines.push(`HTTP \u72B6\u6001: ${r.status}`);
|
|
4809
|
+
if (r.responseSnippet)
|
|
4810
|
+
lines.push(`\u54CD\u5E94\u6458\u8981: ${r.responseSnippet}`);
|
|
4811
|
+
return lines;
|
|
3819
4812
|
}
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
return "txt";
|
|
3826
|
-
}
|
|
3827
|
-
function sanitizeName2(name) {
|
|
3828
|
-
const cleaned = (name || "").replace(/[<>:"/\\|?*\x00-\x1f]/g, "_").trim().replace(/\s+/g, "_");
|
|
3829
|
-
return cleaned || "node";
|
|
3830
|
-
}
|
|
3831
|
-
function readFlowJson2(flowDir) {
|
|
3832
|
-
const raw = JSON.parse(import_fs6.default.readFileSync(import_path7.default.join(flowDir, FLOW_JSON2), "utf8"));
|
|
3833
|
-
return {
|
|
3834
|
-
nodes: Array.isArray(raw.nodes) ? raw.nodes : [],
|
|
3835
|
-
edges: Array.isArray(raw.edges) ? raw.edges : []
|
|
3836
|
-
};
|
|
4813
|
+
};
|
|
4814
|
+
|
|
4815
|
+
// cli/shared/src/auth.js
|
|
4816
|
+
function authFilePath() {
|
|
4817
|
+
return import_path.default.join(import_os.default.homedir(), ".dazi", "auth.json");
|
|
3837
4818
|
}
|
|
3838
|
-
function
|
|
3839
|
-
const p =
|
|
3840
|
-
if (!
|
|
4819
|
+
function loadAuth() {
|
|
4820
|
+
const p = authFilePath();
|
|
4821
|
+
if (!import_fs.default.existsSync(p))
|
|
4822
|
+
throw new AuthError();
|
|
3841
4823
|
try {
|
|
3842
|
-
return JSON.parse(
|
|
4824
|
+
return JSON.parse(import_fs.default.readFileSync(p, "utf-8"));
|
|
3843
4825
|
} catch {
|
|
3844
|
-
|
|
4826
|
+
throw new AuthError("auth.json \u683C\u5F0F\u635F\u574F\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55");
|
|
3845
4827
|
}
|
|
3846
4828
|
}
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
function
|
|
3851
|
-
const
|
|
3852
|
-
if (
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
return import_fs6.default.statSync(import_path7.default.join(nodesRoot, n)).isDirectory();
|
|
3856
|
-
} catch {
|
|
3857
|
-
return false;
|
|
3858
|
-
}
|
|
3859
|
-
});
|
|
4829
|
+
|
|
4830
|
+
// cli/shared/src/httpClient.js
|
|
4831
|
+
var SNIPPET_MAX = 280;
|
|
4832
|
+
function truncateSnippet(text) {
|
|
4833
|
+
const oneLine = text.replace(/\s+/g, " ").trim();
|
|
4834
|
+
if (oneLine.length <= SNIPPET_MAX)
|
|
4835
|
+
return oneLine;
|
|
4836
|
+
return `${oneLine.slice(0, SNIPPET_MAX)}\u2026`;
|
|
3860
4837
|
}
|
|
3861
|
-
function
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
4838
|
+
function buildHttpErrorMessage(ctx, detail) {
|
|
4839
|
+
const parts = [
|
|
4840
|
+
ctx.label ? `${ctx.label}\u5931\u8D25` : "HTTP \u8BF7\u6C42\u5931\u8D25",
|
|
4841
|
+
`[${ctx.status} ${ctx.method} ${ctx.path}]`,
|
|
4842
|
+
detail
|
|
4843
|
+
].filter(Boolean);
|
|
4844
|
+
return parts.join(" \u2014 ");
|
|
3867
4845
|
}
|
|
3868
|
-
function
|
|
3869
|
-
const
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
4846
|
+
async function apiRequest(path19, opts = {}) {
|
|
4847
|
+
const auth = opts.token || opts.serverUrl ? { token: opts.token ?? "", serverUrl: opts.serverUrl ?? "" } : loadAuth();
|
|
4848
|
+
const method = (opts.method ?? "GET").toUpperCase();
|
|
4849
|
+
const serverBase = auth.serverUrl.replace(/\/$/, "");
|
|
4850
|
+
const url = `${serverBase}${path19}`;
|
|
4851
|
+
const headers = {
|
|
4852
|
+
"Content-Type": "application/json",
|
|
4853
|
+
Authorization: `Bearer ${auth.token}`,
|
|
4854
|
+
...opts.headers
|
|
4855
|
+
};
|
|
4856
|
+
const res = await fetch(url, {
|
|
4857
|
+
method,
|
|
4858
|
+
headers,
|
|
4859
|
+
body: opts.body != null ? JSON.stringify(opts.body) : void 0
|
|
4860
|
+
});
|
|
4861
|
+
if (!res.ok) {
|
|
4862
|
+
let detail = `HTTP ${res.status} ${res.statusText}`;
|
|
4863
|
+
let responseSnippet;
|
|
4864
|
+
const rawText = await res.text();
|
|
4865
|
+
if (rawText) {
|
|
4866
|
+
responseSnippet = truncateSnippet(rawText);
|
|
3873
4867
|
try {
|
|
3874
|
-
const
|
|
3875
|
-
if (
|
|
4868
|
+
const j = JSON.parse(rawText);
|
|
4869
|
+
if (typeof j.detail === "string" && j.detail.trim()) {
|
|
4870
|
+
detail = j.detail;
|
|
4871
|
+
} else if (Array.isArray(j.detail) && j.detail.length) {
|
|
4872
|
+
detail = j.detail.map((d) => d.msg ?? JSON.stringify(d)).join("; ");
|
|
4873
|
+
} else if (j.message) {
|
|
4874
|
+
detail = j.message;
|
|
4875
|
+
}
|
|
3876
4876
|
} catch {
|
|
4877
|
+
if (rawText.trim() && detail.startsWith("HTTP ")) {
|
|
4878
|
+
detail = `\u975E JSON \u54CD\u5E94\uFF08\u53EF\u80FD\u662F\u7F51\u5173/\u524D\u7AEF 404\uFF09`;
|
|
4879
|
+
}
|
|
3877
4880
|
}
|
|
3878
4881
|
}
|
|
4882
|
+
const ctx = {
|
|
4883
|
+
method,
|
|
4884
|
+
path: path19,
|
|
4885
|
+
url,
|
|
4886
|
+
status: res.status,
|
|
4887
|
+
label: opts.label,
|
|
4888
|
+
responseSnippet
|
|
4889
|
+
};
|
|
4890
|
+
throw new NetworkError(buildHttpErrorMessage(ctx, detail), res.status, ctx);
|
|
3879
4891
|
}
|
|
3880
|
-
|
|
4892
|
+
if (res.status === 204 || res.headers.get("content-length") === "0") {
|
|
4893
|
+
return void 0;
|
|
4894
|
+
}
|
|
4895
|
+
const text = await res.text();
|
|
4896
|
+
if (!text.trim())
|
|
4897
|
+
return void 0;
|
|
4898
|
+
return JSON.parse(text);
|
|
3881
4899
|
}
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
const
|
|
3896
|
-
|
|
3897
|
-
canvasCodeNodeCount++;
|
|
3898
|
-
const label = String(node.data?.label ?? node.id ?? "");
|
|
3899
|
-
const m = meta.nodes[uuid];
|
|
3900
|
-
if (!m?.dir || !m.codeFile) {
|
|
3901
|
-
missingInMeta.push({ uuid, nodeId: String(node.id ?? ""), nodeType, label });
|
|
3902
|
-
continue;
|
|
3903
|
-
}
|
|
3904
|
-
const codePath = import_path7.default.join(flowDir, m.dir, m.codeFile);
|
|
3905
|
-
if (!import_fs6.default.existsSync(codePath)) {
|
|
3906
|
-
missingCodeFiles.push({ uuid, dir: m.dir, codeFile: m.codeFile });
|
|
4900
|
+
|
|
4901
|
+
// cli/shared/src/output.js
|
|
4902
|
+
function printJsonSummary(summary) {
|
|
4903
|
+
console.log(`__JSON_SUMMARY__${JSON.stringify(summary)}`);
|
|
4904
|
+
}
|
|
4905
|
+
function ok(data) {
|
|
4906
|
+
printJsonSummary({ ok: true, data });
|
|
4907
|
+
}
|
|
4908
|
+
function fail(code, message) {
|
|
4909
|
+
printJsonSummary({ ok: false, error: { code, message } });
|
|
4910
|
+
}
|
|
4911
|
+
function handleError(err) {
|
|
4912
|
+
if (err instanceof NetworkError) {
|
|
4913
|
+
for (const line of err.formatDetailLines()) {
|
|
4914
|
+
console.error(line);
|
|
3907
4915
|
}
|
|
4916
|
+
fail(err.code, err.message);
|
|
4917
|
+
} else if (err instanceof Error) {
|
|
4918
|
+
const code = err.code ?? "ERR_UNKNOWN";
|
|
4919
|
+
console.error(`\u9519\u8BEF: ${err.message}`);
|
|
4920
|
+
fail(code, err.message);
|
|
4921
|
+
} else {
|
|
4922
|
+
console.error(`\u672A\u77E5\u9519\u8BEF`, err);
|
|
4923
|
+
fail("ERR_UNKNOWN", String(err));
|
|
3908
4924
|
}
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
if (!findCodeFileInDir(dirAbs)) continue;
|
|
3918
|
-
const rel = import_path7.default.posix.join(NODES_DIR2, dirName);
|
|
3919
|
-
const indexed = Object.values(meta.nodes).some((m) => m.dir?.replace(/\\/g, "/") === rel);
|
|
3920
|
-
if (!indexed) unindexedDirs.push(rel);
|
|
3921
|
-
}
|
|
3922
|
-
if (canvasCodeNodeCount !== metaCodeIndexedCount) {
|
|
3923
|
-
warnings.push(
|
|
3924
|
-
`\u753B\u5E03\u4EE3\u7801\u8282\u70B9 ${canvasCodeNodeCount} \u4E2A\uFF0Cmeta \u5DF2\u7D22\u5F15 ${metaCodeIndexedCount} \u4E2A\uFF08\u4E0D\u4E00\u81F4\u4F1A\u5BFC\u81F4 node push / \u8BBE\u8BA1\u5668\u6253\u5F00\u4EE3\u7801\u5931\u8D25\uFF09`
|
|
3925
|
-
);
|
|
3926
|
-
}
|
|
3927
|
-
if (missingInMeta.length) {
|
|
3928
|
-
warnings.push("\u90E8\u5206 flow.json \u4EE3\u7801\u8282\u70B9\u672A\u5199\u5165 flow.meta.json\uFF0C\u8BF7\u6267\u884C project repair-meta");
|
|
3929
|
-
}
|
|
3930
|
-
if (unindexedDirs.length) {
|
|
3931
|
-
warnings.push(`\u5B58\u5728\u672A\u7D22\u5F15\u7684\u8282\u70B9\u76EE\u5F55\uFF1A${unindexedDirs.join(", ")}`);
|
|
3932
|
-
}
|
|
3933
|
-
const ok3 = missingInMeta.length === 0 && orphanInMeta.length === 0 && missingCodeFiles.length === 0 && unindexedDirs.length === 0 && canvasCodeNodeCount === metaCodeIndexedCount;
|
|
4925
|
+
process.exit(1);
|
|
4926
|
+
}
|
|
4927
|
+
|
|
4928
|
+
// cli/shared/src/workspaceLayout.js
|
|
4929
|
+
var import_path2 = __toESM(require("path"), 1);
|
|
4930
|
+
var WORKSPACE_RESOURCE_DIR = "\u8D44\u6E90";
|
|
4931
|
+
function resolveWorkspace(cwd = process.cwd()) {
|
|
4932
|
+
const resources = import_path2.default.join(cwd, WORKSPACE_RESOURCE_DIR);
|
|
3934
4933
|
return {
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
4934
|
+
root: cwd,
|
|
4935
|
+
resources,
|
|
4936
|
+
dazi: import_path2.default.join(cwd, ".dazi"),
|
|
4937
|
+
onto: import_path2.default.join(cwd, "onto"),
|
|
4938
|
+
flows: import_path2.default.join(cwd, "flows"),
|
|
4939
|
+
apps: import_path2.default.join(cwd, "apps"),
|
|
4940
|
+
data: import_path2.default.join(cwd, "data"),
|
|
4941
|
+
docs: import_path2.default.join(resources, "docs"),
|
|
4942
|
+
prompts: import_path2.default.join(resources, "prompts"),
|
|
4943
|
+
examples: import_path2.default.join(resources, "examples"),
|
|
4944
|
+
dataspaces: import_path2.default.join(resources, "dataspaces"),
|
|
4945
|
+
datasources: import_path2.default.join(resources, "datasources"),
|
|
4946
|
+
files: import_path2.default.join(resources, "files")
|
|
3945
4947
|
};
|
|
3946
4948
|
}
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
}
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
if (!meta.nodes) meta.nodes = {};
|
|
3976
|
-
const usedDirNames = new Set(
|
|
3977
|
-
Object.values(meta.nodes).map((m) => m.dir?.split("/").pop()).filter(Boolean)
|
|
3978
|
-
);
|
|
3979
|
-
for (const node of doc.nodes) {
|
|
3980
|
-
const uuid = String(node.node_uuid ?? "").trim();
|
|
3981
|
-
if (!uuid) continue;
|
|
3982
|
-
const nodeType = resolveNodeType2(node);
|
|
3983
|
-
const codeKey = NODE_TYPE_CODE_DATA_KEY2[nodeType];
|
|
3984
|
-
const semanticId = String(node.id ?? "");
|
|
3985
|
-
const label = String(node.data?.label ?? semanticId ?? nodeType);
|
|
3986
|
-
let entry = meta.nodes[uuid];
|
|
3987
|
-
if (!entry) {
|
|
3988
|
-
entry = { nodeId: semanticId, nodeType };
|
|
3989
|
-
meta.nodes[uuid] = entry;
|
|
3990
|
-
repairedUuids.push(uuid);
|
|
3991
|
-
} else {
|
|
3992
|
-
entry.nodeId = semanticId || entry.nodeId;
|
|
3993
|
-
entry.nodeType = nodeType;
|
|
4949
|
+
|
|
4950
|
+
// cli/dazi-flow/src/commands/flows.ts
|
|
4951
|
+
function makeFlowsCommand() {
|
|
4952
|
+
const cmd = new Command("flows").description("Flow \u7BA1\u7406");
|
|
4953
|
+
cmd.command("list").description("\u5217\u51FA\u6240\u6709 Flow").option("--space <spaceId>", "\u8FC7\u6EE4\u7A7A\u95F4").option("--status <status>", "\u8FC7\u6EE4\u72B6\u6001\uFF08active/draft/archived\uFF09").option("--json", "\u8F93\u51FA JSON").action(async (opts) => {
|
|
4954
|
+
try {
|
|
4955
|
+
const qs = new URLSearchParams();
|
|
4956
|
+
if (opts.space) qs.set("spaceId", opts.space);
|
|
4957
|
+
if (opts.status) qs.set("status", opts.status);
|
|
4958
|
+
const qsStr = qs.toString() ? `?${qs}` : "";
|
|
4959
|
+
const endpoint = `/api/data-pipelines/v1/flows${qsStr}`;
|
|
4960
|
+
const flows = await apiRequest(endpoint);
|
|
4961
|
+
if (opts.json) {
|
|
4962
|
+
console.log(JSON.stringify(flows, null, 2));
|
|
4963
|
+
ok({ flows });
|
|
4964
|
+
return;
|
|
4965
|
+
}
|
|
4966
|
+
if (!flows.length) {
|
|
4967
|
+
console.log("\uFF08\u6682\u65E0 Flow\uFF09");
|
|
4968
|
+
ok({ flows: [] });
|
|
4969
|
+
return;
|
|
4970
|
+
}
|
|
4971
|
+
for (const f of flows) {
|
|
4972
|
+
console.log(` ${String(f.id).padEnd(8)} ${(f.name ?? "").padEnd(40)} [${f.status ?? "\u2014"}]`);
|
|
4973
|
+
}
|
|
4974
|
+
ok({ flows });
|
|
4975
|
+
} catch (err) {
|
|
4976
|
+
handleError(err);
|
|
3994
4977
|
}
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4978
|
+
});
|
|
4979
|
+
cmd.command("get <flowId>").alias("show").description("\u67E5\u770B Flow \u8BE6\u60C5").option("--json", "\u8F93\u51FA JSON").action(async (flowId, opts) => {
|
|
4980
|
+
try {
|
|
4981
|
+
const flow = await apiRequest(`/api/data-pipelines/v1/flows/${flowId}`);
|
|
4982
|
+
if (opts.json || true) console.log(JSON.stringify(flow, null, 2));
|
|
4983
|
+
ok({ flow });
|
|
4984
|
+
} catch (err) {
|
|
4985
|
+
handleError(err);
|
|
4000
4986
|
}
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4987
|
+
});
|
|
4988
|
+
cmd.command("create").alias("new").description("\u65B0\u5EFA Flow").requiredOption("--name <name>", "Flow \u540D\u79F0").option("--space <spaceId>", "\u7A7A\u95F4 ID").option("--description <desc>", "\u63CF\u8FF0").option("--file <path>", "\u4ECE\u672C\u5730 JSON \u6587\u4EF6\u8BFB\u53D6\u5B9A\u4E49").option("--json", "\u8F93\u51FA JSON").action(async (opts) => {
|
|
4989
|
+
try {
|
|
4990
|
+
let body;
|
|
4991
|
+
if (opts.file) {
|
|
4992
|
+
body = JSON.parse(import_fs2.default.readFileSync(import_path3.default.resolve(opts.file), "utf-8"));
|
|
4993
|
+
} else {
|
|
4994
|
+
body = { name: opts.name, spaceId: opts.space, description: opts.description };
|
|
4005
4995
|
}
|
|
4996
|
+
const flow = await apiRequest("/api/data-pipelines/v1/flows", { method: "POST", body });
|
|
4997
|
+
if (opts.json) {
|
|
4998
|
+
console.log(JSON.stringify(flow, null, 2));
|
|
4999
|
+
} else {
|
|
5000
|
+
console.log(`\u2705 \u5DF2\u521B\u5EFA Flow: ${flow.id} ${flow.name}`);
|
|
5001
|
+
}
|
|
5002
|
+
ok({ flow });
|
|
5003
|
+
} catch (err) {
|
|
5004
|
+
handleError(err);
|
|
4006
5005
|
}
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
if (!findCodeFileInDir(import_path7.default.join(flowDir, relDir))) {
|
|
4017
|
-
import_fs6.default.writeFileSync(import_path7.default.join(flowDir, relDir, codeFile2), template, "utf8");
|
|
4018
|
-
warnings.push(`\u5DF2\u4E3A ${uuid} \u521B\u5EFA\u7A7A\u4EE3\u7801\u6A21\u677F ${relDir}/${codeFile2}`);
|
|
5006
|
+
});
|
|
5007
|
+
cmd.command("validate <flowId>").description("\u9A8C\u8BC1 Flow \u5B9A\u4E49").option("--file <path>", "\u4ECE\u672C\u5730\u5FEB\u7167\u6587\u4EF6\u9A8C\u8BC1\uFF08\u79BB\u7EBF\uFF09").action(async (flowId, opts) => {
|
|
5008
|
+
try {
|
|
5009
|
+
let result;
|
|
5010
|
+
if (opts.file) {
|
|
5011
|
+
const body = JSON.parse(import_fs2.default.readFileSync(import_path3.default.resolve(opts.file), "utf-8"));
|
|
5012
|
+
result = await apiRequest(`/api/data-pipelines/v1/flows/compile-plan`, { method: "POST", body });
|
|
5013
|
+
} else {
|
|
5014
|
+
result = await apiRequest(`/api/data-pipelines/v1/flows/${flowId}/validate`, { method: "POST" });
|
|
4019
5015
|
}
|
|
5016
|
+
console.log("\u2705 \u9A8C\u8BC1\u901A\u8FC7");
|
|
5017
|
+
ok({ flowId, result });
|
|
5018
|
+
} catch (err) {
|
|
5019
|
+
handleError(err);
|
|
4020
5020
|
}
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
5021
|
+
});
|
|
5022
|
+
cmd.command("patch <flowId>").description("\u90E8\u5206\u66F4\u65B0 Flow \u5C5E\u6027").option("--name <name>", "\u65B0\u540D\u79F0").option("--description <desc>", "\u65B0\u63CF\u8FF0").option("--status <status>", "\u65B0\u72B6\u6001").option("--file <path>", "\u4ECE JSON \u6587\u4EF6\u8BFB\u53D6 patch body").action(async (flowId, opts) => {
|
|
5023
|
+
try {
|
|
5024
|
+
let patch;
|
|
5025
|
+
if (opts.file) {
|
|
5026
|
+
patch = JSON.parse(import_fs2.default.readFileSync(import_path3.default.resolve(opts.file), "utf-8"));
|
|
5027
|
+
} else {
|
|
5028
|
+
patch = {};
|
|
5029
|
+
if (opts.name) patch.name = opts.name;
|
|
5030
|
+
if (opts.description) patch.description = opts.description;
|
|
5031
|
+
if (opts.status) patch.status = opts.status;
|
|
5032
|
+
}
|
|
5033
|
+
const flow = await apiRequest(`/api/data-pipelines/v1/flows/${flowId}`, { method: "PUT", body: patch });
|
|
5034
|
+
console.log(`\u2705 Flow ${flowId} \u5DF2\u66F4\u65B0`);
|
|
5035
|
+
ok({ flow });
|
|
5036
|
+
} catch (err) {
|
|
5037
|
+
handleError(err);
|
|
4026
5038
|
}
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
if (!import_fs6.default.existsSync(infoPath)) {
|
|
4037
|
-
writeNodeInfo(flowDir, node, uuid, nodeType, relDir, codeFile, language, strippedData);
|
|
4038
|
-
wroteNodeInfo.push(relDir);
|
|
5039
|
+
});
|
|
5040
|
+
const nodeCmd = new Command("flow-node").description("Flow \u8282\u70B9\u7BA1\u7406");
|
|
5041
|
+
nodeCmd.command("get <flowId> <nodeId>").description("\u67E5\u770B Flow \u8282\u70B9\u8BE6\u60C5").option("--json", "\u8F93\u51FA JSON").action(async (flowId, nodeId, opts) => {
|
|
5042
|
+
try {
|
|
5043
|
+
const node = await apiRequest(`/api/data-pipelines/v1/flows/${flowId}/flow-nodes/${nodeId}`);
|
|
5044
|
+
console.log(JSON.stringify(node, null, 2));
|
|
5045
|
+
ok({ node });
|
|
5046
|
+
} catch (err) {
|
|
5047
|
+
handleError(err);
|
|
4039
5048
|
}
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
}
|
|
4052
|
-
function buildFlowConsistencyMarkdown(audit, localFilesSpecLink = "../../\u8D44\u6E90/docs/flow/local-files-spec.md") {
|
|
4053
|
-
const lines = [
|
|
4054
|
-
"## \u672C\u5730\u6587\u4EF6\u4E00\u81F4\u6027",
|
|
4055
|
-
"",
|
|
4056
|
-
"| \u6307\u6807 | \u6570\u91CF |",
|
|
4057
|
-
"|------|------|",
|
|
4058
|
-
`| \u753B\u5E03\u8282\u70B9\uFF08flow.json\uFF09 | ${audit.canvasNodeCount} |`,
|
|
4059
|
-
`| \u753B\u5E03\u4EE3\u7801\u8282\u70B9\uFF08flow.json\uFF09 | ${audit.canvasCodeNodeCount} |`,
|
|
4060
|
-
`| meta \u5DF2\u767B\u8BB0\u8282\u70B9 | ${audit.metaIndexedCount} |`,
|
|
4061
|
-
`| meta \u5DF2\u7D22\u5F15\u4EE3\u7801\uFF08dir+codeFile\uFF09 | ${audit.metaCodeIndexedCount} |`,
|
|
4062
|
-
""
|
|
4063
|
-
];
|
|
4064
|
-
if (audit.ok) {
|
|
4065
|
-
lines.push("\u2705 **flow.json / flow.meta.json / \u8282\u70B9/ \u4E00\u81F4**\u3002\u8BBE\u8BA1\u5668\u53EF\u6B63\u5E38\u300C\u6253\u5F00\u4EE3\u7801\u300D\uFF0C`node push` \u53EF\u8BC6\u522B\u810F\u8282\u70B9\u3002", "");
|
|
4066
|
-
} else {
|
|
4067
|
-
lines.push("\u26A0\uFE0F **\u76EE\u5F55\u4E0D\u4E00\u81F4**\uFF08\u4F1A\u5BFC\u81F4\u8BBE\u8BA1\u5668\u627E\u4E0D\u5230\u4EE3\u7801\u3001\u6216 `node push` \u8DF3\u8FC7\uFF09\uFF1A", "");
|
|
4068
|
-
if (audit.missingInMeta.length) {
|
|
4069
|
-
lines.push("| uuid | \u8282\u70B9 | \u7C7B\u578B |");
|
|
4070
|
-
lines.push("|------|------|------|");
|
|
4071
|
-
for (const m of audit.missingInMeta) {
|
|
4072
|
-
lines.push(`| \`${m.uuid.slice(0, 8)}\u2026\` | ${m.label || m.nodeId} | ${m.nodeType} |`);
|
|
5049
|
+
});
|
|
5050
|
+
nodeCmd.command("patch <flowId> <nodeId>").description("\u90E8\u5206\u66F4\u65B0 Flow \u8282\u70B9\u914D\u7F6E").option("--file <path>", "\u4ECE JSON \u6587\u4EF6\u8BFB\u53D6 patch body").option("--config <json>", "config patch JSON \u5B57\u7B26\u4E32").action(async (flowId, nodeId, opts) => {
|
|
5051
|
+
try {
|
|
5052
|
+
let patch;
|
|
5053
|
+
if (opts.file) {
|
|
5054
|
+
patch = JSON.parse(import_fs2.default.readFileSync(import_path3.default.resolve(opts.file), "utf-8"));
|
|
5055
|
+
} else if (opts.config) {
|
|
5056
|
+
patch = { config: JSON.parse(opts.config) };
|
|
5057
|
+
} else {
|
|
5058
|
+
console.error("--file \u6216 --config \u5FC5\u987B\u63D0\u4F9B");
|
|
5059
|
+
process.exit(1);
|
|
4073
5060
|
}
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
5061
|
+
const node = await apiRequest(
|
|
5062
|
+
`/api/data-pipelines/v1/flows/${flowId}/flow-nodes/${nodeId}`,
|
|
5063
|
+
{ method: "PATCH", body: patch }
|
|
5064
|
+
);
|
|
5065
|
+
console.log(`\u2705 \u8282\u70B9 ${nodeId} \u5DF2\u66F4\u65B0`);
|
|
5066
|
+
ok({ node });
|
|
5067
|
+
} catch (err) {
|
|
5068
|
+
handleError(err);
|
|
4078
5069
|
}
|
|
4079
|
-
|
|
4080
|
-
|
|
5070
|
+
});
|
|
5071
|
+
cmd.addCommand(nodeCmd);
|
|
5072
|
+
cmd.command("workspace-init <flowId>").description("\u521D\u59CB\u5316 Flow \u672C\u5730\u5DE5\u4F5C\u76EE\u5F55 flows/<flowId>/").action(async (flowId) => {
|
|
5073
|
+
try {
|
|
5074
|
+
const ws = resolveWorkspace();
|
|
5075
|
+
const flowDir = import_path3.default.join(ws.flows, flowId);
|
|
5076
|
+
const dirs = [flowDir, import_path3.default.join(flowDir, "plans"), import_path3.default.join(flowDir, "data")];
|
|
5077
|
+
for (const d of dirs) {
|
|
5078
|
+
if (!import_fs2.default.existsSync(d)) import_fs2.default.mkdirSync(d, { recursive: true });
|
|
5079
|
+
}
|
|
5080
|
+
const metaPath = import_path3.default.join(flowDir, ".dazi-flow.json");
|
|
5081
|
+
if (!import_fs2.default.existsSync(metaPath)) {
|
|
5082
|
+
import_fs2.default.writeFileSync(metaPath, JSON.stringify({ flowId, initializedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2), "utf-8");
|
|
5083
|
+
}
|
|
5084
|
+
console.log(`\u2705 Flow \u5DE5\u4F5C\u76EE\u5F55\u5DF2\u521D\u59CB\u5316: ${flowDir}`);
|
|
5085
|
+
ok({ flowId, dir: flowDir });
|
|
5086
|
+
} catch (err) {
|
|
5087
|
+
handleError(err);
|
|
4081
5088
|
}
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
"",
|
|
4085
|
-
"\u4FEE\u590D\uFF08\u5728\u6D41\u7A0B\u76EE\u5F55\uFF09\uFF1A",
|
|
4086
|
-
"",
|
|
4087
|
-
"```powershell",
|
|
4088
|
-
"dazi flow project repair-meta --dir .",
|
|
4089
|
-
"dazi flow project doctor --dir .",
|
|
4090
|
-
"```",
|
|
4091
|
-
"",
|
|
4092
|
-
`\u8BE6\u89C1 [\u6D41\u7A0B\u672C\u5730\u6587\u4EF6\u89C4\u8303](${localFilesSpecLink})\u3002`,
|
|
4093
|
-
""
|
|
4094
|
-
);
|
|
4095
|
-
}
|
|
4096
|
-
lines.push(
|
|
4097
|
-
"## \u53D8\u66F4\u63D0\u4EA4\u547D\u4EE4\u77E9\u9635",
|
|
4098
|
-
"",
|
|
4099
|
-
"| \u6539\u4E86\u4EC0\u4E48 | \u547D\u4EE4 |",
|
|
4100
|
-
"|----------|------|",
|
|
4101
|
-
"| `managed_file_id`\u3001`output_variable_name`\u3001\u8FDE\u7EBF\u3001\u589E\u5220\u8282\u70B9 | `dazi flow project push --dir . --canvas` |",
|
|
4102
|
-
"| `\u8282\u70B9/<\u540D>/code.py` \u6216 `code.sql` | `dazi flow node push --node <uuid> --dir .` |",
|
|
4103
|
-
'| **\u65B0\u589E\u4EE3\u7801\u8282\u70B9** | `dazi flow node new --type <type> --dir . --label "<\u540D>"` \u2192 \u6539\u914D\u7F6E \u2192 `push --canvas` \u2192 \u5199 code \u2192 `node push` |',
|
|
4104
|
-
"",
|
|
4105
|
-
"> \u7981\u6B62\u53EA\u6539 `flow.json` \u800C\u4E0D\u66F4\u65B0 `flow.meta.json`\uFF08\u987B `node new` / `pull` / `repair-meta`\uFF09\u3002",
|
|
4106
|
-
""
|
|
4107
|
-
);
|
|
4108
|
-
return lines;
|
|
5089
|
+
});
|
|
5090
|
+
return cmd;
|
|
4109
5091
|
}
|
|
4110
5092
|
|
|
4111
|
-
// src/
|
|
4112
|
-
var
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
5093
|
+
// cli/dazi-flow/src/commands/snapshot.ts
|
|
5094
|
+
var import_path6 = __toESM(require("path"), 1);
|
|
5095
|
+
var import_fs5 = __toESM(require("fs"), 1);
|
|
5096
|
+
|
|
5097
|
+
// cli/dazi-flow/src/lib/flowLocal.ts
|
|
5098
|
+
var import_crypto = __toESM(require("crypto"), 1);
|
|
5099
|
+
var import_fs3 = __toESM(require("fs"), 1);
|
|
5100
|
+
var import_path4 = __toESM(require("path"), 1);
|
|
5101
|
+
var NODE_TYPE_CODE_DATA_KEY = {
|
|
5102
|
+
"database-source": "sql",
|
|
5103
|
+
"dataspace-source": "sql",
|
|
5104
|
+
"python-script": "pythonCode",
|
|
5105
|
+
"excel-python": "pythonCode",
|
|
5106
|
+
"sql-query": "sql",
|
|
5107
|
+
condition: "pythonCode",
|
|
5108
|
+
"data-quality-check": "dqPythonCode"
|
|
4116
5109
|
};
|
|
4117
|
-
function
|
|
4118
|
-
|
|
4119
|
-
|
|
5110
|
+
function codeLanguageForNodeType(nodeType) {
|
|
5111
|
+
if (["python-script", "excel-python", "condition", "data-quality-check"].includes(nodeType)) {
|
|
5112
|
+
return "python";
|
|
5113
|
+
}
|
|
5114
|
+
if (["database-source", "dataspace-source", "sql-query"].includes(nodeType)) {
|
|
5115
|
+
return "sql";
|
|
5116
|
+
}
|
|
5117
|
+
return void 0;
|
|
4120
5118
|
}
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
return safe || "flow";
|
|
5119
|
+
function codeFileExt(language) {
|
|
5120
|
+
if (language === "python") return "py";
|
|
5121
|
+
if (language === "sql") return "sql";
|
|
5122
|
+
return "txt";
|
|
4126
5123
|
}
|
|
4127
|
-
|
|
4128
|
-
|
|
5124
|
+
var NODES_DIR = "\u8282\u70B9";
|
|
5125
|
+
var VARIABLES_DIR = "\u53D8\u91CF";
|
|
5126
|
+
var RUN_DIR = "_run";
|
|
5127
|
+
var FLOW_JSON = "flow.json";
|
|
5128
|
+
var FLOW_META_JSON = "flow.meta.json";
|
|
5129
|
+
var NODE_INFO_JSON = "node.info.json";
|
|
5130
|
+
function resolveNodeType(node) {
|
|
5131
|
+
const nt = node.type;
|
|
5132
|
+
if (nt === "custom") {
|
|
5133
|
+
const data = node.data ?? {};
|
|
5134
|
+
return String(data.type ?? "custom");
|
|
5135
|
+
}
|
|
5136
|
+
return String(nt ?? "custom");
|
|
4129
5137
|
}
|
|
4130
|
-
function
|
|
4131
|
-
return
|
|
5138
|
+
function sha1(text) {
|
|
5139
|
+
return import_crypto.default.createHash("sha1").update(text, "utf8").digest("hex");
|
|
4132
5140
|
}
|
|
4133
|
-
function
|
|
4134
|
-
|
|
4135
|
-
return
|
|
5141
|
+
function sanitizeName(name) {
|
|
5142
|
+
const cleaned = (name || "").replace(/[<>:"/\\|?*\x00-\x1f]/g, "_").trim().replace(/\s+/g, "_");
|
|
5143
|
+
return cleaned || "node";
|
|
4136
5144
|
}
|
|
4137
|
-
function
|
|
4138
|
-
const
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
["**\u6D41\u7A0B\u672C\u5730\u6587\u4EF6\u89C4\u8303\uFF08AI \u5FC5\u8BFB\uFF09**", "flow/local-files-spec.md"],
|
|
4146
|
-
["\u6D41\u7A0B AI \u5DE5\u4F5C\u624B\u518C", "flow/ai-workflow-playbook.md"],
|
|
4147
|
-
["CLI \u8C03\u7528\u7EA6\u5B9A\uFF08`dazi` / `dazi.ps1`\uFF09", "guides/cli-invocation.md"]
|
|
4148
|
-
];
|
|
4149
|
-
return [
|
|
4150
|
-
"## \u5E2E\u52A9\u6587\u6863",
|
|
4151
|
-
"",
|
|
4152
|
-
"\u5DE5\u4F5C\u533A\u6587\u6863\u4F4D\u4E8E **`\u8D44\u6E90/docs/`**\uFF08\u6269\u5C55\u4FA7\u680F **\u5E2E\u52A9 \u2192 \u4E0B\u8F7D\u6240\u6709\u6587\u6863**\uFF0C\u6216\u5728\u5DE5\u4F5C\u533A\u6839\u6267\u884C `dazi docs sync`\uFF09\uFF1A",
|
|
4153
|
-
"",
|
|
4154
|
-
"| \u6587\u6863 | \u94FE\u63A5 |",
|
|
4155
|
-
"|------|------|",
|
|
4156
|
-
...rows.map(([title, p]) => `| ${title} | [${p.split("/").pop()}](${flowDocsRel(anchor, p)}) |`),
|
|
4157
|
-
"",
|
|
4158
|
-
"\u7EC8\u7AEF\u6253\u5F00\u6587\u6863\uFF08**dazi-work \u6839**\u6216\u5DF2 `cd` \u5230\u6D41\u7A0B\u76EE\u5F55\uFF09\uFF1A",
|
|
4159
|
-
"",
|
|
4160
|
-
"```powershell",
|
|
4161
|
-
psDaziLine("docs open flow/flow-project-guide"),
|
|
4162
|
-
psDaziLine("docs open flow/variables-guide"),
|
|
4163
|
-
psDaziLine("docs open flow/node-code-guide"),
|
|
4164
|
-
psDaziLine("docs open flow/flows-guide"),
|
|
4165
|
-
"```",
|
|
4166
|
-
"",
|
|
4167
|
-
"**\u4EE3\u7801\u793A\u4F8B**\uFF1A\u53D8\u91CF\u8BFB\u5199\u3001`python-script` / `sql-query` \u6A21\u677F\u89C1 [\u8282\u70B9\u4EE3\u7801\u7F16\u5199\u6307\u5357](" + flowDocsRel(anchor, "flow/node-code-guide.md") + ") \u4E0E [\u6D41\u7A0B\u53D8\u91CF\u7CFB\u7EDF\u6307\u5357](" + flowDocsRel(anchor, "flow/variables-guide.md") + ")\u3002",
|
|
4168
|
-
""
|
|
4169
|
-
];
|
|
5145
|
+
function readMeta(flowDir) {
|
|
5146
|
+
const p = import_path4.default.join(flowDir, FLOW_META_JSON);
|
|
5147
|
+
if (!import_fs3.default.existsSync(p)) return void 0;
|
|
5148
|
+
try {
|
|
5149
|
+
return JSON.parse(import_fs3.default.readFileSync(p, "utf8"));
|
|
5150
|
+
} catch {
|
|
5151
|
+
return void 0;
|
|
5152
|
+
}
|
|
4170
5153
|
}
|
|
4171
|
-
function
|
|
4172
|
-
|
|
5154
|
+
function writeMeta(flowDir, meta) {
|
|
5155
|
+
import_fs3.default.writeFileSync(import_path4.default.join(flowDir, FLOW_META_JSON), JSON.stringify(meta, null, 2), "utf8");
|
|
4173
5156
|
}
|
|
4174
|
-
function
|
|
4175
|
-
const
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
"",
|
|
4180
|
-
`\u6B22\u8FCE\u5F00\u59CB **\u6570\u636E\u6D41\u7A0B\u9879\u76EE** \u5F00\u53D1\uFF08\`${folder}\`\uFF09\u3002`,
|
|
4181
|
-
"",
|
|
4182
|
-
"## 1. \u6D41\u7A0B\u76EE\u5F55\u7ED3\u6784",
|
|
4183
|
-
"",
|
|
4184
|
-
"\u6BCF\u4E2A\u6D41\u7A0B\u662F `\u6D41\u7A0B/<\u6D41\u7A0B\u540D>/` \u76EE\u5F55\uFF1A",
|
|
4185
|
-
"",
|
|
4186
|
-
"| \u8DEF\u5F84 | \u8BF4\u660E |",
|
|
4187
|
-
"|------|------|",
|
|
4188
|
-
"| `flow.json` | \u753B\u5E03\u771F\u7406\u6E90\uFF08\u8282\u70B9\u914D\u7F6E + \u8FDE\u7EBF\uFF0C\u4EE3\u7801\u5DF2\u5265\u79BB\uFF09 |",
|
|
4189
|
-
"| `flow.meta.json` | flowId\u3001node_uuid \u6620\u5C04\uFF08CLI \u7EF4\u62A4\uFF0C\u52FF\u624B\u6539\uFF09 |",
|
|
4190
|
-
"| `\u8282\u70B9/<\u540D>/code.*` | SQL / Python \u8282\u70B9\u4EE3\u7801 |",
|
|
4191
|
-
"| `\u53D8\u91CF/<\u540D>.json` | \u8C03\u8BD5 Run \u53D8\u91CF\u9884\u89C8\uFF08\u53EA\u8BFB\uFF0Cpull/sync \u751F\u6210\uFF09 |",
|
|
4192
|
-
"| `_run/` | \u6D4B\u8BD5/\u8FD0\u884C\u4EA7\u7269\uFF08`*.last-error.md` \u7B49\uFF09 |",
|
|
4193
|
-
"",
|
|
4194
|
-
"> \u6D41\u7A0B**\u4E0D\u7ED1\u5B9A\u6570\u636E\u7A7A\u95F4**\uFF1B`connectionId` \u4EC5\u4E3A\u6570\u636E\u5E93\u8282\u70B9\u7684\u914D\u7F6E\u5B57\u6BB5\u3002",
|
|
4195
|
-
"",
|
|
4196
|
-
"## 2. \u65B0\u5EFA / \u62C9\u53D6\u6D41\u7A0B",
|
|
4197
|
-
"",
|
|
4198
|
-
"\u8D44\u6E90\u7BA1\u7406\u5668\uFF08\u63A8\u8350 **\u8868\u5355**\uFF09\uFF1A",
|
|
4199
|
-
"",
|
|
4200
|
-
"| \u64CD\u4F5C | \u83DC\u5355 |",
|
|
4201
|
-
"|------|------|",
|
|
4202
|
-
"| \u65B0\u5EFA\u6D41\u7A0B | \u53F3\u952E **`\u6D41\u7A0B/`** \u2192 **\u65B0\u5EFA\u6D41\u7A0B** |",
|
|
4203
|
-
"| \u62C9\u53D6\u5E73\u53F0\u6D41\u7A0B | \u53F3\u952E **`\u6D41\u7A0B/`** \u6216\u9879\u76EE\u6839 \u2192 **\u62C9\u53D6\u5E73\u53F0\u6D41\u7A0B** |",
|
|
4204
|
-
"",
|
|
4205
|
-
"\u62C9\u53D6\u8868\u5355\u53EF\u4ECE\u5E73\u53F0 Flow \u5217\u8868\u9009\u62E9\uFF0C\u6216\u624B\u52A8\u586B\u5199 Flow ID\uFF1B\u65B0\u5EFA\u8868\u5355\u586B\u5199\u540D\u79F0\u4E0E\u8BF4\u660E\u540E\u81EA\u52A8\u521B\u5EFA\u5E76\u62C9\u53D6\u3002",
|
|
4206
|
-
"",
|
|
4207
|
-
"\u547D\u4EE4\u884C\uFF08`dazi-work` \u6839\uFF09\uFF1A",
|
|
4208
|
-
"",
|
|
4209
|
-
"```powershell",
|
|
4210
|
-
psFlowLine(`project pull --flow <flowId> --dir "\u9879\u76EE\\${folder}\\\u6D41\u7A0B\\<\u6D41\u7A0B\u540D>"`),
|
|
4211
|
-
"```",
|
|
4212
|
-
"",
|
|
4213
|
-
"\u62C9\u53D6\u540E\u6BCF\u4E2A\u6D41\u7A0B\u76EE\u5F55\u4F1A\u751F\u6210 **`\u5FEB\u901F\u542F\u52A8_<\u6D41\u7A0B\u540D>.md`**\uFF08\u542B flowId \u4E0E\u672C\u6D41\u7A0B\u5E38\u7528\u547D\u4EE4\uFF0C\u4FBF\u4E8E @ \u9644\u52A0\u7ED9 AI\uFF09\u3002",
|
|
4214
|
-
"",
|
|
4215
|
-
"## 3. \u5F00\u53D1\u4E0E\u63D0\u4EA4",
|
|
4216
|
-
"",
|
|
4217
|
-
"1. \u7F16\u8F91 `\u8282\u70B9/<\u540D>/code.sql` \u6216 `code.py`",
|
|
4218
|
-
"2. \u53F3\u952E **\u6D4B\u8BD5\u8FD0\u884C\u8282\u70B9** \u6216 `flow run node-exec --node <uuid>`",
|
|
4219
|
-
"3. \u53F3\u952E **\u63D0\u4EA4\u8282\u70B9** / **\u63D0\u4EA4\u6D41\u7A0B** \u6216 `flow node push` / `flow project push --canvas`",
|
|
4220
|
-
"4. \u67E5\u770B\u8868\u53D8\u91CF\uFF1A\u8BBE\u8BA1\u5668 **output_variable_name** \u65C1 \u{1F4CA}\uFF0C\u6216 `flow variable pull --name <\u540D>`",
|
|
4221
|
-
"",
|
|
4222
|
-
"\u547D\u4EE4\u524D\u7F00\uFF1A" + cliPrefix(),
|
|
4223
|
-
"",
|
|
4224
|
-
"## 4. \u63A8\u8350\u5F00\u53D1\u5FAA\u73AF",
|
|
4225
|
-
"",
|
|
4226
|
-
"\u8BE6\u89C1 [\u6570\u636E\u6D41\u7A0B\u9879\u76EE\u5F00\u53D1\u6307\u5357](" + flowDocsRel("project-root", "flow/flow-project-guide.md") + ") \xA74\u3002",
|
|
4227
|
-
"",
|
|
4228
|
-
"## 5. AI \u63D0\u793A\u8BCD\u63A8\u8350",
|
|
4229
|
-
"",
|
|
4230
|
-
"| \u573A\u666F | \u63D0\u793A\u8BCD ID |",
|
|
4231
|
-
"|------|-----------|",
|
|
4232
|
-
"| \u8BBE\u8BA1/\u65B0\u589E\u6D41\u7A0B | `flow/flow-design` |",
|
|
4233
|
-
"| **\u8FD0\u884C\u5931\u8D25\u3001\u81EA\u4E3B\u6539\u9519** | **`flow/run-fix-loop`**\uFF08\u2B50 \u9996\u9009\uFF09 |",
|
|
4234
|
-
"| \u5206\u6790\u7528\u6237\u7C98\u8D34\u7684\u9519\u8BEF | `flow/run-debug` |",
|
|
4235
|
-
"",
|
|
4236
|
-
"\u4FA7\u680F **\u5E2E\u52A9 \u2192 \u{1F916} \u63D0\u793A\u8BCD** \u4E2D \u2B50 \u4E3A\u6D41\u7A0B\u63A8\u8350\u3002\u53F3\u952E **`flow.json`** \u2192 **\u6253\u5F00 AI \u6539\u9519\u63D0\u793A\u8BCD**\u3002",
|
|
4237
|
-
"\u7ED9 AI \u7684\u4EFB\u52A1\u793A\u4F8B\uFF1A\u300C\u6539 XX \u8282\u70B9\uFF0C\u81EA\u5DF1\u8DD1\u6D4B\u8BD5\uFF0C\u5931\u8D25\u6309 last-error \u6539\u5230\u901A\u8FC7\u518D push\u300D\u3002",
|
|
4238
|
-
"",
|
|
4239
|
-
...buildDocsTable("project-root")
|
|
4240
|
-
].join("\n");
|
|
5157
|
+
function extractDocument(snapshot) {
|
|
5158
|
+
const doc = snapshot.document ?? snapshot;
|
|
5159
|
+
const nodes = Array.isArray(doc.nodes) ? doc.nodes : [];
|
|
5160
|
+
const edges = Array.isArray(doc.edges) ? doc.edges : [];
|
|
5161
|
+
return { nodes, edges };
|
|
4241
5162
|
}
|
|
4242
|
-
function
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
""
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
5163
|
+
function splitDocumentToFiles(flowDir, doc) {
|
|
5164
|
+
const nodesDir = import_path4.default.join(flowDir, NODES_DIR);
|
|
5165
|
+
const strippedNodes = [];
|
|
5166
|
+
const nodeMetas = {};
|
|
5167
|
+
const usedDirNames = /* @__PURE__ */ new Set();
|
|
5168
|
+
for (const node of doc.nodes) {
|
|
5169
|
+
if (!node || typeof node !== "object") continue;
|
|
5170
|
+
const nodeUuid = String(node.node_uuid ?? "").trim();
|
|
5171
|
+
const nodeType = resolveNodeType(node);
|
|
5172
|
+
const semanticId = String(node.id ?? "");
|
|
5173
|
+
const codeKey = NODE_TYPE_CODE_DATA_KEY[nodeType];
|
|
5174
|
+
const stripped = JSON.parse(JSON.stringify(node));
|
|
5175
|
+
const meta = { nodeId: semanticId, nodeType };
|
|
5176
|
+
if (codeKey && nodeUuid) {
|
|
5177
|
+
const data = stripped.data ?? {};
|
|
5178
|
+
const rawCode = data[codeKey];
|
|
5179
|
+
const codeBody = typeof rawCode === "string" ? rawCode : rawCode != null ? JSON.stringify(rawCode) : "";
|
|
5180
|
+
delete data[codeKey];
|
|
5181
|
+
stripped.data = data;
|
|
5182
|
+
const language = codeLanguageForNodeType(nodeType);
|
|
5183
|
+
const ext = codeFileExt(language);
|
|
5184
|
+
const label = String(node.data?.label ?? "") || semanticId || nodeType;
|
|
5185
|
+
let dirName = sanitizeName(label);
|
|
5186
|
+
if (usedDirNames.has(dirName)) {
|
|
5187
|
+
dirName = `${dirName}_${nodeUuid.slice(0, 6)}`;
|
|
5188
|
+
}
|
|
5189
|
+
usedDirNames.add(dirName);
|
|
5190
|
+
const nodeDirAbs = import_path4.default.join(nodesDir, dirName);
|
|
5191
|
+
import_fs3.default.mkdirSync(nodeDirAbs, { recursive: true });
|
|
5192
|
+
const codeFile = `code.${ext}`;
|
|
5193
|
+
import_fs3.default.writeFileSync(import_path4.default.join(nodeDirAbs, codeFile), codeBody, "utf8");
|
|
5194
|
+
import_fs3.default.writeFileSync(
|
|
5195
|
+
import_path4.default.join(nodeDirAbs, NODE_INFO_JSON),
|
|
5196
|
+
JSON.stringify(
|
|
5197
|
+
{
|
|
5198
|
+
_readonly: "\u6B64\u6587\u4EF6\u7531 dazi-flow \u751F\u6210\uFF0C\u4EC5\u4F9B\u67E5\u770B\uFF1B\u7F16\u8F91\u4EE3\u7801\u8BF7\u6539 " + codeFile + "\uFF0C\u914D\u7F6E\u6539 flow.json",
|
|
5199
|
+
node_uuid: nodeUuid,
|
|
5200
|
+
nodeId: semanticId,
|
|
5201
|
+
nodeType,
|
|
5202
|
+
label,
|
|
5203
|
+
codeFile,
|
|
5204
|
+
codeLanguage: language,
|
|
5205
|
+
position: node.position,
|
|
5206
|
+
data: stripped.data
|
|
5207
|
+
},
|
|
5208
|
+
null,
|
|
5209
|
+
2
|
|
5210
|
+
),
|
|
5211
|
+
"utf8"
|
|
5212
|
+
);
|
|
5213
|
+
meta.dir = import_path4.default.posix.join(NODES_DIR, dirName);
|
|
5214
|
+
meta.codeFile = codeFile;
|
|
5215
|
+
meta.codeLanguage = language;
|
|
5216
|
+
meta.codeHash = sha1(codeBody);
|
|
5217
|
+
}
|
|
5218
|
+
if (nodeUuid) {
|
|
5219
|
+
nodeMetas[nodeUuid] = meta;
|
|
5220
|
+
}
|
|
5221
|
+
strippedNodes.push(stripped);
|
|
5222
|
+
}
|
|
5223
|
+
const strippedDoc = { nodes: strippedNodes, edges: doc.edges };
|
|
5224
|
+
import_fs3.default.writeFileSync(import_path4.default.join(flowDir, FLOW_JSON), JSON.stringify(strippedDoc, null, 2), "utf8");
|
|
5225
|
+
return { strippedDoc, nodeMetas };
|
|
4266
5226
|
}
|
|
4267
|
-
function
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
5227
|
+
function fingerprintDoc(doc) {
|
|
5228
|
+
return "sha1:" + sha1(JSON.stringify({ nodes: doc.nodes, edges: doc.edges }));
|
|
5229
|
+
}
|
|
5230
|
+
function readFlowJson(flowDir) {
|
|
5231
|
+
const p = import_path4.default.join(flowDir, FLOW_JSON);
|
|
5232
|
+
const raw = JSON.parse(import_fs3.default.readFileSync(p, "utf8"));
|
|
5233
|
+
return {
|
|
5234
|
+
nodes: Array.isArray(raw.nodes) ? raw.nodes : [],
|
|
5235
|
+
edges: Array.isArray(raw.edges) ? raw.edges : []
|
|
5236
|
+
};
|
|
5237
|
+
}
|
|
5238
|
+
function readNodeCode(flowDir, meta) {
|
|
5239
|
+
if (!meta.dir || !meta.codeFile) return void 0;
|
|
5240
|
+
const p = import_path4.default.join(flowDir, meta.dir, meta.codeFile);
|
|
5241
|
+
if (!import_fs3.default.existsSync(p)) return void 0;
|
|
5242
|
+
return import_fs3.default.readFileSync(p, "utf8");
|
|
5243
|
+
}
|
|
5244
|
+
function assembleFullDocument(flowDir, meta) {
|
|
5245
|
+
const doc = readFlowJson(flowDir);
|
|
5246
|
+
for (const node of doc.nodes) {
|
|
5247
|
+
const uuid = String(node.node_uuid ?? "");
|
|
5248
|
+
const nodeMeta = meta.nodes[uuid];
|
|
5249
|
+
if (!nodeMeta) continue;
|
|
5250
|
+
const codeKey = NODE_TYPE_CODE_DATA_KEY[nodeMeta.nodeType];
|
|
5251
|
+
if (!codeKey) continue;
|
|
5252
|
+
const code = readNodeCode(flowDir, nodeMeta);
|
|
5253
|
+
if (code != null) {
|
|
5254
|
+
node.data = { ...node.data ?? {}, [codeKey]: code };
|
|
5255
|
+
}
|
|
5256
|
+
}
|
|
5257
|
+
return doc;
|
|
5258
|
+
}
|
|
5259
|
+
function listDirtyCodeNodes(flowDir, meta) {
|
|
5260
|
+
const dirty = [];
|
|
5261
|
+
for (const [uuid, nodeMeta] of Object.entries(meta.nodes)) {
|
|
5262
|
+
if (!nodeMeta.codeFile) continue;
|
|
5263
|
+
const code = readNodeCode(flowDir, nodeMeta);
|
|
5264
|
+
if (code == null) continue;
|
|
5265
|
+
if (sha1(code) !== (nodeMeta.codeHash ?? "")) {
|
|
5266
|
+
dirty.push(uuid);
|
|
4274
5267
|
}
|
|
4275
5268
|
}
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
5269
|
+
return dirty;
|
|
5270
|
+
}
|
|
5271
|
+
|
|
5272
|
+
// cli/dazi-flow/src/lib/flowApi.ts
|
|
5273
|
+
var import_path5 = __toESM(require("path"), 1);
|
|
5274
|
+
var import_fs4 = __toESM(require("fs"), 1);
|
|
5275
|
+
var FLOW_API = "/api/data-pipelines/v1/flows";
|
|
5276
|
+
async function pushCodeNode(flowId, flowDir, meta, uuid, opts = {}) {
|
|
5277
|
+
const nodeMeta = meta.nodes[uuid];
|
|
5278
|
+
if (!nodeMeta) return { uuid, status: "skipped" };
|
|
5279
|
+
const localCode = readNodeCode(flowDir, nodeMeta);
|
|
5280
|
+
if (localCode == null) return { uuid, status: "skipped" };
|
|
5281
|
+
const nodeLabel = nodeMeta.nodeId || uuid;
|
|
5282
|
+
const remote = await apiRequest(`${FLOW_API}/${flowId}/flow-nodes/${uuid}`, {
|
|
5283
|
+
label: `\u8BFB\u53D6\u8FDC\u7AEF\u8282\u70B9\u4EE3\u7801 (nodeId=${nodeLabel}, uuid=${uuid})`
|
|
5284
|
+
});
|
|
5285
|
+
const remoteHash = sha1(remote.code_body ?? "");
|
|
5286
|
+
const baseHash = nodeMeta.codeHash ?? "";
|
|
5287
|
+
if (!opts.force && baseHash && remoteHash !== baseHash) {
|
|
5288
|
+
return { uuid, status: "conflict", version: remote.version };
|
|
4286
5289
|
}
|
|
4287
|
-
if (
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
5290
|
+
if (opts.dryRun) return { uuid, status: "dry-run", version: remote.version };
|
|
5291
|
+
const updated = await apiRequest(`${FLOW_API}/${flowId}/flow-nodes/${uuid}`, {
|
|
5292
|
+
method: "PATCH",
|
|
5293
|
+
body: { code_body: localCode, expected_version: opts.force ? void 0 : remote.version },
|
|
5294
|
+
label: `\u63D0\u4EA4\u8282\u70B9\u4EE3\u7801 (nodeId=${nodeLabel}, uuid=${uuid})`
|
|
5295
|
+
});
|
|
5296
|
+
nodeMeta.codeHash = sha1(localCode);
|
|
5297
|
+
nodeMeta.codeVersion = updated.version;
|
|
5298
|
+
return { uuid, status: "pushed", version: updated.version };
|
|
5299
|
+
}
|
|
5300
|
+
async function pullCodeNode(flowId, flowDir, meta, uuid) {
|
|
5301
|
+
const nodeMeta = meta.nodes[uuid];
|
|
5302
|
+
if (!nodeMeta?.dir || !nodeMeta.codeFile) {
|
|
5303
|
+
throw new Error(`\u8282\u70B9 ${uuid} \u4E0D\u662F\u4EE3\u7801\u8282\u70B9\u6216\u7F3A\u5C11\u672C\u5730\u6620\u5C04`);
|
|
4293
5304
|
}
|
|
4294
|
-
const
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
"",
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
"\u5728 **dazi-work \u6839**\uFF08\u6216\u5C06 `--dir` \u6307\u5411\u672C\u76EE\u5F55\uFF09\uFF1B\u9700\u5DF2\u5B89\u88C5\u5168\u5C40 CLI\uFF08`pnpm add -g @dazitech/cli`\uFF09\uFF1A",
|
|
4314
|
-
"",
|
|
4315
|
-
"```powershell",
|
|
4316
|
-
`cd "\u9879\u76EE\\${opts.projectFolder ?? "flow_<\u9879\u76EE\u540D>"}\\\u6D41\u7A0B\\${name}"`,
|
|
4317
|
-
"",
|
|
4318
|
-
"# \u72B6\u6001 / \u62C9\u53D6 / \u63D0\u4EA4",
|
|
4319
|
-
psFlowLine("project status --dir ."),
|
|
4320
|
-
psFlowLine(`project pull --flow ${opts.flowId} --dir .`),
|
|
4321
|
-
psFlowLine("project push --dir . --canvas"),
|
|
4322
|
-
"",
|
|
4323
|
-
"# \u5355\u8282\u70B9\u6D4B\u8BD5\uFF08uuid \u89C1 flow.meta.json \u6216 node.info.json\uFF09",
|
|
4324
|
-
psFlowLine("run node-exec --node <node_uuid> --dir ."),
|
|
4325
|
-
"",
|
|
4326
|
-
"# \u6574\u6D41\u7A0B\u8C03\u8BD5 + \u53D8\u91CF",
|
|
4327
|
-
psFlowLine("run flow-exec --dir . --type debug"),
|
|
4328
|
-
psFlowLine("variable sync --dir ."),
|
|
4329
|
-
psFlowLine("variable pull --name <output_variable_name> --dir ."),
|
|
4330
|
-
"```",
|
|
4331
|
-
"",
|
|
4332
|
-
...buildFlowNodeCatalogQuickStartSection(flowDocsRel("flow-dir", "flow/flows-guide.md")),
|
|
4333
|
-
"## AI \u4FEE\u6539\u73B0\u6709\u6D41\u7A0B\uFF08\u5355\u6587\u4EF6\u5165\u53E3\uFF09",
|
|
4334
|
-
"",
|
|
4335
|
-
"> \u63A8\u8350\u53EA\u628A\u672C\u6587\u4EF6\u9644\u52A0\u7ED9 AI\uFF1B\u82E5\u4FE1\u606F\u4E0D\u8DB3\uFF0C\u518D\u6309\u9700\u6253\u5F00\u300C\u5E2E\u52A9\u6587\u6863\u300D\u4E2D\u7684\u4E13\u9898\u3002",
|
|
4336
|
-
"",
|
|
4337
|
-
"### \u573A\u666F A\uFF1A\u65B0\u589E\u8282\u70B9\uFF08\u5DF2\u6709\u6D41\u7A0B\u7EE7\u7EED\u6539\uFF09",
|
|
4338
|
-
"",
|
|
4339
|
-
"1. \u5148\u8BFB `flow.json` \u4E0E `flow.meta.json`\uFF0C\u6267\u884C `dazi flow project doctor --dir .`",
|
|
4340
|
-
`2. **\u5FC5\u987B**\u7528 CLI \u65B0\u5EFA\u8282\u70B9\uFF08\u7981\u6B62\u624B\u6413 uuid\uFF09\uFF1A${mdFlowCmd('node new --type <node_type> --dir . --label "<\u8282\u70B9\u540D>"')}`,
|
|
4341
|
-
"3. \u5728 `flow.json` \u91CC\u8865 `nodes/edges`\uFF08\u9075\u5B88\u951A\u70B9\uFF1A`sourceHandle` \u4EC5 `r/b/true/false`\uFF0C`targetHandle` \u4EC5 `l/t`\uFF09",
|
|
4342
|
-
"4. \u7F16\u8F91 `\u8282\u70B9/<\u540D>/code.sql|py`\uFF08`node new` \u4F1A\u521B\u5EFA\u76EE\u5F55\u4E0E meta \u7D22\u5F15\uFF09",
|
|
4343
|
-
`5. \u5355\u8282\u70B9\u6D4B\u8BD5\uFF1A${mdFlowCmd("run node-exec --node <node_uuid> --dir .")}`,
|
|
4344
|
-
`6. \u63D0\u4EA4\u753B\u5E03\uFF08\u542B\u8FDE\u7EBF/\u914D\u7F6E\uFF09\uFF1A${mdFlowCmd("project push --dir . --canvas")}`,
|
|
4345
|
-
"",
|
|
4346
|
-
"### \u573A\u666F B\uFF1A\u4EC5\u6539\u8282\u70B9\u4EE3\u7801",
|
|
4347
|
-
"",
|
|
4348
|
-
"1. \u7F16\u8F91 `\u8282\u70B9/<\u540D>/code.sql|py`\uFF08\u4E0D\u8981\u628A\u6B63\u6587\u5199\u56DE `flow.json`\uFF09",
|
|
4349
|
-
`2. \u8FD0\u884C\u8282\u70B9\uFF1A${mdFlowCmd("run node-exec --node <node_uuid> --dir .")}`,
|
|
4350
|
-
`3. \u63D0\u4EA4\u4EE3\u7801\uFF1A${mdFlowCmd("node push --node <node_uuid> --dir .")}`,
|
|
4351
|
-
"",
|
|
4352
|
-
"### \u573A\u666F C\uFF1A\u753B\u5E03\u548C\u4EE3\u7801\u4E0D\u540C\u6B65",
|
|
4353
|
-
"",
|
|
4354
|
-
`1. \u5148 ${mdFlowCmd("project status --dir .")} \u770B\u672C\u5730\u810F\u6539\u52A8`,
|
|
4355
|
-
`2. \u82E5\u6539\u4E86\u62D3\u6251/\u8FDE\u7EBF/\u914D\u7F6E\uFF1A\u6267\u884C ${mdFlowCmd("project push --dir . --canvas")}`,
|
|
4356
|
-
`3. \u82E5\u53EA\u6539\u4E86\u4EE3\u7801\uFF1A\u6267\u884C ${mdFlowCmd("node push --node <node_uuid> --dir .")}`,
|
|
4357
|
-
`4. \u5FC5\u8981\u65F6\u91CD\u65B0\u62C9\u53D6\u6821\u5BF9\uFF1A${mdFlowCmd(`project pull --flow ${opts.flowId} --dir .`)}`,
|
|
4358
|
-
"",
|
|
4359
|
-
"## AI \u81EA\u68C0\u6E05\u5355\uFF08\u63D0\u4EA4\u524D\uFF09",
|
|
4360
|
-
"",
|
|
4361
|
-
`- \u547D\u4EE4\u524D\u7F00\u662F\u5426\u7EDF\u4E00\u4E3A ${mdFlowCmd("...")}\uFF08\u800C\u4E0D\u662F\u88F8 \`dazi-flow\`\uFF09`,
|
|
4362
|
-
"- `flow.json` \u662F\u5426\u53EA\u627F\u8F7D\u753B\u5E03\u62D3\u6251\u4E0E\u8282\u70B9\u914D\u7F6E\uFF08\u4E0D\u5D4C\u5165\u5927\u6BB5 SQL/Python\uFF09",
|
|
4363
|
-
"- `code.*` \u662F\u5426\u4E0E\u8282\u70B9\u4E1A\u52A1\u7C7B\u578B\u4E00\u81F4\uFF08SQL \u8282\u70B9 `code.sql`\uFF0CPython \u8282\u70B9 `code.py`\uFF09",
|
|
4364
|
-
"- \u6761\u4EF6\u8282\u70B9\u51FA\u8FB9\u662F\u5426\u4EC5\u4F7F\u7528 `true/false`\uFF0C\u672A\u8BEF\u7528 `r/b`",
|
|
4365
|
-
"- \u82E5\u6539\u52A8\u753B\u5E03\uFF0C\u662F\u5426\u6267\u884C\u4E86 `flow project push --canvas`",
|
|
4366
|
-
"",
|
|
4367
|
-
"## \u5E38\u89C1\u9519\u8BEF\u4E0E\u4FEE\u590D",
|
|
4368
|
-
"",
|
|
4369
|
-
"| \u73B0\u8C61 | \u5E38\u89C1\u539F\u56E0 | \u4FEE\u590D |",
|
|
4370
|
-
"|------|----------|------|",
|
|
4371
|
-
`| \u547D\u4EE4\u627E\u4E0D\u5230 | \u672A\u88C5\u5168\u5C40 CLI \u6216\u4E0D\u5728 dazi-work | \`pnpm add -g @dazitech/cli\` \u6216 ${mdFlowCmd("...")} / \`.scriptsdazi.ps1 flow ...\` |`,
|
|
4372
|
-
"| \u8282\u70B9\u6D4B\u8BD5\u62A5\u4E0A\u6E38\u53D8\u91CF\u4E0D\u5B58\u5728 | \u672A\u5148\u8FD0\u884C\u4E0A\u6E38\u8282\u70B9\u4EA7\u51FA\u53D8\u91CF | \u5148\u8DD1\u4E0A\u6E38\uFF0C\u6216\u6574\u6D41\u7A0B `flow run flow-exec --type debug` \u540E\u518D\u6D4B |",
|
|
4373
|
-
"| excel-python \u627E\u4E0D\u5230\u6587\u4EF6 | code.py \u5199\u4E86\u6587\u4EF6\u540D/\u672C\u5730\u8DEF\u5F84 | \u753B\u5E03\u914D `managed_file_id`\uFF08UUID\uFF09\uFF1B\u4EE3\u7801\u7528 `excel_source_path` |",
|
|
4374
|
-
"| Excel \u7528\u4E86 file-source | file-source \u4E0D\u89E3\u6790 xlsx | \u6539\u4E3A **`excel-python`** + `managed_file_id` |",
|
|
4375
|
-
"| excel-python \u65E0\u4E3B\u8F93\u51FA | \u672A `set_table_output` \u6216\u540D\u79F0\u4E0E `output_variable_name` \u4E0D\u4E00\u81F4 | \u89C1 node-code-guide \xA75 |",
|
|
4376
|
-
"| \u753B\u5E03\u663E\u793A\u5BF9\u4F46\u5E73\u53F0\u4E0D\u751F\u6548 | \u53EA push \u4E86\u4EE3\u7801\uFF0C\u672A push \u753B\u5E03 | \u6267\u884C `flow project push --dir . --canvas` |",
|
|
4377
|
-
"| \u4EE3\u7801\u6539\u4E86\u4F46\u5E73\u53F0\u8FD8\u662F\u65E7\u4EE3\u7801 | \u6539\u4E86\u672C\u5730 `code.*` \u4F46\u672A node push | \u6267\u884C `flow node push --node <node_uuid> --dir .` |",
|
|
4378
|
-
"",
|
|
4379
|
-
"## AI \u81EA\u4E3B\u8FD0\u884C\u4E0E\u6539\u9519\u95ED\u73AF\uFF08Agent \u5FC5\u8BFB\uFF09",
|
|
4380
|
-
"",
|
|
4381
|
-
"> **\u6269\u5C55/\u83DC\u5355\u4E0D\u4F1A\u81EA\u52A8\u6539\u4EE3\u7801**\uFF08\u5E73\u53F0 D6\uFF09\uFF1B\u7528\u6237\u59D4\u6258\u4F60\u6539\u6D41\u7A0B\u65F6\uFF0C\u4F60**\u5FC5\u987B\u4E3B\u52A8**\u6267\u884C\u300C\u6539 \u2192 \u8DD1 \u2192 \u8BFB\u9519 \u2192 \u518D\u6539 \u2192 \u518D\u8DD1\u300D\uFF0C\u76F4\u5230\u901A\u8FC7\u6216\u8FBE\u5230\u91CD\u8BD5\u4E0A\u9650\u3002",
|
|
4382
|
-
"",
|
|
4383
|
-
"### \u9519\u8BEF\u843D\u5728\u54EA\u91CC\uFF08\u8DD1\u5B8C\u5FC5\u67E5\uFF09",
|
|
4384
|
-
"",
|
|
4385
|
-
"| \u8FD0\u884C\u65B9\u5F0F | \u5931\u8D25\u65F6\u8BFB | \u6210\u529F/\u6B65\u9AA4\u6458\u8981 |",
|
|
4386
|
-
"|----------|----------|---------------|",
|
|
4387
|
-
"| \u5355\u8282\u70B9 `run node-exec` | `_run/<\u8282\u70B9\u540D>.last-error.md` | \u65E0 error \u6587\u4EF6\u5373\u901A\u8FC7 |",
|
|
4388
|
-
"| \u6574\u6D41\u7A0B `run flow-exec` | `_run/flow.last-error.md` | `_run/flow.last-run.md`\uFF08\u6B65\u9AA4+\u65E5\u5FD7\uFF09 |",
|
|
4389
|
-
"",
|
|
4390
|
-
"CLI \u5E26 `--json` \u65F6\uFF1A\u770B\u8FD4\u56DE `success: false` \u6216 `errorFile` \u5B57\u6BB5\uFF0C**\u518D\u6253\u5F00\u5BF9\u5E94 md \u6587\u4EF6**\uFF0C\u4E0D\u8981\u53EA\u770B\u7EC8\u7AEF\u4E00\u884C\u62A5\u9519\u3002",
|
|
4391
|
-
"",
|
|
4392
|
-
"### \u6807\u51C6\u6539\u9519\u5FAA\u73AF\uFF08\u9ED8\u8BA4\u6700\u591A 3 \u8F6E\uFF09",
|
|
4393
|
-
"",
|
|
4394
|
-
"1. **\u5B9A\u4F4D**\uFF1A\u8BFB `flow.json` + \u76EE\u6807 `\u8282\u70B9/<\u540D>/code.*` + `flow.meta.json`\uFF08\u53D6 `node_uuid`\uFF09",
|
|
4395
|
-
"2. **\u4FEE\u6539**\uFF1A\u53EA\u6539\u5FC5\u8981\u6587\u4EF6\uFF08\u4EE3\u7801 \u2192 `code.*`\uFF1B\u8FDE\u7EBF/\u914D\u7F6E \u2192 `flow.json`\uFF09",
|
|
4396
|
-
"3. **\u9A8C\u8BC1**\uFF08\u5148\u5C0F\u540E\u5927\uFF09\uFF1A",
|
|
4397
|
-
` - \u5355\u8282\u70B9\uFF1A${mdFlowCmd("run node-exec --node <node_uuid> --dir .")}`,
|
|
4398
|
-
` - \u6574\u6D41\u7A0B\uFF1A${mdFlowCmd("run flow-exec --dir . --type debug")}`,
|
|
4399
|
-
"4. **\u5224\u9519**\uFF1A\u9000\u51FA\u7801\u975E 0 / JSON `success:false` \u2192 \u6253\u5F00 `_run/*.last-error.md`\uFF0C\u6309\u5176\u4E2D**\u9519\u8BEF\u5206\u7C7B**\u4E0E traceback \u4FEE\u590D",
|
|
4400
|
-
"5. **\u91CD\u8BD5**\uFF1A\u56DE\u5230\u6B65\u9AA4 2\uFF1B\u82E5 3 \u8F6E\u4ECD\u5931\u8D25\uFF0C\u6C47\u603B\u5DF2\u5C1D\u8BD5\u4FEE\u590D\u70B9\u5E76\u8BF7\u6C42\u7528\u6237\u4ECB\u5165",
|
|
4401
|
-
"6. **\u63D0\u4EA4**\uFF08\u4EC5\u901A\u8FC7\u540E\uFF09\uFF1A\u4EE3\u7801 `node push`\uFF1B\u753B\u5E03 `project push --canvas`",
|
|
4402
|
-
"",
|
|
4403
|
-
"### \u5E38\u89C1\u5931\u8D25 \u2192 \u4F18\u5148\u52A8\u4F5C",
|
|
4404
|
-
"",
|
|
4405
|
-
"| last-error \u5206\u7C7B | \u4F18\u5148\u68C0\u67E5 |",
|
|
4406
|
-
"|-----------------|----------|",
|
|
4407
|
-
"| \u7F3A\u4E0A\u6E38\u53D8\u91CF | \u5148\u8DD1\u4E0A\u6E38\u8282\u70B9\u6216\u6574\u6D41\u7A0B debug\uFF0C\u518D `variable pull` \u770B schema |",
|
|
4408
|
-
"| \u914D\u7F6E\u7F3A\u5931 | `flow.json` \u8BE5\u8282\u70B9 `data`\uFF08connectionId / output_variable_name \u7B49\uFF09 |",
|
|
4409
|
-
"| \u4EE3\u7801\u9519\u8BEF | `code.*` \u4E0E traceback\uFF1B\u6539\u540E\u53EA `node push` |",
|
|
4410
|
-
"| \u8FDE\u63A5/\u6570\u636E\u6E90 | connectionId / spaceId \u662F\u5426\u6709\u6548 |",
|
|
4411
|
-
"",
|
|
4412
|
-
"### Agent \u7981\u6B62\u9879",
|
|
4413
|
-
"",
|
|
4414
|
-
"- **\u7981\u6B62**\u672A\u5B9E\u9645\u8FD0\u884C\u5C31\u58F0\u79F0\u300C\u5DF2\u4FEE\u590D/\u5DF2\u901A\u8FC7\u300D",
|
|
4415
|
-
"- **\u7981\u6B62**\u4E0D\u8BFB `_run/*.last-error.md` \u5C31\u731C\u6D4B\u539F\u56E0",
|
|
4416
|
-
"- **\u7981\u6B62**\u4FEE\u590D\u540E\u8DF3\u8FC7\u9A8C\u8BC1\u76F4\u63A5 `push`",
|
|
4417
|
-
"- **\u7981\u6B62**\u628A SQL/Python \u6B63\u6587\u5199\u56DE `flow.json`",
|
|
4418
|
-
"",
|
|
4419
|
-
"\u4FA7\u680F\u63D0\u793A\u8BCD\u53EF\u9009\u7528 **`flow/run-fix-loop`**\uFF08\u81EA\u4E3B\u6539\u9519\u4E13\u7528\uFF09\u3002",
|
|
4420
|
-
"",
|
|
4421
|
-
"\u6269\u5C55\uFF1A\u53F3\u952E **`flow.json`** / **\u8282\u70B9/** / **`code.*`** \u53EF\u6D4B\u8BD5\u3001\u63D0\u4EA4\u3001\u6253\u5F00\u8BBE\u8BA1\u5668\u3002",
|
|
4422
|
-
"",
|
|
4423
|
-
"## \u7F16\u5199\u8282\u70B9\u4EE3\u7801",
|
|
4424
|
-
"",
|
|
4425
|
-
"- **SQL \u8282\u70B9**\uFF08`sql-query` / `database-source`\uFF09\uFF1A\u7F16\u8F91 `\u8282\u70B9/<\u540D>/code.sql`\uFF1B`sql-query` \u4E2D\u7528 **\u4E0A\u6E38\u53D8\u91CF\u540D\u4F5C\u8868\u540D**\uFF08`FROM \u4E0A\u6E38\u53D8\u91CF\u540D`\uFF09",
|
|
4426
|
-
'- **Python \u8282\u70B9**\uFF08`python-script`\uFF09\uFF1A\u7F16\u8F91 `code.py`\uFF1B\u5355\u8282\u70B9\u6D4B\u8BD5\u7528 **`get_variable("\u4E0A\u6E38\u53D8\u91CF\u540D")`**\uFF0C\u8F93\u51FA\u8D4B\u503C **`result_df`**',
|
|
4427
|
-
"- **`excel-python`\uFF08Excel \u9ED8\u8BA4\u9996\u9009\uFF09**\uFF1A",
|
|
4428
|
-
" - \u6709 **`managed_file_id` \u7684 Excel \u2192 \u4F18\u5148 `excel-python`**\uFF0C**\u52FF\u7528 `file-source`**\uFF08file-source \u4E0D\u89E3\u6790 Excel\uFF09",
|
|
4429
|
-
" - **\u753B\u5E03**\u914D **`managed_file_id`**\uFF08UUID\uFF09\uFF1B**`code.py` \u53EA\u7528 `excel_source_path`**",
|
|
4430
|
-
' - \u4E3B\u8F93\u51FA **`set_table_output("<\u4E0E output_variable_name \u540C\u540D>", df)`**',
|
|
4431
|
-
" - \u5B8C\u6574\u793A\u4F8B \u2192 [node-code-guide \xA75](" + flowDocsRel("flow-dir", "flow/node-code-guide.md") + "#5-excel-pythonexcel-\u5F00\u53D1--\u9ED8\u8BA4\u9996\u9009)",
|
|
4432
|
-
"- \u53D8\u91CF\u7EA6\u5B9A\u4E0E\u5B8C\u6574\u793A\u4F8B \u2192 [\u6D41\u7A0B\u53D8\u91CF\u7CFB\u7EDF\u6307\u5357](" + flowDocsRel("flow-dir", "flow/variables-guide.md") + ") \xB7 [\u8282\u70B9\u4EE3\u7801\u7F16\u5199\u6307\u5357](" + flowDocsRel("flow-dir", "flow/node-code-guide.md") + ")",
|
|
4433
|
-
"",
|
|
4434
|
-
...buildDocsTable("flow-dir")
|
|
4435
|
-
].join("\n");
|
|
5305
|
+
const remote = await apiRequest(`${FLOW_API}/${flowId}/flow-nodes/${uuid}`, {
|
|
5306
|
+
label: `\u62C9\u53D6\u8282\u70B9\u4EE3\u7801 (uuid=${uuid})`
|
|
5307
|
+
});
|
|
5308
|
+
const code = remote.code_body ?? "";
|
|
5309
|
+
const target = import_path5.default.join(flowDir, nodeMeta.dir, nodeMeta.codeFile);
|
|
5310
|
+
import_fs4.default.mkdirSync(import_path5.default.dirname(target), { recursive: true });
|
|
5311
|
+
import_fs4.default.writeFileSync(target, code, "utf8");
|
|
5312
|
+
nodeMeta.codeHash = sha1(code);
|
|
5313
|
+
nodeMeta.codeVersion = remote.version;
|
|
5314
|
+
return { uuid, version: remote.version };
|
|
5315
|
+
}
|
|
5316
|
+
async function pushCanvasDocument(flowId, document) {
|
|
5317
|
+
const nodeCount = document.nodes?.length ?? 0;
|
|
5318
|
+
const edgeCount = document.edges?.length ?? 0;
|
|
5319
|
+
await apiRequest(`${FLOW_API}/${flowId}`, {
|
|
5320
|
+
method: "PUT",
|
|
5321
|
+
body: { data: document },
|
|
5322
|
+
label: `\u63D0\u4EA4\u753B\u5E03 flow.json (flowId=${flowId}, nodes=${nodeCount}, edges=${edgeCount})`
|
|
5323
|
+
});
|
|
4436
5324
|
}
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
5325
|
+
|
|
5326
|
+
// cli/dazi-flow/src/commands/snapshot.ts
|
|
5327
|
+
function makeSnapshotCommand() {
|
|
5328
|
+
const cmd = new Command("snapshot").description("Flow \u5FEB\u7167\u7BA1\u7406");
|
|
5329
|
+
cmd.command("pull").description("\u4ECE\u5E73\u53F0\u62C9\u53D6 Flow \u5FEB\u7167\u5230\u672C\u5730 flows/<flowId>/").requiredOption("--flow <flowId>", "Flow ID\uFF08\u77ED\u9009\u9879 -f\uFF09").alias("-f").option("--out <dir>", "\u8F93\u51FA\u76EE\u5F55\uFF08\u9ED8\u8BA4 flows/<flowId>/\uFF09").option("--json", "\u8F93\u51FA JSON").action(async (opts) => {
|
|
4440
5330
|
try {
|
|
4441
|
-
|
|
4442
|
-
|
|
5331
|
+
console.log(`\u6B63\u5728\u62C9\u53D6\u5FEB\u7167: ${opts.flow} ...`);
|
|
5332
|
+
const snapshot = await apiRequest(
|
|
5333
|
+
`/api/data-pipelines/v1/flows/${opts.flow}/snapshot`
|
|
5334
|
+
);
|
|
5335
|
+
const ws = resolveWorkspace();
|
|
5336
|
+
const outDir = opts.out ?? import_path6.default.join(ws.flows, opts.flow);
|
|
5337
|
+
if (!import_fs5.default.existsSync(outDir)) import_fs5.default.mkdirSync(outDir, { recursive: true });
|
|
5338
|
+
const outFile = import_path6.default.join(outDir, "snapshot.json");
|
|
5339
|
+
import_fs5.default.writeFileSync(outFile, JSON.stringify(snapshot, null, 2), "utf-8");
|
|
5340
|
+
if (opts.json) {
|
|
5341
|
+
console.log(JSON.stringify(snapshot, null, 2));
|
|
5342
|
+
} else {
|
|
5343
|
+
console.log(`\u2705 \u5FEB\u7167\u5DF2\u4FDD\u5B58: ${outFile}`);
|
|
4443
5344
|
}
|
|
4444
|
-
|
|
5345
|
+
ok({ flowId: opts.flow, file: outFile });
|
|
5346
|
+
} catch (err) {
|
|
5347
|
+
handleError(err);
|
|
4445
5348
|
}
|
|
4446
|
-
}
|
|
4447
|
-
|
|
4448
|
-
if (entry === currentFilename) continue;
|
|
4449
|
-
if (!/^快速启动_.+\.md$/.test(entry)) continue;
|
|
4450
|
-
const full = import_path8.default.join(flowDir, entry);
|
|
5349
|
+
});
|
|
5350
|
+
cmd.command("push-graph").description("\u5C06\u672C\u5730 flows/<flowId>/snapshot.json \u56FE\u7ED3\u6784\u63A8\u9001\u5230\u5E73\u53F0").requiredOption("--flow <flowId>", "Flow ID").option("--dir <dir>", "\u5FEB\u7167\u76EE\u5F55\uFF08\u9ED8\u8BA4 flows/<flowId>/\uFF09").option("--dry-run", "\u4EC5\u9A8C\u8BC1\uFF0C\u4E0D\u63A8\u9001").action(async (opts) => {
|
|
4451
5351
|
try {
|
|
4452
|
-
|
|
4453
|
-
|
|
5352
|
+
const ws = resolveWorkspace();
|
|
5353
|
+
const dir = opts.dir ?? import_path6.default.join(ws.flows, opts.flow);
|
|
5354
|
+
const file = import_path6.default.join(dir, "snapshot.json");
|
|
5355
|
+
if (!import_fs5.default.existsSync(file)) {
|
|
5356
|
+
console.error(`\u9519\u8BEF: \u627E\u4E0D\u5230 ${file}\uFF0C\u8BF7\u5148\u8FD0\u884C snapshot pull`);
|
|
5357
|
+
process.exit(1);
|
|
4454
5358
|
}
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
}
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
if (isFlowScaffoldFile(fsImpl.readFileSync(legacy, "utf8"))) {
|
|
4470
|
-
fsImpl.unlinkSync(legacy);
|
|
4471
|
-
}
|
|
4472
|
-
} catch {
|
|
4473
|
-
}
|
|
4474
|
-
}
|
|
4475
|
-
function writeScaffoldIfAllowed(filePath, content, fsImpl, opts) {
|
|
4476
|
-
if (fsImpl.existsSync(filePath)) {
|
|
4477
|
-
const existing = fsImpl.readFileSync(filePath, "utf8");
|
|
4478
|
-
if (!isFlowScaffoldFile(existing)) {
|
|
4479
|
-
if (!(opts?.upgradeLegacy && isLegacyFlowScaffoldFile(existing))) return false;
|
|
5359
|
+
const snapshot = JSON.parse(import_fs5.default.readFileSync(file, "utf-8"));
|
|
5360
|
+
if (opts.dryRun) {
|
|
5361
|
+
console.log("[dry-run] \u5C06\u63A8\u9001\u56FE\u5FEB\u7167:");
|
|
5362
|
+
console.log(` \u8282\u70B9\u6570: ${snapshot.nodes?.length ?? "?"}`);
|
|
5363
|
+
console.log(` \u8FB9\u6570: ${snapshot.edges?.length ?? "?"}`);
|
|
5364
|
+
ok({ flowId: opts.flow, dryRun: true });
|
|
5365
|
+
return;
|
|
5366
|
+
}
|
|
5367
|
+
const doc = extractDocument(snapshot);
|
|
5368
|
+
await pushCanvasDocument(opts.flow, doc);
|
|
5369
|
+
console.log(`\u2705 \u56FE\u5FEB\u7167\u5DF2\u63A8\u9001`);
|
|
5370
|
+
ok({ flowId: opts.flow, nodeCount: doc.nodes.length, edgeCount: doc.edges.length });
|
|
5371
|
+
} catch (err) {
|
|
5372
|
+
handleError(err);
|
|
4480
5373
|
}
|
|
4481
|
-
}
|
|
4482
|
-
|
|
4483
|
-
return true;
|
|
5374
|
+
});
|
|
5375
|
+
return cmd;
|
|
4484
5376
|
}
|
|
4485
5377
|
|
|
5378
|
+
// cli/dazi-flow/src/commands/project.ts
|
|
5379
|
+
var import_path9 = __toESM(require("path"), 1);
|
|
5380
|
+
var import_fs8 = __toESM(require("fs"), 1);
|
|
5381
|
+
var import_flowScaffoldDocs = __toESM(require_flowScaffoldDocs(), 1);
|
|
5382
|
+
|
|
4486
5383
|
// cli/dazi-flow/src/lib/flowVariables.ts
|
|
4487
5384
|
var import_fs7 = __toESM(require("fs"), 1);
|
|
4488
|
-
var
|
|
5385
|
+
var import_path8 = __toESM(require("path"), 1);
|
|
4489
5386
|
async function ensureFlowDebugRun(flowId) {
|
|
4490
5387
|
return apiRequest(`${FLOW_API}/${flowId}/debug-run`);
|
|
4491
5388
|
}
|
|
4492
5389
|
function variablesDir(flowDir) {
|
|
4493
|
-
return
|
|
5390
|
+
return import_path8.default.join(flowDir, VARIABLES_DIR);
|
|
4494
5391
|
}
|
|
4495
5392
|
function variableFilePath(flowDir, varName) {
|
|
4496
5393
|
const safe = sanitizeName(varName) || "variable";
|
|
4497
|
-
return
|
|
5394
|
+
return import_path8.default.join(variablesDir(flowDir), `${safe}.json`);
|
|
4498
5395
|
}
|
|
4499
5396
|
function collectDesignTimeVariableNames(flowDir) {
|
|
4500
5397
|
const doc = readFlowJson(flowDir);
|
|
@@ -4633,11 +5530,10 @@ async function syncAllVariables(flowId, flowDir, previewLimit = 10) {
|
|
|
4633
5530
|
}
|
|
4634
5531
|
|
|
4635
5532
|
// cli/dazi-flow/src/commands/project.ts
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
}
|
|
5533
|
+
var import_flowWorkspaceAudit = __toESM(require_flowWorkspaceAudit(), 1);
|
|
5534
|
+
var import_flowDirResolve = __toESM(require_flowDirResolve(), 1);
|
|
4639
5535
|
function readLocalCanvasNodeCount(flowDir) {
|
|
4640
|
-
const p =
|
|
5536
|
+
const p = import_path9.default.join(flowDir, "flow.json");
|
|
4641
5537
|
if (!import_fs8.default.existsSync(p)) return 0;
|
|
4642
5538
|
try {
|
|
4643
5539
|
const doc = JSON.parse(import_fs8.default.readFileSync(p, "utf8"));
|
|
@@ -4646,15 +5542,10 @@ function readLocalCanvasNodeCount(flowDir) {
|
|
|
4646
5542
|
return 0;
|
|
4647
5543
|
}
|
|
4648
5544
|
}
|
|
4649
|
-
function inferProjectFolder(flowDir) {
|
|
4650
|
-
const norm = flowDir.replace(/\\/g, "/");
|
|
4651
|
-
const m = norm.match(/(?:^|\/)项目\/(flow_[^/]+)\/流程(?:\/|$)/);
|
|
4652
|
-
return m?.[1];
|
|
4653
|
-
}
|
|
4654
5545
|
function writeFlowPullScaffold(flowDir, meta) {
|
|
4655
|
-
const projectFolder =
|
|
4656
|
-
const flowName = meta.flowName ||
|
|
4657
|
-
const quickStart = buildFlowDirQuickStartMarkdown({
|
|
5546
|
+
const projectFolder = (0, import_flowDirResolve.inferBusinessProjectFolder)(flowDir) ?? "<\u4E1A\u52A1\u9879\u76EE\u540D>";
|
|
5547
|
+
const flowName = meta.flowName || import_path9.default.basename(flowDir);
|
|
5548
|
+
const quickStart = (0, import_flowScaffoldDocs.buildFlowDirQuickStartMarkdown)({
|
|
4658
5549
|
flowName,
|
|
4659
5550
|
flowId: meta.flowId,
|
|
4660
5551
|
projectFolder,
|
|
@@ -4663,62 +5554,76 @@ function writeFlowPullScaffold(flowDir, meta) {
|
|
|
4663
5554
|
pulledAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4664
5555
|
flowDir
|
|
4665
5556
|
});
|
|
4666
|
-
writeFlowDirQuickStartScaffold(flowDir, flowName, quickStart, import_fs8.default);
|
|
4667
|
-
removeLegacyFlowDirScaffoldReadme(flowDir, import_fs8.default);
|
|
4668
|
-
const
|
|
4669
|
-
if (
|
|
4670
|
-
const
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
5557
|
+
(0, import_flowScaffoldDocs.writeFlowDirQuickStartScaffold)(flowDir, flowName, quickStart, import_fs8.default);
|
|
5558
|
+
(0, import_flowScaffoldDocs.removeLegacyFlowDirScaffoldReadme)(flowDir, import_fs8.default);
|
|
5559
|
+
const flowRoot = (0, import_flowScaffoldDocs.resolveFlowRootFromFlowDir)(flowDir);
|
|
5560
|
+
if (flowRoot) {
|
|
5561
|
+
const flowsContainer = import_path9.default.join(flowRoot, "flows");
|
|
5562
|
+
const flowsReadme = (0, import_flowScaffoldDocs.buildFlowsDirReadmeMarkdown)({ projectFolder });
|
|
5563
|
+
if (import_fs8.default.existsSync(flowsContainer)) {
|
|
5564
|
+
(0, import_flowScaffoldDocs.writeScaffoldIfAllowed)(import_path9.default.join(flowsContainer, "README.md"), flowsReadme, import_fs8.default, {
|
|
5565
|
+
upgradeLegacy: true
|
|
5566
|
+
});
|
|
5567
|
+
} else if (import_path9.default.basename(import_path9.default.dirname(flowDir)) === "\u6D41\u7A0B") {
|
|
5568
|
+
(0, import_flowScaffoldDocs.writeScaffoldIfAllowed)(import_path9.default.join(flowRoot, "README.md"), flowsReadme, import_fs8.default, { upgradeLegacy: true });
|
|
5569
|
+
}
|
|
5570
|
+
const rootReadme = (0, import_flowScaffoldDocs.buildFlowRootReadmeMarkdown)({ projectFolder });
|
|
5571
|
+
(0, import_flowScaffoldDocs.writeScaffoldIfAllowed)(import_path9.default.join(flowRoot, "README.md"), rootReadme, import_fs8.default, { upgradeLegacy: true });
|
|
5572
|
+
(0, import_flowScaffoldDocs.removeLegacyFlowRootQuickStart)(flowRoot, import_fs8.default);
|
|
4675
5573
|
}
|
|
4676
5574
|
}
|
|
4677
5575
|
function makeProjectCommand() {
|
|
4678
5576
|
const cmd = new Command("project").description("\u6D41\u7A0B\u9879\u76EE\u672C\u5730\u6587\u4EF6\u5316\uFF08\u62C9\u53D6/\u63D0\u4EA4/\u72B6\u6001\uFF09");
|
|
4679
|
-
cmd.command("init <name>").description("\u5728 \u9879\u76EE
|
|
5577
|
+
cmd.command("init <name>").description("\u5728 \u9879\u76EE/<\u4E1A\u52A1\u540D>/ \u521D\u59CB\u5316\u4E1A\u52A1\u9879\u76EE\u6D41\u7A0B\u9AA8\u67B6\uFF08\u542B \u6D41\u7A0B/flows/\uFF09").option("--root <dir>", "\u5DE5\u4F5C\u533A\u6839\uFF08\u9ED8\u8BA4 cwd\uFF09").option("--json", "\u8F93\u51FA JSON").action((name, opts) => {
|
|
4680
5578
|
try {
|
|
4681
|
-
const root =
|
|
4682
|
-
const folder = name.
|
|
4683
|
-
|
|
5579
|
+
const root = import_path9.default.resolve(opts.root ?? process.cwd());
|
|
5580
|
+
const folder = name.trim();
|
|
5581
|
+
if (!folder) {
|
|
5582
|
+
console.error("\u9519\u8BEF: \u4E1A\u52A1\u9879\u76EE\u540D\u4E0D\u80FD\u4E3A\u7A7A");
|
|
5583
|
+
process.exit(1);
|
|
5584
|
+
}
|
|
5585
|
+
const projectRoot = import_path9.default.join(root, "\u9879\u76EE", folder);
|
|
4684
5586
|
if (import_fs8.default.existsSync(projectRoot)) {
|
|
4685
5587
|
console.error(`\u9519\u8BEF: \u9879\u76EE\u76EE\u5F55\u5DF2\u5B58\u5728: ${projectRoot}`);
|
|
4686
5588
|
process.exit(1);
|
|
4687
5589
|
}
|
|
4688
|
-
import_fs8.default.mkdirSync(
|
|
4689
|
-
import_fs8.default.mkdirSync(
|
|
5590
|
+
import_fs8.default.mkdirSync(import_path9.default.join(projectRoot, "\u6D41\u7A0B", "flows"), { recursive: true });
|
|
5591
|
+
import_fs8.default.mkdirSync(import_path9.default.join(projectRoot, "\u6D41\u7A0B", "\u89C4\u5212"), { recursive: true });
|
|
4690
5592
|
import_fs8.default.writeFileSync(
|
|
4691
|
-
|
|
4692
|
-
`# ${
|
|
5593
|
+
import_path9.default.join(projectRoot, "README.md"),
|
|
5594
|
+
`# ${folder}
|
|
4693
5595
|
|
|
4694
|
-
\
|
|
5596
|
+
\u4E1A\u52A1\u9879\u76EE\uFF08\u672C\u4F53 / \u6D41\u7A0B / \u5E94\u7528\uFF09\u3002\u6D41\u7A0B\u4F4D\u4E8E \`\u6D41\u7A0B/flows/\`\u3002
|
|
4695
5597
|
|
|
4696
|
-
\u8BE6\u89C1 \`\
|
|
5598
|
+
\u8BE6\u89C1 \`\u6D41\u7A0B/README.md\` \u4E0E \`\u8D44\u6E90/docs/flow/\`\u3002
|
|
4697
5599
|
`,
|
|
4698
5600
|
"utf8"
|
|
4699
5601
|
);
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
5602
|
+
const flowRoot = import_path9.default.join(projectRoot, "\u6D41\u7A0B");
|
|
5603
|
+
import_fs8.default.mkdirSync(import_path9.default.join(flowRoot, "flows"), { recursive: true });
|
|
5604
|
+
(0, import_flowScaffoldDocs.writeScaffoldIfAllowed)(
|
|
5605
|
+
import_path9.default.join(flowRoot, "README.md"),
|
|
5606
|
+
(0, import_flowScaffoldDocs.buildFlowRootReadmeMarkdown)({ projectFolder: folder }),
|
|
4703
5607
|
import_fs8.default
|
|
4704
5608
|
);
|
|
4705
|
-
writeScaffoldIfAllowed(
|
|
4706
|
-
|
|
4707
|
-
buildFlowsDirReadmeMarkdown({ projectFolder: folder }),
|
|
5609
|
+
(0, import_flowScaffoldDocs.writeScaffoldIfAllowed)(
|
|
5610
|
+
import_path9.default.join(flowRoot, "flows", "README.md"),
|
|
5611
|
+
(0, import_flowScaffoldDocs.buildFlowsDirReadmeMarkdown)({ projectFolder: folder }),
|
|
4708
5612
|
import_fs8.default
|
|
4709
5613
|
);
|
|
5614
|
+
(0, import_flowScaffoldDocs.removeLegacyFlowRootQuickStart)(flowRoot, import_fs8.default);
|
|
4710
5615
|
console.log(`\u2705 \u6D41\u7A0B\u9879\u76EE\u5DF2\u521D\u59CB\u5316: ${projectRoot}`);
|
|
4711
5616
|
ok({ projectRoot, folder });
|
|
4712
5617
|
} catch (err) {
|
|
4713
5618
|
handleError(err);
|
|
4714
5619
|
}
|
|
4715
5620
|
});
|
|
4716
|
-
cmd.command("pull").description("\u4ECE\u5E73\u53F0\u62C9\u53D6\u6D41\u7A0B\u5FEB\u7167\u5E76\u62C6\u5206\u4E3A\u672C\u5730\u6587\u4EF6\uFF08flow.json + \u8282\u70B9/<\u540D>/code.*\uFF09").requiredOption("--flow <flowId>", "Flow ID").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\
|
|
5621
|
+
cmd.command("pull").description("\u4ECE\u5E73\u53F0\u62C9\u53D6\u6D41\u7A0B\u5FEB\u7167\u5E76\u62C6\u5206\u4E3A\u672C\u5730\u6587\u4EF6\uFF08flow.json + \u8282\u70B9/<\u540D>/code.*\uFF09").requiredOption("--flow <flowId>", "Flow ID").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\u987B\u542B flow.json\uFF1B\u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84\uFF09").option("--json", "\u8F93\u51FA JSON").action(async (opts) => {
|
|
4717
5622
|
try {
|
|
4718
|
-
const flowDir = resolveFlowDir(opts.dir);
|
|
5623
|
+
const flowDir = (0, import_flowDirResolve.resolveFlowDir)(opts.dir, { json: opts.json });
|
|
4719
5624
|
import_fs8.default.mkdirSync(flowDir, { recursive: true });
|
|
4720
5625
|
const localCount = readLocalCanvasNodeCount(flowDir);
|
|
4721
|
-
const preAudit = localCount > 0 ? auditFlowWorkspace(flowDir) : null;
|
|
5626
|
+
const preAudit = localCount > 0 ? (0, import_flowWorkspaceAudit.auditFlowWorkspace)(flowDir) : null;
|
|
4722
5627
|
if (preAudit && !preAudit.ok) {
|
|
4723
5628
|
console.warn("\u26A0\uFE0F flow.json \u4E0E flow.meta.json \u4E0D\u4E00\u81F4\uFF1Bpull \u5C06\u7528\u5E73\u53F0\u5FEB\u7167\u8986\u76D6 flow.json\u3002\u624B\u6539\u753B\u5E03\u672A push \u65F6\u53EF\u80FD\u4E22\u5931\uFF0C\u53EF\u5148 repair-meta \u6216 push --canvas\u3002");
|
|
4724
5629
|
}
|
|
@@ -4743,7 +5648,7 @@ function makeProjectCommand() {
|
|
|
4743
5648
|
const codeNodes = Object.values(nodeMetas).filter((m) => m.codeFile).length;
|
|
4744
5649
|
writeFlowPullScaffold(flowDir, {
|
|
4745
5650
|
flowId: opts.flow,
|
|
4746
|
-
flowName: String(flowMeta.name ??
|
|
5651
|
+
flowName: String(flowMeta.name ?? import_path9.default.basename(flowDir)),
|
|
4747
5652
|
nodeCount: strippedDoc.nodes.length,
|
|
4748
5653
|
codeNodeCount: codeNodes
|
|
4749
5654
|
});
|
|
@@ -4762,9 +5667,9 @@ function makeProjectCommand() {
|
|
|
4762
5667
|
handleError(err);
|
|
4763
5668
|
}
|
|
4764
5669
|
});
|
|
4765
|
-
cmd.command("push").description("\u63D0\u4EA4\u672C\u5730\u6539\u52A8\u5230\u5E73\u53F0\uFF08\u9ED8\u8BA4\u4EC5\u589E\u91CF\u63A8\u9001\u5DF2\u6539\u4EE3\u7801\u8282\u70B9\uFF09").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\
|
|
5670
|
+
cmd.command("push").description("\u63D0\u4EA4\u672C\u5730\u6539\u52A8\u5230\u5E73\u53F0\uFF08\u9ED8\u8BA4\u4EC5\u589E\u91CF\u63A8\u9001\u5DF2\u6539\u4EE3\u7801\u8282\u70B9\uFF09").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\u987B\u542B flow.json\uFF1B\u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84\uFF09").option("--canvas", "\u540C\u65F6\u5168\u91CF\u63A8\u9001\u753B\u5E03\uFF08flow.json\uFF0CPUT /flows/{id} \u6574\u56FE replace\uFF09").option("--force", "\u5FFD\u7565\u8FDC\u7AEF\u7248\u672C\u51B2\u7A81\uFF08\u8986\u76D6\uFF09").option("--dry-run", "\u4EC5\u663E\u793A\u5C06\u63A8\u9001\u7684\u5185\u5BB9").option("--json", "\u8F93\u51FA JSON").action(async (opts) => {
|
|
4766
5671
|
try {
|
|
4767
|
-
const flowDir = resolveFlowDir(opts.dir);
|
|
5672
|
+
const flowDir = (0, import_flowDirResolve.resolveFlowDir)(opts.dir, { json: opts.json });
|
|
4768
5673
|
const meta = readMeta(flowDir);
|
|
4769
5674
|
if (!meta?.flowId) {
|
|
4770
5675
|
console.error("\u9519\u8BEF: \u7F3A\u5C11 flow.meta.json \u6216\u672A\u5173\u8054 flowId\uFF0C\u8BF7\u5148 project pull");
|
|
@@ -4812,9 +5717,9 @@ function makeProjectCommand() {
|
|
|
4812
5717
|
handleError(err);
|
|
4813
5718
|
}
|
|
4814
5719
|
});
|
|
4815
|
-
cmd.command("status").description("\u663E\u793A\u672C\u5730\u76F8\u5BF9\u4E0A\u6B21\u62C9\u53D6\u7684\u6539\u52A8\uFF08\u4EE3\u7801\u8282\u70B9\uFF09").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\
|
|
5720
|
+
cmd.command("status").description("\u663E\u793A\u672C\u5730\u76F8\u5BF9\u4E0A\u6B21\u62C9\u53D6\u7684\u6539\u52A8\uFF08\u4EE3\u7801\u8282\u70B9\uFF09").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\u987B\u542B flow.json\uFF1B\u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84\uFF09").option("--json", "\u8F93\u51FA JSON").action((opts) => {
|
|
4816
5721
|
try {
|
|
4817
|
-
const flowDir = resolveFlowDir(opts.dir);
|
|
5722
|
+
const flowDir = (0, import_flowDirResolve.resolveFlowDir)(opts.dir, { json: opts.json });
|
|
4818
5723
|
const meta = readMeta(flowDir);
|
|
4819
5724
|
if (!meta) {
|
|
4820
5725
|
console.error("\u9519\u8BEF: \u7F3A\u5C11 flow.meta.json\uFF0C\u8BF7\u5148 project pull");
|
|
@@ -4839,10 +5744,10 @@ function makeProjectCommand() {
|
|
|
4839
5744
|
handleError(err);
|
|
4840
5745
|
}
|
|
4841
5746
|
});
|
|
4842
|
-
cmd.command("doctor").description("\u68C0\u67E5 flow.json / flow.meta.json / \u8282\u70B9/ \u4E00\u81F4\u6027").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\
|
|
5747
|
+
cmd.command("doctor").description("\u68C0\u67E5 flow.json / flow.meta.json / \u8282\u70B9/ \u4E00\u81F4\u6027").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\u987B\u542B flow.json\uFF1B\u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84\uFF09").option("--json", "\u8F93\u51FA JSON").action((opts) => {
|
|
4843
5748
|
try {
|
|
4844
|
-
const flowDir = resolveFlowDir(opts.dir);
|
|
4845
|
-
const audit = auditFlowWorkspace(flowDir);
|
|
5749
|
+
const flowDir = (0, import_flowDirResolve.resolveFlowDir)(opts.dir, { json: opts.json });
|
|
5750
|
+
const audit = (0, import_flowWorkspaceAudit.auditFlowWorkspace)(flowDir);
|
|
4846
5751
|
if (!opts.json) {
|
|
4847
5752
|
console.log(`\u6D41\u7A0B\u76EE\u5F55: ${flowDir}`);
|
|
4848
5753
|
console.log(audit.ok ? "\u2705 \u672C\u5730\u6587\u4EF6\u4E00\u81F4" : "\u26A0\uFE0F \u5B58\u5728\u4E0D\u4E00\u81F4\u9879");
|
|
@@ -4857,16 +5762,16 @@ function makeProjectCommand() {
|
|
|
4857
5762
|
handleError(err);
|
|
4858
5763
|
}
|
|
4859
5764
|
});
|
|
4860
|
-
cmd.command("repair-meta").description("\u6839\u636E flow.json \u4E0E \u8282\u70B9/ \u76EE\u5F55\u4FEE\u590D flow.meta.json\uFF08\u53CA node.info.json\uFF09").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\
|
|
5765
|
+
cmd.command("repair-meta").description("\u6839\u636E flow.json \u4E0E \u8282\u70B9/ \u76EE\u5F55\u4FEE\u590D flow.meta.json\uFF08\u53CA node.info.json\uFF09").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\u987B\u542B flow.json\uFF1B\u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84\uFF09").option("--json", "\u8F93\u51FA JSON").action((opts) => {
|
|
4861
5766
|
try {
|
|
4862
|
-
const flowDir = resolveFlowDir(opts.dir);
|
|
4863
|
-
const result = repairFlowMeta(flowDir);
|
|
5767
|
+
const flowDir = (0, import_flowDirResolve.resolveFlowDir)(opts.dir, { json: opts.json });
|
|
5768
|
+
const result = (0, import_flowWorkspaceAudit.repairFlowMeta)(flowDir);
|
|
4864
5769
|
const meta = readMeta(flowDir);
|
|
4865
5770
|
if (meta?.flowId) {
|
|
4866
|
-
const audit = auditFlowWorkspace(flowDir);
|
|
5771
|
+
const audit = (0, import_flowWorkspaceAudit.auditFlowWorkspace)(flowDir);
|
|
4867
5772
|
writeFlowPullScaffold(flowDir, {
|
|
4868
5773
|
flowId: String(meta.flowId),
|
|
4869
|
-
flowName: meta.flowName ||
|
|
5774
|
+
flowName: meta.flowName || import_path9.default.basename(flowDir),
|
|
4870
5775
|
nodeCount: audit.canvasNodeCount,
|
|
4871
5776
|
codeNodeCount: audit.canvasCodeNodeCount,
|
|
4872
5777
|
pulledAt: meta.lastPulledAt,
|
|
@@ -4883,7 +5788,7 @@ function makeProjectCommand() {
|
|
|
4883
5788
|
}
|
|
4884
5789
|
for (const p of result.wroteNodeInfo) console.log(` + node.info.json \u2192 ${p}`);
|
|
4885
5790
|
for (const w of result.warnings) console.log(` \u26A0 ${w}`);
|
|
4886
|
-
const audit = auditFlowWorkspace(flowDir);
|
|
5791
|
+
const audit = (0, import_flowWorkspaceAudit.auditFlowWorkspace)(flowDir);
|
|
4887
5792
|
console.log(audit.ok ? "\u2705 doctor \u68C0\u67E5\u901A\u8FC7" : "\u26A0\uFE0F \u4ECD\u6709\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u67E5\u770B doctor \u8F93\u51FA");
|
|
4888
5793
|
}
|
|
4889
5794
|
ok(result);
|
|
@@ -4895,8 +5800,9 @@ function makeProjectCommand() {
|
|
|
4895
5800
|
}
|
|
4896
5801
|
|
|
4897
5802
|
// cli/dazi-flow/src/commands/node.ts
|
|
4898
|
-
var
|
|
5803
|
+
var import_path10 = __toESM(require("path"), 1);
|
|
4899
5804
|
var import_fs9 = __toESM(require("fs"), 1);
|
|
5805
|
+
var import_flowDirResolve2 = __toESM(require_flowDirResolve(), 1);
|
|
4900
5806
|
var NODE_TYPE_REQUIRED = {
|
|
4901
5807
|
"database-source": ["connectionId", "sql"],
|
|
4902
5808
|
"database-sink": ["connectionId", "tableName"],
|
|
@@ -4927,9 +5833,6 @@ var NODE_TYPE_LABELS = {
|
|
|
4927
5833
|
"folder-resource-import": "\u6587\u4EF6\u5939\u8D44\u6E90\u5BFC\u5165",
|
|
4928
5834
|
"folder-resource-register": "\u8D44\u6E90\u6CE8\u518C"
|
|
4929
5835
|
};
|
|
4930
|
-
function resolveFlowDir2(dir) {
|
|
4931
|
-
return import_path11.default.resolve(dir ?? process.cwd());
|
|
4932
|
-
}
|
|
4933
5836
|
function requireMeta(flowDir) {
|
|
4934
5837
|
const meta = readMeta(flowDir);
|
|
4935
5838
|
if (!meta?.flowId) {
|
|
@@ -4963,9 +5866,9 @@ function makeNodeCommand() {
|
|
|
4963
5866
|
}
|
|
4964
5867
|
ok({ types });
|
|
4965
5868
|
});
|
|
4966
|
-
cmd.command("pull").description("\u62C9\u53D6\u5355\u4E2A\u4EE3\u7801\u8282\u70B9\uFF08\u8986\u76D6\u672C\u5730 code.*\uFF09").requiredOption("--node <uuid>", "\u8282\u70B9 node_uuid").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\
|
|
5869
|
+
cmd.command("pull").description("\u62C9\u53D6\u5355\u4E2A\u4EE3\u7801\u8282\u70B9\uFF08\u8986\u76D6\u672C\u5730 code.*\uFF09").requiredOption("--node <uuid>", "\u8282\u70B9 node_uuid").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\u987B\u542B flow.json\uFF1B\u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84\uFF09").option("--json", "\u8F93\u51FA JSON").action(async (opts) => {
|
|
4967
5870
|
try {
|
|
4968
|
-
const flowDir =
|
|
5871
|
+
const flowDir = (0, import_flowDirResolve2.resolveFlowDir)(opts.dir, { json: opts.json });
|
|
4969
5872
|
const { meta, flowId } = requireMeta(flowDir);
|
|
4970
5873
|
const r = await pullCodeNode(flowId, flowDir, meta, opts.node);
|
|
4971
5874
|
writeMeta(flowDir, meta);
|
|
@@ -4975,9 +5878,9 @@ function makeNodeCommand() {
|
|
|
4975
5878
|
handleError(err);
|
|
4976
5879
|
}
|
|
4977
5880
|
});
|
|
4978
|
-
cmd.command("push").description("\u63D0\u4EA4\u5355\u4E2A\u4EE3\u7801\u8282\u70B9\uFF08\u4E50\u89C2\u9501\uFF1B\u8FDC\u7AEF\u51B2\u7A81\u9700 --force\uFF09").requiredOption("--node <uuid>", "\u8282\u70B9 node_uuid").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\
|
|
5881
|
+
cmd.command("push").description("\u63D0\u4EA4\u5355\u4E2A\u4EE3\u7801\u8282\u70B9\uFF08\u4E50\u89C2\u9501\uFF1B\u8FDC\u7AEF\u51B2\u7A81\u9700 --force\uFF09").requiredOption("--node <uuid>", "\u8282\u70B9 node_uuid").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\u987B\u542B flow.json\uFF1B\u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84\uFF09").option("--force", "\u5FFD\u7565\u8FDC\u7AEF\u7248\u672C\u51B2\u7A81\uFF08\u8986\u76D6\uFF09").option("--dry-run", "\u4EC5\u68C0\u6D4B\uFF0C\u4E0D\u63D0\u4EA4").option("--json", "\u8F93\u51FA JSON").action(async (opts) => {
|
|
4979
5882
|
try {
|
|
4980
|
-
const flowDir =
|
|
5883
|
+
const flowDir = (0, import_flowDirResolve2.resolveFlowDir)(opts.dir, { json: opts.json });
|
|
4981
5884
|
const { meta, flowId } = requireMeta(flowDir);
|
|
4982
5885
|
const r = await pushCodeNode(flowId, flowDir, meta, opts.node, opts);
|
|
4983
5886
|
writeMeta(flowDir, meta);
|
|
@@ -4991,9 +5894,9 @@ function makeNodeCommand() {
|
|
|
4991
5894
|
handleError(err);
|
|
4992
5895
|
}
|
|
4993
5896
|
});
|
|
4994
|
-
cmd.command("new").description("\u65B0\u5EFA\u8282\u70B9\uFF08POST \u5E73\u53F0\uFF0C\u5E76\u5199\u5165\u672C\u5730 flow.json \u4E0E\u4EE3\u7801\u6A21\u677F\uFF09").requiredOption("--type <nodeType>", "\u8282\u70B9\u7C7B\u578B\uFF08\u89C1 node types\uFF09").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\
|
|
5897
|
+
cmd.command("new").description("\u65B0\u5EFA\u8282\u70B9\uFF08POST \u5E73\u53F0\uFF0C\u5E76\u5199\u5165\u672C\u5730 flow.json \u4E0E\u4EE3\u7801\u6A21\u677F\uFF09").requiredOption("--type <nodeType>", "\u8282\u70B9\u7C7B\u578B\uFF08\u89C1 node types\uFF09").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\u987B\u542B flow.json\uFF1B\u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84\uFF09").option("--label <label>", "\u8282\u70B9\u663E\u793A\u540D").option("--id <nodeId>", "\u8BED\u4E49 id\uFF08\u7F3A\u7701\u7531\u5E73\u53F0\u751F\u6210\uFF09").option("--json", "\u8F93\u51FA JSON").action(async (opts) => {
|
|
4995
5898
|
try {
|
|
4996
|
-
const flowDir =
|
|
5899
|
+
const flowDir = (0, import_flowDirResolve2.resolveFlowDir)(opts.dir, { json: opts.json });
|
|
4997
5900
|
const { meta, flowId } = requireMeta(flowDir);
|
|
4998
5901
|
const created = await apiRequest(`${FLOW_API}/${flowId}/nodes`, {
|
|
4999
5902
|
method: "POST",
|
|
@@ -5014,19 +5917,19 @@ function makeNodeCommand() {
|
|
|
5014
5917
|
data: created.data ?? {}
|
|
5015
5918
|
};
|
|
5016
5919
|
doc.nodes.push(stripped);
|
|
5017
|
-
import_fs9.default.writeFileSync(
|
|
5920
|
+
import_fs9.default.writeFileSync(import_path10.default.join(flowDir, FLOW_JSON), JSON.stringify(doc, null, 2), "utf8");
|
|
5018
5921
|
const nodeMeta = { nodeId: String(created.id ?? ""), nodeType: opts.type };
|
|
5019
5922
|
const codeKey = NODE_TYPE_CODE_DATA_KEY[opts.type];
|
|
5020
5923
|
if (codeKey) {
|
|
5021
5924
|
const language = codeLanguageForNodeType(opts.type);
|
|
5022
5925
|
const ext = codeFileExt(language);
|
|
5023
5926
|
const dirName = sanitizeName(opts.label || String(created.id ?? "") || opts.type);
|
|
5024
|
-
const nodeDirAbs =
|
|
5927
|
+
const nodeDirAbs = import_path10.default.join(flowDir, NODES_DIR, dirName);
|
|
5025
5928
|
import_fs9.default.mkdirSync(nodeDirAbs, { recursive: true });
|
|
5026
5929
|
const codeFile = `code.${ext}`;
|
|
5027
5930
|
const template = CODE_TEMPLATES[language ?? ""] ?? "";
|
|
5028
|
-
import_fs9.default.writeFileSync(
|
|
5029
|
-
nodeMeta.dir =
|
|
5931
|
+
import_fs9.default.writeFileSync(import_path10.default.join(nodeDirAbs, codeFile), template, "utf8");
|
|
5932
|
+
nodeMeta.dir = import_path10.default.posix.join(NODES_DIR, dirName);
|
|
5030
5933
|
nodeMeta.codeFile = codeFile;
|
|
5031
5934
|
nodeMeta.codeLanguage = language;
|
|
5032
5935
|
nodeMeta.codeHash = sha1(template);
|
|
@@ -5046,11 +5949,12 @@ function makeNodeCommand() {
|
|
|
5046
5949
|
}
|
|
5047
5950
|
|
|
5048
5951
|
// cli/dazi-flow/src/commands/run.ts
|
|
5049
|
-
var
|
|
5952
|
+
var import_path12 = __toESM(require("path"), 1);
|
|
5953
|
+
var import_flowDirResolve3 = __toESM(require_flowDirResolve(), 1);
|
|
5050
5954
|
|
|
5051
5955
|
// cli/dazi-flow/src/lib/flowRun.ts
|
|
5052
5956
|
var import_fs10 = __toESM(require("fs"), 1);
|
|
5053
|
-
var
|
|
5957
|
+
var import_path11 = __toESM(require("path"), 1);
|
|
5054
5958
|
function classifyError(text) {
|
|
5055
5959
|
const t = (text || "").toLowerCase();
|
|
5056
5960
|
if (/(变量|variable).*(不存在|未找到|missing|not found|undefined)|缺少.*输入|no.*input|上游/.test(t)) {
|
|
@@ -5080,7 +5984,7 @@ function classifyError(text) {
|
|
|
5080
5984
|
return { category: "\u672A\u77E5", hint: "\u8BF7\u67E5\u770B\u5B8C\u6574 traceback \u4E0E\u65E5\u5FD7\u3002" };
|
|
5081
5985
|
}
|
|
5082
5986
|
function runDir(flowDir) {
|
|
5083
|
-
const d =
|
|
5987
|
+
const d = import_path11.default.join(flowDir, RUN_DIR);
|
|
5084
5988
|
import_fs10.default.mkdirSync(d, { recursive: true });
|
|
5085
5989
|
return d;
|
|
5086
5990
|
}
|
|
@@ -5088,7 +5992,7 @@ function safeBase(name) {
|
|
|
5088
5992
|
return (name || "run").replace(/[<>:"/\\|?*\x00-\x1f]/g, "_").trim() || "run";
|
|
5089
5993
|
}
|
|
5090
5994
|
function writeLastRun(flowDir, base, payload) {
|
|
5091
|
-
const p =
|
|
5995
|
+
const p = import_path11.default.join(runDir(flowDir), `${safeBase(base)}.last-run.json`);
|
|
5092
5996
|
import_fs10.default.writeFileSync(p, JSON.stringify(payload, null, 2), "utf8");
|
|
5093
5997
|
return p;
|
|
5094
5998
|
}
|
|
@@ -5126,7 +6030,7 @@ function writeErrorMarkdown(flowDir, base, input) {
|
|
|
5126
6030
|
if (input.failureBundle != null) {
|
|
5127
6031
|
lines.push("## FailureBundle", "", "```json", JSON.stringify(input.failureBundle, null, 2), "```", "");
|
|
5128
6032
|
}
|
|
5129
|
-
const p =
|
|
6033
|
+
const p = import_path11.default.join(runDir(flowDir), `${safeBase(base)}.last-error.md`);
|
|
5130
6034
|
import_fs10.default.writeFileSync(p, lines.join("\n"), "utf8");
|
|
5131
6035
|
return p;
|
|
5132
6036
|
}
|
|
@@ -5260,16 +6164,13 @@ function writeRunProgressMarkdown(flowDir, base, snap, runId) {
|
|
|
5260
6164
|
}
|
|
5261
6165
|
}
|
|
5262
6166
|
}
|
|
5263
|
-
const p =
|
|
6167
|
+
const p = import_path11.default.join(runDir(flowDir), `${safeBase(base)}.last-run.md`);
|
|
5264
6168
|
import_fs10.default.writeFileSync(p, lines.join("\n"), "utf8");
|
|
5265
6169
|
return p;
|
|
5266
6170
|
}
|
|
5267
6171
|
|
|
5268
6172
|
// cli/dazi-flow/src/commands/run.ts
|
|
5269
6173
|
var FLOW_API2 = "/api/data-pipelines/v1/flows";
|
|
5270
|
-
function resolveFlowDir3(dir) {
|
|
5271
|
-
return import_path13.default.resolve(dir ?? process.cwd());
|
|
5272
|
-
}
|
|
5273
6174
|
function sleep(ms) {
|
|
5274
6175
|
return new Promise((r) => setTimeout(r, ms));
|
|
5275
6176
|
}
|
|
@@ -5428,9 +6329,9 @@ function makeRunCommand() {
|
|
|
5428
6329
|
handleError(err);
|
|
5429
6330
|
}
|
|
5430
6331
|
});
|
|
5431
|
-
cmd.command("node-exec").description("\u6D4B\u8BD5\u8FD0\u884C\u5355\u4E2A\u8282\u70B9\uFF08\u6309 node_uuid\uFF0C\u7ED3\u679C\u843D\u76D8 _run/\uFF09").requiredOption("--node <uuid>", "\u8282\u70B9 node_uuid").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\
|
|
6332
|
+
cmd.command("node-exec").description("\u6D4B\u8BD5\u8FD0\u884C\u5355\u4E2A\u8282\u70B9\uFF08\u6309 node_uuid\uFF0C\u7ED3\u679C\u843D\u76D8 _run/\uFF09").requiredOption("--node <uuid>", "\u8282\u70B9 node_uuid").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\u987B\u542B flow.json\uFF1B\u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84\uFF09").option("--json", "\u8F93\u51FA JSON").action(async (opts) => {
|
|
5432
6333
|
try {
|
|
5433
|
-
const flowDir =
|
|
6334
|
+
const flowDir = (0, import_flowDirResolve3.resolveFlowDir)(opts.dir, { json: opts.json });
|
|
5434
6335
|
const meta = readMeta(flowDir);
|
|
5435
6336
|
if (!meta?.flowId) {
|
|
5436
6337
|
console.error("\u9519\u8BEF: \u7F3A\u5C11 flow.meta.json\uFF0C\u8BF7\u5148 project pull");
|
|
@@ -5443,7 +6344,7 @@ function makeRunCommand() {
|
|
|
5443
6344
|
console.error(`\u9519\u8BEF: \u672A\u627E\u5230\u8282\u70B9 ${opts.node} \u7684\u8BED\u4E49 id\uFF08meta.nodeId\uFF09`);
|
|
5444
6345
|
process.exit(1);
|
|
5445
6346
|
}
|
|
5446
|
-
const base = nodeMeta?.dir ?
|
|
6347
|
+
const base = nodeMeta?.dir ? import_path12.default.basename(nodeMeta.dir) : nodeId;
|
|
5447
6348
|
await apiRequest(`${FLOW_API2}/${flowId}/debug-run`);
|
|
5448
6349
|
const result = await apiRequest(
|
|
5449
6350
|
`${FLOW_API2}/${flowId}/nodes/${encodeURIComponent(nodeId)}/run`,
|
|
@@ -5483,9 +6384,9 @@ function makeRunCommand() {
|
|
|
5483
6384
|
handleError(err);
|
|
5484
6385
|
}
|
|
5485
6386
|
});
|
|
5486
|
-
cmd.command("flow-exec").description("\u8FD0\u884C\u6574\u6D41\u7A0B\u5E76\u7B49\u5F85\u7ED3\u679C\uFF08\u5931\u8D25\u65F6\u843D\u76D8 _run/flow.last-error.md\uFF09").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\
|
|
6387
|
+
cmd.command("flow-exec").description("\u8FD0\u884C\u6574\u6D41\u7A0B\u5E76\u7B49\u5F85\u7ED3\u679C\uFF08\u5931\u8D25\u65F6\u843D\u76D8 _run/flow.last-error.md\uFF09").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\u987B\u542B flow.json\uFF1B\u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84\uFF09").option("--flow <flowId>", "Flow ID\uFF08\u7F3A\u7701\u8BFB meta\uFF09").option("--type <type>", "debug | preview", "debug").option("--timeout <sec>", "\u7B49\u5F85\u8D85\u65F6\u79D2\u6570", "120").option("--json", "\u8F93\u51FA JSON").option("--designer-progress", "\u8F93\u51FA NDJSON \u8FDB\u5EA6\u4E8B\u4EF6\uFF08\u4F9B VS Code \u8BBE\u8BA1\u5668\u89E3\u6790\uFF09").action(async (opts) => {
|
|
5487
6388
|
try {
|
|
5488
|
-
const flowDir =
|
|
6389
|
+
const flowDir = (0, import_flowDirResolve3.resolveFlowDir)(opts.dir, { json: opts.json });
|
|
5489
6390
|
const meta = readMeta(flowDir);
|
|
5490
6391
|
const flowId = opts.flow ?? (meta?.flowId != null ? String(meta.flowId) : "");
|
|
5491
6392
|
if (!flowId) {
|
|
@@ -5589,9 +6490,9 @@ function makeRunCommand() {
|
|
|
5589
6490
|
handleError(err);
|
|
5590
6491
|
}
|
|
5591
6492
|
});
|
|
5592
|
-
cmd.command("failure").description("\u62C9\u53D6\u67D0\u6B21 Run \u7684 failure-bundle \u5E76\u843D\u76D8 _run/flow.last-error.md").requiredOption("--run <runId>", "Run ID").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\
|
|
6493
|
+
cmd.command("failure").description("\u62C9\u53D6\u67D0\u6B21 Run \u7684 failure-bundle \u5E76\u843D\u76D8 _run/flow.last-error.md").requiredOption("--run <runId>", "Run ID").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\u987B\u542B flow.json\uFF1B\u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84\uFF09").option("--json", "\u8F93\u51FA JSON").action(async (opts) => {
|
|
5593
6494
|
try {
|
|
5594
|
-
const flowDir =
|
|
6495
|
+
const flowDir = (0, import_flowDirResolve3.resolveFlowDir)(opts.dir, { json: opts.json });
|
|
5595
6496
|
const bundle = await apiRequest(`${FLOW_API2}/runs/${opts.run}/failure-bundle`);
|
|
5596
6497
|
const errorFile = writeErrorMarkdown(flowDir, "flow", {
|
|
5597
6498
|
title: `\u5931\u8D25\u5206\u6790\uFF08Run ${opts.run}\uFF09`,
|
|
@@ -5608,7 +6509,7 @@ function makeRunCommand() {
|
|
|
5608
6509
|
}
|
|
5609
6510
|
|
|
5610
6511
|
// cli/dazi-flow/src/commands/source.ts
|
|
5611
|
-
var
|
|
6512
|
+
var import_path13 = __toESM(require("path"), 1);
|
|
5612
6513
|
var import_fs11 = __toESM(require("fs"), 1);
|
|
5613
6514
|
function makeSourceCommand() {
|
|
5614
6515
|
const cmd = new Command("source").description("\u6570\u636E\u6E90\u7BA1\u7406");
|
|
@@ -5683,9 +6584,9 @@ function makeSourceCommand() {
|
|
|
5683
6584
|
`/api/connections/${sourceId}/tables${qs}`
|
|
5684
6585
|
);
|
|
5685
6586
|
const ws = resolveWorkspace();
|
|
5686
|
-
const dataDir =
|
|
6587
|
+
const dataDir = import_path13.default.join(ws.flows, opts.flow, "data");
|
|
5687
6588
|
if (!import_fs11.default.existsSync(dataDir)) import_fs11.default.mkdirSync(dataDir, { recursive: true });
|
|
5688
|
-
const outFile =
|
|
6589
|
+
const outFile = import_path13.default.join(dataDir, `${tableName}.schema.json`);
|
|
5689
6590
|
import_fs11.default.writeFileSync(outFile, JSON.stringify({
|
|
5690
6591
|
sourceId,
|
|
5691
6592
|
tableName,
|
|
@@ -5760,7 +6661,7 @@ function makeDataspaceCommand() {
|
|
|
5760
6661
|
}
|
|
5761
6662
|
|
|
5762
6663
|
// cli/dazi-flow/src/commands/plan.ts
|
|
5763
|
-
var
|
|
6664
|
+
var import_path14 = __toESM(require("path"), 1);
|
|
5764
6665
|
var import_fs12 = __toESM(require("fs"), 1);
|
|
5765
6666
|
function makePlanCommand() {
|
|
5766
6667
|
const cmd = new Command("plan").description("Flow \u6267\u884C\u8BA1\u5212");
|
|
@@ -5772,8 +6673,8 @@ function makePlanCommand() {
|
|
|
5772
6673
|
{ method: "POST", body: { input } }
|
|
5773
6674
|
);
|
|
5774
6675
|
const ws = resolveWorkspace();
|
|
5775
|
-
const outFile = opts.out ??
|
|
5776
|
-
const outDir =
|
|
6676
|
+
const outFile = opts.out ?? import_path14.default.join(ws.flows, flowId, "plans", "plan.json");
|
|
6677
|
+
const outDir = import_path14.default.dirname(outFile);
|
|
5777
6678
|
if (!import_fs12.default.existsSync(outDir)) import_fs12.default.mkdirSync(outDir, { recursive: true });
|
|
5778
6679
|
import_fs12.default.writeFileSync(outFile, JSON.stringify(plan, null, 2), "utf-8");
|
|
5779
6680
|
if (opts.json) {
|
|
@@ -5789,7 +6690,7 @@ function makePlanCommand() {
|
|
|
5789
6690
|
cmd.command("apply <flowId>").description("\u5C06\u672C\u5730\u8BA1\u5212\u6587\u4EF6\u63A8\u9001\u5230\u5E73\u53F0\u5E76\u5E94\u7528").option("--file <path>", "\u8BA1\u5212\u6587\u4EF6\uFF08\u9ED8\u8BA4 flows/<flowId>/plans/plan.json\uFF09").option("--dry-run", "\u4EC5\u9A8C\u8BC1\uFF0C\u4E0D\u5B9E\u9645\u5E94\u7528").action(async (flowId, opts) => {
|
|
5790
6691
|
try {
|
|
5791
6692
|
const ws = resolveWorkspace();
|
|
5792
|
-
const planFile = opts.file ??
|
|
6693
|
+
const planFile = opts.file ?? import_path14.default.join(ws.flows, flowId, "plans", "plan.json");
|
|
5793
6694
|
if (!import_fs12.default.existsSync(planFile)) {
|
|
5794
6695
|
console.error(`\u8BA1\u5212\u6587\u4EF6\u4E0D\u5B58\u5728: ${planFile}\uFF0C\u8BF7\u5148\u6267\u884C plan compile`);
|
|
5795
6696
|
process.exit(1);
|
|
@@ -5809,8 +6710,8 @@ function makePlanCommand() {
|
|
|
5809
6710
|
`/api/data-pipelines/v1/flows/${flowId}/snapshot`
|
|
5810
6711
|
);
|
|
5811
6712
|
const ws = resolveWorkspace();
|
|
5812
|
-
const outFile = opts.out ??
|
|
5813
|
-
const outDir =
|
|
6713
|
+
const outFile = opts.out ?? import_path14.default.join(ws.flows, flowId, "plans", `plan-${opts.type}.md`);
|
|
6714
|
+
const outDir = import_path14.default.dirname(outFile);
|
|
5814
6715
|
if (!import_fs12.default.existsSync(outDir)) import_fs12.default.mkdirSync(outDir, { recursive: true });
|
|
5815
6716
|
import_fs12.default.writeFileSync(outFile, doc.content, "utf-8");
|
|
5816
6717
|
console.log(`\u2705 Markdown \u6587\u6863\u5DF2\u4FDD\u5B58: ${outFile}`);
|
|
@@ -5825,8 +6726,8 @@ function makePlanCommand() {
|
|
|
5825
6726
|
`/api/data-pipelines/v1/dq-ai-code-prompt`
|
|
5826
6727
|
);
|
|
5827
6728
|
const ws = resolveWorkspace();
|
|
5828
|
-
const outFile = opts.out ??
|
|
5829
|
-
const outDir =
|
|
6729
|
+
const outFile = opts.out ?? import_path14.default.join(ws.flows, flowId, "plans", "llm-guide.md");
|
|
6730
|
+
const outDir = import_path14.default.dirname(outFile);
|
|
5830
6731
|
if (!import_fs12.default.existsSync(outDir)) import_fs12.default.mkdirSync(outDir, { recursive: true });
|
|
5831
6732
|
import_fs12.default.writeFileSync(outFile, guide.content, "utf-8");
|
|
5832
6733
|
console.log(`\u2705 LLM \u5F15\u5BFC\u6587\u6863\u5DF2\u4FDD\u5B58: ${outFile}`);
|
|
@@ -5841,10 +6742,10 @@ function makePlanCommand() {
|
|
|
5841
6742
|
`/api/data-pipelines/v1/compile-plan`
|
|
5842
6743
|
);
|
|
5843
6744
|
const ws = resolveWorkspace();
|
|
5844
|
-
const outDir = opts.out ??
|
|
6745
|
+
const outDir = opts.out ?? import_path14.default.join(ws.flows, flowId, "plans", "db");
|
|
5845
6746
|
if (!import_fs12.default.existsSync(outDir)) import_fs12.default.mkdirSync(outDir, { recursive: true });
|
|
5846
6747
|
for (const f of scaffold.files ?? []) {
|
|
5847
|
-
const outFile =
|
|
6748
|
+
const outFile = import_path14.default.join(outDir, f.name);
|
|
5848
6749
|
import_fs12.default.writeFileSync(outFile, f.content, "utf-8");
|
|
5849
6750
|
console.log(` \u2192 ${outFile}`);
|
|
5850
6751
|
}
|
|
@@ -5858,7 +6759,7 @@ function makePlanCommand() {
|
|
|
5858
6759
|
}
|
|
5859
6760
|
|
|
5860
6761
|
// cli/dazi-flow/src/commands/file.ts
|
|
5861
|
-
var
|
|
6762
|
+
var import_path15 = __toESM(require("path"), 1);
|
|
5862
6763
|
var import_fs13 = __toESM(require("fs"), 1);
|
|
5863
6764
|
function makeFileCommand() {
|
|
5864
6765
|
const cmd = new Command("file").description("\u5E73\u53F0\u6258\u7BA1\u6587\u4EF6\u7BA1\u7406");
|
|
@@ -5904,13 +6805,13 @@ function makeFileCommand() {
|
|
|
5904
6805
|
});
|
|
5905
6806
|
cmd.command("upload <localFile>").description("\u4E0A\u4F20\u672C\u5730\u6587\u4EF6\u5230\u5E73\u53F0").option("--space <spaceId>", "\u7A7A\u95F4 ID").option("--remote-path <path>", "\u8FDC\u7AEF\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u4E0E\u6587\u4EF6\u540D\u76F8\u540C\uFF09").option("--overwrite", "\u8986\u76D6\u5DF2\u5B58\u5728\u6587\u4EF6").action(async (localFile, opts) => {
|
|
5906
6807
|
try {
|
|
5907
|
-
const filePath =
|
|
6808
|
+
const filePath = import_path15.default.resolve(localFile);
|
|
5908
6809
|
if (!import_fs13.default.existsSync(filePath)) {
|
|
5909
6810
|
console.error(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`);
|
|
5910
6811
|
process.exit(1);
|
|
5911
6812
|
}
|
|
5912
6813
|
const content = import_fs13.default.readFileSync(filePath);
|
|
5913
|
-
const remotePath = opts.remotePath ??
|
|
6814
|
+
const remotePath = opts.remotePath ?? import_path15.default.basename(filePath);
|
|
5914
6815
|
const endpoint = opts.space ? `/api/v1/spaces/${opts.space}/files/upload` : "/api/v1/files/upload";
|
|
5915
6816
|
const result = await apiRequest(endpoint, {
|
|
5916
6817
|
method: "POST",
|
|
@@ -5936,14 +6837,14 @@ function makeFileCommand() {
|
|
|
5936
6837
|
const content = data.encoding === "base64" ? Buffer.from(data.content, "base64") : Buffer.from(data.content, "utf-8");
|
|
5937
6838
|
let outFile;
|
|
5938
6839
|
if (opts.out) {
|
|
5939
|
-
outFile =
|
|
6840
|
+
outFile = import_path15.default.resolve(opts.out);
|
|
5940
6841
|
} else if (opts.flow) {
|
|
5941
6842
|
const ws = resolveWorkspace();
|
|
5942
|
-
const dataDir =
|
|
6843
|
+
const dataDir = import_path15.default.join(ws.flows, opts.flow, "data");
|
|
5943
6844
|
if (!import_fs13.default.existsSync(dataDir)) import_fs13.default.mkdirSync(dataDir, { recursive: true });
|
|
5944
|
-
outFile =
|
|
6845
|
+
outFile = import_path15.default.join(dataDir, import_path15.default.basename(remotePath));
|
|
5945
6846
|
} else {
|
|
5946
|
-
outFile =
|
|
6847
|
+
outFile = import_path15.default.join(process.cwd(), import_path15.default.basename(remotePath));
|
|
5947
6848
|
}
|
|
5948
6849
|
import_fs13.default.writeFileSync(outFile, content);
|
|
5949
6850
|
console.log(`\u2705 \u5DF2\u4E0B\u8F7D: ${outFile}`);
|
|
@@ -5956,18 +6857,18 @@ function makeFileCommand() {
|
|
|
5956
6857
|
}
|
|
5957
6858
|
|
|
5958
6859
|
// cli/dazi-flow/src/commands/data.ts
|
|
5959
|
-
var
|
|
6860
|
+
var import_path16 = __toESM(require("path"), 1);
|
|
5960
6861
|
var import_fs14 = __toESM(require("fs"), 1);
|
|
5961
6862
|
function makeDataCommand() {
|
|
5962
6863
|
const cmd = new Command("data").description("Flow \u6570\u636E\u4E0A\u4F20");
|
|
5963
6864
|
cmd.command("upload <localFile>").description("\u5C06\u672C\u5730\u6570\u636E\u6587\u4EF6\u4E0A\u4F20\u5230\u5E73\u53F0\uFF08CSV / JSON / Parquet\uFF09").option("--space <spaceId>", "\u76EE\u6807\u7A7A\u95F4 ID").option("--flow <flowId>", "\u5173\u8054 Flow ID\uFF08\u5199\u5165 flows/<flowId> \u5143\u6570\u636E\uFF09").option("--table <name>", "\u76EE\u6807\u8868\u540D\uFF08\u82E5\u5E73\u53F0\u652F\u6301\u76F4\u63A5\u5199\u8868\uFF09").option("--overwrite", "\u8986\u76D6\u5DF2\u6709\u6570\u636E").option("--json", "\u8F93\u51FA JSON").action(async (localFile, opts) => {
|
|
5964
6865
|
try {
|
|
5965
|
-
const filePath =
|
|
6866
|
+
const filePath = import_path16.default.resolve(localFile);
|
|
5966
6867
|
if (!import_fs14.default.existsSync(filePath)) {
|
|
5967
6868
|
console.error(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`);
|
|
5968
6869
|
process.exit(1);
|
|
5969
6870
|
}
|
|
5970
|
-
const ext =
|
|
6871
|
+
const ext = import_path16.default.extname(filePath).toLowerCase();
|
|
5971
6872
|
const supportedExts = [".csv", ".json", ".jsonl", ".parquet", ".tsv"];
|
|
5972
6873
|
if (!supportedExts.includes(ext)) {
|
|
5973
6874
|
console.error(`\u4E0D\u652F\u6301\u7684\u6587\u4EF6\u683C\u5F0F: ${ext}\uFF08\u652F\u6301: ${supportedExts.join(", ")}\uFF09`);
|
|
@@ -5977,7 +6878,7 @@ function makeDataCommand() {
|
|
|
5977
6878
|
const body = {
|
|
5978
6879
|
content: content.toString("base64"),
|
|
5979
6880
|
encoding: "base64",
|
|
5980
|
-
fileName:
|
|
6881
|
+
fileName: import_path16.default.basename(filePath),
|
|
5981
6882
|
format: ext.slice(1),
|
|
5982
6883
|
overwrite: opts.overwrite ?? false
|
|
5983
6884
|
};
|
|
@@ -6005,10 +6906,8 @@ function makeDataCommand() {
|
|
|
6005
6906
|
}
|
|
6006
6907
|
|
|
6007
6908
|
// cli/dazi-flow/src/commands/variable.ts
|
|
6008
|
-
var
|
|
6009
|
-
|
|
6010
|
-
return import_path18.default.resolve(dir ?? process.cwd());
|
|
6011
|
-
}
|
|
6909
|
+
var import_path17 = __toESM(require("path"), 1);
|
|
6910
|
+
var import_flowDirResolve4 = __toESM(require_flowDirResolve(), 1);
|
|
6012
6911
|
function requireFlowId(flowDir) {
|
|
6013
6912
|
const meta = readMeta(flowDir);
|
|
6014
6913
|
if (!meta?.flowId) {
|
|
@@ -6019,22 +6918,22 @@ function requireFlowId(flowDir) {
|
|
|
6019
6918
|
}
|
|
6020
6919
|
function makeVariableCommand() {
|
|
6021
6920
|
const cmd = new Command("variable").description("\u6D41\u7A0B\u8FD0\u884C\u671F\u53D8\u91CF\uFF08\u540C\u6B65\u5230\u672C\u5730 \u53D8\u91CF/ \u76EE\u5F55\uFF09");
|
|
6022
|
-
cmd.command("sync").description("\u4ECE\u8C03\u8BD5 Run \u540C\u6B65\u5168\u90E8\u53D8\u91CF\u5230 \u53D8\u91CF/<name>.json\uFF08\u542B schema \u4E0E\u524D N \u884C\u9884\u89C8\uFF09").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\
|
|
6921
|
+
cmd.command("sync").description("\u4ECE\u8C03\u8BD5 Run \u540C\u6B65\u5168\u90E8\u53D8\u91CF\u5230 \u53D8\u91CF/<name>.json\uFF08\u542B schema \u4E0E\u524D N \u884C\u9884\u89C8\uFF09").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\u987B\u542B flow.json\uFF1B\u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84\uFF09").option("--limit <n>", "\u8868\u53D8\u91CF\u9884\u89C8\u884C\u6570", "10").option("--json", "\u8F93\u51FA JSON").action(async (opts) => {
|
|
6023
6922
|
try {
|
|
6024
|
-
const flowDir =
|
|
6923
|
+
const flowDir = (0, import_flowDirResolve4.resolveFlowDir)(opts.dir, { json: opts.json });
|
|
6025
6924
|
const flowId = requireFlowId(flowDir);
|
|
6026
6925
|
const previewLimit = Math.max(1, Math.min(100, parseInt(opts.limit, 10) || 10));
|
|
6027
6926
|
if (!opts.json) console.log(`\u6B63\u5728\u540C\u6B65\u53D8\u91CF\uFF08flowId=${flowId}\uFF09\u2026`);
|
|
6028
6927
|
const result = await syncAllVariables(flowId, flowDir, previewLimit);
|
|
6029
|
-
if (!opts.json) console.log(`\u2705 \u5DF2\u540C\u6B65 ${result.count} \u4E2A\u53D8\u91CF \u2192 ${
|
|
6928
|
+
if (!opts.json) console.log(`\u2705 \u5DF2\u540C\u6B65 ${result.count} \u4E2A\u53D8\u91CF \u2192 ${import_path17.default.join(flowDir, "\u53D8\u91CF")}`);
|
|
6030
6929
|
ok({ flowId, flowDir, ...result });
|
|
6031
6930
|
} catch (err) {
|
|
6032
6931
|
handleError(err);
|
|
6033
6932
|
}
|
|
6034
6933
|
});
|
|
6035
|
-
cmd.command("pull").description("\u62C9\u53D6\u5355\u4E2A\u53D8\u91CF\u5230 \u53D8\u91CF/<name>.json").requiredOption("--name <varName>", "\u53D8\u91CF\u540D\uFF08output_variable_name\uFF09").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\
|
|
6934
|
+
cmd.command("pull").description("\u62C9\u53D6\u5355\u4E2A\u53D8\u91CF\u5230 \u53D8\u91CF/<name>.json").requiredOption("--name <varName>", "\u53D8\u91CF\u540D\uFF08output_variable_name\uFF09").option("--dir <dir>", "\u6D41\u7A0B\u76EE\u5F55\uFF08\u987B\u542B flow.json\uFF1B\u63A8\u8350\u7EDD\u5BF9\u8DEF\u5F84\uFF09").option("--limit <n>", "\u8868\u53D8\u91CF\u9884\u89C8\u884C\u6570", "10").option("--json", "\u8F93\u51FA JSON").action(async (opts) => {
|
|
6036
6935
|
try {
|
|
6037
|
-
const flowDir =
|
|
6936
|
+
const flowDir = (0, import_flowDirResolve4.resolveFlowDir)(opts.dir, { json: opts.json });
|
|
6038
6937
|
const flowId = requireFlowId(flowDir);
|
|
6039
6938
|
const previewLimit = Math.max(1, Math.min(100, parseInt(opts.limit, 10) || 10));
|
|
6040
6939
|
const result = await syncVariableByName(flowId, flowDir, opts.name, previewLimit);
|
|
@@ -6241,201 +7140,17 @@ function makeMcpCommand() {
|
|
|
6241
7140
|
}
|
|
6242
7141
|
|
|
6243
7142
|
// cli/dazi-flow/src/commands/managedFiles.ts
|
|
6244
|
-
var
|
|
6245
|
-
var
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
var import_fs15 = __toESM(require("fs"));
|
|
6249
|
-
var import_path19 = __toESM(require("path"));
|
|
6250
|
-
|
|
6251
|
-
// src/shared/managedFilesTypes.ts
|
|
6252
|
-
var MANAGED_FILES_API = "/api/data-pipelines/v1/managed-files";
|
|
6253
|
-
var MANAGED_FS_API = "/api/data-pipelines/v1/managed-fs";
|
|
6254
|
-
var MANAGED_BUNDLE_FILES = {
|
|
6255
|
-
manifest: "\u6587\u4EF6\u4FE1\u606F.json",
|
|
6256
|
-
originalPrefix: "\u539F\u6587\u4EF6",
|
|
6257
|
-
nativeDigest: "\u539F\u751F\u89E3\u6790.md",
|
|
6258
|
-
aiStructure: "\u8868\u7ED3\u6784.json",
|
|
6259
|
-
reportLayout: "\u62A5\u8868\u5E03\u5C40.json"
|
|
6260
|
-
};
|
|
6261
|
-
|
|
6262
|
-
// src/shared/managedFilesBundle.ts
|
|
6263
|
-
function apiBase(auth) {
|
|
6264
|
-
return auth.serverUrl.replace(/\/$/, "");
|
|
6265
|
-
}
|
|
6266
|
-
function sanitizeDirPart(raw) {
|
|
6267
|
-
return raw.trim().replace(/\s+/g, "_").replace(/[<>:"|?*/\\]/g, "_").slice(0, 80) || "file";
|
|
6268
|
-
}
|
|
6269
|
-
function managedFileLocalFolderName(meta) {
|
|
6270
|
-
const base = sanitizeDirPart(meta.display_name ?? meta.file_id);
|
|
6271
|
-
const shortId = meta.file_id.slice(0, 8);
|
|
6272
|
-
return `${base}_${shortId}`;
|
|
6273
|
-
}
|
|
6274
|
-
function managedFileLocalDir(filesRoot, meta) {
|
|
6275
|
-
return import_path19.default.join(filesRoot, managedFileLocalFolderName(meta));
|
|
6276
|
-
}
|
|
6277
|
-
function isExcelManagedFile(meta) {
|
|
6278
|
-
const ext = (meta.file_ext ?? import_path19.default.extname(meta.display_name ?? "")).toLowerCase();
|
|
6279
|
-
if (ext === ".xlsx" || ext === ".xls") return true;
|
|
6280
|
-
const mime = (meta.mime_type ?? "").toLowerCase();
|
|
6281
|
-
return mime.includes("spreadsheet") || mime.endsWith(".sheet");
|
|
6282
|
-
}
|
|
6283
|
-
async function fetchJson(auth, urlPath, method = "GET") {
|
|
6284
|
-
const res = await fetch(`${apiBase(auth)}${urlPath}`, {
|
|
6285
|
-
method,
|
|
6286
|
-
headers: {
|
|
6287
|
-
Authorization: `Bearer ${auth.token}`,
|
|
6288
|
-
Accept: "application/json",
|
|
6289
|
-
...method === "POST" ? { "Content-Type": "application/json" } : {}
|
|
6290
|
-
}
|
|
6291
|
-
});
|
|
6292
|
-
if (!res.ok) {
|
|
6293
|
-
const text = await res.text().catch(() => "");
|
|
6294
|
-
throw new Error(`HTTP ${res.status}: ${text || res.statusText}`);
|
|
6295
|
-
}
|
|
6296
|
-
return res.json();
|
|
6297
|
-
}
|
|
6298
|
-
async function downloadBinary(auth, urlPath, destPath) {
|
|
6299
|
-
const res = await fetch(`${apiBase(auth)}${urlPath}`, {
|
|
6300
|
-
headers: { Authorization: `Bearer ${auth.token}` }
|
|
6301
|
-
});
|
|
6302
|
-
if (!res.ok) {
|
|
6303
|
-
const text = await res.text().catch(() => "");
|
|
6304
|
-
throw new Error(`\u4E0B\u8F7D\u5931\u8D25 HTTP ${res.status}: ${text || res.statusText}`);
|
|
6305
|
-
}
|
|
6306
|
-
const buf = Buffer.from(await res.arrayBuffer());
|
|
6307
|
-
import_fs15.default.mkdirSync(import_path19.default.dirname(destPath), { recursive: true });
|
|
6308
|
-
import_fs15.default.writeFileSync(destPath, buf);
|
|
6309
|
-
}
|
|
6310
|
-
async function resolveNativeDigest(auth, fileId, parseIfMissing) {
|
|
6311
|
-
if (!parseIfMissing) {
|
|
6312
|
-
try {
|
|
6313
|
-
return await fetchJson(
|
|
6314
|
-
auth,
|
|
6315
|
-
`${MANAGED_FILES_API}/${encodeURIComponent(fileId)}/excel-native-digest`
|
|
6316
|
-
);
|
|
6317
|
-
} catch {
|
|
6318
|
-
return null;
|
|
6319
|
-
}
|
|
6320
|
-
}
|
|
6321
|
-
try {
|
|
6322
|
-
let resp = await fetchJson(
|
|
6323
|
-
auth,
|
|
6324
|
-
`${MANAGED_FILES_API}/${encodeURIComponent(fileId)}/excel-native-digest`
|
|
6325
|
-
);
|
|
6326
|
-
if (resp.markdown) return resp;
|
|
6327
|
-
} catch {
|
|
6328
|
-
}
|
|
6329
|
-
try {
|
|
6330
|
-
return await fetchJson(
|
|
6331
|
-
auth,
|
|
6332
|
-
`${MANAGED_FILES_API}/${encodeURIComponent(fileId)}/excel-native-parse`,
|
|
6333
|
-
"POST"
|
|
6334
|
-
);
|
|
6335
|
-
} catch {
|
|
6336
|
-
return null;
|
|
6337
|
-
}
|
|
6338
|
-
}
|
|
6339
|
-
async function resolveAiStructure(auth, fileId) {
|
|
6340
|
-
try {
|
|
6341
|
-
return await fetchJson(
|
|
6342
|
-
auth,
|
|
6343
|
-
`${MANAGED_FILES_API}/${encodeURIComponent(fileId)}/excel-ai-structure`
|
|
6344
|
-
);
|
|
6345
|
-
} catch {
|
|
6346
|
-
return null;
|
|
6347
|
-
}
|
|
6348
|
-
}
|
|
6349
|
-
async function resolveReportLayout(auth, fileId) {
|
|
6350
|
-
try {
|
|
6351
|
-
return await fetchJson(
|
|
6352
|
-
auth,
|
|
6353
|
-
`${MANAGED_FILES_API}/${encodeURIComponent(fileId)}/excel-report-layout`
|
|
6354
|
-
);
|
|
6355
|
-
} catch {
|
|
6356
|
-
return null;
|
|
6357
|
-
}
|
|
6358
|
-
}
|
|
6359
|
-
async function pullManagedFileBundle(opts) {
|
|
6360
|
-
const { auth, meta } = opts;
|
|
6361
|
-
const fileId = meta.file_id?.trim();
|
|
6362
|
-
if (!fileId) throw new Error("\u7F3A\u5C11 file_id\uFF0C\u4EC5\u652F\u6301\u5DF2\u767B\u8BB0\u6587\u4EF6");
|
|
6363
|
-
const dir = managedFileLocalDir(opts.filesRootDir, meta);
|
|
6364
|
-
import_fs15.default.mkdirSync(dir, { recursive: true });
|
|
6365
|
-
const written = [];
|
|
6366
|
-
const notes = [];
|
|
6367
|
-
const pulledAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
6368
|
-
const ext = (meta.file_ext && meta.file_ext.startsWith(".") ? meta.file_ext : meta.file_ext ? `.${meta.file_ext}` : "") || import_path19.default.extname(meta.display_name ?? meta.stored_filename ?? "") || "";
|
|
6369
|
-
const originalName = `${MANAGED_BUNDLE_FILES.originalPrefix}${ext || ""}`;
|
|
6370
|
-
const originalPath = import_path19.default.join(dir, originalName);
|
|
6371
|
-
await downloadBinary(
|
|
6372
|
-
auth,
|
|
6373
|
-
`${MANAGED_FILES_API}/${encodeURIComponent(fileId)}/content`,
|
|
6374
|
-
originalPath
|
|
6375
|
-
);
|
|
6376
|
-
written.push(originalName);
|
|
6377
|
-
if (isExcelManagedFile(meta)) {
|
|
6378
|
-
const digest = await resolveNativeDigest(auth, fileId, opts.parseNativeIfMissing !== false);
|
|
6379
|
-
if (digest?.markdown) {
|
|
6380
|
-
import_fs15.default.writeFileSync(import_path19.default.join(dir, MANAGED_BUNDLE_FILES.nativeDigest), digest.markdown, "utf8");
|
|
6381
|
-
written.push(MANAGED_BUNDLE_FILES.nativeDigest);
|
|
6382
|
-
} else {
|
|
6383
|
-
notes.push("\u539F\u751F\u89E3\u6790\u672A\u751F\u6210\uFF1A\u8BF7\u5728\u5E73\u53F0\u300C\u6587\u4EF6\u4E0A\u4F20\u7BA1\u7406\u300D\u4E2D\u5BF9 Excel \u6267\u884C\u300C\u539F\u751F\u89E3\u6790\u300D\u540E\u91CD\u8BD5\u62C9\u53D6");
|
|
6384
|
-
}
|
|
6385
|
-
const structureResp = await resolveAiStructure(auth, fileId);
|
|
6386
|
-
if (structureResp?.structure) {
|
|
6387
|
-
import_fs15.default.writeFileSync(
|
|
6388
|
-
import_path19.default.join(dir, MANAGED_BUNDLE_FILES.aiStructure),
|
|
6389
|
-
JSON.stringify(structureResp.structure, null, 2),
|
|
6390
|
-
"utf8"
|
|
6391
|
-
);
|
|
6392
|
-
written.push(MANAGED_BUNDLE_FILES.aiStructure);
|
|
6393
|
-
} else {
|
|
6394
|
-
notes.push("\u8868\u7ED3\u6784\u672A\u751F\u6210\uFF1A\u8BF7\u5148\u5728\u5E73\u53F0\u5B8C\u6210\u300C\u539F\u751F\u89E3\u6790\u300D\u4E0E\u300CAI \u8868\u7ED3\u6784\u300D\u540E\u518D\u62C9\u53D6\uFF0C\u6216\u4EC5\u4F7F\u7528\u539F\u751F\u89E3\u6790.md \u4EA4\u7ED9 AI");
|
|
6395
|
-
}
|
|
6396
|
-
const layoutResp = await resolveReportLayout(auth, fileId);
|
|
6397
|
-
if (layoutResp?.layout) {
|
|
6398
|
-
import_fs15.default.writeFileSync(
|
|
6399
|
-
import_path19.default.join(dir, MANAGED_BUNDLE_FILES.reportLayout),
|
|
6400
|
-
JSON.stringify(layoutResp.layout, null, 2),
|
|
6401
|
-
"utf8"
|
|
6402
|
-
);
|
|
6403
|
-
written.push(MANAGED_BUNDLE_FILES.reportLayout);
|
|
6404
|
-
} else {
|
|
6405
|
-
notes.push("\u62A5\u8868\u5E03\u5C40\u672A\u751F\u6210\uFF1A\u8BF7\u5728\u5E73\u53F0\u300C\u62A5\u8868\u5E03\u5C40\u300D\u9875\u7B7E\u6267\u884C\u89C4\u5219\u89E3\u6790\u6216 AI \u62A5\u8868\u5E03\u5C40\u540E\u518D\u62C9\u53D6");
|
|
6406
|
-
}
|
|
6407
|
-
} else {
|
|
6408
|
-
notes.push("\u975E Excel \u6587\u4EF6\uFF1A\u4EC5\u62C9\u53D6\u539F\u6587\u4EF6\u4E0E\u6587\u4EF6\u4FE1\u606F\uFF08\u65E0\u539F\u751F\u89E3\u6790/\u8868\u7ED3\u6784\uFF09");
|
|
6409
|
-
}
|
|
6410
|
-
const manifest = {
|
|
6411
|
-
pulledAt,
|
|
6412
|
-
file_id: fileId,
|
|
6413
|
-
display_name: meta.display_name,
|
|
6414
|
-
relative_dir: meta.relative_dir,
|
|
6415
|
-
localDir: dir,
|
|
6416
|
-
files: written,
|
|
6417
|
-
notes: notes.length ? notes : void 0
|
|
6418
|
-
};
|
|
6419
|
-
manifest.files = [...written, MANAGED_BUNDLE_FILES.manifest];
|
|
6420
|
-
import_fs15.default.writeFileSync(
|
|
6421
|
-
import_path19.default.join(dir, MANAGED_BUNDLE_FILES.manifest),
|
|
6422
|
-
JSON.stringify({ ...meta, ...manifest }, null, 2),
|
|
6423
|
-
"utf8"
|
|
6424
|
-
);
|
|
6425
|
-
return { dir, manifest };
|
|
6426
|
-
}
|
|
6427
|
-
function findManagedFileInBrowse(items, fileId) {
|
|
6428
|
-
return items.find((i) => i.file_id === fileId);
|
|
6429
|
-
}
|
|
6430
|
-
|
|
6431
|
-
// cli/dazi-flow/src/commands/managedFiles.ts
|
|
7143
|
+
var import_path18 = __toESM(require("path"), 1);
|
|
7144
|
+
var import_fs15 = __toESM(require("fs"), 1);
|
|
7145
|
+
var import_managedFilesBundle = __toESM(require_managedFilesBundle(), 1);
|
|
7146
|
+
var import_managedFilesTypes = __toESM(require_managedFilesTypes(), 1);
|
|
6432
7147
|
function makeManagedFilesCommand() {
|
|
6433
7148
|
const cmd = new Command("managed-files").description("\u6587\u4EF6\u4E0A\u4F20\u7BA1\u7406\uFF08managed_files\uFF09");
|
|
6434
7149
|
cmd.command("dirs").description("\u5217\u51FA\u7BA1\u7406\u76EE\u5F55\u5B50\u6587\u4EF6\u5939").option("--path <relativePath>", "\u76F8\u5BF9\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u6839\uFF09", "").option("--json", "\u8F93\u51FA JSON").action(async (opts) => {
|
|
6435
7150
|
try {
|
|
6436
7151
|
const qs = new URLSearchParams();
|
|
6437
7152
|
qs.set("path", opts.path ?? "");
|
|
6438
|
-
const data = await apiRequest(`${MANAGED_FS_API}/children?${qs}`);
|
|
7153
|
+
const data = await apiRequest(`${import_managedFilesTypes.MANAGED_FS_API}/children?${qs}`);
|
|
6439
7154
|
if (!opts.json) {
|
|
6440
7155
|
for (const c of data.children ?? []) {
|
|
6441
7156
|
console.log(` ${c.path || "/"} ${c.name}`);
|
|
@@ -6451,7 +7166,7 @@ function makeManagedFilesCommand() {
|
|
|
6451
7166
|
const qs = new URLSearchParams();
|
|
6452
7167
|
qs.set("relative_dir", opts.relativeDir ?? "");
|
|
6453
7168
|
qs.set("include_unregistered", "false");
|
|
6454
|
-
const data = await apiRequest(`${MANAGED_FILES_API}/browse?${qs}`);
|
|
7169
|
+
const data = await apiRequest(`${import_managedFilesTypes.MANAGED_FILES_API}/browse?${qs}`);
|
|
6455
7170
|
if (!opts.json) {
|
|
6456
7171
|
for (const it of data.items ?? []) {
|
|
6457
7172
|
if (!it.file_id) continue;
|
|
@@ -6470,17 +7185,17 @@ function makeManagedFilesCommand() {
|
|
|
6470
7185
|
const qs = new URLSearchParams();
|
|
6471
7186
|
qs.set("relative_dir", opts.relativeDir ?? "");
|
|
6472
7187
|
qs.set("include_unregistered", "false");
|
|
6473
|
-
const browse = await apiRequest(`${MANAGED_FILES_API}/browse?${qs}`);
|
|
6474
|
-
let meta = findManagedFileInBrowse(browse.items ?? [], opts.fileId);
|
|
7188
|
+
const browse = await apiRequest(`${import_managedFilesTypes.MANAGED_FILES_API}/browse?${qs}`);
|
|
7189
|
+
let meta = (0, import_managedFilesBundle.findManagedFileInBrowse)(browse.items ?? [], opts.fileId);
|
|
6475
7190
|
if (!meta) {
|
|
6476
7191
|
console.error(`\u9519\u8BEF: \u5728 relative_dir="${opts.relativeDir ?? ""}" \u672A\u627E\u5230 file_id=${opts.fileId}`);
|
|
6477
7192
|
console.error("\u63D0\u793A: \u6307\u5B9A\u6B63\u786E\u7684 --relative-dir\uFF0C\u6216\u4ECE\u4FA7\u680F\u6811\u53F3\u952E\u62C9\u53D6");
|
|
6478
7193
|
process.exit(1);
|
|
6479
7194
|
}
|
|
6480
7195
|
const ws = resolveWorkspace();
|
|
6481
|
-
const filesRoot =
|
|
6482
|
-
|
|
6483
|
-
const result = await pullManagedFileBundle({
|
|
7196
|
+
const filesRoot = import_path18.default.resolve(opts.filesRoot ?? ws.files);
|
|
7197
|
+
import_fs15.default.mkdirSync(filesRoot, { recursive: true });
|
|
7198
|
+
const result = await (0, import_managedFilesBundle.pullManagedFileBundle)({
|
|
6484
7199
|
auth: { serverUrl: auth.serverUrl, token: auth.token },
|
|
6485
7200
|
meta,
|
|
6486
7201
|
filesRootDir: filesRoot,
|
|
@@ -6503,7 +7218,7 @@ function makeManagedFilesCommand() {
|
|
|
6503
7218
|
|
|
6504
7219
|
// cli/dazi-flow/src/index.ts
|
|
6505
7220
|
var program2 = new Command();
|
|
6506
|
-
program2.name("dazi-flow").description("\u642D\u5B50 Flow CLI \u2014 \u5DE5\u4F5C\u6D41\u7BA1\u7406").version("3.0.
|
|
7221
|
+
program2.name("dazi-flow").description("\u642D\u5B50 Flow CLI \u2014 \u5DE5\u4F5C\u6D41\u7BA1\u7406").version("3.0.3", "-v, --version");
|
|
6507
7222
|
program2.addCommand(makeFlowsCommand());
|
|
6508
7223
|
program2.addCommand(makeSnapshotCommand());
|
|
6509
7224
|
program2.addCommand(makeProjectCommand());
|