diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000..33484750d0 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +playwright_skip_browser_download=1 \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f7896b86c8..8c66b30ebf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -97,6 +97,8 @@ Test samples are kept in `/test/xxx/samples` folder. #### Running tests +> PREREQUISITE: Install chromium via playwright by running `pnpm playwright install chromium` + 1. To run test, run `pnpm test`. 1. To run test for a specific feature, you can use the `-g` (aka `--grep`) option. For example, to only run test involving transitions, run `pnpm test -- -g transition`. diff --git a/documentation/docs/02-template-syntax/05-element-directives.md b/documentation/docs/02-template-syntax/05-element-directives.md index 9fa3196094..9df73c8c07 100644 --- a/documentation/docs/02-template-syntax/05-element-directives.md +++ b/documentation/docs/02-template-syntax/05-element-directives.md @@ -521,7 +521,7 @@ Transitions are local by default (in Svelte 3, they were global by default). Loc {/if} ``` -> By default intro transitions will not play on first render. You can modify this behaviour by setting `intro: true` when you [create a component](/docs#run-time-client-side-component-api) and marking the transition as `global`. +> By default intro transitions will not play on first render. You can modify this behaviour by setting `intro: true` when you [create a component](/docs/client-side-component-api) and marking the transition as `global`. ## Transition parameters diff --git a/documentation/docs/05-misc/04-v4-migration-guide.md b/documentation/docs/05-misc/04-v4-migration-guide.md index cbde43c6f6..1863566d7e 100644 --- a/documentation/docs/05-misc/04-v4-migration-guide.md +++ b/documentation/docs/05-misc/04-v4-migration-guide.md @@ -157,7 +157,76 @@ This makes slot bindings more consistent as the behavior is undefined when for e ## Preprocessors -The order in which preprocessors are applied has changed. Now, preprocessors are executed in order, and within one group, the order is markup, script, style. Each preprocessor must also have a name. ([#8618](https://github.com/sveltejs/svelte/issues/8618)) +The order in which preprocessors are applied has changed. Now, preprocessors are executed in order, and within one group, the order is markup, script, style. + +```js +// @errors: 2304 +import { preprocess } from 'svelte/compiler'; + +const { code } = await preprocess( + source, + [ + { + markup: () => { + console.log('markup-1'); + }, + script: () => { + console.log('script-1'); + }, + style: () => { + console.log('style-1'); + } + }, + { + markup: () => { + console.log('markup-2'); + }, + script: () => { + console.log('script-2'); + }, + style: () => { + console.log('style-2'); + } + } + ], + { + filename: 'App.svelte' + } +); + +// Svelte 3 logs: +// markup-1 +// markup-2 +// script-1 +// script-2 +// style-1 +// style-2 + +// Svelte 4 logs: +// markup-1 +// script-1 +// style-1 +// markup-2 +// script-2 +// style-2 +``` + +This could affect you for example if you are using `MDsveX` - in which case you should make sure it comes before any script or style preprocessor. + +```diff +preprocess: [ +- vitePreprocess(), +- mdsvex(mdsvexConfig) ++ mdsvex(mdsvexConfig), ++ vitePreprocess() +] +``` + +Each preprocessor must also have a name. ([#8618](https://github.com/sveltejs/svelte/issues/8618)) + +## New eslint package + +`eslint-plugin-svelte3` is deprecated. It may still work with Svelte 4 but we make no guarantees about that. We recommend switching to our new package [eslint-plugin-svelte](https://github.com/sveltejs/eslint-plugin-svelte). See [this Github post](https://github.com/sveltejs/kit/issues/10242#issuecomment-1610798405) for an instruction how to migrate. Alternatively, you can create a new project using `npm create svelte@latest`, select the eslint (and possibly TypeScript) option and then copy over the related files into your existing project. ## Other breaking changes diff --git a/documentation/examples/05-bindings/12-component-bindings/App.svelte b/documentation/examples/05-bindings/12-component-bindings/App.svelte index b3666f891d..254ced9464 100644 --- a/documentation/examples/05-bindings/12-component-bindings/App.svelte +++ b/documentation/examples/05-bindings/12-component-bindings/App.svelte @@ -9,6 +9,21 @@ } -
invalid
+invalid
\ No newline at end of file diff --git a/packages/svelte/test/hydration/samples/raw-repair/_before.html b/packages/svelte/test/hydration/samples/raw-repair/_before.html new file mode 100644 index 0000000000..fe958bece5 --- /dev/null +++ b/packages/svelte/test/hydration/samples/raw-repair/_before.html @@ -0,0 +1,8 @@ + +invalid
+ + + +invalid
+ + diff --git a/packages/svelte/test/hydration/samples/raw-repair/inner.svelte b/packages/svelte/test/hydration/samples/raw-repair/inner.svelte new file mode 100644 index 0000000000..a2df6c9ded --- /dev/null +++ b/packages/svelte/test/hydration/samples/raw-repair/inner.svelte @@ -0,0 +1,5 @@ + + +{@html content}
diff --git a/packages/svelte/test/hydration/samples/raw-repair/main.svelte b/packages/svelte/test/hydration/samples/raw-repair/main.svelte new file mode 100644 index 0000000000..41deb9d3e6 --- /dev/null +++ b/packages/svelte/test/hydration/samples/raw-repair/main.svelte @@ -0,0 +1,7 @@ + + +{@html '
invalid
'} diff --git a/packages/svelte/test/hydration/samples/raw-svg/_after.html b/packages/svelte/test/hydration/samples/raw-svg/_after.html new file mode 100644 index 0000000000..801d9627cd --- /dev/null +++ b/packages/svelte/test/hydration/samples/raw-svg/_after.html @@ -0,0 +1,3 @@ + diff --git a/packages/svelte/test/hydration/samples/raw-svg/_before.html b/packages/svelte/test/hydration/samples/raw-svg/_before.html new file mode 100644 index 0000000000..2a1285938d --- /dev/null +++ b/packages/svelte/test/hydration/samples/raw-svg/_before.html @@ -0,0 +1,5 @@ + diff --git a/packages/svelte/test/hydration/samples/raw-svg/_config.js b/packages/svelte/test/hydration/samples/raw-svg/_config.js new file mode 100644 index 0000000000..ffcc89e7ff --- /dev/null +++ b/packages/svelte/test/hydration/samples/raw-svg/_config.js @@ -0,0 +1,14 @@ +export default { + snapshot(target) { + const svg = target.querySelector('svg'); + + return { + svg, + circle: svg.querySelector('circle') + }; + }, + test(assert, _, snapshot) { + assert.instanceOf(snapshot.svg, SVGElement); + assert.instanceOf(snapshot.circle, SVGElement); + } +}; diff --git a/packages/svelte/test/hydration/samples/raw-svg/main.svelte b/packages/svelte/test/hydration/samples/raw-svg/main.svelte new file mode 100644 index 0000000000..1b9310e09b --- /dev/null +++ b/packages/svelte/test/hydration/samples/raw-svg/main.svelte @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/svelte/test/hydration/samples/raw/_after.html b/packages/svelte/test/hydration/samples/raw/_after.html index d58c6f9d4d..f465f3094f 100644 --- a/packages/svelte/test/hydration/samples/raw/_after.html +++ b/packages/svelte/test/hydration/samples/raw/_after.html @@ -1,4 +1,2 @@ -this is some html
and so is this
- diff --git a/packages/svelte/test/hydration/samples/raw/_before.html b/packages/svelte/test/hydration/samples/raw/_before.html index f465f3094f..de20b90f6c 100644 --- a/packages/svelte/test/hydration/samples/raw/_before.html +++ b/packages/svelte/test/hydration/samples/raw/_before.html @@ -1,2 +1,4 @@ +this is some html
and so is this
+ diff --git a/packages/svelte/test/hydration/samples/raw/_config.js b/packages/svelte/test/hydration/samples/raw/_config.js index 14ba7b12c1..829079d4f0 100644 --- a/packages/svelte/test/hydration/samples/raw/_config.js +++ b/packages/svelte/test/hydration/samples/raw/_config.js @@ -1,6 +1,4 @@ export default { - skip: true, // existing nodes are blown away - props: { raw: 'this is some html
and so is this
' }, diff --git a/packages/svelte/test/hydration/samples/raw/main.svelte b/packages/svelte/test/hydration/samples/raw/main.svelte index 105e9e0581..94278521dd 100644 --- a/packages/svelte/test/hydration/samples/raw/main.svelte +++ b/packages/svelte/test/hydration/samples/raw/main.svelte @@ -1 +1,5 @@ -{@html raw} \ No newline at end of file + + +{@html raw} diff --git a/packages/svelte/test/runtime/samples/raw-svg/_config.js b/packages/svelte/test/runtime/samples/raw-svg/_config.js new file mode 100644 index 0000000000..7744c8bdd1 --- /dev/null +++ b/packages/svelte/test/runtime/samples/raw-svg/_config.js @@ -0,0 +1,10 @@ +export default { + html: '', + + test({ assert, component, target }) { + component.show = true; + assert.equal(target.innerHTML, ''); + assert.instanceOf(target.querySelector('svg'), SVGElement); + assert.instanceOf(target.querySelector('circle'), SVGElement); + } +}; diff --git a/packages/svelte/test/runtime/samples/raw-svg/main.svelte b/packages/svelte/test/runtime/samples/raw-svg/main.svelte new file mode 100644 index 0000000000..248fa9125d --- /dev/null +++ b/packages/svelte/test/runtime/samples/raw-svg/main.svelte @@ -0,0 +1,7 @@ + + +{#if show} + +{/if} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3abc8ed214..734a548d88 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -157,8 +157,8 @@ importers: specifier: ^2.26.0 version: 2.26.0 '@sveltejs/repl': - specifier: 0.5.0-next.10 - version: 0.5.0-next.10(@codemirror/lang-html@6.4.5)(@codemirror/search@6.5.0)(@lezer/common@1.0.3)(@lezer/javascript@1.4.3)(@lezer/lr@1.3.7)(@sveltejs/kit@1.21.0)(svelte@packages+svelte) + specifier: 0.5.0-next.11 + version: 0.5.0-next.11(@codemirror/lang-html@6.4.5)(@codemirror/search@6.5.0)(@lezer/common@1.0.3)(@lezer/javascript@1.4.3)(@lezer/lr@1.3.7)(@sveltejs/kit@1.22.0)(svelte@packages+svelte) cookie: specifier: ^0.5.0 version: 0.5.0 @@ -180,22 +180,25 @@ importers: version: 2.4.1 '@sveltejs/adapter-vercel': specifier: ^3.0.1 - version: 3.0.1(@sveltejs/kit@1.21.0) + version: 3.0.1(@sveltejs/kit@1.22.0) '@sveltejs/kit': - specifier: ^1.21.0 - version: 1.21.0(svelte@packages+svelte)(vite@4.3.9) + specifier: ^1.22.0 + version: 1.22.0(svelte@packages+svelte)(vite@4.3.9) '@sveltejs/site-kit': - specifier: 6.0.0-next.18 - version: 6.0.0-next.18(@sveltejs/kit@1.21.0)(svelte@packages+svelte) + specifier: 6.0.0-next.20 + version: 6.0.0-next.20(@sveltejs/kit@1.22.0)(svelte@packages+svelte) '@sveltejs/vite-plugin-svelte': specifier: ^2.4.2 version: 2.4.2(svelte@packages+svelte)(vite@4.3.9) + '@types/cookie': + specifier: ^0.5.1 + version: 0.5.1 '@types/marked': specifier: ^5.0.0 version: 5.0.0 '@types/node': - specifier: ^20.3.2 - version: 20.3.2 + specifier: ^20.3.3 + version: 20.3.3 '@types/prettier': specifier: ^2.7.3 version: 2.7.3 @@ -209,14 +212,11 @@ importers: specifier: ^0.22.8 version: 0.22.8 magic-string: - specifier: ^0.30.0 - version: 0.30.0 + specifier: ^0.30.1 + version: 0.30.1 marked: specifier: ^5.1.0 version: 5.1.0 - node-fetch: - specifier: ^3.3.1 - version: 3.3.1 prettier: specifier: ^2.8.8 version: 2.8.8 @@ -258,7 +258,7 @@ importers: version: 5.1.6 vite: specifier: ^4.3.9 - version: 4.3.9(@types/node@20.3.2)(sass@1.63.6) + version: 4.3.9(@types/node@20.3.3)(sass@1.63.6) vite-imagetools: specifier: ^5.0.4 version: 5.0.4 @@ -1690,12 +1690,12 @@ packages: - supports-color dev: false - /@sveltejs/adapter-vercel@3.0.1(@sveltejs/kit@1.21.0): + /@sveltejs/adapter-vercel@3.0.1(@sveltejs/kit@1.22.0): resolution: {integrity: sha512-PBY3YRm7Q7Prax07mxD/rvcho2CntGkYncAIkz2DtG5NTcVG5JZ1RM627it5zYYtc2/RB3YjMkZuCMBqDCiPkA==} peerDependencies: '@sveltejs/kit': ^1.5.0 dependencies: - '@sveltejs/kit': 1.21.0(svelte@packages+svelte)(vite@4.3.9) + '@sveltejs/kit': 1.22.0(svelte@packages+svelte)(vite@4.3.9) '@vercel/nft': 0.22.6 esbuild: 0.17.19 transitivePeerDependencies: @@ -1723,8 +1723,8 @@ packages: typescript: 5.1.3 dev: true - /@sveltejs/kit@1.21.0(svelte@packages+svelte)(vite@4.3.9): - resolution: {integrity: sha512-CBsYoI34SjtOQp0eG85dmVnvTR3Pjs8VgAQhO0CgQja9BIorKl808F1X8EunPhCcyek5r5lKQE1Mmbi0RuzHqA==} + /@sveltejs/kit@1.22.0(svelte@packages+svelte)(vite@4.3.9): + resolution: {integrity: sha512-LQhM7CvTaO7OopQffFMuJ2n1lBhfYJKVO2Rujc+/473Yb8jb1mpJm59q5Avbx29kcz8N9lvYUyRP3FXc63VIFA==} engines: {node: ^16.14 || >=18} hasBin: true requiresBuild: true @@ -1738,19 +1738,19 @@ packages: devalue: 4.3.2 esm-env: 1.0.0 kleur: 4.1.5 - magic-string: 0.30.0 + magic-string: 0.30.1 mime: 3.0.0 sade: 1.8.1 set-cookie-parser: 2.6.0 sirv: 2.0.3 svelte: link:packages/svelte undici: 5.22.1 - vite: 4.3.9(@types/node@20.3.2)(sass@1.63.6) + vite: 4.3.9(@types/node@20.3.3)(sass@1.63.6) transitivePeerDependencies: - supports-color - /@sveltejs/repl@0.5.0-next.10(@codemirror/lang-html@6.4.5)(@codemirror/search@6.5.0)(@lezer/common@1.0.3)(@lezer/javascript@1.4.3)(@lezer/lr@1.3.7)(@sveltejs/kit@1.21.0)(svelte@packages+svelte): - resolution: {integrity: sha512-Y167w5wExssjloafIeLeTCzN9Vh22Sg/DgE4ARfw4J/5VVkEkEINVBbHalpjDMHhXnvOejnbNCJEw0TYW2lN4A==} + /@sveltejs/repl@0.5.0-next.11(@codemirror/lang-html@6.4.5)(@codemirror/search@6.5.0)(@lezer/common@1.0.3)(@lezer/javascript@1.4.3)(@lezer/lr@1.3.7)(@sveltejs/kit@1.22.0)(svelte@packages+svelte): + resolution: {integrity: sha512-bZ7WmmwwujhO1b1r7hN5Lt4z/Y4J3Bfx1DHiITOLshHTPgEU9XNOdq2JzSmN4DIWhmU0T/OVZ53XyXpaR1KTWA==} peerDependencies: svelte: ^3.54.0 || ^4.0.0-next.0 || ^4.0.0 dependencies: @@ -1770,7 +1770,7 @@ packages: '@replit/codemirror-lang-svelte': 6.0.0(@codemirror/autocomplete@6.8.1)(@codemirror/lang-css@6.2.0)(@codemirror/lang-html@6.4.5)(@codemirror/lang-javascript@6.1.9)(@codemirror/language@6.8.0)(@codemirror/state@6.2.1)(@codemirror/view@6.14.0)(@lezer/common@1.0.3)(@lezer/highlight@1.1.6)(@lezer/javascript@1.4.3)(@lezer/lr@1.3.7) '@rich_harris/svelte-split-pane': 1.1.1(svelte@packages+svelte) '@rollup/browser': 3.25.3 - '@sveltejs/site-kit': 5.2.2(@sveltejs/kit@1.21.0)(svelte@packages+svelte) + '@sveltejs/site-kit': 5.2.2(@sveltejs/kit@1.22.0)(svelte@packages+svelte) acorn: 8.9.0 codemirror: 6.0.1(@lezer/common@1.0.3) esm-env: 1.0.0 @@ -1778,7 +1778,7 @@ packages: marked: 5.1.0 resolve.exports: 2.0.2 svelte: link:packages/svelte - svelte-json-tree: 1.0.0 + svelte-json-tree: 2.1.0(svelte@packages+svelte) transitivePeerDependencies: - '@codemirror/lang-html' - '@codemirror/search' @@ -1788,25 +1788,25 @@ packages: - '@sveltejs/kit' dev: false - /@sveltejs/site-kit@5.2.2(@sveltejs/kit@1.21.0)(svelte@packages+svelte): + /@sveltejs/site-kit@5.2.2(@sveltejs/kit@1.22.0)(svelte@packages+svelte): resolution: {integrity: sha512-XLLxVUV/dYytCsUeODAkjtzlaIBSn1kdcH5U36OuN7gMsPEHDy5L/dsWjf1/vDln3JStH5lqZPEN8Fovm33KhA==} peerDependencies: '@sveltejs/kit': ^1.0.0 svelte: ^3.54.0 dependencies: - '@sveltejs/kit': 1.21.0(svelte@packages+svelte)(vite@4.3.9) + '@sveltejs/kit': 1.22.0(svelte@packages+svelte)(vite@4.3.9) esm-env: 1.0.0 svelte: link:packages/svelte svelte-local-storage-store: 0.4.0(svelte@packages+svelte) dev: false - /@sveltejs/site-kit@6.0.0-next.18(@sveltejs/kit@1.21.0)(svelte@packages+svelte): - resolution: {integrity: sha512-8uWjP61UAkCqWf9UuQQWSCpyPNk4cqnGaQozjIr3sGbQnauTQDiS4K8AxqyBSyphEIrhxd68iYMEFQDQVAHjcg==} + /@sveltejs/site-kit@6.0.0-next.20(@sveltejs/kit@1.22.0)(svelte@packages+svelte): + resolution: {integrity: sha512-tWT/pKdCFxY+Wsayoj287AcNOYsm0EW5fiOsSSVseEK+62R1KcWHcioSgm1Fk12HOUgFcYnskaJ9JOo+p7+9/w==} peerDependencies: - '@sveltejs/kit': ^1.0.0 - svelte: ^3.54.0 || ^4.0.0-next.1 || ^4.0.0 + '@sveltejs/kit': ^1.20.0 + svelte: ^4.0.0 dependencies: - '@sveltejs/kit': 1.21.0(svelte@packages+svelte)(vite@4.3.9) + '@sveltejs/kit': 1.22.0(svelte@packages+svelte)(vite@4.3.9) esm-env: 1.0.0 svelte: link:packages/svelte svelte-local-storage-store: 0.5.0(svelte@packages+svelte) @@ -1823,7 +1823,7 @@ packages: '@sveltejs/vite-plugin-svelte': 2.4.2(svelte@packages+svelte)(vite@4.3.9) debug: 4.3.4 svelte: link:packages/svelte - vite: 4.3.9(@types/node@20.3.2)(sass@1.63.6) + vite: 4.3.9(@types/node@20.3.3)(sass@1.63.6) transitivePeerDependencies: - supports-color @@ -1838,10 +1838,10 @@ packages: debug: 4.3.4 deepmerge: 4.3.1 kleur: 4.1.5 - magic-string: 0.30.0 + magic-string: 0.30.1 svelte: link:packages/svelte svelte-hmr: 0.15.2(svelte@packages+svelte) - vite: 4.3.9(@types/node@20.3.2)(sass@1.63.6) + vite: 4.3.9(@types/node@20.3.3)(sass@1.63.6) vitefu: 0.2.4(vite@4.3.9) transitivePeerDependencies: - supports-color @@ -1915,8 +1915,8 @@ packages: resolution: {integrity: sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==} dev: true - /@types/node@20.3.2: - resolution: {integrity: sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==} + /@types/node@20.3.3: + resolution: {integrity: sha512-wheIYdr4NYML61AjC8MKj/2jrR/kDQri/CIpVoZwldwhnIrD/j9jIU5bJ8yBKuB2VhpFV7Ab6G2XkBjv9r9Zzw==} /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} @@ -1949,7 +1949,7 @@ packages: /@types/websocket@1.0.5: resolution: {integrity: sha512-NbsqiNX9CnEfC1Z0Vf4mE1SgAJ07JnRYcNex7AJ9zAVzmiGHmjKFEk7O4TJIsgv2B1sLEb6owKFZrACwdYngsQ==} dependencies: - '@types/node': 20.3.2 + '@types/node': 20.3.3 dev: false /@typescript-eslint/eslint-plugin@5.60.0(@typescript-eslint/parser@5.60.1)(eslint@8.43.0)(typescript@5.1.6): @@ -2300,7 +2300,7 @@ packages: /@vitest/snapshot@0.31.4: resolution: {integrity: sha512-LemvNumL3NdWSmfVAMpXILGyaXPkZbG5tyl6+RQSdcHnTj6hvA49UAI8jzez9oQyE/FWLKRSNqTGzsHuk89LRA==} dependencies: - magic-string: 0.30.0 + magic-string: 0.30.1 pathe: 1.1.1 pretty-format: 27.5.1 dev: true @@ -2947,11 +2947,6 @@ packages: type: 1.2.0 dev: false - /data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} - engines: {node: '>= 12'} - dev: true - /data-urls@4.0.0: resolution: {integrity: sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==} engines: {node: '>=14'} @@ -3602,14 +3597,6 @@ packages: engines: {node: '>=12'} dev: true - /fetch-blob@3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 3.2.1 - dev: true - /fflate@0.7.4: resolution: {integrity: sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==} dev: true @@ -3699,13 +3686,6 @@ packages: mime-types: 2.1.35 dev: true - /formdata-polyfill@4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} - dependencies: - fetch-blob: 3.2.0 - dev: true - /fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} dev: true @@ -4561,6 +4541,12 @@ packages: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 + /magic-string@0.30.1: + resolution: {integrity: sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + /make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -4798,11 +4784,6 @@ packages: resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} dev: true - /node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - dev: true - /node-fetch@2.6.11: resolution: {integrity: sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==} engines: {node: 4.x || >=6.0.0} @@ -4814,15 +4795,6 @@ packages: dependencies: whatwg-url: 5.0.0 - /node-fetch@3.3.1: - resolution: {integrity: sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 - dev: true - /node-gyp-build@4.6.0: resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} hasBin: true @@ -5997,8 +5969,12 @@ packages: dependencies: svelte: link:packages/svelte - /svelte-json-tree@1.0.0: - resolution: {integrity: sha512-scs1OdkC8uFpTN4MX0yKkOzZ1/EG3eP1ARC+xcFthXp2IfcwBaXgab0FqA4Am0vQwffNNB+1Gd1LFkJBlynWTA==} + /svelte-json-tree@2.1.0(svelte@packages+svelte): + resolution: {integrity: sha512-IAU//hE5bIA0SoM9AuP7xOoD9PUcMh4fio0oI52r0XJ7iNDytW7AnBdkIn1QSYLUyWzvQX3tp59JfLYfhd7lTw==} + peerDependencies: + svelte: ^4.0.0 + dependencies: + svelte: link:packages/svelte dev: false /svelte-local-storage-store@0.4.0(svelte@packages+svelte): @@ -6469,7 +6445,7 @@ packages: fsevents: 2.3.2 dev: true - /vite@4.3.9(@types/node@20.3.2)(sass@1.63.6): + /vite@4.3.9(@types/node@20.3.3)(sass@1.63.6): resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -6494,7 +6470,7 @@ packages: terser: optional: true dependencies: - '@types/node': 20.3.2 + '@types/node': 20.3.3 esbuild: 0.17.19 postcss: 8.4.24 rollup: 3.25.1 @@ -6510,7 +6486,7 @@ packages: vite: optional: true dependencies: - vite: 4.3.9(@types/node@20.3.2)(sass@1.63.6) + vite: 4.3.9(@types/node@20.3.3)(sass@1.63.6) /vitest@0.31.4(happy-dom@9.20.3)(jsdom@21.1.2)(playwright@1.35.1): resolution: {integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==} @@ -6609,11 +6585,6 @@ packages: defaults: 1.0.4 dev: true - /web-streams-polyfill@3.2.1: - resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} - engines: {node: '>= 8'} - dev: true - /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} diff --git a/sites/svelte.dev/package.json b/sites/svelte.dev/package.json index 17b7ae599c..6b736faa3b 100644 --- a/sites/svelte.dev/package.json +++ b/sites/svelte.dev/package.json @@ -1,60 +1,60 @@ { - "name": "svelte.dev", - "private": true, - "version": "1.0.0", - "description": "Docs and examples for Svelte", - "type": "module", - "scripts": { - "dev": "node scripts/update.js && pnpm run generate && vite dev", - "build": "node scripts/update.js && pnpm run generate && vite build", - "generate": "node scripts/type-gen/index.js && node scripts/generate_examples.js", - "update": "node scripts/update.js --force=true", - "preview": "vite preview", - "start": "node build", - "check": "node scripts/update.js && pnpm generate && svelte-kit sync && svelte-check", - "check:watch": "svelte-kit sync && svelte-check --watch", - "format": "pnpm run check:format -- --write", - "check:format": "prettier --check . --ignore-path .gitignore --plugin-search-dir=." - }, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15", - "@supabase/supabase-js": "^2.26.0", - "@sveltejs/repl": "0.5.0-next.10", - "cookie": "^0.5.0", - "devalue": "^4.3.2", - "do-not-zip": "^1.0.0", - "flexsearch": "^0.7.31", - "flru": "^1.0.2" - }, - "devDependencies": { - "@resvg/resvg-js": "^2.4.1", - "@sveltejs/adapter-vercel": "^3.0.1", - "@sveltejs/kit": "^1.21.0", - "@sveltejs/site-kit": "6.0.0-next.18", - "@sveltejs/vite-plugin-svelte": "^2.4.2", - "@types/marked": "^5.0.0", - "@types/node": "^20.3.2", - "@types/prettier": "^2.7.3", - "degit": "^2.8.4", - "dotenv": "^16.3.1", - "jimp": "^0.22.8", - "magic-string": "^0.30.0", - "marked": "^5.1.0", - "node-fetch": "^3.3.1", - "prettier": "^2.8.8", - "prettier-plugin-svelte": "^2.10.1", - "sass": "^1.63.6", - "satori": "^0.10.1", - "satori-html": "^0.3.2", - "shelljs": "^0.8.5", - "shiki": "^0.14.3", - "shiki-twoslash": "^3.1.2", - "svelte": "workspace:*", - "svelte-check": "^3.4.4", - "svelte-preprocess": "^5.0.4", - "tiny-glob": "^0.2.9", - "typescript": "^5.1.6", - "vite": "^4.3.9", - "vite-imagetools": "^5.0.4" - } + "name": "svelte.dev", + "private": true, + "version": "1.0.0", + "description": "Docs and examples for Svelte", + "type": "module", + "scripts": { + "dev": "node scripts/update.js && pnpm run generate && vite dev", + "build": "node scripts/update.js && pnpm run generate && vite build", + "generate": "node scripts/type-gen/index.js && node scripts/generate_examples.js", + "update": "node scripts/update.js --force=true", + "preview": "vite preview", + "start": "node build", + "check": "node scripts/update.js && pnpm generate && svelte-kit sync && svelte-check", + "check:watch": "svelte-kit sync && svelte-check --watch", + "format": "pnpm run check:format -- --write", + "check:format": "prettier --check . --ignore-path .gitignore --plugin-search-dir=." + }, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "@supabase/supabase-js": "^2.26.0", + "@sveltejs/repl": "0.5.0-next.11", + "cookie": "^0.5.0", + "devalue": "^4.3.2", + "do-not-zip": "^1.0.0", + "flexsearch": "^0.7.31", + "flru": "^1.0.2" + }, + "devDependencies": { + "@resvg/resvg-js": "^2.4.1", + "@sveltejs/adapter-vercel": "^3.0.1", + "@sveltejs/kit": "^1.22.0", + "@sveltejs/site-kit": "6.0.0-next.20", + "@sveltejs/vite-plugin-svelte": "^2.4.2", + "@types/cookie": "^0.5.1", + "@types/marked": "^5.0.0", + "@types/node": "^20.3.3", + "@types/prettier": "^2.7.3", + "degit": "^2.8.4", + "dotenv": "^16.3.1", + "jimp": "^0.22.8", + "magic-string": "^0.30.1", + "marked": "^5.1.0", + "prettier": "^2.8.8", + "prettier-plugin-svelte": "^2.10.1", + "sass": "^1.63.6", + "satori": "^0.10.1", + "satori-html": "^0.3.2", + "shelljs": "^0.8.5", + "shiki": "^0.14.3", + "shiki-twoslash": "^3.1.2", + "svelte": "workspace:*", + "svelte-check": "^3.4.4", + "svelte-preprocess": "^5.0.4", + "tiny-glob": "^0.2.9", + "typescript": "^5.1.6", + "vite": "^4.3.9", + "vite-imagetools": "^5.0.4" + } } diff --git a/sites/svelte.dev/scripts/generate_examples.js b/sites/svelte.dev/scripts/generate_examples.js index bbdf05fae2..360cba79bd 100644 --- a/sites/svelte.dev/scripts/generate_examples.js +++ b/sites/svelte.dev/scripts/generate_examples.js @@ -1,16 +1,16 @@ import { fileURLToPath } from 'node:url'; import { get_examples_data } from '../src/lib/server/examples/index.js'; -import fs from 'node:fs'; +import { mkdir, writeFile } from 'node:fs/promises'; -const examples_data = get_examples_data( +const examples_data = await get_examples_data( fileURLToPath(new URL('../../../documentation/examples', import.meta.url)) ); try { - fs.mkdirSync(new URL('../src/lib/generated/', import.meta.url), { recursive: true }); + await mkdir(new URL('../src/lib/generated/', import.meta.url), { recursive: true }); } catch {} -fs.writeFileSync( +writeFile( new URL('../src/lib/generated/examples-data.js', import.meta.url), `export default ${JSON.stringify(examples_data)}` ); diff --git a/sites/svelte.dev/scripts/get_contributors.js b/sites/svelte.dev/scripts/get_contributors.js index 05392e4939..2949dea5df 100644 --- a/sites/svelte.dev/scripts/get_contributors.js +++ b/sites/svelte.dev/scripts/get_contributors.js @@ -1,28 +1,30 @@ +// @ts-check import 'dotenv/config'; -import fs from 'fs'; -import fetch from 'node-fetch'; import Jimp from 'jimp'; -import { dirname } from 'path'; -import { fileURLToPath } from 'url'; +import { stat, writeFile } from 'node:fs/promises'; +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; const force = process.env.FORCE_UPDATE === 'true'; const __dirname = dirname(fileURLToPath(import.meta.url)); process.chdir(__dirname); -const outputFile = `../src/routes/_components/Supporters/contributors.js`; -if (!force && fs.existsSync(outputFile)) { - console.info(`[update/contributors] ${outputFile} exists. Skipping`); - process.exit(0); -} +// ../src/routes/_components/Supporters/contributors.js +const outputFile = new URL(`../src/routes/_components/Supporters/contributors.js`, import.meta.url); -const base = `https://api.github.com/repos/sveltejs/svelte/contributors`; -const { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET } = process.env; +try { + if (!force && (await stat(outputFile))) { + console.info(`[update/contributors] ${outputFile} exists. Skipping`); + process.exit(0); + } +} catch { + const base = `https://api.github.com/repos/sveltejs/svelte/contributors`; + const { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET } = process.env; -const MAX = 24; -const SIZE = 128; + const MAX = 24; + const SIZE = 128; -async function main() { const contributors = []; let page = 1; @@ -32,6 +34,8 @@ async function main() { ); const list = await res.json(); + if (!Array.isArray(list)) throw new Error('Expected an array'); + if (list.length === 0) break; contributors.push(...list); @@ -51,13 +55,19 @@ async function main() { const image_data = await fetch(author.avatar_url); const buffer = await image_data.arrayBuffer(); + // @ts-ignore const image = await Jimp.read(buffer); image.resize(SIZE, SIZE); sprite.composite(image, i * SIZE, 0); } - await sprite.quality(80).write(`../src/routes/_components/Supporters/contributors.jpg`); + await sprite + .quality(80) + .writeAsync( + new URL(`../src/routes/_components/Supporters/contributors.jpeg`, import.meta.url).pathname + ); + // TODO: Optimizing the static/contributors.jpg image should probably get automated as well console.log( 'remember to additionally optimize the resulting /static/contributors.jpg image file via e.g. https://squoosh.app ' @@ -65,7 +75,5 @@ async function main() { const str = `[\n\t${authors.map((a) => `'${a.login}'`).join(',\n\t')}\n]`; - fs.writeFileSync(outputFile, `export default ${str};`); + writeFile(outputFile, `export default ${str};`); } - -main(); diff --git a/sites/svelte.dev/scripts/get_donors.js b/sites/svelte.dev/scripts/get_donors.js index bd8af280a1..6383548f3b 100644 --- a/sites/svelte.dev/scripts/get_donors.js +++ b/sites/svelte.dev/scripts/get_donors.js @@ -1,28 +1,31 @@ +// @ts-check import 'dotenv/config'; -import fs from 'fs'; -import fetch from 'node-fetch'; import Jimp from 'jimp'; -import { dirname } from 'path'; -import { fileURLToPath } from 'url'; +import { stat, writeFile } from 'node:fs/promises'; +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; const force = process.env.FORCE_UPDATE === 'true'; const __dirname = dirname(fileURLToPath(import.meta.url)); process.chdir(__dirname); -const outputFile = `../src/routes/_components/Supporters/donors.js`; -if (!force && fs.existsSync(outputFile)) { - console.info(`[update/donors] ${outputFile} exists. Skipping`); - process.exit(0); -} +const outputFile = new URL(`../src/routes/_components/Supporters/donors.js`, import.meta.url); -const MAX = 24; -const SIZE = 128; +try { + if (!force && (await stat(outputFile))) { + console.info(`[update/donors] ${outputFile} exists. Skipping`); + process.exit(0); + } +} catch { + const MAX = 24; + const SIZE = 128; -async function main() { const res = await fetch('https://opencollective.com/svelte/members/all.json'); const donors = await res.json(); + if (!Array.isArray(donors)) throw new Error('Expected an array'); + const unique = new Map(); donors.forEach((d) => unique.set(d.profile, d)); @@ -39,6 +42,7 @@ async function main() { try { const image_data = await fetch(backer.image); const buffer = await image_data.arrayBuffer(); + // @ts-ignore const image = await Jimp.read(buffer); image.resize(SIZE, SIZE); included.push({ backer, image }); @@ -52,7 +56,11 @@ async function main() { sprite.composite(included[i].image, i * SIZE, 0); } - await sprite.quality(80).write(`../src/routes/_components/Supporters/donors.jpg`); + await sprite + .quality(80) + .writeAsync( + new URL(`../src/routes/_components/Supporters/donors.jpg`, import.meta.url).pathname + ); // TODO: Optimizing the static/donors.jpg image should probably get automated as well console.log( 'remember to additionally optimize the resulting /static/donors.jpg image file via e.g. https://squoosh.app ' @@ -60,7 +68,5 @@ async function main() { const str = `[\n\t${included.map((a) => `${JSON.stringify(a.backer.name)}`).join(',\n\t')}\n]`; - fs.writeFileSync(outputFile, `export default ${str};`); + writeFile(outputFile, `export default ${str};`); } - -main(); diff --git a/sites/svelte.dev/scripts/type-gen/index.js b/sites/svelte.dev/scripts/type-gen/index.js index 0959ac8309..18c82f19b0 100644 --- a/sites/svelte.dev/scripts/type-gen/index.js +++ b/sites/svelte.dev/scripts/type-gen/index.js @@ -1,5 +1,5 @@ // @ts-check -import fs from 'node:fs'; +import { mkdir, readFile, writeFile } from 'node:fs/promises'; import path from 'node:path'; import prettier from 'prettier'; import ts from 'typescript'; @@ -236,12 +236,12 @@ function strip_origin(str) { /** * @param {string} file */ -function read_d_ts_file(file) { +async function read_d_ts_file(file) { const resolved = path.resolve('../../packages/svelte', file); // We can't use JSDoc comments inside JSDoc, so we would get ts(7031) errors if // we didn't ignore this error specifically for `/// file:` code examples - const str = fs.readFileSync(resolved, 'utf-8'); + const str = await readFile(resolved, 'utf-8'); return str.replace(/(\s*\*\s*)```js([\s\S]+?)```/g, (match, prefix, code) => { return `${prefix}\`\`\`js${prefix}// @errors: 7031${code}\`\`\``; @@ -249,7 +249,7 @@ function read_d_ts_file(file) { } { - const code = read_d_ts_file('types/index.d.ts'); + const code = await read_d_ts_file('types/index.d.ts'); const node = ts.createSourceFile('index.d.ts', code, ts.ScriptTarget.Latest, true); for (const statement of node.statements) { @@ -296,10 +296,10 @@ $: { } try { - fs.mkdirSync(new URL('../../src/lib/generated', import.meta.url), { recursive: true }); + await mkdir(new URL('../../src/lib/generated', import.meta.url), { recursive: true }); } catch {} -fs.writeFileSync( +writeFile( new URL('../../src/lib/generated/type-info.js', import.meta.url), ` /* This file is generated by running \`pnpm generate\` diff --git a/sites/svelte.dev/scripts/update_template.js b/sites/svelte.dev/scripts/update_template.js index a54a3acb06..2d371e1f65 100644 --- a/sites/svelte.dev/scripts/update_template.js +++ b/sites/svelte.dev/scripts/update_template.js @@ -1,7 +1,8 @@ +// @ts-check +import { lstat, readFile, stat, writeFile } from 'node:fs/promises'; +import path, { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; import sh from 'shelljs'; -import fs from 'fs'; -import path, { dirname } from 'path'; -import { fileURLToPath } from 'url'; const force = process.env.FORCE_UPDATE === 'true'; @@ -9,28 +10,34 @@ const __dirname = dirname(fileURLToPath(import.meta.url)); sh.cd(path.join(__dirname, '..')); const outputFile = 'static/svelte-app.json'; -if (!force && fs.existsSync(outputFile)) { - console.info(`[update/template] ${outputFile} exists. Skipping`); - process.exit(0); -} - -// fetch svelte app -sh.rm('-rf', 'scripts/svelte-app'); -sh.exec('npx degit sveltejs/template scripts/svelte-app'); - -// remove src (will be recreated client-side) and node_modules -sh.rm('-rf', 'scripts/svelte-app/src'); -sh.rm('-rf', 'scripts/svelte-app/node_modules'); -// build svelte-app.json -const appPath = 'scripts/svelte-app'; -const files = []; - -for (const path of sh.find(appPath).filter((p) => fs.lstatSync(p).isFile())) { - const bytes = fs.readFileSync(path); - const string = bytes.toString(); - const data = bytes.compare(Buffer.from(string)) === 0 ? string : [...bytes]; - files.push({ path: path.slice(appPath.length + 1), data }); +try { + if (!force && (await stat(outputFile))) { + console.info(`[update/template] ${outputFile} exists. Skipping`); + process.exit(0); + } +} catch { + // fetch svelte app + sh.rm('-rf', 'scripts/svelte-app'); + sh.exec('npx degit sveltejs/template scripts/svelte-app'); + + // remove src (will be recreated client-side) and node_modules + sh.rm('-rf', 'scripts/svelte-app/src'); + sh.rm('-rf', 'scripts/svelte-app/node_modules'); + + // build svelte-app.json + const appPath = 'scripts/svelte-app'; + const files = []; + + for (const path of sh.find(appPath)) { + // Skip directories + if (!(await lstat(path)).isFile()) continue; + + const bytes = await readFile(path); + const string = bytes.toString(); + const data = bytes.compare(Buffer.from(string)) === 0 ? string : [...bytes]; + files.push({ path: path.slice(appPath.length + 1), data }); + } + + writeFile(outputFile, JSON.stringify(files)); } - -fs.writeFileSync(outputFile, JSON.stringify(files)); diff --git a/sites/svelte.dev/src/lib/components/ReplWidget.svelte b/sites/svelte.dev/src/lib/components/ReplWidget.svelte index a650c86985..9884c429a7 100644 --- a/sites/svelte.dev/src/lib/components/ReplWidget.svelte +++ b/sites/svelte.dev/src/lib/components/ReplWidget.svelte @@ -26,7 +26,7 @@ } if (gist) { - fetch(`/repl/${gist}.json`) + fetch(`/repl/api/${gist}.json`) .then((r) => r.json()) .then((data) => { const { description, components } = data; diff --git a/sites/svelte.dev/src/lib/db/client.js b/sites/svelte.dev/src/lib/db/client.js index 241629edbd..b5a5437781 100644 --- a/sites/svelte.dev/src/lib/db/client.js +++ b/sites/svelte.dev/src/lib/db/client.js @@ -4,4 +4,7 @@ import { createClient } from '@supabase/supabase-js'; export const client = (!dev || (SUPABASE_URL && SUPABASE_KEY)) && - createClient(SUPABASE_URL, SUPABASE_KEY, { global: { fetch } }); + createClient(SUPABASE_URL, SUPABASE_KEY, { + global: { fetch }, + auth: { persistSession: false } + }); diff --git a/sites/svelte.dev/src/lib/server/blog/index.js b/sites/svelte.dev/src/lib/server/blog/index.js index 23bca26233..40bbf4ef48 100644 --- a/sites/svelte.dev/src/lib/server/blog/index.js +++ b/sites/svelte.dev/src/lib/server/blog/index.js @@ -1,6 +1,5 @@ // @ts-check import { extractFrontmatter } from '@sveltejs/site-kit/markdown'; -import fs from 'node:fs'; import { CONTENT_BASE_PATHS } from '../../../constants.js'; import { render_content } from '../renderer.js'; @@ -23,16 +22,18 @@ export async function get_processed_blog_post(blog_data, slug) { const BLOG_NAME_REGEX = /^(\d{4}-\d{2}-\d{2})-(.+)\.md$/; -/** @returns {import('./types').BlogData} */ -export function get_blog_data(base = CONTENT_BASE_PATHS.BLOG) { +/** @returns {Promise