@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.
- package/dist/Address.js +8 -11
- package/dist/Attachment.js +7 -8
- package/dist/AttachmentBaseUrl.js +10 -10
- package/dist/AuthTokens.js +12 -7
- package/dist/Business.js +19 -19
- package/dist/BusinessIdentifier.js +2 -2
- package/dist/BusinessLink.js +16 -16
- package/dist/BusinessProfile.js +4 -4
- package/dist/CartEditor.js +137 -166
- package/dist/Catalog.js +19 -25
- package/dist/Constants.js +10 -10
- package/dist/ContainerNames.js +10 -11
- package/dist/Entity.js +11 -9
- package/dist/Enums.js +2 -2
- package/dist/Exceptions.js +2 -2
- package/dist/GeneralSettings.js +23 -21
- package/dist/HttpStatusCodes.js +10 -11
- package/dist/Ids.js +24 -30
- package/dist/Item.js +6 -7
- package/dist/LatLong.js +3 -3
- package/dist/LiveData.js +6 -6
- package/dist/Measures.js +2 -2
- package/dist/Message.js +6 -6
- package/dist/MockDatabase.js +2 -2
- package/dist/Model.js +294 -365
- package/dist/Order.js +20 -17
- package/dist/Package.js +7 -8
- package/dist/PackageIdentifier.js +2 -2
- package/dist/PaymentMethodDetail.js +4 -4
- package/dist/Photo.js +6 -7
- package/dist/Price.js +8 -9
- package/dist/PriceList.js +2 -2
- package/dist/Product.js +17 -22
- package/dist/ProductCategory.js +3 -4
- package/dist/Profile.js +26 -27
- package/dist/ProtoMap.d.ts +3 -0
- package/dist/ProtoMap.js +288 -294
- package/dist/Routes.js +3 -3
- package/dist/ServiceExceptions.js +11 -12
- package/dist/ServiceProxy.js +19 -23
- package/dist/ShoppingList.js +112 -130
- package/dist/SyncCache.d.ts +3 -0
- package/dist/SyncCache.js +92 -75
- package/dist/SyncKeys.js +8 -8
- package/dist/SyncState.js +5 -5
- package/dist/Tax.js +16 -21
- package/dist/TaxHelper.js +22 -30
- package/dist/TaxType.js +8 -9
- package/dist/UserProfile.js +4 -4
- package/dist/WorkingDays.js +15 -15
- package/dist/index.js +9 -9
- 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
|
-
//
|
|
6
|
-
// a
|
|
7
|
-
//
|
|
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
|
-
//
|
|
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
|
|
28
|
-
//
|
|
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.
|
|
36
|
-
//
|
|
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
|
|
41
|
-
//
|
|
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
|
|
49
|
-
//
|
|
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
|
|
54
|
-
// deliveryAddressId
|
|
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
|
|
66
|
-
// recorded
|
|
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
|
|
3
|
-
//
|
|
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)
|
|
41
|
-
// business has not priced it,
|
|
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
|
|
46
|
-
//
|
|
47
|
-
//
|
|
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
|
|
2
|
-
//
|
|
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
|
|
2
|
-
//
|
|
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
|
|
5
|
-
//
|
|
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:
|
|
2
|
-
// All that
|
|
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
|
|
5
|
-
//
|
|
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
|
|
16
|
-
// owning business's base url
|
|
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
|
|
7
|
-
//
|
|
8
|
-
//
|
|
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
|
-
//
|
|
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
|
|
38
|
-
//
|
|
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
|
|
50
|
-
//
|
|
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
|
|
3
|
-
//
|
|
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
|
|
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
|
|
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
|
|
31
|
-
//
|
|
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
|
|
42
|
-
// A UI shows a price as
|
|
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
|
|
51
|
-
// other, flagged, and
|
|
52
|
-
// never holds one, so only a
|
|
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
|
|
61
|
-
//
|
|
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,
|
|
68
|
-
//
|
|
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
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
//
|
|
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
|
}
|
package/dist/ProductCategory.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import Item from "./Item";
|
|
2
|
-
// A category that groups products, real or the dummy one a Catalog builds
|
|
3
|
-
//
|
|
4
|
-
//
|
|
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
|
|
10
|
-
//
|
|
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
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
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
|
-
//
|
|
49
|
-
// businessId
|
|
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
|
|
54
|
-
// the server finds a business
|
|
55
|
-
//
|
|
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
|
|
68
|
-
// normalized
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
//
|
|
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
|
|
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
|
|
103
|
-
// spaces
|
|
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
|
|
128
|
-
// U+202F) and the
|
|
129
|
-
// byte order mark, and
|
|
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;
|
package/dist/ProtoMap.d.ts
CHANGED
|
@@ -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;
|