@actiondock/builder 2.0.11 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -30
- package/dist/archive.d.ts +47 -0
- package/dist/archive.js +519 -0
- package/dist/build.d.ts +9 -0
- package/dist/build.js +576 -0
- package/dist/dependency-check.d.ts +14 -0
- package/dist/dependency-check.js +246 -0
- package/dist/errors.d.ts +14 -0
- package/dist/errors.js +22 -0
- package/dist/exporter.d.ts +69 -0
- package/dist/exporter.js +761 -0
- package/dist/fs-utils.d.ts +16 -0
- package/dist/fs-utils.js +146 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +21 -0
- package/dist/manifest.d.ts +75 -0
- package/dist/manifest.js +213 -0
- package/dist/pack.d.ts +13 -0
- package/dist/pack.js +339 -0
- package/dist/planner.d.ts +68 -0
- package/dist/planner.js +681 -0
- package/dist/types.d.ts +442 -0
- package/dist/types.js +1 -0
- package/package.json +15 -17
- package/src/archive.ts +0 -248
- package/src/build.ts +0 -106
- package/src/compiler.ts +0 -303
- package/src/errors.ts +0 -67
- package/src/exporter.ts +0 -680
- package/src/index.ts +0 -6
- package/src/planner.ts +0 -731
- package/src/types.ts +0 -337
package/dist/pack.js
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statSync, writeFileSync, } from "node:fs";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
import { dirname, join, relative, resolve } from "node:path";
|
|
7
|
+
import { getPackageSlug, loadProjectConfig } from "@actiondock/core";
|
|
8
|
+
import { BuilderError } from "./errors.js";
|
|
9
|
+
import { assertNoFileProtocolDeps, assertValidManifestActionIds, normalizePkgExportsAndEngines, readPackageJson, serializePlanManifest, } from "./manifest.js";
|
|
10
|
+
import { collectRelativeFiles } from "./fs-utils.js";
|
|
11
|
+
import { SelectionPlanner } from "./planner.js";
|
|
12
|
+
/**
|
|
13
|
+
* 对 Action Package 执行打包并生成标准 npm Action 压缩包(.tgz)。
|
|
14
|
+
*
|
|
15
|
+
* 职责:
|
|
16
|
+
* - 调用项目本地 TypeScript 编译(Node 执行),输出声明文件(.d.ts)与纯 JavaScript ESM 产物到临时暂存目录。
|
|
17
|
+
* - 严格校验导出的 Manifest(入口全部指向编译后的 .js/.mjs,不得包含 actionsDir 或 playbooksDir 等废弃目录字段)。
|
|
18
|
+
* - 在暂存目录调用带有 --ignore-scripts 的 npm pack 生成标准 npm 压缩包(.tgz),严禁使用正则替换与自建 tar 压缩。
|
|
19
|
+
*
|
|
20
|
+
* @param options 打包参数选项
|
|
21
|
+
* @returns 打包结果元数据
|
|
22
|
+
*/
|
|
23
|
+
export async function packProject(options) {
|
|
24
|
+
const root = resolve(options.projectRoot);
|
|
25
|
+
const pkgConfig = options.config || loadProjectConfig(root);
|
|
26
|
+
const plan = SelectionPlanner.plan({
|
|
27
|
+
projectRoot: root,
|
|
28
|
+
config: pkgConfig,
|
|
29
|
+
manifest: options.manifest,
|
|
30
|
+
});
|
|
31
|
+
if (plan.actions.length === 0) {
|
|
32
|
+
throw new BuilderError("No actions resolved for packing");
|
|
33
|
+
}
|
|
34
|
+
const pkgSlug = getPackageSlug(plan.packageId);
|
|
35
|
+
const pkgJsonPath = join(root, "package.json");
|
|
36
|
+
if (!existsSync(pkgJsonPath)) {
|
|
37
|
+
throw new BuilderError(`package.json not found in project root: ${root}`);
|
|
38
|
+
}
|
|
39
|
+
const sourcePkgJson = readPackageJson(pkgJsonPath);
|
|
40
|
+
// 校验生产依赖合法性(禁止 file: 本地协议)
|
|
41
|
+
assertNoFileProtocolDeps(sourcePkgJson.dependencies, "packed packages");
|
|
42
|
+
// 创建干净临时目录,确保不改写源工程
|
|
43
|
+
const tempBase = mkdtempSync(join(tmpdir(), "ad-pack-"));
|
|
44
|
+
const stagingPkgDir = join(tempBase, "package");
|
|
45
|
+
mkdirSync(stagingPkgDir, { recursive: true });
|
|
46
|
+
try {
|
|
47
|
+
await compileTypeScript(root, stagingPkgDir, plan);
|
|
48
|
+
stageSources(root, stagingPkgDir, plan);
|
|
49
|
+
writeManifestAndPkgJson(stagingPkgDir, plan, sourcePkgJson);
|
|
50
|
+
// 收集打包文件相对清单与摘要
|
|
51
|
+
const relativeFiles = collectRelativeFiles(stagingPkgDir);
|
|
52
|
+
const manifestSummary = {
|
|
53
|
+
actionsCount: plan.actions.length,
|
|
54
|
+
actions: plan.actions.map((a) => a.id),
|
|
55
|
+
assetsCount: plan.assets.length,
|
|
56
|
+
filesCount: relativeFiles.length,
|
|
57
|
+
};
|
|
58
|
+
const tarballName = `${pkgSlug}-${plan.version}.tgz`;
|
|
59
|
+
const targetOutDir = resolve(options.outDir || join(root, "dist"));
|
|
60
|
+
if (options.dryRun) {
|
|
61
|
+
return {
|
|
62
|
+
packageId: plan.packageId,
|
|
63
|
+
packageName: plan.packageName,
|
|
64
|
+
version: plan.version,
|
|
65
|
+
tarballName,
|
|
66
|
+
sizeBytes: 0,
|
|
67
|
+
sha256: "",
|
|
68
|
+
files: relativeFiles,
|
|
69
|
+
manifestSummary,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
mkdirSync(targetOutDir, { recursive: true });
|
|
73
|
+
const finalTarballPath = join(targetOutDir, tarballName);
|
|
74
|
+
if (existsSync(finalTarballPath)) {
|
|
75
|
+
rmSync(finalTarballPath, { force: true });
|
|
76
|
+
}
|
|
77
|
+
const generatedTarball = await runNpmPack(stagingPkgDir, tempBase, tarballName);
|
|
78
|
+
copyFileSync(generatedTarball, finalTarballPath);
|
|
79
|
+
rmSync(generatedTarball, { force: true });
|
|
80
|
+
const stat = statSync(finalTarballPath);
|
|
81
|
+
const fileBuf = readFileSync(finalTarballPath);
|
|
82
|
+
const sha256 = createHash("sha256").update(fileBuf).digest("hex");
|
|
83
|
+
return {
|
|
84
|
+
packageId: plan.packageId,
|
|
85
|
+
packageName: plan.packageName,
|
|
86
|
+
version: plan.version,
|
|
87
|
+
tarballPath: finalTarballPath,
|
|
88
|
+
tarballName,
|
|
89
|
+
sizeBytes: stat.size,
|
|
90
|
+
sha256,
|
|
91
|
+
files: relativeFiles,
|
|
92
|
+
manifestSummary,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
if (existsSync(tempBase)) {
|
|
97
|
+
rmSync(tempBase, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 判断文件路径是否为 TypeScript 源码。
|
|
103
|
+
*/
|
|
104
|
+
function isTypeScriptSource(path) {
|
|
105
|
+
return path.endsWith(".ts") || path.endsWith(".mts");
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 解析项目本地 TypeScript 编译器(回退到打包工具自身依赖)。
|
|
109
|
+
*/
|
|
110
|
+
async function resolveTypeScriptCompiler(root) {
|
|
111
|
+
try {
|
|
112
|
+
const req = createRequire(join(root, "package.json"));
|
|
113
|
+
const tsPath = req.resolve("typescript");
|
|
114
|
+
const imported = await import(tsPath);
|
|
115
|
+
return imported.default || imported;
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
try {
|
|
119
|
+
const imported = await import("typescript");
|
|
120
|
+
return imported.default || imported;
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
throw new BuilderError(`TypeScript is required to pack TypeScript Action packages, but 'typescript' could not be resolved from ${root}.`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* 在暂存目录内执行 TypeScript 编译,产出 .js 与 .d.ts。
|
|
129
|
+
* 仅在存在 TypeScript 源码时执行。
|
|
130
|
+
*/
|
|
131
|
+
async function compileTypeScript(root, stagingPkgDir, plan) {
|
|
132
|
+
const hasTypeScript = plan.actions.some((a) => isTypeScriptSource(a.entry)) ||
|
|
133
|
+
plan.dependencies.modulesAndAssets.some((m) => (m.type === "module" || m.type === "file") && isTypeScriptSource(m.path));
|
|
134
|
+
if (!hasTypeScript) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const ts = await resolveTypeScriptCompiler(root);
|
|
138
|
+
const tsSourceFiles = new Set();
|
|
139
|
+
for (const act of plan.actions) {
|
|
140
|
+
if (act.isExternal || act.id.includes("/"))
|
|
141
|
+
continue;
|
|
142
|
+
if (isTypeScriptSource(act.entry)) {
|
|
143
|
+
tsSourceFiles.add(act.resolvedPath);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
for (const mod of plan.dependencies.modulesAndAssets) {
|
|
147
|
+
if ((mod.type === "module" || mod.type === "file") && isTypeScriptSource(mod.path)) {
|
|
148
|
+
tsSourceFiles.add(mod.resolvedPath);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const compilerOptions = {
|
|
152
|
+
target: ts.ScriptTarget.ES2022,
|
|
153
|
+
module: ts.ModuleKind.NodeNext,
|
|
154
|
+
moduleResolution: ts.ModuleResolutionKind.NodeNext,
|
|
155
|
+
declaration: true,
|
|
156
|
+
emitDeclarationOnly: false,
|
|
157
|
+
rewriteRelativeImportExtensions: true,
|
|
158
|
+
rootDir: root,
|
|
159
|
+
outDir: stagingPkgDir,
|
|
160
|
+
skipLibCheck: true,
|
|
161
|
+
esModuleInterop: true,
|
|
162
|
+
allowSyntheticDefaultImports: true,
|
|
163
|
+
allowJs: true,
|
|
164
|
+
};
|
|
165
|
+
const tsconfigPath = join(root, "tsconfig.json");
|
|
166
|
+
if (existsSync(tsconfigPath)) {
|
|
167
|
+
try {
|
|
168
|
+
const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile);
|
|
169
|
+
if (!configFile.error) {
|
|
170
|
+
const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, root);
|
|
171
|
+
Object.assign(compilerOptions, parsedConfig.options, {
|
|
172
|
+
outDir: stagingPkgDir,
|
|
173
|
+
rootDir: root,
|
|
174
|
+
declaration: true,
|
|
175
|
+
emitDeclarationOnly: false,
|
|
176
|
+
rewriteRelativeImportExtensions: true,
|
|
177
|
+
noEmit: false,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
// 忽略 tsconfig 解析失败,回退到标准 compilerOptions
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const host = ts.createCompilerHost(compilerOptions);
|
|
186
|
+
const program = ts.createProgram(Array.from(tsSourceFiles), compilerOptions, host);
|
|
187
|
+
const emitResult = program.emit();
|
|
188
|
+
const preEmitDiagnostics = ts.getPreEmitDiagnostics(program);
|
|
189
|
+
const allDiagnostics = [...preEmitDiagnostics, ...emitResult.diagnostics];
|
|
190
|
+
const errors = allDiagnostics.filter((d) => d.category === ts.DiagnosticCategory.Error);
|
|
191
|
+
if (errors.length > 0 || emitResult.emitSkipped) {
|
|
192
|
+
const diagnosticsToFormat = errors.length > 0 ? errors : allDiagnostics;
|
|
193
|
+
const formatted = ts.formatDiagnosticsWithColorAndContext(diagnosticsToFormat, {
|
|
194
|
+
getCanonicalFileName: (f) => f,
|
|
195
|
+
getCurrentDirectory: () => root,
|
|
196
|
+
getNewLine: () => "\n",
|
|
197
|
+
});
|
|
198
|
+
throw new BuilderError(`TypeScript compilation failed during pack:\n${formatted}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* 拷贝声明的非 TypeScript 模块、静态资产、原生 JavaScript 入口、Playbook 与基础文档到暂存目录。
|
|
203
|
+
*/
|
|
204
|
+
function stageSources(root, stagingPkgDir, plan) {
|
|
205
|
+
// 拷贝声明的非 TypeScript 模块与静态资产
|
|
206
|
+
for (const dep of plan.dependencies.modulesAndAssets) {
|
|
207
|
+
if ((dep.type === "asset" || dep.type === "module" || dep.type === "file") &&
|
|
208
|
+
existsSync(dep.resolvedPath)) {
|
|
209
|
+
if (isTypeScriptSource(dep.path)) {
|
|
210
|
+
continue; // 已由 TypeScript 编译生成 .js 与 .d.ts
|
|
211
|
+
}
|
|
212
|
+
const destPath = join(stagingPkgDir, dep.path);
|
|
213
|
+
mkdirSync(dirname(destPath), { recursive: true });
|
|
214
|
+
copyFileSync(dep.resolvedPath, destPath);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
// 拷贝原生 JavaScript Action 入口(若存在)
|
|
218
|
+
for (const act of plan.actions) {
|
|
219
|
+
if (!isTypeScriptSource(act.entry)) {
|
|
220
|
+
const destPath = join(stagingPkgDir, act.entry);
|
|
221
|
+
mkdirSync(dirname(destPath), { recursive: true });
|
|
222
|
+
copyFileSync(act.resolvedPath, destPath);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// 拷贝 Playbook 规程文件
|
|
226
|
+
for (const pb of plan.playbooks) {
|
|
227
|
+
if (existsSync(pb.filePath)) {
|
|
228
|
+
const destPb = join(stagingPkgDir, relative(root, pb.filePath));
|
|
229
|
+
mkdirSync(dirname(destPb), { recursive: true });
|
|
230
|
+
copyFileSync(pb.filePath, destPb);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// 拷贝 README 等基础文档(若存在)
|
|
234
|
+
for (const doc of ["README.md", "readme.md", "LICENSE", "license"]) {
|
|
235
|
+
const srcDoc = join(root, doc);
|
|
236
|
+
if (existsSync(srcDoc)) {
|
|
237
|
+
copyFileSync(srcDoc, join(stagingPkgDir, doc));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* 计算编译后的 Action 入口相对路径(.ts 转 .js、.mts 转 .mjs)。
|
|
243
|
+
*/
|
|
244
|
+
function compiledEntryFor(action) {
|
|
245
|
+
if (action.entry.endsWith(".ts")) {
|
|
246
|
+
return action.entry.slice(0, -3) + ".js";
|
|
247
|
+
}
|
|
248
|
+
if (action.entry.endsWith(".mts")) {
|
|
249
|
+
return action.entry.slice(0, -4) + ".mjs";
|
|
250
|
+
}
|
|
251
|
+
return action.entry;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* 生成并写入严格校验后的 actiondock.json 与规范化 package.json。
|
|
255
|
+
*/
|
|
256
|
+
function writeManifestAndPkgJson(stagingPkgDir, plan, sourcePkgJson) {
|
|
257
|
+
// 构建编译后的 Action 清单字典并严格校验入口扩展名
|
|
258
|
+
const compiledEntries = new Map();
|
|
259
|
+
for (const act of plan.actions) {
|
|
260
|
+
if (act.isExternal || act.id.includes("/"))
|
|
261
|
+
continue;
|
|
262
|
+
const destEntry = compiledEntryFor(act);
|
|
263
|
+
if (!destEntry.endsWith(".js") && !destEntry.endsWith(".mjs")) {
|
|
264
|
+
throw new BuilderError(`Action '${act.id}' entry '${destEntry}' must point to compiled .js or .mjs`);
|
|
265
|
+
}
|
|
266
|
+
if (!existsSync(join(stagingPkgDir, destEntry))) {
|
|
267
|
+
throw new BuilderError(`Compiled action entry file not found: ${destEntry}`);
|
|
268
|
+
}
|
|
269
|
+
compiledEntries.set(act.id, destEntry);
|
|
270
|
+
}
|
|
271
|
+
// 严格生成与校验 actiondock.json(严禁包含废弃 actionsDir 或 playbooksDir 字段)
|
|
272
|
+
const packedConfig = serializePlanManifest(plan, {
|
|
273
|
+
includeSchema: true,
|
|
274
|
+
configBeforeActions: true,
|
|
275
|
+
includePlaybooks: false,
|
|
276
|
+
actionEntryOverride: (act) => compiledEntries.get(act.id),
|
|
277
|
+
});
|
|
278
|
+
if ("actionsDir" in packedConfig || "playbooksDir" in packedConfig) {
|
|
279
|
+
throw new BuilderError("Packed manifest must not contain deprecated fields 'actionsDir' or 'playbooksDir'.");
|
|
280
|
+
}
|
|
281
|
+
if (packedConfig.actions && typeof packedConfig.actions === "object") {
|
|
282
|
+
assertValidManifestActionIds(packedConfig.actions);
|
|
283
|
+
}
|
|
284
|
+
writeFileSync(join(stagingPkgDir, "actiondock.json"), JSON.stringify(packedConfig, null, 2) + "\n", "utf-8");
|
|
285
|
+
// 规范化 package.json:导出 ./actiondock.json,设定 node 引擎约束与 ESM 类型
|
|
286
|
+
const normalizedPkg = normalizePkgExportsAndEngines(sourcePkgJson);
|
|
287
|
+
writeFileSync(join(stagingPkgDir, "package.json"), JSON.stringify(normalizedPkg, null, 2) + "\n", "utf-8");
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* 在暂存目录调用带有 --ignore-scripts 的 npm pack 生成标准 npm 压缩包(.tgz)。
|
|
291
|
+
* 优先解析 --json 结构化输出,失败时回退到尾部行文件名解析。
|
|
292
|
+
* Windows 兼容:npm 是 .cmd 脚本,无 shell 直接 spawn 会 ENOENT/EINVAL。
|
|
293
|
+
*/
|
|
294
|
+
async function runNpmPack(stagingPkgDir, packDestination, fallbackName) {
|
|
295
|
+
const { stdout } = await new Promise((resolvePromise, rejectPromise) => {
|
|
296
|
+
const child = spawn("npm", ["pack", "--ignore-scripts", "--json", "--pack-destination", packDestination], {
|
|
297
|
+
cwd: stagingPkgDir,
|
|
298
|
+
shell: process.platform === "win32",
|
|
299
|
+
});
|
|
300
|
+
let stdoutBuf = "";
|
|
301
|
+
let stderrBuf = "";
|
|
302
|
+
child.stdout.on("data", (chunk) => (stdoutBuf += chunk));
|
|
303
|
+
child.stderr.on("data", (chunk) => (stderrBuf += chunk));
|
|
304
|
+
child.on("error", rejectPromise);
|
|
305
|
+
child.on("close", (code) => {
|
|
306
|
+
if (code === 0) {
|
|
307
|
+
resolvePromise({ stdout: stdoutBuf, stderr: stderrBuf });
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
rejectPromise(new BuilderError(`npm pack exited with code ${code}. Output:\n${stdoutBuf}\n${stderrBuf}`));
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
// 优先解析 --json 结构化输出中的压缩包文件名
|
|
315
|
+
let generatedName;
|
|
316
|
+
const trimmed = stdout.trim();
|
|
317
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
|
318
|
+
try {
|
|
319
|
+
const parsed = JSON.parse(trimmed);
|
|
320
|
+
const items = Array.isArray(parsed) ? parsed : [parsed];
|
|
321
|
+
const filename = items[0]?.filename;
|
|
322
|
+
if (typeof filename === "string" && filename.length > 0) {
|
|
323
|
+
generatedName = filename;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
catch {
|
|
327
|
+
// 回退到尾部行解析
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
if (!generatedName) {
|
|
331
|
+
const packLines = trimmed.split("\n");
|
|
332
|
+
generatedName = packLines.pop()?.trim() || fallbackName;
|
|
333
|
+
}
|
|
334
|
+
const generatedTarball = join(packDestination, generatedName);
|
|
335
|
+
if (!existsSync(generatedTarball)) {
|
|
336
|
+
throw new BuilderError(`npm pack did not produce expected tarball at ${generatedTarball}. Output:\n${stdout}`);
|
|
337
|
+
}
|
|
338
|
+
return generatedTarball;
|
|
339
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { SelectionPlan, SelectionPlannerOptions } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* 声明式选择集与构建规划器 (SelectionPlanner)。
|
|
4
|
+
* 仅读取 actiondock.json、锁文件与显式构建参数,彻底移除 TypeScript AST 源码扫描。
|
|
5
|
+
*/
|
|
6
|
+
export declare class SelectionPlanner {
|
|
7
|
+
private projectRoot;
|
|
8
|
+
constructor(options?: {
|
|
9
|
+
projectRoot?: string;
|
|
10
|
+
});
|
|
11
|
+
/**
|
|
12
|
+
* 解析项目配置:优先使用传入对象,缺失则读取 actiondock.json。
|
|
13
|
+
*/
|
|
14
|
+
private resolveConfig;
|
|
15
|
+
/**
|
|
16
|
+
* 解析声明式清单:优先使用传入清单,缺失则读取 actiondock.json,仍未提供则采用安全备用清单。
|
|
17
|
+
*/
|
|
18
|
+
private resolveManifest;
|
|
19
|
+
/**
|
|
20
|
+
* 收集 Playbook 规程定义(统一复用 core 的 loadPlaybooks,清单为唯一事实源)。
|
|
21
|
+
*/
|
|
22
|
+
private collectPlaybooks;
|
|
23
|
+
/**
|
|
24
|
+
* 计算初始 Action 与 Playbook 集合(显式声明过滤、uses 顶层依赖与默认全集)。
|
|
25
|
+
*/
|
|
26
|
+
private resolveInitialSelection;
|
|
27
|
+
/**
|
|
28
|
+
* 进行依赖闭包(uses)解析计算,自动处理环形依赖与传递依赖(支持当前清单与已链接外部包)。
|
|
29
|
+
*/
|
|
30
|
+
private resolveClosure;
|
|
31
|
+
/**
|
|
32
|
+
* 构造 Action 依赖结构(闭包结果物化为 ActionDependency 列表)。
|
|
33
|
+
*/
|
|
34
|
+
private buildActionDependencies;
|
|
35
|
+
/**
|
|
36
|
+
* 收集声明式文件与资产依赖结构(仅依据显式声明,杜绝 AST 依赖扫描与未声明模块猜测)。
|
|
37
|
+
*/
|
|
38
|
+
private collectDeclaredFilesAndAssets;
|
|
39
|
+
/**
|
|
40
|
+
* 执行依赖闭包裁剪与构建规划。
|
|
41
|
+
* 主流程仅做编排,各阶段职责由私有方法承担。
|
|
42
|
+
*
|
|
43
|
+
* @param options 规划参数
|
|
44
|
+
* @returns 完整的 SelectionPlan / BuildPlan 结构
|
|
45
|
+
*/
|
|
46
|
+
plan(options?: SelectionPlannerOptions): SelectionPlan;
|
|
47
|
+
/**
|
|
48
|
+
* 静态辅助调用方法。
|
|
49
|
+
*/
|
|
50
|
+
static plan(options: SelectionPlannerOptions): SelectionPlan;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 构建规划器标准导出。
|
|
54
|
+
* @deprecated SelectionPlanner 的历史别名,请直接使用 SelectionPlanner,将在两个版本后移除。
|
|
55
|
+
*/
|
|
56
|
+
export declare const BuildPlanner: typeof SelectionPlanner;
|
|
57
|
+
/** @deprecated SelectionPlanner 类型的历史别名,请直接使用 SelectionPlanner 类型。 */
|
|
58
|
+
export type BuildPlanner = SelectionPlanner;
|
|
59
|
+
/**
|
|
60
|
+
* 快捷选择规划函数。
|
|
61
|
+
* @deprecated 便捷快捷函数,请直接使用 SelectionPlanner.plan,将在两个版本后移除。
|
|
62
|
+
*/
|
|
63
|
+
export declare function selectionPlan(options: SelectionPlannerOptions): SelectionPlan;
|
|
64
|
+
/**
|
|
65
|
+
* 快捷构建规划函数标准导出。
|
|
66
|
+
* @deprecated selectionPlan 的历史别名,请改用 SelectionPlanner.plan,将在两个版本后移除。
|
|
67
|
+
*/
|
|
68
|
+
export declare const buildPlan: typeof selectionPlan;
|