From 4e707347dd6d91e61395c376634f8b87d3192e45 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Fri, 20 Mar 2026 14:03:33 +0000 Subject: [PATCH] BREAKING CHANGE(api): redesign smartsitemap around builder-based sitemap creation, parsing, validation, and import utilities --- changelog.md | 7 + npmextra.json | 39 +- package.json | 36 +- pnpm-lock.yaml | 3006 ++++++++++++--------- readme.md | 1127 ++++---- test/test.ts | 489 +++- ts/00_commitinfo_data.ts | 4 +- ts/index.ts | 47 +- ts/interfaces/index.ts | 307 ++- ts/smartsitemap.classes.feedimporter.ts | 159 ++ ts/smartsitemap.classes.indexbuilder.ts | 82 + ts/smartsitemap.classes.newsbuilder.ts | 95 + ts/smartsitemap.classes.sitemapnews.ts | 79 - ts/smartsitemap.classes.sitemapparser.ts | 251 ++ ts/smartsitemap.classes.sitemapstream.ts | 168 ++ ts/smartsitemap.classes.sitemapwebsite.ts | 47 - ts/smartsitemap.classes.smartsitemap.ts | 168 +- ts/smartsitemap.classes.urlsetbuilder.ts | 274 ++ ts/smartsitemap.classes.validator.ts | 289 ++ ts/smartsitemap.classes.xmlrenderer.ts | 294 ++ ts/smartsitemap.classes.yamlimporter.ts | 61 + ts/smartsitemap.plugins.ts | 10 +- 22 files changed, 4843 insertions(+), 2196 deletions(-) create mode 100644 ts/smartsitemap.classes.feedimporter.ts create mode 100644 ts/smartsitemap.classes.indexbuilder.ts create mode 100644 ts/smartsitemap.classes.newsbuilder.ts delete mode 100644 ts/smartsitemap.classes.sitemapnews.ts create mode 100644 ts/smartsitemap.classes.sitemapparser.ts create mode 100644 ts/smartsitemap.classes.sitemapstream.ts delete mode 100644 ts/smartsitemap.classes.sitemapwebsite.ts create mode 100644 ts/smartsitemap.classes.urlsetbuilder.ts create mode 100644 ts/smartsitemap.classes.validator.ts create mode 100644 ts/smartsitemap.classes.xmlrenderer.ts create mode 100644 ts/smartsitemap.classes.yamlimporter.ts diff --git a/changelog.md b/changelog.md index cdcbfb9..717bbb0 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2026-03-20 - 4.0.0 - BREAKING CHANGE(api) +redesign smartsitemap around builder-based sitemap creation, parsing, validation, and import utilities + +- Replace the previous SmartSitemap instance API and legacy sitemap classes with exported builder, parser, renderer, validator, stream, feed importer, and YAML importer modules +- Add support for sitemap indexes, news/image/video/hreflang extensions, auto-splitting, gzip and stream output, and structured validation and statistics +- Expand public TypeScript interfaces and package metadata to reflect the broader sitemap feature set + ## 2025-11-19 - 2.0.4 - fix(smartsitemap) Update CI configuration, bump dependencies, and apply small code cleanups diff --git a/npmextra.json b/npmextra.json index 4d271b1..9f1e0b7 100644 --- a/npmextra.json +++ b/npmextra.json @@ -1,34 +1,45 @@ { - "gitzone": { + "@git.zone/cli": { "projectType": "npm", "module": { "githost": "code.foss.global", "gitscope": "push.rocks", "gitrepo": "smartsitemap", - "description": "A module for generating and managing sitemaps, supporting dynamic sitemap generation from feeds.", + "description": "A comprehensive TypeScript sitemap library with builder API, supporting standard, news, image, video, and hreflang sitemaps with auto-splitting, streaming, validation, and RSS feed integration.", "npmPackagename": "@push.rocks/smartsitemap", "license": "MIT", "projectDomain": "push.rocks", "keywords": [ + "sitemap", "sitemap generator", - "RSS feeds", - "news sitemap", + "sitemap index", "XML sitemap", - "website indexing", - "search engine optimization", + "news sitemap", + "image sitemap", + "video sitemap", + "hreflang", + "RSS feeds", "SEO", - "web crawling", - "dynamic sitemap creation", + "search engine optimization", + "builder API", + "streaming", + "validation", "TypeScript", "node.js" ] + }, + "release": { + "registries": [ + "https://verdaccio.lossless.digital", + "https://registry.npmjs.org" + ], + "accessLevel": "public" } }, - "npmci": { - "npmGlobalTools": [], - "npmAccessLevel": "public" - }, - "tsdoc": { + "@git.zone/tsdoc": { "legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n" + }, + "@ship.zone/szci": { + "npmGlobalTools": [] } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 5fea5bb..fa0faa3 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "@push.rocks/smartsitemap", - "version": "2.0.4", + "version": "3.0.0", "private": false, - "description": "A module for generating and managing sitemaps, supporting dynamic sitemap generation from feeds.", + "description": "A comprehensive TypeScript sitemap library with builder API, supporting standard, news, image, video, and hreflang sitemaps with auto-splitting, streaming, validation, and RSS feed integration.", "main": "dist_ts/index.js", "typings": "dist_ts/index.d.ts", "type": "module", @@ -14,21 +14,20 @@ "buildDocs": "tsdoc" }, "devDependencies": { - "@git.zone/tsbuild": "^3.1.0", - "@git.zone/tsbundle": "^2.0.8", - "@git.zone/tsrun": "^2.0.0", - "@git.zone/tstest": "^2.8.2", + "@git.zone/tsbuild": "^4.3.0", + "@git.zone/tsbundle": "^2.9.1", + "@git.zone/tsrun": "^2.0.1", + "@git.zone/tstest": "^3.5.0", "@push.rocks/smartenv": "^6.0.0", "@push.rocks/tapbundle": "^6.0.3", - "@types/node": "^20.8.7" + "@types/node": "^22.0.0" }, "dependencies": { - "@push.rocks/smartcache": "^1.0.16", "@push.rocks/smartfeed": "^1.0.11", "@push.rocks/smartxml": "^2.0.0", "@push.rocks/smartyaml": "^3.0.4", - "@push.rocks/webrequest": "^4.0.1", - "@tsclass/tsclass": "^9.3.0" + "@push.rocks/webrequest": "^4.0.5", + "@tsclass/tsclass": "^9.5.0" }, "browserslist": [ "last 1 chrome versions" @@ -46,15 +45,20 @@ "readme.md" ], "keywords": [ + "sitemap", "sitemap generator", - "RSS feeds", - "news sitemap", + "sitemap index", "XML sitemap", - "website indexing", - "search engine optimization", + "news sitemap", + "image sitemap", + "video sitemap", + "hreflang", + "RSS feeds", "SEO", - "web crawling", - "dynamic sitemap creation", + "search engine optimization", + "builder API", + "streaming", + "validation", "TypeScript", "node.js" ], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ebc8bcf..ce8a182 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,6 @@ importers: .: dependencies: - '@push.rocks/smartcache': - specifier: ^1.0.16 - version: 1.0.18 '@push.rocks/smartfeed': specifier: ^1.0.11 version: 1.4.0 @@ -21,24 +18,24 @@ importers: specifier: ^3.0.4 version: 3.0.4 '@push.rocks/webrequest': - specifier: ^4.0.1 - version: 4.0.1 + specifier: ^4.0.5 + version: 4.0.5 '@tsclass/tsclass': - specifier: ^9.3.0 - version: 9.3.0 + specifier: ^9.5.0 + version: 9.5.0 devDependencies: '@git.zone/tsbuild': - specifier: ^3.1.0 - version: 3.1.0 + specifier: ^4.3.0 + version: 4.3.0 '@git.zone/tsbundle': - specifier: ^2.0.8 - version: 2.5.2 + specifier: ^2.9.1 + version: 2.9.1 '@git.zone/tsrun': - specifier: ^2.0.0 - version: 2.0.0 + specifier: ^2.0.1 + version: 2.0.1 '@git.zone/tstest': - specifier: ^2.8.2 - version: 2.8.2(socks@2.8.7)(typescript@5.9.3) + specifier: ^3.5.0 + version: 3.5.0(socks@2.8.7)(typescript@5.9.3) '@push.rocks/smartenv': specifier: ^6.0.0 version: 6.0.0 @@ -46,8 +43,8 @@ importers: specifier: ^6.0.3 version: 6.0.3(socks@2.8.7) '@types/node': - specifier: ^20.8.7 - version: 20.19.25 + specifier: ^22.0.0 + version: 22.19.15 packages: @@ -60,11 +57,8 @@ packages: '@api.global/typedrequest@3.1.10': resolution: {integrity: sha512-EiCp44XVcMjBvEs4oM1nMUaeY4ySU0Pzt3+mDwVG5DNP6EV87Nwancbr2jKScvaFNel9eeDgGtgEnFBKjOnApA==} - '@api.global/typedserver@3.0.79': - resolution: {integrity: sha512-NIZMQOeqEpqPT3qeA0hqTyLgZw5zO3bvRHkiDfFOrWMtnfvOLWZwmqJAcgpSSHHiwzuw47NNPvBZdJGXKnH+Zg==} - - '@api.global/typedsocket@3.0.1': - resolution: {integrity: sha512-xojiAVNXtHoxkpBo8U2HHJG8FrVXXuLvDNndSHXwx4C9VslUwDn5zSCI+PdBl8iAg+ZuBmKjqkpZZ9sL6DC5yQ==} + '@api.global/typedrequest@3.3.0': + resolution: {integrity: sha512-Jwobqla+9k2IBG0duwrCFtc6GU6wsvHS3f0gJJsxTrpapylBW1YSF7NnGHPGs7F9hbATsO6IoUBpR2ScoKyGJA==} '@aws-crypto/crc32@5.2.0': resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} @@ -236,8 +230,8 @@ packages: '@borewit/text-codec@0.1.1': resolution: {integrity: sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==} - '@cloudflare/workers-types@4.20251119.0': - resolution: {integrity: sha512-DfCMGhqhvOow3NDViL3T9SgAtogc+xjtAKCfL+aWpVcAcct31P8FSFFRqlZCjcXJ5Kqw/TOjD/87UEAXAqaQZA==} + '@cfworker/json-schema@4.1.1': + resolution: {integrity: sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==} '@colors/colors@1.6.0': resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} @@ -267,158 +261,158 @@ packages: '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} - '@esbuild/aix-ppc64@0.25.12': - resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + '@esbuild/aix-ppc64@0.27.4': + resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.25.12': - resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + '@esbuild/android-arm64@0.27.4': + resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.12': - resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + '@esbuild/android-arm@0.27.4': + resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.12': - resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + '@esbuild/android-x64@0.27.4': + resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.12': - resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + '@esbuild/darwin-arm64@0.27.4': + resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.12': - resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + '@esbuild/darwin-x64@0.27.4': + resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.25.12': - resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + '@esbuild/freebsd-arm64@0.27.4': + resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.12': - resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + '@esbuild/freebsd-x64@0.27.4': + resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.12': - resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + '@esbuild/linux-arm64@0.27.4': + resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.12': - resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + '@esbuild/linux-arm@0.27.4': + resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.12': - resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + '@esbuild/linux-ia32@0.27.4': + resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.25.12': - resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + '@esbuild/linux-loong64@0.27.4': + resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.12': - resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + '@esbuild/linux-mips64el@0.27.4': + resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.12': - resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + '@esbuild/linux-ppc64@0.27.4': + resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.12': - resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + '@esbuild/linux-riscv64@0.27.4': + resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.25.12': - resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + '@esbuild/linux-s390x@0.27.4': + resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.12': - resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + '@esbuild/linux-x64@0.27.4': + resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.12': - resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + '@esbuild/netbsd-arm64@0.27.4': + resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.12': - resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + '@esbuild/netbsd-x64@0.27.4': + resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.12': - resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + '@esbuild/openbsd-arm64@0.27.4': + resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.12': - resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + '@esbuild/openbsd-x64@0.27.4': + resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.12': - resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + '@esbuild/openharmony-arm64@0.27.4': + resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.25.12': - resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + '@esbuild/sunos-x64@0.27.4': + resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.12': - resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + '@esbuild/win32-arm64@0.27.4': + resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.12': - resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + '@esbuild/win32-ia32@0.27.4': + resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.12': - resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + '@esbuild/win32-x64@0.27.4': + resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -426,36 +420,221 @@ packages: '@esm-bundle/chai@4.3.4-fix.0': resolution: {integrity: sha512-26SKdM4uvDWlY8/OOOxSB1AqQWeBosCX3wRYUZO7enTAj03CtVxIiCimYVG2WpULcyV51qapK4qTovwkUr5Mlw==} - '@git.zone/tsbuild@3.1.0': - resolution: {integrity: sha512-j8lMd84pmzWiU6NG3e+pyu0o41oo6mQVfcZv8kDsCrQwZMhoQV9Jp87MlU0i/XI5IZkqDjelG8Kx1QhOmbK+iQ==} + '@git.zone/tsbuild@4.3.0': + resolution: {integrity: sha512-lb6eMQ8RQPaJqAB4kC++GIElOiTAH1pClmoND/q7XHuiMZxv6cXz2/U/sZt339mon2c40dXRG2tkLF2jRsP0pQ==} hasBin: true - '@git.zone/tsbundle@2.5.2': - resolution: {integrity: sha512-EYTCfunqoxhxkowREZ+cJnww6eDh9cL18HJbHbSZ+vxzNeyS9x8mT9aqRlWkI7zgpvgDlGIYlyRUlUISXkQO6Q==} + '@git.zone/tsbundle@2.9.1': + resolution: {integrity: sha512-JW1xjSv7UjAm2lwAQPxhCWs14wqs+UIq5FqIGUPuI6rrDBWIMT2d0gpP6iP6TqXqgm6XpBlfU4rHcHheUXzXbQ==} hasBin: true - '@git.zone/tspublish@1.10.3': - resolution: {integrity: sha512-o2/jvNsdLC8SRdH1kQ7JjNOQNu9el0FpJ/QOW3mgiC5C9reuTp18iU4kijsVVLgvw4KZv6Z289SoKPh3HPsS0g==} + '@git.zone/tspublish@1.11.2': + resolution: {integrity: sha512-BcGap1OzXDgXpfQXMh9W17r/CkWNhPsJ3WzjG2wrGE+ePUJCJAm9w6+J8G5WdZZcZKPqTB07cp707LbSiksc5A==} hasBin: true - '@git.zone/tsrun@1.6.2': - resolution: {integrity: sha512-SOHbQqBg3/769/jPQcdpPCmugdEtIJINiG0O6aWx+su91GvGhheha5dAhccsCutJYErr+aJcBqBYuUYfhOfkFQ==} + '@git.zone/tsrun@2.0.1': + resolution: {integrity: sha512-NEcnsjvlC1o3Z6SS3VhKCf6Ev+Sh4EAinmggslrIR/ppMrvjDbXNFXoyr3PB+GLeSAR0JRZ1fGvVYjpEzjBdIg==} hasBin: true - '@git.zone/tsrun@2.0.0': - resolution: {integrity: sha512-yA6zCjL+kn7xfZe6sL/m4K+zYqgkznG/pF6++i/E17iwzpG6dHmW+VZmYldHe86sW4DcLMvqM6CxM+KlgaEpKw==} - hasBin: true - - '@git.zone/tstest@2.8.2': - resolution: {integrity: sha512-qIZFor1mT4+Xth24jbqZtrh2B2Vz2n27OVY1R22zEg4TgFldjEUVwIKz27axqK1HUA1PIw0mYn+vOgd+yMWO4w==} + '@git.zone/tstest@3.5.0': + resolution: {integrity: sha512-ugIJzdVkbgqSSw08SZajE7TB01GIYjEAmIy67O5skhvOyszGifwzJdR+8dS1VbQGlUUWQZMGQ2IowllHbAZYJQ==} hasBin: true '@hapi/bourne@3.0.0': resolution: {integrity: sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w==} - '@happy-dom/global-registrator@15.11.7': - resolution: {integrity: sha512-mfOoUlIw8VBiJYPrl5RZfMzkXC/z7gbSpi2ecycrj/gRWLq2CMV+Q+0G+JPjeOmuNFgg0skEIzkVFzVYFP6URw==} - engines: {node: '>=18.0.0'} + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@inquirer/checkbox@3.0.1': + resolution: {integrity: sha512-0hm2nrToWUdD6/UHnel/UKGdk1//ke5zGUpHIvk5ZWmaKezlGxZkOJXNSWsdxO/rEqTkbB3lNC2J6nBElV2aAQ==} + engines: {node: '>=18'} + + '@inquirer/confirm@4.0.1': + resolution: {integrity: sha512-46yL28o2NJ9doViqOy0VDcoTzng7rAb6yPQKU7VDLqkmbCaH4JqK4yk4XqlzNWy9PVC5pG1ZUXPBQv+VqnYs2w==} + engines: {node: '>=18'} + + '@inquirer/core@9.2.1': + resolution: {integrity: sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==} + engines: {node: '>=18'} + + '@inquirer/editor@3.0.1': + resolution: {integrity: sha512-VA96GPFaSOVudjKFraokEEmUQg/Lub6OXvbIEZU1SDCmBzRkHGhxoFAVaF30nyiB4m5cEbDgiI2QRacXZ2hw9Q==} + engines: {node: '>=18'} + + '@inquirer/expand@3.0.1': + resolution: {integrity: sha512-ToG8d6RIbnVpbdPdiN7BCxZGiHOTomOX94C2FaT5KOHupV40tKEDozp12res6cMIfRKrXLJyexAZhWVHgbALSQ==} + engines: {node: '>=18'} + + '@inquirer/figures@1.0.15': + resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} + engines: {node: '>=18'} + + '@inquirer/input@3.0.1': + resolution: {integrity: sha512-BDuPBmpvi8eMCxqC5iacloWqv+5tQSJlUafYWUe31ow1BVXjW2a5qe3dh4X/Z25Wp22RwvcaLCc2siHobEOfzg==} + engines: {node: '>=18'} + + '@inquirer/number@2.0.1': + resolution: {integrity: sha512-QpR8jPhRjSmlr/mD2cw3IR8HRO7lSVOnqUvQa8scv1Lsr3xoAMMworcYW3J13z3ppjBFBD2ef1Ci6AE5Qn8goQ==} + engines: {node: '>=18'} + + '@inquirer/password@3.0.1': + resolution: {integrity: sha512-haoeEPUisD1NeE2IanLOiFr4wcTXGWrBOyAyPZi1FfLJuXOzNmxCJPgUrGYKVh+Y8hfGJenIfz5Wb/DkE9KkMQ==} + engines: {node: '>=18'} + + '@inquirer/prompts@6.0.1': + resolution: {integrity: sha512-yl43JD/86CIj3Mz5mvvLJqAOfIup7ncxfJ0Btnl0/v5TouVUyeEdcpknfgc+yMevS/48oH9WAkkw93m7otLb/A==} + engines: {node: '>=18'} + + '@inquirer/rawlist@3.0.1': + resolution: {integrity: sha512-VgRtFIwZInUzTiPLSfDXK5jLrnpkuSOh1ctfaoygKAdPqjcjKYmGh6sCY1pb0aGnCGsmhUxoqLDUAU0ud+lGXQ==} + engines: {node: '>=18'} + + '@inquirer/search@2.0.1': + resolution: {integrity: sha512-r5hBKZk3g5MkIzLVoSgE4evypGqtOannnB3PKTG9NRZxyFRKcfzrdxXXPcoJQsxJPzvdSU2Rn7pB7lw0GCmGAg==} + engines: {node: '>=18'} + + '@inquirer/select@3.0.1': + resolution: {integrity: sha512-lUDGUxPhdWMkN/fHy1Lk7pF3nK1fh/gqeyWXmctefhxLYxlDsc7vsPBEpxrfVGDsVdyYJsiJoD4bJ1b623cV1Q==} + engines: {node: '>=18'} + + '@inquirer/type@2.0.0': + resolution: {integrity: sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==} + engines: {node: '>=18'} '@isaacs/balanced-match@4.0.1': resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} @@ -481,6 +660,118 @@ packages: resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jimp/core@1.6.0': + resolution: {integrity: sha512-EQQlKU3s9QfdJqiSrZWNTxBs3rKXgO2W+GxNXDtwchF3a4IqxDheFX1ti+Env9hdJXDiYLp2jTRjlxhPthsk8w==} + engines: {node: '>=18'} + + '@jimp/diff@1.6.0': + resolution: {integrity: sha512-+yUAQ5gvRC5D1WHYxjBHZI7JBRusGGSLf8AmPRPCenTzh4PA+wZ1xv2+cYqQwTfQHU5tXYOhA0xDytfHUf1Zyw==} + engines: {node: '>=18'} + + '@jimp/file-ops@1.6.0': + resolution: {integrity: sha512-Dx/bVDmgnRe1AlniRpCKrGRm5YvGmUwbDzt+MAkgmLGf+jvBT75hmMEZ003n9HQI/aPnm/YKnXjg/hOpzNCpHQ==} + engines: {node: '>=18'} + + '@jimp/js-bmp@1.6.0': + resolution: {integrity: sha512-FU6Q5PC/e3yzLyBDXupR3SnL3htU7S3KEs4e6rjDP6gNEOXRFsWs6YD3hXuXd50jd8ummy+q2WSwuGkr8wi+Gw==} + engines: {node: '>=18'} + + '@jimp/js-gif@1.6.0': + resolution: {integrity: sha512-N9CZPHOrJTsAUoWkWZstLPpwT5AwJ0wge+47+ix3++SdSL/H2QzyMqxbcDYNFe4MoI5MIhATfb0/dl/wmX221g==} + engines: {node: '>=18'} + + '@jimp/js-jpeg@1.6.0': + resolution: {integrity: sha512-6vgFDqeusblf5Pok6B2DUiMXplH8RhIKAryj1yn+007SIAQ0khM1Uptxmpku/0MfbClx2r7pnJv9gWpAEJdMVA==} + engines: {node: '>=18'} + + '@jimp/js-png@1.6.0': + resolution: {integrity: sha512-AbQHScy3hDDgMRNfG0tPjL88AV6qKAILGReIa3ATpW5QFjBKpisvUaOqhzJ7Reic1oawx3Riyv152gaPfqsBVg==} + engines: {node: '>=18'} + + '@jimp/js-tiff@1.6.0': + resolution: {integrity: sha512-zhReR8/7KO+adijj3h0ZQUOiun3mXUv79zYEAKvE0O+rP7EhgtKvWJOZfRzdZSNv0Pu1rKtgM72qgtwe2tFvyw==} + engines: {node: '>=18'} + + '@jimp/plugin-blit@1.6.0': + resolution: {integrity: sha512-M+uRWl1csi7qilnSK8uxK4RJMSuVeBiO1AY0+7APnfUbQNZm6hCe0CCFv1Iyw1D/Dhb8ph8fQgm5mwM0eSxgVA==} + engines: {node: '>=18'} + + '@jimp/plugin-blur@1.6.0': + resolution: {integrity: sha512-zrM7iic1OTwUCb0g/rN5y+UnmdEsT3IfuCXCJJNs8SZzP0MkZ1eTvuwK9ZidCuMo4+J3xkzCidRwYXB5CyGZTw==} + engines: {node: '>=18'} + + '@jimp/plugin-circle@1.6.0': + resolution: {integrity: sha512-xt1Gp+LtdMKAXfDp3HNaG30SPZW6AQ7dtAtTnoRKorRi+5yCJjKqXRgkewS5bvj8DEh87Ko1ydJfzqS3P2tdWw==} + engines: {node: '>=18'} + + '@jimp/plugin-color@1.6.0': + resolution: {integrity: sha512-J5q8IVCpkBsxIXM+45XOXTrsyfblyMZg3a9eAo0P7VPH4+CrvyNQwaYatbAIamSIN1YzxmO3DkIZXzRjFSz1SA==} + engines: {node: '>=18'} + + '@jimp/plugin-contain@1.6.0': + resolution: {integrity: sha512-oN/n+Vdq/Qg9bB4yOBOxtY9IPAtEfES8J1n9Ddx+XhGBYT1/QTU/JYkGaAkIGoPnyYvmLEDqMz2SGihqlpqfzQ==} + engines: {node: '>=18'} + + '@jimp/plugin-cover@1.6.0': + resolution: {integrity: sha512-Iow0h6yqSC269YUJ8HC3Q/MpCi2V55sMlbkkTTx4zPvd8mWZlC0ykrNDeAy9IJegrQ7v5E99rJwmQu25lygKLA==} + engines: {node: '>=18'} + + '@jimp/plugin-crop@1.6.0': + resolution: {integrity: sha512-KqZkEhvs+21USdySCUDI+GFa393eDIzbi1smBqkUPTE+pRwSWMAf01D5OC3ZWB+xZsNla93BDS9iCkLHA8wang==} + engines: {node: '>=18'} + + '@jimp/plugin-displace@1.6.0': + resolution: {integrity: sha512-4Y10X9qwr5F+Bo5ME356XSACEF55485j5nGdiyJ9hYzjQP9nGgxNJaZ4SAOqpd+k5sFaIeD7SQ0Occ26uIng5Q==} + engines: {node: '>=18'} + + '@jimp/plugin-dither@1.6.0': + resolution: {integrity: sha512-600d1RxY0pKwgyU0tgMahLNKsqEcxGdbgXadCiVCoGd6V6glyCvkNrnnwC0n5aJ56Htkj88PToSdF88tNVZEEQ==} + engines: {node: '>=18'} + + '@jimp/plugin-fisheye@1.6.0': + resolution: {integrity: sha512-E5QHKWSCBFtpgZarlmN3Q6+rTQxjirFqo44ohoTjzYVrDI6B6beXNnPIThJgPr0Y9GwfzgyarKvQuQuqCnnfbA==} + engines: {node: '>=18'} + + '@jimp/plugin-flip@1.6.0': + resolution: {integrity: sha512-/+rJVDuBIVOgwoyVkBjUFHtP+wmW0r+r5OQ2GpatQofToPVbJw1DdYWXlwviSx7hvixTWLKVgRWQ5Dw862emDg==} + engines: {node: '>=18'} + + '@jimp/plugin-hash@1.6.0': + resolution: {integrity: sha512-wWzl0kTpDJgYVbZdajTf+4NBSKvmI3bRI8q6EH9CVeIHps9VWVsUvEyb7rpbcwVLWYuzDtP2R0lTT6WeBNQH9Q==} + engines: {node: '>=18'} + + '@jimp/plugin-mask@1.6.0': + resolution: {integrity: sha512-Cwy7ExSJMZszvkad8NV8o/Z92X2kFUFM8mcDAhNVxU0Q6tA0op2UKRJY51eoK8r6eds/qak3FQkXakvNabdLnA==} + engines: {node: '>=18'} + + '@jimp/plugin-print@1.6.0': + resolution: {integrity: sha512-zarTIJi8fjoGMSI/M3Xh5yY9T65p03XJmPsuNet19K/Q7mwRU6EV2pfj+28++2PV2NJ+htDF5uecAlnGyxFN2A==} + engines: {node: '>=18'} + + '@jimp/plugin-quantize@1.6.0': + resolution: {integrity: sha512-EmzZ/s9StYQwbpG6rUGBCisc3f64JIhSH+ncTJd+iFGtGo0YvSeMdAd+zqgiHpfZoOL54dNavZNjF4otK+mvlg==} + engines: {node: '>=18'} + + '@jimp/plugin-resize@1.6.0': + resolution: {integrity: sha512-uSUD1mqXN9i1SGSz5ov3keRZ7S9L32/mAQG08wUwZiEi5FpbV0K8A8l1zkazAIZi9IJzLlTauRNU41Mi8IF9fA==} + engines: {node: '>=18'} + + '@jimp/plugin-rotate@1.6.0': + resolution: {integrity: sha512-JagdjBLnUZGSG4xjCLkIpQOZZ3Mjbg8aGCCi4G69qR+OjNpOeGI7N2EQlfK/WE8BEHOW5vdjSyglNqcYbQBWRw==} + engines: {node: '>=18'} + + '@jimp/plugin-threshold@1.6.0': + resolution: {integrity: sha512-M59m5dzLoHOVWdM41O8z9SyySzcDn43xHseOH0HavjsfQsT56GGCC4QzU1banJidbUrePhzoEdS42uFE8Fei8w==} + engines: {node: '>=18'} + + '@jimp/types@1.6.0': + resolution: {integrity: sha512-7UfRsiKo5GZTAATxm2qQ7jqmUXP0DxTArztllTcYdyw6Xi5oT4RaoXynVtCD4UyLK5gJgkZJcwonoijrhYFKfg==} + engines: {node: '>=18'} + + '@jimp/utils@1.6.0': + resolution: {integrity: sha512-gqFTGEosKbOkYF/WFj26jMHOI5OH2jeP1MmC/zbK6BF6VJBf8rIC5898dPfSzZEbSA0wbbV5slbntWVc5PKLFA==} + engines: {node: '>=18'} + '@koa/router@9.4.0': resolution: {integrity: sha512-dOOXgzqaDoHu5qqMEPLKEgLz5CeIA7q8+1W62mCvFVCOqeC71UoTGJ4u1xUSOpIl2J1x2pqrNULkFteUeZW3/A==} engines: {node: '>= 8.0.0'} @@ -497,23 +788,23 @@ packages: '@mixmark-io/domino@2.2.0': resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==} - '@module-federation/error-codes@0.21.4': - resolution: {integrity: sha512-ClpL5MereWNXh+EgDjz7w4RrC1JlisQTvXDa1gLxpviHafzNDfdViVmuhi9xXVuj+EYo8KU70Y999KHhk9424Q==} + '@module-federation/error-codes@0.22.0': + resolution: {integrity: sha512-xF9SjnEy7vTdx+xekjPCV5cIHOGCkdn3pIxo9vU7gEZMIw0SvAEdsy6Uh17xaCpm8V0FWvR0SZoK9Ik6jGOaug==} - '@module-federation/runtime-core@0.21.4': - resolution: {integrity: sha512-SGpmoOLGNxZofpTOk6Lxb2ewaoz5wMi93AFYuuJB04HTVcngEK+baNeUZ2D/xewrqNIJoMY6f5maUjVfIIBPUA==} + '@module-federation/runtime-core@0.22.0': + resolution: {integrity: sha512-GR1TcD6/s7zqItfhC87zAp30PqzvceoeDGYTgF3Vx2TXvsfDrhP6Qw9T4vudDQL3uJRne6t7CzdT29YyVxlgIA==} - '@module-federation/runtime-tools@0.21.4': - resolution: {integrity: sha512-RzFKaL0DIjSmkn76KZRfzfB6dD07cvID84950jlNQgdyoQFUGkqD80L6rIpVCJTY/R7LzR3aQjHnoqmq4JPo3w==} + '@module-federation/runtime-tools@0.22.0': + resolution: {integrity: sha512-4ScUJ/aUfEernb+4PbLdhM/c60VHl698Gn1gY21m9vyC1Ucn69fPCA1y2EwcCB7IItseRMoNhdcWQnzt/OPCNA==} - '@module-federation/runtime@0.21.4': - resolution: {integrity: sha512-wgvGqryurVEvkicufJmTG0ZehynCeNLklv8kIk5BLIsWYSddZAE+xe4xov1kgH5fIJQAoQNkRauFFjVNlHoAkA==} + '@module-federation/runtime@0.22.0': + resolution: {integrity: sha512-38g5iPju2tPC3KHMPxRKmy4k4onNp6ypFPS1eKGsNLUkXgHsPMBFqAjDw96iEcjri91BrahG4XcdyKi97xZzlA==} - '@module-federation/sdk@0.21.4': - resolution: {integrity: sha512-tzvhOh/oAfX++6zCDDxuvioHY4Jurf8vcfoCbKFxusjmyKr32GPbwFDazUP+OPhYCc3dvaa9oWU6X/qpUBLfJw==} + '@module-federation/sdk@0.22.0': + resolution: {integrity: sha512-x4aFNBKn2KVQRuNVC5A7SnrSCSqyfIWmm1DvubjbO9iKFe7ith5niw8dqSFBekYBg2Fwy+eMg4sEFNVvCAdo6g==} - '@module-federation/webpack-bundler-runtime@0.21.4': - resolution: {integrity: sha512-dusmR3uPnQh9u9ChQo3M+GLOuGFthfvnh7WitF/a1eoeTfRmXqnMFsXtZCUK+f/uXf+64874Zj/bhAgbBcVHZA==} + '@module-federation/webpack-bundler-runtime@0.22.0': + resolution: {integrity: sha512-aM8gCqXu+/4wBmJtVeMeeMN5guw3chf+2i6HajKtQv7SJfxV/f4IyNQJUeUQu9HfiAZHjqtMV5Lvq/Lvh8LdyA==} '@mongodb-js/saslprep@1.3.2': resolution: {integrity: sha512-QgA5AySqB27cGTXBFmnpifAi7HxoGUeezwo6p9dI03MuDB6Pp33zgclqVb6oVK3j6I9Vesg0+oojW2XxB59SGg==} @@ -533,22 +824,6 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@oozcitak/dom@1.15.10': - resolution: {integrity: sha512-0JT29/LaxVgRcGKvHmSrUTEvZ8BXvZhGl2LASRUgHqDTC1M5g1pLmVv56IYNyt3bG2CUjDkc67wnyZC14pbQrQ==} - engines: {node: '>=8.0'} - - '@oozcitak/infra@1.0.8': - resolution: {integrity: sha512-JRAUc9VR6IGHOL7OGF+yrvs0LO8SlqGnPAMqyzOuFZPSZSXI7Xf2O9+awQPSMXgIWGtgUf/dA6Hs6X6ySEaWTg==} - engines: {node: '>=6.0'} - - '@oozcitak/url@1.0.4': - resolution: {integrity: sha512-kDcD8y+y3FCSOvnBI6HJgl00viO/nGbQoCINmQ0h98OhnGITrWR3bOGfwYCthgcrV8AnTJz8MzslTQbC3SOAmw==} - engines: {node: '>=8.0'} - - '@oozcitak/util@8.3.8': - resolution: {integrity: sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ==} - engines: {node: '>=8.0'} - '@open-wc/dedupe-mixin@2.0.1': resolution: {integrity: sha512-+R4VxvceUxHAUJXJQipkkoV9fy10vNo+OnUnGKZnVmcwxMl460KLzytnUM4S35SI073R0yZQp9ra0MbPUwVcEA==} @@ -564,8 +839,8 @@ packages: '@open-wc/testing@4.0.0': resolution: {integrity: sha512-KI70O0CJEpBWs3jrTju4BFCy7V/d4tFfYWkg8pMzncsDhD7TYNHLw5cy+s1FHXIgVFetnMDhPpwlKIPvtTQW7w==} - '@oxc-project/types@0.98.0': - resolution: {integrity: sha512-Vzmd6FsqVuz5HQVcRC/hrx7Ujo3WEVeQP7C2UNP5uy1hUY4SQvMB+93jxkI1KRHz9a/6cni3glPOtvteN+zpsw==} + '@oxc-project/types@0.99.0': + resolution: {integrity: sha512-LLDEhXB7g1m5J+woRSgfKsFPS3LhR9xRhTeIoEBm5WrkwMxn6eZ0Ld0c0K5eHB57ChZX6I3uSmmLjZ8pcjlRcw==} '@pdf-lib/standard-fonts@1.0.0': resolution: {integrity: sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==} @@ -630,9 +905,6 @@ packages: '@push.rocks/early@4.0.4': resolution: {integrity: sha512-ak6/vqZ1PlFV08fSFQ6UwiBrr+K6IsfieZWWzT7eex1Ls6GvWEi8wZ3REFDPJq/qckNLWSgEy0EsqzRtltkaCA==} - '@push.rocks/isohash@2.0.1': - resolution: {integrity: sha512-UulhEui8O9Ei9fSqTldsB73TUmAFNqEBk82tHsJSLLpNK9gJZQE82iaSNsQUakoUQ2c9KueueMfwC3IoDaYRrQ==} - '@push.rocks/isounique@1.0.5': resolution: {integrity: sha512-Z0BVqZZOCif1THTbIKWMgg0wxCzt9CyBtBBqQJiZ+jJ0KlQFrQHNHrPt81/LXe/L4x0cxWsn0bpL6W5DNSvNLw==} @@ -642,17 +914,23 @@ packages: '@push.rocks/lik@6.2.2': resolution: {integrity: sha512-j64FFPPyMXeeUorjKJVF6PWaJUfiIrF3pc41iJH4lOh0UUpBAHpcNzHVxTR58orwbVA/h3Hz+DQd4b1Rq0dFDQ==} + '@push.rocks/lik@6.3.1': + resolution: {integrity: sha512-UWDwGBaVx5yPtAFXqDDBtQZCzETUOA/7myQIXb+YBsuiIw4yQuhNZ23uY2ChQH2Zn6DLqdNSgQcYC0WywMZBNQ==} + '@push.rocks/mongodump@1.1.0': resolution: {integrity: sha512-kW0ZUGyf1e4nwloVwBQjNId+MzgTcNS834C+RxH21i1NqyOubbpWZtJtPP+K+s35nSJRyCTy3ICfBMdDBTAm2w==} + '@push.rocks/npmextra@5.3.3': + resolution: {integrity: sha512-snLpSHwaQ5OXlZzF1KX/FY71W5LwajjBzor82Vue0smjEPnSeUPY5/JcVdMwtdprdJe13pc/EQQuIiL/zw4/yg==} + '@push.rocks/qenv@6.1.3': resolution: {integrity: sha512-+z2hsAU/7CIgpYLFqvda8cn9rUBMHqLdQLjsFfRn5jPoD7dJ5rFlpkbhfM4Ws8mHMniwWaxGKo+q/YBhtzRBLg==} '@push.rocks/smartarchive@4.2.2': resolution: {integrity: sha512-6EpqbKU32D6Gcqsc9+Tn1dOCU5HoTlrqqs/7IdUr9Tirp9Ngtptkapca1Fw/D0kVJ7SSw3kG/miAYnuPMZLEoA==} - '@push.rocks/smartbrowser@2.0.8': - resolution: {integrity: sha512-0KWRZj3TuKo/sNwgPbiSE6WL+TMeR19t1JmXBZWh9n8iA2mpc4HhMrQAndEUdRCkx5ofSaHWojIRVFzGChj0Dg==} + '@push.rocks/smartbrowser@2.0.11': + resolution: {integrity: sha512-Rj3+VodlFbW7CkvXqYxH4dEhtbYy987gVY7wsM76B+ipvnkSfjfEGuKUeMfKe4DscUBSmhlbJVYEYaH8RafUoQ==} '@push.rocks/smartbucket@3.3.10': resolution: {integrity: sha512-0H2MioALspC8Aj0Q1FPCs2w4k2u9oJg7Q5yM8+1TZo7aRfrdxgM5HQ7z3apUaqC3ZEDewW6vSlttjHFHhMEC3A==} @@ -663,11 +941,8 @@ packages: '@push.rocks/smartcache@1.0.18': resolution: {integrity: sha512-3+cmLu9chbnmi4yD4kjlFP/Tn4NReaZIoicEcGTtwbcokTrSDMs3YPdJzIpDZkAs83PW7OcVSHa3Ak5KU5OWzA==} - '@push.rocks/smartchok@1.1.1': - resolution: {integrity: sha512-WmNigGmn1muBJMANVuJb4F8x3TzgYrnn6YZm6ixTsG+0WFbYevivEwp+J4S7npobLHsR7ynf+Ky8LxRYmsL50A==} - - '@push.rocks/smartcli@4.0.19': - resolution: {integrity: sha512-s1jZSgDZWi/az26AY4TJ2HPuG1qZzGC5R9fKWaECLmwnSpk6y9JXL5dnJAUohcdu50kdXCWEcRmLfYxOt81vEA==} + '@push.rocks/smartcli@4.0.20': + resolution: {integrity: sha512-gCo4ItvsPj8WoVAJw/6vkuoGA5FtIoACux2ktcCeH0nrFe7/xGR6waJ1aZcYAi7QN4gi52TlsgwuKz7BzXqhmQ==} '@push.rocks/smartclickhouse@2.0.17': resolution: {integrity: sha512-IYO8Obor/Ruam2KQ2B/+5uQ+rL0exU5KZoSgOc3jkkrfjn+zZenN2xoV8lVqavAtxZVfG7MfxFrcv6I7I9ZMmA==} @@ -696,6 +971,9 @@ packages: '@push.rocks/smartexit@1.0.23': resolution: {integrity: sha512-WmwKYcwbHBByoABhHHB+PAjr5475AtD/xBh1mDcqPrFsOOUOZq3BBUdpq25wI3ccu/SZB5IwaimiVzadls6HkA==} + '@push.rocks/smartexit@2.0.3': + resolution: {integrity: sha512-ZWpZ3Elorpv/rKtUcCUejUHG4BIE5B3QWysBAgb7lTcA7y0vGdFY32Y5/Q5tHpZM6PPxl/WTdUOYtSojQTq+pA==} + '@push.rocks/smartexpect@2.5.0': resolution: {integrity: sha512-yoyuCoQ3tTiAriuvF+/09fNbVfFnacudL2SwHSzPhX/ugaE7VTSWXQ9A34eKOWvil0MPyDcOY36fVZDxvrPd8A==} @@ -708,17 +986,29 @@ packages: '@push.rocks/smartfile@11.2.7': resolution: {integrity: sha512-8Yp7/sAgPpWJBHohV92ogHWKzRomI5MEbSG6b5W2n18tqwfAmjMed0rQvsvGrSBlnEWCKgoOrYIIZbLO61+J0Q==} + '@push.rocks/smartfile@13.1.2': + resolution: {integrity: sha512-DaEhwmnGEpX4coeeToaw4cZe3pNBhH7CY1iGr+d3pIXihozREvzzAR9/0i2r7bUXXL5+Lgy8YYIk5ZS+fwxMKA==} + + '@push.rocks/smartfs@1.5.0': + resolution: {integrity: sha512-QwMD44HgX3d9PPxUwR0uS+0PEMtesKvKbZR+s4pezL2er6oPneKJMLkO6TJPvJ38nug6Lmlk9Bu7UrwR2kS3Vw==} + '@push.rocks/smartguard@3.1.0': resolution: {integrity: sha512-J23q84f1O+TwFGmd4lrO9XLHUh2DaLXo9PN/9VmTWYzTkQDv5JehmifXVI0esophXcCIfbdIu6hbt7/aHlDF4A==} '@push.rocks/smarthash@3.2.6': resolution: {integrity: sha512-Mq/WNX0Tjjes3X1gHd/ZBwOOKSrAG/Z3Xoc0OcCm3P20WKpniihkMpsnlE7wGjvpHLi/ZRe/XkB3KC3d5r9X4g==} + '@push.rocks/smartinteract@2.0.16': + resolution: {integrity: sha512-eltvVRRUKBKd77DSFA4DPY2g4V4teZLNe8A93CDy/WglglYcUjxMoLY/b0DFTWCWKYT+yjk6Fe6p0FRrvX9Yvg==} + + '@push.rocks/smartjimp@1.2.0': + resolution: {integrity: sha512-SPz8p2ZuphNqIXK/UDsNFrnpJn/jr6FbuBSMQc0V2v2ffQIF32ZqktKQpXpitiqD1K5JEYS56JAhlYHgrAu7yw==} + '@push.rocks/smartjson@5.2.0': resolution: {integrity: sha512-710e8UwovRfPgUtaBHcd6unaODUjV5fjxtGcGCqtaTcmvOV6VpasdVfT66xMDzQmWH2E9ZfHDJeso9HdDQzNQA==} - '@push.rocks/smartlog-destination-devtools@1.0.12': - resolution: {integrity: sha512-zvsIkrqByc0JRaBgIyhh+PSz2SY/e/bmhZdUcr/OW6pudgAcqe2sso68EzrKux0w9OMl1P9ZnzF3FpCZPFWD/A==} + '@push.rocks/smartjson@6.0.0': + resolution: {integrity: sha512-FYfJnmukt66WePn6xrVZ3BLmRQl9W82LcsICK3VU9sGW7kasig090jKXPm+yX8ibQcZAO/KyR/Q8tMIYZNxGew==} '@push.rocks/smartlog-destination-local@9.0.2': resolution: {integrity: sha512-htzIY+4+hU61Z2J4Oz+IHnAB3RGe+fpS0VKCKnAoppZqzMWnJ3UOgYIyr4djDBy2WtgpXV/16KdisKrOmwuuvw==} @@ -729,8 +1019,8 @@ packages: '@push.rocks/smartlog@3.1.10': resolution: {integrity: sha512-5pf5JyzOE2WTCUislNIW4EHePo1a7hiXB+jbil38+N5hW71AEwcPFe6oGxbp5w9ALlz66hV2+E+25R0SsxN+fQ==} - '@push.rocks/smartmanifest@2.0.2': - resolution: {integrity: sha512-QGc5C9vunjfUbYsPGz5bynV/mVmPHkrQDkWp8ZO8VJtK1GZe+njgbrNyxn2SUHR0IhSAbSXl1j4JvBqYf5eTVg==} + '@push.rocks/smartlog@3.2.1': + resolution: {integrity: sha512-x9/P59pfzY6HOGYmYrhqmoRl/pliTVx44g2Vbb8dIr/0zA39cAJHlPze1+UGncn37XKGmutK2iLSsJLEsexD0A==} '@push.rocks/smartmarkdown@3.0.3': resolution: {integrity: sha512-9KhKZxDQKPk4P/2CYdVqJa5dpGfTA8w1cxqoVZL3e8RPA7EGxbdYEqMp0n2d9mth0btk/m0KHHV+G09LfCVeBw==} @@ -744,29 +1034,26 @@ packages: '@push.rocks/smartmongo@2.0.14': resolution: {integrity: sha512-fvfPeCDDy5JaDBpVnsMKednsOoRzuYC0OszO8OoLOX/RaR755zIbRppCCK8Cez0hqd6eNkJGQeWdX/vXlJOPBA==} + '@push.rocks/smartmongo@5.1.0': + resolution: {integrity: sha512-2tpKf8K+SMdLHOEpafgKPIN+ypWTLwHc33hCUDNMQ1KaL7vokkavA44+fHxQydOGPMtDi22tSMFeVMCcUSzs4w==} + '@push.rocks/smartnetwork@4.4.0': resolution: {integrity: sha512-OvFtz41cvQ7lcXwaIOhghNUUlNoMxvwKDctbDvMyuZyEH08SpLjhyv2FuKbKL/mgwA/WxakTbohoC8SW7t+kiw==} '@push.rocks/smartnpm@2.0.6': resolution: {integrity: sha512-7anKDOjX6gXWs1IAc+YWz9ZZ8gDsTwaLh+CxRnGHjAawOmK788NrrgVCg2Fb3qojrPnoxecc46F8Ivp1BT7Izw==} - '@push.rocks/smartntml@2.0.8': - resolution: {integrity: sha512-LIYeOQbmav2m2kZQz4pGS74xvWAm4YAGQnbPkofA2oas4RW9SGR1JTRpFd9pxGCOXd6djYdNGsZZ/xz+k/vRPQ==} - '@push.rocks/smartobject@1.0.12': resolution: {integrity: sha512-xSMiqXiZXXUOixT3QIPsOUKOWjL3YA/1h9/YTiCzqs5C0D3tyfTbojnfcp6YbKZoBzans2I5LghaDHsGid2DKQ==} - '@push.rocks/smartopen@2.0.0': - resolution: {integrity: sha512-eVT0GhtQ2drb95j/kktYst/Toh1zCwCqjTJFYtaYFUnnBnBUajPtBZDFnPQo01DN8JxoeCTo8jggq+PCvzcfww==} - '@push.rocks/smartpath@5.1.0': resolution: {integrity: sha512-pJ4UGATHV/C6Dw5DU0D3MJaPMASlKAgeS+Hl9dkhD2ceYArn86Ky3Z/g7LNj40Oz6cUe77/AP1chztmJZISrpw==} '@push.rocks/smartpath@6.0.0': resolution: {integrity: sha512-r94u1MbBaIOSy+517PZp2P7SuZPSe9LkwJ8l3dXQKHeIOri/zDxk/RQPiFM+j4N9301ztkRyhvRj7xgUDroOsg==} - '@push.rocks/smartpdf@3.3.0': - resolution: {integrity: sha512-k4mBZAIl/TVBHDYQXaBZAgC8DdmHXsIZ3hRrLY3ysLr143YJ1VkwqQ2poqWh3A2SZQDrVfpKRYliUtjFRFrYVw==} + '@push.rocks/smartpdf@4.2.0': + resolution: {integrity: sha512-+egzby5QKJGO10MDvWp+N69cJ8i5M354l9ntc+uLRpxuq/FEY9kigpRwMvRYF5qwOBTuGTLqvmvILzlLtboAQg==} '@push.rocks/smartping@1.0.8': resolution: {integrity: sha512-Fvx1Db6hSsDOI6pdiCuS9GjtOX8ugx865YQrPg5vK2iw6Qj/srwyXcWLFYt+19WVKtvtWDJIAKbW+q3bXFsCeA==} @@ -783,23 +1070,29 @@ packages: '@push.rocks/smartrequest@4.4.2': resolution: {integrity: sha512-Om4y1Ce4YdSu8VoXREz2SgFz9pDxcFEm0+SC1YYa3RXd0AH2Mknaj/1XfvfMqojnK9L7N2z1fY4xX8tO1IwqFQ==} + '@push.rocks/smartrequest@5.0.1': + resolution: {integrity: sha512-gZQQF6HVt3LwTBxaPh6hHObd4VF76PUYQcs5pHD7f0VXaEewmrNAQSnccoinOY7fi45+0dOf04PJOXu9MibPzQ==} + '@push.rocks/smartrouter@1.3.3': resolution: {integrity: sha512-1+xZEnWlhzqLWAaJ1zFNhQ0zgbfCWQl1DBT72LygLxTs+P0K8AwJKgqo/IX6CT55kGCFnPAZIYSbVJlGsgrB0w==} + '@push.rocks/smartrust@1.3.2': + resolution: {integrity: sha512-HPzSJgDnKUdE5fkn2+BC9JvFXk7wl6aURAiHAXjHSCBLtzfgB7jEXjlg+K6CEfMjwQV7sy+hYABlq5DLXcFseQ==} + '@push.rocks/smartrx@3.0.10': resolution: {integrity: sha512-USjIYcsSfzn14cwOsxgq/bBmWDTTzy3ouWAnW5NdMyRRzEbmeNrvmy6TRqNeDlJ2PsYNTt1rr/zGUqvIy72ITg==} '@push.rocks/smarts3@2.2.6': resolution: {integrity: sha512-f2i2keHs+KZr5cyB8nBOnmRGiE2YG42W4pSx+8gmZEsf8yZUT1iUnuD/YZVTKosH2v5dPCKdmtSpMSux8Q/tCw==} + '@push.rocks/smartserve@2.0.1': + resolution: {integrity: sha512-YQb2qexfCzCqOlLWBBXKMg6xG4zahCPAxomz/KEKAwHtW6wMTtuHKSTSkRTQ0vl9jssLMAmRz2OyafiL9XGJXQ==} + '@push.rocks/smartshell@3.3.0': resolution: {integrity: sha512-m0w618H6YBs+vXGz1CgS4nPi5CUAnqRtckcS9/koGwfcIx1IpjqmiP47BoCTbdgcv0IPUxQVBG1IXTHPuZ8Z5g==} - '@push.rocks/smartsitemap@2.0.3': - resolution: {integrity: sha512-jIcms8V1b2mt3dS4PKNlLR1DRC8pCDWMRVbnyM/2+snZOJZonQRlQzAyX8No0EfLbfdrfnxv2IjPX13X29Re6g==} - - '@push.rocks/smartsocket@2.1.0': - resolution: {integrity: sha512-etOGyfiDFQz/1WJnD3jFL2N7ykujTjiudAz6qZTz82xE5oabKuKX+Cn8SdM9dOwzyWmBUKbUdll8QhovAXjn+g==} + '@push.rocks/smartshell@3.3.8': + resolution: {integrity: sha512-t9J/py0vnea4ZtOs7Anc9dc6lcvg6EDvYBw5eE1mB+KUWxMQf/ROIQwWMo6B9SMNY4JS2UwvfuJQJ8makP/7Tg==} '@push.rocks/smartspawn@3.0.3': resolution: {integrity: sha512-DyrGPV69wwOiJgKkyruk5hS3UEGZ99xFAqBE9O2nM8VXCRLbbty3xt1Ug5Z092ZZmJYaaGMSnMw3ijyZJFCT0Q==} @@ -807,6 +1100,9 @@ packages: '@push.rocks/smartstate@2.0.27': resolution: {integrity: sha512-q4UKir7GV3hakJWXQR4DoA4tUVwT5GRkJ/MtanHYF0wZLHfS19+nGmyO9y974zk3eT9hmy3+Lq5cKtU2W6+Y3w==} + '@push.rocks/smartstorage@6.0.1': + resolution: {integrity: sha512-W5PEVwO0J2K9YUZRTbKXadC11h6/IBzzqU+P0TIE/xpJZC4K1duEXwEhxGWcbfhCkPRRa51xH8Z5mAmzzm8qxA==} + '@push.rocks/smartstream@3.2.5': resolution: {integrity: sha512-PLGGIFDy8JLNVUnnntMSIYN4W081YSbNC7Y/sWpvUT8PAXtbEXXUiDFgK5o3gcI0ptpKQxHAwxhzNlPj0sbFVg==} @@ -816,6 +1112,9 @@ packages: '@push.rocks/smarttime@4.1.1': resolution: {integrity: sha512-Ha/3J/G+zfTl4ahpZgF6oUOZnUjpLhrBja0OQ2cloFxF9sKT8I1COaSqIfBGDtoK2Nly4UD4aTJ3JcJNOg/kgA==} + '@push.rocks/smarttime@4.2.3': + resolution: {integrity: sha512-8gMg8RUkrCG4p9NcEUZV7V6KpL24+jAMK02g7qyhfA6giz/JJWD0+8w8xjSR+G7qe16KVQ2y3RbvAL9TxmO36g==} + '@push.rocks/smartunique@3.0.9': resolution: {integrity: sha512-q6DYQgT7/dqdWi9HusvtWCjdsFzLFXY9LTtaZV6IYNJt6teZOonoygxTdNt9XLn6niBSbLYrHSKvJNTRH/uK+g==} @@ -825,8 +1124,9 @@ packages: '@push.rocks/smartversion@3.0.5': resolution: {integrity: sha512-8MZSo1yqyaKxKq0Q5N188l4un++9GFWVbhCAX5mXJwewZHn97ujffTeL+eOQYpWFTEpUhaq1QhL4NhqObBCt1Q==} - '@push.rocks/smartxml@1.1.1': - resolution: {integrity: sha512-1toSmLE1EGK8oENh09XjV588+IdzUB3x1PCaxKjSyIsAt54bUQj3kH/yzLODF+19p07OE0KM5U1oqWpjOcFCzA==} + '@push.rocks/smartwatch@6.3.0': + resolution: {integrity: sha512-TeZ1PGBoBMpC4/CK8StIj5InEiFfKp7xWJSm3aYMjB/uaoeRP0vXqv1ORIC/TKYGJuEDuAXUsit8tZVjn0qT1Q==} + engines: {node: '>=20.0.0'} '@push.rocks/smartxml@2.0.0': resolution: {integrity: sha512-1d06zYJX4Zt8s5w5qFOUg2LAEz9ykrh9d6CQPK4WAgOBIefb1xzVEWHc7yoxicc2OkzNgC3IBCEg3s6BncZKWw==} @@ -846,8 +1146,8 @@ packages: '@push.rocks/webrequest@3.0.37': resolution: {integrity: sha512-fLN7kP6GeHFxE4UH4r9C9pjcQb0QkJxHeAMwXvbOqB9hh0MFNKhtGU7GoaTn8SVRGRMPc9UqZVNwo6u5l8Wn0A==} - '@push.rocks/webrequest@4.0.1': - resolution: {integrity: sha512-I60XZZLVf8W5I7YdmUVVu4G92teE3rg3/aKaV00BRg8vJ3VXx3wc59Qj4em7zxQ5o0HvL8m1Aezw3RFMDPyVgA==} + '@push.rocks/webrequest@4.0.5': + resolution: {integrity: sha512-wVSCaXqJ9Vh+rbwVz0wDl46dYz4rnwwSrm5vbVXKbuH6oKTPF0YRoujeJPqRltIn64RVGdLeY9/6ix+ZCrzhsg==} '@push.rocks/websetup@3.0.19': resolution: {integrity: sha512-iKJDwXdMmQdu5siOIgziPRxM51lN1AU9HOr+yMteu1YMDkZT7HKCyisDAr4gC9WZ9a7FzsG8zgthm4dMeA8NTw==} @@ -858,178 +1158,154 @@ packages: '@push.rocks/webstream@1.0.10': resolution: {integrity: sha512-45CcR0I4/9v0qSjLvz2dYTGMkR0YP3x66ItpStdad5hidJm86t1lfHF06d0oiEvJTpvQkeyIX/8YKAumf21d/Q==} - '@pushrocks/isounique@1.0.5': - resolution: {integrity: sha512-XYeoKGkmIdsWX64NlPA1fuA41n/1bQ7LdYXytlU/QqYeW7ojgA0ARRhBSh/2phL6o0Jpw6K/7gJ8jc7ab/Tc+w==} - deprecated: This package has been deprecated in favour of the new package at @push.rocks/isounique - '@pushrocks/smartdelay@3.0.1': resolution: {integrity: sha512-I+i/QhC6kLsXsWyW19UgD1vH2r1YWVxK19VMxt2CEuvxMyC6tuCd0vqud9vv5JxaxsJwxWlOsrURkgL4tXeILQ==} deprecated: This package has been deprecated in favour of the new package at @push.rocks/smartdelay - '@pushrocks/smartenv@5.0.5': - resolution: {integrity: sha512-VWON1OJ4qV2/9hzJbgRquRekaO9am3b8W82tgCwgO6LBg23ea2tanfd+gESVMbRFduxHVoFLvlhSBcDGM5zsLA==} - deprecated: This package has been deprecated in favour of the new package at @push.rocks/smartenv - - '@pushrocks/smarthash@3.0.2': - resolution: {integrity: sha512-jXW4f8k6iqOQRvkCmXMID1C+qXyNvUMKm7apPETxnO+L172VlzxP1dml0Ey1+vjfpU2luKCteJWX7W95sOdLDg==} - deprecated: This package has been deprecated in favour of the new package at @push.rocks/smarthash - - '@pushrocks/smartjson@5.0.6': - resolution: {integrity: sha512-9OJbnRgLTaCRQz+pqu5tB3ZCqRs5Zh0hnBe7t7URE+TgwIZ8aiELUIbWRkgn4mSGVzHyL6pqTyIowP6AjUCG3w==} - deprecated: This package has been deprecated in favour of the new package at @push.rocks/smartjson - - '@pushrocks/smartpromise@3.1.10': - resolution: {integrity: sha512-VeTurbZ1+ZMxBDJk1Y1LV8SN9xLI+oDXKVeCFw41FAGEKOUEqordqFpi6t+7Vhe/TXUZzCVpZ5bXxAxrGf8yTQ==} - deprecated: This package has been deprecated in favour of the new package at @push.rocks/smartpromise - '@pushrocks/smartpromise@4.0.2': resolution: {integrity: sha512-bqorOaGXPOuiOSV81luTKrTghg4O4NBRD0zyv7TIqmrMGf4a0uoozaUMp1X8vQdZW+y0gTzUJP9wkzAE6Cci0g==} deprecated: This package has been deprecated in favour of the new package at @push.rocks/smartpromise - '@pushrocks/smartstring@4.0.7': - resolution: {integrity: sha512-TxHSar7Cj29E+GOcIj4DeZKWCNVzHKdqnrBRqcBqLqmeYZvzFosLXpFKoaCJDq7MSxuPoCvu5woSdp9YmPXyog==} - deprecated: This package has been deprecated in favour of the new package at @push.rocks/smartstring - - '@rolldown/binding-android-arm64@1.0.0-beta.51': - resolution: {integrity: sha512-Ctn8FUXKWWQI9pWC61P1yumS9WjQtelNS9riHwV7oCkknPGaAry4o7eFx2KgoLMnI2BgFJYpW7Im8/zX3BuONg==} + '@rolldown/binding-android-arm64@1.0.0-beta.52': + resolution: {integrity: sha512-MBGIgysimZPqTDcLXI+i9VveijkP5C3EAncEogXhqfax6YXj1Tr2LY3DVuEOMIjWfMPMhtQSPup4fSTAmgjqIw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-beta.51': - resolution: {integrity: sha512-EL1aRW2Oq15ShUEkBPsDtLMO8GTqfb/ktM/dFaVzXKQiEE96Ss6nexMgfgQrg8dGnNpndFyffVDb5IdSibsu1g==} + '@rolldown/binding-darwin-arm64@1.0.0-beta.52': + resolution: {integrity: sha512-MmKeoLnKu1d9j6r19K8B+prJnIZ7u+zQ+zGQ3YHXGnr41rzE3eqQLovlkvoZnRoxDGPA4ps0pGiwXy6YE3lJyg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-beta.51': - resolution: {integrity: sha512-uGtYKlFen9pMIPvkHPWZVDtmYhMQi5g5Ddsndg1gf3atScKYKYgs5aDP4DhHeTwGXQglhfBG7lEaOIZ4UAIWww==} + '@rolldown/binding-darwin-x64@1.0.0-beta.52': + resolution: {integrity: sha512-qpHedvQBmIjT8zdnjN3nWPR2qjQyJttbXniCEKKdHeAbZG9HyNPBUzQF7AZZGwmS9coQKL+hWg9FhWzh2dZ2IA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-beta.51': - resolution: {integrity: sha512-JRoVTQtHYbZj1P07JLiuTuXjiBtIa7ag7/qgKA6CIIXnAcdl4LrOf7nfDuHPJcuRKaP5dzecMgY99itvWfmUFQ==} + '@rolldown/binding-freebsd-x64@1.0.0-beta.52': + resolution: {integrity: sha512-dDp7WbPapj/NVW0LSiH/CLwMhmLwwKb3R7mh2kWX+QW85X1DGVnIEyKh9PmNJjB/+suG1dJygdtdNPVXK1hylg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.51': - resolution: {integrity: sha512-BKATVnpPZ0TYBW9XfDwyd4kPGgvf964HiotIwUgpMrFOFYWqpZ+9ONNzMV4UFAYC7Hb5C2qgYQk/qj2OnAd4RQ==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.52': + resolution: {integrity: sha512-9e4l6vy5qNSliDPqNfR6CkBOAx6PH7iDV4OJiEJzajajGrVy8gc/IKKJUsoE52G8ud8MX6r3PMl97NfwgOzB7g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.51': - resolution: {integrity: sha512-xLd7da5jkfbVsBCm1buIRdWtuXY8+hU3+6ESXY/Tk5X5DPHaifrUblhYDgmA34dQt6WyNC2kfXGgrduPEvDI6Q==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.52': + resolution: {integrity: sha512-V48oDR84feRU2KRuzpALp594Uqlx27+zFsT6+BgTcXOtu7dWy350J1G28ydoCwKB+oxwsRPx2e7aeQnmd3YJbQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.51': - resolution: {integrity: sha512-EQFXTgHxxTzv3t5EmjUP/DfxzFYx9sMndfLsYaAY4DWF6KsK1fXGYsiupif6qPTViPC9eVmRm78q0pZU/kuIPg==} + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.52': + resolution: {integrity: sha512-ENLmSQCWqSA/+YN45V2FqTIemg7QspaiTjlm327eUAMeOLdqmSOVVyrQexJGNTQ5M8sDYCgVAig2Kk01Ggmqaw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.51': - resolution: {integrity: sha512-p5P6Xpa68w3yFaAdSzIZJbj+AfuDnMDqNSeglBXM7UlJT14Q4zwK+rV+8Mhp9MiUb4XFISZtbI/seBprhkQbiQ==} + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.52': + resolution: {integrity: sha512-klahlb2EIFltSUubn/VLjuc3qxp1E7th8ukayPfdkcKvvYcQ5rJztgx8JsJSuAKVzKtNTqUGOhy4On71BuyV8g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@rolldown/binding-linux-x64-musl@1.0.0-beta.51': - resolution: {integrity: sha512-sNVVyLa8HB8wkFipdfz1s6i0YWinwpbMWk5hO5S+XAYH2UH67YzUT13gs6wZTKg2x/3gtgXzYnHyF5wMIqoDAw==} + '@rolldown/binding-linux-x64-musl@1.0.0-beta.52': + resolution: {integrity: sha512-UuA+JqQIgqtkgGN2c/AQ5wi8M6mJHrahz/wciENPTeI6zEIbbLGoth5XN+sQe2pJDejEVofN9aOAp0kaazwnVg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] - '@rolldown/binding-openharmony-arm64@1.0.0-beta.51': - resolution: {integrity: sha512-e/JMTz9Q8+T3g/deEi8DK44sFWZWGKr9AOCW5e8C8SCVWzAXqYXAG7FXBWBNzWEZK0Rcwo9TQHTQ9Q0gXgdCaA==} + '@rolldown/binding-openharmony-arm64@1.0.0-beta.52': + resolution: {integrity: sha512-1BNQW8u4ro8bsN1+tgKENJiqmvc+WfuaUhXzMImOVSMw28pkBKdfZtX2qJPADV3terx+vNJtlsgSGeb3+W6Jiw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-beta.51': - resolution: {integrity: sha512-We3LWqSu6J9s5Y0MK+N7fUiiu37aBGPG3Pc347EoaROuAwkCS2u9xJ5dpIyLW4B49CIbS3KaPmn4kTgPb3EyPw==} + '@rolldown/binding-wasm32-wasi@1.0.0-beta.52': + resolution: {integrity: sha512-K/p7clhCqJOQpXGykrFaBX2Dp9AUVIDHGc+PtFGBwg7V+mvBTv/tsm3LC3aUmH02H2y3gz4y+nUTQ0MLpofEEg==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.51': - resolution: {integrity: sha512-fj56buHRuMM+r/cb6ZYfNjNvO/0xeFybI6cTkTROJatdP4fvmQ1NS8D/Lm10FCSDEOkqIz8hK3TGpbAThbPHsA==} + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.52': + resolution: {integrity: sha512-a4EkXBtnYYsKipjS7QOhEBM4bU5IlR9N1hU+JcVEVeuTiaslIyhWVKsvf7K2YkQHyVAJ+7/A9BtrGqORFcTgng==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.51': - resolution: {integrity: sha512-fkqEqaeEx8AySXiDm54b/RdINb3C0VovzJA3osMhZsbn6FoD73H0AOIiaVAtGr6x63hefruVKTX8irAm4Jkt2w==} + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.52': + resolution: {integrity: sha512-5ZXcYyd4GxPA6QfbGrNcQjmjbuLGvfz6728pZMsQvGHI+06LT06M6TPtXvFvLgXtexc+OqvFe1yAIXJU1gob/w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.51': - resolution: {integrity: sha512-CWuLG/HMtrVcjKGa0C4GnuxONrku89g0+CsH8nT0SNhOtREXuzwgjIXNJImpE/A/DMf9JF+1Xkrq/YRr+F/rCg==} + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.52': + resolution: {integrity: sha512-tzpnRQXJrSzb8Z9sm97UD3cY0toKOImx+xRKsDLX4zHaAlRXWh7jbaKBePJXEN7gNw7Nm03PBNwphdtA8KSUYQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.0-beta.51': - resolution: {integrity: sha512-51/8cNXMrqWqX3o8DZidhwz1uYq0BhHDDSfVygAND1Skx5s1TDw3APSSxCMcFFedwgqGcx34gRouwY+m404BBQ==} + '@rolldown/pluginutils@1.0.0-beta.52': + resolution: {integrity: sha512-/L0htLJZbaZFL1g9OHOblTxbCYIGefErJjtYOwgl9ZqNx27P3L0SDfjhhHIss32gu5NWgnxuT2a2Hnnv6QGHKA==} - '@rspack/binding-darwin-arm64@1.6.4': - resolution: {integrity: sha512-qD2C5xwdY2qKEXTZiPJQx1L1kELapOc0AaZDqcAyzXs30d1qTKpx6PdyW3HN+gueKovyWZwMMYfz6RxcMCnaDQ==} + '@rspack/binding-darwin-arm64@1.7.9': + resolution: {integrity: sha512-64dgstte0If5czi9bA/cpOe0ryY6wC9AIQRtyJ3DlOF6Tt+y9cKkmUoGu3V+WYaYIZRT7HNk8V7kL8amVjFTYw==} cpu: [arm64] os: [darwin] - '@rspack/binding-darwin-x64@1.6.4': - resolution: {integrity: sha512-IHceyLDxeubqIrGz4gUqJavnygTij4vtDDE2Fkgobz7hkTJwGtD5mxBKbVNRqGvhrasVw0h9rEjR7tdbDSiUhQ==} + '@rspack/binding-darwin-x64@1.7.9': + resolution: {integrity: sha512-2QSLs3w4rLy4UUGVnIlkt6IlIKOzR1e0RPsq2FYQW6s3p9JrwRCtOeHohyh7EJSqF54dtfhe9UZSAwba3LqH1Q==} cpu: [x64] os: [darwin] - '@rspack/binding-linux-arm64-gnu@1.6.4': - resolution: {integrity: sha512-Ldpoz2wWnBaL2+XKLIOyCZMkAkd4pk/L24EVgma3SpRtwgenLEr10bQupvwGAK5OLkjayslOTZmRiAv0FH5o/w==} + '@rspack/binding-linux-arm64-gnu@1.7.9': + resolution: {integrity: sha512-qhUGI/uVfvLmKWts4QkVHGL8yfUyJkblZs+OFD5Upa2y676EOsbQgWsCwX4xGB6Tv+TOzFP0SLh/UfO8ZfdE+w==} cpu: [arm64] os: [linux] - '@rspack/binding-linux-arm64-musl@1.6.4': - resolution: {integrity: sha512-3fLMSDK5yMjKmx7iFbYG3P3A0xNdtmNu09v5P6hzq65tkJ3dflIt3p8DvtOTURtuSgQZV2A1LDd9hpIXdnigqA==} + '@rspack/binding-linux-arm64-musl@1.7.9': + resolution: {integrity: sha512-VjfmR1hgO9n3L6MaE5KG+DXSrrLVqHHOkVcOtS2LMq3bjMTwbBywY7ycymcLnX5KJsol8d3ZGYep6IfSOt3lFA==} cpu: [arm64] os: [linux] - '@rspack/binding-linux-x64-gnu@1.6.4': - resolution: {integrity: sha512-5YzXUKLnaiqND05CDgkKE0WNRtC1ulkVncYs78xPikonzZmgVXa8eRaTPOZC6ZjpLR0eTsg+MSesLUsPUu27hA==} + '@rspack/binding-linux-x64-gnu@1.7.9': + resolution: {integrity: sha512-0kldV+3WTs/VYDWzxJ7K40hCW26IHtnk8xPK3whKoo1649rgeXXa0EdsU5P7hG8Ef5SWQjHHHZ/fuHYSO3Y6HA==} cpu: [x64] os: [linux] - '@rspack/binding-linux-x64-musl@1.6.4': - resolution: {integrity: sha512-KcSFla8a9bXG1mmV5oQ1R5h/dSXfd41/qHOsNuLqho2UCX8CVh4dezUA153dj7p1S4yOhTy6VZZi6C1szweE9A==} + '@rspack/binding-linux-x64-musl@1.7.9': + resolution: {integrity: sha512-Gi4872cFtc2d83FKATR6Qcf2VBa/tFCqffI/IwRRl6Hx5FulEBqx+tH7gAuRVF693vrbXNxK+FQ+k4iEsEJxrw==} cpu: [x64] os: [linux] - '@rspack/binding-wasm32-wasi@1.6.4': - resolution: {integrity: sha512-mfFJbDJkRy5I1iW3m0JlWbc0X8pjVd+GRUz5nhbccwEhSQOc27ao3evf7XPU4aaDxud1B3UEqYiRcRmtm1BrjA==} + '@rspack/binding-wasm32-wasi@1.7.9': + resolution: {integrity: sha512-5QEzqo6EaolpuZmK6w/mgSueorgGnnzp7dJaAvBj6ECFIg/aLXhXXmWCWbxt7Ws2gKvG5/PgaxDqbUxYL51juA==} cpu: [wasm32] - '@rspack/binding-win32-arm64-msvc@1.6.4': - resolution: {integrity: sha512-QtIqxsfeTSS1lwfaPGrPFfJ9ir/3aWZv5t3iAgYj/CNUA8MTKWt4vQKcco7NRIGK4ZLMI+dgJBFtvd/lUDMQsw==} + '@rspack/binding-win32-arm64-msvc@1.7.9': + resolution: {integrity: sha512-MMqvcrIc8aOqTuHjWkjdzilvoZ3Hv07Od0Foogiyq3JMudsS3Wcmh7T1dFerGg19MOJcRUeEkrg2NQOMOQ6xDA==} cpu: [arm64] os: [win32] - '@rspack/binding-win32-ia32-msvc@1.6.4': - resolution: {integrity: sha512-HXEWGDllgh0jFwjGhkGcLqb0dzXbc/rA8vQr2JcSdC41p1DTzLgO215jWdKSIvzCzhyPh3VeQkXk76hjFB2cLQ==} + '@rspack/binding-win32-ia32-msvc@1.7.9': + resolution: {integrity: sha512-4kYYS+NZ2CuNbKjq40yB/UEyB51o1PHj5wpr+Y943oOJXpEKWU2Q4vkF8VEohPEcnA9cKVotYCnqStme+02suA==} cpu: [ia32] os: [win32] - '@rspack/binding-win32-x64-msvc@1.6.4': - resolution: {integrity: sha512-MAO5rOnGYoeuT2LPn/P7JVJCi3d78XoXgOq3tkGh6qXhvhkjsBRtYluWCzACXQpXfFHEWYd7uT5yHoZgxiVuoA==} + '@rspack/binding-win32-x64-msvc@1.7.9': + resolution: {integrity: sha512-1g+QyXXvs+838Un/4GaUvJfARDGHMCs15eXDYWBl5m/Skubyng8djWAgr6ag1+cVoJZXCPOvybTItcblWF3gbQ==} cpu: [x64] os: [win32] - '@rspack/binding@1.6.4': - resolution: {integrity: sha512-vUxc/zUdsCuyysOvP4CTdIYxsZPb2jIXST5vrLABiTPIaHpXZ0hVdgKif2XPJwJeuCVS6w25xvyPN0mBCU0MvQ==} + '@rspack/binding@1.7.9': + resolution: {integrity: sha512-A56e0NdfNwbOSJoilMkxzaPuVYaKCNn1shuiwWnCIBmhV9ix1n9S1XvquDjkGyv+gCdR1+zfJBOa5DMB7htLHw==} - '@rspack/core@1.6.4': - resolution: {integrity: sha512-5F1+MQD8rfbFbUHnaiZe4jqOu9pnSb+PliqQvi0lj+uvpMpcS3sJDIs/mz6P1u87lfkfBXChIT4zSLAzeOgMWw==} + '@rspack/core@1.7.9': + resolution: {integrity: sha512-VHuSKvRkuv42Ya+TxEGO0LE0r9+8P4tKGokmomj4R1f/Nu2vtS3yoaIMfC4fR6VuHGd3MZ+KTI0cNNwHfFcskw==} engines: {node: '>=18.12.0'} peerDependencies: '@swc/helpers': '>=0.5.1' @@ -1269,9 +1545,6 @@ packages: '@so-ric/colorspace@1.1.6': resolution: {integrity: sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==} - '@socket.io/component-emitter@3.1.2': - resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} - '@szmarczak/http-timer@5.0.1': resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} engines: {node: '>=14.16'} @@ -1292,8 +1565,8 @@ packages: '@tsclass/tsclass@4.4.4': resolution: {integrity: sha512-YZOAF+u+r4u5rCev2uUd1KBTBdfyFdtDmcv4wuN+864lMccbdfRICR3SlJwCfYS1lbeV3QNLYGD30wjRXgvCJA==} - '@tsclass/tsclass@9.3.0': - resolution: {integrity: sha512-KD3oTUN3RGu67tgjNHgWWZGsdYipr1RUDxQ9MMKSgIJ6oNZ4q5m2rg0ibrgyHWkAjTPlHVa6kHP3uVOY+8bnHw==} + '@tsclass/tsclass@9.5.0': + resolution: {integrity: sha512-HwMVwkrBnEFMjwOsMkGwWN/q+XEczSpf4a/PBAXgkDdV6sXdxAMFXUH1tW8Y5ecuvXFYMvFry4X57MCCT7Dm8A==} '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} @@ -1310,9 +1583,6 @@ packages: '@types/body-parser@1.19.6': resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} - '@types/buffer-json@2.0.3': - resolution: {integrity: sha512-ItD4UfF3Q5jA+PEV6ZUWEHvlWaXJbd0rpuBKOIrEebM053FHaJddKsgUf0vy7nLSTs44nqFj3Mh8J3TiT0xv4g==} - '@types/chai-dom@1.11.3': resolution: {integrity: sha512-EUEZI7uID4ewzxnU7DJXtyvykhQuwe+etJ1wwOiJyQRTH/ifMWKX+ghiXkxCUvNJ6IQDodf0JXhuP6zZcy2qXQ==} @@ -1340,9 +1610,6 @@ packages: '@types/cookies@0.9.2': resolution: {integrity: sha512-1AvkDdZM2dbyFybL4fxpuNCaWyv//0AwsuUk2DWeXyM1/5ZKm6W3z6mQi24RZ4l2ucY+bkSHzbDVpySqPGuV8A==} - '@types/cors@2.8.19': - resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} - '@types/debounce@1.2.4': resolution: {integrity: sha512-jBqiORIzKDOToaF63Fm//haOCHuwQuLa2202RK4MozpA6lh93eCBc+/8+wZn5OzjJt3ySdc+74SXWXB55Ewtyw==} @@ -1424,11 +1691,17 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/mute-stream@0.0.4': + resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} + '@types/node-forge@1.3.14': resolution: {integrity: sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==} - '@types/node@20.19.25': - resolution: {integrity: sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==} + '@types/node@16.9.1': + resolution: {integrity: sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==} + + '@types/node@22.19.15': + resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==} '@types/parse5@6.0.3': resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} @@ -1439,9 +1712,6 @@ packages: '@types/qs@6.14.0': resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} - '@types/randomatic@3.1.5': - resolution: {integrity: sha512-VCwCTw6qh1pRRw+5rNTAwqPmf6A+hdrkdM7dBpZVmhl7g+em3ONXlYK/bWPVKqVGMWgP0d1bog8Vc/X6zRwRRQ==} - '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} @@ -1511,6 +1781,9 @@ packages: '@types/which@3.0.4': resolution: {integrity: sha512-liyfuo/106JdlgSchJzXEQCVArk0CvevqPote8F8HgWgJ3dRCcTHgJIsLDuee0kxk/mhbInzIZk3QWSZJ8R+2w==} + '@types/wrap-ansi@3.0.0': + resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} + '@types/ws@7.4.7': resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} @@ -1549,14 +1822,14 @@ packages: resolution: {integrity: sha512-84E1025aUSjvZU1j17eCTwV7m5Zg3cZHErV3+CaJM9JPCesZwLraIa0ONIQ9w4KLgcDgJFw9UnJ0LbFf42h6tg==} engines: {node: '>=18.0.0'} + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} - accepts@2.0.0: - resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} - engines: {node: '>= 0.6'} - acme-client@5.4.0: resolution: {integrity: sha512-mORqg60S8iML6XSmVjqjGHJkINrCGLMj2QvDmFzI9vIlv1RGlyjmw3nrzaINJjkNsYXC41XhhD5pfy7CtuGcbA==} engines: {node: '>= 16'} @@ -1601,6 +1874,9 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} + any-base@1.1.0: + resolution: {integrity: sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==} + argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -1636,6 +1912,10 @@ packages: asynckit@0.4.0: resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=} + await-to-js@3.0.0: + resolution: {integrity: sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g==} + engines: {node: '>=6.0.0'} + axe-core@4.11.0: resolution: {integrity: sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==} engines: {node: '>=4'} @@ -1698,21 +1978,16 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - base64id@2.0.0: - resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} - engines: {node: ^4.5.0 || >= 5.9} - basic-ftp@5.0.5: resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} engines: {node: '>=10.0.0'} + bmp-ts@1.0.9: + resolution: {integrity: sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw==} + bn.js@4.12.2: resolution: {integrity: sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==} - body-parser@2.2.0: - resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} - engines: {node: '>=18'} - bowser@2.12.1: resolution: {integrity: sha512-z4rE2Gxh7tvshQ4hluIT7XcFrgLIQaw9X3A+kTTRdovCz5PMukm/0QC/BKSYPj3omF5Qfypn9O/c5kgpmvYUCw==} @@ -1739,9 +2014,6 @@ packages: buffer-crc32@0.2.13: resolution: {integrity: sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=} - buffer-json@2.0.0: - resolution: {integrity: sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==} - buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} @@ -1811,10 +2083,17 @@ packages: character-entities@2.0.2: resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + chromium-bidi@11.0.0: resolution: {integrity: sha512-cM3DI+OOb89T3wO8cpPSro80Q9eKYJ7hGVXoGS3GkDPxnYSqiv+6xwpIf6XERyJ9Tdsl09hmNmY94BkgZdVekw==} peerDependencies: @@ -1836,6 +2115,10 @@ packages: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -1908,10 +2191,6 @@ packages: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} - content-disposition@1.0.1: - resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} - engines: {node: '>=18'} - content-type@1.0.5: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} @@ -1919,22 +2198,10 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - cookie-signature@1.2.2: - resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} - engines: {node: '>=6.6.0'} - - cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} - cookies@0.9.1: resolution: {integrity: sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==} engines: {node: '>= 0.8'} - cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} - engines: {node: '>= 0.10'} - cosmiconfig@9.0.0: resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} engines: {node: '>=14'} @@ -1944,6 +2211,10 @@ packages: typescript: optional: true + croner@10.0.1: + resolution: {integrity: sha512-ixNtAJndqh173VQ4KodSdJEI6nuioBWI0V1ITNKhZZsO0pEMoDxz539T4FTTbSZ/xIOSuDnzxLVRqBVSvPNE2g==} + engines: {node: '>=18.0'} + croner@9.1.0: resolution: {integrity: sha512-p9nwwR4qyT5W996vBZhdvBCnMhicY5ytZkR4D1Xj0wuTDEiMnjwR57Q3RXYY/s0EpX6Ay3vgIcfaR+ewGHsi+g==} engines: {node: '>=18.0'} @@ -1952,10 +2223,6 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - crypto-random-string@5.0.0: - resolution: {integrity: sha512-KWjTXWwxFd6a94m5CdRGW/t82Tr8DoBc9dNnPCAbFI1EBweN6v1tv8y4Y1m7ndkp/nkIBRxUxAzpaBnR2k3bcQ==} - engines: {node: '>=14.16'} - data-uri-to-buffer@6.0.2: resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} engines: {node: '>= 14'} @@ -1977,15 +2244,6 @@ packages: supports-color: optional: true - debug@4.3.7: - resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -2060,6 +2318,10 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -2108,28 +2370,9 @@ packages: resolution: {integrity: sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=} engines: {node: '>= 0.8'} - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} - end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - engine.io-client@6.6.3: - resolution: {integrity: sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==} - - engine.io-parser@5.2.3: - resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} - engines: {node: '>=10.0.0'} - - engine.io@6.6.4: - resolution: {integrity: sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==} - engines: {node: '>=10.2.0'} - - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} @@ -2159,8 +2402,8 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} - esbuild@0.25.12: - resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + esbuild@0.27.4: + resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} engines: {node: '>=18'} hasBin: true @@ -2209,31 +2452,38 @@ packages: resolution: {integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=} engines: {node: '>= 0.6'} + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} events-universal@1.0.1: resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} + exif-parser@0.1.12: + resolution: {integrity: sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==} + expect@29.7.0: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - express-force-ssl@0.3.2: - resolution: {integrity: sha1-AbK0mK5v0uQRUrIrV6Phc3c69n4=} - engines: {node: '>=0.2.2'} - - express@5.1.0: - resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} - engines: {node: '>= 18'} - extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + extract-zip@2.0.1: resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} engines: {node: '>= 10.17.0'} @@ -2243,10 +2493,6 @@ packages: resolution: {integrity: sha512-cB507r5T3D55DfclY01GLkninZLfU7HXV/mhVRTnTRm5k2u+fY7Fof2dBkr80p5t7G7dlA/G5dI87QiMdPpMCQ==} engines: {node: '>=18'} - fake-indexeddb@6.2.5: - resolution: {integrity: sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w==} - engines: {node: '>=18'} - fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -2295,6 +2541,10 @@ packages: resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} engines: {node: '>=18'} + file-type@16.5.4: + resolution: {integrity: sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==} + engines: {node: '>=10'} + file-type@19.6.0: resolution: {integrity: sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ==} engines: {node: '>=18'} @@ -2307,10 +2557,6 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - finalhandler@2.1.0: - resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} - engines: {node: '>= 0.8'} - find-cache-dir@3.3.2: resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} engines: {node: '>=8'} @@ -2351,18 +2597,10 @@ packages: resolution: {integrity: sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=} engines: {node: '>=0.4.x'} - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - fresh@0.5.2: resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} engines: {node: '>= 0.6'} - fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} - fs-extra@11.3.2: resolution: {integrity: sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==} engines: {node: '>=14.14'} @@ -2417,6 +2655,9 @@ packages: resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} engines: {node: '>= 14'} + gifwrap@0.10.1: + resolution: {integrity: sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2447,10 +2688,6 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - happy-dom@15.11.7: - resolution: {integrity: sha512-KyrFvnl+J9US63TEzwoiJOQzZBJY7KgBushJA8X61DMbNsH+2ONkDuLDnCnwUiPTF42tLoEmrPyoqbenVA5zrg==} - engines: {node: '>=18.0.0'} - has-flag@3.0.0: resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=} engines: {node: '>=4'} @@ -2549,14 +2786,6 @@ packages: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - - iconv-lite@0.7.0: - resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} - engines: {node: '>=0.10.0'} - ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -2564,6 +2793,9 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} + image-q@4.0.0: + resolution: {integrity: sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==} + import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} @@ -2584,6 +2816,10 @@ packages: ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + inquirer@11.1.0: + resolution: {integrity: sha512-CmLAZT65GG/v30c+D2Fk8+ceP6pxD6RL+hIUOWAltCmeyEqWYwqu9v76q03OvjyZ3AB0C1Ala2stn1z/rMqGEw==} + engines: {node: '>=18'} + internal-ip@6.2.0: resolution: {integrity: sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg==} engines: {node: '>=10'} @@ -2632,10 +2868,6 @@ packages: resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} engines: {node: '>= 0.4'} - is-number@4.0.0: - resolution: {integrity: sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==} - engines: {node: '>=0.10.0'} - is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -2648,9 +2880,6 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} - is-promise@4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} @@ -2686,6 +2915,10 @@ packages: resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} engines: {node: '>=16'} + isexe@4.0.0: + resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==} + engines: {node: '>=20'} + isopen@1.3.0: resolution: {integrity: sha512-AN6Q9J0UlqHFl1fN/2xJCHCBLCBCFDjZhpGBO1gh3wzgRPsFSFBUL36I2Lbfd9qkuoj58axmE7j83iejTQsk8Q==} @@ -2725,16 +2958,16 @@ packages: resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - js-base64@3.7.8: - resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==} + jimp@1.6.0: + resolution: {integrity: sha512-YcwCHw1kiqEeI5xRpDlPPBGL2EOpBKLwO4yIBJcXWHPj5PnA5urGq0jbyhM5KoNpypQ6VboSoxc9D8HyfvngSg==} + engines: {node: '>=18'} + + jpeg-js@0.4.4: + resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==} js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - js-yaml@3.14.2: resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} hasBin: true @@ -2762,10 +2995,6 @@ packages: keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} - koa-compose@4.1.0: resolution: {integrity: sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==} @@ -2825,42 +3054,9 @@ packages: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} - lodash._baseassign@3.2.0: - resolution: {integrity: sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=} - - lodash._basecopy@3.0.1: - resolution: {integrity: sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=} - - lodash._bindcallback@3.0.1: - resolution: {integrity: sha1-5THCdkTPi1epnhftlbNcdIeJOS4=} - - lodash._createassigner@3.1.1: - resolution: {integrity: sha1-g4pbri/aymOsIt7o4Z+k5taXCxE=} - - lodash._getnative@3.9.1: - resolution: {integrity: sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=} - - lodash._isiterateecall@3.0.9: - resolution: {integrity: sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=} - - lodash.assign@3.2.0: - resolution: {integrity: sha1-POnwI0tLIiPilrj6CsH+6OvKZPo=} - lodash.clonedeep@4.5.0: resolution: {integrity: sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=} - lodash.isarguments@3.1.0: - resolution: {integrity: sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=} - - lodash.isarray@3.0.4: - resolution: {integrity: sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=} - - lodash.keys@3.1.2: - resolution: {integrity: sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=} - - lodash.restparam@3.6.1: - resolution: {integrity: sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=} - lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -2919,9 +3115,6 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} - math-random@1.0.4: - resolution: {integrity: sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==} - mdast-util-find-and-replace@3.0.2: resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} @@ -2965,17 +3158,9 @@ packages: resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} engines: {node: '>= 0.6'} - media-typer@1.1.0: - resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} - engines: {node: '>= 0.8'} - memory-pager@1.5.0: resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==} - merge-descriptors@2.0.0: - resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} - engines: {node: '>=18'} - merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -3082,17 +3267,14 @@ packages: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} - mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} - mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - mime-types@3.0.1: - resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} - engines: {node: '>= 0.6'} + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true mime@4.1.0: resolution: {integrity: sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==} @@ -3111,6 +3293,9 @@ packages: resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + mingo@7.2.0: + resolution: {integrity: sha512-UeX942qZpofn5L97h295SkS7j/ADf7Qac8gdRCMBPxi0/1m70aeB2owLFvWbyuMj1dowonlivlVRQVDx+6h+7Q==} + minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} @@ -3184,6 +3369,10 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + nanocolors@0.2.13: resolution: {integrity: sha512-0n3mSAQLPpGLV9ORXT5+C/D4mwew7Ebws69Hx4E2sgz2ZA5+32Q80B9tL8PbL7XHnRDiAxH/pnrUJ9a4fkTNTA==} @@ -3201,10 +3390,6 @@ packages: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} - negotiator@1.0.0: - resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} - engines: {node: '>= 0.6'} - netmask@2.0.2: resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} engines: {node: '>= 0.4.0'} @@ -3220,10 +3405,6 @@ packages: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} - normalize-newline@4.1.0: - resolution: {integrity: sha512-ff4jKqMI8Xl50/4Mms/9jPobzAV/UK+kXG2XJ/7AqOmxIx8mqfqTIHYxuAnEgJ2AQeBbLnlbmZ5+38Y9A0w/YA==} - engines: {node: '>=12'} - normalize-url@8.1.0: resolution: {integrity: sha512-X06Mfd/5aKsRHc0O0J5CUedwnPmnDtLF2+nq+KN9KSDlJHkPuh0JUviWjEWMe0SW/9TDdSLVPuk7L5gGTIA1/w==} engines: {node: '>=14.16'} @@ -3232,10 +3413,6 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} - object-assign@4.1.1: - resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=} - engines: {node: '>=0.10.0'} - object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} @@ -3251,6 +3428,9 @@ packages: observable-fns@0.6.1: resolution: {integrity: sha512-9gRK4+sRWzeN6AOewNBTLXir7Zl/i3GB6Yl26gK4flxz8BXVpD3kt8amREmWNb0mxYOGDotvE5a4N+PtGGKdkg==} + omggif@1.0.10: + resolution: {integrity: sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==} + on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -3272,6 +3452,10 @@ packages: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} + os-tmpdir@1.0.2: + resolution: {integrity: sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=} + engines: {node: '>=0.10.0'} + p-cancelable@3.0.0: resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} engines: {node: '>=12.20'} @@ -3329,6 +3513,15 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-bmfont-ascii@1.0.6: + resolution: {integrity: sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==} + + parse-bmfont-binary@1.0.6: + resolution: {integrity: sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==} + + parse-bmfont-xml@1.1.6: + resolution: {integrity: sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==} + parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -3376,12 +3569,16 @@ packages: pdf-lib@1.17.1: resolution: {integrity: sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==} - pdf2json@3.2.0: - resolution: {integrity: sha512-5RJYU5zWFXTQ5iRXAo75vlhK5ybZOyqEyg/szw2VtHc6ZOPcC7ruX4nnXk1OqqlY56Z7XT+WCFhV+/XPj4QwtQ==} + pdf2json@4.0.2: + resolution: {integrity: sha512-iiRSuRmLihoEJ4YGkoqSq3/r4MR0OmkMTYDda0Pq7DAWqJwMylTilXu46T16gfS3DUp3fhiVuz7NtRMbk3uBhw==} engines: {node: '>=20.18.0'} hasBin: true bundledDependencies: [] + peek-readable@4.1.0: + resolution: {integrity: sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==} + engines: {node: '>=8'} + peek-readable@5.4.2: resolution: {integrity: sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg==} engines: {node: '>=14.16'} @@ -3404,10 +3601,22 @@ packages: resolution: {integrity: sha512-56ZMC0j7SCsMMLdOoUg12VZCfj/+ZO+yfOSjaNCRrmZZr6GLbN2X/Ui56T15dI8NhiHckaw5X2pvyfAomanwqQ==} engines: {node: '>=4.0.0'} + pixelmatch@5.3.0: + resolution: {integrity: sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==} + hasBin: true + pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} + pngjs@6.0.0: + resolution: {integrity: sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==} + engines: {node: '>=12.13.0'} + + pngjs@7.0.0: + resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==} + engines: {node: '>=14.19.0'} + pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3416,6 +3625,10 @@ packages: resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==} engines: {node: '>=18'} + process@0.11.10: + resolution: {integrity: sha1-czIwDoQBYb2j5podHZGn1LwW8YI=} + engines: {node: '>= 0.6.0'} + progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} @@ -3426,10 +3639,6 @@ packages: proto-list@1.2.4: resolution: {integrity: sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=} - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - proxy-agent@6.5.0: resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==} engines: {node: '>= 14'} @@ -3440,9 +3649,6 @@ packages: pump@3.0.3: resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} - punycode@1.4.1: - resolution: {integrity: sha1-wNWmOycYgArY4esPpSachN1BhF4=} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -3474,22 +3680,10 @@ packages: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} - randomatic@3.1.1: - resolution: {integrity: sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==} - engines: {node: '>= 0.10.0'} - - range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - raw-body@2.5.2: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} - raw-body@3.0.1: - resolution: {integrity: sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==} - engines: {node: '>= 0.10'} - rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true @@ -3501,10 +3695,22 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readable-web-to-node-stream@3.0.4: + resolution: {integrity: sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==} + engines: {node: '>=8'} + readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + reflect-metadata@0.2.2: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} @@ -3535,10 +3741,6 @@ packages: remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} - replace-buffer@1.2.1: - resolution: {integrity: sha512-ly3OKwKu+3T55DjP5PjIMzxgz9lFx6dQnBmAIxryZyRKl8f22juy12ShOyuq8WrQE5UlFOseZgQZDua0iF9DHw==} - engines: {node: '>=4'} - require-directory@2.1.1: resolution: {integrity: sha1-jGStX9MNqxyXbiNE/+f3kqam30I=} engines: {node: '>=0.10.0'} @@ -3573,14 +3775,14 @@ packages: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true - rolldown@1.0.0-beta.51: - resolution: {integrity: sha512-ZRLgPlS91l4JztLYEZnmMcd3Umcla1hkXJgiEiR4HloRJBBoeaX8qogTu5Jfu36rRMVLndzqYv0h+M5gJAkUfg==} + rolldown@1.0.0-beta.52: + resolution: {integrity: sha512-Hbnpljue+JhMJrlOjQ1ixp9me7sUec7OjFvS+A1Qm8k8Xyxmw3ZhxFu7LlSXW1s9AX3POE9W9o2oqCEeR5uDmg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - router@2.2.0: - resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} - engines: {node: '>= 18'} + run-async@3.0.0: + resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} + engines: {node: '>=0.12.0'} run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -3607,6 +3809,10 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -3616,14 +3822,6 @@ packages: engines: {node: '>=10'} hasBin: true - send@1.2.0: - resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} - engines: {node: '>= 18'} - - serve-static@2.2.0: - resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} - engines: {node: '>= 18'} - set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -3634,6 +3832,10 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -3665,6 +3867,10 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-xml-to-json@1.2.4: + resolution: {integrity: sha512-3MY16e0ocMHL7N1ufpdObURGyX+lCo0T/A+y6VCwosLdH1HSda4QZl1Sdt/O+2qWp48WFi26XEp5rF0LoaL0Dg==} + engines: {node: '>=20.12.2'} + slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -3677,21 +3883,6 @@ packages: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - socket.io-adapter@2.5.5: - resolution: {integrity: sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==} - - socket.io-client@4.8.1: - resolution: {integrity: sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==} - engines: {node: '>=10.0.0'} - - socket.io-parser@4.2.4: - resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} - engines: {node: '>=10.0.0'} - - socket.io@4.8.1: - resolution: {integrity: sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==} - engines: {node: '>=10.2.0'} - socks-proxy-agent@8.0.5: resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} engines: {node: '>= 14'} @@ -3773,10 +3964,6 @@ packages: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} - strip-indent@4.1.1: - resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==} - engines: {node: '>=12'} - strip-json-comments@2.0.1: resolution: {integrity: sha1-PFMZQukIwml8DsNEhYwobHygpgo=} engines: {node: '>=0.10.0'} @@ -3791,6 +3978,10 @@ packages: resolution: {integrity: sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==} engines: {node: '>=18'} + strtok3@6.3.0: + resolution: {integrity: sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==} + engines: {node: '>=10'} + strtok3@9.1.1: resolution: {integrity: sha512-FhwotcEqjr241ZbjFzjlIYg6c5/L/s4yBGWSMvJ9UoExiSqL+FnFA/CaeZx17WGaZMS/4SOZp8wH18jSS4R4lw==} engines: {node: '>=16'} @@ -3815,6 +4006,10 @@ packages: os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] hasBin: true + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} + tar-fs@3.1.1: resolution: {integrity: sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==} @@ -3839,6 +4034,13 @@ packages: tiny-worker@2.3.0: resolution: {integrity: sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g==} + tinycolor2@1.6.0: + resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -3847,6 +4049,10 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + token-types@4.2.1: + resolution: {integrity: sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==} + engines: {node: '>=10'} + token-types@6.1.1: resolution: {integrity: sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ==} engines: {node: '>=14.16'} @@ -3879,8 +4085,8 @@ packages: resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} engines: {node: '>=0.6.x'} - tsx@4.20.6: - resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} engines: {node: '>=18.0.0'} hasBin: true @@ -3898,30 +4104,21 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} - type-fest@2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} - type-fest@4.41.0: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} + type-fest@5.5.0: + resolution: {integrity: sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==} + engines: {node: '>=20'} + type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} - type-is@2.0.1: - resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} - engines: {node: '>= 0.6'} - typed-query-selector@2.12.0: resolution: {integrity: sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==} - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} - engines: {node: '>=14.17'} - hasBin: true - typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} @@ -3975,9 +4172,8 @@ packages: upper-case@1.1.3: resolution: {integrity: sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=} - url@0.11.4: - resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} - engines: {node: '>= 0.4'} + utif2@4.1.0: + resolution: {integrity: sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w==} util-deprecate@1.0.2: resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=} @@ -4003,10 +4199,6 @@ packages: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} - whatwg-mimetype@3.0.0: - resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} - engines: {node: '>=12'} - whatwg-url@14.2.0: resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} engines: {node: '>=18'} @@ -4021,6 +4213,11 @@ packages: engines: {node: ^18.17.0 || >=20.5.0} hasBin: true + which@6.0.1: + resolution: {integrity: sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==} + engines: {node: ^20.17.0 || >=22.9.0} + hasBin: true + winston-transport@4.9.0: resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} engines: {node: '>= 12.0.0'} @@ -4056,8 +4253,8 @@ packages: utf-8-validate: optional: true - ws@8.17.1: - resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -4068,25 +4265,16 @@ packages: utf-8-validate: optional: true - ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true + xml-parse-from-string@1.0.1: + resolution: {integrity: sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==} - xmlbuilder2@3.1.1: - resolution: {integrity: sha512-WCSfbfZnQDdLQLiMdGUQpMxxckeQ4oZNMNhLVkcekTu7xhD4tuUDyAPoY8CwXvBYE6LwBHd6QW2WZXlOWr1vCw==} - engines: {node: '>=12.0'} + xml2js@0.5.0: + resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} + engines: {node: '>=4.0.0'} - xmlhttprequest-ssl@2.1.2: - resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==} - engines: {node: '>=0.4.0'} + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} @@ -4120,6 +4308,10 @@ packages: resolution: {integrity: sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==} engines: {node: '>= 4.0.0'} + yoctocolors-cjs@2.1.3: + resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} + engines: {node: '>=18'} + zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -4144,70 +4336,17 @@ snapshots: '@push.rocks/webrequest': 3.0.37 '@push.rocks/webstream': 1.0.10 - '@api.global/typedserver@3.0.79': + '@api.global/typedrequest@3.3.0': dependencies: - '@api.global/typedrequest': 3.1.10 '@api.global/typedrequest-interfaces': 3.0.19 - '@api.global/typedsocket': 3.0.1 - '@cloudflare/workers-types': 4.20251119.0 - '@design.estate/dees-comms': 1.0.27 - '@push.rocks/lik': 6.2.2 - '@push.rocks/smartchok': 1.1.1 + '@push.rocks/isounique': 1.0.5 + '@push.rocks/lik': 6.3.1 + '@push.rocks/smartbuffer': 3.0.5 '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartenv': 5.0.13 - '@push.rocks/smartfeed': 1.4.0 - '@push.rocks/smartfile': 11.2.7 - '@push.rocks/smartjson': 5.2.0 - '@push.rocks/smartlog': 3.1.10 - '@push.rocks/smartlog-destination-devtools': 1.0.12 - '@push.rocks/smartlog-interfaces': 3.0.2 - '@push.rocks/smartmanifest': 2.0.2 - '@push.rocks/smartmatch': 2.0.0 - '@push.rocks/smartmime': 2.0.4 - '@push.rocks/smartntml': 2.0.8 - '@push.rocks/smartopen': 2.0.0 - '@push.rocks/smartpath': 6.0.0 + '@push.rocks/smartguard': 3.1.0 '@push.rocks/smartpromise': 4.2.3 - '@push.rocks/smartrequest': 4.4.2 - '@push.rocks/smartrx': 3.0.10 - '@push.rocks/smartsitemap': 2.0.3 - '@push.rocks/smartstream': 3.2.5 - '@push.rocks/smarttime': 4.1.1 - '@push.rocks/taskbuffer': 3.4.0 - '@push.rocks/webrequest': 3.0.37 - '@push.rocks/webstore': 2.0.20 - '@tsclass/tsclass': 9.3.0 - '@types/express': 5.0.5 - body-parser: 2.2.0 - cors: 2.8.5 - express: 5.1.0 - express-force-ssl: 0.3.2 - lit: 3.3.1 - transitivePeerDependencies: - - '@nuxt/kit' - - bufferutil - - react - - supports-color - - utf-8-validate - - vue - - '@api.global/typedsocket@3.0.1': - dependencies: - '@api.global/typedrequest': 3.1.10 - '@api.global/typedrequest-interfaces': 3.0.19 - '@push.rocks/isohash': 2.0.1 - '@push.rocks/smartjson': 5.2.0 - '@push.rocks/smartrx': 3.0.10 - '@push.rocks/smartsocket': 2.1.0 - '@push.rocks/smartstring': 4.1.0 - '@push.rocks/smarturl': 3.1.0 - transitivePeerDependencies: - - '@nuxt/kit' - - bufferutil - - react - - supports-color - - utf-8-validate - - vue + '@push.rocks/webrequest': 4.0.5 + '@push.rocks/webstream': 1.0.10 '@aws-crypto/crc32@5.2.0': dependencies: @@ -4686,7 +4825,7 @@ snapshots: '@borewit/text-codec@0.1.1': {} - '@cloudflare/workers-types@4.20251119.0': {} + '@cfworker/json-schema@4.1.1': {} '@colors/colors@1.6.0': {} @@ -4761,96 +4900,97 @@ snapshots: tslib: 2.8.1 optional: true - '@esbuild/aix-ppc64@0.25.12': + '@esbuild/aix-ppc64@0.27.4': optional: true - '@esbuild/android-arm64@0.25.12': + '@esbuild/android-arm64@0.27.4': optional: true - '@esbuild/android-arm@0.25.12': + '@esbuild/android-arm@0.27.4': optional: true - '@esbuild/android-x64@0.25.12': + '@esbuild/android-x64@0.27.4': optional: true - '@esbuild/darwin-arm64@0.25.12': + '@esbuild/darwin-arm64@0.27.4': optional: true - '@esbuild/darwin-x64@0.25.12': + '@esbuild/darwin-x64@0.27.4': optional: true - '@esbuild/freebsd-arm64@0.25.12': + '@esbuild/freebsd-arm64@0.27.4': optional: true - '@esbuild/freebsd-x64@0.25.12': + '@esbuild/freebsd-x64@0.27.4': optional: true - '@esbuild/linux-arm64@0.25.12': + '@esbuild/linux-arm64@0.27.4': optional: true - '@esbuild/linux-arm@0.25.12': + '@esbuild/linux-arm@0.27.4': optional: true - '@esbuild/linux-ia32@0.25.12': + '@esbuild/linux-ia32@0.27.4': optional: true - '@esbuild/linux-loong64@0.25.12': + '@esbuild/linux-loong64@0.27.4': optional: true - '@esbuild/linux-mips64el@0.25.12': + '@esbuild/linux-mips64el@0.27.4': optional: true - '@esbuild/linux-ppc64@0.25.12': + '@esbuild/linux-ppc64@0.27.4': optional: true - '@esbuild/linux-riscv64@0.25.12': + '@esbuild/linux-riscv64@0.27.4': optional: true - '@esbuild/linux-s390x@0.25.12': + '@esbuild/linux-s390x@0.27.4': optional: true - '@esbuild/linux-x64@0.25.12': + '@esbuild/linux-x64@0.27.4': optional: true - '@esbuild/netbsd-arm64@0.25.12': + '@esbuild/netbsd-arm64@0.27.4': optional: true - '@esbuild/netbsd-x64@0.25.12': + '@esbuild/netbsd-x64@0.27.4': optional: true - '@esbuild/openbsd-arm64@0.25.12': + '@esbuild/openbsd-arm64@0.27.4': optional: true - '@esbuild/openbsd-x64@0.25.12': + '@esbuild/openbsd-x64@0.27.4': optional: true - '@esbuild/openharmony-arm64@0.25.12': + '@esbuild/openharmony-arm64@0.27.4': optional: true - '@esbuild/sunos-x64@0.25.12': + '@esbuild/sunos-x64@0.27.4': optional: true - '@esbuild/win32-arm64@0.25.12': + '@esbuild/win32-arm64@0.27.4': optional: true - '@esbuild/win32-ia32@0.25.12': + '@esbuild/win32-ia32@0.27.4': optional: true - '@esbuild/win32-x64@0.25.12': + '@esbuild/win32-x64@0.27.4': optional: true '@esm-bundle/chai@4.3.4-fix.0': dependencies: '@types/chai': 4.3.20 - '@git.zone/tsbuild@3.1.0': + '@git.zone/tsbuild@4.3.0': dependencies: - '@git.zone/tspublish': 1.10.3 + '@git.zone/tspublish': 1.11.2 '@push.rocks/early': 4.0.4 - '@push.rocks/smartcli': 4.0.19 + '@push.rocks/smartcli': 4.0.20 '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartfile': 11.2.7 - '@push.rocks/smartlog': 3.1.10 + '@push.rocks/smartfile': 13.1.2 + '@push.rocks/smartfs': 1.5.0 + '@push.rocks/smartlog': 3.2.1 '@push.rocks/smartpath': 6.0.0 '@push.rocks/smartpromise': 4.2.3 typescript: 5.9.3 @@ -4863,38 +5003,45 @@ snapshots: - supports-color - vue - '@git.zone/tsbundle@2.5.2': + '@git.zone/tsbundle@2.9.1': dependencies: '@push.rocks/early': 4.0.4 - '@push.rocks/smartcli': 4.0.19 + '@push.rocks/npmextra': 5.3.3 + '@push.rocks/smartcli': 4.0.20 '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartfile': 11.2.7 + '@push.rocks/smartfs': 1.5.0 + '@push.rocks/smartinteract': 2.0.16 '@push.rocks/smartlog': 3.1.10 '@push.rocks/smartlog-destination-local': 9.0.2 - '@push.rocks/smartpath': 5.1.0 + '@push.rocks/smartpath': 6.0.0 '@push.rocks/smartpromise': 4.2.3 '@push.rocks/smartspawn': 3.0.3 - '@rspack/core': 1.6.4 + '@rspack/core': 1.7.9 '@types/html-minifier': 4.0.6 - esbuild: 0.25.12 + esbuild: 0.27.4 html-minifier: 4.0.0 - rolldown: 1.0.0-beta.51 - typescript: 5.8.3 + rolldown: 1.0.0-beta.52 + typescript: 5.9.3 transitivePeerDependencies: + - '@nuxt/kit' - '@swc/helpers' + - react - supports-color + - vue - '@git.zone/tspublish@1.10.3': + '@git.zone/tspublish@1.11.2': dependencies: '@push.rocks/consolecolor': 2.0.3 - '@push.rocks/smartcli': 4.0.19 + '@push.rocks/npmextra': 5.3.3 + '@push.rocks/smartcli': 4.0.20 '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartfile': 11.2.7 - '@push.rocks/smartlog': 3.1.10 + '@push.rocks/smartfile': 13.1.2 + '@push.rocks/smartfs': 1.5.0 + '@push.rocks/smartlog': 3.2.1 '@push.rocks/smartnpm': 2.0.6 '@push.rocks/smartpath': 6.0.0 - '@push.rocks/smartrequest': 4.4.2 - '@push.rocks/smartshell': 3.3.0 + '@push.rocks/smartrequest': 5.0.1 + '@push.rocks/smartshell': 3.3.8 transitivePeerDependencies: - '@nuxt/kit' - aws-crt @@ -4904,45 +5051,40 @@ snapshots: - supports-color - vue - '@git.zone/tsrun@1.6.2': + '@git.zone/tsrun@2.0.1': dependencies: - '@push.rocks/smartfile': 11.2.7 + '@push.rocks/smartfile': 13.1.2 '@push.rocks/smartshell': 3.3.0 - tsx: 4.20.6 + tsx: 4.21.0 - '@git.zone/tsrun@2.0.0': + '@git.zone/tstest@3.5.0(socks@2.8.7)(typescript@5.9.3)': dependencies: - '@push.rocks/smartfile': 11.2.7 - '@push.rocks/smartshell': 3.3.0 - tsx: 4.20.6 - - '@git.zone/tstest@2.8.2(socks@2.8.7)(typescript@5.9.3)': - dependencies: - '@api.global/typedserver': 3.0.79 - '@git.zone/tsbundle': 2.5.2 - '@git.zone/tsrun': 1.6.2 + '@git.zone/tsbundle': 2.9.1 + '@git.zone/tsrun': 2.0.1 '@push.rocks/consolecolor': 2.0.3 '@push.rocks/qenv': 6.1.3 - '@push.rocks/smartbrowser': 2.0.8(typescript@5.9.3) - '@push.rocks/smartchok': 1.1.1 + '@push.rocks/smartbrowser': 2.0.11(typescript@5.9.3) '@push.rocks/smartcrypto': 2.0.4 '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartenv': 5.0.13 + '@push.rocks/smartenv': 6.0.0 '@push.rocks/smartexpect': 2.5.0 - '@push.rocks/smartfile': 11.2.7 - '@push.rocks/smartjson': 5.2.0 - '@push.rocks/smartlog': 3.1.10 - '@push.rocks/smartmongo': 2.0.14(socks@2.8.7) + '@push.rocks/smartfile': 13.1.2 + '@push.rocks/smartfs': 1.5.0 + '@push.rocks/smartjson': 6.0.0 + '@push.rocks/smartlog': 3.2.1 + '@push.rocks/smartmongo': 5.1.0(socks@2.8.7) '@push.rocks/smartnetwork': 4.4.0 '@push.rocks/smartpath': 6.0.0 '@push.rocks/smartpromise': 4.2.3 - '@push.rocks/smartrequest': 4.4.2 - '@push.rocks/smarts3': 2.2.6 - '@push.rocks/smartshell': 3.3.0 - '@push.rocks/smarttime': 4.1.1 + '@push.rocks/smartrequest': 5.0.1 + '@push.rocks/smartserve': 2.0.1 + '@push.rocks/smartshell': 3.3.8 + '@push.rocks/smartstorage': 6.0.1 + '@push.rocks/smarttime': 4.2.3 + '@push.rocks/smartwatch': 6.3.0 '@types/ws': 8.18.1 figures: 6.1.0 - ws: 8.18.3 + ws: 8.19.0 transitivePeerDependencies: - '@aws-sdk/credential-providers' - '@mongodb-js/zstd' @@ -4966,9 +5108,197 @@ snapshots: '@hapi/bourne@3.0.0': {} - '@happy-dom/global-registrator@15.11.7': + '@img/colour@1.1.0': {} + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': dependencies: - happy-dom: 15.11.7 + '@emnapi/runtime': 1.7.1 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + + '@inquirer/checkbox@3.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 2.0.0 + ansi-escapes: 4.3.2 + yoctocolors-cjs: 2.1.3 + + '@inquirer/confirm@4.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 2.0.0 + + '@inquirer/core@9.2.1': + dependencies: + '@inquirer/figures': 1.0.15 + '@inquirer/type': 2.0.0 + '@types/mute-stream': 0.0.4 + '@types/node': 22.19.15 + '@types/wrap-ansi': 3.0.0 + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 1.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 + + '@inquirer/editor@3.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 2.0.0 + external-editor: 3.1.0 + + '@inquirer/expand@3.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 2.0.0 + yoctocolors-cjs: 2.1.3 + + '@inquirer/figures@1.0.15': {} + + '@inquirer/input@3.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 2.0.0 + + '@inquirer/number@2.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 2.0.0 + + '@inquirer/password@3.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 2.0.0 + ansi-escapes: 4.3.2 + + '@inquirer/prompts@6.0.1': + dependencies: + '@inquirer/checkbox': 3.0.1 + '@inquirer/confirm': 4.0.1 + '@inquirer/editor': 3.0.1 + '@inquirer/expand': 3.0.1 + '@inquirer/input': 3.0.1 + '@inquirer/number': 2.0.1 + '@inquirer/password': 3.0.1 + '@inquirer/rawlist': 3.0.1 + '@inquirer/search': 2.0.1 + '@inquirer/select': 3.0.1 + + '@inquirer/rawlist@3.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 2.0.0 + yoctocolors-cjs: 2.1.3 + + '@inquirer/search@2.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 2.0.0 + yoctocolors-cjs: 2.1.3 + + '@inquirer/select@3.0.1': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 2.0.0 + ansi-escapes: 4.3.2 + yoctocolors-cjs: 2.1.3 + + '@inquirer/type@2.0.0': + dependencies: + mute-stream: 1.0.0 '@isaacs/balanced-match@4.0.1': {} @@ -4998,10 +5328,199 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/yargs': 17.0.35 chalk: 4.1.2 + '@jimp/core@1.6.0': + dependencies: + '@jimp/file-ops': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + await-to-js: 3.0.0 + exif-parser: 0.1.12 + file-type: 16.5.4 + mime: 3.0.0 + + '@jimp/diff@1.6.0': + dependencies: + '@jimp/plugin-resize': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + pixelmatch: 5.3.0 + + '@jimp/file-ops@1.6.0': {} + + '@jimp/js-bmp@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + bmp-ts: 1.0.9 + + '@jimp/js-gif@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + gifwrap: 0.10.1 + omggif: 1.0.10 + + '@jimp/js-jpeg@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + jpeg-js: 0.4.4 + + '@jimp/js-png@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + pngjs: 7.0.0 + + '@jimp/js-tiff@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + utif2: 4.1.0 + + '@jimp/plugin-blit@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-blur@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/utils': 1.6.0 + + '@jimp/plugin-circle@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-color@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + tinycolor2: 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-contain@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/plugin-blit': 1.6.0 + '@jimp/plugin-resize': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-cover@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/plugin-crop': 1.6.0 + '@jimp/plugin-resize': 1.6.0 + '@jimp/types': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-crop@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-displace@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-dither@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + + '@jimp/plugin-fisheye@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-flip@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-hash@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/js-bmp': 1.6.0 + '@jimp/js-jpeg': 1.6.0 + '@jimp/js-png': 1.6.0 + '@jimp/js-tiff': 1.6.0 + '@jimp/plugin-color': 1.6.0 + '@jimp/plugin-resize': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + any-base: 1.1.0 + + '@jimp/plugin-mask@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-print@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/js-jpeg': 1.6.0 + '@jimp/js-png': 1.6.0 + '@jimp/plugin-blit': 1.6.0 + '@jimp/types': 1.6.0 + parse-bmfont-ascii: 1.0.6 + parse-bmfont-binary: 1.0.6 + parse-bmfont-xml: 1.1.6 + simple-xml-to-json: 1.2.4 + zod: 3.25.76 + + '@jimp/plugin-quantize@1.6.0': + dependencies: + image-q: 4.0.0 + zod: 3.25.76 + + '@jimp/plugin-resize@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-rotate@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/plugin-crop': 1.6.0 + '@jimp/plugin-resize': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-threshold@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/plugin-color': 1.6.0 + '@jimp/plugin-hash': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + zod: 3.25.76 + + '@jimp/types@1.6.0': + dependencies: + zod: 3.25.76 + + '@jimp/utils@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + tinycolor2: 1.6.0 + '@koa/router@9.4.0': dependencies: debug: 4.4.3 @@ -5022,30 +5541,30 @@ snapshots: '@mixmark-io/domino@2.2.0': {} - '@module-federation/error-codes@0.21.4': {} + '@module-federation/error-codes@0.22.0': {} - '@module-federation/runtime-core@0.21.4': + '@module-federation/runtime-core@0.22.0': dependencies: - '@module-federation/error-codes': 0.21.4 - '@module-federation/sdk': 0.21.4 + '@module-federation/error-codes': 0.22.0 + '@module-federation/sdk': 0.22.0 - '@module-federation/runtime-tools@0.21.4': + '@module-federation/runtime-tools@0.22.0': dependencies: - '@module-federation/runtime': 0.21.4 - '@module-federation/webpack-bundler-runtime': 0.21.4 + '@module-federation/runtime': 0.22.0 + '@module-federation/webpack-bundler-runtime': 0.22.0 - '@module-federation/runtime@0.21.4': + '@module-federation/runtime@0.22.0': dependencies: - '@module-federation/error-codes': 0.21.4 - '@module-federation/runtime-core': 0.21.4 - '@module-federation/sdk': 0.21.4 + '@module-federation/error-codes': 0.22.0 + '@module-federation/runtime-core': 0.22.0 + '@module-federation/sdk': 0.22.0 - '@module-federation/sdk@0.21.4': {} + '@module-federation/sdk@0.22.0': {} - '@module-federation/webpack-bundler-runtime@0.21.4': + '@module-federation/webpack-bundler-runtime@0.22.0': dependencies: - '@module-federation/runtime': 0.21.4 - '@module-federation/sdk': 0.21.4 + '@module-federation/runtime': 0.22.0 + '@module-federation/sdk': 0.22.0 '@mongodb-js/saslprep@1.3.2': dependencies: @@ -5070,23 +5589,6 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@oozcitak/dom@1.15.10': - dependencies: - '@oozcitak/infra': 1.0.8 - '@oozcitak/url': 1.0.4 - '@oozcitak/util': 8.3.8 - - '@oozcitak/infra@1.0.8': - dependencies: - '@oozcitak/util': 8.3.8 - - '@oozcitak/url@1.0.4': - dependencies: - '@oozcitak/infra': 1.0.8 - '@oozcitak/util': 8.3.8 - - '@oozcitak/util@8.3.8': {} - '@open-wc/dedupe-mixin@2.0.1': {} '@open-wc/scoped-elements@3.0.6': @@ -5122,7 +5624,7 @@ snapshots: - supports-color - utf-8-validate - '@oxc-project/types@0.98.0': {} + '@oxc-project/types@0.99.0': {} '@pdf-lib/standard-fonts@1.0.0': dependencies: @@ -5258,11 +5760,6 @@ snapshots: '@push.rocks/consolecolor': 2.0.3 '@push.rocks/smartpromise': 4.2.3 - '@push.rocks/isohash@2.0.1': - dependencies: - '@pushrocks/smartenv': 5.0.5 - '@pushrocks/smarthash': 3.0.2 - '@push.rocks/isounique@1.0.5': {} '@push.rocks/levelcache@3.2.0': @@ -5279,7 +5776,7 @@ snapshots: '@push.rocks/smartstring': 4.1.0 '@push.rocks/smartunique': 3.0.9 '@push.rocks/taskbuffer': 3.4.0 - '@tsclass/tsclass': 9.3.0 + '@tsclass/tsclass': 9.5.0 transitivePeerDependencies: - '@nuxt/kit' - aws-crt @@ -5298,6 +5795,17 @@ snapshots: '@types/symbol-tree': 3.2.5 symbol-tree: 3.2.4 + '@push.rocks/lik@6.3.1': + dependencies: + '@push.rocks/smartdelay': 3.0.5 + '@push.rocks/smartmatch': 2.0.0 + '@push.rocks/smartpromise': 4.2.3 + '@push.rocks/smartrx': 3.0.10 + '@push.rocks/smarttime': 4.2.3 + '@types/minimatch': 5.1.2 + '@types/symbol-tree': 3.2.5 + symbol-tree: 3.2.4 + '@push.rocks/mongodump@1.1.0(socks@2.8.7)': dependencies: '@push.rocks/lik': 6.2.2 @@ -5305,7 +5813,7 @@ snapshots: '@push.rocks/smartjson': 5.2.0 '@push.rocks/smartpath': 6.0.0 '@push.rocks/smartpromise': 4.2.3 - '@tsclass/tsclass': 9.3.0 + '@tsclass/tsclass': 9.5.0 mongodb: 6.21.0(socks@2.8.7) transitivePeerDependencies: - '@aws-sdk/credential-providers' @@ -5316,6 +5824,23 @@ snapshots: - snappy - socks + '@push.rocks/npmextra@5.3.3': + dependencies: + '@push.rocks/qenv': 6.1.3 + '@push.rocks/smartfile': 11.2.7 + '@push.rocks/smartjson': 5.2.0 + '@push.rocks/smartlog': 3.1.10 + '@push.rocks/smartpath': 6.0.0 + '@push.rocks/smartpromise': 4.2.3 + '@push.rocks/smartrx': 3.0.10 + '@push.rocks/taskbuffer': 3.4.0 + '@tsclass/tsclass': 9.5.0 + transitivePeerDependencies: + - '@nuxt/kit' + - react + - supports-color + - vue + '@push.rocks/qenv@6.1.3': dependencies: '@api.global/typedrequest': 3.1.10 @@ -5345,20 +5870,24 @@ snapshots: - react-native-b4a - supports-color - '@push.rocks/smartbrowser@2.0.8(typescript@5.9.3)': + '@push.rocks/smartbrowser@2.0.11(typescript@5.9.3)': dependencies: '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartpdf': 3.3.0(typescript@5.9.3) + '@push.rocks/smartpdf': 4.2.0(typescript@5.9.3) '@push.rocks/smartpuppeteer': 2.0.5(typescript@5.9.3) '@push.rocks/smartunique': 3.0.9 transitivePeerDependencies: + - '@nuxt/kit' + - aws-crt - bare-abort-controller - bare-buffer - bufferutil + - react - react-native-b4a - supports-color - typescript - utf-8-validate + - vue '@push.rocks/smartbucket@3.3.10': dependencies: @@ -5370,7 +5899,7 @@ snapshots: '@push.rocks/smartstream': 3.2.5 '@push.rocks/smartstring': 4.1.0 '@push.rocks/smartunique': 3.0.9 - '@tsclass/tsclass': 9.3.0 + '@tsclass/tsclass': 9.5.0 transitivePeerDependencies: - aws-crt @@ -5386,18 +5915,10 @@ snapshots: '@push.rocks/smartpromise': 4.2.3 '@push.rocks/smarttime': 4.1.1 - '@push.rocks/smartchok@1.1.1': + '@push.rocks/smartcli@4.0.20': dependencies: '@push.rocks/lik': 6.2.2 - '@push.rocks/smartpromise': 4.2.3 - '@push.rocks/smartrx': 3.0.10 - chokidar: 4.0.3 - picomatch: 4.0.3 - - '@push.rocks/smartcli@4.0.19': - dependencies: - '@push.rocks/lik': 6.2.2 - '@push.rocks/smartlog': 3.1.10 + '@push.rocks/smartlog': 3.2.1 '@push.rocks/smartobject': 1.0.12 '@push.rocks/smartpromise': 4.2.3 '@push.rocks/smartrx': 3.0.10 @@ -5430,7 +5951,7 @@ snapshots: '@push.rocks/smarttime': 4.1.1 '@push.rocks/smartunique': 3.0.9 '@push.rocks/taskbuffer': 3.4.0 - '@tsclass/tsclass': 9.3.0 + '@tsclass/tsclass': 9.5.0 mongodb: 6.21.0(socks@2.8.7) transitivePeerDependencies: - '@aws-sdk/credential-providers' @@ -5457,7 +5978,7 @@ snapshots: '@push.rocks/smartenv': 5.0.13 '@push.rocks/smartpromise': 4.2.3 '@push.rocks/smartrequest': 2.1.0 - '@tsclass/tsclass': 9.3.0 + '@tsclass/tsclass': 9.5.0 '@types/dns-packet': 5.6.5 '@types/elliptic': 6.4.18 acme-client: 5.4.0 @@ -5487,6 +6008,11 @@ snapshots: '@push.rocks/smartpromise': 4.2.3 tree-kill: 1.2.2 + '@push.rocks/smartexit@2.0.3': + dependencies: + '@push.rocks/lik': 6.2.2 + '@push.rocks/smartpromise': 4.2.3 + '@push.rocks/smartexpect@2.5.0': dependencies: '@push.rocks/smartdelay': 3.0.5 @@ -5495,7 +6021,7 @@ snapshots: '@push.rocks/smartfeed@1.4.0': dependencies: - '@tsclass/tsclass': 9.3.0 + '@tsclass/tsclass': 9.5.0 fast-xml-parser: 4.5.3 '@push.rocks/smartfile-interfaces@1.0.7': {} @@ -5518,6 +6044,28 @@ snapshots: glob: 11.1.0 js-yaml: 4.1.1 + '@push.rocks/smartfile@13.1.2': + dependencies: + '@push.rocks/lik': 6.2.2 + '@push.rocks/smartdelay': 3.0.5 + '@push.rocks/smartfile-interfaces': 1.0.7 + '@push.rocks/smartfs': 1.5.0 + '@push.rocks/smarthash': 3.2.6 + '@push.rocks/smartjson': 5.2.0 + '@push.rocks/smartmime': 2.0.4 + '@push.rocks/smartpath': 6.0.0 + '@push.rocks/smartpromise': 4.2.3 + '@push.rocks/smartrequest': 4.4.2 + '@push.rocks/smartstream': 3.2.5 + '@types/js-yaml': 4.0.9 + glob: 11.1.0 + js-yaml: 4.1.1 + + '@push.rocks/smartfs@1.5.0': + dependencies: + '@push.rocks/smartpath': 6.0.0 + '@push.rocks/smartrust': 1.3.2 + '@push.rocks/smartguard@3.1.0': dependencies: '@push.rocks/smartpromise': 4.2.3 @@ -5531,6 +6079,29 @@ snapshots: '@types/through2': 2.0.41 through2: 4.0.2 + '@push.rocks/smartinteract@2.0.16': + dependencies: + '@push.rocks/lik': 6.2.2 + '@push.rocks/smartobject': 1.0.12 + '@push.rocks/smartpromise': 4.2.3 + inquirer: 11.1.0 + + '@push.rocks/smartjimp@1.2.0': + dependencies: + '@push.rocks/levelcache': 3.2.0 + '@push.rocks/smartfile': 11.2.7 + '@push.rocks/smarthash': 3.2.6 + '@push.rocks/smartpath': 6.0.0 + '@push.rocks/smartrequest': 4.4.2 + jimp: 1.6.0 + sharp: 0.34.5 + transitivePeerDependencies: + - '@nuxt/kit' + - aws-crt + - react + - supports-color + - vue + '@push.rocks/smartjson@5.2.0': dependencies: '@push.rocks/smartenv': 5.0.13 @@ -5538,9 +6109,12 @@ snapshots: fast-json-stable-stringify: 2.1.0 lodash.clonedeep: 4.5.0 - '@push.rocks/smartlog-destination-devtools@1.0.12': + '@push.rocks/smartjson@6.0.0': dependencies: - '@push.rocks/smartlog-interfaces': 3.0.2 + '@push.rocks/smartenv': 6.0.0 + '@push.rocks/smartstring': 4.1.0 + fast-json-stable-stringify: 2.1.0 + lodash.clonedeep: 4.5.0 '@push.rocks/smartlog-destination-local@9.0.2': dependencies: @@ -5564,9 +6138,20 @@ snapshots: '@push.rocks/smartpromise': 4.2.3 '@push.rocks/smarttime': 4.1.1 '@push.rocks/webrequest': 3.0.37 - '@tsclass/tsclass': 9.3.0 + '@tsclass/tsclass': 9.5.0 - '@push.rocks/smartmanifest@2.0.2': {} + '@push.rocks/smartlog@3.2.1': + dependencies: + '@api.global/typedrequest-interfaces': 3.0.19 + '@push.rocks/consolecolor': 2.0.3 + '@push.rocks/isounique': 1.0.5 + '@push.rocks/smartclickhouse': 2.0.17 + '@push.rocks/smartfile': 11.2.7 + '@push.rocks/smarthash': 3.2.6 + '@push.rocks/smartpromise': 4.2.3 + '@push.rocks/smarttime': 4.1.1 + '@push.rocks/webrequest': 4.0.5 + '@tsclass/tsclass': 9.5.0 '@push.rocks/smartmarkdown@3.0.3': dependencies: @@ -5615,6 +6200,32 @@ snapshots: - supports-color - vue + '@push.rocks/smartmongo@5.1.0(socks@2.8.7)': + dependencies: + '@push.rocks/mongodump': 1.1.0(socks@2.8.7) + '@push.rocks/smartdata': 5.16.7(socks@2.8.7) + '@push.rocks/smartfs': 1.5.0 + '@push.rocks/smartpath': 5.1.0 + '@push.rocks/smartpromise': 4.2.3 + '@push.rocks/smartrx': 3.0.10 + bson: 6.10.4 + mingo: 7.2.0 + mongodb-memory-server: 10.3.0(socks@2.8.7) + transitivePeerDependencies: + - '@aws-sdk/credential-providers' + - '@mongodb-js/zstd' + - '@nuxt/kit' + - bare-abort-controller + - gcp-metadata + - kerberos + - mongodb-client-encryption + - react + - react-native-b4a + - snappy + - socks + - supports-color + - vue + '@push.rocks/smartnetwork@4.4.0': dependencies: '@push.rocks/smartdns': 7.6.1 @@ -5647,54 +6258,42 @@ snapshots: - supports-color - vue - '@push.rocks/smartntml@2.0.8': - dependencies: - '@design.estate/dees-element': 2.1.3 - '@happy-dom/global-registrator': 15.11.7 - '@push.rocks/smartpromise': 4.2.3 - fake-indexeddb: 6.2.5 - transitivePeerDependencies: - - '@nuxt/kit' - - react - - supports-color - - vue - '@push.rocks/smartobject@1.0.12': dependencies: fast-deep-equal: 3.1.3 minimatch: 9.0.5 - '@push.rocks/smartopen@2.0.0': - dependencies: - open: 8.4.2 - '@push.rocks/smartpath@5.1.0': {} '@push.rocks/smartpath@6.0.0': {} - '@push.rocks/smartpdf@3.3.0(typescript@5.9.3)': + '@push.rocks/smartpdf@4.2.0(typescript@5.9.3)': dependencies: '@push.rocks/smartbuffer': 3.0.5 '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartfile': 11.2.7 + '@push.rocks/smartfs': 1.5.0 + '@push.rocks/smartjimp': 1.2.0 '@push.rocks/smartnetwork': 4.4.0 '@push.rocks/smartpath': 6.0.0 '@push.rocks/smartpromise': 4.2.3 '@push.rocks/smartpuppeteer': 2.0.5(typescript@5.9.3) + '@push.rocks/smartserve': 2.0.1 '@push.rocks/smartunique': 3.0.9 - '@tsclass/tsclass': 9.3.0 - '@types/express': 5.0.5 - express: 5.1.0 + '@tsclass/tsclass': 9.5.0 pdf-lib: 1.17.1 - pdf2json: 3.2.0 + pdf2json: 4.0.2 transitivePeerDependencies: + - '@nuxt/kit' + - aws-crt - bare-abort-controller - bare-buffer - bufferutil + - react - react-native-b4a - supports-color - typescript - utf-8-validate + - vue '@push.rocks/smartping@1.0.8': dependencies: @@ -5706,7 +6305,7 @@ snapshots: '@push.rocks/smartpuppeteer@2.0.5(typescript@5.9.3)': dependencies: '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartshell': 3.3.0 + '@push.rocks/smartshell': 3.3.8 puppeteer: 24.30.0(typescript@5.9.3) tree-kill: 1.2.2 transitivePeerDependencies: @@ -5734,12 +6333,25 @@ snapshots: agentkeepalive: 4.6.0 form-data: 4.0.5 + '@push.rocks/smartrequest@5.0.1': + dependencies: + '@push.rocks/smartenv': 6.0.0 + '@push.rocks/smartpath': 6.0.0 + '@push.rocks/smartpromise': 4.2.3 + '@push.rocks/smarturl': 3.1.0 + agentkeepalive: 4.6.0 + form-data: 4.0.5 + '@push.rocks/smartrouter@1.3.3': dependencies: '@push.rocks/lik': 6.2.2 '@push.rocks/smartrx': 3.0.10 path-to-regexp: 8.3.0 + '@push.rocks/smartrust@1.3.2': + dependencies: + '@push.rocks/smartpath': 6.0.0 + '@push.rocks/smartrx@3.0.10': dependencies: '@push.rocks/smartpromise': 4.2.3 @@ -5750,13 +6362,26 @@ snapshots: '@push.rocks/smartbucket': 3.3.10 '@push.rocks/smartfile': 11.2.7 '@push.rocks/smartpath': 6.0.0 - '@tsclass/tsclass': 9.3.0 + '@tsclass/tsclass': 9.5.0 '@types/s3rver': 3.7.4 s3rver: 3.7.1 transitivePeerDependencies: - aws-crt - supports-color + '@push.rocks/smartserve@2.0.1': + dependencies: + '@api.global/typedrequest': 3.3.0 + '@cfworker/json-schema': 4.1.1 + '@push.rocks/lik': 6.2.2 + '@push.rocks/smartenv': 6.0.0 + '@push.rocks/smartlog': 3.2.1 + '@push.rocks/smartpath': 6.0.0 + ws: 8.19.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + '@push.rocks/smartshell@3.3.0': dependencies: '@push.rocks/smartdelay': 3.0.5 @@ -5766,39 +6391,13 @@ snapshots: tree-kill: 1.2.2 which: 5.0.0 - '@push.rocks/smartsitemap@2.0.3': + '@push.rocks/smartshell@3.3.8': dependencies: - '@push.rocks/smartcache': 1.0.18 - '@push.rocks/smartfeed': 1.4.0 - '@push.rocks/smartxml': 1.1.1 - '@push.rocks/smartyaml': 2.0.5 - '@push.rocks/webrequest': 3.0.37 - '@tsclass/tsclass': 4.4.4 - - '@push.rocks/smartsocket@2.1.0': - dependencies: - '@api.global/typedrequest-interfaces': 3.0.19 - '@api.global/typedserver': 3.0.79 - '@push.rocks/isohash': 2.0.1 - '@push.rocks/isounique': 1.0.5 - '@push.rocks/lik': 6.2.2 '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartenv': 5.0.13 - '@push.rocks/smartjson': 5.2.0 - '@push.rocks/smartlog': 3.1.10 + '@push.rocks/smartexit': 2.0.3 '@push.rocks/smartpromise': 4.2.3 - '@push.rocks/smartrx': 3.0.10 - '@push.rocks/smarttime': 4.1.1 - engine.io: 6.6.4 - socket.io: 4.8.1 - socket.io-client: 4.8.1 - transitivePeerDependencies: - - '@nuxt/kit' - - bufferutil - - react - - supports-color - - utf-8-validate - - vue + '@types/which': 3.0.4 + which: 6.0.1 '@push.rocks/smartspawn@3.0.3': dependencies: @@ -5818,6 +6417,12 @@ snapshots: '@push.rocks/smartrx': 3.0.10 '@push.rocks/webstore': 2.0.20 + '@push.rocks/smartstorage@6.0.1': + dependencies: + '@push.rocks/smartpath': 6.0.0 + '@push.rocks/smartrust': 1.3.2 + '@tsclass/tsclass': 9.5.0 + '@push.rocks/smartstream@3.2.5': dependencies: '@push.rocks/lik': 6.2.2 @@ -5840,6 +6445,17 @@ snapshots: is-nan: 1.3.2 pretty-ms: 9.3.0 + '@push.rocks/smarttime@4.2.3': + dependencies: + '@push.rocks/lik': 6.2.2 + '@push.rocks/smartdelay': 3.0.5 + '@push.rocks/smartpromise': 4.2.3 + croner: 10.0.1 + date-fns: 4.1.0 + dayjs: 1.11.19 + is-nan: 1.3.2 + pretty-ms: 9.3.0 + '@push.rocks/smartunique@3.0.9': dependencies: '@types/uuid': 9.0.8 @@ -5853,10 +6469,14 @@ snapshots: '@types/semver': 7.7.1 semver: 7.7.3 - '@push.rocks/smartxml@1.1.1': + '@push.rocks/smartwatch@6.3.0': dependencies: - fast-xml-parser: 4.5.3 - xmlbuilder2: 3.1.1 + '@push.rocks/lik': 6.2.2 + '@push.rocks/smartenv': 6.0.0 + '@push.rocks/smartpromise': 4.2.3 + '@push.rocks/smartrx': 3.0.10 + chokidar: 5.0.0 + picomatch: 4.0.3 '@push.rocks/smartxml@2.0.0': dependencies: @@ -5929,11 +6549,11 @@ snapshots: '@push.rocks/smartpromise': 4.2.3 '@push.rocks/webstore': 2.0.20 - '@push.rocks/webrequest@4.0.1': + '@push.rocks/webrequest@4.0.5': dependencies: '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartenv': 5.0.13 - '@push.rocks/smartjson': 5.2.0 + '@push.rocks/smartenv': 6.0.0 + '@push.rocks/smartjson': 6.0.0 '@push.rocks/smartpromise': 4.2.3 '@push.rocks/webstore': 2.0.20 @@ -5958,143 +6578,107 @@ snapshots: dependencies: '@push.rocks/smartenv': 5.0.13 - '@pushrocks/isounique@1.0.5': {} - '@pushrocks/smartdelay@3.0.1': dependencies: '@pushrocks/smartpromise': 4.0.2 - '@pushrocks/smartenv@5.0.5': - dependencies: - '@pushrocks/smartpromise': 3.1.10 - - '@pushrocks/smarthash@3.0.2': - dependencies: - '@pushrocks/smartjson': 5.0.6 - '@pushrocks/smartpromise': 3.1.10 - '@types/through2': 2.0.41 - through2: 4.0.2 - - '@pushrocks/smartjson@5.0.6': - dependencies: - '@pushrocks/smartstring': 4.0.7 - '@types/buffer-json': 2.0.3 - buffer-json: 2.0.0 - fast-json-stable-stringify: 2.1.0 - lodash.clonedeep: 4.5.0 - - '@pushrocks/smartpromise@3.1.10': {} - '@pushrocks/smartpromise@4.0.2': {} - '@pushrocks/smartstring@4.0.7': - dependencies: - '@pushrocks/isounique': 1.0.5 - '@pushrocks/smartenv': 5.0.5 - '@types/randomatic': 3.1.5 - buffer: 6.0.3 - crypto-random-string: 5.0.0 - js-base64: 3.7.8 - normalize-newline: 4.1.0 - randomatic: 3.1.1 - strip-indent: 4.1.1 - url: 0.11.4 - - '@rolldown/binding-android-arm64@1.0.0-beta.51': + '@rolldown/binding-android-arm64@1.0.0-beta.52': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-beta.51': + '@rolldown/binding-darwin-arm64@1.0.0-beta.52': optional: true - '@rolldown/binding-darwin-x64@1.0.0-beta.51': + '@rolldown/binding-darwin-x64@1.0.0-beta.52': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-beta.51': + '@rolldown/binding-freebsd-x64@1.0.0-beta.52': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.51': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.52': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.51': + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.52': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.51': + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.52': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.51': + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.52': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-beta.51': + '@rolldown/binding-linux-x64-musl@1.0.0-beta.52': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-beta.51': + '@rolldown/binding-openharmony-arm64@1.0.0-beta.52': optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-beta.51': + '@rolldown/binding-wasm32-wasi@1.0.0-beta.52': dependencies: '@napi-rs/wasm-runtime': 1.0.7 optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.51': + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.52': optional: true - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.51': + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.52': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.51': + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.52': optional: true - '@rolldown/pluginutils@1.0.0-beta.51': {} + '@rolldown/pluginutils@1.0.0-beta.52': {} - '@rspack/binding-darwin-arm64@1.6.4': + '@rspack/binding-darwin-arm64@1.7.9': optional: true - '@rspack/binding-darwin-x64@1.6.4': + '@rspack/binding-darwin-x64@1.7.9': optional: true - '@rspack/binding-linux-arm64-gnu@1.6.4': + '@rspack/binding-linux-arm64-gnu@1.7.9': optional: true - '@rspack/binding-linux-arm64-musl@1.6.4': + '@rspack/binding-linux-arm64-musl@1.7.9': optional: true - '@rspack/binding-linux-x64-gnu@1.6.4': + '@rspack/binding-linux-x64-gnu@1.7.9': optional: true - '@rspack/binding-linux-x64-musl@1.6.4': + '@rspack/binding-linux-x64-musl@1.7.9': optional: true - '@rspack/binding-wasm32-wasi@1.6.4': + '@rspack/binding-wasm32-wasi@1.7.9': dependencies: '@napi-rs/wasm-runtime': 1.0.7 optional: true - '@rspack/binding-win32-arm64-msvc@1.6.4': + '@rspack/binding-win32-arm64-msvc@1.7.9': optional: true - '@rspack/binding-win32-ia32-msvc@1.6.4': + '@rspack/binding-win32-ia32-msvc@1.7.9': optional: true - '@rspack/binding-win32-x64-msvc@1.6.4': + '@rspack/binding-win32-x64-msvc@1.7.9': optional: true - '@rspack/binding@1.6.4': + '@rspack/binding@1.7.9': optionalDependencies: - '@rspack/binding-darwin-arm64': 1.6.4 - '@rspack/binding-darwin-x64': 1.6.4 - '@rspack/binding-linux-arm64-gnu': 1.6.4 - '@rspack/binding-linux-arm64-musl': 1.6.4 - '@rspack/binding-linux-x64-gnu': 1.6.4 - '@rspack/binding-linux-x64-musl': 1.6.4 - '@rspack/binding-wasm32-wasi': 1.6.4 - '@rspack/binding-win32-arm64-msvc': 1.6.4 - '@rspack/binding-win32-ia32-msvc': 1.6.4 - '@rspack/binding-win32-x64-msvc': 1.6.4 + '@rspack/binding-darwin-arm64': 1.7.9 + '@rspack/binding-darwin-x64': 1.7.9 + '@rspack/binding-linux-arm64-gnu': 1.7.9 + '@rspack/binding-linux-arm64-musl': 1.7.9 + '@rspack/binding-linux-x64-gnu': 1.7.9 + '@rspack/binding-linux-x64-musl': 1.7.9 + '@rspack/binding-wasm32-wasi': 1.7.9 + '@rspack/binding-win32-arm64-msvc': 1.7.9 + '@rspack/binding-win32-ia32-msvc': 1.7.9 + '@rspack/binding-win32-x64-msvc': 1.7.9 - '@rspack/core@1.6.4': + '@rspack/core@1.7.9': dependencies: - '@module-federation/runtime-tools': 0.21.4 - '@rspack/binding': 1.6.4 + '@module-federation/runtime-tools': 0.22.0 + '@rspack/binding': 1.7.9 '@rspack/lite-tapable': 1.1.0 '@rspack/lite-tapable@1.1.0': {} @@ -6448,8 +7032,6 @@ snapshots: color: 5.0.3 text-hex: 1.0.0 - '@socket.io/component-emitter@3.1.2': {} - '@szmarczak/http-timer@5.0.1': dependencies: defer-to-connect: 2.0.1 @@ -6471,9 +7053,9 @@ snapshots: dependencies: type-fest: 4.41.0 - '@tsclass/tsclass@9.3.0': + '@tsclass/tsclass@9.5.0': dependencies: - type-fest: 4.41.0 + type-fest: 5.5.0 '@tybys/wasm-util@0.10.1': dependencies: @@ -6482,20 +7064,18 @@ snapshots: '@types/accepts@1.3.7': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/babel__code-frame@7.0.6': {} '@types/bn.js@5.2.0': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 20.19.25 - - '@types/buffer-json@2.0.3': {} + '@types/node': 22.19.15 '@types/chai-dom@1.11.3': dependencies: @@ -6510,17 +7090,17 @@ snapshots: '@types/clean-css@4.2.11': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 source-map: 0.6.1 '@types/co-body@6.1.3': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/qs': 6.14.0 '@types/connect@3.4.38': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/content-disposition@0.5.9': {} @@ -6531,11 +7111,7 @@ snapshots: '@types/connect': 3.4.38 '@types/express': 5.0.5 '@types/keygrip': 1.0.6 - '@types/node': 20.19.25 - - '@types/cors@2.8.19': - dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/debounce@1.2.4': {} @@ -6547,7 +7123,7 @@ snapshots: '@types/dns-packet@5.6.5': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/elliptic@6.4.18': dependencies: @@ -6555,7 +7131,7 @@ snapshots: '@types/express-serve-static-core@5.1.0': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -6569,7 +7145,7 @@ snapshots: '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/hast@3.0.4': dependencies: @@ -6603,7 +7179,7 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/keygrip@1.0.6': {} @@ -6620,7 +7196,7 @@ snapshots: '@types/http-errors': 2.0.5 '@types/keygrip': 1.0.6 '@types/koa-compose': 3.2.9 - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/mdast@4.0.4': dependencies: @@ -6634,11 +7210,17 @@ snapshots: '@types/ms@2.1.0': {} + '@types/mute-stream@0.0.4': + dependencies: + '@types/node': 22.19.15 + '@types/node-forge@1.3.14': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 - '@types/node@20.19.25': + '@types/node@16.9.1': {} + + '@types/node@22.19.15': dependencies: undici-types: 6.21.0 @@ -6648,31 +7230,29 @@ snapshots: '@types/qs@6.14.0': {} - '@types/randomatic@3.1.5': {} - '@types/range-parser@1.2.7': {} '@types/relateurl@0.2.33': {} '@types/s3rver@3.7.4': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/semver@7.7.1': {} '@types/send@0.17.6': dependencies: '@types/mime': 1.3.5 - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/send@1.2.1': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/serve-static@1.15.10': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/send': 0.17.6 '@types/sinon-chai@3.2.12': @@ -6692,11 +7272,11 @@ snapshots: '@types/tar-stream@3.1.4': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/through2@2.0.41': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/triple-beam@1.3.5': {} @@ -6720,13 +7300,15 @@ snapshots: '@types/which@3.0.4': {} + '@types/wrap-ansi@3.0.0': {} + '@types/ws@7.4.7': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/ws@8.18.1': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 '@types/yargs-parser@21.0.3': {} @@ -6736,7 +7318,7 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 20.19.25 + '@types/node': 22.19.15 optional: true '@ungap/structured-clone@1.3.0': {} @@ -6817,16 +7399,15 @@ snapshots: - supports-color - utf-8-validate + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + accepts@1.3.8: dependencies: mime-types: 2.1.35 negotiator: 0.6.3 - accepts@2.0.0: - dependencies: - mime-types: 3.0.1 - negotiator: 1.0.0 - acme-client@5.4.0: dependencies: '@peculiar/x509': 1.14.2 @@ -6865,6 +7446,8 @@ snapshots: ansi-styles@6.2.3: {} + any-base@1.1.0: {} + argparse@1.0.10: dependencies: sprintf-js: 1.0.3 @@ -6895,6 +7478,8 @@ snapshots: asynckit@0.4.0: {} + await-to-js@3.0.0: {} + axe-core@4.11.0: {} axios@1.13.2(debug@4.4.3): @@ -6950,25 +7535,11 @@ snapshots: base64-js@1.5.1: {} - base64id@2.0.0: {} - basic-ftp@5.0.5: {} - bn.js@4.12.2: {} + bmp-ts@1.0.9: {} - body-parser@2.2.0: - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 4.4.3 - http-errors: 2.0.0 - iconv-lite: 0.6.3 - on-finished: 2.4.1 - qs: 6.14.0 - raw-body: 3.0.1 - type-is: 2.0.1 - transitivePeerDependencies: - - supports-color + bn.js@4.12.2: {} bowser@2.12.1: {} @@ -6998,8 +7569,6 @@ snapshots: buffer-crc32@0.2.13: {} - buffer-json@2.0.0: {} - buffer@6.0.3: dependencies: base64-js: 1.5.1 @@ -7077,10 +7646,16 @@ snapshots: character-entities@2.0.2: {} + chardet@0.7.0: {} + chokidar@4.0.3: dependencies: readdirp: 4.1.2 + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + chromium-bidi@11.0.0(devtools-protocol@0.0.1521046): dependencies: devtools-protocol: 0.0.1521046 @@ -7099,6 +7674,8 @@ snapshots: dependencies: restore-cursor: 3.1.0 + cli-width@4.1.0: {} + cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -7167,26 +7744,15 @@ snapshots: dependencies: safe-buffer: 5.2.1 - content-disposition@1.0.1: {} - content-type@1.0.5: {} convert-source-map@2.0.0: {} - cookie-signature@1.2.2: {} - - cookie@0.7.2: {} - cookies@0.9.1: dependencies: depd: 2.0.0 keygrip: 1.1.0 - cors@2.8.5: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - cosmiconfig@9.0.0(typescript@5.9.3): dependencies: env-paths: 2.2.1 @@ -7196,6 +7762,8 @@ snapshots: optionalDependencies: typescript: 5.9.3 + croner@10.0.1: {} + croner@9.1.0: {} cross-spawn@7.0.6: @@ -7204,10 +7772,6 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - crypto-random-string@5.0.0: - dependencies: - type-fest: 2.19.0 - data-uri-to-buffer@6.0.2: {} date-fns@4.1.0: {} @@ -7220,10 +7784,6 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.3.7: - dependencies: - ms: 2.1.3 - debug@4.4.3: dependencies: ms: 2.1.3 @@ -7280,6 +7840,8 @@ snapshots: destroy@1.2.0: {} + detect-libc@2.1.2: {} + devlop@1.1.0: dependencies: dequal: 2.0.3 @@ -7328,44 +7890,10 @@ snapshots: encodeurl@1.0.2: {} - encodeurl@2.0.0: {} - end-of-stream@1.4.5: dependencies: once: 1.4.0 - engine.io-client@6.6.3: - dependencies: - '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 - engine.io-parser: 5.2.3 - ws: 8.17.1 - xmlhttprequest-ssl: 2.1.2 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - engine.io-parser@5.2.3: {} - - engine.io@6.6.4: - dependencies: - '@types/cors': 2.8.19 - '@types/node': 20.19.25 - accepts: 1.3.8 - base64id: 2.0.0 - cookie: 0.7.2 - cors: 2.8.5 - debug: 4.3.7 - engine.io-parser: 5.2.3 - ws: 8.17.1 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - entities@4.5.0: {} - env-paths@2.2.1: {} error-ex@1.3.4: @@ -7391,34 +7919,34 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 - esbuild@0.25.12: + esbuild@0.27.4: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.12 - '@esbuild/android-arm': 0.25.12 - '@esbuild/android-arm64': 0.25.12 - '@esbuild/android-x64': 0.25.12 - '@esbuild/darwin-arm64': 0.25.12 - '@esbuild/darwin-x64': 0.25.12 - '@esbuild/freebsd-arm64': 0.25.12 - '@esbuild/freebsd-x64': 0.25.12 - '@esbuild/linux-arm': 0.25.12 - '@esbuild/linux-arm64': 0.25.12 - '@esbuild/linux-ia32': 0.25.12 - '@esbuild/linux-loong64': 0.25.12 - '@esbuild/linux-mips64el': 0.25.12 - '@esbuild/linux-ppc64': 0.25.12 - '@esbuild/linux-riscv64': 0.25.12 - '@esbuild/linux-s390x': 0.25.12 - '@esbuild/linux-x64': 0.25.12 - '@esbuild/netbsd-arm64': 0.25.12 - '@esbuild/netbsd-x64': 0.25.12 - '@esbuild/openbsd-arm64': 0.25.12 - '@esbuild/openbsd-x64': 0.25.12 - '@esbuild/openharmony-arm64': 0.25.12 - '@esbuild/sunos-x64': 0.25.12 - '@esbuild/win32-arm64': 0.25.12 - '@esbuild/win32-ia32': 0.25.12 - '@esbuild/win32-x64': 0.25.12 + '@esbuild/aix-ppc64': 0.27.4 + '@esbuild/android-arm': 0.27.4 + '@esbuild/android-arm64': 0.27.4 + '@esbuild/android-x64': 0.27.4 + '@esbuild/darwin-arm64': 0.27.4 + '@esbuild/darwin-x64': 0.27.4 + '@esbuild/freebsd-arm64': 0.27.4 + '@esbuild/freebsd-x64': 0.27.4 + '@esbuild/linux-arm': 0.27.4 + '@esbuild/linux-arm64': 0.27.4 + '@esbuild/linux-ia32': 0.27.4 + '@esbuild/linux-loong64': 0.27.4 + '@esbuild/linux-mips64el': 0.27.4 + '@esbuild/linux-ppc64': 0.27.4 + '@esbuild/linux-riscv64': 0.27.4 + '@esbuild/linux-s390x': 0.27.4 + '@esbuild/linux-x64': 0.27.4 + '@esbuild/netbsd-arm64': 0.27.4 + '@esbuild/netbsd-x64': 0.27.4 + '@esbuild/openbsd-arm64': 0.27.4 + '@esbuild/openbsd-x64': 0.27.4 + '@esbuild/openharmony-arm64': 0.27.4 + '@esbuild/sunos-x64': 0.27.4 + '@esbuild/win32-arm64': 0.27.4 + '@esbuild/win32-ia32': 0.27.4 + '@esbuild/win32-x64': 0.27.4 escalade@3.2.0: {} @@ -7448,6 +7976,8 @@ snapshots: etag@1.8.1: {} + event-target-shim@5.0.1: {} + eventemitter3@4.0.7: {} events-universal@1.0.1: @@ -7456,6 +7986,8 @@ snapshots: transitivePeerDependencies: - bare-abort-controller + events@3.3.0: {} + execa@5.1.1: dependencies: cross-spawn: 7.0.6 @@ -7468,6 +8000,8 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 + exif-parser@0.1.12: {} + expect@29.7.0: dependencies: '@jest/expect-utils': 29.7.0 @@ -7476,44 +8010,14 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 - express-force-ssl@0.3.2: - dependencies: - lodash.assign: 3.2.0 - - express@5.1.0: - dependencies: - accepts: 2.0.0 - body-parser: 2.2.0 - content-disposition: 1.0.1 - content-type: 1.0.5 - cookie: 0.7.2 - cookie-signature: 1.2.2 - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 2.1.0 - fresh: 2.0.0 - http-errors: 2.0.0 - merge-descriptors: 2.0.0 - mime-types: 3.0.1 - on-finished: 2.4.1 - once: 1.4.0 - parseurl: 1.3.3 - proxy-addr: 2.0.7 - qs: 6.14.0 - range-parser: 1.2.1 - router: 2.2.0 - send: 1.2.0 - serve-static: 2.2.0 - statuses: 2.0.2 - type-is: 2.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - extend@3.0.2: {} + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + extract-zip@2.0.1: dependencies: debug: 4.4.3 @@ -7526,8 +8030,6 @@ snapshots: fake-indexeddb@5.0.2: {} - fake-indexeddb@6.2.5: {} - fast-deep-equal@3.1.3: {} fast-fifo@1.3.2: {} @@ -7578,6 +8080,12 @@ snapshots: dependencies: is-unicode-supported: 2.1.0 + file-type@16.5.4: + dependencies: + readable-web-to-node-stream: 3.0.4 + strtok3: 6.3.0 + token-types: 4.2.1 + file-type@19.6.0: dependencies: get-stream: 9.0.1 @@ -7598,17 +8106,6 @@ snapshots: dependencies: to-regex-range: 5.0.1 - finalhandler@2.1.0: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - find-cache-dir@3.3.2: dependencies: commondir: 1.0.1 @@ -7648,12 +8145,8 @@ snapshots: format@0.2.2: {} - forwarded@0.2.0: {} - fresh@0.5.2: {} - fresh@2.0.0: {} - fs-extra@11.3.2: dependencies: graceful-fs: 4.2.11 @@ -7718,6 +8211,11 @@ snapshots: transitivePeerDependencies: - supports-color + gifwrap@0.10.1: + dependencies: + image-q: 4.0.0 + omggif: 1.0.10 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -7769,12 +8267,6 @@ snapshots: graceful-fs@4.2.11: {} - happy-dom@15.11.7: - dependencies: - entities: 4.5.0 - webidl-conversions: 7.0.0 - whatwg-mimetype: 3.0.0 - has-flag@3.0.0: {} has-flag@4.0.0: {} @@ -7905,18 +8397,14 @@ snapshots: dependencies: safer-buffer: 2.1.2 - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - - iconv-lite@0.7.0: - dependencies: - safer-buffer: 2.1.2 - ieee754@1.2.1: {} ignore@5.3.2: {} + image-q@4.0.0: + dependencies: + '@types/node': 16.9.1 + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 @@ -7935,6 +8423,17 @@ snapshots: ini@1.3.8: {} + inquirer@11.1.0: + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/prompts': 6.0.1 + '@inquirer/type': 2.0.0 + '@types/mute-stream': 0.0.4 + ansi-escapes: 4.3.2 + mute-stream: 1.0.0 + run-async: 3.0.0 + rxjs: 7.8.2 + internal-ip@6.2.0: dependencies: default-gateway: 6.0.3 @@ -7977,16 +8476,12 @@ snapshots: call-bind: 1.0.8 define-properties: 1.2.1 - is-number@4.0.0: {} - is-number@7.0.0: {} is-observable@2.1.0: {} is-plain-obj@4.1.0: {} - is-promise@4.0.0: {} - is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -8012,6 +8507,8 @@ snapshots: isexe@3.1.1: {} + isexe@4.0.0: {} + isopen@1.3.0: {} istanbul-lib-coverage@3.2.2: {} @@ -8062,21 +8559,46 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.19.25 + '@types/node': 22.19.15 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 picomatch: 2.3.1 - js-base64@3.7.8: {} + jimp@1.6.0: + dependencies: + '@jimp/core': 1.6.0 + '@jimp/diff': 1.6.0 + '@jimp/js-bmp': 1.6.0 + '@jimp/js-gif': 1.6.0 + '@jimp/js-jpeg': 1.6.0 + '@jimp/js-png': 1.6.0 + '@jimp/js-tiff': 1.6.0 + '@jimp/plugin-blit': 1.6.0 + '@jimp/plugin-blur': 1.6.0 + '@jimp/plugin-circle': 1.6.0 + '@jimp/plugin-color': 1.6.0 + '@jimp/plugin-contain': 1.6.0 + '@jimp/plugin-cover': 1.6.0 + '@jimp/plugin-crop': 1.6.0 + '@jimp/plugin-displace': 1.6.0 + '@jimp/plugin-dither': 1.6.0 + '@jimp/plugin-fisheye': 1.6.0 + '@jimp/plugin-flip': 1.6.0 + '@jimp/plugin-hash': 1.6.0 + '@jimp/plugin-mask': 1.6.0 + '@jimp/plugin-print': 1.6.0 + '@jimp/plugin-quantize': 1.6.0 + '@jimp/plugin-resize': 1.6.0 + '@jimp/plugin-rotate': 1.6.0 + '@jimp/plugin-threshold': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + + jpeg-js@0.4.4: {} js-tokens@4.0.0: {} - js-yaml@3.14.1: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - js-yaml@3.14.2: dependencies: argparse: 1.0.10 @@ -8108,8 +8630,6 @@ snapshots: dependencies: json-buffer: 3.0.1 - kind-of@6.0.3: {} - koa-compose@4.1.0: {} koa-convert@2.0.0: @@ -8197,45 +8717,8 @@ snapshots: dependencies: p-locate: 4.1.0 - lodash._baseassign@3.2.0: - dependencies: - lodash._basecopy: 3.0.1 - lodash.keys: 3.1.2 - - lodash._basecopy@3.0.1: {} - - lodash._bindcallback@3.0.1: {} - - lodash._createassigner@3.1.1: - dependencies: - lodash._bindcallback: 3.0.1 - lodash._isiterateecall: 3.0.9 - lodash.restparam: 3.6.1 - - lodash._getnative@3.9.1: {} - - lodash._isiterateecall@3.0.9: {} - - lodash.assign@3.2.0: - dependencies: - lodash._baseassign: 3.2.0 - lodash._createassigner: 3.1.1 - lodash.keys: 3.1.2 - lodash.clonedeep@4.5.0: {} - lodash.isarguments@3.1.0: {} - - lodash.isarray@3.0.4: {} - - lodash.keys@3.1.2: - dependencies: - lodash._getnative: 3.9.1 - lodash.isarguments: 3.1.0 - lodash.isarray: 3.0.4 - - lodash.restparam@3.6.1: {} - lodash@4.17.21: {} log-update@4.0.0: @@ -8288,8 +8771,6 @@ snapshots: math-intrinsics@1.1.0: {} - math-random@1.0.4: {} - mdast-util-find-and-replace@3.0.2: dependencies: '@types/mdast': 4.0.4 @@ -8417,12 +8898,8 @@ snapshots: media-typer@0.3.0: {} - media-typer@1.1.0: {} - memory-pager@1.5.0: {} - merge-descriptors@2.0.0: {} - merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -8634,15 +9111,11 @@ snapshots: mime-db@1.52.0: {} - mime-db@1.54.0: {} - mime-types@2.1.35: dependencies: mime-db: 1.52.0 - mime-types@3.0.1: - dependencies: - mime-db: 1.54.0 + mime@3.0.0: {} mime@4.1.0: {} @@ -8652,6 +9125,8 @@ snapshots: mimic-response@4.0.0: {} + mingo@7.2.0: {} + minimalistic-assert@1.0.1: {} minimalistic-crypto-utils@1.0.1: {} @@ -8733,6 +9208,8 @@ snapshots: ms@2.1.3: {} + mute-stream@1.0.0: {} + nanocolors@0.2.13: {} nanoid@3.3.11: {} @@ -8741,8 +9218,6 @@ snapshots: negotiator@0.6.3: {} - negotiator@1.0.0: {} - netmask@2.0.2: {} new-find-package-json@2.0.0: @@ -8757,18 +9232,12 @@ snapshots: node-forge@1.3.1: {} - normalize-newline@4.1.0: - dependencies: - replace-buffer: 1.2.1 - normalize-url@8.1.0: {} npm-run-path@4.0.1: dependencies: path-key: 3.1.1 - object-assign@4.1.1: {} - object-inspect@1.13.4: {} object-keys@1.1.1: {} @@ -8777,6 +9246,8 @@ snapshots: observable-fns@0.6.1: {} + omggif@1.0.10: {} + on-finished@2.4.1: dependencies: ee-first: 1.1.1 @@ -8801,6 +9272,8 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 + os-tmpdir@1.0.2: {} + p-cancelable@3.0.0: {} p-event@4.2.0: @@ -8865,6 +9338,15 @@ snapshots: dependencies: callsites: 3.1.0 + parse-bmfont-ascii@1.0.6: {} + + parse-bmfont-binary@1.0.6: {} + + parse-bmfont-xml@1.1.6: + dependencies: + xml-parse-from-string: 1.0.1 + xml2js: 0.5.0 + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.27.1 @@ -8904,7 +9386,9 @@ snapshots: pako: 1.0.11 tslib: 1.14.1 - pdf2json@3.2.0: {} + pdf2json@4.0.2: {} + + peek-readable@4.1.0: {} peek-readable@5.4.2: {} @@ -8918,10 +9402,18 @@ snapshots: ping@0.4.4: {} + pixelmatch@5.3.0: + dependencies: + pngjs: 6.0.0 + pkg-dir@4.2.0: dependencies: find-up: 4.1.0 + pngjs@6.0.0: {} + + pngjs@7.0.0: {} + pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 @@ -8932,17 +9424,14 @@ snapshots: dependencies: parse-ms: 4.0.0 + process@0.11.10: {} + progress@2.0.3: {} property-information@7.1.0: {} proto-list@1.2.4: {} - proxy-addr@2.0.7: - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - proxy-agent@6.5.0: dependencies: agent-base: 7.1.4 @@ -8963,8 +9452,6 @@ snapshots: end-of-stream: 1.4.5 once: 1.4.0 - punycode@1.4.1: {} - punycode@2.3.1: {} puppeteer-core@24.30.0: @@ -8975,7 +9462,7 @@ snapshots: devtools-protocol: 0.0.1521046 typed-query-selector: 2.12.0 webdriver-bidi-protocol: 0.3.8 - ws: 8.18.3 + ws: 8.19.0 transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -9015,14 +9502,6 @@ snapshots: quick-lru@5.1.1: {} - randomatic@3.1.1: - dependencies: - is-number: 4.0.0 - kind-of: 6.0.3 - math-random: 1.0.4 - - range-parser@1.2.1: {} - raw-body@2.5.2: dependencies: bytes: 3.1.2 @@ -9030,13 +9509,6 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - raw-body@3.0.1: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.7.0 - unpipe: 1.0.0 - rc@1.2.8: dependencies: deep-extend: 0.6.0 @@ -9052,8 +9524,22 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + readable-web-to-node-stream@3.0.4: + dependencies: + readable-stream: 4.7.0 + readdirp@4.1.2: {} + readdirp@5.0.0: {} + reflect-metadata@0.2.2: {} registry-auth-token@5.1.0: @@ -9109,8 +9595,6 @@ snapshots: mdast-util-to-markdown: 2.1.2 unified: 11.0.5 - replace-buffer@1.2.1: {} - require-directory@2.1.1: {} resolve-alpn@1.2.1: {} @@ -9139,35 +9623,27 @@ snapshots: dependencies: glob: 7.2.3 - rolldown@1.0.0-beta.51: + rolldown@1.0.0-beta.52: dependencies: - '@oxc-project/types': 0.98.0 - '@rolldown/pluginutils': 1.0.0-beta.51 + '@oxc-project/types': 0.99.0 + '@rolldown/pluginutils': 1.0.0-beta.52 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-beta.51 - '@rolldown/binding-darwin-arm64': 1.0.0-beta.51 - '@rolldown/binding-darwin-x64': 1.0.0-beta.51 - '@rolldown/binding-freebsd-x64': 1.0.0-beta.51 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.51 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.51 - '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.51 - '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.51 - '@rolldown/binding-linux-x64-musl': 1.0.0-beta.51 - '@rolldown/binding-openharmony-arm64': 1.0.0-beta.51 - '@rolldown/binding-wasm32-wasi': 1.0.0-beta.51 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.51 - '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.51 - '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.51 + '@rolldown/binding-android-arm64': 1.0.0-beta.52 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.52 + '@rolldown/binding-darwin-x64': 1.0.0-beta.52 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.52 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.52 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.52 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.52 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.52 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.52 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.52 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.52 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.52 + '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.52 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.52 - router@2.2.0: - dependencies: - debug: 4.4.3 - depd: 2.0.0 - is-promise: 4.0.0 - parseurl: 1.3.3 - path-to-regexp: 8.3.0 - transitivePeerDependencies: - - supports-color + run-async@3.0.0: {} run-parallel@1.2.0: dependencies: @@ -9205,35 +9681,12 @@ snapshots: safer-buffer@2.1.2: {} + sax@1.6.0: {} + semver@6.3.1: {} semver@7.7.3: {} - send@1.2.0: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 2.0.0 - http-errors: 2.0.0 - mime-types: 3.0.1 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - - serve-static@2.2.0: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 1.2.0 - transitivePeerDependencies: - - supports-color - set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -9247,6 +9700,37 @@ snapshots: setprototypeof@1.2.0: {} + sharp@0.34.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.7.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -9285,6 +9769,8 @@ snapshots: signal-exit@4.1.0: {} + simple-xml-to-json@1.2.4: {} + slash@3.0.0: {} slice-ansi@4.0.0: @@ -9295,47 +9781,6 @@ snapshots: smart-buffer@4.2.0: {} - socket.io-adapter@2.5.5: - dependencies: - debug: 4.3.7 - ws: 8.17.1 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - socket.io-client@4.8.1: - dependencies: - '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 - engine.io-client: 6.6.3 - socket.io-parser: 4.2.4 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - socket.io-parser@4.2.4: - dependencies: - '@socket.io/component-emitter': 3.1.2 - debug: 4.3.7 - transitivePeerDependencies: - - supports-color - - socket.io@4.8.1: - dependencies: - accepts: 1.3.8 - base64id: 2.0.0 - cors: 2.8.5 - debug: 4.3.7 - engine.io: 6.6.4 - socket.io-adapter: 2.5.5 - socket.io-parser: 4.2.4 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - socks-proxy-agent@8.0.5: dependencies: agent-base: 7.1.4 @@ -9424,8 +9869,6 @@ snapshots: strip-final-newline@2.0.0: {} - strip-indent@4.1.1: {} - strip-json-comments@2.0.1: {} strnum@1.1.2: {} @@ -9436,6 +9879,11 @@ snapshots: dependencies: '@tokenizer/token': 0.3.0 + strtok3@6.3.0: + dependencies: + '@tokenizer/token': 0.3.0 + peek-readable: 4.1.0 + strtok3@9.1.1: dependencies: '@tokenizer/token': 0.3.0 @@ -9455,6 +9903,8 @@ snapshots: systeminformation@5.27.11: {} + tagged-tag@1.0.0: {} + tar-fs@3.1.1: dependencies: pump: 3.0.3 @@ -9505,12 +9955,23 @@ snapshots: dependencies: esm: 3.2.25 + tinycolor2@1.6.0: {} + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 toidentifier@1.0.1: {} + token-types@4.2.1: + dependencies: + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + token-types@6.1.1: dependencies: '@borewit/text-codec': 0.1.1 @@ -9535,9 +9996,9 @@ snapshots: tsscmp@1.0.6: {} - tsx@4.20.6: + tsx@4.21.0: dependencies: - esbuild: 0.25.12 + esbuild: 0.27.4 get-tsconfig: 4.13.0 optionalDependencies: fsevents: 2.3.3 @@ -9554,25 +10015,19 @@ snapshots: type-fest@0.21.3: {} - type-fest@2.19.0: {} - type-fest@4.41.0: {} + type-fest@5.5.0: + dependencies: + tagged-tag: 1.0.0 + type-is@1.6.18: dependencies: media-typer: 0.3.0 mime-types: 2.1.35 - type-is@2.0.1: - dependencies: - content-type: 1.0.5 - media-typer: 1.1.0 - mime-types: 3.0.1 - typed-query-selector@2.12.0: {} - typescript@5.8.3: {} - typescript@5.9.3: {} uglify-js@3.19.3: {} @@ -9624,10 +10079,9 @@ snapshots: upper-case@1.1.3: {} - url@0.11.4: + utif2@4.1.0: dependencies: - punycode: 1.4.1 - qs: 6.14.0 + pako: 1.0.11 util-deprecate@1.0.2: {} @@ -9649,8 +10103,6 @@ snapshots: webidl-conversions@7.0.0: {} - whatwg-mimetype@3.0.0: {} - whatwg-url@14.2.0: dependencies: tr46: 5.1.1 @@ -9664,6 +10116,10 @@ snapshots: dependencies: isexe: 3.1.1 + which@6.0.1: + dependencies: + isexe: 4.0.0 + winston-transport@4.9.0: dependencies: logform: 2.7.0 @@ -9706,18 +10162,16 @@ snapshots: ws@7.5.10: {} - ws@8.17.1: {} + ws@8.19.0: {} - ws@8.18.3: {} + xml-parse-from-string@1.0.1: {} - xmlbuilder2@3.1.1: + xml2js@0.5.0: dependencies: - '@oozcitak/dom': 1.15.10 - '@oozcitak/infra': 1.0.8 - '@oozcitak/util': 8.3.8 - js-yaml: 3.14.1 + sax: 1.6.0 + xmlbuilder: 11.0.1 - xmlhttprequest-ssl@2.1.2: {} + xmlbuilder@11.0.1: {} y18n@5.0.8: {} @@ -9749,6 +10203,8 @@ snapshots: ylru@1.4.0: {} + yoctocolors-cjs@2.1.3: {} + zod@3.25.76: {} zwitch@2.0.4: {} diff --git a/readme.md b/readme.md index 8133c1d..fff644a 100644 --- a/readme.md +++ b/readme.md @@ -1,159 +1,46 @@ # @push.rocks/smartsitemap -> 🗺️ **Modern sitemap generation and management for TypeScript** — Create XML sitemaps from RSS feeds, YAML configs, or programmatically. Perfect for SEO optimization and search engine indexing. +> 🗺️ A comprehensive TypeScript sitemap library with a chainable builder API — supporting standard, news, image, video, and hreflang sitemaps with auto-splitting, streaming, validation, and RSS feed integration. + +## Issue Reporting and Security + +For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly. ## Install ```bash -# Using pnpm (recommended) pnpm install @push.rocks/smartsitemap - -# Using npm -npm install @push.rocks/smartsitemap - -# Using yarn -yarn add @push.rocks/smartsitemap ``` -## Features +## ✨ Features -✨ **Multiple Sitemap Types** -- 📰 **News Sitemaps** — Generate Google News-compatible sitemaps from RSS feeds -- 🌐 **Website Sitemaps** — Standard XML sitemaps with customizable update frequencies -- 🔄 **Dynamic Generation** — Create sitemaps from various sources (RSS, YAML, arrays) - -🚀 **Developer-Friendly** -- 💪 **Full TypeScript Support** — Complete type definitions and interfaces -- 🎯 **Simple API** — Intuitive methods for common sitemap operations -- 📦 **Zero Configuration** — Works out of the box with sensible defaults -- 🔍 **Sitemap Parsing** — Read and parse existing sitemaps from URLs - -🎨 **Flexible Input Sources** -- RSS/Atom feeds (URL or string) -- YAML configuration files -- URL info arrays -- Article objects +🔗 **Chainable Builder API** — Fluent, composable API where every method returns `this` +📰 **News Sitemaps** — Google News-compatible with proper namespace handling +🖼️ **Image Sitemaps** — Full `image:image` extension support +🎬 **Video Sitemaps** — Full `video:video` extension with all fields +🌍 **hreflang / i18n** — `xhtml:link` alternate language annotations +📑 **Sitemap Index** — Automatic splitting at 50K URLs with index generation +🌊 **Streaming** — Node.js Readable stream for million-URL sitemaps +✅ **Validation** — URL validation, size limits, spec compliance checks +📊 **Statistics** — URL counts, image/video/news counts, size estimates +📡 **RSS/Atom Feed Import** — Convert feeds to sitemaps (unique feature!) +📄 **YAML Config** — Declarative sitemap definition from YAML +🗂️ **Multi-Format Output** — XML, TXT, JSON, gzipped buffer +🎨 **XSL Stylesheets** — Browser-viewable sitemaps +🔍 **Bidirectional Parsing** — Parse existing sitemaps back into structured data +💪 **Full TypeScript** — Complete type safety with exported interfaces ## Quick Start ```typescript import { SmartSitemap } from '@push.rocks/smartsitemap'; -const sitemap = new SmartSitemap(); - -// Generate a news sitemap from RSS feed -const newsSitemap = await sitemap.createSitemapNewsFromFeedUrl( - 'https://yoursite.com/rss/' -); - -console.log(newsSitemap); -``` - -## Usage Examples - -### 📰 Creating News Sitemaps - -#### From RSS Feed URL - -Perfect for blogs, news sites, and content platforms with RSS feeds: - -```typescript -import { SmartSitemap } from '@push.rocks/smartsitemap'; - -const sitemap = new SmartSitemap(); - -// Fetch RSS feed and generate Google News sitemap -const newsSitemap = await sitemap.createSitemapNewsFromFeedUrl( - 'https://coffee.link/rss/' -); - -console.log(newsSitemap); -``` - -**Output:** -```xml - - - - https://coffee.link/article-url/ - - - en - some name - - - 2025-11-18T16:57:15.000Z - Article Title - - - -``` - -#### From RSS Feed String - -When you already have the RSS XML content: - -```typescript -import { SmartSitemap } from '@push.rocks/smartsitemap'; - -const rssFeedXml = ` - - - - -`; - -const sitemap = new SmartSitemap(); -const newsSitemap = await sitemap.createSitemapNewsFromAFeedStringArg(rssFeedXml); - -console.log(newsSitemap); -``` - -#### From Article Array - -Create news sitemaps programmatically from your CMS or database: - -```typescript -import { SmartSitemap } from '@push.rocks/smartsitemap'; -import type { IArticle } from '@tsclass/tsclass'; - -const articles: IArticle[] = [ - { - title: 'Breaking News Article', - content: 'Article content here...', - url: 'https://yoursite.com/breaking-news', - // Add other required IArticle properties - }, - // More articles... -]; - -const sitemap = new SmartSitemap(); -const newsSitemap = await sitemap.createSitemapNewsFromArticleArray(articles); - -console.log(newsSitemap); -``` - -### 🌐 Creating Website Sitemaps - -#### From YAML Configuration - -Define your sitemap structure in YAML for easy maintenance: - -```typescript -import { SmartSitemap } from '@push.rocks/smartsitemap'; - -const yamlConfig = ` -daily: - - https://yoursite.com/ - - https://yoursite.com/blog - - https://yoursite.com/products -`; - -const sitemap = new SmartSitemap(); -const websiteSitemap = await sitemap.createSitemapFromYmlString(yamlConfig); - -console.log(websiteSitemap); +// 3 lines to a valid sitemap 🚀 +const xml = SmartSitemap.create() + .addUrl('https://example.com/') + .addUrl('https://example.com/about') + .addUrl('https://example.com/blog') + .toXml(); ``` **Output:** @@ -161,272 +48,401 @@ console.log(websiteSitemap); - https://yoursite.com/ - 2025-11-19T12:00:00.000Z - daily + https://example.com/ + + + https://example.com/about + + + https://example.com/blog - ``` -#### From URL Info Array +## Usage -Fine-grained control over each URL's properties: - -```typescript -import { SmartSitemap, IUrlInfo } from '@push.rocks/smartsitemap'; - -const urlInfos: IUrlInfo[] = [ - { - url: 'https://yoursite.com/', - timestamp: Date.now(), - frequency: 'daily', // How often the page changes - }, - { - url: 'https://yoursite.com/about', - timestamp: Date.now() - 86400000, // Yesterday - frequency: 'monthly', - }, - { - url: 'https://yoursite.com/blog', - timestamp: Date.now(), - frequency: 'weekly', - }, -]; - -const sitemap = new SmartSitemap(); -const websiteSitemap = await sitemap.createSitemapFromUrlInfoArray(urlInfos); - -console.log(websiteSitemap); -``` - -**Available Frequencies:** -- `'never'` — Archived content -- `'daily'` — Updated every day -- `'weekly'` — Updated weekly -- `'monthly'` — Updated monthly -- `'yearly'` — Updated annually - -### 🔍 Parsing Existing Sitemaps - -Read and parse sitemaps from remote URLs: +### 🌐 Standard Sitemap with Full Control ```typescript import { SmartSitemap } from '@push.rocks/smartsitemap'; -const sitemap = new SmartSitemap(); +const xml = SmartSitemap.create({ baseUrl: 'https://example.com' }) + .setDefaultChangeFreq('weekly') + .setDefaultPriority(0.5) + .setXslUrl('/sitemap.xsl') + .add({ + loc: 'https://example.com/', + changefreq: 'daily', + priority: 1.0, + lastmod: new Date(), + }) + .add({ + loc: 'https://example.com/products', + changefreq: 'daily', + priority: 0.9, + images: [ + { loc: 'https://example.com/img/product1.jpg', title: 'Product 1' }, + ], + }) + .add({ + loc: 'https://example.com/blog/post-1', + lastmod: '2025-01-15', + alternates: [ + { hreflang: 'de', href: 'https://example.com/de/blog/post-1' }, + { hreflang: 'fr', href: 'https://example.com/fr/blog/post-1' }, + ], + }) + .toXml(); +``` -// Parse a sitemap from URL -const parsedSitemap = await sitemap.parseSitemapUrl( - 'https://www.theverge.com/sitemaps/google_news' -); +### 🔗 Builder from a URL Array -console.log(parsedSitemap); +```typescript +const builder = SmartSitemap.fromUrls([ + 'https://example.com/', + 'https://example.com/about', + 'https://example.com/contact', +]); + +const xml = builder + .setDefaultChangeFreq('monthly') + .toXml(); +``` + +### 📰 News Sitemap + +```typescript +const xml = SmartSitemap.createNews({ + publicationName: 'The Daily Tech', + publicationLanguage: 'en', +}) + .addNewsUrl( + 'https://example.com/news/breaking-story', + 'Breaking: TypeScript 6.0 Released!', + new Date(), + ['typescript', 'programming'], + ) + .addNewsUrl( + 'https://example.com/news/another-story', + 'Node.js Gets Even Faster', + new Date(), + ) + .toXml(); +``` + +### 📰 News Sitemap from RSS Feed + +This is smartsitemap's killer feature — no other sitemap library does this: + +```typescript +// From a feed URL +const builder = SmartSitemap.createNews({ + publicationName: 'The Daily Tech', + publicationLanguage: 'en', +}); +await builder.importFromFeedUrl('https://thedailytech.com/rss/'); +const xml = builder.toXml(); + +// Or as a one-liner with the static factory +const feedBuilder = await SmartSitemap.fromFeedUrl('https://example.com/rss/'); +const feedXml = feedBuilder.toXml(); +``` + +### 📰 News Sitemap from Articles + +Works seamlessly with `@tsclass/tsclass` `IArticle` objects from your CMS: + +```typescript +import type { content } from '@tsclass/tsclass'; + +const articles: content.IArticle[] = [/* from your CMS or database */]; + +const xml = SmartSitemap.fromArticles(articles, { + publicationName: 'My Publication', + publicationLanguage: 'en', +}).toXml(); +``` + +### 🖼️ Image Sitemap + +```typescript +const xml = SmartSitemap.create() + .add({ + loc: 'https://example.com/gallery', + images: [ + { loc: 'https://example.com/img/photo1.jpg', title: 'Sunset' }, + { loc: 'https://example.com/img/photo2.jpg', caption: 'Mountain view' }, + ], + }) + .toXml(); +``` + +### 🎬 Video Sitemap + +```typescript +const xml = SmartSitemap.create() + .add({ + loc: 'https://example.com/videos/tutorial', + videos: [ + { + thumbnailLoc: 'https://example.com/thumb.jpg', + title: 'Getting Started with TypeScript', + description: 'A comprehensive guide to TypeScript for beginners.', + contentLoc: 'https://example.com/video.mp4', + duration: 600, + rating: 4.8, + publicationDate: new Date(), + tags: ['typescript', 'tutorial', 'programming'], + }, + ], + }) + .toXml(); +``` + +### 🌍 hreflang / Internationalization + +```typescript +const xml = SmartSitemap.create() + .add({ + loc: 'https://example.com/page', + alternates: [ + { hreflang: 'en', href: 'https://example.com/page' }, + { hreflang: 'de', href: 'https://example.com/de/page' }, + { hreflang: 'fr', href: 'https://example.com/fr/page' }, + { hreflang: 'x-default', href: 'https://example.com/page' }, + ], + }) + .toXml(); +``` + +### 📑 Automatic Sitemap Index Splitting + +When you exceed 50K URLs, smartsitemap automatically splits into a sitemap index: + +```typescript +const builder = SmartSitemap.create({ + baseUrl: 'https://example.com', + maxUrlsPerSitemap: 45000, // default is 50000 +}); + +// Add hundreds of thousands of URLs +for (const page of allPages) { + builder.addUrl(page.url, page.lastModified); +} + +const set = builder.toSitemapSet(); +// set.needsIndex === true +// set.indexXml → '...' +// set.sitemaps → [ +// { filename: 'sitemap-1.xml', xml: '...' }, +// { filename: 'sitemap-2.xml', xml: '...' }, +// { filename: 'sitemap-3.xml', xml: '...' }, +// ] + +// Or build an index manually +const index = SmartSitemap.createIndex() + .addSitemap('https://example.com/sitemap-blog.xml') + .addSitemap('https://example.com/sitemap-products.xml', new Date()) + .toXml(); +``` + +### 🌊 Streaming for Large Sitemaps + +For sitemaps with millions of URLs that can't fit in memory: + +```typescript +import { createWriteStream } from 'fs'; +import { createGzip } from 'zlib'; +import { SitemapStream } from '@push.rocks/smartsitemap'; + +const stream = new SitemapStream(); +const output = createWriteStream('/var/www/sitemap.xml.gz'); +stream.pipe(createGzip()).pipe(output); + +// Stream URLs from a database cursor +for await (const page of databaseCursor()) { + stream.pushUrl({ + loc: page.url, + lastmod: page.updatedAt, + changefreq: 'weekly', + }); +} + +stream.finish(); +``` + +### 🔀 Merge, Dedupe, Filter & Sort + +Combine multiple sitemap sources with powerful collection operations: + +```typescript +const blogSitemap = SmartSitemap.create() + .setDefaultChangeFreq('weekly') + .addFromArray(blogUrls); + +const productSitemap = SmartSitemap.create() + .setDefaultChangeFreq('daily') + .addFromArray(productUrls); + +const xml = SmartSitemap.create() + .merge(blogSitemap) + .merge(productSitemap) + .dedupe() + .filter(url => !url.loc.includes('/deprecated/')) + .sort((a, b) => a.loc.localeCompare(b.loc)) + .toXml(); +``` + +### 📄 YAML Configuration + +Define sitemaps declaratively: + +```typescript +const yaml = ` +baseUrl: https://example.com +defaults: + priority: 0.5 +urls: + daily: + - / + - /blog + weekly: + - /docs + - /tutorials + monthly: + - /about + - /contact + yearly: + - /privacy + - /terms +`; + +const builder = await SmartSitemap.fromYaml(yaml); +const xml = builder.toXml(); +``` + +### ✅ Validation + +Catch errors before they reach search engines: + +```typescript +const result = SmartSitemap.create() + .addUrl('not-a-valid-url') + .add({ loc: 'https://example.com/', priority: 1.5 }) // out of range + .validate(); + +console.log(result.valid); // false +console.log(result.errors); +// [ +// { field: 'loc', message: 'Invalid URL: "not-a-valid-url"', url: 'not-a-valid-url' }, +// { field: 'priority', message: 'Priority must be between 0.0 and 1.0', url: 'https://example.com/' }, +// ] +``` + +### 📊 Statistics + +Get insight into your sitemap: + +```typescript +const stats = SmartSitemap.create() + .addUrl('https://example.com/') + .add({ loc: 'https://example.com/gallery', images: [{ loc: '/img/1.jpg' }] }) + .stats(); + +console.log(stats); // { -// urlset: { -// url: [ -// { loc: '...', lastmod: '...', changefreq: '...' }, -// // ... -// ] -// } +// urlCount: 2, +// imageCount: 1, +// videoCount: 0, +// newsCount: 0, +// alternateCount: 0, +// estimatedSizeBytes: 750, +// needsIndex: false, // } ``` -#### Parse Sitemap String +### 🗂️ Multi-Format Output -If you already have the sitemap XML: +```typescript +const builder = SmartSitemap.create() + .addUrl('https://example.com/') + .addUrl('https://example.com/about'); + +// XML (default) +const xml = builder.toXml(); + +// Plain text (one URL per line) +const txt = builder.toTxt(); +// "https://example.com/\nhttps://example.com/about" + +// JSON +const json = builder.toJson(); + +// Gzipped XML buffer (for serving compressed) +const gzipped = await builder.toGzipBuffer(); +``` + +### 🔍 Parse Existing Sitemaps + +Read and parse sitemaps back into structured data: + +```typescript +// From URL +const parsed = await SmartSitemap.parseUrl('https://example.com/sitemap.xml'); +console.log(parsed.type); // 'urlset' or 'sitemapindex' +console.log(parsed.urls); // ISitemapUrl[] + +// From XML string +const result = await SmartSitemap.parse(sitemapXmlString); + +// Parse and get a pre-populated builder for modification +const builder = await SitemapParser.toBuilder(existingSitemapXml); +builder + .addUrl('https://example.com/new-page') + .filter(url => !url.loc.includes('/old/')) + .toXml(); + +// Detect type without full parsing +SitemapParser.detectType(''); // 'urlset' +SitemapParser.detectType(''); // 'sitemapindex' +``` + +## 🏗️ Real-World Integration Examples + +### Express.js / Hono / Fastify Server ```typescript import { SmartSitemap } from '@push.rocks/smartsitemap'; -const sitemapXml = ` - - - - -`; - -const sitemap = new SmartSitemap(); -const parsed = await sitemap.parseSitemap(sitemapXml); - -console.log(parsed); -``` - -## Advanced Usage - -### Working with Lower-Level Classes - -For more control, use the individual sitemap classes directly: - -#### SitemapWebsite Class - -```typescript -import { SitemapWebsite, IUrlInfo } from '@push.rocks/smartsitemap'; - -const websiteSitemap = new SitemapWebsite(); - -// Add URLs one by one -websiteSitemap.addUrl({ - url: 'https://yoursite.com/page1', - timestamp: Date.now(), - frequency: 'daily', -}); - -websiteSitemap.addUrl({ - url: 'https://yoursite.com/page2', - timestamp: Date.now(), - frequency: 'weekly', -}); - -// Export to XML -const xml = websiteSitemap.exportSitemapXml(); -console.log(xml); -``` - -#### SitemapNews Class - -```typescript -import { SitemapNews } from '@push.rocks/smartsitemap'; - -const newsSitemap = new SitemapNews({}); - -// Add from RSS feed URL -await newsSitemap.readAndAddFromRssFeedUrl('https://yoursite.com/rss'); - -// Or from RSS string -await newsSitemap.readAndAddFromRssFeedString(rssFeedXml); - -// Or from articles -await newsSitemap.readAndParseArticles(articles); - -// Export to XML -const xml = newsSitemap.exportSitemapXml(); -console.log(xml); -``` - -### Combining Multiple Sources - -Create comprehensive sitemaps by combining different data sources: - -```typescript -import { SitemapWebsite } from '@push.rocks/smartsitemap'; - -const sitemap = new SitemapWebsite(); - -// Add static pages -sitemap.addUrl({ - url: 'https://yoursite.com/', - timestamp: Date.now(), - frequency: 'daily', -}); - -// Add dynamic content from database -const blogPosts = await fetchBlogPostsFromDB(); -for (const post of blogPosts) { - sitemap.addUrl({ - url: post.url, - timestamp: post.updatedAt, - frequency: 'weekly', - }); -} - -// Add pages from CMS -const cmsPages = await fetchPagesFromCMS(); -for (const page of cmsPages) { - sitemap.addUrl({ - url: page.url, - timestamp: page.lastModified, - frequency: page.updateFrequency, - }); -} - -const xml = sitemap.exportSitemapXml(); -``` - -## TypeScript Types - -### IUrlInfo - -```typescript -interface IUrlInfo { - url: string; - timestamp: number; // Unix timestamp in milliseconds - frequency?: TUpdateFrequency; -} - -type TUpdateFrequency = 'never' | 'daily' | 'weekly' | 'monthly' | 'yearly'; -``` - -### IParsedSiteMap - -```typescript -interface IParsedSiteMap { - urlset: { - url: - | { loc: string; lastmod: string; changefreq: string } - | { loc: string; lastmod: string; changefreq: string }[] - | { - loc: string; - 'news:news': { - 'news:publication': []; - 'news:keywords': string; - 'news:publication_date': string; - 'news:title': string; - }; - }[]; - }; -} -``` - -### IRssItem - -```typescript -interface IRssItem { - [key: string]: any; - link?: string; - guid?: string; - title?: string; - pubDate?: string; - creator?: string; - content?: string; - isoDate?: string; - categories?: string[]; - contentSnippet?: string; - enclosure?: any; -} -``` - -## Real-World Integration Examples - -### Express.js Server - -```typescript -import express from 'express'; -import { SmartSitemap } from '@push.rocks/smartsitemap'; - -const app = express(); -const sitemap = new SmartSitemap(); - -// Serve sitemap dynamically +// Serve dynamic sitemap app.get('/sitemap.xml', async (req, res) => { - const urlInfos = await getUrlsFromDatabase(); - const xml = await sitemap.createSitemapFromUrlInfoArray(urlInfos); + const xml = SmartSitemap.create() + .setDefaultChangeFreq('weekly') + .addFromArray(await getUrlsFromDatabase()) + .toXml(); res.header('Content-Type', 'application/xml'); res.send(xml); }); -// News sitemap from RSS +// Serve news sitemap from RSS app.get('/news-sitemap.xml', async (req, res) => { - const xml = await sitemap.createSitemapNewsFromFeedUrl( - 'https://yoursite.com/rss' - ); + const builder = SmartSitemap.createNews({ publicationName: 'My Site' }); + await builder.importFromFeedUrl('https://mysite.com/rss/'); res.header('Content-Type', 'application/xml'); - res.send(xml); + res.send(builder.toXml()); }); -app.listen(3000); +// Auto-split with sitemap index +app.get('/sitemap-index.xml', async (req, res) => { + const builder = SmartSitemap.create({ baseUrl: 'https://mysite.com' }); + builder.addFromArray(await getAllUrls()); // 200K+ URLs + + const set = builder.toSitemapSet(); + res.header('Content-Type', 'application/xml'); + res.send(set.indexXml ?? set.sitemaps[0].xml); +}); ``` ### Static Site Generator @@ -435,294 +451,139 @@ app.listen(3000); import { SmartSitemap } from '@push.rocks/smartsitemap'; import { writeFileSync } from 'fs'; -async function generateSitemap() { - const sitemap = new SmartSitemap(); +const xml = SmartSitemap.create() + .setDefaultChangeFreq('weekly') + .add({ loc: 'https://mysite.com/', changefreq: 'daily', priority: 1.0 }) + .add({ loc: 'https://mysite.com/about', changefreq: 'monthly' }) + .addFromArray(blogPostUrls) + .dedupe() + .toXml(); - // Get all pages from your static site - const pages = [ - { url: 'https://yoursite.com/', frequency: 'daily' as const }, - { url: 'https://yoursite.com/about', frequency: 'monthly' as const }, - // ... more pages - ]; - - const urlInfos = pages.map(page => ({ - url: page.url, - timestamp: Date.now(), - frequency: page.frequency, - })); - - const xml = await sitemap.createSitemapFromUrlInfoArray(urlInfos); - - // Write to public directory - writeFileSync('./public/sitemap.xml', xml); - console.log('✅ Sitemap generated!'); -} - -generateSitemap(); -``` - -### Content Management System - -```typescript -import { SmartSitemap, IUrlInfo } from '@push.rocks/smartsitemap'; - -class CMSSitemapGenerator { - private sitemap = new SmartSitemap(); - - async generateCompleteSitemap(): Promise { - const urlInfos: IUrlInfo[] = []; - - // Add all content types - urlInfos.push(...await this.getPageUrls()); - urlInfos.push(...await this.getBlogUrls()); - urlInfos.push(...await this.getProductUrls()); - - return this.sitemap.createSitemapFromUrlInfoArray(urlInfos); - } - - private async getPageUrls(): Promise { - const pages = await this.cms.getPages(); - return pages.map(page => ({ - url: page.url, - timestamp: page.updatedAt, - frequency: 'weekly', - })); - } - - private async getBlogUrls(): Promise { - const posts = await this.cms.getBlogPosts(); - return posts.map(post => ({ - url: post.url, - timestamp: post.publishedAt, - frequency: 'monthly', - })); - } - - private async getProductUrls(): Promise { - const products = await this.cms.getProducts(); - return products.map(product => ({ - url: product.url, - timestamp: product.lastModified, - frequency: 'daily', - })); - } -} -``` - -## Best Practices - -### 1. Update Frequencies - -Choose appropriate update frequencies for better crawling: - -```typescript -// Homepage and main sections: daily -{ url: 'https://yoursite.com/', frequency: 'daily' } - -// Blog posts: weekly -{ url: 'https://yoursite.com/blog/post', frequency: 'weekly' } - -// Static pages: monthly or yearly -{ url: 'https://yoursite.com/about', frequency: 'monthly' } - -// Archived content: never -{ url: 'https://yoursite.com/archive/2020', frequency: 'never' } -``` - -### 2. Sitemap Size Limits - -Google recommends keeping sitemaps under 50,000 URLs and 50MB. Split large sitemaps: - -```typescript -import { SitemapWebsite } from '@push.rocks/smartsitemap'; - -async function generateSitemaps(allUrls: IUrlInfo[]) { - const chunkSize = 50000; - const chunks = []; - - for (let i = 0; i < allUrls.length; i += chunkSize) { - chunks.push(allUrls.slice(i, i + chunkSize)); - } - - const sitemaps = await Promise.all( - chunks.map(async (chunk, index) => { - const sitemap = new SitemapWebsite(); - chunk.forEach(url => sitemap.addUrl(url)); - const xml = sitemap.exportSitemapXml(); - - // Save as sitemap-1.xml, sitemap-2.xml, etc. - return { filename: `sitemap-${index + 1}.xml`, content: xml }; - }) - ); - - return sitemaps; -} -``` - -### 3. Cache Generated Sitemaps - -Don't regenerate on every request: - -```typescript -import { SmartSitemap } from '@push.rocks/smartsitemap'; - -class SitemapCache { - private cache: string | null = null; - private lastGenerated: number = 0; - private cacheDuration = 3600000; // 1 hour - - async getSitemap(): Promise { - const now = Date.now(); - - if (!this.cache || now - this.lastGenerated > this.cacheDuration) { - const sitemap = new SmartSitemap(); - const urls = await this.fetchUrls(); - this.cache = await sitemap.createSitemapFromUrlInfoArray(urls); - this.lastGenerated = now; - } - - return this.cache; - } - - invalidate() { - this.cache = null; - } - - private async fetchUrls() { - // Fetch from your data source - return []; - } -} -``` - -### 4. Submit to Search Engines - -After generating your sitemap, submit it to search engines: - -```typescript -// In your robots.txt -` -User-agent: * -Allow: / -Sitemap: https://yoursite.com/sitemap.xml -Sitemap: https://yoursite.com/news-sitemap.xml -` -``` - -Or ping search engines programmatically: - -```typescript -async function submitSitemap(sitemapUrl: string) { - const encodedUrl = encodeURIComponent(sitemapUrl); - - // Google - await fetch(`https://www.google.com/ping?sitemap=${encodedUrl}`); - - // Bing - await fetch(`https://www.bing.com/ping?sitemap=${encodedUrl}`); -} - -submitSitemap('https://yoursite.com/sitemap.xml'); +writeFileSync('./public/sitemap.xml', xml); ``` ## API Reference -### SmartSitemap +### SmartSitemap (Static Factories) -Main class for sitemap operations. +| Method | Returns | Description | +|--------|---------|-------------| +| `SmartSitemap.create(options?)` | `UrlsetBuilder` | Create a standard sitemap builder | +| `SmartSitemap.createNews(options)` | `NewsSitemapBuilder` | Create a news sitemap builder | +| `SmartSitemap.createIndex(options?)` | `SitemapIndexBuilder` | Create a sitemap index builder | +| `SmartSitemap.fromUrls(urls, options?)` | `UrlsetBuilder` | Builder from URL string array | +| `SmartSitemap.fromYaml(yaml)` | `Promise` | Builder from YAML config | +| `SmartSitemap.fromFeedUrl(url, options?)` | `Promise` | Builder from RSS/Atom feed URL | +| `SmartSitemap.fromFeedString(xml, options?)` | `Promise` | Builder from RSS/Atom feed string | +| `SmartSitemap.fromArticles(articles, options)` | `NewsSitemapBuilder` | Builder from IArticle array | +| `SmartSitemap.parse(xml)` | `Promise` | Parse sitemap XML string | +| `SmartSitemap.parseUrl(url)` | `Promise` | Fetch and parse sitemap | +| `SmartSitemap.validate(xml)` | `Promise` | Validate sitemap XML | -#### Methods +### UrlsetBuilder (Chainable) -**`createSitemapNewsFromFeedUrl(feedUrl: string): Promise`** -- Generate a Google News sitemap from an RSS/Atom feed URL -- Returns XML string +| Method | Returns | Description | +|--------|---------|-------------| +| `.add(url)` | `this` | Add a URL with full `ISitemapUrl` options | +| `.addUrl(loc, lastmod?)` | `this` | Add by URL string | +| `.addUrls(urls)` | `this` | Add multiple `ISitemapUrl` objects | +| `.addFromArray(locs)` | `this` | Add from plain string array | +| `.merge(other)` | `this` | Merge in another builder's URLs | +| `.filter(predicate)` | `this` | Filter URLs in-place | +| `.map(transform)` | `this` | Transform URLs in-place | +| `.sort(compareFn?)` | `this` | Sort URLs (default: alphabetical) | +| `.dedupe()` | `this` | Remove duplicate URLs by loc | +| `.setDefaultChangeFreq(freq)` | `this` | Set default changefreq | +| `.setDefaultPriority(priority)` | `this` | Set default priority (0.0–1.0) | +| `.setXslUrl(url)` | `this` | Set XSL stylesheet URL | +| `.importFromFeedUrl(url, options?)` | `Promise` | Import from RSS/Atom feed URL | +| `.importFromFeedString(xml, options?)` | `Promise` | Import from RSS/Atom feed string | +| `.importFromYaml(yaml)` | `Promise` | Import from YAML config | +| `.importFromArticles(articles)` | `this` | Import from IArticle array | +| `.toXml()` | `string` | Export as sitemap XML | +| `.toTxt()` | `string` | Export as plain text | +| `.toJson()` | `string` | Export as JSON | +| `.toGzipBuffer()` | `Promise` | Export as gzipped XML | +| `.toSitemapSet()` | `ISitemapSet` | Auto-split with index | +| `.toStream()` | `SitemapStream` | Export as Node.js Readable stream | +| `.validate()` | `IValidationResult` | Validate against spec | +| `.stats()` | `ISitemapStats` | Get statistics | +| `.getUrls()` | `ISitemapUrl[]` | Get the raw URL array | +| `.count` | `number` | Get URL count | -**`createSitemapNewsFromAFeedStringArg(feedString: string): Promise`** -- Generate a Google News sitemap from RSS/Atom feed XML string -- Returns XML string +### NewsSitemapBuilder (extends UrlsetBuilder) -**`createSitemapNewsFromArticleArray(articles: IArticle[]): Promise`** -- Generate a Google News sitemap from an array of article objects -- Returns XML string +| Method | Returns | Description | +|--------|---------|-------------| +| `.addNewsUrl(loc, title, date, keywords?)` | `this` | Add a news article with publication info | -**`createSitemapFromYmlString(yamlString: string): Promise`** -- Generate a standard sitemap from YAML configuration -- Returns XML string +### SitemapIndexBuilder -**`createSitemapFromUrlInfoArray(urlInfos: IUrlInfo[]): Promise`** -- Generate a standard sitemap from URL info array -- Returns XML string +| Method | Returns | Description | +|--------|---------|-------------| +| `.add(entry)` | `this` | Add a sitemap index entry | +| `.addSitemap(loc, lastmod?)` | `this` | Add by URL string | +| `.addSitemaps(entries)` | `this` | Add multiple entries | +| `SitemapIndexBuilder.fromBuilder(builder, baseUrl)` | `{index, sitemaps[]}` | Auto-split a builder | +| `.toXml()` | `string` | Export as sitemap index XML | +| `.count` | `number` | Get entry count | -**`parseSitemapUrl(url: string): Promise`** -- Parse a sitemap from a URL -- Returns parsed sitemap object +### SitemapStream -**`parseSitemap(sitemapXml: string): Promise`** -- Parse a sitemap from XML string -- Returns parsed sitemap object +| Method | Description | +|--------|-------------| +| `.pushUrl(url)` | Push a URL entry to the stream | +| `.finish()` | Signal end of stream, writes closing tag | +| `.count` | Number of URLs written | -### SitemapWebsite +### Key Types -Lower-level class for website sitemaps. +```typescript +interface ISitemapUrl { + loc: string; // Required — absolute URL + lastmod?: Date | string | number; // Date, ISO string, or timestamp (ms) + changefreq?: TChangeFreq; // 'always'|'hourly'|'daily'|'weekly'|'monthly'|'yearly'|'never' + priority?: number; // 0.0 to 1.0 + images?: ISitemapImage[]; // Image extension + videos?: ISitemapVideo[]; // Video extension + news?: ISitemapNews; // News extension + alternates?: ISitemapAlternate[]; // hreflang alternates +} -#### Methods +interface ISitemapOptions { + baseUrl?: string; + xslUrl?: string; + defaultChangeFreq?: TChangeFreq; + defaultPriority?: number; + prettyPrint?: boolean; // default: true + maxUrlsPerSitemap?: number; // default: 50000 + gzip?: boolean; + validate?: boolean; // default: true +} -**`addUrl(urlInfo: IUrlInfo): void`** -- Add a URL to the sitemap - -**`exportSitemapXml(): string`** -- Export sitemap as XML string - -### SitemapNews - -Lower-level class for news sitemaps. - -#### Methods - -**`readAndAddFromRssFeedUrl(url: string): Promise`** -- Add news items from RSS feed URL - -**`readAndAddFromRssFeedString(feedString: string): Promise`** -- Add news items from RSS feed string - -**`readAndParseArticles(articles: IArticle[]): Promise`** -- Add news items from article array - -**`exportSitemapXml(): string`** -- Export news sitemap as XML string - -## Why @push.rocks/smartsitemap? - -- ✅ **Simple & Intuitive** — Clean API that just works -- ✅ **Type-Safe** — Full TypeScript support with complete type definitions -- ✅ **Flexible** — Multiple input sources and output formats -- ✅ **Battle-Tested** — Used in production across multiple projects -- ✅ **Modern** — ESM-first, async/await, latest standards -- ✅ **SEO-Friendly** — Generates valid XML sitemaps that search engines love - -## Related Packages - -Part of the `@push.rocks` ecosystem: - -- **[@push.rocks/smartfeed](https://www.npmjs.com/package/@push.rocks/smartfeed)** — RSS/Atom feed parsing -- **[@push.rocks/smartxml](https://www.npmjs.com/package/@push.rocks/smartxml)** — XML parsing and generation -- **[@push.rocks/smartyaml](https://www.npmjs.com/package/@push.rocks/smartyaml)** — YAML parsing +interface INewsSitemapOptions extends ISitemapOptions { + publicationName: string; // Required + publicationLanguage?: string; // default: 'en' +} +``` ## License and Legal Information -This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. +This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file. **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file. ### Trademarks -This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH. +This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein. + +Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar. ### Company Information Task Venture Capital GmbH -Registered at District court Bremen HRB 35230 HB, Germany +Registered at District Court Bremen HRB 35230 HB, Germany -For any legal inquiries or if you require further information, please contact us via email at hello@task.vc. +For any legal inquiries or further information, please contact us via email at hello@task.vc. By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works. diff --git a/test/test.ts b/test/test.ts index ef7ff73..d017092 100644 --- a/test/test.ts +++ b/test/test.ts @@ -1,25 +1,484 @@ import { expect, tap } from '@push.rocks/tapbundle'; import * as smartsitemap from '../ts/index.js'; -let testSmartsitemap: smartsitemap.SmartSitemap; +// ────────────────────────────────────────────── +// Basic builder tests +// ────────────────────────────────────────────── -tap.test('should create an instance of Smartsitemap', async () => { - testSmartsitemap = new smartsitemap.SmartSitemap(); - expect(testSmartsitemap).toBeInstanceOf(smartsitemap.SmartSitemap); +tap.test('SmartSitemap.create() should return a UrlsetBuilder', async () => { + const builder = smartsitemap.SmartSitemap.create(); + expect(builder).toBeInstanceOf(smartsitemap.UrlsetBuilder); }); -tap.test('should create a sitemap from feed', async () => { - const sitemapString = await testSmartsitemap.createSitemapNewsFromFeedUrl( - 'https://coffee.link/rss/', - ); - console.log(sitemapString); +tap.test('should create a basic sitemap with addUrl()', async () => { + const xml = smartsitemap.SmartSitemap.create() + .addUrl('https://example.com/') + .addUrl('https://example.com/about') + .addUrl('https://example.com/blog') + .toXml(); + + expect(xml).toInclude(''); + expect(xml).toInclude('https://example.com/'); + expect(xml).toInclude('https://example.com/about'); + expect(xml).toInclude('https://example.com/blog'); }); -tap.test('should parse a sitemap', async () => { - const result = await testSmartsitemap.parseSitemapUrl( - 'https://www.theverge.com/sitemaps/google_news', - ); - // console.log(result.urlset.url); +tap.test('should apply default changefreq and priority', async () => { + const xml = smartsitemap.SmartSitemap.create() + .setDefaultChangeFreq('weekly') + .setDefaultPriority(0.5) + .addUrl('https://example.com/') + .toXml(); + + expect(xml).toInclude('weekly'); + expect(xml).toInclude('0.5'); }); -tap.start(); +tap.test('should support per-URL changefreq and priority override', async () => { + const xml = smartsitemap.SmartSitemap.create() + .setDefaultChangeFreq('weekly') + .setDefaultPriority(0.5) + .add({ + loc: 'https://example.com/', + changefreq: 'daily', + priority: 1.0, + }) + .toXml(); + + expect(xml).toInclude('daily'); + expect(xml).toInclude('1.0'); + expect(xml).not.toInclude('weekly'); +}); + +tap.test('should support lastmod as Date, string, and number', async () => { + const date = new Date('2025-06-15T00:00:00.000Z'); + const xml = smartsitemap.SmartSitemap.create() + .addUrl('https://example.com/a', date) + .addUrl('https://example.com/b', '2025-06-15') + .addUrl('https://example.com/c', date.getTime()) + .toXml(); + + expect(xml).toInclude('2025-06-15T00:00:00.000Z'); +}); + +// ────────────────────────────────────────────── +// URL escaping +// ────────────────────────────────────────────── + +tap.test('should escape XML special characters in URLs', async () => { + const xml = smartsitemap.SmartSitemap.create() + .addUrl('https://example.com/search?q=foo&bar=baz') + .toXml(); + + expect(xml).toInclude('&'); + expect(xml).not.toInclude('&bar=baz'); +}); + +// ────────────────────────────────────────────── +// Image extension +// ────────────────────────────────────────────── + +tap.test('should generate image sitemap extension', async () => { + const xml = smartsitemap.SmartSitemap.create() + .add({ + loc: 'https://example.com/gallery', + images: [ + { loc: 'https://example.com/img/photo1.jpg', title: 'Photo 1' }, + { loc: 'https://example.com/img/photo2.jpg', caption: 'A nice photo' }, + ], + }) + .toXml(); + + expect(xml).toInclude('xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"'); + expect(xml).toInclude(''); + expect(xml).toInclude('https://example.com/img/photo1.jpg'); + expect(xml).toInclude('Photo 1'); + expect(xml).toInclude('A nice photo'); +}); + +// ────────────────────────────────────────────── +// Video extension +// ────────────────────────────────────────────── + +tap.test('should generate video sitemap extension', async () => { + const xml = smartsitemap.SmartSitemap.create() + .add({ + loc: 'https://example.com/video-page', + videos: [ + { + thumbnailLoc: 'https://example.com/thumb.jpg', + title: 'My Video', + description: 'A great video about testing.', + contentLoc: 'https://example.com/video.mp4', + duration: 120, + rating: 4.5, + }, + ], + }) + .toXml(); + + expect(xml).toInclude('xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"'); + expect(xml).toInclude(''); + expect(xml).toInclude('https://example.com/thumb.jpg'); + expect(xml).toInclude('My Video'); + expect(xml).toInclude('120'); + expect(xml).toInclude('4.5'); +}); + +// ────────────────────────────────────────────── +// News extension +// ────────────────────────────────────────────── + +tap.test('should generate news sitemap', async () => { + const xml = smartsitemap.SmartSitemap.createNews({ + publicationName: 'The Daily Test', + publicationLanguage: 'en', + }) + .addNewsUrl( + 'https://example.com/news/article-1', + 'Breaking: Tests Pass!', + new Date('2025-06-15T12:00:00Z'), + ['testing', 'CI'], + ) + .toXml(); + + expect(xml).toInclude('xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"'); + expect(xml).toInclude(''); + expect(xml).toInclude('The Daily Test'); + expect(xml).toInclude('en'); + expect(xml).toInclude('Breaking: Tests Pass!'); + expect(xml).toInclude('testing, CI'); + expect(xml).toInclude(''); +}); + +// ────────────────────────────────────────────── +// hreflang alternates +// ────────────────────────────────────────────── + +tap.test('should generate hreflang alternate links', async () => { + const xml = smartsitemap.SmartSitemap.create() + .add({ + loc: 'https://example.com/page', + alternates: [ + { hreflang: 'en', href: 'https://example.com/page' }, + { hreflang: 'de', href: 'https://example.com/de/page' }, + { hreflang: 'x-default', href: 'https://example.com/page' }, + ], + }) + .toXml(); + + expect(xml).toInclude('xmlns:xhtml="http://www.w3.org/1999/xhtml"'); + expect(xml).toInclude('xhtml:link'); +}); + +// ────────────────────────────────────────────── +// XSL stylesheet +// ────────────────────────────────────────────── + +tap.test('should include XSL stylesheet processing instruction', async () => { + const xml = smartsitemap.SmartSitemap.create() + .setXslUrl('/sitemap.xsl') + .addUrl('https://example.com/') + .toXml(); + + expect(xml).toInclude(''); +}); + +// ────────────────────────────────────────────── +// Builder operations: fromUrls, merge, dedupe, filter, sort +// ────────────────────────────────────────────── + +tap.test('SmartSitemap.fromUrls() should create builder from string array', async () => { + const builder = smartsitemap.SmartSitemap.fromUrls([ + 'https://example.com/a', + 'https://example.com/b', + ]); + expect(builder.count).toEqual(2); +}); + +tap.test('should merge two builders', async () => { + const a = smartsitemap.SmartSitemap.create().addUrl('https://example.com/a'); + const b = smartsitemap.SmartSitemap.create().addUrl('https://example.com/b'); + const merged = smartsitemap.SmartSitemap.create().merge(a).merge(b); + expect(merged.count).toEqual(2); +}); + +tap.test('should deduplicate URLs', async () => { + const builder = smartsitemap.SmartSitemap.create() + .addUrl('https://example.com/a') + .addUrl('https://example.com/a') + .addUrl('https://example.com/b') + .dedupe(); + expect(builder.count).toEqual(2); +}); + +tap.test('should filter URLs', async () => { + const builder = smartsitemap.SmartSitemap.create() + .addUrl('https://example.com/keep') + .addUrl('https://example.com/remove') + .filter((url) => !url.loc.includes('remove')); + expect(builder.count).toEqual(1); + expect(builder.getUrls()[0].loc).toEqual('https://example.com/keep'); +}); + +tap.test('should sort URLs', async () => { + const builder = smartsitemap.SmartSitemap.create() + .addUrl('https://example.com/z') + .addUrl('https://example.com/a') + .addUrl('https://example.com/m') + .sort(); + const urls = builder.getUrls(); + expect(urls[0].loc).toEqual('https://example.com/a'); + expect(urls[1].loc).toEqual('https://example.com/m'); + expect(urls[2].loc).toEqual('https://example.com/z'); +}); + +// ────────────────────────────────────────────── +// Output formats +// ────────────────────────────────────────────── + +tap.test('should export as TXT format', async () => { + const txt = smartsitemap.SmartSitemap.create() + .addUrl('https://example.com/a') + .addUrl('https://example.com/b') + .toTxt(); + + expect(txt).toEqual('https://example.com/a\nhttps://example.com/b'); +}); + +tap.test('should export as JSON format', async () => { + const json = smartsitemap.SmartSitemap.create() + .addUrl('https://example.com/a') + .toJson(); + + const parsed = JSON.parse(json); + expect(parsed).toBeArray(); + expect(parsed[0].loc).toEqual('https://example.com/a'); +}); + +tap.test('should export as gzip buffer', async () => { + const buffer = await smartsitemap.SmartSitemap.create() + .addUrl('https://example.com/') + .toGzipBuffer(); + + expect(buffer).toBeInstanceOf(Buffer); + expect(buffer.length).toBeGreaterThan(0); +}); + +// ────────────────────────────────────────────── +// Auto-splitting (sitemap index) +// ────────────────────────────────────────────── + +tap.test('should auto-split into sitemap index when URLs exceed max', async () => { + const builder = smartsitemap.SmartSitemap.create({ + maxUrlsPerSitemap: 3, + baseUrl: 'https://example.com', + }); + + for (let i = 0; i < 7; i++) { + builder.addUrl(`https://example.com/page-${i}`); + } + + const set = builder.toSitemapSet(); + + expect(set.needsIndex).toBeTrue(); + expect(set.indexXml).toBeTruthy(); + expect(set.sitemaps.length).toEqual(3); // ceil(7/3) = 3 + expect(set.indexXml).toInclude(' { + const builder = smartsitemap.SmartSitemap.create({ maxUrlsPerSitemap: 100 }); + builder.addUrl('https://example.com/a'); + builder.addUrl('https://example.com/b'); + + const set = builder.toSitemapSet(); + expect(set.needsIndex).toBeFalse(); + expect(set.indexXml).toBeNull(); + expect(set.sitemaps.length).toEqual(1); +}); + +// ────────────────────────────────────────────── +// Sitemap Index Builder +// ────────────────────────────────────────────── + +tap.test('SitemapIndexBuilder should generate valid index XML', async () => { + const xml = smartsitemap.SmartSitemap.createIndex() + .addSitemap('https://example.com/sitemap-1.xml') + .addSitemap('https://example.com/sitemap-2.xml', new Date('2025-06-15')) + .toXml(); + + expect(xml).toInclude('https://example.com/sitemap-1.xml'); + expect(xml).toInclude('https://example.com/sitemap-2.xml'); + expect(xml).toInclude('2025-06-15'); +}); + +// ────────────────────────────────────────────── +// Validation +// ────────────────────────────────────────────── + +tap.test('should validate URLs and detect errors', async () => { + const result = smartsitemap.SmartSitemap.create() + .addUrl('not-a-valid-url') + .add({ loc: 'https://example.com/', priority: 1.5 }) + .validate(); + + expect(result.valid).toBeFalse(); + expect(result.errors.length).toBeGreaterThan(0); + + const locError = result.errors.find((e) => e.url === 'not-a-valid-url'); + expect(locError).toBeTruthy(); + + const priorityError = result.errors.find((e) => e.field === 'priority'); + expect(priorityError).toBeTruthy(); +}); + +tap.test('should pass validation for valid sitemap', async () => { + const result = smartsitemap.SmartSitemap.create() + .addUrl('https://example.com/') + .add({ loc: 'https://example.com/about', priority: 0.8, changefreq: 'weekly' }) + .validate(); + + expect(result.valid).toBeTrue(); + expect(result.errors.length).toEqual(0); +}); + +// ────────────────────────────────────────────── +// Statistics +// ────────────────────────────────────────────── + +tap.test('should compute stats', async () => { + const stats = smartsitemap.SmartSitemap.create() + .addUrl('https://example.com/') + .add({ + loc: 'https://example.com/gallery', + images: [{ loc: 'https://example.com/img/1.jpg' }, { loc: 'https://example.com/img/2.jpg' }], + }) + .add({ + loc: 'https://example.com/news', + news: { + publication: { name: 'Test', language: 'en' }, + publicationDate: new Date(), + title: 'Article', + }, + }) + .stats(); + + expect(stats.urlCount).toEqual(3); + expect(stats.imageCount).toEqual(2); + expect(stats.newsCount).toEqual(1); + expect(stats.estimatedSizeBytes).toBeGreaterThan(0); +}); + +// ────────────────────────────────────────────── +// YAML import +// ────────────────────────────────────────────── + +tap.test('should import from YAML config', async () => { + const yaml = ` +baseUrl: https://example.com +defaults: + priority: 0.5 +urls: + daily: + - / + - /blog + monthly: + - /about + - /contact + yearly: + - /privacy +`; + + const builder = await smartsitemap.SmartSitemap.fromYaml(yaml); + expect(builder.count).toEqual(5); + + const xml = builder.toXml(); + expect(xml).toInclude('https://example.com/'); + expect(xml).toInclude('daily'); + expect(xml).toInclude('monthly'); + expect(xml).toInclude('yearly'); +}); + +// ────────────────────────────────────────────── +// SitemapStream +// ────────────────────────────────────────────── + +tap.test('should stream sitemap XML', async () => { + const stream = new smartsitemap.SitemapStream(); + const chunks: string[] = []; + + stream.on('data', (chunk: string) => { + chunks.push(chunk); + }); + + const done = new Promise((resolve) => { + stream.on('end', resolve); + }); + + stream.pushUrl({ loc: 'https://example.com/' }); + stream.pushUrl({ loc: 'https://example.com/about' }); + stream.finish(); + + await done; + + const xml = chunks.join(''); + expect(xml).toInclude(''); + expect(xml).toInclude('https://example.com/'); + expect(xml).toInclude('https://example.com/about'); + expect(xml).toInclude(''); + expect(stream.count).toEqual(2); +}); + +// ────────────────────────────────────────────── +// Sitemap parsing +// ────────────────────────────────────────────── + +tap.test('should parse a urlset sitemap XML', async () => { + const xml = smartsitemap.SmartSitemap.create() + .addUrl('https://example.com/', new Date('2025-06-15')) + .add({ loc: 'https://example.com/about', changefreq: 'monthly' }) + .toXml(); + + const parsed = await smartsitemap.SmartSitemap.parse(xml); + expect(parsed.type).toEqual('urlset'); + expect(parsed.urls.length).toEqual(2); + expect(parsed.urls[0].loc).toEqual('https://example.com/'); +}); + +tap.test('should detect sitemap type', async () => { + expect(smartsitemap.SitemapParser.detectType('')).toEqual('urlset'); + expect(smartsitemap.SitemapParser.detectType('')).toEqual('sitemapindex'); + expect(smartsitemap.SitemapParser.detectType('')).toEqual('unknown'); +}); + +// ────────────────────────────────────────────── +// XmlRenderer utility +// ────────────────────────────────────────────── + +tap.test('XmlRenderer.escapeXml should escape special characters', async () => { + expect(smartsitemap.XmlRenderer.escapeXml('a&b')).toEqual('a&b'); + expect(smartsitemap.XmlRenderer.escapeXml('')).toEqual('<tag>'); + expect(smartsitemap.XmlRenderer.escapeXml('"quoted"')).toEqual('"quoted"'); +}); + +tap.test('XmlRenderer.formatDate should handle all date types', async () => { + const iso = smartsitemap.XmlRenderer.formatDate(new Date('2025-06-15T00:00:00.000Z')); + expect(iso).toEqual('2025-06-15T00:00:00.000Z'); + + const fromString = smartsitemap.XmlRenderer.formatDate('2025-06-15'); + expect(fromString).toInclude('2025-06-15'); + + const fromNumber = smartsitemap.XmlRenderer.formatDate(new Date('2025-06-15').getTime()); + expect(fromNumber).toInclude('2025-06-15'); +}); + +export default tap.start(); diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index d275cdb..d248c09 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@push.rocks/smartsitemap', - version: '2.0.4', - description: 'A module for generating and managing sitemaps, supporting dynamic sitemap generation from feeds.' + version: '4.0.0', + description: 'A comprehensive TypeScript sitemap library with builder API, supporting standard, news, image, video, and hreflang sitemaps with auto-splitting, streaming, validation, and RSS feed integration.' } diff --git a/ts/index.ts b/ts/index.ts index be62bef..39df402 100644 --- a/ts/index.ts +++ b/ts/index.ts @@ -1,3 +1,44 @@ -export * from './smartsitemap.classes.smartsitemap.js'; -export * from './smartsitemap.classes.sitemapnews.js'; -export * from './smartsitemap.classes.sitemapwebsite.js'; +// Main facade +export { SmartSitemap } from './smartsitemap.classes.smartsitemap.js'; + +// Builders +export { UrlsetBuilder } from './smartsitemap.classes.urlsetbuilder.js'; +export { NewsSitemapBuilder } from './smartsitemap.classes.newsbuilder.js'; +export { SitemapIndexBuilder } from './smartsitemap.classes.indexbuilder.js'; + +// Parser +export { SitemapParser } from './smartsitemap.classes.sitemapparser.js'; + +// Stream +export { SitemapStream } from './smartsitemap.classes.sitemapstream.js'; + +// Utilities +export { XmlRenderer } from './smartsitemap.classes.xmlrenderer.js'; +export { SitemapValidator } from './smartsitemap.classes.validator.js'; + +// Feed & YAML importers +export { FeedImporter } from './smartsitemap.classes.feedimporter.js'; +export { YamlImporter } from './smartsitemap.classes.yamlimporter.js'; + +// All interfaces and types +export type { + TChangeFreq, + TOutputFormat, + ISitemapUrl, + ISitemapImage, + ISitemapVideo, + ISitemapNews, + ISitemapAlternate, + ISitemapIndexEntry, + ISitemapOptions, + INewsSitemapOptions, + IFeedImportOptions, + IFeedItem, + ISitemapYamlConfig, + IParsedSitemap, + IValidationError, + IValidationWarning, + IValidationResult, + ISitemapStats, + ISitemapSet, +} from './interfaces/index.js'; diff --git a/ts/interfaces/index.ts b/ts/interfaces/index.ts index cb9ab7d..75e8b5b 100644 --- a/ts/interfaces/index.ts +++ b/ts/interfaces/index.ts @@ -1,42 +1,277 @@ -export interface ISitemapYaml { - daily: string[]; +// ============================================================ +// CORE TYPES +// ============================================================ + +/** + * Change frequency values per the sitemap protocol specification. + * Note: Google ignores changefreq, but other search engines may use it. + */ +export type TChangeFreq = + | 'always' + | 'hourly' + | 'daily' + | 'weekly' + | 'monthly' + | 'yearly' + | 'never'; + +/** Supported output formats */ +export type TOutputFormat = 'xml' | 'txt' | 'json'; + +// ============================================================ +// URL ENTRY — the core unit of a sitemap +// ============================================================ + +/** + * A single URL entry in a sitemap, supporting all standard extensions. + */ +export interface ISitemapUrl { + /** Absolute URL of the page (required, max 2048 chars) */ + loc: string; + /** Last modification date — accepts Date, ISO string, or Unix timestamp (ms) */ + lastmod?: Date | string | number; + /** How frequently the page changes */ + changefreq?: TChangeFreq; + /** Priority relative to other URLs on your site, 0.0 to 1.0 */ + priority?: number; + /** Image sitemap extension entries */ + images?: ISitemapImage[]; + /** Video sitemap extension entries */ + videos?: ISitemapVideo[]; + /** News sitemap extension */ + news?: ISitemapNews; + /** Alternate language versions (hreflang) */ + alternates?: ISitemapAlternate[]; } -export interface IRssItem { - [key: string]: any; - link?: string; - guid?: string; +// ============================================================ +// SITEMAP EXTENSIONS +// ============================================================ + +export interface ISitemapImage { + /** URL of the image (required) */ + loc: string; + /** Caption for the image */ + caption?: string; + /** Title of the image */ title?: string; - pubDate?: string; - creator?: string; - content?: string; - isoDate?: string; - categories?: string[]; - contentSnippet?: string; - enclosure?: any; + /** Geographic location (e.g. "New York, USA") */ + geoLocation?: string; + /** URL to the image license */ + licenseUrl?: string; } -export interface IParsedSiteMap { - urlset: { - url: - | { - loc: string; - lastmod: string; - changefreq: string; - } - | { - loc: string; - lastmod: string; - changefreq: string; - }[] - | { - loc: string; - 'news:news': { - 'news:publication': []; - 'news:keywords': string; - 'news:publication_date': string; - 'news:title': string; - }; - }[]; - }; +export interface ISitemapVideo { + /** URL to the video thumbnail (required) */ + thumbnailLoc: string; + /** Title of the video (required) */ + title: string; + /** Description of the video, max 2048 chars (required) */ + description: string; + /** URL of the actual video media file */ + contentLoc?: string; + /** URL of the embeddable player — at least one of contentLoc or playerLoc required */ + playerLoc?: string; + /** Duration in seconds (1–28800) */ + duration?: number; + /** Rating 0.0 to 5.0 */ + rating?: number; + /** Number of views */ + viewCount?: number; + /** Publication date */ + publicationDate?: Date | string; + /** Whether the video is family friendly (default true) */ + familyFriendly?: boolean; + /** Tags for the video (max 32) */ + tags?: string[]; + /** Whether this is a live stream */ + live?: boolean; + /** Whether a subscription is required to view */ + requiresSubscription?: boolean; +} + +export interface ISitemapNews { + /** Publication information */ + publication: { + /** Publication name (e.g. "The New York Times") */ + name: string; + /** Language code (ISO 639, e.g. "en", "de", "zh-cn") */ + language: string; + }; + /** Publication date of the article */ + publicationDate: Date | string | number; + /** Article title */ + title: string; + /** Keywords (array or comma-separated string) */ + keywords?: string[] | string; +} + +export interface ISitemapAlternate { + /** Language code (ISO 639) or 'x-default' for the default version */ + hreflang: string; + /** URL for this language version */ + href: string; +} + +// ============================================================ +// SITEMAP INDEX +// ============================================================ + +export interface ISitemapIndexEntry { + /** URL to the sitemap file */ + loc: string; + /** Last modification date of the referenced sitemap */ + lastmod?: Date | string | number; +} + +// ============================================================ +// CONFIGURATION +// ============================================================ + +export interface ISitemapOptions { + /** Base URL for the website (used to resolve relative URLs and for auto-split filenames) */ + baseUrl?: string; + /** XSL stylesheet URL for browser-viewable sitemaps */ + xslUrl?: string; + /** Default changefreq for URLs that don't specify one */ + defaultChangeFreq?: TChangeFreq; + /** Default priority for URLs that don't specify one (0.0–1.0) */ + defaultPriority?: number; + /** Whether to pretty-print XML output (default: true) */ + prettyPrint?: boolean; + /** Maximum URLs per sitemap file before auto-splitting (default: 50000, max: 50000) */ + maxUrlsPerSitemap?: number; + /** Enable gzip compression for toGzipBuffer() */ + gzip?: boolean; + /** Whether to validate URLs and fields (default: true) */ + validate?: boolean; +} + +export interface INewsSitemapOptions extends ISitemapOptions { + /** Publication name — required for news sitemaps */ + publicationName: string; + /** Publication language (default: 'en') */ + publicationLanguage?: string; +} + +export interface IFeedImportOptions { + /** Publication name for news sitemap mapping */ + publicationName?: string; + /** Publication language for news sitemap mapping */ + publicationLanguage?: string; + /** Only include items newer than this date */ + newerThan?: Date | number; + /** Maximum number of items to import */ + limit?: number; + /** Custom mapping function from feed item to sitemap URL (return null to skip) */ + mapItem?: (item: IFeedItem) => ISitemapUrl | null; +} + +/** Shape of a parsed RSS/Atom feed item */ +export interface IFeedItem { + title?: string; + link?: string; + pubDate?: string; + author?: string; + content?: string; + contentSnippet?: string; + isoDate?: string; + id?: string; + categories?: string[]; + enclosure?: { + url?: string; + type?: string; + length?: string; + }; + [key: string]: any; +} + +// ============================================================ +// YAML CONFIG +// ============================================================ + +/** + * Enhanced YAML configuration format for defining sitemaps declaratively. + * Supports per-frequency URL groups, default settings, and feed imports. + */ +export interface ISitemapYamlConfig { + /** Base URL to prepend to relative paths */ + baseUrl?: string; + /** Default values for all URLs */ + defaults?: { + changefreq?: TChangeFreq; + priority?: number; + }; + /** URL groups organized by change frequency */ + urls?: { [K in TChangeFreq]?: string[] }; + /** RSS/Atom feeds to import */ + feeds?: Array<{ + url: string; + type: 'news' | 'standard'; + publicationName?: string; + publicationLanguage?: string; + }>; +} + +// ============================================================ +// PARSED SITEMAP (bidirectional) +// ============================================================ + +export interface IParsedSitemap { + /** Whether this is a urlset or a sitemap index */ + type: 'urlset' | 'sitemapindex'; + /** Parsed URL entries (populated when type is 'urlset') */ + urls: ISitemapUrl[]; + /** Parsed index entries (populated when type is 'sitemapindex') */ + sitemaps: ISitemapIndexEntry[]; +} + +// ============================================================ +// VALIDATION +// ============================================================ + +export interface IValidationError { + field: string; + message: string; + url?: string; +} + +export interface IValidationWarning { + field: string; + message: string; + url?: string; +} + +export interface IValidationResult { + valid: boolean; + errors: IValidationError[]; + warnings: IValidationWarning[]; + stats: ISitemapStats; +} + +// ============================================================ +// STATISTICS +// ============================================================ + +export interface ISitemapStats { + urlCount: number; + imageCount: number; + videoCount: number; + newsCount: number; + alternateCount: number; + estimatedSizeBytes: number; + needsIndex: boolean; +} + +// ============================================================ +// AUTO-SPLIT OUTPUT +// ============================================================ + +export interface ISitemapSet { + /** Whether the URL count exceeded maxUrlsPerSitemap */ + needsIndex: boolean; + /** The sitemap index XML (null if all URLs fit in one sitemap) */ + indexXml: string | null; + /** Individual sitemap chunks */ + sitemaps: Array<{ filename: string; xml: string }>; } diff --git a/ts/smartsitemap.classes.feedimporter.ts b/ts/smartsitemap.classes.feedimporter.ts new file mode 100644 index 0000000..dcb110d --- /dev/null +++ b/ts/smartsitemap.classes.feedimporter.ts @@ -0,0 +1,159 @@ +import * as plugins from './smartsitemap.plugins.js'; +import type * as interfaces from './interfaces/index.js'; + +/** + * Imports RSS/Atom feeds and converts them to sitemap URL entries. + * This is a unique feature of smartsitemap that competitors don't offer. + */ +export class FeedImporter { + /** + * Import from a feed URL, returning standard sitemap URL entries. + */ + static async fromUrl( + feedUrl: string, + options?: interfaces.IFeedImportOptions, + ): Promise { + const smartfeed = new plugins.smartfeed.Smartfeed(); + const feed = await smartfeed.parseFeedFromUrl(feedUrl); + return FeedImporter.mapItems(feed.items, options); + } + + /** + * Import from a feed XML string, returning standard sitemap URL entries. + */ + static async fromString( + feedXml: string, + options?: interfaces.IFeedImportOptions, + ): Promise { + const smartfeed = new plugins.smartfeed.Smartfeed(); + const feed = await smartfeed.parseFeedFromString(feedXml); + return FeedImporter.mapItems(feed.items, options); + } + + /** + * Import from a feed URL, returning news sitemap URL entries. + */ + static async fromUrlAsNews( + feedUrl: string, + publicationName: string, + publicationLanguage?: string, + options?: interfaces.IFeedImportOptions, + ): Promise { + const smartfeed = new plugins.smartfeed.Smartfeed(); + const feed = await smartfeed.parseFeedFromUrl(feedUrl); + return FeedImporter.mapItemsAsNews(feed.items, publicationName, publicationLanguage ?? 'en', options); + } + + /** + * Import from a feed string, returning news sitemap URL entries. + */ + static async fromStringAsNews( + feedXml: string, + publicationName: string, + publicationLanguage?: string, + options?: interfaces.IFeedImportOptions, + ): Promise { + const smartfeed = new plugins.smartfeed.Smartfeed(); + const feed = await smartfeed.parseFeedFromString(feedXml); + return FeedImporter.mapItemsAsNews(feed.items, publicationName, publicationLanguage ?? 'en', options); + } + + /** + * Map parsed feed items to standard sitemap URLs. + */ + private static mapItems( + items: any[], + options?: interfaces.IFeedImportOptions, + ): interfaces.ISitemapUrl[] { + let filtered = FeedImporter.filterItems(items, options); + + if (options?.mapItem) { + const results: interfaces.ISitemapUrl[] = []; + for (const item of filtered) { + const mapped = options.mapItem(item as interfaces.IFeedItem); + if (mapped) results.push(mapped); + } + return results; + } + + return filtered + .filter((item: any) => item.link) + .map((item: any) => { + const url: interfaces.ISitemapUrl = { + loc: item.link, + }; + if (item.isoDate) { + url.lastmod = item.isoDate; + } + return url; + }); + } + + /** + * Map parsed feed items to news sitemap URLs. + */ + private static mapItemsAsNews( + items: any[], + publicationName: string, + publicationLanguage: string, + options?: interfaces.IFeedImportOptions, + ): interfaces.ISitemapUrl[] { + let filtered = FeedImporter.filterItems(items, options); + + if (options?.mapItem) { + const results: interfaces.ISitemapUrl[] = []; + for (const item of filtered) { + const mapped = options.mapItem(item as interfaces.IFeedItem); + if (mapped) results.push(mapped); + } + return results; + } + + return filtered + .filter((item: any) => item.link) + .map((item: any) => { + const url: interfaces.ISitemapUrl = { + loc: item.link, + news: { + publication: { + name: publicationName, + language: publicationLanguage, + }, + publicationDate: item.isoDate || new Date().toISOString(), + title: item.title || '', + keywords: item.categories, + }, + }; + if (item.isoDate) { + url.lastmod = item.isoDate; + } + return url; + }); + } + + /** + * Apply date and limit filters to feed items. + */ + private static filterItems(items: any[], options?: interfaces.IFeedImportOptions): any[] { + let result = [...items]; + + // Filter by date + if (options?.newerThan != null) { + const threshold = options.newerThan instanceof Date + ? options.newerThan.getTime() + : options.newerThan; + + result = result.filter((item: any) => { + if (!item.isoDate) return true; // keep items without dates + return new Date(item.isoDate).getTime() >= threshold; + }); + } + + // Apply limit + if (options?.limit != null && options.limit > 0) { + result = result.slice(0, options.limit); + } + + return result; + } +} diff --git a/ts/smartsitemap.classes.indexbuilder.ts b/ts/smartsitemap.classes.indexbuilder.ts new file mode 100644 index 0000000..bd03188 --- /dev/null +++ b/ts/smartsitemap.classes.indexbuilder.ts @@ -0,0 +1,82 @@ +import type * as interfaces from './interfaces/index.js'; +import { XmlRenderer } from './smartsitemap.classes.xmlrenderer.js'; +import { UrlsetBuilder } from './smartsitemap.classes.urlsetbuilder.js'; + +/** + * Builder for sitemap index files (). + * Used when you have multiple sitemaps that need to be referenced from a single index. + * Every mutating method returns `this` for fluent chaining. + */ +export class SitemapIndexBuilder { + private entries: interfaces.ISitemapIndexEntry[] = []; + private options: interfaces.ISitemapOptions; + + constructor(options?: interfaces.ISitemapOptions) { + this.options = options ?? {}; + } + + /** Add a sitemap index entry */ + add(entry: interfaces.ISitemapIndexEntry): this { + this.entries.push(entry); + return this; + } + + /** Add a sitemap by URL, optionally with lastmod */ + addSitemap(loc: string, lastmod?: Date | string | number): this { + const entry: interfaces.ISitemapIndexEntry = { loc }; + if (lastmod != null) { + entry.lastmod = lastmod; + } + this.entries.push(entry); + return this; + } + + /** Add multiple sitemap entries */ + addSitemaps(entries: interfaces.ISitemapIndexEntry[]): this { + this.entries.push(...entries); + return this; + } + + /** + * Build an index and individual sitemaps from a UrlsetBuilder that needs splitting. + * The builder's URLs are divided into chunks of maxUrlsPerSitemap. + */ + static fromBuilder( + builder: UrlsetBuilder, + baseUrl: string, + ): { index: SitemapIndexBuilder; sitemaps: UrlsetBuilder[] } { + const urls = builder.getUrls(); + const options = builder.getOptions(); + const maxUrls = Math.min(options.maxUrlsPerSitemap ?? 50000, 50000); + + const index = new SitemapIndexBuilder(options); + const sitemaps: UrlsetBuilder[] = []; + + for (let i = 0; i < urls.length; i += maxUrls) { + const chunk = urls.slice(i, i + maxUrls); + const chunkBuilder = new UrlsetBuilder(options); + chunkBuilder.addUrls(chunk); + sitemaps.push(chunkBuilder); + + const filename = `sitemap-${sitemaps.length}.xml`; + index.addSitemap(`${baseUrl.replace(/\/$/, '')}/${filename}`); + } + + return { index, sitemaps }; + } + + /** Export as sitemap index XML string */ + toXml(): string { + return XmlRenderer.renderIndex(this.entries, this.options); + } + + /** Get all entries */ + getEntries(): interfaces.ISitemapIndexEntry[] { + return [...this.entries]; + } + + /** Get the number of sitemaps in this index */ + get count(): number { + return this.entries.length; + } +} diff --git a/ts/smartsitemap.classes.newsbuilder.ts b/ts/smartsitemap.classes.newsbuilder.ts new file mode 100644 index 0000000..8c324b5 --- /dev/null +++ b/ts/smartsitemap.classes.newsbuilder.ts @@ -0,0 +1,95 @@ +import * as plugins from './smartsitemap.plugins.js'; +import type * as interfaces from './interfaces/index.js'; +import { UrlsetBuilder } from './smartsitemap.classes.urlsetbuilder.js'; +import { FeedImporter } from './smartsitemap.classes.feedimporter.js'; + +/** + * Specialized builder for Google News sitemaps. + * Extends UrlsetBuilder with news-specific convenience methods. + * All standard builder methods (add, filter, merge, etc.) are inherited. + */ +export class NewsSitemapBuilder extends UrlsetBuilder { + private publicationName: string; + private publicationLanguage: string; + + constructor(options: interfaces.INewsSitemapOptions) { + super(options); + this.publicationName = options.publicationName; + this.publicationLanguage = options.publicationLanguage ?? 'en'; + } + + /** + * Add a news article URL with convenient parameters. + * Automatically fills in publication name and language from constructor options. + */ + addNewsUrl( + loc: string, + title: string, + publicationDate: Date | string | number, + keywords?: string[] | string, + ): this { + this.add({ + loc, + news: { + publication: { + name: this.publicationName, + language: this.publicationLanguage, + }, + publicationDate, + title, + keywords, + }, + }); + return this; + } + + /** + * Import from RSS/Atom feed URL, automatically mapping items to news entries. + */ + async importFromFeedUrl(feedUrl: string, options?: interfaces.IFeedImportOptions): Promise { + const imported = await FeedImporter.fromUrlAsNews( + feedUrl, + options?.publicationName ?? this.publicationName, + options?.publicationLanguage ?? this.publicationLanguage, + options, + ); + this.addUrls(imported); + return this; + } + + /** + * Import from RSS/Atom feed string, automatically mapping items to news entries. + */ + async importFromFeedString(feedXml: string, options?: interfaces.IFeedImportOptions): Promise { + const imported = await FeedImporter.fromStringAsNews( + feedXml, + options?.publicationName ?? this.publicationName, + options?.publicationLanguage ?? this.publicationLanguage, + options, + ); + this.addUrls(imported); + return this; + } + + /** + * Import from @tsclass/tsclass IArticle array with proper news mapping. + */ + importFromArticles(articles: plugins.tsclass.content.IArticle[]): this { + for (const article of articles) { + this.add({ + loc: article.url, + lastmod: article.timestamp ? new Date(article.timestamp) : undefined, + news: { + publication: { + name: this.publicationName, + language: this.publicationLanguage, + }, + publicationDate: article.timestamp ? new Date(article.timestamp) : new Date(), + title: article.title || '', + keywords: article.tags, + }, + }); + } + return this; + } +} diff --git a/ts/smartsitemap.classes.sitemapnews.ts b/ts/smartsitemap.classes.sitemapnews.ts deleted file mode 100644 index 4730b20..0000000 --- a/ts/smartsitemap.classes.sitemapnews.ts +++ /dev/null @@ -1,79 +0,0 @@ -import * as plugins from './smartsitemap.plugins.js'; -import * as interfaces from './interfaces/index.js'; - -export class SitemapNews { - public rssItems: interfaces.IRssItem[] = []; - - constructor(optionsArg: {}) {} - - public async readAndAddFromRssFeedString(feedStringArg: string) { - const smartfeedInstance = new plugins.smartfeed.Smartfeed(); - const parsedFeed = - await smartfeedInstance.parseFeedFromString(feedStringArg); - this.rssItems = this.rssItems.concat(parsedFeed.items); - } - - public async readAndAddFromRssFeedUrl(urlArg: string) { - const smartfeedInstance = new plugins.smartfeed.Smartfeed(); - const parsedFeed = await smartfeedInstance.parseFeedFromUrl(urlArg); - this.rssItems = this.rssItems.concat(parsedFeed.items); - } - - public async readAndParseArticles( - articleArrayArg: plugins.tsclass.content.IArticle[], - ) { - const rssItemArray = articleArrayArg.map( - (articleArg): interfaces.IRssItem => { - return { - title: articleArg.title, - content: articleArg.content, - isoDate: - new Date(/* TODO: put article timestamp here */).toISOString(), - link: articleArg.url, - }; - }, - ); - - this.rssItems = this.rssItems.concat(rssItemArray); - } - - public exportSitemapXml() { - const urls: { - loc: string; - 'news:news': { - 'news:publication': { - 'news:name': string; - 'news:language': string; - }; - 'news:publication_date': string; - 'news:keywords': string; - 'news:title': string; - }; - }[] = []; - for (const itemArg of this.rssItems) { - console.log(itemArg); - urls.push({ - loc: itemArg.link, - 'news:news': { - 'news:publication': { - 'news:language': 'en', - 'news:name': 'some name', - }, - 'news:keywords': '', - 'news:publication_date': itemArg.isoDate, - 'news:title': itemArg.title, - }, - }); - } - const sitemapObject: any = { - urlset: { - '@_xmlns': 'http://www.sitemaps.org/schemas/sitemap/0.9', - '@_xmlns:news': 'http://www.google.com/schemas/sitemap-news/0.9', - url: urls, - }, - }; - const smartxmlInstance = new plugins.smartxml.SmartXml(); - const sitemapString = smartxmlInstance.createXmlFromObject(sitemapObject); - return sitemapString; - } -} diff --git a/ts/smartsitemap.classes.sitemapparser.ts b/ts/smartsitemap.classes.sitemapparser.ts new file mode 100644 index 0000000..59a55c3 --- /dev/null +++ b/ts/smartsitemap.classes.sitemapparser.ts @@ -0,0 +1,251 @@ +import * as plugins from './smartsitemap.plugins.js'; +import type * as interfaces from './interfaces/index.js'; +import { UrlsetBuilder } from './smartsitemap.classes.urlsetbuilder.js'; + +/** + * Parses existing sitemap XML into structured data. + * Handles both sitemaps and files. + */ +export class SitemapParser { + /** + * Parse a sitemap XML string into structured data. + */ + static async parse(xml: string): Promise { + const smartXml = new plugins.smartxml.SmartXml(); + const parsed = smartXml.parseXmlToObject(xml); + + // The parser returns ordered format (preserveOrder: true) + // We need to walk the structure to extract urls or sitemap entries + return SitemapParser.processOrderedParsed(parsed); + } + + /** + * Fetch and parse a sitemap from a URL. + */ + static async parseUrl(url: string): Promise { + const response = await plugins.webrequest.webrequest(url); + const xml = await response.text(); + return SitemapParser.parse(xml); + } + + /** + * Parse a sitemap XML and return a pre-populated UrlsetBuilder. + */ + static async toBuilder(xml: string, options?: interfaces.ISitemapOptions): Promise { + const parsed = await SitemapParser.parse(xml); + const builder = new UrlsetBuilder(options); + builder.addUrls(parsed.urls); + return builder; + } + + /** + * Detect whether XML is a urlset or sitemapindex without full parsing. + */ + static detectType(xml: string): 'urlset' | 'sitemapindex' | 'unknown' { + if (xml.includes(' = new Set(); + + constructor(options?: interfaces.ISitemapOptions) { + super({ encoding: 'utf-8' }); + this.options = { + prettyPrint: true, + ...options, + }; + } + + /** + * Push a URL entry into the stream. + * The URL is immediately rendered to XML and pushed to the readable buffer. + */ + pushUrl(url: interfaces.ISitemapUrl): boolean { + if (this.finished) { + throw new Error('Cannot push URLs after calling finish()'); + } + + // Detect needed namespaces + if (url.images?.length) this.namespaces.add('image'); + if (url.videos?.length) this.namespaces.add('video'); + if (url.news) this.namespaces.add('news'); + if (url.alternates?.length) this.namespaces.add('xhtml'); + + // Write header on first URL + if (!this.headerWritten) { + this.writeHeader(); + } + + // Build URL element XML using XmlRenderer internals + const indent = this.options.prettyPrint !== false ? ' ' : ''; + const nl = this.options.prettyPrint !== false ? '\n' : ''; + + let urlXml = `${indent}${nl}`; + urlXml += `${indent}${indent}${XmlRenderer.escapeXml(url.loc)}${nl}`; + + if (url.lastmod != null) { + urlXml += `${indent}${indent}${XmlRenderer.formatDate(url.lastmod)}${nl}`; + } + + const changefreq = url.changefreq ?? this.options.defaultChangeFreq; + if (changefreq) { + urlXml += `${indent}${indent}${changefreq}${nl}`; + } + + const priority = url.priority ?? this.options.defaultPriority; + if (priority != null) { + urlXml += `${indent}${indent}${priority.toFixed(1)}${nl}`; + } + + // Extensions (simplified inline rendering for streaming) + if (url.images) { + for (const img of url.images) { + urlXml += `${indent}${indent}${nl}`; + urlXml += `${indent}${indent}${indent}${XmlRenderer.escapeXml(img.loc)}${nl}`; + if (img.caption) urlXml += `${indent}${indent}${indent}${XmlRenderer.escapeXml(img.caption)}${nl}`; + if (img.title) urlXml += `${indent}${indent}${indent}${XmlRenderer.escapeXml(img.title)}${nl}`; + urlXml += `${indent}${indent}${nl}`; + } + } + + if (url.news) { + urlXml += `${indent}${indent}${nl}`; + urlXml += `${indent}${indent}${indent}${nl}`; + urlXml += `${indent}${indent}${indent}${indent}${XmlRenderer.escapeXml(url.news.publication.name)}${nl}`; + urlXml += `${indent}${indent}${indent}${indent}${url.news.publication.language}${nl}`; + urlXml += `${indent}${indent}${indent}${nl}`; + urlXml += `${indent}${indent}${indent}${XmlRenderer.formatDate(url.news.publicationDate)}${nl}`; + urlXml += `${indent}${indent}${indent}${XmlRenderer.escapeXml(url.news.title)}${nl}`; + if (url.news.keywords) { + const kw = Array.isArray(url.news.keywords) ? url.news.keywords.join(', ') : url.news.keywords; + urlXml += `${indent}${indent}${indent}${XmlRenderer.escapeXml(kw)}${nl}`; + } + urlXml += `${indent}${indent}${nl}`; + } + + if (url.alternates) { + for (const alt of url.alternates) { + urlXml += `${indent}${indent}${nl}`; + } + } + + urlXml += `${indent}${nl}`; + + this.urlCount++; + return this.push(urlXml); + } + + /** + * Signal that no more URLs will be added. + * Writes the closing tag and ends the stream. + */ + finish(): void { + if (this.finished) return; + this.finished = true; + + if (!this.headerWritten) { + // Empty sitemap + this.writeHeader(); + } + + this.push('\n'); + this.push(null); // signal end of stream + } + + /** Get the number of URLs written so far */ + get count(): number { + return this.urlCount; + } + + // Required by Readable + _read(): void { + // Data is pushed via pushUrl(), not pulled + } + + /** + * Write the XML header and opening urlset tag. + * Namespace declarations are based on what's been detected so far. + */ + private writeHeader(): void { + this.headerWritten = true; + const nl = this.options.prettyPrint !== false ? '\n' : ''; + + let header = `${nl}`; + + if (this.options.xslUrl) { + header += `${nl}`; + } + + header += '${nl}`; + + this.push(header); + } +} diff --git a/ts/smartsitemap.classes.sitemapwebsite.ts b/ts/smartsitemap.classes.sitemapwebsite.ts deleted file mode 100644 index fe6e790..0000000 --- a/ts/smartsitemap.classes.sitemapwebsite.ts +++ /dev/null @@ -1,47 +0,0 @@ -import * as plugins from './smartsitemap.plugins.js'; - -export type TUpdateFrequency = - | 'never' - | 'daily' - | 'weekly' - | 'monthly' - | 'yearly'; - -export interface IUrlInfo { - url: string; - timestamp: number; - frequency?: TUpdateFrequency; -} - -export class SitemapWebsite { - urlInfos: IUrlInfo[] = []; - constructor() {} - - public addUrl(urlInfoArg: IUrlInfo) { - this.urlInfos.push(urlInfoArg); - } - - public exportSitemapXml() { - const urls: { - loc: string; - lastmod: string; - changefreq: TUpdateFrequency; - }[] = []; - for (const urlInfoArg of this.urlInfos) { - urls.push({ - loc: urlInfoArg.url, - lastmod: new Date(urlInfoArg.timestamp).toISOString(), - changefreq: urlInfoArg.frequency ? urlInfoArg.frequency : 'weekly', - }); - } - const sitemapObject: any = { - urlset: { - '@_xmlns': 'http://www.sitemaps.org/schemas/sitemap/0.9', - url: urls, - }, - }; - const smartxmlInstance = new plugins.smartxml.SmartXml(); - const sitemapString = smartxmlInstance.createXmlFromObject(sitemapObject); - return sitemapString; - } -} diff --git a/ts/smartsitemap.classes.smartsitemap.ts b/ts/smartsitemap.classes.smartsitemap.ts index a5f7ef4..a07919d 100644 --- a/ts/smartsitemap.classes.smartsitemap.ts +++ b/ts/smartsitemap.classes.smartsitemap.ts @@ -1,92 +1,112 @@ -import { SitemapNews } from './smartsitemap.classes.sitemapnews.js'; -import { - type IUrlInfo, - SitemapWebsite, -} from './smartsitemap.classes.sitemapwebsite.js'; import * as plugins from './smartsitemap.plugins.js'; -import * as interfaces from './interfaces/index.js'; +import type * as interfaces from './interfaces/index.js'; +import { UrlsetBuilder } from './smartsitemap.classes.urlsetbuilder.js'; +import { NewsSitemapBuilder } from './smartsitemap.classes.newsbuilder.js'; +import { SitemapIndexBuilder } from './smartsitemap.classes.indexbuilder.js'; +import { SitemapParser } from './smartsitemap.classes.sitemapparser.js'; +import { FeedImporter } from './smartsitemap.classes.feedimporter.js'; +import { YamlImporter } from './smartsitemap.classes.yamlimporter.js'; +import { SitemapValidator } from './smartsitemap.classes.validator.js'; +/** + * Main entry point for @push.rocks/smartsitemap. + * Provides static factory methods for creating, parsing, and validating sitemaps. + * + * @example Simple sitemap + * ```typescript + * const xml = SmartSitemap.create() + * .addUrl('https://example.com/') + * .addUrl('https://example.com/about') + * .toXml(); + * ``` + * + * @example News sitemap from RSS feed + * ```typescript + * const builder = SmartSitemap.createNews({ publicationName: 'My Pub' }); + * await builder.importFromFeedUrl('https://example.com/rss/'); + * const xml = builder.toXml(); + * ``` + */ export class SmartSitemap { - constructor() {} + // ────────────────────────────────────────────── + // Static Factory Methods + // ────────────────────────────────────────────── - /** - * creates a sitemap for news from feedurl - */ - public async createSitemapNewsFromFeedUrl( - feedUrlArg: string, - ): Promise { - const sitemapNewsInstance = new SitemapNews({}); - await sitemapNewsInstance.readAndAddFromRssFeedUrl(feedUrlArg); - return sitemapNewsInstance.exportSitemapXml(); + /** Create a standard sitemap builder */ + static create(options?: interfaces.ISitemapOptions): UrlsetBuilder { + return new UrlsetBuilder(options); } - /** - * creates a sitemap for news from feedxmlstring - */ - public async createSitemapNewsFromAFeedStringArg( - feedStringArg: string, - ): Promise { - const sitemapNewsInstance = new SitemapNews({}); - await sitemapNewsInstance.readAndAddFromRssFeedString(feedStringArg); - return sitemapNewsInstance.exportSitemapXml(); + /** Create a news sitemap builder */ + static createNews(options: interfaces.INewsSitemapOptions): NewsSitemapBuilder { + return new NewsSitemapBuilder(options); } - /** - * creates a sitemap for news from an array of articles - */ - public async createSitemapNewsFromArticleArray( - articleArrayArg: plugins.tsclass.content.IArticle[], - ): Promise { - const sitemapNewsInstance = new SitemapNews({}); - await sitemapNewsInstance.readAndParseArticles(articleArrayArg); - return sitemapNewsInstance.exportSitemapXml(); + /** Create a sitemap index builder */ + static createIndex(options?: interfaces.ISitemapOptions): SitemapIndexBuilder { + return new SitemapIndexBuilder(options); } - /** - * creates a normal sitemap from a list of urls - */ - public async createSitemapFromYmlString(yamlString: string): Promise { - const yamlObject: interfaces.ISitemapYaml = - await plugins.smartyaml.yamlStringToObject(yamlString); - const sitemapWebsite = new SitemapWebsite(); - for (const urlArg of yamlObject.daily) { - sitemapWebsite.addUrl({ - url: urlArg, - timestamp: Date.now() - 10000, - frequency: 'daily', - }); - } - return sitemapWebsite.exportSitemapXml(); + /** Parse a sitemap XML string into structured data */ + static async parse(xml: string): Promise { + return SitemapParser.parse(xml); } - /** - * creates a normal sitemap from a list of urls - */ - public async createSitemapFromUrlInfoArray(urlInfosArg: IUrlInfo[]) { - const sitemapWebsite = new SitemapWebsite(); - for (const urlInfo of urlInfosArg) { - sitemapWebsite.addUrl(urlInfo); - } - return sitemapWebsite.exportSitemapXml(); + /** Fetch and parse a sitemap from a URL */ + static async parseUrl(url: string): Promise { + return SitemapParser.parseUrl(url); } - /** - * parses a sitemap url - */ - public async parseSitemapUrl(urlArg: string) { - const response = await plugins.webrequest.webrequest(urlArg); - const sitemapXml = await response.text(); - - const parsedSitemap = await this.parseSitemap(sitemapXml); - return parsedSitemap; + /** Create a UrlsetBuilder populated from an RSS/Atom feed URL */ + static async fromFeedUrl( + feedUrl: string, + options?: interfaces.IFeedImportOptions, + ): Promise { + const urls = await FeedImporter.fromUrl(feedUrl, options); + const builder = new UrlsetBuilder(); + builder.addUrls(urls); + return builder; } - /** - * parses a sitemap - */ - public async parseSitemap( - sitemapXmlArg: string, - ): Promise { - return new plugins.smartxml.SmartXml().parseXmlToObject(sitemapXmlArg); + /** Create a UrlsetBuilder populated from an RSS/Atom feed string */ + static async fromFeedString( + feedXml: string, + options?: interfaces.IFeedImportOptions, + ): Promise { + const urls = await FeedImporter.fromString(feedXml, options); + const builder = new UrlsetBuilder(); + builder.addUrls(urls); + return builder; + } + + /** Create a UrlsetBuilder populated from a YAML config string */ + static async fromYaml(yamlString: string): Promise { + const urls = await YamlImporter.parseConfig(yamlString); + const builder = new UrlsetBuilder(); + builder.addUrls(urls); + return builder; + } + + /** Create a NewsSitemapBuilder populated from @tsclass/tsclass IArticle array */ + static fromArticles( + articles: plugins.tsclass.content.IArticle[], + options: interfaces.INewsSitemapOptions, + ): NewsSitemapBuilder { + const builder = new NewsSitemapBuilder(options); + builder.importFromArticles(articles); + return builder; + } + + /** Create a UrlsetBuilder from a simple URL string array */ + static fromUrls(urls: string[], options?: interfaces.ISitemapOptions): UrlsetBuilder { + const builder = new UrlsetBuilder(options); + builder.addFromArray(urls); + return builder; + } + + /** Validate a sitemap XML string */ + static async validate(xml: string): Promise { + const parsed = await SitemapParser.parse(xml); + return SitemapValidator.validateUrlset(parsed.urls); } } diff --git a/ts/smartsitemap.classes.urlsetbuilder.ts b/ts/smartsitemap.classes.urlsetbuilder.ts new file mode 100644 index 0000000..dc216d2 --- /dev/null +++ b/ts/smartsitemap.classes.urlsetbuilder.ts @@ -0,0 +1,274 @@ +import * as plugins from './smartsitemap.plugins.js'; +import type * as interfaces from './interfaces/index.js'; +import { XmlRenderer } from './smartsitemap.classes.xmlrenderer.js'; +import { SitemapValidator } from './smartsitemap.classes.validator.js'; +import { FeedImporter } from './smartsitemap.classes.feedimporter.js'; +import { YamlImporter } from './smartsitemap.classes.yamlimporter.js'; +import type { SitemapStream } from './smartsitemap.classes.sitemapstream.js'; + +/** + * Chainable builder for creating standard XML sitemaps (). + * Every mutating method returns `this` for fluent chaining. + * + * Supports all sitemap extensions (images, videos, news, hreflang), + * auto-splitting at 50K URLs, multiple output formats, and validation. + */ +export class UrlsetBuilder { + protected urls: interfaces.ISitemapUrl[] = []; + protected options: interfaces.ISitemapOptions; + + constructor(options?: interfaces.ISitemapOptions) { + this.options = { + prettyPrint: true, + maxUrlsPerSitemap: 50000, + validate: true, + ...options, + }; + } + + // ────────────────────────────────────────────── + // Adding URLs + // ────────────────────────────────────────────── + + /** Add a single URL with full options */ + add(url: interfaces.ISitemapUrl): this { + this.urls.push(url); + return this; + } + + /** Add a URL by loc string, optionally with lastmod */ + addUrl(loc: string, lastmod?: Date | string | number): this { + const url: interfaces.ISitemapUrl = { loc }; + if (lastmod != null) { + url.lastmod = lastmod; + } + this.urls.push(url); + return this; + } + + /** Add multiple URL objects */ + addUrls(urls: interfaces.ISitemapUrl[]): this { + this.urls.push(...urls); + return this; + } + + /** Add URLs from a plain string array */ + addFromArray(locs: string[]): this { + for (const loc of locs) { + this.urls.push({ loc }); + } + return this; + } + + // ────────────────────────────────────────────── + // Bulk operations + // ────────────────────────────────────────────── + + /** Merge all URLs from another UrlsetBuilder */ + merge(other: UrlsetBuilder): this { + this.urls.push(...other.getUrls()); + return this; + } + + /** Filter URLs by predicate (in-place) */ + filter(predicate: (url: interfaces.ISitemapUrl) => boolean): this { + this.urls = this.urls.filter(predicate); + return this; + } + + /** Transform URLs (in-place) */ + map(transform: (url: interfaces.ISitemapUrl) => interfaces.ISitemapUrl): this { + this.urls = this.urls.map(transform); + return this; + } + + /** Sort URLs (in-place) */ + sort(compareFn?: (a: interfaces.ISitemapUrl, b: interfaces.ISitemapUrl) => number): this { + this.urls.sort(compareFn ?? ((a, b) => a.loc.localeCompare(b.loc))); + return this; + } + + /** Remove duplicate URLs by loc */ + dedupe(): this { + const seen = new Set(); + this.urls = this.urls.filter((url) => { + if (seen.has(url.loc)) return false; + seen.add(url.loc); + return true; + }); + return this; + } + + // ────────────────────────────────────────────── + // Defaults + // ────────────────────────────────────────────── + + /** Set default changefreq for URLs that don't specify one */ + setDefaultChangeFreq(freq: interfaces.TChangeFreq): this { + this.options.defaultChangeFreq = freq; + return this; + } + + /** Set default priority for URLs that don't specify one */ + setDefaultPriority(priority: number): this { + this.options.defaultPriority = priority; + return this; + } + + /** Set XSL stylesheet URL for browser rendering */ + setXslUrl(url: string): this { + this.options.xslUrl = url; + return this; + } + + // ────────────────────────────────────────────── + // Import sources (async, return Promise) + // ────────────────────────────────────────────── + + /** Import URLs from an RSS/Atom feed URL */ + async importFromFeedUrl(feedUrl: string, options?: interfaces.IFeedImportOptions): Promise { + const imported = await FeedImporter.fromUrl(feedUrl, options); + this.urls.push(...imported); + return this; + } + + /** Import URLs from an RSS/Atom feed XML string */ + async importFromFeedString(feedXml: string, options?: interfaces.IFeedImportOptions): Promise { + const imported = await FeedImporter.fromString(feedXml, options); + this.urls.push(...imported); + return this; + } + + /** Import URLs from a YAML config string */ + async importFromYaml(yamlString: string): Promise { + const imported = await YamlImporter.parseConfig(yamlString); + this.urls.push(...imported); + return this; + } + + /** Import from @tsclass/tsclass IArticle array */ + importFromArticles(articles: plugins.tsclass.content.IArticle[]): this { + for (const article of articles) { + const url: interfaces.ISitemapUrl = { + loc: article.url, + lastmod: article.timestamp ? new Date(article.timestamp) : undefined, + }; + this.urls.push(url); + } + return this; + } + + // ────────────────────────────────────────────── + // Output + // ────────────────────────────────────────────── + + /** Export as sitemap XML string */ + toXml(): string { + return XmlRenderer.renderUrlset(this.urls, this.options); + } + + /** Export as plain text (one URL per line) */ + toTxt(): string { + return XmlRenderer.renderTxt(this.urls); + } + + /** Export as JSON string */ + toJson(): string { + return XmlRenderer.renderJson(this.urls); + } + + /** Export as gzipped XML buffer */ + async toGzipBuffer(): Promise { + const xml = this.toXml(); + const gzip = plugins.promisify(plugins.zlib.gzip); + return gzip(Buffer.from(xml, 'utf-8')) as Promise; + } + + /** + * Export with automatic index splitting. + * If URL count exceeds maxUrlsPerSitemap, returns a sitemap index + * plus individual sitemap chunks. + */ + toSitemapSet(): interfaces.ISitemapSet { + const maxUrls = Math.min(this.options.maxUrlsPerSitemap ?? 50000, 50000); + + if (this.urls.length <= maxUrls) { + return { + needsIndex: false, + indexXml: null, + sitemaps: [{ filename: 'sitemap.xml', xml: this.toXml() }], + }; + } + + // Split into chunks + const chunks: interfaces.ISitemapUrl[][] = []; + for (let i = 0; i < this.urls.length; i += maxUrls) { + chunks.push(this.urls.slice(i, i + maxUrls)); + } + + const baseUrl = this.options.baseUrl || ''; + const sitemaps: Array<{ filename: string; xml: string }> = []; + const indexEntries: Array<{ loc: string; lastmod?: string }> = []; + + for (let i = 0; i < chunks.length; i++) { + const filename = `sitemap-${i + 1}.xml`; + const xml = XmlRenderer.renderUrlset(chunks[i], this.options); + sitemaps.push({ filename, xml }); + indexEntries.push({ + loc: baseUrl ? `${baseUrl.replace(/\/$/, '')}/${filename}` : filename, + }); + } + + const indexXml = XmlRenderer.renderIndex(indexEntries, this.options); + + return { + needsIndex: true, + indexXml, + sitemaps, + }; + } + + /** Create a Node.js Readable stream for large sitemaps */ + toStream(): SitemapStream { + // Lazy import to avoid circular dependency issues at module level + const { SitemapStream: SitemapStreamClass } = require('./smartsitemap.classes.sitemapstream.js'); + const stream = new SitemapStreamClass(this.options); + // Push all URLs into the stream asynchronously + process.nextTick(() => { + for (const url of this.urls) { + stream.pushUrl(url); + } + stream.finish(); + }); + return stream; + } + + // ────────────────────────────────────────────── + // Inspection + // ────────────────────────────────────────────── + + /** Get the raw URL array */ + getUrls(): interfaces.ISitemapUrl[] { + return [...this.urls]; + } + + /** Get the number of URLs */ + get count(): number { + return this.urls.length; + } + + /** Validate this sitemap against the protocol specification */ + validate(): interfaces.IValidationResult { + return SitemapValidator.validateUrlset(this.urls, this.options); + } + + /** Get statistics about this sitemap */ + stats(): interfaces.ISitemapStats { + return SitemapValidator.computeStats(this.urls, this.options); + } + + /** Get the options for this builder */ + getOptions(): interfaces.ISitemapOptions { + return { ...this.options }; + } +} diff --git a/ts/smartsitemap.classes.validator.ts b/ts/smartsitemap.classes.validator.ts new file mode 100644 index 0000000..8248ec5 --- /dev/null +++ b/ts/smartsitemap.classes.validator.ts @@ -0,0 +1,289 @@ +import type * as interfaces from './interfaces/index.js'; + +const VALID_CHANGEFREQS: interfaces.TChangeFreq[] = [ + 'always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never', +]; + +const MAX_URL_LENGTH = 2048; +const MAX_URLS_PER_SITEMAP = 50000; +const MAX_SITEMAP_SIZE_BYTES = 52_428_800; // 50 MB +const MAX_IMAGES_PER_URL = 1000; +const MAX_VIDEO_TAGS = 32; +const MAX_VIDEO_DURATION = 28800; +const MAX_VIDEO_DESCRIPTION_LENGTH = 2048; + +/** + * Validates sitemap URLs and fields against the sitemap protocol specification. + */ +export class SitemapValidator { + /** + * Validate a single URL entry. + */ + static validateUrl(url: interfaces.ISitemapUrl): interfaces.IValidationError[] { + const errors: interfaces.IValidationError[] = []; + + // loc is required + if (!url.loc) { + errors.push({ field: 'loc', message: 'URL loc is required', url: url.loc }); + } else { + errors.push(...SitemapValidator.validateUrlString(url.loc)); + } + + // priority range + if (url.priority != null && (url.priority < 0 || url.priority > 1)) { + errors.push({ + field: 'priority', + message: 'Priority must be between 0.0 and 1.0', + url: url.loc, + }); + } + + // changefreq + if (url.changefreq && !VALID_CHANGEFREQS.includes(url.changefreq)) { + errors.push({ + field: 'changefreq', + message: `Invalid changefreq "${url.changefreq}". Must be one of: ${VALID_CHANGEFREQS.join(', ')}`, + url: url.loc, + }); + } + + // lastmod date validation + if (url.lastmod != null) { + const date = url.lastmod instanceof Date ? url.lastmod : new Date(url.lastmod as any); + if (isNaN(date.getTime())) { + errors.push({ + field: 'lastmod', + message: `Invalid lastmod date: "${url.lastmod}"`, + url: url.loc, + }); + } + } + + // Images + if (url.images) { + if (url.images.length > MAX_IMAGES_PER_URL) { + errors.push({ + field: 'images', + message: `Maximum ${MAX_IMAGES_PER_URL} images per URL, got ${url.images.length}`, + url: url.loc, + }); + } + for (const img of url.images) { + if (!img.loc) { + errors.push({ field: 'image:loc', message: 'Image loc is required', url: url.loc }); + } + } + } + + // Videos + if (url.videos) { + for (const vid of url.videos) { + if (!vid.thumbnailLoc) { + errors.push({ field: 'video:thumbnail_loc', message: 'Video thumbnail_loc is required', url: url.loc }); + } + if (!vid.title) { + errors.push({ field: 'video:title', message: 'Video title is required', url: url.loc }); + } + if (!vid.description) { + errors.push({ field: 'video:description', message: 'Video description is required', url: url.loc }); + } + if (vid.description && vid.description.length > MAX_VIDEO_DESCRIPTION_LENGTH) { + errors.push({ + field: 'video:description', + message: `Video description exceeds ${MAX_VIDEO_DESCRIPTION_LENGTH} chars`, + url: url.loc, + }); + } + if (!vid.contentLoc && !vid.playerLoc) { + errors.push({ + field: 'video:content_loc', + message: 'Video must have at least one of contentLoc or playerLoc', + url: url.loc, + }); + } + if (vid.duration != null && (vid.duration < 1 || vid.duration > MAX_VIDEO_DURATION)) { + errors.push({ + field: 'video:duration', + message: `Video duration must be 1–${MAX_VIDEO_DURATION} seconds`, + url: url.loc, + }); + } + if (vid.rating != null && (vid.rating < 0 || vid.rating > 5)) { + errors.push({ + field: 'video:rating', + message: 'Video rating must be 0.0–5.0', + url: url.loc, + }); + } + if (vid.tags && vid.tags.length > MAX_VIDEO_TAGS) { + errors.push({ + field: 'video:tag', + message: `Maximum ${MAX_VIDEO_TAGS} video tags, got ${vid.tags.length}`, + url: url.loc, + }); + } + } + } + + // News + if (url.news) { + if (!url.news.publication?.name) { + errors.push({ field: 'news:publication:name', message: 'News publication name is required', url: url.loc }); + } + if (!url.news.publication?.language) { + errors.push({ field: 'news:publication:language', message: 'News publication language is required', url: url.loc }); + } + if (!url.news.title) { + errors.push({ field: 'news:title', message: 'News title is required', url: url.loc }); + } + if (url.news.publicationDate == null) { + errors.push({ field: 'news:publication_date', message: 'News publication date is required', url: url.loc }); + } + } + + // Alternates + if (url.alternates) { + for (const alt of url.alternates) { + if (!alt.hreflang) { + errors.push({ field: 'xhtml:link:hreflang', message: 'Alternate hreflang is required', url: url.loc }); + } + if (!alt.href) { + errors.push({ field: 'xhtml:link:href', message: 'Alternate href is required', url: url.loc }); + } + } + } + + return errors; + } + + /** + * Validate an entire URL array. + */ + static validateUrlset(urls: interfaces.ISitemapUrl[], options?: interfaces.ISitemapOptions): interfaces.IValidationResult { + const errors: interfaces.IValidationError[] = []; + const warnings: interfaces.IValidationWarning[] = []; + + for (const url of urls) { + errors.push(...SitemapValidator.validateUrl(url)); + } + + // Check for duplicates + const locs = new Set(); + for (const url of urls) { + if (locs.has(url.loc)) { + warnings.push({ + field: 'loc', + message: `Duplicate URL: "${url.loc}"`, + url: url.loc, + }); + } + locs.add(url.loc); + } + + const maxUrls = options?.maxUrlsPerSitemap ?? MAX_URLS_PER_SITEMAP; + + // Size limit warnings + if (urls.length > maxUrls) { + warnings.push({ + field: 'urlset', + message: `URL count (${urls.length}) exceeds maximum of ${maxUrls} per sitemap. Use toSitemapSet() for auto-splitting.`, + }); + } + + const stats = SitemapValidator.computeStats(urls, options); + + return { + valid: errors.length === 0, + errors, + warnings, + stats, + }; + } + + /** + * Validate a URL string for proper format. + */ + static validateUrlString(url: string): interfaces.IValidationError[] { + const errors: interfaces.IValidationError[] = []; + + if (url.length > MAX_URL_LENGTH) { + errors.push({ + field: 'loc', + message: `URL exceeds maximum length of ${MAX_URL_LENGTH} characters`, + url, + }); + } + + try { + new URL(url); + } catch { + errors.push({ + field: 'loc', + message: `Invalid URL: "${url}"`, + url, + }); + } + + return errors; + } + + /** + * Compute statistics for a set of URLs. + */ + static computeStats(urls: interfaces.ISitemapUrl[], options?: interfaces.ISitemapOptions): interfaces.ISitemapStats { + let imageCount = 0; + let videoCount = 0; + let newsCount = 0; + let alternateCount = 0; + + for (const url of urls) { + if (url.images) imageCount += url.images.length; + if (url.videos) videoCount += url.videos.length; + if (url.news) newsCount++; + if (url.alternates) alternateCount += url.alternates.length; + } + + // Rough estimate: ~200 bytes per basic URL entry, more for extensions + const estimatedSizeBytes = + 200 + // XML header + urlset tags + urls.length * 200 + // base URL entries + imageCount * 150 + + videoCount * 400 + + newsCount * 300 + + alternateCount * 100; + + const maxUrls = options?.maxUrlsPerSitemap ?? MAX_URLS_PER_SITEMAP; + + return { + urlCount: urls.length, + imageCount, + videoCount, + newsCount, + alternateCount, + estimatedSizeBytes, + needsIndex: urls.length > maxUrls, + }; + } + + /** + * Check size limits for a URL set. + */ + static checkSizeLimits(urls: interfaces.ISitemapUrl[], options?: interfaces.ISitemapOptions): { + withinLimits: boolean; + urlCount: number; + maxUrls: number; + estimatedSizeBytes: number; + maxSizeBytes: number; + } { + const maxUrls = Math.min(options?.maxUrlsPerSitemap ?? MAX_URLS_PER_SITEMAP, MAX_URLS_PER_SITEMAP); + const stats = SitemapValidator.computeStats(urls, options); + + return { + withinLimits: urls.length <= maxUrls && stats.estimatedSizeBytes <= MAX_SITEMAP_SIZE_BYTES, + urlCount: urls.length, + maxUrls, + estimatedSizeBytes: stats.estimatedSizeBytes, + maxSizeBytes: MAX_SITEMAP_SIZE_BYTES, + }; + } +} diff --git a/ts/smartsitemap.classes.xmlrenderer.ts b/ts/smartsitemap.classes.xmlrenderer.ts new file mode 100644 index 0000000..1e1b939 --- /dev/null +++ b/ts/smartsitemap.classes.xmlrenderer.ts @@ -0,0 +1,294 @@ +import * as plugins from './smartsitemap.plugins.js'; +import type * as interfaces from './interfaces/index.js'; + +// Sitemap XML namespace constants +const NS_SITEMAP = 'http://www.sitemaps.org/schemas/sitemap/0.9'; +const NS_IMAGE = 'http://www.google.com/schemas/sitemap-image/1.1'; +const NS_VIDEO = 'http://www.google.com/schemas/sitemap-video/1.1'; +const NS_NEWS = 'http://www.google.com/schemas/sitemap-news/0.9'; +const NS_XHTML = 'http://www.w3.org/1999/xhtml'; + +/** + * Handles all XML generation for sitemaps. + * Supports proper escaping, namespace detection, date formatting, + * XSL stylesheet references, and pretty printing. + */ +export class XmlRenderer { + /** + * Escape a string for use in XML content. + * Handles the 5 XML special characters. + */ + static escapeXml(str: string): string { + return str + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + } + + /** + * Format a date value (Date, ISO string, or Unix timestamp in ms) + * to W3C Datetime format suitable for sitemaps. + */ + static formatDate(date: Date | string | number): string { + if (date instanceof Date) { + return date.toISOString(); + } + if (typeof date === 'number') { + return new Date(date).toISOString(); + } + // Already a string — validate it parses + const parsed = new Date(date); + if (isNaN(parsed.getTime())) { + return date; // Return as-is if unparseable + } + return parsed.toISOString(); + } + + /** + * Detect which XML namespaces are needed based on URL entries. + */ + static detectNamespaces(urls: interfaces.ISitemapUrl[]): Record { + const ns: Record = { + '@_xmlns': NS_SITEMAP, + }; + + for (const url of urls) { + if (url.images && url.images.length > 0) { + ns['@_xmlns:image'] = NS_IMAGE; + } + if (url.videos && url.videos.length > 0) { + ns['@_xmlns:video'] = NS_VIDEO; + } + if (url.news) { + ns['@_xmlns:news'] = NS_NEWS; + } + if (url.alternates && url.alternates.length > 0) { + ns['@_xmlns:xhtml'] = NS_XHTML; + } + } + + return ns; + } + + /** + * Render a URL array to sitemap XML string. + */ + static renderUrlset(urls: interfaces.ISitemapUrl[], options?: interfaces.ISitemapOptions): string { + const namespaces = XmlRenderer.detectNamespaces(urls); + const urlElements = urls.map((url) => XmlRenderer.buildUrlElement(url, options)); + + const xmlObj: any = { + urlset: { + ...namespaces, + url: urlElements, + }, + }; + + const smartXml = new plugins.smartxml.SmartXml(); + let xml = smartXml.createXmlFromObject(xmlObj); + + // Insert XSL stylesheet processing instruction if specified + if (options?.xslUrl) { + xml = XmlRenderer.insertXslInstruction(xml, options.xslUrl); + } + + return xml; + } + + /** + * Render a sitemap index XML string. + */ + static renderIndex(entries: interfaces.ISitemapIndexEntry[], options?: interfaces.ISitemapOptions): string { + const sitemapElements = entries.map((entry) => { + const el: any = { + loc: XmlRenderer.escapeXml(entry.loc), + }; + if (entry.lastmod != null) { + el.lastmod = XmlRenderer.formatDate(entry.lastmod); + } + return el; + }); + + const xmlObj: any = { + sitemapindex: { + '@_xmlns': NS_SITEMAP, + sitemap: sitemapElements, + }, + }; + + const smartXml = new plugins.smartxml.SmartXml(); + let xml = smartXml.createXmlFromObject(xmlObj); + + if (options?.xslUrl) { + xml = XmlRenderer.insertXslInstruction(xml, options.xslUrl); + } + + return xml; + } + + /** + * Render URLs as plain text (one URL per line). + */ + static renderTxt(urls: interfaces.ISitemapUrl[]): string { + return urls.map((u) => u.loc).join('\n'); + } + + /** + * Render URLs as JSON. + */ + static renderJson(urls: interfaces.ISitemapUrl[]): string { + return JSON.stringify(urls, null, 2); + } + + /** + * Build a single element object for use with smartxml. + */ + private static buildUrlElement(url: interfaces.ISitemapUrl, options?: interfaces.ISitemapOptions): any { + const el: any = { + loc: XmlRenderer.escapeXml(url.loc), + }; + + // lastmod + if (url.lastmod != null) { + el.lastmod = XmlRenderer.formatDate(url.lastmod); + } + + // changefreq (use default if not specified) + const changefreq = url.changefreq ?? options?.defaultChangeFreq; + if (changefreq) { + el.changefreq = changefreq; + } + + // priority (use default if not specified) + const priority = url.priority ?? options?.defaultPriority; + if (priority != null) { + el.priority = priority.toFixed(1); + } + + // Image extension + if (url.images && url.images.length > 0) { + el['image:image'] = url.images.map((img) => XmlRenderer.buildImageElement(img)); + } + + // Video extension + if (url.videos && url.videos.length > 0) { + el['video:video'] = url.videos.map((vid) => XmlRenderer.buildVideoElement(vid)); + } + + // News extension + if (url.news) { + el['news:news'] = XmlRenderer.buildNewsElement(url.news); + } + + // hreflang alternates + if (url.alternates && url.alternates.length > 0) { + el['xhtml:link'] = url.alternates.map((alt) => ({ + '@_rel': 'alternate', + '@_hreflang': alt.hreflang, + '@_href': XmlRenderer.escapeXml(alt.href), + })); + } + + return el; + } + + /** + * Build an element object. + */ + private static buildImageElement(img: interfaces.ISitemapImage): any { + const el: any = { + 'image:loc': XmlRenderer.escapeXml(img.loc), + }; + if (img.caption) { + el['image:caption'] = XmlRenderer.escapeXml(img.caption); + } + if (img.title) { + el['image:title'] = XmlRenderer.escapeXml(img.title); + } + if (img.geoLocation) { + el['image:geo_location'] = XmlRenderer.escapeXml(img.geoLocation); + } + if (img.licenseUrl) { + el['image:license'] = XmlRenderer.escapeXml(img.licenseUrl); + } + return el; + } + + /** + * Build a element object. + */ + private static buildVideoElement(vid: interfaces.ISitemapVideo): any { + const el: any = { + 'video:thumbnail_loc': XmlRenderer.escapeXml(vid.thumbnailLoc), + 'video:title': XmlRenderer.escapeXml(vid.title), + 'video:description': XmlRenderer.escapeXml(vid.description), + }; + + if (vid.contentLoc) { + el['video:content_loc'] = XmlRenderer.escapeXml(vid.contentLoc); + } + if (vid.playerLoc) { + el['video:player_loc'] = XmlRenderer.escapeXml(vid.playerLoc); + } + if (vid.duration != null) { + el['video:duration'] = vid.duration; + } + if (vid.rating != null) { + el['video:rating'] = vid.rating; + } + if (vid.viewCount != null) { + el['video:view_count'] = vid.viewCount; + } + if (vid.publicationDate != null) { + el['video:publication_date'] = XmlRenderer.formatDate(vid.publicationDate); + } + if (vid.familyFriendly != null) { + el['video:family_friendly'] = vid.familyFriendly ? 'yes' : 'no'; + } + if (vid.tags && vid.tags.length > 0) { + el['video:tag'] = vid.tags; + } + if (vid.live != null) { + el['video:live'] = vid.live ? 'yes' : 'no'; + } + if (vid.requiresSubscription != null) { + el['video:requires_subscription'] = vid.requiresSubscription ? 'yes' : 'no'; + } + + return el; + } + + /** + * Build a element object. + */ + private static buildNewsElement(news: interfaces.ISitemapNews): any { + const el: any = { + 'news:publication': { + 'news:name': XmlRenderer.escapeXml(news.publication.name), + 'news:language': news.publication.language, + }, + 'news:publication_date': XmlRenderer.formatDate(news.publicationDate), + 'news:title': XmlRenderer.escapeXml(news.title), + }; + + if (news.keywords) { + const kw = Array.isArray(news.keywords) ? news.keywords.join(', ') : news.keywords; + el['news:keywords'] = XmlRenderer.escapeXml(kw); + } + + return el; + } + + /** + * Insert an XSL stylesheet processing instruction after the XML declaration. + */ + private static insertXslInstruction(xml: string, xslUrl: string): string { + const pi = ``; + return xml.replace( + '', + `\n${pi}`, + ); + } +} diff --git a/ts/smartsitemap.classes.yamlimporter.ts b/ts/smartsitemap.classes.yamlimporter.ts new file mode 100644 index 0000000..8e1a18e --- /dev/null +++ b/ts/smartsitemap.classes.yamlimporter.ts @@ -0,0 +1,61 @@ +import * as plugins from './smartsitemap.plugins.js'; +import type * as interfaces from './interfaces/index.js'; + +/** + * Imports sitemap configuration from YAML format. + * Supports the enhanced YAML schema with per-frequency URL groups, + * default settings, and feed imports. + */ +export class YamlImporter { + /** + * Parse a YAML config string and return ISitemapUrl entries. + */ + static async parseConfig(yamlString: string): Promise { + const config = (await plugins.smartyaml.yamlStringToObject(yamlString)) as interfaces.ISitemapYamlConfig; + const urls: interfaces.ISitemapUrl[] = []; + const baseUrl = config.baseUrl?.replace(/\/$/, '') ?? ''; + + // Process URL groups by frequency + if (config.urls) { + const frequencies: interfaces.TChangeFreq[] = [ + 'always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never', + ]; + + for (const freq of frequencies) { + const urlList = config.urls[freq]; + if (urlList && Array.isArray(urlList)) { + for (const path of urlList) { + const loc = path.startsWith('http') ? path : `${baseUrl}${path.startsWith('/') ? '' : '/'}${path}`; + urls.push({ + loc, + changefreq: freq, + priority: config.defaults?.priority, + }); + } + } + } + } + + // Process feed imports + if (config.feeds && Array.isArray(config.feeds)) { + // Dynamic import to avoid circular deps at module load time + const { FeedImporter } = await import('./smartsitemap.classes.feedimporter.js'); + + for (const feedConfig of config.feeds) { + if (feedConfig.type === 'news') { + const newsUrls = await FeedImporter.fromUrlAsNews( + feedConfig.url, + feedConfig.publicationName ?? 'Unknown', + feedConfig.publicationLanguage ?? 'en', + ); + urls.push(...newsUrls); + } else { + const standardUrls = await FeedImporter.fromUrl(feedConfig.url); + urls.push(...standardUrls); + } + } + } + + return urls; + } +} diff --git a/ts/smartsitemap.plugins.ts b/ts/smartsitemap.plugins.ts index 364bce7..1b11acd 100644 --- a/ts/smartsitemap.plugins.ts +++ b/ts/smartsitemap.plugins.ts @@ -1,11 +1,17 @@ +// node built-ins +import * as zlib from 'zlib'; +import { promisify } from 'util'; +import { Readable } from 'stream'; + +export { zlib, promisify, Readable }; + // pushrocks scope -import * as smartcache from '@push.rocks/smartcache'; import * as smartfeed from '@push.rocks/smartfeed'; import * as smartxml from '@push.rocks/smartxml'; import * as smartyaml from '@push.rocks/smartyaml'; import * as webrequest from '@push.rocks/webrequest'; -export { smartcache, smartfeed, smartxml, smartyaml, webrequest }; +export { smartfeed, smartxml, smartyaml, webrequest }; // tsclass import * as tsclass from '@tsclass/tsclass';