diff --git a/package-lock.json b/package-lock.json index 3337f92..2c8dd14 100644 --- a/package-lock.json +++ b/package-lock.json @@ -72,6 +72,43 @@ "astro-ls": "bin/nodeServer.js" } }, + "node_modules/@astrojs/lit": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@astrojs/lit/-/lit-2.1.0.tgz", + "integrity": "sha512-X0CmJOq7kPygZFlpUdQ7fo4K7/pt7Q4osPpQZNYfueHMsgLh6PtikRJb/Oq/zgFAWN//lYWTnjCvsZyV6O1l+w==", + "dependencies": { + "@lit-labs/ssr": "^3.1.3", + "@lit-labs/ssr-client": "^1.1.2", + "@lit-labs/ssr-dom-shim": "^1.1.1", + "parse5": "^7.1.2" + }, + "peerDependencies": { + "@webcomponents/template-shadowroot": "^0.2.1", + "lit": "^2.7.0" + } + }, + "node_modules/@astrojs/lit/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@astrojs/lit/node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/@astrojs/markdown-remark": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-2.2.1.tgz", @@ -172,9 +209,9 @@ } }, "node_modules/@astrojs/sitemap": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-1.3.3.tgz", - "integrity": "sha512-TPyyb/hKxc+bHPpSoNPhsuI0QOTVzq2tueg2r0CTH1HqigYIAA2LQkCBlQzz85R+LrOZpv4kXYmhxdDcSkJCmA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-2.0.0.tgz", + "integrity": "sha512-hcemuFigv05sdXNiw0U23VO+6Duj9nq9xhINw4ZPWAQEhS/F4EiNvd9IUXb4XJ7pG93MWAnQKF9lP8EtwP6paA==", "dependencies": { "sitemap": "^7.1.1", "zod": "^3.17.3" @@ -5396,19 +5433,90 @@ "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==", "dev": true }, + "node_modules/@lit-labs/ssr": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr/-/ssr-3.1.5.tgz", + "integrity": "sha512-OvjM3CZGPRjZTIAgWvLCXS3sFj574rXfAzhtzQjgHYNxTuRy+LMfKpgeu8xF7PywdcOniVaLZuGKF4WS7YI7hA==", + "dependencies": { + "@lit-labs/ssr-client": "^1.1.0", + "@lit-labs/ssr-dom-shim": "^1.1.0", + "@lit/reactive-element": "^1.6.0", + "@parse5/tools": "^0.1.0", + "@types/node": "^16.0.0", + "enhanced-resolve": "^5.10.0", + "lit": "^2.7.0", + "lit-element": "^3.3.0", + "lit-html": "^2.7.0", + "node-fetch": "^3.2.8", + "parse5": "^7.1.1" + }, + "engines": { + "node": ">=13.9.0" + } + }, + "node_modules/@lit-labs/ssr-client": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-client/-/ssr-client-1.1.2.tgz", + "integrity": "sha512-hb10IRTmxtnQ2fcYYJE7bC2f+6UmucBgFnkfxepoE1cZ5mO6ZiTZGoFzFrNd5EQXeQq+HpYmYOF4W/JBwBE+AA==", + "dependencies": { + "@lit/reactive-element": "^1.0.0", + "lit": "^2.0.0", + "lit-html": "^2.7.1" + } + }, "node_modules/@lit-labs/ssr-dom-shim": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.1.tgz", - "integrity": "sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ==", - "dev": true, - "peer": true + "integrity": "sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ==" + }, + "node_modules/@lit-labs/ssr/node_modules/@types/node": { + "version": "16.18.38", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.38.tgz", + "integrity": "sha512-6sfo1qTulpVbkxECP+AVrHV9OoJqhzCsfTNp5NIG+enM4HyM3HvZCO798WShIXBN0+QtDIcutJCjsVYnQP5rIQ==" + }, + "node_modules/@lit-labs/ssr/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@lit-labs/ssr/node_modules/node-fetch": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz", + "integrity": "sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/@lit-labs/ssr/node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } }, "node_modules/@lit/reactive-element": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-1.6.2.tgz", "integrity": "sha512-rDfl+QnCYjuIGf5xI2sVJWdYIi56CTCwWa+nidKYX6oIuBYwUbT/vX4qbUDlHiZKJ/3FRNQ/tWJui44p6/stSA==", - "dev": true, - "peer": true, "dependencies": { "@lit-labs/ssr-dom-shim": "^1.0.0" } @@ -5680,6 +5788,36 @@ "@octokit/openapi-types": "^18.0.0" } }, + "node_modules/@parse5/tools": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@parse5/tools/-/tools-0.1.0.tgz", + "integrity": "sha512-VB9+4BsFoS+4HdB/Ph9jD4FHQt7GyiWESVNfBSh8Eu54LujWyy+NySGLjg8GZFWSZcESG72F67LjgmKZDZCvPg==", + "dependencies": { + "parse5": "^7.0.0" + } + }, + "node_modules/@parse5/tools/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@parse5/tools/node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -10824,9 +10962,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "18.2.14", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.14.tgz", - "integrity": "sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g==", + "version": "18.2.15", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.15.tgz", + "integrity": "sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -10834,9 +10972,9 @@ } }, "node_modules/@types/react-dom": { - "version": "18.2.6", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.6.tgz", - "integrity": "sha512-2et4PDvg6PVCyS7fuTc4gPoksV58bW0RwSxWKcPRcHZf0PRUGq03TKcD/rUHe3azfV6/5/biUBJw+HhCQjaP0A==", + "version": "18.2.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz", + "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==", "dependencies": { "@types/react": "*" } @@ -10904,9 +11042,7 @@ "node_modules/@types/trusted-types": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz", - "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==", - "dev": true, - "peer": true + "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==" }, "node_modules/@types/unist": { "version": "2.0.6", @@ -11422,6 +11558,11 @@ "integrity": "sha512-iGdlqtajmiqed8ptURKPJ/Olz0/mwripVZszg6tygfZSIL9kYFPJTNY6+Q6OjWGznl2L06vxG5HvNvAnWrnzbg==", "dev": true }, + "node_modules/@webcomponents/template-shadowroot": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@webcomponents/template-shadowroot/-/template-shadowroot-0.2.1.tgz", + "integrity": "sha512-fXL/vIUakyZL62hyvUh+EMwbVoTc0hksublmRz6ai6et8znHkJa6gtqMUZo1oc7dIz46exHSIImml9QTdknMHg==" + }, "node_modules/@yarnpkg/esbuild-plugin-pnp": { "version": "3.0.0-rc.15", "resolved": "https://registry.npmjs.org/@yarnpkg/esbuild-plugin-pnp/-/esbuild-plugin-pnp-3.0.0-rc.15.tgz", @@ -11865,9 +12006,9 @@ } }, "node_modules/astro": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/astro/-/astro-2.7.3.tgz", - "integrity": "sha512-DwPvvOYElhCNyAWUlFd17HhTNBx+XXnAZfM/PYHq7RicvC/tG4loBjlYk/Yw7x9wQCkbKjoxVRiNYvmvSUmisw==", + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/astro/-/astro-2.8.5.tgz", + "integrity": "sha512-qfPUKLpZ9lVi5Hc5MrzyekUUx54AyrEphW5eetNQj/+d0iodHEneZXFDzZxTEsk3rL8Y2Y9pYFXJPmQB3eahUA==", "dependencies": { "@astrojs/compiler": "^1.5.3", "@astrojs/internal-helpers": "^0.1.1", @@ -11922,6 +12063,7 @@ "vfile": "^5.3.7", "vite": "^4.3.9", "vitefu": "^0.2.4", + "which-pm": "^2.0.0", "yargs-parser": "^21.1.1", "zod": "^3.20.6" }, @@ -14402,7 +14544,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "dev": true, "engines": { "node": ">= 12" } @@ -15370,6 +15511,18 @@ "once": "^1.4.0" } }, + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -16382,7 +16535,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "dev": true, "funding": [ { "type": "github", @@ -16786,7 +16938,6 @@ "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dev": true, "dependencies": { "fetch-blob": "^3.1.2" }, @@ -23674,11 +23825,9 @@ "dev": true }, "node_modules/lit": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/lit/-/lit-2.7.5.tgz", - "integrity": "sha512-i/cH7Ye6nBDUASMnfwcictBnsTN91+aBjXoTHF2xARghXScKxpD4F4WYI+VLXg9lqbMinDfvoI7VnZXjyHgdfQ==", - "dev": true, - "peer": true, + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/lit/-/lit-2.7.6.tgz", + "integrity": "sha512-1amFHA7t4VaaDe+vdQejSVBklwtH9svGoG6/dZi9JhxtJBBlqY5D1RV7iLUYY0trCqQc4NfhYYZilZiVHt7Hxg==", "dependencies": { "@lit/reactive-element": "^1.6.0", "lit-element": "^3.3.0", @@ -23689,8 +23838,6 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-3.3.2.tgz", "integrity": "sha512-xXAeVWKGr4/njq0rGC9dethMnYCq5hpKYrgQZYTzawt9YQhMiXfD+T1RgrdY3NamOxwq2aXlb0vOI6e29CKgVQ==", - "dev": true, - "peer": true, "dependencies": { "@lit-labs/ssr-dom-shim": "^1.1.0", "@lit/reactive-element": "^1.3.0", @@ -23701,8 +23848,6 @@ "version": "2.7.4", "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-2.7.4.tgz", "integrity": "sha512-/Jw+FBpeEN+z8X6PJva5n7+0MzCVAH2yypN99qHYYkq8bI+j7I39GH+68Z/MZD6rGKDK9RpzBw7CocfmHfq6+g==", - "dev": true, - "peer": true, "dependencies": { "@types/trusted-types": "^2.0.2" } @@ -24066,9 +24211,9 @@ } }, "node_modules/marked": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-5.1.0.tgz", - "integrity": "sha512-z3/nBe7aTI8JDszlYLk7dDVNpngjw0o1ZJtrA9kIfkkHcIF+xH7mO23aISl4WxP83elU+MFROgahqdpd05lMEQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/marked/-/marked-5.1.1.tgz", + "integrity": "sha512-bTmmGdEINWmOMDjnPWDxGPQ4qkDLeYorpYbEtFOXzOruTwUE671q4Guiuchn4N8h/v6NGd7916kXsm3Iz4iUSg==", "bin": { "marked": "bin/marked.js" }, @@ -25801,7 +25946,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "dev": true, "funding": [ { "type": "github", @@ -30222,9 +30366,9 @@ } }, "node_modules/postcss": { - "version": "8.4.24", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", - "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", + "version": "8.4.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.26.tgz", + "integrity": "sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==", "funding": [ { "type": "opencollective", @@ -33798,6 +33942,14 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/tar": { "version": "6.1.15", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", @@ -34947,13 +35099,13 @@ } }, "node_modules/vite": { - "version": "4.3.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", - "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.4.tgz", + "integrity": "sha512-4mvsTxjkveWrKDJI70QmelfVqTm+ihFAb6+xf4sjEU2TmUCTlVX87tmg/QooPEMQb/lM9qGHT99ebqPziEd3wg==", "dependencies": { - "esbuild": "^0.17.5", - "postcss": "^8.4.23", - "rollup": "^3.21.0" + "esbuild": "^0.18.10", + "postcss": "^8.4.25", + "rollup": "^3.25.2" }, "bin": { "vite": "bin/vite.js" @@ -34961,12 +35113,16 @@ "engines": { "node": "^14.18.0 || >=16.0.0" }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@types/node": ">= 14", "less": "*", + "lightningcss": "^1.21.0", "sass": "*", "stylus": "*", "sugarss": "*", @@ -34979,6 +35135,9 @@ "less": { "optional": true }, + "lightningcss": { + "optional": true + }, "sass": { "optional": true }, @@ -35047,6 +35206,372 @@ } } }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.14.tgz", + "integrity": "sha512-blODaaL+lngG5bdK/t4qZcQvq2BBqrABmYwqPPcS5VRxrCSGHb9R/rA3fqxh7R18I7WU4KKv+NYkt22FDfalcg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.14.tgz", + "integrity": "sha512-rZ2v+Luba5/3D6l8kofWgTnqE+qsC/L5MleKIKFyllHTKHrNBMqeRCnZI1BtRx8B24xMYxeU32iIddRQqMsOsg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.14.tgz", + "integrity": "sha512-qSwh8y38QKl+1Iqg+YhvCVYlSk3dVLk9N88VO71U4FUjtiSFylMWK3Ugr8GC6eTkkP4Tc83dVppt2n8vIdlSGg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.14.tgz", + "integrity": "sha512-9Hl2D2PBeDYZiNbnRKRWuxwHa9v5ssWBBjisXFkVcSP5cZqzZRFBUWEQuqBHO4+PKx4q4wgHoWtfQ1S7rUqJ2Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.14.tgz", + "integrity": "sha512-ZnI3Dg4ElQ6tlv82qLc/UNHtFsgZSKZ7KjsUNAo1BF1SoYDjkGKHJyCrYyWjFecmXpvvG/KJ9A/oe0H12odPLQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.14.tgz", + "integrity": "sha512-h3OqR80Da4oQCIa37zl8tU5MwHQ7qgPV0oVScPfKJK21fSRZEhLE4IIVpmcOxfAVmqjU6NDxcxhYaM8aDIGRLw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.14.tgz", + "integrity": "sha512-ha4BX+S6CZG4BoH9tOZTrFIYC1DH13UTCRHzFc3GWX74nz3h/N6MPF3tuR3XlsNjMFUazGgm35MPW5tHkn2lzQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.14.tgz", + "integrity": "sha512-5+7vehI1iqru5WRtJyU2XvTOvTGURw3OZxe3YTdE9muNNIdmKAVmSHpB3Vw2LazJk2ifEdIMt/wTWnVe5V98Kg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.14.tgz", + "integrity": "sha512-IXORRe22In7U65NZCzjwAUc03nn8SDIzWCnfzJ6t/8AvGx5zBkcLfknI+0P+hhuftufJBmIXxdSTbzWc8X/V4w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.14.tgz", + "integrity": "sha512-BfHlMa0nibwpjG+VXbOoqJDmFde4UK2gnW351SQ2Zd4t1N3zNdmUEqRkw/srC1Sa1DRBE88Dbwg4JgWCbNz/FQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.14.tgz", + "integrity": "sha512-j2/Ex++DRUWIAaUDprXd3JevzGtZ4/d7VKz+AYDoHZ3HjJzCyYBub9CU1wwIXN+viOP0b4VR3RhGClsvyt/xSw==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.14.tgz", + "integrity": "sha512-qn2+nc+ZCrJmiicoAnJXJJkZWt8Nwswgu1crY7N+PBR8ChBHh89XRxj38UU6Dkthl2yCVO9jWuafZ24muzDC/A==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.14.tgz", + "integrity": "sha512-aGzXzd+djqeEC5IRkDKt3kWzvXoXC6K6GyYKxd+wsFJ2VQYnOWE954qV2tvy5/aaNrmgPTb52cSCHFE+Z7Z0yg==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.14.tgz", + "integrity": "sha512-8C6vWbfr0ygbAiMFLS6OPz0BHvApkT2gCboOGV76YrYw+sD/MQJzyITNsjZWDXJwPu9tjrFQOVG7zijRzBCnLw==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.14.tgz", + "integrity": "sha512-G/Lf9iu8sRMM60OVGOh94ZW2nIStksEcITkXdkD09/T6QFD/o+g0+9WVyR/jajIb3A0LvBJ670tBnGe1GgXMgw==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.14.tgz", + "integrity": "sha512-TBgStYBQaa3EGhgqIDM+ECnkreb0wkcKqL7H6m+XPcGUoU4dO7dqewfbm0mWEQYH3kzFHrzjOFNpSAVzDZRSJw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.14.tgz", + "integrity": "sha512-stvCcjyCQR2lMTroqNhAbvROqRjxPEq0oQ380YdXxA81TaRJEucH/PzJ/qsEtsHgXlWFW6Ryr/X15vxQiyRXVg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.14.tgz", + "integrity": "sha512-apAOJF14CIsN5ht1PA57PboEMsNV70j3FUdxLmA2liZ20gEQnfTG5QU0FhENo5nwbTqCB2O3WDsXAihfODjHYw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.14.tgz", + "integrity": "sha512-fYRaaS8mDgZcGybPn2MQbn1ZNZx+UXFSUoS5Hd2oEnlsyUcr/l3c6RnXf1bLDRKKdLRSabTmyCy7VLQ7VhGdOQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.14.tgz", + "integrity": "sha512-1c44RcxKEJPrVj62XdmYhxXaU/V7auELCmnD+Ri+UCt+AGxTvzxl9uauQhrFso8gj6ZV1DaORV0sT9XSHOAk8Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.14.tgz", + "integrity": "sha512-EXAFttrdAxZkFQmpvcAQ2bywlWUsONp/9c2lcfvPUhu8vXBBenCXpoq9YkUvVP639ld3YGiYx0YUQ6/VQz3Maw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.14.tgz", + "integrity": "sha512-K0QjGbcskx+gY+qp3v4/940qg8JitpXbdxFhRDA1aYoNaPff88+aEwoq45aqJ+ogpxQxmU0ZTjgnrQD/w8iiUg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.18.14", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.14.tgz", + "integrity": "sha512-uNPj5oHPYmj+ZhSQeYQVFZ+hAlJZbAGOmmILWIqrGvPVlNLbyOvU5Bu6Woi8G8nskcx0vwY0iFoMPrzT86Ko+w==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.14", + "@esbuild/android-arm64": "0.18.14", + "@esbuild/android-x64": "0.18.14", + "@esbuild/darwin-arm64": "0.18.14", + "@esbuild/darwin-x64": "0.18.14", + "@esbuild/freebsd-arm64": "0.18.14", + "@esbuild/freebsd-x64": "0.18.14", + "@esbuild/linux-arm": "0.18.14", + "@esbuild/linux-arm64": "0.18.14", + "@esbuild/linux-ia32": "0.18.14", + "@esbuild/linux-loong64": "0.18.14", + "@esbuild/linux-mips64el": "0.18.14", + "@esbuild/linux-ppc64": "0.18.14", + "@esbuild/linux-riscv64": "0.18.14", + "@esbuild/linux-s390x": "0.18.14", + "@esbuild/linux-x64": "0.18.14", + "@esbuild/netbsd-x64": "0.18.14", + "@esbuild/openbsd-x64": "0.18.14", + "@esbuild/sunos-x64": "0.18.14", + "@esbuild/win32-arm64": "0.18.14", + "@esbuild/win32-ia32": "0.18.14", + "@esbuild/win32-x64": "0.18.14" + } + }, "node_modules/vitefu": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.4.tgz", @@ -35454,7 +35979,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", - "dev": true, "engines": { "node": ">= 8" } @@ -36006,15 +36530,18 @@ "name": "scottnath-dot-com", "version": "0.0.0", "dependencies": { + "@astrojs/lit": "^2.1.0", "@astrojs/mdx": "^0.19.7", "@astrojs/react": "^2.2.1", "@astrojs/rss": "^2.4.3", - "@astrojs/sitemap": "^1.3.3", - "@types/react": "^18.2.14", - "@types/react-dom": "^18.2.6", + "@astrojs/sitemap": "^2.0.0", + "@types/react": "^18.2.15", + "@types/react-dom": "^18.2.7", + "@webcomponents/template-shadowroot": "^0.2.1", "airtable": "^0.12.1", - "astro": "^2.7.3", - "marked": "^5.1.0", + "astro": "^2.8.5", + "lit": "^2.7.6", + "marked": "^5.1.1", "react": "^18.2.0", "react-dom": "^18.2.0", "typescript": "^5.1.6" @@ -36027,7 +36554,7 @@ "postcss-nested": "^6.0.1", "prop-types": "^15.8.1", "sass": "^1.63.6", - "vite": "^4.3.9" + "vite": "^4.4.4" } } } diff --git a/workspaces/components/.storybook/preview.js b/workspaces/components/.storybook/preview.js index a92766a..e0e935a 100644 --- a/workspaces/components/.storybook/preview.js +++ b/workspaces/components/.storybook/preview.js @@ -1,3 +1,7 @@ +import { setCustomElementsManifest } from '@storybook/web-components'; +import customElements from '../src/custom-elements.json'; + +setCustomElementsManifest(customElements); /** @type { import('@storybook/web-components').Preview } */ const preview = { parameters: { diff --git a/workspaces/components/src/devto/README.md b/workspaces/components/src/devto/README.md new file mode 100644 index 0000000..5c974b1 --- /dev/null +++ b/workspaces/components/src/devto/README.md @@ -0,0 +1,24 @@ +# Dev.to profile card widget + +WIP for use on scottnath.com only + +## @todo + +- [ ] Fetch non-key data from api +- [ ] i18 || configure titles +- [ ] use `data-thing` for attributes? +- [ ] re-do `parts`, removing parts that are just for style-sharing +- [ ] interaction tests +- [ ] a11y testing +- [ ] create custom element manifest + - [ ] need [plugins](https://custom-elements-manifest.open-wc.org/blog/intro/#plugins) to do JSDoc correctly +- [ ] separate out fetch and data handling from component +- [ ] alt-option that allows use of api-key +- [ ] test in plain HTML page +- [ ] test in Qwik +- [ ] test in Next.js + +## Inspriation + +- https://dev.to/asheeshh/devembed-embed-your-devto-profile-anywhere-using-widgets-linode-hacakathon-4659 +- https://dev.to/saurabhdaware/i-made-dev-to-widget-for-websites-blogs-40p2 \ No newline at end of file diff --git a/workspaces/components/src/devto/devto.shared-spec.js b/workspaces/components/src/devto/devto.shared-spec.js new file mode 100644 index 0000000..ee2f316 --- /dev/null +++ b/workspaces/components/src/devto/devto.shared-spec.js @@ -0,0 +1,29 @@ + +export const smileySvg = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAJUlEQVR42u3NQQEAAAQEsJNcdFLw2gqsMukcK4lEIpFIJBLJS7KG6yVo40DbTgAAAABJRU5ErkJggg==' + +export const snUserFixture = { + id: 1055555, + username: 'scottnath', + name: 'Scott Nath', + summary: "I'm sorry, as an a.i. language model I cannot write your bio for you.", + joined_at: 'Mar 30, 2023', + profile_image: 'https://res.cloudinary.com/practicaldev/image/fetch/s--8gi1l6OI--/c_fill,f_auto,fl_progressive,h_320,q_auto,w_320/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/1055555/8146c5bb-31d3-4023-a216-5cb5c00ecb3b.jpg', + joined: '2023-03-30', + post_count: 8 +} + +export const snPostFixture = { + title: 'Sharing UI Tests Between Javascript Frameworks', + description: 'How to share testing-library UI tests between Javascript frameworks with the same or similar components and use them in Storybook and unit testing.', + url: 'https://dev.to/scottnath/sharing-ui-tests-between-javascript-frameworks-2l6n', + cover_image: 'https://res.cloudinary.com/practicaldev/image/fetch/s--NqWkGO2---/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z5070dozgnb32uwtm5dm.png', +} + +export const meowUserFixture = { + id: 1055555, + username: 'meowmeow', + name: 'Meow Meow', + summary: "Just a meow, with a meow's worries. Nothin but a meow.", + joined_at: 'Feb 29, 2020', + profile_image: smileySvg, +} diff --git a/workspaces/components/src/devto/devto.stories.js b/workspaces/components/src/devto/devto.stories.js new file mode 100644 index 0000000..0ecf3fa --- /dev/null +++ b/workspaces/components/src/devto/devto.stories.js @@ -0,0 +1,61 @@ + +import './'; +import { snUserFixture, meowUserFixture } from './devto.shared-spec'; + +export default { + title: 'DevTo', + component: 'dev-user', + tags: ['autodocs'], +}; + +export const Username = { + args: { + username: 'scottnath', + }, +}; + +export const NewUser = { + args: { + username: 'soyecoder', + }, +} + +export const AltUserData = { + args: { + user: { + ...snUserFixture, + name: 'Someother Name', + summary: 'Different summary content than what is from the dev.to api', + joined_at: 'Jan 1, 1979', + post_count: 1, + }, + }, +} + +export const SkipFetch = { + args: { + user: meowUserFixture, + skipFetch: true, + }, +} + +export const SkipFetchJustUsername = { + args: { + user: { + username: 'scottnath' + }, + skipFetch: true, + }, +} + +export const SkipFetchFail = { + args: { + skipFetch: true, + }, +} + +export const UnknownUsername = { + args: { + username: 'NotAUserMeow', + }, +} diff --git a/workspaces/components/src/devto/index.js b/workspaces/components/src/devto/index.js new file mode 100644 index 0000000..5f9a68d --- /dev/null +++ b/workspaces/components/src/devto/index.js @@ -0,0 +1,272 @@ +import { LitElement, html, css, unsafeCSS } from 'lit'; +import {when} from 'lit/directives/when.js'; + +// import stylesDep from './style.css' +import styles from './styles.css?inline' + +/** + * Blank base64-encoded png + * @see https://png-pixel.com/ + */ +const blankPng = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mN8/x8AAuMB8DtXNJsAAAAASUVORK5CYII='; + +/** + * dev.to logo + * @see https://dev.to/brand + */ +const devLogoSvg = html` + + +`; + +/** + * Forem icon for a cake (used with "Joined" date) + * @see https://github.com/forem/forem/blob/main/app/assets/images/cake.svg?short_path=e3c7d41 + */ +const joinedSvg = html` + +`; + +/** + * Forem icon for a post + * @see https://github.com/forem/forem/blob/main/app/assets/images/post.svg?short_path=b79fa43 + */ +const postSvg = html` + +`; + +/** + * Content about one post by dev.to (or Forem) user, sourced from the Forem API. + * @see https://developers.forem.com/api/v1#tag/articles/operation/getLatestArticles + * @typedef {Object} ForemPost + * @property {string} title - The title of the post + * @property {string} url - The URL of the post + * @property {string} cover_image - The URL of the post's full-size cover image + */ + +/** + * Render a link to a post + * @param {ForemPost} post - Content about a post + */ +const postLink = (post) => html` +Cover image for post ${post.title} +${post.title}`; + +/** + * Content about a dev.to (or Forem) user, sourced from the Forem API and combined with post data. + * Only the properties used in this component are defined. + * @see https://developers.forem.com/api/v0#tag/users/operation/getUser + * @typedef {Object} ForemUser + * + * @property {string} username - The username of the user + * @property {string} name - The name of the user + * @property {string} summary - The user's bio + * @property {string} joined_at - The date the user joined + * @property {string} profile_image - The URL of the user's profile image + * @property {number} post_count - The number of posts the user has published + */ + + +/** + * Render a link to a user's profile + * @param {ForemUser} user - Content about a user + */ +const profileLink = (user) => html` +
+ View Profile on dev.to +
+`; + +/** + * Render a user's avatar + * @param {ForemUser} user - Content about a user + */ +const userAvatar = (user) => html`Avatar for ${user?.name}`; + +/** + * Render a user's joined date + * @param {ForemUser} user - Content about a user + */ +const userJoined = (user) => this.user?.joined_at ? html`

