diff --git a/.c8rc.json b/.c8rc.json index 3c63a3ff..f25598c3 100644 --- a/.c8rc.json +++ b/.c8rc.json @@ -5,6 +5,7 @@ "**/fixtures", "src/generators/legacy-html/assets", "src/generators/web/ui", - "**/*.d.ts" + "**/*.d.ts", + "tools/" ] } diff --git a/package-lock.json b/package-lock.json index f5584d29..c1a606e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "globals": "^16.4.0", "hast-util-to-string": "^3.0.1", "hastscript": "^9.0.1", + "jsonc-parser": "^3.3.1", "lightningcss": "^1.30.1", "mdast-util-slice-markdown": "^2.0.1", "preact": "^10.27.2", @@ -66,6 +67,8 @@ "eslint-plugin-import-x": "^4.16.1", "eslint-plugin-jsdoc": "^60.5.0", "husky": "^9.1.7", + "json-schema-to-typescript": "^15.0.4", + "jsonschema": "^1.5.0", "lint-staged": "^16.2.3", "prettier": "3.6.2" } @@ -117,6 +120,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "11.9.3", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.9.3.tgz", + "integrity": "sha512-60vepv88RwcJtSHrD6MjIL6Ta3SOYbgfnkHb+ppAVK+o9mXprRtulx7VlRl3lN3bbvysAfCS7WMVfhUYemB0IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.15", + "js-yaml": "^4.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/philsturgeon" + } + }, "node_modules/@bcoe/v8-coverage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", @@ -180,17 +201,17 @@ } }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.62.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.62.0.tgz", - "integrity": "sha512-yWi6sm7INEwnfS7IJvE0dU+RTrwzLPFcY7e7eGpu/l5Q9lWfQ2ROwZ0qVnc242jw2TUPsfHX3XMIISkGBv57RQ==", + "version": "0.68.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.68.1.tgz", + "integrity": "sha512-wJJXnfG2Pq7ZC8IeOupkkAVtEH6OYy1uVxRTeshXDQfSNsZneS7FUQlNf710osZ5Yz/b5ev9xChvybTT7CM63g==", "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.8", - "@typescript-eslint/types": "^8.44.1", + "@typescript-eslint/types": "^8.45.0", "comment-parser": "1.4.1", "esquery": "^1.6.0", - "jsdoc-type-pratt-parser": "~5.9.0" + "jsdoc-type-pratt-parser": "6.3.3" }, "engines": { "node": ">=20.11.0" @@ -236,39 +257,36 @@ } }, "node_modules/@eslint-react/ast": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@eslint-react/ast/-/ast-2.0.1.tgz", - "integrity": "sha512-YUY1QsaDAOOc4fOGHIT5uIQUg14yAbYLXPhcP1cufbbhdf3VU7eGtbw/VeFIkJIPRyIPJYV0cSHW+e8jZUyPGQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@eslint-react/ast/-/ast-2.0.6.tgz", + "integrity": "sha512-i72EzCOYQo+CKnxKRPuguRM0FPIpA/ojDhK0XZI++nO6fG67ggKMSf2DZTIbScus30GsluhaYLpN8R2rppeVJA==", "license": "MIT", "dependencies": { - "@eslint-react/eff": "2.0.1", - "@typescript-eslint/types": "^8.44.1", - "@typescript-eslint/typescript-estree": "^8.44.1", - "@typescript-eslint/utils": "^8.44.1", - "string-ts": "^2.2.1", - "ts-pattern": "^5.8.0" + "@eslint-react/eff": "2.0.6", + "@typescript-eslint/types": "^8.45.0", + "@typescript-eslint/typescript-estree": "^8.45.0", + "@typescript-eslint/utils": "^8.45.0", + "string-ts": "^2.2.1" }, "engines": { "node": ">=20.19.0" } }, "node_modules/@eslint-react/core": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@eslint-react/core/-/core-2.0.1.tgz", - "integrity": "sha512-KzLiClAChDiw2O+sCiDsi/I1hIfJwxnJwNXp1/EzWyZq1Qgn+M1iuesZve2j2RoJv2dz18ItpkT/Tc36hGIJwA==", - "license": "MIT", - "dependencies": { - "@eslint-react/ast": "2.0.1", - "@eslint-react/eff": "2.0.1", - "@eslint-react/kit": "2.0.1", - "@eslint-react/shared": "2.0.1", - "@eslint-react/var": "2.0.1", - "@typescript-eslint/scope-manager": "^8.44.1", - "@typescript-eslint/type-utils": "^8.44.1", - "@typescript-eslint/types": "^8.44.1", - "@typescript-eslint/utils": "^8.44.1", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@eslint-react/core/-/core-2.0.6.tgz", + "integrity": "sha512-VbyrfHT3CK22WrYszjXR38tWudlkwDn1G72i/qArWIDppJCFCxfUfNvpM63TaPEUjY/fWWLfsDn9DWltpAvuYw==", + "license": "MIT", + "dependencies": { + "@eslint-react/ast": "2.0.6", + "@eslint-react/eff": "2.0.6", + "@eslint-react/kit": "2.0.6", + "@eslint-react/shared": "2.0.6", + "@eslint-react/var": "2.0.6", + "@typescript-eslint/scope-manager": "^8.45.0", + "@typescript-eslint/types": "^8.45.0", + "@typescript-eslint/utils": "^8.45.0", "birecord": "^0.1.1", - "ts-api-utils": "^2.1.0", "ts-pattern": "^5.8.0" }, "engines": { @@ -276,47 +294,36 @@ } }, "node_modules/@eslint-react/eff": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@eslint-react/eff/-/eff-2.0.1.tgz", - "integrity": "sha512-VnC5F/8coRS2XuI82cxREw8HeEdxnNl9Ri1flkjZIl6q2geidTb3CVmbep+1NujwEOGe+z4B+8lA/rCeyAGhoQ==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@eslint-react/eff/-/eff-2.0.6.tgz", + "integrity": "sha512-hBXZg93uB8L8UxjAbgSMQA/27qKeNokXy3Dfkhr6I2gQ4A+IjdXBqbI6hHGlyxyGRmkUpk3RLDELZ/0uqqtysg==", "license": "MIT", "engines": { "node": ">=20.19.0" } }, "node_modules/@eslint-react/kit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@eslint-react/kit/-/kit-2.0.1.tgz", - "integrity": "sha512-LEtDYjYhI2A3oG0BesJlU7z3bgMV86kaGuMBIZByuYQmeCVkV0tkvPwMmOJf2kLeJeG9d58Cn691DGl7XXz54g==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@eslint-react/kit/-/kit-2.0.6.tgz", + "integrity": "sha512-7Vz4GcKAsUVwpJMBBxEiHI/kXfUlTTTN71YGmvbgBsHpsXRQRQC1+yl3Q3FNsabd8909ww1eay2uIuigfVUkaQ==", "license": "MIT", "dependencies": { - "@eslint-react/eff": "2.0.1", - "@typescript-eslint/utils": "^8.44.1", - "ts-pattern": "^5.8.0", - "zod": "^4.1.11" + "@eslint-react/eff": "2.0.6", + "@typescript-eslint/utils": "^8.45.0" }, "engines": { "node": ">=20.19.0" } }, - "node_modules/@eslint-react/kit/node_modules/zod": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.11.tgz", - "integrity": "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/@eslint-react/shared": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@eslint-react/shared/-/shared-2.0.1.tgz", - "integrity": "sha512-/E4mHZKCWh+hJ4cbLWqqDx5IMFloTBMEoxiecpAvC1zJQpx0xdAYOZPOPiUPLbyD+v86ho2UUICgbvvCErULyg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@eslint-react/shared/-/shared-2.0.6.tgz", + "integrity": "sha512-yhRcipMwhzhYuJMWXHZVVnlAPntpMSUIvMtUYvplKeQvnEX+/awWobZSKqxWzB2QouBWSo5W3Sp2kb4vZonsig==", "license": "MIT", "dependencies": { - "@eslint-react/eff": "2.0.1", - "@eslint-react/kit": "2.0.1", - "@typescript-eslint/utils": "^8.44.1", + "@eslint-react/eff": "2.0.6", + "@eslint-react/kit": "2.0.6", + "@typescript-eslint/utils": "^8.45.0", "ts-pattern": "^5.8.0", "zod": "^4.1.11" }, @@ -324,27 +331,17 @@ "node": ">=20.19.0" } }, - "node_modules/@eslint-react/shared/node_modules/zod": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.11.tgz", - "integrity": "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/@eslint-react/var": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@eslint-react/var/-/var-2.0.1.tgz", - "integrity": "sha512-Qc8dbg21Bg6SyN5EKeZYmwJPPfxXh8PbRRvleXeIzC7AbAsyjX+MsZ7W04AUkoE9/46o/+CaFPjN+gCUlQY15Q==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@eslint-react/var/-/var-2.0.6.tgz", + "integrity": "sha512-fWx7HZ4vpm3woyoclxbtN/Swz7Qgm4LU3mYDs+pHj4ZSOvtqPCTOACMIFR/MwRwEWBAthUyMMZfxFpWz/8RJmA==", "license": "MIT", "dependencies": { - "@eslint-react/ast": "2.0.1", - "@eslint-react/eff": "2.0.1", - "@typescript-eslint/scope-manager": "^8.44.1", - "@typescript-eslint/types": "^8.44.1", - "@typescript-eslint/utils": "^8.44.1", - "string-ts": "^2.2.1", + "@eslint-react/ast": "2.0.6", + "@eslint-react/eff": "2.0.6", + "@typescript-eslint/scope-manager": "^8.45.0", + "@typescript-eslint/types": "^8.45.0", + "@typescript-eslint/utils": "^8.45.0", "ts-pattern": "^5.8.0" }, "engines": { @@ -355,6 +352,7 @@ "version": "0.21.0", "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", + "license": "Apache-2.0", "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", @@ -365,18 +363,21 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", - "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.0.tgz", + "integrity": "sha512-WUFvV4WoIwW8Bv0KeKCIIEgdSiFOsulyN0xrMu+7z43q/hkOLXjvb5u7UC9jDxvRzcrbEmuZBX5yJZz1741jog==", "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.16.0" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", - "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz", + "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==", "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" @@ -421,9 +422,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.36.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.36.0.tgz", - "integrity": "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==", + "version": "9.37.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.37.0.tgz", + "integrity": "sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -436,17 +437,18 @@ "version": "2.1.6", "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", - "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz", + "integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==", "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.15.2", + "@eslint/core": "^0.16.0", "levn": "^0.4.1" }, "engines": { @@ -519,31 +521,18 @@ } }, "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", "license": "Apache-2.0", "dependencies": { "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" + "@humanwhocodes/retry": "^0.4.0" }, "engines": { "node": ">=18.18.0" } }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -558,9 +547,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", - "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "license": "Apache-2.0", "engines": { "node": ">=18.18" @@ -574,6 +563,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "license": "MIT", "engines": { "node": "20 || >=22" } @@ -582,6 +572,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "license": "MIT", "dependencies": { "@isaacs/balanced-match": "^4.0.1" }, @@ -664,37 +655,44 @@ "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", + "dev": true, + "license": "MIT" + }, "node_modules/@lit-labs/ssr-dom-shim": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.3.0.tgz", - "integrity": "sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.4.0.tgz", + "integrity": "sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==", "license": "BSD-3-Clause" }, "node_modules/@lit/react": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@lit/react/-/react-1.0.7.tgz", - "integrity": "sha512-cencnwwLXQKiKxjfFzSgZRngcWJzUDZi/04E0fSaF86wZgchMdvTyu+lE36DrUfvuus3bH8+xLPrhM1cTjwpzw==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@lit/react/-/react-1.0.8.tgz", + "integrity": "sha512-p2+YcF+JE67SRX3mMlJ1TKCSTsgyOVdAwd/nxp3NuV1+Cb6MWALbN6nT7Ld4tpmYofcE5kcaSY1YBB9erY+6fw==", "license": "BSD-3-Clause", "peerDependencies": { "@types/react": "17 || 18 || 19" } }, "node_modules/@lit/reactive-element": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.0.tgz", - "integrity": "sha512-L2qyoZSQClcBmq0qajBVbhYEcG6iK0XfLn66ifLe/RfC0/ihpc+pl0Wdn8bJ8o+hj38cG0fGXRgSS20MuXn7qA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.1.tgz", + "integrity": "sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==", "license": "BSD-3-Clause", "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.2.0" + "@lit-labs/ssr-dom-shim": "^1.4.0" } }, "node_modules/@minify-html/node": { @@ -777,15 +775,15 @@ ] }, "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.6.tgz", + "integrity": "sha512-DXj75ewm11LIWUk198QSKUTxjyRjsBwk09MuMk5DGK+GDUtyPhhEHOGP/Xwwj3DjQXXkivoBirmOnKrLfc0+9g==", "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@tybys/wasm-util": "^0.10.1" } }, "node_modules/@noble/hashes": { @@ -1207,6 +1205,24 @@ "@types/hast": "^3.0.4" } }, + "node_modules/@orama/wc-components/node_modules/zod": { + "version": "3.24.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.3.tgz", + "integrity": "sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@orama/wc-components/node_modules/zod-to-json-schema": { + "version": "3.24.5", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", + "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.24.1" + } + }, "node_modules/@oramacloud/client": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@oramacloud/client/-/client-2.1.4.tgz", @@ -1219,9 +1235,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.92.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.92.0.tgz", - "integrity": "sha512-PDLfCbwgXjGdTBxzcuDOUxJYNBl6P8dOp3eDKWw54dYvqONan9rwGDRQU0zrkdEMiItfXQQUOI17uOcMX5Zm7A==", + "version": "0.93.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.93.0.tgz", + "integrity": "sha512-yNtwmWZIBtJsMr5TEfoZFDxIWV6OdScOpza/f5YxbqUMJk+j6QX3Cf3jgZShGEFYWQJ5j9mJ6jM0tZHu2J9Yrg==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/Boshen" @@ -2104,9 +2120,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.40.tgz", - "integrity": "sha512-9Ii9phC7QU6Lb+ncMfG1Xlosq0NBB1N/4sw+EGZ3y0BBWGy02TOb5ghWZalphAKv9rn1goqo5WkBjyd2YvsLmA==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.41.tgz", + "integrity": "sha512-Edflndd9lU7JVhVIvJlZhdCj5DkhYDJPIRn4Dx0RUdfc8asP9xHOI5gMd8MesDDx+BJpdIT/uAmVTearteU/mQ==", "cpu": [ "arm64" ], @@ -2120,9 +2136,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.40.tgz", - "integrity": "sha512-5O6d0y2tBQTL+ecQY3qXIwSnF1/Zik8q7LZMKeyF+VJ9l194d0IdMhl2zUF0cqWbYHuF4Pnxplk4OhurPQ/Z9Q==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.41.tgz", + "integrity": "sha512-XGCzqfjdk7550PlyZRTBKbypXrB7ATtXhw/+bjtxnklLQs0mKP/XkQVOKyn9qGKSlvH8I56JLYryVxl0PCvSNw==", "cpu": [ "arm64" ], @@ -2136,9 +2152,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.40.tgz", - "integrity": "sha512-izB9jygt3miPQbOTZfSu5K51isUplqa8ysByOKQqcJHgrBWmbTU8TM9eouv6tRmBR0kjcEcID9xhmA1CeZ1VIg==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.41.tgz", + "integrity": "sha512-Ho6lIwGJed98zub7n0xcRKuEtnZgbxevAmO4x3zn3C3N4GVXZD5xvCvTVxSMoeBJwTcIYzkVDRTIhylQNsTgLQ==", "cpu": [ "x64" ], @@ -2152,9 +2168,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.40.tgz", - "integrity": "sha512-2fdpEpKT+wwP0vig9dqxu+toTeWmVSjo3psJQVDeLJ51rO+GXcCJ1IkCXjhMKVEevNtZS7B8T8Z2vvmRV9MAdA==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.41.tgz", + "integrity": "sha512-ijAZETywvL+gACjbT4zBnCp5ez1JhTRs6OxRN4J+D6AzDRbU2zb01Esl51RP5/8ZOlvB37xxsRQ3X4YRVyYb3g==", "cpu": [ "x64" ], @@ -2168,9 +2184,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.40.tgz", - "integrity": "sha512-HP2lo78OWULN+8TewpLbS9PS00jh0CaF04tA2u8z2I+6QgVgrYOYKvX+T0hlO5smgso4+qb3YchzumWJl3yCPQ==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.41.tgz", + "integrity": "sha512-EgIOZt7UildXKFEFvaiLNBXm+4ggQyGe3E5Z1QP9uRcJJs9omihOnm897FwOBQdCuMvI49iBgjFrkhH+wMJ2MA==", "cpu": [ "arm" ], @@ -2184,9 +2200,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.40.tgz", - "integrity": "sha512-ng00gfr9BhA2NPAOU5RWAlTiL+JcwAD+L+4yUD1sbBy6tgHdLiNBOvKtHISIF9RM9/eQeS0tAiWOYZGIH9JMew==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.41.tgz", + "integrity": "sha512-F8bUwJq8v/JAU8HSwgF4dztoqJ+FjdyjuvX4//3+Fbe2we9UktFeZ27U4lRMXF1vxWtdV4ey6oCSqI7yUrSEeg==", "cpu": [ "arm64" ], @@ -2200,9 +2216,9 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.40.tgz", - "integrity": "sha512-mF0R1l9kLcaag/9cLEiYYdNZ4v1uuX4jklSDZ1s6vJE4RB3LirUney0FavdVRwCJ5sDvfvsPgXgtBXWYr2M2tQ==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.41.tgz", + "integrity": "sha512-MioXcCIX/wB1pBnBoJx8q4OGucUAfC1+/X1ilKFsjDK05VwbLZGRgOVD5OJJpUQPK86DhQciNBrfOKDiatxNmg==", "cpu": [ "arm64" ], @@ -2216,9 +2232,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.40.tgz", - "integrity": "sha512-+wi08S7wT5iLPHRZb0USrS6n+T6m+yY++dePYedE5uvKIpWCJJioFTaRtWjpm0V6dVNLcq2OukrvfdlGtH9Wgg==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.41.tgz", + "integrity": "sha512-m66M61fizvRCwt5pOEiZQMiwBL9/y0bwU/+Kc4Ce/Pef6YfoEkR28y+DzN9rMdjo8Z28NXjsDPq9nH4mXnAP0g==", "cpu": [ "x64" ], @@ -2232,9 +2248,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.40.tgz", - "integrity": "sha512-W5qBGAemUocIBKCcOsDjlV9GUt28qhl/+M6etWBeLS5gQK0J6XDg0YVzfOQdvq57ZGjYNP0NvhYzqhOOnEx+4g==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.41.tgz", + "integrity": "sha512-yRxlSfBvWnnfrdtJfvi9lg8xfG5mPuyoSHm0X01oiE8ArmLRvoJGHUTJydCYz+wbK2esbq5J4B4Tq9WAsOlP1Q==", "cpu": [ "x64" ], @@ -2248,9 +2264,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-beta.40.tgz", - "integrity": "sha512-vJwoDehtt+yqj2zacq1AqNc2uE/oh7mnRGqAUbuldV6pgvU01OSQUJ7Zu+35hTopnjFoDNN6mIezkYlGAv5RFA==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-beta.41.tgz", + "integrity": "sha512-PHVxYhBpi8UViS3/hcvQQb9RFqCtvFmFU1PvUoTRiUdBtgHA6fONNHU4x796lgzNlVSD3DO/MZNk1s5/ozSMQg==", "cpu": [ "arm64" ], @@ -2264,9 +2280,9 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.40.tgz", - "integrity": "sha512-Oj3YyqVUPurr1FlMpEE/bJmMC+VWAWPM/SGUfklO5KUX97bk5Q/733nPg4RykK8q8/TluJoQYvRc05vL/B74dw==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.41.tgz", + "integrity": "sha512-OAfcO37ME6GGWmj9qTaDT7jY4rM0T2z0/8ujdQIJQ2x2nl+ztO32EIwURfmXOK0U1tzkyuaKYvE34Pug/ucXlQ==", "cpu": [ "wasm32" ], @@ -2279,22 +2295,10 @@ "node": ">=14.0.0" } }, - "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.5.tgz", - "integrity": "sha512-TBr9Cf9onSAS2LQ2+QHx6XcC6h9+RIzJgbqG3++9TUZSH204AwEy5jg3BTQ0VATsyoGj4ee49tN/y6rvaOOtcg==", - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.5.0", - "@emnapi/runtime": "^1.5.0", - "@tybys/wasm-util": "^0.10.1" - } - }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.40.tgz", - "integrity": "sha512-0ZtO6yN8XjVoFfN4HDWQj4nDu3ndMybr7jIM00DJqOmc+yFhly7rdOy7fNR9Sky3leCpBtsXfepVqRmVpYKPVA==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.41.tgz", + "integrity": "sha512-NIYGuCcuXaq5BC4Q3upbiMBvmZsTsEPG9k/8QKQdmrch+ocSy5Jv9tdpdmXJyighKqm182nh/zBt+tSJkYoNlg==", "cpu": [ "arm64" ], @@ -2308,9 +2312,9 @@ } }, "node_modules/@rolldown/binding-win32-ia32-msvc": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.0.0-beta.40.tgz", - "integrity": "sha512-BPl1inoJXPpIe38Ja46E4y11vXlJyuleo+9Rmu//pYL5fIDYJkXUj/oAXqjSuwLcssrcwnuPgzvzvlz9++cr3w==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.0.0-beta.41.tgz", + "integrity": "sha512-kANdsDbE5FkEOb5NrCGBJBCaZ2Sabp3D7d4PRqMYJqyLljwh9mDyYyYSv5+QNvdAmifj+f3lviNEUUuUZPEFPw==", "cpu": [ "ia32" ], @@ -2324,9 +2328,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.40.tgz", - "integrity": "sha512-UguA4ltbAk+nbwHRxqaUP/etpTbR0HjyNlsu4Zjbh/ytNbFsbw8CA4tEBkwDyjgI5NIPea6xY11zpl7R2/ddVA==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.41.tgz", + "integrity": "sha512-UlpxKmFdik0Y2VjZrgUCgoYArZJiZllXgIipdBRV1hw6uK45UbQabSTW6Kp6enuOu7vouYWftwhuxfpE8J2JAg==", "cpu": [ "x64" ], @@ -2340,9 +2344,9 @@ } }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.40.tgz", - "integrity": "sha512-s3GeJKSQOwBlzdUrj4ISjJj5SfSh+aqn0wjOar4Bx95iV1ETI7F6S/5hLcfAxZ9kXDcyrAkxPlqmd1ZITttf+w==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.41.tgz", + "integrity": "sha512-ycMEPrS3StOIeb87BT3/+bu+blEtyvwQ4zmo2IcJQy0Rd1DAAhKksA0iUZ3MYSpJtjlPhg0Eo6mvVS6ggPhRbw==", "license": "MIT" }, "node_modules/@rollup/plugin-virtual": { @@ -2534,9 +2538,9 @@ "license": "MIT" }, "node_modules/@stencil/core": { - "version": "4.35.3", - "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.35.3.tgz", - "integrity": "sha512-RH5/I+amV31QI8TMXhXkAkjzs2eod6Y07jkUYTl9kMB+X7c5wUpv95Y/2LtcAx0Rqdhh4SHbJiwpr0ApBZmv0g==", + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.38.0.tgz", + "integrity": "sha512-oC3QFKO0X1yXVvETgc8OLY525MNKhn9vISBrbtKnGoPlokJ6rI8Vk1RK22TevnNrHLI4SExNLbcDnqilKR35JQ==", "license": "MIT", "peer": true, "bin": { @@ -2586,9 +2590,9 @@ } }, "node_modules/@stencil/store": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@stencil/store/-/store-2.1.3.tgz", - "integrity": "sha512-qeWJisbcafVcAhFZidiqK82ULlgBzPNEhlsm0PZ54FHkNTIomxns2MiI7IOGUvGPumK1WK7KzajRomHHc8SYag==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@stencil/store/-/store-2.2.0.tgz", + "integrity": "sha512-+Ub0n3ghwxjXSGrLJDt6SIKJQhB4ch61KyzNkleIN5IADdhwvT8/9SjwU67hhSEoBTpQ81bVNlhuHSHS97iHbA==", "license": "MIT", "engines": { "node": ">=18.0.0", @@ -2599,58 +2603,286 @@ } }, "node_modules/@tailwindcss/node": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.13.tgz", - "integrity": "sha512-eq3ouolC1oEFOAvOMOBAmfCIqZBJuvWvvYWh5h5iOYfe1HFC6+GZ6EIL0JdM3/niGRJmnrOc+8gl9/HGUaaptw==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.14.tgz", + "integrity": "sha512-hpz+8vFk3Ic2xssIA3e01R6jkmsAhvkQdXlEbRTk6S10xDAtiQiM3FyvZVGsucefq764euO/b8WUW9ysLdThHw==", "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", - "jiti": "^2.5.1", + "jiti": "^2.6.0", "lightningcss": "1.30.1", - "magic-string": "^0.30.18", + "magic-string": "^0.30.19", "source-map-js": "^1.2.1", - "tailwindcss": "4.1.13" + "tailwindcss": "4.1.14" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-darwin-arm64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-darwin-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-freebsd-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@tailwindcss/node/node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, "node_modules/@tailwindcss/node/node_modules/tailwindcss": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.13.tgz", - "integrity": "sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.14.tgz", + "integrity": "sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA==", "license": "MIT" }, "node_modules/@tailwindcss/oxide": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.13.tgz", - "integrity": "sha512-CPgsM1IpGRa880sMbYmG1s4xhAy3xEt1QULgTJGQmZUeNgXFR7s1YxYygmJyBGtou4SyEosGAGEeYqY7R53bIA==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.14.tgz", + "integrity": "sha512-23yx+VUbBwCg2x5XWdB8+1lkPajzLmALEfMb51zZUBYaYVPDQvBSD/WYDqiVyBIo2BZFa3yw1Rpy3G2Jp+K0dw==", "hasInstallScript": true, "license": "MIT", "dependencies": { "detect-libc": "^2.0.4", - "tar": "^7.4.3" + "tar": "^7.5.1" }, "engines": { "node": ">= 10" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.13", - "@tailwindcss/oxide-darwin-arm64": "4.1.13", - "@tailwindcss/oxide-darwin-x64": "4.1.13", - "@tailwindcss/oxide-freebsd-x64": "4.1.13", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.13", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.13", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.13", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.13", - "@tailwindcss/oxide-linux-x64-musl": "4.1.13", - "@tailwindcss/oxide-wasm32-wasi": "4.1.13", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.13", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.13" + "@tailwindcss/oxide-android-arm64": "4.1.14", + "@tailwindcss/oxide-darwin-arm64": "4.1.14", + "@tailwindcss/oxide-darwin-x64": "4.1.14", + "@tailwindcss/oxide-freebsd-x64": "4.1.14", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.14", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.14", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.14", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.14", + "@tailwindcss/oxide-linux-x64-musl": "4.1.14", + "@tailwindcss/oxide-wasm32-wasi": "4.1.14", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.14", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.14" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.13.tgz", - "integrity": "sha512-BrpTrVYyejbgGo57yc8ieE+D6VT9GOgnNdmh5Sac6+t0m+v+sKQevpFVpwX3pBrM2qKrQwJ0c5eDbtjouY/+ew==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.14.tgz", + "integrity": "sha512-a94ifZrGwMvbdeAxWoSuGcIl6/DOP5cdxagid7xJv6bwFp3oebp7y2ImYsnZBMTwjn5Ev5xESvS3FFYUGgPODQ==", "cpu": [ "arm64" ], @@ -2664,9 +2896,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.13.tgz", - "integrity": "sha512-YP+Jksc4U0KHcu76UhRDHq9bx4qtBftp9ShK/7UGfq0wpaP96YVnnjFnj3ZFrUAjc5iECzODl/Ts0AN7ZPOANQ==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.14.tgz", + "integrity": "sha512-HkFP/CqfSh09xCnrPJA7jud7hij5ahKyWomrC3oiO2U9i0UjP17o9pJbxUN0IJ471GTQQmzwhp0DEcpbp4MZTA==", "cpu": [ "arm64" ], @@ -2680,9 +2912,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.13.tgz", - "integrity": "sha512-aAJ3bbwrn/PQHDxCto9sxwQfT30PzyYJFG0u/BWZGeVXi5Hx6uuUOQEI2Fa43qvmUjTRQNZnGqe9t0Zntexeuw==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.14.tgz", + "integrity": "sha512-eVNaWmCgdLf5iv6Qd3s7JI5SEFBFRtfm6W0mphJYXgvnDEAZ5sZzqmI06bK6xo0IErDHdTA5/t7d4eTfWbWOFw==", "cpu": [ "x64" ], @@ -2696,9 +2928,9 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.13.tgz", - "integrity": "sha512-Wt8KvASHwSXhKE/dJLCCWcTSVmBj3xhVhp/aF3RpAhGeZ3sVo7+NTfgiN8Vey/Fi8prRClDs6/f0KXPDTZE6nQ==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.14.tgz", + "integrity": "sha512-QWLoRXNikEuqtNb0dhQN6wsSVVjX6dmUFzuuiL09ZeXju25dsei2uIPl71y2Ic6QbNBsB4scwBoFnlBfabHkEw==", "cpu": [ "x64" ], @@ -2712,9 +2944,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.13.tgz", - "integrity": "sha512-mbVbcAsW3Gkm2MGwA93eLtWrwajz91aXZCNSkGTx/R5eb6KpKD5q8Ueckkh9YNboU8RH7jiv+ol/I7ZyQ9H7Bw==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.14.tgz", + "integrity": "sha512-VB4gjQni9+F0VCASU+L8zSIyjrLLsy03sjcR3bM0V2g4SNamo0FakZFKyUQ96ZVwGK4CaJsc9zd/obQy74o0Fw==", "cpu": [ "arm" ], @@ -2728,9 +2960,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.13.tgz", - "integrity": "sha512-wdtfkmpXiwej/yoAkrCP2DNzRXCALq9NVLgLELgLim1QpSfhQM5+ZxQQF8fkOiEpuNoKLp4nKZ6RC4kmeFH0HQ==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.14.tgz", + "integrity": "sha512-qaEy0dIZ6d9vyLnmeg24yzA8XuEAD9WjpM5nIM1sUgQ/Zv7cVkharPDQcmm/t/TvXoKo/0knI3me3AGfdx6w1w==", "cpu": [ "arm64" ], @@ -2744,9 +2976,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.13.tgz", - "integrity": "sha512-hZQrmtLdhyqzXHB7mkXfq0IYbxegaqTmfa1p9MBj72WPoDD3oNOh1Lnxf6xZLY9C3OV6qiCYkO1i/LrzEdW2mg==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.14.tgz", + "integrity": "sha512-ISZjT44s59O8xKsPEIesiIydMG/sCXoMBCqsphDm/WcbnuWLxxb+GcvSIIA5NjUw6F8Tex7s5/LM2yDy8RqYBQ==", "cpu": [ "arm64" ], @@ -2760,9 +2992,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.13.tgz", - "integrity": "sha512-uaZTYWxSXyMWDJZNY1Ul7XkJTCBRFZ5Fo6wtjrgBKzZLoJNrG+WderJwAjPzuNZOnmdrVg260DKwXCFtJ/hWRQ==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.14.tgz", + "integrity": "sha512-02c6JhLPJj10L2caH4U0zF8Hji4dOeahmuMl23stk0MU1wfd1OraE7rOloidSF8W5JTHkFdVo/O7uRUJJnUAJg==", "cpu": [ "x64" ], @@ -2776,9 +3008,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.13.tgz", - "integrity": "sha512-oXiPj5mi4Hdn50v5RdnuuIms0PVPI/EG4fxAfFiIKQh5TgQgX7oSuDWntHW7WNIi/yVLAiS+CRGW4RkoGSSgVQ==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.14.tgz", + "integrity": "sha512-TNGeLiN1XS66kQhxHG/7wMeQDOoL0S33x9BgmydbrWAb9Qw0KYdd8o1ifx4HOGDWhVmJ+Ul+JQ7lyknQFilO3Q==", "cpu": [ "x64" ], @@ -2792,9 +3024,9 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.13.tgz", - "integrity": "sha512-+LC2nNtPovtrDwBc/nqnIKYh/W2+R69FA0hgoeOn64BdCX522u19ryLh3Vf3F8W49XBcMIxSe665kwy21FkhvA==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.14.tgz", + "integrity": "sha512-uZYAsaW/jS/IYkd6EWPJKW/NlPNSkWkBlaeVBi/WsFQNP05/bzkebUL8FH1pdsqx4f2fH/bWFcUABOM9nfiJkQ==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -2809,21 +3041,21 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.4.5", - "@emnapi/runtime": "^1.4.5", - "@emnapi/wasi-threads": "^1.0.4", - "@napi-rs/wasm-runtime": "^0.2.12", - "@tybys/wasm-util": "^0.10.0", - "tslib": "^2.8.0" + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.0.5", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.4.0" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.13.tgz", - "integrity": "sha512-dziTNeQXtoQ2KBXmrjCxsuPk3F3CQ/yb7ZNZNA+UkNTeiTGgfeh+gH5Pi7mRncVgcPD2xgHvkFCh/MhZWSgyQg==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.14.tgz", + "integrity": "sha512-Az0RnnkcvRqsuoLH2Z4n3JfAef0wElgzHD5Aky/e+0tBUxUhIeIqFBTMNQvmMRSP15fWwmvjBxZ3Q8RhsDnxAA==", "cpu": [ "arm64" ], @@ -2837,9 +3069,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.13.tgz", - "integrity": "sha512-3+LKesjXydTkHk5zXX01b5KMzLV1xl2mcktBJkje7rhFUpUlYJy7IMOLqjIRQncLTa1WZZiFY/foAeB5nmaiTw==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.14.tgz", + "integrity": "sha512-ttblVGHgf68kEE4om1n/n44I0yGPkCPbLsqzjvybhpwa6mKKtgFfAzy6btc3HRmuW7nHe0OOrSeNP9sQmmH9XA==", "cpu": [ "x64" ], @@ -2853,22 +3085,22 @@ } }, "node_modules/@tailwindcss/postcss": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.13.tgz", - "integrity": "sha512-HLgx6YSFKJT7rJqh9oJs/TkBFhxuMOfUKSBEPYwV+t78POOBsdQ7crhZLzwcH3T0UyUuOzU/GK5pk5eKr3wCiQ==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.14.tgz", + "integrity": "sha512-BdMjIxy7HUNThK87C7BC8I1rE8BVUsfNQSI5siQ4JK3iIa3w0XyVvVL9SXLWO//CtYTcp1v7zci0fYwJOjB+Zg==", "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", - "@tailwindcss/node": "4.1.13", - "@tailwindcss/oxide": "4.1.13", + "@tailwindcss/node": "4.1.14", + "@tailwindcss/oxide": "4.1.14", "postcss": "^8.4.41", - "tailwindcss": "4.1.13" + "tailwindcss": "4.1.14" } }, "node_modules/@tailwindcss/postcss/node_modules/tailwindcss": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.13.tgz", - "integrity": "sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.14.tgz", + "integrity": "sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA==", "license": "MIT" }, "node_modules/@ts-morph/common": { @@ -2929,7 +3161,8 @@ "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==" + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" }, "node_modules/@types/estree-jsx": { "version": "1.0.5", @@ -2962,6 +3195,13 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "license": "MIT" }, + "node_modules/@types/lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -2972,15 +3212,15 @@ } }, "node_modules/@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", "license": "MIT" }, "node_modules/@types/node": { - "version": "22.18.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.6.tgz", - "integrity": "sha512-r8uszLPpeIWbNKtvWRt/DbVi5zbqZyj1PTmhRMqBMvDnaz1QpmSKujUtJLrqGZeoM8v72MfYggDceY4K1itzWQ==", + "version": "22.18.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.8.tgz", + "integrity": "sha512-pAZSHMiagDR7cARo/cch1f3rXy0AEXwsVsVH09FcyeJVAzCnGgmYis7P3JidtTUjyadhTeSo8TgRPswstghDaw==", "dev": true, "license": "MIT", "dependencies": { @@ -2988,9 +3228,9 @@ } }, "node_modules/@types/react": { - "version": "19.1.8", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", - "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.0.tgz", + "integrity": "sha512-1LOH8xovvsKsCBq1wnT4ntDUdCJKmnEakhsuoUSy6ExlHCkGP2hqnatagYTgFk6oeL0VU31u7SNjunPN+GchtA==", "license": "MIT", "peer": true, "dependencies": { @@ -3193,214 +3433,230 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", "license": "ISC" }, "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.9.2.tgz", - "integrity": "sha512-tS+lqTU3N0kkthU+rYp0spAYq15DU8ld9kXkaKg9sbQqJNF+WPMuNHZQGCgdxrUOEO0j22RKMwRVhF1HTl+X8A==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.9.2.tgz", - "integrity": "sha512-MffGiZULa/KmkNjHeuuflLVqfhqLv1vZLm8lWIyeADvlElJ/GLSOkoUX+5jf4/EGtfwrNFcEaB8BRas03KT0/Q==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.9.2.tgz", - "integrity": "sha512-dzJYK5rohS1sYl1DHdJ3mwfwClJj5BClQnQSyAgEfggbUwA9RlROQSSbKBLqrGfsiC/VyrDPtbO8hh56fnkbsQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.9.2.tgz", - "integrity": "sha512-gaIMWK+CWtXcg9gUyznkdV54LzQ90S3X3dn8zlh+QR5Xy7Y+Efqw4Rs4im61K1juy4YNb67vmJsCDAGOnIeffQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.9.2.tgz", - "integrity": "sha512-S7QpkMbVoVJb0xwHFwujnwCAEDe/596xqY603rpi/ioTn9VDgBHnCCxh+UFrr5yxuMH+dliHfjwCZJXOPJGPnw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ] }, "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.9.2.tgz", - "integrity": "sha512-+XPUMCuCCI80I46nCDFbGum0ZODP5NWGiwS3Pj8fOgsG5/ctz+/zzuBlq/WmGa+EjWZdue6CF0aWWNv84sE1uw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.9.2.tgz", - "integrity": "sha512-sqvUyAd1JUpwbz33Ce2tuTLJKM+ucSsYpPGl2vuFwZnEIg0CmdxiZ01MHQ3j6ExuRqEDUCy8yvkDKvjYFPb8Zg==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.9.2.tgz", - "integrity": "sha512-UYA0MA8ajkEDCFRQdng/FVx3F6szBvk3EPnkTTQuuO9lV1kPGuTB+V9TmbDxy5ikaEgyWKxa4CI3ySjklZ9lFA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.9.2.tgz", - "integrity": "sha512-P/CO3ODU9YJIHFqAkHbquKtFst0COxdphc8TKGL5yCX75GOiVpGqd1d15ahpqu8xXVsqP4MGFP2C3LRZnnL5MA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.9.2.tgz", - "integrity": "sha512-uKStFlOELBxBum2s1hODPtgJhY4NxYJE9pAeyBgNEzHgTqTiVBPjfTlPFJkfxyTjQEuxZbbJlJnMCrRgD7ubzw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.9.2.tgz", - "integrity": "sha512-LkbNnZlhINfY9gK30AHs26IIVEZ9PEl9qOScYdmY2o81imJYI4IMnJiW0vJVtXaDHvBvxeAgEy5CflwJFIl3tQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.9.2.tgz", - "integrity": "sha512-vI+e6FzLyZHSLFNomPi+nT+qUWN4YSj8pFtQZSFTtmgFoxqB6NyjxSjAxEC1m93qn6hUXhIsh8WMp+fGgxCoRg==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.9.2.tgz", - "integrity": "sha512-sSO4AlAYhSM2RAzBsRpahcJB1msc6uYLAtP6pesPbZtptF8OU/CbCPhSRW6cnYOGuVmEmWVW5xVboAqCnWTeHQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.9.2.tgz", - "integrity": "sha512-jkSkwch0uPFva20Mdu8orbQjv2A3G88NExTN2oPTI1AJ+7mZfYW3cDCTyoH6OnctBKbBVeJCEqh0U02lTkqD5w==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.9.2.tgz", - "integrity": "sha512-Uk64NoiTpQbkpl+bXsbeyOPRpUoMdcUqa+hDC1KhMW7aN1lfW8PBlBH4mJ3n3Y47dYE8qi0XTxy1mBACruYBaw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.9.2.tgz", - "integrity": "sha512-EpBGwkcjDicjR/ybC0g8wO5adPNdVuMrNalVgYcWi+gYtC1XYNuxe3rufcO7dA76OHGeVabcO6cSkPJKVcbCXQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", "cpu": [ "wasm32" ], "dev": true, + "license": "MIT", "optional": true, "dependencies": { "@napi-rs/wasm-runtime": "^0.2.11" @@ -3409,40 +3665,56 @@ "node": ">=14.0.0" } }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.9.2.tgz", - "integrity": "sha512-EdFbGn7o1SxGmN6aZw9wAkehZJetFPao0VGZ9OMBwKx6TkvDuj6cNeLimF/Psi6ts9lMOe+Dt6z19fZQ9Ye2fw==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.9.2.tgz", - "integrity": "sha512-JY9hi1p7AG+5c/dMU8o2kWemM8I6VZxfGwn1GCtf3c5i+IKcMo2NQ8OjZ4Z3/itvY/Si3K10jOBQn7qsD/whUA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.9.2.tgz", - "integrity": "sha512-ryoo+EB19lMxAd80ln9BVf8pdOAxLb97amrQ3SFN9OCRn/5M5wvwDgAe4i8ZjhpbiHoDeP8yavcTEnpKBo7lZg==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -3458,34 +3730,12 @@ "unist-util-visit": "^4.0.0" } }, - "node_modules/@vcarl/remark-headings/node_modules/@types/mdast": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", - "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2" - } - }, "node_modules/@vcarl/remark-headings/node_modules/@types/unist": { "version": "2.0.11", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "license": "MIT" }, - "node_modules/@vcarl/remark-headings/node_modules/mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/@vcarl/remark-headings/node_modules/unist-util-is": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", @@ -3532,6 +3782,7 @@ "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -3565,9 +3816,9 @@ } }, "node_modules/ansi-escapes": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.1.0.tgz", - "integrity": "sha512-YdhtCd19sKRKfAAUsrcC1wzm4JuzJoiX4pOJqIoW2qmKj5WzG/dL8uUJ0361zaXtHqK7gEhOwtAtz7t3Yq3X5g==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.1.1.tgz", + "integrity": "sha512-Zhl0ErHcSRUaVfGUeUdDuLgpkEo8KIFjB4Y9uAc46ScOpdDiU1Dbyplh7qWJeJ/ZHpbyMSM26+X3BySgnIz40Q==", "dev": true, "license": "MIT", "dependencies": { @@ -3581,9 +3832,9 @@ } }, "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", "engines": { "node": ">=12" @@ -3608,9 +3859,9 @@ } }, "node_modules/ansis": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.1.0.tgz", - "integrity": "sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.2.0.tgz", + "integrity": "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==", "license": "ISC", "engines": { "node": ">=14" @@ -4048,6 +4299,7 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -4058,9 +4310,9 @@ } }, "node_modules/css-selector-parser": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.0.5.tgz", - "integrity": "sha512-3itoDFbKUNx1eKmVpYMFyqKX04Ww9osZ+dLgrk6GEv6KMVeXUhUnp4I5X+evw+u3ZxVU6RFXSSRxlTeMh8bA+g==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.1.3.tgz", + "integrity": "sha512-gJMigczVZqYAk0hPVzx/M4Hm1D9QOtqkdQk9005TNzDIUGzo5cnHEDiKUT7jGPximL/oYb+LIitcHFQ4aKupxg==", "funding": [ { "type": "github", @@ -4110,9 +4362,9 @@ } }, "node_modules/decode-named-character-reference": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", - "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", + "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", "license": "MIT", "dependencies": { "character-entities": "^2.0.0" @@ -4152,9 +4404,9 @@ } }, "node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "license": "Apache-2.0", "engines": { "node": ">=8" @@ -4233,9 +4485,9 @@ } }, "node_modules/dompurify": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.6.tgz", - "integrity": "sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz", + "integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -4366,19 +4618,19 @@ } }, "node_modules/eslint": { - "version": "9.36.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.36.0.tgz", - "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==", + "version": "9.37.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.37.0.tgz", + "integrity": "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.0", - "@eslint/config-helpers": "^0.3.1", - "@eslint/core": "^0.15.2", + "@eslint/config-helpers": "^0.4.0", + "@eslint/core": "^0.16.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.36.0", - "@eslint/plugin-kit": "^0.3.5", + "@eslint/js": "9.37.0", + "@eslint/plugin-kit": "^0.4.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", @@ -4430,6 +4682,7 @@ "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", "dev": true, + "license": "MIT", "dependencies": { "get-tsconfig": "^4.10.1", "stable-hash-x": "^0.2.0" @@ -4476,6 +4729,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.16.1.tgz", "integrity": "sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "^8.35.0", "comment-parser": "^1.4.1", @@ -4507,24 +4761,14 @@ } } }, - "node_modules/eslint-plugin-import-x/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/eslint-plugin-import-x/node_modules/minimatch": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", - "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "@isaacs/brace-expansion": "^5.0.0" }, "engines": { "node": "20 || >=22" @@ -4534,13 +4778,13 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "60.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-60.5.0.tgz", - "integrity": "sha512-3ivSigRDi/04GFRRYqvv4PgLD/+ZBLfHEk/0WKNpDBcmucnEAhqFjmJhLo4W4SIpXKZ/WVQNVPEsFXVPz9fRjA==", + "version": "60.8.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-60.8.1.tgz", + "integrity": "sha512-LDcQpH4cYzU+EEri907GSzr16U2UOBiQcm95dK8ka5SnTwIT3Y7bC0iiY/MKyOotTRXaw4MY3Ec9BgHIfDBvHQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "@es-joy/jsdoccomment": "~0.62.0", + "@es-joy/jsdoccomment": "~0.68.1", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.1", "debug": "^4.4.3", @@ -4561,24 +4805,25 @@ } }, "node_modules/eslint-plugin-react-x": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-x/-/eslint-plugin-react-x-2.0.1.tgz", - "integrity": "sha512-wpGcR8SUYcYnTvjyLTTMkXdyjt72vqaHXh0aOpx8nYHW12koQQem/LJEazolpc1fXm+lkwPxOs8tKnG9i1g+EQ==", - "license": "MIT", - "dependencies": { - "@eslint-react/ast": "2.0.1", - "@eslint-react/core": "2.0.1", - "@eslint-react/eff": "2.0.1", - "@eslint-react/kit": "2.0.1", - "@eslint-react/shared": "2.0.1", - "@eslint-react/var": "2.0.1", - "@typescript-eslint/scope-manager": "^8.44.1", - "@typescript-eslint/type-utils": "^8.44.1", - "@typescript-eslint/types": "^8.44.1", - "@typescript-eslint/utils": "^8.44.1", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-x/-/eslint-plugin-react-x-2.0.6.tgz", + "integrity": "sha512-x8i52RElVgIUxSneM4uC+nkQcBGEFkiXAD8/QgxBbrfm0VKZ1748IBuNrp7125Ubx3JDlqJfJz1iEPJCyhvdAA==", + "license": "MIT", + "dependencies": { + "@eslint-react/ast": "2.0.6", + "@eslint-react/core": "2.0.6", + "@eslint-react/eff": "2.0.6", + "@eslint-react/kit": "2.0.6", + "@eslint-react/shared": "2.0.6", + "@eslint-react/var": "2.0.6", + "@typescript-eslint/scope-manager": "^8.45.0", + "@typescript-eslint/type-utils": "^8.45.0", + "@typescript-eslint/types": "^8.45.0", + "@typescript-eslint/utils": "^8.45.0", "compare-versions": "^6.1.1", "is-immutable-type": "^5.0.1", "string-ts": "^2.2.1", + "ts-api-utils": "^2.1.0", "ts-pattern": "^5.8.0" }, "engines": { @@ -4586,14 +4831,14 @@ }, "peerDependencies": { "eslint": "^9.36.0", - "ts-api-utils": "^2.1.0", - "typescript": "^5.9.2" + "typescript": "^5.9.3" } }, "node_modules/eslint-scope": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -4609,6 +4854,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -4620,6 +4866,7 @@ "version": "10.4.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", @@ -4648,6 +4895,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -4702,15 +4950,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/estree-util-to-js/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, "node_modules/estree-util-visit": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", @@ -4856,9 +5095,9 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "license": "ISC" }, "node_modules/foreground-child": { @@ -4924,6 +5163,7 @@ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", "dev": true, + "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" }, @@ -4941,6 +5181,7 @@ "version": "11.0.3", "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", + "license": "ISC", "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", @@ -4975,6 +5216,7 @@ "version": "10.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "license": "ISC", "dependencies": { "@isaacs/brace-expansion": "^5.0.0" }, @@ -5167,6 +5409,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" }, @@ -5249,15 +5492,15 @@ "license": "MIT" }, "node_modules/html-react-parser": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-5.2.5.tgz", - "integrity": "sha512-bRPdv8KTqG9CEQPMNGksDqmbiRfVQeOidry8pVetdh/1jQ1Edx4KX5m0lWvDD89Pt4CqTYjK1BLz6NoNVxN/Uw==", + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/html-react-parser/-/html-react-parser-5.2.6.tgz", + "integrity": "sha512-qcpPWLaSvqXi+TndiHbCa+z8qt0tVzjMwFGFBAa41ggC+ZA5BHaMIeMJla9g3VSp4SmiZb9qyQbmbpHYpIfPOg==", "license": "MIT", "dependencies": { "domhandler": "5.0.3", "html-dom-parser": "5.1.1", "react-property": "2.0.2", - "style-to-js": "1.1.16" + "style-to-js": "1.1.17" }, "peerDependencies": { "@types/react": "0.14 || 15 || 16 || 17 || 18 || 19", @@ -5273,6 +5516,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -5518,9 +5762,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -5535,6 +5779,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -5546,9 +5791,9 @@ } }, "node_modules/jiti": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", - "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" @@ -5567,13 +5812,13 @@ } }, "node_modules/jsdoc-type-pratt-parser": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-5.9.2.tgz", - "integrity": "sha512-TYzkACp/wPvDJLRY7qpHXtrhgwoAaojIOnLaaVNi+AbPU2u1kkjfKd9hXXTq0qSAGsyYXvwUXt99h9I5iCmjjw==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-6.3.3.tgz", + "integrity": "sha512-N1HQK15ZXdwgmXsALjUWW9Cwyg1BQS5hfP8KzDkbR4mjb+Ep8Uxcfwz+OU1tsNCRg99rk62d8GMNdG8Qz4k+Gg==", "dev": true, "license": "MIT", "engines": { - "node": ">=12.0.0" + "node": ">=20.0.0" } }, "node_modules/json-buffer": { @@ -5582,6 +5827,30 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "license": "MIT" }, + "node_modules/json-schema-to-typescript": { + "version": "15.0.4", + "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-15.0.4.tgz", + "integrity": "sha512-Su9oK8DR4xCmDsLlyvadkXzX6+GGXJpbhwoLtOGArAG61dvbW4YQmSEno2y66ahpIdmLMg6YUf/QHLgiwvkrHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@apidevtools/json-schema-ref-parser": "^11.5.5", + "@types/json-schema": "^7.0.15", + "@types/lodash": "^4.17.7", + "is-glob": "^4.0.3", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "minimist": "^1.2.8", + "prettier": "^3.2.5", + "tinyglobby": "^0.2.9" + }, + "bin": { + "json2ts": "dist/src/cli.js" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -5594,6 +5863,22 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "license": "MIT" }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "license": "MIT" + }, + "node_modules/jsonschema": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.5.0.tgz", + "integrity": "sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -5617,9 +5902,9 @@ } }, "node_modules/lightningcss": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", - "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" @@ -5632,22 +5917,43 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-darwin-arm64": "1.30.1", - "lightningcss-darwin-x64": "1.30.1", - "lightningcss-freebsd-x64": "1.30.1", - "lightningcss-linux-arm-gnueabihf": "1.30.1", - "lightningcss-linux-arm64-gnu": "1.30.1", - "lightningcss-linux-arm64-musl": "1.30.1", - "lightningcss-linux-x64-gnu": "1.30.1", - "lightningcss-linux-x64-musl": "1.30.1", - "lightningcss-win32-arm64-msvc": "1.30.1", - "lightningcss-win32-x64-msvc": "1.30.1" + "lightningcss-android-arm64": "1.30.2", + "lightningcss-darwin-arm64": "1.30.2", + "lightningcss-darwin-x64": "1.30.2", + "lightningcss-freebsd-x64": "1.30.2", + "lightningcss-linux-arm-gnueabihf": "1.30.2", + "lightningcss-linux-arm64-gnu": "1.30.2", + "lightningcss-linux-arm64-musl": "1.30.2", + "lightningcss-linux-x64-gnu": "1.30.2", + "lightningcss-linux-x64-musl": "1.30.2", + "lightningcss-win32-arm64-msvc": "1.30.2", + "lightningcss-win32-x64-msvc": "1.30.2" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", - "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", "cpu": [ "arm64" ], @@ -5665,9 +5971,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", - "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", "cpu": [ "x64" ], @@ -5685,9 +5991,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", - "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", "cpu": [ "x64" ], @@ -5705,9 +6011,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", - "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", "cpu": [ "arm" ], @@ -5725,9 +6031,9 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", - "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", "cpu": [ "arm64" ], @@ -5745,9 +6051,9 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", - "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", "cpu": [ "arm64" ], @@ -5765,9 +6071,9 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", - "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", "cpu": [ "x64" ], @@ -5785,9 +6091,9 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", - "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", "cpu": [ "x64" ], @@ -5805,9 +6111,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", - "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", "cpu": [ "arm64" ], @@ -5825,9 +6131,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", - "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", "cpu": [ "x64" ], @@ -5953,9 +6259,9 @@ } }, "node_modules/lit": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lit/-/lit-3.3.0.tgz", - "integrity": "sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.3.1.tgz", + "integrity": "sha512-Ksr/8L3PTapbdXJCk+EJVB78jDodUMaP54gD24W186zGRARvwrsPfS60wae/SSCTCNZVPd1chXqio1qHQmu4NA==", "license": "BSD-3-Clause", "dependencies": { "@lit/reactive-element": "^2.1.0", @@ -5964,20 +6270,20 @@ } }, "node_modules/lit-element": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.0.tgz", - "integrity": "sha512-MGrXJVAI5x+Bfth/pU9Kst1iWID6GHDLEzFEnyULB/sFiRLgkd8NPK/PeeXxktA3T6EIIaq8U3KcbTU5XFcP2Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.1.tgz", + "integrity": "sha512-WGAWRGzirAgyphK2urmYOV72tlvnxw7YfyLDgQ+OZnM9vQQBQnumQ7jUJe6unEzwGU3ahFOjuz1iz1jjrpCPuw==", "license": "BSD-3-Clause", "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.2.0", + "@lit-labs/ssr-dom-shim": "^1.4.0", "@lit/reactive-element": "^2.1.0", "lit-html": "^3.3.0" } }, "node_modules/lit-html": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.0.tgz", - "integrity": "sha512-RHoswrFAxY2d8Cf2mm4OZ1DgzCoBKUKSPvA1fhtSELxUERq2aQQ2h05pO9j81gS1o7RIRJ+CePLogfyahwmynw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.1.tgz", + "integrity": "sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==", "license": "BSD-3-Clause", "dependencies": { "@types/trusted-types": "^2.0.2" @@ -6097,9 +6403,9 @@ } }, "node_modules/lru-cache": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", - "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz", + "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==", "license": "ISC", "engines": { "node": "20 || >=22" @@ -6160,9 +6466,9 @@ } }, "node_modules/markdown-table": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", - "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", "license": "MIT", "funding": { "type": "github", @@ -6191,9 +6497,9 @@ } }, "node_modules/mdast-util-find-and-replace": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", - "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -6219,9 +6525,9 @@ } }, "node_modules/mdast-util-from-markdown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", - "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -6242,10 +6548,23 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-from-markdown/node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", - "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", "license": "MIT", "dependencies": { "mdast-util-from-markdown": "^2.0.0", @@ -6279,9 +6598,9 @@ } }, "node_modules/mdast-util-gfm-footnote": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -6445,9 +6764,9 @@ } }, "node_modules/mdast-util-to-markdown": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", - "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -6455,6 +6774,7 @@ "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" @@ -6464,7 +6784,7 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-to-string": { + "node_modules/mdast-util-to-markdown/node_modules/mdast-util-to-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", @@ -6477,6 +6797,34 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string/node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/mdast-util-to-string/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", @@ -6493,9 +6841,9 @@ } }, "node_modules/micromark": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", "funding": [ { "type": "GitHub Sponsors", @@ -6528,9 +6876,9 @@ } }, "node_modules/micromark-core-commonmark": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", - "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", "funding": [ { "type": "GitHub Sponsors", @@ -6636,9 +6984,9 @@ } }, "node_modules/micromark-extension-gfm-table": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", - "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -6683,9 +7031,9 @@ } }, "node_modules/micromark-factory-destination": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", "funding": [ { "type": "GitHub Sponsors", @@ -6704,9 +7052,9 @@ } }, "node_modules/micromark-factory-label": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", "funding": [ { "type": "GitHub Sponsors", @@ -6726,9 +7074,9 @@ } }, "node_modules/micromark-factory-space": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -6746,9 +7094,9 @@ } }, "node_modules/micromark-factory-title": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", "funding": [ { "type": "GitHub Sponsors", @@ -6768,9 +7116,9 @@ } }, "node_modules/micromark-factory-whitespace": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", "funding": [ { "type": "GitHub Sponsors", @@ -6790,9 +7138,9 @@ } }, "node_modules/micromark-util-character": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -6810,9 +7158,9 @@ } }, "node_modules/micromark-util-chunked": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", "funding": [ { "type": "GitHub Sponsors", @@ -6829,9 +7177,9 @@ } }, "node_modules/micromark-util-classify-character": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", "funding": [ { "type": "GitHub Sponsors", @@ -6850,9 +7198,9 @@ } }, "node_modules/micromark-util-combine-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", "funding": [ { "type": "GitHub Sponsors", @@ -6870,9 +7218,9 @@ } }, "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", "funding": [ { "type": "GitHub Sponsors", @@ -6889,9 +7237,9 @@ } }, "node_modules/micromark-util-decode-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", "funding": [ { "type": "GitHub Sponsors", @@ -6911,9 +7259,9 @@ } }, "node_modules/micromark-util-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", "funding": [ { "type": "GitHub Sponsors", @@ -6927,9 +7275,9 @@ "license": "MIT" }, "node_modules/micromark-util-html-tag-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", "funding": [ { "type": "GitHub Sponsors", @@ -6943,9 +7291,9 @@ "license": "MIT" }, "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", "funding": [ { "type": "GitHub Sponsors", @@ -6962,9 +7310,9 @@ } }, "node_modules/micromark-util-resolve-all": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", "funding": [ { "type": "GitHub Sponsors", @@ -6981,9 +7329,9 @@ } }, "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", "funding": [ { "type": "GitHub Sponsors", @@ -7002,9 +7350,9 @@ } }, "node_modules/micromark-util-subtokenize": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", - "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", "funding": [ { "type": "GitHub Sponsors", @@ -7024,9 +7372,9 @@ } }, "node_modules/micromark-util-symbol": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -7040,9 +7388,9 @@ "license": "MIT" }, "node_modules/micromark-util-types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", "funding": [ { "type": "GitHub Sponsors", @@ -7093,6 +7441,16 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -7103,9 +7461,9 @@ } }, "node_modules/minizlib": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", - "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", "license": "MIT", "dependencies": { "minipass": "^7.1.2" @@ -7132,7 +7490,8 @@ "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/nano-spawn": { "version": "1.0.3", @@ -7166,10 +7525,11 @@ } }, "node_modules/napi-postinstall": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.2.5.tgz", - "integrity": "sha512-kmsgUvCRIJohHjbZ3V8avP0I1Pekw329MVAMDzVxsrkjgdnqiwvMX5XwR+hWV66vsAtZ+iM+fVnq8RTQawUmCQ==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", "dev": true, + "license": "MIT", "bin": { "napi-postinstall": "lib/cli.js" }, @@ -7512,9 +7872,9 @@ } }, "node_modules/preact-render-to-string": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.6.1.tgz", - "integrity": "sha512-IIMfXRjmbSP9QmG18WJLQa4Z4yx3J0VC9QN5q9z2XYlWSzFlJ+bSm/AyLyyV/YFwjof1OXFX2Mz6Ao60LXudJg==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-6.6.2.tgz", + "integrity": "sha512-VJ++Pkzv6+ZOmeN/9Qvx0mRdXqnei1Lo3uu9bGvYHhoMI1VUkDT44hcpGbiokl/kuuYTayYa3yvmYTLZMplfMA==", "license": "MIT", "peerDependencies": { "preact": ">=10 || >= 11.0.0-0" @@ -7534,6 +7894,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -7545,9 +7906,9 @@ } }, "node_modules/property-information": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.0.0.tgz", - "integrity": "sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", "license": "MIT", "funding": { "type": "github", @@ -7593,9 +7954,9 @@ "license": "MIT" }, "node_modules/react": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", + "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", "license": "MIT", "peer": true, "engines": { @@ -7603,16 +7964,16 @@ } }, "node_modules/react-dom": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", - "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", + "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", "license": "MIT", "peer": true, "dependencies": { - "scheduler": "^0.26.0" + "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.1.0" + "react": "^19.2.0" } }, "node_modules/react-property": { @@ -7806,6 +8167,7 @@ "version": "10.0.1", "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-html": "^9.0.0", @@ -7927,6 +8289,7 @@ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } @@ -7966,14 +8329,14 @@ "license": "MIT" }, "node_modules/rolldown": { - "version": "1.0.0-beta.40", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.40.tgz", - "integrity": "sha512-VqEHbKpOgTPmQrZ4fVn4eshDQS/6g/fRpNE7cFSJY+eQLDZn4B9X61J6L+hnlt1u2uRI+pF7r1USs6S5fuWCvw==", + "version": "1.0.0-beta.41", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.41.tgz", + "integrity": "sha512-U+NPR0Bkg3wm61dteD2L4nAM1U9dtaqVrpDXwC36IKRHpEO/Ubpid4Nijpa2imPchcVNHfxVFwSSMJdwdGFUbg==", "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.92.0", - "@rolldown/pluginutils": "1.0.0-beta.40", - "ansis": "^4.0.0" + "@oxc-project/types": "=0.93.0", + "@rolldown/pluginutils": "1.0.0-beta.41", + "ansis": "=4.2.0" }, "bin": { "rolldown": "bin/cli.mjs" @@ -7982,20 +8345,20 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.0-beta.40", - "@rolldown/binding-darwin-arm64": "1.0.0-beta.40", - "@rolldown/binding-darwin-x64": "1.0.0-beta.40", - "@rolldown/binding-freebsd-x64": "1.0.0-beta.40", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.40", - "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.40", - "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.40", - "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.40", - "@rolldown/binding-linux-x64-musl": "1.0.0-beta.40", - "@rolldown/binding-openharmony-arm64": "1.0.0-beta.40", - "@rolldown/binding-wasm32-wasi": "1.0.0-beta.40", - "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.40", - "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.40", - "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.40" + "@rolldown/binding-android-arm64": "1.0.0-beta.41", + "@rolldown/binding-darwin-arm64": "1.0.0-beta.41", + "@rolldown/binding-darwin-x64": "1.0.0-beta.41", + "@rolldown/binding-freebsd-x64": "1.0.0-beta.41", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.41", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.41", + "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.41", + "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.41", + "@rolldown/binding-linux-x64-musl": "1.0.0-beta.41", + "@rolldown/binding-openharmony-arm64": "1.0.0-beta.41", + "@rolldown/binding-wasm32-wasi": "1.0.0-beta.41", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.41", + "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.41", + "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.41" } }, "node_modules/run-parallel": { @@ -8022,9 +8385,9 @@ } }, "node_modules/scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT", "peer": true }, @@ -8125,6 +8488,15 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -8163,16 +8535,16 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.20", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", - "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", "dev": true, "license": "CC0-1.0" }, "node_modules/sse.js": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/sse.js/-/sse.js-2.6.0.tgz", - "integrity": "sha512-eGEqOwiPX9Cm+KsOYkcz7HIEqWUSOFeChr0sT515hDOBLvQy5yxaLSZx9JWMhwjf75CXJq+7cgG1MKNh9GQ36w==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/sse.js/-/sse.js-2.7.2.tgz", + "integrity": "sha512-EDu2kt+A+HIagwUOCrDbKfsUrKxNWdoeKQVKfpruRSO34yL2xwS142Ad3AYhjCY81oWySeCsPs0wSu+c2QG14g==", "license": "Apache-2.0" }, "node_modules/stable-hash-x": { @@ -8180,6 +8552,7 @@ "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.0.0" } @@ -8306,9 +8679,9 @@ } }, "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -8361,18 +8734,18 @@ "license": "MIT" }, "node_modules/style-to-js": { - "version": "1.1.16", - "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.16.tgz", - "integrity": "sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==", + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.17.tgz", + "integrity": "sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==", "license": "MIT", "dependencies": { - "style-to-object": "1.0.8" + "style-to-object": "1.0.9" } }, "node_modules/style-to-object": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", - "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.9.tgz", + "integrity": "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw==", "license": "MIT", "dependencies": { "inline-style-parser": "0.2.4" @@ -8410,9 +8783,9 @@ "license": "MIT" }, "node_modules/tapable": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz", - "integrity": "sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "license": "MIT", "engines": { "node": ">=6" @@ -8423,16 +8796,15 @@ } }, "node_modules/tar": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", - "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.1.tgz", + "integrity": "sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==", "license": "ISC", "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", + "minizlib": "^3.1.0", "yallist": "^5.0.0" }, "engines": { @@ -8541,6 +8913,54 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -8638,7 +9058,8 @@ "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, "node_modules/tunnel": { "version": "0.0.6", @@ -8873,37 +9294,38 @@ } }, "node_modules/unrs-resolver": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.9.2.tgz", - "integrity": "sha512-VUyWiTNQD7itdiMuJy+EuLEErLj3uwX/EpHQF8EOf33Dq3Ju6VW1GXm+swk6+1h7a49uv9fKZ+dft9jU7esdLA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", + "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { - "napi-postinstall": "^0.2.4" + "napi-postinstall": "^0.3.0" }, "funding": { "url": "https://opencollective.com/unrs-resolver" }, "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.9.2", - "@unrs/resolver-binding-android-arm64": "1.9.2", - "@unrs/resolver-binding-darwin-arm64": "1.9.2", - "@unrs/resolver-binding-darwin-x64": "1.9.2", - "@unrs/resolver-binding-freebsd-x64": "1.9.2", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.9.2", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.9.2", - "@unrs/resolver-binding-linux-arm64-gnu": "1.9.2", - "@unrs/resolver-binding-linux-arm64-musl": "1.9.2", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.9.2", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.9.2", - "@unrs/resolver-binding-linux-riscv64-musl": "1.9.2", - "@unrs/resolver-binding-linux-s390x-gnu": "1.9.2", - "@unrs/resolver-binding-linux-x64-gnu": "1.9.2", - "@unrs/resolver-binding-linux-x64-musl": "1.9.2", - "@unrs/resolver-binding-wasm32-wasi": "1.9.2", - "@unrs/resolver-binding-win32-arm64-msvc": "1.9.2", - "@unrs/resolver-binding-win32-ia32-msvc": "1.9.2", - "@unrs/resolver-binding-win32-x64-msvc": "1.9.2" + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" } }, "node_modules/uri-js": { @@ -8959,9 +9381,9 @@ } }, "node_modules/use-sync-external-store": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", - "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", "license": "MIT", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -8992,6 +9414,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" @@ -9016,9 +9439,9 @@ } }, "node_modules/vfile-message": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -9149,9 +9572,9 @@ } }, "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "license": "MIT", "engines": { "node": ">=12" @@ -9288,23 +9711,14 @@ } }, "node_modules/zod": { - "version": "3.24.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.3.tgz", - "integrity": "sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.11.tgz", + "integrity": "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" } }, - "node_modules/zod-to-json-schema": { - "version": "3.24.5", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", - "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.24.1" - } - }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index 5db86dc5..7a96b27b 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,8 @@ "eslint-plugin-import-x": "^4.16.1", "eslint-plugin-jsdoc": "^60.5.0", "husky": "^9.1.7", + "json-schema-to-typescript": "^15.0.4", + "jsonschema": "^1.5.0", "lint-staged": "^16.2.3", "prettier": "3.6.2" }, @@ -58,6 +60,7 @@ "globals": "^16.4.0", "hast-util-to-string": "^3.0.1", "hastscript": "^9.0.1", + "jsonc-parser": "^3.3.1", "lightningcss": "^1.30.1", "mdast-util-slice-markdown": "^2.0.1", "preact": "^10.27.2", diff --git a/src/generators/index.mjs b/src/generators/index.mjs index cca7767e..75430ff7 100644 --- a/src/generators/index.mjs +++ b/src/generators/index.mjs @@ -3,6 +3,8 @@ import addonVerify from './addon-verify/index.mjs'; import apiLinks from './api-links/index.mjs'; import astJs from './ast-js/index.mjs'; +import json from './json/index.mjs'; +import jsonAll from './json-all/index.mjs'; import jsonSimple from './json-simple/index.mjs'; import jsxAst from './jsx-ast/index.mjs'; import legacyHtml from './legacy-html/index.mjs'; @@ -27,6 +29,10 @@ export const publicGenerators = { 'orama-db': oramaDb, 'llms-txt': llmsTxt, web, + 'jsx-ast': jsxAst, + metadata, + json, + 'json-all': jsonAll, }; // These ones are special since they don't produce standard output, diff --git a/src/generators/json-all/__tests__/index.test.mjs b/src/generators/json-all/__tests__/index.test.mjs new file mode 100644 index 00000000..28c5fc0d --- /dev/null +++ b/src/generators/json-all/__tests__/index.test.mjs @@ -0,0 +1,10 @@ +import { describe } from 'node:test'; + +// TODO add test w/ + +describe.todo('generator output complies with json schema', () => { + // TODO: + // - create fixtures that cover various different types of docs we see + // - run them through the generator + // - validate the response with https://www.npmjs.com/package/jsonschema +}); diff --git a/src/generators/json-all/__tests__/version.test.mjs b/src/generators/json-all/__tests__/version.test.mjs new file mode 100644 index 00000000..75294e3e --- /dev/null +++ b/src/generators/json-all/__tests__/version.test.mjs @@ -0,0 +1,18 @@ +'use strict'; + +import assert from 'node:assert'; +import test from 'node:test'; + +import json from '../../json/index.mjs'; +import jsonAll from '../index.mjs'; +import { generateJsonSchema } from '../util/generateJsonSchema.mjs'; + +test('json-all generator matches json generator version match', () => { + assert.strictEqual(jsonAll.version, json.version); +}); + +test('schema version matches generator version', () => { + const schema = generateJsonSchema(); + + assert.strictEqual(schema.$id, `nodejs-api-doc-all@v${jsonAll.version}`); +}); diff --git a/src/generators/json-all/index.mjs b/src/generators/json-all/index.mjs new file mode 100644 index 00000000..a45dc6d5 --- /dev/null +++ b/src/generators/json-all/index.mjs @@ -0,0 +1,79 @@ +// @ts-check +'use strict'; + +import { writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; + +import { DOC_NODE_VERSION } from '../../constants.mjs'; +import { generateJsonSchema } from './util/generateJsonSchema.mjs'; + +// TODO add test w/ https://www.npmjs.com/package/jsonschema + +/** + * TODO docs + * + * @typedef {Array} Input + * + * @type {GeneratorMetadata} + */ +export default { + name: 'json-all', + + // This should be kept in sync with the JSON schema version for this + // generator AND the `json` generator + version: '2.0.0', + + description: 'TODO', + + dependsOn: 'json', + + /** + * Generates a JSON file. + * + * @param {Input} input + * @param {Partial} param1 + * @returns {Promise} + */ + async generate(input, { output }) { + const generatedValue = { + $schema: `https://nodejs.org/docs/${DOC_NODE_VERSION}/api/node-doc-all-schema.jsonc`, + modules: [], + text: [], + }; + + const propertiesToIgnore = ['$schema', 'source']; + + input.forEach(section => { + const copiedSection = {}; + + Object.keys(section).forEach(key => { + if (!propertiesToIgnore.includes(key)) { + copiedSection[key] = section[key]; + } + }); + + switch (section.type) { + case 'module': + generatedValue.modules.push(copiedSection); + break; + case 'text': + generatedValue.text.push(copiedSection); + break; + default: + throw new TypeError(`unsupported root section type ${section.type}`); + } + }); + + if (output) { + const schema = generateJsonSchema(); + + // Write the parsed JSON schema to the output directory + await writeFile( + join(output, 'node-doc-schema.json'), + JSON.stringify(schema) + ); + } + + return generatedValue; + }, +}; diff --git a/src/generators/json-all/util/generateJsonSchema.mjs b/src/generators/json-all/util/generateJsonSchema.mjs new file mode 100644 index 00000000..0455cde9 --- /dev/null +++ b/src/generators/json-all/util/generateJsonSchema.mjs @@ -0,0 +1,27 @@ +'use strict'; + +import { DOC_NODE_VERSION } from '../../../constants.mjs'; +import jsonAll from '../index.mjs'; + +const JSON_SCHEMA_URL = `https://nodejs.org/docs/${DOC_NODE_VERSION}/api/node-doc-schema.json`; + +/** + * + */ +export const generateJsonSchema = () => ({ + $schema: 'http://json-schema.org/draft-07/schema#', + $id: `nodejs-api-doc-all@v${jsonAll.version}`, + title: 'Node.js API Documentation Schema (All)', + readOnly: true, + + properties: { + modules: { + type: 'array', + items: { $ref: `${JSON_SCHEMA_URL}/#/definitions/Module` }, + }, + text: { + type: 'array', + items: { $ref: `${JSON_SCHEMA_URL}/#/definitions/Text` }, + }, + }, +}); diff --git a/src/generators/json/__tests__/fixtures/module.md b/src/generators/json/__tests__/fixtures/module.md new file mode 100644 index 00000000..9d7c22c3 --- /dev/null +++ b/src/generators/json/__tests__/fixtures/module.md @@ -0,0 +1,73 @@ +# Module + + + + +> Stability: 2 - Stable + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla aliquet est sit amet nisi iaculis ornare. Donec eu orci condimentum, semper quam ut, luctus nisl. Aliquam vel erat efficitur, egestas justo a, accumsan mauris. Quisque scelerisque enim rhoncus ornare iaculis. Sed commodo, sem ac accumsan posuere, sapien magna eleifend massa, sit amet rhoncus sem diam quis nulla. Donec feugiat elit a tellus hendrerit congue quis bibendum urna. Pellentesque mollis tincidunt tortor, in lobortis ex fringilla a. + +Nulla sagittis pulvinar lacus et venenatis. Morbi eget varius sem, a rutrum velit. Vestibulum placerat vehicula felis. Proin et porttitor augue. Sed feugiat urna sit amet euismod posuere. Phasellus quis pretium velit. Integer porta ut velit ac consectetur. Pellentesque venenatis leo et volutpat dapibus. Nam consectetur quam venenatis feugiat tempus. Curabitur semper fringilla felis. + +Donec sed est at nulla lacinia suscipit id id neque. Cras quis risus a risus mattis consectetur ut ut ex. Cras non metus a orci facilisis laoreet. Sed eu nisi sit amet mauris iaculis placerat. Nullam interdum, lectus sed convallis tristique, nibh nibh ullamcorper leo, non vehicula metus elit a nisl. Donec eros felis, ornare eget tempor nec, egestas mattis elit. Integer semper purus at risus pretium, in tristique ipsum tristique. + +```mjs +import { something } from 'node:something'; +``` + +## text section + + + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla aliquet est sit amet nisi iaculis ornare. Donec eu orci condimentum, semper quam ut, luctus nisl. Aliquam vel erat efficitur, egestas justo a, accumsan mauris. Quisque scelerisque enim rhoncus ornare iaculis. Sed commodo, sem ac accumsan posuere, sapien magna eleifend massa, sit amet rhoncus sem diam quis nulla. Donec feugiat elit a tellus hendrerit congue quis bibendum urna. Pellentesque mollis tincidunt tortor, in lobortis ex fringilla a. + +Nulla sagittis pulvinar lacus et venenatis. Morbi eget varius sem, a rutrum velit. Vestibulum placerat vehicula felis. Proin et porttitor augue. Sed feugiat urna sit amet euismod posuere. Phasellus quis pretium velit. Integer porta ut velit ac consectetur. Pellentesque venenatis leo et volutpat dapibus. Nam consectetur quam venenatis feugiat tempus. Curabitur semper fringilla felis. + +Donec sed est at nulla lacinia suscipit id id neque. Cras quis risus a risus mattis consectetur ut ut ex. Cras non metus a orci facilisis laoreet. Sed eu nisi sit amet mauris iaculis placerat. Nullam interdum, lectus sed convallis tristique, nibh nibh ullamcorper leo, non vehicula metus elit a nisl. Donec eros felis, ornare eget tempor nec, egestas mattis elit. Integer semper purus at risus pretium, in tristique ipsum tristique. + +## Class: `Something` + + + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla aliquet est sit amet nisi iaculis ornare. Donec eu orci condimentum, semper quam ut, luctus nisl. Aliquam vel erat efficitur, egestas justo a, accumsan mauris. Quisque scelerisque enim rhoncus ornare iaculis. Sed commodo, sem ac accumsan posuere, sapien magna eleifend massa, sit amet rhoncus sem diam quis nulla. Donec feugiat elit a tellus hendrerit congue quis bibendum urna. Pellentesque mollis tincidunt tortor, in lobortis ex fringilla a. + +### `new something.Something([sources[, options]])` + +- `sources` {string\[]|object} something something bla bla bla +- `options` {object} something something bla bla bla + - `optionA` {boolean} asdf + - `bla` qwerty + +### `something.doThing()` + +- Returns: {Promise} + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla aliquet est sit amet nisi iaculis ornare. Donec eu orci condimentum, semper quam ut, luctus nisl. Aliquam vel erat efficitur, egestas justo a, accumsan mauris. Quisque scelerisque enim rhoncus ornare iaculis. Sed commodo, sem ac accumsan posuere, sapien magna eleifend massa, sit amet rhoncus sem diam quis nulla. Donec feugiat elit a tellus hendrerit congue quis bibendum urna. Pellentesque mollis tincidunt tortor, in lobortis ex fringilla a. + +### Static method: `something.doStaticThing()` + +- Returns: {Promise} + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla aliquet est sit amet nisi iaculis ornare. Donec eu orci condimentum, semper quam ut, luctus nisl. Aliquam vel erat efficitur, egestas justo a, accumsan mauris. Quisque scelerisque enim rhoncus ornare iaculis. Sed commodo, sem ac accumsan posuere, sapien magna eleifend massa, sit amet rhoncus sem diam quis nulla. Donec feugiat elit a tellus hendrerit congue quis bibendum urna. Pellentesque mollis tincidunt tortor, in lobortis ex fringilla a. + +### Event: `somethingHappened` + +- `thing` {string} thing that happened +- `how` {string|object} bla + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla aliquet est sit amet nisi iaculis ornare. Donec eu orci condimentum, semper quam ut, luctus nisl. Aliquam vel erat efficitur, egestas justo a, accumsan mauris. Quisque scelerisque enim rhoncus ornare iaculis. Sed commodo, sem ac accumsan posuere, sapien magna eleifend massa, sit amet rhoncus sem diam quis nulla. Donec feugiat elit a tellus hendrerit congue quis bibendum urna. Pellentesque mollis tincidunt tortor, in lobortis ex fringilla a. diff --git a/src/generators/json/__tests__/fixtures/text-doc.md b/src/generators/json/__tests__/fixtures/text-doc.md new file mode 100644 index 00000000..f6495604 --- /dev/null +++ b/src/generators/json/__tests__/fixtures/text-doc.md @@ -0,0 +1,43 @@ +# Hello world + + + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla aliquet est sit amet nisi iaculis ornare. Donec eu orci condimentum, semper quam ut, luctus nisl. Aliquam vel erat efficitur, egestas justo a, accumsan mauris. Quisque scelerisque enim rhoncus ornare iaculis. Sed commodo, sem ac accumsan posuere, sapien magna eleifend massa, sit amet rhoncus sem diam quis nulla. Donec feugiat elit a tellus hendrerit congue quis bibendum urna. Pellentesque mollis tincidunt tortor, in lobortis ex fringilla a. + +## abc123 + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla aliquet est sit amet nisi iaculis ornare. Donec eu orci condimentum, semper quam ut, luctus nisl. Aliquam vel erat efficitur, egestas justo a, accumsan mauris. Quisque scelerisque enim rhoncus ornare iaculis. Sed commodo, sem ac accumsan posuere, sapien magna eleifend massa, sit amet rhoncus sem diam quis nulla. Donec feugiat elit a tellus hendrerit congue quis bibendum urna. Pellentesque mollis tincidunt tortor, in lobortis ex fringilla a. + +Nulla sagittis pulvinar lacus et venenatis. Morbi eget varius sem, a rutrum velit. Vestibulum placerat vehicula felis. Proin et porttitor augue. Sed feugiat urna sit amet euismod posuere. Phasellus quis pretium velit. Integer porta ut velit ac consectetur. Pellentesque venenatis leo et volutpat dapibus. Nam consectetur quam venenatis feugiat tempus. Curabitur semper fringilla felis. + +Donec sed est at nulla lacinia suscipit id id neque. Cras quis risus a risus mattis consectetur ut ut ex. Cras non metus a orci facilisis laoreet. Sed eu nisi sit amet mauris iaculis placerat. Nullam interdum, lectus sed convallis tristique, nibh nibh ullamcorper leo, non vehicula metus elit a nisl. Donec eros felis, ornare eget tempor nec, egestas mattis elit. Integer semper purus at risus pretium, in tristique ipsum tristique. + +Nulla ultrices venenatis ex, vitae ullamcorper dui pulvinar non. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus fermentum, metus in blandit hendrerit, lorem urna interdum lacus, nec pretium turpis justo eget est. Cras tincidunt urna vel massa ultrices ultrices. Vivamus ullamcorper leo at nulla semper, ac vehicula nisl fringilla. Curabitur viverra vulputate tristique. Donec lorem erat, ornare sit amet faucibus id, mattis vel diam. Ut posuere sem laoreet augue tristique, eget volutpat leo malesuada. Nullam non velit mattis, pulvinar sem eu, vehicula purus. Proin placerat accumsan porttitor. Duis pharetra facilisis aliquet. Suspendisse blandit a nulla eget gravida. Etiam molestie porttitor sodales. Donec lobortis pretium sollicitudin. [asd](https://github.com/nodejs/node) + +### asd + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla aliquet est sit amet nisi iaculis ornare. Donec eu orci condimentum, semper quam ut, luctus nisl. Aliquam vel erat efficitur, egestas justo a, accumsan mauris. Quisque scelerisque enim rhoncus ornare iaculis. Sed commodo, sem ac accumsan posuere, sapien magna eleifend massa, sit amet rhoncus sem diam quis nulla. Donec feugiat elit a tellus hendrerit congue quis bibendum urna. Pellentesque mollis tincidunt tortor, in lobortis ex fringilla a. + +Nulla sagittis pulvinar lacus et venenatis. Morbi eget varius sem, a rutrum velit. Vestibulum placerat vehicula felis. Proin et porttitor augue. Sed feugiat urna sit amet euismod posuere. Phasellus quis pretium velit. Integer porta ut velit ac consectetur. Pellentesque venenatis leo et volutpat dapibus. Nam consectetur quam venenatis feugiat tempus. Curabitur semper fringilla felis. + +- lorem +- ipsum + +```c++ +int main() { + std::cout << "blahaj\n"; + return 0; +} +``` + +## lorem + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla aliquet est sit amet nisi iaculis ornare. Donec eu orci condimentum, semper quam ut, luctus nisl. Aliquam vel erat efficitur, egestas justo a, accumsan mauris. Quisque scelerisque enim rhoncus ornare iaculis. Sed commodo, sem ac accumsan posuere, sapien magna eleifend massa, sit amet rhoncus sem diam quis nulla. Donec feugiat elit a tellus hendrerit congue quis bibendum urna. Pellentesque mollis tincidunt tortor, in lobortis ex fringilla a. + +Nulla sagittis pulvinar lacus et venenatis. Morbi eget varius sem, a rutrum velit. Vestibulum placerat vehicula felis. Proin et porttitor augue. Sed feugiat urna sit amet euismod posuere. Phasellus quis pretium velit. Integer porta ut velit ac consectetur. Pellentesque venenatis leo et volutpat dapibus. Nam consectetur quam venenatis feugiat tempus. Curabitur semper fringilla felis. + +Donec sed est at nulla lacinia suscipit id id neque. Cras quis risus a risus mattis consectetur ut ut ex. Cras non metus a orci facilisis laoreet. Sed eu nisi sit amet mauris iaculis placerat. Nullam interdum, lectus sed convallis tristique, nibh nibh ullamcorper leo, non vehicula metus elit a nisl. Donec eros felis, ornare eget tempor nec, egestas mattis elit. Integer semper purus at risus pretium, in tristique ipsum tristique. + +Fusce pretium tincidunt dolor sit amet dignissim. Aliquam egestas purus sed lorem feugiat faucibus. Aenean eget augue non velit maximus tempor cursus eget augue. Suspendisse id laoreet felis. Integer consectetur scelerisque turpis, eu dapibus diam. Etiam ut tempus massa, vel euismod ipsum. Suspendisse quis nisl sapien. Etiam sed euismod dui. Nulla fermentum fringilla dignissim. In mauris ex, iaculis at arcu et, gravida sodales erat. + +Nulla ultrices venenatis ex, vitae ullamcorper dui pulvinar non. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus fermentum, metus in blandit hendrerit, lorem urna interdum lacus, nec pretium turpis justo eget est. Cras tincidunt urna vel massa ultrices ultrices. Vivamus ullamcorper leo at nulla semper, ac vehicula nisl fringilla. Curabitur viverra vulputate tristique. Donec lorem erat, ornare sit amet faucibus id, mattis vel diam. Ut posuere sem laoreet augue tristique, eget volutpat leo malesuada. Nullam non velit mattis, pulvinar sem eu, vehicula purus. Proin placerat accumsan porttitor. Duis pharetra facilisis aliquet. Suspendisse blandit a nulla eget gravida. Etiam molestie porttitor sodales. Donec lobortis pretium sollicitudin. diff --git a/src/generators/json/__tests__/index.test.mjs b/src/generators/json/__tests__/index.test.mjs new file mode 100644 index 00000000..604c1da3 --- /dev/null +++ b/src/generators/json/__tests__/index.test.mjs @@ -0,0 +1,54 @@ +// @ts-check +import assert from 'node:assert'; +import { join } from 'node:path'; +import { describe, test, before } from 'node:test'; + +import { Validator } from 'jsonschema'; +import { SemVer } from 'semver'; + +import createGenerator from '../../../generators.mjs'; +import createMarkdownLoader from '../../../loaders/markdown.mjs'; +import createMarkdownParser from '../../../parsers/markdown.mjs'; +import { parseSchema } from '../utils/parseSchema.mjs'; + +const FIXTURES_DIR = join(import.meta.dirname, 'fixtures'); + +const loader = createMarkdownLoader(); +const parser = createMarkdownParser(); + +describe('generator output complies with json schema', () => { + const validator = new Validator(); + + /** + * @type {object} + */ + let schema; + + before(async () => { + schema = await parseSchema(); + }); + + for (const fixture of ['text-doc', 'module']) { + const input = join(FIXTURES_DIR, `${fixture}.md`); + + test(`${fixture}.md`, async () => { + const files = await loader.loadFiles([input]); + const docs = await parser.parseApiDocs(files); + + const { runGenerators } = createGenerator(docs); + + const result = await runGenerators({ + generators: ['json'], + input, + output: undefined, + version: new SemVer('v1.2.3'), + releases: [], + gitRef: 'a'.repeat(40), + threads: 1, + typeMap: {}, + }); + + assert.ok(validator.validate(result[0], schema).valid); + }); + } +}); diff --git a/src/generators/json/__tests__/version.test.mjs b/src/generators/json/__tests__/version.test.mjs new file mode 100644 index 00000000..dd69bc7c --- /dev/null +++ b/src/generators/json/__tests__/version.test.mjs @@ -0,0 +1,20 @@ +'use strict'; + +import assert from 'node:assert'; +import { readFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import test from 'node:test'; + +import { parse as jsoncParse } from 'jsonc-parser'; + +import json from '../index.mjs'; + +test('schema version matches generator version', async () => { + const schemaString = await readFile( + join(import.meta.dirname, '..', 'schema.jsonc'), + 'utf8' + ); + const schema = await jsoncParse(schemaString); + + assert.strictEqual(schema.$id, `nodejs-api-doc@v${json.version}`); +}); diff --git a/src/generators/json/constants.mjs b/src/generators/json/constants.mjs new file mode 100644 index 00000000..fe75eb75 --- /dev/null +++ b/src/generators/json/constants.mjs @@ -0,0 +1,21 @@ +'use strict'; + +// Grabs the default value if present +export const DEFAULT_EXPRESSION = /^(D|d)efault(s|):$/; + +// Grabs the type and description of one of the formats for event types +export const EVENT_TYPE_DESCRIPTION_EXTRACTOR = /{(.*)}(.*)/; + +// Grabs type and optional description for a method's parameter signature +export const METHOD_TYPE_EXTRACTOR = /^{(.*)}( .*)?$/; + +// Grabs return type and optional description for a method signature +// Accepts the following: +// Returns: {string} +// Returns {string} +// Returns: {string} bla bla bla +export const METHOD_RETURN_TYPE_EXTRACTOR = /^Returns(:?) {(.*)}( .*)?$/; + +// Grabs the parameters from a method's signature +// ex/ 'new buffer.Blob([sources[, options]])'.match(PARAM_EXPRESSION) === ['([sources[, options]])', '[sources[, options]]'] +export const METHOD_PARAM_EXPRESSION = /\((.+)\);?$/; diff --git a/src/generators/json/generated.d.ts b/src/generators/json/generated.d.ts new file mode 100644 index 00000000..c5db1107 --- /dev/null +++ b/src/generators/json/generated.d.ts @@ -0,0 +1,195 @@ +/* eslint-disable */ +/** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + +export type NodeJsAPIDocumentationSchema = DocumentRoot & (Module | Text); +/** + * A JavaScript module. + */ +export type Module = SectionBase & { + type: 'module'; + /** + * https://jsdoc.app/tags-module + */ + '@module': string; + /** + * Classes exported from this module. + */ + classes?: Class[]; + /** + * Methods exported from this module. + */ + methods?: Method[]; + /** + * APIs that are available globally. + */ + globals?: (Class | Method)[]; + properties?: Property[]; + events?: Event[]; + [k: string]: unknown; +}; +export type Text = SectionBase; +/** + * Node.js version number + */ +export type NodeCoreVersion = string; +export type Class = SectionBase & { + type: 'class'; + '@constructor': MethodSignature[]; + methods: Method[]; + staticMethods: Method[]; + properties: Property[]; + events?: Event[]; + [k: string]: unknown; +}; +/** + * A JavaScript function. + */ +export type Method = SectionBase & { + type: 'method'; + signatures: MethodSignature[]; + [k: string]: unknown; +}; +/** + * A property on a JavaScript object or class. + */ +export type Property = SectionBase & { + type: 'property'; + /** + * JavaScript type of the property. + */ + '@type'?: string | [string, ...string[]]; + /** + * Is this property modifiable by user code? + */ + mutable?: boolean; + [k: string]: unknown; +}; +/** + * An event that can be emitted by the parent object or class. + */ +export type Event = SectionBase & { + type: 'event'; + parameters: MethodParameter[]; + [k: string]: unknown; +}; + +/** + * Common properties found at the root of each document. + */ +export interface DocumentRoot { + /** + * The path to the Markdown source used to generate this document. It is relative to the Node.js repository root. + */ + source: string; + [k: string]: unknown; +} +/** + * Common properties found in each section of a document. + */ +export interface SectionBase { + /** + * Type of the section + */ + type: 'module' | 'class' | 'method' | 'property' | 'event' | 'text'; + /** + * https://jsdoc.app/tags-name + */ + '@name': string; + /** + * Description of the section. + */ + description?: string; + /** + * https://jsdoc.app/tags-see + */ + '@see'?: string; + /** + * Sections that just hold further text on this section. + */ + text?: Text[]; + /** + * https://jsdoc.app/tags-example + */ + '@example'?: string | string[]; + /** + * https://jsdoc.app/tags-deprecated + */ + '@deprecated'?: NodeCoreVersion[]; + stability?: Stability; + /** + * The changes this API has underwent. + */ + changes?: Change[]; + /** + * https://jsdoc.app/tags-since + */ + '@since'?: NodeCoreVersion[]; + napiVersion?: number[]; + /** + * Versions that this was removed in. + */ + removedIn?: NodeCoreVersion[]; + [k: string]: unknown; +} +/** + * Describes the stability of an object. + */ +export interface Stability { + /** + * The stability value. + */ + value: number; + /** + * Textual representation of the stability. + */ + text: string; + [k: string]: unknown; +} +export interface Change { + version: NodeCoreVersion[]; + /** + * URL to the PR that introduced this change. + */ + prUrl?: string; + /** + * Description of the change. + */ + description: string; + [k: string]: unknown; +} +export interface MethodSignature { + parameters?: MethodParameter[]; + '@returns'?: MethodReturnType; + [k: string]: unknown; +} +export interface MethodParameter { + /** + * Name of the parameter. + */ + '@name': string; + /** + * Type of the parameter + */ + '@type': string | [string, ...string[]]; + description?: string; + /** + * The parameter's default value + */ + '@default'?: string; + [k: string]: unknown; +} +/** + * A method signature's return type. + */ +export interface MethodReturnType { + description?: string; + /** + * The method signature's return type. + */ + '@type': string | [string, ...string[]]; + [k: string]: unknown; +} diff --git a/src/generators/json/index.mjs b/src/generators/json/index.mjs new file mode 100644 index 00000000..529a43a3 --- /dev/null +++ b/src/generators/json/index.mjs @@ -0,0 +1,103 @@ +// @ts-check +'use strict'; + +import { writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; + +import { createSectionBuilder } from './utils/createSection.mjs'; +import { parseSchema } from './utils/parseSchema.mjs'; +import { groupNodesByModule } from '../../utils/generators.mjs'; + +/** + * This generator is responsible for generating the JSON representation of the + * docs. + * + * This is a top-level generator, intaking the raw AST tree of the api docs. + * It generates JSON files to the specified output directory given by the + * config. + * + * @typedef {Array} Input + * + * @type {GeneratorMetadata>} + */ +export default { + name: 'json', + + // This should be kept in sync with the JSON schema version for this + // generator AND the `json-all` generator + version: '2.0.0', + + description: + 'This generator is responsible for generating the JSON representation of the docs.', + + dependsOn: 'metadata', + + /** + * Generates a JSON file. + * + * @param {Input} input + * @param {Partial} param1 + * @returns {Promise>} + */ + async generate(input, { output }) { + const groupedModules = groupNodesByModule(input); + + const buildSection = createSectionBuilder(); + + /** + * @param {ApiDocMetadataEntry} head + * @returns {import('./generated.d.ts').NodeJsAPIDocumentationSchema} + */ + const processModuleNodes = head => { + const nodes = groupedModules.get(head.api); + if (!nodes) { + throw new TypeError(`no grouped nodes found for ${head.api}`); + } + + const section = buildSection(head, nodes); + + return section; + }; + + /** + * @type {Array} + */ + const generatedValues = []; + + // Gets the first nodes of each module, which is considered the "head" + const headNodes = input.filter(node => node.heading.depth === 1); + + const writeFilePromises = output ? new Array(headNodes.length) : []; + + for (let i = 0; i < headNodes.length; i++) { + const node = headNodes[i]; + + // Get the json for the node's section + const section = processModuleNodes(node); + + generatedValues.push(section); + + if (output) { + writeFilePromises[i] = writeFile( + join(output, `${node.api}.json`), + JSON.stringify(section, null, 2) + ); + } + } + + if (output) { + await Promise.all(writeFilePromises); + + // Parse the JSON schema into an object + const schema = await parseSchema(); + + // Write the parsed JSON schema to the output directory + await writeFile( + join(output, 'node-doc-schema.json'), + JSON.stringify(schema) + ); + } + + return generatedValues; + }, +}; diff --git a/src/generators/json/schema.jsonc b/src/generators/json/schema.jsonc new file mode 100644 index 00000000..554e21d3 --- /dev/null +++ b/src/generators/json/schema.jsonc @@ -0,0 +1,414 @@ +{ + /** + * NOTE: if you modify this, please: + * - Bump the version in the $id property + * - Bump the version of the `json` and `json-all` generator. + * - Run `tools/generate-json-types.mjs` and ensure there aren't type errors + */ + + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "nodejs-api-doc@v2.0.0", // This should be kept in sync with the generator version + "title": "Node.js API Documentation Schema", + "readOnly": true, + + "allOf": [ + { "$ref": "#/definitions/DocumentRoot" }, + { + "oneOf": [ + // Top of a document can either be a module (for api declarations) or + // text (for general docs on things) + { "$ref": "#/definitions/Module" }, + { "$ref": "#/definitions/Text" }, + ], + }, + ], + + "definitions": { + "DocumentRoot": { + "type": "object", + "description": "Common properties found at the root of each document.", + "properties": { + "source": { + "type": "string", + "description": "The path to the Markdown source used to generate this document. It is relative to the Node.js repository root.", + "examples": ["doc/api/net.md"], + }, + }, + "required": ["source"], + }, + + "SectionBase": { + "type": "object", + "description": "Common properties found in each section of a document.", + "properties": { + "type": { + "type": "string", + "enum": ["module", "class", "method", "property", "event", "text"], + "description": "Type of the section", + }, + "@name": { + "type": "string", + "description": "https://jsdoc.app/tags-name", + "examples": ["Buffer", "Addons"], + }, + "description": { + "type": "string", + "description": "Description of the section.", + }, + "@see": { + "type": "string", + "description": "https://jsdoc.app/tags-see", + }, + "text": { + "type": "array", + "description": "Sections that just hold further text on this section.", + "items": { "$ref": "#/definitions/Text" }, + }, + "@example": { + "description": "https://jsdoc.app/tags-example", + "oneOf": [ + { "type": "string" }, + { + "type": "array", + "items": { + "type": "string", + }, + }, + ], + }, + "@deprecated": { + "type": "array", + "description": "https://jsdoc.app/tags-deprecated", + "items": { "$ref": "#/definitions/NodeCoreVersion" }, + }, + "stability": { "$ref": "#/definitions/Stability" }, + "changes": { + "type": "array", + "items": { + "$ref": "#/definitions/Change", + }, + "description": "The changes this API has underwent.", + }, + "@since": { + "type": "array", + "description": "https://jsdoc.app/tags-since", + "items": { "$ref": "#/definitions/NodeCoreVersion" }, + }, + "napiVersion": { + "type": "array", + "items": { "type": "number" }, + }, + "removedIn": { + "type": "array", + "description": "Versions that this was removed in.", + "items": { "$ref": "#/definitions/NodeCoreVersion" }, + }, + }, + "required": ["type", "@name"], + }, + + "Module": { + "description": "A JavaScript module.", + "allOf": [ + { "$ref": "#/definitions/SectionBase" }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["module"], + }, + "@module": { + "type": "string", + "description": "https://jsdoc.app/tags-module", + "examples": ["node:buffer"], + }, + "classes": { + "type": "array", + "description": "Classes exported from this module.", + "items": { "$ref": "#/definitions/Class" }, + }, + "methods": { + "type": "array", + "description": "Methods exported from this module.", + "items": { "$ref": "#/definitions/Method" }, + }, + "globals": { + "type": "array", + "description": "APIs that are available globally.", + "items": { + "oneOf": [ + { "$ref": "#/definitions/Class" }, + { "$ref": "#/definitions/Method" }, + ], + }, + }, + "properties": { + "type": "array", + "items": { "$ref": "#/definitions/Property" }, + }, + "events": { + "type": "array", + "items": { "$ref": "#/definitions/Event" }, + }, + }, + "required": ["type", "@module", "@see"], + }, + ], + }, + + "Class": { + "allOf": [ + { "$ref": "#/definitions/SectionBase" }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["class"], + }, + "@constructor": { + "type": "array", + "items": { "$ref": "#/definitions/MethodSignature" }, + }, + "methods": { + "type": "array", + "items": { "$ref": "#/definitions/Method" }, + }, + "staticMethods": { + "type": "array", + "items": { "$ref": "#/definitions/Method" }, + }, + "properties": { + "type": "array", + "items": { "$ref": "#/definitions/Property" }, + }, + "events": { + "type": "array", + "items": { "$ref": "#/definitions/Event" }, + }, + }, + "required": [ + "type", + "@constructor", + "methods", + "staticMethods", + "properties", + ], + }, + ], + }, + + "Method": { + "description": "A JavaScript function.", + "allOf": [ + { "$ref": "#/definitions/SectionBase" }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["method"], + }, + "signatures": { + "type": "array", + "items": { "$ref": "#/definitions/MethodSignature" }, + }, + }, + "required": ["type", "signatures"], + }, + ], + }, + + "MethodSignature": { + "type": "object", + "properties": { + "parameters": { + "type": "array", + "items": { "$ref": "#/definitions/MethodParameter" }, + }, + "@returns": { + "$ref": "#/definitions/MethodReturnType", + }, + }, + }, + + "MethodParameter": { + "type": "object", + "properties": { + "@name": { + "type": "string", + "description": "Name of the parameter.", + }, + "@type": { + "description": "Type of the parameter", + "oneOf": [ + { + "type": "string", + "examples": ["string"], + }, + { + "type": "array", + "items": { + "type": "string", + }, + "minItems": 1, + }, + ], + }, + "description": { + "type": "string", + }, + "@default": { + "type": "string", + "description": "The parameter's default value", + "examples": ["foo"], + }, + }, + "required": ["@name", "@type"], + }, + + "MethodReturnType": { + "type": "object", + "description": "A method signature's return type.", + "properties": { + "description": { + "type": "string", + }, + "@type": { + "description": "The method signature's return type.", + "oneOf": [ + { + "type": "string", + "examples": ["string"], + }, + { + "type": "array", + "items": { "type": "string" }, + "examples": [["string", "Promise"]], + "minItems": 1, + }, + ], + }, + }, + "required": ["@type"], + }, + + "Global": { + "type": "object", + "properties": {}, + "required": [], + }, + + "Property": { + "description": "A property on a JavaScript object or class.", + "allOf": [ + { "$ref": "#/definitions/SectionBase" }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["property"], + }, + "@type": { + "description": "JavaScript type of the property.", + "oneOf": [ + { + "type": "string", + "examples": ["string"], + }, + { + "type": "array", + "items": { + "type": "string", + }, + "minItems": 1, + }, + ], + }, + "mutable": { + "type": "boolean", + "description": "Is this property modifiable by user code?", + "default": false, + }, + }, + "required": ["type"], + }, + ], + }, + + "Event": { + "description": "An event that can be emitted by the parent object or class.", + "allOf": [ + { "$ref": "#/definitions/SectionBase" }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["event"], + }, + "parameters": { + "type": "array", + "items": { "$ref": "#/definitions/MethodParameter" }, + }, + }, + "required": ["type", "parameters"], + }, + ], + }, + + "Text": { + "allOf": [{ "$ref": "#/definitions/SectionBase" }], + }, + + "NodeCoreVersion": { + "type": "string", + "description": "Node.js version number", + // Taken from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string + // and slightly modified to support the `v` in front + "pattern": "^v(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", + "examples": ["v24.0.0"], + }, + + "Change": { + "type": "object", + "properties": { + "version": { + "type": "array", + "items": { + "$ref": "#/definitions/NodeCoreVersion", + }, + }, + "prUrl": { + "type": "string", + "description": "URL to the PR that introduced this change.", + }, + "description": { + "type": "string", + "description": "Description of the change.", + }, + }, + "required": ["version", "description"], + }, + + "Stability": { + "type": "object", + "description": "Describes the stability of an object.", + "properties": { + "value": { + "type": "number", + "description": "The stability value.", + "minimum": 0, + "maximum": 3, + }, + "text": { + "type": "string", + "description": "Textual representation of the stability.", + }, + }, + "required": ["value", "text"], + }, + }, +} diff --git a/src/generators/json/types.d.ts b/src/generators/json/types.d.ts new file mode 100644 index 00000000..1d947525 --- /dev/null +++ b/src/generators/json/types.d.ts @@ -0,0 +1,20 @@ +import { + Class, + Method, + Module, + Property, + SectionBase, + Text, +} from './generated.d.ts'; + +export type Section = SectionBase & + (Module | Class | Method | Property | Text) & + GeneratorMetadata; + +/** + * This is metadata that's only relevant to the generator and should be removed + * before the file is output. + */ +export type GeneratorMetadata = { + parent?: Section; +}; diff --git a/src/generators/json/utils/__tests__/createMethodSection.test.mjs b/src/generators/json/utils/__tests__/createMethodSection.test.mjs new file mode 100644 index 00000000..1158c9f6 --- /dev/null +++ b/src/generators/json/utils/__tests__/createMethodSection.test.mjs @@ -0,0 +1,61 @@ +// @ts-check +'use strict'; + +import assert from 'node:assert'; +import { describe, test } from 'node:test'; + +import { createParameterGroupings } from '../createMethodSection.mjs'; + +describe('createParameterGroupings', () => { + test('param1, param2', () => { + const groupings = createParameterGroupings('param1, param2'.split(',')); + + assert.deepStrictEqual(groupings, [['param1', 'param2']]); + }); + + test('[param1]', () => { + const groupings = createParameterGroupings('[param1]'.split(',')); + + assert.deepStrictEqual(groupings, [[], ['param1']]); + }); + + test('param1[, param2]', () => { + const groupings = createParameterGroupings('param1[, param2]'.split(',')); + + assert.deepStrictEqual(groupings, [['param1'], ['param1', 'param2']]); + }); + + test('param1[, param2, param3]', () => { + const groupings = createParameterGroupings( + 'param1[, param2, param3]'.split(',') + ); + + assert.deepStrictEqual(groupings, [ + ['param1'], + ['param1', 'param2', 'param3'], + ]); + }); + + test('param1[, param2], param3', () => { + const groupings = createParameterGroupings( + 'param1[, param2], param3'.split(',') + ); + + assert.deepStrictEqual(groupings, [ + ['param1', 'param3'], + ['param1', 'param2', 'param3'], + ]); + }); + + test('param1[, param2[, param3]]', () => { + const groupings = createParameterGroupings( + 'param1[, param2[, param3]]'.split(',') + ); + + assert.deepStrictEqual(groupings, [ + ['param1'], + ['param1', 'param2'], + ['param1', 'param2', 'param3'], + ]); + }); +}); diff --git a/src/generators/json/utils/__tests__/createModuleSection.test.mjs b/src/generators/json/utils/__tests__/createModuleSection.test.mjs new file mode 100644 index 00000000..8414a0db --- /dev/null +++ b/src/generators/json/utils/__tests__/createModuleSection.test.mjs @@ -0,0 +1,28 @@ +'use strict'; + +import assert from 'node:assert'; +import { test } from 'node:test'; + +import { DOC_NODE_VERSION } from '../../../../constants.mjs'; +import { createModuleSectionBuilder } from '../createModuleSection.mjs'; + +const createModuleSection = createModuleSectionBuilder(); + +test('adds expected properties', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { api: 'something' }; + + /** + * @type {import('../../generated.d.ts').Module} + */ + const section = {}; + createModuleSection(entry, section); + + assert.deepStrictEqual( + section['@see'], + `https://nodejs.org/dist/${DOC_NODE_VERSION}/doc/api/${entry.api}.html` + ); + assert.deepStrictEqual(section['@module'], `node:${entry.api}`); +}); diff --git a/src/generators/json/utils/__tests__/createPropertySection.test.mjs b/src/generators/json/utils/__tests__/createPropertySection.test.mjs new file mode 100644 index 00000000..d692218a --- /dev/null +++ b/src/generators/json/utils/__tests__/createPropertySection.test.mjs @@ -0,0 +1,74 @@ +// @ts-check +'use strict'; + +import assert from 'node:assert'; +import test, { describe } from 'node:test'; + +` +#### \`url.username\` + +* Type: {string} + +Gets and sets the username portion of the URL. +`; + +describe('extracts type correctly', () => { + const supportedFormats = [ + '{integer} **Default:** 8192', + '{integer|boolean} bla bla bla', + '{boolean}', + 'Type: {Function} bla bla bla', + ]; + + for (const format of supportedFormats) { + test(format, () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 1, + children: [], + data: { + text: '`asd.something`', + name: '`asd.something`', + depth: 3, + slug: '`asd.something`', + type: 'property', + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [ + { + type: 'list', + children: [ + { + type: 'listItem', + children: [ + { + type: 'paragraph', + // children: + }, + ], + }, + ], + }, + ], + }, + tags: [], + yaml_position: {}, + }; + }); + } +}); diff --git a/src/generators/json/utils/__tests__/createSection.test.mjs b/src/generators/json/utils/__tests__/createSection.test.mjs new file mode 100644 index 00000000..35911589 --- /dev/null +++ b/src/generators/json/utils/__tests__/createSection.test.mjs @@ -0,0 +1,101 @@ +// @ts-check +'use strict'; + +import assert from 'node:assert'; +import { test } from 'node:test'; + +import { DOC_NODE_VERSION } from '../../../../constants.mjs'; +import { createSectionBuilder } from '../createSection.mjs'; + +const createSection = createSectionBuilder(); + +test('empty `module` section', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 1, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 1, + slug: 'some-title', + type: undefined, + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [], + }, + tags: [], + yaml_position: {}, + }; + + assert.deepStrictEqual(createSection(entry, [entry]), { + $schema: `https://nodejs.org/doc/${DOC_NODE_VERSION}/api/node-doc-schema.json`, + source: 'doc/api/something.md', + '@module': 'node:bla', + '@see': `https://nodejs.org/dist/${DOC_NODE_VERSION}/doc/api/bla.html`, + type: 'module', + '@name': 'Some title', + classes: [], + events: [], + globals: [], + methods: [], + properties: [], + }); +}); + +test('empty `text` section', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 1, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 1, + slug: 'some-title', + type: 'misc', + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [], + }, + tags: [], + yaml_position: {}, + }; + + assert.deepStrictEqual(createSection(entry, [entry]), { + $schema: `https://nodejs.org/doc/${DOC_NODE_VERSION}/api/node-doc-schema.json`, + source: 'doc/api/something.md', + type: 'text', + '@name': 'Some title', + }); +}); diff --git a/src/generators/json/utils/__tests__/createSectionBase.test.mjs b/src/generators/json/utils/__tests__/createSectionBase.test.mjs new file mode 100644 index 00000000..d719d045 --- /dev/null +++ b/src/generators/json/utils/__tests__/createSectionBase.test.mjs @@ -0,0 +1,785 @@ +// @ts-check +'use strict'; + +import assert from 'node:assert'; +import test, { describe } from 'node:test'; + +import { + createSectionBaseBuilder, + ENTRY_TO_SECTION_TYPE, +} from '../createSectionBase.mjs'; + +const createSectionBase = createSectionBaseBuilder(); + +describe('determines the correct type for a section', () => { + describe('type fallbacks', () => { + test('fallbacks to `module` if heading depth is 1 and heading type is undefined', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 1, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 1, + slug: 'some-title', + type: undefined, + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [], + }, + tags: [], + yaml_position: {}, + }; + + assert.deepStrictEqual(createSectionBase(entry), { + type: 'module', + '@name': 'Some title', + }); + }); + + test('fallbacks to `text` if heading depth is > 1 and heading type is undefined', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 2, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 2, + slug: 'some-title', + type: undefined, + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [], + }, + tags: [], + yaml_position: {}, + }; + + assert.deepStrictEqual(createSectionBase(entry), { + type: 'text', + '@name': 'Some title', + }); + }); + + test('doc/api/process.md determined as module and not a global', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'process', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 1, + children: [], + data: { + text: 'Process', + name: 'Process', + depth: 1, + slug: 'process', + type: 'global', + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [], + }, + tags: [], + yaml_position: {}, + }; + + assert.deepStrictEqual(createSectionBase(entry), { + type: 'module', + '@name': 'Process', + }); + }); + }); + + for (const entryType in ENTRY_TO_SECTION_TYPE) { + const sectionType = ENTRY_TO_SECTION_TYPE[entryType]; + + test(`\`${entryType}\` -> \`${sectionType}\``, () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 2, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 2, + slug: 'some-title', + type: entryType, + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [], + }, + tags: [], + yaml_position: {}, + }; + + assert.deepStrictEqual(createSectionBase(entry), { + type: sectionType, + '@name': 'Some title', + }); + }); + } +}); + +describe('extracts description and examples correctly', () => { + test('description with `text`', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 2, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 2, + slug: 'some-title', + type: 'module', + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [ + { + type: 'text', + value: 'this should be ignored', + }, + { + type: 'paragraph', + children: [ + { + type: 'text', + value: 'hello', + }, + ], + }, + { + type: 'paragraph', + children: [ + { + type: 'text', + value: 'world', + }, + ], + }, + ], + }, + tags: [], + yaml_position: {}, + }; + + const section = createSectionBase(entry); + + assert.strictEqual(section.description, 'hello world'); + }); + + test('description with `inlineCode` ', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 2, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 2, + slug: 'some-title', + type: 'module', + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [ + { + type: 'text', + value: 'this should be ignored', + }, + { + type: 'paragraph', + children: [ + { + type: 'text', + value: 'hello', + }, + ], + }, + { + type: 'inlineCode', + value: 'world', + }, + ], + }, + tags: [], + yaml_position: {}, + }; + + const section = createSectionBase(entry); + + assert.strictEqual(section.description, 'hello `world`'); + }); + + test('description with `link`', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 2, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 2, + slug: 'some-title', + type: 'module', + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [ + { + type: 'text', + value: 'this should be ignored', + }, + { + type: 'paragraph', + children: [ + { + type: 'text', + value: 'hello', + }, + ], + }, + { + type: 'link', + url: 'https://nodejs.org', + children: [ + { + type: 'text', + value: 'world', + }, + ], + }, + { + type: 'paragraph', + children: [ + { + type: 'text', + value: 'asd', + }, + ], + }, + ], + }, + tags: [], + yaml_position: {}, + }; + + const section = createSectionBase(entry); + + assert.strictEqual( + section.description, + 'hello [world](https://nodejs.org) asd' + ); + }); + + test('description with `emphasis` ', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 2, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 2, + slug: 'some-title', + type: 'module', + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [ + { + type: 'text', + value: 'this should be ignored', + }, + { + type: 'paragraph', + children: [ + { + type: 'text', + value: 'hello', + }, + ], + }, + { + type: 'emphasis', + children: [ + { + type: 'text', + value: 'world', + }, + ], + }, + ], + }, + tags: [], + yaml_position: {}, + }; + + const section = createSectionBase(entry); + + assert.strictEqual(section.description, 'hello _world_'); + }); + + test('extracts code examples', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 2, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 2, + slug: 'some-title', + type: 'module', + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [ + { + type: 'text', + value: 'this should be ignored', + }, + { + type: 'paragraph', + children: [ + { + type: 'text', + value: 'hello', + }, + ], + }, + { + type: 'code', + value: 'some code here', + }, + ], + }, + tags: [], + yaml_position: {}, + }; + + const section = createSectionBase(entry); + + assert.strictEqual(section.description, 'hello'); + assert.strictEqual(section['@example'], 'some code here'); + }); +}); + +describe('`@deprecated`', () => { + test('undefined if not deprecated', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 2, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 2, + slug: 'some-title', + type: 'module', + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [], + }, + tags: [], + yaml_position: {}, + }; + + const section = createSectionBase(entry); + + assert.equal(section['@deprecated'], undefined); + }); + + test('defined if deprecated', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + deprecated_in: ['v10.0.0', 'v11.1.0'], + heading: { + type: 'heading', + depth: 2, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 2, + slug: 'some-title', + type: 'module', + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [], + }, + tags: [], + yaml_position: {}, + }; + + const section = createSectionBase(entry); + + assert.deepStrictEqual(section['@deprecated'], ['v10.0.0', 'v11.1.0']); + }); +}); + +describe('`stability`', () => { + test('undefined if not provided', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 2, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 2, + slug: 'some-title', + type: 'module', + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [], + }, + tags: [], + yaml_position: {}, + }; + + const section = createSectionBase(entry); + + assert.equal(section.stability, undefined); + }); + + test('defined if provided', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 2, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 2, + slug: 'some-title', + type: 'module', + }, + }, + stability: { + type: 'root', + children: [ + { + data: { + index: 0, + description: 'something', + }, + }, + ], + }, + content: { + type: 'root', + children: [], + }, + tags: [], + yaml_position: {}, + }; + + const section = createSectionBase(entry); + + assert.deepStrictEqual(section.stability, { + value: 0, + text: 'something', + }); + }); +}); + +describe('`changes`, `@since`, `napiVersion`, `removedIn`', () => { + test('undefined if not provided', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [], + heading: { + type: 'heading', + depth: 2, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 2, + slug: 'some-title', + type: 'module', + }, + }, + stability: { + type: 'root', + children: [], + }, + content: { + type: 'root', + children: [], + }, + tags: [], + yaml_position: {}, + }; + + const section = createSectionBase(entry); + + assert.equal(section.changes, undefined); + assert.equal(section['@since'], undefined); + assert.equal(section.napiVersion, undefined); + assert.equal(section.removedIn, undefined); + }); + + test('defined if provided', () => { + /** + * @type {import('../createSectionBase.mjs').HierarchizedEntry} + */ + const entry = { + hierarchyChildren: [], + api: 'bla', + slug: 'asd', + api_doc_source: 'doc/api/something.md', + changes: [ + { + description: 'bla', + 'pr-url': 'https://github.com/nodejs/node', + version: ['v10.0.0'], + }, + { + description: 'asd', + 'pr-url': 'https://github.com/nodejs/node', + version: 'v10.2.0', + }, + ], + added_in: ['v5.0.0'], + n_api_version: ['v5.0.0'], + removed_in: ['v20.0.0'], + heading: { + type: 'heading', + depth: 2, + children: [], + data: { + text: 'Some title', + name: 'Some title', + depth: 2, + slug: 'some-title', + type: 'module', + }, + }, + stability: { + type: 'root', + children: [ + { + data: { + index: 0, + description: 'something', + }, + }, + ], + }, + content: { + type: 'root', + children: [], + }, + tags: [], + yaml_position: {}, + }; + + const section = createSectionBase(entry); + + assert.deepStrictEqual(section.changes, [ + { + description: 'bla', + prUrl: 'https://github.com/nodejs/node', + version: ['v10.0.0'], + }, + { + description: 'asd', + prUrl: 'https://github.com/nodejs/node', + version: ['v10.2.0'], + }, + ]); + assert.deepStrictEqual(section['@since'], ['v5.0.0']); + assert.deepStrictEqual(section.napiVersion, ['v5.0.0']); + assert.deepStrictEqual(section.removedIn, ['v20.0.0']); + }); +}); diff --git a/src/generators/json/utils/__tests__/parseTypeList.test.mjs b/src/generators/json/utils/__tests__/parseTypeList.test.mjs new file mode 100644 index 00000000..f6eb3256 --- /dev/null +++ b/src/generators/json/utils/__tests__/parseTypeList.test.mjs @@ -0,0 +1,75 @@ +'use strict'; + +import assert from 'node:assert'; +import { test } from 'node:test'; + +import { parseTypeList } from '../parseTypeList.mjs'; + +test('`bla {[integer](https://mdn-link)} Description start bla bla bla [asd](https://random-link)', () => { + /** + * @type {Array} + */ + const nodes = [ + { + type: 'text', + value: 'this should be ignored', + }, + { + type: 'link', + url: 'https://mdn-link', + children: [{ type: 'text', value: '' }], + }, + { + type: 'text', + value: ' Description start bla bla bla', + }, + { + type: 'link', + url: 'https://node-link', + children: [{ type: 'text', value: 'ignored since in description' }], + }, + ]; + + const result = parseTypeList(nodes, 1); + assert.deepStrictEqual(result.types, ['integer']); + assert.equal(result.endingIndex, 1); +}); + +test('`bla {[integer](https://mdn-link) | [string](https://mdn-link)} Description start bla bla bla [asd](https://random-link)', () => { + /** + * @type {Array} + */ + const nodes = [ + { + type: 'text', + value: 'this should be ignored', + }, + { + type: 'link', + url: 'https://mdn-link', + children: [{ type: 'text', value: '' }], + }, + { + type: 'text', + value: ' | ', + }, + { + type: 'link', + url: 'https://mdn-link', + children: [{ type: 'text', value: '' }], + }, + { + type: 'text', + value: ' Description start bla bla bla', + }, + { + type: 'link', + url: 'https://random-link', + children: [{ type: 'text', value: 'asd' }], + }, + ]; + + const result = parseTypeList(nodes, 1); + assert.deepStrictEqual(result.types, ['integer', 'string']); + assert.equal(result.endingIndex, 3); +}); diff --git a/src/generators/json/utils/__tests__/stringifyNode.test.mjs b/src/generators/json/utils/__tests__/stringifyNode.test.mjs new file mode 100644 index 00000000..ef299419 --- /dev/null +++ b/src/generators/json/utils/__tests__/stringifyNode.test.mjs @@ -0,0 +1,130 @@ +import assert from 'node:assert'; +import test from 'node:test'; + +import { stringifyNode } from '../stringifyNode.mjs'; + +test('break', () => { + /** + * @type {import('mdast').PhrasingContent} + */ + const node = { + type: 'break', + }; + + assert.strictEqual(stringifyNode(node), '\n'); +}); + +test('delete', () => { + /** + * @type {import('mdast').PhrasingContent} + */ + const node = { + type: 'delete', + children: [ + { + type: 'text', + value: 'hello world', + }, + ], + }; + + assert.strictEqual(stringifyNode(node), '~~hello world~~'); +}); + +test('emphasis', () => { + /** + * @type {import('mdast').PhrasingContent} + */ + const node = { + type: 'emphasis', + children: [ + { + type: 'text', + value: 'hello world', + }, + ], + }; + + assert.strictEqual(stringifyNode(node), '*hello world*'); +}); + +test('html', () => { + /** + * @type {import('mdast').PhrasingContent} + */ + const node = { + type: 'html', + value: '', + }; + + assert.strictEqual(stringifyNode(node), node.value); +}); + +test('inlineCode', () => { + /** + * @type {import('mdast').PhrasingContent} + */ + const node = { + type: 'inlineCode', + value: `hello world`, + }; + + assert.strictEqual(stringifyNode(node), '`hello world`'); +}); + +test('link', () => { + { + /** + * @type {import('mdast').PhrasingContent} + */ + const node = { + type: 'link', + value: 'hello', + url: 'https://nodejs.org', + }; + + assert.strictEqual(stringifyNode(node), '[hello](https://nodejs.org)'); + } + + { + /** + * @type {import('mdast').PhrasingContent} + */ + const node = { + type: 'link', + label: 'hello', + url: 'https://nodejs.org', + }; + + assert.strictEqual(stringifyNode(node), '[hello](https://nodejs.org)'); + } +}); + +test('strong', () => { + /** + * @type {import('mdast').PhrasingContent} + */ + const node = { + type: 'strong', + children: [ + { + type: 'text', + value: 'hello world', + }, + ], + }; + + assert.strictEqual(stringifyNode(node), '**hello world**'); +}); + +test('text', () => { + /** + * @type {import('mdast').PhrasingContent} + */ + const node = { + type: 'text', + value: 'hello world', + }; + + assert.strictEqual(stringifyNode(node), 'hello world'); +}); diff --git a/src/generators/json/utils/createClassSection.mjs b/src/generators/json/utils/createClassSection.mjs new file mode 100644 index 00000000..f16ee85e --- /dev/null +++ b/src/generators/json/utils/createClassSection.mjs @@ -0,0 +1,44 @@ +'use strict'; + +import { findParentSection } from './findParentSection.mjs'; +import { GeneratorError } from '../../../utils/generator-error.mjs'; + +/** + * @typedef {import('../../../utils/buildHierarchy.mjs').HierarchizedEntry} HierarchizedEntry + */ + +/** + * + */ +export const createClassSectionBuilder = () => { + /** + * Adds the properties expected in a class section to an object. + * @param {HierarchizedEntry} entry The AST entry + * @param {import('../generated.d.ts').Class} section The class section + */ + return (entry, section) => { + // TODO we could go with lazy creating these + section['@constructor'] = []; + + section.methods = []; + + section.staticMethods = []; + + section.properties = []; + + section.events = []; + + const parent = findParentSection(section, 'module'); + + if (parent) { + if (!Array.isArray(parent.classes)) { + throw new GeneratorError( + `expected parent.classes to be an array, got ${typeof parent.classes}`, + { entry } + ); + } + + parent.classes.push(section); + } + }; +}; diff --git a/src/generators/json/utils/createEventSection.mjs b/src/generators/json/utils/createEventSection.mjs new file mode 100644 index 00000000..581d6e7d --- /dev/null +++ b/src/generators/json/utils/createEventSection.mjs @@ -0,0 +1,184 @@ +// @ts-check +import { GeneratorError } from '../../../utils/generator-error.mjs'; +import { EVENT_TYPE_DESCRIPTION_EXTRACTOR } from '../constants.mjs'; +import { findParentSection } from './findParentSection.mjs'; +import { parseTypeList } from './parseTypeList.mjs'; +import { stringifyNode } from './stringifyNode.mjs'; + +/** + * @typedef {import('../../../utils/buildHierarchy.mjs').HierarchizedEntry} HierarchizedEntry + */ + +/** + * + */ +export const createEventSectionBuilder = () => { + /** + * Parse the parameters for the event's callback method + * @param {HierarchizedEntry} entry The AST entry + * @param {import('../generated.d.ts').Event} section The event section + */ + const parseParameters = (entry, section) => { + const [, ...nodes] = entry.content.children; + const listNode = nodes[0]; + + // If an event has type info it should be the first thing in its child + // elements + if (!listNode || listNode.type !== 'list') { + // No parameters + return; + } + + section.parameters ??= []; + + for (const node of listNode.children) { + let parameterAst = node.children[0]; + if (parameterAst.type !== 'paragraph') { + throw new TypeError( + `expected ast type 'paragraph', got ${parameterAst.type}` + ); + } + + /** + * @type {import('../generated.d.ts').MethodParameter} + */ + const parameter = {}; + + // This list node can be in three different formats: + // 1. `paramName` [description] + // 2. Type: [description] + // 3. [description] + switch (parameterAst.children[0]?.type) { + case 'inlineCode': { + // First format + if (parameterAst.children.length < 2) { + throw new GeneratorError( + `expected min 2 children, got ${parameterAst.children.length}` + ); + } + + const [name, delimiter, ...rest] = parameterAst.children; + parameter['@name'] = name.value; + + if (delimiter.type !== 'text') { + throw new GeneratorError( + `expected delimiter child type in list node to be 'text', got ${delimiter.type} (@name=${parameter['@name']})` + ); + } + + if (rest[0]?.type === 'link') { + // Type _should_ be a link with maybe a description following + const [type, ...descriptionNodes] = rest; + + const { types, endingIndex } = parseTypeList(parameterAst.children); + if (types.length === 0) { + parameter['@type'] = 'any'; + } else { + parameter['@type'] = types.length === 1 ? types[0] : types; + } + + let description = ''; + for ( + let i = endingIndex + 1; + i < parameterAst.children.length; + i++ + ) { + description += stringifyNode(parameterAst.children[i]); + } + + if (description !== '') { + parameter.description = description.trim(); + } + } else { + // Type isn't a link and we get the joy of extracting it + const value = EVENT_TYPE_DESCRIPTION_EXTRACTOR.exec( + delimiter.value + ); + if (value === null) { + throw new GeneratorError( + `failed extracting type & description from '${delimiter.value}'` + ); + } + + parameter['@type'] = value[1].trim(); + parameter.description = value[2].trim(); + } + + break; + } + case 'text': { + // Second format, pop the `Type: ` literal and then fallthrough to + // parsing it like the third format + + if (parameterAst.children[0].value !== 'Type: ') { + // Not what we want + continue; + } + + parameterAst = { + ...parameterAst, + children: structuredClone(parameterAst.children), + }; + parameterAst.children.shift(); + + // Fallthrough on purpose + } + case 'link': { + // Third format + + parameter['@name'] = 'value'; + + const { types, endingIndex } = parseTypeList(parameterAst.children); + if (types.length === 0) { + parameter['@type'] = 'any'; + } else { + parameter['@type'] = types.length === 1 ? types[0] : types; + } + + let description = ''; + for (let i = endingIndex + 1; i < parameterAst.children.length; i++) { + description += stringifyNode(parameterAst.children[i]); + } + + if (description !== '') { + parameter.description = description.trim(); + } + + break; + } + default: { + throw new GeneratorError( + `unexpected list node type: ${parameterAst.children[0].type}` + ); + } + } + + parameter['@name'] = parameter['@name'] + .replaceAll("'", '') + .replaceAll('<', '') + .replaceAll('>', ''); + + if (parameter.description) { + parameter.description = parameter.description.trim(); + } + + section.parameters.push(parameter); + } + }; + + /** + * Adds the properties expected in an event section to an object. + * @param {HierarchizedEntry} entry The AST entry + * @param {import('../generated.d.ts').Event} section The event section + */ + return (entry, section) => { + parseParameters(entry, section); + + const parent = findParentSection(section, ['class', 'module']); + + // Add this section to the parent if it exists + if (parent) { + parent.events.push(section); + } + }; +}; diff --git a/src/generators/json/utils/createMethodSection.mjs b/src/generators/json/utils/createMethodSection.mjs new file mode 100644 index 00000000..b7b136df --- /dev/null +++ b/src/generators/json/utils/createMethodSection.mjs @@ -0,0 +1,476 @@ +// @ts-check +'use strict'; + +import { + assertAstType, + assertAstTypeOptional, +} from '../../../utils/assertAstType.mjs'; +import { GeneratorError } from '../../../utils/generator-error.mjs'; +import { + METHOD_PARAM_EXPRESSION, + METHOD_RETURN_TYPE_EXTRACTOR, + METHOD_TYPE_EXTRACTOR, +} from '../constants.mjs'; +import { findParentSection } from './findParentSection.mjs'; +import { ParameterTree } from './parameter-tree.mjs'; +import { parseTypeList } from './parseTypeList.mjs'; +import { stringifyNode } from './stringifyNode.mjs'; + +/** + * @typedef {import('../../../utils/buildHierarchy.mjs').HierarchizedEntry} HierarchizedEntry + */ + +/** + * Handles each node in a parameter list + * @param {import('mdast').ListItem} param0 + * @returns {import('../generated.d.ts').MethodParameter | (import('../generated.d.ts').MethodReturnType & { returnType: true })} + */ +export const parseParameterListNode = ({ children }) => { + /** + * A parameter's type declaration (ex/ "`asd` {string} Description of asd") + * or the method's return value (ex/ "Returns: {integer}"). + */ + const paragraph = assertAstType(children[0], 'paragraph'); + + // TODO: if the type of the parameter is `object`, sometimes it's followed + // by a `list` node that contains the properties expected on that object. + // I'd really like those to be included in the json output, but for now + // they're not going to be for simplicitly sakes (they still should be in + // the description of the method though). + + /** + * @type {import('../generated.d.ts').MethodParameter | import('../generated.d.ts').MethodReturnType} + */ + const parameter = {}; + + let descriptionIndex; + + const firstChild = paragraph.children[0]; + switch (firstChild.type) { + case 'inlineCode': { + // paragraph is something like "`asd` {string} Description of asd" + parameter['@name'] = firstChild.value; + + const spacer = assertAstTypeOptional(paragraph.children[1], 'text'); + if (!spacer) { + break; + } + + const trimmedSpacer = spacer.value.trim().replaceAll('\n', ''); + + const match = METHOD_TYPE_EXTRACTOR.exec(trimmedSpacer); + if (match) { + parameter['@type'] = match[1].split('|').map(type => type.trim()); + parameter.description = match[2].trim(); + + // Any nodes after this one should be part of the description + descriptionIndex = 1; + + break; + } + + // Spacer is just a spacer, either literally just ' ' or like ': ', + // let's ignore it and try getting type + description from nodes after + // it + const { types, endingIndex } = parseTypeList(paragraph.children, 2); + + if (types.length === 0) { + parameter['@type'] = 'any'; + } else { + parameter['@type'] = types.length === 1 ? types[0] : types; + } + + descriptionIndex = endingIndex + 1; + + break; + } + case 'text': { + // paragraph is something like: "Returns: {integer}"" + + const returnRegex = METHOD_RETURN_TYPE_EXTRACTOR.exec(firstChild.value); + if (returnRegex) { + // Nothing special about this, it's just + + const [_, _2, type, description] = returnRegex; + parameter['@type'] = type.split('|').map(type => type.trim()); + parameter.description = description?.trim(); + + // Any nodes after this one should be part of the description + descriptionIndex = 1; + + break; + } + + if (firstChild.value !== 'Returns: ') { + // Not relevant to us + break; + } + + parameter.returnType = true; + + if (paragraph.children.length < 2) { + throw new GeneratorError( + `expected at least 2 children in a method's return type` + ); + } + + switch (paragraph.children[1].type) { + case 'inlineCode': { + // Returns: undefined + parameter['@type'] = paragraph.children[1].value; + descriptionIndex = 2; + + break; + } + case 'link': { + const { types, endingIndex } = parseTypeList(paragraph.children, 1); + if (types.length === 0) { + parameter['@type'] = 'any'; + } else { + parameter['@type'] = types.length === 1 ? types[0] : types; + } + + descriptionIndex = endingIndex + 1; + + break; + } + default: { + throw new GeneratorError( + `unexpected child type ${paragraph.children[1].type}` + ); + } + } + + break; + } + default: { + throw new GeneratorError(`unexpected type ${firstChild.type}`); + } + } + + if (descriptionIndex) { + for (let i = descriptionIndex; i < paragraph.children.length; i++) { + parameter.description ??= ''; + parameter.description += stringifyNode(paragraph.children[i]); + } + } + + if (parameter.description) { + parameter.description = parameter.description.trim(); + } + + return parameter; +}; + +/** + * Parses the parameters that the method accepts + * @param {HierarchizedEntry} entry The AST entry + * + * @returns {{ + * parameters?: Record, + * returns?: import('../generated.d.ts').MethodReturnType + * } | undefined} + */ +export const parseParameterList = entry => { + // Ignore header + const [, ...nodes] = entry.content.children; + + // The first child node should be the method's parameter list. If there + // isn't one, there is no parameter list. + const listNode = nodes[0]; + if (!listNode || listNode.type !== 'list') { + // Method doesn't take in any parameters + return undefined; + } + + /** + * @type {Record} + */ + const parameters = {}; + /** + * @type {import('../generated.d.ts').MethodReturnType} + */ + let returns = { '@type': 'any' }; + + listNode.children.forEach(listItem => { + const parameter = parseParameterListNode(listItem); + + if (parameter.returnType) { + // Return type + returns = { ...parameter, returnType: undefined }; + } else { + parameters[parameter['@name']] = parameter; + } + }); + + return { + parameters, + returns, + }; +}; + +/** + * TODO docs + * @param {Array} parameterNames + * @param {number} [optionalDepth=0] + * @param {import('./parameter-tree.mjs').Counter} [counter={ count: 0 }] + * @returns {ParameterTree} + */ +export function createParameterTree( + parameterNames, + optionalDepth = 0, + counter = { count: 0 } +) { + const tree = new ParameterTree(counter); + + mainLoop: for (let i = 0; i < parameterNames.length; i++) { + /** + * @example 'length]]' + * @example 'arrayBuffer[' + * @example '[sources[' + * @example 'end' + */ + const parameterName = parameterNames[i].trim(); + + if (parameterName.endsWith('[')) { + // Something like `sources[`, let's add it to the current tree + const name = parameterName.substring(0, parameterName.length - 1); + tree.addParameter(name); + + // Create a child tree to add the optional parameters after this one + const children = createParameterTree( + parameterNames.slice(i + 1), + optionalDepth + 1, + counter + ); + tree.children.push(children); + + // Skip over the parameter names that were processed and included in the + // child tree + let newIndex = i + children.parameters.length; + if (!parameterNames[newIndex]?.endsWith(']')) { + newIndex++; + } + i = newIndex; + + continue; + } + + let nameEndIndex = parameterName.length; + while (nameEndIndex > 0 && parameterName[nameEndIndex - 1] === ']') { + // Something like `length]]` + nameEndIndex--; + optionalDepth--; + + if (optionalDepth <= 0) { + // Finished with the level of optional parameters that we care about, + // break the main loop so we can return what we have so far in the tree + nameEndIndex = + parameterName[nameEndIndex - 1] === ']' + ? nameEndIndex - 1 + : nameEndIndex; + tree.addParameter(parameterName.substring(0, nameEndIndex)); + + break mainLoop; + } + } + + // Nothing special about this parameter, just need to add it to the tree + const name = parameterName.substring(0, nameEndIndex); + tree.addParameter(name); + } + + return tree; +} + +/** + * TODO docs + * @param {Array} parameterNames + * @returns {Array>} + */ +export function createParameterGroupings(parameterNames) { + // Parameters are declared in the section's header with something like + // `new Thing([sources[, options, flag[, abc]]])`. Here we should only see + // the parameters without the function name though (i.e. just + // `[sources[, options, flag[, abc]]]`). + // + // For this example specifically, we want to create three method signatures: + // 1. For `new Thing(sources)` + // 2. For `new Thing(sources, options, flag)` + // 3. For `new Thing(sources, options, flag, abc)` + // + // So, let's create multiple groups that each hold a combination of + // parameter names that can be used to call the function. + + /** + * @type {Array>} + */ + const groupings = []; + + /** + * @type {ParameterTree} + */ + let parameterTree; + + if (parameterNames[0]?.startsWith('[')) { + // Special case: starting off with optional parameters. + // Remove the [ + parameterNames[0] = parameterNames[0].substring(1); + + // Add an empty grouping + groupings.push([]); + + // Create the tree like usual + parameterTree = createParameterTree(parameterNames, 1); + } else { + parameterTree = createParameterTree(parameterNames); + } + + groupings.push(...parameterTree.coalesce()); + + return groupings; +} + +/** + * Given a list of parameter names in the order that they should appear and + * a map of paramter names to their type info, let's create the signature + * objects necessary and add it to the section. + * @param {import('../generated.d.ts').Method} section + * @param {import('../generated.d.ts').MethodSignature} baseSignature Signature to base the others on + * @param {Array} parameterNames + * @param {Record} parameters + */ +export const createSignatures = ( + section, + baseSignature, + parameterNames, + parameters +) => { + const parameterGroupings = createParameterGroupings(parameterNames); + + let signatureIndex = section.signatures?.length ?? 0; + section.signatures = [ + ...(section.signatures ?? []), + ...new Array(parameterGroupings.length), + ]; + + for (const grouping of parameterGroupings) { + /** + * @type {Array} + */ + const signatureParameters = new Array(grouping.length); + + for (let i = 0; i < signatureParameters.length; i++) { + const parameterName = grouping[i]; + + // TODO handle default value for parameters + + let parameter = + parameterName in parameters ? parameters[parameterName] : undefined; + + if (!parameter) { + console.warn( + `parameter name ${parameterName} included in method's signature but not parameter list, defaulting to type \`any\`` + ); + parameter = { '@name': 'value', '@type': 'any' }; + } + + signatureParameters[i] = parameter; + } + + section.signatures[signatureIndex] = { + '@returns': baseSignature['@returns'], + parameters: signatureParameters, + }; + + signatureIndex++; + } +}; + +/** + * Parses the signatures that the method may have and adds them to the + * section. + * @param {HierarchizedEntry} entry The AST entry + * @param {import('../generated.d.ts').Method} section The method section + */ +export const parseSignatures = (entry, section) => { + section.signatures = []; + + /** + * @type {import('../generated.d.ts').MethodSignature} + */ + const baseSignature = { + '@returns': { '@type': 'any' }, + }; + + // Parse the parameters defined in the parameter list and grab the return + // type (if the list actually exists and those are present in it) + const parameterList = parseParameterList(entry) ?? {}; + + if (parameterList.returns) { + // Return type was defined in the parameter list, let's update the base + // signature + baseSignature['@returns'] = parameterList.returns; + } + + /** + * Extract the parameter names mentioned in the entry's header. This gives + * us 1) the order in which they appear and 2) whether or not they're + * optional + * @example `[sources[, options]]` + */ + let [, parametersNames] = + entry.heading.data.text + .substring(1, entry.heading.data.text.length - 1) + .match(METHOD_PARAM_EXPRESSION) || []; + if (!parametersNames) { + // Method doesn't have any parameters, return early + section.signatures.push(baseSignature); + return; + } + + /** + * @example ['[sources[', 'options]]']` + */ + parametersNames = parametersNames.split(','); + + createSignatures( + section, + baseSignature, + parametersNames, + parameterList.parameters + ); +}; + +/** + * + */ +export const createMethodSectionBuilder = () => { + /** + * Adds the properties expected in a method section to an object. + * @param {HierarchizedEntry} entry The AST entry + * @param {import('../generated.d.ts').Method} section The method section + */ + return (entry, section) => { + parseSignatures(entry, section); + + const parent = findParentSection(section, ['class', 'module']); + + // Add this section to the parent if it exists + if (parent) { + // Put static methods in `staticMethods` property and non-static methods + // in the `methods` property + const property = entry.heading.data.text.startsWith('Static method:') + ? 'staticMethods' + : 'methods'; + + if (!Array.isArray(parent[property])) { + throw new GeneratorError( + `expected parent[${property}] to be an array, got type ${typeof parent[property]} instead (parent type=${parent.type})` + ); + } + + parent[property].push(section); + } + }; +}; diff --git a/src/generators/json/utils/createModuleSection.mjs b/src/generators/json/utils/createModuleSection.mjs new file mode 100644 index 00000000..19f84c2c --- /dev/null +++ b/src/generators/json/utils/createModuleSection.mjs @@ -0,0 +1,35 @@ +// @ts-check +'use strict'; + +import { DOC_NODE_VERSION } from '../../../constants.mjs'; + +/** + * @typedef {import('../../../utils/buildHierarchy.mjs').HierarchizedEntry} HierarchizedEntry + */ + +/** + * + */ +export const createModuleSectionBuilder = () => { + /** + * Adds the properties expected in a module section to an object. + * @param {HierarchizedEntry} entry The AST entry + * @param {import('../generated.d.ts').Module} section The module section + */ + return (entry, section) => { + section['@see'] = + `https://nodejs.org/dist/${DOC_NODE_VERSION}/doc/api/${entry.api}.html`; + + section['@module'] = `node:${entry.api}`; + + section.classes = []; + + section.methods = []; + + section.globals = []; + + section.properties = []; + + section.events = []; + }; +}; diff --git a/src/generators/json/utils/createPropertySection.mjs b/src/generators/json/utils/createPropertySection.mjs new file mode 100644 index 00000000..8feb12cd --- /dev/null +++ b/src/generators/json/utils/createPropertySection.mjs @@ -0,0 +1,200 @@ +// @ts-check +'use strict'; + +import { assertAstType } from '../../../utils/assertAstType.mjs'; +import { DEFAULT_EXPRESSION } from '../constants.mjs'; +import { findParentSection } from './findParentSection.mjs'; +import { stringifyNode } from './stringifyNode.mjs'; + +/** + * @typedef {import('../../../utils/buildHierarchy.mjs').HierarchizedEntry} HierarchizedEntry + */ + +/** + * Some types in the docs have different capitalization than what exists in JS + * @type {Record} + */ +const docTypeToCorrectJsType = { + integer: 'number', + bigint: 'BigInt', + symbol: 'Symbol', +}; + +/** + * + */ +export const createPropertySectionBuilder = () => { + /** + * Parse the type of the property from the AST + * @param {HierarchizedEntry} entry The AST entry + * @param {import('../generated.d.ts').Property} section The method section + * @returns {import('mdast').Paragraph | undefined} The list element that contains the property's type information + */ + const parseType = (entry, section) => { + const [, ...nodes] = entry.content.children; + + // The first list that exists in the entry should be its type info + const listNode = nodes.find(node => node.type === 'list'); + + if (!listNode) { + // No type information, default to `any` + section['@type'] = 'any'; + + return undefined; + } + + const firstListElement = structuredClone(listNode.children[0].children[0]); + + if (firstListElement.type !== 'paragraph') { + throw new TypeError( + `expected first node in property type list node to be a paragraph, got ${firstListElement.type}` + ); + } + + // Should look something like these in the Markdown source: + // {integer} **Default:** 8192 + // {integer} bla bla bla + // {boolean} + // Type: {Function} bla bla bla + let typeNode = firstListElement.children[0]; + + /** + * @param {import('mdast').Link} node + */ + const parseTypeFromLink = node => { + const type = assertAstType(node.children[0], 'inlineCode'); + + let formattedValue = type.value; + if (formattedValue.startsWith('<')) { + formattedValue = formattedValue.substring(1, formattedValue.length - 1); + } + + let isArray = false; + if (formattedValue.endsWith('[]')) { + isArray = true; + + // Trim off the [] so we can get the base type + formattedValue = formattedValue.substring(0, formattedValue.length - 2); + } + + formattedValue = + docTypeToCorrectJsType[formattedValue.toLowerCase()] ?? formattedValue; + + if (isArray) { + // Add the [] back + formattedValue += '[]'; + } + + section['@type'] = formattedValue; + }; + + switch (typeNode.type) { + case 'link': { + // Consume the type + firstListElement.children.shift(); + parseTypeFromLink(typeNode); + + break; + } + case 'text': { + if (typeNode.value !== 'Type: ') { + break; + } + + // Consume the `Type: ` text & the type + firstListElement.children.shift(); + typeNode = firstListElement.children.shift(); + + if (typeNode?.type === 'link') { + parseTypeFromLink(typeNode); + } + + break; + } + default: { + // Not something that we can get a type from + break; + } + } + + return firstListElement; + }; + + /** + * Properties can have a link in their docs that provides more information. + * Let's try to find that link and add it as the `@see` property. + * @param {import('mdast').Paragraph} listElement The AST entry + * @param {import('../generated.d.ts').Property} section The method section + */ + const parseReferenceLink = (listElement, section) => { + const possibleLink = listElement.children[0]; + + if (!possibleLink || possibleLink.type !== 'link') { + return; + } + + // Consume the link + listElement.children.shift(); + section['@see'] = possibleLink.url; + }; + + /** + * A property may have its description with its type declaration instead of + * where it is normally defined. If that's the case, let's append it to the + * section's description. + * @param {import('mdast').Paragraph} listElement The AST entry + * @param {import('../generated.d.ts').Property} section The method section + */ + const parseDescription = (listElement, section) => { + if (listElement.children.length === 0) { + return; + } + + let description = ''; + + for (let i = 0; i < listElement.children.length; i++) { + const node = listElement.children[i]; + + // Check if this is defining the property's default value. If so, we can + // mark it as mutable. + if (node.type === 'strong') { + const [child] = node.children; + + // TODO: it'd be great to actually extract the default value here and + // add it as a property in the section, there isn't really a standard + // way to specify the default values so that'd be pretty messy right + // now + if (child.type === 'text' && DEFAULT_EXPRESSION.test(child.value)) { + section.mutable = true; + } + } + + description += stringifyNode(node); + } + + section.description ??= ''; + section.description += description; + }; + + /** + * Adds the properties expected in a method section to an object. + * @param {HierarchizedEntry} entry The AST entry + * @param {import('../generated.d.ts').Property} section The method section + */ + return (entry, section) => { + const listElement = parseType(entry, section); + + if (listElement) { + parseReferenceLink(listElement, section); + + parseDescription(listElement, section); + } + + const parent = findParentSection(section, ['class', 'module']); + + // Add this section to the parent if it exists + if (parent) { + parent.properties.push(section); + } + }; +}; diff --git a/src/generators/json/utils/createSection.mjs b/src/generators/json/utils/createSection.mjs new file mode 100644 index 00000000..d1a478df --- /dev/null +++ b/src/generators/json/utils/createSection.mjs @@ -0,0 +1,136 @@ +'use strict'; + +import { createClassSectionBuilder } from './createClassSection.mjs'; +import { createEventSectionBuilder } from './createEventSection.mjs'; +import { createMethodSectionBuilder } from './createMethodSection.mjs'; +import { createModuleSectionBuilder } from './createModuleSection.mjs'; +import { createPropertySectionBuilder } from './createPropertySection.mjs'; +import { createSectionBaseBuilder } from './createSectionBase.mjs'; +import { DOC_NODE_VERSION } from '../../../constants.mjs'; +import { buildHierarchy } from '../../../utils/buildHierarchy.mjs'; +import { GeneratorError } from '../../../utils/generator-error.mjs'; + +/** + * @typedef {import('../../../utils/buildHierarchy.mjs').HierarchizedEntry} HierarchizedEntry + */ + +/** + * + */ +export const createSectionBuilder = () => { + const createSectionBase = createSectionBaseBuilder(); + const createModuleSection = createModuleSectionBuilder(); + const createClassSection = createClassSectionBuilder(); + const createMethodSection = createMethodSectionBuilder(); + const createPropertySection = createPropertySectionBuilder(); + const createEventSection = createEventSectionBuilder(); + + /** + * Creates the properties that exist in the root of a document + * @param {ApiDocMetadataEntry} head The head metadata entry + * @returns {import('../generated.d.ts').DocumentRoot} + */ + const createDocumentRoot = head => { + return { + source: head.api_doc_source, + }; + }; + + /** + * Processes children of a given entry and updates the section. + * @param {HierarchizedEntry} entry - The current entry. + * @param {import('../types.d.ts').Section | undefined} parent + */ + const handleChildren = ({ hierarchyChildren }, parent) => + hierarchyChildren?.forEach(child => createSection(child, parent)); + + /** + * @param {HierarchizedEntry} entry + * @param {import('../types.d.ts').Section | undefined} parent + * @returns {import('../types.d.ts').Section} + */ + const createSection = (entry, parent) => { + /** + * @type {import('../types.d.ts').Section} + */ + let section; + try { + section = createSectionBase(entry, parent?.type); + + // Temporarily add the parent section to the section so we have access to + // it and can easily traverse through them when we need to + section.parent = parent; + + switch (section.type) { + case 'module': + createModuleSection(entry, section); + break; + case 'class': + createClassSection(entry, section); + break; + case 'method': + createMethodSection(entry, section); + break; + case 'property': + createPropertySection(entry, section); + break; + case 'event': + createEventSection(entry, section); + break; + case 'text': + if (parent) { + parent.text ??= []; + parent.text.push(section); + } + + break; + default: + throw new GeneratorError(`unhandled section type ${section.type}`); + } + } catch (err) { + if (err instanceof GeneratorError) { + err.entry ??= entry; + } + + throw err; + } + + handleChildren(entry, section); + + // Remove the parent property we added to the section earlier + delete section.parent; + + return section; + }; + + /** + * Builds the module section from head metadata and entries. + * @param {ApiDocMetadataEntry} head The head metadata entry + * @param {Array} entries The list of metadata entries + * @returns {import('../generated.d.ts').NodeJsAPIDocumentationSchema} + */ + return (head, entries) => { + const entryHierarchy = buildHierarchy(entries); + + if (entryHierarchy.length != 1) { + throw new TypeError(`${head.api_doc_source} has multiple root elements`); + } + + const documentRoot = createDocumentRoot(head); + + const section = createSection(entryHierarchy[0], undefined); + + if (section.type !== 'module' && section.type !== 'text') { + throw new GeneratorError( + `expected root section to be a module or text, got ${section.type}`, + { entry: head } + ); + } + + return { + $schema: `https://nodejs.org/doc/${DOC_NODE_VERSION}/api/node-doc-schema.json`, + ...documentRoot, + ...section, + }; + }; +}; diff --git a/src/generators/json/utils/createSectionBase.mjs b/src/generators/json/utils/createSectionBase.mjs new file mode 100644 index 00000000..c08ba76e --- /dev/null +++ b/src/generators/json/utils/createSectionBase.mjs @@ -0,0 +1,180 @@ +'use strict'; + +import { enforceArray } from '../../../utils/array.mjs'; +import { GeneratorError } from '../../../utils/generator-error.mjs'; +import { transformNodeToString } from '../../../utils/unist.mjs'; + +/** + * @typedef {import('../../../utils/buildHierarchy.mjs').HierarchizedEntry} HierarchizedEntry + */ + +/** + * Mapping of {@link HeadingMetadataEntry['type']} to types defined in the + * JSON schema. + * + * Exported for tests. + */ +export const ENTRY_TO_SECTION_TYPE = /** @type {const} */ ({ + var: 'property', + global: 'property', + module: 'module', + class: 'class', + ctor: 'method', + method: 'method', + classMethod: 'method', + property: 'property', + event: 'event', + misc: 'text', + text: 'text', + example: 'text', +}); + +/** + * + */ +export const createSectionBaseBuilder = () => { + /** + * @param {import('mdast').Heading} header + * @param {number} depth + * @returns {typeof ENTRY_TO_SECTION_TYPE[string]} + */ + const determineType = header => { + const fallback = header.depth === 1 ? 'module' : 'text'; + + // doc/api/process.md's parent section shouldn't have a defined type, but + // it is defined as `global` for whatever reason + if ( + header?.data.slug === 'process' && + header?.data.type === 'global' && + header?.data.depth === 1 + ) { + return 'module'; + } + + return ENTRY_TO_SECTION_TYPE[header?.data.type ?? fallback]; + }; + + /** + * Adds a description to the section base. + * @param {import('../generated.d.ts').SectionBase} section + * @param {Array} nodes + */ + const addDescriptionAndExamples = (section, nodes) => { + nodes.forEach(node => { + if (node.type === 'code') { + if (Array.isArray(section['@example'])) { + section['@example'] = [...section['@example'], node.value]; + } else if (section['@example']) { + section['@example'] = [section['@example'], node.value]; + } else { + section['@example'] = node.value; + } + + return; + } + + // Not code, let's stringify it and add it to the description. + section.description ??= ''; + section.description += `${transformNodeToString(node)} `; + }); + + if (section.description) { + section.description = section.description.trim(); + } + }; + + /** + * Adds the deprecated property to the section if needed. + * @param {import('../generated.d.ts').SectionBase} section + * @param {HierarchizedEntry} entry + */ + const addDeprecatedStatus = (section, entry) => { + if (!entry.deprecated_in) { + return; + } + + section['@deprecated'] = enforceArray(entry.deprecated_in); + }; + + /** + * Adds the stability property to the section. + * @param {import('../generated.d.ts').SectionBase} section + * @param {HierarchizedEntry} entry + */ + const addStabilityStatus = (section, entry) => { + const stability = entry.stability.children.map(node => node.data)?.[0]; + + if (!stability) { + return; + } + + let value = stability.index; + if (typeof value === 'number') { + value = Number(value); + + if (isNaN(value)) { + throw new GeneratorError(`Stability index ${stability.index} NaN`); + } + } + + section.stability = { + value, + text: stability.description, + }; + }; + + /** + * Adds the properties relating to versioning to the section. + * @param {import('../generated.d.ts').SectionBase} section + * @param {HierarchizedEntry} entry + */ + const addVersionProperties = (section, entry) => { + if (entry.changes.length > 0) { + section.changes = entry.changes.map(change => ({ + description: change.description, + prUrl: change['pr-url'], + version: enforceArray(change.version), + })); + } + + if (entry.added_in) { + section['@since'] = enforceArray(entry.added_in); + } + + if (entry.n_api_version) { + section.napiVersion = enforceArray(entry.n_api_version); + } + + if (entry.removed_in) { + section.removedIn = enforceArray(entry.removed_in); + } + }; + + /** + * Returns an object containing the properties that can be found in every + * section type that we have. + * + * @param {HierarchizedEntry} entry The AST entry + * @returns {import('../generated.d.ts').SectionBase} + */ + return entry => { + const [, ...nodes] = entry.content.children; + + const type = determineType(entry.heading); + + /** + * @type {import('../generated.d.ts').SectionBase} + */ + const base = { + type, + '@name': entry.heading.data.name, + }; + + addDescriptionAndExamples(base, nodes); + addDeprecatedStatus(base, entry); + addStabilityStatus(base, entry); + addVersionProperties(base, entry); + + return base; + }; +}; diff --git a/src/generators/json/utils/findParentSection.mjs b/src/generators/json/utils/findParentSection.mjs new file mode 100644 index 00000000..d5f5fc09 --- /dev/null +++ b/src/generators/json/utils/findParentSection.mjs @@ -0,0 +1,25 @@ +'use strict'; + +import { enforceArray } from '../../../utils/array.mjs'; + +/** + * Finds the closest parent section with the specified type(s). + * @param {import('../types.d.ts').Section} section + * @param {import('../generated.d.ts').SectionBase['type'] | Array} type + * @returns {import('../types.d.ts').Section | undefined} + */ +export function findParentSection(section, type) { + type = enforceArray(type); + + let parent = section.parent; + + while (parent) { + if (type.includes(parent.type)) { + return parent; + } + + parent = parent.parent; + } + + return undefined; +} diff --git a/src/generators/json/utils/parameter-tree.mjs b/src/generators/json/utils/parameter-tree.mjs new file mode 100644 index 00000000..f9988d29 --- /dev/null +++ b/src/generators/json/utils/parameter-tree.mjs @@ -0,0 +1,93 @@ +// @ts-check +'use strict'; + +/** + * @typedef {{ + * name: string, + * createdAt: number + * }} Parameter + * + * @typedef {{ + * count: number + * }} Counter + */ + +/** + * + */ +export class ParameterTree { + /** + * @type {Array} + */ + #parameters = []; + + /** + * @type {Array} + */ + #children = []; + + /** + * @type {Counter} + */ + #counter; + + /** + * @param {Counter} counter + */ + constructor(counter) { + this.#counter = counter; + } + + /** + * @param {string} name + */ + addParameter(name) { + this.#parameters.push({ + name, + createdAt: this.#counter.count++, + }); + } + + /** + * + */ + get parameters() { + return this.#parameters; + } + + /** + * + */ + get children() { + return this.#children; + } + + /** + * @returns {Array>} + */ + coalesceParameters() { + return [ + this.#parameters, + ...this.#children + .map(child => + child + .coalesceParameters() + .map(array => [...this.#parameters, ...array]) + ) + .flat(), + ]; + } + + /** + * @returns {Array>} + */ + coalesce() { + return this.coalesceParameters().map(array => + array + // Sort by the order they were processed + .sort((a, b) => (a.createdAt > b.createdAt ? 1 : -1)) + // Consolidate it to just be the parameter names + .map(param => param.name) + ); + } +} diff --git a/src/generators/json/utils/parseSchema.mjs b/src/generators/json/utils/parseSchema.mjs new file mode 100644 index 00000000..ee511ad7 --- /dev/null +++ b/src/generators/json/utils/parseSchema.mjs @@ -0,0 +1,23 @@ +// @ts-check +'use strict'; + +import { readFile } from 'node:fs/promises'; +import { join } from 'node:path'; + +import { parse as jsoncParse } from 'jsonc-parser'; + +/** + * @returns {Promise} + */ +export async function parseSchema() { + // Read the contents of the JSON schema + const schemaString = await readFile( + join(import.meta.dirname, '..', 'schema.jsonc'), + 'utf8' + ); + + // Parse the JSON schema into an object + const schema = await jsoncParse(schemaString); + + return schema; +} diff --git a/src/generators/json/utils/parseTypeList.mjs b/src/generators/json/utils/parseTypeList.mjs new file mode 100644 index 00000000..90efa9ec --- /dev/null +++ b/src/generators/json/utils/parseTypeList.mjs @@ -0,0 +1,48 @@ +'use strict'; + +import { assertAstType } from '../../../utils/assertAstType.mjs'; + +/** + * Types for properties and parameters can be multiple things. In the Markdown + * source, this looks like `{string | integer | ...}`. + * + * JavaScript primitives are converted into links here, ultimately breaking up + * what would otherwise be just a `text` node in the AST. So, in the AST, this + * instead looks like [`link` node, `text` node, `link` node, ...]. + * + * @param {Array} children + * @param {number} [startingIndex=0] + * @returns {{ types: Array, endingIndex: number }} + */ +export function parseTypeList(children, startingIndex = 0) { + /** + * @type {Array} + */ + const types = []; + let endingIndex = startingIndex; + + for (let i = startingIndex; i < children.length; i += 2) { + const child = children[i]; + + if (child.type !== 'link') { + // Not a type + break; + } + + const typeName = assertAstType(child.children[0], ['text', 'inlineCode']); + types.push(typeName.value.replaceAll('<', '').replaceAll('>', '')); + + const nextChild = children[i + 1]; + if ( + !nextChild || + nextChild.type !== 'text' || + nextChild.value.trim() !== '|' + ) { + // No more types to parse, quit early + endingIndex = i; + break; + } + } + + return { types, endingIndex }; +} diff --git a/src/generators/json/utils/stringifyNode.mjs b/src/generators/json/utils/stringifyNode.mjs new file mode 100644 index 00000000..efc72051 --- /dev/null +++ b/src/generators/json/utils/stringifyNode.mjs @@ -0,0 +1,47 @@ +'use strict'; + +import { GeneratorError } from '../../../utils/generator-error.mjs'; + +/** + * Turn contents of a node into a string + * @param {import('mdast').PhrasingContent} node + * @returns + */ +export function stringifyNode(node) { + let value = ''; + + switch (node.type) { + case 'break': + value += '\n'; + break; + case 'delete': + value += `~~${node.children.map(stringifyNode).join(' ')}~~`; + break; + case 'emphasis': + value += `*${node.children.map(stringifyNode).join(' ')}*`; + break; + case 'text': + value += node.value; + break; + case 'strong': + value += `**${node.children.map(stringifyNode).join(' ')}**`; + break; + case 'inlineCode': + value += `\`${node.value}\``; + break; + case 'link': + value = `[${node.label ?? node.value}](${node.url})`; + break; + case 'html': + // Not actually html, or probably at least. Types mentioned like + // `` are put in the string as html nodes + value += node.value; + break; + case 'footnoteReference': + break; + default: + throw new GeneratorError(`Unsupported node type: ${node.type}`); + } + + return value; +} diff --git a/src/generators/legacy-json/types.d.ts b/src/generators/legacy-json/types.d.ts index 78f657b1..7c481dfb 100644 --- a/src/generators/legacy-json/types.d.ts +++ b/src/generators/legacy-json/types.d.ts @@ -1,16 +1,5 @@ import { ListItem } from '@types/mdast'; -/** - * Represents an entry in a hierarchical structure, extending from ApiDocMetadataEntry. - * It includes children entries organized in a hierarchy. - */ -export interface HierarchizedEntry extends ApiDocMetadataEntry { - /** - * List of child entries that are part of this entry's hierarchy. - */ - hierarchyChildren: ApiDocMetadataEntry[]; -} - /** * Contains metadata related to changes, additions, removals, and deprecated statuses of an entry. */ diff --git a/src/generators/legacy-json/utils/buildSection.mjs b/src/generators/legacy-json/utils/buildSection.mjs index f70c3de3..3d6e4d15 100644 --- a/src/generators/legacy-json/utils/buildSection.mjs +++ b/src/generators/legacy-json/utils/buildSection.mjs @@ -1,6 +1,6 @@ -import { buildHierarchy } from './buildHierarchy.mjs'; import { parseList } from './parseList.mjs'; import { enforceArray } from '../../../utils/array.mjs'; +import { buildHierarchy } from '../../../utils/buildHierarchy.mjs'; import { getRemarkRehype } from '../../../utils/remark.mjs'; import { transformNodesToString } from '../../../utils/unist.mjs'; import { SECTION_TYPE_PLURALS, UNPROMOTED_KEYS } from '../constants.mjs'; @@ -13,7 +13,7 @@ export const createSectionBuilder = () => { /** * Creates metadata from a hierarchized entry. - * @param {import('../types.d.ts').HierarchizedEntry} entry - The entry to create metadata from. + * @param {import('../../../utils/buildHierarchy.mjs').HierarchizedEntry} entry - The entry to create metadata from. * @returns {import('../types.d.ts').Meta} The created metadata. */ const createMeta = ({ diff --git a/src/generators/legacy-json/utils/__tests__/buildHierarchy.test.mjs b/src/utils/__tests__/buildHierarchy.test.mjs similarity index 100% rename from src/generators/legacy-json/utils/__tests__/buildHierarchy.test.mjs rename to src/utils/__tests__/buildHierarchy.test.mjs diff --git a/src/utils/assertAstType.mjs b/src/utils/assertAstType.mjs new file mode 100644 index 00000000..eb02e35b --- /dev/null +++ b/src/utils/assertAstType.mjs @@ -0,0 +1,55 @@ +'use strict'; + +import { enforceArray } from './array.mjs'; +import { GeneratorError } from './generator-error.mjs'; + +/** + * @typedef {import('mdast').BlockContentMap} BlockContentMap + * @typedef {import('mdast').ListContentMap} ListContentMap + * @typedef {import('mdast').FrontmatterContentMap} FrontmatterContentMap + * @typedef {import('mdast').PhrasingContentMap} PhrasingContentMap + * @typedef {import('mdast').RootContentMap} RootContentMap + * @typedef {import('mdast').RowContentMap} RowContentMap + * @typedef {import('mdast').TableContentMap} TableContentMap + * @typedef {import('mdast').DefinitionContentMap} DefinitionContentMap + * + * @typedef {BlockContentMap & ListContentMap & FrontmatterContentMap & PhrasingContentMap & RootContentMap & RowContentMap & TableContentMap & DefinitionContentMap} NodeTypes + */ + +/** + * @template {keyof NodeTypes} T + * + * @param {import('mdast').Node} node + * @param {T | Array} type + * @returns {NodeTypes[T]} + */ +export function assertAstType(node, type) { + if (node?.type === undefined) { + throw new GeneratorError(`expected node.type to be defined`); + } + + type = enforceArray(type); + + if (!type.includes(node.type)) { + throw new GeneratorError( + `expected node to have type ${type}, got ${node.type}` + ); + } + + return node; +} + +/** + * @template {keyof NodeTypes} T + * + * @param {import('mdast').Node | undefined} node + * @param {T} type + * @returns {NodeTypes[T] | undefined} + */ +export function assertAstTypeOptional(node, type) { + if (!node) { + return undefined; + } + + return assertAstType(node, type); +} diff --git a/src/generators/legacy-json/utils/buildHierarchy.mjs b/src/utils/buildHierarchy.mjs similarity index 95% rename from src/generators/legacy-json/utils/buildHierarchy.mjs rename to src/utils/buildHierarchy.mjs index f7ad87cd..bde4288a 100644 --- a/src/generators/legacy-json/utils/buildHierarchy.mjs +++ b/src/utils/buildHierarchy.mjs @@ -1,3 +1,11 @@ +'use strict'; + +/** + * @typedef {{ + * hierarchyChildren: Array + * } & ApiDocMetadataEntry} HierarchizedEntry + */ + /** * Recursively finds the most suitable parent entry for a given `entry` based on heading depth. * diff --git a/src/utils/generator-error.mjs b/src/utils/generator-error.mjs new file mode 100644 index 00000000..6533cfad --- /dev/null +++ b/src/utils/generator-error.mjs @@ -0,0 +1,38 @@ +/** + * An error thrown by a generator when it encounters something unexpected. + * + * @typedef {{ + * entry?: ApiDocMetadataEntry + * } & ErrorOptions} GeneratorErrorOptions + */ +export class GeneratorError extends Error { + /** + * @type {ApiDocMetadataEntry | undefined} + */ + entry; + + /** + * @param {string} message + * @param {GeneratorErrorOptions} [options] + */ + constructor(message, options) { + super(message, options); + + this.entry = options?.entry; + } + + /** + * Get the error message with some debug info attached + */ + get message() { + let message = super.message; + + // Add general info of what was being processed when this error was thrown + // for debugging + if (this.entry) { + message += ` (${this.entry.api_doc_source}#${this.entry.slug})`; + } + + return message; + } +} diff --git a/src/utils/unist.mjs b/src/utils/unist.mjs index fe3bccff..08c1ef88 100644 --- a/src/utils/unist.mjs +++ b/src/utils/unist.mjs @@ -24,6 +24,8 @@ export const transformNodeToString = (node, escape) => { return `**${transformNodesToString(node.children, escape)}**`; case 'emphasis': return `_${transformNodesToString(node.children, escape)}_`; + case 'link': + return `[${transformNodesToString(node.children, escape)}](${node.url})`; default: { if (node.children) { return transformNodesToString(node.children, escape); diff --git a/tools/generate-json-types.mjs b/tools/generate-json-types.mjs new file mode 100755 index 00000000..37d8b5dd --- /dev/null +++ b/tools/generate-json-types.mjs @@ -0,0 +1,35 @@ +#!/usr/bin/env node + +/** + * Generates the typedefs for the JSON generator from the JSON schema + * + * To use, just run this. + */ + +import { readFile, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; + +import { compile } from 'json-schema-to-typescript'; +import { parse } from 'jsonc-parser'; + +const JSON_GENERATOR_PATH = join( + import.meta.dirname, + '..', + 'src', + 'generators', + 'json' +); +const SCHEMA_PATH = join(JSON_GENERATOR_PATH, 'schema.jsonc'); +const TYPES_PATH = join(JSON_GENERATOR_PATH, 'generated.d.ts'); + +// Read the contents of the JSON schema +const schemaString = await readFile(SCHEMA_PATH, 'utf8'); + +// Parse the JSON schema into an object +const schema = await parse(schemaString); + +// Compile the the JSON schema into TypeScript typedefs +const typeDefs = await compile(schema, 'ApiDocSchema'); + +// Write the types to the expected output path +await writeFile(TYPES_PATH, typeDefs);