kintone-migrator 0.35.2 → 0.35.3
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 +136 -94
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -121,7 +121,6 @@ const ProcessManagementErrorCode = {
|
|
|
121
121
|
PmInvalidEntityType: "PM_INVALID_ENTITY_TYPE",
|
|
122
122
|
PmInvalidBooleanField: "PM_INVALID_BOOLEAN_FIELD",
|
|
123
123
|
PmInvalidActionReference: "PM_INVALID_ACTION_REFERENCE",
|
|
124
|
-
PmDuplicateActionName: "PM_DUPLICATE_ACTION_NAME",
|
|
125
124
|
PmUnresolvedConflict: "PM_UNRESOLVED_CONFLICT"
|
|
126
125
|
};
|
|
127
126
|
//#endregion
|
|
@@ -6811,6 +6810,16 @@ async function applyPlugin({ container }) {
|
|
|
6811
6810
|
};
|
|
6812
6811
|
}
|
|
6813
6812
|
//#endregion
|
|
6813
|
+
//#region src/core/domain/processManagement/valueObject.ts
|
|
6814
|
+
/**
|
|
6815
|
+
* Human-readable label of an action, e.g. `申請する (未申請 → 部長承認待ち)`.
|
|
6816
|
+
* The name alone is ambiguous: kintone allows several actions with the same
|
|
6817
|
+
* name, both from different states and as conditional branches from one state.
|
|
6818
|
+
*/
|
|
6819
|
+
function describeProcessAction(action) {
|
|
6820
|
+
return `${action.name} (${action.from} → ${action.to})`;
|
|
6821
|
+
}
|
|
6822
|
+
//#endregion
|
|
6814
6823
|
//#region src/core/domain/processManagement/services/configParser.ts
|
|
6815
6824
|
const VALID_ASSIGNEE_TYPES$1 = /* @__PURE__ */ new Set([
|
|
6816
6825
|
"ONE",
|
|
@@ -6890,15 +6899,10 @@ const ProcessManagementConfigParser = { parse: (parsed) => {
|
|
|
6890
6899
|
for (const [name, value] of Object.entries(rawStates)) states[name] = parseState(value, name);
|
|
6891
6900
|
if (!Array.isArray(obj.actions) && obj.actions !== void 0) throw new BusinessRuleError(ProcessManagementErrorCode.PmInvalidConfigStructure, "Config \"actions\" must be an array");
|
|
6892
6901
|
const actions = (Array.isArray(obj.actions) ? obj.actions : []).map((item, i) => parseAction(item, i));
|
|
6893
|
-
const actionNames = /* @__PURE__ */ new Set();
|
|
6894
|
-
for (const action of actions) {
|
|
6895
|
-
if (actionNames.has(action.name)) throw new BusinessRuleError(ProcessManagementErrorCode.PmDuplicateActionName, `Duplicate action name: "${action.name}"`);
|
|
6896
|
-
actionNames.add(action.name);
|
|
6897
|
-
}
|
|
6898
6902
|
const stateNames = new Set(Object.keys(states));
|
|
6899
6903
|
for (const action of actions) {
|
|
6900
|
-
if (!stateNames.has(action.from)) throw new BusinessRuleError(ProcessManagementErrorCode.PmInvalidActionReference, `Action "${action
|
|
6901
|
-
if (!stateNames.has(action.to)) throw new BusinessRuleError(ProcessManagementErrorCode.PmInvalidActionReference, `Action "${action
|
|
6904
|
+
if (!stateNames.has(action.from)) throw new BusinessRuleError(ProcessManagementErrorCode.PmInvalidActionReference, `Action "${describeProcessAction(action)}" references unknown "from" state: "${action.from}"`);
|
|
6905
|
+
if (!stateNames.has(action.to)) throw new BusinessRuleError(ProcessManagementErrorCode.PmInvalidActionReference, `Action "${describeProcessAction(action)}" references unknown "to" state: "${action.to}"`);
|
|
6902
6906
|
}
|
|
6903
6907
|
return {
|
|
6904
6908
|
enable,
|
|
@@ -9363,6 +9367,56 @@ function groupByKey(items, keyFn) {
|
|
|
9363
9367
|
return map;
|
|
9364
9368
|
}
|
|
9365
9369
|
//#endregion
|
|
9370
|
+
//#region src/lib/pairByKeyInOrder.ts
|
|
9371
|
+
/**
|
|
9372
|
+
* Pairs local and remote items by key. Items sharing a key are matched by
|
|
9373
|
+
* their order of appearance, so the n-th local item with a key pairs with the
|
|
9374
|
+
* n-th remote item with that key.
|
|
9375
|
+
*
|
|
9376
|
+
* Pairs are returned grouped by key: keys in local first-appearance order,
|
|
9377
|
+
* then remote-only keys in remote first-appearance order.
|
|
9378
|
+
*/
|
|
9379
|
+
function pairByKeyInOrder(local, remote, keyFn) {
|
|
9380
|
+
const localGroups = groupByKey(local, keyFn);
|
|
9381
|
+
const remoteGroups = groupByKey(remote, keyFn);
|
|
9382
|
+
const pairs = [];
|
|
9383
|
+
for (const [key, localItems] of localGroups) {
|
|
9384
|
+
const remoteItems = remoteGroups.get(key) ?? [];
|
|
9385
|
+
const length = Math.max(localItems.length, remoteItems.length);
|
|
9386
|
+
for (let index = 0; index < length; index++) if (index >= remoteItems.length) pairs.push({
|
|
9387
|
+
kind: "localOnly",
|
|
9388
|
+
key,
|
|
9389
|
+
index,
|
|
9390
|
+
local: localItems[index]
|
|
9391
|
+
});
|
|
9392
|
+
else if (index >= localItems.length) pairs.push({
|
|
9393
|
+
kind: "remoteOnly",
|
|
9394
|
+
key,
|
|
9395
|
+
index,
|
|
9396
|
+
remote: remoteItems[index]
|
|
9397
|
+
});
|
|
9398
|
+
else pairs.push({
|
|
9399
|
+
kind: "both",
|
|
9400
|
+
key,
|
|
9401
|
+
index,
|
|
9402
|
+
local: localItems[index],
|
|
9403
|
+
remote: remoteItems[index]
|
|
9404
|
+
});
|
|
9405
|
+
}
|
|
9406
|
+
for (const [key, remoteItems] of remoteGroups) {
|
|
9407
|
+
if (localGroups.has(key)) continue;
|
|
9408
|
+
remoteItems.forEach((remoteItem, index) => {
|
|
9409
|
+
pairs.push({
|
|
9410
|
+
kind: "remoteOnly",
|
|
9411
|
+
key,
|
|
9412
|
+
index,
|
|
9413
|
+
remote: remoteItem
|
|
9414
|
+
});
|
|
9415
|
+
});
|
|
9416
|
+
}
|
|
9417
|
+
return pairs;
|
|
9418
|
+
}
|
|
9419
|
+
//#endregion
|
|
9366
9420
|
//#region src/core/domain/notification/services/diffDetector.ts
|
|
9367
9421
|
function serializeEntity$1(entity) {
|
|
9368
9422
|
return `${entity.type}:${entity.code}`;
|
|
@@ -9416,14 +9470,6 @@ function compareGeneralSection(local, remote) {
|
|
|
9416
9470
|
});
|
|
9417
9471
|
return entries;
|
|
9418
9472
|
}
|
|
9419
|
-
/**
|
|
9420
|
-
* Groups per-record notifications by filterCond. Multiple notifications can share
|
|
9421
|
-
* the same filterCond, so notifications within a group are compared by position
|
|
9422
|
-
* (index-based matching).
|
|
9423
|
-
*/
|
|
9424
|
-
function buildPerRecordMultiMap(notifications) {
|
|
9425
|
-
return groupByKey(notifications, (n) => n.filterCond);
|
|
9426
|
-
}
|
|
9427
9473
|
function perRecordLabel(notif) {
|
|
9428
9474
|
return notif.title || notif.filterCond || "(empty filter)";
|
|
9429
9475
|
}
|
|
@@ -9445,43 +9491,30 @@ function describeReminderChanges(local, remote) {
|
|
|
9445
9491
|
}
|
|
9446
9492
|
function comparePerRecordSection(local, remote) {
|
|
9447
9493
|
const entries = [];
|
|
9448
|
-
const
|
|
9449
|
-
|
|
9450
|
-
|
|
9451
|
-
const remoteNotifs = remoteMulti.get(key) ?? [];
|
|
9452
|
-
const maxLen = Math.max(localNotifs.length, remoteNotifs.length);
|
|
9453
|
-
for (let i = 0; i < maxLen; i++) {
|
|
9454
|
-
const localNotif = localNotifs[i];
|
|
9455
|
-
const remoteNotif = remoteNotifs[i];
|
|
9456
|
-
if (localNotif && !remoteNotif) entries.push({
|
|
9494
|
+
for (const pair of pairByKeyInOrder(local, remote, (n) => n.filterCond)) switch (pair.kind) {
|
|
9495
|
+
case "localOnly":
|
|
9496
|
+
entries.push({
|
|
9457
9497
|
type: "added",
|
|
9458
9498
|
section: "perRecord",
|
|
9459
|
-
name: perRecordLabel(
|
|
9499
|
+
name: perRecordLabel(pair.local),
|
|
9460
9500
|
details: "new notification"
|
|
9461
9501
|
});
|
|
9462
|
-
|
|
9502
|
+
break;
|
|
9503
|
+
case "remoteOnly":
|
|
9504
|
+
entries.push({
|
|
9463
9505
|
type: "deleted",
|
|
9464
9506
|
section: "perRecord",
|
|
9465
|
-
name: perRecordLabel(
|
|
9507
|
+
name: perRecordLabel(pair.remote),
|
|
9466
9508
|
details: "removed"
|
|
9467
9509
|
});
|
|
9468
|
-
|
|
9469
|
-
|
|
9470
|
-
|
|
9471
|
-
|
|
9472
|
-
|
|
9473
|
-
|
|
9474
|
-
|
|
9475
|
-
});
|
|
9476
|
-
}
|
|
9477
|
-
}
|
|
9510
|
+
break;
|
|
9511
|
+
case "both": if (!deepEqual(pair.local, pair.remote)) entries.push({
|
|
9512
|
+
type: "modified",
|
|
9513
|
+
section: "perRecord",
|
|
9514
|
+
name: perRecordLabel(pair.local),
|
|
9515
|
+
details: describePerRecordChanges(pair.local, pair.remote)
|
|
9516
|
+
});
|
|
9478
9517
|
}
|
|
9479
|
-
for (const [key, remoteNotifs] of remoteMulti) if (!localMulti.has(key)) for (const remoteNotif of remoteNotifs) entries.push({
|
|
9480
|
-
type: "deleted",
|
|
9481
|
-
section: "perRecord",
|
|
9482
|
-
name: perRecordLabel(remoteNotif),
|
|
9483
|
-
details: "removed"
|
|
9484
|
-
});
|
|
9485
9518
|
return entries;
|
|
9486
9519
|
}
|
|
9487
9520
|
function compareReminderSection(local, remote) {
|
|
@@ -9637,8 +9670,6 @@ function isExecutableUserEqual(a, b) {
|
|
|
9637
9670
|
}
|
|
9638
9671
|
function compareActions(localAction, remoteAction) {
|
|
9639
9672
|
const diffs = [];
|
|
9640
|
-
if (localAction.from !== remoteAction.from) diffs.push(`from: ${remoteAction.from} -> ${localAction.from}`);
|
|
9641
|
-
if (localAction.to !== remoteAction.to) diffs.push(`to: ${remoteAction.to} -> ${localAction.to}`);
|
|
9642
9673
|
if (localAction.filterCond !== remoteAction.filterCond) diffs.push(`filterCond: "${remoteAction.filterCond}" -> "${localAction.filterCond}"`);
|
|
9643
9674
|
if (localAction.type !== remoteAction.type) diffs.push(`type: ${remoteAction.type} -> ${localAction.type}`);
|
|
9644
9675
|
if (!isExecutableUserEqual(localAction.executableUser, remoteAction.executableUser)) diffs.push(`executableUser: ${formatValue(remoteAction.executableUser)} -> ${formatValue(localAction.executableUser)}`);
|
|
@@ -9674,33 +9705,52 @@ function compareStates(local, remote, entries) {
|
|
|
9674
9705
|
details: `assignee: ${remote.states[name].assignee.type}`
|
|
9675
9706
|
});
|
|
9676
9707
|
}
|
|
9708
|
+
/**
|
|
9709
|
+
* Identifies an action by name + from + to. kintone allows same-named actions
|
|
9710
|
+
* both from different states and as conditional branches from one state.
|
|
9711
|
+
* Repeats of the whole triple are not rejected either, so actions sharing a
|
|
9712
|
+
* triple are told apart by their order of appearance.
|
|
9713
|
+
*/
|
|
9714
|
+
function transitionKey(action) {
|
|
9715
|
+
return JSON.stringify([
|
|
9716
|
+
action.name,
|
|
9717
|
+
action.from,
|
|
9718
|
+
action.to
|
|
9719
|
+
]);
|
|
9720
|
+
}
|
|
9721
|
+
function actionLabel(action, index) {
|
|
9722
|
+
const label = describeProcessAction(action);
|
|
9723
|
+
return index === 0 ? label : `${label} #${index + 1}`;
|
|
9724
|
+
}
|
|
9677
9725
|
function compareActionEntries(local, remote, entries) {
|
|
9678
|
-
const
|
|
9679
|
-
|
|
9680
|
-
|
|
9681
|
-
|
|
9682
|
-
|
|
9683
|
-
|
|
9684
|
-
|
|
9685
|
-
|
|
9686
|
-
|
|
9687
|
-
|
|
9688
|
-
|
|
9689
|
-
|
|
9726
|
+
for (const pair of pairByKeyInOrder(local.actions, remote.actions, transitionKey)) switch (pair.kind) {
|
|
9727
|
+
case "localOnly":
|
|
9728
|
+
entries.push({
|
|
9729
|
+
type: "added",
|
|
9730
|
+
category: "action",
|
|
9731
|
+
name: actionLabel(pair.local, pair.index),
|
|
9732
|
+
details: `filterCond: "${pair.local.filterCond}"`
|
|
9733
|
+
});
|
|
9734
|
+
break;
|
|
9735
|
+
case "remoteOnly":
|
|
9736
|
+
entries.push({
|
|
9737
|
+
type: "deleted",
|
|
9738
|
+
category: "action",
|
|
9739
|
+
name: actionLabel(pair.remote, pair.index),
|
|
9740
|
+
details: `filterCond: "${pair.remote.filterCond}"`
|
|
9741
|
+
});
|
|
9742
|
+
break;
|
|
9743
|
+
case "both": {
|
|
9744
|
+
const actionDiffs = compareActions(pair.local, pair.remote);
|
|
9690
9745
|
if (actionDiffs.length > 0) entries.push({
|
|
9691
9746
|
type: "modified",
|
|
9692
9747
|
category: "action",
|
|
9693
|
-
name,
|
|
9748
|
+
name: actionLabel(pair.local, pair.index),
|
|
9694
9749
|
details: actionDiffs.join("\n")
|
|
9695
9750
|
});
|
|
9751
|
+
break;
|
|
9696
9752
|
}
|
|
9697
9753
|
}
|
|
9698
|
-
for (const [name, remoteAction] of remoteActionMap) if (!localActionMap.has(name)) entries.push({
|
|
9699
|
-
type: "deleted",
|
|
9700
|
-
category: "action",
|
|
9701
|
-
name,
|
|
9702
|
-
details: `${remoteAction.from} -> ${remoteAction.to}`
|
|
9703
|
-
});
|
|
9704
9754
|
}
|
|
9705
9755
|
function compareConfigs(local, remote) {
|
|
9706
9756
|
const entries = [];
|
|
@@ -9758,24 +9808,27 @@ function describeRight(right) {
|
|
|
9758
9808
|
});
|
|
9759
9809
|
return perEntity.length > 0 ? perEntity.join(", ") : "no entities";
|
|
9760
9810
|
}
|
|
9761
|
-
|
|
9762
|
-
const
|
|
9763
|
-
for (
|
|
9764
|
-
const
|
|
9765
|
-
|
|
9766
|
-
|
|
9767
|
-
|
|
9768
|
-
|
|
9769
|
-
|
|
9770
|
-
|
|
9771
|
-
|
|
9772
|
-
|
|
9773
|
-
|
|
9774
|
-
|
|
9775
|
-
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
|
|
9811
|
+
const RecordPermissionDiffDetector = { detect: (local, remote) => {
|
|
9812
|
+
const entries = [];
|
|
9813
|
+
for (const pair of pairByKeyInOrder(local.rights, remote.rights, (r) => r.filterCond)) {
|
|
9814
|
+
const filterCond = pair.key;
|
|
9815
|
+
switch (pair.kind) {
|
|
9816
|
+
case "localOnly":
|
|
9817
|
+
entries.push({
|
|
9818
|
+
type: "added",
|
|
9819
|
+
filterCond,
|
|
9820
|
+
details: describeRight(pair.local)
|
|
9821
|
+
});
|
|
9822
|
+
break;
|
|
9823
|
+
case "remoteOnly":
|
|
9824
|
+
entries.push({
|
|
9825
|
+
type: "deleted",
|
|
9826
|
+
filterCond,
|
|
9827
|
+
details: describeRight(pair.remote)
|
|
9828
|
+
});
|
|
9829
|
+
break;
|
|
9830
|
+
case "both": if (!isRightEqual(pair.local, pair.remote)) {
|
|
9831
|
+
const detail = pair.local.entities.length !== pair.remote.entities.length ? `entities: ${pair.remote.entities.length} -> ${pair.local.entities.length}` : `entities: ${describeRight(pair.remote)} -> ${describeRight(pair.local)}`;
|
|
9779
9832
|
entries.push({
|
|
9780
9833
|
type: "modified",
|
|
9781
9834
|
filterCond,
|
|
@@ -9784,17 +9837,6 @@ function compareRightsForFilter(filterCond, localRights, remoteRights, entries)
|
|
|
9784
9837
|
}
|
|
9785
9838
|
}
|
|
9786
9839
|
}
|
|
9787
|
-
}
|
|
9788
|
-
const RecordPermissionDiffDetector = { detect: (local, remote) => {
|
|
9789
|
-
const entries = [];
|
|
9790
|
-
const localMulti = groupByKey(local.rights, (r) => r.filterCond);
|
|
9791
|
-
const remoteMulti = groupByKey(remote.rights, (r) => r.filterCond);
|
|
9792
|
-
for (const [filterCond, localRights] of localMulti) compareRightsForFilter(filterCond, localRights, remoteMulti.get(filterCond) ?? [], entries);
|
|
9793
|
-
for (const [filterCond, remoteRights] of remoteMulti) if (!localMulti.has(filterCond)) for (const remoteRight of remoteRights) entries.push({
|
|
9794
|
-
type: "deleted",
|
|
9795
|
-
filterCond,
|
|
9796
|
-
details: describeRight(remoteRight)
|
|
9797
|
-
});
|
|
9798
9840
|
return buildDiffResult(entries);
|
|
9799
9841
|
} };
|
|
9800
9842
|
//#endregion
|