@peabody-soft/mbs-model-ts 1.11.0 → 1.13.0

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.
Files changed (44) hide show
  1. package/dist/Constants.d.ts +1 -0
  2. package/dist/Constants.js +3 -0
  3. package/dist/Exceptions.d.ts +5 -0
  4. package/dist/Exceptions.js +16 -2
  5. package/dist/Ids.d.ts +1 -0
  6. package/dist/Ids.js +5 -3
  7. package/dist/InMemoryLock.d.ts +5 -0
  8. package/dist/InMemoryLock.js +20 -0
  9. package/dist/Lock.d.ts +3 -0
  10. package/dist/Lock.js +1 -0
  11. package/dist/Message.d.ts +1 -5
  12. package/dist/Message.js +2 -12
  13. package/dist/Model.d.ts +17 -4
  14. package/dist/Model.js +304 -113
  15. package/dist/Order.d.ts +2 -2
  16. package/dist/Order.js +4 -4
  17. package/dist/ProtoMap.d.ts +13 -4
  18. package/dist/ProtoMap.js +139 -71
  19. package/dist/Service.d.ts +3 -4
  20. package/dist/ServiceProxy.d.ts +3 -4
  21. package/dist/ServiceProxy.js +4 -6
  22. package/dist/SyncCache.d.ts +6 -2
  23. package/dist/SyncCache.js +83 -44
  24. package/dist/SyncKeys.js +3 -2
  25. package/dist/generated/BusinessSyncInRequest.d.ts +30 -16
  26. package/dist/generated/BusinessSyncInRequest.js +9 -1
  27. package/dist/generated/BusinessSyncInResponse.d.ts +9 -6
  28. package/dist/generated/Constants.d.ts +2 -12
  29. package/dist/generated/Constants.js +2 -12
  30. package/dist/generated/Message.d.ts +5 -16
  31. package/dist/generated/Message.js +8 -22
  32. package/dist/generated/Party.d.ts +52 -0
  33. package/dist/generated/Party.js +68 -0
  34. package/dist/generated/PartyPreferencesPayload.d.ts +2 -1
  35. package/dist/generated/ProfileSyncOutRequest.d.ts +2 -0
  36. package/dist/generated/ProfileSyncOutResponse.d.ts +2 -2
  37. package/dist/generated/SalesOrderPayload.d.ts +9 -8
  38. package/dist/generated/User.d.ts +3 -1
  39. package/dist/generated/UserRequest.d.ts +52 -0
  40. package/dist/generated/{CreateUserRequest.js → UserRequest.js} +11 -11
  41. package/dist/index.d.ts +4 -2
  42. package/dist/index.js +7 -5
  43. package/package.json +2 -2
  44. package/dist/generated/CreateUserRequest.d.ts +0 -43
package/dist/SyncCache.js CHANGED
@@ -1,9 +1,12 @@
1
1
  import { Constants as proto_Constants } from "./generated/Constants";
2
+ import { StoreCorruptException } from "./Exceptions";
2
3
  import Ids from "./Ids";
3
4
  import * as ProtoMap from "./ProtoMap";
4
5
  import * as SyncKeys from "./SyncKeys";
5
6
  // What the server has already sent, so the next call can ask only for what changed. A read cache:
6
- // everything in it came from a response, so dropping a container costs one refetch.
7
+ // everything in it came from a response, so dropping a container costs one refetch. The exception is
8
+ // the id of a sign up that is under way (readUserId), which the client makes and deletes once the
9
+ // server has answered.
7
10
  // It does not write through or sync. The caller calls the Service, does the paging, and chooses
8
11
  // which writes are reads. It holds only wire data, which ProtoMap reads. See SYNC LAYER in
9
12
  // ../Prompt.txt.
@@ -14,7 +17,8 @@ import * as SyncKeys from "./SyncKeys";
14
17
  // readOrders and readPartyPreferences leave them out.
15
18
  // - A cursor is a blob per entity type (its eTag is the cursor). It is not derived from the
16
19
  // entities, because tombstones and this client's own changes would move it. It rises only with
