Fix pretty doc

This commit is contained in:
CEC 2022-04-28 11:51:55 +02:00
parent 53b084ea7f
commit d6450831c6
7 changed files with 205 additions and 101 deletions

View File

@ -1,5 +1,5 @@
import { z } from "zod";
import {extendApi} from "@anatine/zod-openapi";
import { extendApi } from "@anatine/zod-openapi";
/*
* WARNING! The original file is in /messages/JsonMessages.
@ -8,10 +8,16 @@ import {extendApi} from "@anatine/zod-openapi";
export const isAdminApiData = z.object({
// @ts-ignore
userUuid: extendApi(z.string(), {example: '998ce839-3dea-4698-8b41-ebbdf7688ad9'}),
email: extendApi(z.nullable(z.string()), {description: 'The email of the current user.', example: 'example@workadventu.re'}),
roomUrl: extendApi(z.string(), {example: '/@/teamSlug/worldSlug/roomSlug'}),
mapUrlStart: extendApi(z.string(), {description: 'The full URL to the JSON map file', example: 'https://myuser.github.io/myrepo/map.json'}),
userUuid: extendApi(z.string(), { example: "998ce839-3dea-4698-8b41-ebbdf7688ad9" }),
email: extendApi(z.nullable(z.string()), {
description: "The email of the current user.",
example: "example@workadventu.re",
}),
roomUrl: extendApi(z.string(), { example: "/@/teamSlug/worldSlug/roomSlug" }),
mapUrlStart: extendApi(z.string(), {
description: "The full URL to the JSON map file",
example: "https://myuser.github.io/myrepo/map.json",
}),
messages: z.optional(z.array(z.unknown())),
});

View File

@ -1,5 +1,5 @@
import { z } from "zod";
import {extendApi} from "@anatine/zod-openapi";
import { extendApi } from "@anatine/zod-openapi";
/*
* WARNING! The original file is in /messages/JsonMessages.
@ -10,60 +10,120 @@ export const isErrorApiErrorData = extendApi(
// @ts-ignore
z.object({
type: z.literal("error"),
code: extendApi(z.string(), {description: 'The system code of an error, it must be in SCREAMING_SNAKE_CASE.', example: 'ROOM_NOT_FOUND'}),
title: extendApi(z.string(), {description: "Big title displayed on the error screen.", example: "ERROR"}),
subtitle: extendApi(z.string(), {description: "Subtitle displayed to let the user know what is the main subject of the error.", example: "The room was not found."}),
details: extendApi(z.string(), {description: "Some others details on what the user can do if he don't understand the error.", example: "If you would like more information, you can contact the administrator or us at example@workadventu.re."}),
image: extendApi(z.string(), {description: "The URL of the image displayed just under the logo in the error screen.", example: 'https://example.com/error.png'}),
code: extendApi(z.string(), {
description: "The system code of an error, it must be in SCREAMING_SNAKE_CASE.",
example: "ROOM_NOT_FOUND",
}),
title: extendApi(z.string(), { description: "Big title displayed on the error screen.", example: "ERROR" }),
subtitle: extendApi(z.string(), {
description: "Subtitle displayed to let the user know what is the main subject of the error.",
example: "The room was not found.",
}),
details: extendApi(z.string(), {
description: "Some others details on what the user can do if he don't understand the error.",
example:
"If you would like more information, you can contact the administrator or us at example@workadventu.re.",
}),
image: extendApi(z.string(), {
description: "The URL of the image displayed just under the logo in the error screen.",
example: "https://example.com/error.png",
}),
}),
{
description: 'This is an error that can be returned by the API, its type must be equal to "error".\n If such an error is caught, an error screen will be displayed.',
description:
'This is an error that can be returned by the API, its type must be equal to "error".\n If such an error is caught, an error screen will be displayed.',
}
);
export const isErrorApiRetryData = extendApi(
z.object({
type: z.literal("retry"),
code: extendApi(z.string(), {description: 'The system code of an error, it must be in SCREAMING_SNAKE_CASE. \n It will not be displayed to the user.', example: 'WORLD_FULL'}),
title: extendApi(z.string(), {description: "Big title displayed on the error screen.", example: "ERROR"}),
subtitle: extendApi(z.string(), {description: "Subtitle displayed to let the user know what is the main subject of the error.", example: "Too successful, your WorkAdventure world is full!"}),
details: extendApi(z.string(), {description: "Some others details on what the user can do if he don't understand the error.", example: "New automatic attempt in 30 seconds"}),
image: extendApi(z.string(), {description: "The URL of the image displayed just under the logo in the waiting screen.", example: 'https://example.com/wait.png'}),
buttonTitle: extendApi(z.optional(z.nullable(z.string())), {description: "If this is not defined the button and the parameter canRetryManual is set to true, the button will be not displayed at all.", example: "Retry"}),
timeToRetry: extendApi(z.number(), {description: "This is the time (in millisecond) between the next auto refresh of the page.", example: 30_000}),
canRetryManual: extendApi(z.boolean(), {description: "This boolean show or hide the button to let the user refresh manually the current page.", example: true}),
code: extendApi(z.string(), {
description:
"The system code of an error, it must be in SCREAMING_SNAKE_CASE. \n It will not be displayed to the user.",
example: "WORLD_FULL",
}),
title: extendApi(z.string(), { description: "Big title displayed on the error screen.", example: "ERROR" }),
subtitle: extendApi(z.string(), {
description: "Subtitle displayed to let the user know what is the main subject of the error.",
example: "Too successful, your WorkAdventure world is full!",
}),
details: extendApi(z.string(), {
description: "Some others details on what the user can do if he don't understand the error.",
example: "New automatic attempt in 30 seconds",
}),
image: extendApi(z.string(), {
description: "The URL of the image displayed just under the logo in the waiting screen.",
example: "https://example.com/wait.png",
}),
buttonTitle: extendApi(z.optional(z.nullable(z.string())), {
description:
"If this is not defined the button and the parameter canRetryManual is set to true, the button will be not displayed at all.",
example: "Retry",
}),
timeToRetry: extendApi(z.number(), {
description: "This is the time (in millisecond) between the next auto refresh of the page.",
example: 30_000,
}),
canRetryManual: extendApi(z.boolean(), {
description: "This boolean show or hide the button to let the user refresh manually the current page.",
example: true,
}),
}),
{
description: 'This is an error that can be returned by the API, its type must be equal to "retry".\n' +
'If such an error is caught, a waiting screen will be displayed.',
description:
'This is an error that can be returned by the API, its type must be equal to "retry".\n' +
"If such an error is caught, a waiting screen will be displayed.",
}
);
export const isErrorApiRedirectData = extendApi(
z.object({
type: z.literal("redirect"),
urlToRedirect: extendApi(z.string(), {description: 'A URL specified to redirect the user onto it directly', example: '/contact-us'}),
urlToRedirect: extendApi(z.string(), {
description: "A URL specified to redirect the user onto it directly",
example: "/contact-us",
}),
}),
{
description: 'This is an error that can be returned by the API, its type must be equal to "redirect".\n' +
'If such an error is caught, the user will be automatically redirected to urlToRedirect.',
description:
'This is an error that can be returned by the API, its type must be equal to "redirect".\n' +
"If such an error is caught, the user will be automatically redirected to urlToRedirect.",
}
);
export const isErrorApiUnauthorizedData = extendApi(
z.object({
type: z.literal("unauthorized"),
code: extendApi(z.string(), {description: "This is the system code of an error, it must be in SCREAMING_SNAKE_CASE.", example: "USER_ACCESS_FORBIDDEN"}),
title: extendApi(z.string(), {description: "Big title displayed on the error screen.", example: "ERROR"}),
subtitle: extendApi(z.string(), {description: "Subtitle displayed to let the user know what is the main subject of the error.", example: "You can't access this place."}),
details: extendApi(z.string(), {description: "Some others details on what the user can do if he don't understand the error.", example: "If you would like more information, you can contact the administrator or us at example@workadventu.re."}),
image: extendApi(z.string(), {description: "The URL of the image displayed just under the logo in the error screen.", example: 'https://example.com/error.png'}),
buttonTitle: extendApi(z.optional(z.nullable(z.string())), {description: "If this is not defined the button to logout will be not displayed.", example: "Log out"}),
code: extendApi(z.string(), {
description: "This is the system code of an error, it must be in SCREAMING_SNAKE_CASE.",
example: "USER_ACCESS_FORBIDDEN",
}),
title: extendApi(z.string(), { description: "Big title displayed on the error screen.", example: "ERROR" }),
subtitle: extendApi(z.string(), {
description: "Subtitle displayed to let the user know what is the main subject of the error.",
example: "You can't access this place.",
}),
details: extendApi(z.string(), {
description: "Some others details on what the user can do if he don't understand the error.",
example:
"If you would like more information, you can contact the administrator or us at example@workadventu.re.",
}),
image: extendApi(z.string(), {
description: "The URL of the image displayed just under the logo in the error screen.",
example: "https://example.com/error.png",
}),
buttonTitle: extendApi(z.optional(z.nullable(z.string())), {
description: "If this is not defined the button to logout will be not displayed.",
example: "Log out",
}),
}),
{
description: 'This is an error that can be returned by the API, its type must be equal to "unauthorized".\n' +
'If such an error is caught, an error screen will be displayed with a button to let him logout and go to login page.',
});
description:
'This is an error that can be returned by the API, its type must be equal to "unauthorized".\n' +
"If such an error is caught, an error screen will be displayed with a button to let him logout and go to login page.",
}
);
export const isErrorApiData = z.discriminatedUnion("type", [
isErrorApiErrorData,

View File

@ -1,5 +1,5 @@
import { z } from "zod";
import {extendApi} from "@anatine/zod-openapi";
import { extendApi } from "@anatine/zod-openapi";
/*
* WARNING! The original file is in /messages/JsonMessages.
@ -8,20 +8,47 @@ import {extendApi} from "@anatine/zod-openapi";
export const isMapDetailsData = z.object({
// @ts-ignore
mapUrl: extendApi(z.string(), {description: 'The full URL to the JSON map file', example: 'https://myuser.github.io/myrepo/map.json'}),
authenticationMandatory: extendApi(z.optional(z.nullable(z.boolean())), {description: 'Whether the authentication is mandatory or not for this map', example: true}),
group: extendApi(z.nullable(z.string()), {description: 'The group this room is part of (maps the notion of "world" in WorkAdventure SAAS)', example: 'myorg/myworld'}),
mapUrl: extendApi(z.string(), {
description: "The full URL to the JSON map file",
example: "https://myuser.github.io/myrepo/map.json",
}),
authenticationMandatory: extendApi(z.optional(z.nullable(z.boolean())), {
description: "Whether the authentication is mandatory or not for this map",
example: true,
}),
group: extendApi(z.nullable(z.string()), {
description: 'The group this room is part of (maps the notion of "world" in WorkAdventure SAAS)',
example: "myorg/myworld",
}),
contactPage: extendApi(z.optional(z.nullable(z.string())), {description: 'The URL to the contact page', example: 'https://mycompany.com/contact-us'}),
iframeAuthentication: extendApi(z.optional(z.nullable(z.string())), {description: 'The URL of the authentication Iframe', example: 'https://mycompany.com/authc'}),
contactPage: extendApi(z.optional(z.nullable(z.string())), {
description: "The URL to the contact page",
example: "https://mycompany.com/contact-us",
}),
iframeAuthentication: extendApi(z.optional(z.nullable(z.string())), {
description: "The URL of the authentication Iframe",
example: "https://mycompany.com/authc",
}),
// The date (in ISO 8601 format) at which the room will expire
expireOn: extendApi(z.optional(z.string()), {description: 'The date (in ISO 8601 format) at which the room will expire', example: '2022-11-05T08:15:30-05:00'}),
expireOn: extendApi(z.optional(z.string()), {
description: "The date (in ISO 8601 format) at which the room will expire",
example: "2022-11-05T08:15:30-05:00",
}),
// Whether the "report" feature is enabled or not on this room
canReport: extendApi(z.optional(z.boolean()), {description: 'Whether the "report" feature is enabled or not on this room', example: true}),
canReport: extendApi(z.optional(z.boolean()), {
description: 'Whether the "report" feature is enabled or not on this room',
example: true,
}),
// The URL of the logo image on the loading screen
loadingLogo: extendApi(z.optional(z.nullable(z.string())), {description: 'The URL of the image to be used on the loading page', example: 'https://example.com/logo.png'}),
loadingLogo: extendApi(z.optional(z.nullable(z.string())), {
description: "The URL of the image to be used on the loading page",
example: "https://example.com/logo.png",
}),
// The URL of the logo image on "LoginScene"
loginSceneLogo: extendApi(z.optional(z.nullable(z.string())), {description: 'The URL of the image to be used on the LoginScene', example: 'https://example.com/logo_login.png'}),
loginSceneLogo: extendApi(z.optional(z.nullable(z.string())), {
description: "The URL of the image to be used on the LoginScene",
example: "https://example.com/logo_login.png",
}),
});
export type MapDetailsData = z.infer<typeof isMapDetailsData>;

View File

@ -33,27 +33,27 @@ export class SwaggerController extends BaseHttpController {
info: {
title: "WorkAdventure Pusher",
version: "1.0.0",
description: "This is a documentation about the endpoints called by the pusher. \n You can find out more about WorkAdventure on [github](https://github.com/thecodingmachine/workadventure).",
contact:
{
email: "hello@workadventu.re"
}
description:
"This is a documentation about the endpoints called by the pusher. \n You can find out more about WorkAdventure on [github](https://github.com/thecodingmachine/workadventure).",
contact: {
email: "hello@workadventu.re",
},
},
"host": "pusher." + ADMIN_URL.replace('//',''),
"tags": [
host: "pusher." + ADMIN_URL.replace("//", ""),
tags: [
{
"name": "AdminAPI",
"description": "Access to end points of the admin from the pusher"
name: "AdminAPI",
description: "Access to end points of the admin from the pusher",
},
],
"securityDefinitions": {
"Bearer": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
securityDefinitions: {
Bearer: {
type: "apiKey",
name: "Authorization",
in: "header",
},
},
...SwaggerGenerator.definitions()
...SwaggerGenerator.definitions(),
},
apis: ["./src/Services/*.ts"],
};
@ -81,11 +81,14 @@ export class SwaggerController extends BaseHttpController {
}
const urls = [
{url: "/openapi/pusher", name: "Front -> Pusher"},
{url: "/openapi/admin", name: "Pusher <- Admin"},
{ url: "/openapi/pusher", name: "Front -> Pusher" },
{ url: "/openapi/admin", name: "Pusher <- Admin" },
];
const result = data.replace(/url: "https:\/\/petstore\.swagger\.io\/v2\/swagger.json"/g, `urls: ${JSON.stringify(urls)}, "urls.primaryName": "Pusher <- Admin"`);
const result = data.replace(
/url: "https:\/\/petstore\.swagger\.io\/v2\/swagger.json"/g,
`urls: ${JSON.stringify(urls)}, "urls.primaryName": "Pusher <- Admin"`
);
response.send(result);
return;

View File

@ -1,5 +1,5 @@
import { z } from "zod";
import {extendApi} from "@anatine/zod-openapi";
import { extendApi } from "@anatine/zod-openapi";
export const isBanBannedAdminMessageInterface = z.object({
type: z.enum(["ban", "banned"]),
@ -9,7 +9,7 @@ export const isBanBannedAdminMessageInterface = z.object({
export const isUserMessageAdminMessageInterface = z.object({
event: z.enum(["user-message"]),
message: extendApi(isBanBannedAdminMessageInterface, {$ref: "#/definitions/BanBannedAdminMessageInterface"}),
message: extendApi(isBanBannedAdminMessageInterface, { $ref: "#/definitions/BanBannedAdminMessageInterface" }),
world: z.string(),
jwt: z.string(),
});

View File

@ -9,7 +9,7 @@ import qs from "qs";
import { AdminInterface } from "./AdminInterface";
import { AuthTokenData, jwtTokenManager } from "./JWTTokenManager";
import { InvalidTokenError } from "../Controller/InvalidTokenError";
import {extendApi} from "@anatine/zod-openapi";
import { extendApi } from "@anatine/zod-openapi";
export interface AdminBannedData {
is_banned: boolean;
@ -18,15 +18,30 @@ export interface AdminBannedData {
export const isFetchMemberDataByUuidResponse = z.object({
// @ts-ignore
email: extendApi(z.string(), {description: 'The email of the fetched user, it can be an email, an uuid or undefined.', example: "example@workadventu.re"}),
userUuid: extendApi(z.string(), {description: 'The uuid of the fetched user, it can be an email, an uuid or undefined.', example: "998ce839-3dea-4698-8b41-ebbdf7688ad9"}),
tags: extendApi(z.array(z.string()), {description: 'List of tags related to the user fetched.', example: ['editor']}),
visitCardUrl: extendApi(z.nullable(z.string()), {description: 'URL of the visitCard of the user fetched.', example: 'https://mycompany.com/contact/me'}),
textures: extendApi(z.array(isWokaDetail), {$ref: "#/definitions/WokaDetail"}),
messages: extendApi(z.array(z.unknown()), {description: 'List of user\'s messages.'}),
email: extendApi(z.string(), {
description: "The email of the fetched user, it can be an email, an uuid or undefined.",
example: "example@workadventu.re",
}),
userUuid: extendApi(z.string(), {
description: "The uuid of the fetched user, it can be an email, an uuid or undefined.",
example: "998ce839-3dea-4698-8b41-ebbdf7688ad9",
}),
tags: extendApi(z.array(z.string()), {
description: "List of tags related to the user fetched.",
example: ["editor"],
}),
visitCardUrl: extendApi(z.nullable(z.string()), {
description: "URL of the visitCard of the user fetched.",
example: "https://mycompany.com/contact/me",
}),
textures: extendApi(z.array(isWokaDetail), { $ref: "#/definitions/WokaDetail" }),
messages: extendApi(z.array(z.unknown()), { description: "List of user's messages." }),
anonymous: extendApi(z.optional(z.boolean()), {description: 'Whether the user if logged as anonymous or not', example: false}),
userRoomToken: extendApi(z.optional(z.string()), {description: '', example: ''}),
anonymous: extendApi(z.optional(z.boolean()), {
description: "Whether the user if logged as anonymous or not",
example: false,
}),
userRoomToken: extendApi(z.optional(z.string()), { description: "", example: "" }),
});
export type FetchMemberDataByUuidResponse = z.infer<typeof isFetchMemberDataByUuidResponse>;

View File

@ -1,40 +1,33 @@
import {generateSchema} from "@anatine/zod-openapi";
import {isAdminApiData} from "../Messages/JsonMessages/AdminApiData";
import { generateSchema } from "@anatine/zod-openapi";
import { isAdminApiData } from "../Messages/JsonMessages/AdminApiData";
import {
isErrorApiErrorData,
isErrorApiRedirectData,
isErrorApiRetryData,
isErrorApiUnauthorizedData
isErrorApiUnauthorizedData,
} from "../Messages/JsonMessages/ErrorApiData";
import {isMapDetailsData} from "../Messages/JsonMessages/MapDetailsData";
import {isRegisterData} from "../Messages/JsonMessages/RegisterData";
import {isRoomRedirect} from "../Messages/JsonMessages/RoomRedirect";
import {isFetchMemberDataByUuidResponse} from "./AdminApi";
import {
isBanBannedAdminMessageInterface, isListenRoomsMessageInterface,
isUserMessageAdminMessageInterface
} from "../Model/Websocket/Admin/AdminMessages";
import {isWokaDetail} from "../Messages/JsonMessages/PlayerTextures";
import { isMapDetailsData } from "../Messages/JsonMessages/MapDetailsData";
import { isFetchMemberDataByUuidResponse } from "./AdminApi";
import { isWokaDetail } from "../Messages/JsonMessages/PlayerTextures";
class SwaggerGenerator {
definitions() {
return {
definitions:
{
AdminApiData: generateSchema(isAdminApiData),
//BanBannedAdminMessageInterface: generateSchema(isBanBannedAdminMessageInterface),
ErrorApiErrorData: generateSchema(isErrorApiErrorData),
ErrorApiRedirectData: generateSchema(isErrorApiRedirectData),
ErrorApiRetryData: generateSchema(isErrorApiRetryData),
ErrorApiUnauthorizedData: generateSchema(isErrorApiUnauthorizedData),
FetchMemberDataByUuidResponse: generateSchema(isFetchMemberDataByUuidResponse),
//ListenRoomsMessageInterface: generateSchema(isListenRoomsMessageInterface),
MapDetailsData: generateSchema(isMapDetailsData),
//RegisterData: generateSchema(isRegisterData),
//RoomRedirect: generateSchema(isRoomRedirect),
//UserMessageAdminMessageInterface: generateSchema(isUserMessageAdminMessageInterface),
WokaDetail: generateSchema(isWokaDetail),
}
definitions: {
AdminApiData: generateSchema(isAdminApiData),
//BanBannedAdminMessageInterface: generateSchema(isBanBannedAdminMessageInterface),
ErrorApiErrorData: generateSchema(isErrorApiErrorData),
ErrorApiRedirectData: generateSchema(isErrorApiRedirectData),
ErrorApiRetryData: generateSchema(isErrorApiRetryData),
ErrorApiUnauthorizedData: generateSchema(isErrorApiUnauthorizedData),
FetchMemberDataByUuidResponse: generateSchema(isFetchMemberDataByUuidResponse),
//ListenRoomsMessageInterface: generateSchema(isListenRoomsMessageInterface),
MapDetailsData: generateSchema(isMapDetailsData),
//RegisterData: generateSchema(isRegisterData),
//RoomRedirect: generateSchema(isRoomRedirect),
//UserMessageAdminMessageInterface: generateSchema(isUserMessageAdminMessageInterface),
WokaDetail: generateSchema(isWokaDetail),
},
};
}
}