### Cloudwerk Quick Start Project Setup Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/packages/cli/README.md A quick start guide to setting up a new Cloudwerk project. It covers creating a project directory, initializing npm, installing the CLI, creating a simple page, and starting the development server. ```bash # Create a new project mkdir my-app && cd my-app npm init -y npm install @cloudwerk/cli # Create a simple page mkdir -p app/routes echo 'export default () =>

Hello Cloudwerk!

' > app/routes/page.tsx # Start development npx cloudwerk dev ``` -------------------------------- ### Verify Cloudwerk Installation Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/getting-started/installation.mdx Starts the Cloudwerk development server to verify the installation. Requires the project to be set up and dependencies installed. ```bash pnpm dev ``` -------------------------------- ### Create Cloudwerk App and Install Dependencies Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/examples/blog.mdx Initializes a new Cloudwerk application with the Hono JSX renderer and installs necessary project dependencies using pnpm. ```bash pnpm dlx @cloudwerk/create-app blog --renderer hono-jsx cd blog pnpm install ``` -------------------------------- ### Manual Cloudwerk Installation - App Structure and Scripts Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/getting-started/installation.mdx Creates the application directory with a basic home page and adds essential scripts to `package.json` for development, building, and deployment. Requires Node.js 20+. ```bash mkdir -p app ``` ```tsx // app/page.tsx export default function HomePage() { return (

Welcome to Cloudwerk

Your full-stack framework for Cloudflare Workers.

); } ``` ```json { "scripts": { "dev": "cloudwerk dev", "build": "cloudwerk build", "deploy": "cloudwerk deploy" } } ``` -------------------------------- ### Manual Cloudwerk Installation - Project Initialization Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/getting-started/installation.mdx Initializes a new project directory and installs Cloudwerk core packages, CLI, UI, and Hono. Requires Node.js 20+ and pnpm. ```bash mkdir my-app && cd my-app pnpm init pnpm add @cloudwerk/core @cloudwerk/cli @cloudwerk/ui hono pnpm add -D wrangler typescript @types/node ``` -------------------------------- ### Create New Cloudwerk Project (pnpm) Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/getting-started/installation.mdx Creates a new Cloudwerk application using pnpm and starts the development server. Requires Node.js 20+ and pnpm. ```bash pnpm dlx @cloudwerk/create-app my-app cd my-app pnpm install pnpm dev ``` -------------------------------- ### Create New Cloudwerk Project (npm) Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/getting-started/installation.mdx Creates a new Cloudwerk application using npm and starts the development server. Requires Node.js 20+ and npm. ```bash npx @cloudwerk/create-app@latest my-app cd my-app npm install npm run dev ``` -------------------------------- ### Cloudwerk File-Based Routing Examples Source: https://context7.com/squirrelsoft-dev/cloudwerk/llms.txt Demonstrates how to define routes in Cloudwerk applications using file-based conventions within the `app/` directory. It includes examples for a root page, API routes with GET and POST methods, and dynamic routes that accept parameters. ```typescript // app/page.tsx - GET / export default function HomePage() { return (

Welcome to Cloudwerk

); } // app/api/users/route.ts - API route at /api/users import { json } from '@cloudwerk/core' export async function GET() { const users = await fetchUsers(); return json({ users }); } export async function POST(request: Request) { const body = await request.json(); const user = await createUser(body); return json({ user }, 201); } // app/users/[id]/page.tsx - Dynamic route at /users/:id export default function UserPage({ params }: { params: { id: string } }) { return

User {params.id}

