chore: upgrade ajv from v6 to v8
- Dominant language
- TypeScript
- Stars
- 41
- Forks
- 24
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 56
Description
## 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
- **`dataPath` → `instancePath`.** 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.
Contributor guide
Research direction
Start with src/lib/ajv-validate.ts, src/config/schema.ts, ARCHITECTURE.md, and the documented AJV options. Run the listed AJV, cloud/root-ref, and factory tests to capture current path and message expectations. Done means direct AJV v8 usage is compatible, affected tests pass, and the architecture documentation and stale comment are updated.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli, documentation, testing-qa, tooling
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100