impr: use tsrest for psa endpoints (@fehmer) (#5712)

!nuf
This commit is contained in:
Christian Fehmer 2024-08-08 15:10:26 +02:00 committed by GitHub
parent 657d305abc
commit f6ec006507
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 289 additions and 63 deletions

View file

@ -0,0 +1,64 @@
import request from "supertest";
import app from "../../../src/app";
import * as PsaDal from "../../../src/dal/psa";
import { ObjectId } from "mongodb";
const mockApp = request(app);
describe("Psa Controller", () => {
describe("get psa", () => {
const getPsaMock = vi.spyOn(PsaDal, "get");
afterEach(() => {
getPsaMock.mockReset();
});
it("get psas without authorization", async () => {
//GIVEN
const psaOne: PsaDal.DBPSA = {
_id: new ObjectId(),
message: "test2",
date: 1000,
level: 1,
sticky: true,
};
const psaTwo: PsaDal.DBPSA = {
_id: new ObjectId(),
message: "test2",
date: 2000,
level: 2,
sticky: false,
};
getPsaMock.mockResolvedValue([psaOne, psaTwo]);
//WHEN
const { body } = await mockApp.get("/psas").expect(200);
//THEN
expect(body).toEqual({
message: "PSAs retrieved",
data: [
{
_id: psaOne._id.toHexString(),
date: 1000,
level: 1,
message: "test2",
sticky: true,
},
{
_id: psaTwo._id.toHexString(),
date: 2000,
level: 2,
message: "test2",
sticky: false,
},
],
});
});
it("get psas with authorization", async () => {
await mockApp
.get("/psas")
.set("authorization", `Uid 123456789`)
.expect(200);
});
});
});

View file

@ -649,5 +649,8 @@ describe("Misc Utils", () => {
},
]);
});
it("handles undefined", () => {
expect(misc.replaceObjectIds(undefined as any)).toBeUndefined();
});
});
});

View file