; } ``` -------------------------------- ### Full CloudWerk Configuration Example Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/reference/cloudwerk-config.mdx A comprehensive example of a `cloudwerk.config.ts` file, demonstrating the setup for application directories, build options, database connections, authentication providers, queues, durable objects, triggers, and rendering. ```typescript // cloudwerk.config.ts import { defineConfig } from '@cloudwerk/core'; import type { Database } from './lib/db/schema'; export default defineConfig({ appDir: 'app', publicDir: 'public', outDir: '.cloudwerk', dev: { port: 8787, open: true, }, build: { minify: process.env.NODE_ENV === 'production', sourcemap: true, treeshake: true, }, database: { binding: 'DB', migrationsDir: 'migrations', schema: {} as Database, }, auth: { session: { storage: 'kv', namespace: 'SESSIONS', maxAge: 60 * 60 * 24 * 7, cookie: { name: 'session', httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'lax', }, }, providers: { github: { clientId: process.env.GITHUB_CLIENT_ID!, clientSecret: process.env.GITHUB_CLIENT_SECRET!, scopes: ['user:email'], }, }, }, queues: { EMAIL_QUEUE: { handler: './workers/email-queue.ts', }, }, durableObjects: { RATE_LIMITER: { class: './workers/rate-limiter.ts', className: 'RateLimiter', }, }, triggers: { handler: './workers/triggers.ts', }, rendering: { streaming: true, renderer: 'hono-jsx', }, }); ``` -------------------------------- ### Manual Cloudwerk Installation - Configuration Files Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/getting-started/installation.mdx Sets up the Cloudwerk configuration file (`cloudwerk.config.ts`) and TypeScript configuration (`tsconfig.json`) for a manual installation. Requires Node.js 20+. ```typescript // cloudwerk.config.ts import { defineConfig } from '@cloudwerk/core'; export default defineConfig({ // Your configuration options }); ``` ```json { "compilerOptions": { "target": "ES2022", "module": "ESNext", "moduleResolution": "bundler", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "jsx": "react_jsx", "jsxImportSource": "hono/jsx", "types": ["@cloudflare/workers-types"] }, "include": ["app/**/*", "cloudwerk.config.ts"], "exclude": ["node_modules"] } ``` -------------------------------- ### Create API Route in Cloudwerk (TypeScript) Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/getting-started/quick-start.mdx Implements an API route for handling HTTP requests in Cloudwerk. This example provides `GET` to retrieve posts and `POST` to create new posts. It utilizes `DB` binding and `json` helper from `@cloudwerk/core`. ```typescript // app/api/posts/route.ts import { DB } from '@cloudwerk/core/bindings' import { json } from '@cloudwerk/core' export async function GET() { const { results: posts } = await DB .prepare('SELECT * FROM posts ORDER BY created_at DESC') .all() return json(posts) } export async function POST(request: Request) { const body = await request.json() const id = crypto.randomUUID() await DB .prepare('INSERT INTO posts (id, title, content, created_at) VALUES (?, ?, ?, ?)') .bind(id, body.title, body.content, new Date().toISOString()) .run() return json({ id, title: body.title }, { status: 201 }) } ``` -------------------------------- ### Create Dynamic Routes in Cloudwerk (TypeScript/TSX) Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/getting-started/quick-start.mdx Shows how to create dynamic routes in Cloudwerk using bracket notation for route parameters. This example fetches and displays a single post based on its ID. It uses `params` from `@cloudwerk/core/context` and a `db` binding. ```tsx // app/posts/[id]/page.tsx import type { PageProps } from '@cloudwerk/core' import { NotFoundError } from '@cloudwerk/core' import { params } from '@cloudwerk/core/context' import { db } from '@cloudwerk/core/bindings' export async function loader() { const post = await db .prepare('SELECT id, title, content FROM posts WHERE id = ?') .bind(params.id) .first() if (!post) { throw new NotFoundError('Post not found') } return { post } } interface Props extends PageProps { post: { id: string; title: string; content: string } } export default function PostPage({ post }: Props) { return (

{post.title}

