@theelena/sdk 0.1.0 → 0.1.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.
@@ -0,0 +1,901 @@
1
+ import { bo as ElenaHttpClient, bp as ElenaFetch, bq as ElenaClientOptions, E as ElenaKeyRequestOptions, W as ElenaClientContextV1, b as ElenaKeyPageQuery, V as ElenaClientCatalogV1, X as ElenaClientProductResponseV1, T as ElenaClientAssetResponseV1, j as ElenaKeyTransportOptions } from './key-transport.d-Bopgxw9r.js';
2
+ export { S as ElenaAgentTransportError, U as ElenaClientAssetV1, Y as ElenaClientProductV1, br as ElenaHttpMethod, Z as ElenaKeyTransportErrorCode, a0 as ElenaPublicConnectionV1, bs as ElenaRequestOptions } from './key-transport.d-Bopgxw9r.js';
3
+ import { z } from 'zod';
4
+
5
+ type TicketEstado = 'emitido' | 'usado' | 'anulado';
6
+ interface EventTicketType {
7
+ id: string;
8
+ nombre: string;
9
+ precio: string | null;
10
+ requiereDni: boolean;
11
+ ventana: {
12
+ inicio: string | null;
13
+ fin: string | null;
14
+ } | null;
15
+ cupo: number | null;
16
+ disponibles: number | null;
17
+ agotado: boolean;
18
+ }
19
+ /** Wire shape of GET /api/v1/public/events/detail. */
20
+ interface EventDetail {
21
+ evento: {
22
+ nombre: string;
23
+ imageUrl: string | null;
24
+ imageId: string | null;
25
+ slug: string;
26
+ estado: 'publicado' | 'abierto';
27
+ fechaOperativa: string;
28
+ inicia: string;
29
+ termina: string | null;
30
+ timezone: string;
31
+ capacidad: number | null;
32
+ };
33
+ tipos: EventTicketType[];
34
+ }
35
+ interface TicketEmissionInput {
36
+ restaurantSlug: string;
37
+ eventSlug: string;
38
+ titular: {
39
+ nombre: string;
40
+ dni?: string | null;
41
+ celular: string;
42
+ };
43
+ acompanantes: number;
44
+ ref?: string | null;
45
+ ticketTypeId?: string;
46
+ }
47
+ interface EmittedTicket {
48
+ id: string;
49
+ token: string;
50
+ holderName: string;
51
+ status: TicketEstado;
52
+ ticketTypeName?: string;
53
+ }
54
+ interface TicketEmissionResult {
55
+ partyId: string;
56
+ alreadyRegistered: boolean;
57
+ tickets: EmittedTicket[];
58
+ }
59
+ /** Wire shape of GET /api/v1/public/tickets/:token. */
60
+ interface TicketStatus {
61
+ qr: string;
62
+ estado: TicketEstado;
63
+ titular: {
64
+ nombre: string;
65
+ dni: string | null;
66
+ celular: string;
67
+ };
68
+ tipo: {
69
+ nombre: string | null;
70
+ precio: string | null;
71
+ };
72
+ evento: {
73
+ nombre: string | null;
74
+ slug: string | null;
75
+ estado: string | null;
76
+ fechaOperativa: string | null;
77
+ inicia: string | null;
78
+ timezone: string | null;
79
+ };
80
+ }
81
+
82
+ /**
83
+ * Hero Carousel Types
84
+ * Shared types for hero slide management
85
+ */
86
+ interface HeroSlide {
87
+ id: string;
88
+ restaurantId: string;
89
+ imageId: string;
90
+ imageUrl?: string;
91
+ title: string;
92
+ description: string | null;
93
+ linkUrl: string | null;
94
+ linkLabel: string | null;
95
+ /**
96
+ * Linked event ("noche") destination; mutually exclusive with `linkUrl`
97
+ * (the backend enforces the exclusivity on create and on merged PATCHes).
98
+ */
99
+ eventId: string | null;
100
+ /**
101
+ * Resolved linked event at read time — never a stored slug/URL. Staff
102
+ * reads always include it (even when the event is hidden, with
103
+ * `isPublic: false`); public reads exclude the whole slide when the
104
+ * linked event is not publicly visible.
105
+ */
106
+ event: HeroSlideEvent | null;
107
+ order: number;
108
+ isActive: boolean;
109
+ createdAt: string;
110
+ updatedAt: string;
111
+ }
112
+ /** Lifecycle of an Elena event ("noche"); mirrors the backend `event_status` enum. */
113
+ type HeroSlideEventStatus = 'borrador' | 'publicado' | 'abierto' | 'cerrado';
114
+ /**
115
+ * Event destination resolved from the current event record. Staff panels use
116
+ * `isPublic: false` to explain why a linked slide is hidden from the public
117
+ * catalog without losing its configuration.
118
+ */
119
+ interface HeroSlideEvent {
120
+ id: string;
121
+ slug: string;
122
+ name: string;
123
+ status: HeroSlideEventStatus;
124
+ isPublic: boolean;
125
+ }
126
+
127
+ /**
128
+ * Public domain contracts for Catalog Access Experiences.
129
+ *
130
+ * A single catalog can be published through several configurable access
131
+ * points. Each access point stores an experience policy (personal vs
132
+ * shared-device kiosk), a placement, allowed order types and interaction
133
+ * rules, and produces a stable, non-guessable public URL. These contracts are
134
+ * shared by the Elena backend, staff app and public web so the wire shape has
135
+ * one source of truth.
136
+ */
137
+ /** Interface + session policy applied to a catalog access point. */
138
+ type CatalogExperience = 'personal' | 'shared_device';
139
+ /** Where the access point is physically/logically used. */
140
+ type CatalogPlacement = 'remote' | 'counter' | 'table';
141
+ /**
142
+ * Order types an access point may allow. Mirrors the existing order `tipo`
143
+ * enum; access experiences never introduce new order types.
144
+ */
145
+ type CatalogOrderType = 'para_llevar' | 'en_mesa' | 'reserva';
146
+ /** Session timing policy for shared-device (kiosk) experiences. */
147
+ interface CatalogAccessSessionConfig {
148
+ /** Seconds of inactivity before an unconfirmed kiosk session resets. */
149
+ idleTimeoutSeconds: number;
150
+ /** Seconds the confirmation screen stays before returning to welcome. */
151
+ confirmationTimeoutSeconds: number;
152
+ }
153
+ /**
154
+ * Public resolution of an access point. The server derives the experience from
155
+ * the resolved route; the client never sends a free-form experience value.
156
+ */
157
+ interface CatalogAccessResolution {
158
+ accessPointId: string;
159
+ name: string;
160
+ experience: CatalogExperience;
161
+ placement: CatalogPlacement;
162
+ allowedOrderTypes: CatalogOrderType[];
163
+ tableId: string | null;
164
+ tableNumber: string | null;
165
+ chat: {
166
+ enabled: boolean;
167
+ };
168
+ session: CatalogAccessSessionConfig | null;
169
+ /** URL of the canonical personal catalog (for the kiosk welcome QR). */
170
+ personalCatalogUrl: string;
171
+ }
172
+
173
+ /** A tenant-configured fixed charge that can apply to one or more order types. */
174
+ interface OrderChargeDefinition {
175
+ id: string;
176
+ version: number;
177
+ name: string;
178
+ unitAmount: string;
179
+ applicableOrderTypes: CatalogOrderType[];
180
+ enabled: boolean;
181
+ }
182
+ /** A client selection that identifies a configured charge without asserting pricing. */
183
+ interface OrderChargeSelection {
184
+ definitionId: string;
185
+ definitionVersion: number;
186
+ quantity: number;
187
+ }
188
+ /** A frozen charge snapshot persisted with an order or sale. */
189
+ interface AppliedOrderCharge {
190
+ definitionId: string;
191
+ definitionVersion: number;
192
+ name: string;
193
+ unitAmount: string;
194
+ quantity: number;
195
+ total: string;
196
+ }
197
+
198
+ interface BusinessStatus {
199
+ isOpen: boolean;
200
+ nextOpeningTime: string | null;
201
+ isPaused: boolean;
202
+ }
203
+ interface BusinessContact {
204
+ phone: string | null;
205
+ address: string | null;
206
+ email: string | null;
207
+ }
208
+ interface BusinessSocial {
209
+ facebook: string | null;
210
+ instagram: string | null;
211
+ twitter: string | null;
212
+ }
213
+ type BusinessSchedule = Record<string, {
214
+ abierto: boolean;
215
+ apertura: string;
216
+ cierre: string;
217
+ }>;
218
+ interface BusinessPaymentMethodDetail {
219
+ methodType: 'efectivo' | 'yape' | 'plin' | 'transferencia' | 'tarjeta';
220
+ accountNumber: string | null;
221
+ accountHolder: string | null;
222
+ qrUrl: string | null;
223
+ }
224
+ interface BusinessTicketTypeSummary {
225
+ id: string;
226
+ name: string;
227
+ price: string | null;
228
+ entryWindow: {
229
+ start: string | null;
230
+ end: string | null;
231
+ } | null;
232
+ available: boolean;
233
+ }
234
+ interface BusinessEventSummary {
235
+ id: string;
236
+ slug: string;
237
+ name: string;
238
+ imageUrl: string | null;
239
+ operationalDate: string;
240
+ startsAt: string;
241
+ endsAt: string | null;
242
+ timezone: string;
243
+ ticketTypes: BusinessTicketTypeSummary[];
244
+ }
245
+ /** Wire shape of GET /api/v1/public/catalog/:slug. */
246
+ interface BusinessInfo {
247
+ id: string;
248
+ name: string;
249
+ slug: string;
250
+ description: string | null;
251
+ logoUrl: string | null;
252
+ status: BusinessStatus;
253
+ contact: BusinessContact;
254
+ social: BusinessSocial;
255
+ schedule: BusinessSchedule | null;
256
+ estimatedPreparationTime: number;
257
+ paymentMethods: string[];
258
+ paymentMethodDetails: BusinessPaymentMethodDetail[];
259
+ sunatAvailable: boolean;
260
+ tableManagementActive: boolean;
261
+ country: string;
262
+ currency: string;
263
+ currencySymbol: string;
264
+ preferences: {
265
+ heroCarouselEnabled?: boolean;
266
+ catalogChatEnabled?: boolean;
267
+ };
268
+ orderCharges: OrderChargeDefinition[];
269
+ businessType: 'restaurante' | 'discoteca' | null;
270
+ capabilities: {
271
+ catalogEvents: boolean;
272
+ };
273
+ events: BusinessEventSummary[];
274
+ }
275
+ interface BusinessCategory {
276
+ id: string;
277
+ name: string;
278
+ description: string | null;
279
+ parentId: string | null;
280
+ order: number;
281
+ imageUrl: string | null;
282
+ imageVariants: Partial<Record<'thumb' | 'card' | 'detail' | 'optimized', string>> | null;
283
+ }
284
+ interface CustomizationOption {
285
+ id: string;
286
+ name: string;
287
+ additionalPrice: string;
288
+ order: number;
289
+ }
290
+ interface CustomizationGroup {
291
+ id: string;
292
+ name: string;
293
+ required: boolean;
294
+ minSelections: number;
295
+ maxSelections: number;
296
+ minimum: number;
297
+ maximum: number;
298
+ order: number;
299
+ options: CustomizationOption[];
300
+ }
301
+ interface BusinessProduct {
302
+ id: string;
303
+ categoryId: string | null;
304
+ name: string;
305
+ description: string | null;
306
+ type: 'menu' | 'inventario';
307
+ basePrice: string;
308
+ imageUrl: string | null;
309
+ imageVariants: Partial<Record<'thumb' | 'card' | 'detail' | 'optimized', string>> | null;
310
+ available: boolean;
311
+ preparationTime: number | null;
312
+ servingSize: string | null;
313
+ spiceLevel: number | null;
314
+ isVegetarian: boolean | null;
315
+ isVegan: boolean | null;
316
+ isGlutenFree: boolean | null;
317
+ isSpicy: boolean | null;
318
+ customizationGroups: CustomizationGroup[];
319
+ }
320
+ /** Wire shape of GET /api/v1/public/catalog/:slug/menu. */
321
+ interface CatalogMenu {
322
+ categories: BusinessCategory[];
323
+ products: BusinessProduct[];
324
+ }
325
+ interface MenuQuery {
326
+ search?: string;
327
+ }
328
+ interface BusinessTable {
329
+ id: string;
330
+ number: string;
331
+ description?: string;
332
+ status: string;
333
+ }
334
+
335
+ declare const CustomerOrderStatusSchema: z.ZodEnum<{
336
+ recibido: "recibido";
337
+ aprobado: "aprobado";
338
+ en_preparacion: "en_preparacion";
339
+ listo: "listo";
340
+ completado: "completado";
341
+ rechazado: "rechazado";
342
+ }>;
343
+ type CustomerOrderStatus = z.infer<typeof CustomerOrderStatusSchema>;
344
+
345
+ /** Wire contract for an item submitted through the public catalog order endpoint. */
346
+ interface PublicCatalogOrderItem {
347
+ productId: string;
348
+ cantidad: number;
349
+ unitPrice: string;
350
+ specialNotes?: string;
351
+ extras?: Array<{
352
+ groupName: string;
353
+ optionName: string;
354
+ additionalPrice: string;
355
+ }>;
356
+ }
357
+ /** Optional customer identity accepted by the public catalog endpoint. */
358
+ interface PublicCatalogOrderCustomer {
359
+ name?: string;
360
+ phone?: string;
361
+ whatsappOptIn?: boolean;
362
+ }
363
+ /** Reservation fields required by the public catalog reservation flow. */
364
+ interface PublicCatalogOrderReservation {
365
+ name: string;
366
+ phone: string;
367
+ arrivalDate: string;
368
+ arrivalTime: string;
369
+ peopleCount: number;
370
+ preferredTable?: string;
371
+ tableId?: string;
372
+ whatsappOptIn?: boolean;
373
+ }
374
+ type PublicCatalogOrderReceipt = {
375
+ type: 'simple';
376
+ } | {
377
+ type: 'boleta_sunat' | 'factura_sunat';
378
+ documentType?: 'dni' | 'ruc';
379
+ documentNumber?: string;
380
+ businessName?: string;
381
+ address?: string;
382
+ };
383
+ interface PublicCatalogOrderBase {
384
+ items: PublicCatalogOrderItem[];
385
+ /** Signed lead token from a WhatsApp/catalog-sharing link. */
386
+ leadToken?: string;
387
+ idempotencyKey?: string;
388
+ charges?: OrderChargeSelection[];
389
+ generalNotes?: string;
390
+ preferredPaymentMethod?: string;
391
+ sessionId?: string;
392
+ receipt?: PublicCatalogOrderReceipt;
393
+ }
394
+ /**
395
+ * Public catalog create-order payload. The discriminator mirrors the backend's
396
+ * existing `tipo` wire contract and prevents incompatible flow fields.
397
+ */
398
+ type PublicCatalogOrderPayload = (PublicCatalogOrderBase & {
399
+ tipo: Extract<CatalogOrderType, 'para_llevar'>;
400
+ customer?: PublicCatalogOrderCustomer;
401
+ }) | (PublicCatalogOrderBase & {
402
+ tipo: Extract<CatalogOrderType, 'en_mesa'>;
403
+ customer?: PublicCatalogOrderCustomer;
404
+ tableNumber?: string;
405
+ tableId?: string;
406
+ }) | (PublicCatalogOrderBase & {
407
+ tipo: Extract<CatalogOrderType, 'reserva'>;
408
+ customer?: PublicCatalogOrderCustomer;
409
+ reservation: PublicCatalogOrderReservation;
410
+ });
411
+
412
+ /** Whether the restaurant collects the delivery fee or the customer pays it separately. */
413
+ type DeliveryPaymentMode = 'business' | 'courier';
414
+ /** Frozen operational data, independent from a payment or an operating expense. */
415
+ interface AppliedDelivery {
416
+ amount: string;
417
+ paymentMode: DeliveryPaymentMode;
418
+ costTrackingEnabled: boolean;
419
+ cost: string | null;
420
+ }
421
+ /** Customer-facing delivery information must never contain internal costs. */
422
+ type PublicDelivery = Pick<AppliedDelivery, 'amount' | 'paymentMode'>;
423
+
424
+ type CreateOrderInput = PublicCatalogOrderPayload;
425
+ interface CreateOrderOptions {
426
+ /** Used only when the body has no non-empty idempotencyKey. Reuse for retries. */
427
+ idempotencyKey?: string;
428
+ signal?: AbortSignal;
429
+ }
430
+ interface OrderCreationResult {
431
+ orderId: string;
432
+ orderNumber: string;
433
+ trackingToken: string;
434
+ estimatedTime?: number;
435
+ whatsappSent?: boolean;
436
+ message?: string;
437
+ subtotal?: string;
438
+ charges?: AppliedOrderCharge[];
439
+ chargesTotal?: string;
440
+ total?: string;
441
+ currency?: string;
442
+ currencySymbol?: string;
443
+ }
444
+ /** Wire shape of GET .../orders/:orderId and GET .../tracking/:trackingToken. */
445
+ interface PublicOrderDetail {
446
+ orderId: string;
447
+ restaurantName: string;
448
+ orderNumber: string;
449
+ orderName?: string | null;
450
+ status: CustomerOrderStatus;
451
+ statusLabel: string;
452
+ orderType: string;
453
+ items: Array<{
454
+ name: string;
455
+ quantity: number;
456
+ subtotal: string;
457
+ notes: string | null;
458
+ extras: Array<{
459
+ groupName: string;
460
+ optionName: string;
461
+ }>;
462
+ }>;
463
+ itemCount: number;
464
+ subtotal: string;
465
+ charges: AppliedOrderCharge[];
466
+ chargesTotal: string;
467
+ delivery?: PublicDelivery | null;
468
+ total: string;
469
+ payment?: {
470
+ preferredMethod: string | null;
471
+ status: 'pending_payment' | 'under_review' | 'paid' | 'rejected';
472
+ amount: string;
473
+ instructions: {
474
+ methodType: BusinessPaymentMethodDetail['methodType'];
475
+ accountNumber: string | null;
476
+ accountHolder: string | null;
477
+ qrUrl: string | null;
478
+ } | null;
479
+ claim: {
480
+ id: string;
481
+ status: 'pending' | 'confirmed' | 'rejected';
482
+ referenceNumber: string;
483
+ hasProofImage: boolean;
484
+ proofImageUrl: string | null;
485
+ rejectionReason: string | null;
486
+ createdAt: string;
487
+ } | null;
488
+ };
489
+ currency: string;
490
+ currencySymbol: string;
491
+ receipt: {
492
+ type: string;
493
+ documentType: 'dni' | 'ruc' | null;
494
+ documentNumber: string | null;
495
+ url: string | null;
496
+ } | null;
497
+ customerSteps?: CustomerOrderStatus[];
498
+ rejectionReason: string | null;
499
+ createdAt: string;
500
+ updatedAt: string;
501
+ }
502
+ interface PaymentClaimInput {
503
+ referenceNumber: string;
504
+ proofImage?: Blob;
505
+ }
506
+ interface PaymentClaimResult {
507
+ id: string;
508
+ status: 'pending' | 'confirmed' | 'rejected';
509
+ referenceNumber: string;
510
+ hasProofImage: boolean;
511
+ createdAt: string;
512
+ }
513
+
514
+ declare class AccessResource {
515
+ private readonly http;
516
+ private readonly businessSlug;
517
+ constructor(http: ElenaHttpClient, businessSlug: string);
518
+ resolve(publicKey: string): Promise<CatalogAccessResolution>;
519
+ createOrder(publicKey: string, input: CreateOrderInput, options?: CreateOrderOptions): Promise<OrderCreationResult>;
520
+ }
521
+ declare class OrdersResource {
522
+ private readonly http;
523
+ private readonly businessSlug;
524
+ constructor(http: ElenaHttpClient, businessSlug: string);
525
+ create(input: CreateOrderInput, options?: CreateOrderOptions): Promise<OrderCreationResult>;
526
+ getById(orderId: string): Promise<PublicOrderDetail>;
527
+ getTracking(trackingToken: string): Promise<PublicOrderDetail>;
528
+ submitPaymentClaim(trackingToken: string, input: PaymentClaimInput): Promise<PaymentClaimResult>;
529
+ }
530
+
531
+ declare class CatalogResource {
532
+ private readonly http;
533
+ private readonly businessSlug;
534
+ constructor(http: ElenaHttpClient, businessSlug: string);
535
+ getInfo(): Promise<BusinessInfo>;
536
+ getMenu(query?: MenuQuery): Promise<CatalogMenu>;
537
+ listHeroSlides(): Promise<HeroSlide[]>;
538
+ }
539
+ declare class TablesResource {
540
+ private readonly http;
541
+ private readonly businessSlug;
542
+ constructor(http: ElenaHttpClient, businessSlug: string);
543
+ listAvailable(): Promise<BusinessTable[]>;
544
+ get(tableId: string): Promise<BusinessTable>;
545
+ }
546
+
547
+ interface ElenaApiErrorDetails {
548
+ status: number;
549
+ code?: string;
550
+ details?: unknown;
551
+ retryAfter?: string;
552
+ }
553
+ /** Backend HTTP failure. Preserves status, business code and raw payload. */
554
+ declare class ElenaApiError extends Error {
555
+ readonly status: number;
556
+ readonly code?: string;
557
+ readonly details?: unknown;
558
+ readonly retryAfter?: string;
559
+ constructor(message: string, details: ElenaApiErrorDetails);
560
+ }
561
+ /** Transport failure before any HTTP response (DNS, refused, TLS). */
562
+ declare class ElenaNetworkError extends Error {
563
+ constructor(message?: string);
564
+ }
565
+ /** Configured timeout elapsed before the complete response body was consumed. */
566
+ declare class ElenaTimeoutError extends Error {
567
+ readonly timeoutMs: number;
568
+ constructor(timeoutMs: number);
569
+ }
570
+ /** Caller-provided AbortSignal fired before completion. */
571
+ declare class ElenaRequestAbortedError extends Error {
572
+ constructor(message?: string);
573
+ }
574
+ /** Unusable API response: a redirect or a successful body that is not JSON. */
575
+ declare class ElenaResponseError extends Error {
576
+ readonly status: number;
577
+ readonly bodyText?: string;
578
+ constructor(message: string, details: {
579
+ status: number;
580
+ bodyText?: string;
581
+ });
582
+ }
583
+ type ElenaCheckoutValidationCode = 'PRODUCT_NOT_FOUND' | 'PRODUCT_UNAVAILABLE' | 'INVALID_QUANTITY' | 'UNKNOWN_GROUP' | 'UNKNOWN_OPTION' | 'DUPLICATE_OPTION' | 'REQUIRED_OPTIONS' | 'MIN_SELECTIONS' | 'MAX_SELECTIONS' | 'AMBIGUOUS_SELECTION';
584
+ /** Local catalog-snapshot validation only; the backend remains authoritative. */
585
+ declare class ElenaCheckoutValidationError extends Error {
586
+ readonly code: ElenaCheckoutValidationCode;
587
+ /** Selection path, e.g. selections[0].quantity or selections[0].selectedOptions. */
588
+ readonly field: string;
589
+ constructor(message: string, details: {
590
+ code: ElenaCheckoutValidationCode;
591
+ field: string;
592
+ });
593
+ }
594
+
595
+ interface JourneyParticipant {
596
+ name: string;
597
+ phone: string;
598
+ whatsappOptIn: boolean;
599
+ }
600
+ interface JourneySnapshot<TState = unknown> {
601
+ id: string;
602
+ capability: string;
603
+ status: string;
604
+ state: TState;
605
+ version: number;
606
+ lastActivityAt: string;
607
+ expiresAt: string;
608
+ }
609
+ interface ContinuationExchangeResult<TState = unknown> {
610
+ accessToken: string;
611
+ sessionId: string;
612
+ participant: JourneyParticipant;
613
+ journey: JourneySnapshot<TState>;
614
+ }
615
+ interface JourneyStateResult<TState = unknown> {
616
+ journey: JourneySnapshot<TState>;
617
+ }
618
+ interface JourneyEventInput {
619
+ eventId: string;
620
+ expectedVersion: number;
621
+ event: unknown;
622
+ }
623
+ interface JourneyConfirmInput {
624
+ eventId: string;
625
+ expectedVersion: number;
626
+ fingerprint: string;
627
+ }
628
+ interface JourneyOrderResult {
629
+ orderId: string;
630
+ orderNumber: string;
631
+ trackingToken: string;
632
+ }
633
+ interface JourneyConfirmationResult<TState = unknown> {
634
+ status: 'completed';
635
+ journey: JourneySnapshot<TState>;
636
+ order: JourneyOrderResult;
637
+ }
638
+ interface JourneyActionRequired<TState = unknown> {
639
+ status: 'action_required';
640
+ journey: JourneySnapshot<TState>;
641
+ }
642
+ interface JourneyConflictDetails<TState = unknown> {
643
+ journey: JourneySnapshot<TState>;
644
+ }
645
+
646
+ interface RealtimeConnection {
647
+ url: string;
648
+ }
649
+ interface ChatConnection {
650
+ apiUrl: string;
651
+ businessSlug: string;
652
+ visitorId?: string;
653
+ }
654
+ declare class RealtimeResource {
655
+ private readonly http;
656
+ private readonly businessSlug;
657
+ constructor(http: ElenaHttpClient, businessSlug: string);
658
+ /** SSE stream URL. EventSource-compatible: identity travels in query, not headers. */
659
+ getConnection(visitorId?: string): RealtimeConnection;
660
+ }
661
+ declare class ChatResource {
662
+ private readonly http;
663
+ private readonly businessSlug;
664
+ constructor(http: ElenaHttpClient, businessSlug: string);
665
+ /** Connection descriptor for the existing Tari chat runtime. No HTTP call. */
666
+ getConnection(): ChatConnection;
667
+ }
668
+ declare class ContinuationsResource {
669
+ private readonly http;
670
+ private readonly businessSlug;
671
+ constructor(http: ElenaHttpClient, businessSlug: string);
672
+ exchange<TState = unknown>(token: string): Promise<ContinuationExchangeResult<TState>>;
673
+ }
674
+ declare class JourneyConflictError<TState = unknown> extends ElenaApiError {
675
+ readonly journey: JourneySnapshot<TState>;
676
+ constructor(journey: JourneySnapshot<TState>);
677
+ }
678
+ declare class JourneyResource {
679
+ private readonly http;
680
+ private readonly businessSlug;
681
+ constructor(http: ElenaHttpClient, businessSlug: string);
682
+ getState<TState = unknown>(): Promise<JourneyStateResult<TState>>;
683
+ dispatch<TState = unknown, TData extends Record<string, unknown> = Record<string, unknown>>(input: JourneyEventInput): Promise<TData & {
684
+ journey: JourneySnapshot<TState>;
685
+ }>;
686
+ confirm<TState = unknown>(input: JourneyConfirmInput): Promise<JourneyConfirmationResult<TState> | JourneyActionRequired<TState>>;
687
+ private static withConflict;
688
+ }
689
+
690
+ type LiveSessionStatus = 'browsing' | 'cart' | 'checkout' | 'submitted' | 'abandoned';
691
+ type LiveSessionOrderType = 'para_llevar' | 'en_mesa' | 'reserva';
692
+ interface LiveSessionItem {
693
+ productId: string;
694
+ name: string;
695
+ quantity: number;
696
+ subtotal: number;
697
+ notes?: string;
698
+ extras?: Array<{
699
+ groupName: string;
700
+ optionName: string;
701
+ price: number;
702
+ }>;
703
+ }
704
+ interface LiveSessionInput {
705
+ sessionId: string;
706
+ publicKey?: string;
707
+ status: LiveSessionStatus;
708
+ orderType?: LiveSessionOrderType;
709
+ tableNumber?: string;
710
+ tableId?: string;
711
+ tableName?: string;
712
+ notes?: string;
713
+ itemCount: number;
714
+ total: number;
715
+ items: LiveSessionItem[];
716
+ lastAction: string;
717
+ }
718
+ interface LiveSessionResult {
719
+ status: 'ok';
720
+ }
721
+ interface LiveSessionBeacon {
722
+ url: string;
723
+ body: Blob;
724
+ }
725
+
726
+ /** Wire shape of GET /api/v1/public/catalog/:slug/sales/:receiptToken. */
727
+ interface SaleReceipt {
728
+ restaurantName: string;
729
+ receiptNumber: string;
730
+ orderName?: string | null;
731
+ status: 'completado';
732
+ items: Array<{
733
+ name: string;
734
+ quantity: number;
735
+ subtotal: string;
736
+ notes: string | null;
737
+ extras: Array<{
738
+ groupName: string;
739
+ optionName: string;
740
+ }>;
741
+ }>;
742
+ itemCount: number;
743
+ subtotal: string;
744
+ charges: AppliedOrderCharge[];
745
+ chargesTotal: string;
746
+ delivery?: PublicDelivery | null;
747
+ total: string;
748
+ currency: string;
749
+ currencySymbol: string;
750
+ paymentMethod: string;
751
+ receipt: {
752
+ type: string;
753
+ documentType: 'dni' | 'ruc' | null;
754
+ documentNumber: string | null;
755
+ url: string | null;
756
+ downloadStatus: 'available' | 'pending' | 'unavailable';
757
+ } | null;
758
+ createdAt: string;
759
+ }
760
+
761
+ declare class ReceiptsResource {
762
+ private readonly http;
763
+ private readonly businessSlug;
764
+ constructor(http: ElenaHttpClient, businessSlug: string);
765
+ get(receiptToken: string): Promise<SaleReceipt>;
766
+ /** PDF endpoint answers 302; callers open/download the URL, never JSON-fetch it. */
767
+ getPdfUrl(receiptToken: string): string;
768
+ }
769
+ declare class PresenceResource {
770
+ private readonly http;
771
+ private readonly businessSlug;
772
+ constructor(http: ElenaHttpClient, businessSlug: string);
773
+ report(input: LiveSessionInput, options?: {
774
+ signal?: AbortSignal;
775
+ }): Promise<LiveSessionResult>;
776
+ /** Beacon payload for pagehide/unload, where fetch cannot be awaited. */
777
+ getBeaconRequest(input: LiveSessionInput): LiveSessionBeacon;
778
+ }
779
+
780
+ /**
781
+ * Business-scoped public surface. The slug selects the business once;
782
+ * resources own the endpoints. Backend wire names (restaurantSlug) stay
783
+ * inside the SDK: consumers speak business everywhere.
784
+ */
785
+ declare class BusinessScope {
786
+ private readonly http;
787
+ readonly slug: string;
788
+ readonly catalog: CatalogResource;
789
+ readonly tables: TablesResource;
790
+ readonly access: AccessResource;
791
+ readonly orders: OrdersResource;
792
+ readonly receipts: ReceiptsResource;
793
+ readonly presence: PresenceResource;
794
+ readonly continuations: ContinuationsResource;
795
+ readonly realtime: RealtimeResource;
796
+ readonly chat: ChatResource;
797
+ private readonly eventsResource;
798
+ private readonly ticketsResource;
799
+ constructor(http: ElenaHttpClient, slug: string);
800
+ getInfo(): Promise<BusinessInfo>;
801
+ getEvent(eventSlug: string): Promise<EventDetail>;
802
+ emitTickets(input: Omit<TicketEmissionInput, 'restaurantSlug'>): Promise<TicketEmissionResult>;
803
+ }
804
+
805
+ declare class EventsResource {
806
+ private readonly http;
807
+ constructor(http: ElenaHttpClient);
808
+ get(businessSlug: string, eventSlug: string): Promise<EventDetail>;
809
+ }
810
+ declare class TicketsResource {
811
+ private readonly http;
812
+ constructor(http: ElenaHttpClient);
813
+ emit(input: TicketEmissionInput): Promise<TicketEmissionResult>;
814
+ getStatus(token: string): Promise<TicketStatus>;
815
+ }
816
+ declare class AssetsResource {
817
+ private readonly http;
818
+ constructor(http: ElenaHttpClient);
819
+ /** Render endpoint serves binary content; callers use the URL, never JSON-fetch it. */
820
+ getRenderUrl(assetId: string): string;
821
+ }
822
+
823
+ interface ElenaPublicClient {
824
+ business(slug: string): BusinessScope;
825
+ readonly tickets: TicketsResource;
826
+ readonly assets: AssetsResource;
827
+ }
828
+ declare function createElenaPublicClient(options: ElenaClientOptions): ElenaPublicClient;
829
+ interface ElenaJourneyClientOptions {
830
+ baseUrl: string;
831
+ businessSlug: string;
832
+ accessToken: string;
833
+ fetch?: ElenaFetch;
834
+ timeoutMs?: number;
835
+ }
836
+ interface ElenaJourneyClient {
837
+ readonly businessSlug: string;
838
+ readonly journeys: JourneyResource;
839
+ }
840
+ declare function createElenaJourneyClient(options: ElenaJourneyClientOptions): ElenaJourneyClient;
841
+
842
+ /** Product/option IDs from one public catalog snapshot; no caller-supplied prices. */
843
+ interface OrderItemSelection {
844
+ productId: string;
845
+ quantity: number;
846
+ selectedOptions?: readonly {
847
+ groupId: string;
848
+ optionId: string;
849
+ }[];
850
+ notes?: string;
851
+ }
852
+ /**
853
+ * Build the public order wire items without changing the snapshot or selections.
854
+ * Prices remain decimal strings: unitPrice is the base price, extras are separate.
855
+ * This is early snapshot validation, not a quote, reservation or server guarantee.
856
+ */
857
+ declare function buildOrderItems(menu: CatalogMenu, selections: readonly OrderItemSelection[]): PublicCatalogOrderItem[];
858
+
859
+ interface ElenaClientKeyClientOptions extends ElenaKeyTransportOptions {
860
+ clientKey: string;
861
+ }
862
+ interface ElenaClientKeyClient {
863
+ context: {
864
+ get(options?: ElenaKeyRequestOptions): Promise<ElenaClientContextV1>;
865
+ };
866
+ catalog: {
867
+ list(query?: ElenaKeyPageQuery, options?: ElenaKeyRequestOptions): Promise<ElenaClientCatalogV1>;
868
+ getProduct(id: string, options?: ElenaKeyRequestOptions): Promise<ElenaClientProductResponseV1>;
869
+ };
870
+ assets: {
871
+ get(id: string, options?: ElenaKeyRequestOptions): Promise<ElenaClientAssetResponseV1>;
872
+ };
873
+ }
874
+ /** Published menu only. This client never accepts an agent secret or bearer token. */
875
+ declare function createElenaClientKeyClient(options: ElenaClientKeyClientOptions): ElenaClientKeyClient;
876
+
877
+ /** The explicit origin is pinned: discovery cannot redirect credentials to another API. */
878
+ declare function discoverElenaPublicConnection(options: ElenaKeyTransportOptions, slug: string, requestOptions?: ElenaKeyRequestOptions): Promise<{
879
+ version: "1";
880
+ apiOrigin: string;
881
+ clientKey: string;
882
+ publication: {
883
+ revision: number;
884
+ expiresAt: string;
885
+ };
886
+ context: {
887
+ version: "1";
888
+ restaurant: {
889
+ id: string;
890
+ name: string;
891
+ slug: string;
892
+ currency: "PEN";
893
+ };
894
+ capabilities: {
895
+ menu: true;
896
+ assets: true;
897
+ };
898
+ };
899
+ }>;
900
+
901
+ export { AccessResource, type AppliedOrderCharge, AssetsResource, type BusinessCategory, type BusinessEventSummary, type BusinessInfo, type BusinessPaymentMethodDetail, type BusinessProduct, type BusinessSchedule, BusinessScope, type BusinessSocial, type BusinessStatus, type BusinessTable, type BusinessTicketTypeSummary, type CatalogMenu, CatalogResource, type ChatConnection, ChatResource, type ContinuationExchangeResult, ContinuationsResource, type CreateOrderInput, type CreateOrderOptions, type CustomerOrderStatus, type CustomizationGroup, type CustomizationOption, ElenaApiError, type ElenaApiErrorDetails, type ElenaCheckoutValidationCode, ElenaCheckoutValidationError, ElenaClientAssetResponseV1, ElenaClientCatalogV1, ElenaClientContextV1, type ElenaClientKeyClient, type ElenaClientKeyClientOptions, ElenaClientOptions, ElenaClientProductResponseV1, ElenaFetch, ElenaHttpClient, type ElenaJourneyClient, type ElenaJourneyClientOptions, ElenaKeyPageQuery, ElenaKeyRequestOptions, ElenaKeyTransportOptions, ElenaNetworkError, type ElenaPublicClient, ElenaRequestAbortedError, ElenaResponseError, ElenaTimeoutError, type EmittedTicket, type EventDetail, type EventTicketType, EventsResource, type HeroSlide, type JourneyActionRequired, type JourneyConfirmInput, type JourneyConfirmationResult, type JourneyConflictDetails, JourneyConflictError, type JourneyEventInput, type JourneyOrderResult, type JourneyParticipant, JourneyResource, type JourneySnapshot, type JourneyStateResult, type LiveSessionBeacon, type LiveSessionInput, type LiveSessionOrderType, type LiveSessionResult, type LiveSessionStatus, type MenuQuery, type OrderChargeDefinition, type OrderCreationResult, type OrderItemSelection, OrdersResource, type PaymentClaimInput, type PaymentClaimResult, PresenceResource, type PublicCatalogOrderItem, type PublicCatalogOrderPayload, type PublicOrderDetail, type RealtimeConnection, RealtimeResource, ReceiptsResource, type SaleReceipt, TablesResource, type TicketEmissionInput, type TicketEmissionResult, type TicketEstado, type TicketStatus, TicketsResource, buildOrderItems, createElenaClientKeyClient, createElenaJourneyClient, createElenaPublicClient, discoverElenaPublicConnection };