### 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 (
```
```
--------------------------------
### 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 (
)
}
```
--------------------------------
### 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 (
)
}
```
--------------------------------
### 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 (
)
}
```
--------------------------------
### 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 (