Merge pull request #20007 from backstage/openapi-typing-updates

feat(openapi): improve the internal typings and create real public utility types for OpenAPI
This commit is contained in:
Patrik Oldsberg
2023-10-03 17:36:22 +02:00
committed by GitHub
12 changed files with 313 additions and 117 deletions
+8
View File
@@ -0,0 +1,8 @@
---
'@backstage/backend-openapi-utils': patch
---
Adds new public utility types for common OpenAPI values, like request and response shapes and parameters available on an endpoint.
**deprecated** `internal` namespace
The internal namespace will continue to be exported but now uses OpenAPI format for path parameters. You should use the new utility types.
+6
View File
@@ -61,6 +61,12 @@ export function createRouter() {
}
```
## FAQs
### Why am I getting `unknown` as the type for a response?
This can happen when you have a `charset` defined in your `response.content` section. Something like `response.content[ 'application/json; charset=utf-8:']` will cause this issue.
## INTERNAL
### Limitations
+118 -57
View File
@@ -75,11 +75,18 @@ interface CookieObject extends ParameterObject {
}
// @public (undocumented)
type CookieSchema<
export type CookieParameters<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Method extends DocPathTemplateMethod<Doc, Path>,
> = CookieSchema<Doc, TemplateToDocPath<Doc, Path>, Method>;
// @public (undocumented)
type CookieSchema<
Doc extends RequiredDoc,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = ParametersSchema<Doc, DocPath<Doc, Path>, Method, ImmutableCookieObject>;
> = ParametersSchema<Doc, Path, Method, ImmutableCookieObject>;
// @public
export function createValidatedOpenApiRouter<T extends RequiredDoc>(
@@ -99,16 +106,16 @@ type DiscriminateUnion<T, K extends keyof T, V extends T[K]> = Extract<
// @public (undocumented)
type DocOperation<
Doc extends RequiredDoc,
Path extends keyof Doc['paths'],
Path extends DocPath<Doc>,
Method extends keyof Doc['paths'][Path],
> = Doc['paths'][Path][Method];
// @public (undocumented)
type DocParameter<
Doc extends RequiredDoc,
Path extends Extract<keyof Doc['paths'], string>,
Method extends keyof Doc['paths'][Path],
Parameter extends keyof Doc['paths'][Path][Method]['parameters'],
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
Parameter extends keyof DocOperation<Doc, Path, Method>['parameters'],
> = DocOperation<
Doc,
Path,
@@ -142,32 +149,28 @@ type DocParameters<
};
// @public
type DocPath<
Doc extends PathDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
> = ValueOf<{
[Template in Extract<
keyof Doc['paths'],
string
>]: Path extends PathTemplate<Template> ? Template : never;
}>;
type DocPath<Doc extends PathDoc> = Extract<keyof Doc['paths'], string>;
// @public (undocumented)
type DocPathMethod<
Doc extends Pick<RequiredDoc, 'paths'>,
Path extends DocPathTemplate<Doc>,
> = keyof Doc['paths'][DocPath<Doc, Path>];
Path extends DocPath<Doc>,
> = keyof Doc['paths'][Path];
// @public (undocumented)
type DocPathTemplate<Doc extends PathDoc> = PathTemplate<
Extract<keyof Doc['paths'], string>
>;
type DocPathTemplate<Doc extends PathDoc> = PathTemplate<DocPath<Doc>>;
// @public (undocumented)
type DocPathTemplateMethod<
Doc extends Pick<RequiredDoc, 'paths'>,
Path extends DocPathTemplate<Doc>,
> = keyof Doc['paths'][TemplateToDocPath<Doc, Path>];
// @public
type DocRequestHandler<
Doc extends RequiredDoc,
Path extends DocPathTemplate<Doc>,
Method extends keyof Doc['paths'][Path],
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = core.RequestHandler<
PathSchema<Doc, Path, Method>,
ResponseBodyToJsonSchema<Doc, Path, Method>,
@@ -179,8 +182,8 @@ type DocRequestHandler<
// @public
type DocRequestHandlerParams<
Doc extends RequiredDoc,
Path extends DocPathTemplate<Doc>,
Method extends keyof Doc['paths'][Path],
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = core.RequestHandlerParams<
PathSchema<Doc, Path, Method>,
ResponseBodyToJsonSchema<Doc, Path, Method>,
@@ -204,14 +207,30 @@ interface DocRequestMatcher<
| 'head',
> {
// (undocumented)
<Path extends MethodAwareDocPath<Doc, DocPathTemplate<Doc>, Method>>(
<
Path extends MethodAwareDocPath<
Doc,
PathTemplate<Extract<keyof Doc['paths'], string>>,
Method
>,
>(
path: Path,
...handlers: Array<DocRequestHandler<Doc, Path, Method>>
...handlers: Array<
DocRequestHandler<Doc, TemplateToDocPath<Doc, Path>, Method>
>
): T;
// (undocumented)
<Path extends MethodAwareDocPath<Doc, DocPathTemplate<Doc>, Method>>(
<
Path extends MethodAwareDocPath<
Doc,
PathTemplate<Extract<keyof Doc['paths'], string>>,
Method
>,
>(
path: Path,
...handlers: Array<DocRequestHandlerParams<Doc, Path, Method>>
...handlers: Array<
DocRequestHandlerParams<Doc, TemplateToDocPath<Doc, Path>, Method>
>
): T;
}
@@ -238,11 +257,18 @@ interface HeaderObject extends ParameterObject {
}
// @public (undocumented)
type HeaderSchema<
export type HeaderParameters<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Method extends DocPathTemplateMethod<Doc, Path>,
> = HeaderSchema<Doc, TemplateToDocPath<Doc, Path>, Method>;
// @public (undocumented)
type HeaderSchema<
Doc extends RequiredDoc,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = ParametersSchema<Doc, DocPath<Doc, Path>, Method, ImmutableHeaderObject>;
> = ParametersSchema<Doc, Path, Method, ImmutableHeaderObject>;
// @public
type Immutable<T> = T extends
@@ -304,10 +330,12 @@ declare namespace internal {
RequiredDoc,
PathDoc,
ValueOf,
PathTemplate,
DocPath,
PathTemplate,
TemplateToDocPath,
DocPathTemplate,
DocPathMethod,
DocPathTemplateMethod,
MethodAwareDocPath,
DocOperation,
ComponentTypes,
@@ -362,7 +390,7 @@ declare namespace internal {
RequestBody,
RequestBodySchema,
RequestBodyToJsonSchema,
Response_2 as Response,
Response_3 as Response,
ResponseSchemas,
ResponseBodyToJsonSchema,
};
@@ -394,14 +422,11 @@ type MapToSchema<
// @public (undocumented)
type MethodAwareDocPath<
Doc extends PathDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Method extends keyof Doc['paths'][Path],
Path extends DocPathTemplate<Doc>,
Method extends DocPathTemplateMethod<Doc, Path>,
> = ValueOf<{
[Template in Extract<
keyof Doc['paths'],
string
>]: Path extends PathTemplate<Template>
? Method extends DocPathMethod<Doc, Path>
[Template in DocPath<Doc>]: Path extends PathTemplate<Template>
? Method extends DocPathTemplateMethod<Doc, Path>
? PathTemplate<Template>
: never
: never;
@@ -466,11 +491,18 @@ interface PathObject extends ParameterObject {
}
// @public (undocumented)
type PathSchema<
export type PathParameters<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Method extends DocPathTemplateMethod<Doc, Path>,
> = PathSchema<Doc, TemplateToDocPath<Doc, Path>, Method>;
// @public (undocumented)
type PathSchema<
Doc extends RequiredDoc,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = ParametersSchema<Doc, DocPath<Doc, Path>, Method, ImmutablePathObject>;
> = ParametersSchema<Doc, Path, Method, ImmutablePathObject>;
// @public
type PathTemplate<Path extends string> =
@@ -508,11 +540,26 @@ interface QueryObject extends ParameterObject {
}
// @public (undocumented)
type QuerySchema<
export type QueryParameters<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Method extends DocPathTemplateMethod<Doc, Path>,
> = QuerySchema<Doc, TemplateToDocPath<Doc, Path>, Method>;
// @public (undocumented)
type QuerySchema<
Doc extends RequiredDoc,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = ParametersSchema<Doc, DocPath<Doc, Path>, Method, ImmutableQueryObject>;
> = ParametersSchema<Doc, Path, Method, ImmutableQueryObject>;
// @public (undocumented)
type Request_2<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Method extends DocPathTemplateMethod<Doc, Path>,
> = RequestBodyToJsonSchema<Doc, TemplateToDocPath<Doc, Path>, Method>;
export { Request_2 as Request };
// @public (undocumented)
type RequestBody<
@@ -536,20 +583,16 @@ type RequestBody<
// @public (undocumented)
type RequestBodySchema<
Doc extends RequiredDoc,
Path extends DocPathTemplate<Doc>,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = RequestBody<
Doc,
DocPath<Doc, Path>,
Method
> extends ImmutableRequestBodyObject
? ObjectWithContentSchema<Doc, RequestBody<Doc, DocPath<Doc, Path>, Method>>
> = RequestBody<Doc, Path, Method> extends ImmutableRequestBodyObject
? ObjectWithContentSchema<Doc, RequestBody<Doc, Path, Method>>
: never;
// @public
type RequestBodyToJsonSchema<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = ToTypeSafe<RequestBodySchema<Doc, Path, Method>>;
@@ -568,8 +611,16 @@ type RequiredMap<
// @public (undocumented)
type Response_2<
Doc extends RequiredDoc,
Path extends keyof Doc['paths'],
Method extends keyof Doc['paths'][Path],
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Method extends DocPathTemplateMethod<Doc, Path>,
> = ResponseBodyToJsonSchema<Doc, TemplateToDocPath<Doc, Path>, Method>;
export { Response_2 as Response };
// @public (undocumented)
type Response_3<
Doc extends RequiredDoc,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
StatusCode extends keyof DocOperation<Doc, Path, Method>['responses'],
> = DocOperation<
Doc,
@@ -588,27 +639,27 @@ type Response_2<
// @public
type ResponseBodyToJsonSchema<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = ToTypeSafe<ValueOf<ResponseSchemas<Doc, Path, Method>>>;
// @public (undocumented)
type ResponseSchemas<
Doc extends RequiredDoc,
Path extends DocPathTemplate<Doc>,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = {
[StatusCode in keyof DocOperation<
Doc,
Path,
Method
>['responses']]: Response_2<
>['responses']]: Response_3<
Doc,
Path,
Method,
StatusCode
> extends ImmutableResponseObject
? ObjectWithContentSchema<Doc, Response_2<Doc, Path, Method, StatusCode>>
? ObjectWithContentSchema<Doc, Response_3<Doc, Path, Method, StatusCode>>
: never;
};
@@ -625,6 +676,16 @@ type SchemaRef<Doc extends RequiredDoc, Schema> = Schema extends {
[Key in keyof Schema]: SchemaRef<Doc, Schema[Key]>;
};
// @public
type TemplateToDocPath<
Doc extends PathDoc,
Path extends DocPathTemplate<Doc>,
> = ValueOf<{
[Template in DocPath<Doc>]: Path extends PathTemplate<Template>
? Template
: never;
}>;
// @public (undocumented)
type ToTypeSafe<T> = UnknownIfNever<ConvertAll<TuplifyUnion<T>>[number]>;
@@ -22,5 +22,13 @@
import * as internal from './types';
export { internal };
export type {
Request,
Response,
QueryParameters,
HeaderParameters,
CookieParameters,
PathParameters,
} from './utility';
export type { ApiRouter } from './router';
export { createValidatedOpenApiRouter } from './stub';
@@ -18,15 +18,23 @@ import { createValidatedOpenApiRouter } from './stub';
import express from 'express';
import request from 'supertest';
import singlePathSpec from './___fixtures__/single-path';
import { Response } from './utility';
describe('createRouter', () => {
const pet: Response<typeof singlePathSpec, '/pet/:petId', 'get'> = {
id: 1,
name: 'rover',
status: 'available',
photoUrls: [],
};
it('does NOT override originalUrl and basePath after execution', async () => {
expect.assertions(2);
const router = createValidatedOpenApiRouter(singlePathSpec);
router.get('/pet/:petId', (req, res) => {
expect(req.baseUrl).toBe('/pet-store');
expect(req.originalUrl).toBe(`/pet-store/pet/${req.params.petId}`);
res.send('');
res.status(400).send();
});
const appRouter = express();
@@ -41,7 +49,7 @@ describe('createRouter', () => {
const routerGetFn = jest.fn();
router.get('/pet/:petId', (_, res) => {
routerGetFn();
res.send('');
res.json(pet);
});
const apiRouter = express.Router();
@@ -58,7 +66,7 @@ describe('createRouter', () => {
const router = createValidatedOpenApiRouter(singlePathSpec);
router.get('/pet/:petId', (req, res) => {
expect(typeof req.params.petId).toBe('integer');
res.send('');
res.json(pet);
});
const apiRouter = express.Router();
@@ -42,6 +42,13 @@ export type PathDoc = Pick<ImmutableOpenAPIObject, 'paths'>;
*/
export type ValueOf<T> = T[keyof T];
/**
* All paths for a given doc,
* @example `/pet/{petId}` | `/pet`
* @public
*/
export type DocPath<Doc extends PathDoc> = Extract<keyof Doc['paths'], string>;
/**
* Validate a string against OpenAPI path template, {@link https://spec.openapis.org/oas/v3.1.0#path-templating-matching}.
*
@@ -74,44 +81,46 @@ export type PathTemplate<Path extends string> =
*
* @public
*/
export type DocPath<
export type TemplateToDocPath<
Doc extends PathDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Path extends DocPathTemplate<Doc>,
> = ValueOf<{
[Template in Extract<
keyof Doc['paths'],
string
>]: Path extends PathTemplate<Template> ? Template : never;
[Template in DocPath<Doc>]: Path extends PathTemplate<Template>
? Template
: never;
}>;
/**
* @public
*/
export type DocPathTemplate<Doc extends PathDoc> = PathTemplate<
Extract<keyof Doc['paths'], string>
>;
export type DocPathTemplate<Doc extends PathDoc> = PathTemplate<DocPath<Doc>>;
/**
* @public
*/
export type DocPathMethod<
Doc extends Pick<RequiredDoc, 'paths'>,
Path extends DocPath<Doc>,
> = keyof Doc['paths'][Path];
/**
* @public
*/
export type DocPathTemplateMethod<
Doc extends Pick<RequiredDoc, 'paths'>,
Path extends DocPathTemplate<Doc>,
> = keyof Doc['paths'][DocPath<Doc, Path>];
> = keyof Doc['paths'][TemplateToDocPath<Doc, Path>];
/**
* @public
*/
export type MethodAwareDocPath<
Doc extends PathDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Method extends keyof Doc['paths'][Path],
Path extends DocPathTemplate<Doc>,
Method extends DocPathTemplateMethod<Doc, Path>,
> = ValueOf<{
[Template in Extract<
keyof Doc['paths'],
string
>]: Path extends PathTemplate<Template>
? Method extends DocPathMethod<Doc, Path>
[Template in DocPath<Doc>]: Path extends PathTemplate<Template>
? Method extends DocPathTemplateMethod<Doc, Path>
? PathTemplate<Template>
: never
: never;
@@ -122,7 +131,7 @@ export type MethodAwareDocPath<
*/
export type DocOperation<
Doc extends RequiredDoc,
Path extends keyof Doc['paths'],
Path extends DocPath<Doc>,
Method extends keyof Doc['paths'][Path],
> = Doc['paths'][Path][Method];
@@ -14,7 +14,14 @@
* limitations under the License.
*/
import type core from 'express-serve-static-core';
import { DocPathTemplate, MethodAwareDocPath, RequiredDoc } from './common';
import {
DocPath,
DocPathMethod,
MethodAwareDocPath,
PathTemplate,
RequiredDoc,
TemplateToDocPath,
} from './common';
import { PathSchema, QuerySchema } from './params';
import { RequestBodyToJsonSchema } from './requests';
import { ResponseBodyToJsonSchema } from './responses';
@@ -25,8 +32,8 @@ import { ResponseBodyToJsonSchema } from './responses';
*/
export type DocRequestHandler<
Doc extends RequiredDoc,
Path extends DocPathTemplate<Doc>,
Method extends keyof Doc['paths'][Path],
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = core.RequestHandler<
PathSchema<Doc, Path, Method>,
ResponseBodyToJsonSchema<Doc, Path, Method>,
@@ -41,8 +48,8 @@ export type DocRequestHandler<
*/
export type DocRequestHandlerParams<
Doc extends RequiredDoc,
Path extends DocPathTemplate<Doc>,
Method extends keyof Doc['paths'][Path],
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = core.RequestHandlerParams<
PathSchema<Doc, Path, Method>,
ResponseBodyToJsonSchema<Doc, Path, Method>,
@@ -68,12 +75,28 @@ export interface DocRequestMatcher<
| 'options'
| 'head',
> {
<Path extends MethodAwareDocPath<Doc, DocPathTemplate<Doc>, Method>>(
<
Path extends MethodAwareDocPath<
Doc,
PathTemplate<Extract<keyof Doc['paths'], string>>,
Method
>,
>(
path: Path,
...handlers: Array<DocRequestHandler<Doc, Path, Method>>
...handlers: Array<
DocRequestHandler<Doc, TemplateToDocPath<Doc, Path>, Method>
>
): T;
<Path extends MethodAwareDocPath<Doc, DocPathTemplate<Doc>, Method>>(
<
Path extends MethodAwareDocPath<
Doc,
PathTemplate<Extract<keyof Doc['paths'], string>>,
Method
>,
>(
path: Path,
...handlers: Array<DocRequestHandlerParams<Doc, Path, Method>>
...handlers: Array<
DocRequestHandlerParams<Doc, TemplateToDocPath<Doc, Path>, Method>
>
): T;
}
@@ -32,7 +32,6 @@ import {
Filter,
FullMap,
MapDiscriminatedUnion,
PathTemplate,
RequiredDoc,
SchemaRef,
ValueOf,
@@ -44,9 +43,9 @@ import { FromSchema, JSONSchema7 } from 'json-schema-to-ts';
*/
export type DocParameter<
Doc extends RequiredDoc,
Path extends Extract<keyof Doc['paths'], string>,
Method extends keyof Doc['paths'][Path],
Parameter extends keyof Doc['paths'][Path][Method]['parameters'],
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
Parameter extends keyof DocOperation<Doc, Path, Method>['parameters'],
> = DocOperation<
Doc,
Path,
@@ -138,33 +137,33 @@ export type ParametersSchema<
*/
export type HeaderSchema<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = ParametersSchema<Doc, DocPath<Doc, Path>, Method, ImmutableHeaderObject>;
> = ParametersSchema<Doc, Path, Method, ImmutableHeaderObject>;
/**
* @public
*/
export type CookieSchema<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = ParametersSchema<Doc, DocPath<Doc, Path>, Method, ImmutableCookieObject>;
> = ParametersSchema<Doc, Path, Method, ImmutableCookieObject>;
/**
* @public
*/
export type PathSchema<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = ParametersSchema<Doc, DocPath<Doc, Path>, Method, ImmutablePathObject>;
> = ParametersSchema<Doc, Path, Method, ImmutablePathObject>;
/**
* @public
*/
export type QuerySchema<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = ParametersSchema<Doc, DocPath<Doc, Path>, Method, ImmutableQueryObject>;
> = ParametersSchema<Doc, Path, Method, ImmutableQueryObject>;
@@ -26,8 +26,6 @@ import type {
DocOperation,
DocPath,
DocPathMethod,
DocPathTemplate,
PathTemplate,
ToTypeSafe,
} from './common';
import {
@@ -61,14 +59,10 @@ export type RequestBody<
*/
export type RequestBodySchema<
Doc extends RequiredDoc,
Path extends DocPathTemplate<Doc>,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = RequestBody<
Doc,
DocPath<Doc, Path>,
Method
> extends ImmutableRequestBodyObject
? ObjectWithContentSchema<Doc, RequestBody<Doc, DocPath<Doc, Path>, Method>>
> = RequestBody<Doc, Path, Method> extends ImmutableRequestBodyObject
? ObjectWithContentSchema<Doc, RequestBody<Doc, Path, Method>>
: never;
/**
@@ -77,6 +71,6 @@ export type RequestBodySchema<
*/
export type RequestBodyToJsonSchema<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = ToTypeSafe<RequestBodySchema<Doc, Path, Method>>;
@@ -25,10 +25,9 @@ import type {
RequiredDoc,
DocOperation,
DocPathMethod,
DocPathTemplate,
PathTemplate,
ToTypeSafe,
ValueOf,
DocPath,
} from './common';
import { ImmutableReferenceObject, ImmutableResponseObject } from './immutable';
@@ -37,8 +36,8 @@ import { ImmutableReferenceObject, ImmutableResponseObject } from './immutable';
*/
export type Response<
Doc extends RequiredDoc,
Path extends keyof Doc['paths'],
Method extends keyof Doc['paths'][Path],
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
StatusCode extends keyof DocOperation<Doc, Path, Method>['responses'],
> = DocOperation<
Doc,
@@ -59,7 +58,7 @@ export type Response<
*/
export type ResponseSchemas<
Doc extends RequiredDoc,
Path extends DocPathTemplate<Doc>,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = {
[StatusCode in keyof DocOperation<Doc, Path, Method>['responses']]: Response<
@@ -78,6 +77,6 @@ export type ResponseSchemas<
*/
export type ResponseBodyToJsonSchema<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Path extends DocPath<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = ToTypeSafe<ValueOf<ResponseSchemas<Doc, Path, Method>>>;
@@ -0,0 +1,81 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
CookieSchema,
DocPathTemplateMethod,
HeaderSchema,
PathSchema,
PathTemplate,
QuerySchema,
RequestBodyToJsonSchema,
RequiredDoc,
ResponseBodyToJsonSchema,
TemplateToDocPath,
} from './types';
/**
* @public
*/
export type Response<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Method extends DocPathTemplateMethod<Doc, Path>,
> = ResponseBodyToJsonSchema<Doc, TemplateToDocPath<Doc, Path>, Method>;
/**
* @public
*/
export type Request<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Method extends DocPathTemplateMethod<Doc, Path>,
> = RequestBodyToJsonSchema<Doc, TemplateToDocPath<Doc, Path>, Method>;
/**
* @public
*/
export type HeaderParameters<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Method extends DocPathTemplateMethod<Doc, Path>,
> = HeaderSchema<Doc, TemplateToDocPath<Doc, Path>, Method>;
/**
* @public
*/
export type CookieParameters<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Method extends DocPathTemplateMethod<Doc, Path>,
> = CookieSchema<Doc, TemplateToDocPath<Doc, Path>, Method>;
/**
* @public
*/
export type PathParameters<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Method extends DocPathTemplateMethod<Doc, Path>,
> = PathSchema<Doc, TemplateToDocPath<Doc, Path>, Method>;
/**
* @public
*/
export type QueryParameters<
Doc extends RequiredDoc,
Path extends PathTemplate<Extract<keyof Doc['paths'], string>>,
Method extends DocPathTemplateMethod<Doc, Path>,
> = QuerySchema<Doc, TemplateToDocPath<Doc, Path>, Method>;
@@ -24,10 +24,10 @@ import { parseEntityFilterParams } from './parseEntityFilterParams';
import { parseEntityOrderFieldParams } from './parseEntityOrderFieldParams';
import { parseEntityTransformParams } from './parseEntityTransformParams';
import { spec } from '../../schema/openapi.generated';
import { internal } from '@backstage/backend-openapi-utils';
import { QueryParameters } from '@backstage/backend-openapi-utils';
export function parseQueryEntitiesParams(
params: internal.QuerySchema<typeof spec, '/entities/by-query', 'get'>,
params: QueryParameters<typeof spec, '/entities/by-query', 'get'>,
): Omit<QueryEntitiesRequest, 'authorizationToken' | 'limit'> {
const fields = parseEntityTransformParams(params);