···11+#!/bin/sh
22+33+SCHEMA=openapi.json
44+55+uv run openapi-python-client generate --overwrite --path ../server/build/$SCHEMA
+2-3
preprocessing/geocoding.typ
···7788#title()
991010-The following aims to fully describe the pre-processing some photo
1111-metadata to have information about a personal collection of photos to
1212-support the display in a gallery application.
1010+Deriving location context from photos with positional metadata.
1111+to support the display in a gallery application.
13121413This will cover functionality including:
1514- partitioning photos to ease the frontend data volume
···11+import type { AppBindings } from '@/types.ts'
22+import { OpenAPIHono } from '@hono/zod-openapi'
33+import { Scalar } from '@scalar/hono-api-reference'
44+import { pinoLogger } from 'hono-pino'
55+import pino from 'pino'
66+import pretty from 'pino-pretty'
77+import defaultHook from 'stoker/openapi/default-hook'
88+import openapiConfig from '@/openapi.config.ts'
99+import { PhotoAPI } from '@/src/common/app.ts'
1010+1111+function devTools(app: OpenAPIHono<AppBindings>) {
1212+ app.use(pinoLogger({
1313+ pino: pino(pretty()),
1414+ }))
1515+1616+ app.doc('/doc', openapiConfig)
1717+1818+ app.get(
1919+ '/reference',
2020+ Scalar({
2121+ url: '/doc',
2222+ }),
2323+ )
2424+}
2525+2626+const app = new OpenAPIHono<AppBindings>({
2727+ strict: false,
2828+ defaultHook,
2929+})
3030+devTools(app)
3131+3232+new PhotoAPI(app)
3333+ .configureRoutes()
3434+ .serve()
+11
server/runtimes/generate.ts
···11+import { PhotoAPI } from '@/src/app.ts'
22+import type { AppBindings } from '@/types.ts'
33+import { OpenAPIHono } from '@hono/zod-openapi'
44+import defaultHook from 'stoker/openapi/default-hook'
55+66+new PhotoAPI(new OpenAPIHono<AppBindings>({
77+ strict: false,
88+ defaultHook,
99+}))
1010+ .configureRoutes()
1111+ .writeOpenApiSpec('build/openapi.json')
+11
server/runtimes/main.ts
···11+import { PhotoAPI } from '@/src/app.ts'
22+import type { AppBindings } from '@/types.ts'
33+import { OpenAPIHono } from '@hono/zod-openapi'
44+import defaultHook from 'stoker/openapi/default-hook'
55+66+new PhotoAPI(new OpenAPIHono<AppBindings>({
77+ strict: false,
88+ defaultHook,
99+}))
1010+ .configureRoutes()
1111+ .serve()
+44
server/src/app.ts
···11+import type { OpenAPIHono } from '@hono/zod-openapi'
22+import type { AppBindings } from '@/types.ts'
33+44+import notFound from 'stoker/middlewares/not-found'
55+import onError from 'stoker/middlewares/on-error'
66+import openApiConf from '@/openapi.config.ts'
77+import { allAlbums, createAlbum } from './routes.ts'
88+99+export type App = Pick<OpenAPIHono<AppBindings>, 'openapi'>
1010+1111+interface Routing {
1212+ (r: (a: App) => App): PhotoAPI
1313+}
1414+1515+export class PhotoAPI {
1616+ private app: OpenAPIHono<AppBindings>
1717+1818+ constructor(app: OpenAPIHono<AppBindings>) {
1919+ this.app = app
2020+ }
2121+2222+ configureRoutes(): PhotoAPI {
2323+ return this
2424+ .addRoute(allAlbums)
2525+ .addRoute(createAlbum)
2626+ }
2727+2828+ private addRoute: Routing = (r) => {
2929+ this.app = r(this.app) as OpenAPIHono<AppBindings>
3030+ return this
3131+ }
3232+3333+ serve() {
3434+ Deno.serve(this.app
3535+ .notFound(notFound)
3636+ .onError(onError)
3737+ .fetch)
3838+ }
3939+4040+ writeOpenApiSpec(path: string) {
4141+ const doc = this.app.getOpenAPI31Document(openApiConf)
4242+ Deno.writeTextFileSync(path, JSON.stringify(doc, null, 2))
4343+ }
4444+}
+7
server/src/db/index.ts
···11+import { drizzle } from 'drizzle-orm/libsql'
22+import env from '@/env.ts'
33+import * as schema from './schema/index.ts'
44+55+const db = drizzle(env.DATABASE_URL, { schema })
66+77+export default db