chore: typing audit, validator helpers, and stronger spec parity tests#10
Merged
chore: typing audit, validator helpers, and stronger spec parity tests#10
Conversation
Replace inline preprocessing functions in generate-zod.mjs with import from @devhelm/openapi-tools/preprocess. Adds missing flattenCircularOneOf step and fixes default-field skip logic. Made-with: Cursor
…rity tests Replace 14 hand-maintained enum arrays in zod-schemas.ts and schema.ts with imports from spec-facts.generated.ts, which is extracted from the OpenAPI spec during `npm run zodgen`. Add spec-field-parity.test.ts (39 tests) that verify every YAML field maps to an API request DTO field and vice versa, catching schema drift at compile time. Made-with: Cursor
Add 9 new parity tests (39→48) covering: - statusPageComponentDesiredSnapshot fields vs StatusPageComponentDto - statusPageGroupDesiredSnapshot fields vs StatusPageComponentGroupDto - StatusPageBranding bidirectional field check - EscalationStep fields (channels↔channelIds mapping) - MatchRule fields (monitorNames↔monitorIds mapping) Ensures API schema additions are caught at compile time before they cause silent drift in the reconciliation loop. Made-with: Cursor
- Add AuthMeResponseSchema and DashboardOverviewSchema with safeParse validation
- Remove all `{} as SomeDto` fallbacks — fail explicitly on empty responses
- Document checkedFetch trade-off (compile-time only, critical paths validated)
- Validate auth/me response for entitlement checks that gate deploy behavior
Made-with: Cursor
…BILITIES (END-1152)
The CLI keeps a few enum tuples that duplicate values from the OpenAPI
spec. Two clear consolidations were still outstanding:
1. ``COMPARISON_OPERATORS`` was hand-rolled in ``schema.ts`` and only
loosely typed (``readonly string[]``), even though the same enum is
inlined four times in ``api-zod.generated.ts`` (StatusCodeAssertion,
HeaderValueAssertion, JsonPathAssertion, ResponseSizeAssertion). If
the API ever added a comparison operator, the validator would silently
accept it without ever updating its error messages. Add
``COMPARISON_OPERATORS`` to ``generate-zod.mjs``'s spec-facts
extraction (sourced from StatusCodeAssertion.operator) and re-export
it from ``schema.ts`` so the validator and any future Zod consumers
get a single, spec-derived source of truth typed as a literal tuple.
2. ``STATUS_PAGE_VISIBILITIES`` was intentionally narrowed to
``['PUBLIC']`` (the API also accepts PASSWORD and IP_RESTRICTED, but
they are not yet wired to storage / enforcement). The narrowed tuple
was previously declared in **both** ``schema.ts`` and
``yaml/zod-schemas.ts`` independently — a future contributor flipping
one of them on (e.g. when PASSWORD ships) would silently desync the
validator from the Zod layer. Promote ``schema.ts``'s declaration to
``as const`` and derive ``StatusPageVisibility`` from it so the Zod
layer can re-import the same tuple (follow-up commit) instead of
redeclaring it.
Mechanical changes:
- ``scripts/generate-zod.mjs``: extend ``generateSpecFacts`` to extract
``COMPARISON_OPERATORS`` from ``StatusCodeAssertion.operator``.
- ``src/lib/spec-facts.generated.ts``: regenerated; now exports
``COMPARISON_OPERATORS`` as a typed tuple plus
``ComparisonOperators`` literal union.
- ``src/lib/yaml/schema.ts``:
* Import ``COMPARISON_OPERATORS`` from spec-facts and re-export it
alongside the other generated enum tuples.
* Drop the hand-rolled ``readonly string[]`` declaration so consumers
pick up the spec-derived literal tuple type.
* Convert ``STATUS_PAGE_VISIBILITIES`` to ``['PUBLIC'] as const`` and
derive ``StatusPageVisibility`` from the tuple, with a comment
explaining the intentional narrow vs the spec.
- ``src/lib/yaml/validator.ts``: cast ``COMPARISON_OPERATORS`` to
``readonly string[]`` at the call site for ``Array.includes`` because
it now has a literal-tuple element type rather than ``string``.
``npm run zodgen`` produces a stable diff (only the new
``COMPARISON_OPERATORS`` block); ``npm run typecheck`` and
``npm run lint`` are clean. Pre-existing failing tests in
``test/yaml/entitlements.test.ts`` are unrelated.
Made-with: Cursor
Batch of CLI quality / parity tickets cleaning up boilerplate, removing
the hand-rolled openapi.d.ts shim, and tightening the test suite.
- Drop the stale 11k-line src/types/openapi.d.ts; downstream commands now
import generated path types directly.
- Introduce src/lib/validators.ts with shared Zod-validator helpers used
by every command flag (URL / cron / Joi-style time windows / etc.).
- Refactor every command + the lib/{api-client,base-command,
crud-commands,resources}.ts surface to use the new validators and
consistent error wrapping; matching test/lib/ harness covers the new
helpers.
- yaml/: tighten parser / resolver / interpolation / state / transform /
zod-schemas.ts typing, expand applier + interpolation + spec-field
parity + entitlements + zod-schemas tests; entitlements helper now
builds full /auth/me responses so Zod validation passes.
- Switch to a flat-config eslint setup with a dedicated
tsconfig.eslint.json so test/ files type-check too.
- Update the version command to consume the spec-derived metadata and
refresh the contexts-file / full-stack fixture / version test data
to match.
Lint, typecheck (npm run typecheck), and the full vitest suite (846
tests) all pass locally.
Made-with: Cursor
…-tools The release / spec-check workflows were failing on every CI run with: Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@devhelm/openapi-tools' imported from scripts/generate-zod.mjs because the package was declared as ``file:../mini/packages/openapi-tools`` — that only ever resolves on the maintainer's workstation, where the mono repo happens to live one directory up. Vendor the same preprocessing logic into ``scripts/lib/preprocess.mjs`` (byte-for-byte identical to the upstream module) and drop the broken devDependency. The build is now self-contained and ``npm ci`` works on any clean checkout. Made-with: Cursor
API spec change makes RetryStrategy.maxRetries/interval and CreateEnvironmentRequest.isDefault required (they were always required at the API level — they're primitive int/boolean in Java DTOs). Update YAML schema and transformers to match. Refresh generated types/zod against the corrected monitoring-api.json (MonitorConfig polymorphism inlined). Made-with: Cursor
Mirrors the upstream @devhelm/openapi-tools changes so the CLI's vendored
preprocessing pipeline emits proper Zod discriminated unions for
polymorphic types (MonitorAuthConfig, CheckTypeDetailsDto in the public
surface) and strict objects everywhere.
scripts/lib/preprocess.mjs:
- Add inlineDiscriminatorSubtypesWithInfo that merges parent properties
into each subtype, replaces the discriminator field with z.literal,
drops the allOf back-reference, then rewrites the parent itself as a
oneOf+discriminator union.
- Add rewriteUnionsAsDiscriminated post-processor that swaps z.union
for z.discriminatedUnion when members match a known subtype set.
- preprocessSpec now returns { flattened, inlinedDiscriminators } so the
caller can drive the post-process.
scripts/generate-zod.mjs:
- Pass additionalPropertiesDefaultValue: false to openapi-zod-client so
generated objects no longer carry .passthrough() (zaps the noisy
`unknown` widening that broke YAML validator narrowing).
- Wire the post-processor into the generated source.
Refresh docs/openapi/monitoring-api.json from the upstream public spec
and regenerate src/lib/api-zod.generated.ts. lint, typecheck, and the
full vitest suite (846 tests) pass.
Made-with: Cursor
…nions
Port the `inlineNullableDeductionRefs` preprocessor pass from the mono
repo so `UpdateMonitorRequest.config` (a `@Nullable MonitorConfig`)
resolves to a proper `z.union([...]).nullable()` instead of an empty
object that silently strips the entire config body.
Also:
- Enable `strictObjects: true` in openapi-zod-client so union resolution
picks the correct subtype rather than matching the first partial fit
and stripping extras (the TCP `{host,port}` → IcmpMonitorConfig bug).
- Widen `enumsFrom` in generate-zod.mjs to pick up enum values from
direct `items.enum` on array-typed properties (e.g.
`DnsMonitorConfig.recordTypes`), so `DNS_RECORD_TYPES` no longer
generates a `WARNING: enum not found in spec` comment that breaks
the downstream import in `yaml/schema.ts`.
- Refresh vendored spec + regenerate Zod + TS types.
Made-with: Cursor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Batch of CLI quality / parity tickets cleaning up boilerplate, removing the hand-rolled
openapi.d.tsshim, and tightening the test suite.src/types/openapi.d.ts; downstream commands now import generated path types directly.src/lib/validators.tswith shared Zod-validator helpers used by every command flag (URL / cron / time-window / etc.).lib/{api-client,base-command,crud-commands,resources}.tssurface to use the new validators and consistent error wrapping; matchingtest/lib/harness covers the new helpers.yaml/: tighten parser / resolver / interpolation / state / transform / zod-schemas.ts typing; expand applier + interpolation + spec-field parity + entitlements + zod-schemas tests; entitlements helper now builds full/auth/meresponses so Zod validation passes.tsconfig.eslint.jsonsotest/files type-check too.versioncommand + contexts-file / full-stack fixture / version test data.Test plan
npm run lintnpm run typechecknpm test(846 tests pass)mono#246runsmake test-surface SURFACE=cliagainst this branch)Made with Cursor