{post.content}
) } ``` -------------------------------- ### Create Cloudwerk App and Install Dependencies Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/examples/gallery.mdx Initializes a new Cloudwerk application with the Hono JSX renderer and installs the necessary `@cloudwerk/images` package for image handling functionalities. ```bash pnpm dlx @cloudwerk/create-app gallery --renderer hono-jsx cd gallery pnpm add @cloudwerk/images ``` -------------------------------- ### Install @cloudwerk/core Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/packages/core/README.md Installs the @cloudwerk/core package using npm. This is the first step to integrate the Cloudwerk framework into your project. ```bash npm install @cloudwerk/core ``` -------------------------------- ### Create Cloudwerk App and Install Dependencies Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/examples/linkly.mdx This snippet shows the commands to create a new Cloudwerk application with the 'hono-jsx' renderer and install the necessary project dependencies using pnpm. ```bash pnpm dlx @cloudwerk/create-app linkly --renderer hono-jsx cd linkly pnpm install ``` -------------------------------- ### Install @cloudwerk/utils Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/packages/utils/README.md Installs the @cloudwerk/utils package using npm. This package provides browser-safe utilities with no external dependencies. ```bash npm install @cloudwerk/utils ``` -------------------------------- ### Basic GET Request Handler with @cloudwerk/core Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/packages/core/README.md A basic example of a GET request handler for a dynamic route '/users/[id]'. It demonstrates fetching user data based on the ID parameter and returning a JSON response or a 404 if the user is not found. ```typescript // app/routes/users/[id]/route.ts import { json, notFoundResponse } from '@cloudwerk/core/runtime' import type { CloudwerkHandler } from '@cloudwerk/core/runtime' export const GET: CloudwerkHandler = async (request, { params }) => { const user = await getUser(params.id) if (!user) return notFoundResponse() return json(user) } ``` -------------------------------- ### Install @cloudwerk/vite-plugin and vite Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/packages/vite-plugin/README.md Installs the necessary packages for integrating Cloudwerk routing with Vite. This command uses npm to download and install the specified packages into your project's node_modules directory. ```bash npm install @cloudwerk/vite-plugin vite ``` -------------------------------- ### Image Transformer Example Configuration Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/images.mdx An example demonstrating how to configure the `createImageTransformer` with allowed origins, named presets (thumbnail, hero), and default transformations for format and quality. ```typescript // app/cdn/images/[...path]/route.ts import { createImageTransformer } from '@cloudwerk/images' export const GET = createImageTransformer({ allowedOrigins: ['https://images.mysite.com'], presets: { thumbnail: { width: 100, height: 100, fit: 'cover' }, hero: { width: 1920, height: 1080, fit: 'cover' }, }, defaults: { format: 'auto', quality: 85, }, }) ``` -------------------------------- ### React Component Example Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/guides/authentication/index.mdx Demonstrates how to use the `createAuthStore` to build a React component that displays authentication status and provides sign-in/sign-out functionality. ```APIDOC ## React Component Example ### Description This example shows a practical implementation of the `createAuthStore` within a React component to manage and display authentication status. It includes subscribing to state changes and conditionally rendering UI elements based on the user's logged-in status. ### Method Not applicable (React Component) ### Endpoint Not applicable (React Component) ### Parameters None ### Request Example ```tsx // components/AuthStatus.tsx 'use client' import { createAuthStore, signIn, signOut } from '@cloudwerk/auth/client' import { useEffect, useState } from 'react' const authStore = createAuthStore() export function AuthStatus() { const [session, setSession] = useState(authStore.getSession()) useEffect(() => { // Subscribe to auth changes (e.g., after sign-in/sign-out) return authStore.subscribe((state) => { setSession(state.session) }) }, []) if (!session) { return } return (
Welcome, {session.user.name}
) } ``` ### Response #### Success Response (200) N/A #### Response Example ```html
Welcome, John Doe
``` ``` -------------------------------- ### Add Middleware to Cloudwerk App (TypeScript) Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/getting-started/quick-start.mdx Defines middleware for a Cloudwerk application that runs before route handlers. This example measures and adds the response time to the headers. It requires the `Middleware` type from `@cloudwerk/core`. ```typescript // app/middleware.ts import type { Middleware } from '@cloudwerk/core'; export const middleware: Middleware = async (request, next) => { const start = Date.now(); // Run the route handler const response = await next(); // Add timing header const duration = Date.now() - start; response.headers.set('X-Response-Time', `${duration}ms`); return response; }; ``` -------------------------------- ### CloudWerk Service `onInit` Hook Example Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/services.mdx An example of the `onInit` lifecycle hook, which is executed once when the service is initialized. This is suitable for setting up connections or loading initial configurations. ```typescript hooks: { onInit: async () => { console.log('Service initialized') // Initialize connections, load config, etc. }, } ``` -------------------------------- ### Specify UI Renderer during Project Creation Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/getting-started/installation.mdx Creates a new Cloudwerk project and directly specifies the UI renderer (e.g., Hono JSX) to skip the interactive prompt. Requires Node.js 20+ and a package manager. ```bash npx @cloudwerk/create-app@latest my-app --renderer hono-jsx ``` -------------------------------- ### Logging Hook Example for Cloudwerk Services Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/guides/services.mdx This example demonstrates how to implement logging hooks (onBefore, onAfter, onError) within a Cloudwerk service. It logs method calls, results, and errors, and includes an example of reporting errors to an external tracking service. ```typescript export default defineService({ methods: { async processOrder(orderId: string) { // Business logic }, }, hooks: { onBefore: async (method, args) => { console.log(JSON.stringify({ service: 'orders', method, args, timestamp: Date.now(), })) }, onAfter: async (method, result) => { console.log(JSON.stringify({ service: 'orders', method, success: true, timestamp: Date.now(), })) }, onError: async (method, error) => { // Report to error tracking await fetch('https://errors.example.com/report', { method: 'POST', body: JSON.stringify({ service: 'orders', method, error: error.message, stack: error.stack, }), }) }, }, }) ``` -------------------------------- ### Complete CloudWerk Service Hooks Example Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/services.mdx A comprehensive example demonstrating the integration of all service lifecycle hooks (`onInit`, `onBefore`, `onAfter`, `onError`) within a CloudWerk service definition. This illustrates how to implement logging, tracking, and alerting. ```typescript export default defineService({ methods: { async processPayment(orderId: string, amount: number) { // Process payment logic return { success: true, transactionId: 'txn_123' } }, }, hooks: { onInit: async () => { console.log('Payment service ready') }, onBefore: async (method, args) => { console.log(JSON.stringify({ service: 'payments', method, args, timestamp: Date.now(), })) }, onAfter: async (method, result) => { await trackMetric('payment_processed', 1) }, onError: async (method, error) => { await alertOps(`Payment ${method} failed: ${error.message}`) }, }, }) ``` -------------------------------- ### Start Cloudwerk Development Server Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/packages/cli/README.md Starts the Cloudwerk development server with hot reload capabilities. It accepts options for port, host, config file path, and verbose logging. ```bash cloudwerk dev # With options: cloudwerk dev -p 8080 -H 0.0.0.0 --config ./cloudwerk.config.js --verbose ``` -------------------------------- ### Install CloudWerk Service Package Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/services.mdx Installs the @cloudwerk/service package using pnpm. This is the first step to using the service extraction system. ```bash pnpm add @cloudwerk/service ``` -------------------------------- ### Install @cloudwerk/ui Package Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/packages/ui/README.md Installs the core @cloudwerk/ui package using npm. For React support, additional React and ReactDOM packages are required. ```bash npm install @cloudwerk/ui ``` ```bash npm install @cloudwerk/ui react react-dom ``` -------------------------------- ### CloudWerk Configuration Example (TypeScript) Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/configuration.mdx A comprehensive example of a cloudwerk.config.ts file, demonstrating various configuration options such as app directory, public directory, output directory, development server settings, build optimizations, database configuration, authentication, queues, durable objects, triggers, and rendering. ```typescript // cloudwerk.config.ts import { defineConfig } from '@cloudwerk/core'; export default defineConfig({ appDir: 'app', publicDir: 'public', outDir: '.cloudwerk', dev: { port: 8787, open: true, }, build: { minify: true, sourcemap: true, treeshake: true, }, database: { binding: 'DB', migrationsDir: 'migrations', }, auth: { session: { storage: 'kv', namespace: 'SESSIONS', maxAge: 60 * 60 * 24 * 7, cookie: { name: 'session', httpOnly: true, secure: true, sameSite: 'lax', }, }, }, queues: { EMAIL_QUEUE: { handler: './workers/email-queue.ts', }, }, durableObjects: { RATE_LIMITER: { class: './workers/rate-limiter.ts', className: 'RateLimiter', }, }, triggers: { handler: './workers/triggers.ts', }, rendering: { streaming: true, renderer: 'hono-jsx', }, }); ``` -------------------------------- ### Testing Example with Mocking Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/triggers.mdx An example demonstrating how to test a trigger using Vitest, mocking events and context, and asserting handler behavior. ```typescript import { describe, it, expect, vi } from 'vitest' import { mockScheduledEvent, mockTriggerContext } from '@cloudwerk/trigger/testing' import trigger from './daily-cleanup' describe('daily-cleanup trigger', () => { it('should clean up expired records', async () => { const event = mockScheduledEvent({ cron: '0 0 * * *' }) const ctx = mockTriggerContext({ env: { DB: mockD1Database() }, }) await trigger.handle(event, ctx) expect(ctx.env.DB.prepare).toHaveBeenCalledWith( expect.stringContaining('DELETE FROM') ) }) }) ``` -------------------------------- ### Install @cloudwerk/queue Package Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/queues.mdx Installs the @cloudwerk/queue package using pnpm. This package is essential for setting up queue consumers. ```bash pnpm add @cloudwerk/queue ``` -------------------------------- ### Auth Middleware Examples using TypeScript Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/auth.mdx Illustrates practical usage of the `authMiddleware` with different configurations. Examples include setting up redirects for unauthenticated users, enforcing specific roles, and implementing custom authorization logic based on request details. ```typescript // Require authentication authMiddleware({ unauthenticatedRedirect: '/login', }) // Require specific role authMiddleware({ role: 'admin', unauthorizedRedirect: '/forbidden', }) // Custom authorization logic authMiddleware({ async authorize(user, request) { const url = new URL(request.url) const resourceId = url.pathname.split('/').pop() const resource = await getResource(resourceId) return resource.ownerId === user.id }, }) ``` -------------------------------- ### Install @cloudwerk/cli Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/packages/cli/README.md Installs the @cloudwerk/cli package using npm. This is the first step to using the Cloudwerk CLI for application development. ```bash npm install @cloudwerk/cli ``` -------------------------------- ### Install @cloudwerk/auth Package Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/auth.mdx Installs the @cloudwerk/auth package using the pnpm package manager. This is the first step to integrate the authentication system into your project. ```bash pnpm add @cloudwerk/auth ``` -------------------------------- ### Duration Format Example (Text) Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/guides/queues.mdx Illustrates the expected string format for specifying durations in Cloudwerk queue configurations. Examples include '30s' for 30 seconds, '5m' for 5 minutes, and '1h' for 1 hour. ```text '30s' → 30 seconds '5m' → 5 minutes '1h' → 1 hour ``` -------------------------------- ### Start Development Server with Cloudwerk CLI Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/cli.mdx Starts the Cloudwerk development server with hot reload capabilities. It accepts an optional path to the project and various options to configure the server port, host, configuration file, and logging verbosity. ```bash cloudwerk dev [path] [options] ``` ```bash # Start dev server cloudwerk dev # Custom port cloudwerk dev --port 3000 # All interfaces cloudwerk dev --host 0.0.0.0 # With custom config cloudwerk dev --config cloudwerk.staging.ts ``` -------------------------------- ### Build and Deploy Application Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/examples/linkly.mdx Commands to build the application, apply database migrations to production, and deploy to Cloudflare. Assumes pnpm is used as the package manager. ```bash pnpm build ``` ```bash wrangler d1 migrations apply linkly-db --remote ``` ```bash pnpm deploy ``` -------------------------------- ### Build Application (Bash) Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/examples/blog.mdx Builds the Cloudwerk application for production deployment. This process bundles server code, processes CSS with Tailwind, and pre-renders static pages, outputting the final assets to the 'dist/' directory. ```bash pnpm build ``` -------------------------------- ### Test API Route GET Request Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/testing.mdx Tests a basic GET request to an API route '/api/users'. It verifies the response status and checks for the presence of a 'users' property in the JSON response. Requires a test context setup. ```typescript // app/api/users/route.test.ts import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { createTestContext } from '@cloudwerk/testing'; describe('GET /api/users', () => { let ctx: TestContext; beforeAll(async () => { ctx = await createTestContext(); }); afterAll(async () => { await ctx.cleanup(); }); it('should return users', async () => { const response = await ctx.fetch('/api/users'); expect(response.status).toBe(200); const data = await response.json(); expect(data).toHaveProperty('users'); }); it('should require authentication', async () => { const response = await ctx.fetch('/api/users/me'); expect(response.status).toBe(401); }); }); ``` -------------------------------- ### Cloudflare Image Transformation Example Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/images.mdx An example demonstrating how to use the CloudflareImagesTransformBuilder to upload, transform, and output an image. It shows how to get an image binding, process a file from a form, apply transformations like resizing and rotation, and set output format and quality. ```typescript import { getBinding } from '@cloudwerk/core/bindings' import type { CloudflareImagesBinding } from '@cloudwerk/images' export async function POST(request: Request) { const IMAGES = getBinding('MY_IMAGES') const formData = await request.formData() const file = formData.get('image') as File // Transform the image const response = await IMAGES .input(await file.arrayBuffer()) .transform({ width: 800, rotate: 90 }) .output({ format: 'image/webp', quality: 85 }) .response() return response } ``` -------------------------------- ### Configure Cloudflare Bindings in wrangler.toml Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/examples/gallery.mdx Sets up R2 bucket and IMAGES bindings in the `wrangler.toml` file for image storage and on-the-fly transformations. It also includes necessary variables like account ID and hash, with a caution to manage the API token as a secret. ```toml name = "gallery" main = "dist/index.js" compatibility_date = "2024-09-23" compatibility_flags = ["nodejs_compat"] [assets] directory = "./dist/static" binding = "ASSETS" # R2 bucket for storing images [[r2_buckets]] binding = "GALLERY_BUCKET" bucket_name = "gallery-images" # IMAGES binding for on-the-fly transforms [images] binding = "IMAGES" [vars] CF_ACCOUNT_ID = "your-account-id" CF_ACCOUNT_HASH = "your-account-hash" # CF_IMAGES_TOKEN should be set as a secret, not here ``` -------------------------------- ### Key-Value Storage Operations Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/packages/durable-object/README.md Shows basic Key-Value storage operations within a Durable Object context. It includes examples for putting, getting, and deleting data using `ctx.storage`. ```typescript await ctx.storage.put('key', value) const value = await ctx.storage.get('key') await ctx.storage.delete('key') ``` -------------------------------- ### Create R2 Bucket (Bash) Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/examples/gallery.mdx Creates a new R2 bucket named 'gallery-images' using the Wrangler CLI. This is a prerequisite for storing images in R2. ```bash wrangler r2 bucket create gallery-images ``` -------------------------------- ### Manage Key-Value Preferences in TypeScript Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/guides/durable-objects.mdx Provides examples of managing user preferences using the built-in KV storage within a Durable Object. It covers setting, getting, listing, and clearing preferences. ```typescript export default defineDurableObject({ methods: { async setPreference(key: string, value: unknown) { await this.ctx.storage.put(`pref:${key}`, value) }, async getPreference(key: string) { return this.ctx.storage.get(`pref:${key}`) }, async getAllPreferences() { const prefs = await this.ctx.storage.list({ prefix: 'pref:' }) return Object.fromEntries(prefs) }, async clearPreferences() { const prefs = await this.ctx.storage.list({ prefix: 'pref:' }) for (const key of prefs.keys()) { await this.ctx.storage.delete(key) } }, }, }) ``` -------------------------------- ### Add Data Loading to Cloudwerk Page (TypeScript/TSX) Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/getting-started/quick-start.mdx Demonstrates how to implement server-side data fetching in a Cloudwerk page using the `loader()` function. It fetches posts from a database binding and displays them. Requires `@cloudwerk/core` and a `db` binding. ```tsx // app/page.tsx import type { PageProps } from '@cloudwerk/core' import { db } from '@cloudwerk/core/bindings' export async function loader() { const { results: posts } = await db .prepare('SELECT id, title, excerpt FROM posts ORDER BY created_at DESC LIMIT 10') .all() return { posts } } interface Props extends PageProps { posts: Array<{ id: string; title: string; excerpt: string }> } export default function HomePage({ posts }: Props) { return (

