diff --git a/app/lib/db.service.server.ts b/app/lib/db.service.server.ts index c7ddd3f..7200249 100644 --- a/app/lib/db.service.server.ts +++ b/app/lib/db.service.server.ts @@ -1,6 +1,6 @@ -import { and, eq, gt } from "drizzle-orm"; import type { DrizzleD1Database } from "drizzle-orm/d1"; import { drizzle } from "drizzle-orm/d1"; +import * as schema from "./schema"; const contextWithDb = ( context: Record @@ -15,5 +15,7 @@ export const getDbFromContext = ( throw new Error("No database in context"); } - return drizzle(context.DB); + return drizzle(context.DB, { + schema, + }); }; diff --git a/app/lib/schema.ts b/app/lib/schema.ts index edbfc1c..fd2c5c0 100644 --- a/app/lib/schema.ts +++ b/app/lib/schema.ts @@ -1,6 +1,7 @@ -import type { InferModel } from "drizzle-orm"; +import { type InferModel, relations } from "drizzle-orm"; import { integer, + primaryKey, sqliteTable, text, uniqueIndex, @@ -22,8 +23,9 @@ export const users = sqliteTable( }) ); -export type User = InferModel; -export type NewUser = InferModel; +export const usersRelations = relations(users, ({ many }) => ({ + usersToGroups: many(usersToTeams), +})); export const teams = sqliteTable("teams", { id: integer("id").primaryKey({ @@ -33,11 +35,32 @@ export const teams = sqliteTable("teams", { avatar: text("avatar"), }); -export const usersToTeams = sqliteTable("usersToTeams", { - userId: integer("userId") - .notNull() - .references(() => users.id), - teamId: integer("teamId") - .notNull() - .references(() => teams.id), -}); +export const teamsRelations = relations(teams, ({ many }) => ({ + usersToTeams: many(usersToTeams), +})); + +export const usersToTeams = sqliteTable( + "usersToTeams", + { + userId: integer("userId") + .notNull() + .references(() => users.id), + teamId: integer("teamId") + .notNull() + .references(() => teams.id), + }, + (t) => ({ + pk: primaryKey(t.userId, t.teamId), + }) +); + +export const usersToTeamsRelations = relations(usersToTeams, ({ one }) => ({ + team: one(teams, { + fields: [usersToTeams.teamId], + references: [teams.id], + }), + user: one(users, { + fields: [usersToTeams.userId], + references: [users.id], + }), +})); diff --git a/app/routes/app.tsx b/app/routes/app.tsx index 995c523..27b5430 100644 --- a/app/routes/app.tsx +++ b/app/routes/app.tsx @@ -38,6 +38,9 @@ export async function loader({ request, context }: LoaderArgs) { if (!user) { return redirect("/login"); } + + //const teams = await db.query + const userTeams = await db .select({ id: teams.id, diff --git a/app/routes/register.tsx b/app/routes/register.tsx index 2a0466e..14f13e1 100644 --- a/app/routes/register.tsx +++ b/app/routes/register.tsx @@ -1,21 +1,19 @@ -import { Github, Loader2 } from "lucide-react"; +import { Loader2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { ActionArgs, - LoaderArgs, redirect, } from "@remix-run/cloudflare"; -import { getDbFromContext, getUsers } from "@/lib/db.service.server"; -import { Input } from "@/components/ui/input"; +import { getDbFromContext } from "@/lib/db.service.server"; import { Label } from "@/components/ui/label"; -import { Form, Link, useActionData, useNavigation } from "@remix-run/react"; +import { Link, useActionData, useNavigation } from "@remix-run/react"; import { withZod } from "@remix-validated-form/with-zod"; import { z } from "zod"; import { ValidatedForm, validationError } from "remix-validated-form"; import { InputForm } from "@/components/ui/inputForm"; -import { NewUser, User, users } from "@/lib/schema"; import { hash } from "@/lib/passwordHashing.server"; import { generateRandomLinearGradient } from "@/lib/utils"; +import { users } from "@/lib/schema"; export const validator = withZod( z @@ -43,7 +41,7 @@ export async function action({ request, context }: ActionArgs) { const hashedPassword = await hash({ password: result.data.password, }); - const newUser: NewUser = { + const newUser = { email: result.data.email, password: hashedPassword, avatar: generateRandomLinearGradient(), diff --git a/package-lock.json b/package-lock.json index ab4dc4e..dcc5c51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "clsx": "^1.2.1", "cmdk": "^0.2.0", "cross-env": "^7.0.3", - "drizzle-orm": "^0.24.4", + "drizzle-orm": "^0.26.0", "isbot": "^3.6.8", "lucide-react": "^0.172.0", "posthog-js": "^1.55.0", @@ -43,13 +43,17 @@ "@cloudflare/workers-types": "^3.19.0", "@remix-run/dev": "^1.15.0", "@remix-run/eslint-config": "^1.15.0", + "@types/eslint": "^8.37.0", "@types/react": "^18.0.35", "@types/react-dom": "^18.0.11", "@types/react-grid-layout": "^1.3.2", "better-sqlite3": "^8.3.0", - "drizzle-kit": "^0.17.5", + "drizzle-kit": "^0.18.0", "eslint": "^8.38.0", + "eslint-config-prettier": "^8.8.0", "npm-run-all": "^4.1.5", + "prettier": "2.8.7", + "prettier-plugin-tailwindcss": "^0.2.7", "tailwindcss": "^3.3.1", "typescript": "^4.9.5", "wrangler": "^2.15.1" @@ -3483,6 +3487,21 @@ } } }, + "node_modules/@remix-run/dev/node_modules/prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/@remix-run/eslint-config": { "version": "1.15.0", "dev": true, @@ -3680,6 +3699,16 @@ "@types/ms": "*" } }, + "node_modules/@types/eslint": { + "version": "8.37.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.37.0.tgz", + "integrity": "sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.1", "dev": true, @@ -5991,9 +6020,9 @@ } }, "node_modules/drizzle-kit": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.17.5.tgz", - "integrity": "sha512-oS4qG3d4m7RUHqdhPZSjYh6QSarxbHKyalBeW1cBpJp2F5DB5xvEan6qfaKdasYkI10DNdPuvXcZOR31tiRIGA==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.18.0.tgz", + "integrity": "sha512-43oH0XNWJDfMmVtDVnW8OV+tIs3xXDb1MjdsDiv0a7unQAylr0hpGG0HD5uEPWSbt7oxBots+hnYWxo98D0KAg==", "dev": true, "dependencies": { "camelcase": "^7.0.1", @@ -6004,6 +6033,7 @@ "glob": "^8.1.0", "hanji": "^0.0.5", "json-diff": "0.9.0", + "minimatch": "^7.4.3", "zod": "^3.20.2" }, "bin": { @@ -6096,7 +6126,7 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/drizzle-kit/node_modules/minimatch": { + "node_modules/drizzle-kit/node_modules/glob/node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", @@ -6108,10 +6138,25 @@ "node": ">=10" } }, + "node_modules/drizzle-kit/node_modules/minimatch": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/drizzle-orm": { - "version": "0.24.4", - "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.24.4.tgz", - "integrity": "sha512-mQzuqEHqc2NGN20ACc0NAaFaHlQlTZquoK42xJ8TRSntzAVz4iSDksozVJKBXig+qKgZA9C7KpWCDRo9+NMgng==", + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.26.0.tgz", + "integrity": "sha512-ztjhHehcuG5+lpGYxfT/L5I+yd/Z0dOf0fV3cS2ywBU01wkpxjwl4EJZVT7kVzjYfM8kwMGDghAPRPBCK0vULA==", "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=3", @@ -6121,6 +6166,7 @@ "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", + "@vercel/postgres": "*", "better-sqlite3": ">=7", "bun-types": "*", "knex": "*", @@ -6156,6 +6202,9 @@ "@types/sql.js": { "optional": true }, + "@vercel/postgres": { + "optional": true + }, "better-sqlite3": { "optional": true }, @@ -7002,6 +7051,18 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-config-prettier": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", + "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, "node_modules/eslint-import-resolver-node": { "version": "0.3.6", "dev": true, @@ -11847,6 +11908,17 @@ "version": "4.2.0", "license": "MIT" }, + "node_modules/postgres": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/postgres/-/postgres-3.3.4.tgz", + "integrity": "sha512-XVu0+d/Y56pl2lSaf0c7V19AhAEfpVrhID1IENWN8nf0xch6hFq6dAov5dtUX6ZD46wfr1TxvLhxLtV8WnNsOg==", + "optional": true, + "peer": true, + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/porsager" + } + }, "node_modules/posthog-js": { "version": "1.55.0", "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.55.0.tgz", @@ -11901,9 +11973,10 @@ } }, "node_modules/prettier": { - "version": "2.7.1", + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", + "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", "dev": true, - "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -11914,6 +11987,76 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prettier-plugin-tailwindcss": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.2.8.tgz", + "integrity": "sha512-KgPcEnJeIijlMjsA6WwYgRs5rh3/q76oInqtMXBA/EMcamrcYJpyhtRhyX1ayT9hnHlHTuO8sIifHF10WuSDKg==", + "dev": true, + "engines": { + "node": ">=12.17.0" + }, + "peerDependencies": { + "@ianvs/prettier-plugin-sort-imports": "*", + "@prettier/plugin-pug": "*", + "@shopify/prettier-plugin-liquid": "*", + "@shufo/prettier-plugin-blade": "*", + "@trivago/prettier-plugin-sort-imports": "*", + "prettier": ">=2.2.0", + "prettier-plugin-astro": "*", + "prettier-plugin-css-order": "*", + "prettier-plugin-import-sort": "*", + "prettier-plugin-jsdoc": "*", + "prettier-plugin-organize-attributes": "*", + "prettier-plugin-organize-imports": "*", + "prettier-plugin-style-order": "*", + "prettier-plugin-svelte": "*", + "prettier-plugin-twig-melody": "*" + }, + "peerDependenciesMeta": { + "@ianvs/prettier-plugin-sort-imports": { + "optional": true + }, + "@prettier/plugin-pug": { + "optional": true + }, + "@shopify/prettier-plugin-liquid": { + "optional": true + }, + "@shufo/prettier-plugin-blade": { + "optional": true + }, + "@trivago/prettier-plugin-sort-imports": { + "optional": true + }, + "prettier-plugin-astro": { + "optional": true + }, + "prettier-plugin-css-order": { + "optional": true + }, + "prettier-plugin-import-sort": { + "optional": true + }, + "prettier-plugin-jsdoc": { + "optional": true + }, + "prettier-plugin-organize-attributes": { + "optional": true + }, + "prettier-plugin-organize-imports": { + "optional": true + }, + "prettier-plugin-style-order": { + "optional": true + }, + "prettier-plugin-svelte": { + "optional": true + }, + "prettier-plugin-twig-melody": { + "optional": true + } + } + }, "node_modules/pretty-format": { "version": "27.5.1", "dev": true, diff --git a/package.json b/package.json index 3c49196..d8eaa45 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "clsx": "^1.2.1", "cmdk": "^0.2.0", "cross-env": "^7.0.3", - "drizzle-orm": "^0.24.4", + "drizzle-orm": "^0.26.0", "isbot": "^3.6.8", "lucide-react": "^0.172.0", "posthog-js": "^1.55.0", @@ -50,13 +50,17 @@ "@cloudflare/workers-types": "^3.19.0", "@remix-run/dev": "^1.15.0", "@remix-run/eslint-config": "^1.15.0", + "@types/eslint": "^8.37.0", "@types/react": "^18.0.35", "@types/react-dom": "^18.0.11", "@types/react-grid-layout": "^1.3.2", "better-sqlite3": "^8.3.0", - "drizzle-kit": "^0.17.5", + "drizzle-kit": "^0.18.0", "eslint": "^8.38.0", + "eslint-config-prettier": "^8.8.0", "npm-run-all": "^4.1.5", + "prettier": "2.8.7", + "prettier-plugin-tailwindcss": "^0.2.7", "tailwindcss": "^3.3.1", "typescript": "^4.9.5", "wrangler": "^2.15.1"