diff --git a/README.md b/README.md index fae73af..8dee7b0 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ pnpm wrangler d1 execute dev-certifine --local --file=db/schema/schema.sql pnpm nx serve api-auth VITE_GOOGLE_REDIRECT_URI=http://localhost:8788/api/auth/google/callback pnpm nx build web +$Env:VITE_GOOGLE_REDIRECT_URI=http://localhost:8788/api/auth/google/callback pnpm nx build web pnpm wrangler pages dev dist/apps/web/deploy ``` diff --git a/apps/api/auth/src/main.ts b/apps/api/auth/src/main.ts index 1f7f6dd..981471b 100644 --- a/apps/api/auth/src/main.ts +++ b/apps/api/auth/src/main.ts @@ -1,5 +1,5 @@ import { Hono } from 'hono'; -import { D1Database } from '@cloudflare/workers-types'; +import { D1Database, R2Bucket } from '@cloudflare/workers-types'; import { typeid } from 'typeid-js'; interface ResponseWrapper { @@ -7,16 +7,17 @@ interface ResponseWrapper { error: E; } -const response = (data: T, error ?: E): ResponseWrapper => { +const response = (data: T, error?: E): ResponseWrapper => { return { data, - error + error, }; }; type Bindings = { DB: D1Database; -} + BUCKET: R2Bucket; +}; const app = new Hono<{ Bindings: Bindings }>(); @@ -45,7 +46,7 @@ app.get('/users', async (c) => { op.name 'provider', oa.created_at 'createdAt', oa.updated_at 'updatedAt' - FROM oauth_account as oa + FROM oauth_account as oa JOIN user as u ON (oa.user_id = u.id) JOIN oauth_provider as op ON (oa.oauth_provider_id = op.id) WHERE u.id = ?1 AND oa.deleted_at IS NULL @@ -74,11 +75,7 @@ interface User { deleted_at: number; } -type CreateUserParams = Pick; +type CreateUserParams = Pick; interface CreateOAuthParams { oaid: string; @@ -105,10 +102,7 @@ app.post('/users', async (c) => { const id = typeid('user').toString(); - const results = await c.env.DB.batch([ - createUserStatement.bind(id, body.username, body.firstName, body.lastName, Date.now()), - createOAuthAccountStatement.bind(body.oaid, id, body.provider, body.email, Date.now()), - ]); + const results = await c.env.DB.batch([createUserStatement.bind(id, body.username, body.firstName, body.lastName, Date.now()), createOAuthAccountStatement.bind(body.oaid, id, body.provider, body.email, Date.now())]); return c.json(response(results)); }); @@ -121,9 +115,7 @@ interface OAuthProvider { deleted_at: number; } -type CreateOAuthProviderParams = Pick; +type CreateOAuthProviderParams = Pick; app.get('/providers', async (c) => { const findOAuthProviderStatement = c.env.DB.prepare(` @@ -155,4 +147,182 @@ app.post('/providers', async (c) => { return c.json(response(result)); }); +interface Template { + id: string; + userId: string; + name: string; + createdAt: number; + updatedAt: number; + deletedAt: number; +} + +type CreateTemplateParams = Pick; + +type FindTemplateParams = Pick; + +interface TemplateDataParams { + data: JSON; +} + +type UpdateTemplateParams = Pick; + +type CreateTemplateRequest = CreateTemplateParams & TemplateDataParams; +type UpdateTemplateRequest = UpdateTemplateParams & TemplateDataParams; + +app.post('/templates', async (c) => { + const body = await c.req.json(); + + const id = typeid('tmpl').toString(); + + const key = ['templates', body.userId, id].join('/'); + + const createTemplateStatement = c.env.DB.prepare(` + INSERT INTO template (id, user_id, name, created_at) + VALUES (?1, ?2, ?3, ?4) + `); + + try { + await c.env.BUCKET.put(key, JSON.stringify(body.data)); + + const { results } = await createTemplateStatement.bind(id, body.userId, body.name, Date.now()).run(); + + return c.json(response(results)); + } catch (e) { + return c.json(response(null, e)); + } +}); + +app.get('/templates/:userId', async (c) => { + const { userId } = c.req.param() as FindTemplateParams; + + const getTemplateStatement = c.env.DB.prepare(` + SELECT + t.id, + t.user_id 'userId', + t.key, + t.created_at 'createdAt', + t.updated_at 'updatedAt' + FROM template as t + WHERE t.user_id = ?1 AND t.deleted_at NOT NULL + `); + + const { results } = await getTemplateStatement.bind(userId).all