Compare commits

...

3 Commits

Author SHA1 Message Date
c527a6eac5 docs: expand README with detailed setup, tech stack, development, and project structure. 2025-12-17 06:52:58 -05:00
f16ac80b7e chore: remove unnecessary env scripts
since `wrangler types` works as intended now
2025-12-17 06:52:44 -05:00
cd04a75b06 feat: remove Docker-related files and configuration 2025-12-17 06:43:36 -05:00
6 changed files with 67 additions and 154 deletions

View File

@@ -1,16 +0,0 @@
node_modules
Dockerfile*
docker-compose*
.dockerignore
.git
.gitignore
README.md
LICENSE
.vscode
Makefile
helm-charts
.env
.dev.vars
.editorconfig
.idea
coverage*

View File

@@ -1,41 +0,0 @@
# use the official Bun image
# see all versions at https://hub.docker.com/r/oven/bun/tags
FROM oven/bun:1 as base
WORKDIR /usr/app
# install dependencies into temp directory
# this will cache them and speed up future builds
FROM base AS install
RUN mkdir -p /tmp/dev
COPY package.json bun.lockb /tmp/dev/
RUN cd /tmp/dev && bun install --frozen-lockfile
# install with --production (exclude devDependencies)
RUN mkdir -p /tmp/prod
COPY package.json bun.lockb /tmp/prod/
RUN cd /tmp/prod && bun install --frozen-lockfile --production
# copy node_modules from temp directory
# then copy all (non-ignored) project files into the image
FROM base AS prerelease
COPY --from=install /tmp/dev/node_modules node_modules
COPY . .
# [optional] tests & build
ENV NODE_ENV=production
RUN bun test
RUN bun build --compile src/index.ts --outfile=aniplay
# copy production dependencies and source code into final image
FROM base AS release
COPY --from=install /tmp/prod/node_modules node_modules
COPY --from=prerelease /usr/app/src ./src
COPY --from=prerelease /usr/app/package.json .
COPY --from=prerelease /usr/app/tsconfig.json .
# TODO: uncomment once v2 is ready
# COPY --from=prerelease /usr/app/drizzle.config.ts .
# run the app
USER bun
EXPOSE 3000
ENTRYPOINT [ "bun", "run", "prod:server" ]

View File

@@ -1,12 +1,71 @@
``` # Aniplay API
npm install
npm run dev
```
``` API for [Aniplay](https://github.com/silverAndroid/aniplay), built with Cloudflare Workers, Hono, and Drizzle ORM.
npm run deploy
``` ## Tech Stack
- **Cloudflare Workers**: Serverless execution environment.
- **Hono**: Ultrafast web framework (OpenAPI).
- **GraphQL**: Used internally for communicating with the [AniList](https://anilist.co) API.
- **Drizzle ORM**: TypeScript ORM for D1 (Cloudflare's serverless SQL database).
- **Vitest**: Testing framework.
## Prerequisites
- **Node.js**
- **pnpm**: Package manager.
## Getting Started
1. **Installation**
```bash
pnpm install
```
2. **Environment Setup**
Generate the environment types:
```bash
pnpm exec wrangler types
```
3. **Database Setup**
Apply migrations to the local D1 database:
```bash
pnpm exec wrangler d1 migrations apply aniplay
```
## Development ## Development
If a route is internal-only or doesn't need to appear on the OpenAPI spec (that's autogenerated by Hono), use the `Hono` class. Otherwise, use the `OpenAPIHono` class from `@hono/zod-openapi`. ### Running Locally
Start the development server:
```bash
pnpm run dev
```
### Testing
Run the tests using Vitest:
```bash
pnpm test
```
## Deployment
Deploy to Cloudflare Workers:
```bash
pnpm run deploy
```
## Project Structure
- `src/controllers`: API route handlers (titles, episodes, search, etc.)
- `src/libs`: Shared utilities and logic (AniList integration, background tasks)
- `src/models`: Database schema and models
- `src/scripts`: Utility scripts for maintenance and setup
- `src/types`: TypeScript type definitions

View File

@@ -7,8 +7,6 @@
"scripts": { "scripts": {
"dev": "wrangler dev src/index.ts --port 8080", "dev": "wrangler dev src/index.ts --port 8080",
"deploy": "wrangler deploy --minify src/index.ts", "deploy": "wrangler deploy --minify src/index.ts",
"env:generate": "tsx src/scripts/generateEnv.ts",
"env:verify": "tsx src/scripts/verifyEnv.ts",
"db:generate": "drizzle-kit generate", "db:generate": "drizzle-kit generate",
"db:migrate": "drizzle-kit migrate", "db:migrate": "drizzle-kit migrate",
"test": "vitest", "test": "vitest",

View File

@@ -1,47 +0,0 @@
import { Project } from "ts-morph";
import { $ } from "zx";
import { logStep } from "~/libs/logStep";
await logStep(
'Re-generating "env.d.ts"',
() => $`wrangler types src/types/env.d.ts`.quiet(),
"Generated env.d.ts",
);
const secretNames = await logStep(
"Fetching secrets from Cloudflare",
async (): Promise<string[]> => {
const { stdout } = await $`wrangler secret list`.quiet();
return JSON.parse(stdout.toString()).map(
(secret: { name: string; type: "secret_text" }) => secret.name,
);
},
"Fetched secrets",
);
const project = new Project({});
const envSourceFile = project.addSourceFileAtPath("src/types/env.d.ts");
envSourceFile.insertImportDeclaration(2, {
isTypeOnly: true,
moduleSpecifier: "hono",
namedImports: ["Env as HonoEnv"],
});
envSourceFile
.getInterfaceOrThrow("Env")
.addExtends(["HonoEnv", "Record<string, unknown>"]);
envSourceFile.getInterfaceOrThrow("Env").addProperties(
secretNames.map((name) => ({
name,
type: `string`,
})),
);
await project.save();
await logStep(
"Formatting env.d.ts",
() => $`prettier --write src/types/env.d.ts`.quiet(),
"Formatted env.d.ts",
);

View File

@@ -1,40 +0,0 @@
import { readFile } from "fs/promises";
import { $, sleep } from "zx";
import { logStep } from "~/libs/logStep";
await $`cp src/types/env.d.ts /tmp/env.d.ts`.quiet();
await logStep(
'Generating "env.d.ts"',
// @ts-ignore
() => import("./generateEnv"),
"Generated env.d.ts",
);
await logStep("Comparing env.d.ts", async () => {
function filterComments(content: Buffer) {
return content
.toString()
.split("\n")
.filter((line) => !line.trim().startsWith("//"))
.join("\n");
}
const currentFileContent = filterComments(await readFile("/tmp/env.d.ts"));
const generatedFileContent = filterComments(
await readFile("src/types/env.d.ts"),
);
if (currentFileContent === generatedFileContent) {
console.log("env.d.ts is up to date");
return;
}
const isCI = process.env["IS_CI"] === "true";
const vcsCommand = isCI ? "git" : "sl";
await $`${vcsCommand} diff src/types/env.d.ts`.stdio("inherit");
// add 1 second to make sure spawn completes
await sleep(1000);
throw new Error("env.d.ts is out of date");
});