@affinidi/tools-openapi
Version:
SDK core monorepo for affinity DID solution
122 lines (121 loc) • 8.62 kB
TypeScript
import { AllOfObjectSpec, AnyOfObjectSpec, ContentSpec, FieldSpecArrayType, FieldSpecBooleanType, FieldSpecDoubleType, FieldSpecEnumType, FieldSpecPrimitiveType, FieldSpecRecordType, FieldSpecRefType, FieldSpecStringType, GenericApiSpec, ObjectSpec, ObjectSpecOptionNullable, ObjectSpecs, ObjectSpecType, OneOfObjectSpec, OperationSpec, ParameterSpec, ParameterType, PathSpec, PathSpecs, RequestSpec, RequestSpecWithData, ResponseSpec, ResponseSpecWithData, SimpleObjectSpec } from "./openapi";
import { SafeGetArray, Simplify } from "./util";
declare type GenericDataType<TDataType extends string, TAdditionalData extends Record<string, unknown>> = {
dataType: TDataType;
} & TAdditionalData;
export declare type DataRefType<TRefName extends string> = GenericDataType<'ref', {
refName: TRefName;
}>;
export declare type DataPrimitiveType<TPrimitiveType extends string | boolean | number> = GenericDataType<'primitive', {
primitiveType: TPrimitiveType;
}>;
export declare type DataRecordType = GenericDataType<'record', Record<never, never>>;
export declare type DataArrayType = GenericDataType<'array', {
elementType: DataTypeWithOptions;
}>;
export declare type DataObjectType = GenericDataType<'object', {
properties: Record<string, DataTypeWithOptions & {
isRequired: boolean;
}>;
isAdditionalProperties: boolean;
}>;
export declare type DataAllOfType<TElementTypes extends readonly DataType[]> = GenericDataType<'allOf', {
allOf: TElementTypes;
}>;
export declare type DataAnyOfType<TElementTypes extends readonly DataType[]> = GenericDataType<'anyOf', {
anyOf: TElementTypes;
}>;
export declare type DataType = DataRefType<string> | DataPrimitiveType<string | boolean | number> | DataRecordType | DataArrayType | DataObjectType | DataAllOfType<readonly DataType[]> | DataAnyOfType<readonly DataType[]>;
export declare type DataTypeWithOptions = DataType & {
isNullable: boolean;
};
declare type DataErrorType<TMessage extends string, T> = GenericDataType<'error', {
message: TMessage;
originalType: T;
}>;
declare type ParseFieldSpecPrimitiveType<TField extends FieldSpecPrimitiveType> = TField extends FieldSpecRefType<infer URefName> ? DataRefType<URefName> : TField extends FieldSpecBooleanType ? DataPrimitiveType<boolean> : TField extends FieldSpecStringType ? DataPrimitiveType<string> : TField extends FieldSpecDoubleType ? DataPrimitiveType<number> : TField extends FieldSpecRecordType ? DataRecordType : TField extends FieldSpecEnumType<infer UEnum> ? DataPrimitiveType<UEnum> : DataErrorType<'Unable to find matching primitive type', TField>;
declare type ParseFieldSpecArrayType<TInnerFieldSpec extends ObjectSpecType, TField extends FieldSpecArrayType<TInnerFieldSpec>> = {
dataType: 'array';
elementType: ParseObjectSpec<TInnerFieldSpec>;
};
declare type ParseSimpleObjectSpecWithParameters<TKeys extends string, TRequiredKeysArray extends readonly TKeys[], TIsAdditionalPropertiesAllowed extends boolean, TObject extends SimpleObjectSpec<TKeys, TRequiredKeysArray, TIsAdditionalPropertiesAllowed>> = {
dataType: 'object';
properties: {
readonly [key in TKeys]: ParseObjectSpec<TObject['properties'][key]> & {
isRequired: key extends SafeGetArray<TObject['required']>[number] ? true : false;
};
};
isAdditionalProperties: TObject extends {
additionalProperties?: false;
} ? false : true;
};
declare type ParseFlatObjectSpecType<TObject extends ObjectSpecType> = TObject extends FieldSpecPrimitiveType ? ParseFieldSpecPrimitiveType<TObject> : TObject extends FieldSpecArrayType<infer UInnerFieldSpec> ? ParseFieldSpecArrayType<UInnerFieldSpec, TObject> : TObject extends SimpleObjectSpec<infer UKeys, infer URequiredKeysArray, boolean> ? ParseSimpleObjectSpecWithParameters<UKeys, URequiredKeysArray, boolean, TObject> : DataErrorType<'Unable to find matching object spec type', TObject>;
declare type ParseAllOfObjectSpec<TObjectSpecType extends readonly ObjectSpecType[]> = {
dataType: 'allOf';
allOf: {
[key in keyof TObjectSpecType]: TObjectSpecType[key] extends TObjectSpecType[number] ? ParseFlatObjectSpecType<TObjectSpecType[key]> : never;
};
};
declare type ParseAnyOfObjectSpec<TObjectSpecType extends readonly ObjectSpecType[]> = {
dataType: 'anyOf';
anyOf: {
[key in keyof TObjectSpecType]: TObjectSpecType[key] extends TObjectSpecType[number] ? ParseFlatObjectSpecType<TObjectSpecType[key]> : never;
};
};
declare type ParseComplexObjectSpecType<TObject extends ObjectSpecType> = TObject extends AllOfObjectSpec<infer UObjectSpecTypes> ? ParseAllOfObjectSpec<UObjectSpecTypes> : TObject extends AnyOfObjectSpec<infer UObjectSpecTypes> ? ParseAnyOfObjectSpec<UObjectSpecTypes> : TObject extends OneOfObjectSpec<infer UObjectSpecTypes> ? ParseAnyOfObjectSpec<UObjectSpecTypes> : ParseFlatObjectSpecType<TObject>;
declare type ParseObjectSpec<TObject extends ObjectSpec> = ParseComplexObjectSpecType<TObject> & {
isNullable: TObject extends ObjectSpecOptionNullable ? true : false;
};
declare type ParseObjectSpecs<TObjectSpecs extends ObjectSpecs<string>> = {
[key in keyof TObjectSpecs]: key extends `FreeFormObject${string}` ? {
dataType: 'record';
} : ParseObjectSpec<TObjectSpecs[key]>;
};
declare type ParseContentSpec<TContentSpec extends ContentSpec> = ParseObjectSpec<TContentSpec['content']['application/json']['schema']>;
declare type ParseRequestSpec<TRequestSpec extends RequestSpec> = TRequestSpec extends RequestSpecWithData ? ParseContentSpec<TRequestSpec> : undefined;
declare type ParseResponseSpec<TResponseSpec extends ResponseSpec> = TResponseSpec extends ResponseSpecWithData ? TResponseSpec extends Record<string, infer U> ? ParseContentSpec<Extract<U, ContentSpec>> : DataErrorType<'Unable to infer response content type', TResponseSpec> : undefined;
declare type ParseOperationParameterSpec<TParameterSpec extends ParameterSpec> = ParseObjectSpec<TParameterSpec['schema']> & {
isRequired: TParameterSpec['required'];
};
declare type ParseOperationParametersSpec<TParameterSpecs extends ParameterSpec> = {
dataType: 'object';
properties: {
readonly [key in TParameterSpecs['name']]: ParseOperationParameterSpec<Extract<TParameterSpecs, {
name: key;
}>>;
};
isAdditionalProperties: false;
};
declare type GetOperationParametersByParameterType<TOperationSpec extends OperationSpec, TParameterType extends ParameterType> = TOperationSpec['parameters'] extends readonly (infer UParameterSpec)[] ? TParameterType extends TOperationSpec['parameters'][number]['in'] ? Extract<UParameterSpec, ParameterSpec & {
in: TParameterType;
}> : never : never;
declare type ParseOperationParametersByParameterType<TOperationSpec extends OperationSpec, TParameterType extends ParameterType> = ParseOperationParametersSpec<GetOperationParametersByParameterType<TOperationSpec, TParameterType>>;
export declare type ParsedOperationSpec = {
pathParams?: DataObjectType;
queryParams?: DataObjectType;
requestBody?: DataType;
responseBody?: DataType;
};
declare type ParseOperationSpec<TOperationSpec extends OperationSpec> = {
pathParams: ParseOperationParametersByParameterType<TOperationSpec, 'path'>;
queryParams: ParseOperationParametersByParameterType<TOperationSpec, 'query'>;
requestBody: ParseRequestSpec<TOperationSpec['requestBody']>;
responseBody: ParseResponseSpec<TOperationSpec['responses']>;
};
declare type ParseOperationSpecs<TOperationSpecs extends OperationSpec> = {
readonly [key in TOperationSpecs['operationId']]: ParseOperationSpec<Extract<TOperationSpecs, {
operationId: key;
}>>;
};
declare type GetOperationsFromPathSpec<TPathSpec extends PathSpec> = TPathSpec extends Record<string, infer UOperationSpec> ? Extract<UOperationSpec, OperationSpec> : DataErrorType<'Unable to parse path spec', TPathSpec>;
declare type GetOperationsFromPathSpecs<TPathSpecs extends PathSpecs<string>> = TPathSpecs extends Record<string, infer UPathSpec> ? GetOperationsFromPathSpec<UPathSpec> : DataErrorType<'Unable to parse path specs', TPathSpecs>;
export declare type ParsedSpec = {
objects: Record<string, DataType>;
operations: Record<string, ParsedOperationSpec>;
};
declare type ParseSpecRaw<TApiSpec extends GenericApiSpec> = {
objects: ParseObjectSpecs<TApiSpec['components']['schemas']>;
operations: ParseOperationSpecs<GetOperationsFromPathSpecs<TApiSpec['paths']>>;
};
export declare type ParseSpec<TApiSpec extends GenericApiSpec> = Simplify<ParseSpecRaw<TApiSpec>>;
export {};