@fire-spark/core 0.7.2 → 0.8.1

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/index.d.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  import { Money, PaymentAdapter, PaymentCollectAt, PaymentContext, PaymentResult, PaymentStorage, PaymentUI, RedeemLike, RedeemSource, isRealPaymentMethod, orderRedeems } from "@fire-spark/payments";
2
- import { AndConditions, CheckoutMode, CheckoutResolved, CmsBlock, Condition, Customer, CustomerIdentifyInput, CustomerRegisterInput, CustomerUpdateInput, Fulfillment, FulfillmentListInput, GroupDisplayType, KioskDeviceConfig, KioskDeviceOverrides, KioskHealthBatchInput, KioskHealthBatchResult, KioskHeartbeatInput, KioskHeartbeatResult, KioskRealtimeToken, MatchResult, MatchableRule, Menu, Menu as Menu$1, MenuLookup, MenuLookup as MenuLookup$1, MerchantPayment, ModifierControlType, ModifierGroup, OrConditions, Order as Order$1, Order as Order$2, OrderFulfillment, OrderInsertInput, OrderLine, OrderListInput, OrderRecordPaymentInput, OrderRedeem, OrderRedemptionStep, OrderReorderInput, OrderTotals, OrderUpdateInput, OrderValidateInput, OrderValidateOutput, PaymentCollectAt as PaymentCollectAt$1, PaymentIntentPutInput, PaymentMethod, PaymentProvider, PaymentTender, PaymentTenderInput, PlaceOrderResult, PosCatalog, PosHealthBatchInput, PosHealthBatchResult, PosHeartbeatInput, PosHeartbeatResult, PosKioskOrder, PosKioskSettleInput, PosKioskSettleResult, PosOrderInput, PosOrderResult, PricingModifier, Product, Product as Product$1, Recommendation, RecurringDateCronResult, RecurringDateCronValues, RulesEngineOrderLine, RulesEngineParams, RulesEngineRuntime, Schedule, SdkLogContext, SdkLogErrorInfo, SdkLogLevel, SdkLogOptions, Store, StoreGetInput, StoreListInput, StoreNearbyInput, StorefrontAvailability, StorefrontMenu, StorefrontMenuScope, StorefrontMenuStreamOptions, StorefrontPaymentsListInput, StorefrontPreferences, TenderRefundInput, TenderReplaceInput, TenderVoidInput, Variant, VariantGroup } from "@fire-spark/types";
2
+ import { AndConditions, CheckoutMode, CheckoutResolved, CmsBlock, Condition, Customer, CustomerIdentifyInput, CustomerRegisterInput, CustomerUpdateInput, Fulfillment, FulfillmentListInput, GroupDisplayType, KioskDeviceConfig, KioskDeviceOverrides, KioskHealthBatchInput, KioskHealthBatchResult, KioskHeartbeatInput, KioskHeartbeatResult, KioskRealtimeToken, MatchResult, MatchableRule, Menu, Menu as Menu$1, MenuLookup, MenuLookup as MenuLookup$1, MerchantPayment, ModifierControlType, ModifierGroup, OrConditions, Order as Order$1, Order as Order$2, OrderDeviceListInput, OrderDeviceListResult, OrderFulfillment, OrderInsertInput, OrderLine, OrderListInput, OrderRecordPaymentInput, OrderRedeem, OrderRedemptionStep, OrderReorderInput, OrderTotals, OrderUpdateInput, OrderValidateInput, OrderValidateOutput, PaymentCollectAt as PaymentCollectAt$1, PaymentIntentPutInput, PaymentMethod, PaymentProvider, PaymentTender, PaymentTenderInput, PlaceOrderResult, PosCatalog, PosFloorInput, PosFloorOccupancy, PosFloorPlan, PosFloorRealtimeToken, PosHealthBatchInput, PosHealthBatchResult, PosHeartbeatInput, PosHeartbeatResult, PosKioskOrder, PosKioskSettleInput, PosKioskSettleResult, PosOrderInput, PosOrderResult, PosTableAttachOrderInput, PosTableCloseInput, PosTableJoinInput, PosTableSeatInput, PosTableSeatReservationInput, PosTableSplitInput, PricingModifier, Product, Product as Product$1, Recommendation, RecurringDateCronResult, RecurringDateCronValues, RulesEngineOrderLine, RulesEngineParams, RulesEngineRuntime, Schedule, SdkLogContext, SdkLogErrorInfo, SdkLogLevel, SdkLogOptions, Store, StoreGetInput, StoreListInput, StoreNearbyInput, StorefrontAvailability, StorefrontMenu, StorefrontMenuScope, StorefrontMenuStreamOptions, StorefrontPaymentsListInput, StorefrontPreferences, TenderRefundInput, TenderReplaceInput, TenderVoidInput, Variant, VariantGroup } from "@fire-spark/types";
3
3
  import { Big } from "big.js";
4
+ //#region src/productCustomization/catalog.utils.d.ts
5
+ /** Image for a product inside one modifier group, else the product image. */
6
+ declare const resolveModifierImageUrl: (product: Product$1, groupId: string) => string | null;
7
+ //#endregion
4
8
  //#region src/productCustomization/types.d.ts
5
9
  type SelectionStatus = "IDLE" | "INCOMPLETE" | "VALID" | "INVALID";
6
10
  type StartingPriceCache = Map<string, Big>;
