feat: a little work on a new page generator for endpoint pages

This commit is contained in:
DecDuck
2025-10-21 15:39:50 +11:00
parent 5639af1d78
commit bc94cca012
10 changed files with 560 additions and 9297 deletions

2
.gitignore vendored
View File

@@ -1,7 +1,7 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
node_modules
/.pnp
.pnp.js

183
generator/index.ts Normal file
View File

@@ -0,0 +1,183 @@
type ACLMode = 'user' | 'system'
export type Page = {
path: string
title: string
meta: string
description: string
sections: Array<{ title: string; description: string }>
endpoints: Array<
{
name: string
path: string
apiLevel: ACLMode
acl: string
description: string
response: {
description?: string
json: string
}
} & (
| { method: 'GET' | 'HEAD'; body?: undefined }
| {
method: 'POST' | 'PATCH' | 'PUT' | 'DELETE'
body:
| string
| {
[key: string]: {
type: string
description: string
example: string
}
}
}
)
>
}
async function createCodeGroupSection(endpoint: Page['endpoints'][number]) {
if (endpoint.method == 'GET' || endpoint.method == 'HEAD' || !endpoint.body) {
return `
<CodeGroup title="Request" tag="${endpoint.method}" label="${endpoint.path}">
\`\`\`bash {{ title: 'cURL' }}
curl -${endpoint.method == 'GET' ? 'G' : 'I'} http://localhost:3000${endpoint.path} \\
-H "Authorization: Bearer {token}"
\`\`\`
\`\`\`js
const response = await fetch("http://localhost:3000${endpoint.path}", {
headers: {
Authorization: "Bearer {token}"
},${endpoint.method == 'HEAD' ? '\n method: "HEAD"' : ''}
});
const results = await response.json();
\`\`\`
</CodeGroup>`
}
return `
<CodeGroup title="Request" tag="${endpoint.method}" label="${endpoint.path}">
\`\`\`bash {{ title: 'cURL' }}
curl -X POST http://localhost:3000${endpoint.path} \\
-H "Authorization: Bearer {token}" \\
-H "Content-Type: application/json" \\
-d "{ ... }"
\`\`\`
\`\`\`js
${(await prettier.format(`const response = await fetch("http://localhost:3000${endpoint.path}", {
headers: {
Authorization: "Bearer {token}"
},
method: "${endpoint.method}",
${
typeof endpoint.body == 'string'
? 'body: /* see notes */'
: `body: {
${Object.entries(endpoint.body)
.map(([name, { example }]) => `${name}: ${example},`)
.join('\n')}
}`
}
});
const body = await response.json();`, {parser: "typescript"})).split("\n").map((v) => ` ${v}`).join("\n")}
\`\`\`
</CodeGroup>
`
}
function createRequestDescription(endpoint: Page['endpoints'][number]) {
if (!endpoint.body) return ''
if (typeof endpoint.body == 'string')
return `## Request
${endpoint.body}`
return `
## Request
<Properties>
${Object.entries(endpoint.body)
.map(
([name, { type, description }]) => `
<Property name="${name}" type="${type}">
${description.trim()}
</Property>
`,
)
.join('\n')}
</Properties>
`
}
import fs from 'node:fs'
import { join } from 'node:path'
import prettier from 'prettier'
const pages = ['./pages/import']
for (const page of pages) {
const pageData: Page = (await import(page)).default
const header = `
export const metadata = {
title: "${pageData.title}",
description: "${pageData.meta}"
};
# ${pageData.title}
${pageData.description}`.trim()
const sections = pageData.sections.map((section) =>
`
## ${section.title}
${section.description}`.trim(),
)
const endpoints = await Promise.all(
pageData.endpoints.map(async (endpoint) =>
`
## ${endpoint.name} {{ tag: '${endpoint.method}', label: '${endpoint.path}', apilevel: "${endpoint.apiLevel}", acl: "${endpoint.acl}" }}
<Row>
<Col>
${endpoint.description}
${createRequestDescription(endpoint)}
${
endpoint.response.description
? `## Response
${endpoint.response.description}`
: ''
}
</Col>
<Col sticky>
${await createCodeGroupSection(endpoint)}
\`\`\`json {{ title: 'Response' }}
${(await prettier.format(endpoint.response.json, { parser: 'json', })).split("\n").map((v) => ` ${v}`).join("\n")}
\`\`\`
</Col>
</Row>`.trim(),
),
)
const finalPage = [header, ...sections, ...endpoints].join('\n\n---\n\n')
fs.mkdirSync(pageData.path, { recursive: true })
fs.writeFileSync(pageData.path + '/page.mdx', finalPage)
}

