├── .eslintignore ├── .eslintrc.cjs ├── .gitignore ├── .release-it.json ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── examples ├── lucia-drizzle-mysql-planetscale-qwik │ ├── .env.example │ ├── .eslintignore │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── .prettierignore │ ├── README.md │ ├── adapters │ │ └── vercel-edge │ │ │ └── vite.config.ts │ ├── drizzle.config.ts │ ├── package.json │ ├── postcss.config.js │ ├── public │ │ ├── favicon.svg │ │ ├── fonts │ │ │ ├── poppins-400.woff2 │ │ │ ├── poppins-500.woff2 │ │ │ └── poppins-700.woff2 │ │ ├── manifest.json │ │ └── robots.txt │ ├── src │ │ ├── components │ │ │ └── router-head │ │ │ │ └── router-head.tsx │ │ ├── entry.dev.tsx │ │ ├── entry.preview.tsx │ │ ├── entry.ssr.tsx │ │ ├── entry.vercel-edge.tsx │ │ ├── global.css │ │ ├── lib │ │ │ ├── drizzle │ │ │ │ ├── db.ts │ │ │ │ └── schema.ts │ │ │ └── lucia.ts │ │ ├── root.tsx │ │ └── routes │ │ │ ├── index.tsx │ │ │ ├── layout.tsx │ │ │ ├── login │ │ │ └── index.tsx │ │ │ ├── service-worker.ts │ │ │ └── signup │ │ │ └── index.tsx │ ├── tailwind.config.js │ ├── tsconfig.json │ ├── vercel.json │ └── vite.config.ts ├── lucia-drizzle-pg-neon-qwik │ ├── .env.example │ ├── .eslintignore │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── .prettierignore │ ├── .prettierrc.js │ ├── README.md │ ├── drizzle.config.ts │ ├── package.json │ ├── postcss.config.cjs │ ├── public │ │ ├── favicon.svg │ │ ├── manifest.json │ │ └── robots.txt │ ├── src │ │ ├── components │ │ │ └── router-head │ │ │ │ └── router-head.tsx │ │ ├── entry.dev.tsx │ │ ├── entry.preview.tsx │ │ ├── entry.ssr.tsx │ │ ├── global.css │ │ ├── lib │ │ │ ├── db.ts │ │ │ ├── lucia.ts │ │ │ └── schema.ts │ │ ├── root.tsx │ │ └── routes │ │ │ ├── index.tsx │ │ │ ├── layout.tsx │ │ │ ├── login │ │ │ └── index.tsx │ │ │ ├── service-worker.ts │ │ │ └── signup │ │ │ └── index.tsx │ ├── tailwind.config.js │ ├── tsconfig.json │ └── vite.config.ts └── lucia-drizzle-sqlite-turso-qwik │ ├── .env.example │ ├── .eslintignore │ ├── .eslintrc.cjs │ ├── .gitignore │ ├── .prettierignore │ ├── .prettierrc.js │ ├── README.md │ ├── drizzle.config.ts │ ├── package.json │ ├── postcss.config.cjs │ ├── public │ ├── favicon.svg │ ├── manifest.json │ └── robots.txt │ ├── src │ ├── components │ │ └── router-head │ │ │ └── router-head.tsx │ ├── entry.dev.tsx │ ├── entry.preview.tsx │ ├── entry.ssr.tsx │ ├── global.css │ ├── lib │ │ ├── db.ts │ │ ├── lucia.ts │ │ └── schema.ts │ ├── root.tsx │ └── routes │ │ ├── index.tsx │ │ ├── layout.tsx │ │ ├── login │ │ └── index.tsx │ │ ├── service-worker.ts │ │ └── signup │ │ └── index.tsx │ ├── tailwind.config.js │ ├── tsconfig.json │ └── vite.config.ts ├── package.json ├── src ├── entry.dev.tsx ├── entry.ssr.tsx ├── index.ts ├── root.tsx └── utils │ ├── hashPasword.ts │ ├── qwikLuciaConfig.ts │ └── verifyPassword.ts ├── tsconfig.json └── vite.config.ts /.eslintignore: -------------------------------------------------------------------------------- 1 | **/*.log 2 | **/.DS_Store 3 | *. 4 | .vscode/settings.json 5 | .history 6 | .yarn 7 | bazel-* 8 | bazel-bin 9 | bazel-out 10 | bazel-qwik 11 | bazel-testlogs 12 | dist 13 | dist-dev 14 | lib 15 | lib-types 16 | etc 17 | external 18 | node_modules 19 | temp 20 | tsc-out 21 | tsdoc-metadata.json 22 | target 23 | output 24 | rollup.config.js 25 | build 26 | .cache 27 | .vscode 28 | .rollup.cache 29 | dist 30 | tsconfig.tsbuildinfo 31 | vite.config.ts 32 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | es2021: true, 6 | node: true, 7 | }, 8 | extends: [ 9 | "eslint:recommended", 10 | "plugin:@typescript-eslint/recommended", 11 | "plugin:qwik/recommended", 12 | ], 13 | parser: "@typescript-eslint/parser", 14 | parserOptions: { 15 | tsconfigRootDir: __dirname, 16 | project: ["./tsconfig.json"], 17 | ecmaVersion: 2021, 18 | sourceType: "module", 19 | ecmaFeatures: { 20 | jsx: true, 21 | }, 22 | }, 23 | plugins: ["@typescript-eslint"], 24 | rules: { 25 | "@typescript-eslint/no-explicit-any": "off", 26 | "@typescript-eslint/explicit-module-boundary-types": "off", 27 | "@typescript-eslint/no-inferrable-types": "off", 28 | "@typescript-eslint/no-non-null-assertion": "off", 29 | "@typescript-eslint/no-empty-interface": "off", 30 | "@typescript-eslint/no-namespace": "off", 31 | "@typescript-eslint/no-empty-function": "off", 32 | "@typescript-eslint/no-this-alias": "off", 33 | "@typescript-eslint/ban-types": "off", 34 | "@typescript-eslint/ban-ts-comment": "off", 35 | "prefer-spread": "off", 36 | "no-case-declarations": "off", 37 | "no-console": "off", 38 | "@typescript-eslint/no-unused-vars": ["error"], 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build 2 | /dist 3 | /lib 4 | /lib-types 5 | /server 6 | 7 | # Env 8 | .env 9 | 10 | # Development 11 | node_modules 12 | 13 | bun.lockb 14 | pnpm-lock.yaml 15 | yarn.lock 16 | 17 | # Cache 18 | .cache 19 | .mf 20 | .vscode 21 | .rollup.cache 22 | tsconfig.tsbuildinfo 23 | 24 | # Logs 25 | logs 26 | *.log 27 | npm-debug.log* 28 | yarn-debug.log* 29 | yarn-error.log* 30 | pnpm-debug.log* 31 | lerna-debug.log* 32 | 33 | # Editor 34 | !.vscode/extensions.json 35 | .idea 36 | .DS_Store 37 | *.suo 38 | *.ntvs* 39 | *.njsproj 40 | *.sln 41 | *.sw? 42 | 43 | # Yarn 44 | .yarn/* 45 | !.yarn/releases 46 | -------------------------------------------------------------------------------- /.release-it.json: -------------------------------------------------------------------------------- 1 | { 2 | "git": { 3 | "commitMessage": "chore: release v${version}", 4 | "tagAnnotation": "Release v${version}", 5 | "tagName": "v${version}" 6 | }, 7 | "github": { 8 | "release": true, 9 | "releaseName": "v${version}" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # CONTRIBUTING 2 | 3 | Hey! We are glad that you are interested in contributing to this project. We are open to any kind of contribution, from bug fixes to new features. We are also open to any kind of question or suggestion. We are looking forward to your pull requests and issues. 4 | 5 | ## Team members 6 | 7 | At the moment, the people who are actively maintaining this project are: 8 | 9 | - gustavocadev 10 | 11 | ### Ways to contribute to the project 12 | 13 | - Documentation 14 | - Adding tests 15 | - Adding new features 16 | - Bug fixes 17 | - Answering questions on issues 18 | - Adding new examples 19 | 20 | ### Start contributing by submitting a pull request 21 | 22 | Here are the steps to start contributing to this project: 23 | 24 | 1. Fork and clone the repository 25 | 2. Configure and install the dependencies 26 | 3. At this time we have no tests, so you can change the code and run the examples to see if everything is working 27 | 4. Make sure to add or change the documentation if needed 28 | 5. Make sure the linter passes 29 | 6. Submit a pull request with a description of your changes 30 | 7. Wait that someone review and approve your pull request 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 CA Gustavo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Qwik Lucia 2 | 3 | Qwik Lucia is a library that helps you to integrate [Lucia](https://lucia-auth.com/) with your Qwik project. 4 | 5 | - No more configuration 6 | 7 | ## Installation 8 | 9 | ```sh 10 | npm i qwik-lucia 11 | pnpm add qwik-lucia 12 | bun add qwik-lucia 13 | yarn add qwik-lucia 14 | ``` 15 | 16 | ## Setup Qwik Lucia 17 | 18 | In this example, we will use the `@lucia-auth/adapter-drizzle` adapter to connect to a PostgreSQL database. 19 | 20 | > For simplicity, we won't show the imports that are not related to the `qwik-lucia` or `lucia` package. 21 | 22 | ```ts 23 | // src/server/lucia.ts 24 | import { Lucia } from 'lucia'; 25 | import { DrizzlePostgreSQLAdapter } from '@lucia-auth/adapter-drizzle'; 26 | import { qwikLuciaConfig } from 'qwik-lucia'; 27 | 28 | const adapter = new DrizzlePostgreSQLAdapter(db, sessionTable, userTable); 29 | 30 | export const lucia = new Lucia(adapter, { 31 | sessionCookie: { 32 | attributes: { 33 | // set to `true` when using HTTPS 34 | secure: process.env.NODE_ENV === 'production', 35 | }, 36 | }, 37 | getUserAttributes: (attributes) => { 38 | return { 39 | username: attributes.username, 40 | }; 41 | }, 42 | }); 43 | 44 | /* 45 | IMPORTANT! 46 | Here we need to use `qwikLuciaConfig` to correctly configure the `handleRequest` function 47 | */ 48 | export const { handleRequest } = qwikLuciaConfig(lucia); 49 | 50 | declare module 'lucia' { 51 | interface Register { 52 | Lucia: typeof lucia; 53 | DatabaseUserAttributes: Omit; 54 | } 55 | } 56 | ``` 57 | 58 | ### Set `user` and `session` in SharedMap on every request using `onRequest` handler 59 | 60 | ```tsx 61 | // src/routes/layout.tsx 62 | import type { RequestHandler } from '@builder.io/qwik-city'; 63 | import { handleRequest } from '~/server/lucia'; 64 | 65 | // Run on every request 66 | export const onRequest: RequestHandler = async ({ cookie, sharedMap }) => { 67 | const authRequest = handleRequest({ cookie }); 68 | const { user, session } = await authRequest.validateUser(); 69 | 70 | // share the user and session with the rest of the app 71 | sharedMap.set('user', user); 72 | sharedMap.set('session', session); 73 | }; 74 | ``` 75 | 76 | ### Signup 77 | 78 | ```tsx 79 | // src/routes/signup/index.tsx 80 | import { handleRequest, lucia } from "~/lib/lucia"; 81 | 82 | // This is just a wrapper around the oslo/password library 83 | import { hashPassword } from 'qwik-lucia'; 84 | 85 | export const useSignupUser = routeAction$( 86 | async (values, { redirect }) => { 87 | try { 88 | const passwordHash = await hashPassword(values.password); 89 | 90 | await db.insert(userTable).values({ 91 | username: values.username, 92 | password: passwordHash, 93 | }); 94 | } catch (e) { 95 | ... // handle error 96 | } 97 | // make sure you don't throw inside a try/catch block! 98 | throw redirect(303, '/'); 99 | }, 100 | // validate the input 101 | zod$({ 102 | username: z.string().min(2), 103 | password: z.string().min(5), 104 | }) 105 | ); 106 | ``` 107 | 108 | ### Login 109 | 110 | ```tsx 111 | // src/routes/login/index.tsx 112 | import { handleRequest, lucia } from "~/server/lucia"; 113 | 114 | // This is just a wrapper around the oslo/password library 115 | import { verifyPassword } from 'qwik-lucia'; 116 | 117 | export const useLoginAction = routeAction$( 118 | async (values, { cookie, fail }) => { 119 | // Important! Use `handleRequest` to handle the authentication request 120 | const authRequest = handleRequest({ cookie }); 121 | 122 | try { 123 | //1. search for user 124 | const [user] = await db 125 | .select({ 126 | id: userTable.id, 127 | passwordHash: userTable.password, 128 | username: userTable.username, 129 | }) 130 | .from(userTable) 131 | .where(eq(userTable.username, values.username)); 132 | 133 | //2. if user is not found, throw error 134 | if (!user) { 135 | return fail(400, { 136 | message: 'Incorrect username or password', 137 | }); 138 | } 139 | 140 | // 3. validate password 141 | const isValidPassword = await verifyPassword( 142 | user.passwordHash, 143 | values.password 144 | ); 145 | 146 | if (!isValidPassword) { 147 | return fail(400, { 148 | message: 'Incorrect username or password', 149 | }); 150 | } 151 | 152 | // 4. create session 153 | const session = await lucia.createSession(user.id, {}); 154 | 155 | authRequest.setSession(session); // set session cookie 156 | } catch (e) { 157 | ... // handle error 158 | } 159 | // make sure you don't throw inside a try/catch block! 160 | throw event.redirect(303, '/'); 161 | }, 162 | // validate the input 163 | zod$({ 164 | username: z.string(), 165 | password: z.string(), 166 | }) 167 | ); 168 | ``` 169 | 170 | ### Logout 171 | 172 | ```tsx 173 | // src/routes/index.tsx 174 | import { handleRequest } from '~/server/lucia'; 175 | 176 | // Create a user logout action 177 | export const useLogoutUserAction = routeAction$( 178 | async (values, { cookie, sharedMap, redirect }) => { 179 | const authRequest = handleRequest({ cookie }); 180 | const session = sharedMap.get('session'); 181 | 182 | if (!session) throw redirect(302, '/login'); 183 | 184 | // Remove the session from the database and from the cookie - Logout 185 | await authRequest.invalidateSessionCookie(session); 186 | 187 | throw redirect(302, '/login'); 188 | } 189 | ); 190 | ``` 191 | 192 | ### Get User and Session from SharedMap 193 | 194 | ```tsx 195 | const user = sharedMap.get('user'); 196 | const session = sharedMap.get('session'); 197 | ``` 198 | 199 | Example 200 | 201 | ```tsx 202 | export const isUserLoggedIn = routeLoader$(async ({ sharedMap, redirect }) => { 203 | const user = sharedMap.get('user'); 204 | const session = sharedMap.get('session'); 205 | 206 | if (!user || !session) { 207 | throw redirect(302, '/login'); 208 | } 209 | 210 | return {}; 211 | }); 212 | ``` 213 | -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/.env.example: -------------------------------------------------------------------------------- 1 | DATABASE_URL='' -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/.eslintignore: -------------------------------------------------------------------------------- 1 | **/*.log 2 | **/.DS_Store 3 | *. 4 | .vscode/settings.json 5 | .history 6 | .yarn 7 | bazel-* 8 | bazel-bin 9 | bazel-out 10 | bazel-qwik 11 | bazel-testlogs 12 | dist 13 | dist-dev 14 | lib 15 | lib-types 16 | etc 17 | external 18 | node_modules 19 | temp 20 | tsc-out 21 | tsdoc-metadata.json 22 | target 23 | output 24 | rollup.config.js 25 | build 26 | .cache 27 | .vscode 28 | .rollup.cache 29 | dist 30 | tsconfig.tsbuildinfo 31 | vite.config.ts 32 | *.spec.tsx 33 | *.spec.ts 34 | .netlify 35 | pnpm-lock.yaml 36 | package-lock.json 37 | yarn.lock 38 | server -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | es2021: true, 6 | node: true, 7 | }, 8 | extends: [ 9 | 'eslint:recommended', 10 | 'plugin:@typescript-eslint/recommended', 11 | 'plugin:qwik/recommended', 12 | ], 13 | parser: '@typescript-eslint/parser', 14 | parserOptions: { 15 | tsconfigRootDir: __dirname, 16 | project: ['./tsconfig.json'], 17 | ecmaVersion: 2021, 18 | sourceType: 'module', 19 | ecmaFeatures: { 20 | jsx: true, 21 | }, 22 | }, 23 | plugins: ['@typescript-eslint'], 24 | rules: { 25 | '@typescript-eslint/no-explicit-any': 'off', 26 | '@typescript-eslint/explicit-module-boundary-types': 'off', 27 | '@typescript-eslint/no-inferrable-types': 'off', 28 | '@typescript-eslint/no-non-null-assertion': 'off', 29 | '@typescript-eslint/no-empty-interface': 'off', 30 | '@typescript-eslint/no-namespace': 'off', 31 | '@typescript-eslint/no-empty-function': 'off', 32 | '@typescript-eslint/no-this-alias': 'off', 33 | '@typescript-eslint/ban-types': 'off', 34 | '@typescript-eslint/ban-ts-comment': 'off', 35 | 'prefer-spread': 'off', 36 | 'no-case-declarations': 'off', 37 | 'no-console': 'off', 38 | '@typescript-eslint/no-unused-vars': ['error'], 39 | '@typescript-eslint/consistent-type-imports': 'warn', 40 | '@typescript-eslint/no-unnecessary-condition': 'warn', 41 | }, 42 | }; 43 | -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/.gitignore: -------------------------------------------------------------------------------- 1 | # Build 2 | /dist 3 | /lib 4 | /lib-types 5 | /server 6 | 7 | # Development 8 | node_modules 9 | *.local 10 | 11 | # Cache 12 | .cache 13 | .mf 14 | .rollup.cache 15 | tsconfig.tsbuildinfo 16 | 17 | # Logs 18 | logs 19 | *.log 20 | npm-debug.log* 21 | yarn-debug.log* 22 | yarn-error.log* 23 | pnpm-debug.log* 24 | lerna-debug.log* 25 | 26 | # Editor 27 | .vscode/* 28 | !.vscode/extensions.json 29 | .idea 30 | .DS_Store 31 | *.suo 32 | *.ntvs* 33 | *.njsproj 34 | *.sln 35 | *.sw? 36 | 37 | # Yarn 38 | .yarn/* 39 | !.yarn/releases 40 | 41 | # Env 42 | .env 43 | 44 | # Vercel 45 | .vercel 46 | -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.log 2 | **/.DS_Store 3 | *. 4 | .vscode/settings.json 5 | .history 6 | .yarn 7 | bazel-* 8 | bazel-bin 9 | bazel-out 10 | bazel-qwik 11 | bazel-testlogs 12 | dist 13 | dist-dev 14 | lib 15 | lib-types 16 | etc 17 | external 18 | node_modules 19 | temp 20 | tsc-out 21 | tsdoc-metadata.json 22 | target 23 | output 24 | rollup.config.js 25 | build 26 | .cache 27 | .vscode 28 | .rollup.cache 29 | dist 30 | tsconfig.tsbuildinfo 31 | vite.config.ts 32 | *.spec.tsx 33 | *.spec.ts 34 | .netlify 35 | pnpm-lock.yaml 36 | package-lock.json 37 | yarn.lock 38 | server 39 | -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/README.md: -------------------------------------------------------------------------------- 1 | # Qwik ⚡️ and Lucia Auth + Drizzle ORM + PlanetScale 2 | 3 | This is an example of how to use Lucia Auth + Drizzle ORM with Qwik ⚡️ 4 | 5 | ## Vercel Edge 6 | 7 | This starter site is configured to deploy to [Vercel Edge Functions](https://vercel.com/docs/concepts/functions/edge-functions), which means it will be rendered at an edge location near to your users. 8 | 9 | ## Installation 10 | 11 | The adaptor will add a new `vite.config.ts` within the `adapters/` directory, and a new entry file will be created, such as: 12 | 13 | ``` 14 | └── adapters/ 15 | └── vercel-edge/ 16 | └── vite.config.ts 17 | └── src/ 18 | └── entry.vercel-edge.tsx 19 | ``` 20 | 21 | Additionally, within the `package.json`, the `build.server` script will be updated with the Vercel Edge build. 22 | 23 | ## Production build 24 | 25 | To build the application for production, use the `build` command, this command will automatically run `pnpm build.server` and `pnpm build.client`: 26 | 27 | ```shell 28 | pnpm build 29 | ``` 30 | 31 | [Read the full guide here](https://github.com/BuilderIO/qwik/blob/main/starters/adapters/vercel-edge/README.md) 32 | 33 | ## Dev deploy 34 | 35 | To deploy the application for development: 36 | 37 | ```shell 38 | pnpm deploy 39 | ``` 40 | 41 | Notice that you might need a [Vercel account](https://docs.Vercel.com/get-started/) in order to complete this step! 42 | 43 | ## Production deploy 44 | 45 | The project is ready to be deployed to Vercel. However, you will need to create a git repository and push the code to it. 46 | 47 | You can [deploy your site to Vercel](https://vercel.com/docs/concepts/deployments/overview) either via a Git provider integration or through the Vercel CLI. 48 | -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/adapters/vercel-edge/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { vercelEdgeAdapter } from '@builder.io/qwik-city/adapters/vercel-edge/vite'; 2 | import { extendConfig } from '@builder.io/qwik-city/vite'; 3 | import baseConfig from '../../vite.config'; 4 | 5 | export default extendConfig(baseConfig, () => { 6 | return { 7 | build: { 8 | ssr: true, 9 | rollupOptions: { 10 | input: ['src/entry.vercel-edge.tsx', '@qwik-city-plan'], 11 | }, 12 | outDir: '.vercel/output/functions/_qwik-city.func', 13 | }, 14 | plugins: [vercelEdgeAdapter()], 15 | }; 16 | }); 17 | -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/drizzle.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'drizzle-kit'; 2 | import * as dotenv from 'dotenv'; 3 | dotenv.config(); 4 | 5 | // if your have a eslint error make sure to add the following line `"files":["./drizzle.config.ts"]` in your tsconfig.json file 6 | export default { 7 | schema: './src/db/schema/*', 8 | out: './drizzle', 9 | driver: 'mysql2', 10 | dbCredentials: { 11 | uri: process.env.DATABASE_URL!, 12 | }, 13 | } satisfies Config; 14 | -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lucia-drizzle-mysql-planetscale-qwik", 3 | "description": "App with Routing built-in (recommended)", 4 | "engines": { 5 | "node": ">=15.0.0" 6 | }, 7 | "private": true, 8 | "trustedDependencies": [ 9 | "sharp" 10 | ], 11 | "type": "module", 12 | "scripts": { 13 | "build": "qwik build", 14 | "build.client": "vite build", 15 | "build.preview": "vite build --ssr src/entry.preview.tsx", 16 | "build.server": "vite build -c adapters/vercel-edge/vite.config.ts", 17 | "build.types": "tsc --incremental --noEmit", 18 | "deploy": "vercel deploy", 19 | "dev": "vite --mode ssr", 20 | "dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force", 21 | "fmt": "prettier --write .", 22 | "fmt.check": "prettier --check .", 23 | "lint": "eslint \"src/**/*.ts*\"", 24 | "preview": "qwik build preview && vite preview --open", 25 | "start": "vite --open --mode ssr", 26 | "qwik": "qwik", 27 | "db:generate": "drizzle-kit generate:mysql", 28 | "db:push": "drizzle-kit push:mysql", 29 | "db:up": "drizzle-kit up:mysql" 30 | }, 31 | "devDependencies": { 32 | "@builder.io/qwik": "1.4.5", 33 | "@builder.io/qwik-city": "^1.4.5", 34 | "@types/eslint": "8.56.0", 35 | "@types/node": "^20.10.5", 36 | "@types/pg": "^8.10.9", 37 | "@typescript-eslint/eslint-plugin": "6.15.0", 38 | "@typescript-eslint/parser": "6.15.0", 39 | "autoprefixer": "^10.4.16", 40 | "daisyui": "^4.7.2", 41 | "dotenv": "^16.4.4", 42 | "drizzle-kit": "^0.20.14", 43 | "eslint": "8.56.0", 44 | "eslint-plugin-qwik": "1.4.5", 45 | "postcss": "^8.4.32", 46 | "prettier": "3.1.1", 47 | "tailwindcss": "^3.4.0", 48 | "typescript": "5.3.3", 49 | "undici": "6.6.2", 50 | "vercel": "^29.1.1", 51 | "vite": "5.1.3", 52 | "vite-tsconfig-paths": "4.2.2" 53 | }, 54 | "dependencies": { 55 | "@lucia-auth/adapter-drizzle": "^1.0.2", 56 | "@lucia-auth/adapter-mysql": "^3.0.0", 57 | "@planetscale/database": "^1.16.0", 58 | "drizzle-orm": "^0.29.3", 59 | "lucia": "^3.0.1", 60 | "qwik-lucia": "^0.5.0" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/public/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/public/fonts/poppins-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gustavocadev/qwik-lucia/95c69cc359def84250a85227dc607233e98d625b/examples/lucia-drizzle-mysql-planetscale-qwik/public/fonts/poppins-400.woff2 -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/public/fonts/poppins-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gustavocadev/qwik-lucia/95c69cc359def84250a85227dc607233e98d625b/examples/lucia-drizzle-mysql-planetscale-qwik/public/fonts/poppins-500.woff2 -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/public/fonts/poppins-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gustavocadev/qwik-lucia/95c69cc359def84250a85227dc607233e98d625b/examples/lucia-drizzle-mysql-planetscale-qwik/public/fonts/poppins-700.woff2 -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/web-manifest-combined.json", 3 | "name": "qwik-project-name", 4 | "short_name": "Welcome to Qwik", 5 | "start_url": ".", 6 | "display": "standalone", 7 | "background_color": "#fff", 8 | "description": "A Qwik project app." 9 | } 10 | -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/public/robots.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gustavocadev/qwik-lucia/95c69cc359def84250a85227dc607233e98d625b/examples/lucia-drizzle-mysql-planetscale-qwik/public/robots.txt -------------------------------------------------------------------------------- /examples/lucia-drizzle-mysql-planetscale-qwik/src/components/router-head/router-head.tsx: -------------------------------------------------------------------------------- 1 | import { component$ } from '@builder.io/qwik'; 2 | import { useDocumentHead, useLocation } from '@builder.io/qwik-city'; 3 | 4 | /** 5 | * The RouterHead component is placed inside of the document `` element. 6 | */ 7 | export const RouterHead = component$(() => { 8 | const head = useDocumentHead(); 9 | const loc = useLocation(); 10 | 11 | return ( 12 | <> 13 | {head.title} 14 | 15 | 16 | 17 | 18 | 19 | {head.meta.map((m) => ( 20 | 21 | ))} 22 | 23 | {head.links.map((l) => ( 24 | 25 | ))} 26 | 27 | {head.styles.map((s) => ( 28 |