kintone-migrator 0.34.4 → 0.34.5
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/index.mjs +199 -134
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -10428,6 +10428,128 @@ const CustomizationConfigSerializer = { serialize: (config) => {
|
|
|
10428
10428
|
};
|
|
10429
10429
|
} };
|
|
10430
10430
|
//#endregion
|
|
10431
|
+
//#region src/core/domain/customization/services/customizationMerge.ts
|
|
10432
|
+
const PLATFORMS = ["desktop", "mobile"];
|
|
10433
|
+
const CATEGORIES = ["js", "css"];
|
|
10434
|
+
const SCOPE_KEY = "config:scope";
|
|
10435
|
+
/**
|
|
10436
|
+
* Bucket-qualified resource identity: `platform:category:name`. Shared with the
|
|
10437
|
+
* force/firstTime pull path (`preservePaths`) so path preservation matches the
|
|
10438
|
+
* merge on the same identity and cross-bucket same-basename files stay distinct.
|
|
10439
|
+
*/
|
|
10440
|
+
function resourceKey(platform, category, name) {
|
|
10441
|
+
return `${platform}:${category}:${name}`;
|
|
10442
|
+
}
|
|
10443
|
+
function platformList(config, platform, category) {
|
|
10444
|
+
const p = config[platform];
|
|
10445
|
+
return category === "js" ? p.js : p.css;
|
|
10446
|
+
}
|
|
10447
|
+
/**
|
|
10448
|
+
* Builds the per-side map keyed by `platform:category:name`. `contentTag`
|
|
10449
|
+
* returns the content marker for a same-name FILE so divergent content surfaces
|
|
10450
|
+
* as a conflict. `side` distinguishes local vs remote tags for modified files.
|
|
10451
|
+
*/
|
|
10452
|
+
function toMap(config, contentTag) {
|
|
10453
|
+
const map = /* @__PURE__ */ new Map();
|
|
10454
|
+
for (const platform of PLATFORMS) for (const category of CATEGORIES) for (const resource of platformList(config, platform, category)) {
|
|
10455
|
+
const name = resourceName(resource);
|
|
10456
|
+
const tag = resource.type === "FILE" ? `FILE:${contentTag(name)}` : "URL";
|
|
10457
|
+
map.set(resourceKey(platform, category, name), {
|
|
10458
|
+
resource,
|
|
10459
|
+
tag
|
|
10460
|
+
});
|
|
10461
|
+
}
|
|
10462
|
+
const scope = config.scope ?? "ALL";
|
|
10463
|
+
map.set(SCOPE_KEY, { scope });
|
|
10464
|
+
return map;
|
|
10465
|
+
}
|
|
10466
|
+
function isScopeValue(v) {
|
|
10467
|
+
return "scope" in v;
|
|
10468
|
+
}
|
|
10469
|
+
function eq(a, b) {
|
|
10470
|
+
if (isScopeValue(a) || isScopeValue(b)) return isScopeValue(a) && isScopeValue(b) && a.scope === b.scope;
|
|
10471
|
+
return a.tag === b.tag;
|
|
10472
|
+
}
|
|
10473
|
+
/**
|
|
10474
|
+
* Computes the file-name-keyed 3-way merge of base/local/remote customization.
|
|
10475
|
+
*
|
|
10476
|
+
* `modifiedFileNames` is the set of same-name FILE basenames whose local
|
|
10477
|
+
* content differs from the remote content (reused from the diffDetector flow).
|
|
10478
|
+
* Such files get distinct local/remote tags so they classify as conflicts; all
|
|
10479
|
+
* other matched files share the `"same"` tag and classify as unchanged.
|
|
10480
|
+
*/
|
|
10481
|
+
function computeCustomizationThreeWayMerge(base, local, remote, modifiedFileNames) {
|
|
10482
|
+
const tagFor = (side) => (name) => modifiedFileNames.has(name) ? side : "same";
|
|
10483
|
+
return classifyThreeWay(toMap(base, () => "same"), toMap(local, tagFor("local")), toMap(remote, tagFor("remote")), eq);
|
|
10484
|
+
}
|
|
10485
|
+
/**
|
|
10486
|
+
* Applies a resolved 3-way merge, returning the merged customization config.
|
|
10487
|
+
*
|
|
10488
|
+
* Auto-merged entries take their `merged` value; conflicts take the chosen
|
|
10489
|
+
* side. The resulting resources are flattened back into per-platform js/css
|
|
10490
|
+
* lists, preserving the order they appear in the chosen/merged side. Throws a
|
|
10491
|
+
* BusinessRuleError when a conflict is left unresolved (programmer invariant).
|
|
10492
|
+
*/
|
|
10493
|
+
function resolveCustomizationMerge(merge, resolution, local, remote) {
|
|
10494
|
+
const chosen = /* @__PURE__ */ new Map();
|
|
10495
|
+
let scope = "ALL";
|
|
10496
|
+
for (const entry of merge.entries) {
|
|
10497
|
+
let value;
|
|
10498
|
+
if (entry.change.kind === "conflict") {
|
|
10499
|
+
const choice = resolution.get(entry.key);
|
|
10500
|
+
if (choice === void 0) throw new BusinessRuleError(CustomizationErrorCode.CzUnresolvedConflict, `Unresolved conflict for "${entry.key}"`);
|
|
10501
|
+
value = choice === "local" ? entry.local : entry.remote;
|
|
10502
|
+
} else value = entry.merged;
|
|
10503
|
+
if (value === void 0) continue;
|
|
10504
|
+
if (isScopeValue(value)) scope = value.scope;
|
|
10505
|
+
else chosen.set(entry.key, value.resource);
|
|
10506
|
+
}
|
|
10507
|
+
return rebuild(chosen, scope, local, remote);
|
|
10508
|
+
}
|
|
10509
|
+
/**
|
|
10510
|
+
* Rebuilds the config from the chosen resource keys, ordering each bucket by the
|
|
10511
|
+
* resource's position in local first, then any remote-only resources, so the
|
|
10512
|
+
* resulting list is stable and matches the user's local ordering intent.
|
|
10513
|
+
*
|
|
10514
|
+
* `path` is a local-owned concern (the build-output location) that is orthogonal
|
|
10515
|
+
* to which content wins the merge: whenever a key exists locally, the local
|
|
10516
|
+
* resource (its declared path) is kept regardless of the chosen content side.
|
|
10517
|
+
* Only remote-only keys fall back to the chosen (remote/basename) resource.
|
|
10518
|
+
*/
|
|
10519
|
+
function rebuild(chosen, scope, local, remote) {
|
|
10520
|
+
function bucket(platform, category) {
|
|
10521
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10522
|
+
const out = [];
|
|
10523
|
+
const localByKey = /* @__PURE__ */ new Map();
|
|
10524
|
+
for (const resource of platformList(local, platform, category)) localByKey.set(resourceKey(platform, category, resourceName(resource)), resource);
|
|
10525
|
+
const append = (resources) => {
|
|
10526
|
+
for (const resource of resources) {
|
|
10527
|
+
const key = resourceKey(platform, category, resourceName(resource));
|
|
10528
|
+
if (seen.has(key)) continue;
|
|
10529
|
+
const picked = chosen.get(key);
|
|
10530
|
+
if (picked !== void 0) {
|
|
10531
|
+
out.push(localByKey.get(key) ?? picked);
|
|
10532
|
+
seen.add(key);
|
|
10533
|
+
}
|
|
10534
|
+
}
|
|
10535
|
+
};
|
|
10536
|
+
append(platformList(local, platform, category));
|
|
10537
|
+
append(platformList(remote, platform, category));
|
|
10538
|
+
return out;
|
|
10539
|
+
}
|
|
10540
|
+
return {
|
|
10541
|
+
scope,
|
|
10542
|
+
desktop: {
|
|
10543
|
+
js: bucket("desktop", "js"),
|
|
10544
|
+
css: bucket("desktop", "css")
|
|
10545
|
+
},
|
|
10546
|
+
mobile: {
|
|
10547
|
+
js: bucket("mobile", "js"),
|
|
10548
|
+
css: bucket("mobile", "css")
|
|
10549
|
+
}
|
|
10550
|
+
};
|
|
10551
|
+
}
|
|
10552
|
+
//#endregion
|
|
10431
10553
|
//#region src/lib/deduplicateName.ts
|
|
10432
10554
|
const DEFAULT_MAX_COUNTER = 1e4;
|
|
10433
10555
|
/**
|
|
@@ -10500,7 +10622,7 @@ function usedStemsFor(usedNames, ext) {
|
|
|
10500
10622
|
for (const name of usedNames) if (name.endsWith(ext)) stems.add(name.slice(0, name.length - ext.length));
|
|
10501
10623
|
return stems;
|
|
10502
10624
|
}
|
|
10503
|
-
function planResources(resources, platformDir, resourceType, relativeBaseDir) {
|
|
10625
|
+
function planResources(resources, platformName, platformDir, resourceType, relativeBaseDir, contentBase, preservePaths) {
|
|
10504
10626
|
const planned = [];
|
|
10505
10627
|
const filesToDownload = [];
|
|
10506
10628
|
const dir = join(platformDir, resourceType);
|
|
@@ -10511,28 +10633,42 @@ function planResources(resources, platformDir, resourceType, relativeBaseDir) {
|
|
|
10511
10633
|
});
|
|
10512
10634
|
else {
|
|
10513
10635
|
const fileName = deduplicateFileName(sanitizeFileName(resource.file.name), usedNames);
|
|
10514
|
-
const
|
|
10515
|
-
|
|
10516
|
-
|
|
10517
|
-
|
|
10518
|
-
|
|
10519
|
-
|
|
10520
|
-
|
|
10521
|
-
|
|
10522
|
-
|
|
10523
|
-
|
|
10524
|
-
|
|
10636
|
+
const declaredPath = preservePaths?.get(resourceKey(platformName, resourceType, resource.file.name));
|
|
10637
|
+
if (declaredPath !== void 0) {
|
|
10638
|
+
planned.push({
|
|
10639
|
+
type: "FILE",
|
|
10640
|
+
path: declaredPath
|
|
10641
|
+
});
|
|
10642
|
+
filesToDownload.push({
|
|
10643
|
+
fileName,
|
|
10644
|
+
fileKey: resource.file.fileKey,
|
|
10645
|
+
absolutePath: join(contentBase, declaredPath)
|
|
10646
|
+
});
|
|
10647
|
+
} else {
|
|
10648
|
+
const absolutePath = join(dir, fileName);
|
|
10649
|
+
const relativePath = join(relativeBaseDir, resourceType, fileName);
|
|
10650
|
+
planned.push({
|
|
10651
|
+
type: "FILE",
|
|
10652
|
+
path: relativePath
|
|
10653
|
+
});
|
|
10654
|
+
filesToDownload.push({
|
|
10655
|
+
fileName,
|
|
10656
|
+
fileKey: resource.file.fileKey,
|
|
10657
|
+
absolutePath
|
|
10658
|
+
});
|
|
10659
|
+
}
|
|
10525
10660
|
}
|
|
10526
10661
|
return {
|
|
10527
10662
|
resources: planned,
|
|
10528
10663
|
filesToDownload
|
|
10529
10664
|
};
|
|
10530
10665
|
}
|
|
10531
|
-
function planPlatform(remotePlatform, platformName, basePath, filePrefix) {
|
|
10532
|
-
const
|
|
10666
|
+
function planPlatform(remotePlatform, platformName, basePath, filePrefix, preservePaths) {
|
|
10667
|
+
const contentBase = join(basePath, filePrefix);
|
|
10668
|
+
const platformDir = join(contentBase, platformName);
|
|
10533
10669
|
const platformPrefix = platformName;
|
|
10534
|
-
const jsPlan = planResources(remotePlatform.js, platformDir, "js", platformPrefix);
|
|
10535
|
-
const cssPlan = planResources(remotePlatform.css, platformDir, "css", platformPrefix);
|
|
10670
|
+
const jsPlan = planResources(remotePlatform.js, platformName, platformDir, "js", platformPrefix, contentBase, preservePaths);
|
|
10671
|
+
const cssPlan = planResources(remotePlatform.css, platformName, platformDir, "css", platformPrefix, contentBase, preservePaths);
|
|
10536
10672
|
const fileCount = remotePlatform.js.filter((r) => r.type === "FILE").length + remotePlatform.css.filter((r) => r.type === "FILE").length;
|
|
10537
10673
|
return {
|
|
10538
10674
|
platform: {
|
|
@@ -10560,8 +10696,8 @@ async function downloadFiles(files, container) {
|
|
|
10560
10696
|
async function captureCustomization({ container, input }) {
|
|
10561
10697
|
const existing = await container.customizationStorage.get();
|
|
10562
10698
|
const { scope, desktop, mobile } = await container.customizationConfigurator.getCustomization();
|
|
10563
|
-
const desktopPlan = planPlatform(desktop, "desktop", input.basePath, input.filePrefix);
|
|
10564
|
-
const mobilePlan = planPlatform(mobile, "mobile", input.basePath, input.filePrefix);
|
|
10699
|
+
const desktopPlan = planPlatform(desktop, "desktop", input.basePath, input.filePrefix, input.preservePaths);
|
|
10700
|
+
const mobilePlan = planPlatform(mobile, "mobile", input.basePath, input.filePrefix, input.preservePaths);
|
|
10565
10701
|
const config = {
|
|
10566
10702
|
scope,
|
|
10567
10703
|
desktop: desktopPlan.platform,
|
|
@@ -10571,6 +10707,7 @@ async function captureCustomization({ container, input }) {
|
|
|
10571
10707
|
await downloadFiles([...desktopPlan.filesToDownload, ...mobilePlan.filesToDownload], container);
|
|
10572
10708
|
return {
|
|
10573
10709
|
configText,
|
|
10710
|
+
config,
|
|
10574
10711
|
hasExistingConfig: existing.exists,
|
|
10575
10712
|
fileResourceCount: desktopPlan.fileCount + mobilePlan.fileCount
|
|
10576
10713
|
};
|
|
@@ -11565,116 +11702,6 @@ var apply_default$9 = define({
|
|
|
11565
11702
|
}
|
|
11566
11703
|
});
|
|
11567
11704
|
//#endregion
|
|
11568
|
-
//#region src/core/domain/customization/services/customizationMerge.ts
|
|
11569
|
-
const PLATFORMS = ["desktop", "mobile"];
|
|
11570
|
-
const CATEGORIES = ["js", "css"];
|
|
11571
|
-
const SCOPE_KEY = "config:scope";
|
|
11572
|
-
function resourceKey(platform, category, name) {
|
|
11573
|
-
return `${platform}:${category}:${name}`;
|
|
11574
|
-
}
|
|
11575
|
-
function platformList(config, platform, category) {
|
|
11576
|
-
const p = config[platform];
|
|
11577
|
-
return category === "js" ? p.js : p.css;
|
|
11578
|
-
}
|
|
11579
|
-
/**
|
|
11580
|
-
* Builds the per-side map keyed by `platform:category:name`. `contentTag`
|
|
11581
|
-
* returns the content marker for a same-name FILE so divergent content surfaces
|
|
11582
|
-
* as a conflict. `side` distinguishes local vs remote tags for modified files.
|
|
11583
|
-
*/
|
|
11584
|
-
function toMap(config, contentTag) {
|
|
11585
|
-
const map = /* @__PURE__ */ new Map();
|
|
11586
|
-
for (const platform of PLATFORMS) for (const category of CATEGORIES) for (const resource of platformList(config, platform, category)) {
|
|
11587
|
-
const name = resourceName(resource);
|
|
11588
|
-
const tag = resource.type === "FILE" ? `FILE:${contentTag(name)}` : "URL";
|
|
11589
|
-
map.set(resourceKey(platform, category, name), {
|
|
11590
|
-
resource,
|
|
11591
|
-
tag
|
|
11592
|
-
});
|
|
11593
|
-
}
|
|
11594
|
-
const scope = config.scope ?? "ALL";
|
|
11595
|
-
map.set(SCOPE_KEY, { scope });
|
|
11596
|
-
return map;
|
|
11597
|
-
}
|
|
11598
|
-
function isScopeValue(v) {
|
|
11599
|
-
return "scope" in v;
|
|
11600
|
-
}
|
|
11601
|
-
function eq(a, b) {
|
|
11602
|
-
if (isScopeValue(a) || isScopeValue(b)) return isScopeValue(a) && isScopeValue(b) && a.scope === b.scope;
|
|
11603
|
-
return a.tag === b.tag;
|
|
11604
|
-
}
|
|
11605
|
-
/**
|
|
11606
|
-
* Computes the file-name-keyed 3-way merge of base/local/remote customization.
|
|
11607
|
-
*
|
|
11608
|
-
* `modifiedFileNames` is the set of same-name FILE basenames whose local
|
|
11609
|
-
* content differs from the remote content (reused from the diffDetector flow).
|
|
11610
|
-
* Such files get distinct local/remote tags so they classify as conflicts; all
|
|
11611
|
-
* other matched files share the `"same"` tag and classify as unchanged.
|
|
11612
|
-
*/
|
|
11613
|
-
function computeCustomizationThreeWayMerge(base, local, remote, modifiedFileNames) {
|
|
11614
|
-
const tagFor = (side) => (name) => modifiedFileNames.has(name) ? side : "same";
|
|
11615
|
-
return classifyThreeWay(toMap(base, () => "same"), toMap(local, tagFor("local")), toMap(remote, tagFor("remote")), eq);
|
|
11616
|
-
}
|
|
11617
|
-
/**
|
|
11618
|
-
* Applies a resolved 3-way merge, returning the merged customization config.
|
|
11619
|
-
*
|
|
11620
|
-
* Auto-merged entries take their `merged` value; conflicts take the chosen
|
|
11621
|
-
* side. The resulting resources are flattened back into per-platform js/css
|
|
11622
|
-
* lists, preserving the order they appear in the chosen/merged side. Throws a
|
|
11623
|
-
* BusinessRuleError when a conflict is left unresolved (programmer invariant).
|
|
11624
|
-
*/
|
|
11625
|
-
function resolveCustomizationMerge(merge, resolution, local, remote) {
|
|
11626
|
-
const chosen = /* @__PURE__ */ new Map();
|
|
11627
|
-
let scope = "ALL";
|
|
11628
|
-
for (const entry of merge.entries) {
|
|
11629
|
-
let value;
|
|
11630
|
-
if (entry.change.kind === "conflict") {
|
|
11631
|
-
const choice = resolution.get(entry.key);
|
|
11632
|
-
if (choice === void 0) throw new BusinessRuleError(CustomizationErrorCode.CzUnresolvedConflict, `Unresolved conflict for "${entry.key}"`);
|
|
11633
|
-
value = choice === "local" ? entry.local : entry.remote;
|
|
11634
|
-
} else value = entry.merged;
|
|
11635
|
-
if (value === void 0) continue;
|
|
11636
|
-
if (isScopeValue(value)) scope = value.scope;
|
|
11637
|
-
else chosen.set(entry.key, value.resource);
|
|
11638
|
-
}
|
|
11639
|
-
return rebuild(chosen, scope, local, remote);
|
|
11640
|
-
}
|
|
11641
|
-
/**
|
|
11642
|
-
* Rebuilds the config from the chosen resource keys, ordering each bucket by the
|
|
11643
|
-
* resource's position in local first, then any remote-only resources, so the
|
|
11644
|
-
* resulting list is stable and matches the user's local ordering intent.
|
|
11645
|
-
*/
|
|
11646
|
-
function rebuild(chosen, scope, local, remote) {
|
|
11647
|
-
function bucket(platform, category) {
|
|
11648
|
-
const seen = /* @__PURE__ */ new Set();
|
|
11649
|
-
const out = [];
|
|
11650
|
-
const append = (resources) => {
|
|
11651
|
-
for (const resource of resources) {
|
|
11652
|
-
const key = resourceKey(platform, category, resourceName(resource));
|
|
11653
|
-
if (seen.has(key)) continue;
|
|
11654
|
-
const picked = chosen.get(key);
|
|
11655
|
-
if (picked !== void 0) {
|
|
11656
|
-
out.push(picked);
|
|
11657
|
-
seen.add(key);
|
|
11658
|
-
}
|
|
11659
|
-
}
|
|
11660
|
-
};
|
|
11661
|
-
append(platformList(local, platform, category));
|
|
11662
|
-
append(platformList(remote, platform, category));
|
|
11663
|
-
return out;
|
|
11664
|
-
}
|
|
11665
|
-
return {
|
|
11666
|
-
scope,
|
|
11667
|
-
desktop: {
|
|
11668
|
-
js: bucket("desktop", "js"),
|
|
11669
|
-
css: bucket("desktop", "css")
|
|
11670
|
-
},
|
|
11671
|
-
mobile: {
|
|
11672
|
-
js: bucket("mobile", "js"),
|
|
11673
|
-
css: bucket("mobile", "css")
|
|
11674
|
-
}
|
|
11675
|
-
};
|
|
11676
|
-
}
|
|
11677
|
-
//#endregion
|
|
11678
11705
|
//#region src/core/application/customization/customizationRemote.ts
|
|
11679
11706
|
/**
|
|
11680
11707
|
* Converts the kintone remote customization (file metadata) into a
|
|
@@ -11899,15 +11926,17 @@ async function saveCustomizationSnapshotAndRevision(container, config, revision)
|
|
|
11899
11926
|
async function pullCustomization({ container, input }) {
|
|
11900
11927
|
const { state, local, remote } = await loadCustomizationThreeWayInputs(container);
|
|
11901
11928
|
if (input.force || state === void 0 || local === void 0) {
|
|
11929
|
+
const preservePaths = local !== void 0 ? buildPreservePaths(local) : void 0;
|
|
11902
11930
|
const captured = await captureCustomization({
|
|
11903
11931
|
container,
|
|
11904
11932
|
input: {
|
|
11905
11933
|
basePath: input.captureBasePath,
|
|
11906
|
-
filePrefix: input.filePrefix
|
|
11934
|
+
filePrefix: input.filePrefix,
|
|
11935
|
+
preservePaths
|
|
11907
11936
|
}
|
|
11908
11937
|
});
|
|
11909
11938
|
await container.customizationStorage.update(captured.configText);
|
|
11910
|
-
await saveCustomizationSnapshotAndRevision(container,
|
|
11939
|
+
await saveCustomizationSnapshotAndRevision(container, captured.config, remote.revision);
|
|
11911
11940
|
return { mode: input.force ? "force" : "firstTime" };
|
|
11912
11941
|
}
|
|
11913
11942
|
const modifiedFileNames = await computeModifiedFileNames(local, remote.raw, input.basePath, container);
|
|
@@ -11955,7 +11984,26 @@ async function applyPulledCustomizationMerge({ container, input }) {
|
|
|
11955
11984
|
await Promise.all(downloads);
|
|
11956
11985
|
const configText = stringifyConfig(container.configCodec, CustomizationConfigSerializer.serialize(merged));
|
|
11957
11986
|
await container.customizationStorage.update(configText);
|
|
11958
|
-
await saveCustomizationSnapshotAndRevision(container,
|
|
11987
|
+
await saveCustomizationSnapshotAndRevision(container, merged, input.remoteRevision);
|
|
11988
|
+
}
|
|
11989
|
+
/**
|
|
11990
|
+
* Builds the path-preservation map for `captureCustomization`: bucket-qualified
|
|
11991
|
+
* key (`resourceKey(platform, category, FILE basename)`) → declared local
|
|
11992
|
+
* relative path. The composite key matches the merge identity so cross-bucket
|
|
11993
|
+
* same-basename files (e.g. `app/desktop/js/main.js` vs `app/mobile/js/main.js`)
|
|
11994
|
+
* stay distinct instead of colliding under a flat basename map. Only FILE
|
|
11995
|
+
* resources carry a path.
|
|
11996
|
+
*/
|
|
11997
|
+
function buildPreservePaths(config) {
|
|
11998
|
+
const map = /* @__PURE__ */ new Map();
|
|
11999
|
+
const add = (platform, category, resources) => {
|
|
12000
|
+
for (const resource of resources) if (resource.type === "FILE") map.set(resourceKey(platform, category, resourceName(resource)), resource.path);
|
|
12001
|
+
};
|
|
12002
|
+
add("desktop", "js", config.desktop.js);
|
|
12003
|
+
add("desktop", "css", config.desktop.css);
|
|
12004
|
+
add("mobile", "js", config.mobile.js);
|
|
12005
|
+
add("mobile", "css", config.mobile.css);
|
|
12006
|
+
return map;
|
|
11959
12007
|
}
|
|
11960
12008
|
function allFileResources(config) {
|
|
11961
12009
|
return [
|
|
@@ -11987,6 +12035,25 @@ function remoteFileKeyMap(remote) {
|
|
|
11987
12035
|
}
|
|
11988
12036
|
//#endregion
|
|
11989
12037
|
//#region src/cli/commands/customize/pull.ts
|
|
12038
|
+
/**
|
|
12039
|
+
* Derives the path bases `runPull` feeds to the application layer.
|
|
12040
|
+
*
|
|
12041
|
+
* - `basePath` (= push's {@link computeBasePath}) is where merged/downloaded
|
|
12042
|
+
* content resolves and push uploads from.
|
|
12043
|
+
* - `captureBasePath` + `filePrefix` are passed to the capture-equivalent
|
|
12044
|
+
* (force / first-time) path.
|
|
12045
|
+
*
|
|
12046
|
+
* Invariant: `join(captureBasePath, filePrefix) === basePath`, so pull writes
|
|
12047
|
+
* exactly where push uploads from. Exported so the invariant test pins these
|
|
12048
|
+
* exact derivations rather than a hand-mirrored copy.
|
|
12049
|
+
*/
|
|
12050
|
+
function derivePullPaths(customizeFilePath) {
|
|
12051
|
+
return {
|
|
12052
|
+
basePath: computeBasePath(customizeFilePath),
|
|
12053
|
+
captureBasePath: dirname(resolve(customizeFilePath)),
|
|
12054
|
+
filePrefix: deriveFilePrefix(customizeFilePath)
|
|
12055
|
+
};
|
|
12056
|
+
}
|
|
11990
12057
|
async function resolveConflicts$1(merged, options) {
|
|
11991
12058
|
const resolution = /* @__PURE__ */ new Map();
|
|
11992
12059
|
for (const conflict of merged.merge.conflicts) {
|
|
@@ -12015,9 +12082,7 @@ async function resolveConflicts$1(merged, options) {
|
|
|
12015
12082
|
}
|
|
12016
12083
|
async function runPull$1(containerConfig, options) {
|
|
12017
12084
|
const container = createCustomizationCliContainer(containerConfig);
|
|
12018
|
-
const basePath =
|
|
12019
|
-
const captureBasePath = dirname(resolve(containerConfig.customizeFilePath));
|
|
12020
|
-
const filePrefix = deriveFilePrefix(containerConfig.customizeFilePath);
|
|
12085
|
+
const { basePath, captureBasePath, filePrefix } = derivePullPaths(containerConfig.customizeFilePath);
|
|
12021
12086
|
const s = p.spinner();
|
|
12022
12087
|
s.start("Pulling customization from kintone...");
|
|
12023
12088
|
let result;
|