@@ -232,6 +236,11 @@ declare const storefrontJson: <T>(path: string, init?: RequestInit, options?: Se
232
236
  declare const listOrders: (input?: OrderListInput, options?: ServiceHttpOptions) => Promise<Order$1[]>;
233
237
  declare const createOrder: (body: OrderInsertInput, options?: ServiceHttpOptions) => Promise<Order$1>;
234
238
  declare const getOrder: (id: string, options?: ServiceHttpOptions) => Promise<Order$1>;
239
+ type PlaceOrderDevice = {
240
+ kind: "KIOSK" | "POS";
241
+ uid: string;
242
+ secret: string;
243
+ };
235
244
  type PlaceOrderInput = {
236
245
  /** DRAFT intent built with `PUT /orders/:id/payment-intent`. */
237
246
  intent_id?: string;
@@ -245,6 +254,8 @@ type PlaceOrderInput = {
245
254
  provider?: PaymentProvider;
246
255
  collect_at?: PaymentCollectAt$1;
247
256
  };
257
+ /** Kiosk / POS credential; the server stamps `device_id` on place. */
258
+ device?: PlaceOrderDevice;
248
259
  };
249
260
  declare const placeOrder: (id: string, body?: PlaceOrderInput, options?: ServiceHttpOptions) => Promise<PlaceOrderResult>;
250
261
  /** Records one tender attempt result (idempotent by `attempt_reference`). */
@@ -387,6 +398,11 @@ type OrderScope = {
387
398
  fulfillment_id: string;
388
399
  brand_id?: string | null;
389
400
  };
401
+ type OrderDeviceCredential = {
402
+ kind: "KIOSK" | "POS";
403
+ uid: string;
404
+ secret: string;
405
+ };
390
406
  type CreateOrderOptions = {
391
407
  scope?: OrderScope;
392
408
  customer?: OrderCustomerSource;
@@ -395,6 +411,8 @@ type CreateOrderOptions = {
395
411
  /** When false, skips the OPEN-order lookup and starts a local draft. */
396
412
  reuseOpen?: boolean;
397
413
  orderId?: string;
414
+ /** Stamped on `placeOrder`; not sent with the OPEN cart. */
415
+ device?: OrderDeviceCredential;
398
416
  debounceMs?: number;
399
417
  baseUrl?: string;
400
418
  accessToken?: string;
@@ -464,6 +482,7 @@ declare class Order {
464
482
  * total was low recovers its amount once the total grows back.
465
483
  */
466
484
  private requestedRedeem;
485
+ private readonly device?;
467
486
  private constructor();
468
487
  /**
469
488
  * Opens a cart session: reuses an existing OPEN order for the scope, or a
@@ -986,6 +1005,8 @@ declare const verifyKioskAdminCode: (input: {
986
1005
  }>;
987
1006
  declare const isKioskAdminCodeInvalid: (error: unknown) => boolean;
988
1007
  declare const isKioskAdminCodeLocked: (error: unknown) => boolean;
1008
+ /** Placed orders of this kiosk, newest first. Auth is the device secret. */
1009
+ declare const listKioskOrders: (input: OrderDeviceListInput, options?: ServiceHttpOptions) => Promise<OrderDeviceListResult>;
989
1010
  declare const fetchKioskRealtimeToken: (input: {
990
1011
  device_uid: string;
991
1012
  device_secret: string;
@@ -1074,7 +1095,7 @@ declare const withdrawPosSession: (input: unknown, options?: ServiceHttpOptions)
1074
1095
  declare const drawerPosSession: (input: unknown, options?: ServiceHttpOptions) => Promise<unknown>;
1075
1096
  declare const closePosSession: (input: unknown, options?: ServiceHttpOptions) => Promise<unknown>;
1076
1097
  declare const shiftEndPosSession: (input: unknown, options?: ServiceHttpOptions) => Promise<unknown>;
1077
- /** The device's open caja and its events, or `{ session: null }`. */
1098
+ /** The device's open cash register and its events, or `{ session: null }`. */
1078
1099
  declare const getPosCurrentSession: (input: {
1079
1100
  device_uid: string;
1080
1101
  device_secret: string;
@@ -1083,6 +1104,8 @@ declare const listPosKioskOrders: (input: {
1083
1104
  device_uid: string;
1084
1105
  device_secret: string;
1085
1106
  }, options?: ServiceHttpOptions) => Promise<PosKioskOrder[]>;
1107
+ /** Placed orders of this POS, newest first. Auth is the device secret. */
1108
+ declare const listPosOrders: (input: OrderDeviceListInput, options?: ServiceHttpOptions) => Promise<OrderDeviceListResult>;
1086
1109
  /** Safe to retry with the same `client_id`; the server dedupes the settle. */
1087
1110
  declare const settlePosKioskOrder: (input: PosKioskSettleInput, options?: ServiceHttpOptions) => Promise<PosKioskSettleResult>;
1088
1111
  declare const getPosCatalog: (input: {
@@ -1091,6 +1114,20 @@ declare const getPosCatalog: (input: {
1091
1114
  }, options?: ServiceHttpOptions) => Promise<PosCatalog>;
1092
1115
  /** Safe to retry with the same `client_id`; the server dedupes the sale. */
1093
1116
  declare const createPosOrder: (input: PosOrderInput, options?: ServiceHttpOptions) => Promise<PosOrderResult>;
1117
+ /** Floors, tables (with uids) and the store's open parties. */
1118
+ declare const getPosFloor: (input: PosFloorInput, options?: ServiceHttpOptions) => Promise<PosFloorPlan>;
1119
+ /** Safe to retry with the same `client_id`; the server dedupes the seat. */
1120
+ declare const seatPosTable: (input: PosTableSeatInput, options?: ServiceHttpOptions) => Promise<PosFloorOccupancy>;
1121
+ /** Seats a booked party on its tables; fails once its wait has passed. */
1122
+ declare const seatPosReservation: (input: PosTableSeatReservationInput, options?: ServiceHttpOptions) => Promise<PosFloorOccupancy>;
1123
+ /** Adds tables to a party; tables held by another party merge it in. */
1124
+ declare const joinPosTables: (input: PosTableJoinInput, options?: ServiceHttpOptions) => Promise<PosFloorOccupancy>;
1125
+ /** Moves tables out of a party, optionally seating them as a new party. */
1126
+ declare const splitPosTables: (input: PosTableSplitInput, options?: ServiceHttpOptions) => Promise<PosFloorOccupancy>;
1127
+ declare const closePosTable: (input: PosTableCloseInput, options?: ServiceHttpOptions) => Promise<PosFloorOccupancy>;
1128
+ declare const attachPosTableOrder: (input: PosTableAttachOrderInput, options?: ServiceHttpOptions) => Promise<PosFloorOccupancy>;
1129
+ /** Token for the store's private `floor.changed` channel. */
1130
+ declare const fetchPosFloorRealtimeToken: (input: PosFloorInput, options?: ServiceHttpOptions) => Promise<PosFloorRealtimeToken>;
1094
1131
  //#endregion
1095
1132
  //#region src/services/preferences.d.ts
1096
1133
  declare const getPreferences: (scope?: StorefrontMenuScope, options?: ServiceHttpOptions) => Promise<StorefrontPreferences>;
@@ -1163,6 +1200,7 @@ declare const services: {
1163
1200
  postHealthSamples: typeof postKioskHealthSamples;
1164
1201
  patchOverrides: typeof patchKioskOverrides;
1165
1202
  realtimeToken: typeof fetchKioskRealtimeToken;
1203
+ listOrders: typeof listKioskOrders;
1166
1204
  unlink: typeof unlinkKioskSelf;
1167
1205
  verifyAdminCode: typeof verifyKioskAdminCode;
1168
1206
  isAdminCodeInvalid: typeof isKioskAdminCodeInvalid;
@@ -1188,9 +1226,18 @@ declare const services: {
1188
1226
  shiftEnd: typeof shiftEndPosSession;
1189
1227
  currentSession: typeof getPosCurrentSession;
1190
1228
  listKioskOrders: typeof listPosKioskOrders;
1229
+ listOrders: typeof listPosOrders;
1191
1230
  settleKioskOrder: typeof settlePosKioskOrder;
1192
1231
  getCatalog: typeof getPosCatalog;
1193
1232
  createOrder: typeof createPosOrder;
1233
+ getFloor: typeof getPosFloor;
1234
+ seatTable: typeof seatPosTable;
1235
+ seatReservation: typeof seatPosReservation;
1236
+ joinTables: typeof joinPosTables;
1237
+ splitTables: typeof splitPosTables;
1238
+ closeTable: typeof closePosTable;
1239
+ attachTableOrder: typeof attachPosTableOrder;
1240
+ floorRealtimeToken: typeof fetchPosFloorRealtimeToken;
1194
1241
  isDeviceNotLinked: typeof isPosDeviceNotLinked;
1195
1242
  isUnauthorized: typeof isPosUnauthorized;
1196
1243
  isPinLocked: typeof isPosPinLocked;
@@ -1465,4 +1512,4 @@ declare const validateCardholderName: (value: string) => CardholderNameError | n
1465
1512
  */
1466
1513
  declare const cardPreviewGroups: (value: string) => CardPreviewSlot[][];
1467
1514
  //#endregion
1468
- export { type ApplyRedeemInput, type AuthConfigureOptions, CARD_BRANDS, type CardBrand, type CardBrandSpec, type CardCvcError, type CardExpiry, type CardExpiryError, type CardNumberError, type CardPreviewSlot, type CardholderNameError, type CreateOrderOptions, type CreateSessionOptions, type CustomizationPath, type CustomizationSession, DEFAULT_RECOMMENDATION_TYPES, type ExchangeOptions, type FailedCharge, type FlatMenuCategory, type GroupDisplayType, type IdBuilder, type ListMenusStreamOptions, type ListPaymentsOptions, type Menu, type MenuCategoryNode, type MenuLookup, type MilestoneSteps, type MilestoneTrackItem, type ModifierControlType, type ModifierCtx, type ModifierGroupCtx, type NestedMenuCategory, Order, type OrderCustomerSource, type OrderDraft, type OrderIssue, type OrderIssueCode, type OrderLineDiff, type OrderLineIssue, type OrderLineIssueCode, OrderPaymentRequiredError, type OrderScope, OrderSyncPendingError, OrderSyncRejectedError, OrderValidationError, type OrderValidationResult, type PayIntentOptions, type PayIntentResult, type PayOptions, type PaymentCardBrand, type PaymentProgressEvent, type PaymentProgressListener, type PaymentRunOptions, type PaymentSessionOptions, type PricingModifier, type Product, type ProductCtx, type QuantitiesByPath, type RecommendationType, RecurringDateCron, type RedeemPaymentRow, type RemoveRedeemInput, type ReorderOrderOptions, type ResetOptions, type ReversalOutcome, type ReverseAllOptions, RulesEngine, type ScheduleWindow, type SelectionStatus, type SelectionsByPath, type SerializedError, type ServiceHttpOptions, type SimpleTenderPayment, type Snapshot, type StorefrontAccessToken, type StorefrontErrorDetails, StorefrontHttpError, type TrackWorkflow, type ValidateOptions, type ValidateOrderAgainstMenuInput, type Variant, type VariantGroup, type VariantGroupCtx, type VariantOptionCtx, type VariantSelection, type VerifyWebhookSignatureInput, type VisitedState, addLines, auth, buildCustomerSnapshot, capRedeems, cappedRedeems, cardBrandSpec, cardDigits, cardNumberGaps, cardNumberMaxLength, cardPreviewGroups, caretAfterDigits, collectOrderLineDiffs, computeStartingPrice, countCartProducts, coveredAmount, createSession, currentNodes, cvcMaxLength, defaultConditionError, detectCardBrand, fitRedeems, flattenMenuCategories, flushLogs, formatCardNumber, formatCvc, formatExpiry, fromOrderLines, genId, genOrderId, getLogContext, getScheduleWindow, indexMenu, isCardNumberComplete, isCardNumberDefinitelyInvalid, isCheckoutFieldFilled, isCvcComplete, isDeviceCharged, isDeviceNotLinked, isExpiryComplete, isKioskUnauthorized, isMilestoneStepDone, isOnSchedule, isOrderPaymentRequiredError, isOrderValidationError, isPosDeviceNotLinked, isPosUnauthorized, isRealPaymentMethod, isStorefrontNotFound, isVariantBase, linePayableTotal, listMenusStream, localizePosError, log, logError, luhnCheck, matchAbsoluteDateOperator, matchBooleanOperator, matchCurrencyOperator, matchEnumOperator, matchNumberOperator, matchRecurringDateOperator, matchRelativeDateOperator, matchStringOperator, milestoneSteps, milestoneTrack, nestMenuCategories, normalizeCardholderName, orderPayableTotal, orderRedeemedTotal, orderRedeems, parseExpiry, paymentMatchesClientConditions, rebuildRootGroups, recomputeTotals, redeemedTotal, redemptionCap, redemptionSteps, remainingAmount, removeLine, replaceLine, resolveCheckout, reversePayment, runPaymentAttempt, selectablePayments, serializeError, services, setLineQuantity, storefrontJson, toOrderLines, toPaymentCardBrand, validateCardNumber, validateCardholderName, validateCvc, validateExpiry, validateOrderAgainstMenu, verifyWebhookSignature, visitedStates };
1515
+ export { type ApplyRedeemInput, type AuthConfigureOptions, CARD_BRANDS, type CardBrand, type CardBrandSpec, type CardCvcError, type CardExpiry, type CardExpiryError, type CardNumberError, type CardPreviewSlot, type CardholderNameError, type CreateOrderOptions, type CreateSessionOptions, type CustomizationPath, type CustomizationSession, DEFAULT_RECOMMENDATION_TYPES, type ExchangeOptions, type FailedCharge, type FlatMenuCategory, type GroupDisplayType, type IdBuilder, type ListMenusStreamOptions, type ListPaymentsOptions, type Menu, type MenuCategoryNode, type MenuLookup, type MilestoneSteps, type MilestoneTrackItem, type ModifierControlType, type ModifierCtx, type ModifierGroupCtx, type NestedMenuCategory, Order, type OrderCustomerSource, type OrderDeviceCredential, type OrderDraft, type OrderIssue, type OrderIssueCode, type OrderLineDiff, type OrderLineIssue, type OrderLineIssueCode, OrderPaymentRequiredError, type OrderScope, OrderSyncPendingError, OrderSyncRejectedError, OrderValidationError, type OrderValidationResult, type PayIntentOptions, type PayIntentResult, type PayOptions, type PaymentCardBrand, type PaymentProgressEvent, type PaymentProgressListener, type PaymentRunOptions, type PaymentSessionOptions, type PricingModifier, type Product, type ProductCtx, type QuantitiesByPath, type RecommendationType, RecurringDateCron, type RedeemPaymentRow, type RemoveRedeemInput, type ReorderOrderOptions, type ResetOptions, type ReversalOutcome, type ReverseAllOptions, RulesEngine, type ScheduleWindow, type SelectionStatus, type SelectionsByPath, type SerializedError, type ServiceHttpOptions, type SimpleTenderPayment, type Snapshot, type StorefrontAccessToken, type StorefrontErrorDetails, StorefrontHttpError, type TrackWorkflow, type ValidateOptions, type ValidateOrderAgainstMenuInput, type Variant, type VariantGroup, type VariantGroupCtx, type VariantOptionCtx, type VariantSelection, type VerifyWebhookSignatureInput, type VisitedState, addLines, auth, buildCustomerSnapshot, capRedeems, cappedRedeems, cardBrandSpec, cardDigits, cardNumberGaps, cardNumberMaxLength, cardPreviewGroups, caretAfterDigits, collectOrderLineDiffs, computeStartingPrice, countCartProducts, coveredAmount, createSession, currentNodes, cvcMaxLength, defaultConditionError, detectCardBrand, fitRedeems, flattenMenuCategories, flushLogs, formatCardNumber, formatCvc, formatExpiry, fromOrderLines, genId, genOrderId, getLogContext, getScheduleWindow, indexMenu, isCardNumberComplete, isCardNumberDefinitelyInvalid, isCheckoutFieldFilled, isCvcComplete, isDeviceCharged, isDeviceNotLinked, isExpiryComplete, isKioskUnauthorized, isMilestoneStepDone, isOnSchedule, isOrderPaymentRequiredError, isOrderValidationError, isPosDeviceNotLinked, isPosUnauthorized, isRealPaymentMethod, isStorefrontNotFound, isVariantBase, linePayableTotal, listMenusStream, localizePosError, log, logError, luhnCheck, matchAbsoluteDateOperator, matchBooleanOperator, matchCurrencyOperator, matchEnumOperator, matchNumberOperator, matchRecurringDateOperator, matchRelativeDateOperator, matchStringOperator, milestoneSteps, milestoneTrack, nestMenuCategories, normalizeCardholderName, orderPayableTotal, orderRedeemedTotal, orderRedeems, parseExpiry, paymentMatchesClientConditions, rebuildRootGroups, recomputeTotals, redeemedTotal, redemptionCap, redemptionSteps, remainingAmount, removeLine, replaceLine, resolveCheckout, resolveModifierImageUrl, reversePayment, runPaymentAttempt, selectablePayments, serializeError, services, setLineQuantity, storefrontJson, toOrderLines, toPaymentCardBrand, validateCardNumber, validateCardholderName, validateCvc, validateExpiry, validateOrderAgainstMenu, verifyWebhookSignature, visitedStates };
package/dist/index.js CHANGED
@@ -28,23 +28,16 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  enumerable: true
29
29
  }) : target, mod));
30
30
  //#endregion
31
- //#region src/productCustomization/clamp.utils.ts
32
- const clampModifierQuantity = (type, quantity, min, max) => {
33
- let next = Math.max(0, Math.floor(quantity));
34
- if (type === "RADIO" || type === "CHECKBOX") next = next > 0 ? 1 : 0;
35
- if (next === 0) return 0;
36
- let lower = min;
37
- if (type === "QUANTITY") lower = 0;
38
- return Math.min(max, Math.max(lower, next));
39
- };
40
- const clampProductQuantity = (quantity, min, max) => {
41
- return Math.min(max, Math.max(min, Math.max(0, Math.floor(quantity))));
42
- };
43
- //#endregion
44
31
  //#region src/productCustomization/catalog.utils.ts
45
32
  const resolvePricingModifier = (product, groupId) => {
46
33
  return product.pricing.modifiers.find((modifier) => modifier.modifier_group_id === groupId);
47
34
  };
35
+ /** Image for a product inside one modifier group, else the product image. */
36
+ const resolveModifierImageUrl = (product, groupId) => {
37
+ const entry = resolvePricingModifier(product, groupId);
38
+ if (entry?.image_url) return entry.image_url;
39
+ return product.image_url ?? null;
40
+ };
48
41
  /** Unit price and tax of a modifier in a group. A variant base listed in the
49
42
  * group keeps the limits; the variant it resolves to sets what is charged. */
50
43
  const modifierUnitPricing = (listed, ordered, groupId) => {
@@ -138,6 +131,19 @@ const resolveModifierGroupsForLookup = (products, modifierGroups) => {
138
131
  return [...byId.values()];
139
132
  };
140
133
  //#endregion
134
+ //#region src/productCustomization/clamp.utils.ts
135
+ const clampModifierQuantity = (type, quantity, min, max) => {
136
+ let next = Math.max(0, Math.floor(quantity));
137
+ if (type === "RADIO" || type === "CHECKBOX") next = next > 0 ? 1 : 0;
138
+ if (next === 0) return 0;
139
+ let lower = min;
140
+ if (type === "QUANTITY") lower = 0;
141
+ return Math.min(max, Math.max(lower, next));
142
+ };
143
+ const clampProductQuantity = (quantity, min, max) => {
144
+ return Math.min(max, Math.max(min, Math.max(0, Math.floor(quantity))));
145
+ };
146
+ //#endregion
141
147
  //#region src/productCustomization/store.ts
142
148
  const createStore = () => {
143
149
  return {
@@ -2413,6 +2419,21 @@ const isKioskAdminCodeInvalid = (error) => {
2413
2419
  const isKioskAdminCodeLocked = (error) => {
2414
2420
  return error instanceof StorefrontHttpError && error.status === 429;
2415
2421
  };
2422
+ /** Placed orders of this kiosk, newest first. Auth is the device secret. */
2423
+ const listKioskOrders = async (input, options) => {
2424
+ const path = "/api/storefront/v1/kiosk/devices/me/orders";
2425
+ const init = {
2426
+ method: "POST",
2427
+ body: JSON.stringify(input)
2428
+ };
2429
+ const response = await kioskFetch(path, init, options);
2430
+ if (!response.ok) {
2431
+ const body = await readError$1(response);
2432
+ throwKioskError(body, response.status);
2433
+ }
2434
+ captureLogDevice(input.device_uid);
2435
+ return await response.json();
2436
+ };
2416
2437
  const fetchKioskRealtimeToken = async (input, options) => {
2417
2438
  const path = "/api/storefront/v1/kiosk/realtime/token";
2418
2439
  const init = {
@@ -2697,7 +2718,20 @@ const enUS = {
2697
2718
  BREAKDOWN_MISMATCH: "The cash breakdown does not match the amount.",
2698
2719
  DIFFERENCE_NEEDS_AUTH: "The difference needs a manager PIN.",
2699
2720
  KIOSK_ORDER_NOT_SETTLEABLE: "This kiosk order cannot be settled here.",
2700
- PAYMENT_NOT_AVAILABLE: "This payment method is not available on this register."
2721
+ PAYMENT_NOT_AVAILABLE: "This payment method is not available on this register.",
2722
+ STORE_NOT_FOUND: "This register has no store.",
2723
+ TABLE_NOT_FOUND: "That table is not on this store's floor plan.",
2724
+ TABLE_OCCUPIED: "That table is already seated.",
2725
+ TABLE_NOT_IN_SESSION: "That table is not part of this party.",
2726
+ TABLE_SESSION_NOT_FOUND: "That party no longer exists.",
2727
+ TABLE_SESSION_NOT_OPEN: "That party is already closed.",
2728
+ TABLE_SESSION_CONFLICT: "Someone else changed this party. Check it again.",
2729
+ TABLE_SESSION_LAST_TABLE: "A party needs at least one table.",
2730
+ ORDER_NOT_FOUND: "That order is not from this store.",
2731
+ ORDER_IN_OTHER_TABLE_SESSION: "That order belongs to another open party.",
2732
+ RESERVATION_NOT_FOUND: "That reservation is not from this store.",
2733
+ RESERVATION_NOT_BOOKED: "That reservation was already seated or cancelled.",
2734
+ RESERVATION_EXPIRED: "That reservation is a no-show now. Its tables are free again."
2701
2735
  };
2702
2736
  const posErrorMessages = {
2703
2737
  en: enUS,
@@ -2717,7 +2751,20 @@ const posErrorMessages = {
2717
2751
  BREAKDOWN_MISMATCH: "El desglose de efectivo no coincide con el monto.",
2718
2752
  DIFFERENCE_NEEDS_AUTH: "La diferencia necesita el PIN de un supervisor.",
2719
2753
  KIOSK_ORDER_NOT_SETTLEABLE: "Este pedido de kiosco no se puede cobrar aquí.",
2720
- PAYMENT_NOT_AVAILABLE: "Este método de pago no está disponible en esta caja."
2754
+ PAYMENT_NOT_AVAILABLE: "Este método de pago no está disponible en esta caja.",
2755
+ STORE_NOT_FOUND: "Esta caja no tiene tienda.",
2756
+ TABLE_NOT_FOUND: "Esa mesa no está en el plano de esta tienda.",
2757
+ TABLE_OCCUPIED: "Esa mesa ya está ocupada.",
2758
+ TABLE_NOT_IN_SESSION: "Esa mesa no es parte de este grupo.",
2759
+ TABLE_SESSION_NOT_FOUND: "Ese grupo ya no existe.",
2760
+ TABLE_SESSION_NOT_OPEN: "Ese grupo ya se cerró.",
2761
+ TABLE_SESSION_CONFLICT: "Alguien más cambió este grupo. Revísalo otra vez.",
2762
+ TABLE_SESSION_LAST_TABLE: "Un grupo necesita al menos una mesa.",
2763
+ ORDER_NOT_FOUND: "Ese pedido no es de esta tienda.",
2764
+ ORDER_IN_OTHER_TABLE_SESSION: "Ese pedido es de otro grupo abierto.",
2765
+ RESERVATION_NOT_FOUND: "Esa reserva no es de esta tienda.",
2766
+ RESERVATION_NOT_BOOKED: "Esa reserva ya se sentó o se canceló.",
2767
+ RESERVATION_EXPIRED: "Esa reserva se marcó como no presentada. Sus mesas ya están libres."
2721
2768
  },
2722
2769
  "pt-BR": {
2723
2770
  DEVICE_NOT_LINKED: "Este caixa não está vinculado.",
@@ -2734,7 +2781,20 @@ const posErrorMessages = {
2734
2781
  BREAKDOWN_MISMATCH: "A composição do dinheiro não confere com o valor.",
2735
2782
  DIFFERENCE_NEEDS_AUTH: "A diferença precisa do PIN de um supervisor.",
2736
2783
  KIOSK_ORDER_NOT_SETTLEABLE: "Este pedido do totem não pode ser cobrado aqui.",
2737
- PAYMENT_NOT_AVAILABLE: "Esta forma de pagamento não está disponível neste caixa."
2784
+ PAYMENT_NOT_AVAILABLE: "Esta forma de pagamento não está disponível neste caixa.",
2785
+ STORE_NOT_FOUND: "Este caixa não tem loja.",
2786
+ TABLE_NOT_FOUND: "Essa mesa não está na planta desta loja.",
2787
+ TABLE_OCCUPIED: "Essa mesa já está ocupada.",
2788
+ TABLE_NOT_IN_SESSION: "Essa mesa não faz parte deste grupo.",
2789
+ TABLE_SESSION_NOT_FOUND: "Esse grupo não existe mais.",
2790
+ TABLE_SESSION_NOT_OPEN: "Esse grupo já foi fechado.",
2791
+ TABLE_SESSION_CONFLICT: "Outra pessoa alterou este grupo. Confira de novo.",
2792
+ TABLE_SESSION_LAST_TABLE: "Um grupo precisa de pelo menos uma mesa.",
2793
+ ORDER_NOT_FOUND: "Esse pedido não é desta loja.",
2794
+ ORDER_IN_OTHER_TABLE_SESSION: "Esse pedido é de outro grupo aberto.",
2795
+ RESERVATION_NOT_FOUND: "Essa reserva não é desta loja.",
2796
+ RESERVATION_NOT_BOOKED: "Essa reserva já foi acomodada ou cancelada.",
2797
+ RESERVATION_EXPIRED: "Essa reserva virou não comparecimento. As mesas estão livres de novo."
2738
2798
  }
2739
2799
  };
2740
2800
  const posErrorMessage = (code, locale = "en-US") => {
@@ -2871,13 +2931,17 @@ const closePosSession = async (input, options) => {
2871
2931
  const shiftEndPosSession = async (input, options) => {
2872
2932
  return (await postJson("/api/storefront/v1/pos/sessions/shift-end", input, options)).data;
2873
2933
  };
2874
- /** The device's open caja and its events, or `{ session: null }`. */
2934
+ /** The device's open cash register and its events, or `{ session: null }`. */
2875
2935
  const getPosCurrentSession = async (input, options) => {
2876
2936
  return (await postJson("/api/storefront/v1/pos/sessions/current", input, options)).data;
2877
2937
  };
2878
2938
  const listPosKioskOrders = async (input, options) => {
2879
2939
  return (await postJson("/api/storefront/v1/pos/kiosk-orders", input, options)).data;
2880
2940
  };
2941
+ /** Placed orders of this POS, newest first. Auth is the device secret. */
2942
+ const listPosOrders = async (input, options) => {
2943
+ return postJson("/api/storefront/v1/pos/devices/me/orders", input, options);
2944
+ };
2881
2945
  /** Safe to retry with the same `client_id`; the server dedupes the settle. */
2882
2946
  const settlePosKioskOrder = async (input, options) => {
2883
2947
  return (await postJson("/api/storefront/v1/pos/kiosk-orders/settle", input, options)).data;
@@ -2889,6 +2953,39 @@ const getPosCatalog = async (input, options) => {
2889
2953
  const createPosOrder = async (input, options) => {
2890
2954
  return (await postJson("/api/storefront/v1/pos/orders", input, options)).data;
2891
2955
  };
2956
+ /** Floors, tables (with uids) and the store's open parties. */
2957
+ const getPosFloor = async (input, options) => {
2958
+ return (await postJson("/api/storefront/v1/pos/floor", input, options)).data;
2959
+ };
2960
+ const postOccupancy = async (path, input, options) => {
2961
+ return (await postJson(path, input, options)).data;
2962
+ };
2963
+ /** Safe to retry with the same `client_id`; the server dedupes the seat. */
2964
+ const seatPosTable = async (input, options) => {
2965
+ return postOccupancy("/api/storefront/v1/pos/tables/seat", input, options);
2966
+ };
2967
+ /** Seats a booked party on its tables; fails once its wait has passed. */
2968
+ const seatPosReservation = async (input, options) => {
2969
+ return postOccupancy("/api/storefront/v1/pos/tables/seat-reservation", input, options);
2970
+ };
2971
+ /** Adds tables to a party; tables held by another party merge it in. */
2972
+ const joinPosTables = async (input, options) => {
2973
+ return postOccupancy("/api/storefront/v1/pos/tables/join", input, options);
2974
+ };
2975
+ /** Moves tables out of a party, optionally seating them as a new party. */
2976
+ const splitPosTables = async (input, options) => {
2977
+ return postOccupancy("/api/storefront/v1/pos/tables/split", input, options);
2978
+ };
2979
+ const closePosTable = async (input, options) => {
2980
+ return postOccupancy("/api/storefront/v1/pos/tables/close", input, options);
2981
+ };
2982
+ const attachPosTableOrder = async (input, options) => {
2983
+ return postOccupancy("/api/storefront/v1/pos/tables/attach-order", input, options);
2984
+ };
2985
+ /** Token for the store's private `floor.changed` channel. */
2986
+ const fetchPosFloorRealtimeToken = async (input, options) => {
2987
+ return (await postJson("/api/storefront/v1/pos/realtime/token", input, options)).data;
2988
+ };
2892
2989
  //#endregion
2893
2990
  //#region src/services/stores.ts
2894
2991
  const storesPath = (suffix) => {
@@ -2977,6 +3074,7 @@ const services = {
2977
3074
  postHealthSamples: postKioskHealthSamples,
2978
3075
  patchOverrides: patchKioskOverrides,
2979
3076
  realtimeToken: fetchKioskRealtimeToken,
3077
+ listOrders: listKioskOrders,
2980
3078
  unlink: unlinkKioskSelf,
2981
3079
  verifyAdminCode: verifyKioskAdminCode,
2982
3080
  isAdminCodeInvalid: isKioskAdminCodeInvalid,
@@ -3002,9 +3100,18 @@ const services = {
3002
3100
  shiftEnd: shiftEndPosSession,
3003
3101
  currentSession: getPosCurrentSession,
3004
3102
  listKioskOrders: listPosKioskOrders,
3103
+ listOrders: listPosOrders,
3005
3104
  settleKioskOrder: settlePosKioskOrder,
3006
3105
  getCatalog: getPosCatalog,
3007
3106
  createOrder: createPosOrder,
3107
+ getFloor: getPosFloor,
3108
+ seatTable: seatPosTable,
3109
+ seatReservation: seatPosReservation,
3110
+ joinTables: joinPosTables,
3111
+ splitTables: splitPosTables,
3112
+ closeTable: closePosTable,
3113
+ attachTableOrder: attachPosTableOrder,
3114
+ floorRealtimeToken: fetchPosFloorRealtimeToken,
3008
3115
  isDeviceNotLinked: isPosDeviceNotLinked,
3009
3116
  isUnauthorized: isPosUnauthorized,
3010
3117
  isPinLocked: isPosPinLocked,
@@ -3943,6 +4050,22 @@ const reversePayment = async (adapter, ctx, result, options = {}) => {
3943
4050
  }
3944
4051
  const run = () => callOperation(ctx, operation, result, clock);
3945
4052
  const next = await withTerminalLock(ctx.paymentId, run);
4053
+ if (kind === "refund" && next.status === "FAILED") {
4054
+ const error = next.error ?? createPaymentError("UNKNOWN");
4055
+ const m1 = {
4056
+ ...result.metadata,
4057
+ error,
4058
+ needs_review: true
4059
+ };
4060
+ return {
4061
+ kind,
4062
+ result: {
4063
+ ...result,
4064
+ metadata: m1,
4065
+ error
4066
+ }
4067
+ };
4068
+ }
3946
4069
  return {
3947
4070
  kind,
3948
4071
  result: next
@@ -5276,6 +5399,7 @@ var Order = class Order {
5276
5399
  * total was low recovers its amount once the total grows back.
5277
5400
  */
5278
5401
  requestedRedeem = null;
5402
+ device;
5279
5403
  constructor(config, notify) {
5280
5404
  this.draft = cloneOrder(config.order);
5281
5405
  this.synced = cloneOrder(config.order);
@@ -5283,6 +5407,7 @@ var Order = class Order {
5283
5407
  this.persisted = config.persisted;
5284
5408
  this.http = config.http;
5285
5409
  this.debounceMs = config.debounceMs;
5410
+ this.device = config.device;
5286
5411
  this.externalNotify = notify;
5287
5412
  this.flush = createFlushController({
5288
5413
  getDraft: () => this.draft,
@@ -5344,14 +5469,16 @@ var Order = class Order {
5344
5469
  order: existing,
5345
5470
  http,
5346
5471
  debounceMs,
5347
- persisted: true
5472
+ persisted: true,
5473
+ device: options.device
5348
5474
  }, notify);
5349
5475
  return new Order({
5350
5476
  order: buildLocalDraft(body),
5351
5477
  http,
5352
5478
  debounceMs,
5353
5479
  persisted: false,
5354
- fresh: !reuse
5480
+ fresh: !reuse,
5481
+ device: options.device
5355
5482
  }, notify);
5356
5483
  }
5357
5484
  static async reorder(orderId, options = {}, notify) {
@@ -5748,13 +5875,20 @@ var Order = class Order {
5748
5875
  await this.flush.settle();
5749
5876
  if (!input.intent_id) this.assertPayable(input.payment);
5750
5877
  await this.validateOrder();
5751
- let body = input;
5878
+ const device = input.device ?? this.device;
5879
+ let body = device ? {
5880
+ ...input,
5881
+ device
5882
+ } : input;
5752
5883
  if (!input.intent_id) {
5753
5884
  const tenders = this.getTenders(input.payment);
5754
5885
  const needsPayment = input.payment && !simpleTenderInput(input.payment);
5755
5886
  if (tenders.length > 0 && !needsPayment) {
5756
5887
  const intent = activeIntent((await this.syncPaymentIntent(tenders)).payment_intents);
5757
- if (intent) body = { intent_id: intent.id };
5888
+ if (intent) body = device ? {
5889
+ intent_id: intent.id,
5890
+ device
5891
+ } : { intent_id: intent.id };
5758
5892
  }
5759
5893
  }
5760
5894
  try {
@@ -8657,4 +8791,4 @@ const cardPreviewGroups = (value) => {
8657
8791
  return groups;
8658
8792
  };
8659
8793
  //#endregion
8660
- export { CARD_BRANDS, DEFAULT_RECOMMENDATION_TYPES, Order, OrderPaymentRequiredError, OrderSyncPendingError, OrderSyncRejectedError, OrderValidationError, RecurringDateCron, RulesEngine, StorefrontHttpError, addLines, auth, buildCustomerSnapshot, capRedeems, cappedRedeems, cardBrandSpec, cardDigits, cardNumberGaps, cardNumberMaxLength, cardPreviewGroups, caretAfterDigits, collectOrderLineDiffs, computeStartingPrice, countCartProducts, coveredAmount, createSession, currentNodes, cvcMaxLength, defaultConditionError, detectCardBrand, fitRedeems, flattenMenuCategories, flushLogs, formatCardNumber, formatCvc, formatExpiry, fromOrderLines, genId, genOrderId, getLogContext, getScheduleWindow, indexMenu, isCardNumberComplete, isCardNumberDefinitelyInvalid, isCheckoutFieldFilled, isCvcComplete, isDeviceCharged, isDeviceNotLinked, isExpiryComplete, isKioskUnauthorized, isMilestoneStepDone, isOnSchedule, isOrderPaymentRequiredError, isOrderValidationError, isPosDeviceNotLinked, isPosUnauthorized, isRealPaymentMethod, isStorefrontNotFound, isVariantBase, linePayableTotal, listMenusStream, localizePosError, log, logError, luhnCheck, matchAbsoluteDateOperator, matchBooleanOperator, matchCurrencyOperator, matchEnumOperator, matchNumberOperator, matchRecurringDateOperator, matchRelativeDateOperator, matchStringOperator, milestoneSteps, milestoneTrack, nestMenuCategories, normalizeCardholderName, orderPayableTotal, orderRedeemedTotal, orderRedeems, parseExpiry, paymentMatchesClientConditions, rebuildRootGroups, recomputeTotals, redeemedTotal, redemptionCap, redemptionSteps, remainingAmount, removeLine, replaceLine, resolveCheckout, reversePayment, runPaymentAttempt, selectablePayments, serializeError, services, setLineQuantity, storefrontJson, toOrderLines, toPaymentCardBrand, validateCardNumber, validateCardholderName, validateCvc, validateExpiry, validateOrderAgainstMenu, verifyWebhookSignature, visitedStates };
8794
+ export { CARD_BRANDS, DEFAULT_RECOMMENDATION_TYPES, Order, OrderPaymentRequiredError, OrderSyncPendingError, OrderSyncRejectedError, OrderValidationError, RecurringDateCron, RulesEngine, StorefrontHttpError, addLines, auth, buildCustomerSnapshot, capRedeems, cappedRedeems, cardBrandSpec, cardDigits, cardNumberGaps, cardNumberMaxLength, cardPreviewGroups, caretAfterDigits, collectOrderLineDiffs, computeStartingPrice, countCartProducts, coveredAmount, createSession, currentNodes, cvcMaxLength, defaultConditionError, detectCardBrand, fitRedeems, flattenMenuCategories, flushLogs, formatCardNumber, formatCvc, formatExpiry, fromOrderLines, genId, genOrderId, getLogContext, getScheduleWindow, indexMenu, isCardNumberComplete, isCardNumberDefinitelyInvalid, isCheckoutFieldFilled, isCvcComplete, isDeviceCharged, isDeviceNotLinked, isExpiryComplete, isKioskUnauthorized, isMilestoneStepDone, isOnSchedule, isOrderPaymentRequiredError, isOrderValidationError, isPosDeviceNotLinked, isPosUnauthorized, isRealPaymentMethod, isStorefrontNotFound, isVariantBase, linePayableTotal, listMenusStream, localizePosError, log, logError, luhnCheck, matchAbsoluteDateOperator, matchBooleanOperator, matchCurrencyOperator, matchEnumOperator, matchNumberOperator, matchRecurringDateOperator, matchRelativeDateOperator, matchStringOperator, milestoneSteps, milestoneTrack, nestMenuCategories, normalizeCardholderName, orderPayableTotal, orderRedeemedTotal, orderRedeems, parseExpiry, paymentMatchesClientConditions, rebuildRootGroups, recomputeTotals, redeemedTotal, redemptionCap, redemptionSteps, remainingAmount, removeLine, replaceLine, resolveCheckout, resolveModifierImageUrl, reversePayment, runPaymentAttempt, selectablePayments, serializeError, services, setLineQuantity, storefrontJson, toOrderLines, toPaymentCardBrand, validateCardNumber, validateCardholderName, validateCvc, validateExpiry, validateOrderAgainstMenu, verifyWebhookSignature, visitedStates };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fire-spark/core",
3
- "version": "0.7.2",
3
+ "version": "0.8.1",
4
4
  "description": "Fire Spark headless SDK",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -20,8 +20,8 @@
20
20
  "big.js": "6.2.1",
21
21
  "dayjs": "1.11.9",
22
22
  "@types/big.js": "6.2.2",
23
- "@fire-spark/payments": "^0.7.2",
24
- "@fire-spark/types": "^0.7.2"
23
+ "@fire-spark/payments": "^0.8.1",
24
+ "@fire-spark/types": "^0.8.1"
25
25
  },
26
26
  "devDependencies": {
27
27
  "tsdown": "^0.22.14",