Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/plenty-deserts-tan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'sv': patch
---

feat(eslint): add `recommendedTypeChecked` config
19 changes: 10 additions & 9 deletions packages/sv/src/addons/better-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,8 @@ export default defineAddon({
? `
signInEmail: async (event) => {
const formData = await event.request.formData();
const email = formData.get('email')?.toString() ?? '';
const password = formData.get('password')?.toString() ?? '';
const email = (formData.get('email') ?? '') as string;
const password = (formData.get('password') ?? '') as string;

try {
await auth.api.signInEmail({
Expand All @@ -262,9 +262,9 @@ export default defineAddon({
},
signUpEmail: async (event) => {
const formData = await event.request.formData();
const email = formData.get('email')?.toString() ?? '';
const password = formData.get('password')?.toString() ?? '';
const name = formData.get('name')?.toString() ?? '';
const email = (formData.get('email') ?? '') as string;
const password = (formData.get('password') ?? '') as string;
const name = (formData.get('name') ?? '') as string;

try {
await auth.api.signUpEmail({
Expand All @@ -290,8 +290,8 @@ export default defineAddon({
? `
signInSocial: async (event) => {
const formData = await event.request.formData();
const provider = formData.get('provider')?.toString() ?? 'github';
const callbackURL = formData.get('callbackURL')?.toString() ?? '/demo/better-auth';
const provider = (formData.get('provider') ?? 'github') as string;
const callbackURL = (formData.get('callbackURL') ?? '/demo/better-auth') as string;

const result = await auth.api.signInSocial({
body: {
Expand All @@ -316,7 +316,7 @@ export default defineAddon({
import { auth } from '$lib/server/auth';
${needsAPIError ? "import { APIError } from 'better-auth/api';" : ''}

export const load${ts(': PageServerLoad')} = async (event) => {
export const load${ts(': PageServerLoad')} = (event) => {
if (event.locals.user) {
return redirect(302, '/demo/better-auth');
}
Expand Down Expand Up @@ -405,7 +405,7 @@ export default defineAddon({
${ts("import type { PageServerLoad } from './$types';")}
import { auth } from '$lib/server/auth';

export const load${ts(': PageServerLoad')} = async (event) => {
export const load${ts(': PageServerLoad')} = (event) => {
if (!event.locals.user) {
return redirect(302, '/demo/better-auth/login');
}
Expand Down Expand Up @@ -443,6 +443,7 @@ export default defineAddon({
${s5(`let { data }${ts(': { data: PageServerData }')} = $props();`, `export let data${ts(': PageServerData')};`)}
</script>

<!-- eslint-disable @typescript-eslint/no-unsafe-member-access -->
<h1>Hi, {data.user.name}!</h1>
Comment thread
jycouet marked this conversation as resolved.
Outdated
<p>Your user ID is {data.user.id}.</p>
<form method="post" action="?/signOut" use:enhance>
Expand Down
10 changes: 10 additions & 0 deletions packages/sv/src/addons/drizzle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,16 @@ export default defineAddon({

return generateCode();
});

if (typescript) {
sv.file('tsconfig.json', (content) => {
const { data, generateCode } = parse.json(content);
const file = `drizzle.config.${language}`;
if (!data.files) data.files = [];
if (!data.files.includes(file)) data.files.push(file);
return generateCode();
});
}
},
nextSteps: ({ options, packageManager }) => {
const steps: string[] = [];
Expand Down
14 changes: 13 additions & 1 deletion packages/sv/src/addons/eslint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default defineAddon({
eslintConfigs.push(jsConfig);

if (typescript) {
const tsConfig = js.common.parseExpression('ts.configs.recommended');
const tsConfig = js.common.parseExpression('ts.configs.recommendedTypeChecked');
eslintConfigs.push(js.common.createSpread(tsConfig));
}

Expand Down Expand Up @@ -77,6 +77,7 @@ export default defineAddon({

const globalsConfig = js.object.create({
languageOptions: {
parserOptions: typescript ? { projectService: true } : undefined,
globals: globalsObjLiteral
},
rules: typescript ? rules : undefined
Expand Down Expand Up @@ -152,5 +153,16 @@ export default defineAddon({
if (prettierInstalled) {
sv.file(files.eslintConfig, addEslintConfigPrettier);
}

if (typescript) {
sv.file('tsconfig.json', (content) => {
const { data, generateCode } = parse.json(content);
if (!data.files) data.files = [];
for (const file of ['svelte.config.js', files.eslintConfig]) {
if (!data.files.includes(file)) data.files.push(file);
}
return generateCode();
});
}
}
});
7 changes: 5 additions & 2 deletions packages/sv/src/addons/paraglide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ export default defineAddon({
});

const expression = js.common.parseExpression(
'(request) => deLocalizeUrl(request.url).pathname'
language === 'ts'
? '(request: { url: URL }) => deLocalizeUrl(request.url).pathname'
: '(request) => deLocalizeUrl(request.url).pathname'
);
const rerouteIdentifier = js.variables.declaration(ast, {
kind: 'const',
Expand Down Expand Up @@ -184,7 +186,8 @@ export default defineAddon({
svelte.addFragment(
ast,
`<div style="display:none">
{#each locales as locale}
{#each locales as locale (locale)}
<!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
<a href={localizeHref(page.url.pathname, { locale })}>{locale}</a>
Comment thread
jycouet marked this conversation as resolved.
Outdated
{/each}
</div>`
Expand Down
11 changes: 11 additions & 0 deletions packages/sv/src/addons/playwright.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ export default defineAddon({
`;
});

if (language === 'ts') {
sv.file('tsconfig.json', (content) => {
const { data, generateCode } = parse.json(content);
if (!data.files) data.files = [];
for (const file of [`playwright.config.ts`, `e2e/demo.test.ts`]) {
if (!data.files.includes(file)) data.files.push(file);
}
return generateCode();
});
}

sv.file(`playwright.config.${language}`, (content) => {
const { ast, generateCode } = parse.script(content);
const defineConfig = js.common.parseExpression('defineConfig({})');
Expand Down
39 changes: 19 additions & 20 deletions packages/sv/src/cli/tests/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

describe('cli', () => {
const testCases = [
{ projectName: 'create-only', args: ['--no-add-ons'] },
{ projectName: 'create-only', args: ['--no-add-ons'], cmds: [] },
{
projectName: 'create-with-all-addons',
args: [
Expand All @@ -34,20 +34,27 @@
'paraglide=languageTags:en,es+demo:yes',
'mcp=ide:claude-code,cursor,gemini,opencode,vscode,other+setup:local'
// 'storybook' // No storybook addon during tests!
],
cmds: [
['i'],
['run', 'auth:schema'],
['run', 'build'],
['exec', 'eslint', '--', '.']
]
},
{
projectName: '@my-org/sv',
template: 'addon',
args: []
args: [],
cmds: [['i'], ['run', 'demo-create'], ['run', 'demo-add:ci'], ['run', 'test']]
}
];

it.for(testCases)(

Check failure on line 53 in packages/sv/src/cli/tests/cli.ts

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

[cli] tests/cli.ts > cli > should create a new project with name 'create-with-all-addons'

Error: Test timed out in 101000ms. If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout". ❯ tests/cli.ts:53:18
'should create a new project with name $projectName',
{ timeout: 51_000 },
{ timeout: 101_000 },
async (testCase) => {
const { projectName, args, template = 'minimal' } = testCase;
const { projectName, args, template = 'minimal', cmds } = testCase;

const testOutputPath = path.relative(
monoRepoPath,
Expand Down Expand Up @@ -124,23 +131,15 @@
packageJsonPath,
JSON.stringify(packageJson, null, 3).replaceAll(' ', '\t')
);
}

const cmds = [
// list of cmds to test
['i'],
['run', 'demo-create'],
['run', 'demo-add:ci'],
['run', 'test']
];
for (const cmd of cmds) {
const res = await exec('npm', cmd, {
nodeOptions: { stdio: 'pipe', cwd: testOutputPath }
});
expect(
res.exitCode,
`Error addon test: '${cmd}' -> ${JSON.stringify(res, null, 2)}`
).toBe(0);
}
for (const cmd of cmds) {
const res = await exec('npm', cmd, {
nodeOptions: { stdio: 'pipe', cwd: testOutputPath }
});
expect(res.exitCode, `Error addon test: '${cmd}' -> ${JSON.stringify(res, null, 2)}`).toBe(
0
);
}
}
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<script lang="ts">
import type { Snippet } from 'svelte';
import favicon from '$lib/assets/favicon.svg';

let { children } = $props();
let { children }: { children: Snippet } = $props();
</script>

<svelte:head>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ const gitignorePath = path.resolve(import.meta.dirname, '.gitignore');
export default defineConfig(
includeIgnoreFile(gitignorePath),
js.configs.recommended,
...ts.configs.recommended,
...ts.configs.recommendedTypeChecked,
...svelte.configs.recommended,
prettier,
...svelte.configs.prettier,
{
languageOptions: { globals: { ...globals.browser, ...globals.node } },
languageOptions: {
parserOptions: { projectService: true },
globals: { ...globals.browser, ...globals.node }
},
rules: {
// typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects.
// see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { deLocalizeUrl } from '$lib/paraglide/runtime';

export const reroute = (request) => deLocalizeUrl(request.url).pathname;
export const reroute = (request: { url: URL }) => deLocalizeUrl(request.url).pathname;
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@
import { page } from '$app/state';
import { locales, localizeHref } from '$lib/paraglide/runtime';
import './layout.css';
import type { Snippet } from 'svelte';
import favicon from '$lib/assets/favicon.svg';

let { children } = $props();
let { children }: { children: Snippet } = $props();
</script>

<svelte:head><link rel="icon" href={favicon} /></svelte:head>
{@render children()}

<div style="display:none">
{#each locales as locale}
{#each locales as locale (locale)}
<!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
<a href={localizeHref(page.url.pathname, { locale })}>{locale}</a>
{/each}
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Actions } from './$types';
import type { PageServerLoad } from './$types';
import { auth } from '$lib/server/auth';

export const load: PageServerLoad = async (event) => {
export const load: PageServerLoad = (event) => {
if (!event.locals.user) {
return redirect(302, '/demo/better-auth/login');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
let { data }: { data: PageServerData } = $props();
</script>

<!-- eslint-disable @typescript-eslint/no-unsafe-member-access -->
<h1>Hi, {data.user.name}!</h1>
<p>Your user ID is {data.user.id}.</p>
<form method="post" action="?/signOut" use:enhance>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { PageServerLoad } from './$types';
import { auth } from '$lib/server/auth';
import { APIError } from 'better-auth/api';

export const load: PageServerLoad = async (event) => {
export const load: PageServerLoad = (event) => {
if (event.locals.user) {
return redirect(302, '/demo/better-auth');
}
Expand All @@ -14,8 +14,8 @@ export const load: PageServerLoad = async (event) => {
export const actions: Actions = {
signInEmail: async (event) => {
const formData = await event.request.formData();
const email = formData.get('email')?.toString() ?? '';
const password = formData.get('password')?.toString() ?? '';
const email = (formData.get('email') ?? '') as string;
const password = (formData.get('password') ?? '') as string;

try {
await auth.api.signInEmail({
Expand All @@ -36,9 +36,9 @@ export const actions: Actions = {
},
signUpEmail: async (event) => {
const formData = await event.request.formData();
const email = formData.get('email')?.toString() ?? '';
const password = formData.get('password')?.toString() ?? '';
const name = formData.get('name')?.toString() ?? '';
const email = (formData.get('email') ?? '') as string;
const password = (formData.get('password') ?? '') as string;
const name = (formData.get('name') ?? '') as string;

try {
await auth.api.signUpEmail({
Expand All @@ -60,8 +60,8 @@ export const actions: Actions = {
},
signInSocial: async (event) => {
const formData = await event.request.formData();
const provider = formData.get('provider')?.toString() ?? 'github';
const callbackURL = formData.get('callbackURL')?.toString() ?? '/demo/better-auth';
const provider = (formData.get('provider') ?? 'github') as string;
const callbackURL = (formData.get('callbackURL') ?? '/demo/better-auth') as string;

const result = await auth.api.signInSocial({
body: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler"
}
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
//
// To make changes to top-level options such as include and exclude, we recommend extending
// the generated config; see https://svelte.dev/docs/kit/configuration#typescript
},
"files": [
"svelte.config.js",
"eslint.config.js",
"playwright.config.ts",
"e2e/demo.test.ts",
"drizzle.config.ts"
]
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<script lang="ts">
import type { Snippet } from 'svelte';
import favicon from '$lib/assets/favicon.svg';

let { children } = $props();
let { children }: { children: Snippet } = $props();
Comment thread
jycouet marked this conversation as resolved.
</script>

<svelte:head>
Expand Down
Loading