react-shopwave-connect 0.4.3 → 0.4.5
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 +31 -4
- package/dist/core/index.cjs +526 -276
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +157 -6
- package/dist/core/index.d.ts +157 -6
- package/dist/core/index.js +517 -277
- package/dist/core/index.js.map +1 -1
- package/dist/hooks/index.cjs +190 -170
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.cts +19 -0
- package/dist/hooks/index.d.ts +19 -0
- package/dist/hooks/index.js +190 -170
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +526 -276
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +157 -6
- package/dist/index.d.ts +157 -6
- package/dist/index.js +517 -277
- package/dist/index.js.map +1 -1
- package/dist/next/index.cjs +75 -57
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +21 -4
- package/dist/next/index.d.ts +21 -4
- package/dist/next/index.js +75 -58
- package/dist/next/index.js.map +1 -1
- package/dist/server/index.cjs +75 -57
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +26 -5
- package/dist/server/index.d.ts +26 -5
- package/dist/server/index.js +75 -58
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/core/index.d.cts
CHANGED
|
@@ -676,6 +676,9 @@ declare function fetchEntityById<K extends EntityKind>(kind: K, id: EntityId, pa
|
|
|
676
676
|
* read) so an edited price is sent as a new instance. As a safeguard, a new
|
|
677
677
|
* product (no `id`, e.g. a duplicate) never sends instance ids: an id copied from
|
|
678
678
|
* another product would otherwise point the save at that product's instances.
|
|
679
|
+
*
|
|
680
|
+
* `images` is sent as file names ({@link toStoredProductImages}), so the URLs a
|
|
681
|
+
* read returns can be passed straight back; leaving `images` out keeps them.
|
|
679
682
|
*/
|
|
680
683
|
declare const saveProduct: (product: ProductSaveInput, options?: RequestOptions) => Promise<Saved<Product>>;
|
|
681
684
|
declare const deleteProduct: (id: EntityId, options?: RequestOptions) => Promise<void>;
|
|
@@ -844,20 +847,40 @@ declare const SHOPWAVE_RESOURCES: Readonly<Record<ResourceKind, ResourceDefiniti
|
|
|
844
847
|
type UploadKind = "merchant" | "merchantFeature" | "product" | "user" | "applicationLogo" | "applicationImages";
|
|
845
848
|
/** `UploadKind` → the API's `contentType` value. */
|
|
846
849
|
declare const UPLOAD_KINDS: Readonly<Record<UploadKind, string>>;
|
|
850
|
+
/**
|
|
851
|
+
* The role an image plays, sent to Shopwave as the uploader's `prefix` header.
|
|
852
|
+
* The uploader names the file `<prefix>_<hash>.<ext>`, so the role travels with
|
|
853
|
+
* the file wherever a record stores it (a product's `images`). Live, merchant
|
|
854
|
+
* 5644, 4 Nov 2026: all four values answered 201.
|
|
855
|
+
* - `product`: a product gallery image;
|
|
856
|
+
* - `product_thumbnail`: the product's lead image, shown in lists;
|
|
857
|
+
* - `variant` / `variant_thumbnail`: a variant's own image and its lead image
|
|
858
|
+
* (used by the Connect integrations).
|
|
859
|
+
*
|
|
860
|
+
* Values are the ones Connect's `uploadFileToShopwave` sends.
|
|
861
|
+
*/
|
|
862
|
+
type UploadPrefix = "product" | "product_thumbnail" | "variant" | "variant_thumbnail";
|
|
863
|
+
/** Every `UploadPrefix`, longest first so a name check never takes `product` for `product_thumbnail`. */
|
|
864
|
+
declare const UPLOAD_PREFIXES: ReadonlyArray<UploadPrefix>;
|
|
847
865
|
/** How uploads are addressed (app route and Shopwave uploader). */
|
|
848
866
|
declare const SHOPWAVE_UPLOAD: Readonly<{
|
|
849
|
-
/** App route: `POST /api/<route>` (multipart `file` + `kind`). */
|
|
867
|
+
/** App route: `POST /api/<route>` (multipart `file` + `kind`, optional `prefix`). */
|
|
850
868
|
route: "upload";
|
|
851
869
|
/** Shopwave path: `PUT {apiUrl}/uploader` (multipart `file`). */
|
|
852
870
|
upstream: "uploader";
|
|
853
871
|
/** Header that carries the upload kind upstream. */
|
|
854
872
|
kindHeader: "contentType";
|
|
873
|
+
/** Header that carries the image role upstream (see `UploadPrefix`). */
|
|
874
|
+
prefixHeader: "prefix";
|
|
855
875
|
/** Multipart field name for the file, on both sides. */
|
|
856
876
|
fileField: "file";
|
|
857
877
|
/** Multipart field name for the kind in the app request. */
|
|
858
878
|
kindField: "kind";
|
|
879
|
+
/** Multipart field name for the image role in the app request. */
|
|
880
|
+
prefixField: "prefix";
|
|
859
881
|
}>;
|
|
860
882
|
declare function isUploadKind(value: unknown): value is UploadKind;
|
|
883
|
+
declare function isUploadPrefix(value: unknown): value is UploadPrefix;
|
|
861
884
|
/**
|
|
862
885
|
* Read-only lists that aren't records: the merchant's distinct tags.
|
|
863
886
|
*
|
|
@@ -890,11 +913,12 @@ declare const SHOPWAVE_LOOKUPS: Readonly<Record<LookupKind, LookupDefinition>>;
|
|
|
890
913
|
//#endregion
|
|
891
914
|
//#region src/core/imageFit.d.ts
|
|
892
915
|
/**
|
|
893
|
-
* Browser helpers for getting an image to
|
|
916
|
+
* Browser helpers for getting an image to the right size before upload.
|
|
894
917
|
*
|
|
895
|
-
* Shopwave doesn't resize uploads,
|
|
896
|
-
*
|
|
897
|
-
*
|
|
918
|
+
* Shopwave doesn't resize uploads, so images are scaled and centre-cropped in
|
|
919
|
+
* the browser: to an exact size for the merchant image slots
|
|
920
|
+
* ({@link fitImageToSize}), or to a rule (ratio, minimum, maximum) with
|
|
921
|
+
* {@link prepareImage}, which apps use to give each kind of image its own rule.
|
|
898
922
|
*/
|
|
899
923
|
/** Source rectangle to draw so the image covers `dstWidth × dstHeight` (centre crop, no stretching). */
|
|
900
924
|
interface CropRect {
|
|
@@ -928,11 +952,113 @@ interface FitImageOptions {
|
|
|
928
952
|
* input, with the output type's extension.
|
|
929
953
|
*/
|
|
930
954
|
declare function fitImageToSize(file: Blob, width: number, height: number, options?: FitImageOptions): Promise<File>;
|
|
955
|
+
/**
|
|
956
|
+
* How an image must end up before upload. Every field is optional; give an
|
|
957
|
+
* exact size (`width` + `height`) or an `aspectRatio`, not both.
|
|
958
|
+
*
|
|
959
|
+
* Images are always scaled down first and then centre-cropped (never
|
|
960
|
+
* stretched): the kept area is the largest one with the right shape.
|
|
961
|
+
*
|
|
962
|
+
* @example
|
|
963
|
+
* // "Cropped to 100:77, at least 600 × 462", at most 2000 px on the long side
|
|
964
|
+
* { aspectRatio: "100:77", minWidth: 600, minHeight: 462, maxLongSide: 2000 }
|
|
965
|
+
* // Exactly 600 × 462
|
|
966
|
+
* { width: 600, height: 462 }
|
|
967
|
+
* // Any shape, scaled down to fit 2000 px
|
|
968
|
+
* { maxLongSide: 2000 }
|
|
969
|
+
*/
|
|
970
|
+
interface ImageRule {
|
|
971
|
+
/** Exact output width (needs `height`). */
|
|
972
|
+
width?: number;
|
|
973
|
+
/** Exact output height (needs `width`). */
|
|
974
|
+
height?: number;
|
|
975
|
+
/** Shape to crop to: `1.3`, `"100:77"`, `"100/77"` or `[100, 77]`. */
|
|
976
|
+
aspectRatio?: number | string | readonly [number, number];
|
|
977
|
+
/** Smallest acceptable output; a smaller image is refused (see `allowUpscale`). */
|
|
978
|
+
minWidth?: number;
|
|
979
|
+
minHeight?: number;
|
|
980
|
+
/** Largest output; a bigger image is scaled down to fit. */
|
|
981
|
+
maxWidth?: number;
|
|
982
|
+
maxHeight?: number;
|
|
983
|
+
/** Largest output on the longer side, whichever it is. */
|
|
984
|
+
maxLongSide?: number;
|
|
985
|
+
/** Enlarge a too-small image instead of refusing it. Default false. */
|
|
986
|
+
allowUpscale?: boolean;
|
|
987
|
+
}
|
|
988
|
+
/** What {@link prepareImage} will do to an image, worked out without touching it. */
|
|
989
|
+
interface ImageFitPlan {
|
|
990
|
+
/** The area of the source that's kept. */
|
|
991
|
+
crop: CropRect;
|
|
992
|
+
/** Output size. */
|
|
993
|
+
width: number;
|
|
994
|
+
height: number;
|
|
995
|
+
/** True when the source already fits the rule, so it can be uploaded as it is. */
|
|
996
|
+
unchanged: boolean;
|
|
997
|
+
}
|
|
998
|
+
/** A rule that can't be met by any image (a mistake in the rule, not the image). */
|
|
999
|
+
declare class ImageRuleError extends Error {
|
|
1000
|
+
constructor(message: string);
|
|
1001
|
+
}
|
|
1002
|
+
/** The image is smaller than the rule's minimum (and `allowUpscale` is off). */
|
|
1003
|
+
declare class ImageTooSmallError extends Error {
|
|
1004
|
+
/** The smallest size the rule accepts. */
|
|
1005
|
+
readonly required: ImageSize;
|
|
1006
|
+
/** The largest area of the right shape the image could give. */
|
|
1007
|
+
readonly actual: ImageSize;
|
|
1008
|
+
constructor(required: ImageSize, actual: ImageSize);
|
|
1009
|
+
}
|
|
1010
|
+
/**
|
|
1011
|
+
* An aspect ratio as width ÷ height: `"100:77"`, `"100/77"`, `[100, 77]` →
|
|
1012
|
+
* 1.2987…; `1.3` → 1.3. Throws {@link ImageRuleError} for anything else.
|
|
1013
|
+
*/
|
|
1014
|
+
declare function parseAspectRatio(value: number | string | readonly [number, number]): number;
|
|
1015
|
+
/** Throws {@link ImageRuleError} when the rule contradicts itself. */
|
|
1016
|
+
declare function checkImageRule(rule: ImageRule): void;
|
|
1017
|
+
/**
|
|
1018
|
+
* Works out what to do to a `source`-sized image to meet `rule`: the centred
|
|
1019
|
+
* crop of the right shape (the largest one), then the output size (scaled
|
|
1020
|
+
* down to the maximum, never below the minimum). Pure: no browser needed.
|
|
1021
|
+
*
|
|
1022
|
+
* Throws {@link ImageTooSmallError} when the crop is below the minimum (or
|
|
1023
|
+
* the exact size) and `allowUpscale` is off, and {@link ImageRuleError} for a
|
|
1024
|
+
* contradictory rule.
|
|
1025
|
+
*
|
|
1026
|
+
* @example
|
|
1027
|
+
* planImageFit({ width: 6000, height: 4000 }, { aspectRatio: "100:77", minWidth: 600, minHeight: 462, maxLongSide: 2000 })
|
|
1028
|
+
* // → crop { sx: 403, sy: 0, sw: 5194, sh: 4000 }, 2000 × 1540
|
|
1029
|
+
*/
|
|
1030
|
+
declare function planImageFit(source: ImageSize, rule: ImageRule): ImageFitPlan;
|
|
1031
|
+
interface PrepareImageOptions {
|
|
1032
|
+
/** Output type. Default: the source's type when it's PNG, JPEG or WebP, else PNG. */
|
|
1033
|
+
type?: "image/png" | "image/jpeg" | "image/webp";
|
|
1034
|
+
/** 0–1, for JPEG and WebP. Default 0.9. */
|
|
1035
|
+
quality?: number;
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Returns the image meeting `rule` ({@link planImageFit}): centre-cropped to
|
|
1039
|
+
* the right shape and scaled in a single draw. An image that already fits is
|
|
1040
|
+
* returned untouched (same bytes). Browser only.
|
|
1041
|
+
*
|
|
1042
|
+
* Throws {@link ImageTooSmallError} (show `required` and `actual` to the
|
|
1043
|
+
* person) or {@link ImageRuleError}; an unreadable file rejects with the
|
|
1044
|
+
* browser's decoding error.
|
|
1045
|
+
*
|
|
1046
|
+
* @example
|
|
1047
|
+
* const ready = await prepareImage(file, { aspectRatio: "100:77", minWidth: 600, minHeight: 462, maxLongSide: 2000 });
|
|
1048
|
+
* await uploadImage(ready, { kind: "product", prefix: "product" });
|
|
1049
|
+
*/
|
|
1050
|
+
declare function prepareImage(file: Blob, rule: ImageRule, options?: PrepareImageOptions): Promise<File>;
|
|
931
1051
|
//#endregion
|
|
932
1052
|
//#region src/core/upload.d.ts
|
|
933
1053
|
interface UploadImageParams {
|
|
934
1054
|
/** What the image is for (sent to Shopwave as the uploader's `contentType`). */
|
|
935
1055
|
kind: UploadKind;
|
|
1056
|
+
/**
|
|
1057
|
+
* The image's role (sent to Shopwave as the uploader's `prefix` header), e.g.
|
|
1058
|
+
* `product_thumbnail` for a product's lead image. Leave it out for images
|
|
1059
|
+
* without a role (merchant logos).
|
|
1060
|
+
*/
|
|
1061
|
+
prefix?: UploadPrefix;
|
|
936
1062
|
/** File name to send when `file` is a Blob without one. Defaults to `File.name`, else `"upload"`. */
|
|
937
1063
|
fileName?: string;
|
|
938
1064
|
}
|
|
@@ -1224,5 +1350,30 @@ interface UserResponse {
|
|
|
1224
1350
|
/** Reads the logged-in user, or `null` when the API returns none. */
|
|
1225
1351
|
declare function fetchUser(options?: RequestOptions): Promise<User | null>;
|
|
1226
1352
|
//#endregion
|
|
1227
|
-
|
|
1353
|
+
//#region src/core/productImages.d.ts
|
|
1354
|
+
/**
|
|
1355
|
+
* Product images, as the live API stores them (merchant 5644, 4 Nov 2026):
|
|
1356
|
+
* - A product's `images` is a list. **Reads return full URLs**
|
|
1357
|
+
* (`http://static.merchantstack.com/images/merchant/<id>/product/<file>`);
|
|
1358
|
+
* **writes take the uploader's file names** ({@link toStoredProductImages};
|
|
1359
|
+
* `saveProduct` does this for you).
|
|
1360
|
+
* - The uploader takes one file per request. With a `prefix` (see
|
|
1361
|
+
* `UploadPrefix`) it names the file `<prefix>_<hash>.<ext>`
|
|
1362
|
+
* (`product_thumbnail_1bdd…41090b.png`); without one, `<hash>.<ext>`. So an
|
|
1363
|
+
* image's role can be read back from its name ({@link productImageRole}).
|
|
1364
|
+
*/
|
|
1365
|
+
/**
|
|
1366
|
+
* The role in an image's file name or URL, from the uploader's `prefix`:
|
|
1367
|
+
* `"…/product_thumbnail_1bdd.png"` → `"product_thumbnail"`. `null` for a name
|
|
1368
|
+
* without one (images uploaded without a prefix, e.g. before prefixes existed).
|
|
1369
|
+
*/
|
|
1370
|
+
declare function productImageRole(value: unknown): UploadPrefix | null;
|
|
1371
|
+
/**
|
|
1372
|
+
* A product's `images` as the API takes them on a save: file names, not the
|
|
1373
|
+
* URLs a read returns. Non-strings, blanks and duplicates are dropped; the
|
|
1374
|
+
* order is kept.
|
|
1375
|
+
*/
|
|
1376
|
+
declare function toStoredProductImages(images: unknown): string[];
|
|
1377
|
+
//#endregion
|
|
1378
|
+
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, ImageFitPlan, ImageRule, ImageRuleError, ImageSize, ImageTooSmallError, LookupDefinition, LookupKind, 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, PrepareImageOptions, 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_LOOKUPS, SHOPWAVE_RESOURCES, SHOPWAVE_UPLOAD, Saved, SessionStatus, ShopwaveApiError, ShopwaveErrorMap, Store, StoreResponse, SubmitEntityArgs, SubmitEntityResponse, SuccessMessage, UPLOAD_KINDS, UPLOAD_PREFIXES, UpdateMerchantOptions, UploadImageParams, UploadKind, UploadMerchantImageOptions, UploadPrefix, UploadedImage, User, UserEmployee, UserResponse, WritableEntityKind, apiDelete, apiGet, apiRequest, apiResponse, apiSend, assertNoApiErrors, authorizationFor, buildBasketReportQuery, buildConsumerMap, checkImageRule, collectConsumerIds, collectProductIds, combineBasketRows, computeBasketSummary, coverCrop, deleteCategory, deleteEmployee, deleteEntity, deleteEntityById, deleteProduct, deletePromotion, deleteStore, fetchCategories, fetchCategory, fetchConsumer, fetchConsumers, fetchEmployee, fetchEmployees, fetchEntityById, fetchMerchant, fetchProduct, fetchProductInstanceTags, fetchProductTags, fetchProducts, fetchProductsMap, fetchPromotion, fetchPromotions, fetchReport, fetchSession, fetchStore, fetchStores, fetchUser, findRepricedInstances, fitImageToSize, formatDateForQuery, getApiErrorMap, getApiErrors, getImageUrl, getMerchantImage, getMerchantImageUrl, imageFileName, isSameInstancePrice, isUploadKind, isUploadPrefix, loginPath, logout, logoutPath, merchantLinksFromForm, merchantLinksToForm, normalizeMerchantLinks, normalizeTagList, parseAspectRatio, parseBasketReportData, planImageFit, prepareImage, productImageRole, readImageSize, rolesById, saveCategory, saveEmployee, saveEntities, saveEntity, saveProduct, savePromotion, saveStore, setMerchantImage, submitEntity, toProductInstancesForSave, toShopwaveApiError, toStoredImageIds, toStoredProductImages, updateMerchant, uploadImage, uploadMerchantImage, validateMerchant, withToken };
|
|
1228
1379
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/core/index.d.ts
CHANGED
|
@@ -676,6 +676,9 @@ declare function fetchEntityById<K extends EntityKind>(kind: K, id: EntityId, pa
|
|
|
676
676
|
* read) so an edited price is sent as a new instance. As a safeguard, a new
|
|
677
677
|
* product (no `id`, e.g. a duplicate) never sends instance ids: an id copied from
|
|
678
678
|
* another product would otherwise point the save at that product's instances.
|
|
679
|
+
*
|
|
680
|
+
* `images` is sent as file names ({@link toStoredProductImages}), so the URLs a
|
|
681
|
+
* read returns can be passed straight back; leaving `images` out keeps them.
|
|
679
682
|
*/
|
|
680
683
|
declare const saveProduct: (product: ProductSaveInput, options?: RequestOptions) => Promise<Saved<Product>>;
|
|
681
684
|
declare const deleteProduct: (id: EntityId, options?: RequestOptions) => Promise<void>;
|
|
@@ -844,20 +847,40 @@ declare const SHOPWAVE_RESOURCES: Readonly<Record<ResourceKind, ResourceDefiniti
|
|
|
844
847
|
type UploadKind = "merchant" | "merchantFeature" | "product" | "user" | "applicationLogo" | "applicationImages";
|
|
845
848
|
/** `UploadKind` → the API's `contentType` value. */
|
|
846
849
|
declare const UPLOAD_KINDS: Readonly<Record<UploadKind, string>>;
|
|
850
|
+
/**
|
|
851
|
+
* The role an image plays, sent to Shopwave as the uploader's `prefix` header.
|
|
852
|
+
* The uploader names the file `<prefix>_<hash>.<ext>`, so the role travels with
|
|
853
|
+
* the file wherever a record stores it (a product's `images`). Live, merchant
|
|
854
|
+
* 5644, 4 Nov 2026: all four values answered 201.
|
|
855
|
+
* - `product`: a product gallery image;
|
|
856
|
+
* - `product_thumbnail`: the product's lead image, shown in lists;
|
|
857
|
+
* - `variant` / `variant_thumbnail`: a variant's own image and its lead image
|
|
858
|
+
* (used by the Connect integrations).
|
|
859
|
+
*
|
|
860
|
+
* Values are the ones Connect's `uploadFileToShopwave` sends.
|
|
861
|
+
*/
|
|
862
|
+
type UploadPrefix = "product" | "product_thumbnail" | "variant" | "variant_thumbnail";
|
|
863
|
+
/** Every `UploadPrefix`, longest first so a name check never takes `product` for `product_thumbnail`. */
|
|
864
|
+
declare const UPLOAD_PREFIXES: ReadonlyArray<UploadPrefix>;
|
|
847
865
|
/** How uploads are addressed (app route and Shopwave uploader). */
|
|
848
866
|
declare const SHOPWAVE_UPLOAD: Readonly<{
|
|
849
|
-
/** App route: `POST /api/<route>` (multipart `file` + `kind`). */
|
|
867
|
+
/** App route: `POST /api/<route>` (multipart `file` + `kind`, optional `prefix`). */
|
|
850
868
|
route: "upload";
|
|
851
869
|
/** Shopwave path: `PUT {apiUrl}/uploader` (multipart `file`). */
|
|
852
870
|
upstream: "uploader";
|
|
853
871
|
/** Header that carries the upload kind upstream. */
|
|
854
872
|
kindHeader: "contentType";
|
|
873
|
+
/** Header that carries the image role upstream (see `UploadPrefix`). */
|
|
874
|
+
prefixHeader: "prefix";
|
|
855
875
|
/** Multipart field name for the file, on both sides. */
|
|
856
876
|
fileField: "file";
|
|
857
877
|
/** Multipart field name for the kind in the app request. */
|
|
858
878
|
kindField: "kind";
|
|
879
|
+
/** Multipart field name for the image role in the app request. */
|
|
880
|
+
prefixField: "prefix";
|
|
859
881
|
}>;
|
|
860
882
|
declare function isUploadKind(value: unknown): value is UploadKind;
|
|
883
|
+
declare function isUploadPrefix(value: unknown): value is UploadPrefix;
|
|
861
884
|
/**
|
|
862
885
|
* Read-only lists that aren't records: the merchant's distinct tags.
|
|
863
886
|
*
|
|
@@ -890,11 +913,12 @@ declare const SHOPWAVE_LOOKUPS: Readonly<Record<LookupKind, LookupDefinition>>;
|
|
|
890
913
|
//#endregion
|
|
891
914
|
//#region src/core/imageFit.d.ts
|
|
892
915
|
/**
|
|
893
|
-
* Browser helpers for getting an image to
|
|
916
|
+
* Browser helpers for getting an image to the right size before upload.
|
|
894
917
|
*
|
|
895
|
-
* Shopwave doesn't resize uploads,
|
|
896
|
-
*
|
|
897
|
-
*
|
|
918
|
+
* Shopwave doesn't resize uploads, so images are scaled and centre-cropped in
|
|
919
|
+
* the browser: to an exact size for the merchant image slots
|
|
920
|
+
* ({@link fitImageToSize}), or to a rule (ratio, minimum, maximum) with
|
|
921
|
+
* {@link prepareImage}, which apps use to give each kind of image its own rule.
|
|
898
922
|
*/
|
|
899
923
|
/** Source rectangle to draw so the image covers `dstWidth × dstHeight` (centre crop, no stretching). */
|
|
900
924
|
interface CropRect {
|
|
@@ -928,11 +952,113 @@ interface FitImageOptions {
|
|
|
928
952
|
* input, with the output type's extension.
|
|
929
953
|
*/
|
|
930
954
|
declare function fitImageToSize(file: Blob, width: number, height: number, options?: FitImageOptions): Promise<File>;
|
|
955
|
+
/**
|
|
956
|
+
* How an image must end up before upload. Every field is optional; give an
|
|
957
|
+
* exact size (`width` + `height`) or an `aspectRatio`, not both.
|
|
958
|
+
*
|
|
959
|
+
* Images are always scaled down first and then centre-cropped (never
|
|
960
|
+
* stretched): the kept area is the largest one with the right shape.
|
|
961
|
+
*
|
|
962
|
+
* @example
|
|
963
|
+
* // "Cropped to 100:77, at least 600 × 462", at most 2000 px on the long side
|
|
964
|
+
* { aspectRatio: "100:77", minWidth: 600, minHeight: 462, maxLongSide: 2000 }
|
|
965
|
+
* // Exactly 600 × 462
|
|
966
|
+
* { width: 600, height: 462 }
|
|
967
|
+
* // Any shape, scaled down to fit 2000 px
|
|
968
|
+
* { maxLongSide: 2000 }
|
|
969
|
+
*/
|
|
970
|
+
interface ImageRule {
|
|
971
|
+
/** Exact output width (needs `height`). */
|
|
972
|
+
width?: number;
|
|
973
|
+
/** Exact output height (needs `width`). */
|
|
974
|
+
height?: number;
|
|
975
|
+
/** Shape to crop to: `1.3`, `"100:77"`, `"100/77"` or `[100, 77]`. */
|
|
976
|
+
aspectRatio?: number | string | readonly [number, number];
|
|
977
|
+
/** Smallest acceptable output; a smaller image is refused (see `allowUpscale`). */
|
|
978
|
+
minWidth?: number;
|
|
979
|
+
minHeight?: number;
|
|
980
|
+
/** Largest output; a bigger image is scaled down to fit. */
|
|
981
|
+
maxWidth?: number;
|
|
982
|
+
maxHeight?: number;
|
|
983
|
+
/** Largest output on the longer side, whichever it is. */
|
|
984
|
+
maxLongSide?: number;
|
|
985
|
+
/** Enlarge a too-small image instead of refusing it. Default false. */
|
|
986
|
+
allowUpscale?: boolean;
|
|
987
|
+
}
|
|
988
|
+
/** What {@link prepareImage} will do to an image, worked out without touching it. */
|
|
989
|
+
interface ImageFitPlan {
|
|
990
|
+
/** The area of the source that's kept. */
|
|
991
|
+
crop: CropRect;
|
|
992
|
+
/** Output size. */
|
|
993
|
+
width: number;
|
|
994
|
+
height: number;
|
|
995
|
+
/** True when the source already fits the rule, so it can be uploaded as it is. */
|
|
996
|
+
unchanged: boolean;
|
|
997
|
+
}
|
|
998
|
+
/** A rule that can't be met by any image (a mistake in the rule, not the image). */
|
|
999
|
+
declare class ImageRuleError extends Error {
|
|
1000
|
+
constructor(message: string);
|
|
1001
|
+
}
|
|
1002
|
+
/** The image is smaller than the rule's minimum (and `allowUpscale` is off). */
|
|
1003
|
+
declare class ImageTooSmallError extends Error {
|
|
1004
|
+
/** The smallest size the rule accepts. */
|
|
1005
|
+
readonly required: ImageSize;
|
|
1006
|
+
/** The largest area of the right shape the image could give. */
|
|
1007
|
+
readonly actual: ImageSize;
|
|
1008
|
+
constructor(required: ImageSize, actual: ImageSize);
|
|
1009
|
+
}
|
|
1010
|
+
/**
|
|
1011
|
+
* An aspect ratio as width ÷ height: `"100:77"`, `"100/77"`, `[100, 77]` →
|
|
1012
|
+
* 1.2987…; `1.3` → 1.3. Throws {@link ImageRuleError} for anything else.
|
|
1013
|
+
*/
|
|
1014
|
+
declare function parseAspectRatio(value: number | string | readonly [number, number]): number;
|
|
1015
|
+
/** Throws {@link ImageRuleError} when the rule contradicts itself. */
|
|
1016
|
+
declare function checkImageRule(rule: ImageRule): void;
|
|
1017
|
+
/**
|
|
1018
|
+
* Works out what to do to a `source`-sized image to meet `rule`: the centred
|
|
1019
|
+
* crop of the right shape (the largest one), then the output size (scaled
|
|
1020
|
+
* down to the maximum, never below the minimum). Pure: no browser needed.
|
|
1021
|
+
*
|
|
1022
|
+
* Throws {@link ImageTooSmallError} when the crop is below the minimum (or
|
|
1023
|
+
* the exact size) and `allowUpscale` is off, and {@link ImageRuleError} for a
|
|
1024
|
+
* contradictory rule.
|
|
1025
|
+
*
|
|
1026
|
+
* @example
|
|
1027
|
+
* planImageFit({ width: 6000, height: 4000 }, { aspectRatio: "100:77", minWidth: 600, minHeight: 462, maxLongSide: 2000 })
|
|
1028
|
+
* // → crop { sx: 403, sy: 0, sw: 5194, sh: 4000 }, 2000 × 1540
|
|
1029
|
+
*/
|
|
1030
|
+
declare function planImageFit(source: ImageSize, rule: ImageRule): ImageFitPlan;
|
|
1031
|
+
interface PrepareImageOptions {
|
|
1032
|
+
/** Output type. Default: the source's type when it's PNG, JPEG or WebP, else PNG. */
|
|
1033
|
+
type?: "image/png" | "image/jpeg" | "image/webp";
|
|
1034
|
+
/** 0–1, for JPEG and WebP. Default 0.9. */
|
|
1035
|
+
quality?: number;
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Returns the image meeting `rule` ({@link planImageFit}): centre-cropped to
|
|
1039
|
+
* the right shape and scaled in a single draw. An image that already fits is
|
|
1040
|
+
* returned untouched (same bytes). Browser only.
|
|
1041
|
+
*
|
|
1042
|
+
* Throws {@link ImageTooSmallError} (show `required` and `actual` to the
|
|
1043
|
+
* person) or {@link ImageRuleError}; an unreadable file rejects with the
|
|
1044
|
+
* browser's decoding error.
|
|
1045
|
+
*
|
|
1046
|
+
* @example
|
|
1047
|
+
* const ready = await prepareImage(file, { aspectRatio: "100:77", minWidth: 600, minHeight: 462, maxLongSide: 2000 });
|
|
1048
|
+
* await uploadImage(ready, { kind: "product", prefix: "product" });
|
|
1049
|
+
*/
|
|
1050
|
+
declare function prepareImage(file: Blob, rule: ImageRule, options?: PrepareImageOptions): Promise<File>;
|
|
931
1051
|
//#endregion
|
|
932
1052
|
//#region src/core/upload.d.ts
|
|
933
1053
|
interface UploadImageParams {
|
|
934
1054
|
/** What the image is for (sent to Shopwave as the uploader's `contentType`). */
|
|
935
1055
|
kind: UploadKind;
|
|
1056
|
+
/**
|
|
1057
|
+
* The image's role (sent to Shopwave as the uploader's `prefix` header), e.g.
|
|
1058
|
+
* `product_thumbnail` for a product's lead image. Leave it out for images
|
|
1059
|
+
* without a role (merchant logos).
|
|
1060
|
+
*/
|
|
1061
|
+
prefix?: UploadPrefix;
|
|
936
1062
|
/** File name to send when `file` is a Blob without one. Defaults to `File.name`, else `"upload"`. */
|
|
937
1063
|
fileName?: string;
|
|
938
1064
|
}
|
|
@@ -1224,5 +1350,30 @@ interface UserResponse {
|
|
|
1224
1350
|
/** Reads the logged-in user, or `null` when the API returns none. */
|
|
1225
1351
|
declare function fetchUser(options?: RequestOptions): Promise<User | null>;
|
|
1226
1352
|
//#endregion
|
|
1227
|
-
|
|
1353
|
+
//#region src/core/productImages.d.ts
|
|
1354
|
+
/**
|
|
1355
|
+
* Product images, as the live API stores them (merchant 5644, 4 Nov 2026):
|
|
1356
|
+
* - A product's `images` is a list. **Reads return full URLs**
|
|
1357
|
+
* (`http://static.merchantstack.com/images/merchant/<id>/product/<file>`);
|
|
1358
|
+
* **writes take the uploader's file names** ({@link toStoredProductImages};
|
|
1359
|
+
* `saveProduct` does this for you).
|
|
1360
|
+
* - The uploader takes one file per request. With a `prefix` (see
|
|
1361
|
+
* `UploadPrefix`) it names the file `<prefix>_<hash>.<ext>`
|
|
1362
|
+
* (`product_thumbnail_1bdd…41090b.png`); without one, `<hash>.<ext>`. So an
|
|
1363
|
+
* image's role can be read back from its name ({@link productImageRole}).
|
|
1364
|
+
*/
|
|
1365
|
+
/**
|
|
1366
|
+
* The role in an image's file name or URL, from the uploader's `prefix`:
|
|
1367
|
+
* `"…/product_thumbnail_1bdd.png"` → `"product_thumbnail"`. `null` for a name
|
|
1368
|
+
* without one (images uploaded without a prefix, e.g. before prefixes existed).
|
|
1369
|
+
*/
|
|
1370
|
+
declare function productImageRole(value: unknown): UploadPrefix | null;
|
|
1371
|
+
/**
|
|
1372
|
+
* A product's `images` as the API takes them on a save: file names, not the
|
|
1373
|
+
* URLs a read returns. Non-strings, blanks and duplicates are dropped; the
|
|
1374
|
+
* order is kept.
|
|
1375
|
+
*/
|
|
1376
|
+
declare function toStoredProductImages(images: unknown): string[];
|
|
1377
|
+
//#endregion
|
|
1378
|
+
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, ImageFitPlan, ImageRule, ImageRuleError, ImageSize, ImageTooSmallError, LookupDefinition, LookupKind, 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, PrepareImageOptions, 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_LOOKUPS, SHOPWAVE_RESOURCES, SHOPWAVE_UPLOAD, Saved, SessionStatus, ShopwaveApiError, ShopwaveErrorMap, Store, StoreResponse, SubmitEntityArgs, SubmitEntityResponse, SuccessMessage, UPLOAD_KINDS, UPLOAD_PREFIXES, UpdateMerchantOptions, UploadImageParams, UploadKind, UploadMerchantImageOptions, UploadPrefix, UploadedImage, User, UserEmployee, UserResponse, WritableEntityKind, apiDelete, apiGet, apiRequest, apiResponse, apiSend, assertNoApiErrors, authorizationFor, buildBasketReportQuery, buildConsumerMap, checkImageRule, collectConsumerIds, collectProductIds, combineBasketRows, computeBasketSummary, coverCrop, deleteCategory, deleteEmployee, deleteEntity, deleteEntityById, deleteProduct, deletePromotion, deleteStore, fetchCategories, fetchCategory, fetchConsumer, fetchConsumers, fetchEmployee, fetchEmployees, fetchEntityById, fetchMerchant, fetchProduct, fetchProductInstanceTags, fetchProductTags, fetchProducts, fetchProductsMap, fetchPromotion, fetchPromotions, fetchReport, fetchSession, fetchStore, fetchStores, fetchUser, findRepricedInstances, fitImageToSize, formatDateForQuery, getApiErrorMap, getApiErrors, getImageUrl, getMerchantImage, getMerchantImageUrl, imageFileName, isSameInstancePrice, isUploadKind, isUploadPrefix, loginPath, logout, logoutPath, merchantLinksFromForm, merchantLinksToForm, normalizeMerchantLinks, normalizeTagList, parseAspectRatio, parseBasketReportData, planImageFit, prepareImage, productImageRole, readImageSize, rolesById, saveCategory, saveEmployee, saveEntities, saveEntity, saveProduct, savePromotion, saveStore, setMerchantImage, submitEntity, toProductInstancesForSave, toShopwaveApiError, toStoredImageIds, toStoredProductImages, updateMerchant, uploadImage, uploadMerchantImage, validateMerchant, withToken };
|
|
1228
1379
|
//# sourceMappingURL=index.d.ts.map
|