@peabody-soft/mbs-model-ts 1.5.0 → 1.7.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 (52) hide show
  1. package/dist/Address.js +8 -11
  2. package/dist/Attachment.js +7 -8
  3. package/dist/AttachmentBaseUrl.js +10 -10
  4. package/dist/AuthTokens.js +12 -7
  5. package/dist/Business.js +19 -19
  6. package/dist/BusinessIdentifier.js +2 -2
  7. package/dist/BusinessLink.js +16 -16
  8. package/dist/BusinessProfile.js +4 -4
  9. package/dist/CartEditor.js +137 -166
  10. package/dist/Catalog.js +19 -25
  11. package/dist/Constants.js +10 -10
  12. package/dist/ContainerNames.js +10 -11
  13. package/dist/Entity.js +11 -9
  14. package/dist/Enums.js +2 -2
  15. package/dist/Exceptions.js +2 -2
  16. package/dist/GeneralSettings.js +23 -21
  17. package/dist/HttpStatusCodes.js +10 -11
  18. package/dist/Ids.js +24 -30
  19. package/dist/Item.js +6 -7
  20. package/dist/LatLong.js +3 -3
  21. package/dist/LiveData.js +6 -6
  22. package/dist/Measures.js +2 -2
  23. package/dist/Message.js +6 -6
  24. package/dist/MockDatabase.js +2 -2
  25. package/dist/Model.js +294 -365
  26. package/dist/Order.js +20 -17
  27. package/dist/Package.js +7 -8
  28. package/dist/PackageIdentifier.js +2 -2
  29. package/dist/PaymentMethodDetail.js +4 -4
  30. package/dist/Photo.js +6 -7
  31. package/dist/Price.js +8 -9
  32. package/dist/PriceList.js +2 -2
  33. package/dist/Product.js +17 -22
  34. package/dist/ProductCategory.js +3 -4
  35. package/dist/Profile.js +26 -27
  36. package/dist/ProtoMap.d.ts +3 -0
  37. package/dist/ProtoMap.js +288 -294
  38. package/dist/Routes.js +3 -3
  39. package/dist/ServiceExceptions.js +11 -12
  40. package/dist/ServiceProxy.js +19 -23
  41. package/dist/ShoppingList.js +112 -130
  42. package/dist/SyncCache.d.ts +3 -0
  43. package/dist/SyncCache.js +92 -75
  44. package/dist/SyncKeys.js +8 -8
  45. package/dist/SyncState.js +5 -5
  46. package/dist/Tax.js +16 -21
  47. package/dist/TaxHelper.js +22 -30
  48. package/dist/TaxType.js +8 -9
  49. package/dist/UserProfile.js +4 -4
  50. package/dist/WorkingDays.js +15 -15
  51. package/dist/index.js +9 -9
  52. package/package.json +1 -1
package/dist/Order.js CHANGED
@@ -2,12 +2,14 @@ import { MessageType as proto_MessageType } from "./generated/MessageType";
2
2
  import { amountFromScaledValue } from "./Constants";
3
3
  import Message from "./Message";
4
4
  // An order a customer has placed: a message carrying a sales order payload.
