From 096c9c0276b88fa206552e49707f20a964828828 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Fri, 11 Oct 2024 15:21:43 -0400 Subject: [PATCH 01/18] update mode --- packages/adders/lucia/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 5a6c40207..982393a12 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -133,7 +133,9 @@ export default defineAdder({ userId: common.expressionFromString( `text('user_id').notNull().references(() => user.id)` ), - expiresAt: common.expressionFromString(`integer('expires_at').notNull()`) + expiresAt: common.expressionFromString( + `integer('expires_at', { mode: 'timestamp' }).notNull()` + ) }); } if (drizzleDialect === 'mysql') { From 6c29fc44e2951c72d65eaaa695c659d176822ba0 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 12 Oct 2024 13:53:06 -0400 Subject: [PATCH 02/18] partial auth impl --- packages/adders/lucia/index.ts | 195 ++++++++++++++++++++++----------- 1 file changed, 134 insertions(+), 61 deletions(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 982393a12..0c6ac9787 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -2,22 +2,16 @@ import { colors, dedent, defineAdder, defineAdderOptions, log, Walker } from '@s import { common, exports, imports, variables, object, functions } from '@sveltejs/cli-core/js'; // eslint-disable-next-line no-duplicate-imports import type { AstTypes } from '@sveltejs/cli-core/js'; -import { addHooksHandle, addGlobalAppInterface, hasTypeProp } from '../common.ts'; +import { addHooksHandle, addGlobalAppInterface, hasTypeProp, createPrinter } from '../common.ts'; import { parseScript } from '@sveltejs/cli-core/parsers'; -const LUCIA_ADAPTER = { - mysql: 'DrizzleMySQLAdapter', - postgresql: 'DrizzlePostgreSQLAdapter', - sqlite: 'DrizzleSQLiteAdapter' -} as const; - const TABLE_TYPE = { mysql: 'mysqlTable', postgresql: 'pgTable', sqlite: 'sqliteTable' }; -type Dialect = keyof typeof LUCIA_ADAPTER; +type Dialect = 'mysql' | 'postgresql' | 'sqlite'; let drizzleDialect: Dialect; let schemaPath: string; @@ -38,8 +32,8 @@ export default defineAdder({ documentation: 'https://lucia-auth.com', options, packages: [ - { name: 'lucia', version: '^3.2.0', dev: false }, - { name: '@lucia-auth/adapter-drizzle', version: '^1.1.0', dev: false }, + { name: '@oslojs/crypto', version: '^1.0.1', dev: false }, + { name: '@oslojs/encoding', version: '^1.1.0', dev: false }, // password hashing for demo { name: '@node-rs/argon2', @@ -195,47 +189,125 @@ export default defineAdder({ }, { name: ({ kit, typescript }) => `${kit?.libDirectory}/server/auth.${typescript ? 'ts' : 'js'}`, - content: ({ content, typescript, options }) => { + content: ({ content, typescript }) => { const { ast, generateCode } = parseScript(content); - const adapter = LUCIA_ADAPTER[drizzleDialect]; - imports.addNamed(ast, '$lib/server/db/schema.js', { user: 'user', session: 'session' }); + imports.addNamespace(content, '$lib/server/db/schema', 'table'); imports.addNamed(ast, '$lib/server/db', { db: 'db' }); - imports.addNamed(ast, 'lucia', { Lucia: 'Lucia' }); - imports.addNamed(ast, '@lucia-auth/adapter-drizzle', { [adapter]: adapter }); - imports.addNamed(ast, '$app/environment', { dev: 'dev' }); + imports.addNamed(ast, '@oslojs/encoding', { + encodeBase32LowerCaseNoPadding: 'encodeBase32LowerCaseNoPadding', + encodeHexLowerCase: 'encodeHexLowerCase' + }); + imports.addNamed(ast, '@oslojs/crypto/random', { + generateRandomString: 'generateRandomString' + }); + imports.addNamed(ast, '@oslojs/crypto/random', { RandomReader: 'RandomReader' }, true); + imports.addNamed(ast, '@oslojs/crypto/sha2', { sha256: 'sha256' }); + imports.addNamed(ast, 'drizzle-orm', { eq: 'eq' }); + + common.addFromString(ast, 'const DAY_IN_MS = 1000 * 60 * 60 * 24;'); + + const cookieName = common.createLiteral('auth-session'); + const session = variables.declaration(ast, 'const', 'sessionCookieName', cookieName); + exports.namedExport(ast, 'sessionCookieName', session); + + const [ts] = createPrinter(typescript); + common.addFromString( + ast, + ` + function generateSessionToken()${ts(': string')} { + const bytes = crypto.getRandomValues(new Uint8Array(20)); + const token = encodeBase32LowerCaseNoPadding(bytes); + return token; + } + ` + ); + common.addFromString( + ast, + ` + const random${ts(': RandomReader')} = { + read(bytes${ts(': Uint8Array')})${ts(': void')} { + crypto.getRandomValues(bytes); + } + }; + ` + ); + common.addFromString( + ast, + ` + export function generateId(length${ts(': number')})${ts(': string')} { + const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789'; + return generateRandomString(random, alphabet, length); + }` + ); + common.addFromString( + ast, + ` + export async function createSession(userId${ts(': string')})${ts(': Promise')} { + const token = generateSessionToken(); + const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token))); + const session${ts(': table.Session')} = { + id: sessionId, + userId, + expiresAt: new Date(Date.now() + DAY_IN_MS * 30) + }; + await db.insert(table.session).values(session); + return session; + }` + ); + common.addFromString( + ast, + ` + export async function validateSession(sessionId${ts(': string')})${ts(': Promise')} { + const [result] = await db + .select({ + // Adjust user table here to tweak returned data + user: { id: table.user.id, username: table.user.username }, + session: table.session + }) + .from(table.session) + .innerJoin(table.user, eq(table.session.userId, table.user.id)) + .where(eq(table.session.id, sessionId)); + + if (!result) { + return { session: null, user: null }; + } + const { session, user } = result; - // adapter - const adapterDecl = common.statementFromString( - `const adapter = new ${adapter}(db, session, user);` + const sessionExpired = Date.now() >= session.expiresAt.getTime(); + if (sessionExpired) { + await db.delete(table.session).where(eq(table.session.id, session.id)); + return { session: null, user: null }; + } + + const renewSession = Date.now() >= session.expiresAt.getTime() - DAY_IN_MS * 15; + if (renewSession) { + session.expiresAt = new Date(Date.now() + DAY_IN_MS * 30); + await db + .update(table.session) + .set({ expiresAt: session.expiresAt }) + .where(eq(table.session.id, session.id)); + } + + return { session, user }; + }` ); - common.addStatement(ast, adapterDecl); - - // lucia export - const luciaInit = common.expressionFromString(` - new Lucia(adapter, { - sessionCookie: { - attributes: { - secure: !dev - } - }, - ${options.demo ? 'getUserAttributes: (attributes) => ({ username: attributes.username })' : ''} - })`); - const luciaDecl = variables.declaration(ast, 'const', 'lucia', luciaInit); - exports.namedExport(ast, 'lucia', luciaDecl); - - // module declaration - if (typescript && !/declare module ["']lucia["']/.test(content)) { - const moduleDecl = common.statementFromString(` - declare module 'lucia' { - interface Register { - Lucia: typeof lucia; - // attributes that are already included are omitted - DatabaseUserAttributes: Omit; - DatabaseSessionAttributes: Omit; - } - }`); - common.addStatement(ast, moduleDecl); + common.addFromString( + ast, + ` + export async function invalidateSession(sessionId${ts(': string')})${ts(': Promise')} { + await db.delete(table.session).where(eq(table.session.id, sessionId)); + }` + ); + + // exports validation type + if (typescript && !content.includes('export type SessionValidationResult')) { + const validatedSessionType = common.statementFromString(` + export type SessionValidationResult = + | { session: table.Session; user: Omit } + | { session: null; user: null }; + `); + common.addStatement(ast, validatedSessionType); } return generateCode(); } @@ -286,7 +358,7 @@ export default defineAdder({ return content; } - const ts = (str: string, opt = '') => (typescript ? str : opt); + const [ts] = createPrinter(typescript); return dedent` import { fail, redirect } from '@sveltejs/kit'; import { hash, verify } from '@node-rs/argon2'; @@ -547,21 +619,22 @@ function createLuciaType(name: string): AstTypes.TSInterfaceBody['body'][number] typeAnnotation: { type: 'TSTypeAnnotation', typeAnnotation: { - type: 'TSUnionType', - types: [ - { - type: 'TSImportType', - argument: { type: 'StringLiteral', value: 'lucia' }, - qualifier: { - type: 'Identifier', - // capitalize first letter - name: `${name[0]!.toUpperCase()}${name.slice(1)}` - } - }, - { - type: 'TSNullKeyword' + type: 'TSIndexedAccessType', + objectType: { + type: 'TSImportType', + argument: { type: 'StringLiteral', value: '$lib/server/auth' }, + qualifier: { + type: 'Identifier', + name: 'SessionValidationResult' + } + }, + indexType: { + type: 'TSLiteralType', + literal: { + type: 'StringLiteral', + value: name } - ] + } } } }; From 7898a058ba0a683be676271bef7e57542e2ad99a Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 12 Oct 2024 13:54:12 -0400 Subject: [PATCH 03/18] add namespace import --- packages/adders/lucia/index.ts | 2 +- packages/core/tooling/js/imports.ts | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 0c6ac9787..6f3ef44ab 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -192,7 +192,7 @@ export default defineAdder({ content: ({ content, typescript }) => { const { ast, generateCode } = parseScript(content); - imports.addNamespace(content, '$lib/server/db/schema', 'table'); + imports.addNamespace(ast, '$lib/server/db/schema', 'table'); imports.addNamed(ast, '$lib/server/db', { db: 'db' }); imports.addNamed(ast, '@oslojs/encoding', { encodeBase32LowerCaseNoPadding: 'encodeBase32LowerCaseNoPadding', diff --git a/packages/core/tooling/js/imports.ts b/packages/core/tooling/js/imports.ts index 7abd01ad9..3f6b70ece 100644 --- a/packages/core/tooling/js/imports.ts +++ b/packages/core/tooling/js/imports.ts @@ -14,6 +14,21 @@ export function addEmpty(ast: AstTypes.Program, importFrom: string): void { addImportIfNecessary(ast, expectedImportDeclaration); } +export function addNamespace(ast: AstTypes.Program, importFrom: string, importAs: string): string { + const expectedImportDeclaration: AstTypes.ImportDeclaration = { + type: 'ImportDeclaration', + source: { type: 'Literal', value: importFrom }, + specifiers: [ + { + type: 'ImportNamespaceSpecifier', + local: { type: 'Identifier', name: importAs } + } + ] + }; + + addImportIfNecessary(ast, expectedImportDeclaration); +} + export function addDefault(ast: AstTypes.Program, importFrom: string, importAs: string): void { const expectedImportDeclaration: AstTypes.ImportDeclaration = { type: 'ImportDeclaration', From b1f72e6ebd758662061b614f3d28145f68997939 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 12 Oct 2024 14:01:10 -0400 Subject: [PATCH 04/18] add test --- .../core/tests/js/imports/namespaced-import/output.ts | 2 ++ packages/core/tests/js/imports/namespaced-import/run.ts | 9 +++++++++ packages/core/tooling/js/imports.ts | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 packages/core/tests/js/imports/namespaced-import/output.ts create mode 100644 packages/core/tests/js/imports/namespaced-import/run.ts diff --git a/packages/core/tests/js/imports/namespaced-import/output.ts b/packages/core/tests/js/imports/namespaced-import/output.ts new file mode 100644 index 000000000..ca6f2f5b3 --- /dev/null +++ b/packages/core/tests/js/imports/namespaced-import/output.ts @@ -0,0 +1,2 @@ +import * as bar from "./some-file"; +import * as foo from "package"; \ No newline at end of file diff --git a/packages/core/tests/js/imports/namespaced-import/run.ts b/packages/core/tests/js/imports/namespaced-import/run.ts new file mode 100644 index 000000000..f46a38afc --- /dev/null +++ b/packages/core/tests/js/imports/namespaced-import/run.ts @@ -0,0 +1,9 @@ +import { imports, type AstTypes } from '@sveltejs/cli-core/js'; + +export function run({ ast }: { ast: AstTypes.Program }): void { + imports.addNamespace(ast, 'package', 'foo'); + + imports.addNamespace(ast, './some-file', 'bar'); + // adding the same import twice should not produce two imports + imports.addNamespace(ast, './some-file', 'bar'); +} diff --git a/packages/core/tooling/js/imports.ts b/packages/core/tooling/js/imports.ts index 3f6b70ece..a0dd0fcf5 100644 --- a/packages/core/tooling/js/imports.ts +++ b/packages/core/tooling/js/imports.ts @@ -14,7 +14,7 @@ export function addEmpty(ast: AstTypes.Program, importFrom: string): void { addImportIfNecessary(ast, expectedImportDeclaration); } -export function addNamespace(ast: AstTypes.Program, importFrom: string, importAs: string): string { +export function addNamespace(ast: AstTypes.Program, importFrom: string, importAs: string): void { const expectedImportDeclaration: AstTypes.ImportDeclaration = { type: 'ImportDeclaration', source: { type: 'Literal', value: importFrom }, From fc8b903d101726b3d8d76f3fbf30daca1206762b Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 12 Oct 2024 14:39:33 -0400 Subject: [PATCH 05/18] replace with a coarser approach for now --- packages/adders/lucia/index.ts | 121 ++++++++++++--------------------- 1 file changed, 42 insertions(+), 79 deletions(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 6f3ef44ab..7d767aea6 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -189,60 +189,36 @@ export default defineAdder({ }, { name: ({ kit, typescript }) => `${kit?.libDirectory}/server/auth.${typescript ? 'ts' : 'js'}`, - content: ({ content, typescript }) => { - const { ast, generateCode } = parseScript(content); - - imports.addNamespace(ast, '$lib/server/db/schema', 'table'); - imports.addNamed(ast, '$lib/server/db', { db: 'db' }); - imports.addNamed(ast, '@oslojs/encoding', { - encodeBase32LowerCaseNoPadding: 'encodeBase32LowerCaseNoPadding', - encodeHexLowerCase: 'encodeHexLowerCase' - }); - imports.addNamed(ast, '@oslojs/crypto/random', { - generateRandomString: 'generateRandomString' - }); - imports.addNamed(ast, '@oslojs/crypto/random', { RandomReader: 'RandomReader' }, true); - imports.addNamed(ast, '@oslojs/crypto/sha2', { sha256: 'sha256' }); - imports.addNamed(ast, 'drizzle-orm', { eq: 'eq' }); + content: ({ content, typescript, kit }) => { + if (content) { + const filePath = `${kit!.libDirectory}/server/auth.${typescript ? 'ts' : 'js'}`; + log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`); + return content; + } + const [ts] = createPrinter(typescript); + return dedent` + import { eq } from 'drizzle-orm'; + import { sha256 } from '@oslojs/crypto/sha2'; + import { generateRandomString } from '@oslojs/crypto/random'; + import { encodeBase32LowerCaseNoPadding, encodeHexLowerCase } from '@oslojs/encoding'; + import { db } from '$lib/server/db'; + import * as table from '$lib/server/db/schema'; - common.addFromString(ast, 'const DAY_IN_MS = 1000 * 60 * 60 * 24;'); + const DAY_IN_MS = 1000 * 60 * 60 * 24; - const cookieName = common.createLiteral('auth-session'); - const session = variables.declaration(ast, 'const', 'sessionCookieName', cookieName); - exports.namedExport(ast, 'sessionCookieName', session); + export const sessionCookieName = 'auth-session'; - const [ts] = createPrinter(typescript); - common.addFromString( - ast, - ` function generateSessionToken()${ts(': string')} { const bytes = crypto.getRandomValues(new Uint8Array(20)); const token = encodeBase32LowerCaseNoPadding(bytes); return token; } - ` - ); - common.addFromString( - ast, - ` - const random${ts(': RandomReader')} = { - read(bytes${ts(': Uint8Array')})${ts(': void')} { - crypto.getRandomValues(bytes); - } - }; - ` - ); - common.addFromString( - ast, - ` + export function generateId(length${ts(': number')})${ts(': string')} { const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789'; - return generateRandomString(random, alphabet, length); - }` - ); - common.addFromString( - ast, - ` + return generateRandomString({ read: (bytes) => crypto.getRandomValues(bytes) }, alphabet, length); + } + export async function createSession(userId${ts(': string')})${ts(': Promise')} { const token = generateSessionToken(); const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token))); @@ -253,11 +229,12 @@ export default defineAdder({ }; await db.insert(table.session).values(session); return session; - }` - ); - common.addFromString( - ast, - ` + } + + ${ts('export type SessionValidationResult =')} + ${ts("| { session: table.Session; user: Omit }")} + ${ts('| { session: null; user: null };')} + export async function validateSession(sessionId${ts(': string')})${ts(': Promise')} { const [result] = await db .select({ @@ -290,26 +267,12 @@ export default defineAdder({ } return { session, user }; - }` - ); - common.addFromString( - ast, - ` + } + export async function invalidateSession(sessionId${ts(': string')})${ts(': Promise')} { await db.delete(table.session).where(eq(table.session.id, sessionId)); - }` - ); - - // exports validation type - if (typescript && !content.includes('export type SessionValidationResult')) { - const validatedSessionType = common.statementFromString(` - export type SessionValidationResult = - | { session: table.Session; user: Omit } - | { session: null; user: null }; - `); - common.addStatement(ast, validatedSessionType); - } - return generateCode(); + } + `; } }, { @@ -350,11 +313,10 @@ export default defineAdder({ name: ({ kit, typescript }) => `${kit!.routesDirectory}/demo/login/+page.server.${typescript ? 'ts' : 'js'}`, condition: ({ options }) => options.demo, - content({ content, typescript }) { + content({ content, typescript, kit }) { if (content) { - log.warn( - `Existing ${colors.yellow('/demo/login/+page.server.[js|ts]')} file. Could not update.` - ); + const filePath = `${kit!.routesDirectory}/demo/login/+page.server.${typescript ? 'ts' : 'js'}`; + log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`); return content; } @@ -495,9 +457,10 @@ export default defineAdder({ { name: ({ kit }) => `${kit!.routesDirectory}/demo/login/+page.svelte`, condition: ({ options }) => options.demo, - content({ content, typescript }) { + content({ content, typescript, kit }) { if (content) { - log.warn(`Existing ${colors.yellow('/demo/login/+page.svelte')} file. Could not update.`); + const filePath = `${kit!.routesDirectory}/demo/login/+page.svelte`; + log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`); return content; } @@ -532,11 +495,10 @@ export default defineAdder({ name: ({ kit, typescript }) => `${kit!.routesDirectory}/demo/+page.server.${typescript ? 'ts' : 'js'}`, condition: ({ options }) => options.demo, - content({ content, typescript }) { + content({ content, typescript, kit }) { if (content) { - log.warn( - `Existing ${colors.yellow('/demo/+page.server.[js|ts]')} file. Could not update.` - ); + const filePath = `${kit!.routesDirectory}/demo/+page.server.${typescript ? 'ts' : 'js'}`; + log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`); return content; } @@ -575,9 +537,10 @@ export default defineAdder({ { name: ({ kit }) => `${kit!.routesDirectory}/demo/+page.svelte`, condition: ({ options }) => options.demo, - content({ content, typescript }) { + content({ content, typescript, kit }) { if (content) { - log.warn(`Existing ${colors.yellow('/demo/+page.svelte')} file. Could not update.`); + const filePath = `${kit!.routesDirectory}/demo/+page.svelte`; + log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`); return content; } From 967548ade49955babfed1c9b15057108d0df83fa Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 12 Oct 2024 15:49:51 -0400 Subject: [PATCH 06/18] simplify --- packages/adders/lucia/index.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 7d767aea6..d03407506 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -184,7 +184,14 @@ export default defineAdder({ ) }); } - return generateCode(); + let code = generateCode(); + if (!code.includes('export type Session =')) { + code += '\n\nexport type Session = typeof session.$inferSelect;'; + } + if (!code.includes('export type User =')) { + code += '\n\nexport type User = typeof user.$inferSelect;'; + } + return code; } }, { @@ -231,11 +238,8 @@ export default defineAdder({ return session; } - ${ts('export type SessionValidationResult =')} - ${ts("| { session: table.Session; user: Omit }")} - ${ts('| { session: null; user: null };')} - - export async function validateSession(sessionId${ts(': string')})${ts(': Promise')} { + ${ts('export type SessionValidationResult = Awaited>;\n')} + export async function validateSession(sessionId${ts(': string')}) { const [result] = await db .select({ // Adjust user table here to tweak returned data From 44e1791f6749424b8f95ff285702a9b72e0383d3 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 12 Oct 2024 15:53:15 -0400 Subject: [PATCH 07/18] update hooks --- packages/adders/lucia/index.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index d03407506..05cd0facb 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -306,7 +306,7 @@ export default defineAdder({ name: ({ typescript }) => `src/hooks.server.${typescript ? 'ts' : 'js'}`, content: ({ content, typescript }) => { const { ast, generateCode } = parseScript(content); - imports.addNamed(ast, '$lib/server/auth.js', { lucia: 'lucia' }); + imports.addNamespace(ast, '$lib/server/auth.js', 'auth'); addHooksHandle(ast, typescript, 'auth', getAuthHandleContent()); return generateCode(); } @@ -610,25 +610,24 @@ function createLuciaType(name: string): AstTypes.TSInterfaceBody['body'][number] function getAuthHandleContent() { return ` async ({ event, resolve }) => { - const sessionId = event.cookies.get(lucia.sessionCookieName); + const sessionId = event.cookies.get(auth.sessionCookieName); if (!sessionId) { event.locals.user = null; event.locals.session = null; return resolve(event); } - const { session, user } = await lucia.validateSession(sessionId); + const { session, user } = await auth.validateSession(sessionId); if (!session) { - event.cookies.delete(lucia.sessionCookieName, { path: '/' }); - } - - if (session?.fresh) { - const sessionCookie = lucia.createSessionCookie(session.id); - - event.cookies.set(sessionCookie.name, sessionCookie.value, { + event.cookies.set(auth.sessionCookieName, session.id, { path: '/', - ...sessionCookie.attributes, + sameSite: 'lax', + httpOnly: true, + expires: session.expiresAt, + secure: !dev }); + } else { + event.cookies.delete(auth.sessionCookieName, { path: '/' }); } event.locals.user = user; From 033b9a2fb9ad428ca38ca31a8c24a65249c5bf52 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 12 Oct 2024 16:04:03 -0400 Subject: [PATCH 08/18] update demo --- packages/adders/lucia/index.ts | 81 +++++++++++++--------------------- 1 file changed, 31 insertions(+), 50 deletions(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 05cd0facb..424b6e108 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -330,9 +330,9 @@ export default defineAdder({ import { hash, verify } from '@node-rs/argon2'; import { eq } from 'drizzle-orm'; import { generateId } from 'lucia'; - import { lucia } from '$lib/server/auth'; import { db } from '$lib/server/db'; - import { user } from '$lib/server/db/schema.js'; + import * as auth from '$lib/server/auth'; + import * as table from '$lib/server/db/schema'; ${ts(`import type { Actions, PageServerLoad } from './$types';`)} export const load${ts(': PageServerLoad')} = async (event) => { @@ -349,26 +349,20 @@ export default defineAdder({ const password = formData.get('password'); if (!validateUsername(username)) { - return fail(400, { - message: 'Invalid username', - }); + return fail(400, { message: 'Invalid username' }); } if (!validatePassword(password)) { - return fail(400, { - message: 'Invalid password', - }); + return fail(400, { message: 'Invalid password' }); } const results = await db .select() .from(user) - .where(eq(user.username, username)); + .where(eq(table.user.username, username)); const existingUser = results.at(0); if (!existingUser) { - return fail(400, { - message: 'Incorrect username or password', - }); + return fail(400, { message: 'Incorrect username or password' }); } const validPassword = await verify(existingUser.passwordHash, password, { @@ -378,16 +372,16 @@ export default defineAdder({ parallelism: 1, }); if (!validPassword) { - return fail(400, { - message: 'Incorrect username or password', - }); + return fail(400, { message: 'Incorrect username or password' }); } - const session = await lucia.createSession(existingUser.id, {}); - const sessionCookie = lucia.createSessionCookie(session.id); - event.cookies.set(sessionCookie.name, sessionCookie.value, { + const session = await auth.createSession(existingUser.id); + event.cookies.set(auth.sessionCookieName, session.id, { path: '/', - ...sessionCookie.attributes, + sameSite: 'lax', + httpOnly: true, + expires: session.expiresAt, + secure: !dev }); return redirect(302, '/demo'); @@ -398,16 +392,13 @@ export default defineAdder({ const password = formData.get('password'); if (!validateUsername(username)) { - return fail(400, { - message: 'Invalid username', - }); + return fail(400, { message: 'Invalid username' }); } if (!validatePassword(password)) { - return fail(400, { - message: 'Invalid password', - }); + return fail(400, { message: 'Invalid password' }); } + const userId = generateId(15); const passwordHash = await hash(password, { // recommended minimum parameters memoryCost: 19456, @@ -415,31 +406,26 @@ export default defineAdder({ outputLen: 32, parallelism: 1, }); - const userId = generateId(15); try { - await db.insert(user).values({ - id: userId, - username, - passwordHash, - }); + await db.insert(user).values({ id: userId, username, passwordHash }); - const session = await lucia.createSession(userId, {}); - const sessionCookie = lucia.createSessionCookie(session.id); - event.cookies.set(sessionCookie.name, sessionCookie.value, { + const session = await auth.createSession(userId); + event.cookies.set(auth.sessionCookieName, session.id, { path: '/', - ...sessionCookie.attributes, + sameSite: 'lax', + httpOnly: true, + expires: session.expiresAt, + secure: !dev }); } catch (e) { - return fail(500, { - message: 'An error has occurred', - }); + return fail(500, { message: 'An error has occurred' }); } return redirect(302, '/demo'); }, }; - function validateUsername(username${ts(': unknown): username is string', ')')} { + function validateUsername(username${ts(': unknown')})${ts(': username is string')} { return ( typeof username === 'string' && username.length >= 3 && @@ -448,7 +434,7 @@ export default defineAdder({ ); } - function validatePassword(password${ts(': unknown): password is string', ')')} { + function validatePassword(password${ts(': unknown')})${ts(': password is string')} { return ( typeof password === 'string' && password.length >= 6 && @@ -508,7 +494,7 @@ export default defineAdder({ const ts = (str: string) => (typescript ? str : ''); return dedent` - import { lucia } from '$lib/server/auth'; + import * as auth from '$lib/server/auth'; import { fail, redirect } from '@sveltejs/kit'; ${ts(`import type { Actions, PageServerLoad } from './$types';`)} @@ -516,9 +502,7 @@ export default defineAdder({ if (!event.locals.user) { return redirect(302, '/demo/login'); } - return { - user: event.locals.user, - }; + return { user: event.locals.user }; }; export const actions${ts(': Actions')} = { @@ -526,12 +510,9 @@ export default defineAdder({ if (!event.locals.session) { return fail(401); } - await lucia.invalidateSession(event.locals.session.id); - const sessionCookie = lucia.createBlankSessionCookie(); - event.cookies.set(sessionCookie.name, sessionCookie.value, { - path: '/', - ...sessionCookie.attributes, - }); + await auth.invalidateSession(event.locals.session.id); + event.cookies.delete(auth.sessionCookieName, { path: '/' }); + return redirect(302, '/demo/login'); }, }; From 6f489c6cee59bd33b1bade7749268d24e05ea641 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 12 Oct 2024 16:11:50 -0400 Subject: [PATCH 09/18] fix flags --- packages/cli/commands/add/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/commands/add/index.ts b/packages/cli/commands/add/index.ts index dca328d92..e2b74455b 100644 --- a/packages/cli/commands/add/index.ts +++ b/packages/cli/commands/add/index.ts @@ -27,7 +27,7 @@ const AddersSchema = v.array(v.string()); const AdderOptionFlagsSchema = v.object({ tailwindcss: v.optional(v.array(v.string())), drizzle: v.optional(v.array(v.string())), - supabase: v.optional(v.array(v.string())) + lucia: v.optional(v.array(v.string())) }); const OptionsSchema = v.strictObject({ cwd: v.string(), From 0267d7adcf9d3934b6e8d5109da69adfdeccb45b Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 12 Oct 2024 16:12:02 -0400 Subject: [PATCH 10/18] update demo code --- packages/adders/lucia/index.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 424b6e108..8ecffa89b 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -326,10 +326,10 @@ export default defineAdder({ const [ts] = createPrinter(typescript); return dedent` + import { dev } from '$app/environment'; import { fail, redirect } from '@sveltejs/kit'; import { hash, verify } from '@node-rs/argon2'; import { eq } from 'drizzle-orm'; - import { generateId } from 'lucia'; import { db } from '$lib/server/db'; import * as auth from '$lib/server/auth'; import * as table from '$lib/server/db/schema'; @@ -357,7 +357,7 @@ export default defineAdder({ const results = await db .select() - .from(user) + .from(table.user) .where(eq(table.user.username, username)); const existingUser = results.at(0); @@ -398,7 +398,7 @@ export default defineAdder({ return fail(400, { message: 'Invalid password' }); } - const userId = generateId(15); + const userId = auth.generateId(15); const passwordHash = await hash(password, { // recommended minimum parameters memoryCost: 19456, @@ -408,7 +408,7 @@ export default defineAdder({ }); try { - await db.insert(user).values({ id: userId, username, passwordHash }); + await db.insert(table.user).values({ id: userId, username, passwordHash }); const session = await auth.createSession(userId); event.cookies.set(auth.sessionCookieName, session.id, { @@ -512,7 +512,7 @@ export default defineAdder({ } await auth.invalidateSession(event.locals.session.id); event.cookies.delete(auth.sessionCookieName, { path: '/' }); - + return redirect(302, '/demo/login'); }, }; From e1c5708a9cbc64b243d0adf1f57275d6876a599e Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 12 Oct 2024 16:20:16 -0400 Subject: [PATCH 11/18] fix issues --- packages/adders/lucia/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 8ecffa89b..bf410bb7c 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -307,6 +307,7 @@ export default defineAdder({ content: ({ content, typescript }) => { const { ast, generateCode } = parseScript(content); imports.addNamespace(ast, '$lib/server/auth.js', 'auth'); + imports.addNamed(ast, '$app/environment', { dev: 'dev' }); addHooksHandle(ast, typescript, 'auth', getAuthHandleContent()); return generateCode(); } @@ -599,7 +600,7 @@ function getAuthHandleContent() { } const { session, user } = await auth.validateSession(sessionId); - if (!session) { + if (session) { event.cookies.set(auth.sessionCookieName, session.id, { path: '/', sameSite: 'lax', From 0fe55038d148c7dc6b6445ac98eb3b914ce33c5a Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sat, 12 Oct 2024 16:24:42 -0400 Subject: [PATCH 12/18] go away --- tsconfig.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 773f62bda..415c0abdc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,7 +20,6 @@ "esModuleInterop": true, "verbatimModuleSyntax": true, "isolatedModules": true, - "noEmit": true, - "noUncheckedIndexedAccess": true + "noEmit": true } } From 5156e8c1a1b1fa8dca073f2829953e6b9c287e34 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 13 Oct 2024 13:09:48 -0400 Subject: [PATCH 13/18] dont export type when in js mode --- packages/adders/lucia/index.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index bf410bb7c..3f22f6cb3 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -74,7 +74,7 @@ export default defineAdder({ }, { name: () => schemaPath, - content: ({ content, options }) => { + content: ({ content, options, typescript }) => { const { ast, generateCode } = parseScript(content); const createTable = (name: string) => functions.call(TABLE_TYPE[drizzleDialect], [name]); @@ -184,12 +184,15 @@ export default defineAdder({ ) }); } + let code = generateCode(); - if (!code.includes('export type Session =')) { - code += '\n\nexport type Session = typeof session.$inferSelect;'; - } - if (!code.includes('export type User =')) { - code += '\n\nexport type User = typeof user.$inferSelect;'; + if (typescript) { + if (!code.includes('export type Session =')) { + code += '\n\nexport type Session = typeof session.$inferSelect;'; + } + if (!code.includes('export type User =')) { + code += '\n\nexport type User = typeof user.$inferSelect;'; + } } return code; } From 7588d412678a5f651c67bc46c1acc4452c3b89e1 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 13 Oct 2024 13:18:39 -0400 Subject: [PATCH 14/18] fix jsdoc comments --- packages/adders/lucia/index.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 3f22f6cb3..eba45f567 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -218,17 +218,23 @@ export default defineAdder({ export const sessionCookieName = 'auth-session'; + ${ts('', '/** @returns {string} */')} function generateSessionToken()${ts(': string')} { const bytes = crypto.getRandomValues(new Uint8Array(20)); const token = encodeBase32LowerCaseNoPadding(bytes); return token; } + ${ts('', '/**')} + ${ts('', ' * @param {number} length')} + ${ts('', ' * @returns {string}')} + ${ts('', ' */')} export function generateId(length${ts(': number')})${ts(': string')} { const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789'; return generateRandomString({ read: (bytes) => crypto.getRandomValues(bytes) }, alphabet, length); } + ${ts('', '/** @param {string} userId */')} export async function createSession(userId${ts(': string')})${ts(': Promise')} { const token = generateSessionToken(); const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token))); @@ -242,6 +248,7 @@ export default defineAdder({ } ${ts('export type SessionValidationResult = Awaited>;\n')} + ${ts('', '/** @param {string} sessionId */')} export async function validateSession(sessionId${ts(': string')}) { const [result] = await db .select({ @@ -275,7 +282,11 @@ export default defineAdder({ return { session, user }; } - + + ${ts('', '/**')} + ${ts('', ' * @param {string} sessionId')} + ${ts('', ' * @returns {Promise}')} + ${ts('', ' */')} export async function invalidateSession(sessionId${ts(': string')})${ts(': Promise')} { await db.delete(table.session).where(eq(table.session.id, sessionId)); } From 5664544212d600eaff5fddb94e6af93f84053225 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 13 Oct 2024 13:45:20 -0400 Subject: [PATCH 15/18] add individual functions for better compatibility --- packages/adders/lucia/index.ts | 203 +++++++++++++++++++-------------- 1 file changed, 115 insertions(+), 88 deletions(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 5da09a93e..20e404b5f 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -1,3 +1,4 @@ +import MagicString from 'magic-string'; import { colors, dedent, @@ -206,98 +207,124 @@ export default defineAdder({ }, { name: ({ kit, typescript }) => `${kit?.libDirectory}/server/auth.${typescript ? 'ts' : 'js'}`, - content: ({ content, typescript, kit }) => { - if (content) { - const filePath = `${kit!.libDirectory}/server/auth.${typescript ? 'ts' : 'js'}`; - log.warn(`Existing ${colors.yellow(filePath)} file. Could not update.`); - return content; - } - const [ts] = utils.createPrinter(typescript); - return dedent` - import { eq } from 'drizzle-orm'; - import { sha256 } from '@oslojs/crypto/sha2'; - import { generateRandomString } from '@oslojs/crypto/random'; - import { encodeBase32LowerCaseNoPadding, encodeHexLowerCase } from '@oslojs/encoding'; - import { db } from '$lib/server/db'; - import * as table from '$lib/server/db/schema'; - - const DAY_IN_MS = 1000 * 60 * 60 * 24; - - export const sessionCookieName = 'auth-session'; - - ${ts('', '/** @returns {string} */')} - function generateSessionToken()${ts(': string')} { - const bytes = crypto.getRandomValues(new Uint8Array(20)); - const token = encodeBase32LowerCaseNoPadding(bytes); - return token; - } - - ${ts('', '/**')} - ${ts('', ' * @param {number} length')} - ${ts('', ' * @returns {string}')} - ${ts('', ' */')} - export function generateId(length${ts(': number')})${ts(': string')} { - const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789'; - return generateRandomString({ read: (bytes) => crypto.getRandomValues(bytes) }, alphabet, length); - } - - ${ts('', '/** @param {string} userId */')} - export async function createSession(userId${ts(': string')})${ts(': Promise')} { - const token = generateSessionToken(); - const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token))); - const session${ts(': table.Session')} = { - id: sessionId, - userId, - expiresAt: new Date(Date.now() + DAY_IN_MS * 30) - }; - await db.insert(table.session).values(session); - return session; - } + content: ({ content, typescript }) => { + const { ast, generateCode } = parseScript(content); - ${ts('export type SessionValidationResult = Awaited>;\n')} - ${ts('', '/** @param {string} sessionId */')} - export async function validateSession(sessionId${ts(': string')}) { - const [result] = await db - .select({ - // Adjust user table here to tweak returned data - user: { id: table.user.id, username: table.user.username }, - session: table.session - }) - .from(table.session) - .innerJoin(table.user, eq(table.session.userId, table.user.id)) - .where(eq(table.session.id, sessionId)); - - if (!result) { - return { session: null, user: null }; - } - const { session, user } = result; + imports.addNamespace(ast, '$lib/server/db/schema', 'table'); + imports.addNamed(ast, '$lib/server/db', { db: 'db' }); + imports.addNamed(ast, '@oslojs/encoding', { + encodeBase32LowerCaseNoPadding: 'encodeBase32LowerCaseNoPadding', + encodeHexLowerCase: 'encodeHexLowerCase' + }); + imports.addNamed(ast, '@oslojs/crypto/random', { + generateRandomString: 'generateRandomString' + }); + imports.addNamed(ast, '@oslojs/crypto/sha2', { sha256: 'sha256' }); + imports.addNamed(ast, 'drizzle-orm', { eq: 'eq' }); - const sessionExpired = Date.now() >= session.expiresAt.getTime(); - if (sessionExpired) { - await db.delete(table.session).where(eq(table.session.id, session.id)); - return { session: null, user: null }; - } + const ms = new MagicString(generateCode().trim()); + const [ts] = utils.createPrinter(typescript); - const renewSession = Date.now() >= session.expiresAt.getTime() - DAY_IN_MS * 15; - if (renewSession) { - session.expiresAt = new Date(Date.now() + DAY_IN_MS * 30); - await db - .update(table.session) - .set({ expiresAt: session.expiresAt }) - .where(eq(table.session.id, session.id)); - } + if (!ms.original.includes('const DAY_IN_MS')) { + ms.append('\n\nconst DAY_IN_MS = 1000 * 60 * 60 * 24;'); + } + if (!ms.original.includes('export const sessionCookieName')) { + ms.append("\n\nexport const sessionCookieName = 'auth-session';"); + } + if (!ms.original.includes('function generateSessionToken')) { + const generateSessionToken = dedent` + ${ts('', '/** @returns {string} */')} + function generateSessionToken()${ts(': string')} { + const bytes = crypto.getRandomValues(new Uint8Array(20)); + const token = encodeBase32LowerCaseNoPadding(bytes); + return token; + }`; + ms.append(`\n\n${generateSessionToken}`); + } + if (!ms.original.includes('function generateId')) { + const generateId = dedent` + ${ts('', '/**')} + ${ts('', ' * @param {number} length')} + ${ts('', ' * @returns {string}')} + ${ts('', ' */')} + export function generateId(length${ts(': number')})${ts(': string')} { + const alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789'; + return generateRandomString({ read: (bytes) => crypto.getRandomValues(bytes) }, alphabet, length); + }`; + ms.append(`\n\n${generateId}`); + } + if (!ms.original.includes('async function createSession')) { + const createSession = dedent` + ${ts('', '/** @param {string} userId */')} + export async function createSession(userId${ts(': string')})${ts(': Promise')} { + const token = generateSessionToken(); + const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token))); + const session${ts(': table.Session')} = { + id: sessionId, + userId, + expiresAt: new Date(Date.now() + DAY_IN_MS * 30) + }; + await db.insert(table.session).values(session); + return session; + }`; + ms.append(`\n\n${createSession}`); + } + if (!ms.original.includes('async function invalidateSession')) { + const invalidateSession = dedent` + ${ts('', '/**')} + ${ts('', ' * @param {string} sessionId')} + ${ts('', ' * @returns {Promise}')} + ${ts('', ' */')} + export async function invalidateSession(sessionId${ts(': string')})${ts(': Promise')} { + await db.delete(table.session).where(eq(table.session.id, sessionId)); + }`; + ms.append(`\n\n${invalidateSession}`); + } + if (typescript && !ms.original.includes('export type SessionValidationResult')) { + const sessionType = + 'export type SessionValidationResult = Awaited>;'; + ms.append(`\n\n${sessionType}`); + } + if (!ms.original.includes('async function validateSession')) { + const validateSession = dedent` + ${ts('', '/** @param {string} sessionId */')} + export async function validateSession(sessionId${ts(': string')}) { + const [result] = await db + .select({ + // Adjust user table here to tweak returned data + user: { id: table.user.id, username: table.user.username }, + session: table.session + }) + .from(table.session) + .innerJoin(table.user, eq(table.session.userId, table.user.id)) + .where(eq(table.session.id, sessionId)); + + if (!result) { + return { session: null, user: null }; + } + const { session, user } = result; + + const sessionExpired = Date.now() >= session.expiresAt.getTime(); + if (sessionExpired) { + await db.delete(table.session).where(eq(table.session.id, session.id)); + return { session: null, user: null }; + } + + const renewSession = Date.now() >= session.expiresAt.getTime() - DAY_IN_MS * 15; + if (renewSession) { + session.expiresAt = new Date(Date.now() + DAY_IN_MS * 30); + await db + .update(table.session) + .set({ expiresAt: session.expiresAt }) + .where(eq(table.session.id, session.id)); + } + + return { session, user }; + }`; + ms.append(`\n\n${validateSession}`); + } - return { session, user }; - } - - ${ts('', '/**')} - ${ts('', ' * @param {string} sessionId')} - ${ts('', ' * @returns {Promise}')} - ${ts('', ' */')} - export async function invalidateSession(sessionId${ts(': string')})${ts(': Promise')} { - await db.delete(table.session).where(eq(table.session.id, sessionId)); - } - `; + return ms.toString(); } }, { From 6d53cdacfc550e33d636f868bdc7244f83dfea17 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Sun, 13 Oct 2024 14:12:54 -0400 Subject: [PATCH 16/18] update docs --- packages/adders/lucia/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index 20e404b5f..fd688150c 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -37,7 +37,7 @@ export default defineAdder({ name: 'Lucia', description: 'An auth library that abstracts away the complexity of handling sessions', environments: { svelte: false, kit: true }, - documentation: 'https://lucia-auth.com', + documentation: 'https://lucia-next.pages.dev', options, packages: [ { name: '@oslojs/crypto', version: '^1.0.1', dev: false }, From 42e24a74119ee6ea4b303ec7471a3ad0b248d41d Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Mon, 14 Oct 2024 12:45:32 -0400 Subject: [PATCH 17/18] fix spacing --- packages/adders/lucia/index.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/adders/lucia/index.ts b/packages/adders/lucia/index.ts index fd688150c..758b3aace 100644 --- a/packages/adders/lucia/index.ts +++ b/packages/adders/lucia/index.ts @@ -382,8 +382,7 @@ export default defineAdder({ import { db } from '$lib/server/db'; import * as auth from '$lib/server/auth'; import * as table from '$lib/server/db/schema'; - ${ts(`import type { Actions, PageServerLoad } from './$types';`)} - + ${ts(`import type { Actions, PageServerLoad } from './$types';\n`)} export const load${ts(': PageServerLoad')} = async (event) => { if (event.locals.user) { return redirect(302, '/demo'); @@ -507,8 +506,7 @@ export default defineAdder({ return dedent` @@ -545,8 +543,7 @@ export default defineAdder({ return dedent` import * as auth from '$lib/server/auth'; import { fail, redirect } from '@sveltejs/kit'; - ${ts(`import type { Actions, PageServerLoad } from './$types';`)} - + ${ts(`import type { Actions, PageServerLoad } from './$types';\n`)} export const load${ts(': PageServerLoad')} = async (event) => { if (!event.locals.user) { return redirect(302, '/demo/login'); @@ -582,8 +579,7 @@ export default defineAdder({ return dedent` From 72d37c1872bc60a790d738f58a0561448ceb9ae1 Mon Sep 17 00:00:00 2001 From: AdrianGonz97 <31664583+AdrianGonz97@users.noreply.github.com> Date: Mon, 14 Oct 2024 12:50:46 -0400 Subject: [PATCH 18/18] update tests --- packages/core/tests/js/imports/namespaced-import/output.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/tests/js/imports/namespaced-import/output.ts b/packages/core/tests/js/imports/namespaced-import/output.ts index ca6f2f5b3..56eda1b3d 100644 --- a/packages/core/tests/js/imports/namespaced-import/output.ts +++ b/packages/core/tests/js/imports/namespaced-import/output.ts @@ -1,2 +1,2 @@ -import * as bar from "./some-file"; -import * as foo from "package"; \ No newline at end of file +import * as bar from './some-file'; +import * as foo from 'package'; \ No newline at end of file