merchi_sdk_js 0.5.2 → 0.5.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "merchi_sdk_js",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "type": "module",
5
5
  "main": "src/merchi.js",
6
6
  "module": "src/merchi.js",
package/src/job.js CHANGED
@@ -51,6 +51,7 @@ export function Job() {
51
51
  addPropertyTo(this, 'deadline');
52
52
  addPropertyTo(this, 'updated');
53
53
  addPropertyTo(this, 'dateLastActioned');
54
+ addPropertyTo(this, 'dateFirstActioned');
54
55
  addPropertyTo(this, 'deductionDate');
55
56
  addPropertyTo(this, 'preDraftCommentsCount');
56
57
  addPropertyTo(this, 'clientFiles', MerchiFile);
package/src/merchi.js CHANGED
@@ -1,3 +1,4 @@
1
+ import axios from 'axios';
1
2
  import { isBrowser } from 'browser-or-node';
2
3
  import { generateUUID } from './uuid.js';
3
4
  import { isNull, isUndefined, isUndefinedOrNull, id,
@@ -88,6 +89,12 @@ import { AgentSkillApproval, AgentSkillApprovals } from './agent_skill_approval.
88
89
  import { DomainChatSettings, DomainChatSettingsList } from './domain_chat_settings.js';
89
90
  import { SupportConversation, SupportConversations } from './support_conversation.js';
90
91
  import { SupportMessage, SupportMessages } from './support_message.js';
92
+ import {
93
+ ProductReview,
94
+ ProductReviews,
95
+ normalizeProductReviewApiJson,
96
+ wireProductReviewCreateBody,
97
+ } from './product_review.js';
91
98
 
92
99
  export function merchi(backendUri, websocketUri) {
93
100
  getGlobal().merchiJsonpHandlers = {};
@@ -866,6 +873,98 @@ export function merchi(backendUri, websocketUri) {
866
873
  request.send();
867
874
  }
868
875
 
876
+ function productReviewsApiRoot() {
877
+ var base = getGlobal().merchiBackendUri;
878
+ if (!base.endsWith('/')) {
879
+ base += '/';
880
+ }
881
+ return base + 'v6';
882
+ }
883
+
884
+ function productReviewsSessionSuffix() {
885
+ if (getGlobal().currentSession &&
886
+ getGlobal().currentSession.token()) {
887
+ return '?session_token=' + encodeURIComponent(
888
+ getGlobal().currentSession.token());
889
+ }
890
+ return '';
891
+ }
892
+
893
+ /**
894
+ * List product reviews (domain manager/admin). ``success`` receives
895
+ * ``{ productReviews: ... }`` — same keys as the API, but each row is a
896
+ * ``ProductReview`` model instance with ``job`` / ``product`` / ``domain``.
897
+ */
898
+ function listProductReviews(productId, success, error) {
899
+ var url = productReviewsApiRoot() + '/products/' + productId +
900
+ '/reviews/' + productReviewsSessionSuffix();
901
+ axios.get(url)
902
+ .then(function (res) {
903
+ var reviews = new ProductReviews().fromProductListResponse(
904
+ res.data);
905
+ success(Object.assign({}, res.data, {productReviews: reviews}));
906
+ })
907
+ .catch(function (err) {
908
+ error(err.response ? err.response.data : err);
909
+ });
910
+ }
911
+
912
+ /**
913
+ * Create a product review (buyer, JSON body). Send ``jobId`` or ``job: { id }``
914
+ * (completed job whose catalog product matches ``productId`` after clone
915
+ * resolution), plus ``rating`` and optional ``title`` / ``content``.
916
+ * ``success`` receives ``{ productReview }`` as a ``ProductReview`` model.
917
+ */
918
+ function createProductReview(productId, data, success, error) {
919
+ var url = productReviewsApiRoot() + '/products/' + productId +
920
+ '/reviews/' + productReviewsSessionSuffix();
921
+ axios.post(url, wireProductReviewCreateBody(data), {
922
+ headers: {'Content-Type': 'application/json'},
923
+ })
924
+ .then(function (res) {
925
+ var pr = fromJson(
926
+ new ProductReview(),
927
+ normalizeProductReviewApiJson(res.data.productReview),
928
+ {makesDirty: false});
929
+ success(Object.assign({}, res.data, {productReview: pr}));
930
+ })
931
+ .catch(function (err) {
932
+ error(err.response ? err.response.data : err);
933
+ });
934
+ }
935
+
936
+ /**
937
+ * Patch a review (``formFields`` plain object: status, rejectionReason,
938
+ * rating, title, content — sent as multipart form data).
939
+ * ``success`` receives ``{ productReview }`` as a model when present.
940
+ */
941
+ function patchProductReview(reviewId, formFields, success, error) {
942
+ var url = productReviewsApiRoot() + '/product-reviews/' + reviewId +
943
+ '/' + productReviewsSessionSuffix();
944
+ var fd = new FormData();
945
+ Object.keys(formFields || {}).forEach(function (k) {
946
+ var v = formFields[k];
947
+ if (v !== undefined && v !== null) {
948
+ fd.append(k, String(v));
949
+ }
950
+ });
951
+ axios.patch(url, fd)
952
+ .then(function (res) {
953
+ if (!res.data || !res.data.productReview) {
954
+ success(res.data);
955
+ return;
956
+ }
957
+ var pr = fromJson(
958
+ new ProductReview(),
959
+ normalizeProductReviewApiJson(res.data.productReview),
960
+ {makesDirty: false});
961
+ success(Object.assign({}, res.data, {productReview: pr}));
962
+ })
963
+ .catch(function (err) {
964
+ error(err.response ? err.response.data : err);
965
+ });
966
+ }
967
+
869
968
  function getProductShipmentOptions(
870
969
  productId, quantity, address, success, error) {
871
970
  var request = new Request(),
@@ -1025,6 +1124,10 @@ export function merchi(backendUri, websocketUri) {
1025
1124
  'supportConversations': new SupportConversations(),
1026
1125
  'SupportMessage': SupportMessage,
1027
1126
  'supportMessages': new SupportMessages(),
1127
+ 'ProductReview': ProductReview,
1128
+ 'productReviews': new ProductReviews(),
1129
+ 'normalizeProductReviewApiJson': normalizeProductReviewApiJson,
1130
+ 'wireProductReviewCreateBody': wireProductReviewCreateBody,
1028
1131
  'SubscriptionPlan': SubscriptionPlan,
1029
1132
  'subscriptionPlans': new SubscriptionPlans(),
1030
1133
  'VariationField': VariationField,
@@ -1103,5 +1206,8 @@ export function merchi(backendUri, websocketUri) {
1103
1206
  'productTypes': productTypes,
1104
1207
  'productTypesInts': productTypesInts,
1105
1208
  'productTypesSeller': productTypesSeller,
1106
- 'getProductShipmentOptions': getProductShipmentOptions};
1209
+ 'getProductShipmentOptions': getProductShipmentOptions,
1210
+ 'listProductReviews': listProductReviews,
1211
+ 'createProductReview': createProductReview,
1212
+ 'patchProductReview': patchProductReview};
1107
1213
  }
package/src/model.js CHANGED
@@ -335,6 +335,10 @@ export function getList(resource, success, error, parameters, withUpdates) {
335
335
  if (parameters.asRole) {
336
336
  request.query().add('as_role', JSON.stringify(parameters.asRole));
337
337
  }
338
+ if (notEmpty(parameters.isJobManager)) {
339
+ request.query().add('is_job_manager',
340
+ JSON.stringify(parameters.isJobManager));
341
+ }
338
342
  if (parameters.groupBuyOnly) {
339
343
  request.query().add('group_buy_only',
340
344
  JSON.stringify(parameters.groupBuyOnly));
@@ -0,0 +1,96 @@
1
+ import { generateUUID } from './uuid.js';
2
+ import { addPropertyTo, fromJson } from './model.js';
3
+ import { Domain } from './domain.js';
4
+ import { Job } from './job.js';
5
+ import { Product } from './product.js';
6
+
7
+ /**
8
+ * Map flat API fields (jobId, productId, domainId) onto job / product / domain
9
+ * before ``fromJson``.
10
+ */
11
+ export function normalizeProductReviewApiJson(json) {
12
+ if (json === null || json === undefined || typeof json !== 'object') {
13
+ return json;
14
+ }
15
+ var row = Object.assign({}, json);
16
+ if (row.jobId !== undefined && row.job === undefined) {
17
+ if (row.jobId != null) {
18
+ row.job = {id: row.jobId};
19
+ }
20
+ delete row.jobId;
21
+ }
22
+ if (row.productId !== undefined && row.product === undefined) {
23
+ if (row.productId != null) {
24
+ row.product = {id: row.productId};
25
+ }
26
+ delete row.productId;
27
+ }
28
+ if (row.domainId !== undefined && row.domain === undefined) {
29
+ if (row.domainId != null) {
30
+ row.domain = {id: row.domainId};
31
+ }
32
+ delete row.domainId;
33
+ }
34
+ return row;
35
+ }
36
+
37
+ /**
38
+ * Turn create payload ``{ job: { id }, rating, ... }`` into API JSON with ``jobId``.
39
+ * Pass-through if ``jobId`` is already set.
40
+ */
41
+ export function wireProductReviewCreateBody(data) {
42
+ if (!data || typeof data !== 'object') {
43
+ return data;
44
+ }
45
+ var body = Object.assign({}, data);
46
+ if (body.job && body.job.id != null && body.jobId === undefined) {
47
+ body.jobId = body.job.id;
48
+ delete body.job;
49
+ }
50
+ return body;
51
+ }
52
+
53
+ export function ProductReview() {
54
+ this.resource = '/product-reviews';
55
+ this.json = 'productReview';
56
+ this.temporaryId = generateUUID();
57
+
58
+ addPropertyTo(this, 'id');
59
+ addPropertyTo(this, 'product', Product);
60
+ addPropertyTo(this, 'domain', Domain);
61
+ addPropertyTo(this, 'authorUserId');
62
+ addPropertyTo(this, 'authorName');
63
+ addPropertyTo(this, 'job', Job);
64
+ addPropertyTo(this, 'rating');
65
+ addPropertyTo(this, 'title');
66
+ addPropertyTo(this, 'content');
67
+ addPropertyTo(this, 'status');
68
+ addPropertyTo(this, 'purchaseInvoiceId');
69
+ addPropertyTo(this, 'submittedAt');
70
+ addPropertyTo(this, 'updatedAt');
71
+ addPropertyTo(this, 'rejectionReason');
72
+ }
73
+
74
+ export function ProductReviews() {
75
+ this.json = 'productReviews';
76
+ this.single = ProductReview;
77
+
78
+ /**
79
+ * @param {object} data - API body with ``productReviews`` array
80
+ * @param {object} [options] - passed to ``fromJson`` (e.g. ``{makesDirty: false}``)
81
+ * @returns {ProductReview[]}
82
+ */
83
+ this.fromProductListResponse = function (data, options) {
84
+ var raw = (data && data.productReviews) ? data.productReviews : [];
85
+ var self = this;
86
+ var defaults = {makesDirty: false};
87
+ var opts = Object.assign({}, defaults, options);
88
+ return raw.map(function (row) {
89
+ return fromJson(
90
+ new self.single(),
91
+ normalizeProductReviewApiJson(row),
92
+ opts
93
+ );
94
+ });
95
+ };
96
+ }