Skip to content

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 01 Sep 18:49
· 78 commits to master since this release
85b947c
  • Reject inconsistent path parameters at compile time: every in: path
    parameter must be required: true and have a {placeholder} in the
    effective path template, and every placeholder must have a path parameter
    after path-level/operation-level merge ($ref-ed parameters included).
    Previously such documents compiled and surfaced as a repeating runtime
    violation; now they throw InvalidContract with the spec pointer.
  • Define PSR-7 body semantics: validation never consumes the caller's stream.
    Seekable bodies have their position restored in finally on every path;
    non-seekable bodies are refused before reading with the stable codes
    request.body.non_seekable/response.body.non_seekable; bodies beyond the
    1 MiB Contract::MAX_MESSAGE_BODY_BYTES budget yield
    request.body.too_large/response.body.too_large.
  • Add ValidationResultFormatter: deterministic, bounded human-readable
    rendering of a complete ValidationResult (operation, code, location,
    instance path, spec pointer, truncated expected/actual). ContractViolation
    uses it for its message; the structured Violation list stays the primary
    API.
  • Validate application/x-www-form-urlencoded request bodies: the wire body
    is parsed as ordered pairs (no parse_str() bracket rewriting) with the
    form-style/Encoding Object semantics of ParameterCodec, then the body
    schema applies to the decoded value.
  • Validate multipart/form-data request bodies with a bounded parser:
    quoted/unquoted boundaries, per-part headers, JSON/text/binary parts,
    repeated parts for arrays, per-property contentType/Encoding Object;
    budgets of 128 parts and 16 KiB of headers per part on top of the shared
    body budget. The default part Content-Type follows OAS 3: text/plain for
    primitives, application/octet-stream for binary strings,
    application/json for objects, and for arrays the default of the item
    type. Malformed framing, a part whose content type disagrees with the
    declared/default one, and budget overflow fail closed with stable
    request.body.* codes.
  • Add Contract::validateResponse(string $operationKey, ResponseInterface $response):
    standalone response validation keyed by operation identity, using the same
    exact → NXX → default selection and the same violations as
    validateExchange(); an unknown key yields response.operation.unknown.
  • Add Operation::responseFor(int $status): the Response Object a concrete
    status resolves to (key and definition) through the same exact →
    NXX → default selection, or null when the status is not declared —
    for response generators that must not copy the selector.
  • Resolve relative $refs to sibling JSON/YAML files through
    Contract::fromFile() (fromArray()/fromJson() stay same-document only).
    The entry file's directory is the trusted root; absolute paths, URI schemes,
    protocol-relative //, percent-encoded forms, backslashes, traversal and
    symlink escapes are rejected before any read. Graph-wide budgets: 64 files
    and the shared 10 MiB byte budget in addition to the ref-depth/node budgets;
    each file is parsed once. Errors carry root-relative paths and the raw
    pointer, never host paths.
  • Model the full server URL: Operation::$servers (scheme/host/port/
    base, operation > path > root precedence, server-variable defaults
    substituted at compile time). Operation::$serverBases remains as the v0.1
    base-path projection. Matching an absolute server now requires agreement on
    every URI component the request actually carries (normalized scheme,
    case-insensitive host, effective port with 80/443 defaults); a relative
    server or a path-only request URI stays host-agnostic. A declared path whose
    server authority disagrees reports request.server.mismatch (spec pointer
    /servers) instead of request.operation.unknown. Undeclared variables,
    missing/non-enum defaults, unsupported schemes, bare relative paths,
    userinfo/query/fragment in a server URL fail compilation.
  • Preserve parameter-level example/examples in the compiled model
    ($refs resolved, present exactly when declared, a non-map examples fails
    compilation). Validation ignores them; they feed the generator's
    deterministic example phase in rasuvaeff/property-testing-openapi. The
    compiled parameter shape is published as the CompiledParameter psalm type
    on Operation.
  • Dev: differential corpus against cebe/php-openapi (require-dev only)
    for the multi-file resolver under tests/fixtures/cebe-differential/, with
    the two pinned divergences documented (cebe hangs on a cross-file cycle and
    inlines a 41-hop chain; this package fails closed at its depth budget).
  • Internal: compilation extracted from the Contract constructor into
    Internal\Compilation\DocumentCompiler; shared MessageReading for both
    validators; dead matching paths removed. No public API change from these.