Status: Draft
Repository: github.com/aerostackdev/open-function-spec
This specification defines the structural and behavioral requirements for a compliant Open Function Spec (OFS) module. A compliant module can be:
- Installed into any OFS-compatible project via the Aerostack CLI.
- Distributed through the Aerostack Registry or any private registry.
- Unit-tested in a standard Node.js environment without framework dependencies.
| Level | Files Required | Use Case |
|---|---|---|
| OFS-Full | schema.ts + core.ts + adapter.ts |
Feature with DB + HTTP route |
| OFS-Core | core.ts only |
Logic-only, no DB or HTTP |
| OFS-Utility | core.ts only, no db access |
Pure utility function |
OFS-Full:
<module-name>/
schema.ts
core.ts
adapter.ts
README.md
OFS-Utility:
<module-name>/
core.ts
README.md
- MUST use Drizzle ORM for all table definitions.
- MUST NOT contain application logic, HTTP routing, or imports from
core.ts/adapter.ts. - Column names MUST be
snake_case. TypeScript field names MUST becamelCasevia Drizzle mapping. - SHOULD export inferred TypeScript types:
export type T = typeof table.$inferSelect.
- MUST accept a
CoreContextobject as the first argument to all exported functions:interface CoreContext { db: DrizzleDB; env?: Record<string, string>; }
- MUST throw standard
Errorinstances for failures. - MUST return plain data objects.
// ❌ FORBIDDEN
import { Hono } from 'hono';
import { Request, Response } from '@cloudflare/workers-types';
return new Response(JSON.stringify(data));
process.env.STRIPE_KEY;
throw new HTTPException(400, { message: '...' });
// ✅ ALLOWED
import { eq } from 'drizzle-orm';
return rawData;
ctx.env.STRIPE_KEY;
throw new Error('Invalid input');A compliant core.ts MUST pass unit tests in Node.js 18+ with a mock CoreContext without any worker-specific setup.
- MUST only import and call functions from
./core. - MUST instantiate the DB client from the project's
createDb()factory per request. - MUST NOT contain any business logic.
- MUST export a named router/app.
- SHOULD catch
Errorfromcore.tsand map to appropriate HTTP status codes.
A compliant module's README.md MUST include:
- Short description of the module's purpose.
- Install command:
npx aerostack add <slug>. - Table of required environment variables with descriptions.
- List of API endpoints exposed by
adapter.ts. - List of database tables created by
schema.ts.
| Runtime | schema.ts client |
core.ts |
adapter.ts example |
|---|---|---|---|
| Cloudflare Workers | drizzle-orm/d1 |
✅ Required | Hono |
| Node.js 18+ | drizzle-orm/libsql or node-postgres |
✅ Required | Express |
| Bun | drizzle-orm/libsql |
✅ Required | Hono or Elysia |
| Deno | varies | ✅ Best-effort | — |
When published, a module is represented by the following manifest:
interface FunctionManifest {
id: string;
slug: string; // URL-safe identifier, e.g. "stripe-checkout"
name: string; // Human readable: "Stripe Checkout"
author: string; // Publisher's username
version: string; // Semver: "1.0.0"
type: 'feature' | 'utility';
category: string; // e.g. "payments", "auth", "storage"
routeExport?: string; // Export name from adapter.ts
routePath?: string; // Mount path: "/checkout"
drizzleSchema: boolean; // Whether module has a schema.ts
envVars: string[]; // Required env var names
npmDependencies: string[];// e.g. ["stripe", "zod"]
files: Array<{
path: string; // "schema.ts", "core.ts", "adapter.ts"
content: string; // Raw source code
}>;
}This specification follows semantic versioning:
- MAJOR: Breaking changes to the file structure or
CoreContextinterface. - MINOR: New optional rules or runtime support additions.
- PATCH: Clarifications and editorial changes.
Current version: 1.0.0-draft