@design-edito/tools 0.4.4 → 0.4.6
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/TODO.md +269 -0
- package/agnostic/arrays/dedupe/index.js +9 -9
- package/agnostic/arrays/dedupe/index.test.js +24 -0
- package/agnostic/arrays/find-duplicates/index.js +34 -24
- package/agnostic/arrays/find-duplicates/index.test.js +31 -0
- package/agnostic/arrays/index.d.ts +1 -1
- package/agnostic/arrays/index.js +1 -1
- package/agnostic/arrays/is-array-of/index.js +28 -26
- package/agnostic/arrays/is-array-of/index.test.js +56 -0
- package/agnostic/arrays/make/index.js +11 -8
- package/agnostic/arrays/make/index.test.js +10 -0
- package/agnostic/arrays/random-pick/index.js +40 -9
- package/agnostic/arrays/random-pick/index.test.js +23 -0
- package/agnostic/arrays/shuffle/index.js +15 -13
- package/agnostic/arrays/shuffle/index.test.js +14 -0
- package/agnostic/booleans/is-falsy/index.js +26 -12
- package/agnostic/booleans/is-falsy/index.test.js +26 -0
- package/agnostic/colors/channels/index.js +145 -19
- package/agnostic/colors/channels/index.test.js +64 -0
- package/agnostic/colors/contrast/index.js +23 -30
- package/agnostic/colors/contrast/index.test.js +21 -0
- package/agnostic/colors/convert/index.js +839 -46
- package/agnostic/colors/convert/index.test.js +98 -0
- package/agnostic/colors/cssColorsMap.js +153 -0
- package/agnostic/colors/distance/index.js +65 -53
- package/agnostic/colors/distance/index.test.js +21 -0
- package/agnostic/colors/grayscale/index.js +96 -137
- package/agnostic/colors/grayscale/index.test.js +34 -0
- package/agnostic/colors/invert/index.js +33 -44
- package/agnostic/colors/invert/index.test.js +31 -0
- package/agnostic/colors/lerp/index.js +74 -88
- package/agnostic/colors/lerp/index.test.js +55 -0
- package/agnostic/colors/luminance/index.js +19 -13
- package/agnostic/colors/luminance/index.test.js +30 -0
- package/agnostic/colors/palette/index.js +80 -87
- package/agnostic/colors/palette/index.test.js +35 -0
- package/agnostic/colors/rotate/index.js +41 -14
- package/agnostic/colors/rotate/index.test.js +45 -0
- package/agnostic/colors/tidy/index.js +80 -12
- package/agnostic/colors/tidy/index.test.js +45 -0
- package/agnostic/colors/typechecks/index.js +196 -25
- package/agnostic/colors/typechecks/index.test.js +113 -0
- package/agnostic/colors/types.js +1 -0
- package/agnostic/css/bem/index.js +135 -160
- package/agnostic/css/clss/index.js +66 -7
- package/agnostic/css/clss/index.test.js +60 -0
- package/agnostic/css/generate-nice-color/index.js +26 -73
- package/agnostic/css/generate-nice-color/index.test.js +8 -0
- package/agnostic/css/index.d.ts +1 -1
- package/agnostic/css/index.js +1 -1
- package/agnostic/css/is-valid-css-class-name/index.js +15 -9
- package/agnostic/css/is-valid-css-class-name/index.test.js +36 -0
- package/agnostic/css/scale/index.js +37 -37
- package/agnostic/css/scale/index.test.js +71 -0
- package/agnostic/css/styles-set/index.js +151 -169
- package/agnostic/errors/register/index.js +45 -51
- package/agnostic/errors/unknown-to-string/index.js +18 -7
- package/agnostic/errors/unknown-to-string/index.test.js +35 -0
- package/agnostic/html/get-node-ancestors/index.js +31 -8
- package/agnostic/html/get-node-ancestors/index.test.js +58 -0
- package/agnostic/html/get-position-inside-parent/index.js +13 -10
- package/agnostic/html/get-position-inside-parent/index.test.js +56 -0
- package/agnostic/html/hyper-json/cast/index.js +137 -24
- package/agnostic/html/hyper-json/index.js +23 -50
- package/agnostic/html/hyper-json/method/index.js +10 -7
- package/agnostic/html/hyper-json/serialize/index.js +91 -11
- package/agnostic/html/hyper-json/smart-tags/coalesced/add/index.js +16 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/addclass/index.js +30 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/and/index.js +15 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/append/index.js +36 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/at/index.js +47 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/call/index.js +50 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/clone/index.js +11 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/deleteproperties/index.js +49 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/equals/index.js +24 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/getattribute/index.js +28 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/getproperties/index.js +21 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/getproperty/index.js +73 -26
- package/agnostic/html/hyper-json/smart-tags/coalesced/hjparse/index.js +24 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/hjstringify/index.js +93 -28
- package/agnostic/html/hyper-json/smart-tags/coalesced/if/index.js +22 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/index.d.ts +14 -14
- package/agnostic/html/hyper-json/smart-tags/coalesced/index.js +14 -14
- package/agnostic/html/hyper-json/smart-tags/coalesced/initialize/index.js +39 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/join/index.js +18 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/length/index.js +23 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/map/index.js +33 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/negate/index.js +11 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/notrailing/index.js +35 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/or/index.js +15 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/pickrandom/index.js +19 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/populate/index.js +61 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/print/index.js +25 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/push/index.js +11 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/pusheach/index.js +28 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/recordtoarray/index.js +11 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/removeattribute/index.js +58 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/removeclass/index.js +30 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/renameproperty/index.js +34 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/replace/index.js +56 -26
- package/agnostic/html/hyper-json/smart-tags/coalesced/select/index.js +34 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/set/index.js +31 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/setattribute/index.js +58 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/setproperty/index.js +237 -26
- package/agnostic/html/hyper-json/smart-tags/coalesced/sorton/index.js +93 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/split/index.js +22 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/spread/index.js +24 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/toarray/index.js +12 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/toboolean/index.js +12 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/toelement/index.js +19 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/toggleclass/index.js +30 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/tonodelist/index.js +12 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/tonull/index.js +11 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/tonumber/index.js +12 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/torecord/index.js +12 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/toref/index.js +12 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/tostring/index.js +12 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/totext/index.js +12 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/transformselected/index.js +86 -24
- package/agnostic/html/hyper-json/smart-tags/coalesced/trim/index.js +16 -24
- package/agnostic/html/hyper-json/smart-tags/index.js +31 -10
- package/agnostic/html/hyper-json/smart-tags/isolated/any/index.js +14 -11
- package/agnostic/html/hyper-json/smart-tags/isolated/array/index.js +14 -11
- package/agnostic/html/hyper-json/smart-tags/isolated/boolean/index.js +13 -24
- package/agnostic/html/hyper-json/smart-tags/isolated/element/index.js +26 -24
- package/agnostic/html/hyper-json/smart-tags/isolated/get/index.js +20 -24
- package/agnostic/html/hyper-json/smart-tags/isolated/guess/index.js +59 -24
- package/agnostic/html/hyper-json/smart-tags/isolated/index.d.ts +1 -1
- package/agnostic/html/hyper-json/smart-tags/isolated/index.js +1 -1
- package/agnostic/html/hyper-json/smart-tags/isolated/nodelist/index.js +20 -24
- package/agnostic/html/hyper-json/smart-tags/isolated/null/index.js +10 -11
- package/agnostic/html/hyper-json/smart-tags/isolated/number/index.js +18 -24
- package/agnostic/html/hyper-json/smart-tags/isolated/record/index.js +14 -24
- package/agnostic/html/hyper-json/smart-tags/isolated/ref/index.js +45 -25
- package/agnostic/html/hyper-json/smart-tags/isolated/string/index.js +18 -24
- package/agnostic/html/hyper-json/smart-tags/isolated/text/index.js +20 -24
- package/agnostic/html/hyper-json/transformer/index.js +113 -9
- package/agnostic/html/hyper-json/tree/index.js +423 -24
- package/agnostic/html/hyper-json/types/index.js +28 -7
- package/agnostic/html/hyper-json/utils/index.js +516 -24
- package/agnostic/html/index.d.ts +2 -2
- package/agnostic/html/index.js +2 -2
- package/agnostic/html/insert-node/index.js +28 -7
- package/agnostic/html/insert-node/index.test.js +73 -0
- package/agnostic/html/placeholders/index.js +26 -31
- package/agnostic/html/replace-in-element/index.js +31 -25
- package/agnostic/html/replace-in-element/index.test.js +80 -0
- package/agnostic/html/selector-to-element/index.js +53 -33
- package/agnostic/html/selector-to-element/index.test.js +69 -0
- package/agnostic/html/string-to-nodes/index.js +24 -19
- package/agnostic/html/string-to-nodes/index.test.js +54 -0
- package/agnostic/index.d.ts +1 -1
- package/agnostic/index.js +1 -1
- package/agnostic/misc/assert/index.js +60 -58
- package/agnostic/misc/cast/index.js +132 -23
- package/agnostic/misc/cast/index.test.js +134 -0
- package/agnostic/misc/connection/index.js +55 -30
- package/agnostic/misc/connection/index.test.js +143 -0
- package/agnostic/misc/crawler/index.js +68 -44
- package/agnostic/misc/crawler/index.test.js +56 -0
- package/agnostic/misc/crossenv/detect-runtime/index.js +41 -16
- package/agnostic/misc/crossenv/detect-runtime/index.test.js +24 -0
- package/agnostic/misc/crossenv/types.js +21 -7
- package/agnostic/misc/crossenv/window/index.js +49 -13
- package/agnostic/misc/crossenv/window/index.test.js +24 -0
- package/agnostic/misc/data-size/index.js +182 -296
- package/agnostic/misc/data-size/index.test.js +100 -0
- package/agnostic/misc/data-size/types.js +1 -0
- package/agnostic/misc/index.d.ts +1 -1
- package/agnostic/misc/index.js +1 -1
- package/agnostic/misc/is-constructor-function/index.js +13 -7
- package/agnostic/misc/is-constructor-function/index.test.js +36 -0
- package/agnostic/misc/is-nullish/index.js +26 -11
- package/agnostic/misc/is-nullish/index.test.js +44 -0
- package/agnostic/misc/logs/logger/index.js +115 -142
- package/agnostic/misc/logs/make-text-block/index.js +14 -7
- package/agnostic/misc/logs/styles/index.js +30 -7
- package/agnostic/misc/lorem-ipsum/index.js +51 -186
- package/agnostic/misc/lorem-ipsum/index.test.js +49 -0
- package/agnostic/misc/normalize-extension/index.js +99 -90
- package/agnostic/misc/normalize-extension/index.test.js +40 -0
- package/agnostic/misc/outcome/index.js +21 -11
- package/agnostic/misc/outcome/index.test.js +40 -0
- package/agnostic/numbers/absolute-modulo/index.js +10 -7
- package/agnostic/numbers/absolute-modulo/index.test.js +23 -0
- package/agnostic/numbers/approximate-rational/index.js +86 -71
- package/agnostic/numbers/approximate-rational/index.test.js +90 -0
- package/agnostic/numbers/clamp/index.js +13 -7
- package/agnostic/numbers/clamp/index.test.js +24 -0
- package/agnostic/numbers/geometric-progressions/index.js +26 -7
- package/agnostic/numbers/geometric-progressions/index.test.js +45 -0
- package/agnostic/numbers/index.d.ts +1 -1
- package/agnostic/numbers/index.js +1 -1
- package/agnostic/numbers/interpolate/index.js +25 -12
- package/agnostic/numbers/interpolate/index.test.js +40 -0
- package/agnostic/numbers/round/index.js +33 -11
- package/agnostic/numbers/round/index.test.js +56 -0
- package/agnostic/objects/deep-get-property/index.js +30 -26
- package/agnostic/objects/deep-get-property/index.test.js +59 -0
- package/agnostic/objects/enums/is-in-enum/index.js +18 -7
- package/agnostic/objects/enums/is-in-enum/index.test.js +100 -0
- package/agnostic/objects/flatten-getters/index.js +15 -16
- package/agnostic/objects/flatten-getters/index.test.js +78 -0
- package/agnostic/objects/index.d.ts +3 -3
- package/agnostic/objects/index.js +3 -3
- package/agnostic/objects/is-object/index.js +18 -9
- package/agnostic/objects/is-object/index.test.js +60 -0
- package/agnostic/objects/is-record/index.js +13 -7
- package/agnostic/objects/is-record/index.test.js +48 -0
- package/agnostic/objects/record-format/index.js +18 -14
- package/agnostic/objects/record-format/index.test.js +92 -0
- package/agnostic/objects/record-map/index.js +18 -7
- package/agnostic/objects/record-map/index.test.js +56 -0
- package/agnostic/objects/sort-keys/index.js +15 -13
- package/agnostic/objects/sort-keys/index.test.js +37 -0
- package/agnostic/objects/validation/index.js +21 -10
- package/agnostic/objects/validation/index.test.js +72 -0
- package/agnostic/optim/index.d.ts +1 -1
- package/agnostic/optim/index.js +1 -1
- package/agnostic/optim/memoize/index.js +24 -18
- package/agnostic/optim/memoize/index.test.js +30 -0
- package/agnostic/optim/throttle-debounce/index.js +120 -104
- package/agnostic/optim/throttle-debounce/index.test.js +44 -0
- package/agnostic/optim/throttle-debounce/types.js +1 -0
- package/agnostic/random/hex-char/index.js +9 -9
- package/agnostic/random/hex-char/index.test.js +20 -0
- package/agnostic/random/index.d.ts +1 -1
- package/agnostic/random/index.js +1 -1
- package/agnostic/random/random/index.js +19 -9
- package/agnostic/random/random/index.test.js +73 -0
- package/agnostic/random/uuid/index.js +31 -12
- package/agnostic/random/uuid/index.test.js +45 -0
- package/agnostic/regexps/index.js +126 -86
- package/agnostic/regexps/index.test.js +108 -0
- package/agnostic/sanitization/file-name/index.js +25 -7
- package/agnostic/sanitization/file-name/index.test.js +23 -0
- package/agnostic/sanitization/html/index.js +172 -116
- package/agnostic/sanitization/path/index.js +23 -13
- package/agnostic/sanitization/path/index.test.js +18 -0
- package/agnostic/sanitization/types.js +1 -0
- package/agnostic/sanitization/user-input/index.js +36 -26
- package/agnostic/sanitization/user-input/index.test.js +31 -0
- package/agnostic/strings/char-codes/index.js +123 -57
- package/agnostic/strings/matches/index.js +38 -11
- package/agnostic/strings/normalize-indent/index.js +34 -18
- package/agnostic/strings/parse-table/index.js +153 -84
- package/agnostic/strings/replace-all/index.js +36 -17
- package/agnostic/strings/to-alphanum/index.js +23 -10
- package/agnostic/strings/trim/index.js +24 -9
- package/agnostic/time/dates/format-date/index.js +140 -74
- package/agnostic/time/duration/index.js +106 -142
- package/agnostic/time/timeout/index.js +24 -18
- package/agnostic/time/transitions/index.js +200 -156
- package/agnostic/time/wait/index.js +11 -7
- package/agnostic/typescript/types.js +1 -0
- package/components/BeforeAfter/index.controlled.js +95 -0
- package/components/BeforeAfter/index.js +54 -152
- package/components/BeforeAfter/utils.js +9 -0
- package/components/Disclaimer/index.js +50 -9
- package/components/Drawer/index.js +82 -88
- package/components/EventListener/index.js +29 -47
- package/components/Gallery/index.js +146 -190
- package/components/Gallery/utils.js +12 -0
- package/components/Image/index.js +67 -106
- package/components/IntersectionObserver/index.js +62 -9
- package/components/Overlayer/index.js +59 -66
- package/components/Paginator/index.js +125 -9
- package/components/ResizeObserver/index.js +68 -9
- package/components/ResizeObserver/style.module.css +0 -0
- package/components/Scrllgngn/index.js +176 -183
- package/components/ScrollListener/index.js +97 -171
- package/components/ScrollListener/utils.js +51 -0
- package/components/Sequencer/index.controlled.js +67 -0
- package/components/Sequencer/index.js +105 -160
- package/components/ShadowRoot/index.js +42 -63
- package/components/Subtitles/index.js +107 -13
- package/components/Subtitles/types.js +1 -0
- package/components/Subtitles/utils.js +102 -0
- package/components/Theatre/index.js +89 -9
- package/components/UIModule/index.js +156 -146
- package/components/Video/index.d.ts +10 -0
- package/components/Video/index.js +292 -503
- package/components/Video/utils.js +137 -0
- package/components/_WIP_AudioQuote/index.js +1 -0
- package/components/_WIP_Icon/index.js +1 -0
- package/components/index.d.ts +2 -2
- package/components/index.js +2 -2
- package/components/public-classnames.js +18 -0
- package/components/utils/index.js +12 -7
- package/components/utils/types.js +1 -0
- package/index.d.ts +1 -2
- package/index.js +1 -2
- package/node/@aws-s3/index.test.js +6 -0
- package/node/@aws-s3/storage/directory/copy-dir/index.js +68 -9
- package/node/@aws-s3/storage/directory/index.d.ts +1 -1
- package/node/@aws-s3/storage/directory/index.js +1 -1
- package/node/@aws-s3/storage/directory/list/index.js +33 -9
- package/node/@aws-s3/storage/directory/move-dir/index.js +69 -9
- package/node/@aws-s3/storage/directory/remove-dir/index.js +59 -9
- package/node/@aws-s3/storage/file/copy/index.js +43 -9
- package/node/@aws-s3/storage/file/download/index.js +30 -9
- package/node/@aws-s3/storage/file/exists/index.js +37 -9
- package/node/@aws-s3/storage/file/index.d.ts +1 -1
- package/node/@aws-s3/storage/file/index.js +1 -1
- package/node/@aws-s3/storage/file/move/index.js +60 -9
- package/node/@aws-s3/storage/file/remove/index.js +38 -9
- package/node/@aws-s3/storage/file/stat/index.js +34 -9
- package/node/@aws-s3/storage/file/upload/index.js +55 -9
- package/node/@design-edito/index.js +1 -0
- package/node/@express/@multer/index.js +61 -45
- package/node/@google-cloud/storage/bucket/get-metadata/index.js +25 -21
- package/node/@google-cloud/storage/directory/copy-dir/index.js +38 -9
- package/node/@google-cloud/storage/directory/list/index.js +29 -9
- package/node/@google-cloud/storage/directory/move-dir/index.js +45 -9
- package/node/@google-cloud/storage/directory/remove-dir/index.js +36 -9
- package/node/@google-cloud/storage/file/copy/index.js +37 -9
- package/node/@google-cloud/storage/file/download/index.js +28 -9
- package/node/@google-cloud/storage/file/exists/index.js +26 -9
- package/node/@google-cloud/storage/file/generate-signed-url/index.js +33 -27
- package/node/@google-cloud/storage/file/get-metadata/index.js +28 -23
- package/node/@google-cloud/storage/file/get-permissions/index.js +25 -23
- package/node/@google-cloud/storage/file/index.d.ts +1 -1
- package/node/@google-cloud/storage/file/index.js +1 -1
- package/node/@google-cloud/storage/file/move/index.js +40 -9
- package/node/@google-cloud/storage/file/remove/index.js +36 -9
- package/node/@google-cloud/storage/file/revoke-signed-urls/index.js +32 -29
- package/node/@google-cloud/storage/file/stat/index.js +35 -9
- package/node/@google-cloud/storage/file/update-metadata/index.js +30 -23
- package/node/@google-cloud/storage/file/upload/index.js +47 -9
- package/node/cloud-storage/clients/index.js +35 -13
- package/node/cloud-storage/operations/copy-dir/index.js +30 -34
- package/node/cloud-storage/operations/copy-file/index.js +30 -34
- package/node/cloud-storage/operations/download-file/index.js +30 -34
- package/node/cloud-storage/operations/exists-file/index.js +30 -34
- package/node/cloud-storage/operations/list-dir/index.js +29 -34
- package/node/cloud-storage/operations/move-dir/index.js +30 -34
- package/node/cloud-storage/operations/move-file/index.js +30 -34
- package/node/cloud-storage/operations/remove-dir/index.js +29 -34
- package/node/cloud-storage/operations/remove-file/index.js +29 -34
- package/node/cloud-storage/operations/stat-file/index.js +29 -34
- package/node/cloud-storage/operations/upload-file/index.js +30 -34
- package/node/encryption/@aes-256-gcm/buffer/index.js +31 -26
- package/node/encryption/@aes-256-gcm/index.d.ts +1 -1
- package/node/encryption/@aes-256-gcm/index.js +1 -1
- package/node/encryption/@aes-256-gcm/uint8-array/index.js +57 -11
- package/node/encryption/key/index.js +19 -14
- package/node/files/is-in-directory/index.js +11 -10
- package/node/files/read-write/index.js +11 -17
- package/node/files/subpaths/index.js +156 -113
- package/node/ftps/directory/copy-dir/index.js +58 -9
- package/node/ftps/directory/index.d.ts +1 -1
- package/node/ftps/directory/index.js +1 -1
- package/node/ftps/directory/list/index.js +25 -9
- package/node/ftps/directory/move-dir/index.js +41 -9
- package/node/ftps/directory/remove-dir/index.js +42 -9
- package/node/ftps/file/copy/index.js +45 -9
- package/node/ftps/file/download/index.js +30 -9
- package/node/ftps/file/exists/index.js +39 -9
- package/node/ftps/file/index.d.ts +1 -1
- package/node/ftps/file/index.js +1 -1
- package/node/ftps/file/move/index.js +49 -9
- package/node/ftps/file/remove/index.js +40 -9
- package/node/ftps/file/stat/index.js +31 -9
- package/node/ftps/file/upload/index.js +44 -9
- package/node/images/create/index.js +10 -18
- package/node/images/format/index.js +264 -251
- package/node/images/index.d.ts +1 -1
- package/node/images/index.js +1 -1
- package/node/images/metadata/index.js +10 -18
- package/node/images/transform/index.js +168 -203
- package/node/images/transform/operations/blur/index.js +12 -10
- package/node/images/transform/operations/brighten/index.js +12 -10
- package/node/images/transform/operations/extend/index.js +26 -17
- package/node/images/transform/operations/extract/index.js +17 -10
- package/node/images/transform/operations/flatten/index.js +21 -17
- package/node/images/transform/operations/flip/index.js +3 -7
- package/node/images/transform/operations/flop/index.js +3 -7
- package/node/images/transform/operations/hue/index.js +14 -10
- 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.js +15 -10
- package/node/images/transform/operations/lighten/index.js +14 -10
- package/node/images/transform/operations/normalize/index.js +15 -10
- package/node/images/transform/operations/overlay/index.js +90 -17
- package/node/images/transform/operations/resize/index.js +47 -17
- package/node/images/transform/operations/rotate/index.js +21 -17
- package/node/images/transform/operations/saturate/index.js +16 -10
- package/node/images/types.js +34 -9
- package/node/images/utils/index.js +85 -19
- package/node/index.d.ts +3 -3
- package/node/index.js +3 -3
- package/node/process/on-exit/index.js +45 -28
- package/node/process/prompt-continue/index.js +29 -16
- package/node/process/spawner/index.js +104 -80
- package/node/sftp/directory/copy-dir/index.js +55 -9
- package/node/sftp/directory/list/index.js +23 -9
- package/node/sftp/directory/move-dir/index.js +38 -9
- package/node/sftp/directory/remove-dir/index.js +42 -9
- package/node/sftp/file/copy/index.js +40 -9
- package/node/sftp/file/download/index.js +27 -9
- package/node/sftp/file/exists/index.js +30 -9
- package/node/sftp/file/index.d.ts +2 -2
- package/node/sftp/file/index.js +2 -2
- package/node/sftp/file/move/index.js +42 -9
- package/node/sftp/file/remove/index.js +33 -9
- package/node/sftp/file/stat/index.js +28 -9
- package/node/sftp/file/upload/index.js +36 -9
- package/package.json +1 -8
- package/chunks/chunk-2FNCUXAX.js +0 -27
- package/chunks/chunk-2GJSPEO4.js +0 -31
- package/chunks/chunk-2IGP6V77.js +0 -22
- package/chunks/chunk-3QI2MSDK.js +0 -34
- package/chunks/chunk-3RNLPW7B.js +0 -101
- package/chunks/chunk-3RZMW72G.js +0 -33
- package/chunks/chunk-4KLCJX2T.js +0 -36
- package/chunks/chunk-4LTN4SCD.js +0 -55
- package/chunks/chunk-4Q4T7QQO.js +0 -27
- package/chunks/chunk-4Q5TKOIG.js +0 -53
- package/chunks/chunk-57YKZBJR.js +0 -29
- package/chunks/chunk-5H3IRSOB.js +0 -8
- package/chunks/chunk-5NTPCRFH.js +0 -32
- package/chunks/chunk-5TM235Z3.js +0 -40
- package/chunks/chunk-5WVGUZL5.js +0 -35
- package/chunks/chunk-6XL25OZX.js +0 -12
- package/chunks/chunk-75BICI4L.js +0 -20
- package/chunks/chunk-77SWZUHV.js +0 -31
- package/chunks/chunk-AC4UMIWM.js +0 -124
- package/chunks/chunk-AG4VERYN.js +0 -25
- package/chunks/chunk-AP3VYSVF.js +0 -36
- package/chunks/chunk-ASXK7XCC.js +0 -18
- package/chunks/chunk-AVIMGMTP.js +0 -17
- package/chunks/chunk-B4HGXMP3.js +0 -20
- package/chunks/chunk-B5V7D2ZL.js +0 -77
- package/chunks/chunk-B6653QJD.js +0 -37
- package/chunks/chunk-BCX4HPD7.js +0 -33
- package/chunks/chunk-CVMYA5XK.js +0 -632
- package/chunks/chunk-DMWGHBIL.js +0 -25
- package/chunks/chunk-DNIOWD7K.js +0 -8
- package/chunks/chunk-E2ZY3SEW.js +0 -26
- package/chunks/chunk-E6MSDKON.js +0 -13
- package/chunks/chunk-E7BBN5JC.js +0 -22
- package/chunks/chunk-EX2QKFY5.js +0 -41
- package/chunks/chunk-EYYNCLVR.js +0 -33
- package/chunks/chunk-F2YJXIT7.js +0 -78
- package/chunks/chunk-FSNNEPY5.js +0 -37
- package/chunks/chunk-GG4EFNMU.js +0 -89
- package/chunks/chunk-GQBFMP6N.js +0 -32
- package/chunks/chunk-H3HRQ52T.js +0 -32
- package/chunks/chunk-H4PP6AHP.js +0 -15
- package/chunks/chunk-HC6ZOHCS.js +0 -14
- package/chunks/chunk-HMMPT3UM.js +0 -47
- package/chunks/chunk-HQLRJ7XW.js +0 -12
- package/chunks/chunk-HYGUIF2O.js +0 -23
- package/chunks/chunk-HYPEWMYZ.js +0 -10
- package/chunks/chunk-I5MRXMHR.js +0 -32
- package/chunks/chunk-I6ZP5T5V.js +0 -10
- package/chunks/chunk-IEZ3O5OF.js +0 -40
- package/chunks/chunk-IPRWXI27.js +0 -31
- package/chunks/chunk-IRKZUMWZ.js +0 -38
- package/chunks/chunk-ISJONMNA.js +0 -16
- package/chunks/chunk-JB27MAKY.js +0 -22
- package/chunks/chunk-JZ6GM444.js +0 -43
- package/chunks/chunk-K5UF634H.js +0 -25
- package/chunks/chunk-LEBGVBYD.js +0 -138
- package/chunks/chunk-LJ5MGLLU.js +0 -56
- package/chunks/chunk-LUAYN7VJ.js +0 -27
- package/chunks/chunk-MDVGDZU6.js +0 -25
- package/chunks/chunk-ML22TIBW.js +0 -37
- package/chunks/chunk-MO4TRYNI.js +0 -29
- package/chunks/chunk-MSU7JU63.js +0 -49
- package/chunks/chunk-NIBRPZJD.js +0 -58
- package/chunks/chunk-O32IRXDX.js +0 -78
- package/chunks/chunk-OAX7GS7C.js +0 -36
- package/chunks/chunk-OBSTP7YR.js +0 -257
- package/chunks/chunk-OFCSIK6J.js +0 -13
- package/chunks/chunk-OFYGPRWE.js +0 -21
- package/chunks/chunk-OGBUSUE6.js +0 -12
- package/chunks/chunk-OSAXBA7G.js +0 -10
- package/chunks/chunk-OT7QXCH6.js +0 -23
- package/chunks/chunk-P4J6S2WQ.js +0 -64
- package/chunks/chunk-PUQUSA6S.js +0 -12
- package/chunks/chunk-PYJKFOMV.js +0 -193
- package/chunks/chunk-QHEWBOQI.js +0 -19
- package/chunks/chunk-QXAJXTXV.js +0 -19
- package/chunks/chunk-R3AWQXMY.js +0 -20
- package/chunks/chunk-R66GH2MQ.js +0 -38
- package/chunks/chunk-RART44AF.js +0 -21
- package/chunks/chunk-REXSJULD.js +0 -28
- package/chunks/chunk-RJRNYRPM.js +0 -23
- package/chunks/chunk-RKX6KLPQ.js +0 -47
- package/chunks/chunk-RW7VAKJW.js +0 -15
- package/chunks/chunk-RZOR7ZC3.js +0 -35
- package/chunks/chunk-S2UZ3HZR.js +0 -31
- package/chunks/chunk-SYH5LYQC.js +0 -28
- package/chunks/chunk-TAXFCVFE.js +0 -30
- package/chunks/chunk-TNZGRXKJ.js +0 -24
- package/chunks/chunk-TRFZSKNB.js +0 -32
- package/chunks/chunk-U664BT44.js +0 -45
- package/chunks/chunk-U6SGKHHA.js +0 -32
- package/chunks/chunk-UTQNGKGQ.js +0 -60
- package/chunks/chunk-VPBZS3S4.js +0 -27
- package/chunks/chunk-W5A2TON3.js +0 -10
- package/chunks/chunk-W7PJ5NQQ.js +0 -23
- package/chunks/chunk-WGRQXVBK.js +0 -207
- package/chunks/chunk-WIFHP4X7.js +0 -56
- package/chunks/chunk-WL4WNJ2Y.js +0 -39
- package/chunks/chunk-WNDMYNDU.js +0 -8
- package/chunks/chunk-WSFCRVEQ.js +0 -9
- package/chunks/chunk-WZS4Q3G3.js +0 -36
- package/chunks/chunk-X4YSGOKG.js +0 -2673
- package/chunks/chunk-XA4HVHJ4.js +0 -18
- package/chunks/chunk-XEQ2PBT2.js +0 -20
- package/chunks/chunk-XFB4PUXO.js +0 -78
- package/chunks/chunk-XIIJYVJZ.js +0 -15
- package/chunks/chunk-XNF5MLCQ.js +0 -14
- package/chunks/chunk-XQUMWHCH.js +0 -25
- package/chunks/chunk-YA2YCZUF.js +0 -8
- package/chunks/chunk-YDIBNEGA.js +0 -9
- package/chunks/chunk-YHMR7IBA.js +0 -24
- package/chunks/chunk-YWSXCFYY.js +0 -61
- package/chunks/chunk-YY3TSU22.js +0 -48
- package/chunks/chunk-ZAP3ELDE.js +0 -40
- package/chunks/chunk-ZJNQRKEJ.js +0 -105
- package/chunks/chunk-ZJR5ASR3.js +0 -26
- package/chunks/index.d.ts +0 -1
- package/chunks/index.js +0 -1
|
@@ -1,122 +1,165 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var defaultListContext = {
|
|
10
|
-
depth: 0,
|
|
11
|
-
lstats: null,
|
|
12
|
-
rootPath: null
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-throw-literal */
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { matchesSome as stringMatchesSome } from '../../../agnostic/strings/matches/index.js';
|
|
5
|
+
export const defaultListContext = {
|
|
6
|
+
depth: 0,
|
|
7
|
+
lstats: null,
|
|
8
|
+
rootPath: null
|
|
13
9
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Fills missing properties in a list context with default values.
|
|
12
|
+
*
|
|
13
|
+
* @param {ListContext} input - The partial list context to fill.
|
|
14
|
+
* @returns {Required<ListContext>} A complete list context with all properties set.
|
|
15
|
+
*/
|
|
16
|
+
export const fillListContext = (input) => {
|
|
17
|
+
return {
|
|
18
|
+
...defaultListContext,
|
|
19
|
+
...input
|
|
20
|
+
};
|
|
19
21
|
};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
22
|
+
export const defaultListOptions = {
|
|
23
|
+
directories: true,
|
|
24
|
+
files: true,
|
|
25
|
+
symlinks: true,
|
|
26
|
+
hidden: true,
|
|
27
|
+
followSimlinks: false,
|
|
28
|
+
dedupeSimlinksContents: false,
|
|
29
|
+
maxDepth: Infinity,
|
|
30
|
+
returnRelative: false,
|
|
31
|
+
exclude: null,
|
|
32
|
+
include: null,
|
|
33
|
+
filter: () => true
|
|
32
34
|
};
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Fills missing properties in list options with default values.
|
|
37
|
+
*
|
|
38
|
+
* @param {ListOptions} input - The partial list options to fill.
|
|
39
|
+
* @returns {Required<ListOptions>} A complete list options object with all properties set.
|
|
40
|
+
*/
|
|
41
|
+
export const fillOptions = (input) => {
|
|
42
|
+
return {
|
|
43
|
+
...defaultListOptions,
|
|
44
|
+
...input
|
|
45
|
+
};
|
|
38
46
|
};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Lists all subpaths under a given directory path.
|
|
49
|
+
*
|
|
50
|
+
* The function recursively traverses the directory tree and returns all matching
|
|
51
|
+
* files, directories, and symlinks based on the provided options.
|
|
52
|
+
*
|
|
53
|
+
* @param inputPath - The root directory path to list subpaths from.
|
|
54
|
+
* @param [options] - Optional configuration for filtering and behavior. See `ListOptions` for details.
|
|
55
|
+
* @returns Array of subpaths (absolute or relative based on `returnRelative` option).
|
|
56
|
+
*/
|
|
57
|
+
export async function list(...args) {
|
|
58
|
+
const [inputPath, _options] = args;
|
|
59
|
+
const options = fillOptions(_options ?? {});
|
|
60
|
+
const subpaths = await listAbsoluteSubpaths(...args);
|
|
61
|
+
return options.returnRelative
|
|
62
|
+
? subpaths.map(subpath => path.relative(inputPath, subpath))
|
|
63
|
+
: subpaths;
|
|
44
64
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Internal function that lists absolute subpaths recursively.
|
|
67
|
+
*
|
|
68
|
+
* @param {string} inputPath - The directory path to list.
|
|
69
|
+
* @param {ListOptions} [_options] - Optional configuration.
|
|
70
|
+
* @param {ListContext} [__private_context] - Internal recursion context.
|
|
71
|
+
* @returns {Promise<string[]>} Array of absolute subpaths.
|
|
72
|
+
*/
|
|
73
|
+
async function listAbsoluteSubpaths(inputPath, _options = {},
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
75
|
+
__private_context = {}) {
|
|
76
|
+
const options = fillOptions(_options);
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
78
|
+
const _private_context = fillListContext(__private_context);
|
|
79
|
+
if (_private_context.rootPath === null) {
|
|
80
|
+
_private_context.rootPath = inputPath;
|
|
81
|
+
}
|
|
82
|
+
const subpaths = [];
|
|
83
|
+
if (_private_context.depth > options.maxDepth)
|
|
84
|
+
return subpaths;
|
|
64
85
|
try {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
const pathStat = _private_context.lstats ?? await fs.lstat(inputPath);
|
|
87
|
+
if (!pathStat.isDirectory())
|
|
88
|
+
return subpaths;
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
return subpaths;
|
|
92
|
+
}
|
|
93
|
+
const childrenRelPaths = await fs.readdir(inputPath);
|
|
94
|
+
await Promise.all(childrenRelPaths.map(async (childRelPath) => {
|
|
95
|
+
const childAbsPath = path.join(inputPath, childRelPath);
|
|
96
|
+
const childRelFromRootPath = path.relative(_private_context.rootPath ?? inputPath, childAbsPath);
|
|
97
|
+
const childLstats = await fs.lstat(childAbsPath);
|
|
98
|
+
try {
|
|
99
|
+
const isDirectory = childLstats.isDirectory();
|
|
100
|
+
const isSymlink = childLstats.isSymbolicLink();
|
|
101
|
+
const isFile = !isDirectory && !isSymlink;
|
|
102
|
+
const isHidden = path.basename(childAbsPath).startsWith('.');
|
|
103
|
+
const type = isDirectory ? 'directory' : (isSymlink ? 'symlink' : 'file');
|
|
104
|
+
if (isDirectory && !options.directories)
|
|
105
|
+
throw true;
|
|
106
|
+
if (isSymlink && !options.symlinks)
|
|
107
|
+
throw false;
|
|
108
|
+
if (isFile && !options.files)
|
|
109
|
+
throw false;
|
|
110
|
+
if (isHidden && !options.hidden)
|
|
111
|
+
throw false;
|
|
112
|
+
const realPath = isSymlink
|
|
113
|
+
? await fs.realpath(childAbsPath)
|
|
114
|
+
: childAbsPath;
|
|
115
|
+
const childPathForFilters = options.returnRelative ? childRelFromRootPath : childAbsPath;
|
|
116
|
+
const isInExclude = stringMatchesSome(childPathForFilters, options.exclude ?? []);
|
|
117
|
+
const isInInclude = stringMatchesSome(childPathForFilters, options.include ?? []);
|
|
118
|
+
if (isInExclude && !isInInclude)
|
|
119
|
+
throw false;
|
|
120
|
+
const isInFilter = await options.filter(childPathForFilters, { type, hidden: isHidden, realPath });
|
|
121
|
+
if (!isInFilter)
|
|
122
|
+
throw true;
|
|
123
|
+
if (isSymlink) {
|
|
124
|
+
if (!options.followSimlinks)
|
|
125
|
+
subpaths.push(childAbsPath);
|
|
126
|
+
else {
|
|
127
|
+
const childSubpaths = await listAbsoluteSubpaths(realPath, options, {
|
|
128
|
+
..._private_context,
|
|
129
|
+
depth: _private_context.depth + 1
|
|
130
|
+
});
|
|
131
|
+
subpaths.push(realPath, ...childSubpaths);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
if (isDirectory) {
|
|
136
|
+
const childSubpaths = await listAbsoluteSubpaths(childAbsPath, options, {
|
|
137
|
+
..._private_context,
|
|
138
|
+
depth: _private_context.depth + 1,
|
|
139
|
+
lstats: childLstats
|
|
140
|
+
});
|
|
141
|
+
subpaths.push(childAbsPath, ...childSubpaths);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
subpaths.push(childAbsPath);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
89
147
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
148
|
+
catch (err) {
|
|
149
|
+
if (typeof err !== 'boolean')
|
|
150
|
+
throw new Error('This try/catch block should only throw booleans');
|
|
151
|
+
const shouldDiveDeeper = err;
|
|
152
|
+
if (!shouldDiveDeeper)
|
|
153
|
+
return [];
|
|
154
|
+
const childSubpaths = await listAbsoluteSubpaths(childAbsPath, options, {
|
|
155
|
+
..._private_context,
|
|
156
|
+
depth: _private_context.depth + 1,
|
|
157
|
+
lstats: childLstats
|
|
158
|
+
});
|
|
159
|
+
subpaths.push(...childSubpaths);
|
|
100
160
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (!shouldDiveDeeper) return [];
|
|
106
|
-
const childSubpaths = await listAbsoluteSubpaths(childAbsPath, options, {
|
|
107
|
-
..._private_context,
|
|
108
|
-
depth: _private_context.depth + 1,
|
|
109
|
-
lstats: childLstats
|
|
110
|
-
});
|
|
111
|
-
subpaths.push(...childSubpaths);
|
|
112
|
-
}
|
|
113
|
-
}));
|
|
114
|
-
return options.dedupeSimlinksContents ? Array.from(new Set(subpaths)) : subpaths;
|
|
161
|
+
}));
|
|
162
|
+
return options.dedupeSimlinksContents
|
|
163
|
+
? Array.from(new Set(subpaths))
|
|
164
|
+
: subpaths;
|
|
115
165
|
}
|
|
116
|
-
export {
|
|
117
|
-
defaultListContext,
|
|
118
|
-
defaultListOptions,
|
|
119
|
-
fillListContext,
|
|
120
|
-
fillOptions,
|
|
121
|
-
list
|
|
122
|
-
};
|
|
@@ -1,9 +1,58 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
} from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
1
|
+
import { PassThrough } from 'node:stream';
|
|
2
|
+
import * as Outcome from '../../../../agnostic/misc/outcome/index.js';
|
|
3
|
+
import { unknownToString } from '../../../../agnostic/errors/unknown-to-string/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Recursively copies every file under `sourceDir` to the same relative path
|
|
6
|
+
* beneath `targetDir` on an FTP server, streaming data to avoid buffering.
|
|
7
|
+
*
|
|
8
|
+
* @param {Client} ftpClient - The FTP client instance.
|
|
9
|
+
* @param {string} sourceDir - The source directory path to copy from.
|
|
10
|
+
* @param {string} targetDir - The target directory path to copy to.
|
|
11
|
+
* @param {CopyDirOptions} [options] - Optional parameters for the operation.
|
|
12
|
+
* @returns {Promise<Outcome.Either<true, string>>}
|
|
13
|
+
* - Success: `Outcome.makeSuccess(true)` if the copy succeeds.
|
|
14
|
+
* - Failure: `Outcome.makeFailure(errStr)` if an error occurs.
|
|
15
|
+
*/
|
|
16
|
+
export async function copyDir(ftpClient, sourceDir, targetDir, options) {
|
|
17
|
+
const { overwrite = false, ensureDir = true } = options ?? {};
|
|
18
|
+
async function recurse(dir) {
|
|
19
|
+
const list = await ftpClient.list(dir);
|
|
20
|
+
for (const entry of list) {
|
|
21
|
+
const src = dir.endsWith('/') ? dir + entry.name : dir + '/' + entry.name;
|
|
22
|
+
const rel = src.substring(sourceDir.length + (sourceDir.endsWith('/') ? 0 : 1));
|
|
23
|
+
const dst = targetDir.endsWith('/') ? targetDir + rel : `${targetDir}/${rel}`;
|
|
24
|
+
if (entry.isDirectory) {
|
|
25
|
+
if (ensureDir)
|
|
26
|
+
await ftpClient.ensureDir(dst);
|
|
27
|
+
await recurse(src);
|
|
28
|
+
}
|
|
29
|
+
else if (entry.isFile) {
|
|
30
|
+
if (!overwrite) {
|
|
31
|
+
try {
|
|
32
|
+
await ftpClient.size(dst);
|
|
33
|
+
throw new Error(`File already exists at ${dst}.`);
|
|
34
|
+
}
|
|
35
|
+
catch { /* 550 “not found” – safe to proceed */ }
|
|
36
|
+
}
|
|
37
|
+
// Make sure parent directory exists if ensureDir is enabled
|
|
38
|
+
if (ensureDir) {
|
|
39
|
+
const dirPath = dst.substring(0, dst.lastIndexOf('/'));
|
|
40
|
+
await ftpClient.ensureDir(dirPath);
|
|
41
|
+
}
|
|
42
|
+
const pass = new PassThrough();
|
|
43
|
+
const upload = ftpClient.uploadFrom(pass, dst);
|
|
44
|
+
await ftpClient.downloadTo(pass, src);
|
|
45
|
+
await upload;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
if (ensureDir)
|
|
51
|
+
await ftpClient.ensureDir(targetDir);
|
|
52
|
+
await recurse(sourceDir);
|
|
53
|
+
return Outcome.makeSuccess(true);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
return Outcome.makeFailure(unknownToString(err));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -1,9 +1,25 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
1
|
+
import * as Outcome from '../../../../agnostic/misc/outcome/index.js';
|
|
2
|
+
import { unknownToString } from '../../../../agnostic/errors/unknown-to-string/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Lists all direct children files under a given directory on an FTP server.
|
|
5
|
+
*
|
|
6
|
+
* This function returns only the immediate files (not recursive) under the specified directory.
|
|
7
|
+
*
|
|
8
|
+
* @param {Client} ftpClient - The basic-ftp client instance used to interact with the FTP server.
|
|
9
|
+
* @param {string} directoryPath - The directory path to list files under.
|
|
10
|
+
* @returns {Promise<Outcome.Either<string[], string>>} Returns either a success with an array of file paths, or a failure with an error message.
|
|
11
|
+
*/
|
|
12
|
+
export async function list(ftpClient, directoryPath) {
|
|
13
|
+
try {
|
|
14
|
+
const list = await ftpClient.list(directoryPath);
|
|
15
|
+
const files = list
|
|
16
|
+
.filter(entry => entry.isFile)
|
|
17
|
+
.map(entry => (directoryPath.endsWith('/')
|
|
18
|
+
? `${directoryPath}${entry.name}`
|
|
19
|
+
: `${directoryPath}/${entry.name}`));
|
|
20
|
+
return Outcome.makeSuccess(files);
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
return Outcome.makeFailure(unknownToString(err));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -1,9 +1,41 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import * as Outcome from '../../../../agnostic/misc/outcome/index.js';
|
|
2
|
+
import { unknownToString } from '../../../../agnostic/errors/unknown-to-string/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Renames (moves) a directory on an FTP server.
|
|
5
|
+
* Most FTP servers allow `RNFR /path/old` + `RNTO /path/new` to move a tree
|
|
6
|
+
* atomically. Falling back to manual copy/delete would be expensive, so this
|
|
7
|
+
* util simply performs `rename`.
|
|
8
|
+
*
|
|
9
|
+
* If `ensureDir` is true (default), the parent directory of `targetDir` is
|
|
10
|
+
* created if it does not exist.
|
|
11
|
+
*
|
|
12
|
+
* @param {Client} ftpClient - The FTP client instance.
|
|
13
|
+
* @param {string} sourceDir - The source directory path to move from.
|
|
14
|
+
* @param {string} targetDir - The target directory path to move to.
|
|
15
|
+
* @param {MoveDirOptions} [options] - Optional parameters for the operation.
|
|
16
|
+
* @returns {Promise<Outcome.Either<true, string>>} A promise that resolves to an `Outcome.Either`:
|
|
17
|
+
* - On success: `Outcome.makeSuccess(true)` indicating the move was successful.
|
|
18
|
+
* - On failure: `Outcome.makeFailure(errStr)` with an error message if the move fails.
|
|
19
|
+
*/
|
|
20
|
+
export async function moveDir(ftpClient, sourceDir, targetDir, options) {
|
|
21
|
+
const { overwrite = false, ensureDir = true } = options ?? {};
|
|
22
|
+
try {
|
|
23
|
+
if (ensureDir) {
|
|
24
|
+
// ensure parent directory of targetDir exists
|
|
25
|
+
const parentDir = targetDir.substring(0, targetDir.lastIndexOf('/'));
|
|
26
|
+
await ftpClient.ensureDir(parentDir);
|
|
27
|
+
}
|
|
28
|
+
if (!overwrite) {
|
|
29
|
+
try {
|
|
30
|
+
await ftpClient.size(targetDir); // will throw 550 for dirs or missing
|
|
31
|
+
return Outcome.makeFailure(`Target ${targetDir} already exists.`);
|
|
32
|
+
}
|
|
33
|
+
catch { /* not found – ok */ }
|
|
34
|
+
}
|
|
35
|
+
await ftpClient.rename(sourceDir, targetDir);
|
|
36
|
+
return Outcome.makeSuccess(true);
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
return Outcome.makeFailure(unknownToString(err));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -1,9 +1,42 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
1
|
+
import * as Outcome from '../../../../agnostic/misc/outcome/index.js';
|
|
2
|
+
import { unknownToString } from '../../../../agnostic/errors/unknown-to-string/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Recursively deletes a directory (and all contents) on an FTP server.
|
|
5
|
+
*
|
|
6
|
+
* @param {Client} ftpClient - The FTP client instance.
|
|
7
|
+
* @param {string} directoryPath - The path of the directory to delete.
|
|
8
|
+
* @param {RemoveDirOptions} [options] - Optional configuration.
|
|
9
|
+
* @param {boolean} [options.ignoreMissing=true] - Whether to ignore a missing directory.
|
|
10
|
+
* @returns {Promise<Outcome.Either<true, string>>}
|
|
11
|
+
* - On success: `Outcome.makeSuccess(true)` – deletion succeeded, or directory
|
|
12
|
+
* was absent and `ignoreMissing` is true.
|
|
13
|
+
* - On failure: `Outcome.makeFailure(errStr)` if deletion fails, or directory
|
|
14
|
+
* absent and `ignoreMissing` is false.
|
|
15
|
+
*/
|
|
16
|
+
export async function removeDir(ftpClient, directoryPath, options) {
|
|
17
|
+
const { ignoreMissing = true } = options ?? {};
|
|
18
|
+
async function recurse(dir) {
|
|
19
|
+
const list = await ftpClient.list(dir);
|
|
20
|
+
for (const entry of list) {
|
|
21
|
+
const full = dir.endsWith('/') ? dir + entry.name : `${dir}/${entry.name}`;
|
|
22
|
+
if (entry.isDirectory) {
|
|
23
|
+
await recurse(full);
|
|
24
|
+
}
|
|
25
|
+
else if (entry.isFile) {
|
|
26
|
+
await ftpClient.remove(full);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
await ftpClient.removeDir(dir);
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
await recurse(directoryPath);
|
|
33
|
+
return Outcome.makeSuccess(true);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
// 550 (“No such file or directory”) when the path is missing
|
|
37
|
+
if (ignoreMissing && err.code === 550) {
|
|
38
|
+
return Outcome.makeSuccess(true);
|
|
39
|
+
}
|
|
40
|
+
return Outcome.makeFailure(unknownToString(err));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -1,9 +1,45 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
} from
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
1
|
+
import { PassThrough } from 'node:stream';
|
|
2
|
+
import * as Outcome from '../../../../agnostic/misc/outcome/index.js';
|
|
3
|
+
import { unknownToString } from '../../../../agnostic/errors/unknown-to-string/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Copies a file from one path to another on the same FTP server, streaming the
|
|
6
|
+
* data instead of buffering it in memory.
|
|
7
|
+
*
|
|
8
|
+
* @param {Client} ftpClient - The basic‑ftp client instance.
|
|
9
|
+
* @param {string} sourcePath - The path of the source file.
|
|
10
|
+
* @param {string} targetPath - The destination path.
|
|
11
|
+
* @param {CopyOptions} [options] - Optional copy configuration.
|
|
12
|
+
* @returns {Promise<Outcome.Either<true, string>>}
|
|
13
|
+
* - On success: `Outcome.makeSuccess(true)`.
|
|
14
|
+
* - On failure: `Outcome.makeFailure(errStr)`.
|
|
15
|
+
*/
|
|
16
|
+
export async function copy(ftpClient, sourcePath, targetPath, options) {
|
|
17
|
+
const { overwrite = false, ensureDir = true } = options ?? {};
|
|
18
|
+
try {
|
|
19
|
+
// Abort if destination exists and overwrite is disabled
|
|
20
|
+
if (!overwrite) {
|
|
21
|
+
try {
|
|
22
|
+
await ftpClient.size(targetPath);
|
|
23
|
+
return Outcome.makeFailure(`File already exists at ${targetPath}.`);
|
|
24
|
+
}
|
|
25
|
+
catch { /* 550 = not found – safe to proceed */ }
|
|
26
|
+
}
|
|
27
|
+
// Create missing target directories if requested
|
|
28
|
+
if (ensureDir) {
|
|
29
|
+
const dirPath = targetPath.substring(0, targetPath.lastIndexOf('/'));
|
|
30
|
+
await ftpClient.ensureDir(dirPath);
|
|
31
|
+
}
|
|
32
|
+
// Stream copy: download → PassThrough → upload
|
|
33
|
+
const pass = new PassThrough();
|
|
34
|
+
// Start the upload first so the server reads from `pass` as data arrives
|
|
35
|
+
const uploadPromise = ftpClient.uploadFrom(pass, targetPath);
|
|
36
|
+
// Pump data from source into `pass`
|
|
37
|
+
await ftpClient.downloadTo(pass, sourcePath);
|
|
38
|
+
// Wait until the upload completes
|
|
39
|
+
await uploadPromise;
|
|
40
|
+
return Outcome.makeSuccess(true);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
return Outcome.makeFailure(unknownToString(err));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -1,9 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { PassThrough } from 'node:stream';
|
|
2
|
+
import { unknownToString } from '../../../../agnostic/errors/unknown-to-string/index.js';
|
|
3
|
+
import * as Outcome from '../../../../agnostic/misc/outcome/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Downloads a file from a specified FTP server.
|
|
6
|
+
*
|
|
7
|
+
* This function downloads a file from the given FTP server at the specified source path,
|
|
8
|
+
* returning the file content as a Readable stream. The download process can be customized
|
|
9
|
+
* using optional download options.
|
|
10
|
+
*
|
|
11
|
+
* @param {Client} ftpClient - The basic-ftp client instance used to interact with the FTP server.
|
|
12
|
+
* @param {string} sourcePath - The path of the file to be downloaded from the FTP server.
|
|
13
|
+
* @param {DownloadOptions} [options] - Optional settings for configuring the download process.
|
|
14
|
+
* @param {number} [options.startAt] - The byte offset at which to start downloading the file.
|
|
15
|
+
* @returns {Promise<Outcome.Either<Readable, string>>} A promise that resolves to an Outcome.Either.
|
|
16
|
+
* - On success: Outcome.makeSuccess(stream) containing the downloaded file's content as a Readable stream.
|
|
17
|
+
* - On failure: Outcome.makeFailure(errStr) with an error message if the download fails.
|
|
18
|
+
*/
|
|
19
|
+
export async function download(ftpClient, sourcePath, options) {
|
|
20
|
+
const { startAt } = options ?? {};
|
|
21
|
+
const stream = new PassThrough();
|
|
22
|
+
try {
|
|
23
|
+
await ftpClient.downloadTo(stream, sourcePath, startAt);
|
|
24
|
+
return Outcome.makeSuccess(stream);
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
const errStr = unknownToString(err);
|
|
28
|
+
return Outcome.makeFailure(errStr);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -1,9 +1,39 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { FileType } from 'basic-ftp';
|
|
2
|
+
import { unknownToString } from '../../../../agnostic/errors/unknown-to-string/index.js';
|
|
3
|
+
import * as Outcome from '../../../../agnostic/misc/outcome/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Checks if a *file* (not a directory) exists on a specified FTP server.
|
|
6
|
+
*
|
|
7
|
+
* `ftpClient.list(parentDir)` returns an array of `FileInfo` objects:
|
|
8
|
+
* • `type === FileType.File` → regular file
|
|
9
|
+
* • `type === FileType.Directory` → directory
|
|
10
|
+
* • `type === FileType.SymbolicLink` → symlink
|
|
11
|
+
*
|
|
12
|
+
* The function reports **true** only for `FileType.File` or
|
|
13
|
+
* `FileType.SymbolicLink`, mirroring the SFTP behaviour where `'-'` and `'l'`
|
|
14
|
+
* are considered files.
|
|
15
|
+
*
|
|
16
|
+
* @param {Client} ftpClient - The basic‑ftp client instance.
|
|
17
|
+
* @param {string} sourcePath - The full path to check on the FTP server.
|
|
18
|
+
* @returns {Promise<Outcome.Either<boolean, string>>}
|
|
19
|
+
* - Success: `Outcome.makeSuccess(true | false)` – true only if a file exists.
|
|
20
|
+
* - Failure: `Outcome.makeFailure(errStr)` if an error occurs.
|
|
21
|
+
*/
|
|
22
|
+
export async function exists(ftpClient, sourcePath) {
|
|
23
|
+
try {
|
|
24
|
+
// Split path into parent dir and base name
|
|
25
|
+
const lastSlash = sourcePath.lastIndexOf('/');
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
27
|
+
const parentDir = lastSlash === -1 ? '.' : sourcePath.slice(0, lastSlash) || '/';
|
|
28
|
+
const baseName = lastSlash === -1 ? sourcePath : sourcePath.slice(lastSlash + 1);
|
|
29
|
+
const list = await ftpClient.list(parentDir);
|
|
30
|
+
const entry = list.find(e => e.name === baseName);
|
|
31
|
+
const isFile = entry !== undefined
|
|
32
|
+
? (entry.type === FileType.File || entry.type === FileType.SymbolicLink)
|
|
33
|
+
: false;
|
|
34
|
+
return Outcome.makeSuccess(isFile);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
return Outcome.makeFailure(unknownToString(err));
|
|
38
|
+
}
|
|
39
|
+
}
|