Add Immutable prefix.

Signed-off-by: Aramis Sennyey <sennyeya@amazon.com>
This commit is contained in:
Aramis Sennyey
2023-02-28 14:05:30 -05:00
committed by Fredrik Adelöw
parent 68c4160011
commit 8bb18ff229
5 changed files with 104 additions and 32 deletions
+50 -13
View File
@@ -37,12 +37,12 @@ export interface ApiRouter<Doc extends RequiredDoc> extends Router {
export type ComponentRef<
Doc extends RequiredDoc,
Type extends ComponentTypes<Doc>,
Ref extends ReferenceObject,
Ref extends ImmutableReferenceObject,
> = Ref extends {
$ref: `#/components/${Type}/${infer Name}`;
}
? Name extends keyof Doc['components'][Type]
? Doc['components'][Type][Name] extends ReferenceObject
? Doc['components'][Type][Name] extends ImmutableReferenceObject
? ComponentRef<Doc, Type, Doc['components'][Type][Name]>
: Doc['components'][Type][Name]
: never
@@ -62,11 +62,6 @@ export type ConvertAll<T, R extends ReadonlyArray<unknown> = []> = T extends [
? ConvertAll<Rest, [...R, FromSchema<First>]>
: R;
// @public
export type DeepWriteable<T> = {
-readonly [P in keyof T]: DeepWriteable<T[P]>;
};
// @public (undocumented)
export type DocOperation<
Doc extends RequiredDoc,
@@ -148,6 +143,40 @@ export interface DocRequestMatcher<
): T;
}
// @public
export type Immutable<T> = T extends
| Function
| boolean
| number
| string
| null
| undefined
? T
: T extends Map<infer K, infer V>
? ReadonlyMap<Immutable<K>, Immutable<V>>
: T extends Set<infer S>
? ReadonlySet<Immutable<S>>
: {
readonly [P in keyof T]: Immutable<T[P]>;
};
// @public (undocumented)
export type ImmutableContentObject = ImmutableObject<ContentObject>;
// @public (undocumented)
export type ImmutableObject<T> = {
readonly [K in keyof T]: Immutable<T[K]>;
};
// @public (undocumented)
export type ImmutableOpenAPIObject = ImmutableObject<OpenAPIObject>;
// @public (undocumented)
export type ImmutableReferenceObject = ImmutableObject<ReferenceObject>;
// @public (undocumented)
export type ImmutableRequestBodyObject = ImmutableObject<RequestBodyObject>;
// @public (undocumented)
export type LastOf<T> = UnionToIntersection<
T extends any ? () => T : never
@@ -175,9 +204,9 @@ export type MethodAwareDocPath<
export type ObjectWithContentSchema<
Doc extends RequiredDoc,
Object extends {
content?: ContentObject;
content?: ImmutableContentObject;
},
> = Object['content'] extends ContentObject
> = Object['content'] extends ImmutableContentObject
? SchemaRef<Doc, Object['content']['application/json']['schema']>
: never;
@@ -188,7 +217,7 @@ export interface ParsedQs {
}
// @public (undocumented)
export type PathDoc = Pick<OpenAPIObject, 'paths'>;
export type PathDoc = Pick<ImmutableOpenAPIObject, 'paths'>;
// @public
export type PathTemplate<Path extends string> =
@@ -204,7 +233,11 @@ export type RequestBody<
Doc extends RequiredDoc,
Path extends Extract<keyof Doc['paths'], string>,
Method extends keyof Doc['paths'][Path],
> = DocOperation<Doc, Path, Method>['requestBody'] extends ReferenceObject
> = DocOperation<
Doc,
Path,
Method
>['requestBody'] extends ImmutableReferenceObject
? 'requestBodies' extends ComponentTypes<Doc>
? ComponentRef<
Doc,
@@ -219,7 +252,11 @@ export type RequestBodySchema<
Doc extends RequiredDoc,
Path extends DocPathTemplate<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = RequestBody<Doc, DocPath<Doc, Path>, Method> extends RequestBodyObject
> = RequestBody<
Doc,
DocPath<Doc, Path>,
Method
> extends ImmutableRequestBodyObject
? ObjectWithContentSchema<Doc, RequestBody<Doc, DocPath<Doc, Path>, Method>>
: never;
@@ -231,7 +268,7 @@ export type RequestBodyToJsonSchema<
> = ToTypeSafe<RequestBodySchema<Doc, Path, Method>>;
// @public
export type RequiredDoc = Pick<OpenAPIObject, 'paths' | 'components'>;
export type RequiredDoc = Pick<ImmutableOpenAPIObject, 'paths' | 'components'>;
// @public (undocumented)
type Response_2<
@@ -19,19 +19,23 @@
*/
import { FromSchema, JSONSchema7 } from 'json-schema-to-ts';
import { ContentObject, OpenAPIObject, ReferenceObject } from './immutable';
import {
ImmutableContentObject,
ImmutableOpenAPIObject,
ImmutableReferenceObject,
} from './immutable';
/**
* Basic OpenAPI spec with paths and components properties enforced.
*
* @public
*/
export type RequiredDoc = Pick<OpenAPIObject, 'paths' | 'components'>;
export type RequiredDoc = Pick<ImmutableOpenAPIObject, 'paths' | 'components'>;
/**
* @public
*/
export type PathDoc = Pick<OpenAPIObject, 'paths'>;
export type PathDoc = Pick<ImmutableOpenAPIObject, 'paths'>;
/**
* Get value types of `T`
@@ -140,10 +144,10 @@ export type ComponentTypes<Doc extends RequiredDoc> = Extract<
export type ComponentRef<
Doc extends RequiredDoc,
Type extends ComponentTypes<Doc>,
Ref extends ReferenceObject,
Ref extends ImmutableReferenceObject,
> = Ref extends { $ref: `#/components/${Type}/${infer Name}` }
? Name extends keyof Doc['components'][Type]
? Doc['components'][Type][Name] extends ReferenceObject
? Doc['components'][Type][Name] extends ImmutableReferenceObject
? ComponentRef<Doc, Type, Doc['components'][Type][Name]>
: Doc['components'][Type][Name]
: never
@@ -167,8 +171,8 @@ export type SchemaRef<Doc extends RequiredDoc, Schema> = Schema extends {
*/
export type ObjectWithContentSchema<
Doc extends RequiredDoc,
Object extends { content?: ContentObject },
> = Object['content'] extends ContentObject
Object extends { content?: ImmutableContentObject },
> = Object['content'] extends ImmutableContentObject
? SchemaRef<Doc, Object['content']['application/json']['schema']>
: never;
@@ -14,10 +14,10 @@
* limitations under the License.
*/
import type {
ContentObject as MutableContentObject,
OpenAPIObject as MutableOpenApiObject,
ReferenceObject as MutableReferenceObject,
RequestBodyObject as MutableRequestBodyObject,
ContentObject,
OpenAPIObject,
ReferenceObject,
RequestBodyObject,
} from 'openapi3-ts';
/**
@@ -25,6 +25,11 @@ import type {
* package due to issues with `as const` supporting only readonly values.
*/
/**
* From {@link https://github.com/microsoft/TypeScript/issues/13923#issuecomment-653675557}, allows
* us to convert from `as const` to the various OpenAPI types documented in `openapi3-ts`.
* @public
*/
export type Immutable<T> = T extends
| Function
| boolean
@@ -39,13 +44,27 @@ export type Immutable<T> = T extends
? ReadonlySet<Immutable<S>>
: { readonly [P in keyof T]: Immutable<T[P]> };
// This works for objects, arrays and tuples:
/**
* @public
*/
export type ImmutableObject<T> = { readonly [K in keyof T]: Immutable<T[K]> };
export type ReferenceObject = ImmutableObject<MutableReferenceObject>;
/**
* @public
*/
export type ImmutableReferenceObject = ImmutableObject<ReferenceObject>;
export type OpenAPIObject = ImmutableObject<MutableOpenApiObject>;
/**
* @public
*/
export type ImmutableOpenAPIObject = ImmutableObject<OpenAPIObject>;
export type ContentObject = ImmutableObject<MutableContentObject>;
/**
* @public
*/
export type ImmutableContentObject = ImmutableObject<ContentObject>;
export type RequestBodyObject = ImmutableObject<MutableRequestBodyObject>;
/**
* @public
*/
export type ImmutableRequestBodyObject = ImmutableObject<RequestBodyObject>;
@@ -17,3 +17,4 @@ export * from './common';
export * from './express';
export * from './requests';
export * from './responses';
export * from './immutable';
@@ -30,7 +30,10 @@ import type {
PathTemplate,
ToTypeSafe,
} from './common';
import { ReferenceObject, RequestBodyObject } from './immutable';
import {
ImmutableReferenceObject,
ImmutableRequestBodyObject,
} from './immutable';
/**
* @public
@@ -39,7 +42,11 @@ export type RequestBody<
Doc extends RequiredDoc,
Path extends Extract<keyof Doc['paths'], string>,
Method extends keyof Doc['paths'][Path],
> = DocOperation<Doc, Path, Method>['requestBody'] extends ReferenceObject
> = DocOperation<
Doc,
Path,
Method
>['requestBody'] extends ImmutableReferenceObject
? 'requestBodies' extends ComponentTypes<Doc>
? ComponentRef<
Doc,
@@ -56,7 +63,11 @@ export type RequestBodySchema<
Doc extends RequiredDoc,
Path extends DocPathTemplate<Doc>,
Method extends DocPathMethod<Doc, Path>,
> = RequestBody<Doc, DocPath<Doc, Path>, Method> extends RequestBodyObject
> = RequestBody<
Doc,
DocPath<Doc, Path>,
Method
> extends ImmutableRequestBodyObject
? ObjectWithContentSchema<Doc, RequestBody<Doc, DocPath<Doc, Path>, Method>>
: never;