1
1
import { Hono } from 'hono' ;
2
- import { D1Database } from '@cloudflare/workers-types' ;
2
+ import { D1Database , R2Bucket } from '@cloudflare/workers-types' ;
3
3
import { typeid } from 'typeid-js' ;
4
4
5
5
interface ResponseWrapper < T , E > {
6
6
data : T ;
7
7
error : E ;
8
8
}
9
9
10
- const response = < T , E > ( data : T , error ?: E ) : ResponseWrapper < T , E > => {
10
+ const response = < T , E > ( data : T , error ?: E ) : ResponseWrapper < T , E > => {
11
11
return {
12
12
data,
13
13
error
@@ -16,6 +16,7 @@ const response = <T, E> (data: T, error ?: E): ResponseWrapper<T, E> => {
16
16
17
17
type Bindings = {
18
18
DB : D1Database ;
19
+ BUCKET : R2Bucket ;
19
20
}
20
21
21
22
const app = new Hono < { Bindings : Bindings } > ( ) ;
@@ -84,7 +85,7 @@ interface CreateOAuthParams {
84
85
oaid : string ;
85
86
provider : string ;
86
87
email : string ;
87
- }
88
+ } ;
88
89
89
90
type CreateUserRequest = CreateUserParams & CreateOAuthParams ;
90
91
@@ -155,4 +156,198 @@ app.post('/providers', async (c) => {
155
156
return c . json ( response ( result ) ) ;
156
157
} ) ;
157
158
159
+ interface Template {
160
+ id : string ;
161
+ userId : string ;
162
+ name : string ;
163
+ createdAt : number ;
164
+ updatedAt : number ;
165
+ deletedAt : number ;
166
+ } ;
167
+
168
+ type CreateTemplateParams = Pick < Template ,
169
+ | 'name'
170
+ | 'userId'
171
+ > ;
172
+
173
+ type FindTemplateParams = Pick < Template ,
174
+ | 'userId'
175
+ > ;
176
+
177
+ interface TemplateDataParams {
178
+ data : JSON ;
179
+ } ;
180
+
181
+ type UpdateTemplateParams = Pick < Template ,
182
+ | 'name'
183
+ > ;
184
+
185
+ type CreateTemplateRequest = CreateTemplateParams & TemplateDataParams ;
186
+ type UpdateTemplateRequest = UpdateTemplateParams & TemplateDataParams ;
187
+
188
+ app . post ( '/templates' , async ( c ) => {
189
+ const body = await c . req . json < CreateTemplateRequest > ( ) ;
190
+
191
+ const id = typeid ( 'tmpl' ) . toString ( ) ;
192
+
193
+ const key = [ 'templates' , body . userId , id ] . join ( '/' ) ;
194
+
195
+ const createTemplateStatement = c . env . DB . prepare ( `
196
+ INSERT INTO template (id, user_id, name, created_at)
197
+ VALUES (?1, ?2, ?3, ?4)
198
+ ` ) ;
199
+
200
+ try {
201
+ await c . env . BUCKET . put ( key , JSON . stringify ( body . data ) ) ;
202
+
203
+ const { results } = await createTemplateStatement . bind ( id , body . userId , body . name , Date . now ( ) ) . run ( ) ;
204
+
205
+ return c . json ( response ( results ) ) ;
206
+ } catch ( e ) {
207
+ return c . json ( response ( null , e ) ) ;
208
+ }
209
+ } ) ;
210
+
211
+ app . get ( '/templates/:userId' , async ( c ) => {
212
+ const { userId } = c . req . param ( ) as FindTemplateParams ;
213
+
214
+ const getTemplateStatement = c . env . DB . prepare ( `
215
+ SELECT
216
+ t.id,
217
+ t.user_id 'userId',
218
+ t.key,
219
+ t.created_at 'createdAt',
220
+ t.updated_at 'updatedAt'
221
+ FROM template as t
222
+ WHERE t.user_id = ?1 AND t.deleted_at NOT NULL
223
+ ` ) ;
224
+
225
+ const { results } = await getTemplateStatement . bind ( userId ) . all < Template > ( ) ;
226
+
227
+ results . map ( ( template ) => {
228
+ template . id ;
229
+ } ) ;
230
+
231
+ return c . json ( response ( results ) ) ;
232
+ } ) ;
233
+
234
+ app . get ( '/templates/:userId/:id' , async ( c ) => {
235
+ const { userId, id } = c . req . param ( ) ;
236
+ const key = [ 'templates' , userId , id ] . join ( '/' ) ;
237
+
238
+ try {
239
+ const objectRef = await c . env . BUCKET . get ( key ) ;
240
+ const data = objectRef . json ( ) ;
241
+
242
+ return c . json ( response ( data ) ) ;
243
+ } catch ( e ) {
244
+ return c . json ( response ( null , e ) ) ;
245
+ }
246
+ } ) ;
247
+
248
+ app . put ( '/templates/:userId/:id' , async ( c ) => {
249
+ const { userId, id } = c . req . param ( ) ;
250
+ const { data, name } = await c . req . json ( ) as UpdateTemplateRequest ;
251
+
252
+ const key = [ 'templates' , userId , id ] . join ( '/' ) ;
253
+
254
+ const updateTemplateStatement = c . env . DB . prepare ( `
255
+ UPDATE template
256
+ SET name = ?1
257
+ WHERE id = ?2 AND deleted_at NOT NULL
258
+ ` ) ;
259
+
260
+ try {
261
+ await c . env . BUCKET . put ( key , JSON . stringify ( data ) ) ;
262
+
263
+ const { results } = await updateTemplateStatement . bind ( name , id ) . run ( ) ;
264
+
265
+ return c . json ( response ( results ) ) ;
266
+ } catch ( e ) {
267
+ return c . json ( response ( null , e ) ) ;
268
+ }
269
+ } ) ;
270
+
271
+ interface Project {
272
+ id : string ;
273
+ userId : string ;
274
+ templateId : string ;
275
+ name : string ;
276
+ createdAt : number ;
277
+ updatedAt : number ;
278
+ deletedAt : number ;
279
+ } ;
280
+
281
+ type CreateProjectRequest = Pick < Project ,
282
+ | 'userId'
283
+ | 'templateId'
284
+ | 'name'
285
+ > ;
286
+
287
+ type FindProjectRequest = Pick < Project ,
288
+ | 'userId'
289
+ > ;
290
+
291
+ type UpdateProjectRequest = Pick < Project ,
292
+ | 'id'
293
+ | 'name'
294
+ > ;
295
+
296
+ app . post ( '/projects' , async ( c ) => {
297
+ const body = await c . req . json < CreateProjectRequest > ( ) ;
298
+
299
+ const createProjectStatement = c . env . DB . prepare ( `
300
+ INSERT INTO project (id, user_id, template_id, name, created_at)
301
+ VALUES (?1, ?2, ?3, ?4, ?5)
302
+ ` ) ;
303
+
304
+ const id = typeid ( 'proj' ) . toString ( ) ;
305
+
306
+ const result = createProjectStatement . bind ( id , body . userId , body . templateId , body . name , Date . now ( ) ) . run ( ) ;
307
+
308
+ return c . json ( response ( result ) ) ;
309
+ } ) ;
310
+
311
+ app . get ( '/projects' , async ( c ) => {
312
+ const { userId } = c . req . query ( ) as FindProjectRequest ;
313
+
314
+ const getProjectStatement = c . env . DB . prepare ( `
315
+ SELECT
316
+ p.id,
317
+ p.user_id 'userId',
318
+ p.template_id 'templateId',
319
+ p.created_at 'createdAt',
320
+ p.updated_at 'updatedAt'
321
+ FROM project as p
322
+ WHERE p.user_id = ?1 AND p.deleted_at NOT NULL
323
+ ` ) ;
324
+
325
+ const { results } = await getProjectStatement . bind ( userId ) . all < Project > ( ) ;
326
+
327
+ return c . json ( response ( results ) ) ;
328
+ } ) ;
329
+
330
+ app . patch ( '/projects' , async ( c ) => {
331
+ const body = await c . req . json < UpdateProjectRequest > ( ) ;
332
+
333
+ const updateProjectStatement = c . env . DB . prepare ( `
334
+ UPDATE project
335
+ SET name = ?1
336
+ WHERE id = ?2 AND deleted_at NOT NULL
337
+ ` ) ;
338
+
339
+ const { results } = await updateProjectStatement . bind ( body . name , body . id ) . run ( ) ;
340
+
341
+ return c . json ( response ( results ) ) ;
342
+ } ) ;
343
+
344
+ // interface Generate {
345
+ // id: string;
346
+ // projectId: string;
347
+ // key: string;
348
+ // args: string;
349
+ // createdAt: number;
350
+ // deletedAt: number;
351
+ // }
352
+
158
353
export default app ;
0 commit comments