From e96cf6346d474f9b40f540364d3a62249217c3e1 Mon Sep 17 00:00:00 2001 From: neverland Date: Wed, 12 Aug 2026 11:41:31 +0800 Subject: [PATCH] fix(fmt): support embedded TypeScript in Vue and Svelte --- packages/rstack/package.json | 2 + packages/rstack/src/fmt/yukuPlugin.ts | 20 ++- packages/rstack/tests/cli/fmt/svelte.test.ts | 37 +++++ packages/rstack/tests/cli/fmt/vue.test.ts | 26 ++++ pnpm-lock.yaml | 156 +++++++++++++++++++ pnpm-workspace.yaml | 2 + 6 files changed, 240 insertions(+), 3 deletions(-) create mode 100644 packages/rstack/tests/cli/fmt/svelte.test.ts create mode 100644 packages/rstack/tests/cli/fmt/vue.test.ts diff --git a/packages/rstack/package.json b/packages/rstack/package.json index 72a6f027..a93613cd 100644 --- a/packages/rstack/package.json +++ b/packages/rstack/package.json @@ -95,8 +95,10 @@ "is-binary-path": "catalog:", "lint-staged": "catalog:", "micromatch": "catalog:", + "prettier-plugin-svelte": "catalog:", "rslog": "catalog:", "sort-package-json": "catalog:", + "svelte": "catalog:", "tiny-readdir": "catalog:", "typescript": "catalog:" }, diff --git a/packages/rstack/src/fmt/yukuPlugin.ts b/packages/rstack/src/fmt/yukuPlugin.ts index cf517ad2..1fa2f646 100644 --- a/packages/rstack/src/fmt/yukuPlugin.ts +++ b/packages/rstack/src/fmt/yukuPlugin.ts @@ -7,10 +7,13 @@ import { type Diagnostic, type ParseOptions, type ParseResult, + type SourceLang, type SourceType, } from 'yuku-parser'; const AST_FORMAT = 'estree-yuku'; +const JS_TS_FILE_REGEXP = /\.(?:js|mjs|cjs|jsx|ts|mts|cts|tsx)$/i; +const JSX_REGEXP = /^[^"'`]*<\/|^[^/]{2}.*\/>/m; const SOURCE_TYPE_COMBINATIONS: SourceType[] = ['module', 'commonjs']; type Range = [start: number, end: number]; @@ -461,6 +464,17 @@ const getSourceType = (filepath: string): SourceType | undefined => { return undefined; }; +const getLanguageCombinations = (text: string, filepath: string): SourceLang[] => { + const normalizedPath = filepath.toLowerCase(); + + if (JS_TS_FILE_REGEXP.test(normalizedPath)) { + return [langFromPath(normalizedPath)]; + } + + // Embedded code from Vue or Svelte keeps the host file path, so detect JSX from its content. + return JSX_REGEXP.test(text) ? ['tsx', 'ts', 'dts'] : ['ts', 'tsx', 'dts']; +}; + const tryCombinations = (combinations: (() => ParseResult)[]): ParseResult => { let firstError: unknown; let hasError = false; @@ -495,9 +509,9 @@ const parseJavaScript = (text: string, options: ParserOptions): AstNode const parseTypeScript = (text: string, options: ParserOptions): AstNode => { const sourceType = getSourceType(options.filepath); - const lang = langFromPath(options.filepath.toLowerCase()); - const combinations = (sourceType ? [sourceType] : SOURCE_TYPE_COMBINATIONS).map( - (candidate) => () => parseWithOptions(text, { sourceType: candidate, lang }), + const languages = getLanguageCombinations(text, options.filepath); + const combinations = (sourceType ? [sourceType] : SOURCE_TYPE_COMBINATIONS).flatMap((candidate) => + languages.map((lang) => () => parseWithOptions(text, { sourceType: candidate, lang })), ); const { program, comments } = tryCombinations(combinations); diff --git a/packages/rstack/tests/cli/fmt/svelte.test.ts b/packages/rstack/tests/cli/fmt/svelte.test.ts new file mode 100644 index 00000000..a7bc4142 --- /dev/null +++ b/packages/rstack/tests/cli/fmt/svelte.test.ts @@ -0,0 +1,37 @@ +import { expect, test } from 'rstack/test'; +import { expectWriteSummary, setupFmtTest } from './helpers.ts'; + +const { readProjectFile, runFmt, writeProjectFile } = setupFmtTest(); + +test.each([ + { + name: 'instance scripts', + source: + '\n\n

{title}

\n', + expected: + '\n\n

{title}

\n', + }, + { + name: 'module scripts', + source: + '\n\n

{identity("Rstack")}

\n', + expected: + '\n\n

{identity("Rstack")}

\n', + }, +])('formats TypeScript embedded in Svelte $name', ({ source, expected }) => { + writeProjectFile( + 'rstack.config.ts', + `import { define } from 'rstack'; + +define.fmt({ plugins: ['prettier-plugin-svelte'] }); +`, + ); + writeProjectFile('App.svelte', source); + + const result = runFmt(['App.svelte']); + + expect(result.status).toBe(0); + expectWriteSummary(result.stdout, 1, 1); + expect(result.stderr).toBe(''); + expect(readProjectFile('App.svelte')).toBe(expected); +}); diff --git a/packages/rstack/tests/cli/fmt/vue.test.ts b/packages/rstack/tests/cli/fmt/vue.test.ts new file mode 100644 index 00000000..ffa19c6a --- /dev/null +++ b/packages/rstack/tests/cli/fmt/vue.test.ts @@ -0,0 +1,26 @@ +import { expect, test } from 'rstack/test'; +import { expectWriteSummary, setupFmtTest } from './helpers.ts'; + +const { readProjectFile, runFmt, writeProjectFile } = setupFmtTest(); + +test.each([ + { + name: 'TypeScript', + source: '\n', + expected: '\n', + }, + { + name: 'TSX', + source: '\n', + expected: '\n', + }, +])('formats $name embedded in Vue files', ({ source, expected }) => { + writeProjectFile('App.vue', source); + + const result = runFmt(['App.vue']); + + expect(result.status).toBe(0); + expectWriteSummary(result.stdout, 1, 1); + expect(result.stderr).toBe(''); + expect(readProjectFile('App.vue')).toBe(expected); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e26f1fa5..e5bf485d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,6 +106,9 @@ catalogs: prettier: specifier: 3.9.6 version: 3.9.6 + prettier-plugin-svelte: + specifier: ^4.1.1 + version: 4.1.1 react: specifier: ^19.2.8 version: 19.2.8 @@ -124,6 +127,9 @@ catalogs: sort-package-json: specifier: 4.0.0 version: 4.0.0 + svelte: + specifier: ^5.56.8 + version: 5.56.8 tiny-readdir: specifier: 3.1.1 version: 3.1.1 @@ -407,12 +413,18 @@ importers: micromatch: specifier: 'catalog:' version: 4.0.8 + prettier-plugin-svelte: + specifier: 'catalog:' + version: 4.1.1(prettier@3.9.6)(svelte@5.56.8) rslog: specifier: 'catalog:' version: 2.3.0 sort-package-json: specifier: 'catalog:' version: 4.0.0 + svelte: + specifier: 'catalog:' + version: 5.56.8 tiny-readdir: specifier: 'catalog:' version: 3.1.1 @@ -711,6 +723,22 @@ packages: '@types/node': optional: true + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@mdx-js/mdx@3.1.1': resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} @@ -1523,6 +1551,11 @@ packages: '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + '@sveltejs/acorn-typescript@1.0.12': + resolution: {integrity: sha512-J1jNYG23QWd67UfrQSFHtjhV37r9mVi0gdc12A3MWPldOjRK35Xk+um+qACPVjgw3AleiqoyEAhok8Wm3q46NA==} + peerDependencies: + acorn: ^8.9.0 + '@swc/helpers@0.5.23': resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==} @@ -1601,6 +1634,9 @@ packages: '@types/react@19.2.18': resolution: {integrity: sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -1834,6 +1870,10 @@ packages: aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + aria-query@5.3.1: + resolution: {integrity: sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==} + engines: {node: '>= 0.4'} + aria-query@5.3.2: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} @@ -1846,6 +1886,10 @@ packages: resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} @@ -1970,6 +2014,9 @@ packages: resolution: {integrity: sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + devalue@5.9.0: + resolution: {integrity: sha512-RWrqdArjvPbsATEhOPUo6Wndc/iWnkWKlhIrdlF3zMMYo/c3CVtoaVAyLtWxz5h8nSlkHzxnzV2uLydPXmtF+A==} + devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -2012,6 +2059,17 @@ packages: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} + esm-env@1.2.2: + resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} + + esrap@2.3.2: + resolution: {integrity: sha512-40GyiEJevYKXzYTHtZkFqAgTjLOuFcaXMao8TPyOlnWTlkHDlvZ6mPMJaJyOqVwrVCgomEG1WhJd81w0X+IcCw==} + peerDependencies: + '@typescript-eslint/types': ^8.2.0 + peerDependenciesMeta: + '@typescript-eslint/types': + optional: true + estree-util-attach-comments@3.0.0: resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} @@ -2178,6 +2236,9 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} + is-reference@3.0.3: + resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2202,6 +2263,9 @@ packages: resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} engines: {node: '>=8.9.0'} + locate-character@3.0.0: + resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} + longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -2209,6 +2273,9 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + markdown-extensions@2.0.0: resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} engines: {node: '>=16'} @@ -2476,6 +2543,13 @@ packages: resolution: {integrity: sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==} engines: {node: ^10 || ^12 || >=14} + prettier-plugin-svelte@4.1.1: + resolution: {integrity: sha512-wXvbXMjSvb4C9ENWTHXyd+ihakKCsJ6rJhLP6/8HFNj4GkZr48jqL9PoKsl2sk7SyCZRTnJ7O2TTowUpOxP/KA==} + engines: {node: '>=20'} + peerDependencies: + prettier: ^3.0.0 + svelte: ^5.0.0 + prettier@3.9.6: resolution: {integrity: sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==} engines: {node: '>=14'} @@ -2839,6 +2913,10 @@ packages: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} + svelte@5.56.8: + resolution: {integrity: sha512-PY8LOw7xP6c8IOiVqdo0sbbZVYhXRSfklOQLAUyGBKqjTX0wx/z4l/9J+PmBpmlLnxzEb1NqltxQ5/wZme/Cmg==} + engines: {node: '>=18'} + sync-child-process@1.0.2: resolution: {integrity: sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==} engines: {node: '>=16.0.0'} @@ -2966,6 +3044,9 @@ packages: yuku-parser@0.8.4: resolution: {integrity: sha512-sw41wouvT5rUmLIp87hmvm5vtF+MRSI3x6yjq6xqpYmtkQj+Ht6N7xRQ8lMhLv8N7JAzughGj0Rfi0jQRSu9HQ==} + zimmerframe@1.1.4: + resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -3191,6 +3272,25 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + '@mdx-js/mdx@3.1.1(supports-color@8.1.1)': dependencies: '@types/estree': 1.0.9 @@ -3934,6 +4034,10 @@ snapshots: '@shikijs/vscode-textmate@10.0.2': {} + '@sveltejs/acorn-typescript@1.0.12(acorn@8.17.0)': + dependencies: + acorn: 8.17.0 + '@swc/helpers@0.5.23': dependencies: tslib: 2.8.1 @@ -4023,6 +4127,8 @@ snapshots: dependencies: csstype: 3.2.3 + '@types/trusted-types@2.0.7': {} + '@types/unist@2.0.11': {} '@types/unist@3.0.3': {} @@ -4154,12 +4260,16 @@ snapshots: dependencies: dequal: 2.0.3 + aria-query@5.3.1: {} + aria-query@5.3.2: {} assertion-error@2.0.1: {} astring@1.9.0: {} + axobject-query@4.1.0: {} + bail@2.0.2: {} before-after-hook@4.0.0: {} @@ -4248,6 +4358,8 @@ snapshots: detect-newline@4.0.1: {} + devalue@5.9.0: {} + devlop@1.1.0: dependencies: dequal: 2.0.3 @@ -4284,6 +4396,12 @@ snapshots: escape-string-regexp@5.0.0: {} + esm-env@1.2.2: {} + + esrap@2.3.2: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + estree-util-attach-comments@3.0.0: dependencies: '@types/estree': 1.0.9 @@ -4527,6 +4645,10 @@ snapshots: is-plain-obj@4.1.0: {} + is-reference@3.0.3: + dependencies: + '@types/estree': 1.0.9 + js-tokens@4.0.0: {} js-yaml@4.3.1: @@ -4551,10 +4673,16 @@ snapshots: emojis-list: 3.0.0 json5: 2.2.3 + locate-character@3.0.0: {} + longest-streak@3.1.0: {} lz-string@1.5.0: {} + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + markdown-extensions@2.0.0: {} markdown-table@3.0.4: {} @@ -5096,6 +5224,11 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + prettier-plugin-svelte@4.1.1(prettier@3.9.6)(svelte@5.56.8): + dependencies: + prettier: 3.9.6 + svelte: 5.56.8 + prettier@3.9.6: {} pretty-format@27.5.1: @@ -5468,6 +5601,27 @@ snapshots: dependencies: has-flag: 4.0.0 + svelte@5.56.8: + dependencies: + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + '@sveltejs/acorn-typescript': 1.0.12(acorn@8.17.0) + '@types/estree': 1.0.9 + '@types/trusted-types': 2.0.7 + acorn: 8.17.0 + aria-query: 5.3.1 + axobject-query: 4.1.0 + clsx: 2.1.1 + devalue: 5.9.0 + esm-env: 1.2.2 + esrap: 2.3.2 + is-reference: 3.0.3 + locate-character: 3.0.0 + magic-string: 0.30.21 + zimmerframe: 1.1.4 + transitivePeerDependencies: + - '@typescript-eslint/types' + sync-child-process@1.0.2: dependencies: sync-message-port: 1.2.0 @@ -5623,4 +5777,6 @@ snapshots: '@yuku-parser/binding-win32-arm64': 0.8.4 '@yuku-parser/binding-win32-x64': 0.8.4 + zimmerframe@1.1.4: {} + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c57d25d7..e9004674 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -45,12 +45,14 @@ catalog: 'lint-staged': '^17.3.0' 'micromatch': '4.0.8' prettier: '3.9.6' + 'prettier-plugin-svelte': '^4.1.1' 'react': '^19.2.8' 'react-dom': '^19.2.8' 'rsbuild-plugin-open-graph': '^1.1.3' rslog: ^2.3.0 'rspress-plugin-font-open-sans': '^1.0.4' 'sort-package-json': '4.0.0' + svelte: '^5.56.8' tinypool: '2.1.0' tiny-readdir: 3.1.1 'typescript': '^7.0.2'