1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-12-22 19:07:54 +01:00

fix: Fix broken OpenAPI (#2379)

## What

This change removes the use of double quotes in the
'addPublicSignupTokenUser' endpoint summary. It also changes the
original summary to a description and adds a new, shorter summary.

## Why

The OpenAPI / docusaurus integration errors out (refer to [this failed
build](https://github.com/Unleash/unleash/actions/runs/3434792557/jobs/5726445104))
if the frontmatter contains invalid characters. In this case, it's
because the automatic sidebar label contains double quotes, which it
interprets as a new key having been declared:

```
Error:  Error while parsing Markdown front matter.
This can happen if you use special characters in front matter values (try using double quotes around that value).
Error:  Loading of version failed for version current
Error:  Unable to build website for locale en.
Error:  YAMLException: can not read a block mapping entry; a multiline key may not be an implicit key at line 4, column 12:
    description: "Create a user with the 'viewe ...
               ^
```

For some reason, I cannot reproduce this error locally. Instead, the
generation goes as expected.

---

Regarding using description instead of summary: summaries should be very
short and sweet, especially because they're also used in the generated
sidebar. Descriptions can be a bit wordier, so I added a shorter summary
for going forward.

## Generated output

This is what the old configuration would generate. Notice the
`sidedar_label` key on line 2:

```md
---
id: add-public-signup-token-user
sidebar_label: Create a user with the "viewer" root role and link them to a signup token
hide_title: true
hide_table_of_contents: true
api: {'tags': ['Public signup tokens'], 'operationId': 'addPublicSignupTokenUser', 'requestBody': {'description': 'createInvitedUserSchema', 'required': true, 'content': {'application/json': {'schema': {'type': 'object', 'additionalProperties': false, 'required': ['email', 'name', 'password'], 'properties': {'username': { 'type': 'string' }, 'email': { 'type': 'string' }, 'name': { 'type': 'string' }, 'password': { 'type': 'string' },},},},},}, 'responses': {'200': {'description': 'userSchema', 'content': {'application/json': {'schema': {'type': 'object', 'additionalProperties': false, 'required': ['id'], 'properties': {'id': {'type': 'number',}, 'isAPI': {'type': 'boolean',}, 'name': {'type': 'string',}, 'email': {'type': 'string',}, 'username': {'type': 'string',}, 'imageUrl': {'type': 'string',}, 'inviteLink': {'type': 'string',}, 'loginAttempts': {'type': 'number',}, 'emailSent': {'type': 'boolean',}, 'rootRole': {'type': 'number',}, 'seenAt': {'type': 'string', 'format': 'date-time', 'nullable': true,}, 'createdAt': {'type': 'string', 'format': 'date-time',},},},},},}, '400': {'description': 'The request data does not match what we expect.',}, '409': {'description': 'The provided resource can not be created or updated because it would conflict with the current state of the resource or with an already existing resource, respectively.',},}, 'parameters': [{'name': 'token', 'in': 'path', 'required': true, 'schema': { 'type': 'string' },},], 'description': 'Create a user with the "viewer" root role and link them to a signup token', 'method': 'post', 'path': '/invite/{token}/signup', 'servers': [{ 'url': '<your-unleash-url>' }], 'security': [{ 'apiKey': [] }], 'securitySchemes': {'apiKey': {'type': 'apiKey', 'in': 'header', 'name': 'Authorization',},}, 'jsonRequestBodyExample': {'username': 'string', 'email': 'string', 'name': 'string', 'password': 'string',}, 'info': { 'title': 'Unleash API', 'version': '4.17.2' }, 'postman': {'name': 'Create a user with the "viewer" root role and link them to a signup token', 'description': { 'type': 'text/plain' }, 'url': {'path': ['invite', ':token', 'signup'], 'host': ['{{baseUrl}}'], 'query': [], 'variable': [{'disabled': false, 'description': {'content': '(Required) ', 'type': 'text/plain',}, 'type': 'any', 'value': '', 'key': 'token',},],}, 'header': [{ 'key': 'Content-Type', 'value': 'application/json' }, { 'key': 'Accept', 'value': 'application/json' },], 'method': 'POST', 'body': {'mode': 'raw', 'raw': '""', 'options': { 'raw': { 'language': 'json' } }}}}
sidebar_class_name: 'post api-method'
info_path: docs/reference/api/unleash/unleash-api
---

import ApiTabs from "@theme/ApiTabs"; import MimeTabs from "@theme/MimeTabs"; import ParamsItem from "@theme/ParamsItem"; import ResponseSamples from "@theme/ResponseSamples"; import SchemaItem from "@theme/SchemaItem" import SchemaTabs from "@theme/SchemaTabs"; import DiscriminatorTabs from "@theme/DiscriminatorTabs"; import TabItem from "@theme/TabItem";

## Create a user with the &quot;viewer&quot; root role and link them to a signup token

Create a user with the &quot;viewer&quot; root role and link them to a signup token

<!-- And much much more! -->
```
This commit is contained in:
Thomas Heartman 2022-11-10 22:55:01 +01:00 committed by GitHub
parent 3f78bc93d8
commit 665638b9da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 6 deletions

View File

@ -2,7 +2,7 @@ export const endpointDescriptions = {
admin: { admin: {
events: { events: {
description: description:
'Returns **the last 100** from the Unleash instance when called without a query parameter. When called with a `project` parameter, returns **all events** for the specified project.\n\nIf the provided project does not exist, the list of events will be empty.', 'Returns **the last 100** events from the Unleash instance when called without a query parameter. When called with a `project` parameter, returns **all events** for the specified project.\n\nIf the provided project does not exist, the list of events will be empty.',
summary: summary:
'Get the most recent events from the Unleash instance or all events related to a project.', 'Get the most recent events from the Unleash instance or all events related to a project.',
}, },

View File

@ -70,8 +70,9 @@ export class PublicInviteController extends Controller {
openApiService.validPath({ openApiService.validPath({
tags: ['Public signup tokens'], tags: ['Public signup tokens'],
operationId: 'addPublicSignupTokenUser', operationId: 'addPublicSignupTokenUser',
summary: summary: 'Add a user via a signup token',
'Create a user with the "viewer" root role and link them to a signup token', description:
'Create a user with the viewer root role and link them to the provided signup token',
requestBody: createRequestSchema('createInvitedUserSchema'), requestBody: createRequestSchema('createInvitedUserSchema'),
responses: { responses: {
200: createResponseSchema('userSchema'), 200: createResponseSchema('userSchema'),

View File

@ -4304,7 +4304,7 @@ exports[`should serve the OpenAPI spec 1`] = `
}, },
"/api/admin/events": { "/api/admin/events": {
"get": { "get": {
"description": "Returns **the last 100** from the Unleash instance when called without a query parameter. When called with a \`project\` parameter, returns **all events** for the specified project. "description": "Returns **the last 100** events from the Unleash instance when called without a query parameter. When called with a \`project\` parameter, returns **all events** for the specified project.
If the provided project does not exist, the list of events will be empty.", If the provided project does not exist, the list of events will be empty.",
"operationId": "getEvents", "operationId": "getEvents",
@ -7364,6 +7364,7 @@ If the provided project does not exist, the list of events will be empty.",
}, },
"/invite/{token}/signup": { "/invite/{token}/signup": {
"post": { "post": {
"description": "Create a user with the viewer root role and link them to the provided signup token",
"operationId": "addPublicSignupTokenUser", "operationId": "addPublicSignupTokenUser",
"parameters": [ "parameters": [
{ {
@ -7404,7 +7405,7 @@ If the provided project does not exist, the list of events will be empty.",
"description": "The provided resource can not be created or updated because it would conflict with the current state of the resource or with an already existing resource, respectively.", "description": "The provided resource can not be created or updated because it would conflict with the current state of the resource or with an already existing resource, respectively.",
}, },
}, },
"summary": "Create a user with the "viewer" root role and link them to a signup token", "summary": "Add a user via a signup token",
"tags": [ "tags": [
"Public signup tokens", "Public signup tokens",
], ],

View File

@ -17,14 +17,27 @@
// save us loooots of questions. // save us loooots of questions.
const replace = require('replace-in-file'); const replace = require('replace-in-file');
const escapeCharacters = (input) => {
unquotedInput =
input.charAt(0) === '"' ? input.substring(1, input.length - 1) : input;
const fixed = unquotedInput.replace(/(?<!\\)"/g, '\\"');
return `"${fixed}"`;
};
const options = { const options = {
files: 'docs/reference/api/**/*.api.mdx', files: 'docs/reference/api/**/*.api.mdx',
from: [ from: [
/\/ushosted/g, /\/ushosted/g,
/"https:\/\/us.app.unleash-hosted.com(\/ushosted)?"/g, /"https:\/\/us.app.unleash-hosted.com(\/ushosted)?"/g,
'"path":["ushosted",', '"path":["ushosted",',
/^(sidebar_label|title): (.+)/gm, // escape potentially unescaped, single-line text fields
],
to: [
'',
'"<your-unleash-url>"',
'"path":[',
(_, key, description) => `${key}: ${escapeCharacters(description)}`,
], ],
to: ['', '"<your-unleash-url>"', '"path":['],
}; };
replace(options); replace(options);