Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/routes/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const createHandleGetApi = (registry: OpenAPIRegistry) => {
def.route.request.query = def.route.request.query.extend({
output: z.string().optional().openapi({
description:
'Use the output value human to receive the JSON results in pretty print format, presented on a HTML page.',
'Request a `human` output to receive the JSON results in pretty print format, presented on a HTML page.',
}),
});

Expand Down Expand Up @@ -151,8 +151,12 @@ export default (app: Hono, registry: OpenAPIRegistry) => {
registry.registerPath({
method: 'get',
path: '/api',
summary: 'Get OpenAPI Specification',
description: 'Returns the OpenAPI specification for the cdnjs API.',
summary: 'Getting the OpenAPI specification for the cdnjs API',
description: [
'The `/api` endpoint will return a JSON object with full OpenAPI specification for the cdnjs API.',
'',
'The cache lifetime on this endpoint is six hours.',
].join('\n'),
tags: ['meta'],
responses: {
200: {
Expand Down
2 changes: 1 addition & 1 deletion src/routes/errors.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ export const errorResponseSchema = z
message: z.string(),
ref: z.string().optional(),
})
.openapi('Error');
.openapi('Error', { description: 'An error response from the cdnjs API' });

export type ErrorResponse = z.infer<typeof errorResponseSchema>;
5 changes: 4 additions & 1 deletion src/routes/libraries.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ export const librariesResponseSchema = z.object({
latest: z.string().nullable(),
}),
)
.openapi('LibraryResult'),
.openapi('LibraryResult', {
description:
'Information about a library on cdnjs when browsing the libraries list',
}),
),
total: z.number(),
available: z.number(),
Expand Down
59 changes: 45 additions & 14 deletions src/routes/libraries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,23 +72,54 @@ export default (app: Hono, registry: OpenAPIRegistry) => {
method: 'get',
path: '/libraries',
summary: 'Browsing all libraries on cdnjs',
description:
'The `/libraries` endpoint will return a JSON object with three top-level properties.\n\nThis API endpoint can also be used to search cdnjs for libraries, by making use of the optional `search` URL query parameter.\n\nThe cache lifetime on this endpoint is six hours.',
description: [
'The `/libraries` endpoint will return a JSON object with key information on all available libraries on cdnjs.',
'',
'This API endpoint can also be used to search cdnjs for specific libraries, by making use of the optional `search` URL query parameter.',
'',
'The cache lifetime on this endpoint is six hours.',
].join('\n'),
tags: ['libraries'],
request: {
query: z.object({
search: z.string().optional().openapi({
description:
"The value to use when searching the libraries index on cdnjs.\n\nLibraries will not be ranked by search relevance when they are returned, they will be ranked using the same ranking as when no search query is provided.\n\n*This ranking is done by Algolia and is primarily based on the number of stars each library's associated GitHub repo has.*",
}),
fields: z.string().optional().openapi({
description:
'Provide a comma-separated string of fields to return in each library object from the cdnjs Algolia index. name and latest will always be present in every object. Any field requested that does not exist will be included in each object with a null value. Currently, the following fields (case-sensitive) are published in the Algolia index for each library and can be requested via this parameter: filename, description, version, keywords, alternativeNames, fileType, github, objectID, license, homepage, repository, author, originalName, sri. The available fields are based on the SearchEntry structure in our tools repo.',
}),
search_fields: z.string().optional().openapi({
description:
'Provide a comma-separated string of fields to be considered when searching for a given search query parameter. Not all fields are supported for this, any unsupported fields given will be silently ignored. Currently, the following fields (case-sensitive) are supported: name, alternativeNames, github.repo, description, keywords, filename, repositories.url, github.user, maintainers.name. The supported fields are controlled by our Algolia settings and are mirrored in the API server libraries route logic.',
}),
search: z
.string()
.optional()
.openapi({
description: [
'The value to use when searching the libraries index on cdnjs.',
'',
'Libraries will not be ranked by search relevance when they are returned, they will be ranked using the same ranking as when no search query is provided.',
'',
"*This ranking is done by Algolia and is primarily based on the number of stars each library's associated GitHub repo has.*",
].join('\n'),
}),
fields: z
.string()
.optional()
.openapi({
description: [
'Provide a comma-separated string of fields to return in each library object from the cdnjs Algolia index.',
'',
'The following fields (case-sensitive) are published in the Algolia index for each library and can be requested via this parameter: `filename`, `description`, `version`, `keywords`, `alternativeNames`, `fileType`, `github`, `objectID`, `license`, `homepage`, `repository`, `author`, `originalName`, `sri`.',
'',
'The `name` and `latest` fields are always returned for each result. If no field are specified, only these fields will be returned. `*` can be provided to return all available fields.',
'',
'*The available fields are based on the [SearchEntry structure in our tools repo](https://github.com/cdnjs/tools/blob/master/cmd/algolia/main.go).*',
].join('\n'),
}),
search_fields: z
.string()
.optional()
.openapi({
description: [
'Provide a comma-separated string of fields to be considered when searching for a given search query parameter.',
'',
'The following fields (case-sensitive) are supported for searching: `name`, `alternativeNames`, `github.repo`, `description`, `keywords`, `filename`, `repositories.url`, `github.user`, `maintainers.name`. Any unsupported fields provided will be silently ignored.',
'',
'*The supported fields are controlled by our Algolia settings and are mirrored in the [API server Algolia libraries logic](https://github.com/cdnjs/api-server/blob/master/src/utils/algolia.ts).*',
].join('\n'),
}),
limit: z.number().optional().openapi({
description:
'Limit the number of library objects that are returned in the results array. This value will be reflected in the total top-level property, but the available property will return the full number with no limit applied.',
Expand Down
9 changes: 7 additions & 2 deletions src/routes/library.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ export const libraryVersionResponseSchema = z
sri: z.record(z.string(), z.string()),
})
.partial()
.openapi('LibraryVersion');
.openapi('LibraryVersion', {
description:
'Information about a specific version of a library on cdnjs',
});

export type LibraryVersionResponse = z.infer<
typeof libraryVersionResponseSchema
Expand All @@ -32,6 +35,8 @@ export const libraryResponseSchema = librarySchema
),
})
.partial()
.openapi('Library');
.openapi('Library', {
description: 'Information about a library on cdnjs',
});

export type LibraryResponse = z.infer<typeof libraryResponseSchema>;
30 changes: 21 additions & 9 deletions src/routes/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,22 +258,27 @@ export default (app: Hono, registry: OpenAPIRegistry) => {
method: 'get',
path: '/libraries/{library}/{version}',
summary: 'Getting a specific version for a library on cdnjs',
description:
'The `/libraries/:library/:version` endpoint returns a JSON object with details specific to a requested version of a library on cdnjs.\n\nThe cache lifetime on this endpoint is 355 days, identical to the CDN. The response is also marked as immutable, as a version on cdnjs will never change once published.\n\ncdnjs only allows access to specific versions of a library, and these are considered immutable. Access to tags for a library, such as `latest`, is not supported as these have a mutable definition, which would go against what cdnjs aims to provide with long-life caching on responses and SRI hashes.',
description: [
'The `/libraries/:library/:version` endpoint returns a JSON object with details specific to a requested version of a library on cdnjs.',
'',
'The cache lifetime on this endpoint is 355 days, identical to the CDN. The response is also marked as immutable, as a version on cdnjs will never change once published.',
'',
'cdnjs only allows access to specific versions of a library, and these are considered immutable. Access to tags for a library, such as `latest`, is not supported as these have a mutable definition, which would go against what cdnjs aims to provide with long-life caching on responses and SRI hashes.',
].join('\n'),
tags: ['libraries'],
request: {
params: z.object({
library: z
.string()
.openapi({ description: 'The name of the library.' }),
.openapi({ description: 'Name of the library.' }),
version: z
.string()
.openapi({ description: 'The version of the library.' }),
.openapi({ description: 'Version of the library.' }),
}),
query: z.object({
fields: z.string().optional().openapi({
description:
'Provide a comma-separated string of fields to return.',
'Provide a comma-separated string of fields to return in the library version object. If no field are specified, all fields will be returned.',
}),
}),
},
Expand Down Expand Up @@ -305,19 +310,26 @@ export default (app: Hono, registry: OpenAPIRegistry) => {
method: 'get',
path: '/libraries/{library}',
summary: 'Getting a specific library on cdnjs',
description:
'Accessing `assets` for all versions of a library using this endpoint is deprecated. The `assets` property now only contains a single entry for the latest version. To access the assets of any version, use the `/libraries/:library/:version` endpoint.\n\nSee [cdnjs/cdnjs issue #14140](https://github.com/cdnjs/cdnjs/issues/14140) for more information.\n\nThe `/libraries/:library` endpoint allows for data on a specific library to be requested and will return a JSON object with all library data properties by default.\n\nThe cache lifetime on this endpoint is six hours.',
description: [
'The `/libraries/:library` endpoint allows for data on a specific library to be requested and will return a JSON object with all library data properties by default.',
'',
'The cache lifetime on this endpoint is six hours.',
'',
'> Accessing `assets` for all versions of a library using this endpoint is deprecated. The `assets` property now only contains a single entry for the latest version. To access the assets of any version, use the `/libraries/:library/:version` endpoint.',
'>',
'> See [cdnjs/cdnjs issue #14140](https://github.com/cdnjs/cdnjs/issues/14140) for more information.',
].join('\n'),
tags: ['libraries'],
request: {
params: z.object({
library: z
.string()
.openapi({ description: 'The name of the library.' }),
.openapi({ description: 'Name of the library.' }),
}),
query: z.object({
fields: z.string().optional().openapi({
description:
'Provide a comma-separated string of fields to return in the library object.',
'Provide a comma-separated string of fields to return in the library object. If no field are specified, all fields will be returned.',
}),
}),
},
Expand Down
9 changes: 6 additions & 3 deletions src/routes/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,17 @@ export default (app: Hono, registry: OpenAPIRegistry) => {
method: 'get',
path: '/stats',
summary: 'Fetch basic statistics for cdnjs',
description:
'The `/stats` endpoint returns a JSON object containing a set of statistics relating to cdnjs.\n\nThe cache lifetime on this endpoint is 6 hours.',
description: [
'The `/stats` endpoint returns a JSON object containing a set of statistics relating to cdnjs.',
'',
'The cache lifetime on this endpoint is 6 hours.',
].join('\n'),
tags: ['meta'],
request: {
query: z.object({
fields: z.string().optional().openapi({
description:
'Provide a comma-separated string of fields to return in the stats object.',
'Provide a comma-separated string of fields to return in the stats object. If no field are specified, all fields will be returned.',
}),
}),
},
Expand Down
9 changes: 6 additions & 3 deletions src/routes/whitelist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,17 @@ export default (app: Hono, registry: OpenAPIRegistry) => {
method: 'get',
path: '/whitelist',
summary: 'Fetch details about the cdnjs file extension whitelist',
description:
'The `/whitelist` endpoint returns a JSON object containing a list of extensions permitted on the CDN as well as categories for those extensions.\n\nThe cache lifetime on this endpoint is 6 hours.',
description: [
'The `/whitelist` endpoint returns a JSON object containing a list of extensions permitted on the CDN as well as categories for those extensions.',
'',
'The cache lifetime on this endpoint is 6 hours.',
].join('\n'),
tags: ['meta'],
request: {
query: z.object({
fields: z.string().optional().openapi({
description:
'Provide a comma-separated string of fields to return from the available whitelist data.',
'Provide a comma-separated string of fields to return from the available whitelist data. If no field are specified, all fields will be returned.',
}),
}),
},
Expand Down
20 changes: 20 additions & 0 deletions src/utils/jsx/islands/swagger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const mixins = {
padding: ${theme.spacing(1.5, 2)} !important;
border-radius: ${theme.radius};
font-size: ${theme.font.small.size};
font-weight: ${theme.font.small.weight};
margin: 0;
display: block;
width: 100%;
Expand All @@ -27,6 +28,7 @@ const mixins = {
padding: ${theme.spacing(0.25, 0.75)};
border-radius: ${theme.radius};
font-size: ${theme.font.small.size};
font-weight: ${theme.font.small.weight};
`,
body: css`
padding: ${theme.spacing(1.5, 2)};
Expand Down Expand Up @@ -61,6 +63,18 @@ const styles = {
}
}

blockquote {
background: rgb(from ${theme.background.brand} r g b / 0.05);
border: 1px solid ${theme.background.brand};
border-radius: ${theme.radius};
margin: ${theme.spacing(1, 0)};
padding: ${theme.spacing(0, 2)};

p {
margin: ${theme.spacing(1.5, 0)};
}
}

/* Remove the default styling of operation sections. */
.opblock {
margin: 0;
Expand Down Expand Up @@ -161,6 +175,10 @@ const styles = {
/* Make the response schema models match the example value code. */
.model {
font-size: ${theme.font.small.size};

.description {
display: none;
}
}
.model-example .model-box {
${mixins.pre};
Expand Down Expand Up @@ -493,6 +511,7 @@ const plugin = (system: System) => ({
if (!entry) return null;

const [name, schema] = entry;
const { description } = schema.toObject();
const fullPath = [...specPathBase, name];
const expanded = system.layoutSelectors.isShown(
fullPath,
Expand All @@ -515,6 +534,7 @@ const plugin = (system: System) => ({
expanded={expanded}
>
<code>{name}</code>
{description}
</Summary>
{expanded && (
<div className={mixins.body}>
Expand Down