@beyondplusmm/doehpos-sdk 0.1.1 → 0.3.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/CHANGELOG.md +36 -0
- package/README.md +13 -5
- package/dist/client.d.ts +9 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -3
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +10 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +16 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/modules/experimental/orders.d.ts +33 -0
- package/dist/modules/experimental/orders.d.ts.map +1 -0
- package/dist/modules/experimental/orders.js +53 -0
- package/dist/modules/experimental/orders.js.map +1 -0
- package/dist/modules/loyalty.d.ts +33 -0
- package/dist/modules/loyalty.d.ts.map +1 -0
- package/dist/modules/{experimental/loyalty.js → loyalty.js} +3 -3
- package/dist/modules/loyalty.js.map +1 -0
- package/dist/types.d.ts +62 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -3
- package/src/client.ts +11 -7
- package/src/errors.ts +12 -0
- package/src/index.ts +24 -5
- package/src/modules/experimental/orders.ts +70 -0
- package/src/modules/{experimental/loyalty.ts → loyalty.ts} +12 -9
- package/src/types.ts +77 -0
- package/dist/modules/experimental/kitchen.d.ts +0 -30
- package/dist/modules/experimental/kitchen.d.ts.map +0 -1
- package/dist/modules/experimental/kitchen.js +0 -32
- package/dist/modules/experimental/kitchen.js.map +0 -1
- package/dist/modules/experimental/loyalty.d.ts +0 -30
- package/dist/modules/experimental/loyalty.d.ts.map +0 -1
- package/dist/modules/experimental/loyalty.js.map +0 -1
- package/src/modules/experimental/kitchen.ts +0 -51
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,42 @@ All notable changes to `@beyondplusmm/doehpos-sdk` are documented here. This pro
|
|
|
4
4
|
[Semantic Versioning](https://semver.org/). The stable surface is `delivery`;
|
|
5
5
|
`@experimental` modules may change in a minor release until they graduate.
|
|
6
6
|
|
|
7
|
+
## 0.3.0
|
|
8
|
+
|
|
9
|
+
### Removed (breaking)
|
|
10
|
+
|
|
11
|
+
- **kitchen** capability — `client.kitchen`, `KitchenModule`, and the
|
|
12
|
+
`TicketCreate` / `TicketResponse` types are removed. Kitchen is an
|
|
13
|
+
operator-facing subsystem (KDS, printers, prep queues, staff workflows), not a
|
|
14
|
+
third-party developer capability, so it no longer ships in the developer SDK or
|
|
15
|
+
the Merchant API docs. Pre-1.0 breaking change per SemVer (a `0.x` minor may
|
|
16
|
+
break). Apps that used `client.kitchen` must remove those calls; `0.2.0`
|
|
17
|
+
remains available on npm with kitchen if needed during migration. The stable
|
|
18
|
+
surface is now `delivery` and `loyalty`.
|
|
19
|
+
|
|
20
|
+
### Added (experimental)
|
|
21
|
+
|
|
22
|
+
- **orders** capability (`client.orders.submit` / `.get`, `POST /v1/orders`) —
|
|
23
|
+
`@experimental`. A server-priced **sales submission**: the client sends a
|
|
24
|
+
basket of `{ sku, qty }`; the server resolves prices/tax/inventory/totals.
|
|
25
|
+
Clients never send prices, a grand total, or a currency. Additive to and
|
|
26
|
+
independent of the legacy money-total `delivery.create`. New typed errors:
|
|
27
|
+
`EmptyOrderError`, `UnknownSkuError`, `UnpricedSkuError`,
|
|
28
|
+
`InsufficientStockError`. **Not live** until the edge façade over the POS sale
|
|
29
|
+
aggregate exists — stays `@experimental` until exercised end to end.
|
|
30
|
+
|
|
31
|
+
## 0.2.0
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- **kitchen** and **loyalty** graduated from `@experimental` to **stable** — now
|
|
36
|
+
exercised end to end by the Expo reference app (`apps/expo-reference`). Their
|
|
37
|
+
module files moved from `modules/experimental/` to `modules/`; the public
|
|
38
|
+
import surface (`import { KitchenModule, LoyaltyModule } from "@beyondplusmm/doehpos-sdk"`)
|
|
39
|
+
is unchanged.
|
|
40
|
+
- `marketplace` and `rider` remain `@experimental` until exercised by the
|
|
41
|
+
reference app.
|
|
42
|
+
|
|
7
43
|
## 0.1.0
|
|
8
44
|
|
|
9
45
|
Initial release — a typed port of the validated golden client.
|
package/README.md
CHANGED
|
@@ -69,11 +69,19 @@ const result = await queue.flush(); // reuses the same key — exactly one order
|
|
|
69
69
|
|
|
70
70
|
## Stability
|
|
71
71
|
|
|
72
|
-
`delivery`
|
|
73
|
-
`
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
72
|
+
`delivery` and `loyalty` are the **stable** surface — both exercised by the Expo
|
|
73
|
+
reference app (`loyalty` graduated in 0.2.0). `marketplace`
|
|
74
|
+
and `rider` remain **`@experimental`** — generated from their OpenAPI specs and
|
|
75
|
+
the golden client, but not yet exercised by the reference app. The **`orders`**
|
|
76
|
+
capability (server-priced sales submission, `POST /v1/orders`) is also
|
|
77
|
+
**`@experimental`** and **not yet live** — its edge façade over the POS sale
|
|
78
|
+
aggregate is not built; the typed surface ships ahead of the backend.
|
|
79
|
+
|
|
80
|
+
**Promotion rule.** A module graduates to stable when its contract has been
|
|
81
|
+
**observed live in sandbox by at least one authoritative client** (the golden
|
|
82
|
+
client and/or the Phase G synthetic probe) **and** is **exercised by the
|
|
83
|
+
reference app**. The phone is not the verifier — it is another consumer of an
|
|
84
|
+
already-proven contract. Evidence promotes an API; a schema only permits it.
|
|
77
85
|
|
|
78
86
|
## Sandbox boundary
|
|
79
87
|
|
package/dist/client.d.ts
CHANGED
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
import { type Environment } from "./config.js";
|
|
13
13
|
import { Transport, type FetchLike } from "./transport.js";
|
|
14
14
|
import { DeliveryModule } from "./modules/delivery.js";
|
|
15
|
-
import {
|
|
16
|
-
import { LoyaltyModule } from "./modules/experimental/loyalty.js";
|
|
15
|
+
import { LoyaltyModule } from "./modules/loyalty.js";
|
|
17
16
|
import { MarketplaceModule } from "./modules/experimental/marketplace.js";
|
|
18
17
|
import { RiderModule } from "./modules/experimental/rider.js";
|
|
18
|
+
import { OrdersModule } from "./modules/experimental/orders.js";
|
|
19
19
|
export interface DoehClientOptions {
|
|
20
20
|
apiKey: string;
|
|
21
21
|
/** "sandbox" (default) or "production". Ignored if baseUrl is given. */
|
|
@@ -37,14 +37,18 @@ export interface DoehClientOptions {
|
|
|
37
37
|
}
|
|
38
38
|
export declare class DoehClient {
|
|
39
39
|
readonly delivery: DeliveryModule;
|
|
40
|
-
/**
|
|
41
|
-
readonly kitchen: KitchenModule;
|
|
42
|
-
/** @experimental Not yet exercised by the reference app. */
|
|
40
|
+
/** Stable since 0.2.0 (reference-app exercised). */
|
|
43
41
|
readonly loyalty: LoyaltyModule;
|
|
44
42
|
/** @experimental Not yet exercised by the reference app. */
|
|
45
43
|
readonly marketplace: MarketplaceModule;
|
|
46
44
|
/** @experimental Not yet exercised by the reference app. */
|
|
47
45
|
readonly rider: RiderModule;
|
|
46
|
+
/**
|
|
47
|
+
* @experimental Server-priced sales submission (`POST /v1/orders`). Additive
|
|
48
|
+
* to `delivery`; the edge façade over the POS sale aggregate is not yet built,
|
|
49
|
+
* so this is not live. See openapi/orders.yaml.
|
|
50
|
+
*/
|
|
51
|
+
readonly orders: OrdersModule;
|
|
48
52
|
private readonly transport;
|
|
49
53
|
constructor(opts: DoehClientOptions);
|
|
50
54
|
/** Internal: the configured transport (used by OfflineQueue wiring/tests). */
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAoC,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAoC,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,qBAAa,UAAU;IACrB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,oDAAoD;IACpD,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAEhC,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IACxC,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAE9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAE1B,IAAI,EAAE,iBAAiB;IAkCnC,8EAA8E;IAC9E,IAAI,UAAU,IAAI,SAAS,CAE1B;CACF"}
|
package/dist/client.js
CHANGED
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
import { BASE_URLS, DEFAULTS, SDK_VERSION } from "./config.js";
|
|
13
13
|
import { Transport } from "./transport.js";
|
|
14
14
|
import { DeliveryModule } from "./modules/delivery.js";
|
|
15
|
-
import {
|
|
16
|
-
import { LoyaltyModule } from "./modules/experimental/loyalty.js";
|
|
15
|
+
import { LoyaltyModule } from "./modules/loyalty.js";
|
|
17
16
|
import { MarketplaceModule } from "./modules/experimental/marketplace.js";
|
|
18
17
|
import { RiderModule } from "./modules/experimental/rider.js";
|
|
18
|
+
import { OrdersModule } from "./modules/experimental/orders.js";
|
|
19
19
|
export class DoehClient {
|
|
20
20
|
constructor(opts) {
|
|
21
21
|
if (!opts.apiKey)
|
|
@@ -41,10 +41,10 @@ export class DoehClient {
|
|
|
41
41
|
sleep: opts.sleep,
|
|
42
42
|
});
|
|
43
43
|
this.delivery = new DeliveryModule(this.transport);
|
|
44
|
-
this.kitchen = new KitchenModule(this.transport);
|
|
45
44
|
this.loyalty = new LoyaltyModule(this.transport);
|
|
46
45
|
this.marketplace = new MarketplaceModule(this.transport);
|
|
47
46
|
this.rider = new RiderModule(this.transport);
|
|
47
|
+
this.orders = new OrdersModule(this.transport);
|
|
48
48
|
}
|
|
49
49
|
/** Internal: the configured transport (used by OfflineQueue wiring/tests). */
|
|
50
50
|
get _transport() {
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAoB,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,SAAS,EAAkB,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAoB,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,SAAS,EAAkB,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAsBhE,MAAM,OAAO,UAAU;IAkBrB,YAAY,IAAuB;QACjC,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnE,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC;QAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS;YAC9B,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,aAAa,WAAW,EAAE;YAC7C,CAAC,CAAC,YAAY,WAAW,EAAE,CAAC;QAE9B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,IAAK,UAAU,CAAC,KAA+B,CAAC;QAC5E,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CACb,uEAAuE;gBACrE,qDAAqD,CACxD,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,IAAI,SAAS,CAAC;YAC7B,OAAO;YACP,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,SAAS;YACT,KAAK,EAAE,SAAS;YAChB,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,SAAS;YAC/C,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU;YAClD,aAAa,EAAE,QAAQ,CAAC,aAAa;YACrC,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACnD,IAAI,CAAC,OAAO,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,CAAC,WAAW,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzD,IAAI,CAAC,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC;IAED,8EAA8E;IAC9E,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -50,6 +50,16 @@ export declare class UnsupportedCurrencyError extends DoehApiError {
|
|
|
50
50
|
}
|
|
51
51
|
export declare class BadBodyError extends DoehApiError {
|
|
52
52
|
}
|
|
53
|
+
export declare class EmptyOrderError extends DoehApiError {
|
|
54
|
+
}
|
|
55
|
+
export declare class UnknownSkuError extends DoehApiError {
|
|
56
|
+
}
|
|
57
|
+
export declare class UnpricedSkuError extends DoehApiError {
|
|
58
|
+
}
|
|
59
|
+
export declare class InsufficientStockError extends DoehApiError {
|
|
60
|
+
}
|
|
61
|
+
export declare class FulfillmentNotAvailableError extends DoehApiError {
|
|
62
|
+
}
|
|
53
63
|
export declare class RateLimitedError extends DoehApiError {
|
|
54
64
|
}
|
|
55
65
|
/** Build the right typed error from an HTTP status + parsed body. */
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAcA,6CAA6C;AAC7C,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAM5B;AAED;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,SAAS;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,+CAA+C;IAC/C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBACd,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAO;CAK/E;AAED,iFAAiF;AACjF,qBAAa,YAAa,SAAQ,SAAS;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;gBAErB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAO;CASjE;AAGD,qBAAa,kBAAmB,SAAQ,YAAY;CAAG;AACvD,qBAAa,kBAAmB,SAAQ,YAAY;CAAG;AACvD,qBAAa,kBAAmB,SAAQ,YAAY;CAAG;AACvD,qBAAa,gBAAiB,SAAQ,YAAY;CAAG;AAGrD,qBAAa,gBAAiB,SAAQ,YAAY;CAAG;AACrD,qBAAa,sBAAuB,SAAQ,YAAY;CAAG;AAG3D,qBAAa,kBAAmB,SAAQ,YAAY;CAAG;AACvD,qBAAa,WAAY,SAAQ,YAAY;CAAG;AAChD,qBAAa,kBAAmB,SAAQ,YAAY;CAAG;AACvD,qBAAa,wBAAyB,SAAQ,YAAY;CAAG;AAC7D,qBAAa,YAAa,SAAQ,YAAY;CAAG;AAGjD,qBAAa,gBAAiB,SAAQ,YAAY;CAAG;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAcA,6CAA6C;AAC7C,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAM5B;AAED;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,SAAS;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,+CAA+C;IAC/C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBACd,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAO;CAK/E;AAED,iFAAiF;AACjF,qBAAa,YAAa,SAAQ,SAAS;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;gBAErB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAO;CASjE;AAGD,qBAAa,kBAAmB,SAAQ,YAAY;CAAG;AACvD,qBAAa,kBAAmB,SAAQ,YAAY;CAAG;AACvD,qBAAa,kBAAmB,SAAQ,YAAY;CAAG;AACvD,qBAAa,gBAAiB,SAAQ,YAAY;CAAG;AAGrD,qBAAa,gBAAiB,SAAQ,YAAY;CAAG;AACrD,qBAAa,sBAAuB,SAAQ,YAAY;CAAG;AAG3D,qBAAa,kBAAmB,SAAQ,YAAY;CAAG;AACvD,qBAAa,WAAY,SAAQ,YAAY;CAAG;AAChD,qBAAa,kBAAmB,SAAQ,YAAY;CAAG;AACvD,qBAAa,wBAAyB,SAAQ,YAAY;CAAG;AAC7D,qBAAa,YAAa,SAAQ,YAAY;CAAG;AAGjD,qBAAa,eAAgB,SAAQ,YAAY;CAAG;AACpD,qBAAa,eAAgB,SAAQ,YAAY;CAAG;AACpD,qBAAa,gBAAiB,SAAQ,YAAY;CAAG;AACrD,qBAAa,sBAAuB,SAAQ,YAAY;CAAG;AAC3D,qBAAa,4BAA6B,SAAQ,YAAY;CAAG;AAGjE,qBAAa,gBAAiB,SAAQ,YAAY;CAAG;AAsBrD,qEAAqE;AACrE,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE,MAAM,GACf,YAAY,CAOd;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAIjD"}
|
package/dist/errors.js
CHANGED
|
@@ -54,6 +54,17 @@ export class UnsupportedCurrencyError extends DoehApiError {
|
|
|
54
54
|
} // EDGE_UNSUPPORTED_CURRENCY
|
|
55
55
|
export class BadBodyError extends DoehApiError {
|
|
56
56
|
} // EDGE_BAD_BODY
|
|
57
|
+
// ── 422 — sales submission / catalog (Orders capability, @experimental) ───────
|
|
58
|
+
export class EmptyOrderError extends DoehApiError {
|
|
59
|
+
} // EDGE_EMPTY_ORDER
|
|
60
|
+
export class UnknownSkuError extends DoehApiError {
|
|
61
|
+
} // EDGE_UNKNOWN_SKU
|
|
62
|
+
export class UnpricedSkuError extends DoehApiError {
|
|
63
|
+
} // EDGE_UNPRICED_SKU
|
|
64
|
+
export class InsufficientStockError extends DoehApiError {
|
|
65
|
+
} // EDGE_INSUFFICIENT_STOCK
|
|
66
|
+
export class FulfillmentNotAvailableError extends DoehApiError {
|
|
67
|
+
} // EDGE_FULFILLMENT_NOT_AVAILABLE (V1: delivery not yet served)
|
|
57
68
|
// ── 429 — rate limited (retried internally; only surfaced when retries exhaust)
|
|
58
69
|
export class RateLimitedError extends DoehApiError {
|
|
59
70
|
}
|
|
@@ -70,6 +81,11 @@ const CODE_TO_CLASS = {
|
|
|
70
81
|
EDGE_INVALID_AMOUNT: InvalidAmountError,
|
|
71
82
|
EDGE_UNSUPPORTED_CURRENCY: UnsupportedCurrencyError,
|
|
72
83
|
EDGE_BAD_BODY: BadBodyError,
|
|
84
|
+
EDGE_EMPTY_ORDER: EmptyOrderError,
|
|
85
|
+
EDGE_UNKNOWN_SKU: UnknownSkuError,
|
|
86
|
+
EDGE_UNPRICED_SKU: UnpricedSkuError,
|
|
87
|
+
EDGE_INSUFFICIENT_STOCK: InsufficientStockError,
|
|
88
|
+
EDGE_FULFILLMENT_NOT_AVAILABLE: FulfillmentNotAvailableError,
|
|
73
89
|
};
|
|
74
90
|
/** Build the right typed error from an HTTP status + parsed body. */
|
|
75
91
|
export function mapApiError(status, body, traceId) {
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAcA,6CAA6C;AAC7C,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;QAC5B,2DAA2D;QAC3D,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,kBAAmB,SAAQ,SAAS;IAI/C,YAAY,OAAe,EAAE,OAA+C,EAAE;QAC5E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC;IACvC,CAAC;CACF;AAED,iFAAiF;AACjF,MAAM,OAAO,YAAa,SAAQ,SAAS;IAMzC,YACE,MAAc,EACd,IAAY,EACZ,OAA4D,EAAE;QAE9D,KAAK,CAAC,QAAQ,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACxB,CAAC;CACF;AAED,gFAAgF;AAChF,MAAM,OAAO,kBAAmB,SAAQ,YAAY;CAAG;AACvD,MAAM,OAAO,kBAAmB,SAAQ,YAAY;CAAG;AACvD,MAAM,OAAO,kBAAmB,SAAQ,YAAY;CAAG;AACvD,MAAM,OAAO,gBAAiB,SAAQ,YAAY;CAAG,CAAC,uBAAuB;AAE7E,gFAAgF;AAChF,MAAM,OAAO,gBAAiB,SAAQ,YAAY;CAAG,CAAC,uBAAuB;AAC7E,MAAM,OAAO,sBAAuB,SAAQ,YAAY;CAAG,CAAC,0BAA0B;AAEtF,gFAAgF;AAChF,MAAM,OAAO,kBAAmB,SAAQ,YAAY;CAAG,CAAC,uBAAuB;AAC/E,MAAM,OAAO,WAAY,SAAQ,YAAY;CAAG,CAAC,gBAAgB;AACjE,MAAM,OAAO,kBAAmB,SAAQ,YAAY;CAAG,CAAC,sBAAsB;AAC9E,MAAM,OAAO,wBAAyB,SAAQ,YAAY;CAAG,CAAC,4BAA4B;AAC1F,MAAM,OAAO,YAAa,SAAQ,YAAY;CAAG,CAAC,gBAAgB;AAElE,iFAAiF;AACjF,MAAM,OAAO,gBAAiB,SAAQ,YAAY;CAAG;AAErD,iFAAiF;AACjF,MAAM,aAAa,GAAwC;IACzD,eAAe,EAAE,kBAAkB;IACnC,eAAe,EAAE,kBAAkB;IACnC,eAAe,EAAE,kBAAkB;IACnC,oBAAoB,EAAE,gBAAgB;IACtC,oBAAoB,EAAE,gBAAgB;IACtC,uBAAuB,EAAE,sBAAsB;IAC/C,oBAAoB,EAAE,kBAAkB;IACxC,aAAa,EAAE,WAAW;IAC1B,mBAAmB,EAAE,kBAAkB;IACvC,yBAAyB,EAAE,wBAAwB;IACnD,aAAa,EAAE,YAAY;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @beyondplusmm/doehpos-sdk — official TypeScript SDK for the Doeh POS public API.
|
|
3
3
|
*
|
|
4
|
-
* A typed port of the validated golden client. The stable surface is `delivery
|
|
5
|
-
*
|
|
6
|
-
* reference app.
|
|
4
|
+
* A typed port of the validated golden client. The stable surface is `delivery`
|
|
5
|
+
* and `loyalty` (reference-app exercised); `marketplace`/`rider` remain
|
|
6
|
+
* @experimental until exercised by the reference app.
|
|
7
7
|
*/
|
|
8
8
|
export { DoehClient } from "./client.js";
|
|
9
9
|
export type { DoehClientOptions } from "./client.js";
|
|
@@ -11,10 +11,11 @@ export { BASE_URLS, SDK_VERSION, type Environment } from "./config.js";
|
|
|
11
11
|
export { generateIdempotencyKey, type UuidFn } from "./idempotency.js";
|
|
12
12
|
export { OfflineQueue, MemoryStorage, type QueueStorage, type QueuedMutation, type DeadLetter, type FlushResult, } from "./queue.js";
|
|
13
13
|
export type { Currency, OrderStatus, OrderCreate, Order, OrderResponse, ErrorBody, CallOptions, } from "./types.js";
|
|
14
|
-
export {
|
|
14
|
+
export type { FulfillmentType, PaymentStatus, OrderLineInput, Customer, Fulfillment, SalesSubmission, OrderLine, OrderTotals, SubmittedOrder, SubmissionResponse, } from "./types.js";
|
|
15
|
+
export { DoehError, DoehTransportError, DoehApiError, ApiKeyInvalidError, ApiKeyExpiredError, ApiKeyRevokedError, EnvMismatchError, ScopeDeniedError, TransportDisabledError, OrderNotFoundError, ReplayError, InvalidAmountError, UnsupportedCurrencyError, BadBodyError, EmptyOrderError, UnknownSkuError, UnpricedSkuError, InsufficientStockError, FulfillmentNotAvailableError, RateLimitedError, isRetryable, mapApiError, } from "./errors.js";
|
|
15
16
|
export { DeliveryModule } from "./modules/delivery.js";
|
|
16
|
-
export {
|
|
17
|
-
export { LoyaltyModule, type EarnInput, type AccountResponse } from "./modules/experimental/loyalty.js";
|
|
17
|
+
export { LoyaltyModule, type EarnInput, type AccountResponse } from "./modules/loyalty.js";
|
|
18
18
|
export { MarketplaceModule, type ListingCreate, type ListingResponse, } from "./modules/experimental/marketplace.js";
|
|
19
19
|
export { RiderModule, type JobCreate, type JobResponse } from "./modules/experimental/rider.js";
|
|
20
|
+
export { OrdersModule } from "./modules/experimental/orders.js";
|
|
20
21
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,sBAAsB,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAEvE,OAAO,EACL,YAAY,EACZ,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,QAAQ,EACR,WAAW,EACX,WAAW,EACX,KAAK,EACL,aAAa,EACb,SAAS,EACT,WAAW,GACZ,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,wBAAwB,EACxB,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,WAAW,GACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,sBAAsB,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAEvE,OAAO,EACL,YAAY,EACZ,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,QAAQ,EACR,WAAW,EACX,WAAW,EACX,KAAK,EACL,aAAa,EACb,SAAS,EACT,WAAW,GACZ,MAAM,YAAY,CAAC;AAGpB,YAAY,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACd,QAAQ,EACR,WAAW,EACX,eAAe,EACf,SAAS,EACT,WAAW,EACX,cAAc,EACd,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,wBAAwB,EACxB,YAAY,EACZ,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,sBAAsB,EACtB,4BAA4B,EAC5B,gBAAgB,EAChB,WAAW,EACX,WAAW,GACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EACL,iBAAiB,EACjB,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @beyondplusmm/doehpos-sdk — official TypeScript SDK for the Doeh POS public API.
|
|
3
3
|
*
|
|
4
|
-
* A typed port of the validated golden client. The stable surface is `delivery
|
|
5
|
-
*
|
|
6
|
-
* reference app.
|
|
4
|
+
* A typed port of the validated golden client. The stable surface is `delivery`
|
|
5
|
+
* and `loyalty` (reference-app exercised); `marketplace`/`rider` remain
|
|
6
|
+
* @experimental until exercised by the reference app.
|
|
7
7
|
*/
|
|
8
8
|
export { DoehClient } from "./client.js";
|
|
9
9
|
export { BASE_URLS, SDK_VERSION } from "./config.js";
|
|
10
10
|
export { generateIdempotencyKey } from "./idempotency.js";
|
|
11
11
|
export { OfflineQueue, MemoryStorage, } from "./queue.js";
|
|
12
12
|
// Error ABI — consumers catch these classes, never parse `code` strings.
|
|
13
|
-
export { DoehError, DoehTransportError, DoehApiError, ApiKeyInvalidError, ApiKeyExpiredError, ApiKeyRevokedError, EnvMismatchError, ScopeDeniedError, TransportDisabledError, OrderNotFoundError, ReplayError, InvalidAmountError, UnsupportedCurrencyError, BadBodyError, RateLimitedError, isRetryable, mapApiError, } from "./errors.js";
|
|
13
|
+
export { DoehError, DoehTransportError, DoehApiError, ApiKeyInvalidError, ApiKeyExpiredError, ApiKeyRevokedError, EnvMismatchError, ScopeDeniedError, TransportDisabledError, OrderNotFoundError, ReplayError, InvalidAmountError, UnsupportedCurrencyError, BadBodyError, EmptyOrderError, UnknownSkuError, UnpricedSkuError, InsufficientStockError, FulfillmentNotAvailableError, RateLimitedError, isRetryable, mapApiError, } from "./errors.js";
|
|
14
14
|
// Module classes + their types (handy for typing app code).
|
|
15
15
|
export { DeliveryModule } from "./modules/delivery.js";
|
|
16
|
-
export {
|
|
17
|
-
export { LoyaltyModule } from "./modules/experimental/loyalty.js";
|
|
16
|
+
export { LoyaltyModule } from "./modules/loyalty.js";
|
|
18
17
|
export { MarketplaceModule, } from "./modules/experimental/marketplace.js";
|
|
19
18
|
export { RiderModule } from "./modules/experimental/rider.js";
|
|
19
|
+
export { OrdersModule } from "./modules/experimental/orders.js";
|
|
20
20
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAoB,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,sBAAsB,EAAe,MAAM,kBAAkB,CAAC;AAEvE,OAAO,EACL,YAAY,EACZ,aAAa,GAKd,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAoB,MAAM,aAAa,CAAC;AAEvE,OAAO,EAAE,sBAAsB,EAAe,MAAM,kBAAkB,CAAC;AAEvE,OAAO,EACL,YAAY,EACZ,aAAa,GAKd,MAAM,YAAY,CAAC;AA0BpB,yEAAyE;AACzE,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,wBAAwB,EACxB,YAAY,EACZ,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,sBAAsB,EACtB,4BAA4B,EAC5B,gBAAgB,EAChB,WAAW,EACX,WAAW,GACZ,MAAM,aAAa,CAAC;AAErB,4DAA4D;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAwC,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EACL,iBAAiB,GAGlB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAoC,MAAM,iCAAiC,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orders (Sales Submission) — EXPERIMENTAL.
|
|
3
|
+
*
|
|
4
|
+
* @experimental The server-priced sales-submission capability. A submission is a
|
|
5
|
+
* basket of {sku, qty}; the server resolves prices from the catalog, applies
|
|
6
|
+
* tax/discounts/promotions/loyalty, deducts inventory, records COGS, and computes
|
|
7
|
+
* all totals. Clients NEVER send prices or a grand total, and never a currency
|
|
8
|
+
* (it is branch-native, derived from the token). This is the typed surface for
|
|
9
|
+
* `POST /v1/orders` (see openapi/orders.yaml).
|
|
10
|
+
*
|
|
11
|
+
* Additive to and independent of the legacy money-total `delivery.create`. Stays
|
|
12
|
+
* @experimental until the edge façade over the POS sale aggregate exists and the
|
|
13
|
+
* capability is exercised live (promotion rule: observed-live + reference-app).
|
|
14
|
+
*/
|
|
15
|
+
import type { Transport } from "../../transport.js";
|
|
16
|
+
import type { CallOptions, SalesSubmission, SubmissionResponse } from "../../types.js";
|
|
17
|
+
export declare class OrdersModule {
|
|
18
|
+
private readonly transport;
|
|
19
|
+
constructor(transport: Transport);
|
|
20
|
+
/**
|
|
21
|
+
* Submit a sale by line items. Returns 201 on first write, or 200 with
|
|
22
|
+
* `idempotent: true` when an Idempotency-Key replays an existing order.
|
|
23
|
+
*
|
|
24
|
+
* Client-side validation is intentionally minimal — it mirrors only the
|
|
25
|
+
* obvious structural rules (non-empty basket, positive integer quantities)
|
|
26
|
+
* so mistakes fail without burning a request. The server remains the source
|
|
27
|
+
* of truth for SKUs, pricing, stock, and totals.
|
|
28
|
+
*/
|
|
29
|
+
submit(input: SalesSubmission, opts?: CallOptions): Promise<SubmissionResponse>;
|
|
30
|
+
/** Read a submitted order (resolved lines + totals) by id. */
|
|
31
|
+
get(id: string, opts?: CallOptions): Promise<SubmissionResponse>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=orders.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orders.d.ts","sourceRoot":"","sources":["../../../src/modules/experimental/orders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAMvF,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAEjD;;;;;;;;OAQG;IACG,MAAM,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAuBzF,8DAA8D;IACxD,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAY3E"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { generateIdempotencyKey } from "../../idempotency.js";
|
|
2
|
+
/** Path ids must match this server-side pattern; we fail fast client-side. */
|
|
3
|
+
const PATH_ID = /^[A-Za-z0-9_]+$/;
|
|
4
|
+
export class OrdersModule {
|
|
5
|
+
constructor(transport) {
|
|
6
|
+
this.transport = transport;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Submit a sale by line items. Returns 201 on first write, or 200 with
|
|
10
|
+
* `idempotent: true` when an Idempotency-Key replays an existing order.
|
|
11
|
+
*
|
|
12
|
+
* Client-side validation is intentionally minimal — it mirrors only the
|
|
13
|
+
* obvious structural rules (non-empty basket, positive integer quantities)
|
|
14
|
+
* so mistakes fail without burning a request. The server remains the source
|
|
15
|
+
* of truth for SKUs, pricing, stock, and totals.
|
|
16
|
+
*/
|
|
17
|
+
async submit(input, opts = {}) {
|
|
18
|
+
if (!Array.isArray(input.lines) || input.lines.length === 0) {
|
|
19
|
+
throw new RangeError("a submission requires at least one line");
|
|
20
|
+
}
|
|
21
|
+
for (const line of input.lines) {
|
|
22
|
+
if (!line || typeof line.sku !== "string" || line.sku.length === 0) {
|
|
23
|
+
throw new RangeError("each line requires a non-empty sku");
|
|
24
|
+
}
|
|
25
|
+
if (!Number.isInteger(line.qty) || line.qty < 1) {
|
|
26
|
+
throw new RangeError(`line ${JSON.stringify(line.sku)} qty must be an integer >= 1`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const { body } = await this.transport.request({
|
|
30
|
+
method: "POST",
|
|
31
|
+
path: "/v1/orders",
|
|
32
|
+
body: input,
|
|
33
|
+
idempotencyKey: opts.idempotencyKey ?? generateIdempotencyKey("orders"),
|
|
34
|
+
traceId: opts.traceId,
|
|
35
|
+
signal: opts.signal,
|
|
36
|
+
});
|
|
37
|
+
return body;
|
|
38
|
+
}
|
|
39
|
+
/** Read a submitted order (resolved lines + totals) by id. */
|
|
40
|
+
async get(id, opts = {}) {
|
|
41
|
+
if (!PATH_ID.test(id)) {
|
|
42
|
+
throw new RangeError(`invalid order id ${JSON.stringify(id)} (must match ${PATH_ID})`);
|
|
43
|
+
}
|
|
44
|
+
const { body } = await this.transport.request({
|
|
45
|
+
method: "GET",
|
|
46
|
+
path: `/v1/orders/${id}`,
|
|
47
|
+
traceId: opts.traceId,
|
|
48
|
+
signal: opts.signal,
|
|
49
|
+
});
|
|
50
|
+
return body;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=orders.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orders.js","sourceRoot":"","sources":["../../../src/modules/experimental/orders.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,8EAA8E;AAC9E,MAAM,OAAO,GAAG,iBAAiB,CAAC;AAElC,MAAM,OAAO,YAAY;IACvB,YAA6B,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IAAG,CAAC;IAErD;;;;;;;;OAQG;IACH,KAAK,CAAC,MAAM,CAAC,KAAsB,EAAE,OAAoB,EAAE;QACzD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5D,MAAM,IAAI,UAAU,CAAC,yCAAyC,CAAC,CAAC;QAClE,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACnE,MAAM,IAAI,UAAU,CAAC,oCAAoC,CAAC,CAAC;YAC7D,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;gBAChD,MAAM,IAAI,UAAU,CAAC,QAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;YACvF,CAAC;QACH,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAqB;YAChE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,YAAY;YAClB,IAAI,EAAE,KAAK;YACX,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,sBAAsB,CAAC,QAAQ,CAAC;YACvE,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8DAA8D;IAC9D,KAAK,CAAC,GAAG,CAAC,EAAU,EAAE,OAAoB,EAAE;QAC1C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,UAAU,CAAC,oBAAoB,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,gBAAgB,OAAO,GAAG,CAAC,CAAC;QACzF,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAqB;YAChE,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,cAAc,EAAE,EAAE;YACxB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loyalty — stable.
|
|
3
|
+
*
|
|
4
|
+
* POST /v1/loyalty/members/{id}/earn award points (auto-provisions the member)
|
|
5
|
+
* GET /v1/loyalty/members/{id} read the member's balance
|
|
6
|
+
*
|
|
7
|
+
* `earn` auto-provisions the member account. Member ids must match [A-Za-z0-9_]+
|
|
8
|
+
* (no hyphens). Graduated from @experimental in 0.2.0 once exercised by the Expo
|
|
9
|
+
* reference app.
|
|
10
|
+
*/
|
|
11
|
+
import type { Transport } from "../transport.js";
|
|
12
|
+
import type { CallOptions } from "../types.js";
|
|
13
|
+
export interface EarnInput {
|
|
14
|
+
points: number;
|
|
15
|
+
reason?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface AccountResponse {
|
|
18
|
+
ok: boolean;
|
|
19
|
+
idempotent?: boolean;
|
|
20
|
+
account: {
|
|
21
|
+
balance: number;
|
|
22
|
+
[k: string]: unknown;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export declare class LoyaltyModule {
|
|
26
|
+
private readonly transport;
|
|
27
|
+
constructor(transport: Transport);
|
|
28
|
+
/** Award points to a member (auto-provisions the account). Idempotent with an Idempotency-Key. */
|
|
29
|
+
earn(memberId: string, input: EarnInput, opts?: CallOptions): Promise<AccountResponse>;
|
|
30
|
+
/** Read a member's balance back by id. */
|
|
31
|
+
getMember(memberId: string, opts?: CallOptions): Promise<AccountResponse>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=loyalty.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loyalty.d.ts","sourceRoot":"","sources":["../../src/modules/loyalty.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AACD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;CACpD;AAID,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAEjD,kGAAkG;IAC5F,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAahG,0CAA0C;IACpC,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;CAUpF"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { generateIdempotencyKey } from "
|
|
1
|
+
import { generateIdempotencyKey } from "../idempotency.js";
|
|
2
2
|
const MEMBER_ID = /^[A-Za-z0-9_]+$/;
|
|
3
3
|
export class LoyaltyModule {
|
|
4
4
|
constructor(transport) {
|
|
5
5
|
this.transport = transport;
|
|
6
6
|
}
|
|
7
|
-
/**
|
|
7
|
+
/** Award points to a member (auto-provisions the account). Idempotent with an Idempotency-Key. */
|
|
8
8
|
async earn(memberId, input, opts = {}) {
|
|
9
9
|
if (!MEMBER_ID.test(memberId))
|
|
10
10
|
throw new RangeError(`invalid member id ${JSON.stringify(memberId)}`);
|
|
@@ -18,7 +18,7 @@ export class LoyaltyModule {
|
|
|
18
18
|
});
|
|
19
19
|
return body;
|
|
20
20
|
}
|
|
21
|
-
/**
|
|
21
|
+
/** Read a member's balance back by id. */
|
|
22
22
|
async getMember(memberId, opts = {}) {
|
|
23
23
|
if (!MEMBER_ID.test(memberId))
|
|
24
24
|
throw new RangeError(`invalid member id ${JSON.stringify(memberId)}`);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loyalty.js","sourceRoot":"","sources":["../../src/modules/loyalty.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAY3D,MAAM,SAAS,GAAG,iBAAiB,CAAC;AAEpC,MAAM,OAAO,aAAa;IACxB,YAA6B,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IAAG,CAAC;IAErD,kGAAkG;IAClG,KAAK,CAAC,IAAI,CAAC,QAAgB,EAAE,KAAgB,EAAE,OAAoB,EAAE;QACnE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,UAAU,CAAC,qBAAqB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACrG,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAkB;YAC7D,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,uBAAuB,QAAQ,OAAO;YAC5C,IAAI,EAAE,KAAK;YACX,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,sBAAsB,CAAC,SAAS,CAAC;YACxE,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0CAA0C;IAC1C,KAAK,CAAC,SAAS,CAAC,QAAgB,EAAE,OAAoB,EAAE;QACtD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,UAAU,CAAC,qBAAqB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACrG,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAkB;YAC7D,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,uBAAuB,QAAQ,EAAE;YACvC,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
package/dist/types.d.ts
CHANGED
|
@@ -37,6 +37,68 @@ export interface ErrorBody {
|
|
|
37
37
|
/** Internal verification step (diagnostic only). */
|
|
38
38
|
step?: string;
|
|
39
39
|
}
|
|
40
|
+
export type FulfillmentType = "pickup" | "delivery" | "dine_in";
|
|
41
|
+
/** One requested line: WHAT and HOW MANY only — never a price, name, or station. */
|
|
42
|
+
export interface OrderLineInput {
|
|
43
|
+
sku: string;
|
|
44
|
+
/** Integer >= 1. */
|
|
45
|
+
qty: number;
|
|
46
|
+
/** Optional catalog modifier ids; priced server-side. */
|
|
47
|
+
modifier_ids?: string[];
|
|
48
|
+
}
|
|
49
|
+
export interface Customer {
|
|
50
|
+
/** E.164, e.g. +95912345678. */
|
|
51
|
+
phone?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface Fulfillment {
|
|
54
|
+
type?: FulfillmentType;
|
|
55
|
+
}
|
|
56
|
+
/** Request body for POST /v1/orders. No currency, no prices, no total. */
|
|
57
|
+
export interface SalesSubmission {
|
|
58
|
+
lines: OrderLineInput[];
|
|
59
|
+
customer?: Customer;
|
|
60
|
+
fulfillment?: Fulfillment;
|
|
61
|
+
}
|
|
62
|
+
/** A line as resolved and priced by the server. */
|
|
63
|
+
export interface OrderLine {
|
|
64
|
+
sku: string;
|
|
65
|
+
name?: string;
|
|
66
|
+
qty: number;
|
|
67
|
+
unit_price_minor: number;
|
|
68
|
+
line_total_minor: number;
|
|
69
|
+
tax_minor?: number;
|
|
70
|
+
}
|
|
71
|
+
export interface OrderTotals {
|
|
72
|
+
currency: Currency;
|
|
73
|
+
subtotal_minor: number;
|
|
74
|
+
discount_minor: number;
|
|
75
|
+
tax_minor: number;
|
|
76
|
+
grand_total_minor: number;
|
|
77
|
+
}
|
|
78
|
+
/** Settlement state of a submitted order. V1 is always "unpaid" (pay_later). */
|
|
79
|
+
export type PaymentStatus = "unpaid" | "paid";
|
|
80
|
+
export interface SubmittedOrder {
|
|
81
|
+
id: string;
|
|
82
|
+
status: OrderStatus;
|
|
83
|
+
/** V1: always "unpaid" — a submission is purchase intent, not settlement. */
|
|
84
|
+
payment_status: PaymentStatus;
|
|
85
|
+
shop_id: number;
|
|
86
|
+
branch_id: number;
|
|
87
|
+
lines: OrderLine[];
|
|
88
|
+
totals: OrderTotals;
|
|
89
|
+
customer?: Customer;
|
|
90
|
+
fulfillment?: Fulfillment;
|
|
91
|
+
created_at_utc: string;
|
|
92
|
+
/** created_at rendered in the branch's native timezone. */
|
|
93
|
+
created_at_local: string;
|
|
94
|
+
idempotency_key?: string;
|
|
95
|
+
}
|
|
96
|
+
export interface SubmissionResponse {
|
|
97
|
+
ok: boolean;
|
|
98
|
+
/** true if this was an idempotent replay (HTTP 200 instead of 201). */
|
|
99
|
+
idempotent?: boolean;
|
|
100
|
+
order: SubmittedOrder;
|
|
101
|
+
}
|
|
40
102
|
/** Per-call options that map onto request headers. */
|
|
41
103
|
export interface CallOptions {
|
|
42
104
|
/**
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAErE,MAAM,MAAM,WAAW,GACnB,SAAS,GACT,WAAW,GACX,YAAY,GACZ,WAAW,GACX,WAAW,CAAC;AAEhB,iDAAiD;AACjD,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,oDAAoD;IACpD,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,2DAA2D;IAC3D,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,uEAAuE;IACvE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,KAAK,CAAC;CACd;AAED,qEAAqE;AACrE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,KAAK,CAAC;IACV,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,sDAAsD;AACtD,MAAM,WAAW,WAAW;IAC1B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beyondplusmm/doehpos-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Official TypeScript SDK for the Doeh POS public API — a typed port of the validated golden client.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -21,8 +21,9 @@
|
|
|
21
21
|
],
|
|
22
22
|
"sideEffects": false,
|
|
23
23
|
"scripts": {
|
|
24
|
-
"
|
|
25
|
-
"
|
|
24
|
+
"clean": "rm -rf dist",
|
|
25
|
+
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
26
|
+
"prepack": "rm -rf dist && tsc -p tsconfig.json",
|
|
26
27
|
"test": "pnpm build && node --test test/",
|
|
27
28
|
"test:integration": "pnpm build && node test/golden.integration.mjs"
|
|
28
29
|
},
|
package/src/client.ts
CHANGED
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
import { BASE_URLS, DEFAULTS, SDK_VERSION, type Environment } from "./config.js";
|
|
13
13
|
import { Transport, type FetchLike } from "./transport.js";
|
|
14
14
|
import { DeliveryModule } from "./modules/delivery.js";
|
|
15
|
-
import {
|
|
16
|
-
import { LoyaltyModule } from "./modules/experimental/loyalty.js";
|
|
15
|
+
import { LoyaltyModule } from "./modules/loyalty.js";
|
|
17
16
|
import { MarketplaceModule } from "./modules/experimental/marketplace.js";
|
|
18
17
|
import { RiderModule } from "./modules/experimental/rider.js";
|
|
18
|
+
import { OrdersModule } from "./modules/experimental/orders.js";
|
|
19
19
|
|
|
20
20
|
export interface DoehClientOptions {
|
|
21
21
|
apiKey: string;
|
|
@@ -39,15 +39,19 @@ export interface DoehClientOptions {
|
|
|
39
39
|
|
|
40
40
|
export class DoehClient {
|
|
41
41
|
readonly delivery: DeliveryModule;
|
|
42
|
-
|
|
43
|
-
/** @experimental Not yet exercised by the reference app. */
|
|
44
|
-
readonly kitchen: KitchenModule;
|
|
45
|
-
/** @experimental Not yet exercised by the reference app. */
|
|
42
|
+
/** Stable since 0.2.0 (reference-app exercised). */
|
|
46
43
|
readonly loyalty: LoyaltyModule;
|
|
44
|
+
|
|
47
45
|
/** @experimental Not yet exercised by the reference app. */
|
|
48
46
|
readonly marketplace: MarketplaceModule;
|
|
49
47
|
/** @experimental Not yet exercised by the reference app. */
|
|
50
48
|
readonly rider: RiderModule;
|
|
49
|
+
/**
|
|
50
|
+
* @experimental Server-priced sales submission (`POST /v1/orders`). Additive
|
|
51
|
+
* to `delivery`; the edge façade over the POS sale aggregate is not yet built,
|
|
52
|
+
* so this is not live. See openapi/orders.yaml.
|
|
53
|
+
*/
|
|
54
|
+
readonly orders: OrdersModule;
|
|
51
55
|
|
|
52
56
|
private readonly transport: Transport;
|
|
53
57
|
|
|
@@ -79,10 +83,10 @@ export class DoehClient {
|
|
|
79
83
|
});
|
|
80
84
|
|
|
81
85
|
this.delivery = new DeliveryModule(this.transport);
|
|
82
|
-
this.kitchen = new KitchenModule(this.transport);
|
|
83
86
|
this.loyalty = new LoyaltyModule(this.transport);
|
|
84
87
|
this.marketplace = new MarketplaceModule(this.transport);
|
|
85
88
|
this.rider = new RiderModule(this.transport);
|
|
89
|
+
this.orders = new OrdersModule(this.transport);
|
|
86
90
|
}
|
|
87
91
|
|
|
88
92
|
/** Internal: the configured transport (used by OfflineQueue wiring/tests). */
|
package/src/errors.ts
CHANGED
|
@@ -75,6 +75,13 @@ export class InvalidAmountError extends DoehApiError {} // EDGE_INVALID_AMOUNT
|
|
|
75
75
|
export class UnsupportedCurrencyError extends DoehApiError {} // EDGE_UNSUPPORTED_CURRENCY
|
|
76
76
|
export class BadBodyError extends DoehApiError {} // EDGE_BAD_BODY
|
|
77
77
|
|
|
78
|
+
// ── 422 — sales submission / catalog (Orders capability, @experimental) ───────
|
|
79
|
+
export class EmptyOrderError extends DoehApiError {} // EDGE_EMPTY_ORDER
|
|
80
|
+
export class UnknownSkuError extends DoehApiError {} // EDGE_UNKNOWN_SKU
|
|
81
|
+
export class UnpricedSkuError extends DoehApiError {} // EDGE_UNPRICED_SKU
|
|
82
|
+
export class InsufficientStockError extends DoehApiError {} // EDGE_INSUFFICIENT_STOCK
|
|
83
|
+
export class FulfillmentNotAvailableError extends DoehApiError {} // EDGE_FULFILLMENT_NOT_AVAILABLE (V1: delivery not yet served)
|
|
84
|
+
|
|
78
85
|
// ── 429 — rate limited (retried internally; only surfaced when retries exhaust)
|
|
79
86
|
export class RateLimitedError extends DoehApiError {}
|
|
80
87
|
|
|
@@ -91,6 +98,11 @@ const CODE_TO_CLASS: Record<string, typeof DoehApiError> = {
|
|
|
91
98
|
EDGE_INVALID_AMOUNT: InvalidAmountError,
|
|
92
99
|
EDGE_UNSUPPORTED_CURRENCY: UnsupportedCurrencyError,
|
|
93
100
|
EDGE_BAD_BODY: BadBodyError,
|
|
101
|
+
EDGE_EMPTY_ORDER: EmptyOrderError,
|
|
102
|
+
EDGE_UNKNOWN_SKU: UnknownSkuError,
|
|
103
|
+
EDGE_UNPRICED_SKU: UnpricedSkuError,
|
|
104
|
+
EDGE_INSUFFICIENT_STOCK: InsufficientStockError,
|
|
105
|
+
EDGE_FULFILLMENT_NOT_AVAILABLE: FulfillmentNotAvailableError,
|
|
94
106
|
};
|
|
95
107
|
|
|
96
108
|
/** Build the right typed error from an HTTP status + parsed body. */
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @beyondplusmm/doehpos-sdk — official TypeScript SDK for the Doeh POS public API.
|
|
3
3
|
*
|
|
4
|
-
* A typed port of the validated golden client. The stable surface is `delivery
|
|
5
|
-
*
|
|
6
|
-
* reference app.
|
|
4
|
+
* A typed port of the validated golden client. The stable surface is `delivery`
|
|
5
|
+
* and `loyalty` (reference-app exercised); `marketplace`/`rider` remain
|
|
6
|
+
* @experimental until exercised by the reference app.
|
|
7
7
|
*/
|
|
8
8
|
export { DoehClient } from "./client.js";
|
|
9
9
|
export type { DoehClientOptions } from "./client.js";
|
|
@@ -31,6 +31,20 @@ export type {
|
|
|
31
31
|
CallOptions,
|
|
32
32
|
} from "./types.js";
|
|
33
33
|
|
|
34
|
+
// Orders (Sales Submission) capability types — @experimental.
|
|
35
|
+
export type {
|
|
36
|
+
FulfillmentType,
|
|
37
|
+
PaymentStatus,
|
|
38
|
+
OrderLineInput,
|
|
39
|
+
Customer,
|
|
40
|
+
Fulfillment,
|
|
41
|
+
SalesSubmission,
|
|
42
|
+
OrderLine,
|
|
43
|
+
OrderTotals,
|
|
44
|
+
SubmittedOrder,
|
|
45
|
+
SubmissionResponse,
|
|
46
|
+
} from "./types.js";
|
|
47
|
+
|
|
34
48
|
// Error ABI — consumers catch these classes, never parse `code` strings.
|
|
35
49
|
export {
|
|
36
50
|
DoehError,
|
|
@@ -47,6 +61,11 @@ export {
|
|
|
47
61
|
InvalidAmountError,
|
|
48
62
|
UnsupportedCurrencyError,
|
|
49
63
|
BadBodyError,
|
|
64
|
+
EmptyOrderError,
|
|
65
|
+
UnknownSkuError,
|
|
66
|
+
UnpricedSkuError,
|
|
67
|
+
InsufficientStockError,
|
|
68
|
+
FulfillmentNotAvailableError,
|
|
50
69
|
RateLimitedError,
|
|
51
70
|
isRetryable,
|
|
52
71
|
mapApiError,
|
|
@@ -54,11 +73,11 @@ export {
|
|
|
54
73
|
|
|
55
74
|
// Module classes + their types (handy for typing app code).
|
|
56
75
|
export { DeliveryModule } from "./modules/delivery.js";
|
|
57
|
-
export {
|
|
58
|
-
export { LoyaltyModule, type EarnInput, type AccountResponse } from "./modules/experimental/loyalty.js";
|
|
76
|
+
export { LoyaltyModule, type EarnInput, type AccountResponse } from "./modules/loyalty.js";
|
|
59
77
|
export {
|
|
60
78
|
MarketplaceModule,
|
|
61
79
|
type ListingCreate,
|
|
62
80
|
type ListingResponse,
|
|
63
81
|
} from "./modules/experimental/marketplace.js";
|
|
64
82
|
export { RiderModule, type JobCreate, type JobResponse } from "./modules/experimental/rider.js";
|
|
83
|
+
export { OrdersModule } from "./modules/experimental/orders.js";
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orders (Sales Submission) — EXPERIMENTAL.
|
|
3
|
+
*
|
|
4
|
+
* @experimental The server-priced sales-submission capability. A submission is a
|
|
5
|
+
* basket of {sku, qty}; the server resolves prices from the catalog, applies
|
|
6
|
+
* tax/discounts/promotions/loyalty, deducts inventory, records COGS, and computes
|
|
7
|
+
* all totals. Clients NEVER send prices or a grand total, and never a currency
|
|
8
|
+
* (it is branch-native, derived from the token). This is the typed surface for
|
|
9
|
+
* `POST /v1/orders` (see openapi/orders.yaml).
|
|
10
|
+
*
|
|
11
|
+
* Additive to and independent of the legacy money-total `delivery.create`. Stays
|
|
12
|
+
* @experimental until the edge façade over the POS sale aggregate exists and the
|
|
13
|
+
* capability is exercised live (promotion rule: observed-live + reference-app).
|
|
14
|
+
*/
|
|
15
|
+
import type { Transport } from "../../transport.js";
|
|
16
|
+
import type { CallOptions, SalesSubmission, SubmissionResponse } from "../../types.js";
|
|
17
|
+
import { generateIdempotencyKey } from "../../idempotency.js";
|
|
18
|
+
|
|
19
|
+
/** Path ids must match this server-side pattern; we fail fast client-side. */
|
|
20
|
+
const PATH_ID = /^[A-Za-z0-9_]+$/;
|
|
21
|
+
|
|
22
|
+
export class OrdersModule {
|
|
23
|
+
constructor(private readonly transport: Transport) {}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Submit a sale by line items. Returns 201 on first write, or 200 with
|
|
27
|
+
* `idempotent: true` when an Idempotency-Key replays an existing order.
|
|
28
|
+
*
|
|
29
|
+
* Client-side validation is intentionally minimal — it mirrors only the
|
|
30
|
+
* obvious structural rules (non-empty basket, positive integer quantities)
|
|
31
|
+
* so mistakes fail without burning a request. The server remains the source
|
|
32
|
+
* of truth for SKUs, pricing, stock, and totals.
|
|
33
|
+
*/
|
|
34
|
+
async submit(input: SalesSubmission, opts: CallOptions = {}): Promise<SubmissionResponse> {
|
|
35
|
+
if (!Array.isArray(input.lines) || input.lines.length === 0) {
|
|
36
|
+
throw new RangeError("a submission requires at least one line");
|
|
37
|
+
}
|
|
38
|
+
for (const line of input.lines) {
|
|
39
|
+
if (!line || typeof line.sku !== "string" || line.sku.length === 0) {
|
|
40
|
+
throw new RangeError("each line requires a non-empty sku");
|
|
41
|
+
}
|
|
42
|
+
if (!Number.isInteger(line.qty) || line.qty < 1) {
|
|
43
|
+
throw new RangeError(`line ${JSON.stringify(line.sku)} qty must be an integer >= 1`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const { body } = await this.transport.request<SubmissionResponse>({
|
|
47
|
+
method: "POST",
|
|
48
|
+
path: "/v1/orders",
|
|
49
|
+
body: input,
|
|
50
|
+
idempotencyKey: opts.idempotencyKey ?? generateIdempotencyKey("orders"),
|
|
51
|
+
traceId: opts.traceId,
|
|
52
|
+
signal: opts.signal,
|
|
53
|
+
});
|
|
54
|
+
return body;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Read a submitted order (resolved lines + totals) by id. */
|
|
58
|
+
async get(id: string, opts: CallOptions = {}): Promise<SubmissionResponse> {
|
|
59
|
+
if (!PATH_ID.test(id)) {
|
|
60
|
+
throw new RangeError(`invalid order id ${JSON.stringify(id)} (must match ${PATH_ID})`);
|
|
61
|
+
}
|
|
62
|
+
const { body } = await this.transport.request<SubmissionResponse>({
|
|
63
|
+
method: "GET",
|
|
64
|
+
path: `/v1/orders/${id}`,
|
|
65
|
+
traceId: opts.traceId,
|
|
66
|
+
signal: opts.signal,
|
|
67
|
+
});
|
|
68
|
+
return body;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Loyalty —
|
|
2
|
+
* Loyalty — stable.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* POST /v1/loyalty/members/{id}/earn award points (auto-provisions the member)
|
|
5
|
+
* GET /v1/loyalty/members/{id} read the member's balance
|
|
6
|
+
*
|
|
7
|
+
* `earn` auto-provisions the member account. Member ids must match [A-Za-z0-9_]+
|
|
8
|
+
* (no hyphens). Graduated from @experimental in 0.2.0 once exercised by the Expo
|
|
9
|
+
* reference app.
|
|
7
10
|
*/
|
|
8
|
-
import type { Transport } from "
|
|
9
|
-
import type { CallOptions } from "
|
|
10
|
-
import { generateIdempotencyKey } from "
|
|
11
|
+
import type { Transport } from "../transport.js";
|
|
12
|
+
import type { CallOptions } from "../types.js";
|
|
13
|
+
import { generateIdempotencyKey } from "../idempotency.js";
|
|
11
14
|
|
|
12
15
|
export interface EarnInput {
|
|
13
16
|
points: number;
|
|
@@ -24,7 +27,7 @@ const MEMBER_ID = /^[A-Za-z0-9_]+$/;
|
|
|
24
27
|
export class LoyaltyModule {
|
|
25
28
|
constructor(private readonly transport: Transport) {}
|
|
26
29
|
|
|
27
|
-
/**
|
|
30
|
+
/** Award points to a member (auto-provisions the account). Idempotent with an Idempotency-Key. */
|
|
28
31
|
async earn(memberId: string, input: EarnInput, opts: CallOptions = {}): Promise<AccountResponse> {
|
|
29
32
|
if (!MEMBER_ID.test(memberId)) throw new RangeError(`invalid member id ${JSON.stringify(memberId)}`);
|
|
30
33
|
const { body } = await this.transport.request<AccountResponse>({
|
|
@@ -38,7 +41,7 @@ export class LoyaltyModule {
|
|
|
38
41
|
return body;
|
|
39
42
|
}
|
|
40
43
|
|
|
41
|
-
/**
|
|
44
|
+
/** Read a member's balance back by id. */
|
|
42
45
|
async getMember(memberId: string, opts: CallOptions = {}): Promise<AccountResponse> {
|
|
43
46
|
if (!MEMBER_ID.test(memberId)) throw new RangeError(`invalid member id ${JSON.stringify(memberId)}`);
|
|
44
47
|
const { body } = await this.transport.request<AccountResponse>({
|
package/src/types.ts
CHANGED
|
@@ -49,6 +49,83 @@ export interface ErrorBody {
|
|
|
49
49
|
step?: string;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
// ── Orders (Sales Submission) capability — @experimental ─────────────────────
|
|
53
|
+
// A submission is a basket of {sku, qty}; the server owns pricing/tax/inventory/
|
|
54
|
+
// totals. Clients NEVER send prices or a grand total. Currency is branch-native
|
|
55
|
+
// (token-derived) and returned in the response. See openapi/orders.yaml.
|
|
56
|
+
|
|
57
|
+
export type FulfillmentType = "pickup" | "delivery" | "dine_in";
|
|
58
|
+
|
|
59
|
+
/** One requested line: WHAT and HOW MANY only — never a price, name, or station. */
|
|
60
|
+
export interface OrderLineInput {
|
|
61
|
+
sku: string;
|
|
62
|
+
/** Integer >= 1. */
|
|
63
|
+
qty: number;
|
|
64
|
+
/** Optional catalog modifier ids; priced server-side. */
|
|
65
|
+
modifier_ids?: string[];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface Customer {
|
|
69
|
+
/** E.164, e.g. +95912345678. */
|
|
70
|
+
phone?: string;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface Fulfillment {
|
|
74
|
+
type?: FulfillmentType;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Request body for POST /v1/orders. No currency, no prices, no total. */
|
|
78
|
+
export interface SalesSubmission {
|
|
79
|
+
lines: OrderLineInput[];
|
|
80
|
+
customer?: Customer;
|
|
81
|
+
fulfillment?: Fulfillment;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** A line as resolved and priced by the server. */
|
|
85
|
+
export interface OrderLine {
|
|
86
|
+
sku: string;
|
|
87
|
+
name?: string;
|
|
88
|
+
qty: number;
|
|
89
|
+
unit_price_minor: number;
|
|
90
|
+
line_total_minor: number;
|
|
91
|
+
tax_minor?: number;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface OrderTotals {
|
|
95
|
+
currency: Currency;
|
|
96
|
+
subtotal_minor: number;
|
|
97
|
+
discount_minor: number;
|
|
98
|
+
tax_minor: number;
|
|
99
|
+
grand_total_minor: number;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Settlement state of a submitted order. V1 is always "unpaid" (pay_later). */
|
|
103
|
+
export type PaymentStatus = "unpaid" | "paid";
|
|
104
|
+
|
|
105
|
+
export interface SubmittedOrder {
|
|
106
|
+
id: string;
|
|
107
|
+
status: OrderStatus;
|
|
108
|
+
/** V1: always "unpaid" — a submission is purchase intent, not settlement. */
|
|
109
|
+
payment_status: PaymentStatus;
|
|
110
|
+
shop_id: number;
|
|
111
|
+
branch_id: number;
|
|
112
|
+
lines: OrderLine[];
|
|
113
|
+
totals: OrderTotals;
|
|
114
|
+
customer?: Customer;
|
|
115
|
+
fulfillment?: Fulfillment;
|
|
116
|
+
created_at_utc: string;
|
|
117
|
+
/** created_at rendered in the branch's native timezone. */
|
|
118
|
+
created_at_local: string;
|
|
119
|
+
idempotency_key?: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface SubmissionResponse {
|
|
123
|
+
ok: boolean;
|
|
124
|
+
/** true if this was an idempotent replay (HTTP 200 instead of 201). */
|
|
125
|
+
idempotent?: boolean;
|
|
126
|
+
order: SubmittedOrder;
|
|
127
|
+
}
|
|
128
|
+
|
|
52
129
|
/** Per-call options that map onto request headers. */
|
|
53
130
|
export interface CallOptions {
|
|
54
131
|
/**
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Kitchen — EXPERIMENTAL.
|
|
3
|
-
*
|
|
4
|
-
* @experimental Schema/golden-client-derived; not yet exercised by the Expo
|
|
5
|
-
* reference app. Shapes may change before they graduate to the stable contract.
|
|
6
|
-
* Promotion rule: experimental -> reference-app exercised -> stable.
|
|
7
|
-
*/
|
|
8
|
-
import type { Transport } from "../../transport.js";
|
|
9
|
-
import type { CallOptions } from "../../types.js";
|
|
10
|
-
export interface TicketCreate {
|
|
11
|
-
station: string;
|
|
12
|
-
items: string[];
|
|
13
|
-
}
|
|
14
|
-
export interface TicketResponse {
|
|
15
|
-
ok: boolean;
|
|
16
|
-
idempotent?: boolean;
|
|
17
|
-
ticket: {
|
|
18
|
-
id: string;
|
|
19
|
-
[k: string]: unknown;
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
export declare class KitchenModule {
|
|
23
|
-
private readonly transport;
|
|
24
|
-
constructor(transport: Transport);
|
|
25
|
-
/** @experimental */
|
|
26
|
-
createTicket(input: TicketCreate, opts?: CallOptions): Promise<TicketResponse>;
|
|
27
|
-
/** @experimental */
|
|
28
|
-
getTicket(id: string, opts?: CallOptions): Promise<TicketResponse>;
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=kitchen.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"kitchen.d.ts","sourceRoot":"","sources":["../../../src/modules/experimental/kitchen.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AACD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;CAC9C;AAID,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAEjD,oBAAoB;IACd,YAAY,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,cAAc,CAAC;IAYxF,oBAAoB;IACd,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,cAAc,CAAC;CAU7E"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { generateIdempotencyKey } from "../../idempotency.js";
|
|
2
|
-
const PATH_ID = /^[A-Za-z0-9_]+$/;
|
|
3
|
-
export class KitchenModule {
|
|
4
|
-
constructor(transport) {
|
|
5
|
-
this.transport = transport;
|
|
6
|
-
}
|
|
7
|
-
/** @experimental */
|
|
8
|
-
async createTicket(input, opts = {}) {
|
|
9
|
-
const { body } = await this.transport.request({
|
|
10
|
-
method: "POST",
|
|
11
|
-
path: "/v1/kitchen/tickets",
|
|
12
|
-
body: input,
|
|
13
|
-
idempotencyKey: opts.idempotencyKey ?? generateIdempotencyKey("kitchen"),
|
|
14
|
-
traceId: opts.traceId,
|
|
15
|
-
signal: opts.signal,
|
|
16
|
-
});
|
|
17
|
-
return body;
|
|
18
|
-
}
|
|
19
|
-
/** @experimental */
|
|
20
|
-
async getTicket(id, opts = {}) {
|
|
21
|
-
if (!PATH_ID.test(id))
|
|
22
|
-
throw new RangeError(`invalid ticket id ${JSON.stringify(id)}`);
|
|
23
|
-
const { body } = await this.transport.request({
|
|
24
|
-
method: "GET",
|
|
25
|
-
path: `/v1/kitchen/tickets/${id}`,
|
|
26
|
-
traceId: opts.traceId,
|
|
27
|
-
signal: opts.signal,
|
|
28
|
-
});
|
|
29
|
-
return body;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
//# sourceMappingURL=kitchen.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"kitchen.js","sourceRoot":"","sources":["../../../src/modules/experimental/kitchen.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAY9D,MAAM,OAAO,GAAG,iBAAiB,CAAC;AAElC,MAAM,OAAO,aAAa;IACxB,YAA6B,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IAAG,CAAC;IAErD,oBAAoB;IACpB,KAAK,CAAC,YAAY,CAAC,KAAmB,EAAE,OAAoB,EAAE;QAC5D,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAiB;YAC5D,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,qBAAqB;YAC3B,IAAI,EAAE,KAAK;YACX,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,sBAAsB,CAAC,SAAS,CAAC;YACxE,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,oBAAoB;IACpB,KAAK,CAAC,SAAS,CAAC,EAAU,EAAE,OAAoB,EAAE;QAChD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,UAAU,CAAC,qBAAqB,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACvF,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAiB;YAC5D,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,uBAAuB,EAAE,EAAE;YACjC,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Loyalty — EXPERIMENTAL.
|
|
3
|
-
*
|
|
4
|
-
* @experimental Schema/golden-client-derived; not yet exercised by the Expo
|
|
5
|
-
* reference app. `earn` auto-provisions the member account. Member ids must
|
|
6
|
-
* match [A-Za-z0-9_]+ (no hyphens).
|
|
7
|
-
*/
|
|
8
|
-
import type { Transport } from "../../transport.js";
|
|
9
|
-
import type { CallOptions } from "../../types.js";
|
|
10
|
-
export interface EarnInput {
|
|
11
|
-
points: number;
|
|
12
|
-
reason?: string;
|
|
13
|
-
}
|
|
14
|
-
export interface AccountResponse {
|
|
15
|
-
ok: boolean;
|
|
16
|
-
idempotent?: boolean;
|
|
17
|
-
account: {
|
|
18
|
-
balance: number;
|
|
19
|
-
[k: string]: unknown;
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
export declare class LoyaltyModule {
|
|
23
|
-
private readonly transport;
|
|
24
|
-
constructor(transport: Transport);
|
|
25
|
-
/** @experimental */
|
|
26
|
-
earn(memberId: string, input: EarnInput, opts?: CallOptions): Promise<AccountResponse>;
|
|
27
|
-
/** @experimental */
|
|
28
|
-
getMember(memberId: string, opts?: CallOptions): Promise<AccountResponse>;
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=loyalty.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"loyalty.d.ts","sourceRoot":"","sources":["../../../src/modules/experimental/loyalty.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AACD,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;CACpD;AAID,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAEjD,oBAAoB;IACd,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;IAahG,oBAAoB;IACd,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;CAUpF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"loyalty.js","sourceRoot":"","sources":["../../../src/modules/experimental/loyalty.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAY9D,MAAM,SAAS,GAAG,iBAAiB,CAAC;AAEpC,MAAM,OAAO,aAAa;IACxB,YAA6B,SAAoB;QAApB,cAAS,GAAT,SAAS,CAAW;IAAG,CAAC;IAErD,oBAAoB;IACpB,KAAK,CAAC,IAAI,CAAC,QAAgB,EAAE,KAAgB,EAAE,OAAoB,EAAE;QACnE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,UAAU,CAAC,qBAAqB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACrG,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAkB;YAC7D,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,uBAAuB,QAAQ,OAAO;YAC5C,IAAI,EAAE,KAAK;YACX,cAAc,EAAE,IAAI,CAAC,cAAc,IAAI,sBAAsB,CAAC,SAAS,CAAC;YACxE,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,oBAAoB;IACpB,KAAK,CAAC,SAAS,CAAC,QAAgB,EAAE,OAAoB,EAAE;QACtD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,UAAU,CAAC,qBAAqB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACrG,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAkB;YAC7D,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,uBAAuB,QAAQ,EAAE;YACvC,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Kitchen — EXPERIMENTAL.
|
|
3
|
-
*
|
|
4
|
-
* @experimental Schema/golden-client-derived; not yet exercised by the Expo
|
|
5
|
-
* reference app. Shapes may change before they graduate to the stable contract.
|
|
6
|
-
* Promotion rule: experimental -> reference-app exercised -> stable.
|
|
7
|
-
*/
|
|
8
|
-
import type { Transport } from "../../transport.js";
|
|
9
|
-
import type { CallOptions } from "../../types.js";
|
|
10
|
-
import { generateIdempotencyKey } from "../../idempotency.js";
|
|
11
|
-
|
|
12
|
-
export interface TicketCreate {
|
|
13
|
-
station: string;
|
|
14
|
-
items: string[];
|
|
15
|
-
}
|
|
16
|
-
export interface TicketResponse {
|
|
17
|
-
ok: boolean;
|
|
18
|
-
idempotent?: boolean;
|
|
19
|
-
ticket: { id: string; [k: string]: unknown };
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const PATH_ID = /^[A-Za-z0-9_]+$/;
|
|
23
|
-
|
|
24
|
-
export class KitchenModule {
|
|
25
|
-
constructor(private readonly transport: Transport) {}
|
|
26
|
-
|
|
27
|
-
/** @experimental */
|
|
28
|
-
async createTicket(input: TicketCreate, opts: CallOptions = {}): Promise<TicketResponse> {
|
|
29
|
-
const { body } = await this.transport.request<TicketResponse>({
|
|
30
|
-
method: "POST",
|
|
31
|
-
path: "/v1/kitchen/tickets",
|
|
32
|
-
body: input,
|
|
33
|
-
idempotencyKey: opts.idempotencyKey ?? generateIdempotencyKey("kitchen"),
|
|
34
|
-
traceId: opts.traceId,
|
|
35
|
-
signal: opts.signal,
|
|
36
|
-
});
|
|
37
|
-
return body;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** @experimental */
|
|
41
|
-
async getTicket(id: string, opts: CallOptions = {}): Promise<TicketResponse> {
|
|
42
|
-
if (!PATH_ID.test(id)) throw new RangeError(`invalid ticket id ${JSON.stringify(id)}`);
|
|
43
|
-
const { body } = await this.transport.request<TicketResponse>({
|
|
44
|
-
method: "GET",
|
|
45
|
-
path: `/v1/kitchen/tickets/${id}`,
|
|
46
|
-
traceId: opts.traceId,
|
|
47
|
-
signal: opts.signal,
|
|
48
|
-
});
|
|
49
|
-
return body;
|
|
50
|
-
}
|
|
51
|
-
}
|