diff options
Diffstat (limited to 'src/data/things/sorting-rule.js')
-rw-r--r-- | src/data/things/sorting-rule.js | 109 |
1 files changed, 61 insertions, 48 deletions
diff --git a/src/data/things/sorting-rule.js b/src/data/things/sorting-rule.js index 18da452e..0ed7fb0f 100644 --- a/src/data/things/sorting-rule.js +++ b/src/data/things/sorting-rule.js @@ -6,7 +6,7 @@ import * as path from 'node:path'; import {input} from '#composite'; import {chunkByProperties, compareArrays, unique} from '#sugar'; import Thing from '#thing'; -import {isObject, isStringNonEmpty, strictArrayOf} from '#validators'; +import {isObject, isStringNonEmpty, anyOf, strictArrayOf} from '#validators'; import { compareCaseLessSensitive, @@ -24,6 +24,17 @@ import { import {flag} from '#composite/wiki-properties'; +function isSelectFollowingEntry(value) { + isObject(value); + + const {length} = Object.keys(value); + if (length !== 1) { + throw new Error(`Expected object with 1 key, got ${length}`); + } + + return true; +} + export class SortingRule extends Thing { static [Thing.friendlyName] = `Sorting Rule`; @@ -61,7 +72,7 @@ export class SortingRule extends Thing { save: (results) => ({sortingRules: results}), }); - check({wikiData}) { + check(opts) { return this.constructor.check(this, opts); } @@ -69,19 +80,22 @@ export class SortingRule extends Thing { return this.constructor.apply(this, opts); } - static check() { - throw new Error(`Not implemented`); + static check(rule, opts) { + const result = this.apply(rule, {...opts, dry: true}); + if (!result) return true; + if (!result.changed) return true; + return false; } - static async apply() { + static async apply(_rule, _opts) { throw new Error(`Not implemented`); } - static async* applyAll() { + static async* applyAll(_rules, _opts) { throw new Error(`Not implemented`); } - static async* go({dataPath, wikiData}) { + static async* go({dataPath, wikiData, dry}) { const rules = wikiData.sortingRules; const constructors = unique(rules.map(rule => rule.constructor)); @@ -90,7 +104,7 @@ export class SortingRule extends Thing { rules .filter(rule => rule.active) .filter(rule => rule.constructor === constructor), - {dataPath, wikiData}); + {dataPath, wikiData, dry}); } } } @@ -186,16 +200,17 @@ export class DocumentSortingRule extends ThingSortingRule { flags: {update: true, expose: true}, update: { - validate(value) { - isObject(value); - - const {length} = Object.keys(value); - if (length !== 1) { - throw new Error(`Expected object with 1 key, got ${length}`); - } + validate: + anyOf( + isSelectFollowingEntry, + strictArrayOf(isSelectFollowingEntry)), + }, - return true; - }, + compute: { + transform: value => + (Array.isArray(value) + ? value + : [value]), }, }, @@ -220,24 +235,17 @@ export class DocumentSortingRule extends ThingSortingRule { ], }); - static check(rule, {wikiData}) { + static async apply(rule, {wikiData, dataPath, dry}) { const oldLayout = getThingLayoutForFilename(rule.filename, wikiData); - if (!oldLayout) return; + if (!oldLayout) return null; const newLayout = rule.#processLayout(oldLayout); const oldOrder = flattenThingLayoutToDocumentOrder(oldLayout); const newOrder = flattenThingLayoutToDocumentOrder(newLayout); + const changed = compareArrays(oldOrder, newOrder); - return compareArrays(oldOrder, newOrder); - } - - static async apply(rule, {wikiData, dataPath}) { - const oldLayout = getThingLayoutForFilename(rule.filename, wikiData); - if (!oldLayout) return; - - const newLayout = rule.#processLayout(oldLayout); - const newOrder = flattenThingLayoutToDocumentOrder(newLayout); + if (dry) return {changed}; const realPath = path.join( @@ -248,9 +256,11 @@ export class DocumentSortingRule extends ThingSortingRule { const newSourceText = reorderDocumentsInYAMLSourceText(oldSourceText, newOrder); await writeFile(realPath, newSourceText); + + return {changed}; } - static async* applyAll(rules, {wikiData, dataPath}) { + static async* applyAll(rules, {wikiData, dataPath, dry}) { rules = rules .slice() @@ -281,6 +291,7 @@ export class DocumentSortingRule extends ThingSortingRule { } if (!anyChanged) continue; + if (dry) continue; const newLayout = currLayout; const newOrder = flattenThingLayoutToDocumentOrder(newLayout); @@ -317,31 +328,33 @@ export class DocumentSortingRule extends ThingSortingRule { } if (this.selectDocumentsFollowing) { - const [field, value] = Object.entries(this.selectDocumentsFollowing)[0]; + for (const entry of this.selectDocumentsFollowing) { + const [field, value] = Object.entries(entry)[0]; - const after = - sortable.findIndex(thing => - thing[Thing.yamlSourceDocument][field] === value); + const after = + sortable.findIndex(thing => + thing[Thing.yamlSourceDocument][field] === value); - const different = - after + - sortable - .slice(after) - .findIndex(thing => - Object.hasOwn(thing[Thing.yamlSourceDocument], field) && - thing[Thing.yamlSourceDocument][field] !== value); + const different = + after + + sortable + .slice(after) + .findIndex(thing => + Object.hasOwn(thing[Thing.yamlSourceDocument], field) && + thing[Thing.yamlSourceDocument][field] !== value); - const before = - (different === -1 - ? sortable.length - : different); + const before = + (different === -1 + ? sortable.length + : different); - const subsortable = - sortable.slice(after + 1, before); + const subsortable = + sortable.slice(after + 1, before); - this.sort(subsortable); + this.sort(subsortable); - sortable.splice(after + 1, before - after - 1, ...subsortable); + sortable.splice(after + 1, before - after - 1, ...subsortable); + } } else if (this.selectDocumentsUnder) { const field = this.selectDocumentsUnder; |