Latest Posts

) } ``` -------------------------------- ### Use D1 Database Binding in Cloudwerk Route Handler Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/guides/database.mdx TypeScript example for using the D1 database binding within a Cloudwerk API route handler (GET request). It demonstrates fetching user data and returning it as JSON. ```typescript // app/api/users/route.ts import { db } from '@cloudwerk/core/bindings' import { json } from '@cloudwerk/core' export async function GET() { const { results: users } = await db.prepare('SELECT * FROM users').all() return json(users) } ``` -------------------------------- ### Create Home Page with Post List - TypeScript/React Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/examples/blog.mdx Renders a list of all published blog posts. It fetches posts using a loader function and displays them using the PostCard component. This component is built with TypeScript and React for the Cloudwerk framework. ```tsx import type { PageProps, LoaderArgs } from '@cloudwerk/core' import { getPosts, type Post } from './lib/db' import PostCard from './components/PostCard' export async function loader(_args: LoaderArgs) { const posts = await getPosts() return { posts } } interface HomePageProps extends PageProps { posts: Post[] } export default function HomePage({ posts }: HomePageProps) { return (

My Blog

A personal blog built with Cloudwerk and Cloudflare Workers.

Latest Posts

{posts.length > 0 ? (
{posts.map((post) => ( ))}
) : (

No posts yet.

)})
) } ``` -------------------------------- ### Use D1 Database via Context in Cloudwerk Loader Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/guides/database.mdx TypeScript example showing how to access the D1 database binding through the `context.env.DB` property within a Cloudwerk loader function. This provides an alternative way to get the database instance. ```tsx import type { PageProps, LoaderArgs } from '@cloudwerk/core' export async function loader({ context }: LoaderArgs) { const db = context.env.DB const { results: users } = await db.prepare('SELECT * FROM users').all() return { users } } ``` -------------------------------- ### Define API Endpoints with route.ts (TypeScript) Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/guides/routing.mdx This snippet demonstrates how to create API endpoints using `route.ts` in Cloudwerk. It shows how to handle GET and POST requests, returning JSON responses. It relies on the `@cloudwerk/core` library for the `json` helper function. ```typescript // app/api/users/route.ts import { json } from '@cloudwerk/core'; export async function GET(request: Request, ctx: CloudwerkHandlerContext) { return json({ users: [] }); } export async function POST(request: Request, ctx: CloudwerkHandlerContext) { const body = await request.json(); return json({ created: body }, { status: 201 }); } ``` -------------------------------- ### Configure D1 Database Binding and Generate Types Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/examples/blog.mdx Sets up a D1 database binding named 'DB' for the blog application and generates TypeScript types for seamless integration with Cloudwerk's core bindings. ```bash npm run bindings add d1 npm run bindings generate-types ``` -------------------------------- ### Quick Start: Daily Cleanup Trigger Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/packages/trigger/README.md A basic example demonstrating how to define a scheduled trigger that runs daily at midnight to clean up expired sessions from a database. It utilizes the `defineTrigger` function and interacts with a D1 database via `ctx.env.DB`. ```typescript // app/triggers/daily-cleanup.ts import { defineTrigger } from '@cloudwerk/trigger' export default defineTrigger({ source: { type: 'scheduled', cron: '0 0 * * *', // Daily at midnight }, async handle(event, ctx) { await ctx.env.DB.exec('DELETE FROM sessions WHERE expires_at < datetime("now")') }, }) ``` -------------------------------- ### Importable Bindings Example Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/bindings.mdx Demonstrates how to import and use bindings directly within route handlers for direct access to Cloudflare services like D1 databases. ```APIDOC ## GET /api/posts ### Description Fetches all posts from the database using a direct D1 binding. ### Method GET ### Endpoint /api/posts ### Parameters #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **posts** (array) - An array of post objects retrieved from the database. #### Response Example ```json [ { "id": 1, "title": "First Post", "content": "This is the content of the first post." }, { "id": 2, "title": "Second Post", "content": "This is the content of the second post." } ] ``` ``` -------------------------------- ### Database Aggregations: Count and Group By in TypeScript Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/guides/database.mdx Provides examples of common database aggregation functions. The first snippet shows how to get a total count of records in a table. The second demonstrates grouping results by month and counting posts per month for a specific author, ordered by month. ```typescript const countResult = await db .prepare('SELECT COUNT(*) as count FROM users') .first(); const total = countResult?.count ?? 0; const { results: monthlyStats } = await db .prepare(` SELECT strftime('%Y-%m', created_at) as month, COUNT(*) as count FROM posts WHERE author_id = ? GROUP BY month ORDER BY month DESC `) .bind(userId) .all(); ``` -------------------------------- ### Create Cloudflare Resources (KV and D1) Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/guides/authentication/passkey-setup.mdx Commands to create the KV namespace and D1 database required for authentication. These resources need to be created before they can be bound in wrangler.toml. ```bash # Create KV namespace wrangler kv:namespace create AUTH_SESSIONS # Create D1 database wrangler d1 create my-app-db ``` -------------------------------- ### Install @cloudwerk/durable-object Package Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/durable-objects.mdx This command installs the @cloudwerk/durable-object package using pnpm. Ensure you have pnpm installed and configured in your project. ```bash pnpm add @cloudwerk/durable-object ``` -------------------------------- ### Implement Passkey Signup Form in React (TSX) Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/guides/authentication/passkey-setup.mdx This component handles the user signup process using Passkey authentication. It manages form state, interacts with backend APIs to get registration options, calls the WebAuthn API to create a new passkey, and verifies the credential with the server. It requires helper functions like `base64UrlToBuffer` and `bufferToBase64Url` which are assumed to be available in the environment. ```tsx // app/components/PasskeySignupForm.tsx 'use client' import { useState } from 'hono/jsx' export default function PasskeySignupForm() { const [name, setName] = useState('') const [email, setEmail] = useState('') const [error, setError] = useState(null) const [loading, setLoading] = useState(false) const handleSubmit = async (e: Event) => { e.preventDefault() setError(null) setLoading(true) try { // Step 1: Get registration options from server const optionsRes = await fetch('/auth/passkey/register/options', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: email.trim(), name: name.trim() }), credentials: 'include', }) if (!optionsRes.ok) { const err = await optionsRes.json().catch(() => ({})) throw new Error(err.error || 'Failed to get registration options') } const options = await optionsRes.json() // Step 2: Call WebAuthn API to create credential const credential = await navigator.credentials.create({ publicKey: { ...options, challenge: base64UrlToBuffer(options.challenge), user: { ...options.user, id: base64UrlToBuffer(options.user.id), }, excludeCredentials: options.excludeCredentials?.map((c) => ({ ...c, id: base64UrlToBuffer(c.id), })), }, }) as PublicKeyCredential | null if (!credential) { throw new Error('Passkey creation was cancelled') } const response = credential.response as AuthenticatorAttestationResponse // Step 3: Verify with server const verifyRes = await fetch('/auth/passkey/register/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ credential: { id: credential.id, rawId: bufferToBase64Url(credential.rawId), response: { clientDataJSON: bufferToBase64Url(response.clientDataJSON), attestationObject: bufferToBase64Url(response.attestationObject), transports: response.getTransports?.() ?? [], }, type: credential.type, }, userId: options.user.id, }), credentials: 'include', }) if (!verifyRes.ok) { const err = await verifyRes.json().catch(() => ({})) throw new Error(err.error || 'Registration failed') } // Success - redirect to dashboard window.location.href = '/dashboard' } catch (err) { setLoading(false) if (err instanceof Error) { if (err.name === 'NotAllowedError') { setError('Passkey creation was cancelled or not allowed') } else { setError(err.message) } } else { setError('An error occurred') } } } return (
{error &&
{error}
} setName(e.target.value)} placeholder="Jane Smith" /> setEmail(e.target.value)} placeholder="you@example.com" />
) } ``` -------------------------------- ### Create Signup Page with Passkey Form in React (TSX) Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/guides/authentication/passkey-setup.mdx This page component serves as the entry point for user signup. It checks for authentication status and redirects to the dashboard if the user is already logged in. Otherwise, it renders the `PasskeySignupForm` component and provides a link to the login page. ```tsx // app/signup/page.tsx import { isAuthenticated, redirect } from '@cloudwerk/auth' import PasskeySignupForm from '../components/PasskeySignupForm' export async function loader() { if (isAuthenticated()) { throw redirect('/dashboard') } return {} } export default function SignupPage() { return (

