v1.2.0 — Response Renderer Refinements
Changelog
All notable changes to the ApiTestSpark project are documented here.
The format is based on Keep a Changelog,
and this project adheres to Semantic Versioning.
Unreleased
v1.2.0 - 2026-06-02
Added
- Editable depth-1 nested objects — primitive fields inside nested response objects render as collapsible editable sub-forms (collapsed by default); edited values are merged back into the "Copy as JSON" output with correct type coercion. Arrays of objects inside nested objects render as read-only sortable tables; flat primitive arrays render as read-only JSON blocks.
- Copy as cURL in response panel — a "Copy as cURL" button appears in the response panel after each successful API call, generating the same cURL format already available on the request side. Captured at
onSuccesstime (not fire time) to guarantee the command always corresponds to the response shown. - Pretty / minified JSON toggle — raw JSON display contexts now offer a toggle between 2-space-indented (pretty) and single-line (minified) views. The active view is reflected when copying JSON. Toggle is absent on sortable table views.
- Session-persistent toggle preference — the pretty/minified preference persists across all API calls within the same browser session via
useHarnessConfigStore; resets to pretty-print on page reload. - JSONPath field tooltips — every field in the response form displays its dot-notation JSONPath address (
$.field,$.parent.field,$[*].col) as a hover/focus tooltip. Clicking the label copies the path to the clipboard. - 2-row table truncation — sortable tables (top-level and nested arrays of objects) show only the first 2 rows by default. A "Show all N items" control reveals the rest inline; "Show less" collapses back. Expanded state resets with each new API call.
buildCurlshared utility — extracted fromDebugPanel.tsxintosrc/utils/curlBuilder.ts; re-exported fromsrc/utils/index.ts. BothDebugPanel.tsxandEndpointTester.tsxnow share one authoritative cURL format.
Architectural Decisions
- ADR-005: Session-only UI preference stored in
useHarnessConfigStore— no new store, nopersistmiddleware - ADR-006:
buildCurlextracted tosrc/utils/curlBuilder.ts— single authoritative cURL format for request and response panels - ADR-007: Native
<details>/<summary>for collapsible nested object sections — zero JS, browser-native, matches existingLazyDetailspattern
Contributors
- Mark Hazleton
v1.1.0 - 2026-05-31
Added
EnableDemoIntegrationsoption — newboolproperty onApiTestSparkOptions(defaulttrue). Set tofalseto hide the built-in JokeAPI and JSONPlaceholder demo screens from the home page and disable their routes entirely, leaving only the Host API Explorer and API Doc Builder. Ideal for production or team installs where the sample integrations add noise.
Changed
ErrorCategorytype expanded — added'React'variant to theErrorCategoryunion ('Network' | 'API' | 'Configuration' | 'React' | 'Unknown').'React'is the correct category for unhandled render errors caught byErrorBoundary.ErrorRecord.categoryandErrorResponse.category— both fields now typed asErrorCategory(was loosely typed asstring). Eliminates an unsafeascast indebugStore.addError.ErrorBoundaryobservability —componentDidCatchnow usescategory: 'React'(was'Unknown') and routes exclusively throughuseDebugStore.addError(). The redundant directtrackException()call (which bypassed the debug panel) has been removed.addErroralready auto-forwards to App Insights viatrackCategorizedError.- Constitution v1.1.1 — three clarifications applied via full-repo review: §IV recognises
createRestCalleras a second valid client pattern; §V addsuseHarnessConfigStoreto the canonical store registry (non-persisted); §VI expandsErrorCategoryunion definition and documents the App Insights integration relationship.
Contributors
- Mark Hazleton
v1.0.2 - 2026-05-30
Fixed
- CSP blocking harness in Development — the
Content-Security-Policyheader on the SPA fallbackindex.htmlresponse now addsws://localhost:* ws://127.0.0.1:* http://localhost:* http://127.0.0.1:*toconnect-srcwhen the host app is running in theDevelopmentenvironment. This allows ASP.NET Core Browser Link and hot-reload WebSocket connections to succeed without being blocked. In non-Development environments the CSP is unchanged. The blank/empty harness page seen after upgrading to v1.0.1 in a Development project was caused by this CSP violation.
Contributors
- Mark Hazleton
v1.0.1 - 2026-05-30
Added
- API Doc Builder (
/api-docs): new screen that lets developers select endpoints, capture live curl commands and real HTTP responses, annotate sections with prose notes, then generate complete markdown documentation targeted at front-end developer agents — includes table of contents, parameters table, request body schema table, response codes table, and fenced curl + JSON response blocks - OpenAPI metadata renderer: full markdown renderer (
renderMarkdown.tsx) supporting**bold**,*italic*,`code`,## headings,- bullet lists,1. numbered lists,```fenced code blocks```, and| markdown tables | - operationId chip: copyable
operationIdbutton shown in the endpoint tester header — useful for SDK codegen and cross-referencing API docs - Response codes panel: all documented status codes shown as coloured badges (green 2xx, yellow 4xx, red 5xx); click a badge to expand the inline response schema
- Schema constraints in UI:
default,nullable,minimum/maximum,minLength/maxLengthfrom OpenAPI schema now shown in property tables and property chips; scaffold pre-fillsdefaultvalues - API info header:
info.contact.email(mailto link) andinfo.license(name + URL) now rendered in the HostApiScreen header - Accordion default-collapsed: endpoint list starts collapsed when 3+ namespaces are present; "expand all / collapse all" buttons appear in the search bar
- Relational seed data in SampleApi:
CustomergainsAddress(street/city/state/postal/country) andCompanyfields;ProductgainsCategory,Description,StockQuantity;OrderCacheseeded with 7 orders across all 5 customers covering everyOrderStatusvalue - New SampleApi endpoints:
GET /products/categories,GET /products/category/{cat},GET /orders/status/{status} - Tag-based accordion grouping: SampleApi endpoint tags changed to
"Products: Catalog","Customers: Accounts","Orders: Lifecycle"— feeds thesplitTag()accordion logic for clean three-level grouping - NuGet badges:
[]version and download count badges added to rootREADME.mdandApiTestSpark/README.md
Changed
- EndpointTester description rendering now uses the shared
renderMarkdownutility — fenced code blocks, markdown tables, and italic text in OpenAPI descriptions render correctly instead of as raw text buildJsonScaffold: priority order changed toexample → default → enum[0] → type placeholder; nested objects and arrays now recursively scaffolded; nullable strings scaffold asnullinstead of""openApiParser:defaultandnullableextracted from schemas;operationIdandrequestBodyDescriptionparsed from operations;info.licenseandcontact.emailextracted byparseApiInfo();nulltype in arrays normalised withnullable: trueflag- HostApiScreen empty state: shows full markdown-rendered API
info.descriptionwhen no endpoint is selected harnessConfigStore: gainsapiInfofield populated from the OpenAPIinfoblock after fetch
Fixed
Microsoft.OpenApiversion: upgraded from2.0.0to2.7.6(latest non-deprecated 2.x;3.xbreaks theMicrosoft.AspNetCore.OpenApi10.0.8 source generator)Microsoft.SourceLink.GitHub: updated to10.0.300
Contributors
- Mark Hazleton
v1.0.0 - 2026-05-30
Added
- Portable NuGet Harness:
MapApiTestSpark()extension onWebApplication— single-call registration embeds the React SPA into any .NET Minimal API project at/api-test-spark/ - Config endpoint:
GET /api-test-spark/configbridges host .NET options to the SPA (OpenAPI URL, auth scheme, default headers, base URL) - OpenAPI v3 autodiscovery: SPA fetches the host app's OpenAPI document on startup and renders discovered endpoints grouped by tag with operation summaries
ApiTestSparkOptions:OpenApiUrl,AuthScheme,DefaultHeaders,Environments,EnableVerboseLogging,CorsOrigins- Environment gating: restrict harness to specific environments (e.g.,
Developmentonly) - Built-in CORS support: no host
AddCors()required — controlled viaCorsOriginsoption - Content-Security-Policy headers on SPA fallback responses (includes App Insights
connect-src) EnableVerboseLoggingoption for per-asset debug output viaILogger- MSBuild targets:
BuildReactSpa(auto-build beforedotnet build),ValidateSpaAssets(guarddotnet packagainst emptybuild/) - Dual-build strategy:
VITE_BASE_PATHenv var produces standalone (/) and NuGet (/api-test-spark/) builds from one source - Smart response rendering: array → sortable table, object → editable form, other → raw pre block
$refresolution: full dereferencing including .NET 10 nullable wrapper (oneOf: [null, $ref])- Integration tests:
ApiTestSpark.Testswith MSTest +WebApplicationFactorycovering 200/404/SPA-fallback/config-shape/embedded-resource-prefix Microsoft.SourceLink.GitHubintegration — consumers can step through source in debugger.snupkgsymbol package published alongside the main package- Azure Application Insights integration via
@microsoft/applicationinsights-react-js - Route-level lazy loading for all screens
- Sample integrations: JokeAPI v2, JSONPlaceholder
Architectural Decisions
- ADR-001: Embedded Resource SPA serving via
EmbeddedFileProvider - ADR-002: Dual-build strategy via
VITE_BASE_PATHenvironment variable - ADR-003: Config endpoint as Minimal API
MapGet - ADR-004: Lightweight bespoke OpenAPI v3 parser (no third-party dependency)
Internal
- Initial project configuration: React 19, Vite 8, TypeScript 6, Zustand 5, TanStack Query 5, Tailwind CSS 4 (2026-05-18)
- API layer refactor:
createRestCallerfactory replacesApiClientsubclass pattern (2026-05-18) - Section config engine: single source of truth for all API metadata (2026-05-18)
- Performance: route-level lazy loading; build tools moved to devDependencies (2026-05-18)
- Config co-located with each section screen; Configuration nav link removed (2026-05-27)
- First NuGet package implementation as
WebSpark.ApiTestHarness; upgraded to .NET 10; xUnit → MSTest (2026-05-29) - Renamed from
WebSpark.ApiTestHarness/MapApiTestHarness//api-test-harness/toApiTestSpark/MapApiTestSpark//api-test-spark/(2026-05-30) - OpenAPI decorator enrichment, smart response rendering, SampleApi vertical slices (2026-05-30)
Contributors
- Mark Hazleton