react-shopwave-connect 0.4.0 → 0.4.1
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 +2 -1
- package/dist/core/index.cjs +101 -7
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +69 -2
- package/dist/core/index.d.ts +69 -2
- package/dist/core/index.js +99 -8
- package/dist/core/index.js.map +1 -1
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +101 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -2
- package/dist/index.d.ts +69 -2
- package/dist/index.js +99 -8
- package/dist/index.js.map +1 -1
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.js.map +1 -1
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/core/index.d.cts
CHANGED
|
@@ -272,6 +272,64 @@ interface FetchProductsParams {
|
|
|
272
272
|
* Fetches products. Returns the flattened `Product[]`.
|
|
273
273
|
*/
|
|
274
274
|
declare function fetchProducts(params?: FetchProductsParams, options?: RequestOptions): Promise<Product[]>;
|
|
275
|
+
/** An instance as a form or caller holds it: `id` is absent for new rows. */
|
|
276
|
+
type ProductInstanceInput = {
|
|
277
|
+
id?: number | string | null;
|
|
278
|
+
price?: string | number | null;
|
|
279
|
+
taxPercentage?: string | number | null;
|
|
280
|
+
name?: string | null;
|
|
281
|
+
};
|
|
282
|
+
/** Instances as the API returns them (keyed by id) or as a plain list. */
|
|
283
|
+
type ProductInstances<T = ProductInstanceInput> = Readonly<Record<string, T>> | Readonly<Record<number, T>> | ReadonlyArray<T>;
|
|
284
|
+
/**
|
|
285
|
+
* What `saveProduct` accepts: any product fields, with `instances` either as the
|
|
286
|
+
* API returns them or as built by {@link toProductInstancesForSave}. Include `id`
|
|
287
|
+
* to update; leave it out to create.
|
|
288
|
+
*/
|
|
289
|
+
type ProductSaveInput = Partial<Omit<Product, "instances">> & {
|
|
290
|
+
instances?: ProductInstances;
|
|
291
|
+
[field: string]: unknown;
|
|
292
|
+
};
|
|
293
|
+
/** True when two instances have the same price and tax (the fields Shopwave won't update). */
|
|
294
|
+
declare function isSameInstancePrice(a: ProductInstanceInput, b: ProductInstanceInput): boolean;
|
|
295
|
+
/** An instance whose price or tax was edited, so saving it will give it a new id. */
|
|
296
|
+
interface RepricedInstance {
|
|
297
|
+
/** Position of the instance in the list that was passed in. */
|
|
298
|
+
index: number;
|
|
299
|
+
/** The id it has now, which Shopwave will replace. */
|
|
300
|
+
id: number | string;
|
|
301
|
+
name: string;
|
|
302
|
+
before: {
|
|
303
|
+
price: string;
|
|
304
|
+
taxPercentage: string;
|
|
305
|
+
};
|
|
306
|
+
after: {
|
|
307
|
+
price: string;
|
|
308
|
+
taxPercentage: string;
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Lists the instances whose price or tax differs from the `original` instance
|
|
313
|
+
* with the same id: saving them creates new instances with new ids, which can
|
|
314
|
+
* affect anything that stores instance ids (integrations, reports, modifiers).
|
|
315
|
+
* Use it to warn before saving. New rows (no id) aren't listed.
|
|
316
|
+
*/
|
|
317
|
+
declare function findRepricedInstances(instances: ProductInstances | null | undefined, original: ProductInstances | null | undefined): RepricedInstance[];
|
|
318
|
+
/**
|
|
319
|
+
* Builds the `instances` map for a product save:
|
|
320
|
+
* - keyed by position (`"0"`, `"1"`, …), like every other ref in a save;
|
|
321
|
+
* - an instance keeps its `id` only when `original` has an instance with that id
|
|
322
|
+
* and the same price and tax; otherwise the id is removed, so Shopwave creates
|
|
323
|
+
* a new instance instead of re-pointing or rewriting someone else's;
|
|
324
|
+
* - server fields (`timestamp`) are removed.
|
|
325
|
+
*
|
|
326
|
+
* Pass the product as last read from the API as `original`. Leave it out for a
|
|
327
|
+
* new product (including a duplicate): every id is then removed.
|
|
328
|
+
* Instances left out of the list are left out of the save (removed).
|
|
329
|
+
*/
|
|
330
|
+
declare function toProductInstancesForSave<T extends ProductInstanceInput>(instances: ProductInstances<T> | null | undefined, original?: ProductInstances | null): Record<string, Omit<T, "id"> & {
|
|
331
|
+
id?: number | string;
|
|
332
|
+
}>;
|
|
275
333
|
/**
|
|
276
334
|
* Fetches products by id and returns them keyed by id, transparently batching
|
|
277
335
|
* the request (default 200 ids per call) to stay within API limits. Extracted
|
|
@@ -573,7 +631,16 @@ interface FetchByIdParams {
|
|
|
573
631
|
}
|
|
574
632
|
/** Reads one entity by id, or `null` when there's no such (non-deleted) record. */
|
|
575
633
|
declare function fetchEntityById<K extends EntityKind>(kind: K, id: EntityId, params?: FetchByIdParams, options?: RequestOptions): Promise<EntityTypes[K] | null>;
|
|
576
|
-
|
|
634
|
+
/**
|
|
635
|
+
* Creates (no `id`) or updates (with `id`) a product.
|
|
636
|
+
*
|
|
637
|
+
* Shopwave instances (prices) can't be updated, only replaced. Build
|
|
638
|
+
* `instances` with {@link toProductInstancesForSave} (passing the product as last
|
|
639
|
+
* read) so an edited price is sent as a new instance. As a safeguard, a new
|
|
640
|
+
* product (no `id`, e.g. a duplicate) never sends instance ids: an id copied from
|
|
641
|
+
* another product would otherwise point the save at that product's instances.
|
|
642
|
+
*/
|
|
643
|
+
declare const saveProduct: (product: ProductSaveInput, options?: RequestOptions) => Promise<Saved<Product>>;
|
|
577
644
|
declare const deleteProduct: (id: EntityId, options?: RequestOptions) => Promise<void>;
|
|
578
645
|
declare const fetchProduct: (id: EntityId, params?: FetchByIdParams, options?: RequestOptions) => Promise<Product | null>;
|
|
579
646
|
declare const saveCategory: (category: EntityInput<Category>, options?: RequestOptions) => Promise<Saved<Category>>;
|
|
@@ -1086,5 +1153,5 @@ interface UserResponse {
|
|
|
1086
1153
|
/** Reads the logged-in user, or `null` when the API returns none. */
|
|
1087
1154
|
declare function fetchUser(options?: RequestOptions): Promise<User | null>;
|
|
1088
1155
|
//#endregion
|
|
1089
|
-
export { Basket, BasketFilters, BasketItem, BasketPagination, BasketReportRow, BasketSummary, Category, CategoryResponse, CombineBasketRowsParams, Consumer, ConsumerResponse, CropRect, DEFAULT_BASKET_FILTERS, DEFAULT_PAGINATION, DeletableEntityKind, Employee, EmployeeResponse, EntityDefinition, EntityId, EntityInput, EntityKind, EntityTypes, ErrorMessage, Extras, FetchByIdParams, FetchCategoriesParams, FetchEmployeesParams, FetchProductsParams, FetchPromotionsParams, FetchStoresParams, FitImageOptions, ImageSize, MERCHANT_COLOUR_KEYS, MERCHANT_FIELD_MAX_LENGTH, MERCHANT_IMAGE_SLOTS, MERCHANT_IMAGE_SLOT_KEYS, MERCHANT_LINK_KEYS, MERCHANT_LINK_PATHS, MERCHANT_OBJECT_FIELDS, MERCHANT_READ_ONLY_FIELDS, Merchant, MerchantColourKey, MerchantColourSet, MerchantColours, MerchantImageIds, MerchantImageSlot, MerchantImageSlotDefinition, MerchantLinkKey, MerchantLinks, MerchantPatch, MerchantResponse, MessageInfo, ParsedBasket, Product, ProductInstance, ProductResponse, Promotion, PromotionResponse, PromotionRuleSet, ReportData, ReportKey, ReportQuery, ReportQueryMap, ReportResponse, RequestOptions, ResourceDefinition, ResourceKind, SHOPWAVE_ENTITIES, SHOPWAVE_IMAGE_BASE_URL, SHOPWAVE_RESOURCES, SHOPWAVE_UPLOAD, Saved, SessionStatus, ShopwaveApiError, ShopwaveErrorMap, Store, StoreResponse, SubmitEntityArgs, SubmitEntityResponse, SuccessMessage, UPLOAD_KINDS, UpdateMerchantOptions, UploadImageParams, UploadKind, UploadMerchantImageOptions, UploadedImage, User, UserEmployee, UserResponse, WritableEntityKind, apiDelete, apiGet, apiRequest, apiResponse, apiSend, assertNoApiErrors, authorizationFor, buildBasketReportQuery, buildConsumerMap, collectConsumerIds, collectProductIds, combineBasketRows, computeBasketSummary, coverCrop, deleteCategory, deleteEmployee, deleteEntity, deleteEntityById, deleteProduct, deletePromotion, deleteStore, fetchCategories, fetchCategory, fetchConsumer, fetchConsumers, fetchEmployee, fetchEmployees, fetchEntityById, fetchMerchant, fetchProduct, fetchProducts, fetchProductsMap, fetchPromotion, fetchPromotions, fetchReport, fetchSession, fetchStore, fetchStores, fetchUser, fitImageToSize, formatDateForQuery, getApiErrorMap, getApiErrors, getImageUrl, getMerchantImage, getMerchantImageUrl, imageFileName, isUploadKind, loginPath, logout, logoutPath, merchantLinksFromForm, merchantLinksToForm, normalizeMerchantLinks, parseBasketReportData, readImageSize, rolesById, saveCategory, saveEmployee, saveEntities, saveEntity, saveProduct, savePromotion, saveStore, setMerchantImage, submitEntity, toShopwaveApiError, toStoredImageIds, updateMerchant, uploadImage, uploadMerchantImage, validateMerchant, withToken };
|
|
1156
|
+
export { Basket, BasketFilters, BasketItem, BasketPagination, BasketReportRow, BasketSummary, Category, CategoryResponse, CombineBasketRowsParams, Consumer, ConsumerResponse, CropRect, DEFAULT_BASKET_FILTERS, DEFAULT_PAGINATION, DeletableEntityKind, Employee, EmployeeResponse, EntityDefinition, EntityId, EntityInput, EntityKind, EntityTypes, ErrorMessage, Extras, FetchByIdParams, FetchCategoriesParams, FetchEmployeesParams, FetchProductsParams, FetchPromotionsParams, FetchStoresParams, FitImageOptions, ImageSize, MERCHANT_COLOUR_KEYS, MERCHANT_FIELD_MAX_LENGTH, MERCHANT_IMAGE_SLOTS, MERCHANT_IMAGE_SLOT_KEYS, MERCHANT_LINK_KEYS, MERCHANT_LINK_PATHS, MERCHANT_OBJECT_FIELDS, MERCHANT_READ_ONLY_FIELDS, Merchant, MerchantColourKey, MerchantColourSet, MerchantColours, MerchantImageIds, MerchantImageSlot, MerchantImageSlotDefinition, MerchantLinkKey, MerchantLinks, MerchantPatch, MerchantResponse, MessageInfo, ParsedBasket, Product, ProductInstance, ProductInstanceInput, ProductInstances, ProductResponse, ProductSaveInput, Promotion, PromotionResponse, PromotionRuleSet, ReportData, ReportKey, ReportQuery, ReportQueryMap, ReportResponse, RepricedInstance, RequestOptions, ResourceDefinition, ResourceKind, SHOPWAVE_ENTITIES, SHOPWAVE_IMAGE_BASE_URL, SHOPWAVE_RESOURCES, SHOPWAVE_UPLOAD, Saved, SessionStatus, ShopwaveApiError, ShopwaveErrorMap, Store, StoreResponse, SubmitEntityArgs, SubmitEntityResponse, SuccessMessage, UPLOAD_KINDS, UpdateMerchantOptions, UploadImageParams, UploadKind, UploadMerchantImageOptions, UploadedImage, User, UserEmployee, UserResponse, WritableEntityKind, apiDelete, apiGet, apiRequest, apiResponse, apiSend, assertNoApiErrors, authorizationFor, buildBasketReportQuery, buildConsumerMap, collectConsumerIds, collectProductIds, combineBasketRows, computeBasketSummary, coverCrop, deleteCategory, deleteEmployee, deleteEntity, deleteEntityById, deleteProduct, deletePromotion, deleteStore, fetchCategories, fetchCategory, fetchConsumer, fetchConsumers, fetchEmployee, fetchEmployees, fetchEntityById, fetchMerchant, fetchProduct, fetchProducts, fetchProductsMap, fetchPromotion, fetchPromotions, fetchReport, fetchSession, fetchStore, fetchStores, fetchUser, findRepricedInstances, fitImageToSize, formatDateForQuery, getApiErrorMap, getApiErrors, getImageUrl, getMerchantImage, getMerchantImageUrl, imageFileName, isSameInstancePrice, isUploadKind, loginPath, logout, logoutPath, merchantLinksFromForm, merchantLinksToForm, normalizeMerchantLinks, parseBasketReportData, readImageSize, rolesById, saveCategory, saveEmployee, saveEntities, saveEntity, saveProduct, savePromotion, saveStore, setMerchantImage, submitEntity, toProductInstancesForSave, toShopwaveApiError, toStoredImageIds, updateMerchant, uploadImage, uploadMerchantImage, validateMerchant, withToken };
|
|
1090
1157
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/core/index.d.ts
CHANGED
|
@@ -272,6 +272,64 @@ interface FetchProductsParams {
|
|
|
272
272
|
* Fetches products. Returns the flattened `Product[]`.
|
|
273
273
|
*/
|
|
274
274
|
declare function fetchProducts(params?: FetchProductsParams, options?: RequestOptions): Promise<Product[]>;
|
|
275
|
+
/** An instance as a form or caller holds it: `id` is absent for new rows. */
|
|
276
|
+
type ProductInstanceInput = {
|
|
277
|
+
id?: number | string | null;
|
|
278
|
+
price?: string | number | null;
|
|
279
|
+
taxPercentage?: string | number | null;
|
|
280
|
+
name?: string | null;
|
|
281
|
+
};
|
|
282
|
+
/** Instances as the API returns them (keyed by id) or as a plain list. */
|
|
283
|
+
type ProductInstances<T = ProductInstanceInput> = Readonly<Record<string, T>> | Readonly<Record<number, T>> | ReadonlyArray<T>;
|
|
284
|
+
/**
|
|
285
|
+
* What `saveProduct` accepts: any product fields, with `instances` either as the
|
|
286
|
+
* API returns them or as built by {@link toProductInstancesForSave}. Include `id`
|
|
287
|
+
* to update; leave it out to create.
|
|
288
|
+
*/
|
|
289
|
+
type ProductSaveInput = Partial<Omit<Product, "instances">> & {
|
|
290
|
+
instances?: ProductInstances;
|
|
291
|
+
[field: string]: unknown;
|
|
292
|
+
};
|
|
293
|
+
/** True when two instances have the same price and tax (the fields Shopwave won't update). */
|
|
294
|
+
declare function isSameInstancePrice(a: ProductInstanceInput, b: ProductInstanceInput): boolean;
|
|
295
|
+
/** An instance whose price or tax was edited, so saving it will give it a new id. */
|
|
296
|
+
interface RepricedInstance {
|
|
297
|
+
/** Position of the instance in the list that was passed in. */
|
|
298
|
+
index: number;
|
|
299
|
+
/** The id it has now, which Shopwave will replace. */
|
|
300
|
+
id: number | string;
|
|
301
|
+
name: string;
|
|
302
|
+
before: {
|
|
303
|
+
price: string;
|
|
304
|
+
taxPercentage: string;
|
|
305
|
+
};
|
|
306
|
+
after: {
|
|
307
|
+
price: string;
|
|
308
|
+
taxPercentage: string;
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Lists the instances whose price or tax differs from the `original` instance
|
|
313
|
+
* with the same id: saving them creates new instances with new ids, which can
|
|
314
|
+
* affect anything that stores instance ids (integrations, reports, modifiers).
|
|
315
|
+
* Use it to warn before saving. New rows (no id) aren't listed.
|
|
316
|
+
*/
|
|
317
|
+
declare function findRepricedInstances(instances: ProductInstances | null | undefined, original: ProductInstances | null | undefined): RepricedInstance[];
|
|
318
|
+
/**
|
|
319
|
+
* Builds the `instances` map for a product save:
|
|
320
|
+
* - keyed by position (`"0"`, `"1"`, …), like every other ref in a save;
|
|
321
|
+
* - an instance keeps its `id` only when `original` has an instance with that id
|
|
322
|
+
* and the same price and tax; otherwise the id is removed, so Shopwave creates
|
|
323
|
+
* a new instance instead of re-pointing or rewriting someone else's;
|
|
324
|
+
* - server fields (`timestamp`) are removed.
|
|
325
|
+
*
|
|
326
|
+
* Pass the product as last read from the API as `original`. Leave it out for a
|
|
327
|
+
* new product (including a duplicate): every id is then removed.
|
|
328
|
+
* Instances left out of the list are left out of the save (removed).
|
|
329
|
+
*/
|
|
330
|
+
declare function toProductInstancesForSave<T extends ProductInstanceInput>(instances: ProductInstances<T> | null | undefined, original?: ProductInstances | null): Record<string, Omit<T, "id"> & {
|
|
331
|
+
id?: number | string;
|
|
332
|
+
}>;
|
|
275
333
|
/**
|
|
276
334
|
* Fetches products by id and returns them keyed by id, transparently batching
|
|
277
335
|
* the request (default 200 ids per call) to stay within API limits. Extracted
|
|
@@ -573,7 +631,16 @@ interface FetchByIdParams {
|
|
|
573
631
|
}
|
|
574
632
|
/** Reads one entity by id, or `null` when there's no such (non-deleted) record. */
|
|
575
633
|
declare function fetchEntityById<K extends EntityKind>(kind: K, id: EntityId, params?: FetchByIdParams, options?: RequestOptions): Promise<EntityTypes[K] | null>;
|
|
576
|
-
|
|
634
|
+
/**
|
|
635
|
+
* Creates (no `id`) or updates (with `id`) a product.
|
|
636
|
+
*
|
|
637
|
+
* Shopwave instances (prices) can't be updated, only replaced. Build
|
|
638
|
+
* `instances` with {@link toProductInstancesForSave} (passing the product as last
|
|
639
|
+
* read) so an edited price is sent as a new instance. As a safeguard, a new
|
|
640
|
+
* product (no `id`, e.g. a duplicate) never sends instance ids: an id copied from
|
|
641
|
+
* another product would otherwise point the save at that product's instances.
|
|
642
|
+
*/
|
|
643
|
+
declare const saveProduct: (product: ProductSaveInput, options?: RequestOptions) => Promise<Saved<Product>>;
|
|
577
644
|
declare const deleteProduct: (id: EntityId, options?: RequestOptions) => Promise<void>;
|
|
578
645
|
declare const fetchProduct: (id: EntityId, params?: FetchByIdParams, options?: RequestOptions) => Promise<Product | null>;
|
|
579
646
|
declare const saveCategory: (category: EntityInput<Category>, options?: RequestOptions) => Promise<Saved<Category>>;
|
|
@@ -1086,5 +1153,5 @@ interface UserResponse {
|
|
|
1086
1153
|
/** Reads the logged-in user, or `null` when the API returns none. */
|
|
1087
1154
|
declare function fetchUser(options?: RequestOptions): Promise<User | null>;
|
|
1088
1155
|
//#endregion
|
|
1089
|
-
export { Basket, BasketFilters, BasketItem, BasketPagination, BasketReportRow, BasketSummary, Category, CategoryResponse, CombineBasketRowsParams, Consumer, ConsumerResponse, CropRect, DEFAULT_BASKET_FILTERS, DEFAULT_PAGINATION, DeletableEntityKind, Employee, EmployeeResponse, EntityDefinition, EntityId, EntityInput, EntityKind, EntityTypes, ErrorMessage, Extras, FetchByIdParams, FetchCategoriesParams, FetchEmployeesParams, FetchProductsParams, FetchPromotionsParams, FetchStoresParams, FitImageOptions, ImageSize, MERCHANT_COLOUR_KEYS, MERCHANT_FIELD_MAX_LENGTH, MERCHANT_IMAGE_SLOTS, MERCHANT_IMAGE_SLOT_KEYS, MERCHANT_LINK_KEYS, MERCHANT_LINK_PATHS, MERCHANT_OBJECT_FIELDS, MERCHANT_READ_ONLY_FIELDS, Merchant, MerchantColourKey, MerchantColourSet, MerchantColours, MerchantImageIds, MerchantImageSlot, MerchantImageSlotDefinition, MerchantLinkKey, MerchantLinks, MerchantPatch, MerchantResponse, MessageInfo, ParsedBasket, Product, ProductInstance, ProductResponse, Promotion, PromotionResponse, PromotionRuleSet, ReportData, ReportKey, ReportQuery, ReportQueryMap, ReportResponse, RequestOptions, ResourceDefinition, ResourceKind, SHOPWAVE_ENTITIES, SHOPWAVE_IMAGE_BASE_URL, SHOPWAVE_RESOURCES, SHOPWAVE_UPLOAD, Saved, SessionStatus, ShopwaveApiError, ShopwaveErrorMap, Store, StoreResponse, SubmitEntityArgs, SubmitEntityResponse, SuccessMessage, UPLOAD_KINDS, UpdateMerchantOptions, UploadImageParams, UploadKind, UploadMerchantImageOptions, UploadedImage, User, UserEmployee, UserResponse, WritableEntityKind, apiDelete, apiGet, apiRequest, apiResponse, apiSend, assertNoApiErrors, authorizationFor, buildBasketReportQuery, buildConsumerMap, collectConsumerIds, collectProductIds, combineBasketRows, computeBasketSummary, coverCrop, deleteCategory, deleteEmployee, deleteEntity, deleteEntityById, deleteProduct, deletePromotion, deleteStore, fetchCategories, fetchCategory, fetchConsumer, fetchConsumers, fetchEmployee, fetchEmployees, fetchEntityById, fetchMerchant, fetchProduct, fetchProducts, fetchProductsMap, fetchPromotion, fetchPromotions, fetchReport, fetchSession, fetchStore, fetchStores, fetchUser, fitImageToSize, formatDateForQuery, getApiErrorMap, getApiErrors, getImageUrl, getMerchantImage, getMerchantImageUrl, imageFileName, isUploadKind, loginPath, logout, logoutPath, merchantLinksFromForm, merchantLinksToForm, normalizeMerchantLinks, parseBasketReportData, readImageSize, rolesById, saveCategory, saveEmployee, saveEntities, saveEntity, saveProduct, savePromotion, saveStore, setMerchantImage, submitEntity, toShopwaveApiError, toStoredImageIds, updateMerchant, uploadImage, uploadMerchantImage, validateMerchant, withToken };
|
|
1156
|
+
export { Basket, BasketFilters, BasketItem, BasketPagination, BasketReportRow, BasketSummary, Category, CategoryResponse, CombineBasketRowsParams, Consumer, ConsumerResponse, CropRect, DEFAULT_BASKET_FILTERS, DEFAULT_PAGINATION, DeletableEntityKind, Employee, EmployeeResponse, EntityDefinition, EntityId, EntityInput, EntityKind, EntityTypes, ErrorMessage, Extras, FetchByIdParams, FetchCategoriesParams, FetchEmployeesParams, FetchProductsParams, FetchPromotionsParams, FetchStoresParams, FitImageOptions, ImageSize, MERCHANT_COLOUR_KEYS, MERCHANT_FIELD_MAX_LENGTH, MERCHANT_IMAGE_SLOTS, MERCHANT_IMAGE_SLOT_KEYS, MERCHANT_LINK_KEYS, MERCHANT_LINK_PATHS, MERCHANT_OBJECT_FIELDS, MERCHANT_READ_ONLY_FIELDS, Merchant, MerchantColourKey, MerchantColourSet, MerchantColours, MerchantImageIds, MerchantImageSlot, MerchantImageSlotDefinition, MerchantLinkKey, MerchantLinks, MerchantPatch, MerchantResponse, MessageInfo, ParsedBasket, Product, ProductInstance, ProductInstanceInput, ProductInstances, ProductResponse, ProductSaveInput, Promotion, PromotionResponse, PromotionRuleSet, ReportData, ReportKey, ReportQuery, ReportQueryMap, ReportResponse, RepricedInstance, RequestOptions, ResourceDefinition, ResourceKind, SHOPWAVE_ENTITIES, SHOPWAVE_IMAGE_BASE_URL, SHOPWAVE_RESOURCES, SHOPWAVE_UPLOAD, Saved, SessionStatus, ShopwaveApiError, ShopwaveErrorMap, Store, StoreResponse, SubmitEntityArgs, SubmitEntityResponse, SuccessMessage, UPLOAD_KINDS, UpdateMerchantOptions, UploadImageParams, UploadKind, UploadMerchantImageOptions, UploadedImage, User, UserEmployee, UserResponse, WritableEntityKind, apiDelete, apiGet, apiRequest, apiResponse, apiSend, assertNoApiErrors, authorizationFor, buildBasketReportQuery, buildConsumerMap, collectConsumerIds, collectProductIds, combineBasketRows, computeBasketSummary, coverCrop, deleteCategory, deleteEmployee, deleteEntity, deleteEntityById, deleteProduct, deletePromotion, deleteStore, fetchCategories, fetchCategory, fetchConsumer, fetchConsumers, fetchEmployee, fetchEmployees, fetchEntityById, fetchMerchant, fetchProduct, fetchProducts, fetchProductsMap, fetchPromotion, fetchPromotions, fetchReport, fetchSession, fetchStore, fetchStores, fetchUser, findRepricedInstances, fitImageToSize, formatDateForQuery, getApiErrorMap, getApiErrors, getImageUrl, getMerchantImage, getMerchantImageUrl, imageFileName, isSameInstancePrice, isUploadKind, loginPath, logout, logoutPath, merchantLinksFromForm, merchantLinksToForm, normalizeMerchantLinks, parseBasketReportData, readImageSize, rolesById, saveCategory, saveEmployee, saveEntities, saveEntity, saveProduct, savePromotion, saveStore, setMerchantImage, submitEntity, toProductInstancesForSave, toShopwaveApiError, toStoredImageIds, updateMerchant, uploadImage, uploadMerchantImage, validateMerchant, withToken };
|
|
1090
1157
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/core/index.js
CHANGED
|
@@ -40,8 +40,8 @@ function getApiErrorMap(body) {
|
|
|
40
40
|
}
|
|
41
41
|
function describeErrors(errors) {
|
|
42
42
|
return Object.entries(errors).map(([code, e]) => {
|
|
43
|
-
const text = [e?.title, e?.details].filter(Boolean).join(": ");
|
|
44
|
-
return text ? `${code} ${text}` : code;
|
|
43
|
+
const text$1 = [e?.title, e?.details].filter(Boolean).join(": ");
|
|
44
|
+
return text$1 ? `${code} ${text$1}` : code;
|
|
45
45
|
}).join("; ");
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
@@ -103,12 +103,12 @@ function buildExtras(extras) {
|
|
|
103
103
|
}
|
|
104
104
|
/** Parses a response body as JSON; `null` for an empty body, `{ raw }` for non-JSON. */
|
|
105
105
|
async function readBody(response) {
|
|
106
|
-
const text = await response.text();
|
|
107
|
-
if (!text) return null;
|
|
106
|
+
const text$1 = await response.text();
|
|
107
|
+
if (!text$1) return null;
|
|
108
108
|
try {
|
|
109
|
-
return JSON.parse(text);
|
|
109
|
+
return JSON.parse(text$1);
|
|
110
110
|
} catch {
|
|
111
|
-
return { raw: text };
|
|
111
|
+
return { raw: text$1 };
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
/**
|
|
@@ -256,6 +256,83 @@ async function fetchProducts(params = {}, options = {}) {
|
|
|
256
256
|
assertNoApiErrors(json, 200);
|
|
257
257
|
return Object.values(json?.products ?? {});
|
|
258
258
|
}
|
|
259
|
+
/** Fields the server sets on an instance; never sent back. */
|
|
260
|
+
const SERVER_INSTANCE_FIELDS = ["timestamp"];
|
|
261
|
+
function instanceList(instances) {
|
|
262
|
+
if (!instances) return [];
|
|
263
|
+
return (Array.isArray(instances) ? [...instances] : Object.values(instances)).filter((inst) => inst != null && typeof inst === "object");
|
|
264
|
+
}
|
|
265
|
+
function hasId(id) {
|
|
266
|
+
return id != null && String(id).trim() !== "";
|
|
267
|
+
}
|
|
268
|
+
/** Same number, so `"422.0"`, `"422"` and `422` are equal; blanks equal each other. */
|
|
269
|
+
function sameAmount(a, b) {
|
|
270
|
+
const blank = (v) => v == null || String(v).trim() === "";
|
|
271
|
+
if (blank(a) || blank(b)) return blank(a) && blank(b);
|
|
272
|
+
const x = Number(a);
|
|
273
|
+
const y = Number(b);
|
|
274
|
+
return Number.isNaN(x) || Number.isNaN(y) ? String(a).trim() === String(b).trim() : x === y;
|
|
275
|
+
}
|
|
276
|
+
/** True when two instances have the same price and tax (the fields Shopwave won't update). */
|
|
277
|
+
function isSameInstancePrice(a, b) {
|
|
278
|
+
return sameAmount(a.price, b.price) && sameAmount(a.taxPercentage, b.taxPercentage);
|
|
279
|
+
}
|
|
280
|
+
const text = (v) => v == null ? "" : String(v);
|
|
281
|
+
/**
|
|
282
|
+
* Lists the instances whose price or tax differs from the `original` instance
|
|
283
|
+
* with the same id: saving them creates new instances with new ids, which can
|
|
284
|
+
* affect anything that stores instance ids (integrations, reports, modifiers).
|
|
285
|
+
* Use it to warn before saving. New rows (no id) aren't listed.
|
|
286
|
+
*/
|
|
287
|
+
function findRepricedInstances(instances, original) {
|
|
288
|
+
const byId = new Map(instanceList(original).filter((o) => hasId(o.id)).map((o) => [String(o.id), o]));
|
|
289
|
+
const result = [];
|
|
290
|
+
instanceList(instances).forEach((inst, index) => {
|
|
291
|
+
if (!hasId(inst.id)) return;
|
|
292
|
+
const before = byId.get(String(inst.id));
|
|
293
|
+
if (!before || isSameInstancePrice(inst, before)) return;
|
|
294
|
+
result.push({
|
|
295
|
+
index,
|
|
296
|
+
id: inst.id,
|
|
297
|
+
name: text(inst.name),
|
|
298
|
+
before: {
|
|
299
|
+
price: text(before.price),
|
|
300
|
+
taxPercentage: text(before.taxPercentage)
|
|
301
|
+
},
|
|
302
|
+
after: {
|
|
303
|
+
price: text(inst.price),
|
|
304
|
+
taxPercentage: text(inst.taxPercentage)
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
return result;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Builds the `instances` map for a product save:
|
|
312
|
+
* - keyed by position (`"0"`, `"1"`, …), like every other ref in a save;
|
|
313
|
+
* - an instance keeps its `id` only when `original` has an instance with that id
|
|
314
|
+
* and the same price and tax; otherwise the id is removed, so Shopwave creates
|
|
315
|
+
* a new instance instead of re-pointing or rewriting someone else's;
|
|
316
|
+
* - server fields (`timestamp`) are removed.
|
|
317
|
+
*
|
|
318
|
+
* Pass the product as last read from the API as `original`. Leave it out for a
|
|
319
|
+
* new product (including a duplicate): every id is then removed.
|
|
320
|
+
* Instances left out of the list are left out of the save (removed).
|
|
321
|
+
*/
|
|
322
|
+
function toProductInstancesForSave(instances, original) {
|
|
323
|
+
const keep = new Map(instanceList(original).filter((o) => hasId(o.id)).map((o) => [String(o.id), o]));
|
|
324
|
+
const out = {};
|
|
325
|
+
instanceList(instances).forEach((inst, index) => {
|
|
326
|
+
const { id,...rest } = inst;
|
|
327
|
+
for (const field of SERVER_INSTANCE_FIELDS) delete rest[field];
|
|
328
|
+
const before = hasId(id) ? keep.get(String(id)) : void 0;
|
|
329
|
+
out[String(index)] = before && isSameInstancePrice(inst, before) ? {
|
|
330
|
+
id,
|
|
331
|
+
...rest
|
|
332
|
+
} : rest;
|
|
333
|
+
});
|
|
334
|
+
return out;
|
|
335
|
+
}
|
|
259
336
|
/**
|
|
260
337
|
* Fetches products by id and returns them keyed by id, transparently batching
|
|
261
338
|
* the request (default 200 ids per call) to stay within API limits. Extracted
|
|
@@ -539,7 +616,21 @@ async function fetchEntityById(kind, id, params = {}, options = {}) {
|
|
|
539
616
|
const map = body?.[def.collection] ?? {};
|
|
540
617
|
return map[String(id)] ?? Object.values(map).find((e) => String(e?.id) === String(id)) ?? null;
|
|
541
618
|
}
|
|
542
|
-
|
|
619
|
+
/**
|
|
620
|
+
* Creates (no `id`) or updates (with `id`) a product.
|
|
621
|
+
*
|
|
622
|
+
* Shopwave instances (prices) can't be updated, only replaced. Build
|
|
623
|
+
* `instances` with {@link toProductInstancesForSave} (passing the product as last
|
|
624
|
+
* read) so an edited price is sent as a new instance. As a safeguard, a new
|
|
625
|
+
* product (no `id`, e.g. a duplicate) never sends instance ids: an id copied from
|
|
626
|
+
* another product would otherwise point the save at that product's instances.
|
|
627
|
+
*/
|
|
628
|
+
const saveProduct = (product, options) => {
|
|
629
|
+
return saveEntity("product", (product.id == null || String(product.id).trim() === "") && product.instances != null ? {
|
|
630
|
+
...product,
|
|
631
|
+
instances: toProductInstancesForSave(product.instances)
|
|
632
|
+
} : product, options);
|
|
633
|
+
};
|
|
543
634
|
const deleteProduct = (id, options) => deleteEntityById("product", id, options);
|
|
544
635
|
const fetchProduct = (id, params, options) => fetchEntityById("product", id, params, options);
|
|
545
636
|
const saveCategory = (category, options) => saveEntity("category", category, options);
|
|
@@ -1189,5 +1280,5 @@ async function fetchUser(options = {}) {
|
|
|
1189
1280
|
}
|
|
1190
1281
|
|
|
1191
1282
|
//#endregion
|
|
1192
|
-
export { DEFAULT_BASKET_FILTERS, DEFAULT_PAGINATION, MERCHANT_COLOUR_KEYS, MERCHANT_FIELD_MAX_LENGTH, MERCHANT_IMAGE_SLOTS, MERCHANT_IMAGE_SLOT_KEYS, MERCHANT_LINK_KEYS, MERCHANT_LINK_PATHS, MERCHANT_OBJECT_FIELDS, MERCHANT_READ_ONLY_FIELDS, PromotionRuleSet, SHOPWAVE_ENTITIES, SHOPWAVE_IMAGE_BASE_URL, SHOPWAVE_RESOURCES, SHOPWAVE_UPLOAD, ShopwaveApiError, UPLOAD_KINDS, apiDelete, apiGet, apiRequest, apiSend, assertNoApiErrors, authorizationFor, buildBasketReportQuery, buildConsumerMap, collectConsumerIds, collectProductIds, combineBasketRows, computeBasketSummary, coverCrop, deleteCategory, deleteEmployee, deleteEntity, deleteEntityById, deleteProduct, deletePromotion, deleteStore, fetchCategories, fetchCategory, fetchConsumer, fetchConsumers, fetchEmployee, fetchEmployees, fetchEntityById, fetchMerchant, fetchProduct, fetchProducts, fetchProductsMap, fetchPromotion, fetchPromotions, fetchReport, fetchSession, fetchStore, fetchStores, fetchUser, fitImageToSize, formatDateForQuery, getApiErrorMap, getApiErrors, getImageUrl, getMerchantImage, getMerchantImageUrl, imageFileName, isUploadKind, loginPath, logout, logoutPath, merchantLinksFromForm, merchantLinksToForm, normalizeMerchantLinks, parseBasketReportData, readImageSize, rolesById, saveCategory, saveEmployee, saveEntities, saveEntity, saveProduct, savePromotion, saveStore, setMerchantImage, submitEntity, toShopwaveApiError, toStoredImageIds, updateMerchant, uploadImage, uploadMerchantImage, validateMerchant, withToken };
|
|
1283
|
+
export { DEFAULT_BASKET_FILTERS, DEFAULT_PAGINATION, MERCHANT_COLOUR_KEYS, MERCHANT_FIELD_MAX_LENGTH, MERCHANT_IMAGE_SLOTS, MERCHANT_IMAGE_SLOT_KEYS, MERCHANT_LINK_KEYS, MERCHANT_LINK_PATHS, MERCHANT_OBJECT_FIELDS, MERCHANT_READ_ONLY_FIELDS, PromotionRuleSet, SHOPWAVE_ENTITIES, SHOPWAVE_IMAGE_BASE_URL, SHOPWAVE_RESOURCES, SHOPWAVE_UPLOAD, ShopwaveApiError, UPLOAD_KINDS, apiDelete, apiGet, apiRequest, apiSend, assertNoApiErrors, authorizationFor, buildBasketReportQuery, buildConsumerMap, collectConsumerIds, collectProductIds, combineBasketRows, computeBasketSummary, coverCrop, deleteCategory, deleteEmployee, deleteEntity, deleteEntityById, deleteProduct, deletePromotion, deleteStore, fetchCategories, fetchCategory, fetchConsumer, fetchConsumers, fetchEmployee, fetchEmployees, fetchEntityById, fetchMerchant, fetchProduct, fetchProducts, fetchProductsMap, fetchPromotion, fetchPromotions, fetchReport, fetchSession, fetchStore, fetchStores, fetchUser, findRepricedInstances, fitImageToSize, formatDateForQuery, getApiErrorMap, getApiErrors, getImageUrl, getMerchantImage, getMerchantImageUrl, imageFileName, isSameInstancePrice, isUploadKind, loginPath, logout, logoutPath, merchantLinksFromForm, merchantLinksToForm, normalizeMerchantLinks, parseBasketReportData, readImageSize, rolesById, saveCategory, saveEmployee, saveEntities, saveEntity, saveProduct, savePromotion, saveStore, setMerchantImage, submitEntity, toProductInstancesForSave, toShopwaveApiError, toStoredImageIds, updateMerchant, uploadImage, uploadMerchantImage, validateMerchant, withToken };
|
|
1193
1284
|
//# sourceMappingURL=index.js.map
|