Create account

Already have an account? Sign in

) } ``` -------------------------------- ### Tail Consumer Example Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/guides/triggers.mdx An example of consuming logs from other Workers using the 'tail' source type. ```APIDOC ## Tail Consumer Consume logs from other Workers: ```typescript // app/triggers/error-alerter.ts import { defineTrigger } from '@cloudwerk/trigger' export default defineTrigger({ source: { type: 'tail', consumers: ['api-worker', 'background-worker'], }, async handle(event, ctx) { for (const log of event.logs) { if (log.level === 'error') { await notifyOncall({ worker: event.worker, message: log.message, timestamp: log.timestamp, }) } } }, }) ``` ``` -------------------------------- ### GET /api/users Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/reference/file-conventions.mdx Handles GET requests to the /api/users endpoint, typically used for retrieving a list of users. ```APIDOC ## GET /api/users ### Description Handles GET requests to the /api/users endpoint, typically used for retrieving a list of users. ### Method GET ### Endpoint `/api/users` ### Parameters #### Query Parameters None #### Request Body None ### Response #### Success Response (200) - **users** (array) - A list of user objects. #### Response Example ```json { "users": [ { "id": "1", "username": "user1" }, { "id": "2", "username": "user2" } ] } ``` ``` -------------------------------- ### Create First Cloudwerk Page (TypeScript/TSX) Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/getting-started/quick-start.mdx Defines the basic structure for a Cloudwerk page component using TypeScript and TSX. It renders a simple welcome message. No external dependencies are required for this basic structure. ```tsx // app/page.tsx export default function HomePage() { return (