+${joinedSvg} +Joined on + + +

+` : ''; + +/** + * dev.to profile component + * @element dev-user + * @cssprop --devto-color + * @prop {string} username - The username of the user + * @prop {ForemUser} user - Content about a user + * @prop {ForemPost} latest_post - Content about a post + */ +export class DevToProfile extends LitElement { + static properties = { + user: { type: Object }, + username: { type: String }, + latest_post: { type: Object }, + skipFetch: { type: Boolean }, + }; + static styles = css` + ${unsafeCSS(styles)} + `; + + async firstUpdated() { + if (!this.username && this.user?.username) { + this.username = this.user.username; + } + if (this.skipFetch) { + if (!this.username) { + this._generateError( + 'A username is required to skip fetching data', + 'UI requires a name and username at minimum', + ) + return; + } + } else { + if (this.username) { + await this._generateUser(this.username); + } else { + await this._generateUser(null, this.user?.id); + } + } + await this._cleanUserData(); + } + + /** + * Format a date for machine-readability + * @param {string} dt + * @returns {string} - the machine-readable value of the date + */ + _formatDate(dt) { + const x = new Date(dt); + const year = x.getFullYear() + const month = String(x.getMonth() + 1).padStart(2, '0') + const day = String(x.getDate()).padStart(2, '0') + + return `${year}-${month}-${day}` + } + + async _fetchPosts(username) { + const articles = await fetch(`https://dev.to/api/articles/latest?per_page=1000&username=${username?.toLowerCase()}`); + const articlesJson = await articles.json(); + this.user.post_count = this.user.post_count || articlesJson.length; + if (articlesJson.length && !this.latest_post) { + this.latest_post = articlesJson[0]; + } + } + + async _fetchUserResponse(username, id) { + if (!username && id) { + return await fetch(`https://dev.to/api/users/${id}`); + } + return await fetch(`https://dev.to/api/users/by_username?url=${username?.toLowerCase()}`); + } + + async _generateError(msg, status) { + this.user = { + name: msg, + status, + } + } + + async _generateUser(username, id) { + const response = await this._fetchUserResponse(username, id); + const jsonResponse = await response.json(); + if (jsonResponse.error) { + this._generateError( + `User ${username || id} ${jsonResponse.error}`, + jsonResponse.error, + ) + return; + } + this.user = { + ...jsonResponse, + ...this.user, + } + if (typeof this.user.post_count !== 'number' || (this.user.post_count > 0 && !this.latest_post)) { + await this._fetchPosts(this.user.username); + } + console.log(this.user) + console.log(this.latest_post) + } + + /** + * Clean up data to conform to the HTML-expected content model + */ + async _cleanUserData() { + this.user.profile_image = this.user.profile_image || blankPng; + this.user.name = this.user.name || `@${this.user.username}`; + if (this.user.joined_at) { + this.user.joined = this.user.joined || this._formatDate(this.user.joined_at); + } + if (this.user.post_count && Number(this.user.post_count) !== NaN) { + this.user.post_count = Number(this.user.post_count); + } else { + delete this.user?.post_count; + } + this.latest_post.cover_image = this.latest_post.cover_image || blankPng; + } + + render() { + if (this.user?.status) { + return html` +
+
+
${devLogoSvg}
+ +

