String Format Overrides
@apical-ts/craft can replace the built-in handling of an OpenAPI
type: string + format combination with your own Zod schema.
This is useful when a format in your API represents a domain-specific value such as a tax code, customer ID, slug, or branded UUID that should be validated by a custom schema instead of the default string-format mapping.
CLI Syntax
Use the repeatable --format option:
npx @apical-ts/craft generate \
--client \
--server \
-i openapi.yaml \
-o generated \
--format <format>=<module-or-path>[#<export>]
Examples:
npx @apical-ts/craft generate \
--client \
--server \
-i openapi.yaml \
-o generated \
--format tax-code=./src/zod/TaxCode.ts \
--format uuid=@acme/domain-schemas#Uuid
<format>must match the OpenAPIformatvalue exactly<module-or-path>accepts package specifiers and explicit project paths#<export>is optional; when omitted,craftinfers the export name from the last module or path segment--formatcan be provided multiple times
Example
OpenAPI schema:
components:
schemas:
Profile:
type: object
properties:
fiscalCode:
type: string
format: tax-code
required:
- fiscalCode
paths:
/profiles/{taxCode}:
get:
operationId: getProfileByTaxCode
parameters:
- in: path
name: taxCode
required: true
schema:
type: string
format: tax-code
Custom Zod schema:
import * as z from "zod";
export const TaxCode = z.union([z.literal("TAX-001"), z.literal("TAX-002")]);
export type TaxCode = z.infer<typeof TaxCode>;
Generation command:
npx @apical-ts/craft generate \
--client \
--routes \
--server \
-i openapi.yaml \
-o generated \
--format tax-code=./src/zod/TaxCode.ts
What Gets Generated
When a field or parameter matches the configured format:
- The generated schema file imports your custom Zod schema.
- The matching property or parameter reuses that schema instead of the built-in string-format logic.
- The resulting type flows through generated schemas, routes, client operations, and server wrappers.
For the example above, both Profile.fiscalCode and the taxCode path
parameter will use TaxCode end-to-end.
Import Sources
You can import overrides from:
-
A package or module specifier
--format uuid=@acme/domain-schemas#Uuid -
A project path
--format tax-code=./src/zod/TaxCode.ts
If you omit #<export>, craft infers the export name automatically:
./src/zod/TaxCode.ts→TaxCode@acme/domain-schemas/Uuid→Uuid
Validation Rules
The CLI validates overrides before generation starts:
- duplicate mappings for the same format are rejected
- empty format names are rejected
- invalid export names are rejected
- an import target ending with
#is rejected - ambiguous mappings that would generate the same internal reference are rejected
Behavior Notes
- The override applies only to matching OpenAPI
type: stringformats - Once a mapping matches, the generated code delegates validation to your custom schema
- Built-in string-format constraints are not combined with the custom schema for that field