Skip to content
This repository has been archived by the owner on Feb 6, 2024. It is now read-only.

Commit

Permalink
refactor: refactor cleanParameters for new APIs, remove dotify
Browse files Browse the repository at this point in the history
  • Loading branch information
justinemmanuelmercado committed Jul 3, 2020
1 parent 623d95a commit ec895a2
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 56 deletions.
64 changes: 30 additions & 34 deletions src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ export type ParameterTypes =
| string
| number
| (number | string)[]
| object[]
| boolean
| { [key: string]: ParameterTypes }
| { [key: string]: ParameterTypes }[]
| undefined

export type Parameters = Record<string, ParameterTypes>
Expand Down Expand Up @@ -194,55 +194,51 @@ const canonicalizeParameters = (parameters: CleanParameters): string => {
return sp.toString().replace(/\+/g, '%20')
}

export const toDotNotation = (object: object, prefix: string) => {
const result: { [key: string]: string | number | boolean } = {}
function dotify(plainObject: object, currentKey?: string | number) {
Object.entries(plainObject).forEach(([key, value]) => {
const newKey = currentKey ? `${currentKey}.${key}` : key // joined key with dot
if (value && typeof value === 'object') {
dotify(value, newKey) // it's a nested object, so do it again
} else {
Object.assign(result, { [`${prefix}.${newKey}`]: value }) // it's not an object, so set the property
}
})
}

dotify(object)
return result
}

export const cleanParameters = (parameters: Parameters): CleanParameters =>
export const cleanParameters = (
parameters: Parameters,
baseObject: Record<string, string> = {},
outerKey?: string,
): CleanParameters =>
Object.entries(parameters)

// Filter undefined
.filter(([, parameter]) => parameter !== undefined)

