CI / frontend (push) Successful in 3m11s
CI / backend (push) Successful in 2m27s
CI / storybook-a11y (push) Successful in 9m28s
CI / e2e (push) Successful in 4m38s
CI / semgrep (push) Successful in 1m20s
CI / api-client-drift (push) Successful in 2m13s
Runnable `npm run gen:value-object` / `gen:form-machine` (plop) that scaffold the two
pure-TS house patterns with a co-located spec: a branded value object + parseX (mirrors
postcode/bsn), and an Elm-style form/wizard machine (Draft/Valid/Errors + Editing/
Submitting/Submitted/Failed union + initial/pure reduce/assertNever). Prompts take
context + PascalCase name (positional-arg bypass); a post-action reminds to add the
English target for the generated $localize id. Templates in plop-templates/ (prettier-
ignored). Skills (value-object, form-machine) point at the generators. ui-component +
bff-endpoint stay skill-driven (Angular {{}} / backend + gen:api).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
18 lines
762 B
Handlebars
18 lines
762 B
Handlebars
import { Brand, Result, ok, err } from '@shared/kernel/fp';
|
|
|
|
/**
|
|
* Value object: {{pascalCase name}}. "Parse, don't validate" — a {{pascalCase name}} is a
|
|
* distinct type from a raw string, mintable only via parse{{pascalCase name}}, so holding one
|
|
* is proof it is well-formed. Format-only check; the backend re-validates (ADR-0001).
|
|
*/
|
|
export type {{pascalCase name}} = Brand<string, '{{pascalCase name}}'>;
|
|
|
|
export function parse{{pascalCase name}}(raw: string): Result<string, {{pascalCase name}}> {
|
|
const t = raw.trim();
|
|
// TODO: replace with the real format rule for {{pascalCase name}}.
|
|
if (t.length === 0) {
|
|
return err($localize`:@@validation.{{camelCase name}}:Voer een geldige waarde in.`);
|
|
}
|
|
return ok(t as {{pascalCase name}});
|
|
}
|