From 4b94019ac2f617f93b82b88a6de2b41d4d2918df Mon Sep 17 00:00:00 2001 From: Michael Cousins Date: Mon, 21 Oct 2024 20:06:09 -0400 Subject: [PATCH 1/2] ci: use production release of Svelte 5 by default (#405) --- .github/workflows/release.yml | 15 +++++++-------- package.json | 4 ++-- scripts/install-dependencies | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+), 10 deletions(-) create mode 100755 scripts/install-dependencies diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8b2ac4a..3f432da 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,13 +33,14 @@ jobs: include: # We only need to lint once, so do it on latest Node and Svelte - { node: '20', svelte: '4', check: 'lint' } - # `SvelteComponent` is not generic in Svelte 3, so type-checking only passes in >= 4 + # Run type checks in latest node + - { node: '20', svelte: '3', check: 'types:legacy' } - { node: '20', svelte: '4', check: 'types:legacy' } - - { node: '20', svelte: 'next', check: 'types' } + - { node: '20', svelte: '5', check: 'types' } # Only run Svelte 5 checks on latest Node - - { node: '20', svelte: 'next', check: 'test:vitest:jsdom' } - - { node: '20', svelte: 'next', check: 'test:vitest:happy-dom' } - - { node: '20', svelte: 'next', check: 'test:jest' } + - { node: '20', svelte: '5', check: 'test:vitest:jsdom' } + - { node: '20', svelte: '5', check: 'test:vitest:happy-dom' } + - { node: '20', svelte: '5', check: 'test:jest' } steps: - name: ⬇️ Checkout repo @@ -51,9 +52,7 @@ jobs: node-version: ${{ matrix.node }} - name: 📥 Download deps - run: | - npm install --no-package-lock - npm install --no-save svelte@${{ matrix.svelte }} + run: ./scripts/install-dependencies ${{ matrix.svelte }} - name: ▶️ Run ${{ matrix.check }} run: npm run ${{ matrix.check }} diff --git a/package.json b/package.json index 192560d..0788f40 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ }, "devDependencies": { "@jest/globals": "^29.7.0", - "@sveltejs/vite-plugin-svelte": "^3.1.1", + "@sveltejs/vite-plugin-svelte": "^2.0.0 || ^3.0.0 || ^4.0.0", "@testing-library/jest-dom": "^6.3.0", "@testing-library/user-event": "^14.5.2", "@typescript-eslint/eslint-plugin": "^8.0.0", @@ -111,7 +111,7 @@ "eslint-plugin-promise": "^6.4.0", "eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-svelte": "^2.42.0", - "expect-type": "^0.20.0", + "expect-type": "^1.1.0", "happy-dom": "^15.7.3", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", diff --git a/scripts/install-dependencies b/scripts/install-dependencies new file mode 100755 index 0000000..2a3f24f --- /dev/null +++ b/scripts/install-dependencies @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Install dependencies for a given version of Svelte +set -euo pipefail + +svelte_version=${1} + +rm -rf node_modules +npm install --no-package-lock + +if [[ "${svelte_version}" == "4" ]]; then + npm uninstall --no-save @sveltejs/vite-plugin-svelte svelte + npm install --no-save @sveltejs/vite-plugin-svelte@3 svelte@4 +elif [[ "${svelte_version}" == "3" ]]; then + npm uninstall --no-save vite vitest @vitest/coverage-v8 @sveltejs/vite-plugin-svelte svelte-check svelte + npm install --no-save vite@4 vitest@1 @vitest/coverage-v8@1 @sveltejs/vite-plugin-svelte@2 svelte-check@3 svelte@3 +fi + +npm ls --depth=0 svelte From acbddfdf3556dd6f411361f9ccfd85c9773c7fdc Mon Sep 17 00:00:00 2001 From: Michael Cousins Date: Mon, 18 Nov 2024 16:55:03 -0500 Subject: [PATCH 2/2] fix(types): adjust legacy types for eslint-plugin-svelte (#409) --- .eslintrc.cjs | 7 +++++-- src/__tests__/render.test-d.ts | 11 +++++++++++ src/component-types.d.ts | 16 +++++++++------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 91f6920..77f8b7c 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -26,9 +26,12 @@ module.exports = { { files: ['*.ts'], parser: '@typescript-eslint/parser', + parserOptions: { + project: './tsconfig.json', + }, extends: [ - 'plugin:@typescript-eslint/recommended', - 'plugin:@typescript-eslint/stylistic', + 'plugin:@typescript-eslint/strict-type-checked', + 'plugin:@typescript-eslint/stylistic-type-checked', 'prettier', ], }, diff --git a/src/__tests__/render.test-d.ts b/src/__tests__/render.test-d.ts index f8d1d90..5b1e16a 100644 --- a/src/__tests__/render.test-d.ts +++ b/src/__tests__/render.test-d.ts @@ -1,4 +1,5 @@ import { expectTypeOf } from 'expect-type' +import { ComponentProps } from 'svelte' import { describe, test } from 'vitest' import * as subject from '../index.js' @@ -36,4 +37,14 @@ describe('types', () => { unmount: () => void }>() }) + + test('render function may be wrapped', () => { + const renderSubject = (props: ComponentProps) => { + return subject.render(Component, props) + } + + renderSubject({ name: 'Alice', count: 42 }) + // @ts-expect-error: name should be a string + renderSubject(Component, { name: 42 }) + }) }) diff --git a/src/component-types.d.ts b/src/component-types.d.ts index 9df84c2..2e4a5a5 100644 --- a/src/component-types.d.ts +++ b/src/component-types.d.ts @@ -1,7 +1,9 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-redundant-type-constituents */ import type * as Svelte from 'svelte' -type IS_MODERN_SVELTE = any extends Svelte.Component ? false : true +type IS_MODERN_SVELTE = Svelte.Component extends (...args: any[]) => any + ? true + : false /** A compiled, imported Svelte component. */ export type Component< @@ -14,12 +16,12 @@ export type Component< /** * The type of an imported, compiled Svelte component. * - * In Svelte 4, this was the Svelte component class' type. * In Svelte 5, this distinction no longer matters. + * In Svelte 4, this is the Svelte component class constructor. */ -export type ComponentType = C extends Svelte.SvelteComponent - ? Svelte.ComponentType - : C +export type ComponentType = IS_MODERN_SVELTE extends true + ? C + : new (...args: any[]) => C /** The props of a component. */ export type Props> = Svelte.ComponentProps @@ -27,8 +29,8 @@ export type Props> = Svelte.ComponentProps /** * The exported fields of a component. * - * In Svelte 4, this is simply the instance of the component class. * In Svelte 5, this is the set of variables marked as `export`'d. + * In Svelte 4, this is simply the instance of the component class. */ export type Exports = C extends Svelte.SvelteComponent ? C