Skip to content

chore: upgrade ajv from v6 to v8 #505

Description

@JoshMock

Summary

ajv is pinned to ^6.14.0 (src/lib/ajv-validate.ts). The pin is deliberate and documented in ARCHITECTURE.md → "AJV Validation" plus the ponytail: comment at src/lib/ajv-validate.ts:69-73. This issue proposes taking the v8 upgrade as its own scoped change.

Benefits

  • Native draft 2020-12 support. @elastic/schemas output declares $schema, which validateWithJsonSchema() currently strips because ajv@6 doesn't understand it. v8 can compile these schemas as authored.
  • Possible deletion of ~90 lines. src/config/schema.ts hand-rolls a strip* family (stripAuth, stripServiceBlock, stripCommandPolicy, stripContext) to reconstruct typed objects from known fields only. The file's own comment cites an ajv@6 mutation bug inside oneOf branches as the reason additionalProperties: false + removeAdditional: true can't be used. If v8 fixes that, the helpers go away.
  • Actively maintained line. v6 receives no feature work; v8 gets the keyword/format fixes and perf work.

Risks

  • dataPathinstancePath. v8 replaces v6's dataPath with a JSON Pointer (/tags/0/name vs .tags[0].name). tokenizePath() parses the v6 syntax specifically, and every consumer of ValidationError.path / path_array / the (root) sentinel is affected — including formatValidationErrors() output users see.
  • Constructor options change meaning. unknownFormats: 'ignore' is gone in v8 (replaced by an explicit formats allowlist / ajv-formats). validateSchema: false and strict behave differently, and useDefaults gains array-item semantics. validateSchema: false is load-bearing: @elastic/schemas output contains cosmetic meta-schema violations (e.g. nullable enums with a repeated null) that would otherwise throw at compile time.
  • Error messages and keyword names shift. enrichMessage(), deduplicateUnionErrors() (which matches the literal string should match some schema in anyOf), and the not-keyword remap in src/config/schema.ts all pattern-match on v6 output.
  • Test baselines. test/lib/ajv-validate.test.ts, test/lib/ajv-validate-real-schemas.test.ts, test/cloud/root-ref.test.ts, and test/factory.test.ts assert on paths and messages that will change.
  • Duplicate copies in the tree. eslint@10 depends on ajv@6, and @cli-schema/spec already pulls ajv@8.20.0. Upgrading the direct dependency won't dedupe v6 out; it just makes the direct usage v8.

Suggested scope

  1. Swap dataPath parsing for instancePath (JSON Pointer) in tokenizePath().
  2. Re-derive the getAjv() options block against v8 semantics; decide on ajv-formats vs. an explicit formats allowlist.
  3. Re-baseline path/message assertions in the tests above.
  4. Re-test whether removeAdditional works inside oneOf and, if so, delete the strip* helpers in src/config/schema.ts.
  5. Update ARCHITECTURE.md (both the "AJV Validation" section and the dependency table row) and drop the now-stale ponytail: comment.

No behavior change is intended for users beyond error-message wording, which should be reviewed as part of the change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions