@retalia/pos-components 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +24 -1
  2. package/fesm2022/retalia-pos-components-services.mjs +171 -0
  3. package/fesm2022/retalia-pos-components-services.mjs.map +1 -0
  4. package/fesm2022/retalia-pos-components.mjs +1089 -0
  5. package/fesm2022/retalia-pos-components.mjs.map +1 -0
  6. package/package.json +43 -17
  7. package/types/retalia-pos-components-services.d.ts +168 -0
  8. package/types/retalia-pos-components.d.ts +300 -0
  9. package/eslint.config.js +0 -32
  10. package/ng-package.json +0 -14
  11. package/src/lib/basket/pos-basket.html +0 -124
  12. package/src/lib/basket/pos-basket.scss +0 -285
  13. package/src/lib/basket/pos-basket.spec.ts +0 -198
  14. package/src/lib/basket/pos-basket.stories.ts +0 -114
  15. package/src/lib/basket/pos-basket.ts +0 -142
  16. package/src/lib/item-entry/pos-item-entry.html +0 -41
  17. package/src/lib/item-entry/pos-item-entry.scss +0 -145
  18. package/src/lib/item-entry/pos-item-entry.spec.ts +0 -123
  19. package/src/lib/item-entry/pos-item-entry.stories.ts +0 -31
  20. package/src/lib/item-entry/pos-item-entry.ts +0 -81
  21. package/src/lib/login/pos-login.html +0 -82
  22. package/src/lib/login/pos-login.scss +0 -238
  23. package/src/lib/login/pos-login.spec.ts +0 -89
  24. package/src/lib/login/pos-login.stories.ts +0 -36
  25. package/src/lib/login/pos-login.ts +0 -150
  26. package/src/lib/receipt/pos-receipt.html +0 -116
  27. package/src/lib/receipt/pos-receipt.scss +0 -367
  28. package/src/lib/receipt/pos-receipt.spec.ts +0 -188
  29. package/src/lib/receipt/pos-receipt.stories.ts +0 -163
  30. package/src/lib/receipt/pos-receipt.ts +0 -129
  31. package/src/lib/tender/pos-tender.html +0 -79
  32. package/src/lib/tender/pos-tender.scss +0 -318
  33. package/src/lib/tender/pos-tender.spec.ts +0 -150
  34. package/src/lib/tender/pos-tender.stories.ts +0 -47
  35. package/src/lib/tender/pos-tender.ts +0 -154
  36. package/src/lib/tokens/pos-theme-css.spec.ts +0 -75
  37. package/src/lib/tokens/pos-theme-css.ts +0 -123
  38. package/src/lib/tokens/pos-token-catalog.ts +0 -514
  39. package/src/lib/tokens/pos-tokens.html +0 -351
  40. package/src/lib/tokens/pos-tokens.scss +0 -437
  41. package/src/lib/tokens/pos-tokens.spec.ts +0 -164
  42. package/src/lib/tokens/pos-tokens.stories.ts +0 -22
  43. package/src/lib/tokens/pos-tokens.ts +0 -208
  44. package/src/public-api.ts +0 -37
  45. package/tsconfig.lib.json +0 -14
  46. package/tsconfig.lib.prod.json +0 -11
  47. package/tsconfig.spec.json +0 -11
  48. /package/{src/styles → styles}/styles.css +0 -0
  49. /package/{src/styles → styles}/tokens.css +0 -0
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Presentational Adaptive POS Angular components. State in, typed intents out — no service calls.
4
4
 
5
+ Optional HTTP clients live behind a **separate entry point**: `@retalia/pos-components/services`. Components never import that entry. The host calls a service, then passes display state into the UI.
6
+
5
7
  Requires **Angular 21** (`@angular/core` and `@angular/common` `^21.2.0`).
6
8
 
7
9
  ## Install
@@ -10,6 +12,27 @@ Requires **Angular 21** (`@angular/core` and `@angular/common` `^21.2.0`).
10
12
  npm i @retalia/pos-components
11
13
  ```
12
14
 
15
+ ## Services
16
+
17
+ Import from `@retalia/pos-components/services`, never from a `pos-*` component.
18
+
19
+ ```ts
20
+ import {
21
+ ClerkAuthService,
22
+ POS_API_CONFIG,
23
+ PosCommandsClient,
24
+ posApiInterceptor,
25
+ } from '@retalia/pos-components/services';
26
+ ```
27
+
28
+ | | |
29
+ |---|---|
30
+ | `posApiInterceptor` | Reads `portalApiToken` + `contextShopId` cookies and sets `Authorization` / `Shop-Context`. Provide via `provideHttpClient(withInterceptors([posApiInterceptor]))`. |
31
+ | `ClerkAuthService` | `signIn(clerkNumber, password)` — GET `/api/v1.0/clerks/{number}`, password check in the service (stub until ID-647). Call this from the host on `login.submit`. |
32
+ | `PosCommandsClient` | `addItem` / `changeQuantity` / `clearBasket` / `tenderCash` / `newSale` — each returns a `PosStateEnvelope`. |
33
+
34
+ In local Adaptive POS, paste a Portal Bearer into the `portalApiToken` cookie and the shop id into `contextShopId`. Do not send clerk credentials to `POST /token`.
35
+
13
36
  ## Styles
14
37
 
15
38
  Add the package stylesheet once in the host app (e.g. `angular.json` `styles`):
@@ -83,7 +106,7 @@ export class App {
83
106
  if (intent.type !== 'login.submit') {
84
107
  return;
85
108
  }
86
- // Host (or optional package AuthService) calls the API, then:
109
+ // Host (or package ClerkAuthService) calls the API, then:
87
110
  // this.session.set({ status: 'busy' });
88
111
  // this.session.set({ status: 'signedIn', displayName: clerk.name });
89
112
  // this.errorMessage.set('Invalid clerk or password');
@@ -0,0 +1,171 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, inject, Injectable } from '@angular/core';
3
+ import { HttpClient, HttpErrorResponse } from '@angular/common/http';
4
+ import { throwError, map, catchError } from 'rxjs';
5
+
6
+ /** Read a document cookie by name. Returns null when missing or not in a browser. */
7
+ function readCookie(name) {
8
+ if (typeof document === 'undefined' || !name) {
9
+ return null;
10
+ }
11
+ const encodedName = encodeURIComponent(name);
12
+ for (const part of document.cookie.split(';')) {
13
+ const trimmed = part.trim();
14
+ const separator = trimmed.indexOf('=');
15
+ if (separator < 0) {
16
+ continue;
17
+ }
18
+ const key = trimmed.slice(0, separator);
19
+ if (key !== name && key !== encodedName) {
20
+ continue;
21
+ }
22
+ return decodeURIComponent(trimmed.slice(separator + 1));
23
+ }
24
+ return null;
25
+ }
26
+
27
+ const DEFAULT_POS_API_CONFIG = {
28
+ apiBaseUrl: '',
29
+ tokenCookieName: 'portalApiToken',
30
+ shopContextCookieName: 'contextShopId',
31
+ };
32
+ const POS_API_CONFIG = new InjectionToken('POS_API_CONFIG', {
33
+ providedIn: 'root',
34
+ factory: () => DEFAULT_POS_API_CONFIG,
35
+ });
36
+ function readAccessToken(config) {
37
+ return config.getAccessToken?.() ?? readCookie(config.tokenCookieName);
38
+ }
39
+ function readShopContext(config) {
40
+ return config.getShopContext?.() ?? readCookie(config.shopContextCookieName);
41
+ }
42
+
43
+ function joinUrl(baseUrl, path) {
44
+ if (!baseUrl || /^https?:\/\//i.test(path)) {
45
+ return path;
46
+ }
47
+ const origin = baseUrl.replace(/\/+$/, '');
48
+ const suffix = path.replace(/^\/+/, '');
49
+ return `${origin}/${suffix}`;
50
+ }
51
+ /** Attaches Bearer + Shop-Context from cookies (or host overrides). */
52
+ const posApiInterceptor = (req, next) => {
53
+ const config = inject(POS_API_CONFIG);
54
+ const token = readAccessToken(config);
55
+ const shopContext = readShopContext(config);
56
+ let headers = req.headers;
57
+ if (token && !headers.has('Authorization')) {
58
+ headers = headers.set('Authorization', `Bearer ${token}`);
59
+ }
60
+ if (shopContext && !headers.has('Shop-Context')) {
61
+ headers = headers.set('Shop-Context', shopContext);
62
+ }
63
+ return next(req.clone({
64
+ url: joinUrl(config.apiBaseUrl, req.url),
65
+ headers,
66
+ }));
67
+ };
68
+
69
+ class ClerkAuthError extends Error {
70
+ name = 'ClerkAuthError';
71
+ constructor(message) {
72
+ super(message);
73
+ }
74
+ }
75
+ function displayName(clerk, clerkNumber) {
76
+ const name = `${clerk.firstName ?? ''} ${clerk.lastName ?? ''}`.trim();
77
+ return name || clerk.clerkNumber || clerkNumber;
78
+ }
79
+ function passwordsMatch(submitted, stored) {
80
+ return submitted === (stored ?? '');
81
+ }
82
+ class ClerkAuthService {
83
+ http = inject(HttpClient);
84
+ /**
85
+ * Looks up the clerk and compares the keypad password in this service.
86
+ * Not a dedicated sign-in endpoint — replace when ID-647 / PosIdentity lands.
87
+ */
88
+ signIn(clerkNumber, password) {
89
+ const number = clerkNumber.trim();
90
+ if (!number) {
91
+ return throwError(() => new ClerkAuthError('Invalid clerk or password'));
92
+ }
93
+ return this.http.get(`/api/v1.0/clerks/${encodeURIComponent(number)}`).pipe(map((clerk) => {
94
+ if (!passwordsMatch(password, clerk.password)) {
95
+ throw new ClerkAuthError('Invalid clerk or password');
96
+ }
97
+ return {
98
+ clerkNumber: clerk.clerkNumber || number,
99
+ displayName: displayName(clerk, number),
100
+ languageCode: clerk.languageCode || 'en',
101
+ isManager: clerk.isManager === true,
102
+ };
103
+ }), catchError((error) => {
104
+ if (error instanceof ClerkAuthError) {
105
+ return throwError(() => error);
106
+ }
107
+ if (error instanceof HttpErrorResponse) {
108
+ if (error.status === 401) {
109
+ return throwError(() => new ClerkAuthError('API token missing or expired. Paste portalApiToken into cookies.'));
110
+ }
111
+ if (error.status === 404) {
112
+ return throwError(() => new ClerkAuthError('Invalid clerk or password'));
113
+ }
114
+ }
115
+ return throwError(() => new ClerkAuthError('Unable to sign in'));
116
+ }));
117
+ }
118
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: ClerkAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
119
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: ClerkAuthService, providedIn: 'root' });
120
+ }
121
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: ClerkAuthService, decorators: [{
122
+ type: Injectable,
123
+ args: [{ providedIn: 'root' }]
124
+ }] });
125
+
126
+ function idempotencyKey() {
127
+ return globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random().toString(16).slice(2)}`;
128
+ }
129
+ /**
130
+ * Thin HTTP client for open-till sale commands (command in → PosStateEnvelope out).
131
+ *
132
+ * Keep as one client while the surface is small. When basket, tender, and sale
133
+ * lifecycle each grow their own handful of methods, split by subdomain, e.g.:
134
+ * - basket: addItem / changeQuantity / clearBasket (+ discounts, modifiers, …)
135
+ * - tender: tenderCash (+ card, void payment, …)
136
+ * - sale: newSale (+ suspend, recall, …)
137
+ * Extract is cheap; avoid splitting early into near-empty clients.
138
+ */
139
+ class PosCommandsClient {
140
+ http = inject(HttpClient);
141
+ addItem(command, key = idempotencyKey()) {
142
+ return this.http.post('/api/v1.0/pos/commands/add-item', command, {
143
+ headers: { 'Idempotency-Key': key },
144
+ });
145
+ }
146
+ changeQuantity(command, key = idempotencyKey()) {
147
+ return this.http.post('/api/v1.0/pos/commands/change-quantity', command, { headers: { 'Idempotency-Key': key } });
148
+ }
149
+ clearBasket(command, key = idempotencyKey()) {
150
+ return this.http.post('/api/v1.0/pos/commands/clear-basket', command, { headers: { 'Idempotency-Key': key } });
151
+ }
152
+ tenderCash(command, key = idempotencyKey()) {
153
+ return this.http.post('/api/v1.0/pos/commands/tender-cash', command, { headers: { 'Idempotency-Key': key } });
154
+ }
155
+ newSale(command, key = idempotencyKey()) {
156
+ return this.http.post('/api/v1.0/pos/commands/new-sale', command, { headers: { 'Idempotency-Key': key } });
157
+ }
158
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: PosCommandsClient, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
159
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: PosCommandsClient, providedIn: 'root' });
160
+ }
161
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: PosCommandsClient, decorators: [{
162
+ type: Injectable,
163
+ args: [{ providedIn: 'root' }]
164
+ }] });
165
+
166
+ /**
167
+ * Generated bundle index. Do not edit.
168
+ */
169
+
170
+ export { ClerkAuthError, ClerkAuthService, DEFAULT_POS_API_CONFIG, POS_API_CONFIG, PosCommandsClient, posApiInterceptor, readAccessToken, readShopContext };
171
+ //# sourceMappingURL=retalia-pos-components-services.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retalia-pos-components-services.mjs","sources":["../../../projects/pos-components/services/read-cookie.ts","../../../projects/pos-components/services/pos-api-config.ts","../../../projects/pos-components/services/pos-api.interceptor.ts","../../../projects/pos-components/services/clerk-auth.service.ts","../../../projects/pos-components/services/pos-commands.client.ts","../../../projects/pos-components/services/retalia-pos-components-services.ts"],"sourcesContent":["/** Read a document cookie by name. Returns null when missing or not in a browser. */\r\nexport function readCookie(name: string): string | null {\r\n if (typeof document === 'undefined' || !name) {\r\n return null;\r\n }\r\n\r\n const encodedName = encodeURIComponent(name);\r\n for (const part of document.cookie.split(';')) {\r\n const trimmed = part.trim();\r\n const separator = trimmed.indexOf('=');\r\n if (separator < 0) {\r\n continue;\r\n }\r\n\r\n const key = trimmed.slice(0, separator);\r\n if (key !== name && key !== encodedName) {\r\n continue;\r\n }\r\n\r\n return decodeURIComponent(trimmed.slice(separator + 1));\r\n }\r\n\r\n return null;\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\n\r\nimport { readCookie } from './read-cookie';\r\n\r\nexport interface PosApiConfig {\r\n /** Origin for HeadlessAPI. Empty string when the host app proxies `/api`. */\r\n readonly apiBaseUrl: string;\r\n /** Cookie holding the Portal Bearer token (paste in local dev). */\r\n readonly tokenCookieName: string;\r\n /** Cookie holding the shop id sent as `Shop-Context`. */\r\n readonly shopContextCookieName: string;\r\n readonly getAccessToken?: () => string | null;\r\n readonly getShopContext?: () => string | null;\r\n}\r\n\r\nexport const DEFAULT_POS_API_CONFIG: PosApiConfig = {\r\n apiBaseUrl: '',\r\n tokenCookieName: 'portalApiToken',\r\n shopContextCookieName: 'contextShopId',\r\n};\r\n\r\nexport const POS_API_CONFIG = new InjectionToken<PosApiConfig>('POS_API_CONFIG', {\r\n providedIn: 'root',\r\n factory: () => DEFAULT_POS_API_CONFIG,\r\n});\r\n\r\nexport function readAccessToken(config: PosApiConfig): string | null {\r\n return config.getAccessToken?.() ?? readCookie(config.tokenCookieName);\r\n}\r\n\r\nexport function readShopContext(config: PosApiConfig): string | null {\r\n return config.getShopContext?.() ?? readCookie(config.shopContextCookieName);\r\n}\r\n","import { HttpInterceptorFn } from '@angular/common/http';\r\nimport { inject } from '@angular/core';\r\n\r\nimport {\r\n POS_API_CONFIG,\r\n readAccessToken,\r\n readShopContext,\r\n} from './pos-api-config';\r\n\r\nfunction joinUrl(baseUrl: string, path: string): string {\r\n if (!baseUrl || /^https?:\\/\\//i.test(path)) {\r\n return path;\r\n }\r\n\r\n const origin = baseUrl.replace(/\\/+$/, '');\r\n const suffix = path.replace(/^\\/+/, '');\r\n return `${origin}/${suffix}`;\r\n}\r\n\r\n/** Attaches Bearer + Shop-Context from cookies (or host overrides). */\r\nexport const posApiInterceptor: HttpInterceptorFn = (req, next) => {\r\n const config = inject(POS_API_CONFIG);\r\n const token = readAccessToken(config);\r\n const shopContext = readShopContext(config);\r\n\r\n let headers = req.headers;\r\n if (token && !headers.has('Authorization')) {\r\n headers = headers.set('Authorization', `Bearer ${token}`);\r\n }\r\n if (shopContext && !headers.has('Shop-Context')) {\r\n headers = headers.set('Shop-Context', shopContext);\r\n }\r\n\r\n return next(\r\n req.clone({\r\n url: joinUrl(config.apiBaseUrl, req.url),\r\n headers,\r\n }),\r\n );\r\n};\r\n","import { HttpClient, HttpErrorResponse } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { catchError, map, Observable, throwError } from 'rxjs';\r\n\r\n/** HeadlessAPI clerk payload. Password check is a stub until ID-647. */\r\ninterface ClerkRecord {\r\n identifier?: number;\r\n firstName?: string;\r\n lastName?: string;\r\n password?: string | null;\r\n languageCode?: string;\r\n clerkNumber?: string;\r\n isManager?: boolean;\r\n}\r\n\r\nexport interface ClerkSession {\r\n readonly clerkNumber: string;\r\n readonly displayName: string;\r\n readonly languageCode: string;\r\n readonly isManager: boolean;\r\n}\r\n\r\nexport class ClerkAuthError extends Error {\r\n override readonly name = 'ClerkAuthError';\r\n\r\n constructor(message: string) {\r\n super(message);\r\n }\r\n}\r\n\r\nfunction displayName(clerk: ClerkRecord, clerkNumber: string): string {\r\n const name = `${clerk.firstName ?? ''} ${clerk.lastName ?? ''}`.trim();\r\n return name || clerk.clerkNumber || clerkNumber;\r\n}\r\n\r\nfunction passwordsMatch(submitted: string, stored: string | null | undefined): boolean {\r\n return submitted === (stored ?? '');\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class ClerkAuthService {\r\n private readonly http = inject(HttpClient);\r\n\r\n /**\r\n * Looks up the clerk and compares the keypad password in this service.\r\n * Not a dedicated sign-in endpoint — replace when ID-647 / PosIdentity lands.\r\n */\r\n signIn(clerkNumber: string, password: string): Observable<ClerkSession> {\r\n const number = clerkNumber.trim();\r\n if (!number) {\r\n return throwError(() => new ClerkAuthError('Invalid clerk or password'));\r\n }\r\n\r\n return this.http.get<ClerkRecord>(`/api/v1.0/clerks/${encodeURIComponent(number)}`).pipe(\r\n map((clerk) => {\r\n if (!passwordsMatch(password, clerk.password)) {\r\n throw new ClerkAuthError('Invalid clerk or password');\r\n }\r\n\r\n return {\r\n clerkNumber: clerk.clerkNumber || number,\r\n displayName: displayName(clerk, number),\r\n languageCode: clerk.languageCode || 'en',\r\n isManager: clerk.isManager === true,\r\n };\r\n }),\r\n catchError((error: unknown) => {\r\n if (error instanceof ClerkAuthError) {\r\n return throwError(() => error);\r\n }\r\n\r\n if (error instanceof HttpErrorResponse) {\r\n if (error.status === 401) {\r\n return throwError(\r\n () =>\r\n new ClerkAuthError(\r\n 'API token missing or expired. Paste portalApiToken into cookies.',\r\n ),\r\n );\r\n }\r\n\r\n if (error.status === 404) {\r\n return throwError(() => new ClerkAuthError('Invalid clerk or password'));\r\n }\r\n }\r\n\r\n return throwError(() => new ClerkAuthError('Unable to sign in'));\r\n }),\r\n );\r\n }\r\n}\r\n","import { HttpClient } from '@angular/common/http';\r\nimport { inject, Injectable } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\n\r\nimport { PosStateEnvelope } from './pos-state-envelope';\r\n\r\nexport interface AddItemCommand {\r\n readonly basketId: string;\r\n readonly sku: string;\r\n readonly qty: number;\r\n}\r\n\r\nexport interface ChangeQuantityCommand {\r\n readonly basketId: string;\r\n readonly lineId: number;\r\n readonly qty: number;\r\n}\r\n\r\nexport interface ClearBasketCommand {\r\n readonly basketId: string;\r\n}\r\n\r\nexport interface TenderCashCommand {\r\n readonly basketId: string;\r\n readonly amount: number;\r\n}\r\n\r\nexport interface NewSaleCommand {\r\n readonly basketId: string;\r\n}\r\n\r\nfunction idempotencyKey(): string {\r\n return globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random().toString(16).slice(2)}`;\r\n}\r\n\r\n/**\r\n * Thin HTTP client for open-till sale commands (command in → PosStateEnvelope out).\r\n *\r\n * Keep as one client while the surface is small. When basket, tender, and sale\r\n * lifecycle each grow their own handful of methods, split by subdomain, e.g.:\r\n * - basket: addItem / changeQuantity / clearBasket (+ discounts, modifiers, …)\r\n * - tender: tenderCash (+ card, void payment, …)\r\n * - sale: newSale (+ suspend, recall, …)\r\n * Extract is cheap; avoid splitting early into near-empty clients.\r\n */\r\n@Injectable({ providedIn: 'root' })\r\nexport class PosCommandsClient {\r\n private readonly http = inject(HttpClient);\r\n\r\n addItem(\r\n command: AddItemCommand,\r\n key = idempotencyKey(),\r\n ): Observable<PosStateEnvelope> {\r\n return this.http.post<PosStateEnvelope>('/api/v1.0/pos/commands/add-item', command, {\r\n headers: { 'Idempotency-Key': key },\r\n });\r\n }\r\n\r\n changeQuantity(\r\n command: ChangeQuantityCommand,\r\n key = idempotencyKey(),\r\n ): Observable<PosStateEnvelope> {\r\n return this.http.post<PosStateEnvelope>(\r\n '/api/v1.0/pos/commands/change-quantity',\r\n command,\r\n { headers: { 'Idempotency-Key': key } },\r\n );\r\n }\r\n\r\n clearBasket(\r\n command: ClearBasketCommand,\r\n key = idempotencyKey(),\r\n ): Observable<PosStateEnvelope> {\r\n return this.http.post<PosStateEnvelope>(\r\n '/api/v1.0/pos/commands/clear-basket',\r\n command,\r\n { headers: { 'Idempotency-Key': key } },\r\n );\r\n }\r\n\r\n tenderCash(\r\n command: TenderCashCommand,\r\n key = idempotencyKey(),\r\n ): Observable<PosStateEnvelope> {\r\n return this.http.post<PosStateEnvelope>(\r\n '/api/v1.0/pos/commands/tender-cash',\r\n command,\r\n { headers: { 'Idempotency-Key': key } },\r\n );\r\n }\r\n\r\n newSale(\r\n command: NewSaleCommand,\r\n key = idempotencyKey(),\r\n ): Observable<PosStateEnvelope> {\r\n return this.http.post<PosStateEnvelope>(\r\n '/api/v1.0/pos/commands/new-sale',\r\n command,\r\n { headers: { 'Idempotency-Key': key } },\r\n );\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}