This is an automated email from the ASF dual-hosted git repository.
kayx23 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-website.git
The following commit(s) were added to refs/heads/master by this push:
new 73e967f5646 fix(docs): label Next Admin API preview correctly (#2146)
73e967f5646 is described below
commit 73e967f564655f2565e94b542ea38c9cd5fff2a5
Author: Traky Deng <[email protected]>
AuthorDate: Mon Nov 2 09:59:53 2026 +0800
fix(docs): label Next Admin API preview correctly (#2146)
---
next/tests/admin-api/admin-api.spec.mjs | 5 ++++-
shared/admin-api-spec.test.mjs | 10 +++++++++-
shared/admin-api-spec.ts | 6 ++++++
shared/admin-api.ts | 7 ++++---
4 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/next/tests/admin-api/admin-api.spec.mjs
b/next/tests/admin-api/admin-api.spec.mjs
index e3d16d1ec18..f7c24ca6f39 100644
--- a/next/tests/admin-api/admin-api.spec.mjs
+++ b/next/tests/admin-api/admin-api.spec.mjs
@@ -37,7 +37,10 @@ const versions = ['', '3.16/', '3.17/', '3.18/', 'next/'];
expect(response.ok()).toBeTruthy();
const spec = await response.json();
expect(spec.openapi).toMatch(/^3\./);
- if (version && version !== 'next/')
expect(spec.info.version).toMatch(new RegExp(`^${version.slice(0,
-1).replace('.', '\\.')}([.]|$)`));
+ if (version === 'next/') {
+ await expect(page.locator('.scalar-api-reference .badge', { hasText:
'Next' })).toBeVisible();
+ expect(spec.info.version).not.toBe('Next');
+ } else if (version) expect(spec.info.version).toMatch(new
RegExp(`^${version.slice(0, -1).replace('.', '\\.')}([.]|$)`));
const downloaded = page.waitForEvent('download');
await download.click();
expect((await
downloaded).suggestedFilename()).toBe('apisix-admin-api.json');
diff --git a/shared/admin-api-spec.test.mjs b/shared/admin-api-spec.test.mjs
index 81e48c7e41e..2ce1b23dabe 100644
--- a/shared/admin-api-spec.test.mjs
+++ b/shared/admin-api-spec.test.mjs
@@ -1,6 +1,6 @@
import assert from 'node:assert/strict';
import { test } from 'node:test';
-import { isAdminApiSpec } from './admin-api-spec.ts';
+import { adminApiDisplaySpec, isAdminApiSpec } from './admin-api-spec.ts';
test('accepts patch releases and development versions without crossing release
series', () => {
const spec = { openapi: '3.1.0', info: { title: 'Admin API', version:
'3.18.0' }, paths: {} };
@@ -10,6 +10,14 @@ test('accepts patch releases and development versions
without crossing release s
assert.equal(isAdminApiSpec({ ...spec, info: { title: 'Admin API', version:
'3.19.0' } }, '3.19.0'), true);
});
+test('labels only the rendered Next copy without mutating the canonical spec',
() => {
+ const spec = { openapi: '3.1.0', info: { title: 'Admin API', version:
'3.19.0' }, paths: {} };
+ const display = adminApiDisplaySpec(spec, 'next');
+ assert.equal(display.info.version, 'Next');
+ assert.equal(spec.info.version, '3.19.0');
+ assert.equal(adminApiDisplaySpec(spec, '3.19'), spec);
+});
+
test('rejects malformed documents without throwing', () => {
[null, [], {}, { openapi: 3 },
{ openapi: '3.1.0', info: { title: 'Admin API', version: '3.18.0' },
paths: null },
diff --git a/shared/admin-api-spec.ts b/shared/admin-api-spec.ts
index ab9c176faca..92b7e926a6a 100644
--- a/shared/admin-api-spec.ts
+++ b/shared/admin-api-spec.ts
@@ -12,3 +12,9 @@ export function isAdminApiSpec(spec: unknown, version?:
string): boolean {
&& (!version || version === 'next' || spec.info.version === version ||
spec.info.version.startsWith(`${version}.`))
&& isObject(spec.paths);
}
+
+/** Keep the canonical Next contract intact while labeling its rendered
preview. */
+export function adminApiDisplaySpec(spec: unknown, version?: string): unknown {
+ if (version !== 'next' || !isObject(spec) || !isObject(spec.info)) return
spec;
+ return { ...spec, info: { ...spec.info, version: 'Next' } };
+}
diff --git a/shared/admin-api.ts b/shared/admin-api.ts
index 0bbc3523fe3..e523fdbe7c8 100644
--- a/shared/admin-api.ts
+++ b/shared/admin-api.ts
@@ -1,4 +1,4 @@
-import { isAdminApiSpec } from './admin-api-spec';
+import { adminApiDisplaySpec, isAdminApiSpec } from './admin-api-spec';
declare const Scalar: {
createApiReference: (
@@ -104,7 +104,8 @@ export function mountAdminApi(
});
if (!response.ok) throw new Error('Unable to load local OpenAPI');
const spec = await response.json();
- if (!isAdminApiSpec(spec, version ?? container.dataset.specVersion))
throw new Error('Invalid OpenAPI document');
+ const specVersion = version ?? container.dataset.specVersion;
+ if (!isAdminApiSpec(spec, specVersion)) throw new Error('Invalid
OpenAPI document');
await new Promise<void>((resolve, reject) => {
const script = document.createElement('script');
script.src =
'https://cdn.jsdelivr.net/npm/@scalar/[email protected]/dist/browser/standalone.js';
@@ -114,7 +115,7 @@ export function mountAdminApi(
});
if (disposed || reference.hidden) return;
const instance = Scalar.createApiReference(container, {
- content: spec,
+ content: adminApiDisplaySpec(spec, specVersion),
onLoaded: () => {
if (disposed || reference.hidden) return;
window.clearTimeout(timeout);