UNPKG

alepha

Version:

Easy-to-use modern TypeScript framework for building many kind of applications.

334 lines (307 loc) 9.98 kB
import { $atom, type Static, z } from "alepha"; /** * Deployment target for the build output. * * - `docker` - Generate Dockerfile for containerized deployment * - `vercel` - Generate Vercel deployment configuration (forces node runtime) * - `cloudflare` - Generate Cloudflare Workers configuration (forces workerd runtime) */ export type BuildTarget = | "bare" | "docker" | "vercel" | "cloudflare" | "static"; /** * JavaScript runtime for the build output. * * - `node` - Node.js runtime (default) * - `bun` - Bun runtime (uses bun export conditions) * - `workerd` - Cloudflare Workers runtime (auto-set with cloudflare target) */ export type BuildRuntime = "node" | "bun" | "workerd"; /** * Build options atom for CLI build command. * * Defines the available build configuration options with their defaults. * Options can be overridden via alepha.config.ts or CLI flags. */ export const buildOptions = $atom({ name: "alepha.cli.build.options", description: "Build configuration options", schema: z.object({ /** * Generate build stats report. * * - `true` - Generate a static HTML report * - `"json"` - Generate a JSON report */ stats: z.union([z.boolean(), z.enum(["json"])]).optional(), /** * Deployment target for the build output. * * - `docker` - Generate Dockerfile for containerized deployment * - `vercel` - Generate Vercel deployment configuration (forces node runtime) * - `cloudflare` - Generate Cloudflare Workers configuration (forces workerd runtime) */ target: z .enum(["bare", "docker", "vercel", "cloudflare", "static"]) .optional(), /** * JavaScript runtime for the build output. * * - `node` - Node.js runtime (default) * - `bun` - Bun runtime (uses bun export conditions) * - `workerd` - Cloudflare Workers runtime (auto-set with cloudflare target) * * Note: Some targets force a specific runtime: * - `cloudflare` always uses `workerd` * - `vercel` always uses `node` */ runtime: z.enum(["node", "bun", "workerd"]).optional(), /** * Output directory configuration. */ output: z .object({ /** * Root dist directory. * * @default "dist" */ dist: z.string().default("dist").optional(), /** * Public/client subdirectory. * * @default "public" */ public: z.string().default("public").optional(), }) .optional(), /** * Vercel-specific deployment configuration. * * Note: Set `target: "vercel"` to enable Vercel deployment. * This object is only for additional configuration. */ vercel: z .object({ projectName: z.string().optional(), orgId: z.string().optional(), projectId: z.string().optional(), config: z .object({ crons: z .array( z.object({ path: z.string(), schedule: z.string(), }), ) .optional(), }) .optional(), }) .optional(), /** * Cloudflare-specific deployment configuration. * * Note: Set `target: "cloudflare"` to enable Cloudflare deployment. * This object is only for additional configuration. */ cloudflare: z .object({ config: z.json().optional(), }) .optional(), /** * Docker-specific deployment configuration. * * Note: Set `target: "docker"` to enable Docker deployment. * This object is only for additional configuration. */ docker: z .object({ /** * Base image for the Dockerfile (FROM instruction). * * @default "node:24-alpine" for node runtime * @default "oven/bun:alpine" for bun runtime */ from: z.string().optional(), /** * Command to run in the Docker container. * * @default "node" for node runtime * @default "bun" for bun runtime */ command: z.string().optional(), /** * Extra packages to install globally in the generated image. * * Each entry becomes a `RUN npm install --global --no-fund * --no-audit <pkg> …` line inserted after `FROM` and before the * app `COPY`. Use it for CLI tools the running app shells out to * — typical example is `wrangler` for a service that deploys to * Cloudflare on someone else's behalf. * * Ignored in `compile` mode (the distroless base has no `npm`). * * @example install: ["wrangler"] */ install: z.array(z.string()).optional(), /** * Docker build options (used when --image flag is passed). */ image: z .object({ /** * Default image tag (name without version). * * Used when --image is provided without a full override: * - `--image` → `tag:latest` * - `--image=1.3.4` → `tag:1.3.4` * - `--image=other/img:v1` → `other/img:v1` (full override) * * @example "myproject/myapp" * @example "ghcr.io/myorg/myapp" */ tag: z.string(), /** * Additional arguments to pass to `docker build`. * * @example '--platform linux/amd64 --no-cache' */ args: z.string().optional(), /** * Auto-add OCI standard labels (revision, created, version). * * Adds: * - org.opencontainers.image.revision (git commit SHA) * - org.opencontainers.image.created (build timestamp) * - org.opencontainers.image.version (from image tag) */ oci: z.boolean().optional(), }) .optional(), /** * Compile the server entry to a single static binary using * `bun build --compile`, then package it inside a minimal base image * (distroless by default). Requires `runtime: "bun"`. * * When enabled: * - the binary is produced at `<dist>/app` and the original `dist/server/`, * `dist/index.js` and `dist/package.json` are removed * - the generated Dockerfile uses a distroless base image and does not * run `bun install` (everything is embedded in the binary) * - any non-empty `dependencies` in the externals manifest causes the * task to fail loudly (compile requires fully-bundled output) * * Pass `true` to enable with defaults, or an object to override. */ compile: z .union([ z.boolean(), z.object({ /** * Bun target triple, e.g. `bun-linux-x64-musl`, * `bun-linux-arm64-musl`, or `bun-linux-x64-modern-musl` * (AVX2 required). * * @default derived from host arch — always linux-musl. */ target: z.string().optional(), /** * Base image for the generated Dockerfile. * * @default "gcr.io/distroless/static-debian12" */ base: z.string().optional(), /** * Minify the compiled output. * * @default true */ minify: z.boolean().optional(), }), ]) .optional(), }) .optional(), /** * Static site deployment configuration. * * Note: Set `target: "static"` to enable static site generation. */ static: z .object({ /** * Surge domain for deployment. * * If set, a CNAME file is written to dist/public/. * If not set, a domain is auto-generated from package.json name. * * @example "my-app.surge.sh" * @example "my-custom-domain.com" */ domain: z.string().optional(), }) .optional(), /** * PWA (Progressive Web App) configuration. * * Generates a web app manifest and enables installability. * Requires a client-side bundle (React). */ pwa: z .object({ /** * Full application name displayed on the splash screen * and in the OS app switcher. */ name: z.string(), /** * Short name displayed on the home screen icon. * Falls back to `name` if omitted. */ shortName: z.string().optional(), /** * Theme color used for the browser toolbar and OS chrome. * * @default "#ffffff" */ themeColor: z.string().optional(), /** * Background color for the splash screen. * * @default "#ffffff" */ backgroundColor: z.string().optional(), /** * Display mode for the installed PWA. * * - `standalone` - Looks like a native app (default) * - `fullscreen` - Uses entire screen (games, immersive) * - `minimal-ui` - Like standalone with minimal browser UI * - `browser` - Standard browser tab * * @default "standalone" */ display: z .enum(["standalone", "fullscreen", "minimal-ui", "browser"]) .optional(), /** * Enable offline support via service worker. * * TODO: Not yet implemented. */ offline: z.boolean().optional(), }) .optional(), }), default: {}, }); /** * Type for build options. */ export type BuildOptions = Static<typeof buildOptions.schema>;