Files
pad/internal/urlimport
xarmian 8771f95ab2 feat(urlimport): OpenAPI 3.x → Markdown converter (TASK-1471) (#555)
* feat(urlimport): OpenAPI 3.x → Markdown converter (TASK-1471)

Adds ConvertOpenAPI to internal/urlimport — the "openapi" branch of
the v1 importer. Built on pb33f/libopenapi.

Layout:
  - H1 with the API title + version + description
  - Contact + License lines
  - Servers list
  - Endpoints section grouped by primary tag (or "Other" for the
    untagged). Per operation: `METHOD /path` heading, summary,
    description, deprecation marker, operation ID, parameter table,
    request-body summary (with media-type fences and YAML-rendered
    example), and response code table.
  - Schemas section with component schemas as Property/Type/Required/
    Description tables, schema names sorted for stable output.

Scope:
  - OpenAPI 3.x only. Swagger 2.0 detection returns an explicit
    "only 3.x" error so the import endpoint (TASK-1472) can fall
    through to the generic converter.
  - Recoverable libopenapi build errors (unresolved refs, etc.) are
    swallowed when the model is still produced — partial spec >
    no output.

Tests:
  - testdata/petstore-openapi.yaml — full v3 fixture: tags, params,
    requestBody example, deprecated op, ref-typed schema array, two
    component schemas with required-field markers.
  - TestConvertOpenAPI_Petstore — 30+ markdown-substring assertions
    on the rendered output.
  - TestConvertOpenAPI_RejectsSwagger2 — explicit v2 error.
  - TestConvertOpenAPI_RejectsGarbage — non-spec input.
  - TestConvertOpenAPI_MinimalSpec — empty paths short-circuits.
  - Helpers: schemaTypeBrief(nil), escapeTableCell, singleLine.

Dependency: github.com/pb33f/libopenapi v0.36.3 (MIT-licensed).

Parent: PLAN-1467.

* fix(urlimport): merge path-level + operation-level parameters per Codex review (round 1)

MEDIUM: OpenAPI path-item-level parameters apply to every operation
on the path. Previously only slot.op.Parameters was rendered, so
common specs that hoist a shared {id} parameter to the path-item
level emitted operations with the path parameter missing from the
docs.

Now opSlot carries item.Parameters as pathParams, and a new
mergeParameters helper produces the spec-conformant union:
- Path-level parameters first, in declared order.
- Operation-level parameters with matching (name, in) override the
  path-level entry in place.
- Operation-only parameters appended after.

Tests:
- TestConvertOpenAPI_PathLevelParametersMerged — inline fixture
  with a path-level widgetId + trace and an operation-level trace
  override + fields op-only param. Asserts widgetId survives, trace
  shows op-level (required=yes), no duplicate path-level trace row,
  fields appears.
- TestMergeParameters_EmptyInputs — nil/nil short-circuit.

* fix(urlimport): no double-backticks on array-of-ref schema types per Codex review (round 2)

MEDIUM: schemaTypeBrief() previously wrapped refs in inline backticks
("`Pet`"). For array-of-ref schemas the brief became "array of `Pet`",
and the table-cell call site (codeOrBlank) then wrapped the entire
value in another pair, producing broken markdown like
"`array of `Pet``". Schema properties whose type is an array of a
component schema are a normal OpenAPI shape — `Litter.pets: array of
Pet` — so this would have hit real specs immediately.

Fixes:
- schemaTypeBrief now returns plain text — ref names without
  surrounding backticks. Docstring updated to make the contract
  explicit ("never contains backticks; caller wraps").
- codeOrBlank strips any stray backticks from input before wrapping
  so the resulting cell always carries exactly one balanced pair.
  Defensive: the contract from schemaTypeBrief is plain text now,
  but stray backticks from any future caller can't corrupt the
  table.

Tests added:
- TestConvertOpenAPI_ArrayOfRefTypeCell — inline spec with a
  `Litter.pets: array of Pet` property. Asserts the type cell is
  exactly `` `array of Pet` `` and no malformed variants leak.
- TestCodeOrBlank — 7-case table covering empty, plain, whitespace,
  pre-backticked, embedded-backtick, and backtick-only inputs.
2026-05-15 00:24:14 -04:00
..