idosell 0.4.34 → 0.4.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -4
- package/changelog.md +14 -0
- package/dist/app.d.ts +140 -1
- package/dist/enums.d.ts +218 -0
- package/dist/enums.js +219 -1
- package/dist/gateways.d.ts +45 -45
- package/dist/index.js +2 -1
- package/dist/methods/getProductsAttachmentsGetContent.js +1 -0
- package/dist/methods/searchProductsCategoriesIdosell.js +1 -2
- package/dist/reqparams.d.ts +241 -206
- package/dist/responses.d.ts +70 -43
- package/dist/utils.d.ts +12 -0
- package/dist/utils.js +20 -1
- package/dist/webhooks.js +124 -0
- package/dist/webhooks.normalizer.js +140 -0
- package/package.json +2 -2
- package/tests/utilMapProductParameters.test.js +97 -0
- package/tests/utilTestData.ts +238 -1
package/dist/responses.d.ts
CHANGED
|
@@ -8404,7 +8404,7 @@ export type GetProductsResponse = {
|
|
|
8404
8404
|
productSizeQuantity: number;
|
|
8405
8405
|
}[];
|
|
8406
8406
|
/** @description Size data */
|
|
8407
|
-
productSizesStocksLocations
|
|
8407
|
+
productSizesStocksLocations?: {
|
|
8408
8408
|
/** @description Stock ID */
|
|
8409
8409
|
stockId: number;
|
|
8410
8410
|
productSizesLocation: {
|
|
@@ -8489,11 +8489,11 @@ export type GetProductsResponse = {
|
|
|
8489
8489
|
/** @description Gross price */
|
|
8490
8490
|
productRetailPrice: number;
|
|
8491
8491
|
/** @description Gross price after promotion. The item is returned when the 'showPromotionsPrices' parameter is specified in the request */
|
|
8492
|
-
productPromoRetailPrice
|
|
8492
|
+
productPromoRetailPrice?: number;
|
|
8493
8493
|
/** @description Wholesale price */
|
|
8494
8494
|
productWholesalePrice: number;
|
|
8495
8495
|
/** @description Wholesale price after promotion. The item is returned when the 'showPromotionsPrices' parameter is specified in the request */
|
|
8496
|
-
productPromoWholesalePrice
|
|
8496
|
+
productPromoWholesalePrice?: number;
|
|
8497
8497
|
/** @description Minimal price */
|
|
8498
8498
|
productMinimalPrice: number;
|
|
8499
8499
|
/** @description Price for automatic calculations */
|
|
@@ -8771,7 +8771,7 @@ export type GetProductsResponse = {
|
|
|
8771
8771
|
sizePanelName: string;
|
|
8772
8772
|
}[];
|
|
8773
8773
|
/** @description Available sizes of products in a set or collection for marketplaces */
|
|
8774
|
-
bundledAvailableSizesInAuctions
|
|
8774
|
+
bundledAvailableSizesInAuctions?: {
|
|
8775
8775
|
/** @description Size identifier */
|
|
8776
8776
|
sizeId: string;
|
|
8777
8777
|
/** @description Size name */
|
|
@@ -8805,7 +8805,7 @@ export type GetProductsResponse = {
|
|
|
8805
8805
|
}[];
|
|
8806
8806
|
}[];
|
|
8807
8807
|
/** @description Parameter values */
|
|
8808
|
-
parameterValues?: {
|
|
8808
|
+
parameterValues?: null | {
|
|
8809
8809
|
/** @description Parameter value ID */
|
|
8810
8810
|
parameterValueId: number;
|
|
8811
8811
|
/** @description Language data */
|
|
@@ -8972,7 +8972,7 @@ export type GetProductsResponse = {
|
|
|
8972
8972
|
/** @description Minimum stock level */
|
|
8973
8973
|
minStockLevel?: number;
|
|
8974
8974
|
}[];
|
|
8975
|
-
} & { resultsLimit: number
|
|
8975
|
+
} & { resultsLimit: number };
|
|
8976
8976
|
|
|
8977
8977
|
export type GetOrdersResponse = {
|
|
8978
8978
|
Results: {
|
|
@@ -8997,7 +8997,7 @@ export type GetOrdersResponse = {
|
|
|
8997
8997
|
/** @description Customer's company name. */
|
|
8998
8998
|
clientFirm: string;
|
|
8999
8999
|
/** @description Product suggestion. */
|
|
9000
|
-
clientAdditional
|
|
9000
|
+
clientAdditional?: string;
|
|
9001
9001
|
/** @description Street and number. */
|
|
9002
9002
|
clientStreet: string;
|
|
9003
9003
|
/** @description Customer's postal code. */
|
|
@@ -9007,7 +9007,7 @@ export type GetOrdersResponse = {
|
|
|
9007
9007
|
/** @description Region name takes priority over clientCountryId. */
|
|
9008
9008
|
clientCountryName: string;
|
|
9009
9009
|
/** @description Client NIP verification status */
|
|
9010
|
-
clientNipUeVerified: string;
|
|
9010
|
+
clientNipUeVerified: string | null;
|
|
9011
9011
|
/** @description Country ID in accordance with ISO-3166. */
|
|
9012
9012
|
clientCountryId: string;
|
|
9013
9013
|
/** @description Cell phone. */
|
|
@@ -9052,9 +9052,9 @@ export type GetOrdersResponse = {
|
|
|
9052
9052
|
/** @description Internal Receiving Point Identifier. */
|
|
9053
9053
|
clientDeliveryAddressPickupPointInternalId: number;
|
|
9054
9054
|
};
|
|
9055
|
-
clientPickupPointAddress
|
|
9055
|
+
clientPickupPointAddress?: {
|
|
9056
9056
|
/** @description Collection point ID. */
|
|
9057
|
-
pickupPointId:
|
|
9057
|
+
pickupPointId: number;
|
|
9058
9058
|
/** @description External service collection point ID. */
|
|
9059
9059
|
externalPickupPointId: string;
|
|
9060
9060
|
/** @description Town / City. */
|
|
@@ -9071,9 +9071,11 @@ export type GetOrdersResponse = {
|
|
|
9071
9071
|
longitude: number;
|
|
9072
9072
|
/** @description Name. */
|
|
9073
9073
|
name: string;
|
|
9074
|
+
/** @description Country (2 letter country code). */
|
|
9075
|
+
country: string;
|
|
9074
9076
|
};
|
|
9075
9077
|
/** @description Buyer's address data. */
|
|
9076
|
-
payerAddress
|
|
9078
|
+
payerAddress?: {
|
|
9077
9079
|
/** @description Buyer's address id. */
|
|
9078
9080
|
payerAddressId: string;
|
|
9079
9081
|
/** @description Buyer's first name. */
|
|
@@ -9137,9 +9139,13 @@ export type GetOrdersResponse = {
|
|
|
9137
9139
|
/** @description Order status. Allowed values: "finished_ext" - order status: completed in FA application, "finished" - completed, "new" - not handled, "payment_waiting" - awaiting payment, "delivery_waiting" - awaiting delivery, "on_order" - in progress, "packed" - being picked, "packed_fulfillment" - being picked - fulfilment, "packed_ready" - packed, "ready" - ready, "wait_for_dispatch" - awaiting dispatch date, "suspended" - on hold, "joined" - merged, "missing" - missing, "lost" - lost, "false" - false, "canceled" - Customer canceled. */
|
|
9138
9140
|
orderStatus: string;
|
|
9139
9141
|
/** @description Order status id */
|
|
9140
|
-
orderStatusId
|
|
9142
|
+
orderStatusId?: number;
|
|
9141
9143
|
/** @description Date of change of status to the currently set status in YYYY-MM-DD HH:MM:SS format. */
|
|
9142
9144
|
orderStatusChangeDate: string;
|
|
9145
|
+
/** @description Split payment MPP marking */
|
|
9146
|
+
splitPayment: boolean;
|
|
9147
|
+
/** @description Transaction type. */
|
|
9148
|
+
transactionType: null |"national" | "oss" | "export" | "intra";
|
|
9143
9149
|
/** @example dropshippingOrderStatus */
|
|
9144
9150
|
dropshippingOrderStatus: string;
|
|
9145
9151
|
/** @description Type of order confirmation. Confirmations listing: "none" - order unconfirmed , "email" - order confirmed by e-mail, "phone_client" - order confirmed by phone call made by client, "phone_service" - order confirmed by phone call made by staff, "postauction" - order confirmed by auction return page, "willingness" - confirmed by willingness to buy letter, "auctionfod" - confirmed by after-sales form Allegro. */
|
|
@@ -9147,11 +9153,11 @@ export type GetOrdersResponse = {
|
|
|
9147
9153
|
/** @description Date of order placing in YYYY-MM-DD HH:MM:SS format. */
|
|
9148
9154
|
orderAddDate: string;
|
|
9149
9155
|
/** @description Date of order sending in YYYY-MM-DD HH:MM:SS format. */
|
|
9150
|
-
orderDispatchDate: string | null;
|
|
9156
|
+
orderDispatchDate: 0 | string | null;
|
|
9151
9157
|
/** @example receivedDate */
|
|
9152
9158
|
receivedDate: string;
|
|
9153
9159
|
/** @description Order handling time in seconds. */
|
|
9154
|
-
orderPrepareTime:
|
|
9160
|
+
orderPrepareTime: number | null;
|
|
9155
9161
|
/** @description Customer comments on order. */
|
|
9156
9162
|
clientNoteToOrder: string;
|
|
9157
9163
|
/** @description Customer remarks for courier. */
|
|
@@ -9171,7 +9177,7 @@ export type GetOrdersResponse = {
|
|
|
9171
9177
|
/** @description Currency average rate set for order (by default, an average rate of order adding date, if it wasn't manually changed). */
|
|
9172
9178
|
orderCurrencyValue: number;
|
|
9173
9179
|
/** @description Currency scaler. */
|
|
9174
|
-
orderCurrencyScale
|
|
9180
|
+
orderCurrencyScale?: number;
|
|
9175
9181
|
/** @description Panel billing currency exchange rate in relation to billing currency in the shop . */
|
|
9176
9182
|
billingCurrencyRate: number;
|
|
9177
9183
|
/** @description Products cost. */
|
|
@@ -9204,7 +9210,7 @@ export type GetOrdersResponse = {
|
|
|
9204
9210
|
};
|
|
9205
9211
|
/** @description Order currency squaring method. "gross" - calculated in gross prices, "net" - squared in net prices. */
|
|
9206
9212
|
orderWorthCalculateType: "gross" | "net";
|
|
9207
|
-
/** @description Information if the VAT for the current order was calculated: "y" - yes, "n" - no. */
|
|
9213
|
+
/** @description Information if the VAT for the current order was calculated: "y" - yes, "n" - no, "p" – requires approval by the store staff. */
|
|
9208
9214
|
orderVatExists: string;
|
|
9209
9215
|
};
|
|
9210
9216
|
/** @description Information about prepayment for the order. */
|
|
@@ -9236,9 +9242,9 @@ export type GetOrdersResponse = {
|
|
|
9236
9242
|
/** @description Currency ID */
|
|
9237
9243
|
currencyId: string;
|
|
9238
9244
|
/** @description Number of voucher used in a payment. */
|
|
9239
|
-
voucherNumber
|
|
9245
|
+
voucherNumber?: string;
|
|
9240
9246
|
/** @description Number of gift card used in a payment. */
|
|
9241
|
-
giftCardNumber
|
|
9247
|
+
giftCardNumber?: string;
|
|
9242
9248
|
}[];
|
|
9243
9249
|
/** @description Order source data. */
|
|
9244
9250
|
orderSourceResults: {
|
|
@@ -9247,7 +9253,7 @@ export type GetOrdersResponse = {
|
|
|
9247
9253
|
/** @description Shop Id */
|
|
9248
9254
|
shopId: number;
|
|
9249
9255
|
/** @description Auction site order comes from. Auction sites listing: "allegro" - Allegro.pl, "testwebapi" - Allegro.pl test site, "ebay" - eBay. */
|
|
9250
|
-
auctionsServiceName: string;
|
|
9256
|
+
auctionsServiceName: string | null;
|
|
9251
9257
|
/** @description Detailed information on order source. */
|
|
9252
9258
|
orderSourceDetails: {
|
|
9253
9259
|
/** @description order source type - possible values:. "self_added" - Orders from panel, "shop" - Orders from shop, "search_engine" - Orders from search engines, "auction" - Orders from auctions, "advertisement_campaign" - Advertisement campaigns, "price_comparer" - Price comparison sites, "affiliate_program" - Affiliate programme, "api" - Order from API, "eletronic_offer" - Order from ODT price lst, "cpa" - Order from CPA program, "refferer_site" - Order from reference sites, "pos" - Orders from POS, "marketplace" - Order from the Marketplace, "iai_ads" - Orders from IAI Ads */
|
|
@@ -9259,11 +9265,11 @@ export type GetOrdersResponse = {
|
|
|
9259
9265
|
/** @description Numerical ID of order source. */
|
|
9260
9266
|
orderSourceId: number;
|
|
9261
9267
|
/** @example 1 */
|
|
9262
|
-
entryProductIdBeforeOrder
|
|
9268
|
+
entryProductIdBeforeOrder?: number;
|
|
9263
9269
|
/** @example sourcePageUrl */
|
|
9264
|
-
sourcePageUrl
|
|
9270
|
+
sourcePageUrl?: string;
|
|
9265
9271
|
/** @description The order ID of the external service */
|
|
9266
|
-
orderExternalId: string;
|
|
9272
|
+
orderExternalId: string | null;
|
|
9267
9273
|
/** @description Order from the InPost Fresh marketplace */
|
|
9268
9274
|
fresh: "y" | "n";
|
|
9269
9275
|
/** @description Order supported by InPost fulfillment */
|
|
@@ -9285,16 +9291,16 @@ export type GetOrdersResponse = {
|
|
|
9285
9291
|
/** @description Data of auction, order comes from (only if it comes from auction). */
|
|
9286
9292
|
auctionInfo: {
|
|
9287
9293
|
/** @description Account ID on auction site. */
|
|
9288
|
-
auctionClientId
|
|
9294
|
+
auctionClientId?: string;
|
|
9289
9295
|
/** @description Account login on auction site. */
|
|
9290
|
-
auctionClientLogin
|
|
9296
|
+
auctionClientLogin?: string;
|
|
9291
9297
|
/** @description #!TablicaNumerowAukcjiDoZamowienia!#. */
|
|
9292
|
-
auctionItemsIds
|
|
9298
|
+
auctionItemsIds?: {
|
|
9293
9299
|
/** @description Auction number. */
|
|
9294
9300
|
auctionItemId: string;
|
|
9295
9301
|
}[];
|
|
9296
9302
|
/** @description The customer's email address at the auction service. */
|
|
9297
|
-
auctionClientEmail
|
|
9303
|
+
auctionClientEmail?: string;
|
|
9298
9304
|
};
|
|
9299
9305
|
/** @description Consignment data. */
|
|
9300
9306
|
dispatch: {
|
|
@@ -9324,7 +9330,7 @@ export type GetOrdersResponse = {
|
|
|
9324
9330
|
/** @description External product system code */
|
|
9325
9331
|
productCode: string;
|
|
9326
9332
|
/** @description Name of the parameter value, e.g. orange, green, red */
|
|
9327
|
-
versionName
|
|
9333
|
+
versionName?: string;
|
|
9328
9334
|
/** @description Size identifier */
|
|
9329
9335
|
sizeId: string;
|
|
9330
9336
|
/** @description Size name */
|
|
@@ -9334,7 +9340,7 @@ export type GetOrdersResponse = {
|
|
|
9334
9340
|
/** @description Stock ID */
|
|
9335
9341
|
stockId: number;
|
|
9336
9342
|
/** @description Serial number of the product. */
|
|
9337
|
-
productSerialNumber
|
|
9343
|
+
productSerialNumber?: string;
|
|
9338
9344
|
/** @description Product quantity. */
|
|
9339
9345
|
productQuantity: number;
|
|
9340
9346
|
/** @description Weight. */
|
|
@@ -9342,7 +9348,7 @@ export type GetOrdersResponse = {
|
|
|
9342
9348
|
/** @description Value of VAT */
|
|
9343
9349
|
productVat: number;
|
|
9344
9350
|
/** @description Is product VAT free Allowed values "y" - yes, "n" - no. */
|
|
9345
|
-
productVatFree
|
|
9351
|
+
productVatFree?: string;
|
|
9346
9352
|
/** @description Gross price of the product in the currency of the administration panel. */
|
|
9347
9353
|
productPanelPrice: number;
|
|
9348
9354
|
/** @description Net price of the product in the currency of the administration panel. */
|
|
@@ -9356,7 +9362,7 @@ export type GetOrdersResponse = {
|
|
|
9356
9362
|
/** @description Product net price of order in shop account currency. */
|
|
9357
9363
|
productOrderPriceNetBaseCurrency: number;
|
|
9358
9364
|
/** @description List of product suggestions . */
|
|
9359
|
-
orderAdditionalList
|
|
9365
|
+
orderAdditionalList?: {
|
|
9360
9366
|
/** @description Product suggestion. */
|
|
9361
9367
|
orderAdditional: {
|
|
9362
9368
|
/** @description Name of suggestion. */
|
|
@@ -9368,13 +9374,13 @@ export type GetOrdersResponse = {
|
|
|
9368
9374
|
/** @description Client's remarks on product. */
|
|
9369
9375
|
remarksToProduct: string;
|
|
9370
9376
|
/** @description Label for grouping products. */
|
|
9371
|
-
label: string;
|
|
9377
|
+
label: string | null;
|
|
9372
9378
|
/** @description Product selling mode. Available values: "money", "gift", "points". */
|
|
9373
9379
|
orderSalesMode: "money" | "gift" | "points";
|
|
9374
9380
|
/** @description A set's ID. */
|
|
9375
9381
|
bundleId: number;
|
|
9376
9382
|
/** @description Serial numbers. */
|
|
9377
|
-
productSerialNumbers: string;
|
|
9383
|
+
productSerialNumbers: string | null;
|
|
9378
9384
|
/** @description Additional information. */
|
|
9379
9385
|
productOrderAdditional: string;
|
|
9380
9386
|
/** @description Item in basket. */
|
|
@@ -9382,7 +9388,7 @@ export type GetOrdersResponse = {
|
|
|
9382
9388
|
/** @description price information. */
|
|
9383
9389
|
productPriceLog: string;
|
|
9384
9390
|
/** @description Information about the selected parameters in the configurator. */
|
|
9385
|
-
priceFormulaParameters
|
|
9391
|
+
priceFormulaParameters?: {
|
|
9386
9392
|
/** @description Parameter ID */
|
|
9387
9393
|
parameterId: string;
|
|
9388
9394
|
/** @description Parameter name. */
|
|
@@ -9409,7 +9415,7 @@ export type GetOrdersResponse = {
|
|
|
9409
9415
|
/** @description Note to the order. */
|
|
9410
9416
|
orderNote: string;
|
|
9411
9417
|
/** @description Information on used discount code. */
|
|
9412
|
-
discountCode
|
|
9418
|
+
discountCode?: {
|
|
9413
9419
|
/** @description Campaign ID. */
|
|
9414
9420
|
campaignId: string;
|
|
9415
9421
|
/** @description Name of code. */
|
|
@@ -9418,14 +9424,14 @@ export type GetOrdersResponse = {
|
|
|
9418
9424
|
discountCodeValue: string;
|
|
9419
9425
|
};
|
|
9420
9426
|
/** @description Discount card */
|
|
9421
|
-
discountCard
|
|
9427
|
+
discountCard?: {
|
|
9422
9428
|
/** @description Name of card */
|
|
9423
9429
|
discountCardName: string;
|
|
9424
9430
|
};
|
|
9425
9431
|
/** @description Order handler. */
|
|
9426
9432
|
orderOperatorLogin: string;
|
|
9427
9433
|
/** @description Order picker. */
|
|
9428
|
-
orderPackingPersonLogin: string;
|
|
9434
|
+
orderPackingPersonLogin: string | null;
|
|
9429
9435
|
/** @description Sale date. ISO 8602 format. */
|
|
9430
9436
|
purchaseDate: string;
|
|
9431
9437
|
/** @description Modification date in YYYY-MM-DD HH:MM:SS format . */
|
|
@@ -9440,14 +9446,9 @@ export type GetOrdersResponse = {
|
|
|
9440
9446
|
verified: boolean;
|
|
9441
9447
|
};
|
|
9442
9448
|
/** @description Information on error that occurred during gate call. */
|
|
9443
|
-
errors:
|
|
9444
|
-
/** @description Error code. */
|
|
9445
|
-
faultCode: number;
|
|
9446
|
-
/** @description Error description. */
|
|
9447
|
-
faultString: string;
|
|
9448
|
-
}[];
|
|
9449
|
+
errors: FaultCodeString[];
|
|
9449
9450
|
}[];
|
|
9450
|
-
};
|
|
9451
|
+
} & { resultsNumberAll: number };
|
|
9451
9452
|
|
|
9452
9453
|
type PromotionErrorEntry = {
|
|
9453
9454
|
/** @description Error code. */
|
|
@@ -9583,4 +9584,30 @@ export type GetRegulationsHistoryResponse = {
|
|
|
9583
9584
|
pagination: PagedResponse;
|
|
9584
9585
|
};
|
|
9585
9586
|
|
|
9587
|
+
export type GetProductsAttachmentsGetContentResponse = {
|
|
9588
|
+
/** @description Product attachment content */
|
|
9589
|
+
data: {
|
|
9590
|
+
/** @description Product attachment content */
|
|
9591
|
+
attachmentContent: string | null;
|
|
9592
|
+
/** @description Product attachment content representation
|
|
9593
|
+
|null} */
|
|
9594
|
+
attachmentContentRepresentation: "base64" | "url" | null;
|
|
9595
|
+
/** @description Product attachment file extension */
|
|
9596
|
+
attachmentContentFileExtension: string | null;
|
|
9597
|
+
};
|
|
9598
|
+
isError: boolean;
|
|
9599
|
+
errors: {
|
|
9600
|
+
/** @description Error code. */
|
|
9601
|
+
code: string;
|
|
9602
|
+
/** @description Field associated with the error. */
|
|
9603
|
+
field: string | null;
|
|
9604
|
+
/** @description Error description. */
|
|
9605
|
+
message: string | null;
|
|
9606
|
+
/** @description Value associated with the error. */
|
|
9607
|
+
value: string | null;
|
|
9608
|
+
/** @description Unique identifier of the error (for support). */
|
|
9609
|
+
uid: string | null;
|
|
9610
|
+
}[];
|
|
9611
|
+
};
|
|
9612
|
+
|
|
9586
9613
|
export { };
|
package/dist/utils.d.ts
CHANGED
|
@@ -11,6 +11,16 @@ type GetLangDataFunction = <T extends {
|
|
|
11
11
|
langId: string;
|
|
12
12
|
}>(_array: T[], _langId?: string) => T | undefined;
|
|
13
13
|
type ClearParametersLangDataFunction = (_products: SearchProductsResponse['results'], _langId?: string) => SearchProductsResponse['results'];
|
|
14
|
+
type MappedParameterValue = {
|
|
15
|
+
valueId: number;
|
|
16
|
+
value: string;
|
|
17
|
+
};
|
|
18
|
+
type MappedParameter = {
|
|
19
|
+
id: number;
|
|
20
|
+
name: string;
|
|
21
|
+
values: MappedParameterValue[];
|
|
22
|
+
};
|
|
23
|
+
type MapProductParametersFunction = (_product: IdosellProduct, _langId?: string) => MappedParameter[];
|
|
14
24
|
declare const _default: {
|
|
15
25
|
/** @description The method allows you to build an IAI code from the product ID and size ID. */
|
|
16
26
|
getIaiCode: GetIaICodeFunction;
|
|
@@ -30,5 +40,7 @@ declare const _default: {
|
|
|
30
40
|
clearParametersLangData: ClearParametersLangDataFunction;
|
|
31
41
|
/** @description Removes attachments to RMA that are returned by default, helps to reduce data if serialized or forwarded */
|
|
32
42
|
removeRmaAttachments: (rmaResponse: GetRmaResponse) => GetRmaResponse;
|
|
43
|
+
/** @description Maps product parameters to a simplified structure for a given language. Skips parameters with no values. */
|
|
44
|
+
mapProductParameters: MapProductParametersFunction;
|
|
33
45
|
};
|
|
34
46
|
export default _default;
|
package/dist/utils.js
CHANGED
|
@@ -269,6 +269,23 @@ const removeRmaAttachments = (rmaResponse) => {
|
|
|
269
269
|
}
|
|
270
270
|
return rmaResponse;
|
|
271
271
|
};
|
|
272
|
+
const mapProductParameters = (product, langId = 'pol') => {
|
|
273
|
+
if (!product.productParameters)
|
|
274
|
+
return [];
|
|
275
|
+
return product.productParameters.reduce((acc, param) => {
|
|
276
|
+
if (!param.parameterValues?.length)
|
|
277
|
+
return acc;
|
|
278
|
+
const name = param.parameterDescriptionsLangData.find((l) => l.langId === langId)?.parameterName ?? '';
|
|
279
|
+
const values = param.parameterValues.reduce((valAcc, pv) => {
|
|
280
|
+
const value = pv.parameterValueDescriptionsLangData.find((l) => l.langId === langId)
|
|
281
|
+
?.parameterValueName ?? '';
|
|
282
|
+
valAcc.push({ valueId: pv.parameterValueId, value });
|
|
283
|
+
return valAcc;
|
|
284
|
+
}, []);
|
|
285
|
+
acc.push({ id: param.parameterId, name, values });
|
|
286
|
+
return acc;
|
|
287
|
+
}, []);
|
|
288
|
+
};
|
|
272
289
|
export default {
|
|
273
290
|
/** @description The method allows you to build an IAI code from the product ID and size ID. */
|
|
274
291
|
getIaiCode,
|
|
@@ -287,5 +304,7 @@ export default {
|
|
|
287
304
|
/** @description Modifies product response by removing all parameter names nad values that are not in selected langId */
|
|
288
305
|
clearParametersLangData,
|
|
289
306
|
/** @description Removes attachments to RMA that are returned by default, helps to reduce data if serialized or forwarded */
|
|
290
|
-
removeRmaAttachments
|
|
307
|
+
removeRmaAttachments,
|
|
308
|
+
/** @description Maps product parameters to a simplified structure for a given language. Skips parameters with no values. */
|
|
309
|
+
mapProductParameters,
|
|
291
310
|
};
|
package/dist/webhooks.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/* eslint-disable no-unused-vars */
|
|
2
|
+
import { normalizeIaiRequest, WebhookValidationError } from "./webhooks.normalizer.js";
|
|
3
|
+
// ─── Runtime constants ────────────────────────────────────────────────────────
|
|
4
|
+
export const WEBHOOK_OBJECT_TYPE = {
|
|
5
|
+
CLIENT: "client",
|
|
6
|
+
PRODUCT: "product",
|
|
7
|
+
ORDER: "order",
|
|
8
|
+
RETURN: "return",
|
|
9
|
+
RMA: "rma",
|
|
10
|
+
};
|
|
11
|
+
export const WEBHOOK_EVENT_TYPE = {
|
|
12
|
+
CLIENT_CREATED: "clientCreated",
|
|
13
|
+
CLIENT_UPDATED: "clientUpdated",
|
|
14
|
+
PRODUCT_CREATED: "productCreated",
|
|
15
|
+
PRODUCT_UPDATED: "productUpdated",
|
|
16
|
+
PRODUCT_PRICE_UPDATED: "productPriceUpdated",
|
|
17
|
+
PRODUCT_STOCK_UPDATED: "productStockUpdated",
|
|
18
|
+
PRODUCT_DISPOSITION_UPDATED: "productDispositionUpdated",
|
|
19
|
+
ORDER_CREATED: "orderCreated",
|
|
20
|
+
ORDER_UPDATED: "orderUpdated",
|
|
21
|
+
ORDER_PAID: "orderPaid",
|
|
22
|
+
ORDER_STATUS_UPDATED: "orderStatusUpdated",
|
|
23
|
+
ORDER_PACKAGE_CREATED: "orderPackageCreated",
|
|
24
|
+
ORDER_FILES_CREATED: "orderFilesCreated",
|
|
25
|
+
ORDER_SALE_DOCUMENT_CREATED: "orderSaleDocumentCreated",
|
|
26
|
+
ORDER_SALE_DOCUMENT_UPDATED: "orderSaleDocumentUpdated",
|
|
27
|
+
ORDER_SENT: "orderSent",
|
|
28
|
+
ORDER_DELIVERED: "orderDelivered",
|
|
29
|
+
ORDER_CANCELED: "orderCanceled",
|
|
30
|
+
RETURN_CREATED: "returnCreated",
|
|
31
|
+
RETURN_UPDATED: "returnUpdated",
|
|
32
|
+
RETURN_FUNDS_CONFIRMED: "returnFundsConfirmed",
|
|
33
|
+
RETURN_PACKAGE_CREATED: "returnPackageCreated",
|
|
34
|
+
RETURN_CONFIRMED: "returnConfirmed",
|
|
35
|
+
RETURN_CANCELED: "returnCanceled",
|
|
36
|
+
RMA_CREATED: "rmaCreated",
|
|
37
|
+
RMA_UPDATED: "rmaUpdated",
|
|
38
|
+
RMA_PACKAGE_CREATED: "rmaPackageCreated",
|
|
39
|
+
RMA_APPROVED: "rmaApproved",
|
|
40
|
+
RMA_REJECTED: "rmaRejected",
|
|
41
|
+
};
|
|
42
|
+
// ─── Runtime event → object map ───────────────────────────────────────────────
|
|
43
|
+
const EVENT_OBJECT_MAP = {
|
|
44
|
+
clientCreated: "client",
|
|
45
|
+
clientUpdated: "client",
|
|
46
|
+
productCreated: "product",
|
|
47
|
+
productUpdated: "product",
|
|
48
|
+
productPriceUpdated: "product",
|
|
49
|
+
productStockUpdated: "product",
|
|
50
|
+
productDispositionUpdated: "product",
|
|
51
|
+
orderCreated: "order",
|
|
52
|
+
orderUpdated: "order",
|
|
53
|
+
orderPaid: "order",
|
|
54
|
+
orderStatusUpdated: "order",
|
|
55
|
+
orderPackageCreated: "order",
|
|
56
|
+
orderFilesCreated: "order",
|
|
57
|
+
orderSaleDocumentCreated: "order",
|
|
58
|
+
orderSaleDocumentUpdated: "order",
|
|
59
|
+
orderSent: "order",
|
|
60
|
+
orderDelivered: "order",
|
|
61
|
+
orderCanceled: "order",
|
|
62
|
+
returnCreated: "return",
|
|
63
|
+
returnUpdated: "return",
|
|
64
|
+
returnFundsConfirmed: "return",
|
|
65
|
+
returnPackageCreated: "return",
|
|
66
|
+
returnConfirmed: "return",
|
|
67
|
+
returnCanceled: "return",
|
|
68
|
+
rmaCreated: "rma",
|
|
69
|
+
rmaUpdated: "rma",
|
|
70
|
+
rmaPackageCreated: "rma",
|
|
71
|
+
rmaApproved: "rma",
|
|
72
|
+
rmaRejected: "rma",
|
|
73
|
+
};
|
|
74
|
+
export class WebhookChain {
|
|
75
|
+
slots = [];
|
|
76
|
+
validator = null;
|
|
77
|
+
validateHeaders(validator) {
|
|
78
|
+
this.validator = validator;
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
on(eventType, handler) {
|
|
82
|
+
this.slots.push({
|
|
83
|
+
eventType,
|
|
84
|
+
fn: handler,
|
|
85
|
+
});
|
|
86
|
+
return this;
|
|
87
|
+
}
|
|
88
|
+
async handle(req) {
|
|
89
|
+
const { headers, body } = await normalizeIaiRequest(req);
|
|
90
|
+
if (this.validator !== null) {
|
|
91
|
+
let valid = false;
|
|
92
|
+
try {
|
|
93
|
+
valid = await this.validator(headers);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
valid = false;
|
|
97
|
+
}
|
|
98
|
+
if (!valid) {
|
|
99
|
+
return { matched: false, eventType: null, reason: "validation_failed" };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const incomingEvent = headers.eventType;
|
|
103
|
+
const expectedObject = EVENT_OBJECT_MAP[incomingEvent];
|
|
104
|
+
if (expectedObject !== undefined && headers.objectType !== expectedObject) {
|
|
105
|
+
throw new WebhookValidationError(`eventType "${incomingEvent}" expects objectType "${expectedObject}", got "${headers.objectType}"`, "x-iai-object-type");
|
|
106
|
+
}
|
|
107
|
+
const slot = this.slots.find(s => s.eventType === incomingEvent);
|
|
108
|
+
if (!slot) {
|
|
109
|
+
return { matched: false, eventType: incomingEvent };
|
|
110
|
+
}
|
|
111
|
+
await slot.fn({ headers, body });
|
|
112
|
+
return { matched: true, eventType: slot.eventType };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// ─── Entry point ──────────────────────────────────────────────────────────────
|
|
116
|
+
export const webhooks = {
|
|
117
|
+
validateHeaders(validator) {
|
|
118
|
+
return new WebhookChain().validateHeaders(validator);
|
|
119
|
+
},
|
|
120
|
+
on(eventType, handler) {
|
|
121
|
+
return new WebhookChain().on(eventType, handler);
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
export default webhooks;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// ─── Errors ──────────────────────────────────────────────────────────────────
|
|
2
|
+
export class WebhookValidationError extends Error {
|
|
3
|
+
field;
|
|
4
|
+
constructor(message, field) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.field = field;
|
|
7
|
+
this.name = `WebhookValidationError ${field}`;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
// ─── Internal helpers ────────────────────────────────────────────────────────
|
|
11
|
+
function requireHeader(headers, key) {
|
|
12
|
+
const value = headers[key];
|
|
13
|
+
if (!value || value.trim() === "") {
|
|
14
|
+
throw new WebhookValidationError(`Missing or empty required header: ${key}`, key);
|
|
15
|
+
}
|
|
16
|
+
return value.trim();
|
|
17
|
+
}
|
|
18
|
+
function parseIntHeader(headers, key) {
|
|
19
|
+
const raw = requireHeader(headers, key);
|
|
20
|
+
const n = Number(raw);
|
|
21
|
+
if (!Number.isInteger(n) || n < 0) {
|
|
22
|
+
throw new WebhookValidationError(`Header ${key} must be a positive integer, got: "${raw}"`, key);
|
|
23
|
+
}
|
|
24
|
+
return n;
|
|
25
|
+
}
|
|
26
|
+
function parseDateHeader(headers, key) {
|
|
27
|
+
const raw = requireHeader(headers, key);
|
|
28
|
+
const date = new Date(raw);
|
|
29
|
+
if (isNaN(date.getTime())) {
|
|
30
|
+
throw new WebhookValidationError(`Header ${key} is not a valid date string, got: "${raw}"`, key);
|
|
31
|
+
}
|
|
32
|
+
return date;
|
|
33
|
+
}
|
|
34
|
+
function parseAuthHeader(headers) {
|
|
35
|
+
const raw = requireHeader(headers, "authorization");
|
|
36
|
+
const [scheme, token] = raw.split(" ");
|
|
37
|
+
if (scheme?.toLowerCase() !== "bearer" || !token) {
|
|
38
|
+
throw new WebhookValidationError(`Authorization header must use Bearer scheme, got: "${raw}"`, "authorization");
|
|
39
|
+
}
|
|
40
|
+
return token;
|
|
41
|
+
}
|
|
42
|
+
function extractHeaders(raw) {
|
|
43
|
+
return {
|
|
44
|
+
token: parseAuthHeader(raw),
|
|
45
|
+
apiVersion: parseIntHeader(raw, "x-iai-api-version"),
|
|
46
|
+
eventTime: parseDateHeader(raw, "x-iai-event-time"),
|
|
47
|
+
eventType: requireHeader(raw, "x-iai-event-type"),
|
|
48
|
+
eventUid: requireHeader(raw, "x-iai-event-uid"),
|
|
49
|
+
objectType: requireHeader(raw, "x-iai-object-type"),
|
|
50
|
+
panelId: parseIntHeader(raw, "x-iai-panel-id"),
|
|
51
|
+
signature: requireHeader(raw, "x-iai-signature"),
|
|
52
|
+
webhookTime: parseDateHeader(raw, "x-iai-webhook-time"),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
// ─── Type guard ──────────────────────────────────────────────────────────────
|
|
56
|
+
function isWebRequest(req) {
|
|
57
|
+
return typeof req.json === "function";
|
|
58
|
+
}
|
|
59
|
+
// ─── Raw headers flattening ──────────────────────────────────────────────────
|
|
60
|
+
function flattenNodeHeaders(headers) {
|
|
61
|
+
const out = {};
|
|
62
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
63
|
+
if (value !== undefined) {
|
|
64
|
+
out[key.toLowerCase()] = Array.isArray(value) ? value.join(", ") : value;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
function flattenWebHeaders(headers) {
|
|
70
|
+
const out = {};
|
|
71
|
+
headers.forEach((value, key) => { out[key.toLowerCase()] = value; });
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
function readNodeStream(req) {
|
|
75
|
+
return new Promise((resolve, reject) => {
|
|
76
|
+
const chunks = [];
|
|
77
|
+
req.on("data", (chunk) => chunks.push(chunk));
|
|
78
|
+
req.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8")));
|
|
79
|
+
req.on("error", reject);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
// ─── Main normalizer ─────────────────────────────────────────────────────────
|
|
83
|
+
/**
|
|
84
|
+
* Parses and validates an incoming IAI webhook request from any of:
|
|
85
|
+
* - Express (pass req directly — do NOT attach express.json())
|
|
86
|
+
* - Next.js Pages (disable bodyParser in route config)
|
|
87
|
+
* - Next.js App (Web Fetch API Request)
|
|
88
|
+
* - SvelteKit (Web Fetch API Request — pass event.request)
|
|
89
|
+
*
|
|
90
|
+
* Throws WebhookValidationError for any missing/malformed header or empty body.
|
|
91
|
+
*
|
|
92
|
+
* @example Express
|
|
93
|
+
* app.post('/webhook', async (req, res) => {
|
|
94
|
+
* const { headers, body } = await normalizeIaiRequest(req);
|
|
95
|
+
* });
|
|
96
|
+
*
|
|
97
|
+
* @example SvelteKit
|
|
98
|
+
* export async function POST({ request }) {
|
|
99
|
+
* const { headers, body } = await normalizeIaiRequest(request);
|
|
100
|
+
* }
|
|
101
|
+
*
|
|
102
|
+
* @example Next.js App Router
|
|
103
|
+
* export async function POST(request: Request) {
|
|
104
|
+
* const { headers, body } = await normalizeIaiRequest(request);
|
|
105
|
+
* }
|
|
106
|
+
*
|
|
107
|
+
* @example Next.js Pages Router (add export const config = { api: { bodyParser: false } })
|
|
108
|
+
* export default async function handler(req, res) {
|
|
109
|
+
* const { headers, body } = await normalizeIaiRequest(req);
|
|
110
|
+
* }
|
|
111
|
+
*/
|
|
112
|
+
export async function normalizeIaiRequest(req) {
|
|
113
|
+
let flatHeaders;
|
|
114
|
+
let rawBody;
|
|
115
|
+
if (isWebRequest(req)) {
|
|
116
|
+
flatHeaders = flattenWebHeaders(req.headers);
|
|
117
|
+
rawBody = await req.text();
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
flatHeaders = flattenNodeHeaders(req.headers);
|
|
121
|
+
rawBody = req.body !== undefined
|
|
122
|
+
? JSON.stringify(req.body)
|
|
123
|
+
: await readNodeStream(req);
|
|
124
|
+
}
|
|
125
|
+
if (!rawBody || rawBody.trim() === "") {
|
|
126
|
+
throw new WebhookValidationError("Request body is empty", "body");
|
|
127
|
+
}
|
|
128
|
+
let body;
|
|
129
|
+
try {
|
|
130
|
+
body = JSON.parse(rawBody);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
throw new WebhookValidationError("Request body is not valid JSON", "body");
|
|
134
|
+
}
|
|
135
|
+
if (typeof body !== "object" || body === null || Array.isArray(body)) {
|
|
136
|
+
throw new WebhookValidationError("Request body must be a JSON object", "body");
|
|
137
|
+
}
|
|
138
|
+
const headers = extractHeaders(flatHeaders);
|
|
139
|
+
return { headers, body };
|
|
140
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "idosell",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.41",
|
|
4
4
|
"description": "Idosell 3 REST connector",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/gateways.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"homepage": "https://idosell-converter.vercel.app",
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"axios": "^1.
|
|
26
|
+
"axios": "^1.17.0"
|
|
27
27
|
},
|
|
28
28
|
"type": "module"
|
|
29
29
|
}
|