ziku 0.21.2 → 0.22.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/dist/hash-BeQ4-IoO.mjs +3 -0
- package/dist/index.mjs +240 -35
- package/dist/merge-DtLUiQDW.mjs +3 -0
- package/dist/modules-BN0Qb_wy.mjs +3 -0
- package/dist/patterns-BKEQ73qt.mjs +3 -0
- package/dist/template-BmUA_WdM.mjs +3 -0
- package/package.json +3 -2
- package/dist/hash-DonjAgHQ.mjs +0 -3
- package/dist/merge-DFEjeYIq.mjs +0 -3
- package/dist/modules-DkQe-r1d.mjs +0 -3
- package/dist/patterns-C3oCRYgX.mjs +0 -3
- package/dist/template-BLwXZEZq.mjs +0 -3
package/dist/index.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import { defineCommand, runMain } from "citty";
|
|
|
5
5
|
import { copyFileSync, existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
7
7
|
import { dirname, join, resolve } from "pathe";
|
|
8
|
+
import * as YAML from "yaml";
|
|
8
9
|
import { parse, stringify } from "yaml";
|
|
9
10
|
import { z } from "zod";
|
|
10
11
|
import { downloadTemplate } from "giget";
|
|
@@ -17,13 +18,15 @@ import { match } from "ts-pattern";
|
|
|
17
18
|
import { execFileSync } from "node:child_process";
|
|
18
19
|
import { Octokit } from "@octokit/rest";
|
|
19
20
|
import { createHash } from "node:crypto";
|
|
21
|
+
import * as TOML from "smol-toml";
|
|
22
|
+
import { z as z$1 } from "zod/v4";
|
|
20
23
|
|
|
21
24
|
//#region rolldown:runtime
|
|
22
25
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
23
26
|
|
|
24
27
|
//#endregion
|
|
25
28
|
//#region package.json
|
|
26
|
-
var version$2 = "0.
|
|
29
|
+
var version$2 = "0.22.0";
|
|
27
30
|
|
|
28
31
|
//#endregion
|
|
29
32
|
//#region src/modules/schemas.ts
|
|
@@ -869,7 +872,7 @@ function getEffectivePatterns(_moduleId, modulePatterns, config) {
|
|
|
869
872
|
*
|
|
870
873
|
* 削除条件: ziku が別の UI フレームワーク(ink 等)に移行する場合。
|
|
871
874
|
*/
|
|
872
|
-
const version$1 = "0.
|
|
875
|
+
const version$1 = "0.22.0";
|
|
873
876
|
/** CLI の開始表示 */
|
|
874
877
|
function intro(command) {
|
|
875
878
|
const title = command ? `ziku ${command}` : "ziku";
|
|
@@ -2037,7 +2040,7 @@ async function hashFiles(dir, patterns) {
|
|
|
2037
2040
|
|
|
2038
2041
|
//#endregion
|
|
2039
2042
|
//#region src/commands/init.ts
|
|
2040
|
-
const version = "0.
|
|
2043
|
+
const version = "0.22.0";
|
|
2041
2044
|
const initCommand = defineCommand({
|
|
2042
2045
|
meta: {
|
|
2043
2046
|
name: "ziku",
|
|
@@ -2309,6 +2312,30 @@ async function saveConfig(targetDir, config) {
|
|
|
2309
2312
|
//#endregion
|
|
2310
2313
|
//#region src/utils/merge.ts
|
|
2311
2314
|
/**
|
|
2315
|
+
* 3-way マージにおけるベース(共通祖先)のファイル内容。
|
|
2316
|
+
*
|
|
2317
|
+
* 背景: threeWayMerge の引数は全て string だが、base/local/template を
|
|
2318
|
+
* 入れ違えるとサイレントに誤った結果を返す(#148 で発生)。
|
|
2319
|
+
* Zod brand で型レベルで区別し、取り違えをコンパイルエラーにする。
|
|
2320
|
+
*/
|
|
2321
|
+
const BaseContent = z$1.string().brand("BaseContent");
|
|
2322
|
+
/** ローカル側(ユーザー)のファイル内容。コンフリクト時に優先される側。 */
|
|
2323
|
+
const LocalContent = z$1.string().brand("LocalContent");
|
|
2324
|
+
/** テンプレート側のファイル内容。ローカルに適用される変更の源。 */
|
|
2325
|
+
const TemplateContent = z$1.string().brand("TemplateContent");
|
|
2326
|
+
/** string を BaseContent にブランドする */
|
|
2327
|
+
function asBaseContent(s) {
|
|
2328
|
+
return BaseContent.parse(s);
|
|
2329
|
+
}
|
|
2330
|
+
/** string を LocalContent にブランドする */
|
|
2331
|
+
function asLocalContent(s) {
|
|
2332
|
+
return LocalContent.parse(s);
|
|
2333
|
+
}
|
|
2334
|
+
/** string を TemplateContent にブランドする */
|
|
2335
|
+
function asTemplateContent(s) {
|
|
2336
|
+
return TemplateContent.parse(s);
|
|
2337
|
+
}
|
|
2338
|
+
/**
|
|
2312
2339
|
* base/local/template のハッシュを比較し、各ファイルを分類する。
|
|
2313
2340
|
*
|
|
2314
2341
|
* 背景: pull/push 時にファイルごとの処理方法(自動上書き・マージ・スキップ等)を
|
|
@@ -2358,10 +2385,11 @@ function classifyFiles(opts) {
|
|
|
2358
2385
|
* ファイル構造を壊さずにマージできる。テキストファイルは fuzz factor や
|
|
2359
2386
|
* hunk 単位のマーカーで精度を上げる。
|
|
2360
2387
|
*
|
|
2361
|
-
*
|
|
2388
|
+
* result の内容は local をベースにし、template 側の変更を適用したもの。
|
|
2389
|
+
* コンフリクト時は local 側の値が保持される。
|
|
2362
2390
|
*/
|
|
2363
|
-
function threeWayMerge(base, local, template, filePath) {
|
|
2364
|
-
if (local === template) return {
|
|
2391
|
+
function threeWayMerge({ base, local, template, filePath }) {
|
|
2392
|
+
if (String(local) === String(template)) return {
|
|
2365
2393
|
content: local,
|
|
2366
2394
|
hasConflicts: false,
|
|
2367
2395
|
conflictDetails: []
|
|
@@ -2370,7 +2398,15 @@ function threeWayMerge(base, local, template, filePath) {
|
|
|
2370
2398
|
const jsonResult = mergeJsonContent(base, local, template);
|
|
2371
2399
|
if (jsonResult !== null) return jsonResult;
|
|
2372
2400
|
}
|
|
2373
|
-
|
|
2401
|
+
if (filePath && isTomlFile(filePath)) {
|
|
2402
|
+
const tomlResult = mergeTomlContent(base, local, template);
|
|
2403
|
+
if (tomlResult !== null) return tomlResult;
|
|
2404
|
+
}
|
|
2405
|
+
if (filePath && isYamlFile(filePath)) {
|
|
2406
|
+
const yamlResult = mergeYamlContent(base, local, template);
|
|
2407
|
+
if (yamlResult !== null) return yamlResult;
|
|
2408
|
+
}
|
|
2409
|
+
return textThreeWayMerge(base, local, template, filePath);
|
|
2374
2410
|
}
|
|
2375
2411
|
/**
|
|
2376
2412
|
* JSON/JSONC ファイルをキーレベルで 3-way マージする。
|
|
@@ -2502,10 +2538,164 @@ function deepEqual(a, b) {
|
|
|
2502
2538
|
if (aKeys.length !== bKeys.length) return false;
|
|
2503
2539
|
return aKeys.every((key) => key in bObj && deepEqual(aObj[key], bObj[key]));
|
|
2504
2540
|
}
|
|
2541
|
+
/**
|
|
2542
|
+
* TOML ファイルをキーレベルで 3-way マージする。
|
|
2543
|
+
*
|
|
2544
|
+
* 背景: TOML ファイルにコンフリクトマーカーを挿入するとパーサーが壊れるため、
|
|
2545
|
+
* JSON マージと同様にキーレベルで変更を検出し、非コンフリクト部分を自動マージする。
|
|
2546
|
+
* コンフリクトがあるキーはローカル値を採用し、conflictDetails で報告する。
|
|
2547
|
+
*
|
|
2548
|
+
* 制約: smol-toml の stringify はコメントを保持しないため、マージ結果では
|
|
2549
|
+
* ローカルのコメントが失われる。ただし、壊れた TOML を出力するよりも
|
|
2550
|
+
* 正しい TOML を出力することを優先する。
|
|
2551
|
+
*
|
|
2552
|
+
* @returns マージ結果。TOML パースに失敗した場合は null(テキストマージにフォールバック)。
|
|
2553
|
+
*/
|
|
2554
|
+
function mergeTomlContent(base, local, template) {
|
|
2555
|
+
let baseObj;
|
|
2556
|
+
let localObj;
|
|
2557
|
+
let templateObj;
|
|
2558
|
+
try {
|
|
2559
|
+
baseObj = TOML.parse(base);
|
|
2560
|
+
localObj = TOML.parse(local);
|
|
2561
|
+
templateObj = TOML.parse(template);
|
|
2562
|
+
} catch {
|
|
2563
|
+
return null;
|
|
2564
|
+
}
|
|
2565
|
+
const templateDiffs = getJsonDiffs(baseObj, templateObj);
|
|
2566
|
+
const localDiffs = getJsonDiffs(baseObj, localObj);
|
|
2567
|
+
const mergedObj = structuredClone(localObj);
|
|
2568
|
+
const conflictDetails = [];
|
|
2569
|
+
for (const diff of templateDiffs) {
|
|
2570
|
+
if (localDiffs.some((ld) => pathsOverlap(ld.path, diff.path))) {
|
|
2571
|
+
const localVal = getValueAtPath(localObj, diff.path);
|
|
2572
|
+
const templateVal = diff.type === "remove" ? void 0 : diff.value;
|
|
2573
|
+
if (deepEqual(localVal, templateVal)) continue;
|
|
2574
|
+
conflictDetails.push({
|
|
2575
|
+
path: diff.path,
|
|
2576
|
+
localValue: localVal,
|
|
2577
|
+
templateValue: templateVal
|
|
2578
|
+
});
|
|
2579
|
+
continue;
|
|
2580
|
+
}
|
|
2581
|
+
if (diff.type === "remove") deleteAtPath(mergedObj, diff.path);
|
|
2582
|
+
else setAtPath(mergedObj, diff.path, diff.value);
|
|
2583
|
+
}
|
|
2584
|
+
return {
|
|
2585
|
+
content: TOML.stringify(mergedObj),
|
|
2586
|
+
hasConflicts: conflictDetails.length > 0,
|
|
2587
|
+
conflictDetails
|
|
2588
|
+
};
|
|
2589
|
+
}
|
|
2590
|
+
/**
|
|
2591
|
+
* YAML ファイルをキーレベルで 3-way マージする。
|
|
2592
|
+
*
|
|
2593
|
+
* 背景: YAML ファイルもインデントベースの構造を持ち、テキストマージで
|
|
2594
|
+
* 壊れることがある。JSON/TOML と同様にキーレベルでマージする。
|
|
2595
|
+
*
|
|
2596
|
+
* @returns マージ結果。YAML パースに失敗した場合は null(テキストマージにフォールバック)。
|
|
2597
|
+
*/
|
|
2598
|
+
function mergeYamlContent(base, local, template) {
|
|
2599
|
+
let baseObj;
|
|
2600
|
+
let localObj;
|
|
2601
|
+
let templateObj;
|
|
2602
|
+
try {
|
|
2603
|
+
baseObj = YAML.parse(base);
|
|
2604
|
+
localObj = YAML.parse(local);
|
|
2605
|
+
templateObj = YAML.parse(template);
|
|
2606
|
+
} catch {
|
|
2607
|
+
return null;
|
|
2608
|
+
}
|
|
2609
|
+
if (baseObj == null || localObj == null || templateObj == null) return null;
|
|
2610
|
+
if (typeof baseObj !== "object" || typeof localObj !== "object" || typeof templateObj !== "object") return null;
|
|
2611
|
+
const templateDiffs = getJsonDiffs(baseObj, templateObj);
|
|
2612
|
+
const localDiffs = getJsonDiffs(baseObj, localObj);
|
|
2613
|
+
const mergedObj = structuredClone(localObj);
|
|
2614
|
+
const conflictDetails = [];
|
|
2615
|
+
for (const diff of templateDiffs) {
|
|
2616
|
+
if (localDiffs.some((ld) => pathsOverlap(ld.path, diff.path))) {
|
|
2617
|
+
const localVal = getValueAtPath(localObj, diff.path);
|
|
2618
|
+
const templateVal = diff.type === "remove" ? void 0 : diff.value;
|
|
2619
|
+
if (deepEqual(localVal, templateVal)) continue;
|
|
2620
|
+
conflictDetails.push({
|
|
2621
|
+
path: diff.path,
|
|
2622
|
+
localValue: localVal,
|
|
2623
|
+
templateValue: templateVal
|
|
2624
|
+
});
|
|
2625
|
+
continue;
|
|
2626
|
+
}
|
|
2627
|
+
if (diff.type === "remove") deleteAtPath(mergedObj, diff.path);
|
|
2628
|
+
else setAtPath(mergedObj, diff.path, diff.value);
|
|
2629
|
+
}
|
|
2630
|
+
return {
|
|
2631
|
+
content: YAML.stringify(mergedObj),
|
|
2632
|
+
hasConflicts: conflictDetails.length > 0,
|
|
2633
|
+
conflictDetails
|
|
2634
|
+
};
|
|
2635
|
+
}
|
|
2636
|
+
/**
|
|
2637
|
+
* ネストされたオブジェクトのパスに値を設定する。
|
|
2638
|
+
* 中間オブジェクトが存在しない場合は自動的に作成する。
|
|
2639
|
+
*/
|
|
2640
|
+
function setAtPath(obj, path, value) {
|
|
2641
|
+
let current = obj;
|
|
2642
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
2643
|
+
const key = path[i];
|
|
2644
|
+
if (current == null || typeof current !== "object") return;
|
|
2645
|
+
const record = current;
|
|
2646
|
+
if (!(key in record) || record[key] == null || typeof record[key] !== "object") record[key] = {};
|
|
2647
|
+
current = record[key];
|
|
2648
|
+
}
|
|
2649
|
+
if (current != null && typeof current === "object") current[path[path.length - 1]] = value;
|
|
2650
|
+
}
|
|
2651
|
+
/**
|
|
2652
|
+
* ネストされたオブジェクトのパスにあるキーを削除する。
|
|
2653
|
+
*/
|
|
2654
|
+
function deleteAtPath(obj, path) {
|
|
2655
|
+
let current = obj;
|
|
2656
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
2657
|
+
const key = path[i];
|
|
2658
|
+
if (current == null || typeof current !== "object") return;
|
|
2659
|
+
current = current[key];
|
|
2660
|
+
}
|
|
2661
|
+
if (current != null && typeof current === "object") delete current[path[path.length - 1]];
|
|
2662
|
+
}
|
|
2505
2663
|
function isJsonFile(filePath) {
|
|
2506
2664
|
const lower = filePath.toLowerCase();
|
|
2507
2665
|
return lower.endsWith(".json") || lower.endsWith(".jsonc");
|
|
2508
2666
|
}
|
|
2667
|
+
function isTomlFile(filePath) {
|
|
2668
|
+
return filePath.toLowerCase().endsWith(".toml");
|
|
2669
|
+
}
|
|
2670
|
+
function isYamlFile(filePath) {
|
|
2671
|
+
const lower = filePath.toLowerCase();
|
|
2672
|
+
return lower.endsWith(".yml") || lower.endsWith(".yaml");
|
|
2673
|
+
}
|
|
2674
|
+
/**
|
|
2675
|
+
* 構造ファイル(TOML/YAML)のマージ結果をパースして妥当性を検証する。
|
|
2676
|
+
*
|
|
2677
|
+
* 背景: テキストベースの diff/patch は行レベルでマージするため、
|
|
2678
|
+
* fuzz factor でパッチが「成功」しても、TOML のセクション重複や
|
|
2679
|
+
* YAML のインデント崩れ等、構造的に壊れた出力を生むことがある。
|
|
2680
|
+
* git の merge がこのような破損を出さないのに対し、patch ベースの
|
|
2681
|
+
* マージはこの検証が必要。パース失敗時はコンフリクトマーカーに
|
|
2682
|
+
* フォールバックすることで、壊れたファイルの生成を防ぐ。
|
|
2683
|
+
*/
|
|
2684
|
+
function validateStructuredContent(content, filePath) {
|
|
2685
|
+
if (isTomlFile(filePath)) try {
|
|
2686
|
+
TOML.parse(content);
|
|
2687
|
+
return true;
|
|
2688
|
+
} catch {
|
|
2689
|
+
return false;
|
|
2690
|
+
}
|
|
2691
|
+
if (isYamlFile(filePath)) try {
|
|
2692
|
+
YAML.parse(content);
|
|
2693
|
+
return true;
|
|
2694
|
+
} catch {
|
|
2695
|
+
return false;
|
|
2696
|
+
}
|
|
2697
|
+
return true;
|
|
2698
|
+
}
|
|
2509
2699
|
/**
|
|
2510
2700
|
* テキストファイルの 3-way マージ。fuzz factor によるパッチ適用と
|
|
2511
2701
|
* hunk 単位のコンフリクトマーカーで、従来のファイル全体マーカーを改善。
|
|
@@ -2513,25 +2703,36 @@ function isJsonFile(filePath) {
|
|
|
2513
2703
|
* 背景: TOML 等の構造ファイルにファイル全体のコンフリクトマーカーを入れると
|
|
2514
2704
|
* パーサーが壊れる。hunk 単位にすることで影響範囲を最小化する。
|
|
2515
2705
|
*
|
|
2706
|
+
* filePath が渡された場合、パッチ適用後に構造ファイルの妥当性を検証する。
|
|
2707
|
+
* fuzz factor でパッチが「成功」しても、TOML のセクション重複等で
|
|
2708
|
+
* 壊れたファイルが生成されることがあるため、パース検証で検出して
|
|
2709
|
+
* コンフリクトマーカーにフォールバックする。
|
|
2710
|
+
*
|
|
2516
2711
|
* 戦略:
|
|
2517
|
-
* 1. 標準パッチ適用(fuzz=0
|
|
2518
|
-
* 2. fuzz factor を上げてリトライ(fuzz=2
|
|
2712
|
+
* 1. 標準パッチ適用(fuzz=0)+ 構造検証
|
|
2713
|
+
* 2. fuzz factor を上げてリトライ(fuzz=2)+ 構造検証
|
|
2519
2714
|
* 3. 失敗時: hunk 単位で適用を試み、失敗した hunk のみにマーカーを付与
|
|
2520
2715
|
*/
|
|
2521
|
-
function textThreeWayMerge(base, local, template) {
|
|
2716
|
+
function textThreeWayMerge(base, local, template, filePath) {
|
|
2522
2717
|
const patch = createPatch("file", base, template);
|
|
2523
2718
|
const result = applyPatch(local, patch);
|
|
2524
|
-
if (typeof result === "string")
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2719
|
+
if (typeof result === "string") {
|
|
2720
|
+
if (filePath && !validateStructuredContent(result, filePath)) return mergeWithPerHunkMarkers(base, local, template);
|
|
2721
|
+
return {
|
|
2722
|
+
content: result,
|
|
2723
|
+
hasConflicts: false,
|
|
2724
|
+
conflictDetails: []
|
|
2725
|
+
};
|
|
2726
|
+
}
|
|
2529
2727
|
const resultFuzzy = applyPatch(local, patch, { fuzzFactor: 2 });
|
|
2530
|
-
if (typeof resultFuzzy === "string")
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2728
|
+
if (typeof resultFuzzy === "string") {
|
|
2729
|
+
if (filePath && !validateStructuredContent(resultFuzzy, filePath)) return mergeWithPerHunkMarkers(base, local, template);
|
|
2730
|
+
return {
|
|
2731
|
+
content: resultFuzzy,
|
|
2732
|
+
hasConflicts: false,
|
|
2733
|
+
conflictDetails: []
|
|
2734
|
+
};
|
|
2735
|
+
}
|
|
2535
2736
|
return mergeWithPerHunkMarkers(base, local, template);
|
|
2536
2737
|
}
|
|
2537
2738
|
/**
|
|
@@ -2605,12 +2806,6 @@ function tryApplyHunk(localLines, hunk) {
|
|
|
2605
2806
|
return newLines;
|
|
2606
2807
|
}
|
|
2607
2808
|
/**
|
|
2608
|
-
* base/local/template の3つの内容から 3-way マージを実行する。
|
|
2609
|
-
* (後方互換性のためのラッパー)
|
|
2610
|
-
*
|
|
2611
|
-
* @deprecated filePath を渡す新しい threeWayMerge を使用してください
|
|
2612
|
-
*/
|
|
2613
|
-
/**
|
|
2614
2809
|
* ファイル内容にコンフリクトマーカーが含まれるかを検出する。
|
|
2615
2810
|
*
|
|
2616
2811
|
* 背景: マージ後のファイルにユーザーが手動解決すべきコンフリクトが
|
|
@@ -2734,7 +2929,12 @@ const pullCommand = defineCommand({
|
|
|
2734
2929
|
const templateContent = await readFile(join(templateDir, file), "utf-8");
|
|
2735
2930
|
let baseContent = "";
|
|
2736
2931
|
if (baseTemplateDir && existsSync(join(baseTemplateDir, file))) baseContent = await readFile(join(baseTemplateDir, file), "utf-8");
|
|
2737
|
-
const result = threeWayMerge(
|
|
2932
|
+
const result = threeWayMerge({
|
|
2933
|
+
base: asBaseContent(baseContent),
|
|
2934
|
+
local: asLocalContent(localContent),
|
|
2935
|
+
template: asTemplateContent(templateContent),
|
|
2936
|
+
filePath: file
|
|
2937
|
+
});
|
|
2738
2938
|
await writeFile(join(targetDir, file), result.content, "utf-8");
|
|
2739
2939
|
if (result.hasConflicts) {
|
|
2740
2940
|
unresolvedConflicts.push(file);
|
|
@@ -3339,10 +3539,10 @@ const pushCommand = defineCommand({
|
|
|
3339
3539
|
const mergedContents = /* @__PURE__ */ new Map();
|
|
3340
3540
|
let pushableFilePaths = /* @__PURE__ */ new Set();
|
|
3341
3541
|
{
|
|
3342
|
-
const { hashFiles: hashFiles$1 } = await import("./hash-
|
|
3343
|
-
const { classifyFiles: classifyFiles$1 } = await import("./merge-
|
|
3344
|
-
const { getModuleById: getModuleById$1 } = await import("./modules-
|
|
3345
|
-
const { getEffectivePatterns: getEffectivePatterns$1 } = await import("./patterns-
|
|
3542
|
+
const { hashFiles: hashFiles$1 } = await import("./hash-BeQ4-IoO.mjs");
|
|
3543
|
+
const { classifyFiles: classifyFiles$1 } = await import("./merge-DtLUiQDW.mjs");
|
|
3544
|
+
const { getModuleById: getModuleById$1 } = await import("./modules-BN0Qb_wy.mjs");
|
|
3545
|
+
const { getEffectivePatterns: getEffectivePatterns$1 } = await import("./patterns-BKEQ73qt.mjs");
|
|
3346
3546
|
const allPatterns = [];
|
|
3347
3547
|
for (const moduleId of effectiveModuleIds) {
|
|
3348
3548
|
const mod = getModuleById$1(moduleId, moduleList);
|
|
@@ -3365,14 +3565,14 @@ const pushCommand = defineCommand({
|
|
|
3365
3565
|
for (const file of classification.autoUpdate) log.message(` ${pc$1.dim("↓")} ${pc$1.dim(file)}`);
|
|
3366
3566
|
}
|
|
3367
3567
|
if (classification.conflicts.length > 0) {
|
|
3368
|
-
const { threeWayMerge: threeWayMerge$1 } = await import("./merge-
|
|
3568
|
+
const { threeWayMerge: threeWayMerge$1, asBaseContent: asBaseContent$1, asLocalContent: asLocalContent$1, asTemplateContent: asTemplateContent$1 } = await import("./merge-DtLUiQDW.mjs");
|
|
3369
3569
|
const baseInfo = config.baseRef ? `since ${pc$1.bold(config.baseRef.slice(0, 7))} (your last sync)` : "since your last pull/init";
|
|
3370
3570
|
log.warn(`Template updated ${baseInfo} — ${classification.conflicts.length} conflict(s) detected, attempting auto-merge...`);
|
|
3371
3571
|
let baseTemplateDir;
|
|
3372
3572
|
let baseCleanup;
|
|
3373
3573
|
if (config.baseRef) try {
|
|
3374
3574
|
log.info(`Downloading base version (${config.baseRef.slice(0, 7)}...) for merge...`);
|
|
3375
|
-
const { downloadTemplateToTemp: downloadBase } = await import("./template-
|
|
3575
|
+
const { downloadTemplateToTemp: downloadBase } = await import("./template-BmUA_WdM.mjs");
|
|
3376
3576
|
const baseResult = await downloadBase(targetDir, `gh:${config.source.owner}/${config.source.repo}#${config.baseRef}`);
|
|
3377
3577
|
baseTemplateDir = baseResult.templateDir;
|
|
3378
3578
|
baseCleanup = baseResult.cleanup;
|
|
@@ -3388,7 +3588,12 @@ const pushCommand = defineCommand({
|
|
|
3388
3588
|
let baseContent;
|
|
3389
3589
|
if (baseTemplateDir && existsSync(join(baseTemplateDir, file))) baseContent = await readFile(join(baseTemplateDir, file), "utf-8");
|
|
3390
3590
|
if (baseContent) {
|
|
3391
|
-
const result$1 = threeWayMerge$1(
|
|
3591
|
+
const result$1 = threeWayMerge$1({
|
|
3592
|
+
base: asBaseContent$1(baseContent),
|
|
3593
|
+
local: asLocalContent$1(localContent),
|
|
3594
|
+
template: asTemplateContent$1(templateContent),
|
|
3595
|
+
filePath: file
|
|
3596
|
+
});
|
|
3392
3597
|
if (!result$1.hasConflicts) {
|
|
3393
3598
|
mergedContents.set(file, result$1.content);
|
|
3394
3599
|
autoMerged.push(file);
|
|
@@ -3792,4 +3997,4 @@ async function run() {
|
|
|
3792
3997
|
run();
|
|
3793
3998
|
|
|
3794
3999
|
//#endregion
|
|
3795
|
-
export {
|
|
4000
|
+
export { getPatternsByModuleIds as C, loadModulesFile as D, getModulesFilePath as E, modulesFileExists as O, getModuleById as S, addPatternToModulesFileWithCreate as T, writeFileWithStrategy as _, hasConflictMarkers as a, resolvePatterns as b, mergeYamlContent as c, hashFiles as d, TEMPLATE_SOURCE as f, fetchTemplates as g, downloadTemplateToTemp as h, classifyFiles as i, saveModulesFile as k, threeWayMerge as l, copyFile as m, asLocalContent as n, mergeJsonContent as o, buildTemplateSource as p, asTemplateContent as r, mergeTomlContent as s, asBaseContent as t, hashContent as u, getEffectivePatterns as v, addPatternToModulesFile as w, defaultModules as x, matchesPatterns as y };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { a as hasConflictMarkers, c as mergeYamlContent, i as classifyFiles, l as threeWayMerge, n as asLocalContent, o as mergeJsonContent, r as asTemplateContent, s as mergeTomlContent, t as asBaseContent } from "./index.mjs";
|
|
2
|
+
|
|
3
|
+
export { asBaseContent, asLocalContent, asTemplateContent, classifyFiles, threeWayMerge };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { C as getPatternsByModuleIds, D as loadModulesFile, E as getModulesFilePath, O as modulesFileExists, S as getModuleById, T as addPatternToModulesFileWithCreate, k as saveModulesFile, w as addPatternToModulesFile, x as defaultModules } from "./index.mjs";
|
|
2
|
+
|
|
3
|
+
export { getModuleById };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ziku",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Interactive CLI to scaffold development environment templates",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"jsonc-parser": "^3.3.1",
|
|
31
31
|
"pathe": "^2.0.3",
|
|
32
32
|
"picocolors": "^1.1.1",
|
|
33
|
+
"smol-toml": "^1.6.0",
|
|
33
34
|
"tinyglobby": "^0.2.15",
|
|
34
35
|
"ts-pattern": "^5.9.0",
|
|
35
36
|
"yaml": "^2.8.2",
|
|
@@ -60,7 +61,7 @@
|
|
|
60
61
|
"test": "vitest",
|
|
61
62
|
"test:run": "vitest run",
|
|
62
63
|
"test:coverage": "vitest run --coverage",
|
|
63
|
-
"check": "npm run format:check && npm run lint && npm run build && npm run test:run && npm run docs:check",
|
|
64
|
+
"check": "npm run format:check && npm run lint && npm run typecheck && npm run build && npm run test:run && npm run docs:check",
|
|
64
65
|
"docs": "npx tsx scripts/generate-readme.ts",
|
|
65
66
|
"docs:check": "npx tsx scripts/generate-readme.ts --check"
|
|
66
67
|
}
|
package/dist/hash-DonjAgHQ.mjs
DELETED
package/dist/merge-DFEjeYIq.mjs
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { C as modulesFileExists, S as loadModulesFile, _ as getModuleById, b as addPatternToModulesFileWithCreate, g as defaultModules, v as getPatternsByModuleIds, w as saveModulesFile, x as getModulesFilePath, y as addPatternToModulesFile } from "./index.mjs";
|
|
2
|
-
|
|
3
|
-
export { getModuleById };
|