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,123 @@
|
|
|
1
|
+
# 🛡️ MediaShield: Robust Media Validation Library
|
|
2
|
+
|
|
3
|
+
Welcome to **MediaShield**! This library is designed to provide security, multi-layered validation for media files (Images, Audio, and Video).
|
|
4
|
+
|
|
5
|
+
When building modern web applications, users often upload files. A common security risk is "File Spoofing," where a malicious actor renames a dangerous script (like `.exe` or `.js`) to a harmless extension (like `.jpg`). **MediaShield** prevents this by looking *inside* the file, not just at the filename.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🚀 Core Concept: The Two-Layer Defense
|
|
10
|
+
|
|
11
|
+
MediaShield operates on a "Defense in Depth" principle. We don't just trust the file extension; we verify the actual data.
|
|
12
|
+
|
|
13
|
+
1. **Layer 1: Magic Number Validation (The Identity Check) 🔍**
|
|
14
|
+
We inspect the "Magic Numbers" (the first few bytes of a file). This tells us what the file *actually* is, regardless of its name.
|
|
15
|
+
2. **Layer 2: Structural Validation (The Integrity Check) 🏗️**
|
|
16
|
+
Once we know the identity, we ask the browser to attempt to decode the file. If the browser cannot read the internal structure (like height/width for images or duration for video), the file is considered corrupted or malicious.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 📖 API Reference
|
|
21
|
+
|
|
22
|
+
### 1. `validateMagicNumbers`
|
|
23
|
+
The first line of defense. It checks the binary signature of the file.
|
|
24
|
+
|
|
25
|
+
| Parameter | Type | Description |
|
|
26
|
+
| :--- | :--- | :--- |
|
|
27
|
+
| `inputData` | `Buffer \| Uint8Array \| Blob` | The raw binary data of the file. |
|
|
28
|
+
| `expectedType` | `'image' \| 'audio' \| 'video'` | The category you are expecting. |
|
|
29
|
+
| `fileTypeFromBuffer` | `Function` | A callback function that identifies MIME types from buffers. |
|
|
30
|
+
|
|
31
|
+
**Returns:** `Promise<string>` (The confirmed MIME type).
|
|
32
|
+
**Throws:** `Error` if the signature doesn't match the expected category.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
### 2. `validateImage`
|
|
37
|
+
Deep structural validation specifically for images.
|
|
38
|
+
|
|
39
|
+
| Parameter | Type | Description |
|
|
40
|
+
| :--- | :--- | :--- |
|
|
41
|
+
| `inputData` | `Blob` | The image file as a Blob. |
|
|
42
|
+
|
|
43
|
+
**Returns:** `Promise<ValidationResult>`
|
|
44
|
+
* **On Success:** `{ mimeType, error: null, data: { width, height, format } }`
|
|
45
|
+
* **On Failure:** `{ mimeType: null, error: "Error message" }`
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
### 3. `validateAudioVideo`
|
|
50
|
+
Deep structural validation for multimedia containers.
|
|
51
|
+
|
|
52
|
+
| Parameter | Type | Description |
|
|
53
|
+
| :--- | :--- | :--- |
|
|
54
|
+
| `inputData` | `Blob` | The media file as a Blob. |
|
|
55
|
+
| `mimeType` | `string` | The MIME type obtained from `validateMagicNumbers`. |
|
|
56
|
+
|
|
57
|
+
**Returns:** `Promise<ValidationResult>`
|
|
58
|
+
* **On Success:** `{ mimeType, error: null, data: { duration } }`
|
|
59
|
+
* **On Failure:** `{ mimeType: null, error: "Error message" }`
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 🛠️ Daily Workflow: How to use it
|
|
64
|
+
|
|
65
|
+
To use MediaShield in your project, you should follow this logical sequence to ensure security.
|
|
66
|
+
|
|
67
|
+
### Step-by-Step Implementation Guide
|
|
68
|
+
|
|
69
|
+
1. **Step 1: Capture the File** 📥
|
|
70
|
+
Get the file from an `<input type="file">` element.
|
|
71
|
+
2. **Step 2: Run Magic Number Check** 🛡️
|
|
72
|
+
Call `validateMagicNumbers`. If this fails, stop immediately. The file is a spoof.
|
|
73
|
+
3. **Step 3: Perform Deep Validation** 🏗️
|
|
74
|
+
Based on the result of Step 2, call either `validateImage` or `validateAudioVideo`.
|
|
75
|
+
4. **Step 4: Proceed or Reject** ✅
|
|
76
|
+
If both layers pass, the file is safe to upload to your server.
|
|
77
|
+
|
|
78
|
+
### 💻 Code Example
|
|
79
|
+
|
|
80
|
+
Here is how you would implement the full pipeline in a real-world scenario:
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
import { validateMagicNumbers, validateImage, validateAudioVideo } from 'tiny-essentials/webTemplates/media/MediaValidator/v1/Browser';
|
|
84
|
+
|
|
85
|
+
async function handleFileUpload(fileBlob) {
|
|
86
|
+
try {
|
|
87
|
+
const fileDetector = async () => ({ mime: fileBlob.type });
|
|
88
|
+
|
|
89
|
+
// --- LAYER 1: Identity Check ---
|
|
90
|
+
const confirmedMime = await validateMagicNumbers({
|
|
91
|
+
inputData: fileBlob,
|
|
92
|
+
expectedType: 'image',
|
|
93
|
+
fileTypeFromBuffer: fileDetector
|
|
94
|
+
});
|
|
95
|
+
console.log(`✅ Identity confirmed: ${confirmedMime}`);
|
|
96
|
+
|
|
97
|
+
// --- LAYER 2: Structural Check ---
|
|
98
|
+
const validation = await validateImage({
|
|
99
|
+
inputData: fileBlob
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
if (validation.error) {
|
|
103
|
+
throw new Error(`❌ Structural validation failed: ${validation.error}`);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.log(`🎉 File is safe! Dimensions: ${validation.data.width}x${validation.data.height}`);
|
|
107
|
+
return validation.data;
|
|
108
|
+
|
|
109
|
+
} catch (error) {
|
|
110
|
+
console.error(`🚨 Security/Validation Error: ${error.message}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Usage
|
|
115
|
+
const fileInput = document.querySelector('input[type="file"]');
|
|
116
|
+
fileInput.addEventListener('change', (e) => handleFileUpload(e.target.files[0]));
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## ⚠️ Security Notes
|
|
122
|
+
* **Always** perform Layer 1 validation on the client side for immediate user feedback.
|
|
123
|
+
* **Crucial:** Client-side validation is for UX and basic security. Always perform a second round of validation on your **Server/Backend** before saving files to permanent storage.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# 🛡️ Secure Media Validator
|
|
2
|
+
|
|
3
|
+
A multi-layered validation toolkit designed to ensure file integrity and prevent security exploits such as **MIME-spoofing** (where a malicious file is disguised with a fake extension).
|
|
4
|
+
|
|
5
|
+
## 📋 Overview
|
|
6
|
+
|
|
7
|
+
When handling file uploads, simply checking a file extension (like `.jpg`) is not enough. An attacker can rename a malicious script to `image.jpg`. This project implements a two-layer defense strategy:
|
|
8
|
+
|
|
9
|
+
1. **Layer 1: Fast Binary Validation (Magic Numbers) 🔍**
|
|
10
|
+
Checks the actual file header (the first few bytes) to see if the internal signature matches the expected category.
|
|
11
|
+
2. **Layer 2: Deep Structural Validation 🏗️**
|
|
12
|
+
Forces the system to parse the internal structure of the file (metadata/frames) to ensure the file isn't just a valid header followed by corrupted or malicious data.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 📦 Dependencies
|
|
17
|
+
|
|
18
|
+
To use this toolkit, you must have the following packages installed in your project:
|
|
19
|
+
|
|
20
|
+
* `file-type`: For magic number detection.
|
|
21
|
+
* `sharp`: For deep image structural analysis.
|
|
22
|
+
* `music-metadata`: For deep audio/video container parsing.
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install file-type sharp music-metadata
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 🛠️ API Reference
|
|
31
|
+
|
|
32
|
+
### 1. Layer 1: `validateMagicNumbers` 🔍
|
|
33
|
+
|
|
34
|
+
This is your first line of defense. It is extremely fast because it only reads the beginning of the file.
|
|
35
|
+
|
|
36
|
+
**Purpose:** To verify that the file's internal "signature" matches the category you expect (image, audio, or video).
|
|
37
|
+
|
|
38
|
+
| Parameter | Type | Description |
|
|
39
|
+
| :--- | :--- | :--- |
|
|
40
|
+
| `buffer` | `Buffer` | The raw binary data of the uploaded file. |
|
|
41
|
+
| `expectedType` | `'image' \| 'audio' \| 'video'` | The category you are expecting. |
|
|
42
|
+
| `fileTypeFromBuffer` | `Function` | The `fileTypeFromBuffer` function from the `file-type` package. |
|
|
43
|
+
|
|
44
|
+
**Returns:** `Promise<string>` (The confirmed MIME type).
|
|
45
|
+
**Throws:** `Error` if the signature is unknown or does not match the `expectedType`.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
### 2. Layer 2 (Images): `validateImage` 🖼️
|
|
50
|
+
|
|
51
|
+
Once the magic numbers are confirmed, use this to inspect the image's internal structure.
|
|
52
|
+
|
|
53
|
+
**Purpose:** Uses the `sharp` engine to parse the image. This detects "Polyglot" files (files that are valid in two different formats) or files with corrupted headers designed to exploit image parsers.
|
|
54
|
+
|
|
55
|
+
| Parameter | Type | Description |
|
|
56
|
+
| :--- | :--- | :--- |
|
|
57
|
+
| `buffer` | `Buffer` | The raw image buffer. |
|
|
58
|
+
| `Sharp` | `SharpConstructor` | The `sharp` constructor. |
|
|
59
|
+
|
|
60
|
+
**Returns:** `Promise<ValidationResult<{ data: Sharp, metadata: SharpMetadata }>>`
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
### 3. Layer 2 (Audio/Video): `validateAudioVideo` 🎵
|
|
65
|
+
|
|
66
|
+
For media files, we need to ensure the container (like MP3 or MP4) is actually intact.
|
|
67
|
+
|
|
68
|
+
**Purpose:** Uses `music-metadata` to parse the container. It ensures the file contains valid audio/video streams and a valid duration.
|
|
69
|
+
|
|
70
|
+
| Parameter | Type | Description |
|
|
71
|
+
| :--- | :--- | :--- |
|
|
72
|
+
| `buffer` | `Buffer` | The raw media buffer. |
|
|
73
|
+
| `parseBuffer` | `Function` | The `parseBuffer` function from `music-metadata`. |
|
|
74
|
+
|
|
75
|
+
**Returns:** `Promise<ValidationResult<IAudioMetadata>>`
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 🚀 Implementation Guide: Daily Workflow
|
|
80
|
+
|
|
81
|
+
To implement this in a real-world upload service, you should follow this sequential logic. **Do not skip Layer 1**, as Layer 2 is more computationally expensive.
|
|
82
|
+
|
|
83
|
+
### 🛠️ Step-by-Step Integration
|
|
84
|
+
|
|
85
|
+
1. **Receive the file** as a Buffer from your upload middleware (e.g., Multer).
|
|
86
|
+
2. **Run `validateMagicNumbers`**: If this fails, reject the upload immediately.
|
|
87
|
+
3. **Branch by Type**:
|
|
88
|
+
* If `mimeType` starts with `image/` $\rightarrow$ Call `validateImage`.
|
|
89
|
+
* If `mimeType` is `audio/` or `video/` $\rightarrow$ Call `validateAudioVideo`.
|
|
90
|
+
4. **Handle the Result**: If the `error` property is present in the result, reject the upload and log the security event.
|
|
91
|
+
|
|
92
|
+
### 💻 Code Example
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
import { validateMagicNumbers, validateImage } from 'tiny-essentials/webTemplates/media/MediaValidator/v1/Node';
|
|
96
|
+
import fileType from 'file-type';
|
|
97
|
+
import sharp from 'sharp';
|
|
98
|
+
|
|
99
|
+
async function handleUpload(fileBuffer, userExpectedType) {
|
|
100
|
+
try {
|
|
101
|
+
// STEP 1: Fast Check
|
|
102
|
+
const mimeType = await validateMagicNumbers({
|
|
103
|
+
buffer: fileBuffer,
|
|
104
|
+
expectedType: userExpectedType,
|
|
105
|
+
fileTypeFromBuffer: fileType.fileTypeFromBuffer
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// STEP 2: Deep Check (if it's an image)
|
|
109
|
+
if (mimeType.startsWith('image/')) {
|
|
110
|
+
const result = await validateImage({
|
|
111
|
+
buffer: fileBuffer,
|
|
112
|
+
Sharp: sharp
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
if (result.error) {
|
|
116
|
+
console.error("❌ Image Security Violation:", result.error);
|
|
117
|
+
return { success: false, message: "Invalid image structure." };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
console.log("✅ Image is safe and valid:", result.metadata.format);
|
|
121
|
+
return { success: true, data: result.data };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// ... handle audio/video similarly
|
|
125
|
+
|
|
126
|
+
} catch (error) {
|
|
127
|
+
console.error("🚨 Security Block:", error.message);
|
|
128
|
+
return { success: false, message: error.message };
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## ⚠️ Security Notes
|
|
134
|
+
|
|
135
|
+
* **Error Handling:** The `ValidationResult` object is used to prevent the application from crashing during deep parsing. Always check `if (result.error)` before accessing `result.data`.
|
|
136
|
+
* **Performance:** Layer 2 functions are CPU-intensive. Always run them in a worker thread or ensure your server has adequate resources if handling high volumes of uploads.
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# 🧬 IPFS Hasher
|
|
2
|
+
|
|
3
|
+
> Generate **IPFS Content Identifiers (CIDs)** locally, in pure JavaScript, without running an IPFS node.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 📖 Table of Contents
|
|
8
|
+
|
|
9
|
+
- [What Is This?](#-what-is-this)
|
|
10
|
+
- [Why Would I Use This?](#-why-would-i-use-this)
|
|
11
|
+
- [Core Concepts (Read This First)](#-core-concepts-read-this-first)
|
|
12
|
+
- [Quick Start](#-quick-start)
|
|
13
|
+
- [API Reference](#-api-reference)
|
|
14
|
+
- [Class: `IPFSHasher`](#class-ipfshasher)
|
|
15
|
+
- [`new IPFSHasher(version)`](#new-ipfshasherversion)
|
|
16
|
+
- [`hasher.generate(data)`](#hashergeneratedata)
|
|
17
|
+
- [Type: `CIDGenerationResult`](#type-cidgenerationresult)
|
|
18
|
+
- [Choosing Between v0 and v1](#-choosing-between-v0-and-v1)
|
|
19
|
+
- [Error Handling](#-error-handling)
|
|
20
|
+
- [Known Limitations](#-known-limitations)
|
|
21
|
+
- [Project Structure](#-project-structure)
|
|
22
|
+
- [FAQ](#-faq)
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 🎯 What Is This?
|
|
27
|
+
|
|
28
|
+
`IPFSHasher` is a small, dependency-light utility class that turns **raw bytes into an IPFS CID**.
|
|
29
|
+
|
|
30
|
+
It does **one thing**: it takes a `Uint8Array` and returns a content identifier. That is all.
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
┌──────────────┐ ┌─────────────────┐ ┌──────────────────────────────┐
|
|
34
|
+
│ Your bytes │ ───▶ │ sha2-256 hash │ ───▶ │ CID string ("bafkrei..." ) │
|
|
35
|
+
└──────────────┘ └─────────────────┘ └──────────────────────────────┘
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**What it does NOT do:**
|
|
39
|
+
|
|
40
|
+
- ❌ It does **not** connect to the IPFS network.
|
|
41
|
+
- ❌ It does **not** upload, pin, or store anything.
|
|
42
|
+
- ❌ It does **not** require a running daemon.
|
|
43
|
+
|
|
44
|
+
It is a pure function with a class wrapper. That makes it safe to use in build scripts, CI pipelines, browsers, and serverless functions.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 💡 Why Would I Use This?
|
|
49
|
+
|
|
50
|
+
| Use case | How this helps |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| 🗄️ **Content-addressable cache** | Use the CID as a cache key. Identical bytes always produce an identical key. |
|
|
53
|
+
| 📦 **Build artifact verification** | Hash a build output and compare it against a published manifest. |
|
|
54
|
+
| 🔍 **Duplicate detection** | Two files with the same CID have identical content. Guaranteed. |
|
|
55
|
+
| 🌐 **Pre-upload preparation** | Compute the CID before uploading so you can store the reference in a database first. |
|
|
56
|
+
| 🧪 **Testing IPFS integrations** | Assert that your upload code produces the expected CID, without a network. |
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 🧠 Core Concepts (Read This First)
|
|
61
|
+
|
|
62
|
+
If you are new to IPFS, read this section. It will save you hours.
|
|
63
|
+
|
|
64
|
+
### What is a CID?
|
|
65
|
+
|
|
66
|
+
A **CID (Content Identifier)** is a self-describing hash. It contains:
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
bafkreiabc123...
|
|
70
|
+
│ │ │
|
|
71
|
+
│ │ └── The hash digest itself
|
|
72
|
+
│ └─────── The codec (how to interpret the bytes)
|
|
73
|
+
└────────── The version + encoding prefix
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Because the metadata is *inside* the string, a CID is portable. Anyone can look at it and know how to verify it.
|
|
77
|
+
|
|
78
|
+
### The three pieces
|
|
79
|
+
|
|
80
|
+
| Piece | Meaning | Values used here |
|
|
81
|
+
| --- | --- | --- |
|
|
82
|
+
| **Version** | The CID format version. | `v0` or `v1` |
|
|
83
|
+
| **Codec** | How to interpret the bytes. | `dag-pb` (`0x70`) or `raw` (`0x55`) |
|
|
84
|
+
| **Hash** | The digest algorithm. | `sha2-256` |
|
|
85
|
+
|
|
86
|
+
### The critical rule
|
|
87
|
+
|
|
88
|
+
> ⚠️ **The same bytes produce different CIDs in v0 and v1.**
|
|
89
|
+
>
|
|
90
|
+
> This is not a bug. It is by design. v0 is locked to the `dag-pb` codec; v1 lets you choose. Different codec means a different CID.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 🚀 Quick Start
|
|
95
|
+
|
|
96
|
+
```javascript
|
|
97
|
+
import { readFile } from 'node:fs/promises';
|
|
98
|
+
import IPFSHasher from 'tiny-essentials/webTemplates/multiformats/14.0/IPFSHasher';
|
|
99
|
+
|
|
100
|
+
// 1. Read some bytes. A Buffer IS a Uint8Array, so this works directly.
|
|
101
|
+
const bytes = await readFile('./hello.txt');
|
|
102
|
+
|
|
103
|
+
// 2. Create a hasher. Defaults to CIDv1.
|
|
104
|
+
const hasher = new IPFSHasher('v1');
|
|
105
|
+
|
|
106
|
+
// 3. Generate the CID.
|
|
107
|
+
const result = await hasher.generate(bytes);
|
|
108
|
+
|
|
109
|
+
console.log(result.cidString); // "bafkreifz..."
|
|
110
|
+
console.log(result.version); // "v1"
|
|
111
|
+
console.log(result.codec); // 85
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Expected output:**
|
|
115
|
+
|
|
116
|
+
```text
|
|
117
|
+
bafkreieq5jui4j25lacwomsqgvn7mq3d3h5c5c5c5c5c5c5c5c5c5c5c5c5
|
|
118
|
+
v1
|
|
119
|
+
85
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 📚 API Reference
|
|
125
|
+
|
|
126
|
+
### Class: `IPFSHasher`
|
|
127
|
+
|
|
128
|
+
A stateless CID generator. Create one instance per version and reuse it.
|
|
129
|
+
|
|
130
|
+
> 💡 **Why a class instead of a function?**
|
|
131
|
+
> The version is the only piece of state. Storing it in a private field (`#version`) means you cannot accidentally mutate it from the outside. The class is immutable after construction.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### `new IPFSHasher(version)`
|
|
136
|
+
|
|
137
|
+
Creates a new hasher.
|
|
138
|
+
|
|
139
|
+
| Parameter | Type | Default | Description |
|
|
140
|
+
| --- | --- | --- | --- |
|
|
141
|
+
| `version` | `'v0' \| 'v1'` | `'v1'` | The CID version to generate. |
|
|
142
|
+
|
|
143
|
+
**Throws:** `TypeError` if `version` is not `'v0'` or `'v1'`.
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
const v1 = new IPFSHasher(); // Defaults to 'v1'
|
|
147
|
+
const v0 = new IPFSHasher('v0'); // Explicit
|
|
148
|
+
|
|
149
|
+
new IPFSHasher('v2');
|
|
150
|
+
// TypeError: Invalid CID version. Use "v0" or "v1".
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
### `hasher.generate(data)`
|
|
156
|
+
|
|
157
|
+
Generates a CID from raw bytes.
|
|
158
|
+
|
|
159
|
+
| Parameter | Type | Description |
|
|
160
|
+
| --- | --- | --- |
|
|
161
|
+
| `data` | `Uint8Array` | The raw bytes to hash. |
|
|
162
|
+
|
|
163
|
+
**Returns:** `Promise<CIDGenerationResult>`
|
|
164
|
+
|
|
165
|
+
**Throws:** `TypeError` if `data` is not a `Uint8Array`.
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
const hasher = new IPFSHasher('v1');
|
|
169
|
+
const result = await hasher.generate(new Uint8Array([1, 2, 3]));
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
> ⚠️ **`Buffer` works, `ArrayBuffer` does not.**
|
|
173
|
+
> `Buffer` extends `Uint8Array`, so it passes the check. A raw `ArrayBuffer` does **not**. Wrap it first:
|
|
174
|
+
>
|
|
175
|
+
> ```javascript
|
|
176
|
+
> const bytes = new Uint8Array(arrayBuffer);
|
|
177
|
+
> ```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
### Type: `CIDGenerationResult`
|
|
182
|
+
|
|
183
|
+
The object resolved by `generate()`.
|
|
184
|
+
|
|
185
|
+
| Property | Type | Description |
|
|
186
|
+
| --- | --- | --- |
|
|
187
|
+
| `cidString` | `string` | The string representation of the CID. |
|
|
188
|
+
| `version` | `'v0' \| 'v1'` | The CID version that was generated. |
|
|
189
|
+
| `hashAlgorithm` | `'sha256'` | The algorithm used for hashing. |
|
|
190
|
+
| `codec` | `number` | The multicodec code of the content. |
|
|
191
|
+
|
|
192
|
+
**Codec reference:**
|
|
193
|
+
|
|
194
|
+
| Constant | Value | Used by |
|
|
195
|
+
| --- | --- | --- |
|
|
196
|
+
| `CODEC_DAG_PB` | `0x70` (`112`) | Always used by v0. |
|
|
197
|
+
| `CODEC_RAW` | `0x55` (`85`) | Used by v1 in this project. |
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## ⚖️ Choosing Between v0 and v1
|
|
202
|
+
|
|
203
|
+
| | **CIDv0** | **CIDv1** |
|
|
204
|
+
| --- | --- | --- |
|
|
205
|
+
| **Prefix** | `Qm...` | `bafkrei...` |
|
|
206
|
+
| **Encoding** | base58btc | base32 (lowercase) |
|
|
207
|
+
| **Codec** | `dag-pb` (locked) | `raw` |
|
|
208
|
+
| **Case sensitive** | Yes | No |
|
|
209
|
+
| **Recommended for new projects** | ❌ No | ✅ **Yes** |
|
|
210
|
+
|
|
211
|
+
### 👉 Recommendation
|
|
212
|
+
|
|
213
|
+
**Use `v1` unless you have a specific reason not to.**
|
|
214
|
+
|
|
215
|
+
Reasons to use `v1`:
|
|
216
|
+
|
|
217
|
+
- ✅ It is case-insensitive, so it is safe in URLs and file names.
|
|
218
|
+
- ✅ It is future-proof. The codec is explicit.
|
|
219
|
+
- ✅ It is what `ipfs add --cid-version=1` produces.
|
|
220
|
+
|
|
221
|
+
Reasons to use `v0`:
|
|
222
|
+
|
|
223
|
+
- You must match a legacy system that only understands `Qm...` addresses.
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## 🚨 Error Handling
|
|
228
|
+
|
|
229
|
+
The class throws exactly one error type. Catch it explicitly.
|
|
230
|
+
|
|
231
|
+
| Condition | Error | Message |
|
|
232
|
+
| --- | --- | --- |
|
|
233
|
+
| Invalid version in constructor | `TypeError` | `Invalid CID version. Use "v0" or "v1".` |
|
|
234
|
+
| Non-`Uint8Array` in `generate()` | `TypeError` | `Expected Uint8Array, but received <type>.` |
|
|
235
|
+
|
|
236
|
+
### ✅ Correct pattern
|
|
237
|
+
|
|
238
|
+
```javascript
|
|
239
|
+
import IPFSHasher from 'tiny-essentials/webTemplates/multiformats/14.0/IPFSHasher';
|
|
240
|
+
|
|
241
|
+
try {
|
|
242
|
+
const hasher = new IPFSHasher('v1');
|
|
243
|
+
const { cidString } = await hasher.generate(new Uint8Array([1, 2, 3]));
|
|
244
|
+
console.log(cidString);
|
|
245
|
+
} catch (error) {
|
|
246
|
+
if (error instanceof TypeError) {
|
|
247
|
+
console.error('Invalid input:', error.message);
|
|
248
|
+
process.exit(1);
|
|
249
|
+
}
|
|
250
|
+
throw error;
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### ❌ Anti-pattern
|
|
255
|
+
|
|
256
|
+
```javascript
|
|
257
|
+
// Never do this. You lose the stack trace and the error type.
|
|
258
|
+
try {
|
|
259
|
+
await hasher.generate(data);
|
|
260
|
+
} catch {
|
|
261
|
+
console.log('Something went wrong');
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## ⚠️ Known Limitations
|
|
268
|
+
|
|
269
|
+
Be aware of these before you file a bug report.
|
|
270
|
+
|
|
271
|
+
| # | Limitation | Impact |
|
|
272
|
+
| --- | --- | --- |
|
|
273
|
+
| 1 | Empty input is allowed. | `new Uint8Array(0)` produces a valid CID. Validate upstream if you need to reject empty files. |
|
|
274
|
+
| 2 | The error message uses `typeof data`. | When `data` is `null`, the message reads `received object`. Cosmetic only. |
|
|
275
|
+
| 3 | Only `sha2-256` is supported. | Hardcoded. Adding `sha2-512` requires a code change. |
|
|
276
|
+
| 4 | `ArrayBuffer` is rejected. | Wrap it: `new Uint8Array(buffer)`. |
|
|
277
|
+
| 5 | No streaming. | The entire file must fit in memory. For files over ~500 MB, use a chunker. |
|
|
278
|
+
| 6 | No network access. | This is intentional. Use `kubo-rpc-client` or `helia` to publish. |
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## ❓ FAQ
|
|
283
|
+
|
|
284
|
+
<details>
|
|
285
|
+
<summary><strong>Do I need an IPFS node running?</strong></summary>
|
|
286
|
+
|
|
287
|
+
No. This library is completely offline. It only does math on bytes.
|
|
288
|
+
|
|
289
|
+
</details>
|
|
290
|
+
|
|
291
|
+
<details>
|
|
292
|
+
<summary><strong>Why does my CID start with <code>bafkrei</code> instead of <code>Qm</code>?</strong></summary>
|
|
293
|
+
|
|
294
|
+
Because you are generating a CIDv1 with the `raw` codec. `Qm...` addresses are always CIDv0 with the `dag-pb` codec. Pass `'v0'` to the constructor if you need the old format.
|
|
295
|
+
|
|
296
|
+
</details>
|
|
297
|
+
|
|
298
|
+
<details>
|
|
299
|
+
<summary><strong>Can I hash a file larger than RAM?</strong></summary>
|
|
300
|
+
|
|
301
|
+
Not with this class. It requires the full `Uint8Array` in memory. For large files, use a chunker such as `ipfs-unixfs-importer`.
|
|
302
|
+
|
|
303
|
+
</details>
|
|
304
|
+
|
|
305
|
+
<details>
|
|
306
|
+
<summary><strong>Why does <code>generate()</code> return a Promise if there is no I/O?</strong></summary>
|
|
307
|
+
|
|
308
|
+
Because `sha256.digest()` from `multiformats` is asynchronous. In a browser, it can delegate to `SubtleCrypto`, which is always async. The API stays consistent across environments.
|
|
309
|
+
|
|
310
|
+
</details>
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# 🚀 Tiny Vite PWA: Developer Documentation
|
|
2
|
+
|
|
3
|
+
Welcome to the official guide for **`tiny-vite-pwa`**! This plugin is designed to make Progressive Web App integration seamless within a Vite-based project. It handles the "heavy lifting" of PWA requirements so you can focus on building your application.
|
|
4
|
+
|
|
5
|
+
## 📋 Table of Contents
|
|
6
|
+
1. [Overview](#overview)
|
|
7
|
+
2. [Key Features](#key-features)
|
|
8
|
+
3. [Configuration Guide](#configuration-guide)
|
|
9
|
+
4. [Step-by-Step Implementation](#step-by-step-implementation)
|
|
10
|
+
5. [Developer Experience (Dev vs. Prod)](#developer-experience-dev-vs-prod)
|
|
11
|
+
6. [TypeScript Integration](#typescript-integration)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 🌟 Overview
|
|
16
|
+
`tiny-vite-pwa` is a lightweight Vite plugin that automates three critical PWA pillars:
|
|
17
|
+
1. **Manifest Management:** Automatically serves and bundles your `manifest.json`.
|
|
18
|
+
2. **Service Worker Lifecycle:** Bundles your Service Worker (SW) for production and provides Hot Module Replacement (HMR) during development.
|
|
19
|
+
3. **Automated Injection:** Injects the necessary `<link>` and `<script>` tags into your `index.html` automatically.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## ✨ Key Features
|
|
24
|
+
|
|
25
|
+
* 📦 **Automatic Bundling:** Uses Vite's internal build engine to bundle your Service Worker as an IIFE (Immediately Invoked Function Expression), ensuring compatibility.
|
|
26
|
+
* ⚡ **Hot Module Replacement (HMR):** When you save changes to your Service Worker file, the plugin detects it and notifies the frontend via a custom event.
|
|
27
|
+
* 🌐 **Global Manifest Access:** Optionally injects your manifest object into the global scope via `define`, making it accessible as `window.__TINY_PWA_MANIFEST__`.
|
|
28
|
+
* 🛡️ **Cache Busting:** Automatically appends version timestamps (`?v=...`) to your manifest and SW in production to prevent stale files.
|
|
29
|
+
* 🎨 **Clear Feedback:** Provides beautiful, color-coded terminal logs to track the plugin's status.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## ⚙️ Configuration Guide
|
|
34
|
+
|
|
35
|
+
When using the plugin, you will pass an options object to `TinyVitePwaPlugin()`. Below are the available properties:
|
|
36
|
+
|
|
37
|
+
| Property | Type | Default | Description |
|
|
38
|
+
| :--- | :--- | :--- | :--- |
|
|
39
|
+
| `manifest` | `Object` | **Required** | The complete Web App Manifest object. |
|
|
40
|
+
| `manifestPath` | `string` | **Required** | The URL path where the manifest should be served (e.g., `'/manifest.json'`). |
|
|
41
|
+
| `srcDir` | `string` | **Required** | The directory where your Service Worker source file is located. |
|
|
42
|
+
| `filename` | `string` | **Required** | The name of your Service Worker file (e.g., `'sw.js'`). |
|
|
43
|
+
| `injectRegister` | `boolean` | `true` | If `true`, the plugin injects the SW registration script into your `<head>`. |
|
|
44
|
+
| `injectManifestToGlobal` | `boolean` | `true` | If `true`, the manifest is available globally via `window.__TINY_PWA_MANIFEST__`. |
|
|
45
|
+
| `swRegistrationOptions` | `Object` | `undefined` | Standard `RegistrationOptions` passed to `navigator.serviceWorker.register`. |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 🛠️ Step-by-Step Implementation
|
|
50
|
+
|
|
51
|
+
Follow these steps to integrate the plugin into your project.
|
|
52
|
+
|
|
53
|
+
### 1. Prepare your Manifest
|
|
54
|
+
Create your manifest object. You can keep this in a separate file or define it directly in your config.
|
|
55
|
+
|
|
56
|
+
### 2. Create your Service Worker
|
|
57
|
+
Place your Service Worker file (e.g., `src/sw.js`) in your source directory.
|
|
58
|
+
|
|
59
|
+
### 3. Configure Vite
|
|
60
|
+
Update your `vite.config.js` as follows:
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
import { defineConfig } from 'vite';
|
|
64
|
+
import TinyVitePwaPlugin from 'tiny-essentials/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin';
|
|
65
|
+
|
|
66
|
+
export default defineConfig({
|
|
67
|
+
plugins: [
|
|
68
|
+
TinyVitePwaPlugin({
|
|
69
|
+
// 1. The Manifest Object
|
|
70
|
+
manifest: {
|
|
71
|
+
name: 'My Awesome App',
|
|
72
|
+
short_name: 'App',
|
|
73
|
+
start_url: '/',
|
|
74
|
+
display: 'standalone',
|
|
75
|
+
background_color: '#ffffff',
|
|
76
|
+
theme_color: '#000000',
|
|
77
|
+
icons: [
|
|
78
|
+
{ src: '/icon-192.png', sizes: '192x192', type: 'image/png' },
|
|
79
|
+
{ src: '/icon-512.png', sizes: '512x512', type: 'image/png' }
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
// 2. Paths and Filenames
|
|
83
|
+
manifestPath: '/manifest.json',
|
|
84
|
+
srcDir: 'src',
|
|
85
|
+
filename: 'sw.js',
|
|
86
|
+
// 3. Optional: Registration settings
|
|
87
|
+
swRegistrationOptions: {
|
|
88
|
+
scope: '/'
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
]
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 🔄 Developer Experience (Dev vs. Prod)
|
|
98
|
+
|
|
99
|
+
The plugin behaves differently depending on whether you are running a development server or building for production.
|
|
100
|
+
|
|
101
|
+
### 🛠️ In Development (`npm run dev`)
|
|
102
|
+
* **Manifest:** Served dynamically via a middleware.
|
|
103
|
+
* **Service Worker:** Served via Vite's transformer, allowing you to use ES6 imports inside your SW.
|
|
104
|
+
* **HMR:** If you modify your SW file, the plugin sends a `pwa:sw-updated` event to the browser.
|
|
105
|
+
* **Console:** You will see `[tiny-vite-pwa] [INFO]` logs in your terminal.
|
|
106
|
+
|
|
107
|
+
### 🚀 In Production (`npm run build`)
|
|
108
|
+
* **Manifest:** Emitted as a static `.json` file in your `dist` folder.
|
|
109
|
+
* **Service Worker:** Bundled into a single, optimized IIFE file in your `dist` folder.
|
|
110
|
+
* **Cache Busting:** The plugin adds `?v=[timestamp]` to the URLs in the HTML to ensure users always get the latest version.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 📘 TypeScript Integration
|
|
115
|
+
|
|
116
|
+
If you are using TypeScript, you need to tell the compiler that `__TINY_PWA_MANIFEST__` exists on the `window` object.
|
|
117
|
+
|
|
118
|
+
Add this to your `env.d.ts` file:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
declare global {
|
|
122
|
+
interface Window {
|
|
123
|
+
/**
|
|
124
|
+
* The Web App Manifest object injected by tiny-vite-pwa
|
|
125
|
+
*/
|
|
126
|
+
__TINY_PWA_MANIFEST__: Record<string, any>;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export {};
|
|
131
|
+
```
|