18
generator/package.json Normal file
View File

@@ -0,0 +1,18 @@
{
"name": "generator",
"version": "1.0.0",
"description": "",
"type": "module",
"main": "index.ts",
"scripts": {
"generate": "deno run --allow-sys --allow-env --allow-read --sloppy-imports --allow-write index.ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "pnpm@10.9.0",
"dependencies": {
"deno": "^2.5.4",
"prettier": "^3.6.2"
}
}

129
generator/pages/import.ts Normal file
View File

@@ -0,0 +1,129 @@
import { Page } from '../index.js'
export default {
path: 'web/import',
title: 'Import',
meta: "On this page, we'll dive into how to import games and versions on Drop, and the options for both.",
description: `While games and versions should be covered in separate sections, importing is a complicated enough of a process to warrant a separate page. Importing is the process of pulling and providing metadata for various complex objects in Drop, namely games and versions.
Both games and versions in Drop are required to imported manually, due to them having additional metadata that must be user-provided.`,
sections: [
{
title: 'Game metadata',
description:
"Game metadata is provided by a series of backend 'metadata providers'. Drop unifies them all into a single API to import the metadata, and handle authentication seamlessly.",
},
],
endpoints: [
{
name: 'Fetch unimported games',
path: '/api/v1/admin/import/game',
apiLevel: 'system',
acl: 'import:game:read',
description:
'This endpoint fetches all unimported games on the instance.',
method: 'GET',
response: {
json: `{
"unimportedGames": [
{
"game": "Abiotic Factor",
"library": {
"id": "8dc4b769-090f-4aec-b73a-d8fafc84f418",
"name": "Example Library",
"backend": "Filesystem",
"options": {
"baseDir": "./.data/library"
},
"working": true
}
},
{
"game": "Balatro",
"library": {
"id": "8dc4b769-090f-4aec-b73a-d8fafc84f418",
"name": "Example Library",
"backend": "Filesystem",
"options": {
"baseDir": "./.data/library"
},
"working": true
}
},
{
"game": "SuperTuxKart",
"library": {
"id": "8dc4b769-090f-4aec-b73a-d8fafc84f418",
"name": "Example Library",
"backend": "Filesystem",
"options": {
"baseDir": "./.data/library"
},
"working": true
}
}
]
}`,
},
},
// Search metadata,
{
name: 'Import game',
path: '/api/v1/admin/import/game',
method: 'POST',
apiLevel: 'system',
acl: 'import:game:new',
description: 'This endpoint imports a game, optionally with metadata.',
body: {
library: {
type: 'string',
description:
"The ID of the library you're importing from. Fetched from `library.id` on the GET endpoint.",
example: `"8dc4b769-090f-4aec-b73a-d8fafc84f418"`,
},
path: {
type: 'string',
description:
"Path of the game you're importing. Fetched from the `game` on the GET endpoint.",
example: `"SuperTuxKart"`,
},
metadata: {
type: 'object',
description: `
Optional, metadata to import from. It requires three fields if set:
\`\`\`json
{
"id": "game ID",
"sourceId": "source ID",
"name": "Name of game"
}
\`\`\`
All these properties are returned from the search endpoint. While you can guess these values, as they are generally the internal IDs of the respective platforms, they *are* internal values and are not recommended to be guessed.
For example, if you had the game already from IGDB, you may be able to use:
\`\`\`json
{
"id": "<IGDB ID>",
"sourceId": "IGDB",
"name": "<Name of game on IGDB>"
}
\`\`\`
Without searching for the game first. *This is officially not recommended, but we are unlikely to break this behaviour.*
`,
example: `{
id: "289018",
sourceId: "IGDB",
name: "Example Block Game"
}`,
},
},
response: {
json: `{
"taskId": "..."
}`,
},
},
],
} satisfies Page

113
generator/pnpm-lock.yaml generated Normal file
View File

@@ -0,0 +1,113 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
dependencies:
'@types/node':
specifier: ^24.9.1
version: 24.9.1
deno:
specifier: ^2.5.4
version: 2.5.4
prettier:
specifier: ^3.6.2
version: 3.6.2
typescript:
specifier: ^5.9.3
version: 5.9.3
packages:
'@deno/darwin-arm64@2.5.4':
resolution: {integrity: sha512-FWybfOwt0d3v4m9EMZd+0cEMTSHjZfoOomT9drK/mwa8uoZQ6PpQzjhlg9lIX2DCP92vZ+Miy4c1c6r0orSzjQ==}
cpu: [arm64]
os: [darwin]
'@deno/darwin-x64@2.5.4':
resolution: {integrity: sha512-uiP24gbIMzLya8DjP+lg3z/Ysnm0rmWVPOT36+nHS5UsO08+eArkAcKMxj7IfVPw1fzl8M8tpHt6d18amdnMJw==}
cpu: [x64]
os: [darwin]
'@deno/linux-arm64-glibc@2.5.4':
resolution: {integrity: sha512-szui2JOiwozBkYRMN+xQGNyrVEel3kpGRKoy9k+kOMWtsu7F/36mLn1dr3hRNV0NmkRtwIyee1DosDVhd0lPlg==}
cpu: [arm64]
os: [linux]
'@deno/linux-x64-glibc@2.5.4':
resolution: {integrity: sha512-HEsUi9vUtrG19uSoILLs+D3/x4U3DUaCYSbsN4frvilbT3A/y3XO6t1OR8LikZ4K4mN6Ur6mS6NOdZbzV4PR/Q==}
cpu: [x64]
os: [linux]
'@deno/win32-arm64@2.5.4':
resolution: {integrity: sha512-WjAXS8kfRrmeR4pJ4pZMfqgP/74canKOS6iJv4DMYSPQiv9DBEcNWj7trbsRuYUZQephNC+7KrACrk0kpriNwg==}
cpu: [arm64]
os: [win32]
'@deno/win32-x64@2.5.4':
resolution: {integrity: sha512-OYgHzdfrNX3iDdPCq5CkulPZ7tVj+bTzA7MX9SGkUgaIxLn16xG3RUK4L2MMRwaxBARcb5TT4eySC43tB9gE4Q==}
cpu: [x64]
os: [win32]
'@types/node@24.9.1':
resolution: {integrity: sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==}
deno@2.5.4:
resolution: {integrity: sha512-2TEB4HtIuSnzN6WBvIDXFgcVCyOZdDA5iiEL3iwIzC+tskOTcabxuVkVQCwWscFSYzYiI79kLZDMFXsSzB6j1Q==}
hasBin: true
prettier@3.6.2:
resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
engines: {node: '>=14'}
hasBin: true
typescript@5.9.3:
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
engines: {node: '>=14.17'}
hasBin: true
undici-types@7.16.0:
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
snapshots:
'@deno/darwin-arm64@2.5.4':
optional: true
'@deno/darwin-x64@2.5.4':
optional: true
'@deno/linux-arm64-glibc@2.5.4':
optional: true
'@deno/linux-x64-glibc@2.5.4':
optional: true
'@deno/win32-arm64@2.5.4':
optional: true
'@deno/win32-x64@2.5.4':
optional: true
'@types/node@24.9.1':
dependencies:
undici-types: 7.16.0
deno@2.5.4:
optionalDependencies:
'@deno/darwin-arm64': 2.5.4
'@deno/darwin-x64': 2.5.4
'@deno/linux-arm64-glibc': 2.5.4
'@deno/linux-x64-glibc': 2.5.4
'@deno/win32-arm64': 2.5.4
'@deno/win32-x64': 2.5.4
prettier@3.6.2: {}
typescript@5.9.3: {}
undici-types@7.16.0: {}

9292
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
{
"name": "tailwind-plus-protocol",
"name": "drop-api-docs",
"version": "0.1.0",
"private": true,
"scripts": {
@@ -40,6 +40,7 @@
"shiki": "^0.14.7",
"simple-functional-loader": "^1.2.1",
"tailwindcss": "^4.1.11",
"ts-node": "^10.9.2",
"typescript": "^5.8.3",
"unist-util-filter": "^5.0.1",
"unist-util-visit": "^5.0.0",

111
pnpm-lock.yaml generated
View File

@@ -98,6 +98,9 @@ importers:
tailwindcss:
specifier: ^4.1.11
version: 4.1.12
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@24.3.0)(typescript@5.9.2)
typescript:
specifier: ^5.8.3
version: 5.9.2
@@ -221,6 +224,10 @@ packages:
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
'@cspotcode/source-map-support@0.8.1':
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'}
'@emnapi/core@1.4.5':
resolution: {integrity: sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==}
@@ -463,6 +470,9 @@ packages:
'@jridgewell/trace-mapping@0.3.30':
resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==}
'@jridgewell/trace-mapping@0.3.9':
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
'@mdx-js/loader@3.1.0':
resolution: {integrity: sha512-xU/lwKdOyfXtQGqn3VnJjlDrmKXEvMi1mgYxVmukEUtVycIz1nh7oQ40bKTd4cA7rLStqu0740pnhGYxGoqsCg==}
peerDependencies:
@@ -723,6 +733,18 @@ packages:
'@tanstack/virtual-core@3.13.12':
resolution: {integrity: sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA==}
'@tsconfig/node10@1.0.11':
resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==}
'@tsconfig/node12@1.0.11':
resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
'@tsconfig/node14@1.0.3':
resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
'@tsconfig/node16@1.0.4':
resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
'@tybys/wasm-util@0.10.0':
resolution: {integrity: sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==}
@@ -935,6 +957,10 @@ packages:
peerDependencies:
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
acorn-walk@8.3.4:
resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==}
engines: {node: '>=0.4.0'}
acorn@8.15.0:
resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
engines: {node: '>=0.4.0'}
@@ -954,6 +980,9 @@ packages:
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
engines: {node: '>=8'}
arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
@@ -1110,6 +1139,9 @@ packages:
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
create-require@1.1.1:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
cross-spawn@7.0.6:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
@@ -1186,6 +1218,10 @@ packages:
devlop@1.1.0:
resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
diff@4.0.2:
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
engines: {node: '>=0.3.1'}
doctrine@2.1.0:
resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
engines: {node: '>=0.10.0'}
@@ -1870,6 +1906,9 @@ packages:
magic-string@0.30.18:
resolution: {integrity: sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==}
make-error@1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
markdown-extensions@2.0.0:
resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==}
engines: {node: '>=16'}
@@ -2587,6 +2626,20 @@ packages:
peerDependencies:
typescript: '>=4.8.4'
ts-node@10.9.2:
resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==}
hasBin: true
peerDependencies:
'@swc/core': '>=1.2.50'
'@swc/wasm': '>=1.2.50'
'@types/node': '*'
typescript: '>=2.7'
peerDependenciesMeta:
'@swc/core':
optional: true
'@swc/wasm':
optional: true
tsconfig-paths@3.15.0:
resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==}
@@ -2672,6 +2725,9 @@ packages:
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
v8-compile-cache-lib@3.0.1:
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
vfile-message@4.0.3:
resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
@@ -2713,6 +2769,10 @@ packages:
resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
engines: {node: '>=18'}
yn@3.1.1:
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
engines: {node: '>=6'}
yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
@@ -2848,6 +2908,10 @@ snapshots:
'@alloc/quick-lru@5.2.0': {}
'@cspotcode/source-map-support@0.8.1':
dependencies:
'@jridgewell/trace-mapping': 0.3.9
'@emnapi/core@1.4.5':
dependencies:
'@emnapi/wasi-threads': 1.0.4
@@ -3069,6 +3133,11 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
'@jridgewell/trace-mapping@0.3.9':
dependencies:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
'@mdx-js/loader@3.1.0(acorn@8.15.0)':
dependencies:
'@mdx-js/mdx': 3.1.0(acorn@8.15.0)
@@ -3329,6 +3398,14 @@ snapshots:
'@tanstack/virtual-core@3.13.12': {}
'@tsconfig/node10@1.0.11': {}
'@tsconfig/node12@1.0.11': {}
'@tsconfig/node14@1.0.3': {}
'@tsconfig/node16@1.0.4': {}
'@tybys/wasm-util@0.10.0':
dependencies:
tslib: 2.8.1
@@ -3538,6 +3615,10 @@ snapshots:
dependencies:
acorn: 8.15.0
acorn-walk@8.3.4:
dependencies:
acorn: 8.15.0
acorn@8.15.0: {}
ajv@6.12.6:
@@ -3570,6 +3651,8 @@ snapshots:
dependencies:
color-convert: 2.0.1
arg@4.1.3: {}
argparse@2.0.1: {}
aria-query@5.3.2: {}
@@ -3740,6 +3823,8 @@ snapshots:
concat-map@0.0.1: {}
create-require@1.1.1: {}
cross-spawn@7.0.6:
dependencies:
path-key: 3.1.1
@@ -3814,6 +3899,8 @@ snapshots:
dependencies:
dequal: 2.0.3
diff@4.0.2: {}
doctrine@2.1.0:
dependencies:
esutils: 2.0.3
@@ -4680,6 +4767,8 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
make-error@1.3.6: {}
markdown-extensions@2.0.0: {}
markdown-table@3.0.4: {}
@@ -5736,6 +5825,24 @@ snapshots:
dependencies:
typescript: 5.9.2
ts-node@10.9.2(@types/node@24.3.0)(typescript@5.9.2):
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.11
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4
'@types/node': 24.3.0
acorn: 8.15.0
acorn-walk: 8.3.4
arg: 4.1.3
create-require: 1.1.1
diff: 4.0.2
make-error: 1.3.6
typescript: 5.9.2
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
tsconfig-paths@3.15.0:
dependencies:
'@types/json5': 0.0.29
@@ -5885,6 +5992,8 @@ snapshots:
util-deprecate@1.0.2: {}
v8-compile-cache-lib@3.0.1: {}
vfile-message@4.0.3:
dependencies:
'@types/unist': 3.0.3
@@ -5948,6 +6057,8 @@ snapshots:
yallist@5.0.0: {}
yn@3.1.1: {}
yocto-queue@0.1.0: {}
zustand@5.0.8(@types/react@19.1.11)(react@19.1.1)(use-sync-external-store@1.5.0(react@19.1.1)):

View File

@@ -66,7 +66,7 @@ function Eyebrow({
)}
{apilevel && acl && (
<span className="font-bold text-xs text-green-300 mb-0.5">
<span className="font-bold text-xs text-green-500 dark:text-green-300 mb-0.5">
ACL: <span className="ml-1 font-mono text-zinc-900 dark:text-zinc-100">{acl}</span>
</span>
)}

View File

@@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "es6",
"target": "es2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
@@ -23,6 +23,6 @@
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "generator/index.ts"],
"exclude": ["node_modules"]
}