From 8a2be8845fe5eac4d8aa7f674f4b0bf0fc9cd49b Mon Sep 17 00:00:00 2001 From: Erik Hvattum Date: Thu, 16 May 2019 10:18:10 +0200 Subject: [PATCH 1/2] Add openapi dictionary/map support to typescript-fetch client generator Change isContainer -> isListContainer for existing array support. Add isMapContainer control flow, adding map support. Add utility function to help map openapi map/dictionaries to ts maps. Close #1878 --- .../typescript-fetch/modelGeneric.mustache | 28 +++++++++++++------ .../typescript-fetch/runtime.mustache | 7 +++++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/typescript-fetch/modelGeneric.mustache b/modules/openapi-generator/src/main/resources/typescript-fetch/modelGeneric.mustache index 476e984fadc7..fc160bb14b92 100644 --- a/modules/openapi-generator/src/main/resources/typescript-fetch/modelGeneric.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-fetch/modelGeneric.mustache @@ -1,4 +1,4 @@ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; {{#hasImports}} import { {{#imports}} @@ -46,17 +46,22 @@ export function {{classname}}FromJSON(json: any): {{classname}} { {{/isDate}} {{/isPrimitiveType}} {{^isPrimitiveType}} - {{#isContainer}} + {{#isListContainer}} '{{name}}': {{^required}}!exists(json, '{{baseName}}') ? undefined : {{/required}}(json['{{baseName}}'] as Array).map({{#items}}{{datatype}}{{/items}}FromJSON), - {{/isContainer}} - {{^isContainer}} + {{/isListContainer}} + {{#isMapContainer}} + '{{name}}': {{^required}}!exists(json, '{{baseName}}') ? undefined : {{/required}}mapValues(json['{{baseName}}'], {{#items}}{{datatype}}{{/items}}FromJSON), + {{/isMapContainer}} + {{^isListContainer}} + {{^isMapContainer}} {{^isFreeFormObject}} '{{name}}': {{^required}}!exists(json, '{{baseName}}') ? undefined : {{/required}}{{datatype}}FromJSON(json['{{baseName}}']), {{/isFreeFormObject}} {{#isFreeFormObject}} '{{name}}': {{^required}}!exists(json, '{{baseName}}') ? undefined : {{/required}}json['{{baseName}}'], {{/isFreeFormObject}} - {{/isContainer}} + {{/isMapContainer}} + {{/isListContainer}} {{/isPrimitiveType}} {{/allVars}} }; @@ -78,17 +83,22 @@ export function {{classname}}ToJSON(value?: {{classname}}): any { '{{baseName}}': {{#isDate}}{{^required}}value.{{name}} === undefined ? undefined : {{/required}}value.{{name}}.toISOString().substr(0,10){{/isDate}}{{#isDateTime}}{{^required}}value.{{name}} === undefined ? undefined : {{/required}}value.{{name}}.toISOString(){{/isDateTime}}{{^isDate}}{{^isDateTime}}value.{{name}}{{/isDateTime}}{{/isDate}}, {{/isPrimitiveType}} {{^isPrimitiveType}} - {{#isContainer}} + {{#isListContainer}} '{{baseName}}': {{^required}}value.{{name}} === undefined ? undefined : {{/required}}(value.{{name}} as Array).map({{#items}}{{datatype}}{{/items}}ToJSON), - {{/isContainer}} - {{^isContainer}} + {{/isListContainer}} + {{#isMapContainer}} + '{{baseName}}': {{^required}}value.{{name}} === undefined ? undefined : {{/required}}mapValues(value.{{name}}, {{#items}}{{datatype}}{{/items}}ToJSON), + {{/isMapContainer}} + {{^isListContainer}} + {{^isMapContainer}} {{^isFreeFormObject}} '{{baseName}}': {{datatype}}ToJSON(value.{{name}}), {{/isFreeFormObject}} {{#isFreeFormObject}} '{{baseName}}': value.{{name}}, {{/isFreeFormObject}} - {{/isContainer}} + {{/isMapContainer}} + {{/isListContainer}} {{/isPrimitiveType}} {{/isReadOnly}} {{/allVars}} diff --git a/modules/openapi-generator/src/main/resources/typescript-fetch/runtime.mustache b/modules/openapi-generator/src/main/resources/typescript-fetch/runtime.mustache index 624feac809f8..6f8038f5bdf2 100644 --- a/modules/openapi-generator/src/main/resources/typescript-fetch/runtime.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-fetch/runtime.mustache @@ -202,6 +202,13 @@ export function querystring(params: HTTPQuery, prefix: string = ''): string { .join('&'); } +export function mapValues(data: any, fn: (item: any) => any) { + return Object.keys(data).reduce( + (acc, key) => ({ ...acc, [key]: fn(data[key]) }), + {} + ); +} + export interface RequestContext { fetch: FetchAPI; url: string; From 2454ade08df979472dc8efacb8684e6b8851ef2b Mon Sep 17 00:00:00 2001 From: Erik Hvattum Date: Thu, 16 May 2019 11:06:38 +0200 Subject: [PATCH 2/2] Run typescript-fetch generator scripts and update output files --- .../typescript-fetch/builds/default/models/Category.ts | 2 +- .../builds/default/models/ModelApiResponse.ts | 2 +- .../typescript-fetch/builds/default/models/Order.ts | 2 +- .../petstore/typescript-fetch/builds/default/models/Pet.ts | 2 +- .../petstore/typescript-fetch/builds/default/models/Tag.ts | 2 +- .../typescript-fetch/builds/default/models/User.ts | 2 +- .../petstore/typescript-fetch/builds/default/runtime.ts | 7 +++++++ .../typescript-fetch/builds/es6-target/models/Category.ts | 2 +- .../builds/es6-target/models/ModelApiResponse.ts | 2 +- .../typescript-fetch/builds/es6-target/models/Order.ts | 2 +- .../typescript-fetch/builds/es6-target/models/Pet.ts | 2 +- .../typescript-fetch/builds/es6-target/models/Tag.ts | 2 +- .../typescript-fetch/builds/es6-target/models/User.ts | 2 +- .../petstore/typescript-fetch/builds/es6-target/runtime.ts | 7 +++++++ .../builds/with-interfaces/models/Category.ts | 2 +- .../builds/with-interfaces/models/ModelApiResponse.ts | 2 +- .../builds/with-interfaces/models/Order.ts | 2 +- .../typescript-fetch/builds/with-interfaces/models/Pet.ts | 2 +- .../typescript-fetch/builds/with-interfaces/models/Tag.ts | 2 +- .../typescript-fetch/builds/with-interfaces/models/User.ts | 2 +- .../typescript-fetch/builds/with-interfaces/runtime.ts | 7 +++++++ .../builds/with-npm-version/models/Category.ts | 2 +- .../builds/with-npm-version/models/ModelApiResponse.ts | 2 +- .../builds/with-npm-version/models/Order.ts | 2 +- .../typescript-fetch/builds/with-npm-version/models/Pet.ts | 2 +- .../typescript-fetch/builds/with-npm-version/models/Tag.ts | 2 +- .../builds/with-npm-version/models/User.ts | 2 +- .../typescript-fetch/builds/with-npm-version/runtime.ts | 7 +++++++ 28 files changed, 52 insertions(+), 24 deletions(-) diff --git a/samples/client/petstore/typescript-fetch/builds/default/models/Category.ts b/samples/client/petstore/typescript-fetch/builds/default/models/Category.ts index 99df10e5f1a8..f8809dccbea3 100644 --- a/samples/client/petstore/typescript-fetch/builds/default/models/Category.ts +++ b/samples/client/petstore/typescript-fetch/builds/default/models/Category.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * A category for a pet * @export diff --git a/samples/client/petstore/typescript-fetch/builds/default/models/ModelApiResponse.ts b/samples/client/petstore/typescript-fetch/builds/default/models/ModelApiResponse.ts index 369973446b9a..8b8e2c45fecd 100644 --- a/samples/client/petstore/typescript-fetch/builds/default/models/ModelApiResponse.ts +++ b/samples/client/petstore/typescript-fetch/builds/default/models/ModelApiResponse.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * Describes the result of uploading an image resource * @export diff --git a/samples/client/petstore/typescript-fetch/builds/default/models/Order.ts b/samples/client/petstore/typescript-fetch/builds/default/models/Order.ts index ef002a60fc9c..6ce0496794f6 100644 --- a/samples/client/petstore/typescript-fetch/builds/default/models/Order.ts +++ b/samples/client/petstore/typescript-fetch/builds/default/models/Order.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * An order for a pets from the pet store * @export diff --git a/samples/client/petstore/typescript-fetch/builds/default/models/Pet.ts b/samples/client/petstore/typescript-fetch/builds/default/models/Pet.ts index 27de4cee46bf..770f991b89d9 100644 --- a/samples/client/petstore/typescript-fetch/builds/default/models/Pet.ts +++ b/samples/client/petstore/typescript-fetch/builds/default/models/Pet.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; import { Category, CategoryFromJSON, diff --git a/samples/client/petstore/typescript-fetch/builds/default/models/Tag.ts b/samples/client/petstore/typescript-fetch/builds/default/models/Tag.ts index a7dd45562096..7c8098f6dc01 100644 --- a/samples/client/petstore/typescript-fetch/builds/default/models/Tag.ts +++ b/samples/client/petstore/typescript-fetch/builds/default/models/Tag.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * A tag for a pet * @export diff --git a/samples/client/petstore/typescript-fetch/builds/default/models/User.ts b/samples/client/petstore/typescript-fetch/builds/default/models/User.ts index f42cf94d748d..fd7430063f1c 100644 --- a/samples/client/petstore/typescript-fetch/builds/default/models/User.ts +++ b/samples/client/petstore/typescript-fetch/builds/default/models/User.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * A User who is purchasing from the pet store * @export diff --git a/samples/client/petstore/typescript-fetch/builds/default/runtime.ts b/samples/client/petstore/typescript-fetch/builds/default/runtime.ts index 3af222044b24..67a45b169fde 100644 --- a/samples/client/petstore/typescript-fetch/builds/default/runtime.ts +++ b/samples/client/petstore/typescript-fetch/builds/default/runtime.ts @@ -213,6 +213,13 @@ export function querystring(params: HTTPQuery, prefix: string = ''): string { .join('&'); } +export function mapValues(data: any, fn: (item: any) => any) { + return Object.keys(data).reduce( + (acc, key) => ({ ...acc, [key]: fn(data[key]) }), + {} + ); +} + export interface RequestContext { fetch: FetchAPI; url: string; diff --git a/samples/client/petstore/typescript-fetch/builds/es6-target/models/Category.ts b/samples/client/petstore/typescript-fetch/builds/es6-target/models/Category.ts index 99df10e5f1a8..f8809dccbea3 100644 --- a/samples/client/petstore/typescript-fetch/builds/es6-target/models/Category.ts +++ b/samples/client/petstore/typescript-fetch/builds/es6-target/models/Category.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * A category for a pet * @export diff --git a/samples/client/petstore/typescript-fetch/builds/es6-target/models/ModelApiResponse.ts b/samples/client/petstore/typescript-fetch/builds/es6-target/models/ModelApiResponse.ts index 369973446b9a..8b8e2c45fecd 100644 --- a/samples/client/petstore/typescript-fetch/builds/es6-target/models/ModelApiResponse.ts +++ b/samples/client/petstore/typescript-fetch/builds/es6-target/models/ModelApiResponse.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * Describes the result of uploading an image resource * @export diff --git a/samples/client/petstore/typescript-fetch/builds/es6-target/models/Order.ts b/samples/client/petstore/typescript-fetch/builds/es6-target/models/Order.ts index ef002a60fc9c..6ce0496794f6 100644 --- a/samples/client/petstore/typescript-fetch/builds/es6-target/models/Order.ts +++ b/samples/client/petstore/typescript-fetch/builds/es6-target/models/Order.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * An order for a pets from the pet store * @export diff --git a/samples/client/petstore/typescript-fetch/builds/es6-target/models/Pet.ts b/samples/client/petstore/typescript-fetch/builds/es6-target/models/Pet.ts index 27de4cee46bf..770f991b89d9 100644 --- a/samples/client/petstore/typescript-fetch/builds/es6-target/models/Pet.ts +++ b/samples/client/petstore/typescript-fetch/builds/es6-target/models/Pet.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; import { Category, CategoryFromJSON, diff --git a/samples/client/petstore/typescript-fetch/builds/es6-target/models/Tag.ts b/samples/client/petstore/typescript-fetch/builds/es6-target/models/Tag.ts index a7dd45562096..7c8098f6dc01 100644 --- a/samples/client/petstore/typescript-fetch/builds/es6-target/models/Tag.ts +++ b/samples/client/petstore/typescript-fetch/builds/es6-target/models/Tag.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * A tag for a pet * @export diff --git a/samples/client/petstore/typescript-fetch/builds/es6-target/models/User.ts b/samples/client/petstore/typescript-fetch/builds/es6-target/models/User.ts index f42cf94d748d..fd7430063f1c 100644 --- a/samples/client/petstore/typescript-fetch/builds/es6-target/models/User.ts +++ b/samples/client/petstore/typescript-fetch/builds/es6-target/models/User.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * A User who is purchasing from the pet store * @export diff --git a/samples/client/petstore/typescript-fetch/builds/es6-target/runtime.ts b/samples/client/petstore/typescript-fetch/builds/es6-target/runtime.ts index 3af222044b24..67a45b169fde 100644 --- a/samples/client/petstore/typescript-fetch/builds/es6-target/runtime.ts +++ b/samples/client/petstore/typescript-fetch/builds/es6-target/runtime.ts @@ -213,6 +213,13 @@ export function querystring(params: HTTPQuery, prefix: string = ''): string { .join('&'); } +export function mapValues(data: any, fn: (item: any) => any) { + return Object.keys(data).reduce( + (acc, key) => ({ ...acc, [key]: fn(data[key]) }), + {} + ); +} + export interface RequestContext { fetch: FetchAPI; url: string; diff --git a/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Category.ts b/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Category.ts index 99df10e5f1a8..f8809dccbea3 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Category.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Category.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * A category for a pet * @export diff --git a/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/ModelApiResponse.ts b/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/ModelApiResponse.ts index 369973446b9a..8b8e2c45fecd 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/ModelApiResponse.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/ModelApiResponse.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * Describes the result of uploading an image resource * @export diff --git a/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Order.ts b/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Order.ts index ef002a60fc9c..6ce0496794f6 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Order.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Order.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * An order for a pets from the pet store * @export diff --git a/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Pet.ts b/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Pet.ts index 27de4cee46bf..770f991b89d9 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Pet.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Pet.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; import { Category, CategoryFromJSON, diff --git a/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Tag.ts b/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Tag.ts index a7dd45562096..7c8098f6dc01 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Tag.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/Tag.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * A tag for a pet * @export diff --git a/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/User.ts b/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/User.ts index f42cf94d748d..fd7430063f1c 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/User.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-interfaces/models/User.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * A User who is purchasing from the pet store * @export diff --git a/samples/client/petstore/typescript-fetch/builds/with-interfaces/runtime.ts b/samples/client/petstore/typescript-fetch/builds/with-interfaces/runtime.ts index 3af222044b24..67a45b169fde 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-interfaces/runtime.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-interfaces/runtime.ts @@ -213,6 +213,13 @@ export function querystring(params: HTTPQuery, prefix: string = ''): string { .join('&'); } +export function mapValues(data: any, fn: (item: any) => any) { + return Object.keys(data).reduce( + (acc, key) => ({ ...acc, [key]: fn(data[key]) }), + {} + ); +} + export interface RequestContext { fetch: FetchAPI; url: string; diff --git a/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Category.ts b/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Category.ts index 99df10e5f1a8..f8809dccbea3 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Category.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Category.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * A category for a pet * @export diff --git a/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/ModelApiResponse.ts b/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/ModelApiResponse.ts index 369973446b9a..8b8e2c45fecd 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/ModelApiResponse.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/ModelApiResponse.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * Describes the result of uploading an image resource * @export diff --git a/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Order.ts b/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Order.ts index ef002a60fc9c..6ce0496794f6 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Order.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Order.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * An order for a pets from the pet store * @export diff --git a/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Pet.ts b/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Pet.ts index 27de4cee46bf..770f991b89d9 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Pet.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Pet.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; import { Category, CategoryFromJSON, diff --git a/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Tag.ts b/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Tag.ts index a7dd45562096..7c8098f6dc01 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Tag.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/Tag.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * A tag for a pet * @export diff --git a/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/User.ts b/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/User.ts index f42cf94d748d..fd7430063f1c 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/User.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-npm-version/models/User.ts @@ -11,7 +11,7 @@ * Do not edit the class manually. */ -import { exists } from '../runtime'; +import { exists, mapValues } from '../runtime'; /** * A User who is purchasing from the pet store * @export diff --git a/samples/client/petstore/typescript-fetch/builds/with-npm-version/runtime.ts b/samples/client/petstore/typescript-fetch/builds/with-npm-version/runtime.ts index 3af222044b24..67a45b169fde 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-npm-version/runtime.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-npm-version/runtime.ts @@ -213,6 +213,13 @@ export function querystring(params: HTTPQuery, prefix: string = ''): string { .join('&'); } +export function mapValues(data: any, fn: (item: any) => any) { + return Object.keys(data).reduce( + (acc, key) => ({ ...acc, [key]: fn(data[key]) }), + {} + ); +} + export interface RequestContext { fetch: FetchAPI; url: string;