react-shopwave-connect 0.4.3 → 0.4.4

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.
@@ -274,6 +274,74 @@ function safeEqual(a, b) {
274
274
  return diff === 0;
275
275
  }
276
276
 
277
+ //#endregion
278
+ //#region src/core/resources.ts
279
+ /**
280
+ * - merchant: `GET /merchant`; `POST /merchant` with `{ merchant: { id, … } }`
281
+ * updates it (without an `id` the API would create a second merchant, so the
282
+ * route requires one).
283
+ * - user: `GET /user` (read-only here; the API's `POST /user` invites users and
284
+ * needs the admin scope).
285
+ */
286
+ const SHOPWAVE_RESOURCES = Object.freeze({
287
+ merchant: {
288
+ route: "merchant",
289
+ key: "merchant",
290
+ upstream: "merchant",
291
+ writable: true
292
+ },
293
+ user: {
294
+ route: "user",
295
+ key: "user",
296
+ upstream: "user",
297
+ writable: false
298
+ }
299
+ });
300
+ /** `UploadKind` → the API's `contentType` value. */
301
+ const UPLOAD_KINDS = Object.freeze({
302
+ merchant: "merchant",
303
+ merchantFeature: "merchantFeature",
304
+ product: "product",
305
+ user: "user",
306
+ applicationLogo: "applicaionLogo",
307
+ applicationImages: "applicaionImages"
308
+ });
309
+ /** Every `UploadPrefix`, longest first so a name check never takes `product` for `product_thumbnail`. */
310
+ const UPLOAD_PREFIXES = Object.freeze([
311
+ "product_thumbnail",
312
+ "variant_thumbnail",
313
+ "product",
314
+ "variant"
315
+ ]);
316
+ /** How uploads are addressed (app route and Shopwave uploader). */
317
+ const SHOPWAVE_UPLOAD = Object.freeze({
318
+ route: "upload",
319
+ upstream: "uploader",
320
+ kindHeader: "contentType",
321
+ prefixHeader: "prefix",
322
+ fileField: "file",
323
+ kindField: "kind",
324
+ prefixField: "prefix"
325
+ });
326
+ function isUploadKind(value) {
327
+ return typeof value === "string" && Object.prototype.hasOwnProperty.call(UPLOAD_KINDS, value);
328
+ }
329
+ function isUploadPrefix(value) {
330
+ return typeof value === "string" && UPLOAD_PREFIXES.includes(value);
331
+ }
332
+ const SHOPWAVE_LOOKUPS = Object.freeze({
333
+ productTags: {
334
+ route: "products/tags",
335
+ key: "tags",
336
+ upstream: "product/tags"
337
+ },
338
+ productInstanceTags: {
339
+ route: "products/instance-tags",
340
+ key: "tags",
341
+ upstream: "product/instance/tags"
342
+ }
343
+ });
344
+
277
345
  //#endregion
278
346
  //#region src/core/entities.ts
