kintone-migrator 0.34.3 → 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 +236 -139
- 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;
|
|
@@ -16275,6 +16340,7 @@ function buildPhases(args) {
|
|
|
16275
16340
|
container: c.schema,
|
|
16276
16341
|
input: { force }
|
|
16277
16342
|
});
|
|
16343
|
+
return [];
|
|
16278
16344
|
}
|
|
16279
16345
|
}]
|
|
16280
16346
|
},
|
|
@@ -16291,6 +16357,7 @@ function buildPhases(args) {
|
|
|
16291
16357
|
force
|
|
16292
16358
|
}
|
|
16293
16359
|
});
|
|
16360
|
+
return [];
|
|
16294
16361
|
}
|
|
16295
16362
|
}, {
|
|
16296
16363
|
domain: "view",
|
|
@@ -16300,6 +16367,7 @@ function buildPhases(args) {
|
|
|
16300
16367
|
container: c.view,
|
|
16301
16368
|
input: { force }
|
|
16302
16369
|
});
|
|
16370
|
+
return [];
|
|
16303
16371
|
}
|
|
16304
16372
|
}]
|
|
16305
16373
|
},
|
|
@@ -16314,6 +16382,7 @@ function buildPhases(args) {
|
|
|
16314
16382
|
container: c.fieldPermission,
|
|
16315
16383
|
input: { force }
|
|
16316
16384
|
});
|
|
16385
|
+
return [];
|
|
16317
16386
|
}
|
|
16318
16387
|
},
|
|
16319
16388
|
{
|
|
@@ -16324,6 +16393,7 @@ function buildPhases(args) {
|
|
|
16324
16393
|
container: c.appPermission,
|
|
16325
16394
|
input: { force }
|
|
16326
16395
|
});
|
|
16396
|
+
return [];
|
|
16327
16397
|
}
|
|
16328
16398
|
},
|
|
16329
16399
|
{
|
|
@@ -16334,6 +16404,7 @@ function buildPhases(args) {
|
|
|
16334
16404
|
container: c.recordPermission,
|
|
16335
16405
|
input: { force }
|
|
16336
16406
|
});
|
|
16407
|
+
return [];
|
|
16337
16408
|
}
|
|
16338
16409
|
}
|
|
16339
16410
|
]
|
|
@@ -16349,6 +16420,7 @@ function buildPhases(args) {
|
|
|
16349
16420
|
container: c.settings,
|
|
16350
16421
|
input: { force }
|
|
16351
16422
|
});
|
|
16423
|
+
return [];
|
|
16352
16424
|
}
|
|
16353
16425
|
},
|
|
16354
16426
|
{
|
|
@@ -16359,6 +16431,7 @@ function buildPhases(args) {
|
|
|
16359
16431
|
container: c.notification,
|
|
16360
16432
|
input: { force }
|
|
16361
16433
|
});
|
|
16434
|
+
return [];
|
|
16362
16435
|
}
|
|
16363
16436
|
},
|
|
16364
16437
|
{
|
|
@@ -16369,6 +16442,7 @@ function buildPhases(args) {
|
|
|
16369
16442
|
container: c.report,
|
|
16370
16443
|
input: { force }
|
|
16371
16444
|
});
|
|
16445
|
+
return [];
|
|
16372
16446
|
}
|
|
16373
16447
|
},
|
|
16374
16448
|
{
|
|
@@ -16379,6 +16453,7 @@ function buildPhases(args) {
|
|
|
16379
16453
|
container: c.action,
|
|
16380
16454
|
input: { force }
|
|
16381
16455
|
});
|
|
16456
|
+
return [];
|
|
16382
16457
|
}
|
|
16383
16458
|
},
|
|
16384
16459
|
{
|
|
@@ -16389,6 +16464,7 @@ function buildPhases(args) {
|
|
|
16389
16464
|
container: c.process,
|
|
16390
16465
|
input: { force }
|
|
16391
16466
|
});
|
|
16467
|
+
return [];
|
|
16392
16468
|
}
|
|
16393
16469
|
},
|
|
16394
16470
|
{
|
|
@@ -16399,16 +16475,34 @@ function buildPhases(args) {
|
|
|
16399
16475
|
container: c.adminNotes,
|
|
16400
16476
|
input: { force }
|
|
16401
16477
|
});
|
|
16478
|
+
return [];
|
|
16402
16479
|
}
|
|
16403
16480
|
},
|
|
16404
16481
|
{
|
|
16405
16482
|
domain: "plugin",
|
|
16406
16483
|
storageExists: async () => (await c.plugin.pluginStorage.get()).exists,
|
|
16407
16484
|
run: async () => {
|
|
16408
|
-
await pushPlugin({
|
|
16485
|
+
const result = await pushPlugin({
|
|
16409
16486
|
container: c.plugin,
|
|
16410
16487
|
input: { force }
|
|
16411
16488
|
});
|
|
16489
|
+
const warnings = [];
|
|
16490
|
+
const deletions = result.skipped.filter((o) => o.reason === "delete").map((o) => o.pluginId);
|
|
16491
|
+
const modifications = result.skipped.filter((o) => o.reason === "modify").map((o) => o.pluginId);
|
|
16492
|
+
const addDisabled = result.skipped.filter((o) => o.reason === "add-disabled").map((o) => o.pluginId);
|
|
16493
|
+
if (deletions.length > 0) warnings.push({
|
|
16494
|
+
domain: "plugin",
|
|
16495
|
+
message: `Cannot remove plugins via the kintone API (add-only); left on the app: ${deletions.join(", ")}`
|
|
16496
|
+
});
|
|
16497
|
+
if (modifications.length > 0) warnings.push({
|
|
16498
|
+
domain: "plugin",
|
|
16499
|
+
message: `Cannot modify existing plugins (name/enabled) via the kintone API (add-only); unchanged: ${modifications.join(", ")}`
|
|
16500
|
+
});
|
|
16501
|
+
if (addDisabled.length > 0) warnings.push({
|
|
16502
|
+
domain: "plugin",
|
|
16503
|
+
message: `Cannot add plugins in a disabled state via the kintone API (add-only; adding would force-enable them); not added — set enabled: false manually in the kintone admin UI: ${addDisabled.join(", ")}`
|
|
16504
|
+
});
|
|
16505
|
+
return warnings;
|
|
16412
16506
|
}
|
|
16413
16507
|
}
|
|
16414
16508
|
]
|
|
@@ -16448,11 +16542,12 @@ async function executeSchemaPhase(phase, containers, state) {
|
|
|
16448
16542
|
continue;
|
|
16449
16543
|
}
|
|
16450
16544
|
try {
|
|
16451
|
-
await task.run();
|
|
16545
|
+
const warnings = await task.run();
|
|
16452
16546
|
await deployApp({ container: containers.schema });
|
|
16453
16547
|
results.push({
|
|
16454
16548
|
domain: task.domain,
|
|
16455
|
-
success: true
|
|
16549
|
+
success: true,
|
|
16550
|
+
warnings
|
|
16456
16551
|
});
|
|
16457
16552
|
} catch (error) {
|
|
16458
16553
|
const err = toError(error);
|
|
@@ -16499,10 +16594,11 @@ async function executeStandardPhase(phase, state) {
|
|
|
16499
16594
|
continue;
|
|
16500
16595
|
}
|
|
16501
16596
|
try {
|
|
16502
|
-
await task.run();
|
|
16597
|
+
const warnings = await task.run();
|
|
16503
16598
|
results.push({
|
|
16504
16599
|
domain: task.domain,
|
|
16505
|
-
success: true
|
|
16600
|
+
success: true,
|
|
16601
|
+
warnings
|
|
16506
16602
|
});
|
|
16507
16603
|
} catch (error) {
|
|
16508
16604
|
const err = toError(error);
|
|
@@ -16615,6 +16711,7 @@ function printPhaseResult(phaseResult) {
|
|
|
16615
16711
|
for (const result of phaseResult.results) {
|
|
16616
16712
|
p.log.message(formatTaskResult(result));
|
|
16617
16713
|
if (!result.success && result.skipped === false) logError(result.error);
|
|
16714
|
+
if (result.success) for (const warning of result.warnings) p.log.warn(warning.message);
|
|
16618
16715
|
}
|
|
16619
16716
|
}
|
|
16620
16717
|
function printPushAllResults(output) {
|