diff --git a/package.json b/package.json index 6644939..56ec8ff 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,12 @@ "format": "prettier --write '**/*.{ts,js,css,json,md}'", "deploy": "wrangler publish", "dev": "wrangler dev", - "addsecret": "wrangler secret put WORKERLINKS_SECRET" + "addsecret": "wrangler secret put WORKERLINKS_SECRET", + "build": "wrangler publish --dry-run --outdir=./dist" }, "dependencies": { - "hono": "^3.0.2" + "hono": "^3.0.2", + "simple-runtypes": "^7.1.3" }, "devDependencies": { "@cloudflare/workers-types": "^4.20230228.0", diff --git a/src/index.ts b/src/index.ts index bdd13e0..fa4081c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import { Context, Hono } from 'hono' +import * as st from 'simple-runtypes' type Variables = { path: string @@ -12,9 +13,23 @@ type Bindings = { kv: KVNamespace } -type BulkUpload = { - [id: string]: string -} +const url = st.runtype((v) => { + const stringCheck = st.use(st.string(), v) + if (!stringCheck.ok) return stringCheck.error + + try { + new URL(stringCheck.result) + return stringCheck.result + } catch { + return st.createError('Must be a valid URL') + } +}) + +const bulkValidator = st.dictionary( + // Starting `/` and no ending `/` + st.string({ match: /^\/.*?[^\/]$/ }), + url, +) const app = new Hono<{ Variables: Variables; Bindings: Bindings }>() @@ -112,26 +127,18 @@ app.put('*', createLink) // add random key app.post('/', async (c) => { - const body = await c.req.text() + const rawBody = await c.req.text() - if (!body) { + if (!rawBody) { c.set('key', '/' + Math.random().toString(36).slice(5)) c.set('shortUrl', new URL(c.get('key'), c.req.url).toString()) return await createLink(c) } else { - // bulk upload from body + // Bulk upload from body - // REMOVE THIS when bulk upload has been migrated - - return c.json({ - code: '501 Not Implemented', - message: 'Bulk upload has not been reimplemented yet.', - }) - - // what type should this be??? - let json: any + let json: unknown try { - json = JSON.parse(body) + json = JSON.parse(rawBody) } catch { return c.json( { @@ -142,9 +149,8 @@ app.post('/', async (c) => { ) } - // change this - const valid = true //validateBulkBody(json); - if (!valid) { + const result = st.use(bulkValidator, json) + if (!result.ok) { return c.json( { code: '400 Bad Request', @@ -158,14 +164,14 @@ app.post('/', async (c) => { ) } - for (const [key, url] of json.entries) { + for (const [key, url] of Object.entries(result.result)) { await c.env.KV.put(key, url) } return Response.json( { message: 'URLs created successfully', - entries: Object.entries(json).map(([key, longurl]) => ({ + entries: Object.entries(result.result).map(([key, longurl]) => ({ key: key.slice(1), shorturl: new URL(key, c.req.url), longurl, diff --git a/yarn.lock b/yarn.lock index fc383b5..0a11e7e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -744,6 +744,11 @@ signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +simple-runtypes@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/simple-runtypes/-/simple-runtypes-7.1.3.tgz#0c9362016ae385995499e85c00dbd4fef3af9769" + integrity sha512-NDxAtKPHQplTyfdt2nAUuTV7RVwEBIRFZT7Z+g4eso5JGI5AwllpRcU9ibmxs+8vKKNrhebgK5zvCX3j8DoHhw== + source-map-support@^0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"