17
- // a page of a read, in that page's batch, and the store keeps the greater.
20
+ // a page of a read, in that page's batch, and the store keeps the greater. Only
21
+ // resetProfileCursors lowers one.
18
22
  export default class SyncCache {
19
23
  constructor(_database) {
20
24
  this._database = _database;
@@ -24,11 +28,11 @@ export default class SyncCache {
24
28
  // written. Tombstones are included as sent: a deleted entity carries what it was, or only its header
25
29
  // for an item. Code that builds on this must leave tombstones out, except for the order of a message.
26
30
  async readBusiness(containerName) {
27
- return ProtoMap.businessResponseFromBlobs(await this.readAll(containerName));
31
+ return this.readDecoded(containerName, ProtoMap.businessResponseFromBlobs);
28
32
  }
29
33
  // The cursors the next read sends: the highest update number of each entity type that a page of a
30
- // read brought, tombstones included, or zero for a type none has brought. Only a read moves them, so
31
- // the next read brings back what this client pushed.
34
+ // read brought, tombstones included, or zero for a type none has brought. A page is a response to a
35
+ // read, or the messages of a response to a sync in.
32
36
  async readBusinessCursors(containerName) {
33
37
  return this.readCursors(containerName, SyncKeys.BUSINESS_SYNC_IN);
34
38
  }
@@ -51,36 +55,40 @@ export default class SyncCache {
51
55
  // The tombstones cached for one business, as a response, each as stored and as the server sent it.
52
56
  // Null when there are none. The entities a deleted entity owned are tombstones too.
53
57
  async readDeletedBusiness(containerName) {
54
- return ProtoMap.deletedBusinessResponseFromBlobs(await this.readAll(containerName));
58
+ return this.readDecoded(containerName, ProtoMap.deletedBusinessResponseFromBlobs);
55
59
  }
56
60
  // The same for one profile: the customer, the businesses they may reach, and the link to each.
57
61
  async readProfile(containerName) {
58
- return ProtoMap.profileResponseFromBlobs(await this.readAll(containerName));
62
+ return this.readDecoded(containerName, ProtoMap.profileResponseFromBlobs);
59
63
  }
60
64
  // The tombstones of a profile, as readDeletedBusiness returns those of a business.
61
65
  async readDeletedProfile(containerName) {
62
- return ProtoMap.deletedProfileResponseFromBlobs(await this.readAll(containerName));
66
+ return this.readDecoded(containerName, ProtoMap.deletedProfileResponseFromBlobs);
63
67
  }
64
68
  async readProfileCursors(containerName) {
65
69
  return this.readCursors(containerName, SyncKeys.PROFILE_SYNC_IN);
66
70
  }
67
- // One page of a profile read - see writeBusiness
71
+ // Deletes the profile cursors, so the next read asks for the whole profile. Use it when the
72
+ // container lacks an entity that its cursors are past, which no read would send again. The
73
+ // entities, tokens and saved user id stay, and a repeated entity changes nothing.
74
+ async resetProfileCursors(containerName) {
75
+ await this.write(containerName, {
76
+ blobs: NO_BLOBS,
77
+ deletedIds: SyncKeys.PROFILE_SYNC_IN.map((key) => Ids.getSyncCursorBlobId(key)),
78
+ });
79
+ }
80
+ // One page of a profile read, or the answer to a sign up or an update, which is the first page of
81
+ // one. See writeBusiness.
68
82
  async writeProfile(containerName, response) {
69
83
  return this.writeRead(containerName, ProtoMap.profileResponseToCacheWrite(response), SyncKeys.PROFILE_SYNC_IN, (cursors) => ProtoMap.raiseProfileCursors(cursors, response));
70
84
  }
71
- // Stores the response to a call that is not a read (a sign up, an update). It holds a change this
72
- // client made, so it moves no cursor and the next read brings it back. Otherwise the same as
73
- // writeProfile.
74
- async storeProfile(containerName, response) {
75
- return this.write(containerName, ProtoMap.profileResponseToCacheWrite(response));
76
- }
77
85
  // The credentials that sign calls about this container (the user token in a profile container, the
78
86
  // link token in a business one), or null before the server issues either.
79
87
  async readAuthTokens(containerName) {
80
88
  const blob = await (await this.getContainer(containerName)).read(Ids.AUTH_TOKENS_BLOB_ID);
81
89
  if (blob === null)
82
90
  return null;
83
- return ProtoMap.authTokensFromBytes(blob.bytes);
91
+ return this.decode(containerName, () => ProtoMap.authTokensFromBytes(blob.bytes));
84
92
  }
85
93
  // Written without comparison, unlike everything else here: a reissued token is not a later version of
86
94
  // the old one, so the last one written wins. Stores only what this server issued - see
@@ -88,23 +96,40 @@ export default class SyncCache {
88
96
  async writeAuthTokens(containerName, authTokens) {
89
97
  await this.writeBlobs(containerName, [ProtoMap.authTokensToBlob(authTokens)]);
90
98
  }
99
+ // The id that a sign up in this profile container creates the user under, or null when none is
100
+ // saved. See Model.createUser. It is not an entity, so no read of a profile returns it.
101
+ async readUserId(containerName) {
102
+ const blob = await (await this.getContainer(containerName)).read(Ids.USER_ID_BLOB_ID);
103
+ if (blob === null)
104
+ return null;
105
+ return this.decode(containerName, () => ProtoMap.userIdFromBytes(blob.bytes));
106
+ }
107
+ // Saves the id before the sign up is sent, and it stays until deleteUserId deletes it. It replaces
108
+ // an id saved before.
109
+ async writeUserId(containerName, userId) {
110
+ await this.writeBlobs(containerName, [ProtoMap.userIdToBlob(userId)]);
111
+ }
112
+ // Deletes the saved id, if there is one, once the sign up is over.
113
+ async deleteUserId(containerName) {
114
+ await this.write(containerName, { blobs: NO_BLOBS, deletedIds: [Ids.USER_ID_BLOB_ID] });
115
+ }
91
116
  // The open orders of the caller whose responses were written here, because a server sends a caller
92
117
  // only their own messages. An open order is one the business has not completed. Completed orders
93
118
  // are deleted messages, which readDeletedOrders returns. Nothing here records which caller that was
94
119
  // or detects a change of caller. See THE MESSAGES OF A BUSINESS ARE NOT PUBLIC.
95
120
  async readOrders(containerName) {
96
- return ProtoMap.orderMessagesFromBlobs(await this.readAll(containerName));
121
+ return this.readDecoded(containerName, ProtoMap.orderMessagesFromBlobs);
97
122
  }
98
123
  // The orders the business has completed, by fulfilling or cancelling. The merchant app completes an
99
124
  // order by deleting its message, so each is a tombstone. A server sends these whole, because the
100
125
  // customer is shown the order afterwards. Each is returned as stored and as sent. A tombstone with
101
126
  // no order in it is not included.
102
127
  async readDeletedOrders(containerName) {
103
- return ProtoMap.deletedOrderMessagesFromBlobs(await this.readAll(containerName));
128
+ return this.readDecoded(containerName, ProtoMap.deletedOrderMessagesFromBlobs);
104
129
  }
105
- // The cursor a push sends: how far reads of this container have got with this customer's messages,
106
- // party preferences and orders alike. It is the cursor the next read sends. What a push stores here
107
- // does not move it, so a change made during the push is not skipped.
130
+ // The cursor a sync in sends: how far reads of this container have got with this customer's
131
+ // messages, party preferences and orders alike. It is the cursor the next read sends. The answer
132
+ // to a sync in is a sync out from it, so what that stores moves it, as a read does.
108
133
  async readMessageUpdateNumber(containerName) {
109
134
  return (await this.readBusinessCursors(containerName)).getUpdateNumber(proto_Constants.MESSAGE_ENTITY_TYPE_ID);
110
135
  }
@@ -117,7 +142,7 @@ export default class SyncCache {
117
142
  // per business, so two would mean two callers share the container, the open question described
118
143
  // for readOrders.
119
144
  async readPartyPreferences(containerName) {
120
- return ProtoMap.partyPreferencesMessageFromBlobs(await this.readAll(containerName));
145
+ return this.readDecoded(containerName, ProtoMap.partyPreferencesMessageFromBlobs);
121
146
  }
122
147
  async writePartyPreferences(containerName, partyPreferences) {
123
148
  return this.writeOwnMessage(containerName, partyPreferences, ProtoMap.partyPreferencesToBlob);
@@ -133,12 +158,12 @@ export default class SyncCache {
133
158
  this._containers.delete(containerName);
134
159
  await this._database.deleteContainer(containerName);
135
160
  }
136
- // Deletes the party preferences message this container holds, and returns zero when there is none.
137
- // It is the only delete that no tombstone caused. A cart written before anybody signed in is handed
138
- // over to the container named for the membership. The copy left behind would be read by the next
139
- // anonymous visitor and the next customer to sign in - see Model.businessSyncIn. A caller deletes
140
- // nothing else from a container: it all came off the wire, and anything the server has not
141
- // reported as deleted stays.
161
+ // Deletes the party preferences message this container stores, and returns zero when there is none.
162
+ // It is the only delete of an entity that no tombstone caused. A cart written before anybody signed
163
+ // in is handed over to the container named for the membership. The copy left behind would be read
164
+ // by the next anonymous visitor and the next customer to sign in - see Model.businessSyncIn. A
165
+ // caller deletes no other entity from a container: it all came off the wire, and anything the
166
+ // server has not reported as deleted stays.
142
167
  async deletePartyPreferences(containerName) {
143
168
  const partyPreferences = await this.readPartyPreferences(containerName);
144
169
  if (partyPreferences === null)
@@ -148,25 +173,39 @@ export default class SyncCache {
148
173
  deletedIds: [ProtoMap.getMessageId(partyPreferences)],
149
174
  });
150
175
  }
151
- // Stores the messages a sync in response carried, in one batch, so the cache cannot hold a pushed
152
- // order without the party preferences message it emptied. Tombstones are included, as for any
153
- // entity array off the wire. This stores a push's own messages once the server has echoed them with
154
- // real update numbers. It checks no payload type, unlike writeOrder and writePartyPreferences.
155
- // Those take a message from the caller, where storing an order as party preferences is a mistake
156
- // worth catching. Here the response is taken as correct. It moves no cursor, because this client
157
- // made the change and the next read brings the same messages back.
176
+ // Stores the messages a sync in response carried, in one batch with the message cursor that they
177
+ // raise, as writeBusiness stores a page of a read: the response is a sync out of the customer's
178
+ // messages, made after the write. So the cache cannot store an order without the party
179
+ // preferences message it emptied, and a cursor cannot get ahead of the messages it describes.
180
+ // Tombstones are included, as for any entity array off the wire. It checks no payload type, unlike
181
+ // writeOrder and writePartyPreferences. Those take a message from the caller, where storing an
182
+ // order as party preferences is a mistake worth catching. Here the response is taken as correct.
183
+ // Returns how many messages it changed, as writeBusiness does.
158
184
  async writeMessages(containerName, messages) {
159
- return this.write(containerName, ProtoMap.messagesToCacheWrite(messages));
185
+ return this.writeRead(containerName, ProtoMap.messagesToCacheWrite(messages), SyncKeys.BUSINESS_SYNC_IN, (cursors) => ProtoMap.raiseMessageCursors(cursors, messages));
186
+ }
187
+ // Reads every blob of the container and decodes them with decoder. Throws StoreCorruptException
188
+ // if decoder throws.
189
+ async readDecoded(containerName, decoder) {
190
+ const blobs = await (await this.getContainer(containerName)).readAll();
191
+ return this.decode(containerName, () => decoder(blobs));
160
192
  }
161
- async readAll(containerName) {
162
- return (await this.getContainer(containerName)).readAll();
193
+ // Anything thrown while reading what the store holds means the store holds something unreadable,
194
+ // since the same bytes decoded when they were written.
195
+ decode(containerName, decoder) {
196
+ try {
197
+ return decoder();
198
+ }
199
+ catch (error) {
200
+ throw new StoreCorruptException(containerName, error);
201
+ }
163
202
  }
164
- // Stores a message the caller holds, not one a response carried, versioned from the copy this
165
- // container holds. A message this client amended has no update number, so it is stored at that of
203
+ // Stores a message the caller built, not one a response carried, versioned from the copy this
204
+ // container stores. A message this client amended has no update number, so it is stored at that of
166
205
  // the copy it amends - see ProtoMap.messageToBlob
167
206
  async writeOwnMessage(containerName, message, toBlob) {
168
- const held = await (await this.getContainer(containerName)).read(ProtoMap.getMessageId(message));
169
- return this.writeBlobs(containerName, [toBlob(message, held?.eTag ?? null)]);
207
+ const stored = await (await this.getContainer(containerName)).read(ProtoMap.getMessageId(message));
208
+ return this.writeBlobs(containerName, [toBlob(message, stored?.eTag ?? null)]);
170
209
  }
171
210
  // For writers that store one blob and delete nothing (a credential or a single message), because no
172
211
  // tombstone comes with either
@@ -176,8 +215,8 @@ export default class SyncCache {
176
215
  // One transaction per call, so an interrupted write can be repeated and never leaves the cache
177
216
  // partly written. The store's count covers only what it stored: a blob that the store already holds
178
217
  // a copy of that is as new (a tombstone too) is not stored and not counted. A delete has nothing
179
- // to compare, so the ids are counted instead. The only delete is a caller's own - see
180
- // deletePartyPreferences.
218
+ // to compare, so the ids are counted instead. A delete is a caller's own: see
219
+ // deletePartyPreferences, deleteUserId and resetProfileCursors.
181
220
  async write(containerName, cacheWrite) {
182
221
  const blobs = cacheWrite.blobs;
183
222
  const deletedIds = cacheWrite.deletedIds;
package/dist/SyncKeys.js CHANGED
@@ -19,8 +19,9 @@ export const PROFILE_SYNC_IN = Object.freeze([
19
19
  proto_Constants.BUSINESS_ENTITY_TYPE_ID,
20
20
  proto_Constants.BUSINESS_LINK_ENTITY_TYPE_ID,
21
21
  ]);
22
- // Update numbers a business sync out records (as a BusinessSyncInResponse returns them). Message
23
- // is the only entity type a storefront may push, so this is a set of one.
22
+ // The cursor of a business sync in: BusinessSyncInRequest.messageUpdateNumber, which is how far
23
+ // reads have got with the customer's messages. The response carries the messages that are newer than
24
+ // it. Message is the only entity type a storefront may send, so this is a set of one.
24
25
  export const BUSINESS_SYNC_OUT = Object.freeze([
25
26
  proto_Constants.MESSAGE_ENTITY_TYPE_ID,
26
27
  ]);
@@ -4,38 +4,52 @@ import type { BinaryReadOptions } from "@protobuf-ts/runtime";
4
4
  import type { IBinaryReader } from "@protobuf-ts/runtime";
5
5
  import type { PartialMessage } from "@protobuf-ts/runtime";
6
6
  import { MessageType } from "@protobuf-ts/runtime";
7
+ import { Party } from "./Party";
7
8
  import { Message } from "./Message";
8
9
  /**
9
- * Pushes the business entities a customer has changed - their shopping cart and the orders placed
10
- * from it - to one business database. The request names no business: the link token in the
11
- * AuthTokens of the authorization header does, as a link names exactly one.
12
- * Not implemented yet: the route (shopBusinessSyncIn) answers 501, and what is said here and in the
13
- * BusinessSyncInResponse is the contract that it is to meet, and not behaviour that the server has.
14
- * ProtoMap.fromProto accepts the paymentReceived of an order, and the senderId and status of a message,
15
- * as they are sent, so, sync in has to enforce who may set each of them when it is written.
16
- * An entity being synced in carries the id it already has, or Constants.ENTITY_ID_NULL if the
17
- * caller is creating it and the server is to assign one; incoming update numbers are the caller's
18
- * own and are replaced by the server, which returns the messages bearing the new ones in the
19
- * BusinessSyncInResponse.
10
+ * Stores the shopping cart and the orders of a customer in one business. The request names no business: the link token in the
11
+ * AuthTokens of the authorization header does, and it must be a customer's (401 otherwise). The business is not checked to be open.
12
+ * The server checks every message before it stores any, so one failure fails the request:
13
+ * - distinct ids, each message an order or a cart with its payload (400)
14
+ * - a cart has the id of the cart of the business link in the link token: the id of the link with the entity type of a message (see
15
+ * Message.getPartyPreferencesMessageId in the merchant app). An order does not have that id (400)
16
+ * - senderId is the party of the link (401), and status is NOT_YET_PROCESSED (400)
17
+ * - an order has OrderStatus NOT_STARTED and no paymentReceived, which only an operator sets (400)
18
+ * - createdAt and updatedAt are set, and not later than the clock skew allows (400)
19
+ * The server replaces the update number and updateInfo, and marks every order as placed by a customer. An order with id
20
+ * Constants.ENTITY_ID_NULL gets an id from the server.
21
+ * A cart is stored as a whole: it replaces the stored cart if its updatedAt is later, and is ignored if it is not. The server reads the
22
+ * party before the write (see party), and the messages of the customer after it (see BusinessSyncInResponse).
23
+ * An order is stored only if no message has its id: the server gives it the oldest possible updatedAt, so a later copy never replaces
24
+ * it. A retry changes nothing, and a customer cannot change an order that the business has started or completed. The createdAt of
25
+ * the order is the one that was sent.
26
+ * A request with no messages and no party changes nothing and is answered with no messages: it is not a way to read.
20
27
  *
21
28
  * @generated from protobuf message com.merabills.storefront.BusinessSyncInRequest
22
29
  */
23
30
  export interface BusinessSyncInRequest {
24
31
  /**
25
- * Client-side cursor for the customer's orders and shopping cart (Constants.MESSAGE_ENTITY_TYPE_ID):
26
- * how far the client's sync outs of them have got, which is not moved by a push. The answer to a push
27
- * is only the messages that were pushed, so, it does not depend on this.
32
+ * Client-side cursor for the customer's orders and shopping cart (Constants.MESSAGE_ENTITY_TYPE_ID): how far the client's sync
33
+ * outs of them have got, as in BusinessSyncOutRequest. The response carries the messages that are newer than it.
28
34
  *
29
35
  * @generated from protobuf field: int64 messageUpdateNumber = 1
30
36
  */
31
37
  messageUpdateNumber: bigint;
32
38
  /**
33
- * The shopping cart (a PartyPreferencesPayload) and orders (a SalesOrderPayload) of the customer -
34
- * entity type Constants.MESSAGE_ENTITY_TYPE_ID, the only entity type a customer may push.
39
+ * The shopping cart (a PartyPreferencesPayload) and orders (a SalesOrderPayload) of the customer - entity type
40
+ * Constants.MESSAGE_ENTITY_TYPE_ID, the only entity type a customer may send.
35
41
  *
36
42
  * @generated from protobuf field: repeated com.merabills.storefront.Message messages = 2
37
43
  */
38
44
  messages: Message[];
45
+ /**
46
+ * The customer, with an order. A client sends it with every order: the business needs the party to show the order and to record
47
+ * payments against it. The server stores it with the messages, in one transaction. It is a 400 without an order in the request, and a
48
+ * 401 if its phone number is not the one the authentication token verified.
49
+ *
50
+ * @generated from protobuf field: com.merabills.storefront.Party party = 3
51
+ */
52
+ party?: Party;
39
53
  }
40
54
  declare class BusinessSyncInRequest$Type extends MessageType<BusinessSyncInRequest> {
41
55
  constructor();
@@ -2,13 +2,15 @@ import { WireType } from "@protobuf-ts/runtime";
2
2
  import { UnknownFieldHandler } from "@protobuf-ts/runtime";
3
3
  import { reflectionMergePartial } from "@protobuf-ts/runtime";
4
4
  import { MessageType } from "@protobuf-ts/runtime";
5
+ import { Party } from "./Party";
5
6
  import { Message } from "./Message";
6
7
  // @generated message type with reflection information, may provide speed optimized methods
7
8
  class BusinessSyncInRequest$Type extends MessageType {
8
9
  constructor() {
9
10
  super("com.merabills.storefront.BusinessSyncInRequest", [
10
11
  { no: 1, name: "messageUpdateNumber", kind: "scalar", T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ },
11
- { no: 2, name: "messages", kind: "message", repeat: 2 /*RepeatType.UNPACKED*/, T: () => Message }
12
+ { no: 2, name: "messages", kind: "message", repeat: 2 /*RepeatType.UNPACKED*/, T: () => Message },
13
+ { no: 3, name: "party", kind: "message", T: () => Party }
12
14
  ]);
13
15
  }
14
16
  create(value) {
@@ -30,6 +32,9 @@ class BusinessSyncInRequest$Type extends MessageType {
30
32
  case /* repeated com.merabills.storefront.Message messages */ 2:
31
33
  message.messages.push(Message.internalBinaryRead(reader, reader.uint32(), options));
32
34
  break;
35
+ case /* com.merabills.storefront.Party party */ 3:
36
+ message.party = Party.internalBinaryRead(reader, reader.uint32(), options, message.party);
37
+ break;
33
38
  default:
34
39
  let u = options.readUnknownField;
35
40
  if (u === "throw")
@@ -48,6 +53,9 @@ class BusinessSyncInRequest$Type extends MessageType {
48
53
  /* repeated com.merabills.storefront.Message messages = 2; */
49
54
  for (let i = 0; i < message.messages.length; i++)
50
55
  Message.internalBinaryWrite(message.messages[i], writer.tag(2, WireType.LengthDelimited).fork(), options).join();
56
+ /* com.merabills.storefront.Party party = 3; */
57
+ if (message.party)
58
+ Party.internalBinaryWrite(message.party, writer.tag(3, WireType.LengthDelimited).fork(), options).join();
51
59
  let u = options.writeUnknownFields;
52
60
  if (u !== false)
53
61
  (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -7,11 +7,14 @@ import { MessageType } from "@protobuf-ts/runtime";
7
7
  import { Message } from "./Message";
8
8
  import { AuthTokens } from "./AuthTokens";
9
9
  /**
10
- * Not implemented yet (the route answers 501): this is the contract that it is to meet.
11
- * The answer to a BusinessSyncInRequest: the messages the server now holds for what was pushed,
12
- * which bear the update numbers it assigned, and any tokens it renewed. A push is not a read, so, do
13
- * not move the message cursor with these update numbers: a change somebody else made, with an update
14
- * number below them, would then never be sent. The next sync out returns what was pushed as well.
10
+ * The answer to a BusinessSyncInRequest: a sync out of the messages of the customer, made after the write, and any tokens the server
11
+ * renewed. It carries the messages that are newer than BusinessSyncInRequest.messageUpdateNumber, in the order of their update
12
+ * numbers, deleted ones included, and at most as many as a sync out sends: a client that gets that many reads on with a sync out. A
13
+ * client moves its message cursor with them as it does with a sync out.
14
+ * They are the stored messages, so an update number in the response is always one that a message is stored under. They include the
15
+ * incoming messages that were stored. One that was not stored (an order whose id exists, or a cart that is not later than the stored
16
+ * one) is in the response only if the stored message is newer than the cursor, and is then the stored message. The messages are not in
17
+ * the order of the request: a client finds its own by id.
15
18
  *
16
19
  * @generated from protobuf message com.merabills.storefront.BusinessSyncInResponse
17
20
  */
@@ -24,7 +27,7 @@ export interface BusinessSyncInResponse {
24
27
  */
25
28
  authTokens?: AuthTokens;
26
29
  /**
27
- * The orders of the customer, and their shopping cart
30
+ * The messages of the customer that are newer than the cursor of the request: the orders and the shopping cart
28
31
  *
29
32
  * @generated from protobuf field: repeated com.merabills.storefront.Message messages = 2
30
33
  */
@@ -134,12 +134,6 @@ export declare enum Constants {
134
134
  * @generated from protobuf enum value: ATTACHMENT_FILE_HASH_SIZE_BYTES = 16;
135
135
  */
136
136
  ATTACHMENT_FILE_NAME_MAX_LENGTH = 16,
137
- /**
138
- * Message.senderName
139
- *
140
- * @generated from protobuf enum value: MESSAGE_SENDER_NAME_MAX_LENGTH = 65;
141
- */
142
- MESSAGE_SENDER_NAME_MAX_LENGTH = 65,
143
137
  /**
144
138
  * SalesOrderPayload.note
145
139
  *
@@ -316,9 +310,7 @@ export declare enum Constants {
316
310
  */
317
311
  PACKAGE_ENTITY_TYPE_ID = 64,
318
312
  /**
319
- * Message.senderName
320
- *
321
- * @generated from protobuf enum value: MESSAGE_SENDER_NAME_MAX_LENGTH = 65;
313
+ * @generated from protobuf enum value: PRODUCT_ENTITY_TYPE_ID = 65;
322
314
  */
323
315
  PRODUCT_ENTITY_TYPE_ID = 65,
324
316
  /**
@@ -393,9 +385,7 @@ export declare enum Constants {
393
385
  */
394
386
  MERABILLS_ONLINE_PRICE_LIST = 64,
395
387
  /**
396
- * Message.senderName
397
- *
398
- * @generated from protobuf enum value: MESSAGE_SENDER_NAME_MAX_LENGTH = 65;
388
+ * @generated from protobuf enum value: PRODUCT_ENTITY_TYPE_ID = 65;
399
389
  */
400
390
  AMAZON_SELLER_PRICE_LIST = 65,
401
391
  /**
@@ -139,12 +139,6 @@ export var Constants;
139
139
  * @generated from protobuf enum value: ATTACHMENT_FILE_HASH_SIZE_BYTES = 16;
140
140
  */
141
141
  Constants[Constants["ATTACHMENT_FILE_NAME_MAX_LENGTH"] = 16] = "ATTACHMENT_FILE_NAME_MAX_LENGTH";
142
- /**
143
- * Message.senderName
144
- *
145
- * @generated from protobuf enum value: MESSAGE_SENDER_NAME_MAX_LENGTH = 65;
146
- */
147
- Constants[Constants["MESSAGE_SENDER_NAME_MAX_LENGTH"] = 65] = "MESSAGE_SENDER_NAME_MAX_LENGTH";
148
142
  /**
149
143
  * SalesOrderPayload.note
150
144
  *
@@ -321,9 +315,7 @@ export var Constants;
321
315
  */
322
316
  Constants[Constants["PACKAGE_ENTITY_TYPE_ID"] = 64] = "PACKAGE_ENTITY_TYPE_ID";
323
317
  /**
324
- * Message.senderName
325
- *
326
- * @generated from protobuf enum value: MESSAGE_SENDER_NAME_MAX_LENGTH = 65;
318
+ * @generated from protobuf enum value: PRODUCT_ENTITY_TYPE_ID = 65;
327
319
  */
328
320
  Constants[Constants["PRODUCT_ENTITY_TYPE_ID"] = 65] = "PRODUCT_ENTITY_TYPE_ID";
329
321
  /**
@@ -398,9 +390,7 @@ export var Constants;
398
390
  */
399
391
  Constants[Constants["MERABILLS_ONLINE_PRICE_LIST"] = 64] = "MERABILLS_ONLINE_PRICE_LIST";
400
392
  /**
401
- * Message.senderName
402
- *
403
- * @generated from protobuf enum value: MESSAGE_SENDER_NAME_MAX_LENGTH = 65;
393
+ * @generated from protobuf enum value: PRODUCT_ENTITY_TYPE_ID = 65;
404
394
  */
405
395
  Constants[Constants["AMAZON_SELLER_PRICE_LIST"] = 65] = "AMAZON_SELLER_PRICE_LIST";
406
396
  /**
@@ -18,6 +18,8 @@ import { Entity } from "./Entity";
18
18
  * its message, so, a deleted message that carries a sales order is an order that the business has
19
19
  * completed, and is the whole of what a customer is shown of it afterwards. A deleted message is not
20
20
  * a cart, whatever it carries.
21
+ * Excluded: senderName, senderPhone. The merchant app makes a Party from them only for a message whose sender has none. A storefront
22
+ * sends the party with its order (see Party), and a customer is sent only the messages of their own party.
21
23
  *
22
24
  * @generated from protobuf message com.merabills.storefront.Message
23
25
  */
@@ -29,8 +31,7 @@ export interface Message {
29
31
  /**
30
32
  * Id of the party that sent this message - Java Message.senderId, which is a party id and not the id
31
33
  * of a User: the party of the BusinessLink of the sender (BusinessLink.partyId). Carried by a business
32
- * sync out, which sends a customer only the messages whose sender is their own party. senderName /
33
- * senderPhone below say who it was without resolving the party.
34
+ * sync out, which sends a customer only the messages whose sender is their own party.
34
35
  *
35
36
  * @generated from protobuf field: int64 senderId = 2
36
37
  */
@@ -43,31 +44,19 @@ export interface Message {
43
44
  * @generated from protobuf field: com.merabills.storefront.TaskStatus status = 4
44
45
  */
45
46
  status: TaskStatus;
46
- /**
47
- * At most Constants.MESSAGE_SENDER_NAME_MAX_LENGTH
48
- *
49
- * @generated from protobuf field: optional string senderName = 5
50
- */
51
- senderName?: string;
52
- /**
53
- * E.164 formatted phone number of the sender
54
- *
55
- * @generated from protobuf field: optional string senderPhone = 6
56
- */
57
- senderPhone?: string;
58
47
  /**
59
48
  * @generated from protobuf oneof: payload
60
49
  */
61
50
  payload: {
62
51
  oneofKind: "salesOrder";
63
52
  /**
64
- * @generated from protobuf field: com.merabills.storefront.SalesOrderPayload salesOrder = 7
53
+ * @generated from protobuf field: com.merabills.storefront.SalesOrderPayload salesOrder = 5
65
54
  */
66
55
  salesOrder: SalesOrderPayload;
67
56
  } | {
68
57
  oneofKind: "partyPreferences";
69
58
  /**
70
- * @generated from protobuf field: com.merabills.storefront.PartyPreferencesPayload partyPreferences = 8
59
+ * @generated from protobuf field: com.merabills.storefront.PartyPreferencesPayload partyPreferences = 6
71
60
  */
72
61
  partyPreferences: PartyPreferencesPayload;
73
62
  } | {
@@ -15,10 +15,8 @@ class Message$Type extends MessageType$ {
15
15
  { no: 2, name: "senderId", kind: "scalar", T: 3 /*ScalarType.INT64*/, L: 0 /*LongType.BIGINT*/ },
16
16
  { no: 3, name: "messageType", kind: "enum", T: () => ["com.merabills.storefront.MessageType", MessageType] },
17
17
  { no: 4, name: "status", kind: "enum", T: () => ["com.merabills.storefront.TaskStatus", TaskStatus] },
18
- { no: 5, name: "senderName", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ },
19
- { no: 6, name: "senderPhone", kind: "scalar", opt: true, T: 9 /*ScalarType.STRING*/ },
20
- { no: 7, name: "salesOrder", kind: "message", oneof: "payload", T: () => SalesOrderPayload },
21
- { no: 8, name: "partyPreferences", kind: "message", oneof: "payload", T: () => PartyPreferencesPayload }
18
+ { no: 5, name: "salesOrder", kind: "message", oneof: "payload", T: () => SalesOrderPayload },
19
+ { no: 6, name: "partyPreferences", kind: "message", oneof: "payload", T: () => PartyPreferencesPayload }
22
20
  ]);
23
21
  }
24
22
  create(value) {
@@ -48,19 +46,13 @@ class Message$Type extends MessageType$ {
48
46
  case /* com.merabills.storefront.TaskStatus status */ 4:
49
47
  message.status = reader.int32();
50
48
  break;
51
- case /* optional string senderName */ 5:
52
- message.senderName = reader.string();
53
- break;
54
- case /* optional string senderPhone */ 6:
55
- message.senderPhone = reader.string();
56
- break;
57
- case /* com.merabills.storefront.SalesOrderPayload salesOrder */ 7:
49
+ case /* com.merabills.storefront.SalesOrderPayload salesOrder */ 5:
58
50
  message.payload = {
59
51
  oneofKind: "salesOrder",
60
52
  salesOrder: SalesOrderPayload.internalBinaryRead(reader, reader.uint32(), options, message.payload.salesOrder)
61
53
  };
62
54
  break;
63
- case /* com.merabills.storefront.PartyPreferencesPayload partyPreferences */ 8:
55
+ case /* com.merabills.storefront.PartyPreferencesPayload partyPreferences */ 6:
64
56
  message.payload = {
65
57
  oneofKind: "partyPreferences",
66
58
  partyPreferences: PartyPreferencesPayload.internalBinaryRead(reader, reader.uint32(), options, message.payload.partyPreferences)
@@ -90,18 +82,12 @@ class Message$Type extends MessageType$ {
90
82
  /* com.merabills.storefront.TaskStatus status = 4; */
91
83
  if (message.status !== 0)
92
84
  writer.tag(4, WireType.Varint).int32(message.status);
93
- /* optional string senderName = 5; */
94
- if (message.senderName !== undefined)
95
- writer.tag(5, WireType.LengthDelimited).string(message.senderName);
96
- /* optional string senderPhone = 6; */
97
- if (message.senderPhone !== undefined)
98
- writer.tag(6, WireType.LengthDelimited).string(message.senderPhone);
99
- /* com.merabills.storefront.SalesOrderPayload salesOrder = 7; */
85
+ /* com.merabills.storefront.SalesOrderPayload salesOrder = 5; */
100
86
  if (message.payload.oneofKind === "salesOrder")
101
- SalesOrderPayload.internalBinaryWrite(message.payload.salesOrder, writer.tag(7, WireType.LengthDelimited).fork(), options).join();
102
- /* com.merabills.storefront.PartyPreferencesPayload partyPreferences = 8; */
87
+ SalesOrderPayload.internalBinaryWrite(message.payload.salesOrder, writer.tag(5, WireType.LengthDelimited).fork(), options).join();
88
+ /* com.merabills.storefront.PartyPreferencesPayload partyPreferences = 6; */
103
89
  if (message.payload.oneofKind === "partyPreferences")
104
- PartyPreferencesPayload.internalBinaryWrite(message.payload.partyPreferences, writer.tag(8, WireType.LengthDelimited).fork(), options).join();
90
+ PartyPreferencesPayload.internalBinaryWrite(message.payload.partyPreferences, writer.tag(6, WireType.LengthDelimited).fork(), options).join();
105
91
  let u = options.writeUnknownFields;
106
92
  if (u !== false)
107
93
  (u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
@@ -0,0 +1,52 @@
1
+ import type { BinaryWriteOptions } from "@protobuf-ts/runtime";
2
+ import type { IBinaryWriter } from "@protobuf-ts/runtime";
3
+ import type { BinaryReadOptions } from "@protobuf-ts/runtime";
4
+ import type { IBinaryReader } from "@protobuf-ts/runtime";
5
+ import type { PartialMessage } from "@protobuf-ts/runtime";
6
+ import { MessageType } from "@protobuf-ts/runtime";
7
+ import { Address } from "./Address";
8
+ /**
9
+ * The customer that places an order, as the business knows them: the party of the business link in the link token. It is sent with an
10
+ * order in BusinessSyncInRequest, so that the business has a party for the customer, and the party has its ledger, as when a customer
11
+ * places an order in the merchant app. It carries no id: the party is the one of the link (BusinessLink.partyId).
12
+ * The server creates the party and its ledger if the business has none. Otherwise it sets the name if the party has none, sets the
13
+ * phone number if it differs, and adds the addresses to the party, or replaces those with the same id. Nothing else of an existing
14
+ * party changes.
15
+ * Excluded: the id (the party is the one of the link) and what only an operator of the business sets: the nickname, the translations of
16
+ * the name and nickname, the contact link, the payment methods, the description and the disabled flag. An existing party keeps them.
17
+ *
18
+ * @generated from protobuf message com.merabills.storefront.Party
19
+ */
20
+ export interface Party {
21
+ /**
22
+ * Required. The name of the party, if it has none. The server shortens a name that is longer than a party's, which is 32 characters,
23
+ * to its first 32 characters.
24
+ *
25
+ * @generated from protobuf field: string name = 1
26
+ */
27
+ name: string;
28
+ /**
29
+ * Required, E.164 formatted. It has to be the phone number that the authentication token verified (401).
30
+ *
31
+ * @generated from protobuf field: string mobilePhoneNumber = 2
32
+ */
33
+ mobilePhoneNumber: string;
34
+ /**
35
+ * The addresses to add to the party, such as the delivery address of the order. An address replaces the one with the same id.
36
+ * Each has a non-zero id. At most Constants.MAX_ADDRESSES.
37
+ *
38
+ * @generated from protobuf field: repeated com.merabills.storefront.Address addresses = 3
39
+ */
40
+ addresses: Address[];
41
+ }
42
+ declare class Party$Type extends MessageType<Party> {
43
+ constructor();
44
+ create(value?: PartialMessage<Party>): Party;
45
+ internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: Party): Party;
46
+ internalBinaryWrite(message: Party, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter;
47
+ }
48
+ /**
49
+ * @generated MessageType for protobuf message com.merabills.storefront.Party
50
+ */
51
+ export declare const Party: Party$Type;
52
+ export {};