tiny-essentials 1.28.19 → 1.29.0

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.
Files changed (555) hide show
  1. package/README.md +1 -1
  2. package/changelog/1/28/19.md +24 -0
  3. package/changelog/1/29/0.md +58 -0
  4. package/dist/v1/ColorSafeStringify.min.js +1 -1
  5. package/dist/v1/TinyAdvancedRaffle.min.js +1 -1
  6. package/dist/v1/TinyAfterScrollWatcher.min.js +1 -1
  7. package/dist/v1/TinyAnalogClock.min.js +1 -1
  8. package/dist/v1/TinyArrayComparator.min.js +1 -1
  9. package/dist/v1/TinyArrayPaginator.min.js +1 -1
  10. package/dist/v1/TinyBasicsEs.min.js +1 -1
  11. package/dist/v1/TinyBrowserMonitor.min.js +1 -0
  12. package/dist/v1/TinyClassManager.min.js +1 -1
  13. package/dist/v1/TinyClipboard.min.js +1 -1
  14. package/dist/v1/TinyCloner.min.js +1 -0
  15. package/dist/v1/TinyColorConverter.min.js +1 -1
  16. package/dist/v1/TinyColorValidator.min.js +1 -1
  17. package/dist/v1/TinyCookieConsent.min.js +1 -1
  18. package/dist/v1/TinyDayNightCycle.min.js +1 -1
  19. package/dist/v1/TinyDebugger.min.js +1 -1
  20. package/dist/v1/TinyDomReadyManager.min.js +1 -1
  21. package/dist/v1/TinyDragDropDetector.min.js +1 -1
  22. package/dist/v1/TinyDragger.min.js +1 -1
  23. package/dist/v1/TinyElementObserver.min.js +1 -1
  24. package/dist/v1/TinyEssentials.min.js +1 -1
  25. package/dist/v1/TinyGamepad.min.js +1 -1
  26. package/dist/v1/TinyHtml.min.js +1 -1
  27. package/dist/v1/TinyHtmlTagRegexBuilder.min.js +1 -0
  28. package/dist/v1/TinyHttpResponseRegistry.min.js +1 -0
  29. package/dist/v1/TinyI18.min.js +1 -1
  30. package/dist/v1/TinyIframeEvents.min.js +1 -1
  31. package/dist/v1/TinyInventory.min.js +1 -1
  32. package/dist/v1/TinyInventoryTrader.min.js +1 -1
  33. package/dist/v1/TinyLevelUp.min.js +1 -1
  34. package/dist/v1/TinyLoadingScreen.min.js +1 -1
  35. package/dist/v1/TinyLocalStorage.min.js +1 -1
  36. package/dist/v1/TinyMaInSys.min.js +1 -1
  37. package/dist/v1/TinyMapCache.min.js +1 -0
  38. package/dist/v1/TinyMediaPlayer.min.js +1 -1
  39. package/dist/v1/TinyNeedBar.min.js +1 -1
  40. package/dist/v1/TinyNewWinEvents.min.js +1 -1
  41. package/dist/v1/TinyNotificationAdapter.min.js +1 -0
  42. package/dist/v1/TinyNotifications.min.js +1 -1
  43. package/dist/v1/TinyNotifyCenter.min.js +1 -1
  44. package/dist/v1/TinyOPFSFileSystem.min.js +1 -0
  45. package/dist/v1/TinyPasswordValidator.min.js +1 -0
  46. package/dist/v1/TinyPluginPackage.min.js +1 -0
  47. package/dist/v1/TinyPromiseQueue.min.js +1 -1
  48. package/dist/v1/TinyPushManager.min.js +1 -0
  49. package/dist/v1/TinyPushPayload.min.js +1 -0
  50. package/dist/v1/TinyPushRouter.min.js +1 -0
  51. package/dist/v1/TinyRadioFm.min.js +1 -1
  52. package/dist/v1/TinyRateLimiter.min.js +1 -1
  53. package/dist/v1/TinyRegexEs.min.js +1 -0
  54. package/dist/v1/TinyRouter.min.js +1 -0
  55. package/dist/v1/TinyServiceWorker.min.js +1 -0
  56. package/dist/v1/TinyServiceWorkerEngine.min.js +1 -0
  57. package/dist/v1/TinySetMapPackage.min.js +1 -0
  58. package/dist/v1/TinySimpleDice.min.js +1 -1
  59. package/dist/v1/TinySmartScroller.min.js +1 -1
  60. package/dist/v1/TinyStorageBucketFileSystem.min.js +1 -0
  61. package/dist/v1/TinyTextDiffer.min.js +1 -1
  62. package/dist/v1/TinyTextRangeEditor.min.js +1 -1
  63. package/dist/v1/TinyTextarea.min.js +1 -1
  64. package/dist/v1/TinyThrottledApi.min.js +1 -0
  65. package/dist/v1/TinyTimeout.min.js +1 -1
  66. package/dist/v1/TinyToastNotify.min.js +1 -1
  67. package/dist/v1/TinyUploadClicker.min.js +1 -1
  68. package/dist/v1/TinyUriParser.min.js +1 -0
  69. package/dist/v1/TinyVersion.min.js +1 -0
  70. package/dist/v1/TinyWebWorker.min.js +1 -0
  71. package/dist/v1/TinyWebWorkerEngine.min.js +1 -0
  72. package/dist/v1/UltraRandomMsgGen.min.js +1 -1
  73. package/dist/v1/basics/array.cjs +2 -2
  74. package/dist/v1/basics/array.d.mts +2 -0
  75. package/dist/v1/basics/array.d.mts.map +1 -1
  76. package/dist/v1/basics/array.mjs +2 -1
  77. package/dist/v1/basics/browserDetector.cjs +37 -12
  78. package/dist/v1/basics/browserDetector.d.mts +8 -0
  79. package/dist/v1/basics/browserDetector.d.mts.map +1 -1
  80. package/dist/v1/basics/browserDetector.mjs +32 -13
  81. package/dist/v1/basics/crypto.cjs +23 -0
  82. package/dist/v1/basics/crypto.d.mts +10 -0
  83. package/dist/v1/basics/crypto.d.mts.map +1 -0
  84. package/dist/v1/basics/crypto.mjs +18 -0
  85. package/dist/v1/basics/html.cjs +0 -3
  86. package/dist/v1/basics/html.d.mts.map +1 -1
  87. package/dist/v1/basics/html.mjs +0 -2
  88. package/dist/v1/basics/index.cjs +8 -1
  89. package/dist/v1/basics/index.d.mts +6 -5
  90. package/dist/v1/basics/index.d.mts.map +1 -1
  91. package/dist/v1/basics/index.mjs +6 -5
  92. package/dist/v1/basics/objChecker.cjs +88 -0
  93. package/dist/v1/basics/objChecker.d.mts +26 -0
  94. package/dist/v1/basics/objChecker.d.mts.map +1 -1
  95. package/dist/v1/basics/objChecker.mjs +74 -0
  96. package/dist/v1/basics/objFilter.cjs +234 -93
  97. package/dist/v1/basics/objFilter.d.mts +96 -22
  98. package/dist/v1/basics/objFilter.d.mts.map +1 -1
  99. package/dist/v1/basics/objFilter.mjs +216 -92
  100. package/dist/v1/basics/promiseUtils.cjs +48 -12
  101. package/dist/v1/basics/promiseUtils.d.mts +45 -12
  102. package/dist/v1/basics/promiseUtils.d.mts.map +1 -1
  103. package/dist/v1/basics/promiseUtils.mjs +47 -12
  104. package/dist/v1/basics/text.cjs +0 -12
  105. package/dist/v1/basics/text.d.mts +0 -10
  106. package/dist/v1/basics/text.d.mts.map +1 -1
  107. package/dist/v1/basics/text.mjs +0 -10
  108. package/dist/v1/index.cjs +88 -3
  109. package/dist/v1/index.d.mts +31 -6
  110. package/dist/v1/index.d.mts.map +1 -1
  111. package/dist/v1/index.mjs +32 -7
  112. package/dist/v1/jsdoc/EventEmitter.cjs +4 -0
  113. package/dist/v1/jsdoc/EventEmitter.d.mts +33 -0
  114. package/dist/v1/jsdoc/EventEmitter.d.mts.map +1 -0
  115. package/dist/v1/jsdoc/EventEmitter.mjs +18 -0
  116. package/dist/v1/libs/array/TinyArrayComparator.cjs +240 -25
  117. package/dist/v1/libs/array/TinyArrayComparator.d.mts +130 -22
  118. package/dist/v1/libs/array/TinyArrayComparator.d.mts.map +1 -1
  119. package/dist/v1/libs/array/TinyArrayComparator.mjs +210 -24
  120. package/dist/v1/libs/fs/constants.cjs +74 -0
  121. package/dist/v1/libs/fs/constants.d.mts +22 -0
  122. package/dist/v1/libs/fs/constants.d.mts.map +1 -0
  123. package/dist/v1/libs/fs/constants.mjs +53 -0
  124. package/dist/v1/libs/fs/encoding.cjs +118 -0
  125. package/dist/v1/libs/fs/encoding.d.mts +50 -0
  126. package/dist/v1/libs/fs/encoding.d.mts.map +1 -0
  127. package/dist/v1/libs/fs/encoding.mjs +102 -0
  128. package/dist/v1/libs/fs/error.cjs +188 -0
  129. package/dist/v1/libs/fs/error.d.mts +105 -0
  130. package/dist/v1/libs/fs/error.d.mts.map +1 -0
  131. package/dist/v1/libs/fs/error.mjs +158 -0
  132. package/dist/v1/libs/fs/handle.cjs +121 -0
  133. package/dist/v1/libs/fs/handle.d.mts +56 -0
  134. package/dist/v1/libs/fs/handle.d.mts.map +1 -0
  135. package/dist/v1/libs/fs/handle.mjs +100 -0
  136. package/dist/v1/libs/fs/index.cjs +700 -0
  137. package/dist/v1/libs/fs/index.d.mts +377 -0
  138. package/dist/v1/libs/fs/index.d.mts.map +1 -0
  139. package/dist/v1/libs/fs/index.mjs +630 -0
  140. package/dist/v1/libs/fs/path.cjs +234 -0
  141. package/dist/v1/libs/fs/path.d.mts +176 -0
  142. package/dist/v1/libs/fs/path.d.mts.map +1 -0
  143. package/dist/v1/libs/fs/path.mjs +197 -0
  144. package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.cjs +202 -0
  145. package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.d.mts +121 -0
  146. package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.d.mts.map +1 -0
  147. package/dist/v1/libs/fs/plugins/OPFS/StorageBucket.mjs +172 -0
  148. package/dist/v1/libs/fs/plugins/OPFS/index.cjs +334 -0
  149. package/dist/v1/libs/fs/plugins/OPFS/index.d.mts +98 -0
  150. package/dist/v1/libs/fs/plugins/OPFS/index.d.mts.map +1 -0
  151. package/dist/v1/libs/fs/plugins/OPFS/index.mjs +300 -0
  152. package/dist/v1/libs/fs/stats.cjs +245 -0
  153. package/dist/v1/libs/fs/stats.d.mts +226 -0
  154. package/dist/v1/libs/fs/stats.d.mts.map +1 -0
  155. package/dist/v1/libs/fs/stats.mjs +197 -0
  156. package/dist/v1/libs/html/events/TinyIframeEvents.cjs +10 -1
  157. package/dist/v1/libs/html/events/TinyIframeEvents.d.mts +9 -2
  158. package/dist/v1/libs/html/events/TinyIframeEvents.d.mts.map +1 -1
  159. package/dist/v1/libs/html/events/TinyIframeEvents.mjs +8 -1
  160. package/dist/v1/libs/html/events/TinyNewWinEvents.cjs +14 -3
  161. package/dist/v1/libs/html/events/TinyNewWinEvents.d.mts +21 -5
  162. package/dist/v1/libs/html/events/TinyNewWinEvents.d.mts.map +1 -1
  163. package/dist/v1/libs/html/events/TinyNewWinEvents.mjs +12 -3
  164. package/dist/v1/libs/html/scroll/TinySmartScroller.cjs +13 -1
  165. package/dist/v1/libs/html/scroll/TinySmartScroller.d.mts +29 -2
  166. package/dist/v1/libs/html/scroll/TinySmartScroller.d.mts.map +1 -1
  167. package/dist/v1/libs/html/scroll/TinySmartScroller.mjs +11 -1
  168. package/dist/v1/libs/math/TinyAdvancedRaffle.cjs +13 -1
  169. package/dist/v1/libs/math/TinyAdvancedRaffle.d.mts +32 -2
  170. package/dist/v1/libs/math/TinyAdvancedRaffle.d.mts.map +1 -1
  171. package/dist/v1/libs/math/TinyAdvancedRaffle.mjs +11 -1
  172. package/dist/v1/libs/math/TinyTimeout.cjs +0 -14
  173. package/dist/v1/libs/math/TinyTimeout.d.mts +0 -11
  174. package/dist/v1/libs/math/TinyTimeout.d.mts.map +1 -1
  175. package/dist/v1/libs/math/TinyTimeout.mjs +0 -13
  176. package/dist/v1/libs/media/TinyMediaPlayer/index.cjs +25 -1
  177. package/dist/v1/libs/media/TinyMediaPlayer/index.d.mts +35 -2
  178. package/dist/v1/libs/media/TinyMediaPlayer/index.d.mts.map +1 -1
  179. package/dist/v1/libs/media/TinyMediaPlayer/index.mjs +23 -1
  180. package/dist/v1/libs/media/TinyMediaPlayer.cjs +2 -2
  181. package/dist/v1/libs/media/TinyMediaPlayer.d.mts +2 -2
  182. package/dist/v1/libs/media/TinyMediaPlayer.d.mts.map +1 -1
  183. package/dist/v1/libs/media/TinyMediaPlayer.mjs +2 -2
  184. package/dist/v1/libs/media/TinyRadioFm.cjs +19 -1
  185. package/dist/v1/libs/media/TinyRadioFm.d.mts +78 -2
  186. package/dist/v1/libs/media/TinyRadioFm.d.mts.map +1 -1
  187. package/dist/v1/libs/media/TinyRadioFm.mjs +17 -1
  188. package/dist/v1/libs/plugin/TinyPlugin.cjs +1630 -0
  189. package/dist/v1/libs/plugin/TinyPlugin.d.mts +753 -0
  190. package/dist/v1/libs/plugin/TinyPlugin.d.mts.map +1 -0
  191. package/dist/v1/libs/plugin/TinyPlugin.mjs +1376 -0
  192. package/dist/v1/libs/plugin/TinyVersion.cjs +204 -0
  193. package/dist/v1/libs/plugin/TinyVersion.d.mts +70 -0
  194. package/dist/v1/libs/plugin/TinyVersion.d.mts.map +1 -0
  195. package/dist/v1/libs/plugin/TinyVersion.mjs +179 -0
  196. package/dist/v1/libs/router/TinyRouter.cjs +661 -0
  197. package/dist/v1/libs/router/TinyRouter.d.mts +320 -0
  198. package/dist/v1/libs/router/TinyRouter.d.mts.map +1 -0
  199. package/dist/v1/libs/router/TinyRouter.mjs +572 -0
  200. package/dist/v1/libs/storage/TinyLocalStorage.cjs +20 -1
  201. package/dist/v1/libs/storage/TinyLocalStorage.d.mts +64 -2
  202. package/dist/v1/libs/storage/TinyLocalStorage.d.mts.map +1 -1
  203. package/dist/v1/libs/storage/TinyLocalStorage.mjs +18 -1
  204. package/dist/v1/libs/storage/TinyMapCache.cjs +373 -0
  205. package/dist/v1/libs/storage/TinyMapCache.d.mts +274 -0
  206. package/dist/v1/libs/storage/TinyMapCache.d.mts.map +1 -0
  207. package/dist/v1/libs/storage/TinyMapCache.mjs +333 -0
  208. package/dist/v1/libs/storage/TinySetMapDatabase.cjs +1167 -0
  209. package/dist/v1/libs/storage/TinySetMapDatabase.d.mts +603 -0
  210. package/dist/v1/libs/storage/TinySetMapDatabase.d.mts.map +1 -0
  211. package/dist/v1/libs/storage/TinySetMapDatabase.mjs +1059 -0
  212. package/dist/v1/libs/sw/browser/TinyNotificationAdapter.cjs +126 -0
  213. package/dist/v1/libs/sw/browser/TinyNotificationAdapter.d.mts +132 -0
  214. package/dist/v1/libs/sw/browser/TinyNotificationAdapter.d.mts.map +1 -0
  215. package/dist/v1/libs/sw/browser/TinyNotificationAdapter.mjs +109 -0
  216. package/dist/v1/libs/sw/browser/TinyPushManager.cjs +310 -0
  217. package/dist/v1/libs/sw/browser/TinyPushManager.d.mts +168 -0
  218. package/dist/v1/libs/sw/browser/TinyPushManager.d.mts.map +1 -0
  219. package/dist/v1/libs/sw/browser/TinyPushManager.mjs +264 -0
  220. package/dist/v1/libs/sw/browser/TinyServiceWorker.cjs +1060 -0
  221. package/dist/v1/libs/sw/browser/TinyServiceWorker.d.mts +348 -0
  222. package/dist/v1/libs/sw/browser/TinyServiceWorker.d.mts.map +1 -0
  223. package/dist/v1/libs/sw/browser/TinyServiceWorker.mjs +933 -0
  224. package/dist/v1/libs/sw/browser/plugins/TabManager.cjs +315 -0
  225. package/dist/v1/libs/sw/browser/plugins/TabManager.d.mts +178 -0
  226. package/dist/v1/libs/sw/browser/plugins/TabManager.d.mts.map +1 -0
  227. package/dist/v1/libs/sw/browser/plugins/TabManager.mjs +274 -0
  228. package/dist/v1/libs/sw/browser/utils.cjs +28 -0
  229. package/dist/v1/libs/sw/browser/utils.d.mts +8 -0
  230. package/dist/v1/libs/sw/browser/utils.d.mts.map +1 -0
  231. package/dist/v1/libs/sw/browser/utils.mjs +21 -0
  232. package/dist/v1/libs/sw/service/TinyPushRouter.cjs +222 -0
  233. package/dist/v1/libs/sw/service/TinyPushRouter.d.mts +138 -0
  234. package/dist/v1/libs/sw/service/TinyPushRouter.d.mts.map +1 -0
  235. package/dist/v1/libs/sw/service/TinyPushRouter.mjs +201 -0
  236. package/dist/v1/libs/sw/service/TinyServiceWorkerEngine.cjs +3016 -0
  237. package/dist/v1/libs/sw/service/TinyServiceWorkerEngine.d.mts +993 -0
  238. package/dist/v1/libs/sw/service/TinyServiceWorkerEngine.d.mts.map +1 -0
  239. package/dist/v1/libs/sw/service/TinyServiceWorkerEngine.mjs +2558 -0
  240. package/dist/v1/libs/sw/service/plugins/GlobBypassPlugin.cjs +88 -0
  241. package/dist/v1/libs/sw/service/plugins/GlobBypassPlugin.d.mts +32 -0
  242. package/dist/v1/libs/sw/service/plugins/GlobBypassPlugin.d.mts.map +1 -0
  243. package/dist/v1/libs/sw/service/plugins/GlobBypassPlugin.mjs +69 -0
  244. package/dist/v1/libs/sw/service/plugins/GlobCachePlugin.cjs +112 -0
  245. package/dist/v1/libs/sw/service/plugins/GlobCachePlugin.d.mts +31 -0
  246. package/dist/v1/libs/sw/service/plugins/GlobCachePlugin.d.mts.map +1 -0
  247. package/dist/v1/libs/sw/service/plugins/GlobCachePlugin.mjs +91 -0
  248. package/dist/v1/libs/sw/service/plugins/Ping.cjs +32 -0
  249. package/dist/v1/libs/sw/service/plugins/Ping.d.mts +9 -0
  250. package/dist/v1/libs/sw/service/plugins/Ping.d.mts.map +1 -0
  251. package/dist/v1/libs/sw/service/plugins/Ping.mjs +25 -0
  252. package/dist/v1/libs/sw/service/plugins/TabManager.cjs +457 -0
  253. package/dist/v1/libs/sw/service/plugins/TabManager.d.mts +91 -0
  254. package/dist/v1/libs/sw/service/plugins/TabManager.d.mts.map +1 -0
  255. package/dist/v1/libs/sw/service/plugins/TabManager.mjs +372 -0
  256. package/dist/v1/libs/sw/service/plugins/ViteFileDetector.cjs +180 -0
  257. package/dist/v1/libs/sw/service/plugins/ViteFileDetector.d.mts +28 -0
  258. package/dist/v1/libs/sw/service/plugins/ViteFileDetector.d.mts.map +1 -0
  259. package/dist/v1/libs/sw/service/plugins/ViteFileDetector.mjs +148 -0
  260. package/dist/v1/libs/sw/service/shared/TinyPushPayload.cjs +199 -0
  261. package/dist/v1/libs/sw/service/shared/TinyPushPayload.d.mts +80 -0
  262. package/dist/v1/libs/sw/service/shared/TinyPushPayload.d.mts.map +1 -0
  263. package/dist/v1/libs/sw/service/shared/TinyPushPayload.mjs +174 -0
  264. package/dist/v1/libs/sw/utils.cjs +57 -0
  265. package/dist/v1/libs/sw/utils.d.mts +173 -0
  266. package/dist/v1/libs/sw/utils.d.mts.map +1 -0
  267. package/dist/v1/libs/sw/utils.mjs +50 -0
  268. package/dist/v1/libs/text/TinyI18/Browser-NON-DOM.cjs +57 -0
  269. package/dist/v1/libs/text/TinyI18/Browser-NON-DOM.d.mts +39 -0
  270. package/dist/v1/libs/text/TinyI18/Browser-NON-DOM.d.mts.map +1 -0
  271. package/dist/v1/libs/text/TinyI18/Browser-NON-DOM.mjs +48 -0
  272. package/dist/v1/libs/text/TinyI18/Browser.cjs +64 -0
  273. package/dist/v1/libs/text/TinyI18/Browser.d.mts +47 -0
  274. package/dist/v1/libs/text/TinyI18/Browser.d.mts.map +1 -0
  275. package/dist/v1/libs/text/TinyI18/Browser.mjs +57 -0
  276. package/dist/v1/libs/text/TinyI18/Node.cjs +49 -0
  277. package/dist/v1/libs/text/TinyI18/Node.d.mts +38 -0
  278. package/dist/v1/libs/text/TinyI18/Node.d.mts.map +1 -0
  279. package/dist/v1/libs/text/TinyI18/Node.mjs +43 -0
  280. package/dist/v1/libs/text/TinyI18/browser-utils.cjs +17 -0
  281. package/dist/v1/libs/text/TinyI18/browser-utils.d.mts +8 -0
  282. package/dist/v1/libs/text/TinyI18/browser-utils.d.mts.map +1 -0
  283. package/dist/v1/libs/text/TinyI18/browser-utils.mjs +13 -0
  284. package/dist/v1/libs/text/{TinyI18.cjs → TinyI18/index.cjs} +205 -104
  285. package/dist/v1/libs/text/{TinyI18.d.mts → TinyI18/index.d.mts} +141 -92
  286. package/dist/v1/libs/text/TinyI18/index.d.mts.map +1 -0
  287. package/dist/v1/libs/text/{TinyI18.mjs → TinyI18/index.mjs} +195 -101
  288. package/dist/v1/libs/tools/TinyBrowserMonitor.cjs +1088 -0
  289. package/dist/v1/libs/tools/TinyBrowserMonitor.d.mts +621 -0
  290. package/dist/v1/libs/tools/TinyBrowserMonitor.d.mts.map +1 -0
  291. package/dist/v1/libs/tools/TinyBrowserMonitor.mjs +940 -0
  292. package/dist/v1/libs/tools/TinyDebugger.cjs +180 -19
  293. package/dist/v1/libs/tools/TinyDebugger.d.mts +220 -24
  294. package/dist/v1/libs/tools/TinyDebugger.d.mts.map +1 -1
  295. package/dist/v1/libs/tools/TinyDebugger.mjs +161 -19
  296. package/dist/v1/libs/tools/TinyHtmlTagRegexBuilder.cjs +256 -0
  297. package/dist/v1/libs/tools/TinyHtmlTagRegexBuilder.d.mts +125 -0
  298. package/dist/v1/libs/tools/TinyHtmlTagRegexBuilder.d.mts.map +1 -0
  299. package/dist/v1/libs/tools/TinyHtmlTagRegexBuilder.mjs +223 -0
  300. package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser-NON-DOM.cjs +23 -0
  301. package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser-NON-DOM.d.mts +17 -0
  302. package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser-NON-DOM.d.mts.map +1 -0
  303. package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser-NON-DOM.mjs +19 -0
  304. package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser.cjs +23 -0
  305. package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser.d.mts +17 -0
  306. package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser.d.mts.map +1 -0
  307. package/dist/v1/libs/tools/TinyHttpResponseRegistry/Browser.mjs +19 -0
  308. package/dist/v1/libs/tools/TinyHttpResponseRegistry/EmptyRequestCodes.cjs +390 -0
  309. package/dist/v1/libs/tools/TinyHttpResponseRegistry/EmptyRequestCodes.d.mts +9 -0
  310. package/dist/v1/libs/tools/TinyHttpResponseRegistry/EmptyRequestCodes.d.mts.map +1 -0
  311. package/dist/v1/libs/tools/TinyHttpResponseRegistry/EmptyRequestCodes.mjs +387 -0
  312. package/dist/v1/libs/tools/TinyHttpResponseRegistry/JsDoc.cjs +2 -0
  313. package/dist/v1/libs/tools/TinyHttpResponseRegistry/JsDoc.d.mts +27 -0
  314. package/dist/v1/libs/tools/TinyHttpResponseRegistry/JsDoc.d.mts.map +1 -0
  315. package/dist/v1/libs/tools/TinyHttpResponseRegistry/JsDoc.mjs +12 -0
  316. package/dist/v1/libs/tools/TinyHttpResponseRegistry/MozillaRequestCodes/LICENSE +53 -0
  317. package/dist/v1/libs/tools/TinyHttpResponseRegistry/MozillaRequestCodes/index.cjs +405 -0
  318. package/dist/v1/libs/tools/TinyHttpResponseRegistry/MozillaRequestCodes/index.d.mts +34 -0
  319. package/dist/v1/libs/tools/TinyHttpResponseRegistry/MozillaRequestCodes/index.d.mts.map +1 -0
  320. package/dist/v1/libs/tools/TinyHttpResponseRegistry/MozillaRequestCodes/index.mjs +342 -0
  321. package/dist/v1/libs/tools/TinyHttpResponseRegistry/Node.cjs +23 -0
  322. package/dist/v1/libs/tools/TinyHttpResponseRegistry/Node.d.mts +17 -0
  323. package/dist/v1/libs/tools/TinyHttpResponseRegistry/Node.d.mts.map +1 -0
  324. package/dist/v1/libs/tools/TinyHttpResponseRegistry/Node.mjs +19 -0
  325. package/dist/v1/libs/tools/TinyHttpResponseRegistry/RequestCodes.cjs +327 -0
  326. package/dist/v1/libs/tools/TinyHttpResponseRegistry/RequestCodes.d.mts +9 -0
  327. package/dist/v1/libs/tools/TinyHttpResponseRegistry/RequestCodes.d.mts.map +1 -0
  328. package/dist/v1/libs/tools/TinyHttpResponseRegistry/RequestCodes.mjs +324 -0
  329. package/dist/v1/libs/tools/TinyHttpResponseRegistry/index.cjs +268 -0
  330. package/dist/v1/libs/tools/TinyHttpResponseRegistry/index.d.mts +107 -0
  331. package/dist/v1/libs/tools/TinyHttpResponseRegistry/index.d.mts.map +1 -0
  332. package/dist/v1/libs/tools/TinyHttpResponseRegistry/index.mjs +238 -0
  333. package/dist/v1/libs/tools/TinyPasswordValidator.cjs +491 -0
  334. package/dist/v1/libs/tools/TinyPasswordValidator.d.mts +246 -0
  335. package/dist/v1/libs/tools/TinyPasswordValidator.d.mts.map +1 -0
  336. package/dist/v1/libs/tools/TinyPasswordValidator.mjs +434 -0
  337. package/dist/v1/libs/tools/TinyPkgExportValidator.cjs +48 -0
  338. package/dist/v1/libs/tools/TinyPkgExportValidator.d.mts +14 -0
  339. package/dist/v1/libs/tools/TinyPkgExportValidator.d.mts.map +1 -1
  340. package/dist/v1/libs/tools/TinyPkgExportValidator.mjs +44 -0
  341. package/dist/v1/libs/tools/TinySiteMap.cjs +1029 -0
  342. package/dist/v1/libs/tools/TinySiteMap.d.mts +429 -0
  343. package/dist/v1/libs/tools/TinySiteMap.d.mts.map +1 -0
  344. package/dist/v1/libs/tools/TinySiteMap.mjs +910 -0
  345. package/dist/v1/libs/tools/TinySiteMapStream.cjs +121 -0
  346. package/dist/v1/libs/tools/TinySiteMapStream.d.mts +51 -0
  347. package/dist/v1/libs/tools/TinySiteMapStream.d.mts.map +1 -0
  348. package/dist/v1/libs/tools/TinySiteMapStream.mjs +85 -0
  349. package/dist/v1/libs/tools/TinyURLSecurityVerifier.cjs +444 -0
  350. package/dist/v1/libs/tools/TinyURLSecurityVerifier.d.mts +217 -0
  351. package/dist/v1/libs/tools/TinyURLSecurityVerifier.d.mts.map +1 -0
  352. package/dist/v1/libs/tools/TinyURLSecurityVerifier.mjs +394 -0
  353. package/dist/v1/libs/tools/TinyUriParser/BlueSky.cjs +613 -0
  354. package/dist/v1/libs/tools/TinyUriParser/BlueSky.d.mts +152 -0
  355. package/dist/v1/libs/tools/TinyUriParser/BlueSky.d.mts.map +1 -0
  356. package/dist/v1/libs/tools/TinyUriParser/BlueSky.mjs +527 -0
  357. package/dist/v1/libs/tools/TinyUriParser/Discord.cjs +1119 -0
  358. package/dist/v1/libs/tools/TinyUriParser/Discord.d.mts +306 -0
  359. package/dist/v1/libs/tools/TinyUriParser/Discord.d.mts.map +1 -0
  360. package/dist/v1/libs/tools/TinyUriParser/Discord.mjs +968 -0
  361. package/dist/v1/libs/tools/TinyUriParser/MatrixProtocol.cjs +469 -0
  362. package/dist/v1/libs/tools/TinyUriParser/MatrixProtocol.d.mts +80 -0
  363. package/dist/v1/libs/tools/TinyUriParser/MatrixProtocol.d.mts.map +1 -0
  364. package/dist/v1/libs/tools/TinyUriParser/MatrixProtocol.mjs +379 -0
  365. package/dist/v1/libs/tools/TinyUriParser.cjs +217 -0
  366. package/dist/v1/libs/tools/TinyUriParser.d.mts +109 -0
  367. package/dist/v1/libs/tools/TinyUriParser.d.mts.map +1 -0
  368. package/dist/v1/libs/tools/TinyUriParser.mjs +183 -0
  369. package/dist/v1/libs/utils/TinyCloner.cjs +466 -0
  370. package/dist/v1/libs/utils/TinyCloner.d.mts +221 -0
  371. package/dist/v1/libs/utils/TinyCloner.d.mts.map +1 -0
  372. package/dist/v1/libs/utils/TinyCloner.mjs +416 -0
  373. package/dist/v1/libs/utils/TinyPromiseQueue.cjs +1 -1
  374. package/dist/v1/libs/utils/TinyPromiseQueue.d.mts +2 -2
  375. package/dist/v1/libs/utils/TinyPromiseQueue.d.mts.map +1 -1
  376. package/dist/v1/libs/utils/TinyPromiseQueue.mjs +1 -1
  377. package/dist/v1/libs/utils/TinyThrottledApi.cjs +333 -0
  378. package/dist/v1/libs/utils/TinyThrottledApi.d.mts +163 -0
  379. package/dist/v1/libs/utils/TinyThrottledApi.d.mts.map +1 -0
  380. package/dist/v1/libs/utils/TinyThrottledApi.mjs +294 -0
  381. package/dist/v1/libs/worker/browser/TinyWebWorker.cjs +342 -0
  382. package/dist/v1/libs/worker/browser/TinyWebWorker.d.mts +97 -0
  383. package/dist/v1/libs/worker/browser/TinyWebWorker.d.mts.map +1 -0
  384. package/dist/v1/libs/worker/browser/TinyWebWorker.mjs +305 -0
  385. package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.cjs +346 -0
  386. package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.d.mts +127 -0
  387. package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.d.mts.map +1 -0
  388. package/dist/v1/libs/worker/engine/TinyWebWorkerEngine.mjs +304 -0
  389. package/dist/v1/regexp/Email.cjs +185 -0
  390. package/dist/v1/regexp/Email.d.mts +73 -0
  391. package/dist/v1/regexp/Email.d.mts.map +1 -0
  392. package/dist/v1/regexp/Email.mjs +153 -0
  393. package/dist/v1/regexp/Glob.cjs +293 -0
  394. package/dist/v1/regexp/Glob.d.mts +45 -0
  395. package/dist/v1/regexp/Glob.d.mts.map +1 -0
  396. package/dist/v1/regexp/Glob.mjs +260 -0
  397. package/dist/v1/regexp/Ipv4.cjs +57 -0
  398. package/dist/v1/regexp/Ipv4.d.mts +29 -0
  399. package/dist/v1/regexp/Ipv4.d.mts.map +1 -0
  400. package/dist/v1/regexp/Ipv4.mjs +45 -0
  401. package/dist/v1/regexp/Ipv6.cjs +67 -0
  402. package/dist/v1/regexp/Ipv6.d.mts +29 -0
  403. package/dist/v1/regexp/Ipv6.d.mts.map +1 -0
  404. package/dist/v1/regexp/Ipv6.mjs +54 -0
  405. package/dist/v1/regexp/SegmentExtractor.cjs +145 -0
  406. package/dist/v1/regexp/SegmentExtractor.d.mts +91 -0
  407. package/dist/v1/regexp/SegmentExtractor.d.mts.map +1 -0
  408. package/dist/v1/regexp/SegmentExtractor.mjs +116 -0
  409. package/dist/v1/regexp/UrlDetector.cjs +125 -0
  410. package/dist/v1/regexp/UrlDetector.d.mts +67 -0
  411. package/dist/v1/regexp/UrlDetector.d.mts.map +1 -0
  412. package/dist/v1/regexp/UrlDetector.mjs +102 -0
  413. package/dist/v1/regexp/Username/index.cjs +233 -0
  414. package/dist/v1/regexp/Username/index.d.mts +77 -0
  415. package/dist/v1/regexp/Username/index.d.mts.map +1 -0
  416. package/dist/v1/regexp/Username/index.mjs +199 -0
  417. package/dist/v1/regexp/Username/jsDoc.cjs +2 -0
  418. package/dist/v1/regexp/Username/jsDoc.d.mts +57 -0
  419. package/dist/v1/regexp/Username/jsDoc.d.mts.map +1 -0
  420. package/dist/v1/regexp/Username/jsDoc.mjs +18 -0
  421. package/dist/v1/regexp/Username/templates/BlueSky.cjs +56 -0
  422. package/dist/v1/regexp/Username/templates/BlueSky.d.mts +35 -0
  423. package/dist/v1/regexp/Username/templates/BlueSky.d.mts.map +1 -0
  424. package/dist/v1/regexp/Username/templates/BlueSky.mjs +52 -0
  425. package/dist/v1/regexp/Username/templates/Discord.cjs +505 -0
  426. package/dist/v1/regexp/Username/templates/Discord.d.mts +209 -0
  427. package/dist/v1/regexp/Username/templates/Discord.d.mts.map +1 -0
  428. package/dist/v1/regexp/Username/templates/Discord.mjs +458 -0
  429. package/dist/v1/regexp/Username/templates/MatrixProtocol.cjs +143 -0
  430. package/dist/v1/regexp/Username/templates/MatrixProtocol.d.mts +70 -0
  431. package/dist/v1/regexp/Username/templates/MatrixProtocol.d.mts.map +1 -0
  432. package/dist/v1/regexp/Username/templates/MatrixProtocol.mjs +128 -0
  433. package/dist/v1/regexp/Username/templates/deprecated/Discord.cjs +24 -0
  434. package/dist/v1/regexp/Username/templates/deprecated/Discord.d.mts +17 -0
  435. package/dist/v1/regexp/Username/templates/deprecated/Discord.d.mts.map +1 -0
  436. package/dist/v1/regexp/Username/templates/deprecated/Discord.mjs +20 -0
  437. package/dist/v1/regexp/Username/templates/index.cjs +11 -0
  438. package/dist/v1/regexp/Username/templates/index.d.mts +5 -0
  439. package/dist/v1/regexp/Username/templates/index.d.mts.map +1 -0
  440. package/dist/v1/regexp/Username/templates/index.mjs +4 -0
  441. package/dist/v1/regexp/index.cjs +41 -0
  442. package/dist/v1/regexp/index.d.mts +9 -0
  443. package/dist/v1/regexp/index.d.mts.map +1 -0
  444. package/dist/v1/regexp/index.mjs +8 -0
  445. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Browser.cjs +64 -0
  446. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Browser.d.mts +11 -0
  447. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Browser.d.mts.map +1 -0
  448. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Browser.mjs +51 -0
  449. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/FileInput.cjs +66 -0
  450. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/FileInput.d.mts +11 -0
  451. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/FileInput.d.mts.map +1 -0
  452. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/FileInput.mjs +51 -0
  453. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Node.cjs +39 -0
  454. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Node.d.mts +11 -0
  455. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Node.d.mts.map +1 -0
  456. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Node.mjs +28 -0
  457. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Template.cjs +494 -0
  458. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Template.d.mts +142 -0
  459. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Template.d.mts.map +1 -0
  460. package/dist/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters/Template.mjs +445 -0
  461. package/dist/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.cjs +30 -4
  462. package/dist/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.d.mts +5 -2
  463. package/dist/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.d.mts.map +1 -1
  464. package/dist/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.mjs +29 -5
  465. package/dist/v1/webTemplates/media/MediaValidator/v1/Browser/index.cjs +135 -0
  466. package/dist/v1/webTemplates/media/MediaValidator/v1/Browser/index.d.mts +83 -0
  467. package/dist/v1/webTemplates/media/MediaValidator/v1/Browser/index.d.mts.map +1 -0
  468. package/dist/v1/webTemplates/media/MediaValidator/v1/Browser/index.mjs +120 -0
  469. package/dist/v1/webTemplates/media/MediaValidator/v1/Node/index.cjs +127 -0
  470. package/dist/v1/webTemplates/media/MediaValidator/v1/Node/index.d.mts +95 -0
  471. package/dist/v1/webTemplates/media/MediaValidator/v1/Node/index.d.mts.map +1 -0
  472. package/dist/v1/webTemplates/media/MediaValidator/v1/Node/index.mjs +109 -0
  473. package/dist/v1/webTemplates/multiformats/14.0/IPFSHasher/index.cjs +83 -0
  474. package/dist/v1/webTemplates/multiformats/14.0/IPFSHasher/index.d.mts +46 -0
  475. package/dist/v1/webTemplates/multiformats/14.0/IPFSHasher/index.d.mts.map +1 -0
  476. package/dist/v1/webTemplates/multiformats/14.0/IPFSHasher/index.mjs +71 -0
  477. package/dist/v1/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin.cjs +493 -0
  478. package/dist/v1/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin.d.mts +67 -0
  479. package/dist/v1/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin.d.mts.map +1 -0
  480. package/dist/v1/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin.mjs +399 -0
  481. package/dist/v1/webTemplates/vite/7.3/plugins/githubUtils.cjs +35 -0
  482. package/dist/v1/webTemplates/vite/7.3/plugins/githubUtils.d.mts +6 -0
  483. package/dist/v1/webTemplates/vite/7.3/plugins/githubUtils.d.mts.map +1 -0
  484. package/dist/v1/webTemplates/vite/7.3/plugins/githubUtils.mjs +29 -0
  485. package/docs/info/RegExp.md +74 -0
  486. package/docs/v1/Exports.md +101 -0
  487. package/docs/v1/README.md +113 -15
  488. package/docs/v1/basics/asyncReplace.md +2 -0
  489. package/docs/v1/basics/browserDetector.md +28 -11
  490. package/docs/v1/basics/crypto.md +85 -0
  491. package/docs/v1/basics/deprecated/html.md +2 -0
  492. package/docs/v1/basics/deprecated/objFilter.md +2 -0
  493. package/docs/v1/basics/html.md +2 -0
  494. package/docs/v1/basics/objChecker.md +55 -0
  495. package/docs/v1/basics/objFilter.md +57 -86
  496. package/docs/v1/basics/promiseUtils.md +12 -3
  497. package/docs/v1/basics/text.md +0 -1
  498. package/docs/v1/libs/array/TinyArrayComparator.md +50 -39
  499. package/docs/v1/libs/fs/TinyFS.md +752 -0
  500. package/docs/v1/libs/fs/TinyOPFSFileSystem.md +495 -0
  501. package/docs/v1/libs/fs/TinyStorageBucketFileSystem.md +407 -0
  502. package/docs/v1/libs/plugin/TinyPlugin.md +441 -0
  503. package/docs/v1/libs/plugin/TinyVersion.md +145 -0
  504. package/docs/v1/libs/router/TinyRouter.md +216 -0
  505. package/docs/v1/libs/storage/TinyMapCache.md +219 -0
  506. package/docs/v1/libs/storage/TinySetMapDatabase.md +478 -0
  507. package/docs/v1/libs/sw/browser/TinyNotificationAdapter.md +280 -0
  508. package/docs/v1/libs/sw/browser/TinyPushManager.md +782 -0
  509. package/docs/v1/libs/sw/browser/TinyServiceWorker.md +365 -0
  510. package/docs/v1/libs/sw/browser/plugins/TabManager.md +133 -0
  511. package/docs/v1/libs/sw/service/TinyPushRouter.md +314 -0
  512. package/docs/v1/libs/sw/service/TinyServiceWorkerEngine.md +748 -0
  513. package/docs/v1/libs/sw/service/plugins/GlobBypassPlugin.md +229 -0
  514. package/docs/v1/libs/sw/service/plugins/GlobCachePlugin.md +91 -0
  515. package/docs/v1/libs/sw/service/plugins/Ping.md +36 -0
  516. package/docs/v1/libs/sw/service/plugins/TabManager.md +64 -0
  517. package/docs/v1/libs/sw/service/plugins/ViteFileDetector.md +92 -0
  518. package/docs/v1/libs/sw/service/shared/TinyPushPayload.md +316 -0
  519. package/docs/v1/libs/text/TinyI18.md +80 -56
  520. package/docs/v1/libs/tools/TinyBrowserMonitor.md +170 -0
  521. package/docs/v1/libs/tools/TinyDebugger.md +117 -1
  522. package/docs/v1/libs/tools/TinyHtmlTagRegexBuilder.md +141 -0
  523. package/docs/v1/libs/tools/TinyHttpResponseRegistry.md +129 -0
  524. package/docs/v1/libs/tools/TinyPasswordValidator.md +153 -0
  525. package/docs/v1/libs/tools/TinyPkgExportValidator.md +45 -1
  526. package/docs/v1/libs/tools/TinySiteMap.md +134 -0
  527. package/docs/v1/libs/tools/TinySiteMapStream.md +97 -0
  528. package/docs/v1/libs/tools/TinyURLSecurityVerifier.md +146 -0
  529. package/docs/v1/libs/tools/TinyUriParser/Discord.md +374 -0
  530. package/docs/v1/libs/tools/TinyUriParser/MatrixProtocol.md +54 -0
  531. package/docs/v1/libs/tools/TinyUriParser.md +128 -0
  532. package/docs/v1/libs/utils/TinyCloner.md +126 -0
  533. package/docs/v1/libs/utils/TinyPromiseQueue.md +1 -1
  534. package/docs/v1/libs/utils/TinyThrottledApi.md +219 -0
  535. package/docs/v1/libs/worker/browser/TinyWebWorker.md +331 -0
  536. package/docs/v1/libs/worker/engine/TinyWebWorkerEngine.md +137 -0
  537. package/docs/v1/regexp/Email.md +127 -0
  538. package/docs/v1/regexp/Glob.md +155 -0
  539. package/docs/v1/regexp/IPv4.md +103 -0
  540. package/docs/v1/regexp/IPv6.md +122 -0
  541. package/docs/v1/regexp/SegmentExtractor.md +120 -0
  542. package/docs/v1/regexp/UrlDetector.md +117 -0
  543. package/docs/v1/regexp/Username/Base.md +131 -0
  544. package/docs/v1/regexp/Username/Discord.md +267 -0
  545. package/docs/v1/regexp/Username/MatrixProtocol.md +131 -0
  546. package/docs/v1/webTemplates/ag-psd/31.0/ProcessSolidFilters.md +569 -0
  547. package/docs/v1/webTemplates/bootstrap/5.3/html/BootstrapDialogs.md +19 -7
  548. package/docs/v1/webTemplates/media/MediaValidator/v1/Browser.md +123 -0
  549. package/docs/v1/webTemplates/media/MediaValidator/v1/Node.md +136 -0
  550. package/docs/v1/webTemplates/multiformats/14.0/IPFSHasher.md +310 -0
  551. package/docs/v1/webTemplates/vite/7.3/plugins/TinyVitePwaPlugin.md +131 -0
  552. package/docs/v1/webTemplates/vite/7.3/plugins/githubUtils.md +50 -0
  553. package/package.json +303 -13
  554. package/types/EventEmitter.d.ts +48 -0
  555. package/dist/v1/libs/text/TinyI18.d.mts.map +0 -1
