@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,121 +1,177 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
import * as Window from '../../misc/crossenv/window/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Default sanitization options.
|
|
4
|
+
*
|
|
5
|
+
* Only sets a default recursion depth of 20.
|
|
6
|
+
*/
|
|
7
|
+
export const defaultOptions = { depth: 20 };
|
|
8
|
+
/**
|
|
9
|
+
* Sanitizes an HTML string according to the provided options.
|
|
10
|
+
*
|
|
11
|
+
* @deprecated
|
|
12
|
+
* @security
|
|
13
|
+
* ⚠️ SECURITY WARNING
|
|
14
|
+
* This function is **not a hardened or complete HTML sanitizer**.
|
|
15
|
+
* It does not guarantee protection against XSS or other injection attacks.
|
|
16
|
+
*
|
|
17
|
+
* Correctness and safety depend entirely on strict caller configuration.
|
|
18
|
+
* In particular, unsafe usage may occur if:
|
|
19
|
+
* - Wildcards (`'*'`) are used for allowed tags or attributes
|
|
20
|
+
* - URL-based attributes (`href`, `src`, `xlink:href`, etc.) are insufficiently constrained
|
|
21
|
+
* - Event handler attributes (`on*`) are not explicitly forbidden
|
|
22
|
+
* - SVG or MathML content is allowed
|
|
23
|
+
*
|
|
24
|
+
* This API must not be used as a security boundary for untrusted HTML.
|
|
25
|
+
* For security-critical sanitization, use a dedicated, security-audited library.
|
|
26
|
+
*
|
|
27
|
+
* @param {string} inputStr - The HTML string to sanitize.
|
|
28
|
+
* @param {SanitizeHtmlOptions} [options=defaultOptions] - Sanitization configuration.
|
|
29
|
+
* @returns {string} The sanitized HTML string.
|
|
30
|
+
*
|
|
31
|
+
* @throws Will throw an error if no document object is available for creating elements.
|
|
32
|
+
*/
|
|
33
|
+
export function sanitizeHtml(inputStr, options = defaultOptions) {
|
|
34
|
+
const { document } = Window.get();
|
|
35
|
+
const wrapperDiv = document.createElement('div');
|
|
36
|
+
const { inputFreeTransform } = options;
|
|
37
|
+
wrapperDiv.innerHTML = inputFreeTransform !== undefined ? inputFreeTransform(inputStr) : inputStr;
|
|
38
|
+
const sanitizedWrapper = sanitizeElement(wrapperDiv, options);
|
|
39
|
+
const returned = sanitizedWrapper?.innerHTML;
|
|
40
|
+
return returned ?? '';
|
|
16
41
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Recursively sanitizes a DOM element and its descendants according to the provided options.
|
|
44
|
+
*
|
|
45
|
+
* @deprecated
|
|
46
|
+
* @security
|
|
47
|
+
* ⚠️ SECURITY WARNING
|
|
48
|
+
* This function is **not a hardened or complete HTML sanitizer**.
|
|
49
|
+
* It does not guarantee protection against XSS or other injection attacks.
|
|
50
|
+
*
|
|
51
|
+
* Correctness and safety depend entirely on strict caller configuration.
|
|
52
|
+
* In particular, unsafe usage may occur if:
|
|
53
|
+
* - Wildcards (`'*'`) are used for allowed tags or attributes
|
|
54
|
+
* - URL-based attributes (`href`, `src`, `xlink:href`, etc.) are insufficiently constrained
|
|
55
|
+
* - Event handler attributes (`on*`) are not explicitly forbidden
|
|
56
|
+
* - SVG or MathML content is allowed
|
|
57
|
+
*
|
|
58
|
+
* This API must not be used as a security boundary for untrusted HTML.
|
|
59
|
+
* For security-critical sanitization, use a dedicated, security-audited library.
|
|
60
|
+
*
|
|
61
|
+
* @param {Element} element - The DOM element to sanitize.
|
|
62
|
+
* @param {SanitizeHtmlOptions} [options=defaultOptions] - Sanitization configuration.
|
|
63
|
+
* @returns {Element | null}
|
|
64
|
+
* - A sanitized clone of the original element with allowed attributes and children.
|
|
65
|
+
* - `null` if the element is forbidden or maximum recursion depth is reached.
|
|
66
|
+
*
|
|
67
|
+
* @throws Will throw an error if no document object is available for creating elements.
|
|
68
|
+
*/
|
|
69
|
+
export function sanitizeElement(element, options = defaultOptions) {
|
|
70
|
+
const { tagName, attributes, childNodes } = element;
|
|
71
|
+
const { allowedTags = [], allowedAttributes = {}, forbiddenTags = [], forbiddenAttributes = {}, depth = 20, verbose = false } = options;
|
|
72
|
+
if (depth <= 0) {
|
|
73
|
+
console.warn('Max depth reached');
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
// Element's tag name checkup
|
|
77
|
+
const normalizedTagName = tagName.toLowerCase().trim();
|
|
78
|
+
const tagIsInForbidden = forbiddenTags.includes('*') || forbiddenTags.includes(normalizedTagName);
|
|
79
|
+
if (tagIsInForbidden) {
|
|
80
|
+
if (verbose)
|
|
81
|
+
console.warn(tagName, 'tag is forbidden');
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
const tagIsInAllowed = allowedTags.includes('*') || allowedTags.includes(normalizedTagName);
|
|
85
|
+
if (!tagIsInAllowed) {
|
|
86
|
+
if (verbose)
|
|
87
|
+
console.warn(tagName, 'tag is not allowed');
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const returnedElement = Window.get().document.createElement(tagName);
|
|
91
|
+
// Element's attributes checkup
|
|
92
|
+
const returnedAttributes = Array.from(attributes).filter(({ name: attributeName, value: attributeValue }) => {
|
|
93
|
+
const allTagsForbiddenAttributes = forbiddenAttributes['*'] ?? [];
|
|
94
|
+
const thisTagForbiddenAttributes = forbiddenAttributes[normalizedTagName] ?? [];
|
|
95
|
+
const mergedForbiddenAttributes = [...allTagsForbiddenAttributes, ...thisTagForbiddenAttributes];
|
|
96
|
+
const isInForbidden = mergedForbiddenAttributes.some(({ attributeName: nameTester, attributeValues: valTesters }) => {
|
|
97
|
+
if (typeof nameTester === 'string' && nameTester !== '*' && attributeName !== nameTester)
|
|
98
|
+
return false; // attribute name doesnt match
|
|
99
|
+
if (typeof nameTester !== 'string' && !nameTester.test(attributeName))
|
|
100
|
+
return false; // attribute name doesnt match
|
|
101
|
+
if (valTesters === undefined) {
|
|
102
|
+
if (verbose)
|
|
103
|
+
console.warn(attributeName, 'attribute on', tagName, 'tag is forbidden');
|
|
104
|
+
return true; // attribute name matches, and all values are forbidden
|
|
105
|
+
}
|
|
106
|
+
if (valTesters.includes('*')) {
|
|
107
|
+
if (verbose)
|
|
108
|
+
console.warn(attributeName, 'attribute on', tagName, 'tag is forbidden');
|
|
109
|
+
return true; // attribute name matches, and all values are EXPLICITLY forbidden
|
|
110
|
+
}
|
|
111
|
+
return valTesters.some(valTester => {
|
|
112
|
+
if (typeof valTester === 'string' && attributeValue === valTester) {
|
|
113
|
+
if (verbose)
|
|
114
|
+
console.warn(attributeValue, 'value for', attributeName, 'attribute on', tagName, 'tag is forbidden. Rule:', valTester);
|
|
115
|
+
return true; // attribute value strictly matches
|
|
116
|
+
}
|
|
117
|
+
if (typeof valTester !== 'string' && valTester.test(attributeValue)) {
|
|
118
|
+
if (verbose)
|
|
119
|
+
console.warn(attributeValue, 'value for', attributeName, 'attribute on', tagName, 'tag is forbidden. Rule:', valTester);
|
|
120
|
+
return true; // attribute value partially matches
|
|
121
|
+
}
|
|
122
|
+
return false;
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
if (isInForbidden)
|
|
126
|
+
return false;
|
|
127
|
+
const allTagsAllowedAttributes = allowedAttributes['*'] ?? [];
|
|
128
|
+
const thisTagAllowedAttributes = allowedAttributes[normalizedTagName] ?? [];
|
|
129
|
+
const mergedAllowedAttributes = [...allTagsAllowedAttributes, ...thisTagAllowedAttributes];
|
|
130
|
+
let latestNotAllowedReason = [tagName, 'has no allowed attributes'];
|
|
131
|
+
const isInAllowed = mergedAllowedAttributes.some(({ attributeName: nameTester, attributeValues: valTesters }) => {
|
|
132
|
+
if (typeof nameTester === 'string' && nameTester !== '*' && attributeName !== nameTester) {
|
|
133
|
+
latestNotAllowedReason = [attributeName, 'attribute on', tagName, 'tag is not allowed'];
|
|
134
|
+
return false; // attribute name doesnt match
|
|
135
|
+
}
|
|
136
|
+
if (typeof nameTester !== 'string' && !nameTester.test(attributeName)) {
|
|
137
|
+
latestNotAllowedReason = [attributeName, 'attribute on', tagName, 'tag is not allowed'];
|
|
138
|
+
return false; // attribute name doesnt match
|
|
139
|
+
}
|
|
140
|
+
if (valTesters === undefined)
|
|
141
|
+
return true; // attribute name matches, and all values are allowed
|
|
142
|
+
if (valTesters.includes('*'))
|
|
143
|
+
return true; // attribute name matches, and all values are EXPLICITLY allowed
|
|
144
|
+
return valTesters.some(valTester => {
|
|
145
|
+
if (typeof valTester === 'string' && attributeValue === valTester)
|
|
146
|
+
return true; // attribute value strictly matches
|
|
147
|
+
if (typeof valTester !== 'string' && valTester.test(attributeValue))
|
|
148
|
+
return true; // attribute value partially matches
|
|
149
|
+
latestNotAllowedReason = [attributeValue, 'value for', attributeName, 'attribute on', tagName, 'tag is not allowed'];
|
|
150
|
+
return false;
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
if (!isInAllowed) {
|
|
154
|
+
if (verbose)
|
|
155
|
+
console.warn(...latestNotAllowedReason);
|
|
156
|
+
return false;
|
|
69
157
|
}
|
|
70
|
-
return
|
|
71
|
-
});
|
|
158
|
+
return true;
|
|
72
159
|
});
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const thisTagAllowedAttributes = allowedAttributes[normalizedTagName] ?? [];
|
|
76
|
-
const mergedAllowedAttributes = [...allTagsAllowedAttributes, ...thisTagAllowedAttributes];
|
|
77
|
-
let latestNotAllowedReason = [tagName, "has no allowed attributes"];
|
|
78
|
-
const isInAllowed = mergedAllowedAttributes.some(({
|
|
79
|
-
attributeName: nameTester,
|
|
80
|
-
attributeValues: valTesters
|
|
81
|
-
}) => {
|
|
82
|
-
if (typeof nameTester === "string" && nameTester !== "*" && attributeName !== nameTester) {
|
|
83
|
-
latestNotAllowedReason = [attributeName, "attribute on", tagName, "tag is not allowed"];
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
if (typeof nameTester !== "string" && !nameTester.test(attributeName)) {
|
|
87
|
-
latestNotAllowedReason = [attributeName, "attribute on", tagName, "tag is not allowed"];
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
if (valTesters === void 0) return true;
|
|
91
|
-
if (valTesters.includes("*")) return true;
|
|
92
|
-
return valTesters.some((valTester) => {
|
|
93
|
-
if (typeof valTester === "string" && attributeValue === valTester) return true;
|
|
94
|
-
if (typeof valTester !== "string" && valTester.test(attributeValue)) return true;
|
|
95
|
-
latestNotAllowedReason = [attributeValue, "value for", attributeName, "attribute on", tagName, "tag is not allowed"];
|
|
96
|
-
return false;
|
|
97
|
-
});
|
|
160
|
+
returnedAttributes.forEach(({ name, value }) => {
|
|
161
|
+
returnedElement.setAttribute(name, value);
|
|
98
162
|
});
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return
|
|
113
|
-
}).filter((elt) => elt !== null);
|
|
114
|
-
returnedElement.replaceChildren(...sanitizedChildNodes);
|
|
115
|
-
return returnedElement;
|
|
163
|
+
// Element's children sanitization
|
|
164
|
+
const sanitizedChildNodes = Array.from(childNodes)
|
|
165
|
+
.map((node) => {
|
|
166
|
+
if (node.nodeType === Node.ELEMENT_NODE)
|
|
167
|
+
return sanitizeElement(node, { ...options, depth: depth - 1 });
|
|
168
|
+
else if (node.nodeType === Node.TEXT_NODE)
|
|
169
|
+
return node;
|
|
170
|
+
else if (options.keepComments === true && node.nodeType === Node.COMMENT_NODE)
|
|
171
|
+
return node;
|
|
172
|
+
return null;
|
|
173
|
+
})
|
|
174
|
+
.filter((elt) => elt !== null);
|
|
175
|
+
returnedElement.replaceChildren(...sanitizedChildNodes);
|
|
176
|
+
return returnedElement;
|
|
116
177
|
}
|
|
117
|
-
export {
|
|
118
|
-
defaultOptions,
|
|
119
|
-
sanitizeElement,
|
|
120
|
-
sanitizeHtml
|
|
121
|
-
};
|
|
@@ -1,14 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { sanitizeFileName } from '../file-name/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Sanitizes a path string by sanitizing each path segment.
|
|
4
|
+
*
|
|
5
|
+
* - Removes empty segments and `..` segments to prevent path traversal.
|
|
6
|
+
* - Sanitizes each segment using `sanitizeFileName`.
|
|
7
|
+
* - Ensures the returned path starts with a `/`.
|
|
8
|
+
*
|
|
9
|
+
* @param {string} targetPath - The path to sanitize.
|
|
10
|
+
* @returns {string | null} Sanitized absolute path, or null if invalid/empty.
|
|
11
|
+
*/
|
|
12
|
+
export function sanitizePath(targetPath) {
|
|
13
|
+
const sanitized = targetPath
|
|
14
|
+
.split('/')
|
|
15
|
+
.filter(chunk => chunk !== '')
|
|
16
|
+
.map(chunk => sanitizeFileName(chunk) ?? '')
|
|
17
|
+
.filter(chunk => chunk !== '' && chunk !== '..')
|
|
18
|
+
.join('/');
|
|
19
|
+
if (sanitized === '')
|
|
20
|
+
return null;
|
|
21
|
+
return sanitized.startsWith('/')
|
|
22
|
+
? sanitized
|
|
23
|
+
: `/${sanitized}`;
|
|
11
24
|
}
|
|
12
|
-
export {
|
|
13
|
-
sanitizePath
|
|
14
|
-
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { sanitizePath } from './index.js';
|
|
3
|
+
describe('sanitizePath', () => {
|
|
4
|
+
it('sanitizes each segment and removes empty/.. segments', () => {
|
|
5
|
+
const input = '/some//../unsafe/..//path/ fi?le.txt';
|
|
6
|
+
const result = sanitizePath(input);
|
|
7
|
+
expect(result).toBe('/some/unsafe/path/file.txt');
|
|
8
|
+
});
|
|
9
|
+
it('returns null for an empty or fully-invalid path', () => {
|
|
10
|
+
expect(sanitizePath('')).toBeNull();
|
|
11
|
+
expect(sanitizePath('/../..///')).toBeNull();
|
|
12
|
+
});
|
|
13
|
+
it('ensures the returned path starts with a leading slash', () => {
|
|
14
|
+
const input = 'relative/path.txt';
|
|
15
|
+
const result = sanitizePath(input);
|
|
16
|
+
expect(result?.startsWith('/')).toBe(true);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,28 +1,38 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
import xss from 'xss';
|
|
2
|
+
/**
|
|
3
|
+
* Recursively sanitizes user input to prevent XSS.
|
|
4
|
+
*
|
|
5
|
+
* - Strings are sanitized using `xss`.
|
|
6
|
+
* - Arrays and objects are sanitized recursively.
|
|
7
|
+
* - Circular references are safely handled via a `WeakMap`.
|
|
8
|
+
*
|
|
9
|
+
* @template T
|
|
10
|
+
* @param input - Input value to sanitize (string, object, or array).
|
|
11
|
+
* @param [seen] - Internal set to track circular references.
|
|
12
|
+
* @returns Sanitized input with the same structure as the original.
|
|
13
|
+
*/
|
|
14
|
+
export const sanitizeUserInput = (input, seen = new WeakMap()) => {
|
|
15
|
+
if (typeof input === 'string')
|
|
16
|
+
return xss(input);
|
|
17
|
+
if (Array.isArray(input)) {
|
|
18
|
+
if (seen.has(input))
|
|
19
|
+
return seen.get(input);
|
|
20
|
+
const sanitized = [];
|
|
21
|
+
seen.set(input, sanitized);
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
23
|
+
sanitized.push(...input.map(item => sanitizeUserInput(item, seen)));
|
|
24
|
+
return sanitized;
|
|
21
25
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
if (input !== null && typeof input === 'object') {
|
|
27
|
+
if (seen.has(input))
|
|
28
|
+
return seen.get(input);
|
|
29
|
+
const sanitized = {};
|
|
30
|
+
seen.set(input, sanitized);
|
|
31
|
+
const entries = Object.entries(input);
|
|
32
|
+
for (const [key, value] of entries) {
|
|
33
|
+
sanitized[xss(key)] = sanitizeUserInput(value, seen);
|
|
34
|
+
}
|
|
35
|
+
return sanitized;
|
|
36
|
+
}
|
|
37
|
+
return input;
|
|
28
38
|
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import { sanitizeUserInput } from './index.js';
|
|
3
|
+
vi.mock('xss', () => ({
|
|
4
|
+
default: vi.fn((value) => `sanitized(${value})`)
|
|
5
|
+
}));
|
|
6
|
+
describe('sanitizeUserInput', () => {
|
|
7
|
+
it('sanitizes plain strings using xss', () => {
|
|
8
|
+
const result = sanitizeUserInput('<script>alert(1)</script>');
|
|
9
|
+
expect(result).toBe('sanitized(<script>alert(1)</script>)');
|
|
10
|
+
});
|
|
11
|
+
it('recursively sanitizes arrays and objects', () => {
|
|
12
|
+
const input = {
|
|
13
|
+
'<key>': ['<v1>', '<v2>'],
|
|
14
|
+
nested: { '<inner>': '<v3>' }
|
|
15
|
+
};
|
|
16
|
+
const result = sanitizeUserInput(input);
|
|
17
|
+
expect(result).toEqual({
|
|
18
|
+
'sanitized(<key>)': ['sanitized(<v1>)', 'sanitized(<v2>)'],
|
|
19
|
+
'sanitized(nested)': { 'sanitized(<inner>)': 'sanitized(<v3>)' }
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
it('handles circular references without infinite recursion', () => {
|
|
23
|
+
const obj = { name: '<name>' };
|
|
24
|
+
obj.self = obj;
|
|
25
|
+
const result = sanitizeUserInput(obj);
|
|
26
|
+
// Just verify it doesn't throw and returns something
|
|
27
|
+
expect(result).toBeDefined();
|
|
28
|
+
// The circular reference should still be circular
|
|
29
|
+
expect(result['sanitized(self)']).toBe(result);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -1,70 +1,136 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
// CharCode to/from B36CharCode
|
|
2
|
+
/**
|
|
3
|
+
* Converts a Unicode character code to a base-36 string.
|
|
4
|
+
* @param charCode - The character code to convert.
|
|
5
|
+
* @returns Base-36 encoded character code.
|
|
6
|
+
*/
|
|
7
|
+
export function charCodeToB36(charCode) {
|
|
8
|
+
if (charCode === null)
|
|
9
|
+
return '\x00';
|
|
10
|
+
return charCode.toString(36);
|
|
7
11
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Converts a base-36 character code string back to a Unicode character code.
|
|
14
|
+
* @param b36CharCode - Base-36 encoded character code.
|
|
15
|
+
* @returns Unicode character code.
|
|
16
|
+
*/
|
|
17
|
+
export function b36CharCodeToCharCode(b36CharCode) {
|
|
18
|
+
if (b36CharCode === null)
|
|
19
|
+
return 0;
|
|
20
|
+
const charCode = parseInt(b36CharCode, 36);
|
|
21
|
+
if (!Number.isInteger(charCode))
|
|
22
|
+
return 0;
|
|
23
|
+
return charCode;
|
|
13
24
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
25
|
+
// Char to
|
|
26
|
+
/**
|
|
27
|
+
* Converts a single character to its Unicode character code.
|
|
28
|
+
* @param char - The character to convert.
|
|
29
|
+
* @returns Unicode character code.
|
|
30
|
+
*/
|
|
31
|
+
export function charToCharCode(char) {
|
|
32
|
+
const charCode = char.charCodeAt(0);
|
|
33
|
+
if (!Number.isInteger(charCode))
|
|
34
|
+
return 0;
|
|
35
|
+
return charCode;
|
|
18
36
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Converts a single character to its base-36 encoded character code.
|
|
39
|
+
* @param char - The character to convert.
|
|
40
|
+
* @returns Base-36 character code.
|
|
41
|
+
*/
|
|
42
|
+
export function charToB36CharCode(char) {
|
|
43
|
+
const charCode = charToCharCode(char);
|
|
44
|
+
return charCodeToB36(charCode);
|
|
22
45
|
}
|
|
23
|
-
|
|
24
|
-
|
|
46
|
+
// Char from
|
|
47
|
+
/**
|
|
48
|
+
* Returns the character corresponding to a Unicode character code.
|
|
49
|
+
* @param charCode - Unicode character code.
|
|
50
|
+
* @returns Single-character string.
|
|
51
|
+
*/
|
|
52
|
+
export function charFromCharCode(charCode) {
|
|
53
|
+
return String.fromCharCode(charCode);
|
|
25
54
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Returns the character corresponding to a base-36 encoded character code.
|
|
57
|
+
* @param b36CharCode - Base-36 character code.
|
|
58
|
+
* @returns Single-character string.
|
|
59
|
+
*/
|
|
60
|
+
export function charFromB36CharCode(b36CharCode) {
|
|
61
|
+
const charCode = parseInt(b36CharCode, 36);
|
|
62
|
+
if (!Number.isInteger(charCode))
|
|
63
|
+
return '\x00';
|
|
64
|
+
return charFromCharCode(charCode);
|
|
30
65
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
66
|
+
// String to
|
|
67
|
+
/**
|
|
68
|
+
* Converts a string into an array of Unicode character codes.
|
|
69
|
+
* @param string - Input string.
|
|
70
|
+
* @returns Array of character codes.
|
|
71
|
+
*/
|
|
72
|
+
export function toCharCodes(string) {
|
|
73
|
+
const chars = string.split('');
|
|
74
|
+
return chars.map(charToCharCode);
|
|
34
75
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
76
|
+
/**
|
|
77
|
+
* Converts a string into an array of base-36 encoded character codes.
|
|
78
|
+
* @param string - Input string.
|
|
79
|
+
* @returns Array of base-36 character codes.
|
|
80
|
+
*/
|
|
81
|
+
export function toB36CharCodes(string) {
|
|
82
|
+
const chars = string.split('');
|
|
83
|
+
return chars.map(charToB36CharCode);
|
|
38
84
|
}
|
|
39
|
-
|
|
40
|
-
|
|
85
|
+
// String from
|
|
86
|
+
/**
|
|
87
|
+
* Converts an array of Unicode character codes back to a string.
|
|
88
|
+
* @param charCodes - Array of character codes.
|
|
89
|
+
* @returns Reconstructed string.
|
|
90
|
+
*/
|
|
91
|
+
export function fromCharCodes(charCodes) {
|
|
92
|
+
return charCodes
|
|
93
|
+
.map(charFromCharCode)
|
|
94
|
+
.map(char => char ?? '\x00')
|
|
95
|
+
.join('');
|
|
41
96
|
}
|
|
42
|
-
|
|
43
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Converts an array of base-36 encoded character codes back to a string.
|
|
99
|
+
* @param b36CharCodes - Array of base-36 character codes.
|
|
100
|
+
* @returns Reconstructed string.
|
|
101
|
+
*/
|
|
102
|
+
export function fromB36CharCodes(b36CharCodes) {
|
|
103
|
+
return b36CharCodes
|
|
104
|
+
.map(charFromB36CharCode)
|
|
105
|
+
.map(char => char ?? '\x00')
|
|
106
|
+
.join('');
|
|
44
107
|
}
|
|
45
|
-
|
|
46
|
-
|
|
108
|
+
// Serialization
|
|
109
|
+
/**
|
|
110
|
+
* Serializes an array of character codes (Unicode or base-36) into a string.
|
|
111
|
+
* @param charCodes - Array of character codes to serialize.
|
|
112
|
+
* @returns Serialized string representation.
|
|
113
|
+
*/
|
|
114
|
+
export function serialize(charCodes) {
|
|
115
|
+
return charCodes
|
|
116
|
+
.map(c => typeof c === 'string' ? c : charCodeToB36(c))
|
|
117
|
+
.join(',');
|
|
47
118
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Deserializes a string of base-36 character codes into an array of Unicode character codes.
|
|
121
|
+
* @param serializedCharCodes - Serialized string.
|
|
122
|
+
* @returns Array of Unicode character codes.
|
|
123
|
+
*/
|
|
124
|
+
export function deserialize(serializedCharCodes) {
|
|
125
|
+
const b36CharCodes = serializedCharCodes.split('');
|
|
126
|
+
return b36CharCodes.map(b36CharCodeToCharCode);
|
|
51
127
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
128
|
+
/**
|
|
129
|
+
* Deserializes a string of base-36 character codes and reconstructs the original string.
|
|
130
|
+
* @param serializedCharCodes - Serialized string.
|
|
131
|
+
* @returns Original string.
|
|
132
|
+
*/
|
|
133
|
+
export function fromSerialized(serializedCharCodes) {
|
|
134
|
+
const charCodes = deserialize(serializedCharCodes);
|
|
135
|
+
return fromCharCodes(charCodes);
|
|
55
136
|
}
|
|
56
|
-
export {
|
|
57
|
-
b36CharCodeToCharCode,
|
|
58
|
-
charCodeToB36,
|
|
59
|
-
charFromB36CharCode,
|
|
60
|
-
charFromCharCode,
|
|
61
|
-
charToB36CharCode,
|
|
62
|
-
charToCharCode,
|
|
63
|
-
deserialize,
|
|
64
|
-
fromB36CharCodes,
|
|
65
|
-
fromCharCodes,
|
|
66
|
-
fromSerialized,
|
|
67
|
-
serialize,
|
|
68
|
-
toB36CharCodes,
|
|
69
|
-
toCharCodes
|
|
70
|
-
};
|