279
347
  /**
@@ -350,62 +418,6 @@ const SHOPWAVE_ENTITIES = Object.freeze({
350
418
  }
351
419
  });
352
420
 
353
- //#endregion
354
- //#region src/core/resources.ts
355
- /**
356
- * - merchant: `GET /merchant`; `POST /merchant` with `{ merchant: { id, … } }`
357
- * updates it (without an `id` the API would create a second merchant, so the
358
- * route requires one).
359
- * - user: `GET /user` (read-only here; the API's `POST /user` invites users and
360
- * needs the admin scope).
361
- */
362
- const SHOPWAVE_RESOURCES = Object.freeze({
363
- merchant: {
364
- route: "merchant",
365
- key: "merchant",
366
- upstream: "merchant",
367
- writable: true
368
- },
369
- user: {
370
- route: "user",
371
- key: "user",
372
- upstream: "user",
373
- writable: false
374
- }
375
- });
376
- /** `UploadKind` → the API's `contentType` value. */
377
- const UPLOAD_KINDS = Object.freeze({
378
- merchant: "merchant",
379
- merchantFeature: "merchantFeature",
380
- product: "product",
381
- user: "user",
382
- applicationLogo: "applicaionLogo",
383
- applicationImages: "applicaionImages"
384
- });
385
- /** How uploads are addressed (app route and Shopwave uploader). */
386
- const SHOPWAVE_UPLOAD = Object.freeze({
387
- route: "upload",
388
- upstream: "uploader",
389
- kindHeader: "contentType",
390
- fileField: "file",
391
- kindField: "kind"
392
- });
393
- function isUploadKind(value) {
394
- return typeof value === "string" && Object.prototype.hasOwnProperty.call(UPLOAD_KINDS, value);
395
- }
396
- const SHOPWAVE_LOOKUPS = Object.freeze({
397
- productTags: {
398
- route: "products/tags",
399
- key: "tags",
400
- upstream: "product/tags"
401
- },
402
- productInstanceTags: {
403
- route: "products/instance-tags",
404
- key: "tags",
405
- upstream: "product/instance/tags"
406
- }
407
- });
408
-
409
421
  //#endregion
410
422
  //#region src/server/api.ts
411
423
  /**
@@ -734,6 +746,8 @@ function createShopwaveApiHandlers(config) {
734
746
  if (!file || typeof file === "string" || file.size === 0) return jsonError(400, "invalid_body", `Missing "${SHOPWAVE_UPLOAD.fileField}"`);
735
747
  const kind = form.get(SHOPWAVE_UPLOAD.kindField);
736
748
  if (!isUploadKind(kind)) return jsonError(400, "invalid_body", `"${SHOPWAVE_UPLOAD.kindField}" must be one of ${Object.keys(UPLOAD_KINDS).join(", ")}`);
749
+ const prefix = form.get(SHOPWAVE_UPLOAD.prefixField);
750
+ if (prefix !== null && !isUploadPrefix(prefix)) return jsonError(400, "invalid_body", `"${SHOPWAVE_UPLOAD.prefixField}" must be one of ${UPLOAD_PREFIXES.join(", ")}`);
737
751
  if (file.size > maxBytes) return jsonError(413, "too_large", `The file is larger than ${maxBytes} bytes`);
738
752
  if (!acceptsType(file.type || "", accept)) return jsonError(415, "unsupported_type", `Files of type "${file.type || "unknown"}" aren't accepted`);
739
753
  const upstreamForm = new FormData();
@@ -741,7 +755,10 @@ function createShopwaveApiHandlers(config) {
741
755
  return forward(request, {
742
756
  method: "PUT",
743
757
  path: SHOPWAVE_UPLOAD.upstream,
744
- headers: { [SHOPWAVE_UPLOAD.kindHeader]: UPLOAD_KINDS[kind] },
758
+ headers: {
759
+ [SHOPWAVE_UPLOAD.kindHeader]: UPLOAD_KINDS[kind],
760
+ ...prefix !== null ? { [SHOPWAVE_UPLOAD.prefixHeader]: prefix } : {}
761
+ },
745
762
  formData: upstreamForm,
746
763
  forwardExtras: false
747
764
  });
@@ -1216,6 +1233,7 @@ exports.SHOPWAVE_LOOKUPS = SHOPWAVE_LOOKUPS;
1216
1233
  exports.SHOPWAVE_RESOURCES = SHOPWAVE_RESOURCES;
1217
1234
  exports.ShopwaveAuthError = ShopwaveAuthError;
1218
1235
  exports.UPLOAD_KINDS = UPLOAD_KINDS;
1236
+ exports.UPLOAD_PREFIXES = UPLOAD_PREFIXES;
1219
1237
  exports.authorizationHeader = authorizationHeader;
1220
1238
  exports.createShopwaveApi = createShopwaveApi;
1221
1239
  exports.createShopwaveAuth = createShopwaveAuth;