forked from loafle/openapi-generator-original
Generalized mime type support (#17285)
* implemented generalized content-type handling * regenerated samples * addressed implementation review feedback * added tests for proposed improvements
This commit is contained in:
parent
dc047b4e91
commit
aacea3477f
@ -22,16 +22,6 @@ let primitives = [
|
||||
"any"
|
||||
];
|
||||
|
||||
const supportedMediaTypes: { [mediaType: string]: number } = {
|
||||
"application/json": Infinity,
|
||||
"application/json-patch+json": 1,
|
||||
"application/merge-patch+json": 1,
|
||||
"application/strategic-merge-patch+json": 1,
|
||||
"application/octet-stream": 0,
|
||||
"application/x-www-form-urlencoded": 0
|
||||
}
|
||||
|
||||
|
||||
let enumsMap: Set<string> = new Set<string>([
|
||||
{{#models}}
|
||||
{{#model}}
|
||||
@ -59,6 +49,58 @@ let typeMap: {[index: string]: any} = {
|
||||
{{/models}}
|
||||
}
|
||||
|
||||
type MimeTypeDescriptor = {
|
||||
type: string;
|
||||
subtype: string;
|
||||
subtypeTokens: string[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Every mime-type consists of a type, subtype, and optional parameters.
|
||||
* The subtype can be composite, including information about the content format.
|
||||
* For example: `application/json-patch+json`, `application/merge-patch+json`.
|
||||
*
|
||||
* This helper transforms a string mime-type into an internal representation.
|
||||
* This simplifies the implementation of predicates that in turn define common rules for parsing or stringifying
|
||||
* the payload.
|
||||
*/
|
||||
const parseMimeType = (mimeType: string): MimeTypeDescriptor => {
|
||||
const [type, subtype] = mimeType.split('/');
|
||||
return {
|
||||
type,
|
||||
subtype,
|
||||
subtypeTokens: subtype.split('+'),
|
||||
};
|
||||
};
|
||||
|
||||
type MimeTypePredicate = (mimeType: string) => boolean;
|
||||
|
||||
// This factory creates a predicate function that checks a string mime-type against defined rules.
|
||||
const mimeTypePredicateFactory = (predicate: (descriptor: MimeTypeDescriptor) => boolean): MimeTypePredicate => (mimeType) => predicate(parseMimeType(mimeType));
|
||||
|
||||
// Use this factory when you need to define a simple predicate based only on type and, if applicable, subtype.
|
||||
const mimeTypeSimplePredicateFactory = (type: string, subtype?: string): MimeTypePredicate => mimeTypePredicateFactory((descriptor) => {
|
||||
if (descriptor.type !== type) return false;
|
||||
if (subtype != null && descriptor.subtype !== subtype) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
// Creating a set of named predicates that will help us determine how to handle different mime-types
|
||||
const isTextLikeMimeType = mimeTypeSimplePredicateFactory('text');
|
||||
const isJsonMimeType = mimeTypeSimplePredicateFactory('application', 'json');
|
||||
const isJsonLikeMimeType = mimeTypePredicateFactory((descriptor) => descriptor.type === 'application' && descriptor.subtypeTokens.some((item) => item === 'json'));
|
||||
const isOctetStreamMimeType = mimeTypeSimplePredicateFactory('application', 'octet-stream');
|
||||
const isFormUrlencodedMimeType = mimeTypeSimplePredicateFactory('application', 'x-www-form-urlencoded');
|
||||
|
||||
// Defining a list of mime-types in the order of prioritization for handling.
|
||||
const supportedMimeTypePredicatesWithPriority: MimeTypePredicate[] = [
|
||||
isJsonMimeType,
|
||||
isJsonLikeMimeType,
|
||||
isTextLikeMimeType,
|
||||
isOctetStreamMimeType,
|
||||
isFormUrlencodedMimeType,
|
||||
];
|
||||
|
||||
export class ObjectSerializer {
|
||||
public static findCorrectType(data: any, expectedType: string) {
|
||||
if (data == undefined) {
|
||||
@ -204,31 +246,27 @@ export class ObjectSerializer {
|
||||
}
|
||||
|
||||
const normalMediaTypes = mediaTypes.map(this.normalizeMediaType);
|
||||
let selectedMediaType: string | undefined = undefined;
|
||||
let selectedRank: number = -Infinity;
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (supportedMediaTypes[mediaType!] > selectedRank) {
|
||||
selectedMediaType = mediaType;
|
||||
selectedRank = supportedMediaTypes[mediaType!];
|
||||
|
||||
for (const predicate of supportedMimeTypePredicatesWithPriority) {
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (mediaType != null && predicate(mediaType)) {
|
||||
return mediaType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedMediaType === undefined) {
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
return selectedMediaType!;
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert data to a string according the given media type
|
||||
*/
|
||||
public static stringify(data: any, mediaType: string): string {
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return String(data);
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
|
||||
@ -243,18 +281,14 @@ export class ObjectSerializer {
|
||||
throw new Error("Cannot parse content. No Content-Type defined.");
|
||||
}
|
||||
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.parse(rawData);
|
||||
}
|
||||
|
||||
if (mediaType === "text/html") {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.parse.");
|
||||
}
|
||||
}
|
||||
|
@ -14,16 +14,6 @@ let primitives = [
|
||||
"any"
|
||||
];
|
||||
|
||||
const supportedMediaTypes: { [mediaType: string]: number } = {
|
||||
"application/json": Infinity,
|
||||
"application/json-patch+json": 1,
|
||||
"application/merge-patch+json": 1,
|
||||
"application/strategic-merge-patch+json": 1,
|
||||
"application/octet-stream": 0,
|
||||
"application/x-www-form-urlencoded": 0
|
||||
}
|
||||
|
||||
|
||||
let enumsMap: Set<string> = new Set<string>([
|
||||
]);
|
||||
|
||||
@ -31,6 +21,58 @@ let typeMap: {[index: string]: any} = {
|
||||
"Response": Response,
|
||||
}
|
||||
|
||||
type MimeTypeDescriptor = {
|
||||
type: string;
|
||||
subtype: string;
|
||||
subtypeTokens: string[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Every mime-type consists of a type, subtype, and optional parameters.
|
||||
* The subtype can be composite, including information about the content format.
|
||||
* For example: `application/json-patch+json`, `application/merge-patch+json`.
|
||||
*
|
||||
* This helper transforms a string mime-type into an internal representation.
|
||||
* This simplifies the implementation of predicates that in turn define common rules for parsing or stringifying
|
||||
* the payload.
|
||||
*/
|
||||
const parseMimeType = (mimeType: string): MimeTypeDescriptor => {
|
||||
const [type, subtype] = mimeType.split('/');
|
||||
return {
|
||||
type,
|
||||
subtype,
|
||||
subtypeTokens: subtype.split('+'),
|
||||
};
|
||||
};
|
||||
|
||||
type MimeTypePredicate = (mimeType: string) => boolean;
|
||||
|
||||
// This factory creates a predicate function that checks a string mime-type against defined rules.
|
||||
const mimeTypePredicateFactory = (predicate: (descriptor: MimeTypeDescriptor) => boolean): MimeTypePredicate => (mimeType) => predicate(parseMimeType(mimeType));
|
||||
|
||||
// Use this factory when you need to define a simple predicate based only on type and, if applicable, subtype.
|
||||
const mimeTypeSimplePredicateFactory = (type: string, subtype?: string): MimeTypePredicate => mimeTypePredicateFactory((descriptor) => {
|
||||
if (descriptor.type !== type) return false;
|
||||
if (subtype != null && descriptor.subtype !== subtype) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
// Creating a set of named predicates that will help us determine how to handle different mime-types
|
||||
const isTextLikeMimeType = mimeTypeSimplePredicateFactory('text');
|
||||
const isJsonMimeType = mimeTypeSimplePredicateFactory('application', 'json');
|
||||
const isJsonLikeMimeType = mimeTypePredicateFactory((descriptor) => descriptor.type === 'application' && descriptor.subtypeTokens.some((item) => item === 'json'));
|
||||
const isOctetStreamMimeType = mimeTypeSimplePredicateFactory('application', 'octet-stream');
|
||||
const isFormUrlencodedMimeType = mimeTypeSimplePredicateFactory('application', 'x-www-form-urlencoded');
|
||||
|
||||
// Defining a list of mime-types in the order of prioritization for handling.
|
||||
const supportedMimeTypePredicatesWithPriority: MimeTypePredicate[] = [
|
||||
isJsonMimeType,
|
||||
isJsonLikeMimeType,
|
||||
isTextLikeMimeType,
|
||||
isOctetStreamMimeType,
|
||||
isFormUrlencodedMimeType,
|
||||
];
|
||||
|
||||
export class ObjectSerializer {
|
||||
public static findCorrectType(data: any, expectedType: string) {
|
||||
if (data == undefined) {
|
||||
@ -176,31 +218,27 @@ export class ObjectSerializer {
|
||||
}
|
||||
|
||||
const normalMediaTypes = mediaTypes.map(this.normalizeMediaType);
|
||||
let selectedMediaType: string | undefined = undefined;
|
||||
let selectedRank: number = -Infinity;
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (supportedMediaTypes[mediaType!] > selectedRank) {
|
||||
selectedMediaType = mediaType;
|
||||
selectedRank = supportedMediaTypes[mediaType!];
|
||||
|
||||
for (const predicate of supportedMimeTypePredicatesWithPriority) {
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (mediaType != null && predicate(mediaType)) {
|
||||
return mediaType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedMediaType === undefined) {
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
return selectedMediaType!;
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert data to a string according the given media type
|
||||
*/
|
||||
public static stringify(data: any, mediaType: string): string {
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return String(data);
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
|
||||
@ -215,18 +253,14 @@ export class ObjectSerializer {
|
||||
throw new Error("Cannot parse content. No Content-Type defined.");
|
||||
}
|
||||
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.parse(rawData);
|
||||
}
|
||||
|
||||
if (mediaType === "text/html") {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.parse.");
|
||||
}
|
||||
}
|
||||
|
@ -24,16 +24,6 @@ let primitives = [
|
||||
"any"
|
||||
];
|
||||
|
||||
const supportedMediaTypes: { [mediaType: string]: number } = {
|
||||
"application/json": Infinity,
|
||||
"application/json-patch+json": 1,
|
||||
"application/merge-patch+json": 1,
|
||||
"application/strategic-merge-patch+json": 1,
|
||||
"application/octet-stream": 0,
|
||||
"application/x-www-form-urlencoded": 0
|
||||
}
|
||||
|
||||
|
||||
let enumsMap: Set<string> = new Set<string>([
|
||||
"OrderStatusEnum",
|
||||
"PetStatusEnum",
|
||||
@ -48,6 +38,58 @@ let typeMap: {[index: string]: any} = {
|
||||
"User": User,
|
||||
}
|
||||
|
||||
type MimeTypeDescriptor = {
|
||||
type: string;
|
||||
subtype: string;
|
||||
subtypeTokens: string[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Every mime-type consists of a type, subtype, and optional parameters.
|
||||
* The subtype can be composite, including information about the content format.
|
||||
* For example: `application/json-patch+json`, `application/merge-patch+json`.
|
||||
*
|
||||
* This helper transforms a string mime-type into an internal representation.
|
||||
* This simplifies the implementation of predicates that in turn define common rules for parsing or stringifying
|
||||
* the payload.
|
||||
*/
|
||||
const parseMimeType = (mimeType: string): MimeTypeDescriptor => {
|
||||
const [type, subtype] = mimeType.split('/');
|
||||
return {
|
||||
type,
|
||||
subtype,
|
||||
subtypeTokens: subtype.split('+'),
|
||||
};
|
||||
};
|
||||
|
||||
type MimeTypePredicate = (mimeType: string) => boolean;
|
||||
|
||||
// This factory creates a predicate function that checks a string mime-type against defined rules.
|
||||
const mimeTypePredicateFactory = (predicate: (descriptor: MimeTypeDescriptor) => boolean): MimeTypePredicate => (mimeType) => predicate(parseMimeType(mimeType));
|
||||
|
||||
// Use this factory when you need to define a simple predicate based only on type and, if applicable, subtype.
|
||||
const mimeTypeSimplePredicateFactory = (type: string, subtype?: string): MimeTypePredicate => mimeTypePredicateFactory((descriptor) => {
|
||||
if (descriptor.type !== type) return false;
|
||||
if (subtype != null && descriptor.subtype !== subtype) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
// Creating a set of named predicates that will help us determine how to handle different mime-types
|
||||
const isTextLikeMimeType = mimeTypeSimplePredicateFactory('text');
|
||||
const isJsonMimeType = mimeTypeSimplePredicateFactory('application', 'json');
|
||||
const isJsonLikeMimeType = mimeTypePredicateFactory((descriptor) => descriptor.type === 'application' && descriptor.subtypeTokens.some((item) => item === 'json'));
|
||||
const isOctetStreamMimeType = mimeTypeSimplePredicateFactory('application', 'octet-stream');
|
||||
const isFormUrlencodedMimeType = mimeTypeSimplePredicateFactory('application', 'x-www-form-urlencoded');
|
||||
|
||||
// Defining a list of mime-types in the order of prioritization for handling.
|
||||
const supportedMimeTypePredicatesWithPriority: MimeTypePredicate[] = [
|
||||
isJsonMimeType,
|
||||
isJsonLikeMimeType,
|
||||
isTextLikeMimeType,
|
||||
isOctetStreamMimeType,
|
||||
isFormUrlencodedMimeType,
|
||||
];
|
||||
|
||||
export class ObjectSerializer {
|
||||
public static findCorrectType(data: any, expectedType: string) {
|
||||
if (data == undefined) {
|
||||
@ -193,31 +235,27 @@ export class ObjectSerializer {
|
||||
}
|
||||
|
||||
const normalMediaTypes = mediaTypes.map(this.normalizeMediaType);
|
||||
let selectedMediaType: string | undefined = undefined;
|
||||
let selectedRank: number = -Infinity;
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (supportedMediaTypes[mediaType!] > selectedRank) {
|
||||
selectedMediaType = mediaType;
|
||||
selectedRank = supportedMediaTypes[mediaType!];
|
||||
|
||||
for (const predicate of supportedMimeTypePredicatesWithPriority) {
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (mediaType != null && predicate(mediaType)) {
|
||||
return mediaType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedMediaType === undefined) {
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
return selectedMediaType!;
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert data to a string according the given media type
|
||||
*/
|
||||
public static stringify(data: any, mediaType: string): string {
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return String(data);
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
|
||||
@ -232,18 +270,14 @@ export class ObjectSerializer {
|
||||
throw new Error("Cannot parse content. No Content-Type defined.");
|
||||
}
|
||||
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.parse(rawData);
|
||||
}
|
||||
|
||||
if (mediaType === "text/html") {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.parse.");
|
||||
}
|
||||
}
|
||||
|
@ -26,16 +26,6 @@ let primitives = [
|
||||
"any"
|
||||
];
|
||||
|
||||
const supportedMediaTypes: { [mediaType: string]: number } = {
|
||||
"application/json": Infinity,
|
||||
"application/json-patch+json": 1,
|
||||
"application/merge-patch+json": 1,
|
||||
"application/strategic-merge-patch+json": 1,
|
||||
"application/octet-stream": 0,
|
||||
"application/x-www-form-urlencoded": 0
|
||||
}
|
||||
|
||||
|
||||
let enumsMap: Set<string> = new Set<string>([
|
||||
"DogBreedEnum",
|
||||
"PetByTypePetTypeEnum",
|
||||
@ -53,6 +43,58 @@ let typeMap: {[index: string]: any} = {
|
||||
"PetsPatchRequest": PetsPatchRequest,
|
||||
}
|
||||
|
||||
type MimeTypeDescriptor = {
|
||||
type: string;
|
||||
subtype: string;
|
||||
subtypeTokens: string[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Every mime-type consists of a type, subtype, and optional parameters.
|
||||
* The subtype can be composite, including information about the content format.
|
||||
* For example: `application/json-patch+json`, `application/merge-patch+json`.
|
||||
*
|
||||
* This helper transforms a string mime-type into an internal representation.
|
||||
* This simplifies the implementation of predicates that in turn define common rules for parsing or stringifying
|
||||
* the payload.
|
||||
*/
|
||||
const parseMimeType = (mimeType: string): MimeTypeDescriptor => {
|
||||
const [type, subtype] = mimeType.split('/');
|
||||
return {
|
||||
type,
|
||||
subtype,
|
||||
subtypeTokens: subtype.split('+'),
|
||||
};
|
||||
};
|
||||
|
||||
type MimeTypePredicate = (mimeType: string) => boolean;
|
||||
|
||||
// This factory creates a predicate function that checks a string mime-type against defined rules.
|
||||
const mimeTypePredicateFactory = (predicate: (descriptor: MimeTypeDescriptor) => boolean): MimeTypePredicate => (mimeType) => predicate(parseMimeType(mimeType));
|
||||
|
||||
// Use this factory when you need to define a simple predicate based only on type and, if applicable, subtype.
|
||||
const mimeTypeSimplePredicateFactory = (type: string, subtype?: string): MimeTypePredicate => mimeTypePredicateFactory((descriptor) => {
|
||||
if (descriptor.type !== type) return false;
|
||||
if (subtype != null && descriptor.subtype !== subtype) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
// Creating a set of named predicates that will help us determine how to handle different mime-types
|
||||
const isTextLikeMimeType = mimeTypeSimplePredicateFactory('text');
|
||||
const isJsonMimeType = mimeTypeSimplePredicateFactory('application', 'json');
|
||||
const isJsonLikeMimeType = mimeTypePredicateFactory((descriptor) => descriptor.type === 'application' && descriptor.subtypeTokens.some((item) => item === 'json'));
|
||||
const isOctetStreamMimeType = mimeTypeSimplePredicateFactory('application', 'octet-stream');
|
||||
const isFormUrlencodedMimeType = mimeTypeSimplePredicateFactory('application', 'x-www-form-urlencoded');
|
||||
|
||||
// Defining a list of mime-types in the order of prioritization for handling.
|
||||
const supportedMimeTypePredicatesWithPriority: MimeTypePredicate[] = [
|
||||
isJsonMimeType,
|
||||
isJsonLikeMimeType,
|
||||
isTextLikeMimeType,
|
||||
isOctetStreamMimeType,
|
||||
isFormUrlencodedMimeType,
|
||||
];
|
||||
|
||||
export class ObjectSerializer {
|
||||
public static findCorrectType(data: any, expectedType: string) {
|
||||
if (data == undefined) {
|
||||
@ -198,31 +240,27 @@ export class ObjectSerializer {
|
||||
}
|
||||
|
||||
const normalMediaTypes = mediaTypes.map(this.normalizeMediaType);
|
||||
let selectedMediaType: string | undefined = undefined;
|
||||
let selectedRank: number = -Infinity;
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (supportedMediaTypes[mediaType!] > selectedRank) {
|
||||
selectedMediaType = mediaType;
|
||||
selectedRank = supportedMediaTypes[mediaType!];
|
||||
|
||||
for (const predicate of supportedMimeTypePredicatesWithPriority) {
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (mediaType != null && predicate(mediaType)) {
|
||||
return mediaType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedMediaType === undefined) {
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
return selectedMediaType!;
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert data to a string according the given media type
|
||||
*/
|
||||
public static stringify(data: any, mediaType: string): string {
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return String(data);
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
|
||||
@ -237,18 +275,14 @@ export class ObjectSerializer {
|
||||
throw new Error("Cannot parse content. No Content-Type defined.");
|
||||
}
|
||||
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.parse(rawData);
|
||||
}
|
||||
|
||||
if (mediaType === "text/html") {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.parse.");
|
||||
}
|
||||
}
|
||||
|
@ -24,16 +24,6 @@ let primitives = [
|
||||
"any"
|
||||
];
|
||||
|
||||
const supportedMediaTypes: { [mediaType: string]: number } = {
|
||||
"application/json": Infinity,
|
||||
"application/json-patch+json": 1,
|
||||
"application/merge-patch+json": 1,
|
||||
"application/strategic-merge-patch+json": 1,
|
||||
"application/octet-stream": 0,
|
||||
"application/x-www-form-urlencoded": 0
|
||||
}
|
||||
|
||||
|
||||
let enumsMap: Set<string> = new Set<string>([
|
||||
"OrderStatusEnum",
|
||||
"PetStatusEnum",
|
||||
@ -48,6 +38,58 @@ let typeMap: {[index: string]: any} = {
|
||||
"User": User,
|
||||
}
|
||||
|
||||
type MimeTypeDescriptor = {
|
||||
type: string;
|
||||
subtype: string;
|
||||
subtypeTokens: string[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Every mime-type consists of a type, subtype, and optional parameters.
|
||||
* The subtype can be composite, including information about the content format.
|
||||
* For example: `application/json-patch+json`, `application/merge-patch+json`.
|
||||
*
|
||||
* This helper transforms a string mime-type into an internal representation.
|
||||
* This simplifies the implementation of predicates that in turn define common rules for parsing or stringifying
|
||||
* the payload.
|
||||
*/
|
||||
const parseMimeType = (mimeType: string): MimeTypeDescriptor => {
|
||||
const [type, subtype] = mimeType.split('/');
|
||||
return {
|
||||
type,
|
||||
subtype,
|
||||
subtypeTokens: subtype.split('+'),
|
||||
};
|
||||
};
|
||||
|
||||
type MimeTypePredicate = (mimeType: string) => boolean;
|
||||
|
||||
// This factory creates a predicate function that checks a string mime-type against defined rules.
|
||||
const mimeTypePredicateFactory = (predicate: (descriptor: MimeTypeDescriptor) => boolean): MimeTypePredicate => (mimeType) => predicate(parseMimeType(mimeType));
|
||||
|
||||
// Use this factory when you need to define a simple predicate based only on type and, if applicable, subtype.
|
||||
const mimeTypeSimplePredicateFactory = (type: string, subtype?: string): MimeTypePredicate => mimeTypePredicateFactory((descriptor) => {
|
||||
if (descriptor.type !== type) return false;
|
||||
if (subtype != null && descriptor.subtype !== subtype) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
// Creating a set of named predicates that will help us determine how to handle different mime-types
|
||||
const isTextLikeMimeType = mimeTypeSimplePredicateFactory('text');
|
||||
const isJsonMimeType = mimeTypeSimplePredicateFactory('application', 'json');
|
||||
const isJsonLikeMimeType = mimeTypePredicateFactory((descriptor) => descriptor.type === 'application' && descriptor.subtypeTokens.some((item) => item === 'json'));
|
||||
const isOctetStreamMimeType = mimeTypeSimplePredicateFactory('application', 'octet-stream');
|
||||
const isFormUrlencodedMimeType = mimeTypeSimplePredicateFactory('application', 'x-www-form-urlencoded');
|
||||
|
||||
// Defining a list of mime-types in the order of prioritization for handling.
|
||||
const supportedMimeTypePredicatesWithPriority: MimeTypePredicate[] = [
|
||||
isJsonMimeType,
|
||||
isJsonLikeMimeType,
|
||||
isTextLikeMimeType,
|
||||
isOctetStreamMimeType,
|
||||
isFormUrlencodedMimeType,
|
||||
];
|
||||
|
||||
export class ObjectSerializer {
|
||||
public static findCorrectType(data: any, expectedType: string) {
|
||||
if (data == undefined) {
|
||||
@ -193,31 +235,27 @@ export class ObjectSerializer {
|
||||
}
|
||||
|
||||
const normalMediaTypes = mediaTypes.map(this.normalizeMediaType);
|
||||
let selectedMediaType: string | undefined = undefined;
|
||||
let selectedRank: number = -Infinity;
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (supportedMediaTypes[mediaType!] > selectedRank) {
|
||||
selectedMediaType = mediaType;
|
||||
selectedRank = supportedMediaTypes[mediaType!];
|
||||
|
||||
for (const predicate of supportedMimeTypePredicatesWithPriority) {
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (mediaType != null && predicate(mediaType)) {
|
||||
return mediaType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedMediaType === undefined) {
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
return selectedMediaType!;
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert data to a string according the given media type
|
||||
*/
|
||||
public static stringify(data: any, mediaType: string): string {
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return String(data);
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
|
||||
@ -232,18 +270,14 @@ export class ObjectSerializer {
|
||||
throw new Error("Cannot parse content. No Content-Type defined.");
|
||||
}
|
||||
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.parse(rawData);
|
||||
}
|
||||
|
||||
if (mediaType === "text/html") {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.parse.");
|
||||
}
|
||||
}
|
||||
|
@ -24,16 +24,6 @@ let primitives = [
|
||||
"any"
|
||||
];
|
||||
|
||||
const supportedMediaTypes: { [mediaType: string]: number } = {
|
||||
"application/json": Infinity,
|
||||
"application/json-patch+json": 1,
|
||||
"application/merge-patch+json": 1,
|
||||
"application/strategic-merge-patch+json": 1,
|
||||
"application/octet-stream": 0,
|
||||
"application/x-www-form-urlencoded": 0
|
||||
}
|
||||
|
||||
|
||||
let enumsMap: Set<string> = new Set<string>([
|
||||
"OrderStatusEnum",
|
||||
"PetStatusEnum",
|
||||
@ -48,6 +38,58 @@ let typeMap: {[index: string]: any} = {
|
||||
"User": User,
|
||||
}
|
||||
|
||||
type MimeTypeDescriptor = {
|
||||
type: string;
|
||||
subtype: string;
|
||||
subtypeTokens: string[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Every mime-type consists of a type, subtype, and optional parameters.
|
||||
* The subtype can be composite, including information about the content format.
|
||||
* For example: `application/json-patch+json`, `application/merge-patch+json`.
|
||||
*
|
||||
* This helper transforms a string mime-type into an internal representation.
|
||||
* This simplifies the implementation of predicates that in turn define common rules for parsing or stringifying
|
||||
* the payload.
|
||||
*/
|
||||
const parseMimeType = (mimeType: string): MimeTypeDescriptor => {
|
||||
const [type, subtype] = mimeType.split('/');
|
||||
return {
|
||||
type,
|
||||
subtype,
|
||||
subtypeTokens: subtype.split('+'),
|
||||
};
|
||||
};
|
||||
|
||||
type MimeTypePredicate = (mimeType: string) => boolean;
|
||||
|
||||
// This factory creates a predicate function that checks a string mime-type against defined rules.
|
||||
const mimeTypePredicateFactory = (predicate: (descriptor: MimeTypeDescriptor) => boolean): MimeTypePredicate => (mimeType) => predicate(parseMimeType(mimeType));
|
||||
|
||||
// Use this factory when you need to define a simple predicate based only on type and, if applicable, subtype.
|
||||
const mimeTypeSimplePredicateFactory = (type: string, subtype?: string): MimeTypePredicate => mimeTypePredicateFactory((descriptor) => {
|
||||
if (descriptor.type !== type) return false;
|
||||
if (subtype != null && descriptor.subtype !== subtype) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
// Creating a set of named predicates that will help us determine how to handle different mime-types
|
||||
const isTextLikeMimeType = mimeTypeSimplePredicateFactory('text');
|
||||
const isJsonMimeType = mimeTypeSimplePredicateFactory('application', 'json');
|
||||
const isJsonLikeMimeType = mimeTypePredicateFactory((descriptor) => descriptor.type === 'application' && descriptor.subtypeTokens.some((item) => item === 'json'));
|
||||
const isOctetStreamMimeType = mimeTypeSimplePredicateFactory('application', 'octet-stream');
|
||||
const isFormUrlencodedMimeType = mimeTypeSimplePredicateFactory('application', 'x-www-form-urlencoded');
|
||||
|
||||
// Defining a list of mime-types in the order of prioritization for handling.
|
||||
const supportedMimeTypePredicatesWithPriority: MimeTypePredicate[] = [
|
||||
isJsonMimeType,
|
||||
isJsonLikeMimeType,
|
||||
isTextLikeMimeType,
|
||||
isOctetStreamMimeType,
|
||||
isFormUrlencodedMimeType,
|
||||
];
|
||||
|
||||
export class ObjectSerializer {
|
||||
public static findCorrectType(data: any, expectedType: string) {
|
||||
if (data == undefined) {
|
||||
@ -193,31 +235,27 @@ export class ObjectSerializer {
|
||||
}
|
||||
|
||||
const normalMediaTypes = mediaTypes.map(this.normalizeMediaType);
|
||||
let selectedMediaType: string | undefined = undefined;
|
||||
let selectedRank: number = -Infinity;
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (supportedMediaTypes[mediaType!] > selectedRank) {
|
||||
selectedMediaType = mediaType;
|
||||
selectedRank = supportedMediaTypes[mediaType!];
|
||||
|
||||
for (const predicate of supportedMimeTypePredicatesWithPriority) {
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (mediaType != null && predicate(mediaType)) {
|
||||
return mediaType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedMediaType === undefined) {
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
return selectedMediaType!;
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert data to a string according the given media type
|
||||
*/
|
||||
public static stringify(data: any, mediaType: string): string {
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return String(data);
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
|
||||
@ -232,18 +270,14 @@ export class ObjectSerializer {
|
||||
throw new Error("Cannot parse content. No Content-Type defined.");
|
||||
}
|
||||
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.parse(rawData);
|
||||
}
|
||||
|
||||
if (mediaType === "text/html") {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.parse.");
|
||||
}
|
||||
}
|
||||
|
@ -24,16 +24,6 @@ let primitives = [
|
||||
"any"
|
||||
];
|
||||
|
||||
const supportedMediaTypes: { [mediaType: string]: number } = {
|
||||
"application/json": Infinity,
|
||||
"application/json-patch+json": 1,
|
||||
"application/merge-patch+json": 1,
|
||||
"application/strategic-merge-patch+json": 1,
|
||||
"application/octet-stream": 0,
|
||||
"application/x-www-form-urlencoded": 0
|
||||
}
|
||||
|
||||
|
||||
let enumsMap: Set<string> = new Set<string>([
|
||||
"OrderStatusEnum",
|
||||
"PetStatusEnum",
|
||||
@ -48,6 +38,58 @@ let typeMap: {[index: string]: any} = {
|
||||
"User": User,
|
||||
}
|
||||
|
||||
type MimeTypeDescriptor = {
|
||||
type: string;
|
||||
subtype: string;
|
||||
subtypeTokens: string[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Every mime-type consists of a type, subtype, and optional parameters.
|
||||
* The subtype can be composite, including information about the content format.
|
||||
* For example: `application/json-patch+json`, `application/merge-patch+json`.
|
||||
*
|
||||
* This helper transforms a string mime-type into an internal representation.
|
||||
* This simplifies the implementation of predicates that in turn define common rules for parsing or stringifying
|
||||
* the payload.
|
||||
*/
|
||||
const parseMimeType = (mimeType: string): MimeTypeDescriptor => {
|
||||
const [type, subtype] = mimeType.split('/');
|
||||
return {
|
||||
type,
|
||||
subtype,
|
||||
subtypeTokens: subtype.split('+'),
|
||||
};
|
||||
};
|
||||
|
||||
type MimeTypePredicate = (mimeType: string) => boolean;
|
||||
|
||||
// This factory creates a predicate function that checks a string mime-type against defined rules.
|
||||
const mimeTypePredicateFactory = (predicate: (descriptor: MimeTypeDescriptor) => boolean): MimeTypePredicate => (mimeType) => predicate(parseMimeType(mimeType));
|
||||
|
||||
// Use this factory when you need to define a simple predicate based only on type and, if applicable, subtype.
|
||||
const mimeTypeSimplePredicateFactory = (type: string, subtype?: string): MimeTypePredicate => mimeTypePredicateFactory((descriptor) => {
|
||||
if (descriptor.type !== type) return false;
|
||||
if (subtype != null && descriptor.subtype !== subtype) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
// Creating a set of named predicates that will help us determine how to handle different mime-types
|
||||
const isTextLikeMimeType = mimeTypeSimplePredicateFactory('text');
|
||||
const isJsonMimeType = mimeTypeSimplePredicateFactory('application', 'json');
|
||||
const isJsonLikeMimeType = mimeTypePredicateFactory((descriptor) => descriptor.type === 'application' && descriptor.subtypeTokens.some((item) => item === 'json'));
|
||||
const isOctetStreamMimeType = mimeTypeSimplePredicateFactory('application', 'octet-stream');
|
||||
const isFormUrlencodedMimeType = mimeTypeSimplePredicateFactory('application', 'x-www-form-urlencoded');
|
||||
|
||||
// Defining a list of mime-types in the order of prioritization for handling.
|
||||
const supportedMimeTypePredicatesWithPriority: MimeTypePredicate[] = [
|
||||
isJsonMimeType,
|
||||
isJsonLikeMimeType,
|
||||
isTextLikeMimeType,
|
||||
isOctetStreamMimeType,
|
||||
isFormUrlencodedMimeType,
|
||||
];
|
||||
|
||||
export class ObjectSerializer {
|
||||
public static findCorrectType(data: any, expectedType: string) {
|
||||
if (data == undefined) {
|
||||
@ -193,31 +235,27 @@ export class ObjectSerializer {
|
||||
}
|
||||
|
||||
const normalMediaTypes = mediaTypes.map(this.normalizeMediaType);
|
||||
let selectedMediaType: string | undefined = undefined;
|
||||
let selectedRank: number = -Infinity;
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (supportedMediaTypes[mediaType!] > selectedRank) {
|
||||
selectedMediaType = mediaType;
|
||||
selectedRank = supportedMediaTypes[mediaType!];
|
||||
|
||||
for (const predicate of supportedMimeTypePredicatesWithPriority) {
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (mediaType != null && predicate(mediaType)) {
|
||||
return mediaType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedMediaType === undefined) {
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
return selectedMediaType!;
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert data to a string according the given media type
|
||||
*/
|
||||
public static stringify(data: any, mediaType: string): string {
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return String(data);
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
|
||||
@ -232,18 +270,14 @@ export class ObjectSerializer {
|
||||
throw new Error("Cannot parse content. No Content-Type defined.");
|
||||
}
|
||||
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.parse(rawData);
|
||||
}
|
||||
|
||||
if (mediaType === "text/html") {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.parse.");
|
||||
}
|
||||
}
|
||||
|
@ -24,16 +24,6 @@ let primitives = [
|
||||
"any"
|
||||
];
|
||||
|
||||
const supportedMediaTypes: { [mediaType: string]: number } = {
|
||||
"application/json": Infinity,
|
||||
"application/json-patch+json": 1,
|
||||
"application/merge-patch+json": 1,
|
||||
"application/strategic-merge-patch+json": 1,
|
||||
"application/octet-stream": 0,
|
||||
"application/x-www-form-urlencoded": 0
|
||||
}
|
||||
|
||||
|
||||
let enumsMap: Set<string> = new Set<string>([
|
||||
"OrderStatusEnum",
|
||||
"PetStatusEnum",
|
||||
@ -48,6 +38,58 @@ let typeMap: {[index: string]: any} = {
|
||||
"User": User,
|
||||
}
|
||||
|
||||
type MimeTypeDescriptor = {
|
||||
type: string;
|
||||
subtype: string;
|
||||
subtypeTokens: string[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Every mime-type consists of a type, subtype, and optional parameters.
|
||||
* The subtype can be composite, including information about the content format.
|
||||
* For example: `application/json-patch+json`, `application/merge-patch+json`.
|
||||
*
|
||||
* This helper transforms a string mime-type into an internal representation.
|
||||
* This simplifies the implementation of predicates that in turn define common rules for parsing or stringifying
|
||||
* the payload.
|
||||
*/
|
||||
const parseMimeType = (mimeType: string): MimeTypeDescriptor => {
|
||||
const [type, subtype] = mimeType.split('/');
|
||||
return {
|
||||
type,
|
||||
subtype,
|
||||
subtypeTokens: subtype.split('+'),
|
||||
};
|
||||
};
|
||||
|
||||
type MimeTypePredicate = (mimeType: string) => boolean;
|
||||
|
||||
// This factory creates a predicate function that checks a string mime-type against defined rules.
|
||||
const mimeTypePredicateFactory = (predicate: (descriptor: MimeTypeDescriptor) => boolean): MimeTypePredicate => (mimeType) => predicate(parseMimeType(mimeType));
|
||||
|
||||
// Use this factory when you need to define a simple predicate based only on type and, if applicable, subtype.
|
||||
const mimeTypeSimplePredicateFactory = (type: string, subtype?: string): MimeTypePredicate => mimeTypePredicateFactory((descriptor) => {
|
||||
if (descriptor.type !== type) return false;
|
||||
if (subtype != null && descriptor.subtype !== subtype) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
// Creating a set of named predicates that will help us determine how to handle different mime-types
|
||||
const isTextLikeMimeType = mimeTypeSimplePredicateFactory('text');
|
||||
const isJsonMimeType = mimeTypeSimplePredicateFactory('application', 'json');
|
||||
const isJsonLikeMimeType = mimeTypePredicateFactory((descriptor) => descriptor.type === 'application' && descriptor.subtypeTokens.some((item) => item === 'json'));
|
||||
const isOctetStreamMimeType = mimeTypeSimplePredicateFactory('application', 'octet-stream');
|
||||
const isFormUrlencodedMimeType = mimeTypeSimplePredicateFactory('application', 'x-www-form-urlencoded');
|
||||
|
||||
// Defining a list of mime-types in the order of prioritization for handling.
|
||||
const supportedMimeTypePredicatesWithPriority: MimeTypePredicate[] = [
|
||||
isJsonMimeType,
|
||||
isJsonLikeMimeType,
|
||||
isTextLikeMimeType,
|
||||
isOctetStreamMimeType,
|
||||
isFormUrlencodedMimeType,
|
||||
];
|
||||
|
||||
export class ObjectSerializer {
|
||||
public static findCorrectType(data: any, expectedType: string) {
|
||||
if (data == undefined) {
|
||||
@ -193,31 +235,27 @@ export class ObjectSerializer {
|
||||
}
|
||||
|
||||
const normalMediaTypes = mediaTypes.map(this.normalizeMediaType);
|
||||
let selectedMediaType: string | undefined = undefined;
|
||||
let selectedRank: number = -Infinity;
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (supportedMediaTypes[mediaType!] > selectedRank) {
|
||||
selectedMediaType = mediaType;
|
||||
selectedRank = supportedMediaTypes[mediaType!];
|
||||
|
||||
for (const predicate of supportedMimeTypePredicatesWithPriority) {
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (mediaType != null && predicate(mediaType)) {
|
||||
return mediaType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedMediaType === undefined) {
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
return selectedMediaType!;
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert data to a string according the given media type
|
||||
*/
|
||||
public static stringify(data: any, mediaType: string): string {
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return String(data);
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
|
||||
@ -232,18 +270,14 @@ export class ObjectSerializer {
|
||||
throw new Error("Cannot parse content. No Content-Type defined.");
|
||||
}
|
||||
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.parse(rawData);
|
||||
}
|
||||
|
||||
if (mediaType === "text/html") {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.parse.");
|
||||
}
|
||||
}
|
||||
|
@ -24,16 +24,6 @@ let primitives = [
|
||||
"any"
|
||||
];
|
||||
|
||||
const supportedMediaTypes: { [mediaType: string]: number } = {
|
||||
"application/json": Infinity,
|
||||
"application/json-patch+json": 1,
|
||||
"application/merge-patch+json": 1,
|
||||
"application/strategic-merge-patch+json": 1,
|
||||
"application/octet-stream": 0,
|
||||
"application/x-www-form-urlencoded": 0
|
||||
}
|
||||
|
||||
|
||||
let enumsMap: Set<string> = new Set<string>([
|
||||
"OrderStatusEnum",
|
||||
"PetStatusEnum",
|
||||
@ -48,6 +38,58 @@ let typeMap: {[index: string]: any} = {
|
||||
"User": User,
|
||||
}
|
||||
|
||||
type MimeTypeDescriptor = {
|
||||
type: string;
|
||||
subtype: string;
|
||||
subtypeTokens: string[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Every mime-type consists of a type, subtype, and optional parameters.
|
||||
* The subtype can be composite, including information about the content format.
|
||||
* For example: `application/json-patch+json`, `application/merge-patch+json`.
|
||||
*
|
||||
* This helper transforms a string mime-type into an internal representation.
|
||||
* This simplifies the implementation of predicates that in turn define common rules for parsing or stringifying
|
||||
* the payload.
|
||||
*/
|
||||
const parseMimeType = (mimeType: string): MimeTypeDescriptor => {
|
||||
const [type, subtype] = mimeType.split('/');
|
||||
return {
|
||||
type,
|
||||
subtype,
|
||||
subtypeTokens: subtype.split('+'),
|
||||
};
|
||||
};
|
||||
|
||||
type MimeTypePredicate = (mimeType: string) => boolean;
|
||||
|
||||
// This factory creates a predicate function that checks a string mime-type against defined rules.
|
||||
const mimeTypePredicateFactory = (predicate: (descriptor: MimeTypeDescriptor) => boolean): MimeTypePredicate => (mimeType) => predicate(parseMimeType(mimeType));
|
||||
|
||||
// Use this factory when you need to define a simple predicate based only on type and, if applicable, subtype.
|
||||
const mimeTypeSimplePredicateFactory = (type: string, subtype?: string): MimeTypePredicate => mimeTypePredicateFactory((descriptor) => {
|
||||
if (descriptor.type !== type) return false;
|
||||
if (subtype != null && descriptor.subtype !== subtype) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
// Creating a set of named predicates that will help us determine how to handle different mime-types
|
||||
const isTextLikeMimeType = mimeTypeSimplePredicateFactory('text');
|
||||
const isJsonMimeType = mimeTypeSimplePredicateFactory('application', 'json');
|
||||
const isJsonLikeMimeType = mimeTypePredicateFactory((descriptor) => descriptor.type === 'application' && descriptor.subtypeTokens.some((item) => item === 'json'));
|
||||
const isOctetStreamMimeType = mimeTypeSimplePredicateFactory('application', 'octet-stream');
|
||||
const isFormUrlencodedMimeType = mimeTypeSimplePredicateFactory('application', 'x-www-form-urlencoded');
|
||||
|
||||
// Defining a list of mime-types in the order of prioritization for handling.
|
||||
const supportedMimeTypePredicatesWithPriority: MimeTypePredicate[] = [
|
||||
isJsonMimeType,
|
||||
isJsonLikeMimeType,
|
||||
isTextLikeMimeType,
|
||||
isOctetStreamMimeType,
|
||||
isFormUrlencodedMimeType,
|
||||
];
|
||||
|
||||
export class ObjectSerializer {
|
||||
public static findCorrectType(data: any, expectedType: string) {
|
||||
if (data == undefined) {
|
||||
@ -193,31 +235,27 @@ export class ObjectSerializer {
|
||||
}
|
||||
|
||||
const normalMediaTypes = mediaTypes.map(this.normalizeMediaType);
|
||||
let selectedMediaType: string | undefined = undefined;
|
||||
let selectedRank: number = -Infinity;
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (supportedMediaTypes[mediaType!] > selectedRank) {
|
||||
selectedMediaType = mediaType;
|
||||
selectedRank = supportedMediaTypes[mediaType!];
|
||||
|
||||
for (const predicate of supportedMimeTypePredicatesWithPriority) {
|
||||
for (const mediaType of normalMediaTypes) {
|
||||
if (mediaType != null && predicate(mediaType)) {
|
||||
return mediaType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedMediaType === undefined) {
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
return selectedMediaType!;
|
||||
throw new Error("None of the given media types are supported: " + mediaTypes.join(", "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert data to a string according the given media type
|
||||
*/
|
||||
public static stringify(data: any, mediaType: string): string {
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return String(data);
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
|
||||
@ -232,18 +270,14 @@ export class ObjectSerializer {
|
||||
throw new Error("Cannot parse content. No Content-Type defined.");
|
||||
}
|
||||
|
||||
if (mediaType === "text/plain") {
|
||||
if (isTextLikeMimeType(mediaType)) {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
if (mediaType === "application/json" || mediaType === "application/json-patch+json" || mediaType === "application/merge-patch+json" || mediaType === "application/strategic-merge-patch+json") {
|
||||
if (isJsonLikeMimeType(mediaType)) {
|
||||
return JSON.parse(rawData);
|
||||
}
|
||||
|
||||
if (mediaType === "text/html") {
|
||||
return rawData;
|
||||
}
|
||||
|
||||
throw new Error("The mediaType " + mediaType + " is not supported by ObjectSerializer.parse.");
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,18 @@ const objectSerializerFile = rewire(__dirname + "/../../node_modules/ts-petstore
|
||||
|
||||
const ObjectSerializer = objectSerializerFile.__get__("ObjectSerializer")
|
||||
|
||||
const htmlContent = `
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<title>Error 404 Not Found</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>HTTP ERROR 404</h2>
|
||||
<p>Resource not found</p>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
describe("ObjectSerializer", () => {
|
||||
describe("Serialize", () => {
|
||||
@ -231,10 +243,52 @@ describe("ObjectSerializer", () => {
|
||||
expect(deserialized).to.deep.equal(categories)
|
||||
})
|
||||
})
|
||||
|
||||
describe("Parse", () => {
|
||||
it("text/html", () => {
|
||||
const input = "<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"/>\n<title>Error 404 Not Found</title>\n</head>\n<body><h2>HTTP ERROR 404</h2>\n<p>Resource not found</p>\n</body>\n</html>\n"
|
||||
expect(ObjectSerializer.parse(input, "text/html")).to.equal(input)
|
||||
it("Text", () => {
|
||||
expect(ObjectSerializer.parse("test", "text/plain")).to.equal("test")
|
||||
expect(ObjectSerializer.parse(htmlContent, "text/html")).to.equal(htmlContent)
|
||||
});
|
||||
|
||||
it("JSON", () => {
|
||||
const jsonContent = { foo: "bar"};
|
||||
|
||||
expect(ObjectSerializer.parse(JSON.stringify(jsonContent), "application/json")).to.deep.equal(jsonContent)
|
||||
expect(ObjectSerializer.parse(JSON.stringify(jsonContent), "application/json-patch+json")).to.deep.equal(jsonContent)
|
||||
expect(ObjectSerializer.parse(JSON.stringify(jsonContent), "application/merge-patch+json")).to.deep.equal(jsonContent)
|
||||
});
|
||||
})
|
||||
|
||||
describe("Stringify", () => {
|
||||
it("Text", () => {
|
||||
expect(ObjectSerializer.stringify("test", "text/plain")).to.equal("test")
|
||||
expect(ObjectSerializer.stringify(htmlContent, "text/html")).to.equal(htmlContent)
|
||||
});
|
||||
|
||||
it("JSON", () => {
|
||||
const jsonContent = { foo: "bar"};
|
||||
|
||||
expect(ObjectSerializer.stringify(jsonContent, "application/json")).to.equal(JSON.stringify(jsonContent))
|
||||
expect(ObjectSerializer.stringify(jsonContent, "application/json-patch+json")).to.equal(JSON.stringify(jsonContent))
|
||||
expect(ObjectSerializer.stringify(jsonContent, "application/merge-patch+json")).to.equal(JSON.stringify(jsonContent))
|
||||
});
|
||||
})
|
||||
|
||||
describe("GetPreferredMediaType", () => {
|
||||
it("Empty media-type", () => {
|
||||
expect(ObjectSerializer.getPreferredMediaType([])).to.equal("application/json")
|
||||
});
|
||||
|
||||
it("JSON media-type", () => {
|
||||
expect(ObjectSerializer.getPreferredMediaType(["application/json"])).to.equal("application/json")
|
||||
});
|
||||
|
||||
it("Multiple media-types", () => {
|
||||
expect(ObjectSerializer.getPreferredMediaType(["text/plain", "application/x-www-form-urlencoded", "application/json"])).to.equal("application/json")
|
||||
});
|
||||
|
||||
it("Unsupported media-type", () => {
|
||||
expect(() => ObjectSerializer.getPreferredMediaType(["foo/bar"])).to.throw('None of the given media types are supported: foo/bar')
|
||||
});
|
||||
})
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user