Releases: markhazleton/ApiTestSpark
Release list
v1.8.0
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.8.0] - 2026-06-21
Added
- Optional harness auth gate — new
RequireAuthenticatedUseroption onApiTestSparkOptions. When enabled, all routes under/api-test-sparkrequire an authenticated user, including SPA assets,/api-test-spark/config,/api-test-spark/remote-spec, and/api-test-spark/remote-call. - Server-side proxy correlation tokens — proxied remote calls now resolve
{request-guid}and{session-guid}tokens inRemoteDefaultHeaderson the server before forwarding requests.
Changed
- Fail-fast CI frontend gate — GitHub workflows now run
npm run verify(lint + typecheck + build) before .NET build/test and publish steps. - Config endpoint CORS cache safety — responses that emit
Access-Control-Allow-Originnow also emitVary: Origin.
Fixed
- Remote spec proxy resource management —
HttpResponseMessageis now properly disposed after proxy reads;ConfigureAwait(false)added throughout; response body is buffered viaArrayPoolfor efficient memory use. - Endpoint list sticky header overlap — the first namespace group header no longer visually overlaps the first endpoint item in the list (
sticky top-9corrected tosticky top-0). - Rendering cleanup — minor UI rendering fixes across the host API explorer.
Migration Notes
- To enforce auth on the embedded harness in any environment, set
options.RequireAuthenticatedUser = truein yourMapApiTestSpark(...)configuration. - If your server-proxied remote profiles use correlation headers, you can now safely use
{request-guid}and{session-guid}inRemoteDefaultHeadersand expect per-request server-side expansion.
Contributors
- Mark Hazleton
[v1.7.0] - 2026-06-21
Added
- Server-side remote call proxy — new
EnableRemoteCallProxyoption routes endpoint calls for server-configured remote API profiles throughGET /api-test-spark/remote-call, avoiding browser CORS requirements while keeping server-held credentials out of the browser. - Expanded identity-aware config payload —
/api-test-spark/confignow returns resolveduserName,userEmail, anduserIdvalues, and configured host/remote headers can expand{user-name},{user-email}, and{user-id}tokens.
Changed
- Remote profile management model — Program.cs server profiles now remain authoritative, while browser customization creates distinct local copies instead of overriding the proxied server entry.
- Frontend bootstrap and build hygiene — host runtime config is separated from remote-profile hydration, and Vite now suppresses the known Application Insights pure-annotation warning so release builds stay actionable.
Fixed
- Remote explorer CORS regression — stale browser profiles can no longer shadow server-configured profiles and force browser-direct OpenAPI fetches that bypass the proxy.
- Required path parameter validation — host and remote endpoint testers now block requests with missing required path parameters and surface inline validation before sending malformed URLs.
Breaking Changes
None. This release is backwards-compatible and the new remote call proxy is opt-in.
Contributors
- Mark Hazleton
[v1.6.0] - 2026-06-20
Added
- User-name token expansion — profiles and request templates now expand
{userName}tokens at request time, enabling personalized header and body content for multi-user environments. - SampleApi publish package — added a dedicated SampleApi publish output package for simplified deployment workflows.
Fixed
- CSP logo rendering — resolved Content Security Policy violations preventing inline logo rendering in the harness UI.
- Base-path build-info fetches — fixed fetch requests for build metadata when the app is deployed at a non-root base path (e.g.,
/api-test-spark/).
Changed
- Package reference updates — upgraded Microsoft.AspNetCore.OpenApi and Microsoft.OpenApi to the latest stable versions for improved OpenAPI v3 compatibility and maintenance.
- Make Bold branding metadata — aligned branding icons and metadata across all delivered assets for consistent product identity.
Breaking Changes
None. This is a fully backwards-compatible patch release.
Contributors
- Mark Hazleton
[v1.5.0] - 2026-06-12
Changed
- Make Bold Solutions brand alignment — refreshed the embedded React UI with the Make Bold Spark product family, Make Bold Solutions ownership, brand colors, Inter Tight typography, updated header/home/footer treatments, and consistent red/black/gray accent states across the app.
- Favicon and visual assets — generated a multi-size
favicon.ico, refreshed PNG favicons, added local Make Bold Solutions logo/font assets to the SPA build, and regenerated the NuGet package icon from the brand asset. - NuGet package identity — updated NuGet authors, company, copyright, title, description, tags, repository casing, package README, root README, packaging walkthrough, and license attribution to consistently present API Test Spark as a Make Bold Spark product owned and managed by Make Bold Solutions.
Breaking Changes
None. This release does not change the public .NET API surface or runtime configuration model.
Contributors
- Mark Hazleton
[v1.4.0] - 2026-06-09
Added
- Remote API Profiles — the remote API experience now supports a collection of named profiles instead of one global remote target. Each profile has a stable id, name, description, base URL, OpenAPI URL, credentials, and profile-scoped headers.
- Program.cs multi-profile defaults — host apps can seed multiple remote APIs with
RemoteApiProfiles. The legacy single-remote options remain supported and seed one compatibility profile when no profile collection is configured. - Browser profile management — the Config page can add, edit, delete, hide, reset, and persist browser-managed remote API profiles. New browser profiles receive GUID ids, and duplicate visible names are blocked with a clear validation alert before save.
- Profile-specific explorer and documentation routes — the home screen, Remote API Explorer, and Remote API Doc Builder now render one entry per visible profile using each profile's name and description.
- Server-profile-only remote spec proxy —
GET /api-test-spark/remote-spec?profileId=...resolves only server-provided profile ids. Browser-created profiles fetch OpenAPI documents directly from the browser, preventing browser-submitted URLs from driving server-side fetches. - Credential redaction for server profiles — server-provided API key values and bearer tokens are no longer serialized in
/api-test-spark/config; configured flags tell the browser that credentials exist without exposing values.
Changed
- Remote configuration persistence — existing single-remote browser configuration migrates into one GUID-backed profile where feasible, while hidden server profile ids and browser overrides preserve the prior reload-surviving behavior.
- SampleApi demo content — the demo app now documents the remote profile model, server-default personalization, duplicate-name validation, and profile-specific API/documentation sections.
Breaking Changes
None. The new RemoteApiProfiles collection and RemoteApiProfile model are additive. Existing RemoteBaseUrl, RemoteOpenApiUrl, RemoteOpenApiApiKeyHeader, RemoteOpenApiApiKeyValue, RemoteOpenApiBearerToken, and RemoteDefaultHeaders options remain supported for this release.
Contributors
- Mark Hazleton
[v1.3.0] - 2026-06-06
Added
- Remote API Explorer — a new screen (
/remote-api) that loads, browses, and tests endpoints from a remote OpenAPI JSON document. The remote URL, API key, and Bearer token are configured viaMapApiTestSpark()inProgram.csand are editable on the Config page. - Remote spec proxy —
GET /api-test-spark/remote-specis a new .NET endpoint that fetches the remote OpenAPI document server-side. API key and Bearer token are injected at the proxy level; credentials never appear in the browser network tab or DevTools. - SSRF guard — the proxy validates that
RemoteOpenApiUrluseshttp://orhttps://and rejects all other schemes (file://,ldap://, etc.) with a400response. ApiTestSparkOptionsadditions — four new properties:RemoteBaseUrl,RemoteOpenApiUrl,RemoteOpenApiApiKeyHeader,RemoteOpenApiApiKeyValue,RemoteOpenApiBearerToken, andRemoteDefaultHeaders(dictionary of headers injected into every browser-side request to the remote API).- Remote API Doc Builder — captures live remote endpoint calls and exports markdown documentation, mirroring the host API Doc Builder.
- Config page — Remote API section — dedicated configuration panel for all remote API settings; credential fields are masked (password inputs) by default.
- Header token expansion — header values support
{session-guid}(one UUID per page load) and{request-guid}(fresh UUID per call), expanded at request-send time. Works for both default headers and per-request extra headers. - Harness version and build date —
GET /api-test-spark/confignow includesharnessVersion(NuGet package version) andharnessBuiltAt(ISO-8601 assembly build timestamp); displayed on the About page. useRemoteConfigStore— new dedicated Zustand persist store (keyapi-test-spark-remote-config) holding all remote API configuration. Reads live inuseHostApiso Config page saves take effect immediately without page reload.- CSP auto-extension —
RemoteBaseUrlis automatically added toContent-Security-Policy connect-src, allo...
v1.7.0
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.7.0] - 2026-06-21
Added
- Server-side remote call proxy — new
EnableRemoteCallProxyoption routes endpoint calls for server-configured remote API profiles throughGET /api-test-spark/remote-call, avoiding browser CORS requirements while keeping server-held credentials out of the browser. - Expanded identity-aware config payload —
/api-test-spark/confignow returns resolveduserName,userEmail, anduserIdvalues, and configured host/remote headers can expand{user-name},{user-email}, and{user-id}tokens.
Changed
- Remote profile management model — Program.cs server profiles now remain authoritative, while browser customization creates distinct local copies instead of overriding the proxied server entry.
- Frontend bootstrap and build hygiene — host runtime config is separated from remote-profile hydration, and Vite now suppresses the known Application Insights pure-annotation warning so release builds stay actionable.
Fixed
- Remote explorer CORS regression — stale browser profiles can no longer shadow server-configured profiles and force browser-direct OpenAPI fetches that bypass the proxy.
- Required path parameter validation — host and remote endpoint testers now block requests with missing required path parameters and surface inline validation before sending malformed URLs.
Breaking Changes
None. This release is backwards-compatible and the new remote call proxy is opt-in.
Contributors
- Mark Hazleton
[v1.6.0] - 2026-06-20
Added
- User-name token expansion — profiles and request templates now expand
{userName}tokens at request time, enabling personalized header and body content for multi-user environments. - SampleApi publish package — added a dedicated SampleApi publish output package for simplified deployment workflows.
Fixed
- CSP logo rendering — resolved Content Security Policy violations preventing inline logo rendering in the harness UI.
- Base-path build-info fetches — fixed fetch requests for build metadata when the app is deployed at a non-root base path (e.g.,
/api-test-spark/).
Changed
- Package reference updates — upgraded Microsoft.AspNetCore.OpenApi and Microsoft.OpenApi to the latest stable versions for improved OpenAPI v3 compatibility and maintenance.
- Make Bold branding metadata — aligned branding icons and metadata across all delivered assets for consistent product identity.
Breaking Changes
None. This is a fully backwards-compatible patch release.
Contributors
- Mark Hazleton
[v1.5.0] - 2026-06-12
Changed
- Make Bold Solutions brand alignment — refreshed the embedded React UI with the Make Bold Spark product family, Make Bold Solutions ownership, brand colors, Inter Tight typography, updated header/home/footer treatments, and consistent red/black/gray accent states across the app.
- Favicon and visual assets — generated a multi-size
favicon.ico, refreshed PNG favicons, added local Make Bold Solutions logo/font assets to the SPA build, and regenerated the NuGet package icon from the brand asset. - NuGet package identity — updated NuGet authors, company, copyright, title, description, tags, repository casing, package README, root README, packaging walkthrough, and license attribution to consistently present API Test Spark as a Make Bold Spark product owned and managed by Make Bold Solutions.
Breaking Changes
None. This release does not change the public .NET API surface or runtime configuration model.
Contributors
- Mark Hazleton
[v1.4.0] - 2026-06-09
Added
- Remote API Profiles — the remote API experience now supports a collection of named profiles instead of one global remote target. Each profile has a stable id, name, description, base URL, OpenAPI URL, credentials, and profile-scoped headers.
- Program.cs multi-profile defaults — host apps can seed multiple remote APIs with
RemoteApiProfiles. The legacy single-remote options remain supported and seed one compatibility profile when no profile collection is configured. - Browser profile management — the Config page can add, edit, delete, hide, reset, and persist browser-managed remote API profiles. New browser profiles receive GUID ids, and duplicate visible names are blocked with a clear validation alert before save.
- Profile-specific explorer and documentation routes — the home screen, Remote API Explorer, and Remote API Doc Builder now render one entry per visible profile using each profile's name and description.
- Server-profile-only remote spec proxy —
GET /api-test-spark/remote-spec?profileId=...resolves only server-provided profile ids. Browser-created profiles fetch OpenAPI documents directly from the browser, preventing browser-submitted URLs from driving server-side fetches. - Credential redaction for server profiles — server-provided API key values and bearer tokens are no longer serialized in
/api-test-spark/config; configured flags tell the browser that credentials exist without exposing values.
Changed
- Remote configuration persistence — existing single-remote browser configuration migrates into one GUID-backed profile where feasible, while hidden server profile ids and browser overrides preserve the prior reload-surviving behavior.
- SampleApi demo content — the demo app now documents the remote profile model, server-default personalization, duplicate-name validation, and profile-specific API/documentation sections.
Breaking Changes
None. The new RemoteApiProfiles collection and RemoteApiProfile model are additive. Existing RemoteBaseUrl, RemoteOpenApiUrl, RemoteOpenApiApiKeyHeader, RemoteOpenApiApiKeyValue, RemoteOpenApiBearerToken, and RemoteDefaultHeaders options remain supported for this release.
Contributors
- Mark Hazleton
[v1.3.0] - 2026-06-06
Added
- Remote API Explorer — a new screen (
/remote-api) that loads, browses, and tests endpoints from a remote OpenAPI JSON document. The remote URL, API key, and Bearer token are configured viaMapApiTestSpark()inProgram.csand are editable on the Config page. - Remote spec proxy —
GET /api-test-spark/remote-specis a new .NET endpoint that fetches the remote OpenAPI document server-side. API key and Bearer token are injected at the proxy level; credentials never appear in the browser network tab or DevTools. - SSRF guard — the proxy validates that
RemoteOpenApiUrluseshttp://orhttps://and rejects all other schemes (file://,ldap://, etc.) with a400response. ApiTestSparkOptionsadditions — four new properties:RemoteBaseUrl,RemoteOpenApiUrl,RemoteOpenApiApiKeyHeader,RemoteOpenApiApiKeyValue,RemoteOpenApiBearerToken, andRemoteDefaultHeaders(dictionary of headers injected into every browser-side request to the remote API).- Remote API Doc Builder — captures live remote endpoint calls and exports markdown documentation, mirroring the host API Doc Builder.
- Config page — Remote API section — dedicated configuration panel for all remote API settings; credential fields are masked (password inputs) by default.
- Header token expansion — header values support
{session-guid}(one UUID per page load) and{request-guid}(fresh UUID per call), expanded at request-send time. Works for both default headers and per-request extra headers. - Harness version and build date —
GET /api-test-spark/confignow includesharnessVersion(NuGet package version) andharnessBuiltAt(ISO-8601 assembly build timestamp); displayed on the About page. useRemoteConfigStore— new dedicated Zustand persist store (keyapi-test-spark-remote-config) holding all remote API configuration. Reads live inuseHostApiso Config page saves take effect immediately without page reload.- CSP auto-extension —
RemoteBaseUrlis automatically added toContent-Security-Policy connect-src, allowing direct browser-to-remote-API calls without modifying the remote server.
Changed
- About page — Version and Build Date now sourced from the
harnessConfigstore (populated from the config endpoint) instead of a separatebuild-info.jsonfetch that fails in NuGet embedded mode. - Config page HeadersEditor — typing a header key no longer loses focus on each keystroke (isolated via uncontrolled
KeyInputsub-component that commits on blur). Newly saved headers are sent in the next request without a page reload. - Constitution v1.1.2 —
useRemoteConfigStoreadded to the §V canonical store registry; ratification history and sync impact report updated.
Architectural Decisions
- ADR-008: Server-side proxy for remote OpenAPI spec fetch — credentials off browser, SSRF guard,
useRemoteConfigStorefor live remote config reads
Contributors
- Mark Hazleton
[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-spa...
v1.6.0
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.6.0] - 2026-06-20
Added
- User-name token expansion — profiles and request templates now expand
{userName}tokens at request time, enabling personalized header and body content for multi-user environments. - SampleApi publish package — added a dedicated SampleApi publish output package for simplified deployment workflows.
Fixed
- CSP logo rendering — resolved Content Security Policy violations preventing inline logo rendering in the harness UI.
- Base-path build-info fetches — fixed fetch requests for build metadata when the app is deployed at a non-root base path (e.g.,
/api-test-spark/).
Changed
- Package reference updates — upgraded Microsoft.AspNetCore.OpenApi and Microsoft.OpenApi to the latest stable versions for improved OpenAPI v3 compatibility and maintenance.
- Make Bold branding metadata — aligned branding icons and metadata across all delivered assets for consistent product identity.
Breaking Changes
None. This is a fully backwards-compatible patch release.
Contributors
- Mark Hazleton
[v1.5.0] - 2026-06-12
Changed
- Make Bold Solutions brand alignment — refreshed the embedded React UI with the Make Bold Spark product family, Make Bold Solutions ownership, brand colors, Inter Tight typography, updated header/home/footer treatments, and consistent red/black/gray accent states across the app.
- Favicon and visual assets — generated a multi-size
favicon.ico, refreshed PNG favicons, added local Make Bold Solutions logo/font assets to the SPA build, and regenerated the NuGet package icon from the brand asset. - NuGet package identity — updated NuGet authors, company, copyright, title, description, tags, repository casing, package README, root README, packaging walkthrough, and license attribution to consistently present API Test Spark as a Make Bold Spark product owned and managed by Make Bold Solutions.
Breaking Changes
None. This release does not change the public .NET API surface or runtime configuration model.
Contributors
- Mark Hazleton
[v1.4.0] - 2026-06-09
Added
- Remote API Profiles — the remote API experience now supports a collection of named profiles instead of one global remote target. Each profile has a stable id, name, description, base URL, OpenAPI URL, credentials, and profile-scoped headers.
- Program.cs multi-profile defaults — host apps can seed multiple remote APIs with
RemoteApiProfiles. The legacy single-remote options remain supported and seed one compatibility profile when no profile collection is configured. - Browser profile management — the Config page can add, edit, delete, hide, reset, and persist browser-managed remote API profiles. New browser profiles receive GUID ids, and duplicate visible names are blocked with a clear validation alert before save.
- Profile-specific explorer and documentation routes — the home screen, Remote API Explorer, and Remote API Doc Builder now render one entry per visible profile using each profile's name and description.
- Server-profile-only remote spec proxy —
GET /api-test-spark/remote-spec?profileId=...resolves only server-provided profile ids. Browser-created profiles fetch OpenAPI documents directly from the browser, preventing browser-submitted URLs from driving server-side fetches. - Credential redaction for server profiles — server-provided API key values and bearer tokens are no longer serialized in
/api-test-spark/config; configured flags tell the browser that credentials exist without exposing values.
Changed
- Remote configuration persistence — existing single-remote browser configuration migrates into one GUID-backed profile where feasible, while hidden server profile ids and browser overrides preserve the prior reload-surviving behavior.
- SampleApi demo content — the demo app now documents the remote profile model, server-default personalization, duplicate-name validation, and profile-specific API/documentation sections.
Breaking Changes
None. The new RemoteApiProfiles collection and RemoteApiProfile model are additive. Existing RemoteBaseUrl, RemoteOpenApiUrl, RemoteOpenApiApiKeyHeader, RemoteOpenApiApiKeyValue, RemoteOpenApiBearerToken, and RemoteDefaultHeaders options remain supported for this release.
Contributors
- Mark Hazleton
[v1.3.0] - 2026-06-06
Added
- Remote API Explorer — a new screen (
/remote-api) that loads, browses, and tests endpoints from a remote OpenAPI JSON document. The remote URL, API key, and Bearer token are configured viaMapApiTestSpark()inProgram.csand are editable on the Config page. - Remote spec proxy —
GET /api-test-spark/remote-specis a new .NET endpoint that fetches the remote OpenAPI document server-side. API key and Bearer token are injected at the proxy level; credentials never appear in the browser network tab or DevTools. - SSRF guard — the proxy validates that
RemoteOpenApiUrluseshttp://orhttps://and rejects all other schemes (file://,ldap://, etc.) with a400response. ApiTestSparkOptionsadditions — four new properties:RemoteBaseUrl,RemoteOpenApiUrl,RemoteOpenApiApiKeyHeader,RemoteOpenApiApiKeyValue,RemoteOpenApiBearerToken, andRemoteDefaultHeaders(dictionary of headers injected into every browser-side request to the remote API).- Remote API Doc Builder — captures live remote endpoint calls and exports markdown documentation, mirroring the host API Doc Builder.
- Config page — Remote API section — dedicated configuration panel for all remote API settings; credential fields are masked (password inputs) by default.
- Header token expansion — header values support
{session-guid}(one UUID per page load) and{request-guid}(fresh UUID per call), expanded at request-send time. Works for both default headers and per-request extra headers. - Harness version and build date —
GET /api-test-spark/confignow includesharnessVersion(NuGet package version) andharnessBuiltAt(ISO-8601 assembly build timestamp); displayed on the About page. useRemoteConfigStore— new dedicated Zustand persist store (keyapi-test-spark-remote-config) holding all remote API configuration. Reads live inuseHostApiso Config page saves take effect immediately without page reload.- CSP auto-extension —
RemoteBaseUrlis automatically added toContent-Security-Policy connect-src, allowing direct browser-to-remote-API calls without modifying the remote server.
Changed
- About page — Version and Build Date now sourced from the
harnessConfigstore (populated from the config endpoint) instead of a separatebuild-info.jsonfetch that fails in NuGet embedded mode. - Config page HeadersEditor — typing a header key no longer loses focus on each keystroke (isolated via uncontrolled
KeyInputsub-component that commits on blur). Newly saved headers are sent in the next request without a page reload. - Constitution v1.1.2 —
useRemoteConfigStoreadded to the §V canonical store registry; ratification history and sync impact report updated.
Architectural Decisions
- ADR-008: Server-side proxy for remote OpenAPI spec fetch — credentials off browser, SSRF guard,
useRemoteConfigStorefor live remote config reads
Contributors
- Mark Hazleton
[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...
v1.5.0
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.5.0] - 2026-06-12
Changed
- Make Bold Solutions brand alignment — refreshed the embedded React UI with the Make Bold Spark product family, Make Bold Solutions ownership, brand colors, Inter Tight typography, updated header/home/footer treatments, and consistent red/black/gray accent states across the app.
- Favicon and visual assets — generated a multi-size
favicon.ico, refreshed PNG favicons, added local Make Bold Solutions logo/font assets to the SPA build, and regenerated the NuGet package icon from the brand asset. - NuGet package identity — updated NuGet authors, company, copyright, title, description, tags, repository casing, package README, root README, packaging walkthrough, and license attribution to consistently present API Test Spark as a Make Bold Spark product owned and managed by Make Bold Solutions.
Breaking Changes
None. This release does not change the public .NET API surface or runtime configuration model.
Contributors
- Mark Hazleton
[v1.4.0] - 2026-06-09
Added
- Remote API Profiles — the remote API experience now supports a collection of named profiles instead of one global remote target. Each profile has a stable id, name, description, base URL, OpenAPI URL, credentials, and profile-scoped headers.
- Program.cs multi-profile defaults — host apps can seed multiple remote APIs with
RemoteApiProfiles. The legacy single-remote options remain supported and seed one compatibility profile when no profile collection is configured. - Browser profile management — the Config page can add, edit, delete, hide, reset, and persist browser-managed remote API profiles. New browser profiles receive GUID ids, and duplicate visible names are blocked with a clear validation alert before save.
- Profile-specific explorer and documentation routes — the home screen, Remote API Explorer, and Remote API Doc Builder now render one entry per visible profile using each profile's name and description.
- Server-profile-only remote spec proxy —
GET /api-test-spark/remote-spec?profileId=...resolves only server-provided profile ids. Browser-created profiles fetch OpenAPI documents directly from the browser, preventing browser-submitted URLs from driving server-side fetches. - Credential redaction for server profiles — server-provided API key values and bearer tokens are no longer serialized in
/api-test-spark/config; configured flags tell the browser that credentials exist without exposing values.
Changed
- Remote configuration persistence — existing single-remote browser configuration migrates into one GUID-backed profile where feasible, while hidden server profile ids and browser overrides preserve the prior reload-surviving behavior.
- SampleApi demo content — the demo app now documents the remote profile model, server-default personalization, duplicate-name validation, and profile-specific API/documentation sections.
Breaking Changes
None. The new RemoteApiProfiles collection and RemoteApiProfile model are additive. Existing RemoteBaseUrl, RemoteOpenApiUrl, RemoteOpenApiApiKeyHeader, RemoteOpenApiApiKeyValue, RemoteOpenApiBearerToken, and RemoteDefaultHeaders options remain supported for this release.
Contributors
- Mark Hazleton
[v1.3.0] - 2026-06-06
Added
- Remote API Explorer — a new screen (
/remote-api) that loads, browses, and tests endpoints from a remote OpenAPI JSON document. The remote URL, API key, and Bearer token are configured viaMapApiTestSpark()inProgram.csand are editable on the Config page. - Remote spec proxy —
GET /api-test-spark/remote-specis a new .NET endpoint that fetches the remote OpenAPI document server-side. API key and Bearer token are injected at the proxy level; credentials never appear in the browser network tab or DevTools. - SSRF guard — the proxy validates that
RemoteOpenApiUrluseshttp://orhttps://and rejects all other schemes (file://,ldap://, etc.) with a400response. ApiTestSparkOptionsadditions — four new properties:RemoteBaseUrl,RemoteOpenApiUrl,RemoteOpenApiApiKeyHeader,RemoteOpenApiApiKeyValue,RemoteOpenApiBearerToken, andRemoteDefaultHeaders(dictionary of headers injected into every browser-side request to the remote API).- Remote API Doc Builder — captures live remote endpoint calls and exports markdown documentation, mirroring the host API Doc Builder.
- Config page — Remote API section — dedicated configuration panel for all remote API settings; credential fields are masked (password inputs) by default.
- Header token expansion — header values support
{session-guid}(one UUID per page load) and{request-guid}(fresh UUID per call), expanded at request-send time. Works for both default headers and per-request extra headers. - Harness version and build date —
GET /api-test-spark/confignow includesharnessVersion(NuGet package version) andharnessBuiltAt(ISO-8601 assembly build timestamp); displayed on the About page. useRemoteConfigStore— new dedicated Zustand persist store (keyapi-test-spark-remote-config) holding all remote API configuration. Reads live inuseHostApiso Config page saves take effect immediately without page reload.- CSP auto-extension —
RemoteBaseUrlis automatically added toContent-Security-Policy connect-src, allowing direct browser-to-remote-API calls without modifying the remote server.
Changed
- About page — Version and Build Date now sourced from the
harnessConfigstore (populated from the config endpoint) instead of a separatebuild-info.jsonfetch that fails in NuGet embedded mode. - Config page HeadersEditor — typing a header key no longer loses focus on each keystroke (isolated via uncontrolled
KeyInputsub-component that commits on blur). Newly saved headers are sent in the next request without a page reload. - Constitution v1.1.2 —
useRemoteConfigStoreadded to the §V canonical store registry; ratification history and sync impact report updated.
Architectural Decisions
- ADR-008: Server-side proxy for remote OpenAPI spec fetch — credentials off browser, SSRF guard,
useRemoteConfigStorefor live remote config reads
Contributors
- Mark Hazleton
[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()ca...
v1.4.0
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.4.0] - 2026-06-09
Added
- Remote API Profiles — the remote API experience now supports a collection of named profiles instead of one global remote target. Each profile has a stable id, name, description, base URL, OpenAPI URL, credentials, and profile-scoped headers.
- Program.cs multi-profile defaults — host apps can seed multiple remote APIs with
RemoteApiProfiles. The legacy single-remote options remain supported and seed one compatibility profile when no profile collection is configured. - Browser profile management — the Config page can add, edit, delete, hide, reset, and persist browser-managed remote API profiles. New browser profiles receive GUID ids, and duplicate visible names are blocked with a clear validation alert before save.
- Profile-specific explorer and documentation routes — the home screen, Remote API Explorer, and Remote API Doc Builder now render one entry per visible profile using each profile's name and description.
- Server-profile-only remote spec proxy —
GET /api-test-spark/remote-spec?profileId=...resolves only server-provided profile ids. Browser-created profiles fetch OpenAPI documents directly from the browser, preventing browser-submitted URLs from driving server-side fetches. - Credential redaction for server profiles — server-provided API key values and bearer tokens are no longer serialized in
/api-test-spark/config; configured flags tell the browser that credentials exist without exposing values.
Changed
- Remote configuration persistence — existing single-remote browser configuration migrates into one GUID-backed profile where feasible, while hidden server profile ids and browser overrides preserve the prior reload-surviving behavior.
- SampleApi demo content — the demo app now documents the remote profile model, server-default personalization, duplicate-name validation, and profile-specific API/documentation sections.
Breaking Changes
None. The new RemoteApiProfiles collection and RemoteApiProfile model are additive. Existing RemoteBaseUrl, RemoteOpenApiUrl, RemoteOpenApiApiKeyHeader, RemoteOpenApiApiKeyValue, RemoteOpenApiBearerToken, and RemoteDefaultHeaders options remain supported for this release.
Contributors
- Mark Hazleton
[v1.3.0] - 2026-06-06
Added
- Remote API Explorer — a new screen (
/remote-api) that loads, browses, and tests endpoints from a remote OpenAPI JSON document. The remote URL, API key, and Bearer token are configured viaMapApiTestSpark()inProgram.csand are editable on the Config page. - Remote spec proxy —
GET /api-test-spark/remote-specis a new .NET endpoint that fetches the remote OpenAPI document server-side. API key and Bearer token are injected at the proxy level; credentials never appear in the browser network tab or DevTools. - SSRF guard — the proxy validates that
RemoteOpenApiUrluseshttp://orhttps://and rejects all other schemes (file://,ldap://, etc.) with a400response. ApiTestSparkOptionsadditions — four new properties:RemoteBaseUrl,RemoteOpenApiUrl,RemoteOpenApiApiKeyHeader,RemoteOpenApiApiKeyValue,RemoteOpenApiBearerToken, andRemoteDefaultHeaders(dictionary of headers injected into every browser-side request to the remote API).- Remote API Doc Builder — captures live remote endpoint calls and exports markdown documentation, mirroring the host API Doc Builder.
- Config page — Remote API section — dedicated configuration panel for all remote API settings; credential fields are masked (password inputs) by default.
- Header token expansion — header values support
{session-guid}(one UUID per page load) and{request-guid}(fresh UUID per call), expanded at request-send time. Works for both default headers and per-request extra headers. - Harness version and build date —
GET /api-test-spark/confignow includesharnessVersion(NuGet package version) andharnessBuiltAt(ISO-8601 assembly build timestamp); displayed on the About page. useRemoteConfigStore— new dedicated Zustand persist store (keyapi-test-spark-remote-config) holding all remote API configuration. Reads live inuseHostApiso Config page saves take effect immediately without page reload.- CSP auto-extension —
RemoteBaseUrlis automatically added toContent-Security-Policy connect-src, allowing direct browser-to-remote-API calls without modifying the remote server.
Changed
- About page — Version and Build Date now sourced from the
harnessConfigstore (populated from the config endpoint) instead of a separatebuild-info.jsonfetch that fails in NuGet embedded mode. - Config page HeadersEditor — typing a header key no longer loses focus on each keystroke (isolated via uncontrolled
KeyInputsub-component that commits on blur). Newly saved headers are sent in the next request without a page reload. - Constitution v1.1.2 —
useRemoteConfigStoreadded to the §V canonical store registry; ratification history and sync impact report updated.
Architectural Decisions
- ADR-008: Server-side proxy for remote OpenAPI spec fetch — credentials off browser, SSRF guard,
useRemoteConfigStorefor live remote config reads
Contributors
- Mark Hazleton
[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...
v1.3.0 — Remote API Explorer
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.3.0] - 2026-06-06
Added
- Remote API Explorer — a new screen (
/remote-api) that loads, browses, and tests endpoints from a remote OpenAPI JSON document. The remote URL, API key, and Bearer token are configured viaMapApiTestSpark()inProgram.csand are editable on the Config page. - Remote spec proxy —
GET /api-test-spark/remote-specis a new .NET endpoint that fetches the remote OpenAPI document server-side. API key and Bearer token are injected at the proxy level; credentials never appear in the browser network tab or DevTools. - SSRF guard — the proxy validates that
RemoteOpenApiUrluseshttp://orhttps://and rejects all other schemes (file://,ldap://, etc.) with a400response. ApiTestSparkOptionsadditions — four new properties:RemoteBaseUrl,RemoteOpenApiUrl,RemoteOpenApiApiKeyHeader,RemoteOpenApiApiKeyValue,RemoteOpenApiBearerToken, andRemoteDefaultHeaders(dictionary of headers injected into every browser-side request to the remote API).- Remote API Doc Builder — captures live remote endpoint calls and exports markdown documentation, mirroring the host API Doc Builder.
- Config page — Remote API section — dedicated configuration panel for all remote API settings; credential fields are masked (password inputs) by default.
- Header token expansion — header values support
{session-guid}(one UUID per page load) and{request-guid}(fresh UUID per call), expanded at request-send time. Works for both default headers and per-request extra headers. - Harness version and build date —
GET /api-test-spark/confignow includesharnessVersion(NuGet package version) andharnessBuiltAt(ISO-8601 assembly build timestamp); displayed on the About page. useRemoteConfigStore— new dedicated Zustand persist store (keyapi-test-spark-remote-config) holding all remote API configuration. Reads live inuseHostApiso Config page saves take effect immediately without page reload.- CSP auto-extension —
RemoteBaseUrlis automatically added toContent-Security-Policy connect-src, allowing direct browser-to-remote-API calls without modifying the remote server.
Changed
- About page — Version and Build Date now sourced from the
harnessConfigstore (populated from the config endpoint) instead of a separatebuild-info.jsonfetch that fails in NuGet embedded mode. - Config page HeadersEditor — typing a header key no longer loses focus on each keystroke (isolated via uncontrolled
KeyInputsub-component that commits on blur). Newly saved headers are sent in the next request without a page reload. - Constitution v1.1.2 —
useRemoteConfigStoreadded to the §V canonical store registry; ratification history and sync impact report updated.
Architectural Decisions
- ADR-008: Server-side proxy for remote OpenAPI spec fetch — credentials off browser, SSRF guard,
useRemoteConfigStorefor live remote config reads
Contributors
- Mark Hazleton
[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 ad...
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 ...
v1.1.0
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.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
v1.0.2
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.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
v1.0.1
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.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