5
- // deliveryAddressId is an id into the customer's address list, not an address; deliveryAddress is
6
- // a full address sent directly instead, and takes precedence over deliveryAddressId when both are
7
- // present. paymentReceived is set only by an operator of the business, never by this library.
5
+ // The business completes an order (fulfilling or cancelling it) by deleting its message, so
6
+ // isDeleted is true of a completed order. That message is still the whole order: status and what
7
+ // the customer ordered are there to show, as for an open one. status says how far the business
8
+ // got with it.
9
+ // deliveryAddressId is an id into the customer's address list. deliveryAddress is a full address
10
+ // sent directly, and takes precedence over deliveryAddressId when both are present.
8
11
  export default class Order extends Message {
9
- // Only ProtoMap calls this: it is the one place that sees a total still multiplied by
10
- // Constants.AMOUNT_FACTOR.
12
+ // For ProtoMap, which sees a total still multiplied by Constants.AMOUNT_FACTOR.
11
13
  static fromScaledValues(header, senderId, taskStatus, senderName, senderPhone, status, fulfillmentMode, shoppingList, scaledShoppingListTotal, shoppingListCount, deliveryAddressId, deliveryAddress, creationDate, note, scaledPaymentReceived) {
12
14
  return new Order(header, senderId, taskStatus, senderName, senderPhone, status, fulfillmentMode, shoppingList, amountFromScaledValue(scaledShoppingListTotal), shoppingListCount, deliveryAddressId, deliveryAddress, creationDate, note, scaledPaymentReceived === undefined ? null : amountFromScaledValue(scaledPaymentReceived));
13
15
  }
@@ -24,34 +26,35 @@ export default class Order extends Message {
24
26
  this._paymentReceived = _paymentReceived;
25
27
  this._creationDate = Number(creationDate);
26
28
  }
27
- // How far the business has got with fulfilling this order, as opposed to taskStatus, which is
28
- // how far it has got with reading the message
29
+ // How far the business has got with fulfilling this order. taskStatus is how far it has got with
30
+ // reading the message.
29
31
  get status() {
30
32
  return this._status;
31
33
  }
32
34
  get fulfillmentMode() {
33
35
  return this._fulfillmentMode;
34
36
  }
35
- // What was ordered. A fulfilled order can have had its list cleared, in which case the totals
36
- // below are all that is left of it.
37
+ // What was ordered. An order completed before the business kept the list with it (an older
38
+ // merchant app moved the list into a record of the sale, which a customer never sees) holds
39
+ // ShoppingList.EMPTY, which has no lines. The totals below are then all that is left.
37
40
  get shoppingList() {
38
41
  return this._shoppingList;
39
42
  }
40
- // The authoritative total to display; survives the shopping list being cleared, unlike a total
41
- // read off the list itself.
43
+ // The authoritative total to display. Unlike a total read off the list, it survives the order
44
+ // having no list.
42
45
  get shoppingListTotal() {
43
46
  return this._shoppingListTotal;
44
47
  }
45
48
  get shoppingListCount() {
46
49
  return this._shoppingListCount;
47
50
  }
48
- // Names an address in the address list of the customer, and Constants.ENTITY_ID_NULL when the
49
- // order has no delivery address - which is normal for one to be picked up
51
+ // Names an address in the customer's address list. Constants.ENTITY_ID_NULL when the order has no
52
+ // delivery address, as is normal for a pickup.
50
53
  get deliveryAddressId() {
51
54
  return this._deliveryAddressId;
52
55
  }
53
- // A full address sent directly rather than by id, and null when none was. Takes precedence over
54
- // deliveryAddressId for display when it is not null - see the comment on this class.
56
+ // A full address sent directly rather than by id. Null when none was. Takes precedence over
57
+ // deliveryAddressId when not null.
55
58
  get deliveryAddress() {
56
59
  return this._deliveryAddress;
57
60
  }
@@ -62,8 +65,8 @@ export default class Order extends Message {
62
65
  get note() {
63
66
  return this._note;
64
67
  }
65
- // What the business has recorded as received against this order so far, and null when it has
66
- // recorded nothing - only a business operator sets this, never this library.
68
+ // What the business has recorded as received against this order so far. Null when nothing is
69
+ // recorded. Only a business operator sets it.
67
70
  get paymentReceived() {
68
71
  return this._paymentReceived;
69
72
  }
package/dist/Package.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import Item from "./Item";
2
- // A package, or variant, of a product - a 500 gram bottle of mango pickle, for example - and the
3
- // thing a customer actually buys. Built complete, with photos and price already resolved, so everything here is readonly.
2
+ // A package, or variant, of a product (a 500 gram bottle of mango pickle, say) and the thing a
3
+ // customer buys. Built complete, with photos and price resolved, so everything here is readonly.
4
4
  export default class Package extends Item {
5
5
  constructor(header, name, description, productId, isDisabled, _isSoldLoose, _itemCode, _identifiers, _dimensions, _weight, _photos, _price) {
6
6
  super(header, name, description, productId, isDisabled);
@@ -37,15 +37,14 @@ export default class Package extends Item {
37
37
  get photos() {
38
38
  return this._photos;
39
39
  }
40
- // What this package costs, with the taxes of its product included (Product.taxes); null when the
41
- // business has not priced it, in which case it cannot be bought.
40
+ // What this package costs, with the taxes of its product included (Product.taxes). Null when the
41
+ // business has not priced it, so it cannot be bought.
42
42
  get price() {
43
43
  return this._price;
44
44
  }
45
- // True when this package is enabled and has a price that is itself enabled. isDisabled is
46
- // checked directly rather than trusted to have been filtered out: a product-level filter does
47
- // not, by itself, guarantee that every package - or every price - of an otherwise visible
48
- // product is itself enabled.
45
+ // True when this package is enabled and has an enabled price. Checked here because a
46
+ // product-level filter does not guarantee that every package, or every price, of an otherwise
47
+ // visible product is enabled.
49
48
  get isBuyable() {
50
49
  return !this.isDisabled && this._price !== null && !this._price.isDisabled;
51
50
  }
@@ -1,5 +1,5 @@
1
- // An identifier of a package - a GTIN, for example - and the kind of identifier it is. Java keys
2
- // these by string id, not ordinal, so map through PackageIdentifierType.proto's comments, never the enum ordinal.
1
+ // An identifier of a package, such as a GTIN, and its kind. Java keys kinds by string id, so map
2
+ // through the comments in PackageIdentifierType.proto, never the enum ordinal.
3
3
  export default class PackageIdentifier {
4
4
  constructor(_type, _value) {
5
5
  this._type = _type;
@@ -1,8 +1,8 @@
1
- // A payment method a business accepts, and what a customer needs in order to use it - the UPI id
2
- // of the business, for example.
1
+ // A payment method a business accepts, and what a customer needs to use it (the UPI id of the
2
+ // business, say).
3
3
  //
4
- // The data is null rather than empty when the business has given none, which is normal for a
5
- // method that needs nothing, such as cash.
4
+ // The data is null, not empty, when the business has given none. That is normal for a method that
5
+ // needs nothing, such as cash.
6
6
  export default class PaymentMethodDetail {
7
7
  constructor(_method, _data) {
8
8
  this._method = _method;
package/dist/Photo.js CHANGED
@@ -1,9 +1,8 @@
1
- // A photo of a business, product or package: which one it belongs to, and where to fetch it from.
2
- // All that's exposed of an Attachment - nothing else on it is useful to a UI.
1
+ // A photo of a business, product or package: its attachment type and where to fetch it from.
2
+ // All that a UI needs of an Attachment.
3
3
  export default class Photo {
4
- // The base url is the one in effect when this photo was built, not looked up at read time - a
5
- // photo is rebuilt by the next sync rather than edited in place, so there is nothing to keep in
6
- // sync with a later renewal.
4
+ // The base url is the one in effect when this photo was built. A photo is rebuilt by the next
5
+ // sync, not edited in place, so a later renewal needs no handling.
7
6
  constructor(_attachment, _attachmentBaseUrl) {
8
7
  this._attachment = _attachment;
9
8
  this._attachmentBaseUrl = _attachmentBaseUrl;
@@ -12,8 +11,8 @@ export default class Photo {
12
11
  get attachmentType() {
13
12
  return this._attachment.attachmentType;
14
13
  }
15
- // Where to fetch this photo from, or null if there's nothing to fetch (deleted attachment, or the
16
- // owning business's base url hadn't arrived when this photo was built). May be expired; cached
14
+ // Where to fetch this photo from. Null if there is nothing to fetch (deleted attachment, or the
15
+ // owning business's base url had not arrived when this photo was built). May be expired. Cached
17
16
  // once built.
18
17
  get url() {
19
18
  if (this._url !== null)
package/dist/Price.js CHANGED
@@ -3,12 +3,11 @@ import Item from "./Item";
3
3
  // What one package costs: the regular price and the offer price. Exposed unscaled as numbers; they
4
4
  // travel multiplied by Constants.AMOUNT_FACTOR and stay well below 2^53, so nothing is lost.
5
5
  //
6
- // BOTH INCLUDE TAXES: the taxes of the product the package belongs to (Product.taxes) are in the
7
- // price, not added to it, so this is what a customer pays and what a catalog shows. A shopping
8
- // list stores a price without them, which is why a cart takes the taxes out of one (CartEditor).
6
+ // BOTH INCLUDE TAXES: the taxes of the package's product (Product.taxes) are in the price, not
7
+ // added to it, so this is what a customer pays and what a catalog shows. A shopping list stores a
8
+ // price without them, so a cart takes the taxes out (CartEditor).
9
9
  export default class Price extends Item {
10
- // Only ProtoMap calls this: it is the one place that sees prices still multiplied by
11
- // Constants.AMOUNT_FACTOR.
10
+ // For ProtoMap, which sees prices still multiplied by Constants.AMOUNT_FACTOR.
12
11
  static fromScaledValues(header, name, description, priceListId, isDisabled, packageId, scaledRegularPrice, scaledOfferPrice) {
13
12
  return new Price(header, name, description, priceListId, isDisabled, packageId, amountFromScaledValue(scaledRegularPrice), amountFromScaledValue(scaledOfferPrice));
14
13
  }
@@ -34,8 +33,8 @@ export default class Price extends Item {
34
33
  get offerPrice() {
35
34
  return this._offerPrice;
36
35
  }
37
- // What a customer actually pays, taxes included: the offer price when there is one, else the
38
- // regular price. Computed here (not sent), matching the "on offer" definition from Price.proto.
36
+ // What a customer pays, taxes included: the offer price when there is one, else the regular
37
+ // price. Computed here, not sent, using the "on offer" definition from Price.proto.
39
38
  get finalPrice() {
40
39
  return this.isOnOffer ? this._offerPrice : this._regularPrice;
41
40
  }
@@ -46,8 +45,8 @@ export default class Price extends Item {
46
45
  get discount() {
47
46
  return this._regularPrice - this.finalPrice;
48
47
  }
49
- // Discount as an exact, unrounded percentage of the regular price - rounding is left to the UI.
50
- // Zero when the regular price is zero.
48
+ // Discount as an unrounded percentage of the regular price. Rounding is left to the UI. Zero
49
+ // when the regular price is zero.
51
50
  get discountPercent() {
52
51
  if (this._regularPrice <= 0)
53
52
  return 0;
package/dist/PriceList.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import Item from "./Item";
2
- // A named list of prices. A storefront sells from exactly one, so no package ever has two prices
3
- // to choose between; it's carried (not just a bare id) because a client naming a cart needs it.
2
+ // A named list of prices. A storefront sells from one, so no package has two prices to choose
3
+ // between. Carried as an object, not a bare id, because a client naming a cart needs it.
4
4
  export default class PriceList extends Item {
5
5
  }
package/dist/Product.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import Item from "./Item";
2
2
  // A product in the catalog: goods, a service, a raw material or a fixed asset. Built complete
3
- // (photos/packages resolved first) so everything here is readonly except category (via parentItemId).
3
+ // (photos and packages resolved first), so everything here is readonly.
4
4
  export default class Product extends Item {
5
5
  constructor(header, name, description, productCategoryId, isDisabled, _productType, _brand, _isManufacturedByBusiness, _manufacturer, _manufacturerAddress, _taxes, _features, _isForOfflineSaleOnly, _photos, packages) {
6
6
  super(header, name, description, productCategoryId, isDisabled);
@@ -13,8 +13,7 @@ export default class Product extends Item {
13
13
  this._features = _features;
14
14
  this._isForOfflineSaleOnly = _isForOfflineSaleOnly;
15
15
  this._photos = _photos;
16
- // A package that cannot be bought is of no use to anyone who has this product, so it is not
17
- // kept - whoever builds a product, and whatever they hand it
16
+ // A package that cannot be bought is not kept, whoever builds the product and whatever they pass in
18
17
  this._packages = Object.freeze(packages.filter((pkg) => pkg.isBuyable));
19
18
  }
20
19
  // The category this product is in, or Constants.ENTITY_ID_NULL when it is in none
@@ -27,8 +26,8 @@ export default class Product extends Item {
27
26
  get brand() {
28
27
  return this._brand;
29
28
  }
30
- // False only when the business says it does not make this product itself: what is sent is false,
31
- // or nothing, which Product.proto says is true.
29
+ // False only when the business says it does not make this product itself. Absent on the wire
30
+ // means true (Product.proto).
32
31
  get isManufacturedByBusiness() {
33
32
  return this._isManufacturedByBusiness;
34
33
  }
@@ -38,8 +37,8 @@ export default class Product extends Item {
38
37
  get manufacturerAddress() {
39
38
  return this._manufacturerAddress;
40
39
  }
41
- // The taxes INCLUDED in the price of every package of this product (Price) - not added to it.
42
- // A UI shows a price as it is, and shows these only as what a bill's total includes.
40
+ // The taxes included in the price of every package of this product (see Price), not added to it.
41
+ // A UI shows a price as is, and shows these only as part of what a bill's total includes.
43
42
  get taxes() {
44
43
  return this._taxes;
45
44
  }
@@ -47,26 +46,23 @@ export default class Product extends Item {
47
46
  get features() {
48
47
  return this._features;
49
48
  }
50
- // True when the business sells this product only offline: the server sends such a product like any
51
- // other, flagged, and it is for this model to not offer it to a customer - see isBuyable. A catalog
52
- // never holds one, so only a product that is built by hand, not one that is read from a catalog,
53
- // can be seen to say so.
49
+ // True when the business sells this product only offline. The server sends such a product like
50
+ // any other, flagged, and this model must not offer it to a customer (see isBuyable). A catalog
51
+ // never holds one, so only a hand-built product can report true.
54
52
  get isForOfflineSaleOnly() {
55
53
  return this._isForOfflineSaleOnly;
56
54
  }
57
55
  get photos() {
58
56
  return this._photos;
59
57
  }
60
- // Every buyable variant of this product, in the order they arrived - ordering them for display
61
- // is a UI decision, see Catalog.comparePackages. A variant that cannot be bought is not here, and
62
- // a product with none cannot be bought.
58
+ // Every buyable variant of this product, in the order they arrived. Ordering for display is a UI
59
+ // decision, see Catalog.comparePackages. A product with no buyable variant cannot be bought.
63
60
  get packages() {
64
61
  return this._packages;
65
62
  }
66
63
  // The cheapest final price across variants (what a listing shows as "from"), or null if there
67
- // are no variants. Compares final price, not regular, since that's what a customer would
68
- // actually pay. Every variant is taxed at this product's rates, so prices with taxes in them
69
- // order the variants as prices without would.
64
+ // are no variants. Compares final price, since that is what a customer pays. Every variant is
65
+ // taxed at this product's rates, so prices with taxes order the variants as prices without would.
70
66
  get lowestPrice() {
71
67
  let result = null;
72
68
  for (const pkg of this._packages) {
@@ -85,11 +81,10 @@ export default class Product extends Item {
85
81
  return true;
86
82
  return false;
87
83
  }
88
- // True when this product itself is enabled, is not one that the business sells only offline, and
89
- // it has at least one buyable variant, which is to say any variant, since it keeps no other. The
90
- // server still filters out draft and non-public products before they ever arrive, but isDisabled
91
- // can change after an item exists, and the server does not filter out what is sold only offline
92
- // (it sends the flag), so both are checked here rather than trusted to have been filtered.
84
+ // True when this product is enabled, is not sold only offline, and has at least one variant (it
85
+ // keeps only buyable ones). The server filters out draft and non-public products before they
86
+ // arrive. isDisabled can change after an item exists and offline-only products are sent flagged,
87
+ // so both are checked here.
93
88
  get isBuyable() {
94
89
  return !this.isDisabled && !this._isForOfflineSaleOnly && this._packages.length > 0;
95
90
  }
@@ -1,8 +1,7 @@
1
1
  import Item from "./Item";
2
- // A category that groups products, real or the dummy one a Catalog builds to stand in for a
3
- // product with no category of its own. Products are set once by the Catalog that builds this, not
4
- // passed to the constructor - the full set isn't known until every product has been read. A
5
- // Catalog never builds one of these with an empty products array - see Catalog for why.
2
+ // A category that groups products, real or the dummy one a Catalog builds for products with no
3
+ // category. The Catalog sets the products once, after reading every product, so they are not
4
+ // constructor arguments. A Catalog never builds one with an empty products array (see Catalog).
6
5
  export default class ProductCategory extends Item {
7
6
  constructor() {
8
7
  super(...arguments);
package/dist/Profile.js CHANGED
@@ -6,8 +6,8 @@ export default class Profile {
6
6
  this._user = _user;
7
7
  this._businessMap = new Map();
8
8
  this._businessLinkMap = new Map();
9
- // A business is listed only when its link is still held; a revoked link is removed by the
10
- // sync but the business it named is not, so filtering here hides it without discarding it.
9
+ // A business is listed only when its link is still held. A revoked link is removed by the sync
10
+ // but its business is not, so filtering here hides the business without discarding it.
11
11
  const linkedBusinessIds = new Set();
12
12
  for (const businessLink of businessLinks)
13
13
  linkedBusinessIds.add(businessLink.businessId);
@@ -15,10 +15,10 @@ export default class Profile {
15
15
  this._businesses = Object.freeze(businesses.filter((business) => linkedBusinessIds.has(business.id)));
16
16
  for (const business of this._businesses)
17
17
  this._businessMap.set(business.id, business);
18
- // One link per business is reached through, and it is the one that names this customer. A profile can hold more
19
- // than one link to a business - one that is not this customer's is not what a customer writes to a business with, nor
20
- // what a link token of theirs signs - so a link that does not name this customer does not take the place of one that
21
- // does, whichever comes last. Where none names them (no user is held yet), the last is kept.
18
+ // One link is kept per business: the one that names this customer. A profile can hold several
19
+ // links to a business, and another user's link is not what this customer writes with. A link
20
+ // that does not name this customer never replaces one that does, whichever comes last. If none
21
+ // names them (no user is held yet), the last is kept.
22
22
  const isOwn = (link) => this._user !== null && link.linkedEntityId === this._user.id;
23
23
  for (const businessLink of this._businessLinks) {
24
24
  const held = this._businessLinkMap.get(businessLink.businessId);
@@ -45,14 +45,14 @@ export default class Profile {
45
45
  getBusiness(businessEntityId) {
46
46
  return this._businessMap.get(businessEntityId) ?? null;
47
47
  }
48
- // BusinessLink.businessId is an entity id, matching Business.entity.id and not the url friendly
49
- // businessId - this join spares a caller from having to remember which one it is holding
48
+ // Takes the entity id (BusinessLink.businessId, matching Business.entity.id), not the url friendly
49
+ // businessId. See getBusinessLinkFor.
50
50
  getBusinessLink(businessEntityId) {
51
51
  return this._businessLinkMap.get(businessEntityId) ?? null;
52
52
  }
53
- // The same, by the url friendly business id a storefront is reached by - however it is written in the url, which
54
- // the server finds a business by whatever its case, and which the one here is not to fail: a customer who has joined
55
- // it is not to be taken for one who has not, and asked to join it again
53
+ // The same, by the url friendly business id a storefront is reached by, however it is written in
54
+ // the url. The server finds a business whatever the case, so this must too, or a customer who
55
+ // has joined would be asked to join again.
56
56
  getBusinessLinkFor(businessId) {
57
57
  const wanted = canonicalizeBusinessId(businessId);
58
58
  for (const business of this._businesses)
@@ -64,20 +64,19 @@ export default class Profile {
64
64
  return `Profile(profileId=${this._profileId}, user=${this._user?.formattedName ?? "none"}, businesses=${this._businesses.length})`;
65
65
  }
66
66
  }
67
- // A business id as the server makes it canonical (Java Business.canonicalizeBusinessId) to find one by it: with its spaces
68
- // normalized the way Java StringHelper.normalizeSpace does, and in lower case. A url is typed, and linked to, in any case, and a
69
- // business is the same business in all of them.
70
- // The spaces are not only those at either end, because a business id can hold some: Java makes one out of the display name when
71
- // none is given ("Warm Loaf_1a2b3c4d"), and takes whatever is typed, so a url that has two spaces where the id has one is still
72
- // that business. normalizeSpace is followed step for step, so as to give what Java gives for every string, quirks included: it
73
- // leaves a string alone that has no whitespace at either end and none twice in a row, and a non-breaking space is not whitespace
74
- // to it, so one between two words stays as it was, and is made a plain space only when something else of the string is normalized.
75
- // What Java then refuses, an id that is not between four and sixty-four characters long, is not refused here, since this is only
76
- // the comparison: the server answers a read of one with a NotFoundException, as it does for a business that does not exist.
67
+ // A business id in the canonical form the server finds it by (Java Business.canonicalizeBusinessId):
68
+ // spaces normalized as Java StringHelper.normalizeSpace does, then lower case. So a url typed in any
69
+ // case or spacing names one business. Inner spaces count, as an id can hold some (Java builds one
70
+ // from the display name, "Warm Loaf_1a2b3c4d", or takes what is typed).
71
+ // normalizeSpace is followed step for step, quirks included: a string with no whitespace at either
72
+ // end and none twice in a row is left alone, and a non-breaking space is not whitespace to it, so
73
+ // one between words stays unless something else in the string is normalized.
74
+ // Java refuses an id not four to sixty-four characters long. This is only a comparison and does
75
+ // not. The server answers a read of such an id with NotFoundException, as for a missing business.
77
76
  export function canonicalizeBusinessId(businessId) {
78
77
  return normalizeSpace(businessId).toLowerCase();
79
78
  }
80
- // Java StringHelper.normalizeSpace, which answers null where this answers an empty string: a string of nothing but whitespace
79
+ // Java StringHelper.normalizeSpace. Where Java answers null (a string of only whitespace), this answers an empty string.
81
80
  function normalizeSpace(input) {
82
81
  if (!needsNormalization(input))
83
82
  return input;
@@ -99,8 +98,8 @@ function normalizeSpace(input) {
99
98
  }
100
99
  if (isAtStart)
101
100
  return "";
102
- // Java String.trim, which takes every character up to a space off either end, and not the trim of a script, which takes the
103
- // spaces of Unicode. The space that stands for whitespace at the end goes with it: Java drops that one first, to the same end
101
+ // Java String.trim removes every character up to a space from either end, unlike a script's trim, which removes
102
+ // Unicode spaces. The space standing for trailing whitespace goes with it (Java drops that one first, same result)
104
103
  let first = 0;
105
104
  let last = result.length;
106
105
  while (first < last && result.charCodeAt(first) <= SPACE)
@@ -124,9 +123,9 @@ function needsNormalization(input) {
124
123
  }
125
124
  return false;
126
125
  }
127
- // Java Character.isWhitespace: the spaces of Unicode that do not hold a place (so not the no-break ones, U+00A0, U+2007 and
128
- // U+202F) and the controls that are spaces. Not what a regular expression's \s is, which has the no-break spaces and the
129
- // byte order mark, and has not the four separators U+001C to U+001F
126
+ // Java Character.isWhitespace: the Unicode spaces that do not hold a place (not the no-break ones U+00A0, U+2007 and
127
+ // U+202F) and the control characters that are spaces. A regular expression's \s differs: it includes the no-break
128
+ // spaces and the byte order mark, and excludes U+001C to U+001F
130
129
  function isWhitespace(unit) {
131
130
  if (unit === SPACE)
132
131
  return true;
@@ -41,7 +41,10 @@ export declare function getMessageId(message: proto_Message): bigint;
41
41
  export declare function partyPreferencesToBlob(partyPreferences: proto_Message, heldETag: bigint | null): StoredBlob;
42
42
  export declare function businessResponseFromBlobs(blobs: ReadonlyArray<StoredBlob>): proto_BusinessSyncOutResponse | null;
43
43
  export declare function profileResponseFromBlobs(blobs: ReadonlyArray<StoredBlob>): proto_ProfileSyncOutResponse | null;
44
+ export declare function deletedBusinessResponseFromBlobs(blobs: ReadonlyArray<StoredBlob>): proto_BusinessSyncOutResponse | null;
45
+ export declare function deletedProfileResponseFromBlobs(blobs: ReadonlyArray<StoredBlob>): proto_ProfileSyncOutResponse | null;
44
46
  export declare function orderMessagesFromBlobs(blobs: ReadonlyArray<StoredBlob>): ReadonlyArray<proto_Message>;
47
+ export declare function deletedOrderMessagesFromBlobs(blobs: ReadonlyArray<StoredBlob>): ReadonlyArray<proto_Message>;
45
48
  export declare function partyPreferencesMessageFromMessages(messages: ReadonlyArray<proto_Message>): proto_Message | null;
46
49
  export declare function partyPreferencesMessageFromBlobs(blobs: ReadonlyArray<StoredBlob>): proto_Message | null;
47
50
  export declare function buildBusinessSyncOutRequest(business: string | bigint, syncInState: SyncState, attachmentBaseUrlExpiry: bigint): proto_BusinessSyncOutRequest;