Overview
SAF uses OpenAPI to define and generate shared schemas and APIs across frontend and backend. This includes:
- API routes
- Business objects
- Product events
Packages using @saflib/openapi can generate:
- TypeScript types (
dist/openapi.d.tsand per-operation/schema fragments) - JSON schemas (
dist/openapi.json) for runtime validation
Use product/init to copy base into a new product. Use openapi/init to scaffold an offshoot spec (+ sibling *-test package). Use openapi/add-route, add-schema, and add-event to extend an existing spec.
The pkg: Extension
SAF extends OpenAPI to support linking schemas across NPM packages. This way an API spec can be split by domain and product/platform without relying on brittle relative paths.
Cross-package schema $refs can use a SAF pkg: convention resolved at generate time:
schema:
$ref: "pkg:@scope/product-offshoot-spec/openapi.yaml#/components/schemas/Widget"The most common use of this is the shared error object which lives in @saflib/openapi.
schema:
$ref: "pkg:@saflib/openapi/schemas/error.yaml"Package structure
Where a spec package lives in the product tree — {product}/service/spec, offshoot slices, and how http / sdk depend on it — is described in monorepo service layout. The golden reference implementation is saflib/base:
| Location | Package | Role |
|---|---|---|
base/service/spec | @saflib/base-spec | Product API contract |
base/service/test | @saflib/base-test | Shared schema factories for tests |
base/__offshoot-name__/spec | (offshoot spec) | Bounded feature slice; paths woven into the parent openapi.yaml |