@devxcommerce/bff-types
v2.1.0
Published
Cross-brand TypeScript types — shared by every BFF, every web app, and future mobile clients. Holds only types that have the same shape across all brands; brand-specific types live in `apps/<brand>/types/` (see [ADR-0016](../../docs/adr/0016-brand-scoped-
Readme
@devxcommerce/bff-types
Cross-brand TypeScript types — shared by every BFF, every web app, and future mobile clients. Holds only types that have the same shape across all brands; brand-specific types live in apps/<brand>/types/ (see ADR-0016).
Envelope decision: ADR-0014. Field-by-field schema:
docs/reference/response-envelope.md.
What's here
ApiResponse<T>— discriminated union of{ data, meta }(2xx) and{ error, meta }(4xx/5xx). Every/api/*route returns one.ApiMeta—request_idalways;cache,refreshed_at,warnings,paginationconditional.ApiError—{ code, message, details? }for non-2xx responses.ApiWarning— one degraded-but-recoverable sub-fetch (e.g. Shopify timed out on 1 of 12 embedded products). Surfaced inmeta.warnings[]under ADR-0014's permissive partial-success rule.ApiPagination—{ cursor, has_more, page_size, total? }. Cursor is opaque to clients (ADR-0014).
Using it
import type {
ApiResponse, ApiMeta, ApiError, ApiWarning, ApiPagination,
CacheStatus,
} from '@devxcommerce/bff-types'Paired with per-brand response types from @devxcommerce/<brand>-types on the consumer side:
import type { ApiResponse } from '@devxcommerce/bff-types'
import type { ProductResponse } from '@devxcommerce/avimee-types'
const res: ApiResponse<ProductResponse> = await fetch('/api/product/serum').then(r => r.json())Why this package exists separately
ApiResponse<T> has the same shape for every brand, every route. Putting it in any one brand's types package would be wrong — every other brand would have to depend on that brand. Keeping it here means each brand's types package depends on this one (unidirectional), and there's zero cross-brand coupling.
Constraints
Dependency-free on purpose — imported by Bun (BFF), Next.js (web), and future mobile targets. No runtime behaviour; just TypeScript.
cd packages/types
bun run typecheck