@design-edito/tools 0.4.5 → 0.4.11
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 -7
- package/agnostic/arrays/dedupe/index.test.js +24 -0
- package/agnostic/arrays/find-duplicates/index.js +34 -22
- package/agnostic/arrays/find-duplicates/index.test.js +31 -0
- package/agnostic/arrays/index.d.ts +2 -2
- package/agnostic/arrays/index.js +2 -2
- 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.d.ts +1 -1
- package/agnostic/arrays/make/index.js +11 -6
- package/agnostic/arrays/make/index.test.js +10 -0
- package/agnostic/arrays/random-pick/index.js +38 -22
- package/agnostic/arrays/random-pick/index.test.js +23 -0
- package/agnostic/arrays/shuffle/index.js +15 -11
- package/agnostic/arrays/shuffle/index.test.js +14 -0
- package/agnostic/booleans/is-falsy/index.js +24 -15
- package/agnostic/booleans/is-falsy/index.test.js +26 -0
- package/agnostic/colors/channels/index.js +139 -936
- package/agnostic/colors/channels/index.test.js +64 -0
- package/agnostic/colors/contrast/index.js +24 -643
- package/agnostic/colors/contrast/index.test.js +21 -0
- package/agnostic/colors/convert/index.js +811 -837
- package/agnostic/colors/convert/index.test.js +98 -0
- package/agnostic/colors/cssColorsMap.js +153 -0
- package/agnostic/colors/distance/index.js +66 -538
- package/agnostic/colors/distance/index.test.js +21 -0
- package/agnostic/colors/grayscale/index.js +95 -872
- package/agnostic/colors/grayscale/index.test.js +34 -0
- package/agnostic/colors/index.d.ts +4 -4
- package/agnostic/colors/index.js +4 -4
- package/agnostic/colors/invert/index.js +34 -719
- package/agnostic/colors/invert/index.test.js +31 -0
- package/agnostic/colors/lerp/index.js +75 -804
- package/agnostic/colors/lerp/index.test.js +55 -0
- package/agnostic/colors/luminance/index.js +17 -625
- package/agnostic/colors/luminance/index.test.js +30 -0
- package/agnostic/colors/palette/index.js +83 -917
- package/agnostic/colors/palette/index.test.js +35 -0
- package/agnostic/colors/rotate/index.js +35 -835
- package/agnostic/colors/rotate/index.test.js +45 -0
- package/agnostic/colors/tidy/index.js +79 -530
- package/agnostic/colors/tidy/index.test.js +45 -0
- package/agnostic/colors/typechecks/index.js +188 -250
- package/agnostic/colors/typechecks/index.test.js +113 -0
- package/agnostic/colors/types.js +1 -0
- package/agnostic/css/bem/index.js +134 -171
- package/agnostic/css/clss/index.js +64 -29
- package/agnostic/css/clss/index.test.js +60 -0
- package/agnostic/css/generate-nice-color/index.js +26 -71
- package/agnostic/css/generate-nice-color/index.test.js +8 -0
- package/agnostic/css/index.d.ts +2 -2
- package/agnostic/css/index.js +2 -2
- package/agnostic/css/is-valid-css-class-name/index.js +14 -8
- package/agnostic/css/is-valid-css-class-name/index.test.js +36 -0
- package/agnostic/css/scale/index.d.ts +46 -16
- package/agnostic/css/scale/index.js +70 -54
- package/agnostic/css/scale/index.test.js +88 -0
- package/agnostic/css/styles-set/index.js +151 -178
- package/agnostic/errors/index.d.ts +1 -1
- package/agnostic/errors/index.js +1 -1
- package/agnostic/errors/register/index.js +45 -49
- package/agnostic/errors/unknown-to-string/index.js +17 -10
- package/agnostic/errors/unknown-to-string/index.test.js +35 -0
- package/agnostic/html/get-node-ancestors/index.js +29 -29
- package/agnostic/html/get-node-ancestors/index.test.js +58 -0
- package/agnostic/html/get-position-inside-parent/index.js +13 -8
- package/agnostic/html/get-position-inside-parent/index.test.js +56 -0
- package/agnostic/html/hyper-json/cast/index.js +128 -2931
- package/agnostic/html/hyper-json/index.js +23 -2954
- package/agnostic/html/hyper-json/method/index.js +10 -14
- package/agnostic/html/hyper-json/serialize/index.js +88 -222
- package/agnostic/html/hyper-json/smart-tags/coalesced/add/index.js +14 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/addclass/index.js +27 -2937
- package/agnostic/html/hyper-json/smart-tags/coalesced/and/index.js +13 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/append/index.js +34 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/at/index.js +42 -2935
- package/agnostic/html/hyper-json/smart-tags/coalesced/call/index.js +47 -2937
- package/agnostic/html/hyper-json/smart-tags/coalesced/clone/index.js +10 -2939
- package/agnostic/html/hyper-json/smart-tags/coalesced/deleteproperties/index.js +45 -2936
- package/agnostic/html/hyper-json/smart-tags/coalesced/equals/index.js +22 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/getattribute/index.js +26 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/getproperties/index.js +19 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/getproperty/index.js +67 -2935
- package/agnostic/html/hyper-json/smart-tags/coalesced/hjparse/index.js +21 -2937
- package/agnostic/html/hyper-json/smart-tags/coalesced/hjstringify/index.js +89 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/if/index.js +20 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/index.d.ts +11 -11
- package/agnostic/html/hyper-json/smart-tags/coalesced/index.js +11 -11
- package/agnostic/html/hyper-json/smart-tags/coalesced/initialize/index.js +37 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/join/index.js +16 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/length/index.js +21 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/map/index.js +31 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/negate/index.js +10 -2939
- package/agnostic/html/hyper-json/smart-tags/coalesced/notrailing/index.js +33 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/or/index.js +13 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/pickrandom/index.js +17 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/populate/index.js +59 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/print/index.js +23 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/push/index.js +10 -2939
- package/agnostic/html/hyper-json/smart-tags/coalesced/pusheach/index.js +26 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/recordtoarray/index.js +10 -2939
- package/agnostic/html/hyper-json/smart-tags/coalesced/removeattribute/index.js +53 -2935
- package/agnostic/html/hyper-json/smart-tags/coalesced/removeclass/index.js +27 -2937
- package/agnostic/html/hyper-json/smart-tags/coalesced/renameproperty/index.js +31 -2937
- package/agnostic/html/hyper-json/smart-tags/coalesced/replace/index.js +55 -2940
- package/agnostic/html/hyper-json/smart-tags/coalesced/select/index.js +29 -2935
- package/agnostic/html/hyper-json/smart-tags/coalesced/set/index.js +29 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/setattribute/index.js +53 -2935
- package/agnostic/html/hyper-json/smart-tags/coalesced/setproperty/index.js +232 -2936
- package/agnostic/html/hyper-json/smart-tags/coalesced/sorton/index.js +89 -2936
- package/agnostic/html/hyper-json/smart-tags/coalesced/split/index.js +20 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/spread/index.js +23 -2939
- package/agnostic/html/hyper-json/smart-tags/coalesced/toarray/index.js +11 -2939
- package/agnostic/html/hyper-json/smart-tags/coalesced/toboolean/index.js +11 -2939
- package/agnostic/html/hyper-json/smart-tags/coalesced/toelement/index.js +17 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/toggleclass/index.js +27 -2937
- package/agnostic/html/hyper-json/smart-tags/coalesced/tonodelist/index.js +11 -2939
- package/agnostic/html/hyper-json/smart-tags/coalesced/tonull/index.js +10 -2939
- package/agnostic/html/hyper-json/smart-tags/coalesced/tonumber/index.js +11 -2939
- package/agnostic/html/hyper-json/smart-tags/coalesced/torecord/index.js +11 -2939
- package/agnostic/html/hyper-json/smart-tags/coalesced/toref/index.js +11 -2939
- package/agnostic/html/hyper-json/smart-tags/coalesced/tostring/index.js +11 -2939
- package/agnostic/html/hyper-json/smart-tags/coalesced/totext/index.js +11 -2939
- package/agnostic/html/hyper-json/smart-tags/coalesced/transformselected/index.js +84 -2938
- package/agnostic/html/hyper-json/smart-tags/coalesced/trim/index.js +14 -2938
- package/agnostic/html/hyper-json/smart-tags/index.js +28 -181
- package/agnostic/html/hyper-json/smart-tags/isolated/any/index.js +12 -195
- package/agnostic/html/hyper-json/smart-tags/isolated/array/index.js +12 -195
- package/agnostic/html/hyper-json/smart-tags/isolated/boolean/index.js +12 -2939
- package/agnostic/html/hyper-json/smart-tags/isolated/element/index.js +24 -2938
- package/agnostic/html/hyper-json/smart-tags/isolated/get/index.js +18 -2938
- package/agnostic/html/hyper-json/smart-tags/isolated/guess/index.js +56 -2937
- package/agnostic/html/hyper-json/smart-tags/isolated/index.d.ts +2 -2
- package/agnostic/html/hyper-json/smart-tags/isolated/index.js +2 -2
- package/agnostic/html/hyper-json/smart-tags/isolated/nodelist/index.js +18 -2938
- package/agnostic/html/hyper-json/smart-tags/isolated/null/index.js +9 -193
- package/agnostic/html/hyper-json/smart-tags/isolated/number/index.js +16 -2938
- package/agnostic/html/hyper-json/smart-tags/isolated/record/index.js +12 -2938
- package/agnostic/html/hyper-json/smart-tags/isolated/ref/index.js +40 -2935
- package/agnostic/html/hyper-json/smart-tags/isolated/string/index.js +16 -2938
- package/agnostic/html/hyper-json/smart-tags/isolated/text/index.js +18 -2938
- package/agnostic/html/hyper-json/transformer/index.js +112 -148
- package/agnostic/html/hyper-json/tree/index.js +411 -2928
- package/agnostic/html/hyper-json/types/index.js +27 -18
- package/agnostic/html/hyper-json/utils/index.js +497 -2921
- package/agnostic/html/index.d.ts +2 -2
- package/agnostic/html/index.js +2 -2
- package/agnostic/html/insert-node/index.js +27 -16
- package/agnostic/html/insert-node/index.test.js +73 -0
- package/agnostic/html/placeholders/index.js +26 -29
- package/agnostic/html/replace-in-element/index.js +31 -48
- package/agnostic/html/replace-in-element/index.test.js +80 -0
- package/agnostic/html/selector-to-element/index.js +53 -39
- package/agnostic/html/selector-to-element/index.test.js +69 -0
- package/agnostic/html/string-to-nodes/index.js +24 -25
- package/agnostic/html/string-to-nodes/index.test.js +54 -0
- package/agnostic/index.d.ts +4 -4
- package/agnostic/index.js +4 -4
- package/agnostic/misc/assert/index.js +60 -66
- package/agnostic/misc/cast/index.js +123 -57
- package/agnostic/misc/cast/index.test.js +134 -0
- package/agnostic/misc/connection/index.js +55 -36
- package/agnostic/misc/connection/index.test.js +143 -0
- package/agnostic/misc/crawler/index.js +68 -46
- package/agnostic/misc/crawler/index.test.js +56 -0
- package/agnostic/misc/crossenv/detect-runtime/index.js +41 -13
- package/agnostic/misc/crossenv/detect-runtime/index.test.js +24 -0
- package/agnostic/misc/crossenv/types.js +21 -14
- package/agnostic/misc/crossenv/window/index.js +45 -24
- package/agnostic/misc/crossenv/window/index.test.js +24 -0
- package/agnostic/misc/data-size/index.js +182 -294
- 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 +5 -5
- package/agnostic/misc/index.js +5 -5
- package/agnostic/misc/is-constructor-function/index.js +12 -6
- package/agnostic/misc/is-constructor-function/index.test.js +36 -0
- package/agnostic/misc/is-nullish/index.js +24 -11
- package/agnostic/misc/is-nullish/index.test.js +44 -0
- package/agnostic/misc/logs/index.d.ts +1 -1
- package/agnostic/misc/logs/index.js +1 -1
- package/agnostic/misc/logs/logger/index.js +115 -140
- package/agnostic/misc/logs/make-text-block/index.js +13 -13
- package/agnostic/misc/logs/styles/index.js +29 -48
- package/agnostic/misc/lorem-ipsum/index.js +51 -201
- package/agnostic/misc/lorem-ipsum/index.test.js +49 -0
- package/agnostic/misc/normalize-extension/index.js +99 -88
- package/agnostic/misc/normalize-extension/index.test.js +40 -0
- package/agnostic/misc/outcome/index.js +20 -14
- package/agnostic/misc/outcome/index.test.js +40 -0
- package/agnostic/numbers/absolute-modulo/index.js +9 -6
- package/agnostic/numbers/absolute-modulo/index.test.js +23 -0
- package/agnostic/numbers/approximate-rational/index.js +86 -69
- package/agnostic/numbers/approximate-rational/index.test.js +90 -0
- package/agnostic/numbers/clamp/index.js +12 -8
- package/agnostic/numbers/clamp/index.test.js +24 -0
- package/agnostic/numbers/geometric-progressions/index.js +25 -16
- package/agnostic/numbers/geometric-progressions/index.test.js +45 -0
- package/agnostic/numbers/index.d.ts +2 -2
- package/agnostic/numbers/index.js +2 -2
- package/agnostic/numbers/interpolate/index.js +25 -10
- package/agnostic/numbers/interpolate/index.test.js +40 -0
- package/agnostic/numbers/round/index.js +30 -15
- package/agnostic/numbers/round/index.test.js +56 -0
- package/agnostic/objects/deep-get-property/index.js +30 -27
- package/agnostic/objects/deep-get-property/index.test.js +59 -0
- package/agnostic/objects/enums/is-in-enum/index.js +17 -11
- package/agnostic/objects/enums/is-in-enum/index.test.js +100 -0
- package/agnostic/objects/flatten-getters/index.js +15 -14
- package/agnostic/objects/flatten-getters/index.test.js +78 -0
- package/agnostic/objects/index.d.ts +4 -4
- package/agnostic/objects/index.js +4 -4
- package/agnostic/objects/is-object/index.js +16 -9
- package/agnostic/objects/is-object/index.test.js +60 -0
- package/agnostic/objects/is-record/index.js +12 -7
- package/agnostic/objects/is-record/index.test.js +48 -0
- package/agnostic/objects/record-format/index.js +18 -12
- package/agnostic/objects/record-format/index.test.js +92 -0
- package/agnostic/objects/record-map/index.js +16 -11
- package/agnostic/objects/record-map/index.test.js +56 -0
- package/agnostic/objects/sort-keys/index.js +15 -11
- package/agnostic/objects/sort-keys/index.test.js +37 -0
- package/agnostic/objects/validation/index.js +21 -8
- package/agnostic/objects/validation/index.test.js +72 -0
- package/agnostic/optim/memoize/index.js +24 -16
- package/agnostic/optim/memoize/index.test.js +30 -0
- package/agnostic/optim/throttle-debounce/index.js +120 -102
- 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 +8 -10
- 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 +17 -14
- package/agnostic/random/random/index.test.js +73 -0
- package/agnostic/random/uuid/index.js +28 -20
- package/agnostic/random/uuid/index.test.js +45 -0
- package/agnostic/regexps/index.js +126 -84
- package/agnostic/regexps/index.test.js +108 -0
- package/agnostic/sanitization/file-name/index.js +24 -8
- package/agnostic/sanitization/file-name/index.test.js +23 -0
- package/agnostic/sanitization/html/index.js +172 -122
- package/agnostic/sanitization/index.d.ts +1 -1
- package/agnostic/sanitization/index.js +1 -1
- package/agnostic/sanitization/path/index.js +23 -15
- package/agnostic/sanitization/path/index.test.js +18 -0
- package/agnostic/sanitization/types.js +1 -0
- package/agnostic/sanitization/user-input/index.js +36 -24
- package/agnostic/sanitization/user-input/index.test.js +31 -0
- package/agnostic/strings/char-codes/index.js +123 -55
- package/agnostic/strings/index.d.ts +1 -1
- package/agnostic/strings/index.js +1 -1
- package/agnostic/strings/matches/index.js +35 -16
- package/agnostic/strings/normalize-indent/index.js +34 -16
- package/agnostic/strings/parse-table/index.js +153 -86
- package/agnostic/strings/replace-all/index.js +36 -15
- package/agnostic/strings/to-alphanum/index.js +23 -8
- package/agnostic/strings/trim/index.js +22 -9
- package/agnostic/time/dates/format-date/index.js +140 -72
- package/agnostic/time/duration/index.js +106 -140
- package/agnostic/time/timeout/index.js +24 -16
- package/agnostic/time/transitions/index.js +200 -158
- package/agnostic/time/wait/index.js +10 -8
- package/agnostic/typescript/types.js +1 -0
- package/components/BeforeAfter/index.controlled.js +95 -0
- package/components/BeforeAfter/index.js +54 -189
- package/components/BeforeAfter/utils.js +9 -0
- package/components/Disclaimer/index.js +50 -110
- package/components/Drawer/index.js +81 -196
- package/components/EventListener/index.js +29 -80
- package/components/Gallery/index.js +146 -221
- package/components/Gallery/utils.js +12 -0
- package/components/Image/index.js +66 -293
- package/components/IntersectionObserver/index.js +62 -110
- package/components/Overlayer/index.js +59 -103
- package/components/Paginator/index.js +124 -155
- package/components/ResizeObserver/index.js +66 -119
- package/components/ResizeObserver/style.module.css +0 -0
- package/components/Scrllgngn/index.js +171 -468
- package/components/ScrollListener/index.js +97 -276
- package/components/ScrollListener/utils.js +51 -0
- package/components/Sequencer/index.controlled.js +67 -0
- package/components/Sequencer/index.js +105 -262
- package/components/ShadowRoot/index.js +42 -96
- package/components/Subtitles/index.js +107 -244
- package/components/Subtitles/types.js +1 -0
- package/components/Subtitles/utils.js +102 -0
- package/components/Theatre/index.js +88 -136
- package/components/UIModule/index.js +156 -199
- package/components/Video/index.js +292 -857
- 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 +4 -4
- package/components/index.js +4 -4
- package/components/public-classnames.js +18 -0
- package/components/utils/index.js +11 -11
- package/components/utils/types.js +1 -0
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/node/@aws-s3/index.test.js +6 -0
- package/node/@aws-s3/storage/directory/copy-dir/index.js +66 -72
- 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 +32 -42
- package/node/@aws-s3/storage/directory/move-dir/index.js +68 -86
- package/node/@aws-s3/storage/directory/remove-dir/index.js +56 -67
- package/node/@aws-s3/storage/file/copy/index.js +41 -53
- package/node/@aws-s3/storage/file/download/index.js +29 -40
- package/node/@aws-s3/storage/file/exists/index.js +35 -43
- 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 +57 -63
- package/node/@aws-s3/storage/file/remove/index.js +35 -43
- package/node/@aws-s3/storage/file/stat/index.js +33 -47
- package/node/@aws-s3/storage/file/upload/index.js +52 -63
- package/node/@design-edito/index.js +1 -0
- package/node/@express/@multer/index.js +61 -55
- package/node/@google-cloud/storage/bucket/get-metadata/index.js +25 -29
- package/node/@google-cloud/storage/directory/copy-dir/index.js +35 -41
- package/node/@google-cloud/storage/directory/index.d.ts +1 -1
- package/node/@google-cloud/storage/directory/index.js +1 -1
- package/node/@google-cloud/storage/directory/list/index.js +28 -35
- package/node/@google-cloud/storage/directory/move-dir/index.js +43 -42
- package/node/@google-cloud/storage/directory/remove-dir/index.js +34 -38
- package/node/@google-cloud/storage/file/copy/index.js +35 -40
- package/node/@google-cloud/storage/file/download/index.js +27 -34
- package/node/@google-cloud/storage/file/exists/index.js +25 -31
- package/node/@google-cloud/storage/file/generate-signed-url/index.js +33 -35
- package/node/@google-cloud/storage/file/get-metadata/index.js +28 -31
- package/node/@google-cloud/storage/file/get-permissions/index.js +25 -31
- package/node/@google-cloud/storage/file/index.d.ts +3 -3
- package/node/@google-cloud/storage/file/index.js +3 -3
- package/node/@google-cloud/storage/file/move/index.js +38 -42
- package/node/@google-cloud/storage/file/remove/index.js +34 -35
- package/node/@google-cloud/storage/file/revoke-signed-urls/index.js +32 -95
- package/node/@google-cloud/storage/file/stat/index.js +34 -38
- package/node/@google-cloud/storage/file/update-metadata/index.js +30 -31
- package/node/@google-cloud/storage/file/upload/index.js +44 -46
- package/node/@google-cloud/storage/index.d.ts +1 -1
- package/node/@google-cloud/storage/index.js +1 -1
- package/node/cloud-storage/clients/index.js +35 -15
- package/node/cloud-storage/operations/copy-dir/index.js +30 -203
- package/node/cloud-storage/operations/copy-file/index.js +30 -152
- package/node/cloud-storage/operations/download-file/index.js +30 -103
- package/node/cloud-storage/operations/exists-file/index.js +30 -103
- package/node/cloud-storage/operations/index.d.ts +2 -2
- package/node/cloud-storage/operations/index.js +2 -2
- package/node/cloud-storage/operations/list-dir/index.js +29 -98
- package/node/cloud-storage/operations/move-dir/index.js +30 -169
- package/node/cloud-storage/operations/move-file/index.js +30 -157
- package/node/cloud-storage/operations/remove-dir/index.js +29 -159
- package/node/cloud-storage/operations/remove-file/index.js +29 -121
- package/node/cloud-storage/operations/stat-file/index.js +29 -124
- package/node/cloud-storage/operations/upload-file/index.js +30 -162
- package/node/encryption/@aes-256-gcm/buffer/index.js +31 -72
- package/node/encryption/@aes-256-gcm/uint8-array/index.js +55 -55
- package/node/encryption/key/index.js +19 -12
- package/node/files/index.d.ts +1 -1
- package/node/files/index.js +1 -1
- package/node/files/is-in-directory/index.js +11 -8
- package/node/files/read-write/index.js +11 -15
- package/node/files/subpaths/index.js +156 -121
- package/node/ftps/directory/copy-dir/index.js +55 -62
- package/node/ftps/directory/list/index.js +24 -29
- package/node/ftps/directory/move-dir/index.js +38 -38
- package/node/ftps/directory/remove-dir/index.js +39 -42
- package/node/ftps/file/copy/index.js +42 -47
- package/node/ftps/file/download/index.js +29 -34
- package/node/ftps/file/exists/index.js +38 -36
- package/node/ftps/file/index.d.ts +2 -2
- package/node/ftps/file/index.js +2 -2
- package/node/ftps/file/move/index.js +46 -44
- package/node/ftps/file/remove/index.js +36 -39
- package/node/ftps/file/stat/index.js +30 -38
- package/node/ftps/file/upload/index.js +40 -44
- package/node/images/create/index.js +10 -562
- package/node/images/format/index.js +264 -815
- package/node/images/metadata/index.js +10 -571
- package/node/images/transform/index.js +169 -1022
- package/node/images/transform/operations/blur/index.js +11 -24
- package/node/images/transform/operations/brighten/index.js +11 -24
- package/node/images/transform/operations/extend/index.js +25 -589
- package/node/images/transform/operations/extract/index.js +15 -28
- package/node/images/transform/operations/flatten/index.js +20 -584
- package/node/images/transform/operations/flip/index.js +2 -6
- package/node/images/transform/operations/flop/index.js +2 -6
- package/node/images/transform/operations/hue/index.js +13 -26
- package/node/images/transform/operations/index.d.ts +3 -3
- package/node/images/transform/operations/index.js +3 -3
- package/node/images/transform/operations/level/index.js +14 -30
- package/node/images/transform/operations/lighten/index.js +13 -26
- package/node/images/transform/operations/normalize/index.js +14 -27
- package/node/images/transform/operations/overlay/index.js +89 -673
- package/node/images/transform/operations/resize/index.js +46 -610
- package/node/images/transform/operations/rotate/index.js +20 -584
- package/node/images/transform/operations/saturate/index.js +14 -27
- package/node/images/types.js +34 -31
- package/node/images/utils/index.js +84 -568
- package/node/index.d.ts +2 -2
- package/node/index.js +2 -2
- package/node/process/on-exit/index.js +45 -26
- package/node/process/prompt-continue/index.js +29 -14
- package/node/process/spawner/index.js +104 -134
- package/node/sftp/directory/copy-dir/index.js +52 -60
- package/node/sftp/directory/index.d.ts +1 -1
- package/node/sftp/directory/index.js +1 -1
- package/node/sftp/directory/list/index.js +22 -29
- package/node/sftp/directory/move-dir/index.js +35 -35
- package/node/sftp/directory/remove-dir/index.js +39 -42
- package/node/sftp/file/copy/index.js +37 -45
- package/node/sftp/file/download/index.js +26 -32
- package/node/sftp/file/exists/index.js +29 -29
- package/node/sftp/file/index.d.ts +2 -2
- package/node/sftp/file/index.js +2 -2
- package/node/sftp/file/move/index.js +39 -38
- package/node/sftp/file/remove/index.js +31 -34
- package/node/sftp/file/stat/index.js +26 -37
- package/node/sftp/file/upload/index.js +34 -38
- package/package.json +1 -1
package/TODO.md
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# To do
|
|
2
|
+
|
|
3
|
+
# -
|
|
4
|
+
|
|
5
|
+
Après le dev :
|
|
6
|
+
- envoyer le code à GPT + Claude, leur demander:
|
|
7
|
+
1/ s'ils comprennent le fichier, on veut juste s'assurer qu'on est raccord avec lui à ce stade
|
|
8
|
+
2/ en gardant en tête de garder le périmètre fonctionnel intact, sans chercher à faire plus ce qu'il y a actuellement, de relever les nommages ou formes de code qui pourraient être améliorées pour que le fichier soit prêt à intégrer une librairie de composants solide, durable dans le temps et facile à maintenir. Préciser qu'il faut respecter les règles de standardjs pour le lint
|
|
9
|
+
- essayer de build, régler les erreurs du linter
|
|
10
|
+
- après ça, fournir à GPT/Claude un exemple de fichier test d'un autre composant, Drawer par ex, + le code actuel de Subtitles, et lui demander de garder le style/approche fourni, et générer les tests pertinents pour le composant Subtitles (utiliser srtFileContents et pas src, ça va être une galère). Lui rappeler que les tests sont évalués par nodejs, donc pas trop se reposer sur des choses qui se passent dans un browser. Pas trop besoin de checker le contenu du fichier de test, moi je prends ce qu'il me donne, je lance le test et espère que ça passe tout, si ça passe pas tu peux lui donner le contenu de l'erreur et voir si il arrive à régler le truc tout seul, si ça veut vraiment pas, commente l'intégralité du test qui bloque, tant pis.
|
|
11
|
+
- ensuite une fois que c'est bon, fournir à GPT/Claude un exemple de JSDOC issu d'un autre composant, Gallery par ex, + le code actuel de Subtitles, et lui demander de générer le JSDOC pour tous les exported members de Subtitles (Props et Subtitles à priori). Juste le JSDOC, pas répéter le code, parfois en générant tout il glisse des erreurs en répétant le code.
|
|
12
|
+
- re build, lint et corrections éventuelles des erreurs du linter
|
|
13
|
+
- pull add commit push 🎉
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# Composants
|
|
17
|
+
|
|
18
|
+
## Composant Vidéo
|
|
19
|
+
|
|
20
|
+
/components/Video
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### D'abord, on va reprendre new-app/src/components/VideoPlayer/MutedVideo.tsx
|
|
24
|
+
Ce composant permet un workaround d'une petite bizzarerie de react avec l'attribut muted.
|
|
25
|
+
Ça va être notre composant vidéo de base, pour ne pas manipuler directement l'élément html vidéo.
|
|
26
|
+
|
|
27
|
+
### Ensuite, un composant tout simple :
|
|
28
|
+
|
|
29
|
+
// "on" evt listeners
|
|
30
|
+
// "state/props"
|
|
31
|
+
// "int/obs triggers"
|
|
32
|
+
// disclaimer
|
|
33
|
+
// subs
|
|
34
|
+
|
|
35
|
+
- une vidéo :
|
|
36
|
+
```tsx
|
|
37
|
+
type SourceData = {
|
|
38
|
+
src?: string
|
|
39
|
+
type?: string
|
|
40
|
+
}
|
|
41
|
+
type TrackData = {
|
|
42
|
+
src?: string
|
|
43
|
+
kind?: 'subtitles' | 'captions' | 'descriptions' | 'chapters' | 'metadata'
|
|
44
|
+
srclang?: string
|
|
45
|
+
label?: string
|
|
46
|
+
default?: boolean
|
|
47
|
+
}
|
|
48
|
+
type Props = {
|
|
49
|
+
sources?: string | string[] | SourceData[] // liste des éléments <source> dans la vidéo (ignore si pas src dans SourceData)
|
|
50
|
+
tracks?: string | string[] | TrackData[] // liste des éléments <tracks> dans la vidéo (ignore si pas src dans TrackData)
|
|
51
|
+
children?: JSX.Element // react children habituel, vient se coller sous les <source> et <tracks>
|
|
52
|
+
} & VideoHTMLAttributes<HTMLVideoElement>
|
|
53
|
+
|
|
54
|
+
const {
|
|
55
|
+
sources,
|
|
56
|
+
tracks,
|
|
57
|
+
children,
|
|
58
|
+
...intrinsicVideoAttributes
|
|
59
|
+
} = props
|
|
60
|
+
```
|
|
61
|
+
- un bouton play
|
|
62
|
+
- sur lm-video :
|
|
63
|
+
- data-play-on
|
|
64
|
+
- lm-video--play-on
|
|
65
|
+
- un bouton pause
|
|
66
|
+
- sur lm-video :
|
|
67
|
+
- data-play-off
|
|
68
|
+
- lm-video--play-off
|
|
69
|
+
- un span "temps écoulé"
|
|
70
|
+
- sur lm-video :
|
|
71
|
+
- data-elapsed-time-percent (0-1)
|
|
72
|
+
- data-elapsed-time-ms
|
|
73
|
+
- data-elapsed-time-readable ((hh:)mm:ss)
|
|
74
|
+
- un span "temps total"
|
|
75
|
+
- sur lm-video :
|
|
76
|
+
- data-total-time-ms
|
|
77
|
+
- data-total-time-readable
|
|
78
|
+
- une div cliquable en guise de timeline (pas de curseur)
|
|
79
|
+
- un bouton sound on
|
|
80
|
+
- sur lm-video:
|
|
81
|
+
- data-sound-on
|
|
82
|
+
- lm-video--sound-on
|
|
83
|
+
- un bouton sound off
|
|
84
|
+
- sur lm-video:
|
|
85
|
+
- data-sound-off
|
|
86
|
+
- lm-video--sound-off
|
|
87
|
+
- un input range (0 - 100, step=1) pour piloter le son
|
|
88
|
+
- sur lm-video:
|
|
89
|
+
- data-sound-volume-percent (0-1) (ne se met pas à 0 si sound off, c'est deux données séparées)
|
|
90
|
+
- data-sound-volume-readable (0-100)
|
|
91
|
+
- un span "volume (0-100)"
|
|
92
|
+
- un bouton full screen
|
|
93
|
+
- sur lm-video:
|
|
94
|
+
- data-fullscreen-on / data-full-screen-off
|
|
95
|
+
- lm-video--fullscreen-on / lm-video--fullscreen-off
|
|
96
|
+
- un bouton download
|
|
97
|
+
- un input range playback-speed (0.25-4 step=0.25)
|
|
98
|
+
- sur lm-video:
|
|
99
|
+
- data-playback-speed (.25-4)
|
|
100
|
+
- un span "playback speed (.25-4)"
|
|
101
|
+
|
|
102
|
+
### Suite [WIP]
|
|
103
|
+
|
|
104
|
+
[ ] Click sur timeline ne semble pas marcher ?
|
|
105
|
+
[ ]
|
|
106
|
+
|
|
107
|
+
- Gérer la partie "controlled behavior" tout d'un coup
|
|
108
|
+
[ ] Idée : quand la vidéo est en mode controlled,
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
## Composant Subtitles
|
|
116
|
+
|
|
117
|
+
lm-tools/src/components/Subtitles/index.tsx
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
<Subtitles
|
|
121
|
+
src='srt.file.url'
|
|
122
|
+
srtFileContent='Contenu srt brut, si présent la prop src est ignorée.'
|
|
123
|
+
subsGroups={[3, 4, 5]}
|
|
124
|
+
timecodeMs={10000}>
|
|
125
|
+
</Subtitles>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
```html
|
|
129
|
+
<div class="dsed-subtitles">
|
|
130
|
+
<!-- Groupe passé (donc que sub prev dedans) -->
|
|
131
|
+
<div
|
|
132
|
+
class="dsed-subtitles__group dsed-subtitles__group--prev"
|
|
133
|
+
data-start-sub-pos="0"
|
|
134
|
+
data-end-sub-pos="1">
|
|
135
|
+
<span class="dsed-subtitles__sub dsed-subtitles__sub--prev" data-sub-pos="0">
|
|
136
|
+
Some sub
|
|
137
|
+
</span>
|
|
138
|
+
</div>
|
|
139
|
+
<!-- Groupe courant (mix de sub prev, curr et next) -->
|
|
140
|
+
<div
|
|
141
|
+
class="dsed-subtitles__group dsed-subtitles__group--curr"
|
|
142
|
+
data-start-timecode="00:02:16,612"
|
|
143
|
+
data-end-timecode="00:02:16,612"
|
|
144
|
+
data-start-time-ms="34754382"
|
|
145
|
+
data-end-time-ms="34754382"
|
|
146
|
+
data-start-sub-pos="0"
|
|
147
|
+
data-end-sub-pos="1">
|
|
148
|
+
<span
|
|
149
|
+
class="dsed-subtitles__sub dsed-subtitles__sub--curr"
|
|
150
|
+
data-start-timecode="00:02:16,612"
|
|
151
|
+
data-end-timecode="00:02:16,612"
|
|
152
|
+
data-start-time-ms="34754382"
|
|
153
|
+
data-end-time-ms="34754382">
|
|
154
|
+
Some sub
|
|
155
|
+
</span>
|
|
156
|
+
</div>
|
|
157
|
+
<!-- Groupe à venir -->
|
|
158
|
+
<div
|
|
159
|
+
class="dsed-subtitles__group dsed-subtitles__group--prev"
|
|
160
|
+
data-start-timecode="00:02:16,612"
|
|
161
|
+
data-end-timecode="00:02:16,612"
|
|
162
|
+
data-start-time-ms="34754382"
|
|
163
|
+
data-end-time-ms="34754382"
|
|
164
|
+
data-start-sub-pos="0"
|
|
165
|
+
data-end-sub-pos="1">
|
|
166
|
+
<span
|
|
167
|
+
class="dsed-subtitles__sub dsed-subtitles__sub--prev"
|
|
168
|
+
data-start-timecode="00:02:16,612"
|
|
169
|
+
data-end-timecode="00:02:16,612"
|
|
170
|
+
data-start-time-ms="34754382"
|
|
171
|
+
data-end-time-ms="34754382">
|
|
172
|
+
Some sub
|
|
173
|
+
</span>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
# CLI Utils
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
## Get diff from commit hash
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
export type GetDiffOptions = {
|
|
188
|
+
cwd?: string
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Pas certain de Array<string> mais c'est peut-être suffisant,
|
|
192
|
+
// l'idée c'est d'avoir une liste descriptive des changements successifs sur un fichier (genre le contenu brut de git diff)
|
|
193
|
+
export type Diff = Record<string, Array<string>>
|
|
194
|
+
|
|
195
|
+
// Ou pas async si pas nécessaire
|
|
196
|
+
export async function getDiffFrom (
|
|
197
|
+
commitHash: string,
|
|
198
|
+
options: GetDiffOptions = {}
|
|
199
|
+
): Promise<Diff> {
|
|
200
|
+
const { cwd } = options
|
|
201
|
+
return {}
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Generate commit message from diff
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
export type GenerateDiffDescriptionOptions = {
|
|
209
|
+
customPromptOrSomething?: string // juste une idée comme ça, sais pas si c'est pertinent
|
|
210
|
+
// Ptet c'est là qu'il faut dire "je veux plutôt un changelog, ou plutôt un message de commit"
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export async function generateDiffDescription (
|
|
214
|
+
diff: Diff,
|
|
215
|
+
options: GenerateDiffDescriptionOptions = {}): Promise<string> {
|
|
216
|
+
return ''
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
# Tests & JSDOC
|
|
224
|
+
|
|
225
|
+
- [ ] Tests manquants (garder la forme describe('funcName') { it('does something') {} })
|
|
226
|
+
- [ ] agnostic/html/hyper-json -> nécessaire mais trop compliqué/long
|
|
227
|
+
- [ ] agnostic/html/placeholders -> pas nécessaire
|
|
228
|
+
- [ ] agnostic/misc/logs/make-text-block -> Manque JSDOC aussi
|
|
229
|
+
- [ ] agnostic/strings/char-codes
|
|
230
|
+
- [ ] agnostic/strings/matches
|
|
231
|
+
- [ ] agnostic/strings/parse-table
|
|
232
|
+
- [ ] agnostic/strings/to-alphanum
|
|
233
|
+
- [ ] agnostic/strings/trim
|
|
234
|
+
- [ ] agnostic/time/dates/format-date
|
|
235
|
+
- [ ] agnostic/time/duration
|
|
236
|
+
- [ ] agnostic/time/timeout
|
|
237
|
+
- [ ] agnostic/time/transitions
|
|
238
|
+
- [ ] agnostic/time/wait
|
|
239
|
+
- [ ] node/@aws-s3 - oui mais comment (valable aussi pour gcs, ftps & sftp) ?
|
|
240
|
+
- [ ] node/@design-edito - vide
|
|
241
|
+
- [ ] node/@express/@multer
|
|
242
|
+
- [ ] node/@google-cloud
|
|
243
|
+
- [ ] node/cloud-storage
|
|
244
|
+
- [ ] node/encryption
|
|
245
|
+
- [ ] node/files
|
|
246
|
+
- [ ] node/ftps
|
|
247
|
+
- [ ] node/images
|
|
248
|
+
- [ ] node/process
|
|
249
|
+
- [ ] node/sftp
|
|
250
|
+
|
|
251
|
+
- Pas utile
|
|
252
|
+
- [ ] agnostic/css/bem -> DEPRECATED
|
|
253
|
+
- [ ] agnostic/css/styles-set -> DEPRECATED
|
|
254
|
+
- [ ] agnostic/errors/register -> pas nécessaire
|
|
255
|
+
- [ ] agnostic/html/sanitization/html -> DEPRECATED
|
|
256
|
+
- [ ] agnostic/misc/assert -> DEPRECATED
|
|
257
|
+
- [ ] agnostic/misc/logs/logger -> presque DEPRECATED
|
|
258
|
+
- [ ] agnostic/misc/logs/styles -> pas nécessaire tout de suite
|
|
259
|
+
- [ ] agnostic/strings/normalize-indent -> pas nécessaire tout de suite, fonction à repenser
|
|
260
|
+
- [ ] agnostic/strings/replace-all -> DEPRECATED
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
# Misc
|
|
265
|
+
|
|
266
|
+
- [ ] Repenser agnostic/optim/throttle-debounce ?
|
|
267
|
+
- [ ] Repenser agnostic/strings/normalize-indent ?
|
|
268
|
+
- [ ] Get rid of namespaces in hyper-json ?
|
|
269
|
+
- [ ] agnostic/misc/logs/styles, se repencher dessus, viser à substituer totalement chalk (styles génériques, bold, red, bgBlue, etc...) + continuer à exporter des "styles nommés" comme actuellement
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Returns a copy of the input array, with stripped duplicates
|
|
3
|
+
*
|
|
4
|
+
* @param arr - The array to search for duplicates.
|
|
5
|
+
* @returns The deduped array
|
|
6
|
+
*/
|
|
7
|
+
export function dedupe(arr) {
|
|
8
|
+
const deduped = Array.from(new Set(arr));
|
|
9
|
+
return deduped;
|
|
5
10
|
}
|
|
6
|
-
export {
|
|
7
|
-
dedupe
|
|
8
|
-
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { dedupe } from './index.js';
|
|
3
|
+
describe('dedupe', () => {
|
|
4
|
+
it('preserves arrays without duplicates', () => {
|
|
5
|
+
const result = dedupe([1, 2, 3]);
|
|
6
|
+
expect(result).toHaveLength(3);
|
|
7
|
+
expect(result).toContain(1);
|
|
8
|
+
expect(result).toContain(2);
|
|
9
|
+
expect(result).toContain(3);
|
|
10
|
+
});
|
|
11
|
+
it('removes duplicates', () => {
|
|
12
|
+
const dupObj = { b: 1 };
|
|
13
|
+
const result = dedupe([
|
|
14
|
+
1, 1, 2,
|
|
15
|
+
'a', 'a', 'b',
|
|
16
|
+
true, true, false,
|
|
17
|
+
null, null,
|
|
18
|
+
undefined, undefined,
|
|
19
|
+
{ a: 1 }, { a: 1 },
|
|
20
|
+
dupObj, dupObj
|
|
21
|
+
]);
|
|
22
|
+
expect(JSON.stringify(result)).toEqual('[1,2,"a","b",true,false,null,null,{"a":1},{"a":1},{"b":1}]');
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -1,24 +1,36 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
// [WIP] could provide an equality check optional function for checking mor complex objects
|
|
2
|
+
/**
|
|
3
|
+
* Finds duplicate elements in an array.
|
|
4
|
+
*
|
|
5
|
+
* @param arr - The array to search for duplicates.
|
|
6
|
+
* @param [stopAtFirst=false] - If `true`, returns immediately after finding the first duplicate.
|
|
7
|
+
* @returns An array of duplicate elements found in the input array.
|
|
8
|
+
*/
|
|
9
|
+
export function findDuplicates(arr, stopAtFirst = false) {
|
|
10
|
+
const seen = new Set();
|
|
11
|
+
const duplicates = new Set();
|
|
12
|
+
for (const item of arr) {
|
|
13
|
+
if (seen.has(item) && stopAtFirst)
|
|
14
|
+
return [item];
|
|
15
|
+
if (seen.has(item))
|
|
16
|
+
duplicates.add(item);
|
|
17
|
+
seen.add(item);
|
|
18
|
+
}
|
|
19
|
+
return Array.from(duplicates);
|
|
11
20
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Finds the positions of duplicate elements in an array.
|
|
23
|
+
*
|
|
24
|
+
* @param arr - The array to search for duplicates positions.
|
|
25
|
+
* @returns An array of the positions of duplicate elements found in the input array.
|
|
26
|
+
*/
|
|
27
|
+
export function findDuplicatesPositions(arr) {
|
|
28
|
+
const seen = new Set();
|
|
29
|
+
const duplicatesPos = [];
|
|
30
|
+
arr.forEach((item, pos) => {
|
|
31
|
+
if (seen.has(item))
|
|
32
|
+
return duplicatesPos.push(pos);
|
|
33
|
+
seen.add(item);
|
|
34
|
+
});
|
|
35
|
+
return duplicatesPos;
|
|
20
36
|
}
|
|
21
|
-
export {
|
|
22
|
-
findDuplicates,
|
|
23
|
-
findDuplicatesPositions
|
|
24
|
-
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { findDuplicates, findDuplicatesPositions } from './index.js';
|
|
3
|
+
describe('find-duplicates', () => {
|
|
4
|
+
it('finds no duplicates when there are none', () => {
|
|
5
|
+
const result = findDuplicates([1, 2, 3]);
|
|
6
|
+
expect(result).toHaveLength(0);
|
|
7
|
+
});
|
|
8
|
+
it('finds duplicates and stops at first when asked', () => {
|
|
9
|
+
const result = findDuplicates([1, 1, 2, 2], true);
|
|
10
|
+
expect(result).toHaveLength(1);
|
|
11
|
+
expect(result).toContain(1);
|
|
12
|
+
});
|
|
13
|
+
it('finds all duplicates otherwise', () => {
|
|
14
|
+
const result = findDuplicates([1, 1, 2, 2]);
|
|
15
|
+
expect(result).toHaveLength(2);
|
|
16
|
+
expect(result).toContain(1);
|
|
17
|
+
expect(result).toContain(2);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
describe('find-duplicates-positions', () => {
|
|
21
|
+
it('finds no duplicates positions when there are no duplicates', () => {
|
|
22
|
+
const result = findDuplicatesPositions([1, 2, 3]);
|
|
23
|
+
expect(result).toHaveLength(0);
|
|
24
|
+
});
|
|
25
|
+
it('finds all duplicates positions', () => {
|
|
26
|
+
const result = findDuplicatesPositions([1, 1, 2, 2]);
|
|
27
|
+
expect(result).toHaveLength(2);
|
|
28
|
+
expect(result).toContain(1);
|
|
29
|
+
expect(result).toContain(3);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * as dedupe from './dedupe/index.js'
|
|
2
|
+
export * as findDuplicates from './find-duplicates/index.js'
|
|
2
3
|
export * as make from './make/index.js'
|
|
4
|
+
export * as isArrayOf from './is-array-of/index.js'
|
|
3
5
|
export * as randomPick from './random-pick/index.js'
|
|
4
6
|
export * as shuffle from './shuffle/index.js'
|
|
5
|
-
export * as findDuplicates from './find-duplicates/index.js'
|
|
6
|
-
export * as isArrayOf from './is-array-of/index.js'
|
package/agnostic/arrays/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * as dedupe from './dedupe/index.js'
|
|
2
|
+
export * as findDuplicates from './find-duplicates/index.js'
|
|
2
3
|
export * as make from './make/index.js'
|
|
4
|
+
export * as isArrayOf from './is-array-of/index.js'
|
|
3
5
|
export * as randomPick from './random-pick/index.js'
|
|
4
6
|
export * as shuffle from './shuffle/index.js'
|
|
5
|
-
export * as findDuplicates from './find-duplicates/index.js'
|
|
6
|
-
export * as isArrayOf from './is-array-of/index.js'
|
|
@@ -1,27 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { isConstructorFunction } from '../../misc/is-constructor-function/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Type guard to check if an input is an array and optionally if all elements match a type.
|
|
4
|
+
*
|
|
5
|
+
* If no type checkers are provided, only checks if the input is an array.
|
|
6
|
+
* Supports constructor functions (e.g., `Number`, `String`, `Boolean`, custom classes)
|
|
7
|
+
* and custom type guard functions.
|
|
8
|
+
*/
|
|
9
|
+
export function isArrayOf(input, _types) {
|
|
10
|
+
if (!Array.isArray(input))
|
|
11
|
+
return false;
|
|
12
|
+
if (_types === undefined)
|
|
13
|
+
return true;
|
|
14
|
+
const types = Array.isArray(_types) ? _types : [_types];
|
|
15
|
+
const primitiveTypeMap = new Map([
|
|
16
|
+
[Number, 'number'],
|
|
17
|
+
[String, 'string'],
|
|
18
|
+
[Boolean, 'boolean']
|
|
19
|
+
]);
|
|
20
|
+
return input.every(entry => types.some(typeChecker => {
|
|
21
|
+
if (!isConstructorFunction(typeChecker))
|
|
22
|
+
return typeChecker(entry);
|
|
23
|
+
const primitiveType = primitiveTypeMap.get(typeChecker);
|
|
24
|
+
// eslint-disable-next-line valid-typeof
|
|
25
|
+
if (primitiveType !== undefined)
|
|
26
|
+
return typeof entry === primitiveType;
|
|
27
|
+
return entry instanceof typeChecker;
|
|
28
|
+
}));
|
|
4
29
|
}
|
|
5
|
-
|
|
6
|
-
// src/agnostic/arrays/is-array-of/index.ts
|
|
7
|
-
function isArrayOf(input, _types) {
|
|
8
|
-
if (!Array.isArray(input)) return false;
|
|
9
|
-
if (_types === void 0) return true;
|
|
10
|
-
const types = Array.isArray(_types) ? _types : [_types];
|
|
11
|
-
const primitiveTypeMap = /* @__PURE__ */ new Map([
|
|
12
|
-
[Number, "number"],
|
|
13
|
-
[String, "string"],
|
|
14
|
-
[Boolean, "boolean"]
|
|
15
|
-
]);
|
|
16
|
-
return input.every(
|
|
17
|
-
(entry) => types.some((typeChecker) => {
|
|
18
|
-
if (!isConstructorFunction(typeChecker)) return typeChecker(entry);
|
|
19
|
-
const primitiveType = primitiveTypeMap.get(typeChecker);
|
|
20
|
-
if (primitiveType !== void 0) return typeof entry === primitiveType;
|
|
21
|
-
return entry instanceof typeChecker;
|
|
22
|
-
})
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
|
-
export {
|
|
26
|
-
isArrayOf
|
|
27
|
-
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { isArrayOf } from './index.js';
|
|
3
|
+
// Custom class & typeguard for testing
|
|
4
|
+
class MyClass {
|
|
5
|
+
value;
|
|
6
|
+
constructor(value) {
|
|
7
|
+
this.value = value;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
const isEvenNumber = (x) => typeof x === 'number' && x % 2 === 0;
|
|
11
|
+
describe('is-array-of', () => {
|
|
12
|
+
it('returns true for empty array without type checkers', () => {
|
|
13
|
+
expect(isArrayOf([])).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
it('returns true for array of numbers', () => {
|
|
16
|
+
expect(isArrayOf([1, 2, 3], Number)).toBe(true);
|
|
17
|
+
});
|
|
18
|
+
it('returns false if any element does not match primitive type', () => {
|
|
19
|
+
expect(isArrayOf([1, '2', 3], Number)).toBe(false);
|
|
20
|
+
expect(isArrayOf([true, false, 0], Boolean)).toBe(false);
|
|
21
|
+
expect(isArrayOf(['a', 'b', 1], String)).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
it('returns true for array of strings', () => {
|
|
24
|
+
expect(isArrayOf(['a', 'b', 'c'], String)).toBe(true);
|
|
25
|
+
});
|
|
26
|
+
it('returns true for array of booleans', () => {
|
|
27
|
+
expect(isArrayOf([true, false, true], Boolean)).toBe(true);
|
|
28
|
+
});
|
|
29
|
+
it('returns true for array of custom class instances', () => {
|
|
30
|
+
const arr = [new MyClass(1), new MyClass(2)];
|
|
31
|
+
expect(isArrayOf(arr, MyClass)).toBe(true);
|
|
32
|
+
});
|
|
33
|
+
it('returns false if any element is not instance of custom class', () => {
|
|
34
|
+
const arr = [new MyClass(1), { value: 2 }];
|
|
35
|
+
expect(isArrayOf(arr, MyClass)).toBe(false);
|
|
36
|
+
});
|
|
37
|
+
it('supports multiple type checkers (union)', () => {
|
|
38
|
+
const arr = [1, 'a', 2, 'b'];
|
|
39
|
+
expect(isArrayOf(arr, [Number, String])).toBe(true);
|
|
40
|
+
expect(isArrayOf([1, true], [Number, String])).toBe(false);
|
|
41
|
+
});
|
|
42
|
+
it('supports custom type guard functions', () => {
|
|
43
|
+
const arr = [2, 4, 6];
|
|
44
|
+
expect(isArrayOf(arr, isEvenNumber)).toBe(true);
|
|
45
|
+
expect(isArrayOf([2, 3, 4], isEvenNumber)).toBe(false);
|
|
46
|
+
});
|
|
47
|
+
it('returns false for non-array input', () => {
|
|
48
|
+
expect(isArrayOf(123, Number)).toBe(false);
|
|
49
|
+
expect(isArrayOf({}, Number)).toBe(false);
|
|
50
|
+
expect(isArrayOf(null, Number)).toBe(false);
|
|
51
|
+
expect(isArrayOf(undefined, Number)).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
it('returns true for array without type checkers', () => {
|
|
54
|
+
expect(isArrayOf([1, 'a', true])).toBe(true);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Creates an array of a specified length using a filler function.
|
|
3
|
+
*
|
|
4
|
+
* @param filler - Function called for each position to generate the array element.
|
|
5
|
+
* @param length - Desired length of the array.
|
|
6
|
+
* @returns A new array with elements generated by the filler function.
|
|
7
|
+
*/
|
|
8
|
+
export function make(filler, length) {
|
|
9
|
+
return new Array(length)
|
|
10
|
+
.fill(null)
|
|
11
|
+
.map((_, pos) => filler(pos));
|
|
4
12
|
}
|
|
5
|
-
export {
|
|
6
|
-
make
|
|
7
|
-
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { make } from './index.js';
|
|
3
|
+
import { randomInt } from '../../random/random/index.js';
|
|
4
|
+
describe('make', () => {
|
|
5
|
+
it('makes the array', () => {
|
|
6
|
+
const made = make(() => randomInt(0, 42), 4);
|
|
7
|
+
expect(made).toHaveLength(4);
|
|
8
|
+
expect(made.every(i => typeof i === 'number')).toBe(true);
|
|
9
|
+
});
|
|
10
|
+
});
|
|
@@ -1,24 +1,40 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Picks a random element from an array, optionally excluding certain elements.
|
|
3
|
+
*
|
|
4
|
+
* @param arr - The array to pick from.
|
|
5
|
+
* @param [exclude] - Array of elements to exclude from selection.
|
|
6
|
+
* @returns A randomly selected element from the array.
|
|
7
|
+
* @throws Throws an error if no elements are available after exclusions.
|
|
8
|
+
*/
|
|
9
|
+
export function randomPick(arr, exclude = []) {
|
|
10
|
+
const filteredArr = [...arr].filter(elt => !exclude.includes(elt));
|
|
11
|
+
const length = filteredArr.length;
|
|
12
|
+
if (length === 0)
|
|
13
|
+
throw new Error('Array length must be at least 1 after exclusion');
|
|
14
|
+
const pos = Math.floor(Math.random() * length);
|
|
15
|
+
const found = filteredArr[pos];
|
|
16
|
+
return found;
|
|
9
17
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Picks multiple random elements from an array without replacement.
|
|
20
|
+
*
|
|
21
|
+
* Each picked element is removed from the pool before the next selection, ensuring
|
|
22
|
+
* no duplicates in the result.
|
|
23
|
+
*
|
|
24
|
+
* @param howMuch - Number of elements to pick.
|
|
25
|
+
* @param arr - The array to pick from.
|
|
26
|
+
* @param [exclude] - Array of elements to exclude from selection.
|
|
27
|
+
* @returns An array of randomly selected elements.
|
|
28
|
+
* @throws Propagates the error thrown by `randomPick` if not enough elements are available.
|
|
29
|
+
*/
|
|
30
|
+
export function randomPickMany(howMuch, arr, exclude = []) {
|
|
31
|
+
const grindedArr = [...arr];
|
|
32
|
+
const pickedSelection = [];
|
|
33
|
+
for (let i = 0; i < howMuch; i++) {
|
|
34
|
+
const picked = randomPick(grindedArr, exclude);
|
|
35
|
+
const indexOfPicked = grindedArr.indexOf(picked);
|
|
36
|
+
grindedArr.splice(indexOfPicked, 1);
|
|
37
|
+
pickedSelection.push(picked);
|
|
38
|
+
}
|
|
39
|
+
return pickedSelection;
|
|
20
40
|
}
|
|
21
|
-
export {
|
|
22
|
-
randomPick,
|
|
23
|
-
randomPickMany
|
|
24
|
-
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { randomPick, randomPickMany } from './index.js';
|
|
3
|
+
import { make } from '../make/index.js';
|
|
4
|
+
describe('random-pick', () => {
|
|
5
|
+
it('correctly picks one', () => {
|
|
6
|
+
const source = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
7
|
+
const pickedOneTenTimes = make(() => randomPick(source), 10);
|
|
8
|
+
expect(pickedOneTenTimes.every(picked => source.includes(picked)));
|
|
9
|
+
});
|
|
10
|
+
it('throws if asked to pick more than there are in the input', () => {
|
|
11
|
+
expect(() => randomPick([])).toThrow();
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
describe('random-pick-many', () => {
|
|
15
|
+
it('correctly picks one and many', () => {
|
|
16
|
+
const source = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
17
|
+
const pickedManyTenTimes = make(() => randomPickMany(3, source), 10);
|
|
18
|
+
expect(pickedManyTenTimes.every(picked => picked.every(p => source.includes(p))));
|
|
19
|
+
});
|
|
20
|
+
it('throws if asked to pick more than there are in the input', () => {
|
|
21
|
+
expect(() => randomPickMany(2, [0])).toThrow();
|
|
22
|
+
});
|
|
23
|
+
});
|