Welcome to Cloudwerk

Your full-stack framework for Cloudflare Workers.

); } ``` -------------------------------- ### Install @cloudwerk/security Package Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/security.mdx Installs the @cloudwerk/security package using pnpm. This package provides various security middleware and utilities for Cloudwerk applications. ```bash pnpm add @cloudwerk/security ``` -------------------------------- ### Install @cloudwerk/trigger Package Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/triggers.mdx Installs the @cloudwerk/trigger package using pnpm. This package is essential for setting up event-driven handlers in your Cloudflare Workers. ```bash pnpm add @cloudwerk/trigger ``` -------------------------------- ### Apply D1 Database Migrations Locally Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/examples/linkly.mdx Command to apply the D1 database migrations locally. This ensures the database schema is up-to-date before running the application. ```bash wrangler d1 migrations apply linkly-db --local ``` -------------------------------- ### Install @cloudwerk/images Package Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/images.mdx Installs the @cloudwerk/images package using the pnpm package manager. This is the first step to integrate Cloudflare Images into your project. ```bash pnpm add @cloudwerk/images ``` -------------------------------- ### Interact with D1 Database using TypeScript Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/bindings.mdx Provides examples of how to query a D1 database using the `context.db` query builder, raw SQL prepared statements with bindings, and batching multiple queries. ```typescript // Query builder (recommended) const users = await context.db .selectFrom('users') .where('status', '=', 'active') .execute(); // Raw queries const result = await context.env.DB .prepare('SELECT * FROM users WHERE id = ?') .bind(userId) .first(); // Batch queries const results = await context.env.DB.batch([ context.env.DB.prepare('SELECT * FROM users'), context.env.DB.prepare('SELECT * FROM posts'), ]); ``` -------------------------------- ### Install Testing Dependencies Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/api/testing.mdx Installs Vitest and the Cloudflare Vitest pool for testing Cloudflare Workers. This is a prerequisite for setting up the testing environment. ```bash pnpm add -D vitest @cloudflare/vitest-pool-workers ``` -------------------------------- ### Create Post Detail Page with SSG - TypeScript/React Source: https://github.com/squirrelsoft-dev/cloudwerk/blob/main/apps/docs/src/content/docs/examples/blog.mdx Renders a single blog post's detail page using Static Site Generation (SSG). It fetches post data by slug, renders markdown content, and pre-renders pages at build time for fast loading. This utilizes Cloudwerk's SSG capabilities. ```tsx import type { PageProps, LoaderArgs } from '@cloudwerk/core' import { NotFoundError } from '@cloudwerk/core' import { raw } from 'hono/html' import { getPostBySlug, getAllSlugs, type Post } from '../../lib/db' import { renderMarkdown } from '../../lib/markdown' // Enable static site generation export const config = { rendering: 'static', } // Generate static paths for all posts export async function generateStaticParams() { const slugs = await getAllSlugs() return slugs.map((slug) => ({ slug })) } export async function loader({ params }: LoaderArgs) { const post = await getPostBySlug(params.slug) if (!post) { throw new NotFoundError(`Post not found: ${params.slug}`) } const html = renderMarkdown(post.content) return { post, html } } interface PostPageProps extends PageProps { post: Post html: string } export default function PostPage({ post, html }: PostPageProps) { const date = post.published_at ? new Date(post.published_at).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric', }) : null return (

{post.title}

{date && }
{raw(html)}
) } ```