tiny-essentials 1.28.19 → 1.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/changelog/1/28/19.md +24 -0
- package/changelog/1/29/0.md +58 -0
- package/changelog/1/29/1.md +11 -0
- package/dist/v1/ColorSafeStringify.min.js +1 -1
- package/dist/v1/TinyAdvancedRaffle.min.js +1 -1
- package/dist/v1/TinyAfterScrollWatcher.min.js +1 -1
- package/dist/v1/TinyAnalogClock.min.js +1 -1
- package/dist/v1/TinyArrayComparator.min.js +1 -1
- package/dist/v1/TinyArrayPaginator.min.js +1 -1
- package/dist/v1/TinyBasicsEs.min.js +1 -1
- package/dist/v1/TinyBrowserMonitor.min.js +1 -0
- package/dist/v1/TinyClassManager.min.js +1 -1
- package/dist/v1/TinyClipboard.min.js +1 -1
- package/dist/v1/TinyCloner.min.js +1 -0
- package/dist/v1/TinyColorConverter.min.js +1 -1
- package/dist/v1/TinyColorValidator.min.js +1 -1
- package/dist/v1/TinyCookieConsent.min.js +1 -1
- package/dist/v1/TinyDayNightCycle.min.js +1 -1
- package/dist/v1/TinyDebugger.min.js +1 -1
- package/dist/v1/TinyDomReadyManager.min.js +1 -1
- package/dist/v1/TinyDragDropDetector.min.js +1 -1
- package/dist/v1/TinyDragger.min.js +1 -1
- package/dist/v1/TinyElementObserver.min.js +1 -1
- package/dist/v1/TinyEssentials.min.js +1 -1
- package/dist/v1/TinyGamepad.min.js +1 -1
- package/dist/v1/TinyHtml.min.js +1 -1
- package/dist/v1/TinyHtmlTagRegexBuilder.min.js +1 -0
- package/dist/v1/TinyHttpResponseRegistry.min.js +1 -0
- package/dist/v1/TinyI18.min.js +1 -1
- package/dist/v1/TinyIframeEvents.min.js +1 -1
- package/dist/v1/TinyInventory.min.js +1 -1
- package/dist/v1/TinyInventoryTrader.min.js +1 -1
- package/dist/v1/TinyLevelUp.min.js +1 -1
- package/dist/v1/TinyLoadingScreen.min.js +1 -1
- package/dist/v1/TinyLocalStorage.min.js +1 -1
- package/dist/v1/TinyMaInSys.min.js +1 -1
- package/dist/v1/TinyMapCache.min.js +1 -0
- package/dist/v1/TinyMediaPlayer.min.js +1 -1
- package/dist/v1/TinyNeedBar.min.js +1 -1
- package/dist/v1/TinyNewWinEvents.min.js +1 -1
- package/dist/v1/TinyNotificationAdapter.min.js +1 -0
- package/dist/v1/TinyNotifications.min.js +1 -1
- package/dist/v1/TinyNotifyCenter.min.js +1 -1
- package/dist/v1/TinyOPFSFileSystem.min.js +1 -0
- package/dist/v1/TinyPasswordValidator.min.js +1 -0
- package/dist/v1/TinyPluginPackage.min.js +1 -0
- package/dist/v1/TinyPromiseQueue.min.js +1 -1
- package/dist/v1/TinyPushManager.min.js +1 -0
- package/dist/v1/TinyPushPayload.min.js +1 -0
- package/dist/v1/TinyPushRouter.min.js +1 -0
- package/dist/v1/TinyRadioFm.min.js +1 -1
- package/dist/v1/TinyRateLimiter.min.js +1 -1
- package/dist/v1/TinyRegexEs.min.js +1 -0
- package/dist/v1/TinyRouter.min.js +1 -0
- package/dist/v1/TinyServiceWorker.min.js +1 -0
- package/dist/v1/TinyServiceWorkerEngine.min.js +1 -0
- package/dist/v1/TinySetMapPackage.min.js +1 -0
- package/dist/v1/TinySimpleDice.min.js +1 -1
- package/dist/v1/TinySmartScroller.min.js +1 -1
- package/dist/v1/TinyStorageBucketFileSystem.min.js +1 -0
- package/dist/v1/TinyTextDiffer.min.js +1 -1
- package/dist/v1/TinyTextRangeEditor.min.js +1 -1
- package/dist/v1/TinyTextarea.min.js +1 -1
- package/dist/v1/TinyThrottledApi.min.js +1 -0
- package/dist/v1/TinyTimeout.min.js +1 -1
- package/dist/v1/TinyToastNotify.min.js +1 -1
- package/dist/v1/TinyUploadClicker.min.js +1 -1
- package/dist/v1/TinyUriParser.min.js +1 -0
- package/dist/v1/TinyVersion.min.js +1 -0
- package/dist/v1/TinyWebWorker.min.js +1 -0
- package/dist/v1/TinyWebWorkerEngine.min.js +1 -0
- package/dist/v1/UltraRandomMsgGen.min.js +1 -1
- package/dist/v1/basics/array.cjs +2 -2
- package/dist/v1/basics/array.d.mts +2 -0
- package/dist/v1/basics/array.d.mts.map +1 -1
- package/dist/v1/basics/array.mjs +2 -1
- package/dist/v1/basics/browserDetector.cjs +37 -12
- package/dist/v1/basics/browserDetector.d.mts +8 -0
- package/dist/v1/basics/browserDetector.d.mts.map +1 -1
- package/dist/v1/basics/browserDetector.mjs +32 -13
- package/dist/v1/basics/crypto.cjs +23 -0
- package/dist/v1/basics/crypto.d.mts +10 -0
- package/dist/v1/basics/crypto.d.mts.map +1 -0
- package/dist/v1/basics/crypto.mjs +18 -0
- package/dist/v1/basics/html.cjs +0 -3
- package/dist/v1/basics/html.d.mts.map +1 -1
- package/dist/v1/basics/html.mjs +0 -2
- package/dist/v1/basics/index.cjs +8 -1
- package/dist/v1/basics/index.d.mts +6 -5
- package/dist/v1/basics/index.d.mts.map +1 -1
- package/dist/v1/basics/index.mjs +6 -5
- package/dist/v1/basics/objChecker.cjs +88 -0
- package/dist/v1/basics/objChecker.d.mts +26 -0
- package/dist/v1/basics/objChecker.d.mts.map +1 -1
- package/dist/v1/basics/objChecker.mjs +74 -0
- package/dist/v1/basics/objFilter.cjs +234 -93
- package/dist/v1/basics/objFilter.d.mts +96 -22
- package/dist/v1/basics/objFilter.d.mts.map +1 -1
- package/dist/v1/basics/objFilter.mjs +216 -92
- package/dist/v1/basics/promiseUtils.cjs +48 -12
- package/dist/v1/basics/promiseUtils.d.mts +45 -12
- package/dist/v1/basics/promiseUtils.d.mts.map +1 -1
- package/dist/v1/basics/promiseUtils.mjs +47 -12
- package/dist/v1/basics/text.cjs +0 -12
- package/dist/v1/basics/text.d.mts +0 -10
- package/dist/v1/basics/text.d.mts.map +1 -1
- package/dist/v1/basics/text.mjs +0 -10
- package/dist/v1/index.cjs +88 -3
- package/dist/v1/index.d.mts +31 -6
- package/dist/v1/index.d.mts.map +1 -1
- package/dist/v1/index.mjs +32 -7
- package/dist/v1/jsdoc/EventEmitter.cjs +4 -0
- package/dist/v1/jsdoc/EventEmitter.d.mts +33 -0
- package/dist/v1/jsdoc/EventEmitter.d.mts.map +1 -0
- package/dist/v1/jsdoc/EventEmitter.mjs +18 -0
- package/dist/v1/libs/array/TinyArrayComparator.cjs +240 -25
- package/dist/v1/libs/array/TinyArrayComparator.d.mts +130 -22
- package/dist/v1/libs/array/TinyArrayComparator.d.mts.map +1 -1
- package/dist/v1/libs/array/TinyArrayComparator.mjs +210 -24
- package/dist/v1/libs/fs/constants.cjs +74 -0
- package/dist/v1/libs/fs/constants.d.mts +22 -0
- package/dist/v1/libs/fs/constants.d.mts.map +1 -0
- package/dist/v1/libs/fs/constants.mjs +53 -0
- package/dist/v1/libs/fs/encoding.cjs +118 -0
- package/dist/v1/libs/fs/encoding.d.mts +50 -0
- package/dist/v1/libs/fs/encoding.d.mts.map +1 -0
- package/dist/v1/libs/fs/encoding.mjs +102 -0
- package/dist/v1/libs/fs/error.cjs +188 -0
- package/dist/v1/libs/fs/error.d.mts +105 -0
- package/dist/v1/libs/fs/error.d.mts.map +1 -0
- package/dist/v1/libs/fs/error.mjs +158 -0
- package/dist/v1/libs/fs/handle.cjs +121 -0
- package/dist/v1/libs/fs/handle.d.mts +56 -0
- package/dist/v1/libs/fs/handle.d.mts.map +1 -0
- package/dist/v1/libs/fs/handle.mjs +100 -0
- package/dist/v1/libs/fs/index.cjs +700 -0
- package/dist/v1/libs/fs/index.d.mts +377 -0
- package/dist/v1/libs/fs/index.d.mts.map +1 -0
- package/dist/v1/libs/fs/index.mjs +630 -0
- package/dist/v1/libs/fs/path.cjs +234 -0
- package/dist/v1/libs/fs/path.d.mts +176 -0
- package/dist/v1/libs/fs/path.d.mts.map +1 -0
- package/dist/v1/libs/fs/path.mjs +197 -0
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.cjs +202 -0
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.d.mts +121 -0
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.d.mts.map +1 -0
- package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.mjs +172 -0
- package/dist/v1/libs/fs/plugins/OPFS/index.cjs +334 -0
- package/dist/v1/libs/fs/plugins/OPFS/index.d.mts +98 -0
- package/dist/v1/libs/fs/plugins/OPFS/index.d.mts.map +1 -0
- package/dist/v1/libs/fs/plugins/OPFS/index.mjs +300 -0
- package/dist/v1/libs/fs/stats.cjs +245 -0
- package/dist/v1/libs/fs/stats.d.mts +226 -0
- package/dist/v1/libs/fs/stats.d.mts.map +1 -0
- package/dist/v1/libs/fs/stats.mjs +197 -0
- package/dist/v1/libs/html/events/TinyIframeEvents.cjs +10 -1
- package/dist/v1/libs/html/events/TinyIframeEvents.d.mts +9 -2
- package/dist/v1/libs/html/events/TinyIframeEvents.d.mts.map +1 -1
- package/dist/v1/libs/html/events/TinyIframeEvents.mjs +8 -1
- package/dist/v1/libs/html/events/TinyNewWinEvents.cjs +14 -3
- package/dist/v1/libs/html/events/TinyNewWinEvents.d.mts +21 -5
- package/dist/v1/libs/html/events/TinyNewWinEvents.d.mts.map +1 -1
- package/dist/v1/libs/html/events/TinyNewWinEvents.mjs +12 -3
- package/dist/v1/libs/html/scroll/TinySmartScroller.cjs +13 -1
- package/dist/v1/libs/html/scroll/TinySmartScroller.d.mts +29 -2
- package/dist/v1/libs/html/scroll/TinySmartScroller.d.mts.map +1 -1
- package/dist/v1/libs/html/scroll/TinySmartScroller.mjs +11 -1
- package/dist/v1/libs/math/TinyAdvancedRaffle.cjs +13 -1
- package/dist/v1/libs/math/TinyAdvancedRaffle.d.mts +32 -2
- package/dist/v1/libs/math/TinyAdvancedRaffle.d.mts.map +1 -1
- package/dist/v1/libs/math/TinyAdvancedRaffle.mjs +11 -1
- package/dist/v1/libs/math/TinyTimeout.cjs +0 -14
- package/dist/v1/libs/math/TinyTimeout.d.mts +0 -11
- package/dist/v1/libs/math/TinyTimeout.d.mts.map +1 -1
- package/dist/v1/libs/math/TinyTimeout.mjs +0 -13
- package/dist/v1/libs/media/TinyMediaPlayer/index.cjs +25 -1
- package/dist/v1/libs/media/TinyMediaPlayer/index.d.mts +35 -2
- package/dist/v1/libs/media/TinyMediaPlayer/index.d.mts.map +1 -1
- package/dist/v1/libs/media/TinyMediaPlayer/index.mjs +23 -1
- package/dist/v1/libs/media/TinyMediaPlayer.cjs +2 -2
- package/dist/v1/libs/media/TinyMediaPlayer.d.mts +2 -2
- package/dist/v1/libs/media/TinyMediaPlayer.d.mts.map +1 -1
- package/dist/v1/libs/media/TinyMediaPlayer.mjs +2 -2
- package/dist/v1/libs/media/TinyRadioFm.cjs +19 -1
- package/dist/v1/libs/media/TinyRadioFm.d.mts +78 -2
- package/dist/v1/libs/media/TinyRadioFm.d.mts.map +1 -1
- package/dist/v1/libs/media/TinyRadioFm.mjs +17 -1
- package/dist/v1/libs/plugin/TinyPlugin.cjs +1630 -0
- package/dist/v1/libs/plugin/TinyPlugin.d.mts +753 -0
- package/dist/v1/libs/plugin/TinyPlugin.d.mts.map +1 -0
- package/dist/v1/libs/plugin/TinyPlugin.mjs +1376 -0
- package/dist/v1/libs/plugin/TinyVersion.cjs +204 -0
- package/dist/v1/libs/plugin/TinyVersion.d.mts +70 -0
- package/dist/v1/libs/plugin/TinyVersion.d.mts.map +1 -0
- package/dist/v1/libs/plugin/TinyVersion.mjs +179 -0
- package/dist/v1/libs/router/TinyRouter.cjs +661 -0
- package/dist/v1/libs/router/TinyRouter.d.mts +320 -0
- package/dist/v1/libs/router/TinyRouter.d.mts.map +1 -0
- package/dist/v1/libs/router/TinyRouter.mjs +572 -0
- package/dist/v1/libs/storage/TinyLocalStorage.cjs +20 -1
- package/dist/v1/libs/storage/TinyLocalStorage.d.mts +64 -2
- package/dist/v1/libs/storage/TinyLocalStorage.d.mts.map +1 -1
- package/dist/v1/libs/storage/TinyLocalStorage.mjs +18 -1
- package/dist/v1/libs/storage/TinyMapCache.cjs +373 -0
- package/dist/v1/libs/storage/TinyMapCache.d.mts +274 -0
- package/dist/v1/libs/storage/TinyMapCache.d.mts.map +1 -0
- package/dist/v1/libs/storage/TinyMapCache.mjs +333 -0
- package/dist/v1/libs/storage/TinySetMapDatabase.cjs +1167 -0
- package/dist/v1/libs/storage/TinySetMapDatabase.d.mts +603 -0
- package/dist/v1/libs/storage/TinySetMapDatabase.d.mts.map +1 -0
- package/dist/v1/libs/storage/TinySetMapDatabase.mjs +1059 -0
- package/dist/v1/libs/sw/browser/TinyNotificationAdapter.cjs +126 -0
- package/dist/v1/libs/sw/browser/TinyNotificationAdapter.d.mts +132 -0
- package/dist/v1/libs/sw/browser/TinyNotificationAdapter.d.mts.map +1 -0
- package/dist/v1/libs/sw/browser/TinyNotificationAdapter.mjs +109 -0
- package/dist/v1/libs/sw/browser/TinyPushManager.cjs +310 -0
- package/dist/v1/libs/sw/browser/TinyPushManager.d.mts +168 -0
- package/dist/v1/libs/sw/browser/TinyPushManager.d.mts.map +1 -0
- package/dist/v1/libs/sw/browser/TinyPushManager.mjs +264 -0
- package/dist/v1/libs/sw/browser/TinyServiceWorker.cjs +1060 -0
- package/dist/v1/libs/sw/browser/TinyServiceWorker.d.mts +348 -0
- package/dist/v1/libs/sw/browser/TinyServiceWorker.d.mts.map +1 -0
- package/dist/v1/libs/sw/browser/TinyServiceWorker.mjs +933 -0
- package/dist/v1/libs/sw/browser/plugins/TabManager.cjs +315 -0
- package/dist/v1/libs/sw/browser/plugins/TabManager.d.mts +178 -0
- package/dist/v1/libs/sw/browser/plugins/TabManager.d.mts.map +1 -0
- package/dist/v1/libs/sw/browser/plugins/TabManager.mjs +274 -0
- package/dist/v1/libs/sw/browser/utils.cjs +28 -0
- package/dist/v1/libs/sw/browser/utils.d.mts +8 -0
- package/dist/v1/libs/sw/browser/utils.d.mts.map +1 -0
- package/dist/v1/libs/sw/browser/utils.mjs +21 -0
- package/dist/v1/libs/sw/service/TinyPushRouter.cjs +222 -0
- package/dist/v1/libs/sw/service/TinyPushRouter.d.mts +138 -0
- package/dist/v1/libs/sw/service/TinyPushRouter.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/TinyPushRouter.mjs +201 -0
- package/dist/v1/libs/sw/service/TinyServiceWorkerEngine.cjs +3016 -0
- package/dist/v1/libs/sw/service/TinyServiceWorkerEngine.d.mts +993 -0
- package/dist/v1/libs/sw/service/TinyServiceWorkerEngine.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/TinyServiceWorkerEngine.mjs +2558 -0
- package/dist/v1/libs/sw/service/plugins/GlobBypassPlugin.cjs +88 -0
- package/dist/v1/libs/sw/service/plugins/GlobBypassPlugin.d.mts +32 -0
- package/dist/v1/libs/sw/service/plugins/GlobBypassPlugin.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/plugins/GlobBypassPlugin.mjs +69 -0
- package/dist/v1/libs/sw/service/plugins/GlobCachePlugin.cjs +112 -0
- package/dist/v1/libs/sw/service/plugins/GlobCachePlugin.d.mts +31 -0
- package/dist/v1/libs/sw/service/plugins/GlobCachePlugin.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/plugins/GlobCachePlugin.mjs +91 -0
- package/dist/v1/libs/sw/service/plugins/Ping.cjs +32 -0
- package/dist/v1/libs/sw/service/plugins/Ping.d.mts +9 -0
- package/dist/v1/libs/sw/service/plugins/Ping.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/plugins/Ping.mjs +25 -0
- package/dist/v1/libs/sw/service/plugins/TabManager.cjs +457 -0
- package/dist/v1/libs/sw/service/plugins/TabManager.d.mts +91 -0
- package/dist/v1/libs/sw/service/plugins/TabManager.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/plugins/TabManager.mjs +372 -0
- package/dist/v1/libs/sw/service/plugins/ViteFileDetector.cjs +180 -0
- package/dist/v1/libs/sw/service/plugins/ViteFileDetector.d.mts +28 -0
- package/dist/v1/libs/sw/service/plugins/ViteFileDetector.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/plugins/ViteFileDetector.mjs +148 -0
- package/dist/v1/libs/sw/service/shared/TinyPushPayload.cjs +199 -0
- package/dist/v1/libs/sw/service/shared/TinyPushPayload.d.mts +80 -0
- package/dist/v1/libs/sw/service/shared/TinyPushPayload.d.mts.map +1 -0
- package/dist/v1/libs/sw/service/shared/TinyPushPayload.mjs +174 -0
- package/dist/v1/libs/sw/utils.cjs +57 -0
- package/dist/v1/libs/sw/utils.d.mts +173 -0
- package/dist/v1/libs/sw/utils.d.mts.map +1 -0
- package/dist/v1/libs/sw/utils.mjs +50 -0
- package/dist/v1/libs/text/TinyI18/Browser-NON-DOM.cjs +57 -0
- package/dist/v1/libs/text/TinyI18/Browser-NON-DOM.d.mts +39 -0
- package/dist/v1/libs/text/TinyI18/Browser-NON-DOM.d.mts.map +1 -0
- package/dist/v1/libs/text/TinyI18/Browser-NON-DOM.mjs +48 -0
- package/dist/v1/libs/text/TinyI18/Browser.cjs +64 -0
- package/dist/v1/libs/text/TinyI18/Browser.d.mts +47 -0
- package/dist/v1/libs/text/TinyI18/Browser.d.mts.map +1 -0
- package/dist/v1/libs/text/TinyI18/Browser.mjs +57 -0
- package/dist/v1/libs/text/TinyI18/Node.cjs +49 -0
- package/dist/v1/libs/text/TinyI18/Node.d.mts +38 -0
- package/dist/v1/libs/text/TinyI18/Node.d.mts.map +1 -0
- package/dist/v1/libs/text/TinyI18/Node.mjs +43 -0
- package/dist/v1/libs/text/TinyI18/browser-utils.cjs +17 -0
- package/dist/v1/libs/text/TinyI18/browser-utils.d.mts +8 -0
- package/dist/v1/libs/text/TinyI18/browser-utils.d.mts.map +1 -0
- package/dist/v1/libs/text/TinyI18/browser-utils.mjs +13 -0
- package/dist/v1/libs/text/{TinyI18.cjs → TinyI18/index.cjs} +205 -104
- package/dist/v1/libs/text/{TinyI18.d.mts → TinyI18/index.d.mts} +141 -92
- package/dist/v1/libs/text/TinyI18/index.d.mts.map +1 -0
- package/dist/v1/libs/text/{TinyI18.mjs → TinyI18/index.mjs} +195 -101
- package/dist/v1/libs/tools/TinyBrowserMonitor.cjs +1088 -0
- package/dist/v1/libs/tools/TinyBrowserMonitor.d.mts +621 -0
- package/dist/v1/libs/tools/TinyBrowserMonitor.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyBrowserMonitor.mjs +940 -0
- package/dist/v1/libs/tools/TinyDebugger.cjs +180 -19
- package/dist/v1/libs/tools/TinyDebugger.d.mts +220 -24
- package/dist/v1/libs/tools/TinyDebugger.d.mts.map +1 -1
- package/dist/v1/libs/tools/TinyDebugger.mjs +161 -19
- package/dist/v1/libs/tools/TinyHtmlTagRegexBuilder.cjs +256 -0
- package/dist/v1/libs/tools/TinyHtmlTagRegexBuilder.d.mts +125 -0
- package/dist/v1/libs/tools/TinyHtmlTagRegexBuilder.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHtmlTagRegexBuilder.mjs +223 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser-NON-DOM.cjs +23 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser-NON-DOM.d.mts +17 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser-NON-DOM.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser-NON-DOM.mjs +19 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser.cjs +23 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser.d.mts +17 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser.mjs +19 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/EmptyRequestCodes.cjs +390 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/EmptyRequestCodes.d.mts +9 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/EmptyRequestCodes.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/EmptyRequestCodes.mjs +387 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/JsDoc.cjs +2 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/JsDoc.d.mts +27 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/JsDoc.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/JsDoc.mjs +12 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/MozillaRequestCodes/LICENSE +53 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/MozillaRequestCodes/index.cjs +405 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/MozillaRequestCodes/index.d.mts +34 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/MozillaRequestCodes/index.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/MozillaRequestCodes/index.mjs +342 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Node.cjs +23 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Node.d.mts +17 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Node.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/Node.mjs +19 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/RequestCodes.cjs +327 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/RequestCodes.d.mts +9 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/RequestCodes.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/RequestCodes.mjs +324 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/index.cjs +268 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/index.d.mts +107 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/index.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyHttpResponseRegistry/index.mjs +238 -0
- package/dist/v1/libs/tools/TinyPasswordValidator.cjs +491 -0
- package/dist/v1/libs/tools/TinyPasswordValidator.d.mts +246 -0
- package/dist/v1/libs/tools/TinyPasswordValidator.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyPasswordValidator.mjs +434 -0
- package/dist/v1/libs/tools/TinyPkgExportValidator.cjs +48 -0
- package/dist/v1/libs/tools/TinyPkgExportValidator.d.mts +14 -0
- package/dist/v1/libs/tools/TinyPkgExportValidator.d.mts.map +1 -1
- package/dist/v1/libs/tools/TinyPkgExportValidator.mjs +44 -0
- package/dist/v1/libs/tools/TinySiteMap.cjs +1029 -0
- package/dist/v1/libs/tools/TinySiteMap.d.mts +429 -0
- package/dist/v1/libs/tools/TinySiteMap.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinySiteMap.mjs +910 -0
- package/dist/v1/libs/tools/TinySiteMapStream.cjs +121 -0
- package/dist/v1/libs/tools/TinySiteMapStream.d.mts +51 -0
- package/dist/v1/libs/tools/TinySiteMapStream.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinySiteMapStream.mjs +85 -0
- package/dist/v1/libs/tools/TinyURLSecurityVerifier.cjs +444 -0
- package/dist/v1/libs/tools/TinyURLSecurityVerifier.d.mts +217 -0
- package/dist/v1/libs/tools/TinyURLSecurityVerifier.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyURLSecurityVerifier.mjs +394 -0
- package/dist/v1/libs/tools/TinyUriParser/BlueSky.cjs +613 -0
- package/dist/v1/libs/tools/TinyUriParser/BlueSky.d.mts +152 -0
- package/dist/v1/libs/tools/TinyUriParser/BlueSky.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyUriParser/BlueSky.mjs +527 -0
- package/dist/v1/libs/tools/TinyUriParser/Discord.cjs +1119 -0
- package/dist/v1/libs/tools/TinyUriParser/Discord.d.mts +306 -0
- package/dist/v1/libs/tools/TinyUriParser/Discord.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyUriParser/Discord.mjs +968 -0
- package/dist/v1/libs/tools/TinyUriParser/MatrixProtocol.cjs +469 -0
- package/dist/v1/libs/tools/TinyUriParser/MatrixProtocol.d.mts +80 -0
- package/dist/v1/libs/tools/TinyUriParser/MatrixProtocol.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyUriParser/MatrixProtocol.mjs +379 -0
- package/dist/v1/libs/tools/TinyUriParser.cjs +217 -0
- package/dist/v1/libs/tools/TinyUriParser.d.mts +109 -0
- package/dist/v1/libs/tools/TinyUriParser.d.mts.map +1 -0
- package/dist/v1/libs/tools/TinyUriParser.mjs +183 -0
- package/dist/v1/libs/utils/TinyCloner.cjs +466 -0
- package/dist/v1/libs/utils/TinyCloner.d.mts +221 -0
- package/dist/v1/libs/utils/TinyCloner.d.mts.map +1 -0
- package/dist/v1/libs/utils/TinyCloner.mjs +416 -0
- package/dist/v1/libs/utils/TinyPromiseQueue.cjs +1 -1
- package/dist/v1/libs/utils/TinyPromiseQueue.d.mts +2 -2
- package/dist/v1/libs/utils/TinyPromiseQueue.d.mts.map +1 -1
- package/dist/v1/libs/utils/TinyPromiseQueue.mjs +1 -1
- package/dist/v1/libs/utils/TinyThrottledApi.cjs +333 -0
- package/dist/v1/libs/utils/TinyThrottledApi.d.mts +163 -0
- package/dist/v1/libs/utils/TinyThrottledApi.d.mts.map +1 -0
- package/dist/v1/libs/utils/TinyThrottledApi.mjs +294 -0
- package/dist/v1/libs/worker/browser/TinyWebWorker.cjs +342 -0
- package/dist/v1/libs/worker/browser/TinyWebWorker.d.mts +97 -0
- package/dist/v1/libs/worker/browser/TinyWebWorker.d.mts.map +1 -0
- package/dist/v1/libs/worker/browser/TinyWebWorker.mjs +305 -0
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.cjs +346 -0
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.d.mts +127 -0
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.d.mts.map +1 -0
- package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.mjs +304 -0
- package/dist/v1/regexp/Email.cjs +185 -0
- package/dist/v1/regexp/Email.d.mts +73 -0
- package/dist/v1/regexp/Email.d.mts.map +1 -0
- package/dist/v1/regexp/Email.mjs +153 -0
- package/dist/v1/regexp/Glob.cjs +293 -0
- package/dist/v1/regexp/Glob.d.mts +45 -0
- package/dist/v1/regexp/Glob.d.mts.map +1 -0
- package/dist/v1/regexp/Glob.mjs +260 -0
- package/dist/v1/regexp/Ipv4.cjs +57 -0
- package/dist/v1/regexp/Ipv4.d.mts +29 -0
- package/dist/v1/regexp/Ipv4.d.mts.map +1 -0
- package/dist/v1/regexp/Ipv4.mjs +45 -0
- package/dist/v1/regexp/Ipv6.cjs +67 -0
- package/dist/v1/regexp/Ipv6.d.mts +29 -0
- package/dist/v1/regexp/Ipv6.d.mts.map +1 -0
- package/dist/v1/regexp/Ipv6.mjs +54 -0
- package/dist/v1/regexp/SegmentExtractor.cjs +145 -0
- package/dist/v1/regexp/SegmentExtractor.d.mts +91 -0
- package/dist/v1/regexp/SegmentExtractor.d.mts.map +1 -0
- package/dist/v1/regexp/SegmentExtractor.mjs +116 -0
- package/dist/v1/regexp/UrlDetector.cjs +125 -0
- package/dist/v1/regexp/UrlDetector.d.mts +67 -0
- package/dist/v1/regexp/UrlDetector.d.mts.map +1 -0
- package/dist/v1/regexp/UrlDetector.mjs +102 -0
- package/dist/v1/regexp/Username/index.cjs +233 -0
- package/dist/v1/regexp/Username/index.d.mts +77 -0
- package/dist/v1/regexp/Username/index.d.mts.map +1 -0
- package/dist/v1/regexp/Username/index.mjs +199 -0
- package/dist/v1/regexp/Username/jsDoc.cjs +2 -0
- package/dist/v1/regexp/Username/jsDoc.d.mts +57 -0
- package/dist/v1/regexp/Username/jsDoc.d.mts.map +1 -0
- package/dist/v1/regexp/Username/jsDoc.mjs +18 -0
- package/dist/v1/regexp/Username/templates/BlueSky.cjs +56 -0
- package/dist/v1/regexp/Username/templates/BlueSky.d.mts +35 -0
- package/dist/v1/regexp/Username/templates/BlueSky.d.mts.map +1 -0
- package/dist/v1/regexp/Username/templates/BlueSky.mjs +52 -0
- package/dist/v1/regexp/Username/templates/Discord.cjs +505 -0
- package/dist/v1/regexp/Username/templates/Discord.d.mts +209 -0
- package/dist/v1/regexp/Username/templates/Discord.d.mts.map +1 -0
- package/dist/v1/regexp/Username/templates/Discord.mjs +458 -0
- package/dist/v1/regexp/Username/templates/MatrixProtocol.cjs +143 -0
- package/dist/v1/regexp/Username/templates/MatrixProtocol.d.mts +70 -0
- package/dist/v1/regexp/Username/templates/MatrixProtocol.d.mts.map +1 -0
- package/dist/v1/regexp/Username/templates/MatrixProtocol.mjs +128 -0
- package/dist/v1/regexp/Username/templates/deprecated/Discord.cjs +24 -0
- package/dist/v1/regexp/Username/templates/deprecated/Discord.d.mts +17 -0
- package/dist/v1/regexp/Username/templates/deprecated/Discord.d.mts.map +1 -0
- package/dist/v1/regexp/Username/templates/deprecated/Discord.mjs +20 -0
- package/dist/v1/regexp/Username/templates/index.cjs +11 -0
- package/dist/v1/regexp/Username/templates/index.d.mts +5 -0
- package/dist/v1/regexp/Username/templates/index.d.mts.map +1 -0
- package/dist/v1/regexp/Username/templates/index.mjs +4 -0
- package/dist/v1/regexp/index.cjs +41 -0
- package/dist/v1/regexp/index.d.mts +9 -0
- package/dist/v1/regexp/index.d.mts.map +1 -0
- package/dist/v1/regexp/index.mjs +8 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Browser.cjs +64 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Browser.d.mts +11 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Browser.d.mts.map +1 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Browser.mjs +51 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/FileInput.cjs +66 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/FileInput.d.mts +11 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/FileInput.d.mts.map +1 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/FileInput.mjs +51 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Node.cjs +39 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Node.d.mts +11 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Node.d.mts.map +1 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Node.mjs +28 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Template.cjs +494 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Template.d.mts +142 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Template.d.mts.map +1 -0
- package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Template.mjs +445 -0
- package/dist/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.cjs +30 -4
- package/dist/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.d.mts +5 -2
- package/dist/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.d.mts.map +1 -1
- package/dist/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.mjs +29 -5
- package/dist/v1/webTemplates/media/MediaValidator/v1/Browser/index.cjs +135 -0
- package/dist/v1/webTemplates/media/MediaValidator/v1/Browser/index.d.mts +83 -0
- package/dist/v1/webTemplates/media/MediaValidator/v1/Browser/index.d.mts.map +1 -0
- package/dist/v1/webTemplates/media/MediaValidator/v1/Browser/index.mjs +120 -0
- package/dist/v1/webTemplates/media/MediaValidator/v1/Node/index.cjs +127 -0
- package/dist/v1/webTemplates/media/MediaValidator/v1/Node/index.d.mts +95 -0
- package/dist/v1/webTemplates/media/MediaValidator/v1/Node/index.d.mts.map +1 -0
- package/dist/v1/webTemplates/media/MediaValidator/v1/Node/index.mjs +109 -0
- package/dist/v1/webTemplates/multiformats/14.0/IPFSHasher/index.cjs +83 -0
- package/dist/v1/webTemplates/multiformats/14.0/IPFSHasher/index.d.mts +46 -0
- package/dist/v1/webTemplates/multiformats/14.0/IPFSHasher/index.d.mts.map +1 -0
- package/dist/v1/webTemplates/multiformats/14.0/IPFSHasher/index.mjs +71 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin.cjs +493 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin.d.mts +67 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin.d.mts.map +1 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin.mjs +399 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/githubUtils.cjs +35 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/githubUtils.d.mts +6 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/githubUtils.d.mts.map +1 -0
- package/dist/v1/webTemplates/vite/7.3/plugins/githubUtils.mjs +29 -0
- package/docs/info/RegExp.md +74 -0
- package/docs/v1/Exports.md +101 -0
- package/docs/v1/README.md +113 -15
- package/docs/v1/basics/asyncReplace.md +2 -0
- package/docs/v1/basics/browserDetector.md +28 -11
- package/docs/v1/basics/crypto.md +85 -0
- package/docs/v1/basics/deprecated/html.md +2 -0
- package/docs/v1/basics/deprecated/objFilter.md +2 -0
- package/docs/v1/basics/html.md +2 -0
- package/docs/v1/basics/objChecker.md +55 -0
- package/docs/v1/basics/objFilter.md +57 -86
- package/docs/v1/basics/promiseUtils.md +12 -3
- package/docs/v1/basics/text.md +0 -1
- package/docs/v1/libs/array/TinyArrayComparator.md +50 -39
- package/docs/v1/libs/fs/TinyFS.md +752 -0
- package/docs/v1/libs/fs/TinyOPFSFileSystem.md +495 -0
- package/docs/v1/libs/fs/TinyStorageBucketFileSystem.md +407 -0
- package/docs/v1/libs/plugin/TinyPlugin.md +441 -0
- package/docs/v1/libs/plugin/TinyVersion.md +145 -0
- package/docs/v1/libs/router/TinyRouter.md +216 -0
- package/docs/v1/libs/storage/TinyMapCache.md +219 -0
- package/docs/v1/libs/storage/TinySetMapDatabase.md +478 -0
- package/docs/v1/libs/sw/browser/TinyNotificationAdapter.md +280 -0
- package/docs/v1/libs/sw/browser/TinyPushManager.md +782 -0
- package/docs/v1/libs/sw/browser/TinyServiceWorker.md +365 -0
- package/docs/v1/libs/sw/browser/plugins/TabManager.md +133 -0
- package/docs/v1/libs/sw/service/TinyPushRouter.md +314 -0
- package/docs/v1/libs/sw/service/TinyServiceWorkerEngine.md +748 -0
- package/docs/v1/libs/sw/service/plugins/GlobBypassPlugin.md +229 -0
- package/docs/v1/libs/sw/service/plugins/GlobCachePlugin.md +91 -0
- package/docs/v1/libs/sw/service/plugins/Ping.md +36 -0
- package/docs/v1/libs/sw/service/plugins/TabManager.md +64 -0
- package/docs/v1/libs/sw/service/plugins/ViteFileDetector.md +92 -0
- package/docs/v1/libs/sw/service/shared/TinyPushPayload.md +316 -0
- package/docs/v1/libs/text/TinyI18.md +80 -56
- package/docs/v1/libs/tools/TinyBrowserMonitor.md +170 -0
- package/docs/v1/libs/tools/TinyDebugger.md +117 -1
- package/docs/v1/libs/tools/TinyHtmlTagRegexBuilder.md +141 -0
- package/docs/v1/libs/tools/TinyHttpResponseRegistry.md +129 -0
- package/docs/v1/libs/tools/TinyPasswordValidator.md +153 -0
- package/docs/v1/libs/tools/TinyPkgExportValidator.md +45 -1
- package/docs/v1/libs/tools/TinySiteMap.md +134 -0
- package/docs/v1/libs/tools/TinySiteMapStream.md +97 -0
- package/docs/v1/libs/tools/TinyURLSecurityVerifier.md +146 -0
- package/docs/v1/libs/tools/TinyUriParser/Discord.md +374 -0
- package/docs/v1/libs/tools/TinyUriParser/MatrixProtocol.md +54 -0
- package/docs/v1/libs/tools/TinyUriParser.md +128 -0
- package/docs/v1/libs/utils/TinyCloner.md +126 -0
- package/docs/v1/libs/utils/TinyPromiseQueue.md +1 -1
- package/docs/v1/libs/utils/TinyThrottledApi.md +219 -0
- package/docs/v1/libs/worker/browser/TinyWebWorker.md +331 -0
- package/docs/v1/libs/worker/engine/TinyWebWorkerEngine.md +137 -0
- package/docs/v1/regexp/Email.md +127 -0
- package/docs/v1/regexp/Glob.md +155 -0
- package/docs/v1/regexp/IPv4.md +103 -0
- package/docs/v1/regexp/IPv6.md +122 -0
- package/docs/v1/regexp/SegmentExtractor.md +120 -0
- package/docs/v1/regexp/UrlDetector.md +117 -0
- package/docs/v1/regexp/Username/Base.md +131 -0
- package/docs/v1/regexp/Username/Discord.md +267 -0
- package/docs/v1/regexp/Username/MatrixProtocol.md +131 -0
- package/docs/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters.md +565 -0
- package/docs/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.md +19 -7
- package/docs/v1/webTemplates/media/MediaValidator/v1/Browser.md +123 -0
- package/docs/v1/webTemplates/media/MediaValidator/v1/Node.md +136 -0
- package/docs/v1/webTemplates/multiformats/14.0/IPFSHasher.md +310 -0
- package/docs/v1/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin.md +131 -0
- package/docs/v1/webTemplates/vite/7.3/plugins/githubUtils.md +50 -0
- package/package.json +340 -22
- package/types/EventEmitter.d.ts +48 -0
- package/dist/v1/libs/text/TinyI18.d.mts.map +0 -1
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @template T
|
|
5
|
+
* @typedef {Object} ValidationResult
|
|
6
|
+
* @property {string|null} error - The error message if validation failed.
|
|
7
|
+
* @property {T} [data]
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* LAYER 1: Fast Binary Validation (Magic Numbers)
|
|
12
|
+
* Validates if the file header matches expected media categories.
|
|
13
|
+
*
|
|
14
|
+
* @param {Object} options
|
|
15
|
+
* @param {Buffer|Uint8Array|Blob} options.inputData - The raw file data.
|
|
16
|
+
* @param {'image' | 'audio' | 'video'} options.expectedType - The expected media category.
|
|
17
|
+
* @param {(buffer: Uint8Array | ArrayBuffer) => Promise<{ mime: string; } | undefined>} options.fileTypeFromBuffer
|
|
18
|
+
* @returns {Promise<string>} Resolves with the confirmed MIME type if valid.
|
|
19
|
+
* @throws {Error} If the file signature does not match the expected type.
|
|
20
|
+
*/
|
|
21
|
+
async function validateMagicNumbers({ inputData, expectedType, fileTypeFromBuffer }) {
|
|
22
|
+
const arrayBuffer = inputData instanceof Blob ? await inputData.arrayBuffer() : inputData;
|
|
23
|
+
const bufferData = new Uint8Array(arrayBuffer);
|
|
24
|
+
const detected = await fileTypeFromBuffer(bufferData);
|
|
25
|
+
|
|
26
|
+
if (!detected) {
|
|
27
|
+
throw new Error('File signature could not be identified (Unknown Magic Numbers).');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const mime = detected.mime;
|
|
31
|
+
const isTypeValid = {
|
|
32
|
+
image: mime.startsWith('image/'),
|
|
33
|
+
audio: mime.startsWith('audio/'),
|
|
34
|
+
video: mime.startsWith('video/') || mime === 'application/x-mpegurl', // Handles some streaming formats
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
if (!isTypeValid[expectedType]) {
|
|
38
|
+
throw new Error(`Security Alert: File disguised as ${expectedType}. Actual MIME type: ${mime}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return mime;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @typedef {import('sharp').SharpConstructor} SharpConstructor
|
|
46
|
+
* @typedef {import('sharp').Sharp} Sharp
|
|
47
|
+
* @typedef {import('sharp').Metadata} SharpMetadata
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* LAYER 2 (IMAGE): Structural and metadata validation for images.
|
|
52
|
+
* Forces the decoding engine to parse the image structure to detect hidden exploits.
|
|
53
|
+
*
|
|
54
|
+
* @param {Object} options
|
|
55
|
+
* @param {Buffer|Blob} options.inputData - The raw image data.
|
|
56
|
+
* @returns {Promise<ValidationResult<{ width: number; height: number }>>} The validation outcome.
|
|
57
|
+
*/
|
|
58
|
+
async function validateImage({ inputData }) {
|
|
59
|
+
try {
|
|
60
|
+
if (!(inputData instanceof Blob)) throw new TypeError('InputData must be a Blob or File.');
|
|
61
|
+
const bitmap = await createImageBitmap(inputData);
|
|
62
|
+
return {
|
|
63
|
+
error: null,
|
|
64
|
+
data: { width: bitmap.width, height: bitmap.height },
|
|
65
|
+
};
|
|
66
|
+
} catch (err) {
|
|
67
|
+
console.error(err);
|
|
68
|
+
return {
|
|
69
|
+
error: err instanceof Error ? err.message : 'Unknown Error',
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @typedef {import('music-metadata').IAudioMetadata} IAudioMetadata
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @typedef {Object} ValidationResultExtra
|
|
80
|
+
* @property {string|null} mimeType - The detected MIME type of the file.
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* LAYER 2 (AUDIO/VIDEO): Deep validation for audio/video files.
|
|
85
|
+
* Validates headers, durations, and container integrity.
|
|
86
|
+
*
|
|
87
|
+
* @param {Object} options
|
|
88
|
+
* @param {Buffer|Blob} options.inputData - The raw media data.
|
|
89
|
+
* @param {string} options.mimeType - Result from {@link validateMagicNumbers}
|
|
90
|
+
* @returns {Promise<ValidationResult<{ duration: number }> & ValidationResultExtra>} The validation outcome.
|
|
91
|
+
*/
|
|
92
|
+
async function validateAudioVideo({ inputData, mimeType }) {
|
|
93
|
+
try {
|
|
94
|
+
if (!(inputData instanceof Blob)) throw new TypeError('InputData must be a Blob or File.');
|
|
95
|
+
return new Promise((resolve) => {
|
|
96
|
+
const isAudio = mimeType.startsWith('audio/');
|
|
97
|
+
const mediaElement = document.createElement(isAudio ? 'audio' : 'video');
|
|
98
|
+
const url = URL.createObjectURL(inputData);
|
|
99
|
+
|
|
100
|
+
mediaElement.preload = 'metadata';
|
|
101
|
+
|
|
102
|
+
mediaElement.onloadedmetadata = () => {
|
|
103
|
+
URL.revokeObjectURL(url);
|
|
104
|
+
if (isNaN(mediaElement.duration) || mediaElement.duration === 0) {
|
|
105
|
+
resolve({
|
|
106
|
+
mimeType: null,
|
|
107
|
+
error: 'Media structure corrupted: Missing duration in browser.',
|
|
108
|
+
});
|
|
109
|
+
} else {
|
|
110
|
+
resolve({ mimeType, error: null, data: { duration: mediaElement.duration } });
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
mediaElement.onerror = () => {
|
|
115
|
+
URL.revokeObjectURL(url);
|
|
116
|
+
resolve({
|
|
117
|
+
mimeType: null,
|
|
118
|
+
error: 'Native browser decoder failed to parse media container.',
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
mediaElement.src = url;
|
|
123
|
+
});
|
|
124
|
+
} catch (err) {
|
|
125
|
+
console.error(err);
|
|
126
|
+
return {
|
|
127
|
+
mimeType: null,
|
|
128
|
+
error: err instanceof Error ? err.message : 'Unknown Error',
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
exports.validateAudioVideo = validateAudioVideo;
|
|
134
|
+
exports.validateImage = validateImage;
|
|
135
|
+
exports.validateMagicNumbers = validateMagicNumbers;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @template T
|
|
3
|
+
* @typedef {Object} ValidationResult
|
|
4
|
+
* @property {string|null} error - The error message if validation failed.
|
|
5
|
+
* @property {T} [data]
|
|
6
|
+
*/
|
|
7
|
+
export type ValidationResult<T> = {
|
|
8
|
+
/**
|
|
9
|
+
* - The error message if validation failed.
|
|
10
|
+
*/
|
|
11
|
+
error: string | null;
|
|
12
|
+
data?: T;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* LAYER 1: Fast Binary Validation (Magic Numbers)
|
|
16
|
+
* Validates if the file header matches expected media categories.
|
|
17
|
+
*
|
|
18
|
+
* @param {Object} options
|
|
19
|
+
* @param {Buffer|Uint8Array|Blob} options.inputData - The raw file data.
|
|
20
|
+
* @param {'image' | 'audio' | 'video'} options.expectedType - The expected media category.
|
|
21
|
+
* @param {(buffer: Uint8Array | ArrayBuffer) => Promise<{ mime: string; } | undefined>} options.fileTypeFromBuffer
|
|
22
|
+
* @returns {Promise<string>} Resolves with the confirmed MIME type if valid.
|
|
23
|
+
* @throws {Error} If the file signature does not match the expected type.
|
|
24
|
+
*/
|
|
25
|
+
export declare function validateMagicNumbers({ inputData, expectedType, fileTypeFromBuffer }: {
|
|
26
|
+
inputData: Buffer | Uint8Array | Blob;
|
|
27
|
+
expectedType: 'image' | 'audio' | 'video';
|
|
28
|
+
fileTypeFromBuffer: (buffer: Uint8Array | ArrayBuffer) => Promise<{
|
|
29
|
+
mime: string;
|
|
30
|
+
} | undefined>;
|
|
31
|
+
}): Promise<string>;
|
|
32
|
+
export type SharpConstructor = import('sharp').SharpConstructor;
|
|
33
|
+
export type Sharp = import('sharp').Sharp;
|
|
34
|
+
export type SharpMetadata = import('sharp').Metadata;
|
|
35
|
+
/**
|
|
36
|
+
* @typedef {import('sharp').SharpConstructor} SharpConstructor
|
|
37
|
+
* @typedef {import('sharp').Sharp} Sharp
|
|
38
|
+
* @typedef {import('sharp').Metadata} SharpMetadata
|
|
39
|
+
*/
|
|
40
|
+
/**
|
|
41
|
+
* LAYER 2 (IMAGE): Structural and metadata validation for images.
|
|
42
|
+
* Forces the decoding engine to parse the image structure to detect hidden exploits.
|
|
43
|
+
*
|
|
44
|
+
* @param {Object} options
|
|
45
|
+
* @param {Buffer|Blob} options.inputData - The raw image data.
|
|
46
|
+
* @returns {Promise<ValidationResult<{ width: number; height: number }>>} The validation outcome.
|
|
47
|
+
*/
|
|
48
|
+
export declare function validateImage({ inputData }: {
|
|
49
|
+
inputData: Buffer | Blob;
|
|
50
|
+
}): Promise<ValidationResult<{
|
|
51
|
+
width: number;
|
|
52
|
+
height: number;
|
|
53
|
+
}>>;
|
|
54
|
+
export type IAudioMetadata = import('music-metadata').IAudioMetadata;
|
|
55
|
+
export type ValidationResultExtra = {
|
|
56
|
+
/**
|
|
57
|
+
* - The detected MIME type of the file.
|
|
58
|
+
*/
|
|
59
|
+
mimeType: string | null;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* @typedef {import('music-metadata').IAudioMetadata} IAudioMetadata
|
|
63
|
+
*/
|
|
64
|
+
/**
|
|
65
|
+
* @typedef {Object} ValidationResultExtra
|
|
66
|
+
* @property {string|null} mimeType - The detected MIME type of the file.
|
|
67
|
+
*/
|
|
68
|
+
/**
|
|
69
|
+
* LAYER 2 (AUDIO/VIDEO): Deep validation for audio/video files.
|
|
70
|
+
* Validates headers, durations, and container integrity.
|
|
71
|
+
*
|
|
72
|
+
* @param {Object} options
|
|
73
|
+
* @param {Buffer|Blob} options.inputData - The raw media data.
|
|
74
|
+
* @param {string} options.mimeType - Result from {@link validateMagicNumbers}
|
|
75
|
+
* @returns {Promise<ValidationResult<{ duration: number }> & ValidationResultExtra>} The validation outcome.
|
|
76
|
+
*/
|
|
77
|
+
export declare function validateAudioVideo({ inputData, mimeType }: {
|
|
78
|
+
inputData: Buffer | Blob;
|
|
79
|
+
mimeType: string;
|
|
80
|
+
}): Promise<ValidationResult<{
|
|
81
|
+
duration: number;
|
|
82
|
+
}> & ValidationResultExtra>;
|
|
83
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../../../../../../src/v1/webTemplates/media/MediaValidator/v1/Browser/index.mjs"],"names":[],"mappings":"AAAA;;;;;GAKG;AAHA,YAAkB,gBAAgB,CADxB,CAAC,IAEX;;;;IAAwB,KAAK,EAAlB,MAAM,GAAC,IAAI,CACtB;IAAe,IAAI,AAAnB,CAAoB,EAAT,CAAC,CAAQ;CAAA,CAAA;AAGvB;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,kBAAkB,EAAE,EANvF;IAAwC,SAAS,EAAzC,MAAM,GAAC,UAAU,GAAC,IAAI,CAC9B;IAA6C,YAAY,EAAjD,OAAO,GAAG,OAAO,GAAG,OAAO,CACnC;IAA8F,kBAAkB,EAAxG,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;KAAE,GAAG,SAAS,CAAC,CACpF;CAGuF,GAH7E,OAAO,CAAC,MAAM,CAAC,CAwB3B;AAGE,YAA4C,gBAAgB,GAAlD,OAAO,OAAO,EAAE,gBAAgB,CAAkB;AAC5D,YAAiC,KAAK,GAA5B,OAAO,OAAO,EAAE,KAAK,CAAO;AACtC,YAAoC,aAAa,GAAvC,OAAO,OAAO,EAAE,QAAQ,CAAe;AAHpD;;;;GAIG;AAEH;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,EAAE,SAAS,EAAE,EAH9C;IAA6B,SAAS,EAA9B,MAAM,GAAC,IAAI,CACnB;CAE8C,GAFpC,OAAO,CAAC,gBAAgB,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAgBxE;AAGE,YAAmD,cAAc,GAAvD,OAAO,gBAAgB,EAAE,cAAc,CAAgB;AAIjE,YAAkB,qBAAqB,GACvC;;;;IAAwB,QAAQ,EAArB,MAAM,GAAC,IAAI,CACxB;CAAA,CAAA;AAPD;;GAEG;AAEH;;;GAGG;AAEH;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,EAJ7D;IAA6B,SAAS,EAA9B,MAAM,GAAC,IAAI,CACnB;IAAwB,QAAQ,EAAxB,MAAM,CACd;CAE6D,GAFnD,OAAO,CAAC,gBAAgB,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,qBAAqB,CAAC,CAyCnF"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @template T
|
|
3
|
+
* @typedef {Object} ValidationResult
|
|
4
|
+
* @property {string|null} error - The error message if validation failed.
|
|
5
|
+
* @property {T} [data]
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* LAYER 1: Fast Binary Validation (Magic Numbers)
|
|
9
|
+
* Validates if the file header matches expected media categories.
|
|
10
|
+
*
|
|
11
|
+
* @param {Object} options
|
|
12
|
+
* @param {Buffer|Uint8Array|Blob} options.inputData - The raw file data.
|
|
13
|
+
* @param {'image' | 'audio' | 'video'} options.expectedType - The expected media category.
|
|
14
|
+
* @param {(buffer: Uint8Array | ArrayBuffer) => Promise<{ mime: string; } | undefined>} options.fileTypeFromBuffer
|
|
15
|
+
* @returns {Promise<string>} Resolves with the confirmed MIME type if valid.
|
|
16
|
+
* @throws {Error} If the file signature does not match the expected type.
|
|
17
|
+
*/
|
|
18
|
+
export async function validateMagicNumbers({ inputData, expectedType, fileTypeFromBuffer }) {
|
|
19
|
+
const arrayBuffer = inputData instanceof Blob ? await inputData.arrayBuffer() : inputData;
|
|
20
|
+
const bufferData = new Uint8Array(arrayBuffer);
|
|
21
|
+
const detected = await fileTypeFromBuffer(bufferData);
|
|
22
|
+
if (!detected) {
|
|
23
|
+
throw new Error('File signature could not be identified (Unknown Magic Numbers).');
|
|
24
|
+
}
|
|
25
|
+
const mime = detected.mime;
|
|
26
|
+
const isTypeValid = {
|
|
27
|
+
image: mime.startsWith('image/'),
|
|
28
|
+
audio: mime.startsWith('audio/'),
|
|
29
|
+
video: mime.startsWith('video/') || mime === 'application/x-mpegurl', // Handles some streaming formats
|
|
30
|
+
};
|
|
31
|
+
if (!isTypeValid[expectedType]) {
|
|
32
|
+
throw new Error(`Security Alert: File disguised as ${expectedType}. Actual MIME type: ${mime}`);
|
|
33
|
+
}
|
|
34
|
+
return mime;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* @typedef {import('sharp').SharpConstructor} SharpConstructor
|
|
38
|
+
* @typedef {import('sharp').Sharp} Sharp
|
|
39
|
+
* @typedef {import('sharp').Metadata} SharpMetadata
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* LAYER 2 (IMAGE): Structural and metadata validation for images.
|
|
43
|
+
* Forces the decoding engine to parse the image structure to detect hidden exploits.
|
|
44
|
+
*
|
|
45
|
+
* @param {Object} options
|
|
46
|
+
* @param {Buffer|Blob} options.inputData - The raw image data.
|
|
47
|
+
* @returns {Promise<ValidationResult<{ width: number; height: number }>>} The validation outcome.
|
|
48
|
+
*/
|
|
49
|
+
export async function validateImage({ inputData }) {
|
|
50
|
+
try {
|
|
51
|
+
if (!(inputData instanceof Blob))
|
|
52
|
+
throw new TypeError('InputData must be a Blob or File.');
|
|
53
|
+
const bitmap = await createImageBitmap(inputData);
|
|
54
|
+
return {
|
|
55
|
+
error: null,
|
|
56
|
+
data: { width: bitmap.width, height: bitmap.height },
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
console.error(err);
|
|
61
|
+
return {
|
|
62
|
+
error: err instanceof Error ? err.message : 'Unknown Error',
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* @typedef {import('music-metadata').IAudioMetadata} IAudioMetadata
|
|
68
|
+
*/
|
|
69
|
+
/**
|
|
70
|
+
* @typedef {Object} ValidationResultExtra
|
|
71
|
+
* @property {string|null} mimeType - The detected MIME type of the file.
|
|
72
|
+
*/
|
|
73
|
+
/**
|
|
74
|
+
* LAYER 2 (AUDIO/VIDEO): Deep validation for audio/video files.
|
|
75
|
+
* Validates headers, durations, and container integrity.
|
|
76
|
+
*
|
|
77
|
+
* @param {Object} options
|
|
78
|
+
* @param {Buffer|Blob} options.inputData - The raw media data.
|
|
79
|
+
* @param {string} options.mimeType - Result from {@link validateMagicNumbers}
|
|
80
|
+
* @returns {Promise<ValidationResult<{ duration: number }> & ValidationResultExtra>} The validation outcome.
|
|
81
|
+
*/
|
|
82
|
+
export async function validateAudioVideo({ inputData, mimeType }) {
|
|
83
|
+
try {
|
|
84
|
+
if (!(inputData instanceof Blob))
|
|
85
|
+
throw new TypeError('InputData must be a Blob or File.');
|
|
86
|
+
return new Promise((resolve) => {
|
|
87
|
+
const isAudio = mimeType.startsWith('audio/');
|
|
88
|
+
const mediaElement = document.createElement(isAudio ? 'audio' : 'video');
|
|
89
|
+
const url = URL.createObjectURL(inputData);
|
|
90
|
+
mediaElement.preload = 'metadata';
|
|
91
|
+
mediaElement.onloadedmetadata = () => {
|
|
92
|
+
URL.revokeObjectURL(url);
|
|
93
|
+
if (isNaN(mediaElement.duration) || mediaElement.duration === 0) {
|
|
94
|
+
resolve({
|
|
95
|
+
mimeType: null,
|
|
96
|
+
error: 'Media structure corrupted: Missing duration in browser.',
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
resolve({ mimeType, error: null, data: { duration: mediaElement.duration } });
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
mediaElement.onerror = () => {
|
|
104
|
+
URL.revokeObjectURL(url);
|
|
105
|
+
resolve({
|
|
106
|
+
mimeType: null,
|
|
107
|
+
error: 'Native browser decoder failed to parse media container.',
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
mediaElement.src = url;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
console.error(err);
|
|
115
|
+
return {
|
|
116
|
+
mimeType: null,
|
|
117
|
+
error: err instanceof Error ? err.message : 'Unknown Error',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @template T
|
|
5
|
+
* @typedef {Object} ValidationResult
|
|
6
|
+
* @property {string|null} error - The error message if validation failed.
|
|
7
|
+
* @property {T} [data]
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {import('stream').Readable} Readable
|
|
12
|
+
* @typedef {typeof import('stream').Readable} ConstructorReadable
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {import('file-type').FileTypeResult} FileTypeResult
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* LAYER 1: Fast Binary Validation (Magic Numbers)
|
|
21
|
+
* Validates if the file header matches expected media categories.
|
|
22
|
+
*
|
|
23
|
+
* `file-type@22.0.2` npm package.
|
|
24
|
+
*
|
|
25
|
+
* @param {Object} options
|
|
26
|
+
* @param {Buffer} options.buffer - The raw file buffer from the upload.
|
|
27
|
+
* @param {'image' | 'audio' | 'video'} options.expectedType - The expected media category.
|
|
28
|
+
* @param {(buffer: Uint8Array | ArrayBuffer) => Promise<FileTypeResult | undefined>} options.fileTypeFromBuffer
|
|
29
|
+
* @returns {Promise<string>} Resolves with the confirmed MIME type if valid.
|
|
30
|
+
* @throws {Error} If the file signature does not match the expected type.
|
|
31
|
+
*/
|
|
32
|
+
async function validateMagicNumbers({ buffer, expectedType, fileTypeFromBuffer }) {
|
|
33
|
+
const detected = await fileTypeFromBuffer(buffer);
|
|
34
|
+
|
|
35
|
+
if (!detected) {
|
|
36
|
+
throw new Error('File signature could not be identified (Unknown Magic Numbers).');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const mime = detected.mime;
|
|
40
|
+
const isTypeValid = {
|
|
41
|
+
image: mime.startsWith('image/'),
|
|
42
|
+
audio: mime.startsWith('audio/'),
|
|
43
|
+
video: mime.startsWith('video/') || mime === 'application/x-mpegurl', // Handles some streaming formats
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
if (!isTypeValid[expectedType]) {
|
|
47
|
+
throw new Error(`Security Alert: File disguised as ${expectedType}. Actual MIME type: ${mime}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return mime;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @typedef {import('sharp').SharpConstructor} SharpConstructor
|
|
55
|
+
* @typedef {import('sharp').Sharp} Sharp
|
|
56
|
+
* @typedef {import('sharp').Metadata} SharpMetadata
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* LAYER 2 (IMAGE): Structural and metadata validation for images.
|
|
61
|
+
* Forces the decoding engine to parse the image structure to detect hidden exploits.
|
|
62
|
+
*
|
|
63
|
+
* `sharp@0.35.4` npm package.
|
|
64
|
+
*
|
|
65
|
+
* @param {Object} options
|
|
66
|
+
* @param {Buffer} options.buffer - The raw image buffer.
|
|
67
|
+
* @param {SharpConstructor} options.Sharp
|
|
68
|
+
* @returns {Promise<ValidationResult<{ data: Sharp; metadata: SharpMetadata }>>} The validation outcome.
|
|
69
|
+
*/
|
|
70
|
+
async function validateImage({ buffer, Sharp }) {
|
|
71
|
+
try {
|
|
72
|
+
// Deep structural parsing (Checks for corrupted structures or embedded malicious scripts)
|
|
73
|
+
// sharp().metadata() forces the libvips C++ library to completely parse the image header/payload.
|
|
74
|
+
const data = Sharp(buffer);
|
|
75
|
+
const metadata = await data.metadata();
|
|
76
|
+
|
|
77
|
+
return { error: null, data: { data, metadata } };
|
|
78
|
+
} catch (err) {
|
|
79
|
+
console.error(err);
|
|
80
|
+
return {
|
|
81
|
+
error: err instanceof Error ? err.message : 'Unknown Error',
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @typedef {import('music-metadata').IAudioMetadata} IAudioMetadata
|
|
88
|
+
* @typedef {import('music-metadata').IFileInfo} IFileInfo
|
|
89
|
+
* @typedef {import('music-metadata').IOptions} IOptions
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* LAYER 2 (AUDIO/VIDEO): Deep validation for audio files using native JS metadata parsing.
|
|
94
|
+
* Validates audio headers, durations, and container integrity without external tools.
|
|
95
|
+
*
|
|
96
|
+
* `music-metadata@11.15.0` npm package.
|
|
97
|
+
*
|
|
98
|
+
* @param {Object} options
|
|
99
|
+
* @param {Buffer} options.buffer - The raw media buffer.
|
|
100
|
+
* @param {(stream: Readable, fileInfo?: IFileInfo | string, options?: IOptions) => Promise<IAudioMetadata>} [options.parseStream]
|
|
101
|
+
* @param {(uint8Array: Uint8Array<ArrayBufferLike>, fileInfo?: IFileInfo | string, options?: IOptions) => Promise<IAudioMetadata>} [options.parseBuffer]
|
|
102
|
+
* @param {ConstructorReadable} [options.Readable]
|
|
103
|
+
* @returns {Promise<ValidationResult<IAudioMetadata>>} The validation outcome.
|
|
104
|
+
*/
|
|
105
|
+
async function validateAudioVideo({ buffer, parseBuffer }) {
|
|
106
|
+
try {
|
|
107
|
+
// Deep metadata structural parsing
|
|
108
|
+
// music-metadata parses the container (ID3 tags, RIFF headers, FLAC blocks).
|
|
109
|
+
// If the file is a disguised script, the parser will fail to find valid audio frames.
|
|
110
|
+
const metadata = await (parseBuffer ? parseBuffer(buffer) : null);
|
|
111
|
+
|
|
112
|
+
if (!metadata || !metadata.format || typeof metadata.format.duration !== 'number') {
|
|
113
|
+
throw new Error('Audio file structure is corrupted or missing explicit audio streams.');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return { error: null, data: metadata };
|
|
117
|
+
} catch (err) {
|
|
118
|
+
console.error(err);
|
|
119
|
+
return {
|
|
120
|
+
error: err instanceof Error ? err.message : 'Unknown Error',
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
exports.validateAudioVideo = validateAudioVideo;
|
|
126
|
+
exports.validateImage = validateImage;
|
|
127
|
+
exports.validateMagicNumbers = validateMagicNumbers;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @template T
|
|
3
|
+
* @typedef {Object} ValidationResult
|
|
4
|
+
* @property {string|null} error - The error message if validation failed.
|
|
5
|
+
* @property {T} [data]
|
|
6
|
+
*/
|
|
7
|
+
export type ValidationResult<T> = {
|
|
8
|
+
/**
|
|
9
|
+
* - The error message if validation failed.
|
|
10
|
+
*/
|
|
11
|
+
error: string | null;
|
|
12
|
+
data?: T;
|
|
13
|
+
};
|
|
14
|
+
export type Readable = import('stream').Readable;
|
|
15
|
+
export type ConstructorReadable = typeof import('stream').Readable;
|
|
16
|
+
export type FileTypeResult = import('file-type').FileTypeResult;
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {import('stream').Readable} Readable
|
|
19
|
+
* @typedef {typeof import('stream').Readable} ConstructorReadable
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {import('file-type').FileTypeResult} FileTypeResult
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* LAYER 1: Fast Binary Validation (Magic Numbers)
|
|
26
|
+
* Validates if the file header matches expected media categories.
|
|
27
|
+
*
|
|
28
|
+
* `file-type@22.0.2` npm package.
|
|
29
|
+
*
|
|
30
|
+
* @param {Object} options
|
|
31
|
+
* @param {Buffer} options.buffer - The raw file buffer from the upload.
|
|
32
|
+
* @param {'image' | 'audio' | 'video'} options.expectedType - The expected media category.
|
|
33
|
+
* @param {(buffer: Uint8Array | ArrayBuffer) => Promise<FileTypeResult | undefined>} options.fileTypeFromBuffer
|
|
34
|
+
* @returns {Promise<string>} Resolves with the confirmed MIME type if valid.
|
|
35
|
+
* @throws {Error} If the file signature does not match the expected type.
|
|
36
|
+
*/
|
|
37
|
+
export declare function validateMagicNumbers({ buffer, expectedType, fileTypeFromBuffer }: {
|
|
38
|
+
buffer: Buffer;
|
|
39
|
+
expectedType: 'image' | 'audio' | 'video';
|
|
40
|
+
fileTypeFromBuffer: (buffer: Uint8Array | ArrayBuffer) => Promise<FileTypeResult | undefined>;
|
|
41
|
+
}): Promise<string>;
|
|
42
|
+
export type SharpConstructor = import('sharp').SharpConstructor;
|
|
43
|
+
export type Sharp = import('sharp').Sharp;
|
|
44
|
+
export type SharpMetadata = import('sharp').Metadata;
|
|
45
|
+
/**
|
|
46
|
+
* @typedef {import('sharp').SharpConstructor} SharpConstructor
|
|
47
|
+
* @typedef {import('sharp').Sharp} Sharp
|
|
48
|
+
* @typedef {import('sharp').Metadata} SharpMetadata
|
|
49
|
+
*/
|
|
50
|
+
/**
|
|
51
|
+
* LAYER 2 (IMAGE): Structural and metadata validation for images.
|
|
52
|
+
* Forces the decoding engine to parse the image structure to detect hidden exploits.
|
|
53
|
+
*
|
|
54
|
+
* `sharp@0.35.4` npm package.
|
|
55
|
+
*
|
|
56
|
+
* @param {Object} options
|
|
57
|
+
* @param {Buffer} options.buffer - The raw image buffer.
|
|
58
|
+
* @param {SharpConstructor} options.Sharp
|
|
59
|
+
* @returns {Promise<ValidationResult<{ data: Sharp; metadata: SharpMetadata }>>} The validation outcome.
|
|
60
|
+
*/
|
|
61
|
+
export declare function validateImage({ buffer, Sharp }: {
|
|
62
|
+
buffer: Buffer;
|
|
63
|
+
Sharp: SharpConstructor;
|
|
64
|
+
}): Promise<ValidationResult<{
|
|
65
|
+
data: Sharp;
|
|
66
|
+
metadata: SharpMetadata;
|
|
67
|
+
}>>;
|
|
68
|
+
export type IAudioMetadata = import('music-metadata').IAudioMetadata;
|
|
69
|
+
export type IFileInfo = import('music-metadata').IFileInfo;
|
|
70
|
+
export type IOptions = import('music-metadata').IOptions;
|
|
71
|
+
/**
|
|
72
|
+
* @typedef {import('music-metadata').IAudioMetadata} IAudioMetadata
|
|
73
|
+
* @typedef {import('music-metadata').IFileInfo} IFileInfo
|
|
74
|
+
* @typedef {import('music-metadata').IOptions} IOptions
|
|
75
|
+
*/
|
|
76
|
+
/**
|
|
77
|
+
* LAYER 2 (AUDIO/VIDEO): Deep validation for audio files using native JS metadata parsing.
|
|
78
|
+
* Validates audio headers, durations, and container integrity without external tools.
|
|
79
|
+
*
|
|
80
|
+
* `music-metadata@11.15.0` npm package.
|
|
81
|
+
*
|
|
82
|
+
* @param {Object} options
|
|
83
|
+
* @param {Buffer} options.buffer - The raw media buffer.
|
|
84
|
+
* @param {(stream: Readable, fileInfo?: IFileInfo | string, options?: IOptions) => Promise<IAudioMetadata>} [options.parseStream]
|
|
85
|
+
* @param {(uint8Array: Uint8Array<ArrayBufferLike>, fileInfo?: IFileInfo | string, options?: IOptions) => Promise<IAudioMetadata>} [options.parseBuffer]
|
|
86
|
+
* @param {ConstructorReadable} [options.Readable]
|
|
87
|
+
* @returns {Promise<ValidationResult<IAudioMetadata>>} The validation outcome.
|
|
88
|
+
*/
|
|
89
|
+
export declare function validateAudioVideo({ buffer, parseBuffer }: {
|
|
90
|
+
buffer: Buffer;
|
|
91
|
+
parseStream?: (stream: Readable, fileInfo?: IFileInfo | string, options?: IOptions) => Promise<IAudioMetadata>;
|
|
92
|
+
parseBuffer?: (uint8Array: Uint8Array<ArrayBufferLike>, fileInfo?: IFileInfo | string, options?: IOptions) => Promise<IAudioMetadata>;
|
|
93
|
+
Readable?: ConstructorReadable;
|
|
94
|
+
}): Promise<ValidationResult<IAudioMetadata>>;
|
|
95
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../../../../../../src/v1/webTemplates/media/MediaValidator/v1/Node/index.mjs"],"names":[],"mappings":"AAAA;;;;;GAKG;AAHA,YAAkB,gBAAgB,CADxB,CAAC,IAEX;;;;IAAwB,KAAK,EAAlB,MAAM,GAAC,IAAI,CACtB;IAAe,IAAI,AAAnB,CAAoB,EAAT,CAAC,CAAQ;CAAA,CAAA;AAIpB,YAAqC,QAAQ,GAAnC,OAAO,QAAQ,EAAE,QAAQ,CAAU;AAC7C,YAA4C,mBAAmB,GAArD,cAAc,QAAQ,EAAE,QAAQ,CAAqB;AAI/D,YAA8C,cAAc,GAAlD,OAAO,WAAW,EAAE,cAAc,CAAgB;AAN/D;;;GAGG;AAEH;;GAEG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAsB,oBAAoB,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,kBAAkB,EAAE,EANpF;IAAwB,MAAM,EAAtB,MAAM,CACd;IAA6C,YAAY,EAAjD,OAAO,GAAG,OAAO,GAAG,OAAO,CACnC;IAA2F,kBAAkB,EAArG,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,KAAK,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CACjF;CAGoF,GAH1E,OAAO,CAAC,MAAM,CAAC,CAsB3B;AAGE,YAA4C,gBAAgB,GAAlD,OAAO,OAAO,EAAE,gBAAgB,CAAkB;AAC5D,YAAiC,KAAK,GAA5B,OAAO,OAAO,EAAE,KAAK,CAAO;AACtC,YAAoC,aAAa,GAAvC,OAAO,OAAO,EAAE,QAAQ,CAAe;AAHpD;;;;GAIG;AAEH;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAJlD;IAAwB,MAAM,EAAtB,MAAM,CACd;IAAkC,KAAK,EAA/B,gBAAgB,CACxB;CAEkD,GAFxC,OAAO,CAAC,gBAAgB,CAAC;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,CAAC,CAAC,CAgB/E;AAGE,YAAmD,cAAc,GAAvD,OAAO,gBAAgB,EAAE,cAAc,CAAgB;AACjE,YAA8C,SAAS,GAA7C,OAAO,gBAAgB,EAAE,SAAS,CAAW;AACvD,YAA6C,QAAQ,GAA3C,OAAO,gBAAgB,EAAE,QAAQ,CAAU;AAHxD;;;;GAIG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAN7D;IAAwB,MAAM,EAAtB,MAAM,CACd;IAAmH,WAAW,AAA9H,CACA,EADQ,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,KAAK,OAAO,CAAC,cAAc,CAAC,CACxG;IAA0I,WAAW,AAArJ,CACA,EADQ,CAAC,UAAU,EAAE,UAAU,CAAC,eAAe,CAAC,EAAE,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,KAAK,OAAO,CAAC,cAAc,CAAC,CAC/H;IAAsC,QAAQ,AAA9C,CACA,EADQ,mBAAmB,CAC3B;CAE6D,GAFnD,OAAO,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,CAoBrD"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @template T
|
|
3
|
+
* @typedef {Object} ValidationResult
|
|
4
|
+
* @property {string|null} error - The error message if validation failed.
|
|
5
|
+
* @property {T} [data]
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {import('stream').Readable} Readable
|
|
9
|
+
* @typedef {typeof import('stream').Readable} ConstructorReadable
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {import('file-type').FileTypeResult} FileTypeResult
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* LAYER 1: Fast Binary Validation (Magic Numbers)
|
|
16
|
+
* Validates if the file header matches expected media categories.
|
|
17
|
+
*
|
|
18
|
+
* `file-type@22.0.2` npm package.
|
|
19
|
+
*
|
|
20
|
+
* @param {Object} options
|
|
21
|
+
* @param {Buffer} options.buffer - The raw file buffer from the upload.
|
|
22
|
+
* @param {'image' | 'audio' | 'video'} options.expectedType - The expected media category.
|
|
23
|
+
* @param {(buffer: Uint8Array | ArrayBuffer) => Promise<FileTypeResult | undefined>} options.fileTypeFromBuffer
|
|
24
|
+
* @returns {Promise<string>} Resolves with the confirmed MIME type if valid.
|
|
25
|
+
* @throws {Error} If the file signature does not match the expected type.
|
|
26
|
+
*/
|
|
27
|
+
export async function validateMagicNumbers({ buffer, expectedType, fileTypeFromBuffer }) {
|
|
28
|
+
const detected = await fileTypeFromBuffer(buffer);
|
|
29
|
+
if (!detected) {
|
|
30
|
+
throw new Error('File signature could not be identified (Unknown Magic Numbers).');
|
|
31
|
+
}
|
|
32
|
+
const mime = detected.mime;
|
|
33
|
+
const isTypeValid = {
|
|
34
|
+
image: mime.startsWith('image/'),
|
|
35
|
+
audio: mime.startsWith('audio/'),
|
|
36
|
+
video: mime.startsWith('video/') || mime === 'application/x-mpegurl', // Handles some streaming formats
|
|
37
|
+
};
|
|
38
|
+
if (!isTypeValid[expectedType]) {
|
|
39
|
+
throw new Error(`Security Alert: File disguised as ${expectedType}. Actual MIME type: ${mime}`);
|
|
40
|
+
}
|
|
41
|
+
return mime;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* @typedef {import('sharp').SharpConstructor} SharpConstructor
|
|
45
|
+
* @typedef {import('sharp').Sharp} Sharp
|
|
46
|
+
* @typedef {import('sharp').Metadata} SharpMetadata
|
|
47
|
+
*/
|
|
48
|
+
/**
|
|
49
|
+
* LAYER 2 (IMAGE): Structural and metadata validation for images.
|
|
50
|
+
* Forces the decoding engine to parse the image structure to detect hidden exploits.
|
|
51
|
+
*
|
|
52
|
+
* `sharp@0.35.4` npm package.
|
|
53
|
+
*
|
|
54
|
+
* @param {Object} options
|
|
55
|
+
* @param {Buffer} options.buffer - The raw image buffer.
|
|
56
|
+
* @param {SharpConstructor} options.Sharp
|
|
57
|
+
* @returns {Promise<ValidationResult<{ data: Sharp; metadata: SharpMetadata }>>} The validation outcome.
|
|
58
|
+
*/
|
|
59
|
+
export async function validateImage({ buffer, Sharp }) {
|
|
60
|
+
try {
|
|
61
|
+
// Deep structural parsing (Checks for corrupted structures or embedded malicious scripts)
|
|
62
|
+
// sharp().metadata() forces the libvips C++ library to completely parse the image header/payload.
|
|
63
|
+
const data = Sharp(buffer);
|
|
64
|
+
const metadata = await data.metadata();
|
|
65
|
+
return { error: null, data: { data, metadata } };
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
console.error(err);
|
|
69
|
+
return {
|
|
70
|
+
error: err instanceof Error ? err.message : 'Unknown Error',
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* @typedef {import('music-metadata').IAudioMetadata} IAudioMetadata
|
|
76
|
+
* @typedef {import('music-metadata').IFileInfo} IFileInfo
|
|
77
|
+
* @typedef {import('music-metadata').IOptions} IOptions
|
|
78
|
+
*/
|
|
79
|
+
/**
|
|
80
|
+
* LAYER 2 (AUDIO/VIDEO): Deep validation for audio files using native JS metadata parsing.
|
|
81
|
+
* Validates audio headers, durations, and container integrity without external tools.
|
|
82
|
+
*
|
|
83
|
+
* `music-metadata@11.15.0` npm package.
|
|
84
|
+
*
|
|
85
|
+
* @param {Object} options
|
|
86
|
+
* @param {Buffer} options.buffer - The raw media buffer.
|
|
87
|
+
* @param {(stream: Readable, fileInfo?: IFileInfo | string, options?: IOptions) => Promise<IAudioMetadata>} [options.parseStream]
|
|
88
|
+
* @param {(uint8Array: Uint8Array<ArrayBufferLike>, fileInfo?: IFileInfo | string, options?: IOptions) => Promise<IAudioMetadata>} [options.parseBuffer]
|
|
89
|
+
* @param {ConstructorReadable} [options.Readable]
|
|
90
|
+
* @returns {Promise<ValidationResult<IAudioMetadata>>} The validation outcome.
|
|
91
|
+
*/
|
|
92
|
+
export async function validateAudioVideo({ buffer, parseBuffer }) {
|
|
93
|
+
try {
|
|
94
|
+
// Deep metadata structural parsing
|
|
95
|
+
// music-metadata parses the container (ID3 tags, RIFF headers, FLAC blocks).
|
|
96
|
+
// If the file is a disguised script, the parser will fail to find valid audio frames.
|
|
97
|
+
const metadata = await (parseBuffer ? parseBuffer(buffer) : null);
|
|
98
|
+
if (!metadata || !metadata.format || typeof metadata.format.duration !== 'number') {
|
|
99
|
+
throw new Error('Audio file structure is corrupted or missing explicit audio streams.');
|
|
100
|
+
}
|
|
101
|
+
return { error: null, data: metadata };
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
console.error(err);
|
|
105
|
+
return {
|
|
106
|
+
error: err instanceof Error ? err.message : 'Unknown Error',
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|