// Loop through each key
.reduce((result, [key, parameter]) => {
if (typeof parameter === 'string' || !Number.isNaN(Number(parameter))) {
/**
* If parameter is type string or number, assign it to result
*/
Object.assign(result, { [key]: String(parameter) })
const trueKey = outerKey ? `${outerKey}.${key}` : key
/**
* If parameter is type string, number, boolean assign it to result
*/
if (
typeof parameter === 'string' ||
!Number.isNaN(Number(parameter)) ||
typeof parameter === 'boolean'
) {
Object.assign(baseObject, { [trueKey]: String(parameter) })
} else if (Array.isArray(parameter)) {
/**
* If parameter is type array reduce it to dotnotation
*/
parameter.forEach((parameterChild: string | number | object, index: number) => {
if (typeof parameterChild === 'string' || !Number.isNaN(Number(parameterChild))) {
Object.assign(result, { [`${key}.${index + 1}`]: String(parameterChild) })
parameter.forEach((parameterChild: ParameterTypes, index: number) => {
if (
typeof parameterChild === 'string' ||
!Number.isNaN(Number(parameterChild)) ||
typeof parameter === 'boolean'
) {
Object.assign(baseObject, { [`${trueKey}.${index + 1}`]: String(parameterChild) })
} else {
Object.assign(result, toDotNotation(parameterChild as object, `${key}.${index + 1}`))
cleanParameters(parameterChild as Parameters, baseObject, `${trueKey}.${index + 1}`)
}
})
} else {
/**
* If parameter is type object parameterize it
*/
Object.entries(
cleanParameters(parameter as Parameters),
).forEach(([innerKey, innerValue]: [string, string]) =>
Object.assign(result, { [`${key}.${innerKey}`]: innerValue }),
)
cleanParameters(parameter as Parameters, baseObject, `${trueKey}`)
}

return result
return baseObject
}, {} as CleanParameters)

const defaultFetch = ({ url, method, headers, data }: Request): Promise<RequestResponse> =>
Expand Down
21 changes: 10 additions & 11 deletions src/sections/merchant-fulfillment/type.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
interface CanonicalizedAddtionalSellerInput
extends Omit<AdditionalSellerInput, 'ValueAsTimestamp'> {
ValueAsTimestamp?: string
}
interface CanonicalizedSellerInputs {
AdditionalInputFieldName: string
AdditionalSellerInput: {
ValueAsString?: string
ValueAsBoolean?: boolean
ValueAsInteger?: number
ValueAsAddress?: Address
ValueAsWeight?: Weight
ValueAsTimestamp?: string
ValueAsDimension?: PackageDimensions
ValueAsCurrency?: CurrencyAmount
}
AdditionalSellerInput: CanonicalizedAddtionalSellerInput
}

export const canonicalizeAdditionalSellerInputs = (
Expand All @@ -26,11 +21,13 @@ export const canonicalizeAdditionalSellerInputs = (
ValueAsTimestamp,
ValueAsDimension,
ValueAsCurrency,
DataType,
} = AdditionalSellerInput

return {
AdditionalInputFieldName,
AdditionalSellerInput: {
DataType,
ValueAsString,
ValueAsBoolean,
ValueAsInteger,
Expand Down Expand Up @@ -214,6 +211,7 @@ export interface AdditionalSellerInput {
interface AdditionalSellerInputs {
AdditionalInputFieldName: string
AdditionalSellerInput: AdditionalSellerInput
[key: string]: string | AdditionalSellerInput
}

export interface Item {
Expand All @@ -222,7 +220,8 @@ export interface Item {
ItemWeight?: Weight
ItemDescription?: string
TransparencyCodeList?: string[]
ItemLevelSellerInputsList?: AdditionalSellerInputs[] // Need to do more research on this
ItemLevelSellerInputsList?: AdditionalSellerInputs[]
[key: string]: string | Weight | AdditionalSellerInputs[] | number | undefined | string[]
}

export type DeliveryExperience =
Expand Down
40 changes: 29 additions & 11 deletions test/unit/http.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import {
InvalidUPCIdentifier,
MWSError,
} from '../../src'
import { cleanParameters, Resource } from '../../src/http'
import { cleanParameters, Parameters, Resource } from '../../src/http'
import {
canonicalizeParametersGetEligibleShippingServiceParameters,
GetEligibleShippingServicesParameters,
Item,
SellerInputDataType,
Weight,
} from '../../src/sections/merchant-fulfillment/type'
Expand Down Expand Up @@ -281,7 +282,7 @@ describe('httpClient', () => {
],
}

const items = [...new Array(4)].map((_, index) => {
const items: Item[] = [...new Array(4)].map((_, index) => {
return {
...item,
OrderItemId: `ITEM${index + 1}`,
Expand Down Expand Up @@ -348,12 +349,16 @@ describe('httpClient', () => {
'ShipmentRequestDetails.ItemList.Item.1.transparencyCodeList.member.2': 'B',
'ShipmentRequestDetails.ItemList.Item.1.ItemLevelSellerInputsList.member.1.AdditionalInputFieldName':
'FieldName',

'ShipmentRequestDetails.ItemList.Item.1.ItemLevelSellerInputsList.member.1.AdditionalSellerInput.DataType':
'Timestamp',
'ShipmentRequestDetails.ItemList.Item.1.ItemLevelSellerInputsList.member.1.AdditionalSellerInput.ValueAsTimestamp': expectedDate,
'ShipmentRequestDetails.ItemList.Item.1.ItemLevelSellerInputsList.member.2.AdditionalInputFieldName':
'FieldName',
'ShipmentRequestDetails.ItemList.Item.1.ItemLevelSellerInputsList.member.2.AdditionalSellerInput.DataType':
'Boolean',

'ShipmentRequestDetails.ItemList.Item.1.ItemLevelSellerInputsList.member.2.AdditionalSellerInput.ValueAsBoolean': true,
'ShipmentRequestDetails.ItemList.Item.1.ItemLevelSellerInputsList.member.2.AdditionalSellerInput.ValueAsBoolean':
'true',

'ShipmentRequestDetails.ItemList.Item.2.OrderItemId': 'ITEM2',
'ShipmentRequestDetails.ItemList.Item.2.Quantity': '1',
Expand All @@ -364,12 +369,16 @@ describe('httpClient', () => {
'ShipmentRequestDetails.ItemList.Item.2.transparencyCodeList.member.2': 'B',
'ShipmentRequestDetails.ItemList.Item.2.ItemLevelSellerInputsList.member.1.AdditionalInputFieldName':
'FieldName',

'ShipmentRequestDetails.ItemList.Item.2.ItemLevelSellerInputsList.member.1.AdditionalSellerInput.DataType':
'Timestamp',
'ShipmentRequestDetails.ItemList.Item.2.ItemLevelSellerInputsList.member.1.AdditionalSellerInput.ValueAsTimestamp': expectedDate,
'ShipmentRequestDetails.ItemList.Item.2.ItemLevelSellerInputsList.member.2.AdditionalInputFieldName':
'FieldName',
'ShipmentRequestDetails.ItemList.Item.2.ItemLevelSellerInputsList.member.2.AdditionalSellerInput.DataType':
'Boolean',

'ShipmentRequestDetails.ItemList.Item.2.ItemLevelSellerInputsList.member.2.AdditionalSellerInput.ValueAsBoolean': true,
'ShipmentRequestDetails.ItemList.Item.2.ItemLevelSellerInputsList.member.2.AdditionalSellerInput.ValueAsBoolean':
'true',

'ShipmentRequestDetails.ItemList.Item.3.OrderItemId': 'ITEM3',
'ShipmentRequestDetails.ItemList.Item.3.Quantity': '1',
Expand All @@ -380,13 +389,17 @@ describe('httpClient', () => {
'ShipmentRequestDetails.ItemList.Item.3.transparencyCodeList.member.2': 'B',
'ShipmentRequestDetails.ItemList.Item.3.ItemLevelSellerInputsList.member.1.AdditionalInputFieldName':
'FieldName',
'ShipmentRequestDetails.ItemList.Item.3.ItemLevelSellerInputsList.member.1.AdditionalSellerInput.DataType':
'Timestamp',

'ShipmentRequestDetails.ItemList.Item.3.ItemLevelSellerInputsList.member.1.AdditionalSellerInput.ValueAsTimestamp': expectedDate,
'ShipmentRequestDetails.ItemList.Item.3.ItemLevelSellerInputsList.member.2.AdditionalInputFieldName':
'FieldName',
'ShipmentRequestDetails.ItemList.Item.3.ItemLevelSellerInputsList.member.2.AdditionalSellerInput.DataType':
'Boolean',

'ShipmentRequestDetails.ItemList.Item.3.ItemLevelSellerInputsList.member.2.AdditionalSellerInput.ValueAsBoolean': true,

'ShipmentRequestDetails.ItemList.Item.3.ItemLevelSellerInputsList.member.2.AdditionalSellerInput.ValueAsBoolean':
'true',
'ShipmentRequestDetails.ItemList.Item.4.OrderItemId': 'ITEM4',
'ShipmentRequestDetails.ItemList.Item.4.Quantity': '1',
'ShipmentRequestDetails.ItemList.Item.4.ItemWeight.Value': '1',
Expand All @@ -398,11 +411,15 @@ describe('httpClient', () => {
'FieldName',

'ShipmentRequestDetails.ItemList.Item.4.ItemLevelSellerInputsList.member.1.AdditionalSellerInput.ValueAsTimestamp': expectedDate,
'ShipmentRequestDetails.ItemList.Item.4.ItemLevelSellerInputsList.member.1.AdditionalSellerInput.DataType':
'Timestamp',
'ShipmentRequestDetails.ItemList.Item.4.ItemLevelSellerInputsList.member.2.AdditionalInputFieldName':
'FieldName',

'ShipmentRequestDetails.ItemList.Item.4.ItemLevelSellerInputsList.member.2.AdditionalSellerInput.ValueAsBoolean': true,

'ShipmentRequestDetails.ItemList.Item.4.ItemLevelSellerInputsList.member.2.AdditionalSellerInput.ValueAsBoolean':
'true',
'ShipmentRequestDetails.ItemList.Item.4.ItemLevelSellerInputsList.member.2.AdditionalSellerInput.DataType':
'Boolean',
'ShipmentRequestDetails.ShipFromAddress.Name': 'string',
'ShipmentRequestDetails.ShipFromAddress.AddressLine1': 'string',
'ShipmentRequestDetails.ShipFromAddress.AddressLine2': 'string',
Expand All @@ -428,7 +445,8 @@ describe('httpClient', () => {
'ShipmentRequestDetails.LabelCustomization.CustomTextForLabel': 'B',
'ShipmentRequestDetails.LabelCustomization.StandardIdForLabel': 'C',
}
const cleaned = cleanParameters(canonicalized)

const cleaned = cleanParameters(canonicalized as Parameters)

expect(cleaned).toStrictEqual(output)
})
Expand Down

0 comments on commit ec895a2

Please sign in to comment.