Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion documentation/docs/30-add-ons/10-eslint.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ npx sv add eslint

- the relevant packages installed including `eslint-plugin-svelte`
- an `eslint.config.js` file
- updated `.vscode/settings.json`
- updated `.vscode/extensions.json`
- configured to work with TypeScript and `prettier` if you're using those packages
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 @@ -297,8 +297,8 @@ export default defineAddon({
? `
signInEmail: async (event) => {${d1AuthLine}
const formData = await event.request.formData();
const email = formData.get('email')?.toString() ?? '';
const password = formData.get('password')?.toString() ?? '';
const email = typeof formData.get('email') === 'string' ? formData.get('email') : '';
const password = typeof formData.get('password') === 'string' ? formData.get('password') : '';

try {
await auth.api.signInEmail({
Expand All @@ -319,9 +319,9 @@ export default defineAddon({
},
signUpEmail: async (event) => {${d1AuthLine}
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 = typeof formData.get('email') === 'string' ? formData.get('email') : '';
const password = typeof formData.get('password') === 'string' ? formData.get('password') : '';
const name = typeof formData.get('name') === 'string' ? formData.get('name') : '';

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

const provider = typeof formData.get('provider') === 'string' ? formData.get('provider') : 'github';
const callbackURL = typeof formData.get('callbackURL') === 'string' ? formData.get('callbackURL') : '/demo/better-auth';

const result = await auth.api.signInSocial({
body: {
Expand All @@ -373,7 +374,7 @@ export default defineAddon({
${!d1 ? "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 @@ -465,7 +466,7 @@ export default defineAddon({
${ts("import type { PageServerLoad } from './$types';")}
${!d1 ? "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
55 changes: 42 additions & 13 deletions packages/sv/src/addons/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,42 @@ export function addEslintConfigPrettier(content: string): string {
let svelteImportName: string;
for (const specifier of sveltePluginImport?.specifiers ?? []) {
if (specifier.type === 'ImportDefaultSpecifier' && specifier.local?.name) {
svelteImportName = specifier.local.name as string;
svelteImportName = specifier.local.name;
}
}

svelteImportName ??= 'svelte';

js.imports.addDefault(ast, { from: 'eslint-plugin-svelte', as: svelteImportName });
js.imports.addDefault(ast, { from: 'eslint-config-prettier', as: 'prettier' });

const fallbackConfig = js.common.parseExpression('[]');
const defaultExport = js.exports.createDefault(ast, { fallback: fallbackConfig });
const eslintConfig = defaultExport.value;
if (eslintConfig.type !== 'ArrayExpression' && eslintConfig.type !== 'CallExpression')

type Elements =
| Extract<typeof eslintConfig, { type: 'CallExpression' }>['arguments']
| Extract<typeof eslintConfig, { type: 'ArrayExpression' }>['elements'];

let elements: Elements = [];

if (eslintConfig.type === 'ArrayExpression') {
// export default []
elements = eslintConfig.elements;
} else if (eslintConfig.type === 'CallExpression') {
if (
eslintConfig.arguments.length === 1 &&
eslintConfig.arguments[0].type === 'ArrayExpression'
) {
// export default defineConfig([...])
elements = eslintConfig.arguments[0].elements;
} else {
// export default defineConfig({}, {})
elements = eslintConfig.arguments;
}
} else {
// fallback: Not an array or a function call
return content;
}

const prettier = js.common.parseExpression('prettier');
const sveltePrettierConfig = js.common.parseExpression(`${svelteImportName}.configs.prettier`);
Expand All @@ -38,19 +61,25 @@ export function addEslintConfigPrettier(content: string): string {
if (!js.common.contains(eslintConfig, sveltePrettierConfig))
nodesToInsert.push(sveltePrettierConfig);

const elements =
eslintConfig.type === 'ArrayExpression' ? eslintConfig.elements : eslintConfig.arguments;
// finds index of `svelte.configs["..."]`
const idx = elements.findIndex(
(el) =>
const isSvelteConfig = (maybeSpread: Elements[number]) => {
const el =
maybeSpread?.type === 'SpreadElement'
? // ...svelte.configs.*
maybeSpread?.argument
: // svelte.configs.*
maybeSpread;
return (
el?.type === 'MemberExpression' &&
el.object.type === 'MemberExpression' &&
el.object.property.type === 'Identifier' &&
el.object.property.name === 'configs' &&
// Check for [svelte].configs.*
el.object.object.type === 'Identifier' &&
el.object.object.name === svelteImportName
);

el.object.object.name === svelteImportName &&
// Check for svelte.[configs].*
el.object.property.type === 'Identifier' &&
el.object.property.name === 'configs'
);
};
const idx = elements.findIndex(isSvelteConfig);
if (idx !== -1) {
elements.splice(idx + 1, 0, ...nodesToInsert);
} else {
Expand Down
17 changes: 17 additions & 0 deletions packages/sv/src/addons/eslint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,23 @@ export default defineAddon({
eslintConfigs.push(svelteTSParserConfig);
}

const rulesOverride = js.object.create({
rules: {}
});
eslintConfigs.push(rulesOverride);

if (rulesOverride.properties[0].type !== 'Property') {
throw new Error('rulesOverride.properties[0].type !== "Property"');
}
comments.add(rulesOverride.properties[0].key, {
type: 'Line',
value: ' Override or add rule settings here, such as:'
});
comments.add(rulesOverride.properties[0].key, {
type: 'Line',
value: " 'svelte/rule-name': 'error'"
});

const exportExpression = js.functions.createCall({ name: 'defineConfig', args: [] });
if (typescript) {
exportExpression.arguments.push(...eslintConfigs);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,10 @@ export default defineConfig(
svelteConfig
}
}
},
{
// Override or add rule settings here, such as:
// 'svelte/rule-name': 'error'
rules: {}
}
);
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 @@ -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 = typeof formData.get('email') === 'string' ? formData.get('email') : '';
const password = typeof formData.get('password') === 'string' ? formData.get('password') : '';

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 = typeof formData.get('email') === 'string' ? formData.get('email') : '';
const password = typeof formData.get('password') === 'string' ? formData.get('password') : '';
const name = typeof formData.get('name') === 'string' ? formData.get('name') : '';

try {
await auth.api.signUpEmail({
Expand All @@ -60,8 +60,9 @@ 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 = typeof formData.get('provider') === 'string' ? formData.get('provider') : 'github';
const callbackURL = typeof formData.get('callbackURL') === 'string' ? formData.get('callbackURL') : '/demo/better-auth';

const result = await auth.api.signInSocial({
body: {
Expand Down
Loading