+ ${this.user?.name} +

+
+
+ `; + } + + return when(this.user?.username, () => html` +
+
+
${devLogoSvg}
+ +

+ + + ${userAvatar(this.user)} + + ${this.user?.name} + +

+
+
+ ${when(this.user?.summary, () => html`

${this.user?.summary}

`)} + ${when(this.user?.joined_at, () => html`

+ ${joinedSvg} + Joined on + + +

`)} + ${when(this.user?.post_count > 0, () => html` +

+ ${postSvg} + ${this.user?.post_count} posts published +

+ `)} + ${when(this.latest_post, () => html` +
+
Latest post
+
${postLink(this.latest_post)}
+
+ `)} +
+ +
+ `); + } +} + +customElements.define('dev-user', DevToProfile); \ No newline at end of file diff --git a/workspaces/components/src/devto/styles.css b/workspaces/components/src/devto/styles.css new file mode 100644 index 0000000..3238dbc --- /dev/null +++ b/workspaces/components/src/devto/styles.css @@ -0,0 +1,190 @@ +:host { + /** styles from forem/forem */ + --ff-sans-serif: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', + 'Segoe UI Symbol'; + --white: 255, 255, 255; + --black: 0, 0, 0; + --grey-100: 245, 245, 245; + --grey-900: 23, 23, 23; + --indigo-600: 79, 70, 229; + --indigo-700: 67, 56, 202; + --base-60: #717171; + --base-70: #575757; + --base-90: #242424; + --radius: 0.375rem; + --radius-auto: Max(0px, Min(var(--radius), calc((100vw - 4px - 100%) * 9999))) / var(--radius); + + --body-bg: rgb(var(--grey-100)); + --card-bg: rgb(var(--white)); + --card-color: var(--base-70); + --card-color-bold: var(--base-90); + --card-shadow-color: rgba(var(--grey-900), 0.05); + --fw-bold: 700; + + --accent-brand: rgb(var(--indigo-600)); + --accent-brand-darker: rgb(var(--indigo-700)); + --profile-brand-color: rgb(var(--black)); + + --cta-bg: transparent; + --cta-bg-hover: rgba(var(--indigo-600), 0.1); + --cta-color: rgb(var(--grey-800)); + --cta-color-hover: var(--accent-brand-darker); + --cta-border: rgb(var(--grey-600)); + --cta-border-hover: var(--accent-brand-darker); + + --cta-branded-bg: transparent; + --cta-branded-bg-hover: var(--accent-brand); + --cta-branded-color: var(--accent-brand); + --cta-branded-color-hover: rgb(var(--white)); + --cta-branded-border: var(--accent-brand); + --cta-branded-border-hover: var(--accent-brand-darker); +} +:host { + color: var(--card-color); + font-size: 16px; + line-height: 1.5; + font-family: var(--ff-sans-serif); +} +/** root elements cleanup */ +a { + text-decoration: none; +} +dl, dd, dt { + margin: 0; + padding: 0; +} +p { + margin: 0.5em 0; +} +p > svg { + vertical-align: top; + width: 1.3em; + height: 1.3em; +} +address { + font-style: normal; +} + +:host::part(mild) { + font-size: .875em; + color: var(--base-70); +} +:host::part(bold) { + font-size: 1.25em; + color: var(--card-color-bold); + font-weight: var(--fw-bold); +} + +:host::part(container) { + position: relative; + border-top: 2em solid var(--profile-brand-color); + border-radius: var(--radius-auto); + box-shadow: 0 0 0 1px var(--card-shadow-color); + background: var(--card-bg); + + overflow-wrap: break-word; + overflow-wrap: anywhere; + max-width: 30em; +} + +:host header { + border-bottom: 1px solid var(--body-bg); + margin-bottom: 1em; + padding: 0 1em; +} +:host footer { + border-top: 1px solid var(--body-bg); + margin: 1em 0 0; + padding: 1em; +} + +:host::part(logo) { + width: 1.6em; + height: 1.6em; + margin: 0 auto; + position: absolute; + right: 1em; + top: -1.8em; + box-shadow: 0 0 0 1px white; + border-radius: .07em; +} + +:host header a { + display: flex; + margin-top: -1em; +} + +:host::part(avatar-container) { + display: inline-block; + border-radius: 100%; + position: relative; + width: 3em; + height: 3em; + overflow: hidden; + vertical-align: middle; + flex-shrink: 0; + margin-right: .5em; +} +:host::part(avatar) { + border-radius: 100%; + width: 100%; + height: 100%; + display: inline-block; + vertical-align: bottom; +} + +:host::part(name) { + margin-top: 1.25em; +} + +:host::part(main) { + padding: 0 1em; +} + +:host::part(post) { + /* display: flex; + gap: .5em; */ + color: var(--card-color-bold); +} +:host::part(post-img) { + width: 100%; + height: auto; + /* object-fit: scale-down; */ +} +:host::part(cta) { + border: 1px solid; + outline: 0; + text-align: center; + display: block; + position: relative; + overflow-wrap: normal; + padding: .5em 1em; + + border-color: var(--cta-border); + border-radius: var(--radius); + background-color: var(--cta-bg); + color: var(--cta-color); +} + +:host::part(cta):hover, :host::part(cta):focus { + background-color: var(--cta-bg-hover); + border-color: var(--cta-border-hover); + color: var(--cta-color-hover); +} + +:host::part(cta):focus { + box-shadow: var(--focus-ring); + text-decoration: underline +} + +:host::part(branded) { + border-color: var(--cta-branded-border); + background-color: var(--cta-branded-bg); + color: var(--cta-branded-color); +} +:host::part(branded):hover, :host::part(branded):focus { + background-color: var(--cta-branded-bg-hover); + border-color: var(--cta-branded-border-hover); + color: var(--cta-branded-color-hover); +} \ No newline at end of file diff --git a/workspaces/components/src/foxes/index.js b/workspaces/components/src/foxes/index.js new file mode 100644 index 0000000..5b5e07c --- /dev/null +++ b/workspaces/components/src/foxes/index.js @@ -0,0 +1,48 @@ +import { LitElement, html } from 'lit'; + +const blankPng = + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mN8/x8AAuMB8DtXNJsAAAAASUVORK5CYII='; + +export class MyFetcher extends LitElement { + + static get properties() { + return { + fox: { type: String }, + fox2: { type: String }, + }; + } + constructor() { + super(); + this.fox = blankPng; + } + + async newfox() { + console.log('this.fox', this.fox); + this.fox = await this._fetchFox(); + console.log('this.fox', this.fox); + } + + async firstUpdated() { + this.fox = await this._fetchFox(); + console.log('this.fox', this.fox); + } + + async _fetchFox() { + const response = await fetch('https://randomfox.ca/floof/'); + const jsonResponse = await response.json(); + return jsonResponse.image; + this.fox = jsonResponse.image; + } + + render() { + return html` +
+

