End‑to‑end in one sitting: init → add → register → openapi → package → curl.
npx smoz init --yes
This scaffolds:
app/config/app.config.ts
— schemas/config (params, env, http tokens)app/functions/**
— endpoints (rest/http and non‑HTTP)app/generated/**
— registers + OpenAPI placeholderserverless.ts
— builds functions from the app registrynpx smoz add rest/foo/get
This creates:
app/functions/rest/hello/get/lambda.ts
— registration (method, basePath, schemas)app/functions/rest/hello/get/handler.ts
— business handlerapp/functions/rest/hello/get/openapi.ts
— OpenAPI operationOpen lambda.ts:
export const fn = app.defineFunction({
eventType: 'rest',
httpContexts: ['public'],
method: 'get',
basePath: 'hello',
contentType: 'application/json',
eventSchema: z.object({}).optional(),
responseSchema: z.object({ ok: z.boolean() }),
callerModuleUrl: import.meta.url,
endpointsRootAbs: /* app/functions/rest root */,
});
npx smoz register
This writes side‑effect files under app/generated/
:
register.functions.ts
— imports all lambda.ts
register.openapi.ts
— imports all openapi.ts
register.serverless.ts
— imports any per‑function serverless.ts
Tip: Commit the generated register.*.ts
so typecheck is stable.
npm run openapi
This imports register.openapi.ts
, collects paths via app.buildAllOpenApiPaths()
, and writes app/generated/openapi.json
.
Alternative: run a live loop that keeps registers/OpenAPI fresh and serves HTTP:
npx smoz dev --local inline
Use --local offline
to drive serverless-offline instead.
npm run package
Serverless picks up:
functions
from app.buildAllServerlessFunctions()
app.environment
app.stages
After you wire a dev endpoint or deploy, curl the route:
curl https://your-api/hello
Expected:
{ "ok": true }
SMOZ supports native {id}
path segments while keeping Windows‑safe folders:
rest/users/:id/get
, rest/users/{id}/get
, or rest/users/[id]/get
app/functions/rest/users/[id]/get/*
basePath: 'users/{id}'
id
For SQS/Step/etc., author the same way but skip HTTP options:
// lambda.ts (non‑HTTP)
export const fn = app.defineFunction({
eventType: 'sqs',
eventSchema: z.any(),
responseSchema: z.any().optional(),
callerModuleUrl: import.meta.url,
endpointsRootAbs: /* app/functions/sqs root */,
});
Attach platform events in a sibling serverless.ts
:
// serverless.ts (non‑HTTP extras)
import { fn } from './lambda';
fn.serverless([
{ sqs: { arn: 'arn:aws:sqs:us-east-1:123456789012:my-queue' } },
]);