@design-edito/tools 0.4.23 → 0.5.1
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/agnostic/arrays/find-duplicates/index.d.ts +1 -1
- package/agnostic/arrays/find-duplicates/index.js +3 -2
- package/agnostic/arrays/index.d.ts +1 -1
- package/agnostic/arrays/index.js +1 -1
- package/agnostic/arrays/is-array-of/index.d.ts +1 -1
- package/agnostic/arrays/is-array-of/index.js +3 -1
- package/agnostic/arrays/make/index.d.ts +1 -1
- package/agnostic/arrays/random-pick/index.js +2 -1
- package/agnostic/arrays/shuffle/index.js +1 -1
- package/agnostic/booleans/is-falsy/index.d.ts +3 -3
- package/agnostic/booleans/is-falsy/index.js +2 -3
- package/agnostic/colors/channels/index.d.ts +16 -16
- package/agnostic/colors/channels/index.js +15 -15
- package/agnostic/colors/contrast/index.d.ts +6 -6
- package/agnostic/colors/contrast/index.js +6 -8
- package/agnostic/colors/contrast/index.test.js +1 -1
- package/agnostic/colors/convert/index.d.ts +43 -43
- package/agnostic/colors/convert/index.js +60 -55
- package/agnostic/colors/distance/index.d.ts +5 -5
- package/agnostic/colors/distance/index.js +5 -4
- package/agnostic/colors/grayscale/index.d.ts +3 -3
- package/agnostic/colors/grayscale/index.js +3 -3
- package/agnostic/colors/index.d.ts +3 -3
- package/agnostic/colors/index.js +3 -3
- package/agnostic/colors/invert/index.d.ts +4 -4
- package/agnostic/colors/invert/index.js +3 -3
- package/agnostic/colors/lerp/index.d.ts +6 -7
- package/agnostic/colors/lerp/index.js +5 -6
- package/agnostic/colors/luminance/index.d.ts +4 -4
- package/agnostic/colors/luminance/index.js +3 -3
- package/agnostic/colors/palette/index.d.ts +3 -3
- package/agnostic/colors/palette/index.js +4 -3
- package/agnostic/colors/rotate/index.d.ts +4 -4
- package/agnostic/colors/rotate/index.js +4 -4
- package/agnostic/colors/tidy/index.d.ts +2 -2
- package/agnostic/colors/tidy/index.js +2 -2
- package/agnostic/colors/typechecks/index.d.ts +21 -21
- package/agnostic/colors/typechecks/index.js +22 -21
- package/agnostic/colors/types.d.ts +33 -33
- package/agnostic/css/bem/index.d.ts +11 -11
- package/agnostic/css/bem/index.js +9 -8
- package/agnostic/css/clss/index.d.ts +1 -1
- package/agnostic/css/clss/index.js +1 -1
- package/agnostic/css/index.d.ts +2 -2
- package/agnostic/css/index.js +2 -2
- package/agnostic/css/is-valid-css-class-name/index.d.ts +2 -2
- package/agnostic/css/is-valid-css-class-name/index.js +3 -3
- package/agnostic/css/scale/index.d.ts +18 -18
- package/agnostic/css/scale/index.js +18 -18
- package/agnostic/css/styles-set/index.d.ts +1 -1
- package/agnostic/css/styles-set/index.js +0 -2
- package/agnostic/errors/register/index.d.ts +1 -1
- package/agnostic/errors/register/index.js +3 -0
- package/agnostic/errors/unknown-to-string/index.d.ts +2 -2
- package/agnostic/errors/unknown-to-string/index.js +2 -3
- package/agnostic/html/deep-select/index.d.ts +3 -3
- package/agnostic/html/deep-select/index.js +11 -7
- package/agnostic/html/get-node-ancestors/index.d.ts +3 -3
- package/agnostic/html/get-node-ancestors/index.js +3 -3
- package/agnostic/html/get-position-inside-parent/index.d.ts +2 -2
- package/agnostic/html/get-position-inside-parent/index.js +2 -2
- package/agnostic/html/hyper-json/cast/index.d.ts +1 -1
- package/agnostic/html/hyper-json/cast/index.js +6 -5
- package/agnostic/html/hyper-json/method/index.d.ts +2 -2
- package/agnostic/html/hyper-json/serialize/index.d.ts +1 -1
- package/agnostic/html/hyper-json/serialize/index.js +9 -5
- package/agnostic/html/hyper-json/smart-tags/coalesced/addclass/index.js +1 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/and/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/append/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/append/index.js +1 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/at/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/at/index.js +1 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/call/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/call/index.js +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/clone/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/deleteproperties/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/deleteproperties/index.js +0 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/equals/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/getattribute/index.js +1 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/getproperties/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/getproperty/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/getproperty/index.js +1 -2
- package/agnostic/html/hyper-json/smart-tags/coalesced/hjparse/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/hjstringify/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/hjstringify/index.js +4 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/if/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/if/index.js +1 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/index.d.ts +12 -12
- package/agnostic/html/hyper-json/smart-tags/coalesced/index.js +12 -12
- package/agnostic/html/hyper-json/smart-tags/coalesced/initialize/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/initialize/index.js +1 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/join/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/length/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/map/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/or/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/pickrandom/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/populate/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/populate/index.js +1 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/print/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/print/index.js +2 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/push/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/pusheach/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/pusheach/index.js +1 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/recordtoarray/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/removeattribute/index.js +3 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/removeclass/index.js +1 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/renameproperty/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/renameproperty/index.js +1 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/replace/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/replace/index.js +1 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/select/index.js +1 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/set/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/set/index.js +1 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/setattribute/index.js +3 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/setproperty/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/setproperty/index.js +4 -2
- package/agnostic/html/hyper-json/smart-tags/coalesced/sorton/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/sorton/index.js +5 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/spread/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/spread/index.js +1 -0
- package/agnostic/html/hyper-json/smart-tags/coalesced/toarray/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/toboolean/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/toelement/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/toggleclass/index.js +3 -2
- package/agnostic/html/hyper-json/smart-tags/coalesced/tonodelist/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/tonull/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/tonumber/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/torecord/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/toref/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/tostring/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/totext/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/transformselected/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/coalesced/trim/index.js +1 -1
- package/agnostic/html/hyper-json/smart-tags/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/isolated/any/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/isolated/array/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/isolated/get/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/isolated/guess/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/isolated/guess/index.js +3 -1
- package/agnostic/html/hyper-json/smart-tags/isolated/index.d.ts +2 -2
- package/agnostic/html/hyper-json/smart-tags/isolated/index.js +2 -2
- package/agnostic/html/hyper-json/smart-tags/isolated/nodelist/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/isolated/nodelist/index.js +1 -0
- package/agnostic/html/hyper-json/smart-tags/isolated/null/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/isolated/record/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/isolated/ref/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/isolated/ref/index.js +3 -1
- package/agnostic/html/hyper-json/smart-tags/isolated/text/index.js +2 -2
- package/agnostic/html/hyper-json/transformer/index.d.ts +5 -5
- package/agnostic/html/hyper-json/tree/index.d.ts +1 -1
- package/agnostic/html/hyper-json/tree/index.js +14 -8
- package/agnostic/html/hyper-json/types/index.d.ts +11 -11
- package/agnostic/html/hyper-json/utils/index.d.ts +3 -3
- package/agnostic/html/hyper-json/utils/index.js +8 -3
- package/agnostic/html/index.d.ts +4 -4
- package/agnostic/html/index.js +4 -4
- package/agnostic/html/insert-node/index.d.ts +4 -4
- package/agnostic/html/insert-node/index.js +4 -4
- package/agnostic/html/replace-in-element/index.d.ts +3 -3
- package/agnostic/html/replace-in-element/index.js +4 -4
- package/agnostic/html/selector-to-element/index.d.ts +2 -2
- package/agnostic/html/selector-to-element/index.js +11 -11
- package/agnostic/html/string-to-nodes/index.d.ts +3 -3
- package/agnostic/html/string-to-nodes/index.js +3 -3
- package/agnostic/html/watch-selection/index.d.ts +4 -5
- package/agnostic/html/watch-selection/index.js +5 -6
- package/agnostic/index.d.ts +3 -3
- package/agnostic/index.js +3 -3
- package/agnostic/misc/assert/index.js +3 -1
- package/agnostic/misc/cast/index.d.ts +16 -16
- package/agnostic/misc/cast/index.js +18 -18
- package/agnostic/misc/connection/index.d.ts +5 -5
- package/agnostic/misc/connection/index.js +4 -2
- package/agnostic/misc/crawler/index.d.ts +18 -18
- package/agnostic/misc/crawler/index.js +10 -9
- package/agnostic/misc/crawler/index.test.js +2 -2
- package/agnostic/misc/crossenv/detect-runtime/index.d.ts +1 -1
- package/agnostic/misc/crossenv/detect-runtime/index.js +10 -11
- package/agnostic/misc/crossenv/window/index.d.ts +6 -6
- package/agnostic/misc/crossenv/window/index.js +6 -5
- package/agnostic/misc/data-size/index.js +2 -0
- package/agnostic/misc/index.d.ts +3 -3
- package/agnostic/misc/index.js +3 -3
- package/agnostic/misc/is-constructor-function/index.d.ts +2 -2
- package/agnostic/misc/is-constructor-function/index.js +3 -2
- package/agnostic/misc/is-constructor-function/index.test.js +2 -2
- package/agnostic/misc/is-nullish/index.d.ts +5 -5
- package/agnostic/misc/is-nullish/index.js +5 -4
- package/agnostic/misc/logs/index.d.ts +1 -1
- package/agnostic/misc/logs/index.js +1 -1
- package/agnostic/misc/logs/logger/index.js +2 -2
- package/agnostic/misc/lorem-ipsum/index.js +4 -4
- package/agnostic/misc/normalize-extension/index.d.ts +3 -3
- package/agnostic/misc/normalize-extension/index.js +4 -4
- package/agnostic/misc/outcome/index.d.ts +14 -14
- package/agnostic/misc/outcome/index.js +6 -4
- package/agnostic/numbers/absolute-modulo/index.d.ts +3 -3
- package/agnostic/numbers/absolute-modulo/index.js +3 -3
- package/agnostic/numbers/approximate-rational/index.d.ts +6 -6
- package/agnostic/numbers/approximate-rational/index.js +9 -9
- package/agnostic/numbers/clamp/index.d.ts +4 -4
- package/agnostic/numbers/clamp/index.js +4 -4
- package/agnostic/numbers/geometric-progressions/index.d.ts +5 -5
- package/agnostic/numbers/geometric-progressions/index.js +7 -5
- package/agnostic/numbers/geometric-progressions/index.test.js +2 -2
- package/agnostic/numbers/index.d.ts +3 -3
- package/agnostic/numbers/index.js +3 -3
- package/agnostic/numbers/interpolate/index.d.ts +8 -8
- package/agnostic/numbers/interpolate/index.js +8 -8
- package/agnostic/numbers/round/index.d.ts +9 -9
- package/agnostic/numbers/round/index.js +9 -9
- package/agnostic/objects/deep-get-property/index.d.ts +4 -4
- package/agnostic/objects/deep-get-property/index.js +3 -3
- package/agnostic/objects/enums/is-in-enum/index.d.ts +3 -3
- package/agnostic/objects/enums/is-in-enum/index.js +3 -3
- package/agnostic/objects/flatten-getters/index.d.ts +2 -2
- package/agnostic/objects/flatten-getters/index.js +3 -2
- package/agnostic/objects/index.d.ts +4 -4
- package/agnostic/objects/index.js +4 -4
- package/agnostic/objects/is-object/index.d.ts +4 -4
- package/agnostic/objects/is-object/index.js +4 -4
- package/agnostic/objects/is-record/index.d.ts +2 -2
- package/agnostic/objects/is-record/index.js +2 -2
- package/agnostic/objects/record-format/index.d.ts +9 -9
- package/agnostic/objects/record-format/index.js +8 -3
- package/agnostic/objects/record-map/index.d.ts +4 -4
- package/agnostic/objects/record-map/index.js +5 -3
- package/agnostic/objects/sort-keys/index.d.ts +3 -3
- package/agnostic/objects/sort-keys/index.js +4 -3
- package/agnostic/objects/validation/index.d.ts +3 -3
- package/agnostic/objects/validation/index.js +4 -3
- package/agnostic/optim/memoize/index.d.ts +2 -2
- package/agnostic/optim/memoize/index.js +4 -2
- package/agnostic/optim/throttle-debounce/index.d.ts +2 -2
- package/agnostic/optim/throttle-debounce/index.js +7 -6
- package/agnostic/optim/throttle-debounce/types.d.ts +2 -1
- package/agnostic/random/index.d.ts +1 -1
- package/agnostic/random/index.js +1 -1
- package/agnostic/random/random/index.d.ts +7 -8
- package/agnostic/random/random/index.js +3 -3
- package/agnostic/random/uuid/index.d.ts +6 -6
- package/agnostic/random/uuid/index.js +6 -6
- package/agnostic/regexps/index.d.ts +30 -60
- package/agnostic/regexps/index.js +27 -26
- package/agnostic/sanitization/file-name/index.d.ts +3 -3
- package/agnostic/sanitization/file-name/index.js +10 -10
- package/agnostic/sanitization/html/index.d.ts +6 -6
- package/agnostic/sanitization/html/index.js +9 -6
- package/agnostic/sanitization/index.d.ts +1 -1
- package/agnostic/sanitization/index.js +1 -1
- package/agnostic/sanitization/path/index.d.ts +2 -2
- package/agnostic/sanitization/path/index.js +2 -2
- package/agnostic/sanitization/user-input/index.js +1 -0
- package/agnostic/strings/char-codes/index.js +2 -6
- package/agnostic/strings/index.d.ts +3 -3
- package/agnostic/strings/index.js +3 -3
- package/agnostic/strings/normalize-indent/index.js +2 -2
- package/agnostic/strings/parse-table/index.d.ts +13 -13
- package/agnostic/strings/parse-table/index.js +31 -16
- package/agnostic/strings/replace-all/index.d.ts +1 -1
- package/agnostic/strings/replace-all/index.js +1 -0
- package/agnostic/strings/to-alphanum/index.js +2 -2
- package/agnostic/strings/trim/index.js +2 -2
- package/agnostic/time/dates/format-date/index.js +3 -1
- package/agnostic/time/dates/index.d.ts +1 -0
- package/agnostic/time/dates/index.js +1 -0
- package/agnostic/time/dates/to-french-republican/index.d.ts +16 -0
- package/agnostic/time/dates/to-french-republican/index.js +82 -0
- package/agnostic/time/dates/to-french-republican/index.test.d.ts +1 -0
- package/agnostic/time/dates/to-french-republican/index.test.js +112 -0
- package/agnostic/time/dates/to-french-republican/types.d.ts +91 -0
- package/agnostic/time/dates/to-french-republican/types.js +47 -0
- package/agnostic/time/dates/to-french-republican/utils.d.ts +32 -0
- package/agnostic/time/dates/to-french-republican/utils.js +155 -0
- package/agnostic/time/duration/index.js +2 -0
- package/agnostic/time/index.d.ts +2 -2
- package/agnostic/time/index.js +2 -2
- package/agnostic/time/timeout/index.js +9 -9
- package/agnostic/time/transitions/index.js +8 -7
- package/components/BeforeAfter/index.controlled.js +1 -0
- package/components/BeforeAfter/index.js +4 -0
- package/components/Button/index.d.ts +1 -1
- package/components/Clippable/index.js +1 -0
- package/components/Drawer/index.js +1 -1
- package/components/Gallery/index.js +2 -1
- package/components/Gallery/utils.js +5 -1
- package/components/Iframe/index.js +3 -0
- package/components/Image/index.js +2 -0
- package/components/Input/index.controlled.js +3 -2
- package/components/IntersectionObserver/index.js +5 -2
- package/components/JsonEditor/index.js +1 -1
- package/components/Overlayer/index.d.ts +1 -1
- package/components/ScrollListener/utils.d.ts +29 -0
- package/components/Select/index.controlled.js +3 -2
- package/components/Sequencer/index.controlled.js +1 -1
- package/components/Subtitles/index.js +3 -1
- package/components/Subtitles/types.d.ts +14 -0
- package/components/Subtitles/utils.d.ts +19 -15
- package/components/Subtitles/utils.js +29 -24
- package/components/Textarea/index.controlled.js +3 -2
- package/components/UIModule/index.js +3 -1
- package/components/Video/index.controlled.d.ts +1 -1
- package/components/Video/index.controlled.js +11 -10
- package/components/Video/index.js +27 -20
- package/components/Video/utils.d.ts +1 -1
- package/components/Video/utils.js +11 -2
- package/components/index.d.ts +5 -5
- package/components/index.js +5 -5
- package/components/utils/types.d.ts +5 -0
- package/node/@aws-s3/storage/directory/copy-dir/index.d.ts +9 -9
- package/node/@aws-s3/storage/directory/copy-dir/index.js +15 -12
- package/node/@aws-s3/storage/directory/list/index.d.ts +5 -5
- package/node/@aws-s3/storage/directory/list/index.js +5 -5
- package/node/@aws-s3/storage/directory/move-dir/index.d.ts +6 -6
- package/node/@aws-s3/storage/directory/move-dir/index.js +11 -7
- package/node/@aws-s3/storage/directory/remove-dir/index.d.ts +5 -5
- package/node/@aws-s3/storage/directory/remove-dir/index.js +5 -5
- package/node/@aws-s3/storage/file/copy/index.d.ts +8 -8
- package/node/@aws-s3/storage/file/copy/index.js +12 -9
- package/node/@aws-s3/storage/file/download/index.d.ts +6 -6
- package/node/@aws-s3/storage/file/download/index.js +6 -5
- package/node/@aws-s3/storage/file/exists/index.d.ts +6 -6
- package/node/@aws-s3/storage/file/exists/index.js +15 -12
- package/node/@aws-s3/storage/file/move/index.d.ts +9 -9
- package/node/@aws-s3/storage/file/move/index.js +18 -15
- package/node/@aws-s3/storage/file/remove/index.d.ts +5 -5
- package/node/@aws-s3/storage/file/remove/index.js +16 -11
- package/node/@aws-s3/storage/file/stat/index.d.ts +5 -5
- package/node/@aws-s3/storage/file/stat/index.js +10 -7
- package/node/@aws-s3/storage/file/upload/index.d.ts +7 -7
- package/node/@aws-s3/storage/file/upload/index.js +11 -9
- package/node/@express/@multer/index.d.ts +12 -12
- package/node/@express/@multer/index.js +27 -25
- package/node/@google-cloud/storage/bucket/get-metadata/index.d.ts +4 -4
- package/node/@google-cloud/storage/bucket/get-metadata/index.js +3 -3
- package/node/@google-cloud/storage/directory/copy-dir/index.d.ts +7 -7
- package/node/@google-cloud/storage/directory/copy-dir/index.js +6 -6
- package/node/@google-cloud/storage/directory/index.d.ts +2 -2
- package/node/@google-cloud/storage/directory/index.js +2 -2
- package/node/@google-cloud/storage/directory/list/index.d.ts +6 -6
- package/node/@google-cloud/storage/directory/list/index.js +5 -5
- package/node/@google-cloud/storage/directory/move-dir/index.d.ts +6 -6
- package/node/@google-cloud/storage/directory/move-dir/index.js +5 -5
- package/node/@google-cloud/storage/directory/remove-dir/index.d.ts +7 -7
- package/node/@google-cloud/storage/directory/remove-dir/index.js +6 -6
- package/node/@google-cloud/storage/file/copy/index.d.ts +9 -9
- package/node/@google-cloud/storage/file/copy/index.js +8 -8
- package/node/@google-cloud/storage/file/download/index.d.ts +7 -7
- package/node/@google-cloud/storage/file/download/index.js +5 -5
- package/node/@google-cloud/storage/file/exists/index.d.ts +7 -7
- package/node/@google-cloud/storage/file/exists/index.js +6 -6
- package/node/@google-cloud/storage/file/generate-signed-url/index.d.ts +7 -7
- package/node/@google-cloud/storage/file/generate-signed-url/index.js +6 -6
- package/node/@google-cloud/storage/file/get-metadata/index.d.ts +5 -5
- package/node/@google-cloud/storage/file/get-metadata/index.js +4 -4
- package/node/@google-cloud/storage/file/get-permissions/index.d.ts +6 -6
- package/node/@google-cloud/storage/file/get-permissions/index.js +4 -4
- package/node/@google-cloud/storage/file/index.d.ts +3 -3
- package/node/@google-cloud/storage/file/index.js +3 -3
- package/node/@google-cloud/storage/file/move/index.d.ts +10 -10
- package/node/@google-cloud/storage/file/move/index.js +9 -9
- package/node/@google-cloud/storage/file/remove/index.d.ts +5 -5
- package/node/@google-cloud/storage/file/remove/index.js +4 -4
- package/node/@google-cloud/storage/file/revoke-signed-urls/index.d.ts +5 -5
- package/node/@google-cloud/storage/file/revoke-signed-urls/index.js +5 -5
- package/node/@google-cloud/storage/file/stat/index.d.ts +5 -5
- package/node/@google-cloud/storage/file/stat/index.js +4 -4
- package/node/@google-cloud/storage/file/update-metadata/index.d.ts +7 -7
- package/node/@google-cloud/storage/file/update-metadata/index.js +5 -5
- package/node/@google-cloud/storage/file/upload/index.d.ts +7 -7
- package/node/@google-cloud/storage/file/upload/index.js +5 -5
- package/node/@google-cloud/storage/index.d.ts +1 -1
- package/node/@google-cloud/storage/index.js +1 -1
- package/node/cloud-storage/clients/index.d.ts +8 -8
- package/node/cloud-storage/clients/index.js +8 -8
- package/node/cloud-storage/operations/copy-dir/index.d.ts +22 -22
- package/node/cloud-storage/operations/copy-dir/index.js +5 -5
- package/node/cloud-storage/operations/copy-file/index.d.ts +22 -22
- package/node/cloud-storage/operations/copy-file/index.js +5 -5
- package/node/cloud-storage/operations/download-file/index.d.ts +19 -19
- package/node/cloud-storage/operations/download-file/index.js +6 -6
- package/node/cloud-storage/operations/exists-file/index.d.ts +15 -26
- package/node/cloud-storage/operations/exists-file/index.js +4 -4
- package/node/cloud-storage/operations/index.d.ts +2 -2
- package/node/cloud-storage/operations/index.js +2 -2
- package/node/cloud-storage/operations/list-dir/index.d.ts +15 -25
- package/node/cloud-storage/operations/list-dir/index.js +4 -4
- package/node/cloud-storage/operations/move-dir/index.d.ts +22 -22
- package/node/cloud-storage/operations/move-dir/index.js +5 -5
- package/node/cloud-storage/operations/move-file/index.d.ts +22 -22
- package/node/cloud-storage/operations/move-file/index.js +5 -5
- package/node/cloud-storage/operations/remove-dir/index.d.ts +18 -18
- package/node/cloud-storage/operations/remove-dir/index.js +4 -4
- package/node/cloud-storage/operations/remove-file/index.d.ts +18 -18
- package/node/cloud-storage/operations/remove-file/index.js +4 -4
- package/node/cloud-storage/operations/stat-file/index.d.ts +16 -16
- package/node/cloud-storage/operations/stat-file/index.js +4 -4
- package/node/cloud-storage/operations/upload-file/index.d.ts +23 -23
- package/node/cloud-storage/operations/upload-file/index.js +5 -5
- package/node/encryption/@aes-256-gcm/buffer/index.d.ts +6 -6
- package/node/encryption/@aes-256-gcm/buffer/index.js +6 -6
- package/node/encryption/@aes-256-gcm/uint8-array/index.d.ts +8 -8
- package/node/encryption/@aes-256-gcm/uint8-array/index.js +8 -8
- package/node/encryption/key/index.d.ts +6 -6
- package/node/encryption/key/index.js +6 -6
- package/node/files/get-size/index.d.ts +56 -0
- package/node/files/get-size/index.js +167 -0
- package/node/files/get-size/index.test.d.ts +1 -0
- package/node/files/get-size/index.test.js +143 -0
- package/node/files/index.d.ts +1 -0
- package/node/files/index.js +1 -0
- package/node/files/read-write/index.d.ts +16 -16
- package/node/files/subpaths/index.d.ts +8 -8
- package/node/files/subpaths/index.js +11 -13
- package/node/ftps/directory/copy-dir/index.d.ts +6 -6
- package/node/ftps/directory/copy-dir/index.js +6 -6
- package/node/ftps/directory/index.d.ts +1 -1
- package/node/ftps/directory/index.js +1 -1
- package/node/ftps/directory/list/index.d.ts +4 -4
- package/node/ftps/directory/list/index.js +3 -3
- package/node/ftps/directory/move-dir/index.d.ts +6 -6
- package/node/ftps/directory/move-dir/index.js +5 -5
- package/node/ftps/directory/remove-dir/index.d.ts +6 -6
- package/node/ftps/directory/remove-dir/index.js +8 -7
- package/node/ftps/file/copy/index.d.ts +6 -6
- package/node/ftps/file/copy/index.js +5 -5
- package/node/ftps/file/download/index.d.ts +6 -6
- package/node/ftps/file/download/index.js +5 -5
- package/node/ftps/file/exists/index.d.ts +3 -3
- package/node/ftps/file/exists/index.js +3 -3
- package/node/ftps/file/index.d.ts +2 -2
- package/node/ftps/file/index.js +2 -2
- package/node/ftps/file/move/index.d.ts +8 -8
- package/node/ftps/file/move/index.js +11 -9
- package/node/ftps/file/remove/index.d.ts +5 -5
- package/node/ftps/file/remove/index.js +4 -4
- package/node/ftps/file/stat/index.d.ts +4 -4
- package/node/ftps/file/stat/index.js +4 -4
- package/node/ftps/file/upload/index.d.ts +7 -7
- package/node/ftps/file/upload/index.js +5 -5
- package/node/images/create/index.d.ts +2 -2
- package/node/images/create/index.js +1 -1
- package/node/images/format/index.d.ts +8 -8
- package/node/images/index.d.ts +1 -1
- package/node/images/index.js +1 -1
- package/node/images/metadata/index.d.ts +2 -2
- package/node/images/transform/index.d.ts +2 -2
- package/node/images/transform/index.js +12 -2
- package/node/images/transform/operations/blur/index.d.ts +2 -2
- package/node/images/transform/operations/blur/index.js +1 -0
- package/node/images/transform/operations/brighten/index.d.ts +2 -2
- package/node/images/transform/operations/brighten/index.js +1 -0
- package/node/images/transform/operations/extend/index.d.ts +2 -2
- package/node/images/transform/operations/extend/index.js +1 -0
- package/node/images/transform/operations/extract/index.d.ts +2 -2
- package/node/images/transform/operations/extract/index.js +1 -0
- package/node/images/transform/operations/flatten/index.d.ts +2 -2
- package/node/images/transform/operations/flatten/index.js +1 -0
- package/node/images/transform/operations/flip/index.d.ts +2 -2
- package/node/images/transform/operations/flip/index.js +1 -0
- package/node/images/transform/operations/flop/index.d.ts +2 -2
- package/node/images/transform/operations/flop/index.js +1 -0
- package/node/images/transform/operations/hue/index.d.ts +2 -2
- package/node/images/transform/operations/hue/index.js +1 -0
- package/node/images/transform/operations/index.d.ts +2 -2
- package/node/images/transform/operations/index.js +2 -2
- package/node/images/transform/operations/level/index.d.ts +2 -2
- package/node/images/transform/operations/level/index.js +1 -0
- package/node/images/transform/operations/lighten/index.d.ts +2 -2
- package/node/images/transform/operations/lighten/index.js +1 -0
- package/node/images/transform/operations/normalize/index.d.ts +2 -2
- package/node/images/transform/operations/normalize/index.js +1 -0
- package/node/images/transform/operations/overlay/index.d.ts +2 -2
- package/node/images/transform/operations/resize/index.d.ts +2 -2
- package/node/images/transform/operations/resize/index.js +1 -0
- package/node/images/transform/operations/rotate/index.d.ts +2 -2
- package/node/images/transform/operations/rotate/index.js +1 -0
- package/node/images/transform/operations/saturate/index.d.ts +2 -2
- package/node/images/transform/operations/saturate/index.js +1 -0
- package/node/images/types.d.ts +41 -2
- package/node/images/utils/index.d.ts +10 -5
- package/node/index.d.ts +2 -2
- package/node/index.js +2 -2
- package/node/process/on-exit/index.js +2 -4
- package/node/process/prompt-continue/index.d.ts +3 -3
- package/node/process/prompt-continue/index.js +4 -3
- package/node/process/spawner/index.js +7 -6
- package/node/sftp/directory/copy-dir/index.d.ts +6 -6
- package/node/sftp/directory/copy-dir/index.js +6 -6
- package/node/sftp/directory/index.d.ts +1 -1
- package/node/sftp/directory/index.js +1 -1
- package/node/sftp/directory/list/index.d.ts +3 -3
- package/node/sftp/directory/list/index.js +4 -4
- package/node/sftp/directory/move-dir/index.d.ts +7 -7
- package/node/sftp/directory/move-dir/index.js +7 -7
- package/node/sftp/directory/remove-dir/index.d.ts +5 -5
- package/node/sftp/directory/remove-dir/index.js +8 -7
- package/node/sftp/file/copy/index.d.ts +6 -6
- package/node/sftp/file/copy/index.js +5 -5
- package/node/sftp/file/download/index.d.ts +7 -7
- package/node/sftp/file/download/index.js +5 -5
- package/node/sftp/file/exists/index.d.ts +3 -3
- package/node/sftp/file/exists/index.js +3 -3
- package/node/sftp/file/index.d.ts +2 -2
- package/node/sftp/file/index.js +2 -2
- package/node/sftp/file/move/index.d.ts +7 -7
- package/node/sftp/file/move/index.js +7 -7
- package/node/sftp/file/remove/index.d.ts +4 -4
- package/node/sftp/file/remove/index.js +4 -4
- package/node/sftp/file/stat/index.d.ts +3 -3
- package/node/sftp/file/stat/index.js +6 -5
- package/node/sftp/file/upload/index.d.ts +6 -6
- package/node/sftp/file/upload/index.js +5 -5
- package/package.json +47 -39
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type PathLike } from 'node:fs';
|
|
2
|
+
import { Duration } from '../../../agnostic/time/duration/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* How to react to a per-entry read error (a failing `lstat`/`readdir`):
|
|
5
|
+
* - `'throw'`: reject the whole computation (default).
|
|
6
|
+
* - `'skip'`: count the offending entry as 0 bytes and keep going.
|
|
7
|
+
* - a function: called with the error and the offending path, then the entry
|
|
8
|
+
* counts as 0 bytes.
|
|
9
|
+
*/
|
|
10
|
+
export type OnError = 'throw' | 'skip' | ((error: unknown, path: string) => void);
|
|
11
|
+
export type GetSizeOptions = {
|
|
12
|
+
/** Maximum number of concurrent filesystem reads. Bounds file-descriptor usage on large trees. @default 32 */
|
|
13
|
+
concurrency?: number;
|
|
14
|
+
/** How to handle a per-entry read error. @default 'throw' */
|
|
15
|
+
onError?: OnError;
|
|
16
|
+
/** Abort the traversal; aborting rejects with the signal's reason. */
|
|
17
|
+
signal?: AbortSignal;
|
|
18
|
+
/** Abort the traversal after this delay. A `number` is milliseconds; a `Duration` is converted via `toMs()`. Combined with `signal` when both are given. */
|
|
19
|
+
timeoutMs?: number | Duration;
|
|
20
|
+
/** Maximum directory depth to descend; entries deeper than this are not counted. @default Infinity */
|
|
21
|
+
maxDepth?: number;
|
|
22
|
+
/** Follow symbolic links instead of counting the link itself. Cycle-safe via inode tracking. @default false */
|
|
23
|
+
followSymlinks?: boolean;
|
|
24
|
+
/** Count a file reached through several hard links only once. @default false */
|
|
25
|
+
dedupeHardlinks?: boolean;
|
|
26
|
+
/** `'content'` = apparent size (`stat.size`); `'allocated'` = on-disk blocks (`stat.blocks × 512`). @default 'content' */
|
|
27
|
+
sizeOf?: 'content' | 'allocated';
|
|
28
|
+
};
|
|
29
|
+
export declare const defaultGetSizeOptions: {
|
|
30
|
+
concurrency: number;
|
|
31
|
+
onError: "throw";
|
|
32
|
+
maxDepth: number;
|
|
33
|
+
followSymlinks: false;
|
|
34
|
+
dedupeHardlinks: false;
|
|
35
|
+
sizeOf: "content";
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Computes the total size, in bytes, of a file or directory.
|
|
39
|
+
*
|
|
40
|
+
* For a regular file, returns its own size. For a directory, returns the summed
|
|
41
|
+
* size of everything it contains, recursively.
|
|
42
|
+
*
|
|
43
|
+
* @param target - Path to a file or directory (`string`, `Buffer`, or a `file:` URL).
|
|
44
|
+
* @param [options] - Optional configuration. See `GetSizeOptions`.
|
|
45
|
+
* @returns The total size in bytes.
|
|
46
|
+
*
|
|
47
|
+
* @remarks
|
|
48
|
+
* By default symbolic links are not followed (each link counts as its own small
|
|
49
|
+
* size) and hard links are counted once per link. Enable `followSymlinks` to
|
|
50
|
+
* resolve links — cycles and repeated targets are made safe by tracking visited
|
|
51
|
+
* inodes — and `dedupeHardlinks` to count a shared inode only once.
|
|
52
|
+
*
|
|
53
|
+
* @throws If a path cannot be read and `onError` is `'throw'` (the default), or if
|
|
54
|
+
* `options.signal` is aborted.
|
|
55
|
+
*/
|
|
56
|
+
export declare function getSize(target: PathLike, options?: GetSizeOptions): Promise<number>;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { Duration } from '../../../agnostic/time/duration/index.js';
|
|
5
|
+
export const defaultGetSizeOptions = {
|
|
6
|
+
concurrency: 32,
|
|
7
|
+
onError: 'throw',
|
|
8
|
+
maxDepth: Infinity,
|
|
9
|
+
followSymlinks: false,
|
|
10
|
+
dedupeHardlinks: false,
|
|
11
|
+
sizeOf: 'content'
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Computes the total size, in bytes, of a file or directory.
|
|
15
|
+
*
|
|
16
|
+
* For a regular file, returns its own size. For a directory, returns the summed
|
|
17
|
+
* size of everything it contains, recursively.
|
|
18
|
+
*
|
|
19
|
+
* @param target - Path to a file or directory (`string`, `Buffer`, or a `file:` URL).
|
|
20
|
+
* @param [options] - Optional configuration. See `GetSizeOptions`.
|
|
21
|
+
* @returns The total size in bytes.
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* By default symbolic links are not followed (each link counts as its own small
|
|
25
|
+
* size) and hard links are counted once per link. Enable `followSymlinks` to
|
|
26
|
+
* resolve links — cycles and repeated targets are made safe by tracking visited
|
|
27
|
+
* inodes — and `dedupeHardlinks` to count a shared inode only once.
|
|
28
|
+
*
|
|
29
|
+
* @throws If a path cannot be read and `onError` is `'throw'` (the default), or if
|
|
30
|
+
* `options.signal` is aborted.
|
|
31
|
+
*/
|
|
32
|
+
export async function getSize(target, options = {}) {
|
|
33
|
+
const concurrency = Math.max(1, Math.floor(options.concurrency ?? defaultGetSizeOptions.concurrency));
|
|
34
|
+
const timeoutMs = options.timeoutMs instanceof Duration ? options.timeoutMs.toMs() : options.timeoutMs;
|
|
35
|
+
const timeout = timeoutMs === undefined ? null : createTimeoutSignal(timeoutMs, options.signal);
|
|
36
|
+
const resolved = {
|
|
37
|
+
onError: options.onError ?? defaultGetSizeOptions.onError,
|
|
38
|
+
signal: timeout?.signal ?? options.signal,
|
|
39
|
+
limit: createLimiter(concurrency),
|
|
40
|
+
maxDepth: options.maxDepth ?? defaultGetSizeOptions.maxDepth,
|
|
41
|
+
followSymlinks: options.followSymlinks ?? defaultGetSizeOptions.followSymlinks,
|
|
42
|
+
dedupeHardlinks: options.dedupeHardlinks ?? defaultGetSizeOptions.dedupeHardlinks,
|
|
43
|
+
sizeOf: options.sizeOf ?? defaultGetSizeOptions.sizeOf,
|
|
44
|
+
visited: new Set()
|
|
45
|
+
};
|
|
46
|
+
try {
|
|
47
|
+
return await computeSize(toPathString(target), resolved, 0);
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
timeout?.dispose();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Builds an abort signal that fires after `timeoutMs`, merged with a caller
|
|
54
|
+
// signal when provided. Aborting either aborts the returned one. `dispose`
|
|
55
|
+
// clears the timer and detaches the listener.
|
|
56
|
+
function createTimeoutSignal(timeoutMs, userSignal) {
|
|
57
|
+
const controller = new AbortController();
|
|
58
|
+
const timer = setTimeout(() => { controller.abort(new Error(`getSize timed out after ${timeoutMs} ms`)); }, Math.max(0, timeoutMs));
|
|
59
|
+
timer.unref();
|
|
60
|
+
if (userSignal === undefined) {
|
|
61
|
+
return { signal: controller.signal, dispose: () => { clearTimeout(timer); } };
|
|
62
|
+
}
|
|
63
|
+
if (userSignal.aborted)
|
|
64
|
+
controller.abort(userSignal.reason);
|
|
65
|
+
const onUserAbort = () => { controller.abort(userSignal.reason); };
|
|
66
|
+
userSignal.addEventListener('abort', onUserAbort, { once: true });
|
|
67
|
+
return {
|
|
68
|
+
signal: controller.signal,
|
|
69
|
+
dispose: () => {
|
|
70
|
+
clearTimeout(timer);
|
|
71
|
+
userSignal.removeEventListener('abort', onUserAbort);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function toPathString(target) {
|
|
76
|
+
if (typeof target === 'string')
|
|
77
|
+
return target;
|
|
78
|
+
if (Buffer.isBuffer(target))
|
|
79
|
+
return target.toString('utf-8');
|
|
80
|
+
return fileURLToPath(target);
|
|
81
|
+
}
|
|
82
|
+
function measure(stats, options) {
|
|
83
|
+
return options.sizeOf === 'allocated' ? stats.blocks * 512 : stats.size;
|
|
84
|
+
}
|
|
85
|
+
async function computeSize(target, options, depth) {
|
|
86
|
+
options.signal?.throwIfAborted();
|
|
87
|
+
let stats;
|
|
88
|
+
try {
|
|
89
|
+
stats = await options.limit(async () => await fs.lstat(target));
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
return handleError(error, target, options);
|
|
93
|
+
}
|
|
94
|
+
// Resolve symlinks when asked; otherwise a link counts as its own size.
|
|
95
|
+
let realTarget = target;
|
|
96
|
+
if (stats.isSymbolicLink()) {
|
|
97
|
+
if (!options.followSymlinks)
|
|
98
|
+
return measure(stats, options);
|
|
99
|
+
try {
|
|
100
|
+
stats = await options.limit(async () => await fs.stat(target));
|
|
101
|
+
if (stats.isDirectory())
|
|
102
|
+
realTarget = await options.limit(async () => await fs.realpath(target));
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
return handleError(error, target, options);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Count each physical inode once when following links (cycle safety) or
|
|
109
|
+
// deduping hard links.
|
|
110
|
+
if (options.followSymlinks || options.dedupeHardlinks) {
|
|
111
|
+
const key = `${stats.dev}:${stats.ino}`;
|
|
112
|
+
if (options.visited.has(key))
|
|
113
|
+
return 0;
|
|
114
|
+
options.visited.add(key);
|
|
115
|
+
}
|
|
116
|
+
if (!stats.isDirectory())
|
|
117
|
+
return measure(stats, options);
|
|
118
|
+
if (depth >= options.maxDepth)
|
|
119
|
+
return 0;
|
|
120
|
+
let children;
|
|
121
|
+
try {
|
|
122
|
+
children = await options.limit(async () => await fs.readdir(realTarget));
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
return handleError(error, realTarget, options);
|
|
126
|
+
}
|
|
127
|
+
const childSizes = await Promise.all(children.map(async (child) => await computeSize(path.join(realTarget, child), options, depth + 1)));
|
|
128
|
+
return childSizes.reduce((total, size) => total + size, 0);
|
|
129
|
+
}
|
|
130
|
+
function handleError(error, target, options) {
|
|
131
|
+
if (options.onError === 'throw')
|
|
132
|
+
throw error;
|
|
133
|
+
if (typeof options.onError === 'function')
|
|
134
|
+
options.onError(error, target);
|
|
135
|
+
return 0;
|
|
136
|
+
}
|
|
137
|
+
// Global concurrency limiter: at most `max` wrapped calls run at once. Wrapped
|
|
138
|
+
// calls must be leaf operations (single fs syscalls) that never await another
|
|
139
|
+
// wrapped call, so the recursive traversal cannot deadlock on slots.
|
|
140
|
+
function createLimiter(max) {
|
|
141
|
+
let active = 0;
|
|
142
|
+
const waiters = [];
|
|
143
|
+
const acquire = async () => {
|
|
144
|
+
if (active < max) {
|
|
145
|
+
active += 1;
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
// Resumed by `release`, which hands over the slot without decrementing.
|
|
149
|
+
await new Promise(resolve => { waiters.push(resolve); });
|
|
150
|
+
};
|
|
151
|
+
const release = () => {
|
|
152
|
+
const resume = waiters.shift();
|
|
153
|
+
if (resume !== undefined)
|
|
154
|
+
resume();
|
|
155
|
+
else
|
|
156
|
+
active -= 1;
|
|
157
|
+
};
|
|
158
|
+
return async function limit(fn) {
|
|
159
|
+
await acquire();
|
|
160
|
+
try {
|
|
161
|
+
return await fn();
|
|
162
|
+
}
|
|
163
|
+
finally {
|
|
164
|
+
release();
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { getSize } from './index.js';
|
|
7
|
+
import { seconds } from '../../../agnostic/time/duration/index.js';
|
|
8
|
+
// Fixtures (all under the OS temp dir):
|
|
9
|
+
// root/ a.txt (10) + sub/b.txt (5) + sub/empty/
|
|
10
|
+
// wideRoot/ 60 x 1-byte files (exercises concurrency)
|
|
11
|
+
// linkRoot/ target.txt (7) + link -> target.txt (symlink to file)
|
|
12
|
+
// cycleRoot/ self -> cycleRoot (symlink cycle to its own dir)
|
|
13
|
+
// hlRoot/ original.txt (9) + hard.txt (hard link to original.txt)
|
|
14
|
+
let root;
|
|
15
|
+
let wideRoot;
|
|
16
|
+
let linkRoot;
|
|
17
|
+
let cycleRoot;
|
|
18
|
+
let hlRoot;
|
|
19
|
+
const aBytes = 10;
|
|
20
|
+
const bBytes = 5;
|
|
21
|
+
const wideFileCount = 60;
|
|
22
|
+
const targetBytes = 7;
|
|
23
|
+
const hardBytes = 9;
|
|
24
|
+
beforeAll(async () => {
|
|
25
|
+
root = await fs.mkdtemp(path.join(os.tmpdir(), 'lm-get-size-'));
|
|
26
|
+
await fs.writeFile(path.join(root, 'a.txt'), 'x'.repeat(aBytes));
|
|
27
|
+
await fs.mkdir(path.join(root, 'sub'));
|
|
28
|
+
await fs.writeFile(path.join(root, 'sub', 'b.txt'), 'y'.repeat(bBytes));
|
|
29
|
+
await fs.mkdir(path.join(root, 'sub', 'empty'));
|
|
30
|
+
wideRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'lm-get-size-wide-'));
|
|
31
|
+
await Promise.all([...Array(wideFileCount)].map(async (_, i) => await fs.writeFile(path.join(wideRoot, `f${i}.txt`), 'z')));
|
|
32
|
+
linkRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'lm-get-size-link-'));
|
|
33
|
+
await fs.writeFile(path.join(linkRoot, 'target.txt'), 't'.repeat(targetBytes));
|
|
34
|
+
await fs.symlink(path.join(linkRoot, 'target.txt'), path.join(linkRoot, 'link'));
|
|
35
|
+
cycleRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'lm-get-size-cycle-'));
|
|
36
|
+
await fs.symlink(cycleRoot, path.join(cycleRoot, 'self'));
|
|
37
|
+
hlRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'lm-get-size-hl-'));
|
|
38
|
+
await fs.writeFile(path.join(hlRoot, 'original.txt'), 'h'.repeat(hardBytes));
|
|
39
|
+
await fs.link(path.join(hlRoot, 'original.txt'), path.join(hlRoot, 'hard.txt'));
|
|
40
|
+
});
|
|
41
|
+
afterAll(async () => {
|
|
42
|
+
await Promise.all([root, wideRoot, linkRoot, cycleRoot, hlRoot].map(async (dir) => await fs.rm(dir, { recursive: true, force: true })));
|
|
43
|
+
});
|
|
44
|
+
describe('getSize', () => {
|
|
45
|
+
it('returns the size of a single file', async () => {
|
|
46
|
+
expect(await getSize(path.join(root, 'a.txt'))).toBe(aBytes);
|
|
47
|
+
});
|
|
48
|
+
it('sums the sizes of a directory recursively', async () => {
|
|
49
|
+
expect(await getSize(root)).toBe(aBytes + bBytes);
|
|
50
|
+
});
|
|
51
|
+
it('returns the size of a nested directory', async () => {
|
|
52
|
+
expect(await getSize(path.join(root, 'sub'))).toBe(bBytes);
|
|
53
|
+
});
|
|
54
|
+
it('returns 0 for an empty directory', async () => {
|
|
55
|
+
expect(await getSize(path.join(root, 'sub', 'empty'))).toBe(0);
|
|
56
|
+
});
|
|
57
|
+
describe('PathLike variants', () => {
|
|
58
|
+
it('accepts a Buffer path', async () => {
|
|
59
|
+
expect(await getSize(Buffer.from(path.join(root, 'a.txt')))).toBe(aBytes);
|
|
60
|
+
});
|
|
61
|
+
it('accepts a file: URL', async () => {
|
|
62
|
+
expect(await getSize(pathToFileURL(root))).toBe(aBytes + bBytes);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
it('rejects when the path does not exist', async () => {
|
|
66
|
+
await expect(getSize(path.join(root, 'does-not-exist'))).rejects.toThrow();
|
|
67
|
+
});
|
|
68
|
+
describe('concurrency', () => {
|
|
69
|
+
it('computes the same total with concurrency: 1', async () => {
|
|
70
|
+
expect(await getSize(root, { concurrency: 1 })).toBe(aBytes + bBytes);
|
|
71
|
+
});
|
|
72
|
+
it('handles a wide directory under a low concurrency', async () => {
|
|
73
|
+
expect(await getSize(wideRoot, { concurrency: 4 })).toBe(wideFileCount);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
describe('onError', () => {
|
|
77
|
+
it("counts a missing path as 0 when onError is 'skip'", async () => {
|
|
78
|
+
expect(await getSize(path.join(root, 'nope'), { onError: 'skip' })).toBe(0);
|
|
79
|
+
});
|
|
80
|
+
it('invokes the onError callback and skips the entry', async () => {
|
|
81
|
+
const seen = [];
|
|
82
|
+
const size = await getSize(path.join(root, 'nope'), {
|
|
83
|
+
onError: (_error, failedPath) => { seen.push(failedPath); }
|
|
84
|
+
});
|
|
85
|
+
expect(size).toBe(0);
|
|
86
|
+
expect(seen).toHaveLength(1);
|
|
87
|
+
expect(seen[0]).toBe(path.join(root, 'nope'));
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
describe('signal', () => {
|
|
91
|
+
it('rejects when the signal is already aborted', async () => {
|
|
92
|
+
await expect(getSize(root, { signal: AbortSignal.abort() })).rejects.toThrow();
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
describe('maxDepth', () => {
|
|
96
|
+
it('counts only the first level with maxDepth: 1', async () => {
|
|
97
|
+
// a.txt (depth 1) counted; sub/ is a dir at depth 1, not descended.
|
|
98
|
+
expect(await getSize(root, { maxDepth: 1 })).toBe(aBytes);
|
|
99
|
+
});
|
|
100
|
+
it('descends one more level with maxDepth: 2', async () => {
|
|
101
|
+
expect(await getSize(root, { maxDepth: 2 })).toBe(aBytes + bBytes);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
describe('followSymlinks', () => {
|
|
105
|
+
it('does not follow links by default (link counts as its own size)', async () => {
|
|
106
|
+
// target.txt (7) + the link's own (non-zero) size.
|
|
107
|
+
expect(await getSize(linkRoot)).toBeGreaterThan(targetBytes);
|
|
108
|
+
});
|
|
109
|
+
it('follows links and dedupes the shared target', async () => {
|
|
110
|
+
// The link resolves to target.txt, so the shared inode is counted once.
|
|
111
|
+
expect(await getSize(linkRoot, { followSymlinks: true })).toBe(targetBytes);
|
|
112
|
+
});
|
|
113
|
+
it('is cycle-safe when a link points back into the tree', async () => {
|
|
114
|
+
expect(await getSize(cycleRoot, { followSymlinks: true })).toBe(0);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
describe('dedupeHardlinks', () => {
|
|
118
|
+
it('counts each hard link separately by default', async () => {
|
|
119
|
+
expect(await getSize(hlRoot)).toBe(hardBytes * 2);
|
|
120
|
+
});
|
|
121
|
+
it('counts a shared inode once when dedupeHardlinks is set', async () => {
|
|
122
|
+
expect(await getSize(hlRoot, { dedupeHardlinks: true })).toBe(hardBytes);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
describe('sizeOf', () => {
|
|
126
|
+
it("'allocated' is at least the apparent content size", async () => {
|
|
127
|
+
const content = await getSize(root);
|
|
128
|
+
const allocated = await getSize(root, { sizeOf: 'allocated' });
|
|
129
|
+
expect(allocated).toBeGreaterThanOrEqual(content);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
describe('timeoutMs', () => {
|
|
133
|
+
it('completes normally within a generous timeout (number)', async () => {
|
|
134
|
+
expect(await getSize(root, { timeoutMs: 10_000 })).toBe(aBytes + bBytes);
|
|
135
|
+
});
|
|
136
|
+
it('accepts a Duration', async () => {
|
|
137
|
+
expect(await getSize(root, { timeoutMs: seconds(10) })).toBe(aBytes + bBytes);
|
|
138
|
+
});
|
|
139
|
+
it('still honours an already-aborted signal when combined with a timeout', async () => {
|
|
140
|
+
await expect(getSize(root, { timeoutMs: 10_000, signal: AbortSignal.abort() })).rejects.toThrow();
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
});
|
package/node/files/index.d.ts
CHANGED
package/node/files/index.js
CHANGED
|
@@ -23,14 +23,14 @@ export type Replacements = Record<string, string>;
|
|
|
23
23
|
* - **Replacements mode**: Pass an object with string replacements.
|
|
24
24
|
* - **Function mode**: Pass a function that transforms the file content.
|
|
25
25
|
*
|
|
26
|
-
* @param
|
|
27
|
-
* @param
|
|
28
|
-
* @param
|
|
29
|
-
* @param
|
|
30
|
-
* @param
|
|
31
|
-
* @param
|
|
32
|
-
* @param
|
|
33
|
-
* @returns
|
|
26
|
+
* @param path - The path to the file to read and edit.
|
|
27
|
+
* @param editor - Object mapping strings to replace with their replacements.
|
|
28
|
+
* @param [opts] - Optional configuration.
|
|
29
|
+
* @param [opts.readOptions] - Extra `readFile` params.
|
|
30
|
+
* @param [opts.writeOptions] - Extra `writeFile` params.
|
|
31
|
+
* @param [opts.output] - Output path (defaults to `path`).
|
|
32
|
+
* @param [opts.dryRun=false] - If `true`, skip writing to disk.
|
|
33
|
+
* @returns The edited file content as a string.
|
|
34
34
|
*/
|
|
35
35
|
export declare function readWrite(path: Path, editor: Replacements, opts?: Options): Promise<string>;
|
|
36
36
|
/**
|
|
@@ -40,14 +40,14 @@ export declare function readWrite(path: Path, editor: Replacements, opts?: Optio
|
|
|
40
40
|
* - **Replacements mode**: Pass an object with string replacements.
|
|
41
41
|
* - **Function mode**: Pass a function that transforms the file content.
|
|
42
42
|
*
|
|
43
|
-
* @param
|
|
44
|
-
* @param
|
|
45
|
-
* @param
|
|
46
|
-
* @param
|
|
47
|
-
* @param
|
|
48
|
-
* @param
|
|
49
|
-
* @param
|
|
50
|
-
* @returns
|
|
43
|
+
* @param path - The path to the file to read and edit.
|
|
44
|
+
* @param editor - Function that transforms the file content.
|
|
45
|
+
* @param [opts] - Optional configuration.
|
|
46
|
+
* @param [opts.readOptions] - Extra `readFile` params.
|
|
47
|
+
* @param [opts.writeOptions] - Extra `writeFile` params.
|
|
48
|
+
* @param [opts.output] - Output path (defaults to `path`).
|
|
49
|
+
* @param [opts.dryRun=false] - If `true`, skip writing to disk.
|
|
50
|
+
* @returns The edited file content of type `T`.
|
|
51
51
|
*/
|
|
52
52
|
export declare function readWrite<T extends WriteFileData>(path: Path, editor: EditorFunc<T>, opts?: Options): Promise<T>;
|
|
53
53
|
export {};
|
|
@@ -15,8 +15,8 @@ export declare const defaultListContext: Required<ListContext>;
|
|
|
15
15
|
/**
|
|
16
16
|
* Fills missing properties in a list context with default values.
|
|
17
17
|
*
|
|
18
|
-
* @param
|
|
19
|
-
* @returns
|
|
18
|
+
* @param input - The partial list context to fill.
|
|
19
|
+
* @returns A complete list context with all properties set.
|
|
20
20
|
*/
|
|
21
21
|
export declare const fillListContext: (input: ListContext) => Required<ListContext>;
|
|
22
22
|
export type ListOptions = {
|
|
@@ -36,8 +36,8 @@ export declare const defaultListOptions: Required<ListOptions>;
|
|
|
36
36
|
/**
|
|
37
37
|
* Fills missing properties in list options with default values.
|
|
38
38
|
*
|
|
39
|
-
* @param
|
|
40
|
-
* @returns
|
|
39
|
+
* @param input - The partial list options to fill.
|
|
40
|
+
* @returns A complete list options object with all properties set.
|
|
41
41
|
*/
|
|
42
42
|
export declare const fillOptions: (input: ListOptions) => Required<ListOptions>;
|
|
43
43
|
/**
|
|
@@ -54,10 +54,10 @@ export declare function list(...args: Parameters<typeof listAbsoluteSubpaths>):
|
|
|
54
54
|
/**
|
|
55
55
|
* Internal function that lists absolute subpaths recursively.
|
|
56
56
|
*
|
|
57
|
-
* @param
|
|
58
|
-
* @param
|
|
59
|
-
* @param
|
|
60
|
-
* @returns
|
|
57
|
+
* @param inputPath - The directory path to list.
|
|
58
|
+
* @param [_options] - Optional configuration.
|
|
59
|
+
* @param [__private_context] - Internal recursion context.
|
|
60
|
+
* @returns Array of absolute subpaths.
|
|
61
61
|
*/
|
|
62
62
|
declare function listAbsoluteSubpaths(inputPath: string, _options?: ListOptions, __private_context?: ListContext): Promise<string[]>;
|
|
63
63
|
export {};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-throw-literal */
|
|
2
1
|
import { promises as fs } from 'node:fs';
|
|
3
2
|
import path from 'node:path';
|
|
4
3
|
import { matchesSome as stringMatchesSome } from '../../../agnostic/strings/matches/index.js';
|
|
@@ -10,8 +9,8 @@ export const defaultListContext = {
|
|
|
10
9
|
/**
|
|
11
10
|
* Fills missing properties in a list context with default values.
|
|
12
11
|
*
|
|
13
|
-
* @param
|
|
14
|
-
* @returns
|
|
12
|
+
* @param input - The partial list context to fill.
|
|
13
|
+
* @returns A complete list context with all properties set.
|
|
15
14
|
*/
|
|
16
15
|
export const fillListContext = (input) => {
|
|
17
16
|
return {
|
|
@@ -35,8 +34,8 @@ export const defaultListOptions = {
|
|
|
35
34
|
/**
|
|
36
35
|
* Fills missing properties in list options with default values.
|
|
37
36
|
*
|
|
38
|
-
* @param
|
|
39
|
-
* @returns
|
|
37
|
+
* @param input - The partial list options to fill.
|
|
38
|
+
* @returns A complete list options object with all properties set.
|
|
40
39
|
*/
|
|
41
40
|
export const fillOptions = (input) => {
|
|
42
41
|
return {
|
|
@@ -65,10 +64,10 @@ export async function list(...args) {
|
|
|
65
64
|
/**
|
|
66
65
|
* Internal function that lists absolute subpaths recursively.
|
|
67
66
|
*
|
|
68
|
-
* @param
|
|
69
|
-
* @param
|
|
70
|
-
* @param
|
|
71
|
-
* @returns
|
|
67
|
+
* @param inputPath - The directory path to list.
|
|
68
|
+
* @param [_options] - Optional configuration.
|
|
69
|
+
* @param [__private_context] - Internal recursion context.
|
|
70
|
+
* @returns Array of absolute subpaths.
|
|
72
71
|
*/
|
|
73
72
|
async function listAbsoluteSubpaths(inputPath, _options = {},
|
|
74
73
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
@@ -76,9 +75,7 @@ __private_context = {}) {
|
|
|
76
75
|
const options = fillOptions(_options);
|
|
77
76
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
78
77
|
const _private_context = fillListContext(__private_context);
|
|
79
|
-
|
|
80
|
-
_private_context.rootPath = inputPath;
|
|
81
|
-
}
|
|
78
|
+
_private_context.rootPath ??= inputPath;
|
|
82
79
|
const subpaths = [];
|
|
83
80
|
if (_private_context.depth > options.maxDepth)
|
|
84
81
|
return subpaths;
|
|
@@ -132,6 +129,7 @@ __private_context = {}) {
|
|
|
132
129
|
}
|
|
133
130
|
}
|
|
134
131
|
else {
|
|
132
|
+
// eslint-disable-next-line no-lonely-if
|
|
135
133
|
if (isDirectory) {
|
|
136
134
|
const childSubpaths = await listAbsoluteSubpaths(childAbsPath, options, {
|
|
137
135
|
..._private_context,
|
|
@@ -147,7 +145,7 @@ __private_context = {}) {
|
|
|
147
145
|
}
|
|
148
146
|
catch (err) {
|
|
149
147
|
if (typeof err !== 'boolean')
|
|
150
|
-
throw new Error('This try/catch block should only throw booleans');
|
|
148
|
+
throw new Error('This try/catch block should only throw booleans', { cause: err });
|
|
151
149
|
const shouldDiveDeeper = err;
|
|
152
150
|
if (!shouldDiveDeeper)
|
|
153
151
|
return [];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Client } from 'basic-ftp';
|
|
2
2
|
import * as Outcome from '../../../../agnostic/misc/outcome/index.js';
|
|
3
3
|
export type CopyDirOptions = {
|
|
4
4
|
/**
|
|
@@ -17,11 +17,11 @@ export type CopyDirOptions = {
|
|
|
17
17
|
* Recursively copies every file under `sourceDir` to the same relative path
|
|
18
18
|
* beneath `targetDir` on an FTP server, streaming data to avoid buffering.
|
|
19
19
|
*
|
|
20
|
-
* @param
|
|
21
|
-
* @param
|
|
22
|
-
* @param
|
|
23
|
-
* @param
|
|
24
|
-
* @returns
|
|
20
|
+
* @param ftpClient - The FTP client instance.
|
|
21
|
+
* @param sourceDir - The source directory path to copy from.
|
|
22
|
+
* @param targetDir - The target directory path to copy to.
|
|
23
|
+
* @param [options] - Optional parameters for the operation.
|
|
24
|
+
* @returns
|
|
25
25
|
* - Success: `Outcome.makeSuccess(true)` if the copy succeeds.
|
|
26
26
|
* - Failure: `Outcome.makeFailure(errStr)` if an error occurs.
|
|
27
27
|
*/
|
|
@@ -5,11 +5,11 @@ import { unknownToString } from '../../../../agnostic/errors/unknown-to-string/i
|
|
|
5
5
|
* Recursively copies every file under `sourceDir` to the same relative path
|
|
6
6
|
* beneath `targetDir` on an FTP server, streaming data to avoid buffering.
|
|
7
7
|
*
|
|
8
|
-
* @param
|
|
9
|
-
* @param
|
|
10
|
-
* @param
|
|
11
|
-
* @param
|
|
12
|
-
* @returns
|
|
8
|
+
* @param ftpClient - The FTP client instance.
|
|
9
|
+
* @param sourceDir - The source directory path to copy from.
|
|
10
|
+
* @param targetDir - The target directory path to copy to.
|
|
11
|
+
* @param [options] - Optional parameters for the operation.
|
|
12
|
+
* @returns
|
|
13
13
|
* - Success: `Outcome.makeSuccess(true)` if the copy succeeds.
|
|
14
14
|
* - Failure: `Outcome.makeFailure(errStr)` if an error occurs.
|
|
15
15
|
*/
|
|
@@ -18,7 +18,7 @@ export async function copyDir(ftpClient, sourceDir, targetDir, options) {
|
|
|
18
18
|
async function recurse(dir) {
|
|
19
19
|
const list = await ftpClient.list(dir);
|
|
20
20
|
for (const entry of list) {
|
|
21
|
-
const src = dir.endsWith('/') ? dir
|
|
21
|
+
const src = dir.endsWith('/') ? `${dir}${entry.name}` : `${dir}/${entry.name}`;
|
|
22
22
|
const rel = src.substring(sourceDir.length + (sourceDir.endsWith('/') ? 0 : 1));
|
|
23
23
|
const dst = targetDir.endsWith('/') ? targetDir + rel : `${targetDir}/${rel}`;
|
|
24
24
|
if (entry.isDirectory) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Client } from 'basic-ftp';
|
|
2
2
|
import * as Outcome from '../../../../agnostic/misc/outcome/index.js';
|
|
3
3
|
/**
|
|
4
4
|
* Lists all direct children files under a given directory on an FTP server.
|
|
5
5
|
*
|
|
6
6
|
* This function returns only the immediate files (not recursive) under the specified directory.
|
|
7
7
|
*
|
|
8
|
-
* @param
|
|
9
|
-
* @param
|
|
10
|
-
* @returns
|
|
8
|
+
* @param ftpClient - The basic-ftp client instance used to interact with the FTP server.
|
|
9
|
+
* @param directoryPath - The directory path to list files under.
|
|
10
|
+
* @returns Returns either a success with an array of file paths, or a failure with an error message.
|
|
11
11
|
*/
|
|
12
12
|
export declare function list(ftpClient: Client, directoryPath: string): Promise<Outcome.Either<string[], string>>;
|
|
@@ -5,9 +5,9 @@ import { unknownToString } from '../../../../agnostic/errors/unknown-to-string/i
|
|
|
5
5
|
*
|
|
6
6
|
* This function returns only the immediate files (not recursive) under the specified directory.
|
|
7
7
|
*
|
|
8
|
-
* @param
|
|
9
|
-
* @param
|
|
10
|
-
* @returns
|
|
8
|
+
* @param ftpClient - The basic-ftp client instance used to interact with the FTP server.
|
|
9
|
+
* @param directoryPath - The directory path to list files under.
|
|
10
|
+
* @returns Returns either a success with an array of file paths, or a failure with an error message.
|
|
11
11
|
*/
|
|
12
12
|
export async function list(ftpClient, directoryPath) {
|
|
13
13
|
try {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Client } from 'basic-ftp';
|
|
2
2
|
import * as Outcome from '../../../../agnostic/misc/outcome/index.js';
|
|
3
3
|
export type MoveDirOptions = {
|
|
4
4
|
/** If false and `targetDir` exists, the operation is aborted. Defaults to false. */
|
|
@@ -15,11 +15,11 @@ export type MoveDirOptions = {
|
|
|
15
15
|
* If `ensureDir` is true (default), the parent directory of `targetDir` is
|
|
16
16
|
* created if it does not exist.
|
|
17
17
|
*
|
|
18
|
-
* @param
|
|
19
|
-
* @param
|
|
20
|
-
* @param
|
|
21
|
-
* @param
|
|
22
|
-
* @returns
|
|
18
|
+
* @param ftpClient - The FTP client instance.
|
|
19
|
+
* @param sourceDir - The source directory path to move from.
|
|
20
|
+
* @param targetDir - The target directory path to move to.
|
|
21
|
+
* @param [options] - Optional parameters for the operation.
|
|
22
|
+
* @returns A promise that resolves to an `Outcome.Either`:
|
|
23
23
|
* - On success: `Outcome.makeSuccess(true)` indicating the move was successful.
|
|
24
24
|
* - On failure: `Outcome.makeFailure(errStr)` with an error message if the move fails.
|
|
25
25
|
*/
|