create-windy 0.6.15 → 0.6.16
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/dist/cli.js
CHANGED
|
@@ -33,7 +33,7 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
33
33
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
34
|
var __require = import.meta.require;
|
|
35
35
|
|
|
36
|
-
// ../../node_modules/cli-width/index.js
|
|
36
|
+
// ../../node_modules/.bun/cli-width@4.1.0/node_modules/cli-width/index.js
|
|
37
37
|
var require_cli_width = __commonJS((exports, module2) => {
|
|
38
38
|
module2.exports = cliWidth;
|
|
39
39
|
function normalizeOpts(options) {
|
|
@@ -73,7 +73,7 @@ var require_cli_width = __commonJS((exports, module2) => {
|
|
|
73
73
|
}
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
-
// ../../node_modules/mute-stream/lib/index.js
|
|
76
|
+
// ../../node_modules/.bun/mute-stream@3.0.0/node_modules/mute-stream/lib/index.js
|
|
77
77
|
var require_lib = __commonJS((exports, module2) => {
|
|
78
78
|
var Stream = __require("stream");
|
|
79
79
|
|
|
@@ -4666,7 +4666,7 @@ function isMissing6(error) {
|
|
|
4666
4666
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
4667
4667
|
import { stdin, stdout } from "process";
|
|
4668
4668
|
|
|
4669
|
-
// ../../node_modules/@inquirer/core/dist/lib/key.js
|
|
4669
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/key.js
|
|
4670
4670
|
var keybindings = ["emacs", "vim"];
|
|
4671
4671
|
var keybindingLookup = new Set(keybindings);
|
|
4672
4672
|
function isKeybinding(value) {
|
|
@@ -4683,7 +4683,7 @@ var isDownKey = (key, keybindings2 = []) => key.name === "down" || keybindings2.
|
|
|
4683
4683
|
var isSpaceKey = (key) => key.name === "space";
|
|
4684
4684
|
var isNumberKey = (key) => "1234567890".includes(key.name);
|
|
4685
4685
|
var isEnterKey = (key) => key.name === "enter" || key.name === "return";
|
|
4686
|
-
// ../../node_modules/@inquirer/core/dist/lib/errors.js
|
|
4686
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/errors.js
|
|
4687
4687
|
class AbortPromptError extends Error {
|
|
4688
4688
|
name = "AbortPromptError";
|
|
4689
4689
|
message = "Prompt was aborted";
|
|
@@ -4709,10 +4709,10 @@ class HookError extends Error {
|
|
|
4709
4709
|
class ValidationError extends Error {
|
|
4710
4710
|
name = "ValidationError";
|
|
4711
4711
|
}
|
|
4712
|
-
// ../../node_modules/@inquirer/core/dist/lib/use-state.js
|
|
4712
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/use-state.js
|
|
4713
4713
|
import { AsyncResource as AsyncResource2 } from "async_hooks";
|
|
4714
4714
|
|
|
4715
|
-
// ../../node_modules/@inquirer/core/dist/lib/hook-engine.js
|
|
4715
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/hook-engine.js
|
|
4716
4716
|
import { AsyncLocalStorage, AsyncResource } from "async_hooks";
|
|
4717
4717
|
var hookStorage = new AsyncLocalStorage;
|
|
4718
4718
|
function createStore(rl) {
|
|
@@ -4817,7 +4817,7 @@ var effectScheduler = {
|
|
|
4817
4817
|
}
|
|
4818
4818
|
};
|
|
4819
4819
|
|
|
4820
|
-
// ../../node_modules/@inquirer/core/dist/lib/use-state.js
|
|
4820
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/use-state.js
|
|
4821
4821
|
function isFactory(value) {
|
|
4822
4822
|
return typeof value === "function";
|
|
4823
4823
|
}
|
|
@@ -4838,7 +4838,7 @@ function useState(defaultValue) {
|
|
|
4838
4838
|
});
|
|
4839
4839
|
}
|
|
4840
4840
|
|
|
4841
|
-
// ../../node_modules/@inquirer/core/dist/lib/use-effect.js
|
|
4841
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/use-effect.js
|
|
4842
4842
|
function useEffect(cb, depArray) {
|
|
4843
4843
|
withPointer((pointer) => {
|
|
4844
4844
|
const oldDeps = pointer.get();
|
|
@@ -4850,10 +4850,10 @@ function useEffect(cb, depArray) {
|
|
|
4850
4850
|
});
|
|
4851
4851
|
}
|
|
4852
4852
|
|
|
4853
|
-
// ../../node_modules/@inquirer/core/dist/lib/theme.js
|
|
4853
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/theme.js
|
|
4854
4854
|
import { styleText } from "util";
|
|
4855
4855
|
|
|
4856
|
-
// ../../node_modules/@inquirer/figures/dist/index.js
|
|
4856
|
+
// ../../node_modules/.bun/@inquirer+figures@2.0.7/node_modules/@inquirer/figures/dist/index.js
|
|
4857
4857
|
import process2 from "process";
|
|
4858
4858
|
function isUnicodeSupported() {
|
|
4859
4859
|
if (!process2.platform.startsWith("win")) {
|
|
@@ -5142,7 +5142,7 @@ var figures = shouldUseMain ? mainSymbols : fallbackSymbols;
|
|
|
5142
5142
|
var dist_default = figures;
|
|
5143
5143
|
var replacements = Object.entries(specialMainSymbols);
|
|
5144
5144
|
|
|
5145
|
-
// ../../node_modules/@inquirer/core/dist/lib/theme.js
|
|
5145
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/theme.js
|
|
5146
5146
|
var defaultTheme = {
|
|
5147
5147
|
prefix: {
|
|
5148
5148
|
idle: styleText("blue", "?"),
|
|
@@ -5170,7 +5170,7 @@ function getDefaultTheme() {
|
|
|
5170
5170
|
};
|
|
5171
5171
|
}
|
|
5172
5172
|
|
|
5173
|
-
// ../../node_modules/@inquirer/core/dist/lib/make-theme.js
|
|
5173
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/make-theme.js
|
|
5174
5174
|
function isPlainObject(value) {
|
|
5175
5175
|
if (typeof value !== "object" || value === null)
|
|
5176
5176
|
return false;
|
|
@@ -5198,7 +5198,7 @@ function makeTheme(...themes) {
|
|
|
5198
5198
|
return deepMerge(...themesToMerge);
|
|
5199
5199
|
}
|
|
5200
5200
|
|
|
5201
|
-
// ../../node_modules/@inquirer/core/dist/lib/use-prefix.js
|
|
5201
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/use-prefix.js
|
|
5202
5202
|
function usePrefix({ status = "idle", theme }) {
|
|
5203
5203
|
const [showLoader, setShowLoader] = useState(false);
|
|
5204
5204
|
const [tick, setTick] = useState(0);
|
|
@@ -5228,7 +5228,7 @@ function usePrefix({ status = "idle", theme }) {
|
|
|
5228
5228
|
const iconName = status === "loading" ? "idle" : status;
|
|
5229
5229
|
return typeof prefix === "string" ? prefix : prefix[iconName] ?? prefix["idle"];
|
|
5230
5230
|
}
|
|
5231
|
-
// ../../node_modules/@inquirer/core/dist/lib/use-memo.js
|
|
5231
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/use-memo.js
|
|
5232
5232
|
function useMemo(fn, dependencies) {
|
|
5233
5233
|
return withPointer((pointer) => {
|
|
5234
5234
|
const prev = pointer.get();
|
|
@@ -5240,12 +5240,12 @@ function useMemo(fn, dependencies) {
|
|
|
5240
5240
|
return prev.value;
|
|
5241
5241
|
});
|
|
5242
5242
|
}
|
|
5243
|
-
// ../../node_modules/@inquirer/core/dist/lib/use-ref.js
|
|
5243
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/use-ref.js
|
|
5244
5244
|
function useRef(val) {
|
|
5245
5245
|
return useState({ current: val })[0];
|
|
5246
5246
|
}
|
|
5247
5247
|
|
|
5248
|
-
// ../../node_modules/@inquirer/core/dist/lib/use-keypress.js
|
|
5248
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/use-keypress.js
|
|
5249
5249
|
function useKeypress(userHandler) {
|
|
5250
5250
|
const signal = useRef(userHandler);
|
|
5251
5251
|
signal.current = userHandler;
|
|
@@ -5263,10 +5263,10 @@ function useKeypress(userHandler) {
|
|
|
5263
5263
|
};
|
|
5264
5264
|
}, []);
|
|
5265
5265
|
}
|
|
5266
|
-
// ../../node_modules/@inquirer/core/dist/lib/utils.js
|
|
5266
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/utils.js
|
|
5267
5267
|
var import_cli_width = __toESM(require_cli_width(), 1);
|
|
5268
5268
|
|
|
5269
|
-
// ../../node_modules/fast-string-truncated-width/dist/utils.js
|
|
5269
|
+
// ../../node_modules/.bun/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/utils.js
|
|
5270
5270
|
var getCodePointsLength = (() => {
|
|
5271
5271
|
const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
5272
5272
|
return (input) => {
|
|
@@ -5285,7 +5285,7 @@ var isWideNotCJKTNotEmoji = (x) => {
|
|
|
5285
5285
|
return x === 8987 || x === 9001 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12771 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 19903 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
|
|
5286
5286
|
};
|
|
5287
5287
|
|
|
5288
|
-
// ../../node_modules/fast-string-truncated-width/dist/index.js
|
|
5288
|
+
// ../../node_modules/.bun/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/index.js
|
|
5289
5289
|
var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
|
|
5290
5290
|
var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
5291
5291
|
var CJKT_WIDE_RE = /(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu;
|
|
@@ -5384,7 +5384,7 @@ var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {})
|
|
|
5384
5384
|
};
|
|
5385
5385
|
var dist_default2 = getStringTruncatedWidth;
|
|
5386
5386
|
|
|
5387
|
-
// ../../node_modules/fast-string-width/dist/index.js
|
|
5387
|
+
// ../../node_modules/.bun/fast-string-width@3.0.2/node_modules/fast-string-width/dist/index.js
|
|
5388
5388
|
var NO_TRUNCATION2 = {
|
|
5389
5389
|
limit: Infinity,
|
|
5390
5390
|
ellipsis: "",
|
|
@@ -5395,7 +5395,7 @@ var fastStringWidth = (input, options = {}) => {
|
|
|
5395
5395
|
};
|
|
5396
5396
|
var dist_default3 = fastStringWidth;
|
|
5397
5397
|
|
|
5398
|
-
// ../../node_modules/fast-wrap-ansi/lib/main.js
|
|
5398
|
+
// ../../node_modules/.bun/fast-wrap-ansi@0.2.2/node_modules/fast-wrap-ansi/lib/main.js
|
|
5399
5399
|
var ESC = "\x1B";
|
|
5400
5400
|
var CSI = "\x9B";
|
|
5401
5401
|
var END_CODE = 39;
|
|
@@ -5607,7 +5607,7 @@ function wrapAnsi(string, columns, options) {
|
|
|
5607
5607
|
`);
|
|
5608
5608
|
}
|
|
5609
5609
|
|
|
5610
|
-
// ../../node_modules/@inquirer/core/dist/lib/utils.js
|
|
5610
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/utils.js
|
|
5611
5611
|
function breakLines(content, width) {
|
|
5612
5612
|
return content.split(`
|
|
5613
5613
|
`).flatMap((line) => wrapAnsi(line, width, { trim: false, wordWrap: false }).split(`
|
|
@@ -5618,7 +5618,7 @@ function readlineWidth() {
|
|
|
5618
5618
|
return import_cli_width.default({ defaultWidth: 80, output: readline().output });
|
|
5619
5619
|
}
|
|
5620
5620
|
|
|
5621
|
-
// ../../node_modules/@inquirer/core/dist/lib/pagination/use-pagination.js
|
|
5621
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/pagination/use-pagination.js
|
|
5622
5622
|
function usePointerPosition({ active, renderedItems, pageSize, loop }) {
|
|
5623
5623
|
const state = useRef({
|
|
5624
5624
|
lastPointer: active,
|
|
@@ -5684,12 +5684,12 @@ function usePagination({ items, active, renderItem, pageSize, loop = true }) {
|
|
|
5684
5684
|
return pageBuffer.filter((line) => typeof line === "string").join(`
|
|
5685
5685
|
`);
|
|
5686
5686
|
}
|
|
5687
|
-
// ../../node_modules/@inquirer/core/dist/lib/create-prompt.js
|
|
5687
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/create-prompt.js
|
|
5688
5688
|
var import_mute_stream = __toESM(require_lib(), 1);
|
|
5689
5689
|
import * as readline2 from "readline";
|
|
5690
5690
|
import { AsyncResource as AsyncResource3 } from "async_hooks";
|
|
5691
5691
|
|
|
5692
|
-
// ../../node_modules/signal-exit/dist/mjs/signals.js
|
|
5692
|
+
// ../../node_modules/.bun/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/signals.js
|
|
5693
5693
|
var signals = [];
|
|
5694
5694
|
signals.push("SIGHUP", "SIGINT", "SIGTERM");
|
|
5695
5695
|
if (process.platform !== "win32") {
|
|
@@ -5699,7 +5699,7 @@ if (process.platform === "linux") {
|
|
|
5699
5699
|
signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
|
|
5700
5700
|
}
|
|
5701
5701
|
|
|
5702
|
-
// ../../node_modules/signal-exit/dist/mjs/index.js
|
|
5702
|
+
// ../../node_modules/.bun/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/index.js
|
|
5703
5703
|
var processOk = (process3) => !!process3 && typeof process3 === "object" && typeof process3.removeListener === "function" && typeof process3.emit === "function" && typeof process3.reallyExit === "function" && typeof process3.listeners === "function" && typeof process3.kill === "function" && typeof process3.pid === "number" && typeof process3.on === "function";
|
|
5704
5704
|
var kExitEmitter = Symbol.for("signal-exit emitter");
|
|
5705
5705
|
var global = globalThis;
|
|
@@ -5897,10 +5897,10 @@ var {
|
|
|
5897
5897
|
unload
|
|
5898
5898
|
} = signalExitWrap(processOk(process3) ? new SignalExit(process3) : new SignalExitFallback);
|
|
5899
5899
|
|
|
5900
|
-
// ../../node_modules/@inquirer/core/dist/lib/screen-manager.js
|
|
5900
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/screen-manager.js
|
|
5901
5901
|
import { stripVTControlCharacters } from "util";
|
|
5902
5902
|
|
|
5903
|
-
// ../../node_modules/@inquirer/ansi/dist/index.js
|
|
5903
|
+
// ../../node_modules/.bun/@inquirer+ansi@2.0.7/node_modules/@inquirer/ansi/dist/index.js
|
|
5904
5904
|
var ESC2 = "\x1B[";
|
|
5905
5905
|
var cursorLeft = ESC2 + "G";
|
|
5906
5906
|
var cursorHide = ESC2 + "?25l";
|
|
@@ -5916,7 +5916,7 @@ var cursorTo = (x, y) => {
|
|
|
5916
5916
|
var eraseLine = ESC2 + "2K";
|
|
5917
5917
|
var eraseLines = (lines) => lines > 0 ? (eraseLine + cursorUp(1)).repeat(lines - 1) + eraseLine + cursorLeft : "";
|
|
5918
5918
|
|
|
5919
|
-
// ../../node_modules/@inquirer/core/dist/lib/screen-manager.js
|
|
5919
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/screen-manager.js
|
|
5920
5920
|
var height = (content) => content.split(`
|
|
5921
5921
|
`).length;
|
|
5922
5922
|
var lastLine = (content) => content.split(`
|
|
@@ -5982,7 +5982,7 @@ class ScreenManager {
|
|
|
5982
5982
|
}
|
|
5983
5983
|
}
|
|
5984
5984
|
|
|
5985
|
-
// ../../node_modules/@inquirer/core/dist/lib/promise-polyfill.js
|
|
5985
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/promise-polyfill.js
|
|
5986
5986
|
class PromisePolyfill extends Promise {
|
|
5987
5987
|
static withResolver() {
|
|
5988
5988
|
let resolve6;
|
|
@@ -5995,7 +5995,7 @@ class PromisePolyfill extends Promise {
|
|
|
5995
5995
|
}
|
|
5996
5996
|
}
|
|
5997
5997
|
|
|
5998
|
-
// ../../node_modules/@inquirer/core/dist/lib/create-prompt.js
|
|
5998
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/create-prompt.js
|
|
5999
5999
|
import path from "path";
|
|
6000
6000
|
var nativeSetImmediate = globalThis.setImmediate;
|
|
6001
6001
|
function getCallSites() {
|
|
@@ -6106,7 +6106,7 @@ function createPrompt(view) {
|
|
|
6106
6106
|
};
|
|
6107
6107
|
return prompt;
|
|
6108
6108
|
}
|
|
6109
|
-
// ../../node_modules/@inquirer/core/dist/lib/Separator.js
|
|
6109
|
+
// ../../node_modules/.bun/@inquirer+core@11.2.1+7cb241fc07b679d9/node_modules/@inquirer/core/dist/lib/Separator.js
|
|
6110
6110
|
import { styleText as styleText2 } from "util";
|
|
6111
6111
|
class Separator {
|
|
6112
6112
|
separator = styleText2("dim", Array.from({ length: 15 }).join(dist_default.line));
|
|
@@ -6120,7 +6120,7 @@ class Separator {
|
|
|
6120
6120
|
return Boolean(choice && typeof choice === "object" && "type" in choice && choice.type === "separator");
|
|
6121
6121
|
}
|
|
6122
6122
|
}
|
|
6123
|
-
// ../../node_modules/@inquirer/checkbox/dist/index.js
|
|
6123
|
+
// ../../node_modules/.bun/@inquirer+checkbox@5.2.1+7cb241fc07b679d9/node_modules/@inquirer/checkbox/dist/index.js
|
|
6124
6124
|
import { styleText as styleText3 } from "util";
|
|
6125
6125
|
var checkboxTheme = {
|
|
6126
6126
|
icon: {
|
|
@@ -7473,11 +7473,14 @@ async function retainTransactionConflicts(root, paths, conflictArtifacts = []) {
|
|
|
7473
7473
|
const current = await readTransactionState(root);
|
|
7474
7474
|
if (!current)
|
|
7475
7475
|
throw new Error("\u7F3A\u5C11\u53EF\u4FDD\u7559\u7684\u66F4\u65B0\u4E8B\u52A1\u72B6\u6001");
|
|
7476
|
+
const preservePaths = [
|
|
7477
|
+
...new Set([...current.preservePaths ?? [], ...paths])
|
|
7478
|
+
].filter((path2) => path2 !== updateStatePath);
|
|
7476
7479
|
const next = {
|
|
7477
7480
|
...current,
|
|
7478
|
-
preservePaths:
|
|
7481
|
+
preservePaths: preservePaths.length ? preservePaths : undefined,
|
|
7479
7482
|
conflictArtifacts: [
|
|
7480
|
-
...new Map([...current.conflictArtifacts ?? [], ...conflictArtifacts].map((artifact) => [artifact.artifactPath, artifact])).values()
|
|
7483
|
+
...new Map([...current.conflictArtifacts ?? [], ...conflictArtifacts].filter((artifact) => artifact.path !== updateStatePath).map((artifact) => [artifact.artifactPath, artifact])).values()
|
|
7481
7484
|
]
|
|
7482
7485
|
};
|
|
7483
7486
|
await publishTransactionState(root, current, next);
|
|
@@ -7729,6 +7732,8 @@ async function assertRestoredEntries(root, state, backups) {
|
|
|
7729
7732
|
async function unresolvedPreservePaths(root, backupPath, state) {
|
|
7730
7733
|
const unresolved = [];
|
|
7731
7734
|
for (const path2 of state.preservePaths ?? []) {
|
|
7735
|
+
if (path2 === updateStatePath)
|
|
7736
|
+
continue;
|
|
7732
7737
|
const entry = state.entries.find((candidate) => candidate.path === path2);
|
|
7733
7738
|
if (!entry) {
|
|
7734
7739
|
unresolved.push(path2);
|
|
@@ -8472,6 +8477,11 @@ var recipes = [
|
|
|
8472
8477
|
id: "starter-0.6.14-to-0.6.15",
|
|
8473
8478
|
from: "0.6.14",
|
|
8474
8479
|
to: "0.6.15"
|
|
8480
|
+
},
|
|
8481
|
+
{
|
|
8482
|
+
id: "starter-0.6.15-to-0.6.16",
|
|
8483
|
+
from: "0.6.15",
|
|
8484
|
+
to: "0.6.16"
|
|
8475
8485
|
}
|
|
8476
8486
|
];
|
|
8477
8487
|
function resolveRecipeChain(sourceVersion, targetVersion) {
|
|
@@ -11461,7 +11471,7 @@ function assertKnownModuleArguments(args) {
|
|
|
11461
11471
|
|
|
11462
11472
|
// src/module-lifecycle-confirmation.ts
|
|
11463
11473
|
import { createInterface as createInterface3 } from "readline/promises";
|
|
11464
|
-
async function confirmModuleMutation(args, dependencies, log) {
|
|
11474
|
+
async function confirmModuleMutation(args, dependencies, log, message = "\u786E\u8BA4\u6267\u884C\u4EE5\u4E0A\u6A21\u5757\u8BA1\u5212\uFF1F") {
|
|
11465
11475
|
if (args.includes("--yes"))
|
|
11466
11476
|
return true;
|
|
11467
11477
|
const isTTY = dependencies.isTTY ?? Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
@@ -11469,7 +11479,7 @@ async function confirmModuleMutation(args, dependencies, log) {
|
|
|
11469
11479
|
throw new Error("\u975E\u4EA4\u4E92\u73AF\u5883\u6B63\u5F0F\u53D8\u66F4\u5FC5\u987B\u4F20\u5165 --yes");
|
|
11470
11480
|
}
|
|
11471
11481
|
const confirm = dependencies.confirm ?? promptForConfirmation;
|
|
11472
|
-
const accepted = await confirm(
|
|
11482
|
+
const accepted = await confirm(message);
|
|
11473
11483
|
if (!accepted)
|
|
11474
11484
|
log("\u5DF2\u53D6\u6D88\uFF1A\u9879\u76EE\u672A\u88AB\u4FEE\u6539");
|
|
11475
11485
|
return accepted;
|
|
@@ -12180,6 +12190,750 @@ function readValue4(args, flag) {
|
|
|
12180
12190
|
return index >= 0 ? args[index + 1] : undefined;
|
|
12181
12191
|
}
|
|
12182
12192
|
|
|
12193
|
+
// src/package-command.ts
|
|
12194
|
+
import { resolve as resolve14 } from "path";
|
|
12195
|
+
|
|
12196
|
+
// src/package-configuration.ts
|
|
12197
|
+
import { createHash as createHash5 } from "crypto";
|
|
12198
|
+
import { readFile as readFile27 } from "fs/promises";
|
|
12199
|
+
import { isAbsolute as isAbsolute3, normalize, relative as relative8, resolve as resolve11, sep as sep6 } from "path";
|
|
12200
|
+
|
|
12201
|
+
// src/package-types.ts
|
|
12202
|
+
var packagePlatforms = ["linux/amd64", "linux/arm64"];
|
|
12203
|
+
|
|
12204
|
+
// src/package-configuration.ts
|
|
12205
|
+
var configurationFile = "windy.build.json";
|
|
12206
|
+
var shellCharacters = /[;&|`><\r\n$()'"]/u;
|
|
12207
|
+
var placeholder = /\$\{(platform|output\.directory|input\.([a-z][a-z0-9-]*))\}/gu;
|
|
12208
|
+
var secretName = /secret|token|password|credential|private[-_]?key|api[-_]?key/iu;
|
|
12209
|
+
var shellExecutables = new Set([
|
|
12210
|
+
"sh",
|
|
12211
|
+
"bash",
|
|
12212
|
+
"zsh",
|
|
12213
|
+
"fish",
|
|
12214
|
+
"cmd",
|
|
12215
|
+
"powershell",
|
|
12216
|
+
"pwsh"
|
|
12217
|
+
]);
|
|
12218
|
+
async function readPackageConfiguration(projectDirectory) {
|
|
12219
|
+
const path2 = resolve11(projectDirectory, configurationFile);
|
|
12220
|
+
let source;
|
|
12221
|
+
try {
|
|
12222
|
+
source = await readFile27(path2, "utf8");
|
|
12223
|
+
} catch (error) {
|
|
12224
|
+
if (error.code === "ENOENT") {
|
|
12225
|
+
throw new Error("\u672A\u58F0\u660E\u6253\u5305\u9002\u914D\u5668\uFF1A\u9879\u76EE\u6839\u76EE\u5F55\u7F3A\u5C11 windy.build.json", {
|
|
12226
|
+
cause: error
|
|
12227
|
+
});
|
|
12228
|
+
}
|
|
12229
|
+
throw error;
|
|
12230
|
+
}
|
|
12231
|
+
try {
|
|
12232
|
+
const configuration = parsePackageConfiguration(JSON.parse(source));
|
|
12233
|
+
return { configuration, digest: sha256(canonicalJson(configuration)) };
|
|
12234
|
+
} catch (error) {
|
|
12235
|
+
if (error instanceof SyntaxError)
|
|
12236
|
+
throw new Error("windy.build.json \u4E0D\u662F\u6709\u6548 JSON", { cause: error });
|
|
12237
|
+
throw error;
|
|
12238
|
+
}
|
|
12239
|
+
}
|
|
12240
|
+
function parsePackageConfiguration(value) {
|
|
12241
|
+
const root = object(value, "windy.build.json");
|
|
12242
|
+
rejectUnknown(root, ["schemaVersion", "product", "platforms", "profiles"], "windy.build.json");
|
|
12243
|
+
if (root.schemaVersion !== 1)
|
|
12244
|
+
throw new Error("windy.build.json \u53EA\u652F\u6301 schemaVersion: 1");
|
|
12245
|
+
const platforms = array(root.platforms, "platforms").map((item) => {
|
|
12246
|
+
const platform = string(item, "platforms[]");
|
|
12247
|
+
if (!packagePlatforms.includes(platform)) {
|
|
12248
|
+
throw new Error(`\u4E0D\u652F\u6301\u7684\u76EE\u6807\u5E73\u53F0\uFF1A${platform}`);
|
|
12249
|
+
}
|
|
12250
|
+
return platform;
|
|
12251
|
+
});
|
|
12252
|
+
unique2(platforms, "platforms");
|
|
12253
|
+
if (!platforms.length)
|
|
12254
|
+
throw new Error("platforms \u4E0D\u80FD\u4E3A\u7A7A");
|
|
12255
|
+
const profiles = array(root.profiles, "profiles").map(parseProfile);
|
|
12256
|
+
unique2(profiles.map(({ key }) => key), "profile key");
|
|
12257
|
+
if (!profiles.length)
|
|
12258
|
+
throw new Error("profiles \u4E0D\u80FD\u4E3A\u7A7A");
|
|
12259
|
+
return {
|
|
12260
|
+
schemaVersion: 1,
|
|
12261
|
+
product: string(root.product, "product"),
|
|
12262
|
+
platforms,
|
|
12263
|
+
profiles
|
|
12264
|
+
};
|
|
12265
|
+
}
|
|
12266
|
+
function parseProfile(value) {
|
|
12267
|
+
const profile = object(value, "profile");
|
|
12268
|
+
rejectUnknown(profile, [
|
|
12269
|
+
"key",
|
|
12270
|
+
"label",
|
|
12271
|
+
"description",
|
|
12272
|
+
"inputs",
|
|
12273
|
+
"command",
|
|
12274
|
+
"output",
|
|
12275
|
+
"requirements"
|
|
12276
|
+
], "profile");
|
|
12277
|
+
const key = identifier(profile.key, "profile key");
|
|
12278
|
+
const inputs = array(profile.inputs, `profile ${key}.inputs`).map((item) => parseInput(item, key));
|
|
12279
|
+
unique2(inputs.map(({ key: inputKey }) => inputKey), `profile ${key} input key`);
|
|
12280
|
+
const command = object(profile.command, `profile ${key}.command`);
|
|
12281
|
+
rejectUnknown(command, ["executable", "arguments"], `profile ${key}.command`);
|
|
12282
|
+
const executable = string(command.executable, `profile ${key}.command.executable`);
|
|
12283
|
+
if (shellExecutables.has(executable.toLowerCase()) || shellCharacters.test(executable) || !/^[a-zA-Z0-9._-]+$/u.test(executable)) {
|
|
12284
|
+
throw new Error(`profile ${key} \u7684 command.executable \u5FC5\u987B\u662F PATH \u4E2D\u7684\u5B89\u5168\u7A0B\u5E8F\u540D`);
|
|
12285
|
+
}
|
|
12286
|
+
const commandArguments = array(command.arguments, `profile ${key}.command.arguments`).map((item) => {
|
|
12287
|
+
const argument = string(item, `profile ${key}.command.arguments[]`);
|
|
12288
|
+
validatePlaceholders(argument, inputs, key);
|
|
12289
|
+
if (shellCharacters.test(argument.replace(placeholder, ""))) {
|
|
12290
|
+
throw new Error(`profile ${key} \u7684 command.arguments \u4E0D\u5141\u8BB8 Shell \u5B57\u7B26\u4E32`);
|
|
12291
|
+
}
|
|
12292
|
+
return argument;
|
|
12293
|
+
});
|
|
12294
|
+
const output = object(profile.output, `profile ${key}.output`);
|
|
12295
|
+
rejectUnknown(output, ["directory", "artifactSuffix"], `profile ${key}.output`);
|
|
12296
|
+
const directory = string(output.directory, `profile ${key}.output.directory`);
|
|
12297
|
+
if (!isSafeRelativePath(directory) || !/^[a-zA-Z0-9._/-]+$/u.test(directory))
|
|
12298
|
+
throw new Error(`profile ${key} \u7684 output.directory \u8D8A\u51FA\u9879\u76EE\u8FB9\u754C`);
|
|
12299
|
+
const artifactSuffix = string(output.artifactSuffix, `profile ${key}.output.artifactSuffix`);
|
|
12300
|
+
if (!artifactSuffix.startsWith(".") || shellCharacters.test(artifactSuffix) || !/^\.[a-zA-Z0-9._-]+$/u.test(artifactSuffix)) {
|
|
12301
|
+
throw new Error(`profile ${key} \u7684 output.artifactSuffix \u975E\u6CD5`);
|
|
12302
|
+
}
|
|
12303
|
+
const requirements = object(profile.requirements, `profile ${key}.requirements`);
|
|
12304
|
+
rejectUnknown(requirements, ["docker", "buildx"], `profile ${key}.requirements`);
|
|
12305
|
+
const docker = boolean(requirements.docker, `profile ${key}.requirements.docker`);
|
|
12306
|
+
const buildx = boolean(requirements.buildx, `profile ${key}.requirements.buildx`);
|
|
12307
|
+
if (buildx && !docker)
|
|
12308
|
+
throw new Error(`profile ${key} \u7684 buildx \u9700\u8981 docker`);
|
|
12309
|
+
return {
|
|
12310
|
+
key,
|
|
12311
|
+
label: string(profile.label, `profile ${key}.label`),
|
|
12312
|
+
description: string(profile.description, `profile ${key}.description`),
|
|
12313
|
+
inputs,
|
|
12314
|
+
command: { executable, arguments: commandArguments },
|
|
12315
|
+
output: { directory, artifactSuffix },
|
|
12316
|
+
requirements: { docker, buildx }
|
|
12317
|
+
};
|
|
12318
|
+
}
|
|
12319
|
+
function parseInput(value, profile) {
|
|
12320
|
+
const input = object(value, `profile ${profile}.input`);
|
|
12321
|
+
rejectUnknown(input, ["key", "label", "required", "pattern"], `profile ${profile}.input`);
|
|
12322
|
+
const key = identifier(input.key, `profile ${profile}.input.key`);
|
|
12323
|
+
if (secretName.test(key))
|
|
12324
|
+
throw new Error(`profile ${profile} \u4E0D\u5141\u8BB8 secret \u8F93\u5165\uFF1A${key}`);
|
|
12325
|
+
const pattern = input.pattern === undefined ? undefined : string(input.pattern, `profile ${profile}.input.pattern`);
|
|
12326
|
+
if (pattern) {
|
|
12327
|
+
try {
|
|
12328
|
+
new RegExp(pattern, "u");
|
|
12329
|
+
} catch {
|
|
12330
|
+
throw new Error(`profile ${profile} \u7684\u8F93\u5165 pattern \u975E\u6CD5`);
|
|
12331
|
+
}
|
|
12332
|
+
}
|
|
12333
|
+
return {
|
|
12334
|
+
key,
|
|
12335
|
+
label: string(input.label, `profile ${profile}.input.label`),
|
|
12336
|
+
required: boolean(input.required, `profile ${profile}.input.required`),
|
|
12337
|
+
pattern
|
|
12338
|
+
};
|
|
12339
|
+
}
|
|
12340
|
+
function validatePlaceholders(value, inputs, profile) {
|
|
12341
|
+
const tokens = [...value.matchAll(placeholder)];
|
|
12342
|
+
for (const token of tokens) {
|
|
12343
|
+
const inputKey = token[2];
|
|
12344
|
+
if (inputKey && !inputs.some(({ key }) => key === inputKey)) {
|
|
12345
|
+
throw new Error(`profile ${profile} \u4F7F\u7528\u672A\u58F0\u660E\u5360\u4F4D\u7B26\uFF1Ainput.${inputKey}`);
|
|
12346
|
+
}
|
|
12347
|
+
}
|
|
12348
|
+
if (value.replace(placeholder, "").includes("${"))
|
|
12349
|
+
throw new Error(`profile ${profile} \u5305\u542B\u672A\u58F0\u660E\u5360\u4F4D\u7B26`);
|
|
12350
|
+
}
|
|
12351
|
+
function object(value, label) {
|
|
12352
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
12353
|
+
throw new Error(`${label} \u5FC5\u987B\u662F\u5BF9\u8C61`);
|
|
12354
|
+
return value;
|
|
12355
|
+
}
|
|
12356
|
+
function array(value, label) {
|
|
12357
|
+
if (!Array.isArray(value))
|
|
12358
|
+
throw new Error(`${label} \u5FC5\u987B\u662F\u6570\u7EC4`);
|
|
12359
|
+
return value;
|
|
12360
|
+
}
|
|
12361
|
+
function string(value, label) {
|
|
12362
|
+
if (typeof value !== "string" || !value.trim())
|
|
12363
|
+
throw new Error(`${label} \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`);
|
|
12364
|
+
return value;
|
|
12365
|
+
}
|
|
12366
|
+
function boolean(value, label) {
|
|
12367
|
+
if (typeof value !== "boolean")
|
|
12368
|
+
throw new Error(`${label} \u5FC5\u987B\u662F\u5E03\u5C14\u503C`);
|
|
12369
|
+
return value;
|
|
12370
|
+
}
|
|
12371
|
+
function identifier(value, label) {
|
|
12372
|
+
const result2 = string(value, label);
|
|
12373
|
+
if (!/^[a-z][a-z0-9-]*$/u.test(result2))
|
|
12374
|
+
throw new Error(`${label} \u5FC5\u987B\u662F\u5C0F\u5199 kebab-case`);
|
|
12375
|
+
return result2;
|
|
12376
|
+
}
|
|
12377
|
+
function unique2(values, label) {
|
|
12378
|
+
if (new Set(values).size !== values.length)
|
|
12379
|
+
throw new Error(`${label} \u4E0D\u80FD\u91CD\u590D`);
|
|
12380
|
+
}
|
|
12381
|
+
function rejectUnknown(source, allowed, label) {
|
|
12382
|
+
for (const key of Object.keys(source))
|
|
12383
|
+
if (!allowed.includes(key))
|
|
12384
|
+
throw new Error(`${label} \u5305\u542B\u672A\u77E5\u5B57\u6BB5\uFF1A${key}`);
|
|
12385
|
+
}
|
|
12386
|
+
function isSafeRelativePath(value) {
|
|
12387
|
+
return Boolean(value) && normalize(value) !== "." && !isAbsolute3(value) && !value.includes("\\") && !relative8(".", resolve11(".", value)).split(sep6).includes("..") && !normalize(value).startsWith("..");
|
|
12388
|
+
}
|
|
12389
|
+
function canonicalJson(value) {
|
|
12390
|
+
if (Array.isArray(value))
|
|
12391
|
+
return `[${value.map(canonicalJson).join(",")}]`;
|
|
12392
|
+
if (value && typeof value === "object")
|
|
12393
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`).join(",")}}`;
|
|
12394
|
+
return JSON.stringify(value);
|
|
12395
|
+
}
|
|
12396
|
+
function sha256(value) {
|
|
12397
|
+
return createHash5("sha256").update(value).digest("hex");
|
|
12398
|
+
}
|
|
12399
|
+
|
|
12400
|
+
// src/package-execution.ts
|
|
12401
|
+
import { createHash as createHash6 } from "crypto";
|
|
12402
|
+
import { readdir as readdir10, realpath as realpath2, stat as stat3 } from "fs/promises";
|
|
12403
|
+
import { relative as relative9, resolve as resolve12 } from "path";
|
|
12404
|
+
var bunPackageProcess = {
|
|
12405
|
+
async run(command, args, cwd) {
|
|
12406
|
+
const child = Bun.spawn([command, ...args], {
|
|
12407
|
+
cwd,
|
|
12408
|
+
env: withoutParentGitRepository(process.env),
|
|
12409
|
+
stdin: "inherit",
|
|
12410
|
+
stdout: "pipe",
|
|
12411
|
+
stderr: "pipe"
|
|
12412
|
+
});
|
|
12413
|
+
const [stdout2, stderr, code] = await Promise.all([
|
|
12414
|
+
new Response(child.stdout).text(),
|
|
12415
|
+
new Response(child.stderr).text(),
|
|
12416
|
+
child.exited
|
|
12417
|
+
]);
|
|
12418
|
+
return { code, stdout: stdout2, stderr };
|
|
12419
|
+
}
|
|
12420
|
+
};
|
|
12421
|
+
async function readPackageSource(projectDirectory, process4 = bunPackageProcess, ignoredPaths = []) {
|
|
12422
|
+
const revision = await currentGitRevision(projectDirectory, process4);
|
|
12423
|
+
const status = await assertCommand(process4, "git", ["status", "--porcelain"], projectDirectory, "\u65E0\u6CD5\u8BFB\u53D6 Git \u5DE5\u4F5C\u533A\u72B6\u6001");
|
|
12424
|
+
const root = await realpath2(projectDirectory);
|
|
12425
|
+
const ignored = new Set(ignoredPaths.map((path2) => relative9(root, path2)));
|
|
12426
|
+
const dirty = status.stdout.trim().split(`
|
|
12427
|
+
`).filter(Boolean).filter((line) => !ignored.has(line.slice(3)));
|
|
12428
|
+
if (dirty.length)
|
|
12429
|
+
throw new Error("Git \u5DE5\u4F5C\u533A\u5FC5\u987B\u5E72\u51C0\u624D\u80FD\u51BB\u7ED3\u6216\u6267\u884C\u6253\u5305\u8BA1\u5212");
|
|
12430
|
+
return revision;
|
|
12431
|
+
}
|
|
12432
|
+
async function currentGitRevision(projectDirectory, process4 = bunPackageProcess) {
|
|
12433
|
+
const revision = await assertCommand(process4, "git", ["rev-parse", "HEAD"], projectDirectory, "\u65E0\u6CD5\u8BFB\u53D6 Git SHA");
|
|
12434
|
+
return revision.stdout.trim();
|
|
12435
|
+
}
|
|
12436
|
+
async function preflightPackage(plan, projectDirectory, process4 = bunPackageProcess, ignoredPaths = []) {
|
|
12437
|
+
const sourceRevision = await readPackageSource(projectDirectory, process4, ignoredPaths);
|
|
12438
|
+
if (sourceRevision !== plan.source.revision)
|
|
12439
|
+
throw new Error("\u6267\u884C\u524D\u6E90\u7801 SHA \u5DF2\u6F02\u79FB\uFF0C\u62D2\u7EDD\u6267\u884C");
|
|
12440
|
+
await assertCommand(process4, "bun", ["--version"], projectDirectory, "\u672A\u68C0\u6D4B\u5230\u53EF\u7528\u7684 Bun");
|
|
12441
|
+
if (!plan.requirements.docker)
|
|
12442
|
+
return;
|
|
12443
|
+
await assertCommand(process4, "docker", ["version", "--format", "{{.Server.Version}}"], projectDirectory, "\u672A\u68C0\u6D4B\u5230\u53EF\u7528\u7684 Docker Server");
|
|
12444
|
+
if (!plan.requirements.buildx)
|
|
12445
|
+
return;
|
|
12446
|
+
const buildx = await assertCommand(process4, "docker", ["buildx", "inspect"], projectDirectory, "\u672A\u68C0\u6D4B\u5230\u53EF\u7528\u7684 Docker Buildx builder");
|
|
12447
|
+
if (!buildx.stdout.includes(plan.platform) && !buildx.stderr.includes(plan.platform)) {
|
|
12448
|
+
throw new Error(`\u5F53\u524D Buildx builder \u4E0D\u652F\u6301 ${plan.platform}`);
|
|
12449
|
+
}
|
|
12450
|
+
}
|
|
12451
|
+
async function executePackagePlan(plan, projectDirectory, process4 = bunPackageProcess, ignoredPaths = []) {
|
|
12452
|
+
const beforeRevision = await readPackageSource(projectDirectory, process4, ignoredPaths);
|
|
12453
|
+
if (beforeRevision !== plan.source.revision)
|
|
12454
|
+
throw new Error("\u6267\u884C\u524D\u6E90\u7801 SHA \u5DF2\u6F02\u79FB\uFF0C\u62D2\u7EDD\u6267\u884C");
|
|
12455
|
+
const projectRoot = await realpath2(projectDirectory);
|
|
12456
|
+
const outputDirectory = await guardedOutputDirectory(projectDirectory, plan.output.directory, false);
|
|
12457
|
+
const before = new Map((await artifacts(outputDirectory, plan.output.artifactSuffix, projectRoot)).map(({ path: path2, sha256: sha2562 }) => [path2, sha2562]));
|
|
12458
|
+
const command = await process4.run(plan.command.executable, plan.command.arguments, projectDirectory);
|
|
12459
|
+
if (command.code !== 0)
|
|
12460
|
+
return failed(beforeRevision, `\u6784\u5EFA\u547D\u4EE4\u9000\u51FA\u7801 ${command.code}\uFF1A${details(command)}`);
|
|
12461
|
+
const afterRevision = await currentGitRevision(projectDirectory, process4);
|
|
12462
|
+
if (afterRevision !== beforeRevision)
|
|
12463
|
+
return failed(afterRevision, "\u6784\u5EFA\u671F\u95F4\u6E90\u7801 SHA \u53D1\u751F\u6F02\u79FB");
|
|
12464
|
+
const finalOutput = await guardedOutputDirectory(projectDirectory, plan.output.directory, true);
|
|
12465
|
+
const after = await artifacts(finalOutput, plan.output.artifactSuffix, projectRoot);
|
|
12466
|
+
const changed = after.filter((artifact) => before.get(artifact.path) !== artifact.sha256);
|
|
12467
|
+
const sourceDrift = await sourceDriftAfterBuild(process4, projectDirectory, ignoredPaths, changed.map(({ path: path2 }) => path2));
|
|
12468
|
+
if (sourceDrift)
|
|
12469
|
+
return failed(afterRevision, sourceDrift, changed);
|
|
12470
|
+
if (changed.length !== 1)
|
|
12471
|
+
return failed(afterRevision, `\u9884\u671F\u6070\u597D\u4E00\u4E2A\u65B0\u589E\u6216\u53D8\u66F4\u4EA7\u7269\uFF0C\u5B9E\u9645\u53D1\u73B0 ${changed.length} \u4E2A`, changed);
|
|
12472
|
+
return {
|
|
12473
|
+
status: "succeeded",
|
|
12474
|
+
completedAt: new Date().toISOString(),
|
|
12475
|
+
sourceRevision: afterRevision,
|
|
12476
|
+
artifacts: changed
|
|
12477
|
+
};
|
|
12478
|
+
}
|
|
12479
|
+
async function assertCommand(process4, command, args, cwd, message) {
|
|
12480
|
+
const result2 = await process4.run(command, args, cwd);
|
|
12481
|
+
if (result2.code !== 0)
|
|
12482
|
+
throw new Error(`${message}\uFF1A${details(result2)}`);
|
|
12483
|
+
return result2;
|
|
12484
|
+
}
|
|
12485
|
+
async function guardedOutputDirectory(projectDirectory, directory, mustExist) {
|
|
12486
|
+
const root = await realpath2(projectDirectory);
|
|
12487
|
+
const output = resolve12(root, directory);
|
|
12488
|
+
if (!within(root, output))
|
|
12489
|
+
throw new Error("\u8F93\u51FA\u76EE\u5F55\u8D8A\u51FA\u9879\u76EE\u8FB9\u754C");
|
|
12490
|
+
try {
|
|
12491
|
+
const actual = await realpath2(output);
|
|
12492
|
+
if (!within(root, actual))
|
|
12493
|
+
throw new Error("\u8F93\u51FA\u76EE\u5F55\u8D8A\u51FA\u9879\u76EE\u8FB9\u754C");
|
|
12494
|
+
return actual;
|
|
12495
|
+
} catch (error) {
|
|
12496
|
+
if (error instanceof Error && error.message === "\u8F93\u51FA\u76EE\u5F55\u8D8A\u51FA\u9879\u76EE\u8FB9\u754C")
|
|
12497
|
+
throw error;
|
|
12498
|
+
if (mustExist)
|
|
12499
|
+
throw new Error("\u6784\u5EFA\u6CA1\u6709\u4EA7\u751F\u58F0\u660E\u7684\u8F93\u51FA\u76EE\u5F55", { cause: error });
|
|
12500
|
+
return output;
|
|
12501
|
+
}
|
|
12502
|
+
}
|
|
12503
|
+
async function artifacts(directory, suffix, projectDirectory) {
|
|
12504
|
+
try {
|
|
12505
|
+
await stat3(directory);
|
|
12506
|
+
} catch {
|
|
12507
|
+
return [];
|
|
12508
|
+
}
|
|
12509
|
+
const entries = await readdir10(directory, {
|
|
12510
|
+
recursive: true,
|
|
12511
|
+
withFileTypes: true
|
|
12512
|
+
});
|
|
12513
|
+
return await Promise.all(entries.filter((entry) => entry.isFile() && entry.name.endsWith(suffix)).map(async (entry) => {
|
|
12514
|
+
const path2 = resolve12(directory, entry.parentPath, entry.name);
|
|
12515
|
+
return {
|
|
12516
|
+
path: relative9(projectDirectory, path2),
|
|
12517
|
+
sha256: createHash6("sha256").update(Buffer.from(await Bun.file(path2).arrayBuffer())).digest("hex")
|
|
12518
|
+
};
|
|
12519
|
+
}));
|
|
12520
|
+
}
|
|
12521
|
+
async function sourceDriftAfterBuild(process4, projectDirectory, ignoredPaths, generatedArtifacts) {
|
|
12522
|
+
const status = await process4.run("git", ["status", "--porcelain"], projectDirectory);
|
|
12523
|
+
if (status.code !== 0)
|
|
12524
|
+
return `\u65E0\u6CD5\u68C0\u67E5\u6784\u5EFA\u540E\u7684\u6E90\u7801\u6F02\u79FB\uFF1A${details(status)}`;
|
|
12525
|
+
const root = await realpath2(projectDirectory);
|
|
12526
|
+
const ignored = new Set(ignoredPaths.map((path2) => relative9(root, path2)));
|
|
12527
|
+
const generated = new Set(generatedArtifacts);
|
|
12528
|
+
const drift = status.stdout.trim().split(`
|
|
12529
|
+
`).filter(Boolean).filter((line) => {
|
|
12530
|
+
const path2 = line.slice(3);
|
|
12531
|
+
return !ignored.has(path2) && !(line.startsWith("?? ") && generated.has(path2));
|
|
12532
|
+
});
|
|
12533
|
+
return drift.length ? "\u6784\u5EFA\u671F\u95F4\u6E90\u7801\u5DE5\u4F5C\u533A\u53D1\u751F\u6F02\u79FB" : undefined;
|
|
12534
|
+
}
|
|
12535
|
+
function within(root, path2) {
|
|
12536
|
+
const result2 = relative9(root, path2);
|
|
12537
|
+
return Boolean(result2) && !result2.startsWith("..") && result2 !== "..";
|
|
12538
|
+
}
|
|
12539
|
+
function details(result2) {
|
|
12540
|
+
return (result2.stderr || result2.stdout).trim() || "\u672A\u63D0\u4F9B\u8BCA\u65AD\u4FE1\u606F";
|
|
12541
|
+
}
|
|
12542
|
+
function failed(sourceRevision, diagnostic, artifacts2 = []) {
|
|
12543
|
+
return {
|
|
12544
|
+
status: "failed",
|
|
12545
|
+
completedAt: new Date().toISOString(),
|
|
12546
|
+
sourceRevision,
|
|
12547
|
+
artifacts: artifacts2,
|
|
12548
|
+
diagnostic
|
|
12549
|
+
};
|
|
12550
|
+
}
|
|
12551
|
+
|
|
12552
|
+
// src/package-plan.ts
|
|
12553
|
+
import { readFile as readFile28, realpath as realpath3, writeFile as writeFile15 } from "fs/promises";
|
|
12554
|
+
import { dirname as dirname12, relative as relative10, resolve as resolve13 } from "path";
|
|
12555
|
+
function resolvePackageProfile(configuration, profileKey) {
|
|
12556
|
+
const profile = configuration.profiles.find(({ key }) => key === profileKey);
|
|
12557
|
+
if (!profile)
|
|
12558
|
+
throw new Error(`\u672A\u58F0\u660E\u7684\u6253\u5305 profile\uFF1A${profileKey}`);
|
|
12559
|
+
return profile;
|
|
12560
|
+
}
|
|
12561
|
+
function validatePackageInputs(profile, supplied) {
|
|
12562
|
+
for (const key of Object.keys(supplied)) {
|
|
12563
|
+
if (!profile.inputs.some((input) => input.key === key)) {
|
|
12564
|
+
throw new Error(`profile ${profile.key} \u4E0D\u63A5\u53D7\u8F93\u5165\uFF1A${key}`);
|
|
12565
|
+
}
|
|
12566
|
+
}
|
|
12567
|
+
const validated = {};
|
|
12568
|
+
for (const input of profile.inputs) {
|
|
12569
|
+
const value = supplied[input.key];
|
|
12570
|
+
if (input.required && !value)
|
|
12571
|
+
throw new Error(`profile ${profile.key} \u7F3A\u5C11\u5FC5\u586B\u8F93\u5165\uFF1A${input.key}`);
|
|
12572
|
+
if (value === undefined)
|
|
12573
|
+
continue;
|
|
12574
|
+
if (input.pattern && !new RegExp(input.pattern, "u").test(value)) {
|
|
12575
|
+
throw new Error(`\u8F93\u5165 ${input.key} \u4E0D\u7B26\u5408\u58F0\u660E\u7684\u683C\u5F0F`);
|
|
12576
|
+
}
|
|
12577
|
+
validated[input.key] = value;
|
|
12578
|
+
}
|
|
12579
|
+
return validated;
|
|
12580
|
+
}
|
|
12581
|
+
function createFrozenPackagePlan(input) {
|
|
12582
|
+
const {
|
|
12583
|
+
configuration,
|
|
12584
|
+
configDigest,
|
|
12585
|
+
sourceRevision,
|
|
12586
|
+
profile,
|
|
12587
|
+
platform,
|
|
12588
|
+
inputs
|
|
12589
|
+
} = input;
|
|
12590
|
+
return {
|
|
12591
|
+
schemaVersion: 1,
|
|
12592
|
+
product: configuration.product,
|
|
12593
|
+
configDigest,
|
|
12594
|
+
source: { revision: sourceRevision, clean: true },
|
|
12595
|
+
profile: profile.key,
|
|
12596
|
+
platform,
|
|
12597
|
+
inputs,
|
|
12598
|
+
command: {
|
|
12599
|
+
executable: profile.command.executable,
|
|
12600
|
+
arguments: profile.command.arguments.map((argument) => expand(argument, platform, profile.output.directory, inputs))
|
|
12601
|
+
},
|
|
12602
|
+
output: profile.output,
|
|
12603
|
+
requirements: profile.requirements,
|
|
12604
|
+
createdAt: new Date().toISOString()
|
|
12605
|
+
};
|
|
12606
|
+
}
|
|
12607
|
+
function assertFrozenPlanCurrent(input) {
|
|
12608
|
+
const { plan, configuration, configDigest, sourceRevision } = input;
|
|
12609
|
+
if (plan.product !== configuration.product)
|
|
12610
|
+
throw new Error("\u51BB\u7ED3\u8BA1\u5212\u7684\u4EA7\u54C1\u6807\u8BC6\u4E0E\u5F53\u524D\u9879\u76EE\u4E0D\u4E00\u81F4");
|
|
12611
|
+
if (plan.configDigest !== configDigest)
|
|
12612
|
+
throw new Error("windy.build.json \u5DF2\u6F02\u79FB\uFF0C\u62D2\u7EDD\u6267\u884C\u51BB\u7ED3\u8BA1\u5212");
|
|
12613
|
+
if (plan.source.revision !== sourceRevision)
|
|
12614
|
+
throw new Error("\u6E90\u7801 SHA \u5DF2\u6F02\u79FB\uFF0C\u62D2\u7EDD\u6267\u884C\u51BB\u7ED3\u8BA1\u5212");
|
|
12615
|
+
if (!configuration.platforms.includes(plan.platform))
|
|
12616
|
+
throw new Error("\u51BB\u7ED3\u8BA1\u5212\u7684\u76EE\u6807\u5E73\u53F0\u5DF2\u4E0D\u88AB\u5F53\u524D\u914D\u7F6E\u652F\u6301");
|
|
12617
|
+
const profile = resolvePackageProfile(configuration, plan.profile);
|
|
12618
|
+
const inputs = validatePackageInputs(profile, plan.inputs);
|
|
12619
|
+
const expected = createFrozenPackagePlan({
|
|
12620
|
+
configuration,
|
|
12621
|
+
configDigest,
|
|
12622
|
+
sourceRevision,
|
|
12623
|
+
profile,
|
|
12624
|
+
platform: plan.platform,
|
|
12625
|
+
inputs
|
|
12626
|
+
});
|
|
12627
|
+
if (canonicalJson(withoutCreatedAt(expected)) !== canonicalJson(withoutCreatedAt(plan))) {
|
|
12628
|
+
throw new Error("\u51BB\u7ED3\u8BA1\u5212\u4E0E\u5F53\u524D\u6784\u5EFA\u914D\u7F6E\u4E0D\u4E00\u81F4\uFF0C\u62D2\u7EDD\u6267\u884C");
|
|
12629
|
+
}
|
|
12630
|
+
}
|
|
12631
|
+
async function readFrozenPackagePlan(path2) {
|
|
12632
|
+
try {
|
|
12633
|
+
return parseFrozenPackagePlan(JSON.parse(await readFile28(path2, "utf8")));
|
|
12634
|
+
} catch (error) {
|
|
12635
|
+
if (error instanceof Error && error.message.startsWith("\u51BB\u7ED3\u6253\u5305\u8BA1\u5212"))
|
|
12636
|
+
throw error;
|
|
12637
|
+
throw new Error("\u65E0\u6CD5\u8BFB\u53D6\u6709\u6548\u7684\u51BB\u7ED3\u6253\u5305\u8BA1\u5212", { cause: error });
|
|
12638
|
+
}
|
|
12639
|
+
}
|
|
12640
|
+
async function writeFrozenPackagePlan(path2, plan) {
|
|
12641
|
+
await writeFile15(path2, `${JSON.stringify(plan, null, 2)}
|
|
12642
|
+
`, "utf8");
|
|
12643
|
+
}
|
|
12644
|
+
async function resolvePackagePlanPath(projectDirectory, requested) {
|
|
12645
|
+
if (!isSafeRelativePath(requested) || !/^[a-zA-Z0-9._/-]+$/u.test(requested))
|
|
12646
|
+
throw new Error("\u8BA1\u5212\u6587\u4EF6\u8DEF\u5F84\u8D8A\u51FA\u9879\u76EE\u8FB9\u754C");
|
|
12647
|
+
const root = await realpath3(projectDirectory);
|
|
12648
|
+
const path2 = resolve13(root, requested);
|
|
12649
|
+
if (relative10(root, path2).startsWith(".."))
|
|
12650
|
+
throw new Error("\u8BA1\u5212\u6587\u4EF6\u8DEF\u5F84\u8D8A\u51FA\u9879\u76EE\u8FB9\u754C");
|
|
12651
|
+
let parent;
|
|
12652
|
+
try {
|
|
12653
|
+
parent = await realpath3(dirname12(path2));
|
|
12654
|
+
} catch {
|
|
12655
|
+
throw new Error("\u8BA1\u5212\u6587\u4EF6\u7236\u76EE\u5F55\u5FC5\u987B\u5DF2\u5B58\u5728\u4E14\u4F4D\u4E8E\u9879\u76EE\u8FB9\u754C\u5185");
|
|
12656
|
+
}
|
|
12657
|
+
if (!withinOrEqual(root, parent))
|
|
12658
|
+
throw new Error("\u8BA1\u5212\u6587\u4EF6\u8DEF\u5F84\u8D8A\u51FA\u9879\u76EE\u8FB9\u754C");
|
|
12659
|
+
try {
|
|
12660
|
+
if (!withinOrEqual(root, await realpath3(path2))) {
|
|
12661
|
+
throw new Error("\u8BA1\u5212\u6587\u4EF6\u8DEF\u5F84\u8D8A\u51FA\u9879\u76EE\u8FB9\u754C");
|
|
12662
|
+
}
|
|
12663
|
+
} catch (error) {
|
|
12664
|
+
if (error instanceof Error && error.message === "\u8BA1\u5212\u6587\u4EF6\u8DEF\u5F84\u8D8A\u51FA\u9879\u76EE\u8FB9\u754C")
|
|
12665
|
+
throw error;
|
|
12666
|
+
}
|
|
12667
|
+
return path2;
|
|
12668
|
+
}
|
|
12669
|
+
function expand(value, platform, outputDirectory, inputs) {
|
|
12670
|
+
return value.replace(/\$\{(platform|output\.directory|input\.([a-z][a-z0-9-]*))\}/gu, (_, token, inputKey) => {
|
|
12671
|
+
if (token === "platform")
|
|
12672
|
+
return platform;
|
|
12673
|
+
if (token === "output.directory")
|
|
12674
|
+
return outputDirectory;
|
|
12675
|
+
return inputs[inputKey] ?? "";
|
|
12676
|
+
});
|
|
12677
|
+
}
|
|
12678
|
+
function withoutCreatedAt(plan) {
|
|
12679
|
+
const { createdAt: _createdAt, ...rest } = plan;
|
|
12680
|
+
return rest;
|
|
12681
|
+
}
|
|
12682
|
+
function withinOrEqual(root, path2) {
|
|
12683
|
+
const result2 = relative10(root, path2);
|
|
12684
|
+
return !result2 || !result2.startsWith("..") && result2 !== "..";
|
|
12685
|
+
}
|
|
12686
|
+
function parseFrozenPackagePlan(value) {
|
|
12687
|
+
const plan = record(value, "\u51BB\u7ED3\u6253\u5305\u8BA1\u5212");
|
|
12688
|
+
rejectUnknown2(plan, [
|
|
12689
|
+
"schemaVersion",
|
|
12690
|
+
"product",
|
|
12691
|
+
"configDigest",
|
|
12692
|
+
"source",
|
|
12693
|
+
"profile",
|
|
12694
|
+
"platform",
|
|
12695
|
+
"inputs",
|
|
12696
|
+
"command",
|
|
12697
|
+
"output",
|
|
12698
|
+
"requirements",
|
|
12699
|
+
"createdAt",
|
|
12700
|
+
"result"
|
|
12701
|
+
], "\u51BB\u7ED3\u6253\u5305\u8BA1\u5212");
|
|
12702
|
+
if (plan.result !== undefined)
|
|
12703
|
+
throw new Error("\u5DF2\u5B8C\u6210\u7684\u6253\u5305\u8BA1\u5212\u4E0D\u80FD\u518D\u6B21\u6267\u884C");
|
|
12704
|
+
const source = record(plan.source, "\u51BB\u7ED3\u6253\u5305\u8BA1\u5212 source");
|
|
12705
|
+
rejectUnknown2(source, ["revision", "clean"], "\u51BB\u7ED3\u6253\u5305\u8BA1\u5212 source");
|
|
12706
|
+
const command = record(plan.command, "\u51BB\u7ED3\u6253\u5305\u8BA1\u5212 command");
|
|
12707
|
+
rejectUnknown2(command, ["executable", "arguments"], "\u51BB\u7ED3\u6253\u5305\u8BA1\u5212 command");
|
|
12708
|
+
const output = record(plan.output, "\u51BB\u7ED3\u6253\u5305\u8BA1\u5212 output");
|
|
12709
|
+
rejectUnknown2(output, ["directory", "artifactSuffix"], "\u51BB\u7ED3\u6253\u5305\u8BA1\u5212 output");
|
|
12710
|
+
const requirements = record(plan.requirements, "\u51BB\u7ED3\u6253\u5305\u8BA1\u5212 requirements");
|
|
12711
|
+
rejectUnknown2(requirements, ["docker", "buildx"], "\u51BB\u7ED3\u6253\u5305\u8BA1\u5212 requirements");
|
|
12712
|
+
const inputs = record(plan.inputs, "\u51BB\u7ED3\u6253\u5305\u8BA1\u5212 inputs");
|
|
12713
|
+
for (const [key, input] of Object.entries(inputs)) {
|
|
12714
|
+
if (!/^[a-z][a-z0-9-]*$/u.test(key) || typeof input !== "string") {
|
|
12715
|
+
throw new Error("\u51BB\u7ED3\u6253\u5305\u8BA1\u5212 inputs \u975E\u6CD5");
|
|
12716
|
+
}
|
|
12717
|
+
}
|
|
12718
|
+
const arguments_ = array2(command.arguments, "\u51BB\u7ED3\u6253\u5305\u8BA1\u5212 command.arguments");
|
|
12719
|
+
if (!arguments_.every((argument) => typeof argument === "string")) {
|
|
12720
|
+
throw new Error("\u51BB\u7ED3\u6253\u5305\u8BA1\u5212 command.arguments \u975E\u6CD5");
|
|
12721
|
+
}
|
|
12722
|
+
if (plan.schemaVersion !== 1 || !nonEmptyString(plan.product) || !nonEmptyString(plan.configDigest) || !nonEmptyString(plan.profile) || !nonEmptyString(plan.platform) || !nonEmptyString(plan.createdAt) || !nonEmptyString(source.revision) || source.clean !== true || !nonEmptyString(command.executable) || !nonEmptyString(output.directory) || !nonEmptyString(output.artifactSuffix) || typeof requirements.docker !== "boolean" || typeof requirements.buildx !== "boolean") {
|
|
12723
|
+
throw new Error("\u51BB\u7ED3\u6253\u5305\u8BA1\u5212\u7F3A\u5C11\u5FC5\u8981\u5B57\u6BB5");
|
|
12724
|
+
}
|
|
12725
|
+
return {
|
|
12726
|
+
schemaVersion: 1,
|
|
12727
|
+
product: plan.product,
|
|
12728
|
+
configDigest: plan.configDigest,
|
|
12729
|
+
source: { revision: source.revision, clean: true },
|
|
12730
|
+
profile: plan.profile,
|
|
12731
|
+
platform: plan.platform,
|
|
12732
|
+
inputs,
|
|
12733
|
+
command: { executable: command.executable, arguments: arguments_ },
|
|
12734
|
+
output: {
|
|
12735
|
+
directory: output.directory,
|
|
12736
|
+
artifactSuffix: output.artifactSuffix
|
|
12737
|
+
},
|
|
12738
|
+
requirements: { docker: requirements.docker, buildx: requirements.buildx },
|
|
12739
|
+
createdAt: plan.createdAt
|
|
12740
|
+
};
|
|
12741
|
+
}
|
|
12742
|
+
function record(value, label) {
|
|
12743
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
12744
|
+
throw new Error(`${label} \u5FC5\u987B\u662F\u5BF9\u8C61`);
|
|
12745
|
+
return value;
|
|
12746
|
+
}
|
|
12747
|
+
function array2(value, label) {
|
|
12748
|
+
if (!Array.isArray(value))
|
|
12749
|
+
throw new Error(`${label} \u5FC5\u987B\u662F\u6570\u7EC4`);
|
|
12750
|
+
return value;
|
|
12751
|
+
}
|
|
12752
|
+
function rejectUnknown2(source, allowed, label) {
|
|
12753
|
+
for (const key of Object.keys(source)) {
|
|
12754
|
+
if (!allowed.includes(key))
|
|
12755
|
+
throw new Error(`${label} \u5305\u542B\u672A\u77E5\u5B57\u6BB5\uFF1A${key}`);
|
|
12756
|
+
}
|
|
12757
|
+
}
|
|
12758
|
+
function nonEmptyString(value) {
|
|
12759
|
+
return typeof value === "string" && Boolean(value.trim());
|
|
12760
|
+
}
|
|
12761
|
+
|
|
12762
|
+
// src/package-command.ts
|
|
12763
|
+
async function runPackageCommand(args, dependencies = {}) {
|
|
12764
|
+
if (args[0] !== "package")
|
|
12765
|
+
return false;
|
|
12766
|
+
const log = dependencies.log ?? console.log;
|
|
12767
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
12768
|
+
log(packageHelpText);
|
|
12769
|
+
return true;
|
|
12770
|
+
}
|
|
12771
|
+
const options = await parsePackageArguments(args.slice(1), dependencies.cwd ?? process.cwd());
|
|
12772
|
+
const planPath = options.fromPlan ?? options.plan;
|
|
12773
|
+
const config = await readPackageConfiguration(options.projectDirectory);
|
|
12774
|
+
const sourceRevision = await readPackageSource(options.projectDirectory, dependencies.process, planPath ? [planPath] : []);
|
|
12775
|
+
let plan;
|
|
12776
|
+
if (options.fromPlan) {
|
|
12777
|
+
plan = await readFrozenPackagePlan(options.fromPlan);
|
|
12778
|
+
assertFrozenPlanCurrent({
|
|
12779
|
+
plan,
|
|
12780
|
+
configuration: config.configuration,
|
|
12781
|
+
configDigest: config.digest,
|
|
12782
|
+
sourceRevision
|
|
12783
|
+
});
|
|
12784
|
+
} else {
|
|
12785
|
+
const profile = resolvePackageProfile(config.configuration, options.profile);
|
|
12786
|
+
if (!config.configuration.platforms.includes(options.platform))
|
|
12787
|
+
throw new Error(`profile ${profile.key} \u4E0D\u652F\u6301\u76EE\u6807\u5E73\u53F0\uFF1A${options.platform}`);
|
|
12788
|
+
const inputs = validatePackageInputs(profile, options.inputs);
|
|
12789
|
+
plan = createFrozenPackagePlan({
|
|
12790
|
+
configuration: config.configuration,
|
|
12791
|
+
configDigest: config.digest,
|
|
12792
|
+
sourceRevision,
|
|
12793
|
+
profile,
|
|
12794
|
+
platform: options.platform,
|
|
12795
|
+
inputs
|
|
12796
|
+
});
|
|
12797
|
+
if (options.plan)
|
|
12798
|
+
await writeFrozenPackagePlan(options.plan, plan);
|
|
12799
|
+
}
|
|
12800
|
+
printPlan2(plan, log);
|
|
12801
|
+
if (!options.execute)
|
|
12802
|
+
return true;
|
|
12803
|
+
if (!planPath)
|
|
12804
|
+
throw new Error("\u6267\u884C\u6253\u5305\u5FC5\u987B\u63D0\u4F9B --plan <\u6587\u4EF6> \u6216 --from-plan <\u6587\u4EF6>\uFF0C\u7528\u4E8E\u5199\u56DE\u7ED3\u679C");
|
|
12805
|
+
let persisted = false;
|
|
12806
|
+
try {
|
|
12807
|
+
await preflightPackage(plan, options.projectDirectory, dependencies.process, [planPath]);
|
|
12808
|
+
const current = await readPackageConfiguration(options.projectDirectory);
|
|
12809
|
+
const currentSource = await readPackageSource(options.projectDirectory, dependencies.process, [planPath]);
|
|
12810
|
+
assertFrozenPlanCurrent({
|
|
12811
|
+
plan,
|
|
12812
|
+
configuration: current.configuration,
|
|
12813
|
+
configDigest: current.digest,
|
|
12814
|
+
sourceRevision: currentSource
|
|
12815
|
+
});
|
|
12816
|
+
const accepted = await confirmModuleMutation(args, dependencies, log, "\u786E\u8BA4\u6267\u884C\u4EE5\u4E0A\u51BB\u7ED3\u6253\u5305\u8BA1\u5212\uFF1F");
|
|
12817
|
+
if (!accepted)
|
|
12818
|
+
return true;
|
|
12819
|
+
const result2 = await executePackagePlan(plan, options.projectDirectory, dependencies.process, [planPath]);
|
|
12820
|
+
await persistPackageResult(planPath, plan, result2);
|
|
12821
|
+
persisted = true;
|
|
12822
|
+
logResult(result2, log);
|
|
12823
|
+
if (result2.status === "failed")
|
|
12824
|
+
throw new Error(result2.diagnostic);
|
|
12825
|
+
} catch (error) {
|
|
12826
|
+
if (!persisted) {
|
|
12827
|
+
const result2 = failedResult(plan, error);
|
|
12828
|
+
await persistPackageResult(planPath, plan, result2);
|
|
12829
|
+
logResult(result2, log);
|
|
12830
|
+
}
|
|
12831
|
+
throw error;
|
|
12832
|
+
}
|
|
12833
|
+
return true;
|
|
12834
|
+
}
|
|
12835
|
+
async function persistPackageResult(planPath, plan, result2) {
|
|
12836
|
+
await writeFrozenPackagePlan(planPath, { ...plan, result: result2 });
|
|
12837
|
+
}
|
|
12838
|
+
function failedResult(plan, error) {
|
|
12839
|
+
return {
|
|
12840
|
+
status: "failed",
|
|
12841
|
+
completedAt: new Date().toISOString(),
|
|
12842
|
+
sourceRevision: plan.source.revision,
|
|
12843
|
+
artifacts: [],
|
|
12844
|
+
diagnostic: error instanceof Error ? error.message : String(error)
|
|
12845
|
+
};
|
|
12846
|
+
}
|
|
12847
|
+
function logResult(result2, log) {
|
|
12848
|
+
log(result2.status === "succeeded" ? `\u6253\u5305\u5B8C\u6210\uFF1A${result2.artifacts.map(({ path: path2, sha256: sha2562 }) => `${path2} sha256:${sha2562}`).join("\uFF0C")}` : `\u6253\u5305\u5931\u8D25\uFF1A${result2.diagnostic}`);
|
|
12849
|
+
}
|
|
12850
|
+
async function parsePackageArguments(args, workingDirectory) {
|
|
12851
|
+
const allowed = new Set([
|
|
12852
|
+
"--profile",
|
|
12853
|
+
"--platform",
|
|
12854
|
+
"--input",
|
|
12855
|
+
"--plan",
|
|
12856
|
+
"--from-plan",
|
|
12857
|
+
"--execute",
|
|
12858
|
+
"--yes",
|
|
12859
|
+
"--cwd"
|
|
12860
|
+
]);
|
|
12861
|
+
const values = new Map;
|
|
12862
|
+
for (let index = 0;index < args.length; index += 1) {
|
|
12863
|
+
const argument = args[index];
|
|
12864
|
+
if (!allowed.has(argument))
|
|
12865
|
+
throw new Error(`\u672A\u77E5 package \u53C2\u6570\uFF1A${argument}`);
|
|
12866
|
+
if (argument === "--execute" || argument === "--yes")
|
|
12867
|
+
continue;
|
|
12868
|
+
const value = args[index + 1];
|
|
12869
|
+
if (!value || value.startsWith("--"))
|
|
12870
|
+
throw new Error(`${argument} \u9700\u8981\u4E00\u4E2A\u503C`);
|
|
12871
|
+
values.set(argument, [...values.get(argument) ?? [], value]);
|
|
12872
|
+
index += 1;
|
|
12873
|
+
}
|
|
12874
|
+
const single = (name) => {
|
|
12875
|
+
const entries = values.get(name) ?? [];
|
|
12876
|
+
if (entries.length > 1)
|
|
12877
|
+
throw new Error(`${name} \u4E0D\u80FD\u91CD\u590D`);
|
|
12878
|
+
return entries[0];
|
|
12879
|
+
};
|
|
12880
|
+
const plan = single("--plan");
|
|
12881
|
+
const fromPlan = single("--from-plan");
|
|
12882
|
+
if (plan && fromPlan)
|
|
12883
|
+
throw new Error("--plan \u4E0D\u80FD\u4E0E --from-plan \u540C\u65F6\u4F7F\u7528");
|
|
12884
|
+
const projectDirectory = resolve14(workingDirectory, single("--cwd") ?? ".");
|
|
12885
|
+
const inputEntries = values.get("--input") ?? [];
|
|
12886
|
+
const inputs = {};
|
|
12887
|
+
for (const entry of inputEntries) {
|
|
12888
|
+
const match = /^([a-z][a-z0-9-]*)=(.*)$/u.exec(entry);
|
|
12889
|
+
if (!match)
|
|
12890
|
+
throw new Error("--input \u5FC5\u987B\u4E3A key=value\uFF0C\u4E14 key \u4F7F\u7528\u5C0F\u5199 kebab-case");
|
|
12891
|
+
const [, key, value] = match;
|
|
12892
|
+
if (inputs[key] !== undefined)
|
|
12893
|
+
throw new Error(`--input ${key} \u4E0D\u80FD\u91CD\u590D`);
|
|
12894
|
+
inputs[key] = value;
|
|
12895
|
+
}
|
|
12896
|
+
const profile = single("--profile");
|
|
12897
|
+
const platform = single("--platform");
|
|
12898
|
+
if (fromPlan && (profile || platform || inputEntries.length))
|
|
12899
|
+
throw new Error("--from-plan \u4E0D\u63A5\u53D7 --profile\u3001--platform \u6216 --input");
|
|
12900
|
+
if (!fromPlan && (!profile || !platform))
|
|
12901
|
+
throw new Error("\u65B0\u5EFA\u51BB\u7ED3\u8BA1\u5212\u5FC5\u987B\u540C\u65F6\u63D0\u4F9B --profile \u548C --platform");
|
|
12902
|
+
if (platform && !packagePlatforms.includes(platform))
|
|
12903
|
+
throw new Error(`\u4E0D\u652F\u6301\u7684\u76EE\u6807\u5E73\u53F0\uFF1A${platform}`);
|
|
12904
|
+
return {
|
|
12905
|
+
projectDirectory,
|
|
12906
|
+
profile,
|
|
12907
|
+
platform,
|
|
12908
|
+
inputs,
|
|
12909
|
+
plan: plan ? await resolvePackagePlanPath(projectDirectory, plan) : undefined,
|
|
12910
|
+
fromPlan: fromPlan ? await resolvePackagePlanPath(projectDirectory, fromPlan) : undefined,
|
|
12911
|
+
execute: args.includes("--execute")
|
|
12912
|
+
};
|
|
12913
|
+
}
|
|
12914
|
+
function printPlan2(plan, log) {
|
|
12915
|
+
log("\u51BB\u7ED3\u6253\u5305\u8BA1\u5212\uFF1A");
|
|
12916
|
+
log(` \u4EA7\u54C1\uFF1A${plan.product}`);
|
|
12917
|
+
log(` profile\uFF1A${plan.profile}`);
|
|
12918
|
+
log(` \u5E73\u53F0\uFF1A${plan.platform}`);
|
|
12919
|
+
log(` \u6E90\u7801\uFF1A${plan.source.revision}`);
|
|
12920
|
+
log(` \u547D\u4EE4\uFF1A${[plan.command.executable, ...plan.command.arguments].join(" ")}`);
|
|
12921
|
+
log(` \u8F93\u51FA\uFF1A${plan.output.directory}/*${plan.output.artifactSuffix}`);
|
|
12922
|
+
}
|
|
12923
|
+
var packageHelpText = `\u7528\u6CD5\uFF1Acreate-windy package [\u9009\u9879]
|
|
12924
|
+
|
|
12925
|
+
--profile <key> \u58F0\u660E\u7684\u6253\u5305 profile
|
|
12926
|
+
--platform <platform> linux/amd64 \u6216 linux/arm64
|
|
12927
|
+
--input key=value \u4E3A\u58F0\u660E\u7684\u975E secret \u8F93\u5165\u8D4B\u503C\uFF0C\u53EF\u91CD\u590D\u4F7F\u7528
|
|
12928
|
+
--plan <\u6587\u4EF6> \u4FDD\u5B58\u65B0\u5EFA\u51BB\u7ED3\u8BA1\u5212\uFF08\u9879\u76EE\u76EE\u5F55\u5185\uFF09
|
|
12929
|
+
--from-plan <\u6587\u4EF6> \u8BFB\u53D6\u51BB\u7ED3\u8BA1\u5212\uFF08\u9879\u76EE\u76EE\u5F55\u5185\uFF09
|
|
12930
|
+
--execute \u901A\u8FC7\u9884\u68C0\u5E76\u786E\u8BA4\u540E\u6267\u884C
|
|
12931
|
+
--yes \u975E\u4EA4\u4E92\u6267\u884C\u65F6\u786E\u8BA4\u8BA1\u5212
|
|
12932
|
+
--cwd <\u76EE\u5F55> \u6307\u5B9A\u9879\u76EE\u76EE\u5F55
|
|
12933
|
+
|
|
12934
|
+
\u6253\u5305\u9002\u914D\u5668\u5FC5\u987B\u7531\u9879\u76EE\u6839\u76EE\u5F55\u7684 windy.build.json \u660E\u786E\u58F0\u660E\u3002\u6267\u884C\u5FC5\u987B\u4F7F\u7528 --plan \u6216
|
|
12935
|
+
--from-plan\uFF0C\u4EE5\u4FBF\u628A\u4EA7\u7269 SHA-256 \u4E0E\u6E90\u7801\u6F02\u79FB\u7ED3\u679C\u5199\u56DE\u51BB\u7ED3\u8BA1\u5212\u3002`;
|
|
12936
|
+
|
|
12183
12937
|
// src/cli.ts
|
|
12184
12938
|
async function main() {
|
|
12185
12939
|
const args = process.argv.slice(2);
|
|
@@ -12187,6 +12941,8 @@ async function main() {
|
|
|
12187
12941
|
return;
|
|
12188
12942
|
if (await runLifecycleCommand(args))
|
|
12189
12943
|
return;
|
|
12944
|
+
if (await runPackageCommand(args))
|
|
12945
|
+
return;
|
|
12190
12946
|
const options = parseArguments(args);
|
|
12191
12947
|
if (options === "help") {
|
|
12192
12948
|
console.log(helpText);
|
package/package.json
CHANGED
|
@@ -55,7 +55,8 @@ function searchActors() {
|
|
|
55
55
|
:key="item.value"
|
|
56
56
|
size="sm"
|
|
57
57
|
class="h-8 px-3"
|
|
58
|
-
:variant="range === item.value ? '
|
|
58
|
+
:variant="range === item.value ? 'default' : 'ghost'"
|
|
59
|
+
:aria-pressed="range === item.value"
|
|
59
60
|
:disabled="disabled"
|
|
60
61
|
@click="emit('update:range', item.value)"
|
|
61
62
|
>
|
package/template/apps/web/src/pages/system/components/ai-runtime/AiRuntimeFilters.webtest.ts
CHANGED
|
@@ -6,6 +6,22 @@ import AiRuntimeFilters from "./AiRuntimeFilters.vue";
|
|
|
6
6
|
afterEach(() => document.body.replaceChildren());
|
|
7
7
|
|
|
8
8
|
describe("AI Runtime 操作者筛选", () => {
|
|
9
|
+
test("当前时间范围使用主按钮样式并暴露选中状态", () => {
|
|
10
|
+
const wrapper = mount(AiRuntimeFilters, {
|
|
11
|
+
props: {
|
|
12
|
+
range: "month",
|
|
13
|
+
actors: [],
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const selectedRange = wrapper.get("button[data-variant='default']");
|
|
18
|
+
const unselectedRange = wrapper.get("button[data-variant='ghost']");
|
|
19
|
+
|
|
20
|
+
expect(selectedRange.text()).toContain("近 30 天");
|
|
21
|
+
expect(selectedRange.attributes("aria-pressed")).toBe("true");
|
|
22
|
+
expect(unselectedRange.attributes("aria-pressed")).toBe("false");
|
|
23
|
+
});
|
|
24
|
+
|
|
9
25
|
test("按姓名搜索后通过设计系统 Select 选择服务端返回的操作者", async () => {
|
|
10
26
|
const wrapper = mount(AiRuntimeFilters, {
|
|
11
27
|
props: {
|