summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2020-12-18 15:16:07 -0500
committerGitHub <noreply@github.com>2020-12-18 15:16:07 -0500
commit5dc7bc0e1522482dd2262846a66b62a70f840ff4 (patch)
tree7df811ae8c3410e39cb1f0b58f311994dad483cc
parent194359f4ec1998a5b36121fa0733ff6329d33633 (diff)
Improve build copy/move modifications to support property ordering (#1122)
-rw-r--r--dev/build.js58
1 files changed, 47 insertions, 11 deletions
diff --git a/dev/build.js b/dev/build.js
index 52e7d541..3fd62893 100644
--- a/dev/build.js
+++ b/dev/build.js
@@ -123,21 +123,24 @@ function applyModifications(manifest, modifications) {
}
break;
case 'copy':
- {
- const {newPath} = modification;
- const value = getObjectProperties(manifest, path2, path2.length);
- const newObject = getObjectProperties(manifest, newPath, newPath.length - 1);
- newObject[newPath[newPath.length - 1]] = value;
- }
- break;
case 'move':
{
- const {newPath} = modification;
- const value = getObjectProperties(manifest, path2, path2.length);
+ const {newPath, before, after} = modification;
+ const oldKey = path2[path2.length - 1];
+ const newKey = newPath[newPath.length - 1];
const oldObject = getObjectProperties(manifest, path2, path2.length - 1);
const newObject = getObjectProperties(manifest, newPath, newPath.length - 1);
- newObject[newPath[newPath.length - 1]] = value;
- delete oldObject[path2[path2.length - 1]];
+ const oldObjectIsNewObject = arraysAreSame(path2, newPath, -1);
+ const value = oldObject[oldKey];
+
+ let index = (oldObjectIsNewObject && action !== 'copy') ? getObjectKeyIndex(oldObject, oldKey) : -1;
+ if (typeof before === 'string') { index = getObjectKeyIndex(newObject, before); }
+ if (typeof after === 'string') { index = getObjectKeyIndex(newObject, after); }
+
+ setObjectKeyAtIndex(newObject, newKey, value, index);
+ if (action !== 'copy' && (!oldObjectIsNewObject || oldKey !== newKey)) {
+ delete oldObject[oldKey];
+ }
}
break;
}
@@ -147,6 +150,39 @@ function applyModifications(manifest, modifications) {
return manifest;
}
+function arraysAreSame(array1, array2, lengthOffset) {
+ let ii = array1.length;
+ if (ii !== array2.length) { return false; }
+ ii += lengthOffset;
+ for (let i = 0; i < ii; ++i) {
+ if (array1[i] !== array2[i]) { return false; }
+ }
+ return true;
+}
+
+function getObjectKeyIndex(object, key) {
+ return Object.keys(object).indexOf(key);
+}
+
+function setObjectKeyAtIndex(object, key, value, index) {
+ if (index < 0 || Object.prototype.hasOwnProperty.call(object, key)) {
+ object[key] = value;
+ return;
+ }
+
+ const entries = Object.entries(object);
+ index = Math.min(index, entries.length);
+ for (let i = index, ii = entries.length; i < ii; ++i) {
+ const [key2] = entries[i];
+ delete object[key2];
+ }
+ entries.splice(index, 0, [key, value]);
+ for (let i = index, ii = entries.length; i < ii; ++i) {
+ const [key2, value2] = entries[i];
+ object[key2] = value2;
+ }
+}
+
function getObjectProperties(object, path2, count) {
for (let i = 0; i < count; ++i) {
object = object[path2[i]];