From fc1daf43350b092e1faac78e00cede2b01e1e35a Mon Sep 17 00:00:00 2001 From: radishzzz Date: Sat, 25 Jan 2025 08:19:31 +0000 Subject: [PATCH] refactor: restructure project configuration and utility modules - Move configuration and utility files to more organized locations - Update import paths across the project to reflect new file structure - Simplify content and internationalization utilities - Remove redundant configuration files and consolidate logic - Add prefetch configuration to Astro config for improved performance --- astro.config.ts | 6 +- package.json | 4 +- pnpm-lock.yaml | 385 +++++++++--------- ...anguageSwitcher.astro => LangSwitch.astro} | 0 .../{Navigation.astro => Navbar.astro} | 0 src/{config/index.ts => config.ts} | 44 +- src/layouts/Layout.astro | 4 +- src/pages/[lang]/about.astro | 6 +- src/pages/[lang]/index.astro | 8 +- src/pages/[lang]/posts/[slug].astro | 16 +- src/pages/[lang]/rss.xml.ts | 77 +--- src/pages/[lang]/tags/[tags].astro | 11 +- src/pages/[lang]/tags/index.astro | 9 +- src/pages/index.astro | 2 +- src/pages/posts/[slug].astro | 12 +- src/pages/rss.xml.ts | 64 +-- src/pages/tags/[tags].astro | 2 +- src/pages/tags/index.astro | 2 +- src/styles/scrollbar.css | 3 - src/types/index.d.ts | 9 +- src/utils/{content.config.ts => content.ts} | 0 src/utils/i18n.ts | 38 ++ src/utils/rss.ts | 71 ++++ 23 files changed, 380 insertions(+), 393 deletions(-) rename src/components/{LanguageSwitcher.astro => LangSwitch.astro} (100%) rename src/components/{Navigation.astro => Navbar.astro} (100%) rename src/{config/index.ts => config.ts} (74%) rename src/utils/{content.config.ts => content.ts} (100%) create mode 100644 src/utils/i18n.ts create mode 100644 src/utils/rss.ts diff --git a/astro.config.ts b/astro.config.ts index 21b221a..4883900 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -18,7 +18,7 @@ import remarkGithubAdmonitionsToDirectives from 'remark-github-admonitions-to-di import remarkMath from 'remark-math' import remarkSectionize from 'remark-sectionize' import UnoCSS from 'unocss/astro' -import { themeConfig } from './src/config' +import { themeConfig } from './src/config.js' // Local plugins import { AdmonitionComponent } from './src/plugins/rehype-component-admonition.mjs' import { GithubCardComponent } from './src/plugins/rehype-component-github-card.mjs' @@ -34,6 +34,10 @@ const { locale } = themeConfig.global export default defineConfig({ site: url, base: '/', + prefetch: { + prefetchAll: true, + defaultStrategy: 'viewport', + }, i18n: { locales: Object.entries(langMap).map(([path, codes]) => ({ path, diff --git a/package.json b/package.json index 3f96a23..12aeb7c 100644 --- a/package.json +++ b/package.json @@ -51,8 +51,8 @@ "@types/sanitize-html": "^2.13.0", "@unocss/eslint-plugin": "^65.4.3", "@unocss/preset-attributify": "^65.4.3", - "astro-eslint-parser": "^1.1.0", - "eslint": "^9.18.0", + "astro-eslint-parser": "^1.2.0", + "eslint": "^9.19.0", "eslint-plugin-astro": "^1.3.1", "lint-staged": "^15.4.2", "mdast-util-to-string": "^4.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 666f76c..e1a2d54 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -98,7 +98,7 @@ importers: devDependencies: '@antfu/eslint-config': specifier: ^3.16.0 - version: 3.16.0(@typescript-eslint/utils@8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(@unocss/eslint-plugin@65.4.3(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.7.3))(eslint-plugin-astro@1.3.1(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) + version: 3.16.0(@typescript-eslint/utils@8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(@unocss/eslint-plugin@65.4.3(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.2.0)(eslint-plugin-astro@1.3.1(eslint@9.19.0(jiti@2.4.2)))(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) '@types/markdown-it': specifier: ^14.1.2 version: 14.1.2 @@ -110,19 +110,19 @@ importers: version: 2.13.0 '@unocss/eslint-plugin': specifier: ^65.4.3 - version: 65.4.3(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) + version: 65.4.3(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) '@unocss/preset-attributify': specifier: ^65.4.3 version: 65.4.3 astro-eslint-parser: - specifier: ^1.1.0 - version: 1.1.0(typescript@5.7.3) + specifier: ^1.2.0 + version: 1.2.0 eslint: - specifier: ^9.18.0 - version: 9.18.0(jiti@2.4.2) + specifier: ^9.19.0 + version: 9.19.0(jiti@2.4.2) eslint-plugin-astro: specifier: ^1.3.1 - version: 1.3.1(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) + version: 1.3.1(eslint@9.19.0(jiti@2.4.2)) lint-staged: specifier: ^15.4.2 version: 15.4.2 @@ -268,13 +268,13 @@ packages: resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} - '@babel/parser@7.26.5': - resolution: {integrity: sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==} + '@babel/parser@7.26.7': + resolution: {integrity: sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/types@7.26.5': - resolution: {integrity: sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==} + '@babel/types@7.26.7': + resolution: {integrity: sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==} engines: {node: '>=6.9.0'} '@clack/core@0.4.1': @@ -646,8 +646,8 @@ packages: resolution: {integrity: sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.18.0': - resolution: {integrity: sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==} + '@eslint/js@9.19.0': + resolution: {integrity: sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/markdown@6.2.2': @@ -976,6 +976,10 @@ packages: '@shikijs/vscode-textmate@10.0.1': resolution: {integrity: sha512-fTIQwLF+Qhuws31iw7Ncl1R3HUDtGwIipiJ9iU+UsDUwMhegFcQKQHd51nZjb7CArq0MvON8rbgCGQYWHUKAdg==} + '@sindresorhus/merge-streams@2.3.0': + resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} + engines: {node: '>=18'} + '@stylistic/eslint-plugin@2.13.0': resolution: {integrity: sha512-RnO1SaiCFHn666wNz2QfZEFxvmiNRqhzaMXHXxXXKt+MEP7aajlPxUSMIQpKAaJfverpovEYqjBOXDq6dDcaOQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1342,10 +1346,6 @@ packages: array-iterate@2.0.1: resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - astring@1.9.0: resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true @@ -1353,8 +1353,8 @@ packages: astro-compress@2.3.6: resolution: {integrity: sha512-P93OXRRykS2iLGN20KAr1tJUAUGptKOnUybqg00/8N4aHrZxR76giBhK/C9RCLm8tsnxL0nR5FCXR53MUza9Mg==} - astro-eslint-parser@1.1.0: - resolution: {integrity: sha512-F6NW1RJo5pp2kPnnM97M5Ohw8zAGjv83MpxHqfAochH68n/kiXN57+hYaNUCA7XkScoVNr6yzvly3hsY34TGfQ==} + astro-eslint-parser@1.2.0: + resolution: {integrity: sha512-LmJ63+AsDEBjo1rXFe87rxqhvMCS3W756oGBDqg83+FAOqGPjj1OncpCcn1OPqOhk5MyENkx3w0H6TrDgXEgPQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} astro-robots-txt@1.0.0: @@ -1581,8 +1581,8 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - crossws@0.3.2: - resolution: {integrity: sha512-S2PpQHRcgYABOS2465b34wqTOn5dbLL+iSvyweJYGGFLDsKq88xrjDXUiEhfYkhWZq1HuS6of3okRHILbkrqxw==} + crossws@0.3.3: + resolution: {integrity: sha512-/71DJT3xJlqSnBr83uGJesmVHSzZEvgxHt/fIKxBAAngqMHmnBWQNxCphVxxJ2XL3xleu5+hJD6IQ3TglBedcw==} css-select@5.1.0: resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} @@ -1679,10 +1679,6 @@ packages: resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} engines: {node: '>=0.3.1'} - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} @@ -1717,8 +1713,8 @@ packages: duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - electron-to-chromium@1.5.87: - resolution: {integrity: sha512-mPFwmEWmRivw2F8x3w3l2m6htAUN97Gy0kwpO++2m9iT1Gt8RCFVUfv9U/sIbHJ6rY4P6/ooqFL/eL7ock+pPg==} + electron-to-chromium@1.5.88: + resolution: {integrity: sha512-K3C2qf1o+bGzbilTDCTBhTQcMS9KW60yTAaTeeXsfvQuTDDwlokLam/AdqlqcSy9u4UainDgsHV23ksXAOgamw==} emmet@2.4.11: resolution: {integrity: sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==} @@ -1740,6 +1736,10 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} + entities@6.0.0: + resolution: {integrity: sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw==} + engines: {node: '>=0.12'} + environment@1.1.0: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} engines: {node: '>=18'} @@ -1849,8 +1849,8 @@ packages: peerDependencies: eslint: ^8.57.0 || ^9.0.0 - eslint-plugin-jsdoc@50.6.2: - resolution: {integrity: sha512-n7GNZ4czMAAbDg7DsDA7PvHo1IPIUwAXYmxTx6j/hTlXbt5V0x5q/kGkiJ7s4wA9SpB/yaiK8jF7CO237lOLew==} + eslint-plugin-jsdoc@50.6.3: + resolution: {integrity: sha512-NxbJyt1M5zffPcYZ8Nb53/8nnbIScmiLAMdoe0/FAszwb7lcSiX3iYBTsuF7RV84dZZJC8r3NghomrUXsmWvxQ==} engines: {node: '>=18'} peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 @@ -1938,8 +1938,8 @@ packages: resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.18.0: - resolution: {integrity: sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==} + eslint@9.19.0: + resolution: {integrity: sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -2126,9 +2126,9 @@ packages: resolution: {integrity: sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==} engines: {node: '>=18'} - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} + globby@14.0.2: + resolution: {integrity: sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==} + engines: {node: '>=18'} graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -2940,9 +2940,9 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} + path-type@5.0.0: + resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==} + engines: {node: '>=12'} pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} @@ -3276,9 +3276,9 @@ packages: engines: {node: '>=14.0.0', npm: '>=6.0.0'} hasBin: true - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} slashes@3.0.12: resolution: {integrity: sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==} @@ -3509,6 +3509,10 @@ packages: unenv@1.10.0: resolution: {integrity: sha512-wY5bskBQFL9n3Eca5XnhH6KbUo/tfvkwm9OpcdCvLaeA7piBNbavbOKJySEwQ1V0RH6HvNlSAFRTpvTqgKRQXQ==} + unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -3939,48 +3943,48 @@ snapshots: '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 - '@antfu/eslint-config@3.16.0(@typescript-eslint/utils@8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(@unocss/eslint-plugin@65.4.3(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.7.3))(eslint-plugin-astro@1.3.1(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3)': + '@antfu/eslint-config@3.16.0(@typescript-eslint/utils@8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(@unocss/eslint-plugin@65.4.3(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.2.0)(eslint-plugin-astro@1.3.1(eslint@9.19.0(jiti@2.4.2)))(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3)': dependencies: '@antfu/install-pkg': 1.0.0 '@clack/prompts': 0.9.1 - '@eslint-community/eslint-plugin-eslint-comments': 4.4.1(eslint@9.18.0(jiti@2.4.2)) + '@eslint-community/eslint-plugin-eslint-comments': 4.4.1(eslint@9.19.0(jiti@2.4.2)) '@eslint/markdown': 6.2.2 - '@stylistic/eslint-plugin': 2.13.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) - '@typescript-eslint/eslint-plugin': 8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) - '@typescript-eslint/parser': 8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) - '@vitest/eslint-plugin': 1.1.25(@typescript-eslint/utils@8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) - eslint: 9.18.0(jiti@2.4.2) - eslint-config-flat-gitignore: 1.0.0(eslint@9.18.0(jiti@2.4.2)) + '@stylistic/eslint-plugin': 2.13.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) + '@typescript-eslint/eslint-plugin': 8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) + '@typescript-eslint/parser': 8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) + '@vitest/eslint-plugin': 1.1.25(@typescript-eslint/utils@8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) + eslint: 9.19.0(jiti@2.4.2) + eslint-config-flat-gitignore: 1.0.0(eslint@9.19.0(jiti@2.4.2)) eslint-flat-config-utils: 1.1.0 - eslint-merge-processors: 1.0.0(eslint@9.18.0(jiti@2.4.2)) - eslint-plugin-antfu: 2.7.0(eslint@9.18.0(jiti@2.4.2)) - eslint-plugin-command: 2.1.0(eslint@9.18.0(jiti@2.4.2)) - eslint-plugin-import-x: 4.6.1(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) - eslint-plugin-jsdoc: 50.6.2(eslint@9.18.0(jiti@2.4.2)) - eslint-plugin-jsonc: 2.19.1(eslint@9.18.0(jiti@2.4.2)) - eslint-plugin-n: 17.15.1(eslint@9.18.0(jiti@2.4.2)) + eslint-merge-processors: 1.0.0(eslint@9.19.0(jiti@2.4.2)) + eslint-plugin-antfu: 2.7.0(eslint@9.19.0(jiti@2.4.2)) + eslint-plugin-command: 2.1.0(eslint@9.19.0(jiti@2.4.2)) + eslint-plugin-import-x: 4.6.1(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) + eslint-plugin-jsdoc: 50.6.3(eslint@9.19.0(jiti@2.4.2)) + eslint-plugin-jsonc: 2.19.1(eslint@9.19.0(jiti@2.4.2)) + eslint-plugin-n: 17.15.1(eslint@9.19.0(jiti@2.4.2)) eslint-plugin-no-only-tests: 3.3.0 - eslint-plugin-perfectionist: 4.7.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) - eslint-plugin-regexp: 2.7.0(eslint@9.18.0(jiti@2.4.2)) - eslint-plugin-toml: 0.12.0(eslint@9.18.0(jiti@2.4.2)) - eslint-plugin-unicorn: 56.0.1(eslint@9.18.0(jiti@2.4.2)) - eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.18.0(jiti@2.4.2)) - eslint-plugin-vue: 9.32.0(eslint@9.18.0(jiti@2.4.2)) - eslint-plugin-yml: 1.16.0(eslint@9.18.0(jiti@2.4.2)) - eslint-processor-vue-blocks: 1.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.18.0(jiti@2.4.2)) + eslint-plugin-perfectionist: 4.7.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) + eslint-plugin-regexp: 2.7.0(eslint@9.19.0(jiti@2.4.2)) + eslint-plugin-toml: 0.12.0(eslint@9.19.0(jiti@2.4.2)) + eslint-plugin-unicorn: 56.0.1(eslint@9.19.0(jiti@2.4.2)) + eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.19.0(jiti@2.4.2)) + eslint-plugin-vue: 9.32.0(eslint@9.19.0(jiti@2.4.2)) + eslint-plugin-yml: 1.16.0(eslint@9.19.0(jiti@2.4.2)) + eslint-processor-vue-blocks: 1.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.19.0(jiti@2.4.2)) globals: 15.14.0 jsonc-eslint-parser: 2.4.0 local-pkg: 1.0.0 parse-gitignore: 2.0.0 picocolors: 1.1.1 toml-eslint-parser: 0.10.0 - vue-eslint-parser: 9.4.3(eslint@9.18.0(jiti@2.4.2)) + vue-eslint-parser: 9.4.3(eslint@9.19.0(jiti@2.4.2)) yaml-eslint-parser: 1.2.3 yargs: 17.7.2 optionalDependencies: - '@unocss/eslint-plugin': 65.4.3(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) - astro-eslint-parser: 1.1.0(typescript@5.7.3) - eslint-plugin-astro: 1.3.1(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) + '@unocss/eslint-plugin': 65.4.3(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) + astro-eslint-parser: 1.2.0 + eslint-plugin-astro: 1.3.1(eslint@9.19.0(jiti@2.4.2)) transitivePeerDependencies: - '@eslint/json' - '@typescript-eslint/utils' @@ -4130,11 +4134,11 @@ snapshots: '@babel/helper-validator-identifier@7.25.9': {} - '@babel/parser@7.26.5': + '@babel/parser@7.26.7': dependencies: - '@babel/types': 7.26.5 + '@babel/types': 7.26.7 - '@babel/types@7.26.5': + '@babel/types@7.26.7': dependencies: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 @@ -4340,22 +4344,22 @@ snapshots: '@esbuild/win32-x64@0.24.2': optional: true - '@eslint-community/eslint-plugin-eslint-comments@4.4.1(eslint@9.18.0(jiti@2.4.2))': + '@eslint-community/eslint-plugin-eslint-comments@4.4.1(eslint@9.19.0(jiti@2.4.2))': dependencies: escape-string-regexp: 4.0.0 - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) ignore: 5.3.2 - '@eslint-community/eslint-utils@4.4.1(eslint@9.18.0(jiti@2.4.2))': + '@eslint-community/eslint-utils@4.4.1(eslint@9.19.0(jiti@2.4.2))': dependencies: - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/compat@1.2.5(eslint@9.18.0(jiti@2.4.2))': + '@eslint/compat@1.2.5(eslint@9.19.0(jiti@2.4.2))': optionalDependencies: - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) '@eslint/config-array@0.19.1': dependencies: @@ -4383,7 +4387,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.18.0': {} + '@eslint/js@9.19.0': {} '@eslint/markdown@6.2.2': dependencies: @@ -4687,10 +4691,12 @@ snapshots: '@shikijs/vscode-textmate@10.0.1': {} - '@stylistic/eslint-plugin@2.13.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3)': + '@sindresorhus/merge-streams@2.3.0': {} + + '@stylistic/eslint-plugin@2.13.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3)': dependencies: - '@typescript-eslint/utils': 8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) - eslint: 9.18.0(jiti@2.4.2) + '@typescript-eslint/utils': 8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) + eslint: 9.19.0(jiti@2.4.2) eslint-visitor-keys: 4.2.0 espree: 10.3.0 estraverse: 5.3.0 @@ -4785,15 +4791,15 @@ snapshots: '@types/unist@3.0.3': {} - '@typescript-eslint/eslint-plugin@8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3)': + '@typescript-eslint/eslint-plugin@8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) + '@typescript-eslint/parser': 8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) '@typescript-eslint/scope-manager': 8.21.0 - '@typescript-eslint/type-utils': 8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) - '@typescript-eslint/utils': 8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) + '@typescript-eslint/type-utils': 8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) + '@typescript-eslint/utils': 8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) '@typescript-eslint/visitor-keys': 8.21.0 - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 @@ -4802,14 +4808,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3)': + '@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3)': dependencies: '@typescript-eslint/scope-manager': 8.21.0 '@typescript-eslint/types': 8.21.0 '@typescript-eslint/typescript-estree': 8.21.0(typescript@5.7.3) '@typescript-eslint/visitor-keys': 8.21.0 debug: 4.4.0 - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) typescript: 5.7.3 transitivePeerDependencies: - supports-color @@ -4819,12 +4825,12 @@ snapshots: '@typescript-eslint/types': 8.21.0 '@typescript-eslint/visitor-keys': 8.21.0 - '@typescript-eslint/type-utils@8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3)': + '@typescript-eslint/type-utils@8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3)': dependencies: '@typescript-eslint/typescript-estree': 8.21.0(typescript@5.7.3) - '@typescript-eslint/utils': 8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) + '@typescript-eslint/utils': 8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) debug: 4.4.0 - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) ts-api-utils: 2.0.0(typescript@5.7.3) typescript: 5.7.3 transitivePeerDependencies: @@ -4846,13 +4852,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3)': + '@typescript-eslint/utils@8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.18.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.19.0(jiti@2.4.2)) '@typescript-eslint/scope-manager': 8.21.0 '@typescript-eslint/types': 8.21.0 '@typescript-eslint/typescript-estree': 8.21.0(typescript@5.7.3) - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) typescript: 5.7.3 transitivePeerDependencies: - supports-color @@ -4906,9 +4912,9 @@ snapshots: '@unocss/core@65.4.3': {} - '@unocss/eslint-plugin@65.4.3(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3)': + '@unocss/eslint-plugin@65.4.3(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3)': dependencies: - '@typescript-eslint/utils': 8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) + '@typescript-eslint/utils': 8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) '@unocss/config': 65.4.3 '@unocss/core': 65.4.3 '@unocss/rule-utils': 65.4.3 @@ -5036,10 +5042,10 @@ snapshots: - supports-color - vue - '@vitest/eslint-plugin@1.1.25(@typescript-eslint/utils@8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3)': + '@vitest/eslint-plugin@1.1.25(@typescript-eslint/utils@8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3)': dependencies: - '@typescript-eslint/utils': 8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) - eslint: 9.18.0(jiti@2.4.2) + '@typescript-eslint/utils': 8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) + eslint: 9.19.0(jiti@2.4.2) optionalDependencies: typescript: 5.7.3 @@ -5095,7 +5101,7 @@ snapshots: '@vue/compiler-core@3.5.13': dependencies: - '@babel/parser': 7.26.5 + '@babel/parser': 7.26.7 '@vue/shared': 3.5.13 entities: 4.5.0 estree-walker: 2.0.2 @@ -5108,7 +5114,7 @@ snapshots: '@vue/compiler-sfc@3.5.13': dependencies: - '@babel/parser': 7.26.5 + '@babel/parser': 7.26.7 '@vue/compiler-core': 3.5.13 '@vue/compiler-dom': 3.5.13 '@vue/compiler-ssr': 3.5.13 @@ -5204,8 +5210,6 @@ snapshots: array-iterate@2.0.1: {} - array-union@2.1.0: {} - astring@1.9.0: {} astro-compress@2.3.6(@types/node@22.10.10)(jiti@2.4.2)(rollup@4.32.0)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0): @@ -5256,24 +5260,22 @@ snapshots: - uploadthing - yaml - astro-eslint-parser@1.1.0(typescript@5.7.3): + astro-eslint-parser@1.2.0: dependencies: '@astrojs/compiler': 2.10.3 '@typescript-eslint/scope-manager': 8.21.0 '@typescript-eslint/types': 8.21.0 - '@typescript-eslint/typescript-estree': 8.21.0(typescript@5.7.3) astrojs-compiler-sync: 1.0.1(@astrojs/compiler@2.10.3) debug: 4.4.0 - entities: 4.5.0 + entities: 6.0.0 eslint-scope: 8.2.0 eslint-visitor-keys: 4.2.0 espree: 10.3.0 - globby: 11.1.0 + globby: 14.0.2 is-glob: 4.0.3 semver: 7.6.3 transitivePeerDependencies: - supports-color - - typescript astro-robots-txt@1.0.0: dependencies: @@ -5421,7 +5423,7 @@ snapshots: browserslist@4.24.4: dependencies: caniuse-lite: 1.0.30001695 - electron-to-chromium: 1.5.87 + electron-to-chromium: 1.5.88 node-releases: 2.0.19 update-browserslist-db: 1.1.2(browserslist@4.24.4) @@ -5567,7 +5569,7 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - crossws@0.3.2: + crossws@0.3.3: dependencies: uncrypto: 0.1.3 @@ -5644,10 +5646,6 @@ snapshots: diff@5.2.0: {} - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - dlv@1.1.3: {} doctrine@3.0.0: @@ -5683,7 +5681,7 @@ snapshots: duplexer@0.1.2: {} - electron-to-chromium@1.5.87: {} + electron-to-chromium@1.5.88: {} emmet@2.4.11: dependencies: @@ -5703,6 +5701,8 @@ snapshots: entities@4.5.0: {} + entities@6.0.0: {} + environment@1.1.0: {} error-ex@1.3.2: @@ -5788,20 +5788,20 @@ snapshots: escape-string-regexp@5.0.0: {} - eslint-compat-utils@0.5.1(eslint@9.18.0(jiti@2.4.2)): + eslint-compat-utils@0.5.1(eslint@9.19.0(jiti@2.4.2)): dependencies: - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) semver: 7.6.3 - eslint-compat-utils@0.6.4(eslint@9.18.0(jiti@2.4.2)): + eslint-compat-utils@0.6.4(eslint@9.19.0(jiti@2.4.2)): dependencies: - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) semver: 7.6.3 - eslint-config-flat-gitignore@1.0.0(eslint@9.18.0(jiti@2.4.2)): + eslint-config-flat-gitignore@1.0.0(eslint@9.19.0(jiti@2.4.2)): dependencies: - '@eslint/compat': 1.2.5(eslint@9.18.0(jiti@2.4.2)) - eslint: 9.18.0(jiti@2.4.2) + '@eslint/compat': 1.2.5(eslint@9.19.0(jiti@2.4.2)) + eslint: 9.19.0(jiti@2.4.2) find-up-simple: 1.0.0 eslint-flat-config-utils@1.1.0: @@ -5816,57 +5816,56 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-json-compat-utils@0.2.1(eslint@9.18.0(jiti@2.4.2))(jsonc-eslint-parser@2.4.0): + eslint-json-compat-utils@0.2.1(eslint@9.19.0(jiti@2.4.2))(jsonc-eslint-parser@2.4.0): dependencies: - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) esquery: 1.6.0 jsonc-eslint-parser: 2.4.0 - eslint-merge-processors@1.0.0(eslint@9.18.0(jiti@2.4.2)): + eslint-merge-processors@1.0.0(eslint@9.19.0(jiti@2.4.2)): dependencies: - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) - eslint-plugin-antfu@2.7.0(eslint@9.18.0(jiti@2.4.2)): + eslint-plugin-antfu@2.7.0(eslint@9.19.0(jiti@2.4.2)): dependencies: '@antfu/utils': 0.7.10 - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) - eslint-plugin-astro@1.3.1(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3): + eslint-plugin-astro@1.3.1(eslint@9.19.0(jiti@2.4.2)): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.18.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.19.0(jiti@2.4.2)) '@jridgewell/sourcemap-codec': 1.5.0 '@typescript-eslint/types': 8.21.0 - astro-eslint-parser: 1.1.0(typescript@5.7.3) - eslint: 9.18.0(jiti@2.4.2) - eslint-compat-utils: 0.6.4(eslint@9.18.0(jiti@2.4.2)) + astro-eslint-parser: 1.2.0 + eslint: 9.19.0(jiti@2.4.2) + eslint-compat-utils: 0.6.4(eslint@9.19.0(jiti@2.4.2)) globals: 15.14.0 postcss: 8.5.1 postcss-selector-parser: 7.0.0 transitivePeerDependencies: - supports-color - - typescript - eslint-plugin-command@2.1.0(eslint@9.18.0(jiti@2.4.2)): + eslint-plugin-command@2.1.0(eslint@9.19.0(jiti@2.4.2)): dependencies: '@es-joy/jsdoccomment': 0.50.0 - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) - eslint-plugin-es-x@7.8.0(eslint@9.18.0(jiti@2.4.2)): + eslint-plugin-es-x@7.8.0(eslint@9.19.0(jiti@2.4.2)): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.18.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.19.0(jiti@2.4.2)) '@eslint-community/regexpp': 4.12.1 - eslint: 9.18.0(jiti@2.4.2) - eslint-compat-utils: 0.5.1(eslint@9.18.0(jiti@2.4.2)) + eslint: 9.19.0(jiti@2.4.2) + eslint-compat-utils: 0.5.1(eslint@9.19.0(jiti@2.4.2)) - eslint-plugin-import-x@4.6.1(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3): + eslint-plugin-import-x@4.6.1(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3): dependencies: '@types/doctrine': 0.0.9 '@typescript-eslint/scope-manager': 8.21.0 - '@typescript-eslint/utils': 8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) + '@typescript-eslint/utils': 8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) debug: 4.4.0 doctrine: 3.0.0 enhanced-resolve: 5.18.0 - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 get-tsconfig: 4.10.0 is-glob: 4.0.3 @@ -5878,14 +5877,14 @@ snapshots: - supports-color - typescript - eslint-plugin-jsdoc@50.6.2(eslint@9.18.0(jiti@2.4.2)): + eslint-plugin-jsdoc@50.6.3(eslint@9.19.0(jiti@2.4.2)): dependencies: '@es-joy/jsdoccomment': 0.49.0 are-docs-informative: 0.0.2 comment-parser: 1.4.1 debug: 4.4.0 escape-string-regexp: 4.0.0 - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) espree: 10.3.0 esquery: 1.6.0 parse-imports: 2.2.1 @@ -5895,12 +5894,12 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-jsonc@2.19.1(eslint@9.18.0(jiti@2.4.2)): + eslint-plugin-jsonc@2.19.1(eslint@9.19.0(jiti@2.4.2)): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.18.0(jiti@2.4.2)) - eslint: 9.18.0(jiti@2.4.2) - eslint-compat-utils: 0.6.4(eslint@9.18.0(jiti@2.4.2)) - eslint-json-compat-utils: 0.2.1(eslint@9.18.0(jiti@2.4.2))(jsonc-eslint-parser@2.4.0) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.19.0(jiti@2.4.2)) + eslint: 9.19.0(jiti@2.4.2) + eslint-compat-utils: 0.6.4(eslint@9.19.0(jiti@2.4.2)) + eslint-json-compat-utils: 0.2.1(eslint@9.19.0(jiti@2.4.2))(jsonc-eslint-parser@2.4.0) espree: 9.6.1 graphemer: 1.4.0 jsonc-eslint-parser: 2.4.0 @@ -5909,12 +5908,12 @@ snapshots: transitivePeerDependencies: - '@eslint/json' - eslint-plugin-n@17.15.1(eslint@9.18.0(jiti@2.4.2)): + eslint-plugin-n@17.15.1(eslint@9.19.0(jiti@2.4.2)): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.18.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.19.0(jiti@2.4.2)) enhanced-resolve: 5.18.0 - eslint: 9.18.0(jiti@2.4.2) - eslint-plugin-es-x: 7.8.0(eslint@9.18.0(jiti@2.4.2)) + eslint: 9.19.0(jiti@2.4.2) + eslint-plugin-es-x: 7.8.0(eslint@9.19.0(jiti@2.4.2)) get-tsconfig: 4.10.0 globals: 15.14.0 ignore: 5.3.2 @@ -5923,45 +5922,45 @@ snapshots: eslint-plugin-no-only-tests@3.3.0: {} - eslint-plugin-perfectionist@4.7.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3): + eslint-plugin-perfectionist@4.7.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3): dependencies: '@typescript-eslint/types': 8.21.0 - '@typescript-eslint/utils': 8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) - eslint: 9.18.0(jiti@2.4.2) + '@typescript-eslint/utils': 8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) + eslint: 9.19.0(jiti@2.4.2) natural-orderby: 5.0.0 transitivePeerDependencies: - supports-color - typescript - eslint-plugin-regexp@2.7.0(eslint@9.18.0(jiti@2.4.2)): + eslint-plugin-regexp@2.7.0(eslint@9.19.0(jiti@2.4.2)): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.18.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.19.0(jiti@2.4.2)) '@eslint-community/regexpp': 4.12.1 comment-parser: 1.4.1 - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) jsdoc-type-pratt-parser: 4.1.0 refa: 0.12.1 regexp-ast-analysis: 0.7.1 scslre: 0.3.0 - eslint-plugin-toml@0.12.0(eslint@9.18.0(jiti@2.4.2)): + eslint-plugin-toml@0.12.0(eslint@9.19.0(jiti@2.4.2)): dependencies: debug: 4.4.0 - eslint: 9.18.0(jiti@2.4.2) - eslint-compat-utils: 0.6.4(eslint@9.18.0(jiti@2.4.2)) + eslint: 9.19.0(jiti@2.4.2) + eslint-compat-utils: 0.6.4(eslint@9.19.0(jiti@2.4.2)) lodash: 4.17.21 toml-eslint-parser: 0.10.0 transitivePeerDependencies: - supports-color - eslint-plugin-unicorn@56.0.1(eslint@9.18.0(jiti@2.4.2)): + eslint-plugin-unicorn@56.0.1(eslint@9.19.0(jiti@2.4.2)): dependencies: '@babel/helper-validator-identifier': 7.25.9 - '@eslint-community/eslint-utils': 4.4.1(eslint@9.18.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.19.0(jiti@2.4.2)) ci-info: 4.1.0 clean-regexp: 1.0.0 core-js-compat: 3.40.0 - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) esquery: 1.6.0 globals: 15.14.0 indent-string: 4.0.0 @@ -5974,41 +5973,41 @@ snapshots: semver: 7.6.3 strip-indent: 3.0.0 - eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.18.0(jiti@2.4.2)): + eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.19.0(jiti@2.4.2)): dependencies: - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3) + '@typescript-eslint/eslint-plugin': 8.21.0(@typescript-eslint/parser@8.21.0(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.19.0(jiti@2.4.2))(typescript@5.7.3) - eslint-plugin-vue@9.32.0(eslint@9.18.0(jiti@2.4.2)): + eslint-plugin-vue@9.32.0(eslint@9.19.0(jiti@2.4.2)): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.18.0(jiti@2.4.2)) - eslint: 9.18.0(jiti@2.4.2) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.19.0(jiti@2.4.2)) + eslint: 9.19.0(jiti@2.4.2) globals: 13.24.0 natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.1.2 semver: 7.6.3 - vue-eslint-parser: 9.4.3(eslint@9.18.0(jiti@2.4.2)) + vue-eslint-parser: 9.4.3(eslint@9.19.0(jiti@2.4.2)) xml-name-validator: 4.0.0 transitivePeerDependencies: - supports-color - eslint-plugin-yml@1.16.0(eslint@9.18.0(jiti@2.4.2)): + eslint-plugin-yml@1.16.0(eslint@9.19.0(jiti@2.4.2)): dependencies: debug: 4.4.0 - eslint: 9.18.0(jiti@2.4.2) - eslint-compat-utils: 0.6.4(eslint@9.18.0(jiti@2.4.2)) + eslint: 9.19.0(jiti@2.4.2) + eslint-compat-utils: 0.6.4(eslint@9.19.0(jiti@2.4.2)) lodash: 4.17.21 natural-compare: 1.4.0 yaml-eslint-parser: 1.2.3 transitivePeerDependencies: - supports-color - eslint-processor-vue-blocks@1.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.18.0(jiti@2.4.2)): + eslint-processor-vue-blocks@1.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.19.0(jiti@2.4.2)): dependencies: '@vue/compiler-sfc': 3.5.13 - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) eslint-scope@7.2.2: dependencies: @@ -6024,14 +6023,14 @@ snapshots: eslint-visitor-keys@4.2.0: {} - eslint@9.18.0(jiti@2.4.2): + eslint@9.19.0(jiti@2.4.2): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.18.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.4.1(eslint@9.19.0(jiti@2.4.2)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.19.1 '@eslint/core': 0.10.0 '@eslint/eslintrc': 3.2.0 - '@eslint/js': 9.18.0 + '@eslint/js': 9.19.0 '@eslint/plugin-kit': 0.2.5 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 @@ -6239,14 +6238,14 @@ snapshots: globals@15.14.0: {} - globby@11.1.0: + globby@14.0.2: dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 + '@sindresorhus/merge-streams': 2.3.0 fast-glob: 3.3.3 ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 + path-type: 5.0.0 + slash: 5.1.0 + unicorn-magic: 0.1.0 graceful-fs@4.2.11: {} @@ -6259,7 +6258,7 @@ snapshots: h3@1.14.0: dependencies: cookie-es: 1.2.2 - crossws: 0.3.2 + crossws: 0.3.3 defu: 6.1.4 destr: 2.0.3 iron-webcrypto: 1.2.1 @@ -6731,8 +6730,8 @@ snapshots: magicast@0.3.5: dependencies: - '@babel/parser': 7.26.5 - '@babel/types': 7.26.5 + '@babel/parser': 7.26.7 + '@babel/types': 7.26.7 source-map-js: 1.2.1 markdown-extensions@2.0.0: {} @@ -7442,7 +7441,7 @@ snapshots: path-parse@1.0.7: {} - path-type@4.0.0: {} + path-type@5.0.0: {} pathe@1.1.2: {} @@ -7927,7 +7926,7 @@ snapshots: arg: 5.0.2 sax: 1.4.1 - slash@3.0.0: {} + slash@5.1.0: {} slashes@3.0.12: {} @@ -8140,6 +8139,8 @@ snapshots: node-fetch-native: 1.6.6 pathe: 1.1.2 + unicorn-magic@0.1.0: {} + unified@11.0.5: dependencies: '@types/unist': 3.0.3 @@ -8422,10 +8423,10 @@ snapshots: vscode-uri@3.0.8: {} - vue-eslint-parser@9.4.3(eslint@9.18.0(jiti@2.4.2)): + vue-eslint-parser@9.4.3(eslint@9.19.0(jiti@2.4.2)): dependencies: debug: 4.4.0 - eslint: 9.18.0(jiti@2.4.2) + eslint: 9.19.0(jiti@2.4.2) eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 diff --git a/src/components/LanguageSwitcher.astro b/src/components/LangSwitch.astro similarity index 100% rename from src/components/LanguageSwitcher.astro rename to src/components/LangSwitch.astro diff --git a/src/components/Navigation.astro b/src/components/Navbar.astro similarity index 100% rename from src/components/Navigation.astro rename to src/components/Navbar.astro diff --git a/src/config/index.ts b/src/config.ts similarity index 74% rename from src/config/index.ts rename to src/config.ts index 5794a47..10ab3b9 100644 --- a/src/config/index.ts +++ b/src/config.ts @@ -3,11 +3,11 @@ import type { ThemeConfig } from '@/types' export const themeConfig: ThemeConfig = { // SITE INFORMATION >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START site: { - title: 'Retypeset', - subtitle: '再现版式之美', - description: '重新编排 - 再现版式之美 | Retypeset - Rediscover the beauty of typography', - author: 'radishzz', - url: 'https://retypeset.radishzz.cc', + title: 'Retypeset', // site title + subtitle: '再现版式之美', // site subtitle + description: 'This is Retypeset, an elegant and open-source Astro blog theme, help you rediscover the beauty of typography.', // site description for SEO + author: 'radishzz', // author name + url: 'https://retypeset.radishzz.cc', // site url favicon: '/image/logo.svg', // or https://image.example.com/logo.svg. Support only webp, svg, png }, // SITE INFORMATION >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END @@ -60,20 +60,20 @@ export const themeConfig: ThemeConfig = { facebookLink: '', // facebook profile link // site verification verification: { - google: '', - bing: '', - yandex: '', - baidu: '', + google: '', // Google Search Console: https://search.google.com/search-console + bing: '', // Bing Webmaster Tools: https://www.bing.com/webmasters + yandex: '', // Yandex Webmaster: https://webmaster.yandex.com + baidu: '', // Baidu Search: https://ziyuan.baidu.com }, // site analytics - googleAnalyticsID: '', - umamiAnalyticsID: '', + googleAnalyticsID: '', // Google Analytics: https://analytics.google.com + umamiAnalyticsID: '', // Umami Analytics: https://cloud.umami.is // follow verification follow: { - feedID: '', - userID: '', + feedID: '', // feed ID + userID: '', // user ID }, - siteScreenshot: '', // please take a screenshot of your website homepage to show on twitter card + siteScreenshot: '', // take a screenshot of your website homepage to show on twitter card }, // SEO SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END @@ -96,16 +96,28 @@ export const themeConfig: ThemeConfig = { // PRELOAD SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START preload: { - cdn: 'https://cdn.jsdelivr.net', // Recommended to keep default. Unless you can proxy https://cdn.jsdelivr.net/gh/radishzzz/astro-theme-retypeset/src/styles/font.css + cdn: 'https://cdn.jsdelivr.net', // Keep the default CDN unless you can proxy https://cdn.jsdelivr.net/gh/radishzzz/astro-theme-retypeset/src/styles/font.css commentURL: '', // https://comment.example.com/ imageHostURL: '', // https://image.example.com/ // If you proxy analytics requests to the custom domain, you can fill in below customGoogleAnalyticsURL: '', // https://custom.example.com/ customUmamiAnalyticsURL: '', // https://custom.example.com/ customUmamiAnalyticsJS: '', // https://custom.example.com/custom.js - lazyload: false, }, // PRELOAD SETTINGS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END + + // ABOUT PAGE CONTENT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> START + about: { + // Required: Content for about page in default language + '[locale]': '关于我', + // Optional: Content for about page in other languages. If not set, will fallback to [locale] content + 'zh-tw': '關於我', + 'ja': '私について', + 'en': 'About me', + 'es': 'Sobre mí', + 'ru': 'Обо мне', + }, + // ABOUT PAGE CONTENT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> END } export default themeConfig diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index 0fe565f..b62ae88 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -1,8 +1,8 @@ --- import Footer from '@/components/Footer.astro' import Header from '@/components/Header.astro' -import LanguageSwitcher from '@/components/LanguageSwitcher.astro' -import Navigation from '@/components/Navigation.astro' +import LanguageSwitcher from '@/components/LangSwitch.astro' +import Navigation from '@/components/Navbar.astro' import PhotoSwipe from '@/components/PhotoSwipe.astro' import Scrollbar from '@/components/Scrollbar.astro' import ThemeToggle from '@/components/ThemeToggle.astro' diff --git a/src/pages/[lang]/about.astro b/src/pages/[lang]/about.astro index f33fc26..988602d 100644 --- a/src/pages/[lang]/about.astro +++ b/src/pages/[lang]/about.astro @@ -1,11 +1,9 @@ --- -import { themeConfig } from '@/config' import Layout from '@/layouts/Layout.astro' +import { generateLanguagePaths } from '@/utils/i18n' export function getStaticPaths() { - return themeConfig.global.moreLocale.map(lang => ({ - params: { lang }, - })) + return generateLanguagePaths() } --- diff --git a/src/pages/[lang]/index.astro b/src/pages/[lang]/index.astro index def533c..0a3cccb 100644 --- a/src/pages/[lang]/index.astro +++ b/src/pages/[lang]/index.astro @@ -1,12 +1,10 @@ --- -import { themeConfig } from '@/config' import Layout from '@/layouts/Layout.astro' -import { getPinnedPosts, getPosts } from '@/utils/content.config' +import { getPinnedPosts, getPosts } from '@/utils/content' +import { generateLanguagePaths } from '@/utils/i18n' export function getStaticPaths() { - return themeConfig.global.moreLocale.map(lang => ({ - params: { lang }, - })) + return generateLanguagePaths() } const { lang } = Astro.params diff --git a/src/pages/[lang]/posts/[slug].astro b/src/pages/[lang]/posts/[slug].astro index e65d6a7..6a2f2a0 100644 --- a/src/pages/[lang]/posts/[slug].astro +++ b/src/pages/[lang]/posts/[slug].astro @@ -1,26 +1,18 @@ --- -import { themeConfig } from '@/config' import Layout from '@/layouts/Layout.astro' -import { checkSlugDuplication } from '@/utils/content.config' +import { checkSlugDuplication } from '@/utils/content' +import { generateMultiLangPostPaths } from '@/utils/i18n' import { getCollection } from 'astro:content' export async function getStaticPaths() { const posts = await getCollection('posts') - + const duplicates = await checkSlugDuplication(posts) if (duplicates.length > 0) { throw new Error(`Slug conflicts found:\n${duplicates.join('\n')}`) } - return themeConfig.global.moreLocale.flatMap(lang => - posts.map(post => ({ - params: { - lang, - slug: post.data.slug || post.slug, - }, - props: { post }, - })), - ) + return generateMultiLangPostPaths(posts) } const { post } = Astro.props diff --git a/src/pages/[lang]/rss.xml.ts b/src/pages/[lang]/rss.xml.ts index 408cee3..d84aab7 100644 --- a/src/pages/[lang]/rss.xml.ts +++ b/src/pages/[lang]/rss.xml.ts @@ -1,38 +1,8 @@ import type { APIContext } from 'astro' -import type { CollectionEntry } from 'astro:content' import themeConfig from '@/config' -import rss from '@astrojs/rss' -import { getCollection } from 'astro:content' -import MarkdownIt from 'markdown-it' -import sanitizeHtml from 'sanitize-html' +import { generateRSS } from '@/utils/rss' -const parser = new MarkdownIt() -const { title, description, url } = themeConfig.site const { moreLocale } = themeConfig.global -const followConfig = themeConfig.seo?.follow - -// Returns first 200 chars with proper truncation -function getExcerpt(content: string): string { - if (!content) - return '' - - // Convert markdown to plain text by removing all HTML tags - const plainText = sanitizeHtml(parser.render(content), { - allowedTags: [], - allowedAttributes: {}, - }) - - const excerpt = plainText.slice(0, 200).trim() - return excerpt.length === 200 ? `${excerpt}...` : excerpt -} - -// Return 404 for invalid language paths -function return404() { - return new Response(null, { - status: 404, - statusText: 'Not found', - }) -} // Type for supported non-default languages type SupportedLanguage = typeof moreLocale[number] @@ -46,43 +16,12 @@ export async function GET({ params }: APIContext) { const lang = params.lang as SupportedLanguage // Return 404 if language is not supported - if (!moreLocale.includes(lang)) - return return404() + if (!moreLocale.includes(lang)) { + return new Response(null, { + status: 404, + statusText: 'Not found', + }) + } - // Get posts for specific language (including universal posts) - const posts = await getCollection( - 'posts', - ({ data }: { data: CollectionEntry<'posts'>['data'] }) => - (!data.draft && (data.lang === lang || data.lang === '')), - ) - - return rss({ - title: `${title} (${lang})`, - description, - site: url, - items: posts.map((post: CollectionEntry<'posts'>) => ({ - title: post.data.title, - pubDate: post.data.published, - description: post.data.description || getExcerpt(post.body), - // Generate absolute URL with language prefix - link: new URL(`${lang}/posts/${post.data.slug || post.slug}/`, url).toString(), - // Convert markdown content to HTML, allowing img tags - content: post.body - ? sanitizeHtml(parser.render(post.body), { - allowedTags: sanitizeHtml.defaults.allowedTags.concat(['img']), - }) - : '', - })), - // Add XML namespaces for language and follow challenge - customData: ` - ${lang} - ${followConfig?.feedID && followConfig?.userID - ? ` - ${followConfig.feedID} - ${followConfig.userID} - ` - : '' - } - `.trim(), - }) + return generateRSS({ lang }) } diff --git a/src/pages/[lang]/tags/[tags].astro b/src/pages/[lang]/tags/[tags].astro index aaac175..eb21168 100644 --- a/src/pages/[lang]/tags/[tags].astro +++ b/src/pages/[lang]/tags/[tags].astro @@ -1,16 +1,11 @@ --- -import { themeConfig } from '@/config' import Layout from '@/layouts/Layout.astro' -import { getAllTags, getPostsByTag } from '@/utils/content.config' +import { getAllTags, getPostsByTag } from '@/utils/content' +import { generateMultiLangTagPaths } from '@/utils/i18n' export async function getStaticPaths() { const tags = await getAllTags() - return themeConfig.global.moreLocale.flatMap(lang => - tags.map(tag => ({ - params: { lang, tags: tag }, - props: { tags: tag }, - })), - ) + return generateMultiLangTagPaths(tags) } const { lang } = Astro.params diff --git a/src/pages/[lang]/tags/index.astro b/src/pages/[lang]/tags/index.astro index b759350..de5f96d 100644 --- a/src/pages/[lang]/tags/index.astro +++ b/src/pages/[lang]/tags/index.astro @@ -1,12 +1,10 @@ --- -import { themeConfig } from '@/config' import Layout from '@/layouts/Layout.astro' -import { getAllTags } from '@/utils/content.config' +import { getAllTags } from '@/utils/content' +import { generateLanguagePaths } from '@/utils/i18n' export function getStaticPaths() { - return themeConfig.global.moreLocale.map(lang => ({ - params: { lang }, - })) + return generateLanguagePaths() } const { lang } = Astro.params @@ -21,3 +19,4 @@ const allTags = await getAllTags() ))} + diff --git a/src/pages/index.astro b/src/pages/index.astro index 0433832..0222185 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,6 +1,6 @@ --- import Layout from '@/layouts/Layout.astro' -import { getPinnedPosts, getPosts } from '@/utils/content.config' +import { getPinnedPosts, getPosts } from '@/utils/content' const posts = await getPosts() const pinnedPosts = await getPinnedPosts() diff --git a/src/pages/posts/[slug].astro b/src/pages/posts/[slug].astro index da1714d..9bc70cc 100644 --- a/src/pages/posts/[slug].astro +++ b/src/pages/posts/[slug].astro @@ -1,22 +1,18 @@ --- import Layout from '@/layouts/Layout.astro' -import { checkSlugDuplication } from '@/utils/content.config' +import { checkSlugDuplication } from '@/utils/content' +import { generatePostPaths } from '@/utils/i18n' import { getCollection } from 'astro:content' export async function getStaticPaths() { const posts = await getCollection('posts') - + const duplicates = await checkSlugDuplication(posts) if (duplicates.length > 0) { throw new Error(`Slug conflicts found:\n${duplicates.join('\n')}`) } - return posts.map(post => ({ - params: { - slug: post.data.slug || post.slug, - }, - props: { post }, - })) + return generatePostPaths(posts) } const { post } = Astro.props diff --git a/src/pages/rss.xml.ts b/src/pages/rss.xml.ts index 11a07e3..6432db1 100644 --- a/src/pages/rss.xml.ts +++ b/src/pages/rss.xml.ts @@ -1,65 +1,5 @@ -import type { CollectionEntry } from 'astro:content' -import themeConfig from '@/config' -import rss from '@astrojs/rss' -import { getCollection } from 'astro:content' -import MarkdownIt from 'markdown-it' -import sanitizeHtml from 'sanitize-html' - -const parser = new MarkdownIt() -const { title, description, url } = themeConfig.site -const { locale } = themeConfig.global -const followConfig = themeConfig.seo?.follow - -// Returns first 200 chars with proper truncation -function getExcerpt(content: string): string { - if (!content) - return '' - - // Convert markdown to plain text by removing all HTML tags - const plainText = sanitizeHtml(parser.render(content), { - allowedTags: [], - allowedAttributes: {}, - }) - - const excerpt = plainText.slice(0, 200).trim() - return excerpt.length === 200 ? `${excerpt}...` : excerpt -} +import { generateRSS } from '@/utils/rss' export async function GET() { - // Get all posts for default language (including universal posts) - const posts = await getCollection( - 'posts', - ({ data }: { data: CollectionEntry<'posts'>['data'] }) => - (!data.draft && (data.lang === locale || data.lang === '')), - ) - - return rss({ - title, - description, - site: url, - items: posts.map((post: CollectionEntry<'posts'>) => ({ - title: post.data.title, - pubDate: post.data.published, - description: post.data.description || getExcerpt(post.body), - // Generate absolute URL for post - link: new URL(`posts/${post.data.slug || post.slug}/`, url).toString(), - // Convert markdown content to HTML, allowing img tags - content: post.body - ? sanitizeHtml(parser.render(post.body), { - allowedTags: sanitizeHtml.defaults.allowedTags.concat(['img']), - }) - : '', - })), - // Add XML namespaces for language and follow challenge - customData: ` - ${locale} - ${followConfig?.feedID && followConfig?.userID - ? ` - ${followConfig.feedID} - ${followConfig.userID} - ` - : '' - } - `.trim(), - }) + return generateRSS() } diff --git a/src/pages/tags/[tags].astro b/src/pages/tags/[tags].astro index 4703bf9..6817c41 100644 --- a/src/pages/tags/[tags].astro +++ b/src/pages/tags/[tags].astro @@ -1,6 +1,6 @@ --- import Layout from '@/layouts/Layout.astro' -import { getAllTags, getPostsByTag } from '@/utils/content.config' +import { getAllTags, getPostsByTag } from '@/utils/content' export async function getStaticPaths() { const tags = await getAllTags() diff --git a/src/pages/tags/index.astro b/src/pages/tags/index.astro index ab600e1..5f55487 100644 --- a/src/pages/tags/index.astro +++ b/src/pages/tags/index.astro @@ -1,6 +1,6 @@ --- import Layout from '@/layouts/Layout.astro' -import { getAllTags } from '@/utils/content.config' +import { getAllTags } from '@/utils/content' const allTags = await getAllTags() --- diff --git a/src/styles/scrollbar.css b/src/styles/scrollbar.css index 7388ecd..7c3f2bb 100644 --- a/src/styles/scrollbar.css +++ b/src/styles/scrollbar.css @@ -10,19 +10,16 @@ --os-handle-perpendicular-size-active: 160%; --os-handle-interactive-area-offset: 3px; } - .scrollbar-light { --os-handle-bg: #C9C4C1; --os-handle-bg-hover: #B8B3B0; --os-handle-bg-active: #B8B3B0; } - .scrollbar-dark { --os-handle-bg: #383838; --os-handle-bg-hover: #464646; --os-handle-bg-active: #464646; } - @media (max-width: 1023px) { .os-scrollbar { display: none !important; diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 08ef58d..39b990a 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -1,5 +1,7 @@ import type { langPath } from '@/utils/ui' +type Exclude = T extends U ? never : T + export interface ThemeConfig { site: { @@ -84,7 +86,12 @@ export interface ThemeConfig { customGoogleAnalyticsURL?: string customUmamiAnalyticsURL?: string customUmamiAnalyticsJS?: string - lazyload: boolean + } + + about: { + [key in ThemeConfig['global']['locale']]: string + } & { + [key in ThemeConfig['global']['moreLocale'][number]]?: string } } diff --git a/src/utils/content.config.ts b/src/utils/content.ts similarity index 100% rename from src/utils/content.config.ts rename to src/utils/content.ts diff --git a/src/utils/i18n.ts b/src/utils/i18n.ts new file mode 100644 index 0000000..f710ed0 --- /dev/null +++ b/src/utils/i18n.ts @@ -0,0 +1,38 @@ +import type { CollectionEntry } from 'astro:content' +import { themeConfig } from '@/config' + +export function generateLanguagePaths() { + return themeConfig.global.moreLocale.map(lang => ({ + params: { lang }, + })) +} + +export function generatePostPaths(posts: CollectionEntry<'posts'>[]) { + return posts.map(post => ({ + params: { + slug: post.data.slug || post.slug, + }, + props: { post }, + })) +} + +export function generateMultiLangPostPaths(posts: CollectionEntry<'posts'>[]) { + return themeConfig.global.moreLocale.flatMap(lang => + posts.map(post => ({ + params: { + lang, + slug: post.data.slug || post.slug, + }, + props: { post }, + })), + ) +} + +export function generateMultiLangTagPaths(tags: string[]) { + return themeConfig.global.moreLocale.flatMap(lang => + tags.map(tag => ({ + params: { lang, tags: tag }, + props: { tags: tag }, + })), + ) +} diff --git a/src/utils/rss.ts b/src/utils/rss.ts new file mode 100644 index 0000000..bd198a9 --- /dev/null +++ b/src/utils/rss.ts @@ -0,0 +1,71 @@ +import type { CollectionEntry } from 'astro:content' +import themeConfig from '@/config' +import rss from '@astrojs/rss' +import { getCollection } from 'astro:content' +import MarkdownIt from 'markdown-it' +import sanitizeHtml from 'sanitize-html' + +const parser = new MarkdownIt() +const { title, description, url } = themeConfig.site +const followConfig = themeConfig.seo?.follow + +// Returns first 200 chars with proper truncation +function getExcerpt(content: string): string { + if (!content) + return '' + + // Convert markdown to plain text by removing all HTML tags + const plainText = sanitizeHtml(parser.render(content), { + allowedTags: [], + allowedAttributes: {}, + }) + + const excerpt = plainText.slice(0, 200).trim() + return excerpt.length === 200 ? `${excerpt}...` : excerpt +} + +interface GenerateRSSOptions { + lang?: string +} + +export async function generateRSS({ lang }: GenerateRSSOptions = {}) { + // Get posts for specific language (including universal posts) + const posts = await getCollection( + 'posts', + ({ data }: { data: CollectionEntry<'posts'>['data'] }) => + (!data.draft && (data.lang === lang || data.lang === '')), + ) + + return rss({ + title: lang ? `${title} (${lang})` : title, + description, + site: url, + items: posts.map((post: CollectionEntry<'posts'>) => ({ + title: post.data.title, + pubDate: post.data.published, + description: post.data.description || getExcerpt(post.body), + // Generate absolute URL with optional language prefix + link: new URL( + `${lang ? `${lang}/` : ''}posts/${post.data.slug || post.slug}/`, + url, + ).toString(), + // Convert markdown content to HTML, allowing img tags + content: post.body + ? sanitizeHtml(parser.render(post.body), { + allowedTags: sanitizeHtml.defaults.allowedTags.concat(['img']), + }) + : '', + })), + // Add XML namespaces for language and follow challenge + customData: ` + ${lang || themeConfig.global.locale} + ${followConfig?.feedID && followConfig?.userID + ? ` + ${followConfig.feedID} + ${followConfig.userID} + ` + : '' + } + `.trim(), + }) +}