fox:

+ + +
+ `; + } +} + +customElements.define('my-fetcher', MyFetcher); diff --git a/workspaces/website/astro.config.mjs b/workspaces/website/astro.config.mjs index bbfb7ee..b2109f4 100644 --- a/workspaces/website/astro.config.mjs +++ b/workspaces/website/astro.config.mjs @@ -1,4 +1,5 @@ import { defineConfig } from 'astro/config'; +import lit from '@astrojs/lit'; import mdx from '@astrojs/mdx'; import partytown from '@astrojs/partytown'; import react from '@astrojs/react'; @@ -8,12 +9,14 @@ import sitemap from '@astrojs/sitemap'; // https://astro.build/config export default defineConfig({ site: 'https://scottnath.com', - integrations: [mdx(), sitemap(), react(), partytown({ - // Adds dataLayer.push as a forwarding-event. - config: { - forward: ['dataLayer.push'], - }, - }),], + integrations: [lit(), mdx(), sitemap(), react(), + partytown({ + // Adds dataLayer.push as a forwarding-event. + config: { + forward: ['dataLayer.push'], + }, + }), + ], experimental: { assets: true } diff --git a/workspaces/website/package.json b/workspaces/website/package.json index 39ef746..7b5b299 100644 --- a/workspaces/website/package.json +++ b/workspaces/website/package.json @@ -14,15 +14,18 @@ "site-files": "npm run 404file && npm run jekyllfile && npm run cname" }, "dependencies": { + "@astrojs/lit": "^2.1.0", "@astrojs/mdx": "^0.19.7", "@astrojs/react": "^2.2.1", "@astrojs/rss": "^2.4.3", - "@astrojs/sitemap": "^1.3.3", - "@types/react": "^18.2.14", - "@types/react-dom": "^18.2.6", + "@astrojs/sitemap": "^2.0.0", + "@types/react": "^18.2.15", + "@types/react-dom": "^18.2.7", + "@webcomponents/template-shadowroot": "^0.2.1", "airtable": "^0.12.1", - "astro": "^2.7.3", - "marked": "^5.1.0", + "astro": "^2.8.5", + "lit": "^2.7.6", + "marked": "^5.1.1", "react": "^18.2.0", "react-dom": "^18.2.0", "typescript": "^5.1.6" @@ -35,6 +38,6 @@ "postcss-nested": "^6.0.1", "prop-types": "^15.8.1", "sass": "^1.63.6", - "vite": "^4.3.9" + "vite": "^4.4.4" } } diff --git a/workspaces/website/src/content/sites-to-check-if-should-link.txt b/workspaces/website/src/content/sites-to-check-if-should-link.txt new file mode 100644 index 0000000..1dd88ce --- /dev/null +++ b/workspaces/website/src/content/sites-to-check-if-should-link.txt @@ -0,0 +1,46 @@ +extracted via /Users/scottnath/development/deletable/sherlock + +https://discussions.apple.com/profile/scottnath +https://ask.fm/scottnath +https://audiojungle.net/user/scottnath +https://www.codecademy.com/profiles/scottnath +https://dev.to/scottnath +https://disqus.com/scottnath +https://hub.docker.com/u/scottnath/ +https://www.duolingo.com/profile/scottnath +https://www.fiverr.com/scottnath +https://flipboard.com/@scottnath +https://www.freelancer.com/u/scottnath +https://freesound.org/people/scottnath/ +https://www.g2g.com/scottnath +https://www.github.com/scottnath +http://en.gravatar.com/scottnath +https://www.ifttt.com/p/scottnath +https://imgur.com/user/scottnath +https://www.instructables.com/member/scottnath +https://kik.me/scottnath +https://medium.com/@scottnath +https://www.reddit.com/user/scottnath +https://www.roblox.com/user.aspx?username=scottnath +https://slideshare.net/scottnath +https://slides.com/scottnath +https://www.smule.com/scottnath +https://www.snapchat.com/add/scottnath +https://soundcloud.com/scottnath +https://open.spotify.com/user/scottnath +https://themeforest.net/user/scottnath +https://trello.com/scottnath +https://www.twitch.tv/scottnath +https://twitter.com/scottnath +https://unsplash.com/@scottnath +https://account.venmo.com/u/scottnath +https://en.wikipedia.org/wiki/Special:CentralAuth/scottnath?uselang=qqx +https://profiles.wordpress.org/scottnath/ +https://www.youtube.com/c/scottnath +https://www.youtube.com/user/scottnath +https://last.fm/user/scottnath +https://mastodon.social/@scottnath +https://www.npmjs.com/~scottnath +Total Websites Username Detected On : 41 + +https://stackexchange.com/users/19070958/scott-nath