@ -16,7 +16,7 @@
"knip": "knip",
"docker-db-only": "docker compose -f docker/compose.db-only.yml up",
"docker": "docker compose -f docker/compose.yml up",
"gen-docs": "tsx scripts/openapi.ts dist/static/api/openapi.json && redocly build-docs -o dist/static/api/internal.html internal@v2 && redocly bundle -o dist/static/api/public.json public-filter && redocly build-docs -o dist/static/api/public.html public@v2"
"gen-docs": "tsx scripts/openapi.ts dist/static/api/openapi.json && openapi-recursive-tagging dist/static/api/openapi.json dist/static/api/openapi-tagged.json && redocly build-docs -o dist/static/api/internal.html internal@v2 && redocly bundle -o dist/static/api/public.json public-filter && redocly build-docs -o dist/static/api/public.html public@v2"
},
"engines": {
"node": "20.16.0"
@ -90,6 +90,7 @@
"eslint": "8.57.0",
"eslint-watch": "8.0.0",
"ioredis-mock": "7.4.0",
"openapi-recursive-tagging": "0.0.6",
"readline-sync": "1.4.10",
"supertest": "6.2.3",
"tsx": "4.16.2",

View file

@ -5,7 +5,7 @@ apis:
internal@v2:
root: dist/static/api/openapi.json
public-filter:
root: dist/static/api/openapi.json
root: dist/static/api/openapi-tagged.json
decorators:
filter-in:
property: x-public

View file

@ -66,6 +66,11 @@ export function getOpenApi(): OpenAPIObject {
description: "Ape keys provide access to certain API endpoints.",
"x-displayName": "Ape Keys",
},
{
name: "psas",
description: "Public service announcements.",
"x-displayName": "PSAs",
},
{
name: "admin",
description:

View file

@ -1,7 +1,11 @@
import { GetPsaResponse } from "@monkeytype/contracts/psas";
import * as PsaDAL from "../../dal/psa";
import { MonkeyResponse } from "../../utils/monkey-response";
import { MonkeyResponse2 } from "../../utils/monkey-response";
import { replaceObjectIds } from "../../utils/misc";
export async function getPsas(): Promise<MonkeyResponse> {
export async function getPsas(
_req: MonkeyTypes.Request2
): Promise<GetPsaResponse> {
const data = await PsaDAL.get();
return new MonkeyResponse("PSAs retrieved", data);
return new MonkeyResponse2("PSAs retrieved", replaceObjectIds(data));
}

View file

@ -43,7 +43,6 @@ const APP_START_TIME = Date.now();
const API_ROUTE_MAP = {
"/users": users,
"/results": results,
"/psas": psas,
"/public": publicStats,
"/leaderboards": leaderboards,
"/quotes": quotes,
@ -57,6 +56,7 @@ const router = s.router(contract, {
apeKeys,
configs,
presets,
psas,
});
export function addApiRoutes(app: Application): void {

View file

@ -1,10 +1,13 @@
import { Router } from "express";
import * as PsaController from "../controllers/psa";
import { psasContract } from "@monkeytype/contracts/psas";
import { initServer } from "@ts-rest/express";
import * as RateLimit from "../../middlewares/rate-limit";
import { asyncHandler } from "../../middlewares/utility";
import * as PsaController from "../controllers/psa";
import { callController } from "../ts-rest-adapter";
const router = Router();
router.get("/", RateLimit.psaGet, asyncHandler(PsaController.getPsas));
export default router;
const s = initServer();
export default s.router(psasContract, {
get: {
middleware: [RateLimit.psaGet],
handler: async (r) => callController(PsaController.getPsas)(r),
},
});

View file

@ -1,7 +1,7 @@
import { PSA } from "@monkeytype/shared-types";
import { PSA } from "@monkeytype/contracts/schemas/psas";
import * as db from "../init/db";
type DBPSA = MonkeyTypes.WithObjectId<PSA>;
export type DBPSA = MonkeyTypes.WithObjectId<PSA>;
export async function get(): Promise<DBPSA[]> {
return await db.collection<DBPSA>("psa").find().toArray();

View file

@ -23,10 +23,6 @@
"name": "users",
"description": "User data and related operations"
},
{
"name": "psas",
"description": "Public service announcements"
},
{
"name": "leaderboards",
"description": "Leaderboard data"
@ -416,20 +412,6 @@
}
}
},
"/psas": {
"get": {
"tags": ["psas"],
"summary": "Gets the latest public service announcements",
"responses": {
"default": {
"description": "",
"schema": {
"$ref": "#/definitions/Response"
}
}
}
}
},
"/leaderboards": {
"get": {
"tags": ["leaderboards"],

View file

@ -331,5 +331,6 @@ export function replaceObjectId<T extends { _id: ObjectId }>(
export function replaceObjectIds<T extends { _id: ObjectId }>(
data: T[]
): (T & { _id: string })[] {
if (data === undefined) return data;
return data.map((it) => replaceObjectId(it));
}

View file

@ -1,5 +1,4 @@
import Leaderboards from "./leaderboards";
import Psas from "./psas";
import Quotes from "./quotes";
import Results from "./results";
import Users from "./users";
@ -9,7 +8,6 @@ import Dev from "./dev";
export default {
Leaderboards,
Psas,
Public,
Quotes,
Results,

View file

@ -1,13 +0,0 @@
import { PSA } from "@monkeytype/shared-types";
const BASE_PATH = "/psas";
export default class Psas {
constructor(private httpClient: Ape.HttpClient) {
this.httpClient = httpClient;
}
async get(): Ape.EndpointResponse<PSA[]> {
return await this.httpClient.get(BASE_PATH);
}
}

View file

@ -5,6 +5,7 @@ import { buildClient } from "./adapters/ts-rest-adapter";
import { configsContract } from "@monkeytype/contracts/configs";
import { presetsContract } from "@monkeytype/contracts/presets";
import { apeKeysContract } from "@monkeytype/contracts/ape-keys";
import { psasContract } from "@monkeytype/contracts/psas";
const API_PATH = "";
const BASE_URL = envConfig.backendUrl;
@ -17,7 +18,7 @@ const Ape = {
users: new endpoints.Users(httpClient),
configs: buildClient(configsContract, BASE_URL, 10_000),
results: new endpoints.Results(httpClient),
psas: new endpoints.Psas(httpClient),
psas: buildClient(psasContract, BASE_URL, 10_000),
quotes: new endpoints.Quotes(httpClient),
leaderboards: new endpoints.Leaderboards(httpClient),
presets: buildClient(presetsContract, BASE_URL, 10_000),

View file

@ -4,7 +4,7 @@ import { secondsToString } from "../utils/date-and-time";
import * as Notifications from "./notifications";
import { format } from "date-fns/format";
import * as Alerts from "./alerts";
import { PSA } from "@monkeytype/shared-types";
import { PSA } from "@monkeytype/contracts/schemas/psas";
function clearMemory(): void {
window.localStorage.setItem("confirmedPSAs", JSON.stringify([]));
@ -61,7 +61,7 @@ async function getLatest(): Promise<PSA[] | null> {
} else if (response.status !== 200) {
return null;
}
return response.data;
return response.body.data;
}
export async function show(): Promise<void> {

View file

@ -3,6 +3,7 @@ import { adminContract } from "./admin";
import { apeKeysContract } from "./ape-keys";
import { configsContract } from "./configs";
import { presetsContract } from "./presets";
import { psasContract } from "./psas";
const c = initContract();
@ -11,4 +12,5 @@ export const contract = c.router({
apeKeys: apeKeysContract,
configs: configsContract,
presets: presetsContract,
psas: psasContract,
});

View file

@ -0,0 +1,37 @@
import { initContract } from "@ts-rest/core";
import { z } from "zod";
import { PSASchema } from "./schemas/psas";
import {
CommonResponses,
EndpointMetadata,
responseWithData,
} from "./schemas/api";
export const GetPsaResponseSchema = responseWithData(z.array(PSASchema));
export type GetPsaResponse = z.infer<typeof GetPsaResponseSchema>;
const c = initContract();
export const psasContract = c.router(
{
get: {
summary: "get psas",
description: "Get list of public service announcements",
method: "GET",
path: "/",
responses: {
200: GetPsaResponseSchema,
},
},
},
{
pathPrefix: "/psas",
strictStatusCodes: true,
metadata: {
openApiTags: "psas",
authenticationOptions: {
isPublic: true,
},
} as EndpointMetadata,
commonResponses: CommonResponses,
}
);

View file

@ -1,6 +1,6 @@
import { z, ZodSchema } from "zod";
export type OpenApiTag = "configs" | "presets" | "ape-keys" | "admin";
export type OpenApiTag = "configs" | "presets" | "ape-keys" | "admin" | "psas";
export type EndpointMetadata = {
/** Authentication options, by default a bearer token is required. */
@ -74,4 +74,7 @@ export const CommonResponses = {
422: MonkeyValidationErrorSchema.describe("Request validation failed"),
429: MonkeyClientError.describe("Rate limit exceeded"),
500: MonkeyServerError.describe("Generic server error"),
503: MonkeyServerError.describe(
"Endpoint disabled or server is under maintenance"
),
};

View file

@ -0,0 +1,11 @@
import { z } from "zod";
import { IdSchema } from "./util";
export const PSASchema = z.object({
_id: IdSchema,
message: z.string(),
date: z.number().int().min(0).optional(),
level: z.number().int().optional(),
sticky: z.boolean().optional(),
});
export type PSA = z.infer<typeof PSASchema>;

View file

@ -301,14 +301,6 @@ export type ResultFilters = {
} & Record<string, boolean>;
};
export type PSA = {
_id: string;
message: string;
sticky?: boolean;
level?: number;
date?: number;
};
export type SpeedHistogram = {
[key: string]: number;
};

136
pnpm-lock.yaml generated
View file

@ -264,6 +264,9 @@ importers:
ioredis-mock:
specifier: 7.4.0
version: 7.4.0(ioredis@4.28.5)
openapi-recursive-tagging:
specifier: 0.0.6
version: 0.0.6
readline-sync:
specifier: 1.4.10
version: 1.4.10
@ -2844,6 +2847,10 @@ packages:
resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==}
engines: {node: '>=0.10.0'}
ansi-regex@4.1.1:
resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==}
engines: {node: '>=6'}
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
@ -3449,6 +3456,9 @@ packages:
cliui@3.2.0:
resolution: {integrity: sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==}
cliui@5.0.0:
resolution: {integrity: sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==}
cliui@7.0.4:
resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
@ -4189,6 +4199,9 @@ packages:
electron-to-chromium@1.5.5:
resolution: {integrity: sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==}
emoji-regex@7.0.3:
resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==}
emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@ -4665,6 +4678,10 @@ packages:
resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==}
engines: {node: '>=4'}
find-up@3.0.0:
resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==}
engines: {node: '>=6'}
find-up@4.1.0:
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
engines: {node: '>=8'}
@ -5504,6 +5521,10 @@ packages:
resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==}
engines: {node: '>=0.10.0'}
is-fullwidth-code-point@2.0.0:
resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==}
engines: {node: '>=4'}
is-fullwidth-code-point@3.0.0:
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
engines: {node: '>=8'}
@ -6028,6 +6049,10 @@ packages:
resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==}
engines: {node: '>=4'}
locate-path@3.0.0:
resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==}
engines: {node: '>=6'}
locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'}
@ -6989,6 +7014,10 @@ packages:
resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
engines: {node: '>=12'}
openapi-recursive-tagging@0.0.6:
resolution: {integrity: sha512-ZtHR0jHeIMTuyeenbee7j0fK58Uf9ZMFGTXv3abQvsdjImfdEXfmmNlMNgpW27DmoomOgwwpGNGldUUQd0oJ4g==}
hasBin: true
openapi-sampler@1.5.1:
resolution: {integrity: sha512-tIWIrZUKNAsbqf3bd9U1oH6JEXo8LNYuDlXw26By67EygpjT+ArFnsxxyTMjFWRfbqo5ozkvgSQDK69Gd8CddA==}
@ -7041,6 +7070,10 @@ packages:
resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==}
engines: {node: '>=4'}
p-locate@3.0.0:
resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==}
engines: {node: '>=6'}
p-locate@4.1.0:
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
engines: {node: '>=8'}
@ -7764,6 +7797,9 @@ packages:
require-main-filename@1.0.1:
resolution: {integrity: sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==}
require-main-filename@2.0.0:
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
requirejs-config-file@4.0.0:
resolution: {integrity: sha512-jnIre8cbWOyvr8a5F2KuqBnY+SDA4NXr/hzEZJG79Mxm2WiFQz2dzhC8ibtPJS7zkmBEl1mxSwp5HhC1W4qpxw==}
engines: {node: '>=10.13.0'}
@ -8300,6 +8336,10 @@ packages:
resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==}
engines: {node: '>=0.10.0'}
string-width@3.1.0:
resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==}
engines: {node: '>=6'}
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
@ -8340,6 +8380,10 @@ packages:
resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==}
engines: {node: '>=0.10.0'}
strip-ansi@5.2.0:
resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==}
engines: {node: '>=6'}
strip-ansi@6.0.1:
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
@ -9292,6 +9336,9 @@ packages:
which-module@1.0.0:
resolution: {integrity: sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==}
which-module@2.0.1:
resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
which-pm-runs@1.1.0:
resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==}
engines: {node: '>=4'}
@ -9397,6 +9444,10 @@ packages:
resolution: {integrity: sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==}
engines: {node: '>=0.10.0'}
wrap-ansi@5.1.0:
resolution: {integrity: sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==}
engines: {node: '>=6'}
wrap-ansi@6.2.0:
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
engines: {node: '>=8'}
@ -9438,6 +9489,9 @@ packages:
y18n@3.2.2:
resolution: {integrity: sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==}
y18n@4.0.3:
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
@ -9460,6 +9514,9 @@ packages:
engines: {node: '>= 14'}
hasBin: true
yargs-parser@15.0.3:
resolution: {integrity: sha512-/MVEVjTXy/cGAjdtQf8dW3V9b97bPN7rNn8ETj6BmAQL7ibC7O1Q9SPJbGjgh3SlwoBNXMzj/ZGIj8mBgl12YA==}
yargs-parser@20.2.9:
resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
engines: {node: '>=10'}
@ -9471,6 +9528,9 @@ packages:
yargs-parser@5.0.1:
resolution: {integrity: sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==}
yargs@14.2.3:
resolution: {integrity: sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==}
yargs@16.2.0:
resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==}
engines: {node: '>=10'}
@ -12174,6 +12234,8 @@ snapshots:
ansi-regex@2.1.1: {}
ansi-regex@4.1.1: {}
ansi-regex@5.0.1: {}
ansi-regex@6.0.1: {}
@ -12887,6 +12949,12 @@ snapshots:
strip-ansi: 3.0.1
wrap-ansi: 2.1.0
cliui@5.0.0:
dependencies:
string-width: 3.1.0
strip-ansi: 5.2.0
wrap-ansi: 5.1.0
cliui@7.0.4:
dependencies:
string-width: 4.2.3
@ -13651,6 +13719,8 @@ snapshots:
electron-to-chromium@1.5.5: {}
emoji-regex@7.0.3: {}
emoji-regex@8.0.0: {}
emoji-regex@9.2.2: {}
@ -14464,6 +14534,10 @@ snapshots:
dependencies:
locate-path: 2.0.0
find-up@3.0.0:
dependencies:
locate-path: 3.0.0
find-up@4.1.0:
dependencies:
locate-path: 5.0.0
@ -15594,6 +15668,8 @@ snapshots:
dependencies:
number-is-nan: 1.0.1
is-fullwidth-code-point@2.0.0: {}
is-fullwidth-code-point@3.0.0: {}
is-fullwidth-code-point@4.0.0: {}
@ -16132,6 +16208,11 @@ snapshots:
p-locate: 2.0.0
path-exists: 3.0.0
locate-path@3.0.0:
dependencies:
p-locate: 3.0.0
path-exists: 3.0.0
locate-path@5.0.0:
dependencies:
p-locate: 4.1.0
@ -17206,7 +17287,7 @@ snapshots:
oas-kit-common: 1.0.8
reftools: 1.1.9
yaml: 1.10.2
yargs: 17.0.1
yargs: 17.7.2
oas-schema-walker@1.1.5: {}
@ -17348,6 +17429,12 @@ snapshots:
is-docker: 2.2.1
is-wsl: 2.2.0
openapi-recursive-tagging@0.0.6:
dependencies:
reftools: 1.1.9
yaml: 1.10.2
yargs: 14.2.3
openapi-sampler@1.5.1:
dependencies:
'@types/json-schema': 7.0.15
@ -17414,6 +17501,10 @@ snapshots:
dependencies:
p-limit: 1.3.0
p-locate@3.0.0:
dependencies:
p-limit: 2.3.0
p-locate@4.1.0:
dependencies:
p-limit: 2.3.0
@ -18203,6 +18294,8 @@ snapshots:
require-main-filename@1.0.1: {}
require-main-filename@2.0.0: {}
requirejs-config-file@4.0.0:
dependencies:
esprima: 4.0.1
@ -18789,6 +18882,12 @@ snapshots:
is-fullwidth-code-point: 1.0.0
strip-ansi: 3.0.1
string-width@3.1.0:
dependencies:
emoji-regex: 7.0.3
is-fullwidth-code-point: 2.0.0
strip-ansi: 5.2.0
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
@ -18855,6 +18954,10 @@ snapshots:
dependencies:
ansi-regex: 2.1.1
strip-ansi@5.2.0:
dependencies:
ansi-regex: 4.1.1
strip-ansi@6.0.1:
dependencies:
ansi-regex: 5.0.1
@ -19037,7 +19140,7 @@ snapshots:
oas-validator: 5.0.8
reftools: 1.1.9
yaml: 1.10.2
yargs: 17.0.1
yargs: 17.7.2
transitivePeerDependencies:
- encoding
@ -19924,6 +20027,8 @@ snapshots:
which-module@1.0.0: {}
which-module@2.0.1: {}
which-pm-runs@1.1.0: {}
which-typed-array@1.1.15:
@ -20105,6 +20210,12 @@ snapshots:
string-width: 1.0.2
strip-ansi: 3.0.1
wrap-ansi@5.1.0:
dependencies:
ansi-styles: 3.2.1
string-width: 3.1.0
strip-ansi: 5.2.0
wrap-ansi@6.2.0:
dependencies:
ansi-styles: 4.3.0
@ -20140,6 +20251,8 @@ snapshots:
y18n@3.2.2: {}
y18n@4.0.3: {}
y18n@5.0.8: {}
yallist@3.1.1: {}
@ -20152,6 +20265,11 @@ snapshots:
yaml@2.5.0: {}
yargs-parser@15.0.3:
dependencies:
camelcase: 5.3.1
decamelize: 1.2.0
yargs-parser@20.2.9: {}
yargs-parser@21.1.1: {}
@ -20161,6 +20279,20 @@ snapshots:
camelcase: 3.0.0
object.assign: 4.1.5
yargs@14.2.3:
dependencies:
cliui: 5.0.0
decamelize: 1.2.0
find-up: 3.0.0
get-caller-file: 2.0.5
require-directory: 2.1.1
require-main-filename: 2.0.0
set-blocking: 2.0.0
string-width: 3.1.0
which-module: 2.0.1
y18n: 4.0.3
yargs-parser: 15.0.3
yargs@16.2.0:
dependencies:
cliui: 7.0.4