@@ -0,0 +1,1029 @@
1
+ 'use strict';
2
+
3
+ var TinyURLSecurityVerifier = require('./TinyURLSecurityVerifier.cjs');
4
+
5
+ /**
6
+ * @typedef {Object} SitemapNamespace
7
+ * @property {'xmlns'|'attribute'} [type] - Defines if it's a namespace declaration or a raw root attribute. Defaults to 'xmlns'.
8
+ * @property {string} [prefix] - The namespace prefix (e.g., 'example'). Used only if type is 'xmlns'.
9
+ * @property {string} [name] - The exact attribute name (e.g., 'xsi:schemaLocation'). Required if type is 'attribute'.
10
+ * @property {string} [uri] - The namespace URI. Used if type is 'xmlns'.
11
+ * @property {string} [value] - The attribute value. Used if type is 'attribute' (acts as an alias to 'uri' for flexibility).
12
+ */
13
+
14
+ /**
15
+ * @typedef {(instance: TinySiteMap) => SitemapNamespace[]} NamespaceStrategy
16
+ * A function that receives the TinySiteMap instance and returns an array of namespaces.
17
+ */
18
+
19
+ /**
20
+ * A map where keys are the XML tag names and values are the tag contents.
21
+ * @typedef {Object} CustomTagMap
22
+ * @property {string} [tag] - The tag name (key in the object, e.g., 'example:tag').
23
+ * @property {string} [value] - The content of the tag (value in the object).
24
+ */
25
+
26
+ /**
27
+ * @typedef {Object} SitemapEntry
28
+ * @property {string} loc - The absolute URL of the page (or relative path).
29
+ * @property {string} [lastmod] - The last modified date in ISO 8601 format (e.g., '2023-10-27T10:00:00Z').
30
+ * @property {'always'|'hourly'|'daily'|'weekly'|'monthly'|'yearly'|'never'} [changefreq] - Frequency of change.
31
+ * @property {number} [priority] - Importance of the URL (0.0 to 1.0).
32
+ * @property {CustomTagMap} [customTags] - Custom XML tags to include in this entry.
33
+ */
34
+
35
+ /**
36
+ * @typedef {Object} SitemapIndexEntry
37
+ * @property {string} loc - The absolute URL of the sitemap file.
38
+ * @property {string} [lastmod] - The last modified date in ISO 8601 format.
39
+ */
40
+
41
+ /**
42
+ * @typedef {Object} SitemapConfig
43
+ * @property {string} [xslUrl] - URL to XSL stylesheet.
44
+ * @property {boolean} [xslUrlPathnameOnly=true]
45
+ * @property {boolean} [lastmodDateOnly] - Format lastmod as date only (YYYY-MM-DD).
46
+ * @property {'normal'|'index'} [type] - The type of sitemap to generate. Defaults to 'normal'.
47
+ * @property {string} baseUrl - The base URL of the website.
48
+ * @property {SitemapNamespace[]} [namespaces] - Initial manual namespaces or root attributes.
49
+ * @property {NamespaceStrategy} [namespaceStrategy] - Dynamic logic to provide namespaces.
50
+ * @property {SitemapEntry[] | SitemapIndexEntry[]} entries - Array of entries.
51
+ */
52
+
53
+ /**
54
+ * A service to manage and generate secure XML sitemaps or sitemap indexes.
55
+ * This class handles URL resolution, root attributes management, and XML escaping to prevent injection.
56
+ */
57
+ class TinySiteMap {
58
+ /** The security verifier used to validate URLs. @type {TinyURLSecurityVerifier} */
59
+ #urlVerifier = new TinyURLSecurityVerifier();
60
+ /** @type {URL} The base URL used for resolving relative paths. */
61
+ #baseUrl;
62
+ /** @type {(SitemapEntry|SitemapIndexEntry)[]} The internal list of validated entries. */
63
+ #entries = [];
64
+ /** @type {SitemapNamespace[]} The list of manually added namespaces/attributes. */
65
+ #namespaces = [];
66
+ /** @type {NamespaceStrategy | null} The dynamic strategy for generating namespaces. */
67
+ #namespaceStrategy = null;
68
+ /** @type {'normal'|'index'} The mode of the generator. */
69
+ #type;
70
+ /** @type {number} The maximum allowed length for a resolved URL. */
71
+ #maxResolvedUrlSize = 2048;
72
+ /** @type {boolean} Determines if the 'lastmod' field is formatted as a simple date (YYYY-MM-DD) instead of full ISO 8601. */
73
+ #lastmodDateOnly = false;
74
+ /** @type {URL|null} The URL of the XSL stylesheet used to style the XML output in web browsers. */
75
+ #xslUrl = null;
76
+ /** @type {boolean} */
77
+ #xslUrlPathnameOnly = true;
78
+
79
+ /**
80
+ * Official limit established by sitemaps.org
81
+ * @type {number}
82
+ */
83
+ static #MAX_URLS = 50000;
84
+
85
+ /**
86
+ * Gets the maximum number of URLs allowed in a single sitemap.
87
+ * @returns {number}
88
+ */
89
+ static get maxUrls() {
90
+ return TinySiteMap.#MAX_URLS;
91
+ }
92
+
93
+ /**
94
+ * Sets the maximum number of URLs allowed in a single sitemap.
95
+ * @param {number} value
96
+ * @throws {TypeError} If the value is not a number.
97
+ */
98
+ static set maxUrls(value) {
99
+ if (typeof value !== 'number' || Number.isNaN(value)) {
100
+ throw new TypeError('entry.priority must be a number.');
101
+ }
102
+ TinySiteMap.#MAX_URLS = value;
103
+ }
104
+
105
+ /**
106
+ * @type {RegExp} Regex to validate XML Names/Prefixes.
107
+ * From package "sitemap.js" by Eugene Kalinin.
108
+ * @reference https://github.com/ekalinin/sitemap.js/blob/1a782cf41e0d391299029c9e00c8bfa8cdaad212/lib/sitemap-xml.ts
109
+ */
110
+ static #xmlNameRegex = /^[a-zA-Z_:][\w:.-]*$/;
111
+
112
+ /**
113
+ * @type {RegExp} Regex to validate XML Names/Prefixes.
114
+ *
115
+ * From package "sitemap.js" by Eugene Kalinin.
116
+ * @reference https://github.com/ekalinin/sitemap.js/blob/1a782cf41e0d391299029c9e00c8bfa8cdaad212/lib/sitemap-xml.ts
117
+ *
118
+ */
119
+ static get xmlNameRegex() {
120
+ return new RegExp(TinySiteMap.#xmlNameRegex.source, TinySiteMap.#xmlNameRegex.flags);
121
+ }
122
+
123
+ /**
124
+ * A static map storing predefined XML namespace identifiers and their corresponding URIs.
125
+ * @type {Map<string, string>}
126
+ */
127
+ static #attrValues = new Map([
128
+ ['ROOT', 'http://www.sitemaps.org/schemas/sitemap/0.9'],
129
+ ['exampleSchema', 'http://www.example.com/schemas/example_schema'],
130
+ ['news', 'http://www.google.com/schemas/sitemap-news/0.9'],
131
+ ['xhtml', 'http://www.google.com/schemas/sitemap-news/0.9'],
132
+ ['image', 'http://www.google.com/schemas/sitemap-news/0.9'],
133
+ ['video', 'http://www.google.com/schemas/sitemap-news/0.9'],
134
+ ['xsi', 'http://www.w3.org/2001/XMLSchema-instance'],
135
+ [
136
+ 'schemaLocation:normal',
137
+ 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd',
138
+ ],
139
+ [
140
+ 'schemaLocation:index',
141
+ 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd',
142
+ ],
143
+ ]);
144
+
145
+ /**
146
+ * Retrieves the URI for a specific namespace ID.
147
+ * @param {string} id - The namespace identifier.
148
+ * @returns {string|undefined} The namespace URI or undefined if not found.
149
+ */
150
+ static getAttrVal(id) {
151
+ return TinySiteMap.#attrValues.get(id);
152
+ }
153
+
154
+ /**
155
+ * Sets or updates a namespace URI for a specific ID.
156
+ * @param {string} id - The namespace identifier.
157
+ * @param {string} value - The namespace URI.
158
+ * @throws {TypeError} If the ID or value are not strings.
159
+ */
160
+ static setAttrVal(id, value) {
161
+ if (typeof id !== 'string') throw new TypeError('Namespace ID must be a string.');
162
+ if (typeof value !== 'string') throw new TypeError('Namespace URI must be a string.');
163
+ TinySiteMap.#attrValues.set(id, value);
164
+ }
165
+
166
+ /**
167
+ * Checks if a namespace ID exists.
168
+ * @param {string} id - The namespace identifier.
169
+ * @returns {boolean} True if it exists, false otherwise.
170
+ */
171
+ static hasAttrVal(id) {
172
+ return TinySiteMap.#attrValues.has(id);
173
+ }
174
+
175
+ /**
176
+ * Gets all namespaces as a plain object.
177
+ * @returns {Record<string, string>} A map of IDs to URIs.
178
+ */
179
+ static get attrValues() {
180
+ return Object.fromEntries(TinySiteMap.#attrValues);
181
+ }
182
+
183
+ /**
184
+ * Replaces all current namespaces with a new set.
185
+ * @param {Record<string, string>} obj - The new namespace mapping.
186
+ * @throws {TypeError} If the input is not a valid object or contains non-string values.
187
+ */
188
+ static set attrValues(obj) {
189
+ if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
190
+ throw new TypeError('attrValues must be a non-null object.');
191
+ }
192
+
193
+ const attrValues = TinySiteMap.#attrValues;
194
+ try {
195
+ // Validate all values are strings before applying to ensure atomicity
196
+ TinySiteMap.#attrValues = new Map();
197
+ for (const [key, value] of Object.entries(obj)) {
198
+ TinySiteMap.setAttrVal(key, value);
199
+ }
200
+ } catch (err) {
201
+ TinySiteMap.#attrValues = attrValues;
202
+ throw err;
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Gets the total number of registered namespaces.
208
+ * @returns {number} The count of namespaces.
209
+ */
210
+ static get attrValuesSize() {
211
+ return TinySiteMap.#attrValues.size;
212
+ }
213
+
214
+ /**
215
+ * Clears all registered namespaces in the static attribute map.
216
+ * Note: This affects all instances of TinySiteMap globally.
217
+ */
218
+ static clearAttrValues() {
219
+ TinySiteMap.#attrValues.clear();
220
+ }
221
+
222
+ /**
223
+ * Initializes a new instance of the TinySiteMap class with the provided configuration.
224
+ * @param {SitemapConfig} config - The configuration object.
225
+ * @throws {TypeError} If the configuration is invalid.
226
+ */
227
+ constructor(config) {
228
+ this.#validateConfig(config);
229
+ this.#type = config.type ?? 'normal';
230
+ this.#baseUrl = new URL(config.baseUrl);
231
+ this.xslUrlPathnameOnly = config.xslUrlPathnameOnly ?? true;
232
+ this.#xslUrl = config.xslUrl
233
+ ? this.#xslUrlPathnameOnly
234
+ ? new URL(config.xslUrl, this.#baseUrl.origin)
235
+ : new URL(config.xslUrl)
236
+ : null;
237
+ this.lastmodDateOnly = config.lastmodDateOnly ?? false;
238
+ this.namespaces = config.namespaces ?? [];
239
+ this.namespaceStrategy = config.namespaceStrategy ?? TinySiteMap.simpleStrategy;
240
+
241
+ if (config.entries && config.entries.length > 0) {
242
+ for (const entry of config.entries) {
243
+ this.addEntry(entry);
244
+ }
245
+ }
246
+ }
247
+
248
+ /**
249
+ * Validates a single namespace object for correct structure and XML naming compliance.
250
+ * @param {SitemapNamespace} ns
251
+ * @param {RegExp} regex
252
+ * @throws {TypeError}
253
+ */
254
+ #validateNamespace(ns, regex = TinySiteMap.#xmlNameRegex) {
255
+ if (typeof ns !== 'object' || ns === null)
256
+ throw new TypeError('Namespace or Attribute must be a non-null object.');
257
+
258
+ const type = ns.type ?? 'xmlns';
259
+ if (!['xmlns', 'attribute'].includes(type))
260
+ throw new TypeError('Type must be either "xmlns" or "attribute".');
261
+
262
+ const val = ns.value ?? ns.uri;
263
+ if (typeof val !== 'string')
264
+ throw new TypeError('Namespace URI or Attribute value must be a string.');
265
+
266
+ if (type === 'xmlns') {
267
+ if (ns.prefix !== undefined && typeof ns.prefix !== 'string')
268
+ throw new TypeError('Namespace prefix must be a string.');
269
+
270
+ if (ns.prefix && !regex.test(ns.prefix))
271
+ throw new TypeError(`Invalid namespace prefix: "${ns.prefix}".`);
272
+ } else if (type === 'attribute') {
273
+ if (typeof ns.name !== 'string')
274
+ throw new TypeError('Attribute name must be a string when type is "attribute".');
275
+
276
+ if (!regex.test(ns.name)) throw new TypeError(`Invalid attribute name: "${ns.name}".`);
277
+ }
278
+ }
279
+
280
+ /**
281
+ * Validates a collection of namespace objects.
282
+ * @param {SitemapNamespace[]} namespaces
283
+ * @throws {TypeError}
284
+ */
285
+ #validateNamespaceSet(namespaces) {
286
+ if (!Array.isArray(namespaces)) throw new TypeError('namespaces must be an array.');
287
+ for (const ns of namespaces) this.#validateNamespace(ns);
288
+ }
289
+
290
+ /**
291
+ * Escapes special XML characters to prevent XML injection.
292
+ * @param {string} str - The raw string to be escaped.
293
+ * @param {boolean} isOtag
294
+ * @reference https://github.com/ekalinin/sitemap.js/blob/1a782cf41e0d391299029c9e00c8bfa8cdaad212/lib/sitemap-xml.ts
295
+ * @returns {string} The escaped string with characters like <, >, &, ", and ' replaced by entities.
296
+ */
297
+ static #escapeXml(str, isOtag) {
298
+ const amp = /&/g;
299
+ const lt = /</g;
300
+ const gt = />/g;
301
+ const apos = /'/g;
302
+ const quot = /"/g;
303
+ let result = str;
304
+ result = result.replace(amp, '&amp;').replace(lt, '&lt;').replace(gt, '&gt;');
305
+ if (isOtag) {
306
+ result = result.replace(apos, '&apos;').replace(quot, '&quot;');
307
+ }
308
+ return result.replace(
309
+ /[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u0084\u0086-\u009F\uD800-\uDFFF\p{NChar}]/gu,
310
+ '',
311
+ );
312
+ }
313
+
314
+ /**
315
+ * Escapes special XML characters to prevent XML injection.
316
+ * @param {string} str - The raw string to be escaped.
317
+ * @param {boolean} isOtag
318
+ * @reference https://github.com/ekalinin/sitemap.js/blob/1a782cf41e0d391299029c9e00c8bfa8cdaad212/lib/sitemap-xml.ts
319
+ * @returns {string} The escaped string with characters like <, >, &, ", and ' replaced by entities.
320
+ */
321
+ static escapeXml(str, isOtag) {
322
+ return this.#escapeXml(str, isOtag);
323
+ }
324
+
325
+ /**
326
+ * Validates the initial configuration object.
327
+ * @param {SitemapConfig} config - The configuration to validate.
328
+ * @throws {TypeError} If config is not an object, baseUrl is invalid, type is unsupported, or namespaces are malformed.
329
+ */
330
+ #validateConfig(config) {
331
+ if (typeof config !== 'object' || config === null) {
332
+ throw new TypeError('Configuration must be a non-null object.');
333
+ }
334
+ if (typeof config.baseUrl !== 'string') {
335
+ throw new TypeError('config.baseUrl must be a string.');
336
+ }
337
+ try {
338
+ new URL(config.baseUrl);
339
+ } catch {
340
+ throw new TypeError('config.baseUrl must be a valid absolute URL.');
341
+ }
342
+ if (config.type && !['normal', 'index'].includes(config.type)) {
343
+ throw new TypeError('config.type must be either "normal" or "index".');
344
+ }
345
+ }
346
+
347
+ /**
348
+ * Resolves relative URLs, validates all fields, and returns a new normalized object.
349
+ * @param {SitemapEntry | SitemapIndexEntry} entry - The entry object to process.
350
+ * @param {URL} baseUrl
351
+ * @param {'normal'|'index'} type
352
+ * @param {number} maxUrlSize
353
+ * @param {RegExp} regex
354
+ * @param {TinyURLSecurityVerifier} urlVerifier
355
+ * @returns {SitemapEntry | SitemapIndexEntry} A new, normalized, and validated entry object.
356
+ * @throws {TypeError} If the entry is invalid, if loc is not a string, if origin doesn't match, or if field values are invalid.
357
+ * @throws {RangeError} If the resolved URL exceeds maxResolvedUrlSize or if priority is outside [0.0, 1.0].
358
+ */
359
+ static #resolveAndValidate(entry, baseUrl, type, maxUrlSize, regex, urlVerifier) {
360
+ if (typeof entry !== 'object' || entry === null)
361
+ throw new TypeError('Entry must be a non-null object.');
362
+
363
+ // Validate loc: Must be string, must be valid URL, must match base origin
364
+ if (typeof entry.loc !== 'string') throw new TypeError('entry.loc must be a string.');
365
+
366
+ // Automatically handle relative paths using the baseUrl
367
+ const resolvedUrl = new URL(entry.loc, baseUrl);
368
+
369
+ // Security: Ensure the resolved URL belongs to the same origin
370
+ if (resolvedUrl.origin !== baseUrl.origin) {
371
+ throw new TypeError(
372
+ `entry.loc "${entry.loc}" must belong to the same origin as ${baseUrl.origin}`,
373
+ );
374
+ }
375
+
376
+ if (resolvedUrl.href.length >= maxUrlSize) {
377
+ throw new RangeError(`entry.loc must be less than ${maxUrlSize} characters.`);
378
+ }
379
+
380
+ if (urlVerifier.isDangerous(resolvedUrl)) {
381
+ throw new Error('');
382
+ }
383
+
384
+ /** @type {SitemapEntry} */
385
+ const normalizedEntry = { ...entry, loc: resolvedUrl.href };
386
+
387
+ // Validate lastmod (Shared by both types)
388
+ if (normalizedEntry.lastmod && typeof normalizedEntry.lastmod === 'string') {
389
+ if (Number.isNaN(Date.parse(normalizedEntry.lastmod))) {
390
+ throw new TypeError(`entry.lastmod "${normalizedEntry.lastmod}" is an invalid date.`);
391
+ }
392
+ }
393
+
394
+ // Type-specific validation
395
+ if (type === 'normal') {
396
+ // Validate changefreq
397
+ const validFreqs = ['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'];
398
+ if (normalizedEntry.changefreq && !validFreqs.includes(normalizedEntry.changefreq)) {
399
+ throw new TypeError(`entry.changefreq must be one of: ${validFreqs.join(', ')}`);
400
+ }
401
+
402
+ // Validate priority
403
+ if (normalizedEntry.priority !== undefined) {
404
+ if (
405
+ typeof normalizedEntry.priority !== 'number' ||
406
+ Number.isNaN(normalizedEntry.priority)
407
+ ) {
408
+ throw new TypeError('entry.priority must be a number.');
409
+ }
410
+ if (normalizedEntry.priority < 0 || normalizedEntry.priority > 1) {
411
+ throw new RangeError('entry.priority must be between 0.0 and 1.0.');
412
+ }
413
+ }
414
+
415
+ // Validate customTags
416
+ if (normalizedEntry.customTags) {
417
+ // Validation for customTags
418
+ if (typeof normalizedEntry.customTags !== 'object' || normalizedEntry.customTags === null) {
419
+ throw new TypeError('entry.customTags must be an object.');
420
+ }
421
+ for (const [tag, value] of Object.entries(normalizedEntry.customTags)) {
422
+ // SECURITY: Validate that the tag name is a valid XML QName to prevent injection
423
+ if (!regex.test(tag)) throw new TypeError(`Invalid custom tag name: "${tag}".`);
424
+ // Validate content
425
+ if (typeof value !== 'string')
426
+ throw new TypeError(`The content for custom tag "${tag}" must be a string.`);
427
+ }
428
+ }
429
+ } else if (type === 'index') {
430
+ // Strict mode for 'index': forbid properties that don't belong to <sitemap>
431
+ if (normalizedEntry.changefreq || normalizedEntry.priority || normalizedEntry.customTags) {
432
+ throw new TypeError(
433
+ 'Sitemap Index entries cannot contain changefreq, priority, or customTags.',
434
+ );
435
+ }
436
+ }
437
+
438
+ return normalizedEntry;
439
+ }
440
+
441
+ /**
442
+ * Resolves relative URLs, validates all fields, and returns a new normalized object.
443
+ * @param {SitemapEntry | SitemapIndexEntry} entry - The entry object to process.
444
+ * @param {URL} baseUrl
445
+ * @param {'normal'|'index'} type
446
+ * @param {number} maxUrlSize
447
+ * @param {RegExp} regex
448
+ * @param {TinyURLSecurityVerifier} urlVerifier
449
+ * @returns {SitemapEntry | SitemapIndexEntry} A new, normalized, and validated entry object.
450
+ * @throws {TypeError} If the entry is invalid, if loc is not a string, if origin doesn't match, or if field values are invalid.
451
+ * @throws {RangeError} If the resolved URL exceeds maxResolvedUrlSize or if priority is outside [0.0, 1.0].
452
+ */
453
+ static resolveAndValidate(entry, baseUrl, type, maxUrlSize, regex, urlVerifier) {
454
+ return TinySiteMap.#resolveAndValidate(entry, baseUrl, type, maxUrlSize, regex, urlVerifier);
455
+ }
456
+
457
+ /**
458
+ * Resolves relative URLs, validates all fields, and returns a new normalized object.
459
+ * @param {SitemapEntry | SitemapIndexEntry} entry - The entry object to process.
460
+ * @returns {SitemapEntry | SitemapIndexEntry} A new, normalized, and validated entry object.
461
+ * @throws {TypeError} If the entry is invalid, if loc is not a string, if origin doesn't match, or if field values are invalid.
462
+ * @throws {RangeError} If the resolved URL exceeds maxResolvedUrlSize or if priority is outside [0.0, 1.0].
463
+ */
464
+ #rav(entry) {
465
+ return TinySiteMap.#resolveAndValidate(
466
+ entry,
467
+ this.#baseUrl,
468
+ this.#type,
469
+ this.#maxResolvedUrlSize,
470
+ TinySiteMap.#xmlNameRegex,
471
+ this.#urlVerifier,
472
+ );
473
+ }
474
+
475
+ /**
476
+ * Adds a namespace to the sitemap, preventing duplicate prefixes or attribute names.
477
+ * @param {SitemapNamespace} ns - The namespace to add.
478
+ * @throws {TypeError} If the namespace format is invalid.
479
+ */
480
+ addNamespace(ns) {
481
+ this.#validateNamespace(ns);
482
+ const newType = ns.type ?? 'xmlns';
483
+
484
+ // Prevent duplicate attributes or prefixes
485
+ const exists = this.#namespaces.some((existing) => {
486
+ const existingType = existing.type ?? 'xmlns';
487
+ if (existingType !== newType) return false;
488
+
489
+ if (newType === 'attribute') {
490
+ return existing.name === ns.name;
491
+ }
492
+ return existing.prefix === ns.prefix;
493
+ });
494
+
495
+ if (exists) {
496
+ const identifier = newType === 'attribute' ? ns.name : ns.prefix || 'ROOT';
497
+ throw new Error(`Root declaration with identifier "${identifier}" already exists.`);
498
+ }
499
+
500
+ this.#namespaces.push(ns);
501
+ }
502
+
503
+ /**
504
+ * Removes a namespace from the sitemap list by its identifier (prefix or name).
505
+ * @param {string} identifier - The identifier to remove.
506
+ */
507
+ removeNamespace(identifier) {
508
+ this.#namespaces = this.#namespaces.filter((ns) => {
509
+ const type = ns.type ?? 'xmlns';
510
+ if (type === 'attribute') return ns.name !== identifier;
511
+ return ns.prefix !== identifier;
512
+ });
513
+ }
514
+
515
+ /**
516
+ * Clears all manually added namespaces.
517
+ */
518
+ clearNamespaces() {
519
+ this.#namespaces = [];
520
+ }
521
+
522
+ /**
523
+ * Adds a new entry to the sitemap.
524
+ * @param {SitemapEntry | SitemapIndexEntry} entry - The entry to add.
525
+ * @param {number} [index] - The optional index at which to insert the entry.
526
+ * @returns {number} The new length of the entries array.
527
+ */
528
+ addEntry(entry, index) {
529
+ if (this.#entries.length >= TinySiteMap.#MAX_URLS) {
530
+ throw new RangeError(`Sitemaps cannot exceed ${TinySiteMap.#MAX_URLS} entries.`);
531
+ }
532
+ const validated = this.#rav(entry);
533
+ const newSize = this.#entries.push(validated);
534
+ if (typeof index !== 'undefined') this.moveEntry(newSize - 1, index);
535
+ return newSize;
536
+ }
537
+
538
+ /**
539
+ * Removes an entry from the sitemap by its index.
540
+ * @param {number} index - The index of the entry to remove.
541
+ * @returns {boolean} True if an element was removed, false otherwise.
542
+ * @throws {RangeError} If the index is out of bounds.
543
+ */
544
+ removeEntry(index) {
545
+ if (index < 0 || index >= this.#entries.length) {
546
+ throw new RangeError('Index out of bounds.');
547
+ }
548
+ const oldSize = this.#entries.length;
549
+ this.#entries.splice(index, 1);
550
+ return oldSize !== this.#entries.length;
551
+ }
552
+
553
+ /**
554
+ * Updates an existing entry with new data.
555
+ * @param {number} index - The index of the entry to update.
556
+ * @param {Partial<SitemapEntry | SitemapIndexEntry>} entryData - The partial data to merge into the existing entry.
557
+ * @throws {RangeError} If the index is out of bounds.
558
+ */
559
+ updateEntry(index, entryData) {
560
+ if (index < 0 || index >= this.#entries.length) {
561
+ throw new RangeError('Index out of bounds.');
562
+ }
563
+ // Merge current data with new data to allow partial updates
564
+ const updatedData = { ...this.#entries[index], ...entryData };
565
+ // Re-validate the entire merged object
566
+ this.#entries[index] = this.#rav(updatedData);
567
+ }
568
+
569
+ /**
570
+ * Changes the position of an entry within the list.
571
+ * @param {number} fromIndex - The index of the entry to move.
572
+ * @param {number} toIndex - The index to move the entry to.
573
+ * @throws {RangeError} If either index is out of bounds.
574
+ */
575
+ moveEntry(fromIndex, toIndex) {
576
+ if (
577
+ fromIndex < 0 ||
578
+ fromIndex >= this.#entries.length ||
579
+ toIndex < 0 ||
580
+ toIndex >= this.#entries.length
581
+ ) {
582
+ throw new RangeError('Index out of bounds.');
583
+ }
584
+ const [movedItem] = this.#entries.splice(fromIndex, 1);
585
+ this.#entries.splice(toIndex, 0, movedItem);
586
+ }
587
+
588
+ /**
589
+ * Clears all manually added entries.
590
+ */
591
+ clearEntries() {
592
+ this.#entries = [];
593
+ }
594
+
595
+ /**
596
+ * Gets the URL security verifier.
597
+ * @returns {TinyURLSecurityVerifier}
598
+ */
599
+ get urlVerifier() {
600
+ return this.#urlVerifier;
601
+ }
602
+
603
+ /**
604
+ * Sets a dynamic strategy to provide namespaces based on the instance state.
605
+ * @param {NamespaceStrategy} strategy - The strategy function.
606
+ * @throws {TypeError} If the strategy is not a function.
607
+ */
608
+ set namespaceStrategy(strategy) {
609
+ if (typeof strategy !== 'function') {
610
+ throw new TypeError('namespaceStrategy must be a function.');
611
+ }
612
+ this.#namespaceStrategy = strategy;
613
+ }
614
+
615
+ /**
616
+ * Returns a copy of the manually added namespaces.
617
+ * @returns {SitemapNamespace[]}
618
+ */
619
+ get namespaces() {
620
+ return this.#namespaces.map((i) => ({ ...i }));
621
+ }
622
+
623
+ /**
624
+ * Sets the manual namespaces for the sitemap.
625
+ * @param {SitemapNamespace[]} nss - The array of namespaces to set.
626
+ * @throws {TypeError} If the namespaces array is invalid.
627
+ */
628
+ set namespaces(nss) {
629
+ if (!Array.isArray(nss)) throw new TypeError('namespaces must be an array.');
630
+ const oldNamespaces = this.#namespaces;
631
+ try {
632
+ this.#namespaces = [];
633
+ for (const ns of nss) this.addNamespace(ns);
634
+ } catch (err) {
635
+ this.#namespaces = oldNamespaces;
636
+ throw err;
637
+ }
638
+ }
639
+
640
+ /**
641
+ * Gets the sitemap type.
642
+ * @returns {'normal'|'index'} The type of sitemap.
643
+ */
644
+ get type() {
645
+ return this.#type;
646
+ }
647
+
648
+ /**
649
+ * Gets the base URL.
650
+ * @returns {URL} The copy of the base URL instance.
651
+ */
652
+ get baseUrl() {
653
+ return new URL(this.#baseUrl.href);
654
+ }
655
+
656
+ /**
657
+ * Gets a shallow copy of the current entries.
658
+ * @returns {SitemapEntry[] | SitemapIndexEntry[]} A copy of the entries array.
659
+ */
660
+ get entries() {
661
+ return this.#entries.map((/** @type {SitemapEntry} */ e) => ({
662
+ ...e,
663
+ ...(e.customTags ? { customTags: { ...e.customTags } } : {}),
664
+ }));
665
+ }
666
+
667
+ /**
668
+ * Sets the sitemap entries, validating each one via the addEntry method.
669
+ * @param {SitemapEntry[] | SitemapIndexEntry[]} entries - The entries to set.
670
+ * @throws {TypeError} If the entries is not an array.
671
+ */
672
+ set entries(entries) {
673
+ if (!Array.isArray(entries)) throw new TypeError('entries must be an array.');
674
+ const oldEntries = this.#entries;
675
+ try {
676
+ this.#entries = [];
677
+ for (const entry of entries) this.addEntry(entry);
678
+ } catch (err) {
679
+ this.#entries = oldEntries;
680
+ throw err;
681
+ }
682
+ }
683
+
684
+ /**
685
+ * Gets the maximum allowed URL size.
686
+ * @returns {number} The current maximum size.
687
+ */
688
+ get maxResolvedUrlSize() {
689
+ return this.#maxResolvedUrlSize;
690
+ }
691
+
692
+ /**
693
+ * Sets the maximum allowed URL size.
694
+ * @param {number} value - The new maximum size.
695
+ * @throws {TypeError} If the provided value is not a non-negative number.
696
+ */
697
+ set maxResolvedUrlSize(value) {
698
+ if (typeof value !== 'number' || Number.isNaN(value) || !Number.isFinite(value) || value < 0) {
699
+ throw new TypeError('maxResolvedUrlSize must be a non-negative number.');
700
+ }
701
+ this.#maxResolvedUrlSize = value;
702
+ }
703
+
704
+ /**
705
+ * Gets the current configuration state for 'lastmod' date formatting.
706
+ * @returns {boolean} True if date-only formatting is enabled, false otherwise.
707
+ */
708
+ get lastmodDateOnly() {
709
+ return this.#lastmodDateOnly;
710
+ }
711
+
712
+ /**
713
+ * Sets whether the 'lastmod' field should be formatted as a simple date (YYYY-MM-DD) instead of full ISO 8601.
714
+ * @param {boolean} value - True to use YYYY-MM-DD format, false to use full ISO 8601.
715
+ * @throws {TypeError} If the provided value is not a boolean.
716
+ */
717
+ set lastmodDateOnly(value) {
718
+ if (typeof value !== 'boolean') {
719
+ throw new TypeError('lastmodDateOnly must be a boolean.');
720
+ }
721
+ this.#lastmodDateOnly = value;
722
+ }
723
+
724
+ /**
725
+ * Gets the URL of the XSL stylesheet used to style the XML output.
726
+ * @returns {string|null} The XSL stylesheet URL or null.
727
+ */
728
+ get xslUrl() {
729
+ return this.#xslUrlPathnameOnly
730
+ ? (this.#xslUrl?.pathname ?? null)
731
+ : (this.#xslUrl?.href ?? null);
732
+ }
733
+
734
+ /**
735
+ * Sets the URL of the XSL stylesheet used to style the XML output.
736
+ * @param {string|null} value - The URL of the XSL stylesheet used to style the XML output.
737
+ * @throws {TypeError} If the value is not a string or null.
738
+ */
739
+ set xslUrl(value) {
740
+ if (value !== null && typeof value !== 'string') {
741
+ throw new TypeError('xslUrl must be a string or null.');
742
+ }
743
+ this.#xslUrl = value
744
+ ? this.#xslUrlPathnameOnly
745
+ ? new URL(value, this.#baseUrl.origin)
746
+ : new URL(value)
747
+ : null;
748
+ }
749
+
750
+ /**
751
+ * Gets whether the XSL URL is treated as a pathname only.
752
+ * @returns {boolean}
753
+ */
754
+ get xslUrlPathnameOnly() {
755
+ return this.#xslUrlPathnameOnly;
756
+ }
757
+
758
+ /**
759
+ * Sets whether the XSL URL is treated as a pathname only.
760
+ * @param {boolean} value - Sets whether the XSL URL is treated as a pathname only.
761
+ * @throws {TypeError} If the value is not a boolean.
762
+ */
763
+ set xslUrlPathnameOnly(value) {
764
+ if (value !== null && typeof value !== 'boolean') {
765
+ throw new TypeError('xslUrlPathnameOnly must be a boolean or null.');
766
+ }
767
+ this.#xslUrlPathnameOnly = value;
768
+ }
769
+
770
+ /**
771
+ * Gets the total number of entries in the sitemap.
772
+ * @returns {number}
773
+ */
774
+ get entriesSize() {
775
+ return this.#entries.length;
776
+ }
777
+
778
+ /**
779
+ * Gets the total number of namespaces in the sitemap.
780
+ * @returns {number}
781
+ */
782
+ get namespacesSize() {
783
+ return this.#namespaces.length;
784
+ }
785
+
786
+ /**
787
+ * Resets the instance by clearing all entries and namespaces.
788
+ */
789
+ clearAll() {
790
+ this.clearEntries();
791
+ this.clearNamespaces();
792
+ }
793
+
794
+ /**
795
+ * Generates the XML header.
796
+ * @param {SitemapNamespace[]} namespaces
797
+ * @param {string} [xslUrl]
798
+ * @param {'normal'|'index'} [type]
799
+ * @returns {string}
800
+ */
801
+ static #generateHeader(namespaces, xslUrl, type) {
802
+ let header = '';
803
+ if (xslUrl) {
804
+ header += `<?xml-stylesheet type="text/xsl" href="${TinySiteMap.#escapeXml(xslUrl, true)}"?>\n`;
805
+ }
806
+
807
+ let rootAttributes = '';
808
+ for (const ns of namespaces) {
809
+ const nsType = ns.type ?? 'xmlns';
810
+ const val = ns.value ?? ns.uri ?? '';
811
+
812
+ // Handles the schemaLocation properly as an attribute, not an xmlns prefix
813
+ if (nsType === 'attribute') {
814
+ rootAttributes += ` ${ns.name}="${TinySiteMap.#escapeXml(val, true)}"`;
815
+ } else {
816
+ const prefixPart = ns.prefix ? `:${ns.prefix}` : '';
817
+ rootAttributes += ` xmlns${prefixPart}="${TinySiteMap.#escapeXml(val, true)}"`;
818
+ }
819
+ }
820
+
821
+ header +=
822
+ type === 'index' ? `<sitemapindex${rootAttributes}>\n` : `<urlset${rootAttributes}>\n`;
823
+ return header;
824
+ }
825
+
826
+ /**
827
+ * Generates the XML fragment for a single entry.
828
+ * @param {SitemapEntry} entry
829
+ * @param {'normal'|'index'} type
830
+ * @param {boolean} [lastmodDateOnly=false]
831
+ * @returns {string}
832
+ */
833
+ static #generateEntry(entry, type, lastmodDateOnly = false) {
834
+ let lastmodStr = '';
835
+ if (entry.lastmod) {
836
+ const dateObj = new Date(entry.lastmod);
837
+ lastmodStr = TinySiteMap.#escapeXml(
838
+ lastmodDateOnly ? dateObj.toISOString().split('T')[0] : dateObj.toISOString(),
839
+ false,
840
+ );
841
+ }
842
+
843
+ // All dynamic content is passed through #escapeXml to prevent XML Injection
844
+ if (type === 'index') {
845
+ return ` <sitemap>\n <loc>${TinySiteMap.#escapeXml(entry.loc, false)}</loc>\n${
846
+ lastmodStr ? ` <lastmod>${lastmodStr}</lastmod>\n` : ''
847
+ } </sitemap>\n`;
848
+ }
849
+
850
+ let xml = ` <url>\n <loc>${TinySiteMap.#escapeXml(entry.loc, false)}</loc>\n`;
851
+ if (lastmodStr) xml += ` <lastmod>${lastmodStr}</lastmod>\n`;
852
+ if (entry.changefreq)
853
+ xml += ` <changefreq>${TinySiteMap.#escapeXml(entry.changefreq, false)}</changefreq>\n`;
854
+ if (entry.priority !== undefined)
855
+ xml += ` <priority>${entry.priority.toFixed(1)}</priority>\n`;
856
+
857
+ // Render custom tags
858
+ if (entry.customTags) {
859
+ for (const [tag, value] of Object.entries(entry.customTags)) {
860
+ xml += ` <${TinySiteMap.#escapeXml(tag, true)}>${TinySiteMap.#escapeXml(value, false)}</${tag}>\n`;
861
+ }
862
+ }
863
+ xml += ` </url>\n`;
864
+ return xml;
865
+ }
866
+
867
+ /**
868
+ * Generates the XML footer.
869
+ * @param {'normal'|'index'} type
870
+ * @returns {string}
871
+ */
872
+ static #generateFooter(type) {
873
+ return type === 'index' ? '</sitemapindex>' : '</urlset>';
874
+ }
875
+
876
+ /**
877
+ * Generates the XML header.
878
+ * @param {SitemapNamespace[]} namespaces
879
+ * @param {string} [xslUrl]
880
+ * @param {'normal'|'index'} [type]
881
+ * @returns {string}
882
+ */
883
+ static _generateHeader(namespaces, xslUrl, type) {
884
+ return TinySiteMap.#generateHeader(namespaces, xslUrl, type);
885
+ }
886
+
887
+ /**
888
+ * Generates the XML fragment for a single entry.
889
+ * @param {SitemapEntry} entry
890
+ * @param {'normal'|'index'} type
891
+ * @param {boolean} [lastmodDateOnly=false]
892
+ * @returns {string}
893
+ */
894
+ static _generateEntry(entry, type, lastmodDateOnly = false) {
895
+ return TinySiteMap.#generateEntry(entry, type, lastmodDateOnly);
896
+ }
897
+
898
+ /**
899
+ * Generates the XML footer.
900
+ * @param {'normal'|'index'} type
901
+ * @returns {string}
902
+ */
903
+ static _generateFooter(type) {
904
+ return TinySiteMap.#generateFooter(type);
905
+ }
906
+
907
+ /**
908
+ * Generates the sitemap or sitemap index as a valid XML string.
909
+ * @returns {string} The generated XML content.
910
+ */
911
+ generateXml() {
912
+ // 1. Collect all namespaces (Manual + Dynamic Strategy)
913
+ const dynamicNamespaces = this.#namespaceStrategy ? this.#namespaceStrategy(this) : [];
914
+
915
+ // 2. SECURITY: Validate all collected namespaces before rendering
916
+ this.#validateNamespaceSet(dynamicNamespaces);
917
+ const allNamespaces = [...dynamicNamespaces, ...this.#namespaces];
918
+
919
+ const xmlChunks = [`<?xml version="1.0" encoding="UTF-8"?>\n`];
920
+
921
+ // 3. Add header (Stylesheet + Root Tag)
922
+ xmlChunks.push(
923
+ TinySiteMap.#generateHeader(
924
+ allNamespaces,
925
+ this.#xslUrl ? this.#xslUrl.href : undefined,
926
+ this.#type,
927
+ ),
928
+ );
929
+
930
+ // 4. Add entries
931
+ for (const entry of this.#entries) {
932
+ xmlChunks.push(TinySiteMap.#generateEntry(entry, this.#type, this.#lastmodDateOnly));
933
+ }
934
+
935
+ // 5. Add o footer
936
+ xmlChunks.push(TinySiteMap.#generateFooter(this.#type));
937
+
938
+ return xmlChunks.join('');
939
+ }
940
+
941
+ /**
942
+ * Returns a namespace strategy that includes standard Google sitemaps namespaces (news, xhtml, image, and video).
943
+ *
944
+ * The function name is a fun reference to name of Eugene Kalinin. This strategy is inspired in the original "sitemap.js" package.
945
+ * @reference https://github.com/ekalinin/sitemap.js/blob/1a782cf41e0d391299029c9e00c8bfa8cdaad212/lib/sitemap-stream.ts
946
+ * @type {NamespaceStrategy}
947
+ */
948
+ static kaliStrategy() {
949
+ /** @type {SitemapNamespace[]} */
950
+ const namespaces = [];
951
+ namespaces.push({ type: 'xmlns', uri: TinySiteMap.#attrValues.get('ROOT') ?? '' });
952
+ namespaces.push({
953
+ type: 'xmlns',
954
+ uri: TinySiteMap.#attrValues.get('news') ?? '',
955
+ prefix: 'news',
956
+ });
957
+ namespaces.push({
958
+ type: 'xmlns',
959
+ uri: TinySiteMap.#attrValues.get('xhtml') ?? '',
960
+ prefix: 'xhtml',
961
+ });
962
+ namespaces.push({
963
+ type: 'xmlns',
964
+ uri: TinySiteMap.#attrValues.get('image') ?? '',
965
+ prefix: 'image',
966
+ });
967
+ namespaces.push({
968
+ type: 'xmlns',
969
+ uri: TinySiteMap.#attrValues.get('video') ?? '',
970
+ prefix: 'video',
971
+ });
972
+ return namespaces;
973
+ }
974
+
975
+ /**
976
+ * Returns a basic namespace strategy that only includes the default XML sitemap ROOT namespace.
977
+ * @type {NamespaceStrategy}
978
+ */
979
+ static simpleStrategy() {
980
+ return [{ type: 'xmlns', uri: TinySiteMap.#attrValues.get('ROOT') ?? '' }];
981
+ }
982
+
983
+ /**
984
+ * Returns a comprehensive namespace strategy that includes the ROOT, XSI, and schemaLocation namespaces,
985
+ * and conditionally includes custom namespaces based on the sitemap instance state.
986
+ * @reference https://www.sitemaps.org/protocol.html
987
+ * @type {NamespaceStrategy}
988
+ */
989
+ static protocolStrategy(instance) {
990
+ /** @type {SitemapNamespace[]} */
991
+ const namespaces = [];
992
+
993
+ // Default xmlns
994
+ namespaces.push({ type: 'xmlns', uri: TinySiteMap.#attrValues.get('ROOT') ?? '' });
995
+
996
+ // xmlns:xsi
997
+ namespaces.push({
998
+ type: 'xmlns',
999
+ prefix: 'xsi',
1000
+ uri: TinySiteMap.#attrValues.get('xsi') ?? '',
1001
+ });
1002
+
1003
+ // Schema Location
1004
+ const schemaUri =
1005
+ instance.type === 'normal'
1006
+ ? (TinySiteMap.#attrValues.get('schemaLocation:normal') ?? '')
1007
+ : (TinySiteMap.#attrValues.get('schemaLocation:index') ?? '');
1008
+
1009
+ namespaces.push({ type: 'attribute', name: 'xsi:schemaLocation', value: schemaUri });
1010
+
1011
+ // Custom Tags logic (original insertNamespaces behavior)
1012
+ if (instance.type === 'normal') {
1013
+ const hasCustomTags = instance.entries.some(
1014
+ (/** @type {SitemapEntry} */ e) => e.customTags && Object.keys(e.customTags).length > 0,
1015
+ );
1016
+ if (hasCustomTags) {
1017
+ namespaces.push({
1018
+ type: 'xmlns',
1019
+ prefix: 'example',
1020
+ uri: TinySiteMap.#attrValues.get('exampleSchema') ?? '',
1021
+ });
1022
+ }
1023
+ }
1024
+
1025
+ return namespaces;
1026
+ }
1027
+ }
1028
+
1029
+ module.exports = TinySiteMap;