@estoreclub/api 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/bridgeClient.d.ts +10 -0
  2. package/dist/bridgeClient.js +10 -0
  3. package/dist/bridgeClient.js.map +7 -0
  4. package/dist/chunks/chunk-2554RPSS.js +45 -0
  5. package/dist/chunks/chunk-2554RPSS.js.map +7 -0
  6. package/dist/chunks/chunk-2BH4QPV2.js +27 -0
  7. package/dist/chunks/chunk-2BH4QPV2.js.map +7 -0
  8. package/dist/chunks/chunk-3KEEGSMP.js +86 -0
  9. package/dist/chunks/chunk-3KEEGSMP.js.map +7 -0
  10. package/dist/chunks/chunk-5DN7L6LX.js +861 -0
  11. package/dist/chunks/chunk-5DN7L6LX.js.map +7 -0
  12. package/dist/chunks/chunk-DUVULZ6N.js +111 -0
  13. package/dist/chunks/chunk-DUVULZ6N.js.map +7 -0
  14. package/dist/chunks/chunk-GJZ7EZEF.js +25 -0
  15. package/dist/chunks/chunk-GJZ7EZEF.js.map +7 -0
  16. package/dist/chunks/chunk-HFEQWXG6.js +24 -0
  17. package/dist/chunks/chunk-HFEQWXG6.js.map +7 -0
  18. package/dist/chunks/chunk-OFFTL6RC.js +24 -0
  19. package/dist/chunks/chunk-OFFTL6RC.js.map +7 -0
  20. package/dist/chunks/chunk-TSERNR4R.js +15 -0
  21. package/dist/chunks/chunk-TSERNR4R.js.map +7 -0
  22. package/dist/chunks/chunk-ZITPZDI7.js +280 -0
  23. package/dist/chunks/chunk-ZITPZDI7.js.map +7 -0
  24. package/dist/client.d.ts +407 -0
  25. package/dist/client.js +14 -0
  26. package/dist/client.js.map +7 -0
  27. package/dist/companyApiKey.d.ts +9 -0
  28. package/dist/companyApiKey.js +9 -0
  29. package/dist/companyApiKey.js.map +7 -0
  30. package/dist/customerToken.d.ts +18 -0
  31. package/dist/customerToken.js +11 -0
  32. package/dist/customerToken.js.map +7 -0
  33. package/dist/errors.d.ts +41 -0
  34. package/dist/errors.js +9 -0
  35. package/dist/errors.js.map +7 -0
  36. package/dist/index.d.ts +82 -0
  37. package/dist/index.js +166 -0
  38. package/dist/index.js.map +7 -0
  39. package/dist/language.d.ts +27 -0
  40. package/dist/language.js +11 -0
  41. package/dist/language.js.map +7 -0
  42. package/dist/params.d.ts +58 -0
  43. package/dist/params.js +27 -0
  44. package/dist/params.js.map +7 -0
  45. package/dist/requestCache.d.ts +46 -0
  46. package/dist/requestCache.js +9 -0
  47. package/dist/requestCache.js.map +7 -0
  48. package/dist/siteData.d.ts +237 -0
  49. package/dist/siteData.js +132 -0
  50. package/dist/siteData.js.map +7 -0
  51. package/dist/types.d.ts +2123 -0
  52. package/dist/types.js +1 -0
  53. package/dist/types.js.map +7 -0
  54. package/dist/visitorCountry.d.ts +25 -0
  55. package/dist/visitorCountry.js +15 -0
  56. package/dist/visitorCountry.js.map +7 -0
  57. package/package.json +64 -4
  58. package/README.md +0 -3
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../packages/api/src/client.ts"],
4
+ "sourcesContent": ["import type {\n AddCartItemParams,\n ComboPick,\n CreateCheckoutParams,\n GetCartParams,\n GetCheckoutParams,\n TrackOrderParams,\n GetCategoryParams,\n ListCategoriesParams,\n ListProductsParams,\n Paginated,\n PublicCart,\n PublicCheckout,\n PublicCheckoutSession,\n PublicCategory,\n PublicCompany,\n GetDictionaryParams,\n GetProductParams,\n ListCombosParams,\n PublicCategoryInclude,\n PublicCombo,\n PublicDiscountRule,\n PublicDictionary,\n PublicImage,\n PublicDictionarySummary,\n PublicStoreLocation,\n PublicTerms,\n PublicProduct,\n PublicProductInclude,\n PublicProductVariant,\n PublicProductSettingDefinition,\n PublicSiteInfo,\n RemoveCartItemParams,\n SetCartBookingParams,\n SetCartItemQuantityParams,\n SetCheckoutEmailParams,\n ProductSort,\n CreateBookingParams,\n GetBookingPlanParams,\n GetBookingSlotsParams,\n GetOrderTimesParams,\n PublicBooking,\n CustomerTokenParams,\n PublicCustomer,\n PublicCustomerAccount,\n PublicCustomerBooking,\n PublicBookingPreorder,\n SetBookingPreorderParams,\n PublicCustomerOrder,\n PublicCustomerOrderDetail,\n PublicCustomerSession,\n CustomerPage,\n CustomerHistoryParams,\n CustomerBookingsParams,\n AddCustomerAddressParams,\n PublicCustomerAddress,\n PublicCustomerPaymentMethod,\n CreateProductCommentParams,\n DeleteProductCommentParams,\n GetProductCommentsParams,\n GetProductFeedbackParams,\n PublicProductComment,\n PublicProductCommentsPage,\n PublicProductFeedback,\n PublicCommentVoteResult,\n PublicProductRating,\n RateProductParams,\n UnrateProductParams,\n VoteProductCommentParams,\n RequestSignInCodeParams,\n SignInWithAppleParams,\n SignInWithGoogleParams,\n RefreshCustomerTokenParams,\n UpdateCustomerProfileParams,\n VerifySignInCodeParams,\n PublicBookingPlan,\n PublicBookingSlots,\n PublicOrderTimes,\n PublicDiningTable,\n} from \"./types\";\n\nimport { getCompanyApiKey } from \"./companyApiKey\";\nimport { PublicApiError, refusalFactsOf, type RefusalFacts } from \"./errors\";\nimport { memoGet } from \"./requestCache\";\nimport {\n flag,\n idOrName,\n include,\n oneOf,\n paging,\n segment,\n text,\n trimSlash,\n whole,\n} from \"./params\";\nimport { resolveCustomerToken } from \"./customerToken\";\nimport { resolveLanguage } from \"./language\";\nimport { normalCountry, resolveVisitorCountry } from \"./visitorCountry\";\n\n/** The longest comment the server keeps (`PRODUCT_COMMENT_MAX_LENGTH`). */\nconst COMMENT_MAX_LENGTH = 2000;\n\n/** Everything a category can carry. Asked for when a caller does not narrow it. */\nconst CATEGORY_INCLUDES: readonly PublicCategoryInclude[] = [\n \"translations\",\n \"media\",\n \"count\",\n];\n\n/** Everything a listed product can carry. Asked for when a caller does not narrow it. */\nconst PRODUCT_INCLUDES: readonly PublicProductInclude[] = [\n \"translations\",\n \"media\",\n \"categories\",\n \"settings\",\n];\n\n/** The orders a product list may be asked for \u2014 anything else is dropped, not sent. */\nconst PRODUCT_SORTS: readonly ProductSort[] = [\n \"custom\",\n \"name\",\n \"price\",\n \"popularity\",\n \"discount\",\n];\n\n/** Per-call budget. A slow internal service must not hold a page render open. */\nconst DEFAULT_TIMEOUT_MS = 2000;\n\n/**\n * For the calls that wait on STRIPE.\n *\n * Two seconds is right for this server answering out of its own database \u2014 a catalogue read\n * that takes longer than that has gone wrong. Opening a checkout is a different shape of\n * request: the server creates a session at Stripe and waits for it, over the internet, and a\n * cold one regularly takes three or four. The 2s ceiling aborted those, and a visitor pressing\n * Pay got \"Checkout is not available right now\" for a payment that was about to work.\n *\n * Fifteen seconds is Stripe's own guidance for a client waiting on their API. It is long\n * enough that the ceiling means \"Stripe is down\" rather than \"Stripe was slow\".\n */\nconst STRIPE_TIMEOUT_MS = 15_000;\n\n/** The most of one thing a cart line may hold. A basket, not a wholesale order. */\nconst MAX_QUANTITY = 99;\n\nexport interface PublicApiConfig {\n /** e.g. `http://localhost:4000` \u2014 the value of `NEXT_PUBLIC_SERVER_URL`. */\n baseUrl: string;\n /**\n * The COMPANY's own key, and the only credential this client knows.\n *\n * It goes on the wire as `x-company-api-key`, which every public route authenticates with \u2014\n * and the server resolves the company FROM it. That is why there is no domain in this\n * config: the key already says whose data this is, so there is nothing left for a caller to\n * choose, and no way to point one company's key at another's catalogue.\n *\n * `setCompanyApiKey()` sets the same thing process-wide, for a caller that learns the key\n * after this client was built; a key given here wins over that one.\n *\n * Where it comes from is deliberately somebody else's problem. The TRUSTED layer in front of\n * a rendered page \u2014 the preview's route handler, the public site's server \u2014 turns a host or\n * a deployment id into a company key and hands the page only that. The platform key and the\n * lookup that uses it never enter this package.\n */\n companyApiKey?: string;\n /**\n * Read a product SAMPLE instead of the company's own catalogue \u2014 its slug, e.g. `sample-pizza`,\n * the same id a template names as its `productSampleId`. Sent as `x-product-sample`.\n *\n * The key still decides whose SITE this is: `getSiteInfo()` answers with the company's own\n * name, languages and currency. Only the menu changes \u2014 products, categories, lists, product\n * settings, and the cart built from them. A checkout is refused, since nobody sells a sample.\n */\n productSample?: string;\n /**\n * The visitor a call is made for, sent as `x-visitor-ip` with `platformKey` as `x-api-key`:\n * the API counts the emails a visitor sets off (sign-in codes, confirmations) by their address,\n * and a call relayed by a server would otherwise all come from that server. Believed only with\n * the platform key, so set by the platform's own site server only - never page code.\n */\n visitor?: { ip: string; platformKey: string };\n /**\n * How `fetch` may cache. `no-store` unless told otherwise: a page is rendered per request\n * and a menu, a price or a basket must never be served stale.\n *\n * A STATIC EXPORT is the exception \u2014 it is rendered once, at build time, and Next refuses a\n * `no-store` fetch there (the route \"couldn't be rendered statically\"), which a page catches\n * as an unavailable API and draws its empty state. The template preview is one.\n */\n cache?: RequestCache;\n /**\n * The language names and descriptions come back in, sent as `x-language`. Omitted, the one\n * `setLanguageResolver()` answers with for this request \u2014 see `language.ts`. Null: the shop's\n * default, never the resolver - a client made for one request, whose resolver may be set by\n * another request's render at the same moment.\n */\n language?: string | null;\n /**\n * The signed-in customer every call is made as, sent as `x-customer-token` - what a shop\n * open to signed-in customers only (`customerAccess: signed_in`) needs on its catalogue,\n * cart and checkout reads too. A call's own `customerToken` wins. Omitted, the one\n * `setCustomerTokenResolver()` answers with for this render - see `customerToken.ts`. Set by\n * the trusted layer only, from its cookie: the token never reaches page code. Null: a guest,\n * never the resolver - a client made for one request (the RPC endpoint), which must not pick\n * up the token of another visitor's render running at the same moment.\n */\n customerToken?: string | null;\n /**\n * The country the visitor is in (\"NZ\"), answered as `getSiteInfo().visitorCountry`. Omitted,\n * the one `setVisitorCountryResolver()` answers with for this render - see\n * `visitorCountry.ts`. Null: unknown, never the resolver - a client made for one request.\n */\n visitorCountry?: string | null;\n /** Injected for tests, and for callers with their own fetch wrapper (caching, retries). */\n fetchImpl?: typeof fetch;\n timeoutMs?: number;\n}\n\n/**\n * The public API, bound to one company by its key.\n *\n * Every method here maps to a route that exists. A page list is not among them, so it is\n * absent rather than stubbed.\n *\n * The listings and single-category read take `include`, the optional parts of each row. The\n * API sends none of them unless asked; this client asks for ALL of them unless the caller\n * narrows the list \u2014 pages written before `include` existed keep rendering images and\n * settings, and a page that wants a lighter response says which parts it needs.\n */\nexport interface PublicApiClient {\n /** The company the key belongs to, minus the key itself. */\n getCompany(): Promise<PublicCompany>;\n /** The same record as a *site*: what a page renders in its header and its `<head>`. */\n getSiteInfo(): Promise<PublicSiteInfo>;\n /**\n * Active categories, in the order the author arranged them. A plain array \u2014 this route is\n * not paginated, so `limit` is applied to the answer rather than to the request.\n */\n getCategories(params?: ListCategoriesParams): Promise<PublicCategory[]>;\n /** One category by `id`, or by what it is CALLED. See `GetCategoryParams`. */\n getCategory(params: GetCategoryParams): Promise<PublicCategory>;\n /** Active products. PAGINATED \u2014 the list is under `.data`, unlike categories. */\n getProducts(params?: ListProductsParams): Promise<Paginated<PublicProduct>>;\n /**\n * One product by `id`, or by what it is called \u2014 the counterpart of `getCategory`.\n *\n * A page written by hand can say \"Pizza Margherita\"; a page holding a row from a listing\n * passes its `id`. Always carries every part \u2014 the same settings, media and prices as a\n * full listing row.\n */\n getProduct(params: GetProductParams): Promise<PublicProduct>;\n /**\n * The shop's own settings CATALOGUE: which fields it keeps on a product, what kind of value\n * each holds, and which of them it shows. A plain array \u2014 the response wraps it in\n * `{ settings }` and this unwraps it, the way `getCategories` flattens its own answer.\n *\n * For one product's values, read `product.settings`: the same keys, described, with what\n * that product holds.\n *\n * Only the fields the shop has switched on and lets websites read: a field it keeps private\n * (a SKU, a cost, a supplier) is in neither answer.\n */\n getProductSettings(params?: {\n /** Only the yes/no fields \u2014 the same set `getProducts({ tags })` filters against. */\n tagsOnly?: boolean;\n }): Promise<PublicProductSettingDefinition[]>;\n\n /**\n * Every list the shop can read \u2014 its own, then the platform's (currencies, languages) \u2014\n * with the columns their entries carry, but not the entries. Find a list here, read its\n * entries with `getDictionary({ identifier })`.\n *\n * Only the lists the shop marked \"Visible on site\" in the admin; a list it keeps private is\n * not here, and a column it keeps private is left out of every list.\n */\n listDictionaries(): Promise<PublicDictionarySummary[]>;\n\n /**\n * The shop's locations, in its own order \u2014 for a \"find us\" list or a map. Not split by\n * workspace: a location is a place. Empty for a shop that has entered none.\n */\n getLocations(): Promise<PublicStoreLocation[]>;\n\n /** A table a guest is ordering from, by the id on its QR code: its name, and whether it is open. */\n getDiningTable(params: { tableId: string }): Promise<PublicDiningTable>;\n\n /** Checks the code staff gave a guest at this table; rejects a wrong one. Books nothing. */\n verifyDiningTableCode(params: { tableId: string; code: string }): Promise<void>;\n\n\n /**\n * The shop's terms and privacy policy - whether customers must accept them, and the text it\n * wrote (Markdown) in the visitor's language. Shown at sign-up and to a signed-in customer\n * with `terms` among their `missingFields`; accepted with `acceptTerms: true` on their account.\n */\n getTerms(params?: { language?: string }): Promise<PublicTerms>;\n\n /**\n * The times a party can book on a day at one location \u2014 every half hour it is open, each\n * saying whether a table that seats them is free. Refused while the shop takes no bookings\n * (`getSiteInfo().reservationMode` not `off`).\n */\n getBookingSlots(params: GetBookingSlotsParams): Promise<PublicBookingSlots>;\n\n /**\n * When an order can be for \u2014 now, and the later times on the location's clock. Empty `days`\n * when the shop does not let customers choose a time.\n */\n getOrderTimes(params?: GetOrderTimesParams): Promise<PublicOrderTimes>;\n\n /** The location's floor plan at a time: what to draw, which tables are free, the best fit. */\n getBookingPlan(params: GetBookingPlanParams): Promise<PublicBookingPlan>;\n\n /**\n * Book a table \u2014 confirmed at once. Refused (409) when no table is free any more; pick\n * another time.\n */\n createBooking(params: CreateBookingParams): Promise<PublicBooking>;\n\n /**\n * Emails the visitor a six-digit sign-in code \u2014 only while `customerSignInMethods.email`.\n * There is no separate sign-up: an email the shop does not know becomes a\n * customer. Refused (429) when a code went to that email under two minutes ago.\n */\n requestSignInCode(\n params: RequestSignInCodeParams,\n ): Promise<{ expiresIn: number }>;\n\n /**\n * Signs in with the emailed code. Keep the `token` it answers with where only the site's\n * server can read it (an httpOnly cookie), and pass it as `customerToken`.\n */\n verifySignInCode(\n params: VerifySignInCodeParams,\n ): Promise<PublicCustomerSession>;\n\n /** Signs in with the ID token Google Identity Services gave the page. */\n signInWithGoogle(\n params: SignInWithGoogleParams,\n ): Promise<PublicCustomerSession>;\n\n /**\n * Signs in with the ID token the platform's Apple popup posted back, and the name Apple sent\n * beside it (the first sign-in only).\n */\n signInWithApple(\n params: SignInWithAppleParams,\n ): Promise<PublicCustomerSession>;\n\n /**\n * Trades a refresh token for a new session \u2014 a new `token` AND a new `refreshToken`; the one\n * sent is spent. 401 when it is unknown, run out, spent, or for another shop: sign out.\n * Server side only, like the sign-ins: neither token may reach the browser.\n */\n refreshCustomerToken(\n params: RefreshCustomerTokenParams,\n ): Promise<PublicCustomerSession>;\n\n /** Ends the session the refresh token belongs to. Quiet for one already gone. */\n signOutCustomer(params: RefreshCustomerTokenParams): Promise<void>;\n\n /** The signed-in customer, with their recent orders and bookings. 401 when the token lapsed. */\n getCustomerAccount(\n params: CustomerTokenParams,\n ): Promise<PublicCustomerAccount>;\n\n /** The signed-in customer's orders on this site, newest first. */\n getCustomerOrders(\n params: CustomerTokenParams & CustomerHistoryParams,\n ): Promise<CustomerPage<PublicCustomerOrder>>;\n\n /** One of their orders, with its lines. Rejects (404) for an order that is not theirs. */\n getCustomerOrder(\n params: CustomerTokenParams & { orderId: string },\n ): Promise<PublicCustomerOrderDetail>;\n\n /** Their bookings \u2014 upcoming by default. */\n getCustomerBookings(\n params: CustomerTokenParams & CustomerBookingsParams,\n ): Promise<CustomerPage<PublicCustomerBooking>>;\n\n /**\n * Calls off one of their bookings \u2014 only while it is still ahead and not yet seated. Answers\n * with the booking, now `cancelled`.\n */\n cancelCustomerBooking(\n params: CustomerTokenParams & {\n /** The booking - its `bookingNumber` (`12`) or its `bookingId`. */\n bookingId: string | number;\n },\n ): Promise<PublicCustomerBooking>;\n\n /**\n * Sets the dishes they order ahead for one of their bookings - every dish and how many,\n * replacing what was there; empty takes the preorder away. Kept as the booking's unpaid order,\n * paid at the table. Refused once the booking is no longer theirs to change\n * (`cancellableUntil`). Answers with the preorder as kept, or null.\n */\n setCustomerBookingPreorder(\n params: SetBookingPreorderParams,\n ): Promise<{ preorder: PublicBookingPreorder | null }>;\n\n /** The places they have had orders delivered to, or saved - the one used last first. */\n getCustomerAddresses(\n params: CustomerTokenParams,\n ): Promise<{ data: PublicCustomerAddress[] }>;\n\n /** Saves an address for them; the same one again only moves its `lastUsedAt`. */\n addCustomerAddress(\n params: AddCustomerAddressParams,\n ): Promise<PublicCustomerAddress>;\n\n /** Forgets one of their addresses. */\n deleteCustomerAddress(\n params: CustomerTokenParams & { customerAddressId: string },\n ): Promise<void>;\n\n /** The cards they saved paying here - brand, last four, expiry; nothing that can pay. */\n getCustomerPaymentMethods(\n params: CustomerTokenParams,\n ): Promise<{ data: PublicCustomerPaymentMethod[] }>;\n\n /** Removes one of their saved cards. Refused (409) for one an upcoming booking keeps. */\n deleteCustomerPaymentMethod(\n params: CustomerTokenParams & { paymentMethodId: string },\n ): Promise<void>;\n\n /**\n * Their favourite products, as `getProducts` lists them - the same paging, `include` and\n * filters, limited to the ones they added.\n */\n getCustomerFavourites(\n params: CustomerTokenParams & ListProductsParams,\n ): Promise<Paginated<PublicProduct>>;\n\n /** Just their favourites' ids, newest first - to fill in the hearts on a listing. */\n getCustomerFavouriteIds(\n params: CustomerTokenParams,\n ): Promise<{ productIds: string[] }>;\n\n /** Adds a product to their favourites; one already there stays once. */\n addCustomerFavourite(\n params: CustomerTokenParams & { productId: string },\n ): Promise<void>;\n\n /** Takes a product out of their favourites; one not there is no error. */\n removeCustomerFavourite(\n params: CustomerTokenParams & { productId: string },\n ): Promise<void>;\n\n /** Changes the signed-in customer's name or phone; their email stays. */\n updateCustomerProfile(\n params: UpdateCustomerProfileParams,\n ): Promise<PublicCustomer>;\n\n /**\n * What a product takes \u2014 comments, stars, likes \u2014 and its totals. Any visitor may read it;\n * pass `customerToken` for the signed-in customer's own stars.\n */\n getProductFeedback(\n params: GetProductFeedbackParams,\n ): Promise<PublicProductFeedback>;\n\n /**\n * A product's comments, newest first \u2014 roots only, each with its `replyCount`. With\n * `parentId`, that root's replies, oldest first. Empty when the product takes no comments.\n */\n getProductComments(\n params: GetProductCommentsParams,\n ): Promise<PublicProductCommentsPage>;\n\n /**\n * Comments on a product as the signed-in customer, or replies with `parentId`. 403 when the\n * product takes no comments (`getProductFeedback().allowComments`).\n */\n createProductComment(\n params: CreateProductCommentParams,\n ): Promise<PublicProductComment>;\n\n /** Removes one of the signed-in customer's own comments; a root goes with its replies. */\n deleteProductComment(params: DeleteProductCommentParams): Promise<void>;\n\n /**\n * The signed-in customer's vote on a product, the shop's way (`productVoting`): stars or a\n * like / dislike. A new one replaces theirs. Answers with the product's votes. 403 when the\n * product takes none, 400 for a vote the other way.\n */\n rateProduct(params: RateProductParams): Promise<PublicProductRating>;\n\n /** Takes the signed-in customer's vote on a product back. */\n unrateProduct(params: UnrateProductParams): Promise<PublicProductRating>;\n\n /**\n * The signed-in customer's vote on a comment, the shop's way (`commentVoting`); 0 takes it\n * back. Answers with the comment's votes.\n */\n voteProductComment(\n params: VoteProductCommentParams,\n ): Promise<PublicCommentVoteResult>;\n\n /**\n * The combos on sale NOW \u2014 active, inside their dates and inside one of their weekly windows\n * at the moment of the request \u2014 in the shop's order, each with its slots and the products\n * that may fill them. Pass `categoryId` for the ones the shop displays in that category.\n */\n getCombos(params?: ListCombosParams): Promise<PublicCombo[]>;\n\n /**\n * The discount rules on now, for badging the products they target. Display only: the cart\n * decides which rule a unit actually takes.\n */\n getDiscountRules(): Promise<PublicDiscountRule[]>;\n\n /**\n * One of the shop's own lists, by `identifier`, by `id` or by name \u2014 its sizes, its add-ons,\n * its ingredients.\n *\n * `identifier` is the handle the shop gave the list (`\"add_ons\"`): set once, never changed,\n * and shown on the list's own page in the admin. Write pages against it \u2014 the label is\n * translated and reworded, so a page reading by name breaks when the shop renames the list.\n *\n * What a product carries is the NAMES it uses out of a list; this is the list itself, with\n * the columns each entry holds. A page that prices an add-on reads it here, because the\n * surcharge is a fact about the entry rather than about any product offering it.\n *\n * A list the shop keeps private (not \"Visible on site\") answers 404 exactly like a missing\n * one, and a private column is left out of `columns` and of every entry's `values`.\n */\n getDictionary(params: GetDictionaryParams): Promise<PublicDictionary>;\n\n /**\n * Several lists in ONE request, by identifier \u2014 the batch form of `getDictionary`.\n *\n * A page that needs many lists (a menu's sizes, add-ons, bases, \u2026) reads them all in a single\n * round trip instead of one each. The answer is the lists that exist, each carrying its own\n * `identifier` to match back against what was asked; an identifier with no list is simply\n * absent (not an error), so map by `identifier` rather than by position. A private list is\n * absent the same way.\n */\n getDictionaries(params: {\n identifiers: string[];\n }): Promise<PublicDictionary[]>;\n\n /**\n * Size and resized copies of pictures the site holds only as URLs \u2014 a \"Site images\" entry, a\n * size's drawing, a location photo \u2014 so `Image` can serve them like a product's photos.\n *\n * Answers only for the shop's own media and the platform's shared images that have copies;\n * any other URL is left out, and is drawn from the URL as it is. At most 200 per call.\n */\n lookupImages(params: { urls: string[] }): Promise<PublicImage[]>;\n\n /**\n * The basket, held by the server so it survives a reload.\n *\n * `createCart` first; everything after it needs the `cartId` that returns. The server also\n * sets that id as a cookie, so a browser on the same site can omit it \u2014 but this client\n * passes it explicitly whenever it has one, because a server component has no cookie jar and\n * because an explicit id cannot be silently swapped by whatever the jar happens to hold.\n *\n * Every call answers with the WHOLE cart, so a caller never has to reconstruct it from a\n * response describing only what changed.\n */\n createCart(): Promise<PublicCart>;\n getCart(params: GetCartParams): Promise<PublicCart>;\n /** Adds, or increases a line already there \u2014 lines are (product, variantId, variant). */\n addCartItem(params: AddCartItemParams): Promise<PublicCart>;\n /** Zero removes the line, so a stepper needs no second call. */\n setCartItemQuantity(params: SetCartItemQuantityParams): Promise<PublicCart>;\n removeCartItem(params: RemoveCartItemParams): Promise<PublicCart>;\n /** Say which table booking the basket is ordered for - or none. */\n setCartBooking(params: SetCartBookingParams): Promise<PublicCart>;\n destroyCart(params: GetCartParams): Promise<void>;\n\n /**\n * Turn the basket into a checkout, and get the page that takes the payment.\n *\n * The answer's `checkoutUrl` is where the SHOPPER goes \u2014 redirect their browser to it. The\n * page asks for their email unless `customerEmail` was given, shows the order, takes the card\n * (saving it only if they choose), and sends them back to `successUrl` once paid. The cart moves to `checkout` now, and to `paid` when Stripe\n * confirms.\n */\n createCheckout(params: CreateCheckoutParams): Promise<PublicCheckout>;\n\n /**\n * Read a checkout \u2014 including what is needed to take the card in the page itself.\n *\n * The id is the credential, exactly as a cart id is: the route takes no key, because the\n * page that charges may be a browser. While the checkout can still be paid the answer\n * carries `payment`, which Stripe's Elements mount against; once it is paid or cancelled\n * that is gone and `status` is the answer.\n */\n getCheckout(params: GetCheckoutParams): Promise<PublicCheckoutSession>;\n\n /**\n * Record who is paying, from the site's own payment page \u2014 the receipt goes there, and it is\n * how a card they saved at this shop is offered again. Answers with the checkout as\n * `getCheckout` would, its `payment` now carrying `customerSessionClientSecret`. Like\n * `getCheckout`, the id is the credential; refused once the checkout can no longer be paid.\n */\n setCheckoutEmail(\n params: SetCheckoutEmailParams,\n ): Promise<PublicCheckoutSession>;\n\n /**\n * Find a placed order for the shop's tracking page - signed in or not: its `number` (`1042`,\n * `#1042`, or the delivery's `D-17`) with the `email` it was placed with, or `checkoutId`\n * alone. Answers as `getCustomerOrder` does, with `shipment` once a carrier has it. Every\n * mismatch is the same 404 (`order_track_not_found`); limited per visitor (429). Never cached.\n */\n trackOrder(params: TrackOrderParams): Promise<PublicCustomerOrderDetail>;\n}\n\n/**\n * Build a client.\n *\n * Whose data it reads is decided entirely by the key, and that is the whole design. A client\n * that took a domain per call would let whoever held one read any company; a client that took\n * one at construction still made every caller carry a value the server does not read. Neither\n * is here any more.\n */\nexport function createPublicApiClient(\n config: PublicApiConfig,\n): PublicApiClient {\n const call = requester(config);\n const send = writer(config);\n // One lookup per key, so a render that asks for the site's name in its layout and again in\n // its page makes one request rather than two.\n const companyRecord = companyResolver(config);\n\n return {\n getCompany: async () => strip(await companyRecord()),\n getSiteInfo: async () => {\n const company = await companyRecord();\n\n return {\n siteName: company.name,\n defaultLanguage: company.defaultLanguage,\n languages: company.languages ?? [],\n currency: company.defaultCurrency,\n countryCode: company.countryCode ?? null,\n // Per request, not per company: asked of the render, never of the API.\n visitorCountry:\n config.visitorCountry === null\n ? null\n : (normalCountry(config.visitorCountry) ?? resolveVisitorCountry()),\n currencySymbol: company.currencySymbol,\n currencySymbolPosition: company.currencySymbolPosition,\n taxRate: company.taxRate ?? 0,\n taxInclusive: company.taxInclusive ?? true,\n taxName: company.taxName ?? \"Tax\",\n orderLocation: company.orderLocation ?? \"optional\",\n orderTypes: company.orderTypes ?? [\"pickup\"],\n reservationMode: company.reservationMode ?? \"off\",\n reservationKinds: company.reservationKinds ?? [],\n // Deprecated, for sites written before: no longer sent by the server.\n tableReservations: (company.reservationMode ?? \"off\") !== \"off\",\n customerSignIn: true,\n // `apple` is false from a server that predates it.\n customerSignInMethods: {\n apple: false,\n ...(company.customerSignInMethods ?? { email: false, google: true }),\n },\n customerAccess: company.customerAccess ?? \"public\",\n reservationRequiresSignIn: company.reservationRequiresSignIn ?? false,\n reservationOrder: company.reservationOrder ?? \"off\",\n reservationPayment: company.reservationPayment ?? {\n order: false,\n deferred: false,\n },\n orderRequiresSignIn: company.orderRequiresSignIn ?? false,\n publicOrderTracking: company.publicOrderTracking ?? false,\n paymentDiscounts: company.paymentDiscounts ?? {\n online: null,\n inStore: null,\n },\n googleClientId: company.googleClientId ?? null,\n googleSignInUrl: company.googleSignInUrl ?? null,\n appleClientId: company.appleClientId ?? null,\n appleSignInUrl: company.appleSignInUrl ?? null,\n settings: company.settings,\n };\n },\n getCategories: async (params = {}) => {\n const list = await call<PublicCategory[]>(\"product-categories\", {\n ...text(\"search\", params.search),\n ...include(params.include, CATEGORY_INCLUDES),\n });\n const limit = Number(params.limit);\n\n if (!Array.isArray(list)) return [];\n\n return Number.isFinite(limit) && limit > 0 ? list.slice(0, limit) : list;\n },\n getCategory: async (params) =>\n // The name goes in the QUERY, not the path. It is whatever the shop typed \u2014 any\n // language, any script, possibly a slash \u2014 and a path segment carries that only as\n // percent-encoded UTF-8 that proxies, logs and humans all handle worse than a query\n // parameter does.\n call<PublicCategory>(\"product-categories/by-identifier\", {\n ...idOrName(params),\n ...include(params.include, CATEGORY_INCLUDES),\n }),\n getProducts: async (params = {}) => {\n const page = await call<Paginated<PublicProduct>>(\"products\", {\n ...paging(params),\n ...text(\"categoryId\", params.categoryId),\n ...text(\"categoryName\", params.categoryName),\n ...text(\"search\", params.search),\n ...text(\"tags\", params.tags),\n ...flag(\"categoryEmpty\", params.categoryEmpty),\n ...oneOf(\"sortBy\", params.sortBy, PRODUCT_SORTS),\n ...oneOf(\"sortOrder\", params.sortOrder, [\"ASC\", \"DESC\"]),\n ...whole(\"popularityDays\", params.popularityDays, 1, 365),\n ...include(params.include, PRODUCT_INCLUDES),\n });\n\n return { ...page, data: (page?.data ?? []).map(priced) };\n },\n getProduct: async (params) =>\n priced(\n await call<PublicProduct>(\"products/by-identifier\", idOrName(params)),\n ),\n\n getProductSettings: async (params = {}) => {\n const answer = await call<{\n settings?: PublicProductSettingDefinition[];\n }>(\"products/settings\", flag(\"tagsOnly\", params.tagsOnly));\n\n return Array.isArray(answer?.settings) ? answer.settings : [];\n },\n\n listDictionaries: async () => {\n const list = await call<PublicDictionarySummary[]>(\"dictionaries\");\n\n return Array.isArray(list) ? list : [];\n },\n\n getTerms: async (params = {}) =>\n call<PublicTerms>(\n \"terms\",\n params.language ? { language: params.language } : {},\n ),\n\n getDiningTable: async ({ tableId }) =>\n call<PublicDiningTable>(`tables/${segment(tableId, \"tableId\")}`),\n verifyDiningTableCode: async ({ tableId, code }) =>\n send<void>(\"POST\", `tables/${segment(tableId, \"tableId\")}/code`, {}, { code }),\n getLocations: async () => {\n // `{ data }`, like the admin's list it shares a DTO with.\n const answer = await call<{ data?: PublicStoreLocation[] }>(\"locations\");\n\n return Array.isArray(answer?.data) ? answer.data : [];\n },\n\n getCombos: async (params = {}) => {\n const answer = await call<{ data?: PublicCombo[] }>(\"combos\", {\n ...(params.categoryId\n ? { categoryId: segment(params.categoryId, \"categoryId\") }\n : {}),\n });\n\n return Array.isArray(answer?.data) ? answer.data : [];\n },\n\n getDiscountRules: async () => {\n const answer = await call<{ data?: PublicDiscountRule[] }>(\n \"discount-rules\",\n );\n\n return Array.isArray(answer?.data) ? answer.data : [];\n },\n\n getDictionary: async (params) =>\n call<PublicDictionary>(\"dictionaries/by-identifier\", idOrName(params)),\n\n getDictionaries: async (params) =>\n params.identifiers.length === 0\n ? []\n : call<PublicDictionary[]>(\"dictionaries/by-identifiers\", {\n identifiers: params.identifiers.join(\",\"),\n }),\n\n lookupImages: async (params) => {\n const urls = Array.from(new Set(params.urls.filter(Boolean))).slice(\n 0,\n 200,\n );\n\n // Sorted, so the same pictures asked for in another order are the same read - see\n // `READ_POSTS`.\n return urls.length === 0\n ? []\n : send<PublicImage[]>(\n \"POST\",\n \"images/lookup\",\n {},\n { urls: urls.sort() },\n );\n },\n\n getOrderTimes: async (params = {}) =>\n call<PublicOrderTimes>(\"checkout/times\", {\n ...(params.locationId\n ? { locationId: segment(params.locationId, \"locationId\") }\n : {}),\n }),\n\n getBookingSlots: async (params) =>\n call<PublicBookingSlots>(\"bookings/slots\", {\n locationId: segment(params.locationId, \"locationId\"),\n date: params.date,\n partySize: String(params.partySize),\n ...(params.seating ? { seating: params.seating } : {}),\n ...(params.timeZone ? { timeZone: params.timeZone } : {}),\n ...(params.tableId\n ? { tableId: segment(params.tableId, \"tableId\") }\n : {}),\n ...(params.durationMinutes\n ? { durationMinutes: String(params.durationMinutes) }\n : {}),\n ...(params.entryId\n ? { entryId: segment(params.entryId, \"entryId\") }\n : {}),\n ...(params.entryIds?.length\n ? {\n entryIds: params.entryIds\n .map((id) => segment(id, \"entryIds\"))\n .join(\",\"),\n }\n : {}),\n ...(params.productId\n ? { productId: segment(params.productId, \"productId\") }\n : {}),\n ...(params.productIds?.length\n ? {\n productIds: params.productIds\n .map((id) => segment(id, \"productIds\"))\n .join(\",\"),\n }\n : {}),\n ...(params.kind ? { kind: params.kind } : {}),\n }),\n getBookingPlan: async (params) =>\n call<PublicBookingPlan>(\"bookings/plan\", {\n locationId: segment(params.locationId, \"locationId\"),\n startsAt: params.startsAt,\n partySize: String(params.partySize),\n ...(params.seating ? { seating: params.seating } : {}),\n ...(params.durationMinutes\n ? { durationMinutes: String(params.durationMinutes) }\n : {}),\n ...(params.kind ? { kind: params.kind } : {}),\n }),\n createBooking: async ({ customerToken, ...params }) =>\n send<PublicBooking>(\n \"POST\",\n \"bookings\",\n {},\n params,\n undefined,\n token(customerToken),\n ),\n\n requestSignInCode: async (params) =>\n send<{ expiresIn: number }>(\n \"POST\",\n \"customers/sign-in/code\",\n {},\n { email: requiredEmail(params.email) },\n ),\n verifySignInCode: async (params) =>\n send<PublicCustomerSession>(\n \"POST\",\n \"customers/sign-in/verify\",\n {},\n {\n email: requiredEmail(params.email),\n code: signInCode(params.code),\n },\n ),\n signInWithGoogle: async (params) =>\n send<PublicCustomerSession>(\n \"POST\",\n \"customers/sign-in/google\",\n {},\n { idToken: textOf(params.idToken, \"idToken\", 4096) },\n ),\n signInWithApple: async (params) =>\n send<PublicCustomerSession>(\n \"POST\",\n \"customers/sign-in/apple\",\n {},\n {\n idToken: textOf(params.idToken, \"idToken\", 4096),\n ...(params.name?.trim()\n ? { name: textOf(params.name.trim(), \"name\", 200) }\n : {}),\n },\n ),\n refreshCustomerToken: async (params) =>\n send<PublicCustomerSession>(\n \"POST\",\n \"customers/token/refresh\",\n {},\n { refreshToken: textOf(params.refreshToken, \"refreshToken\", 128) },\n ),\n signOutCustomer: async (params) =>\n send<void>(\n \"POST\",\n \"customers/sign-out\",\n {},\n { refreshToken: textOf(params.refreshToken, \"refreshToken\", 128) },\n ),\n getCustomerAccount: async (params) =>\n call<PublicCustomerAccount>(\n \"customers/me\",\n {},\n undefined,\n requiredToken(params.customerToken),\n ),\n getCustomerOrders: async ({ customerToken, page, limit }) =>\n call<CustomerPage<PublicCustomerOrder>>(\n \"customers/me/orders\",\n historyQuery(page, limit),\n undefined,\n requiredToken(customerToken),\n ),\n getCustomerOrder: async ({ customerToken, orderId }) =>\n call<PublicCustomerOrderDetail>(\n `customers/me/orders/${segment(orderId, \"orderId\")}`,\n {},\n undefined,\n requiredToken(customerToken),\n ),\n getCustomerBookings: async ({ customerToken, scope, page, limit }) =>\n call<CustomerPage<PublicCustomerBooking>>(\n \"customers/me/bookings\",\n {\n ...historyQuery(page, limit),\n ...oneOf(\"scope\", scope, [\"upcoming\", \"past\", \"all\"]),\n },\n undefined,\n requiredToken(customerToken),\n ),\n cancelCustomerBooking: async ({ customerToken, bookingId }) =>\n send<PublicCustomerBooking>(\n \"POST\",\n `customers/me/bookings/${segment(bookingId, \"bookingId\")}/cancel`,\n {},\n undefined,\n undefined,\n requiredToken(customerToken),\n ),\n setCustomerBookingPreorder: async ({ customerToken, bookingId, lines }) =>\n send<{ preorder: PublicBookingPreorder | null }>(\n \"PUT\",\n `customers/me/bookings/${segment(bookingId, \"bookingId\")}/preorder`,\n {},\n { lines },\n undefined,\n requiredToken(customerToken),\n ),\n getCustomerAddresses: async ({ customerToken }) =>\n call<{ data: PublicCustomerAddress[] }>(\n \"customers/me/addresses\",\n {},\n undefined,\n requiredToken(customerToken),\n ),\n addCustomerAddress: async ({\n customerToken,\n address,\n details,\n latitude,\n longitude,\n postcode,\n }) =>\n send<PublicCustomerAddress>(\n \"POST\",\n \"customers/me/addresses\",\n {},\n {\n address,\n ...(details !== undefined ? { details } : {}),\n ...(latitude !== undefined ? { latitude } : {}),\n ...(longitude !== undefined ? { longitude } : {}),\n ...(postcode !== undefined ? { postcode } : {}),\n },\n undefined,\n requiredToken(customerToken),\n ),\n deleteCustomerAddress: async ({ customerToken, customerAddressId }) =>\n send<void>(\n \"DELETE\",\n `customers/me/addresses/${segment(customerAddressId, \"customerAddressId\")}`,\n {},\n undefined,\n undefined,\n requiredToken(customerToken),\n ),\n getCustomerPaymentMethods: async ({ customerToken }) =>\n call<{ data: PublicCustomerPaymentMethod[] }>(\n \"customers/me/payment-methods\",\n {},\n undefined,\n requiredToken(customerToken),\n ),\n deleteCustomerPaymentMethod: async ({ customerToken, paymentMethodId }) =>\n send<void>(\n \"DELETE\",\n `customers/me/payment-methods/${segment(paymentMethodId, \"paymentMethodId\")}`,\n {},\n undefined,\n undefined,\n requiredToken(customerToken),\n ),\n getCustomerFavourites: async ({ customerToken, ...params }) => {\n const page = await call<Paginated<PublicProduct>>(\n \"customers/me/favourites\",\n {\n ...paging(params),\n ...text(\"categoryId\", params.categoryId),\n ...text(\"categoryName\", params.categoryName),\n ...text(\"search\", params.search),\n ...text(\"tags\", params.tags),\n ...oneOf(\"sortBy\", params.sortBy, PRODUCT_SORTS),\n ...oneOf(\"sortOrder\", params.sortOrder, [\"ASC\", \"DESC\"]),\n ...include(params.include, PRODUCT_INCLUDES),\n },\n undefined,\n requiredToken(customerToken),\n );\n\n return { ...page, data: (page?.data ?? []).map(priced) };\n },\n getCustomerFavouriteIds: async ({ customerToken }) =>\n call<{ productIds: string[] }>(\n \"customers/me/favourites/ids\",\n {},\n undefined,\n requiredToken(customerToken),\n ),\n addCustomerFavourite: async ({ customerToken, productId }) =>\n send<void>(\n \"PUT\",\n `customers/me/favourites/${segment(productId, \"productId\")}`,\n {},\n undefined,\n undefined,\n requiredToken(customerToken),\n ),\n removeCustomerFavourite: async ({ customerToken, productId }) =>\n send<void>(\n \"DELETE\",\n `customers/me/favourites/${segment(productId, \"productId\")}`,\n {},\n undefined,\n undefined,\n requiredToken(customerToken),\n ),\n updateCustomerProfile: async ({\n customerToken,\n name,\n phone,\n dateOfBirth,\n acceptTerms,\n healthConsent,\n language,\n }) =>\n send<PublicCustomer>(\n \"PATCH\",\n \"customers/me\",\n {},\n {\n ...(name !== undefined ? { name: name ?? \"\" } : {}),\n ...(phone !== undefined ? { phone: phone ?? \"\" } : {}),\n ...(dateOfBirth !== undefined\n ? { dateOfBirth: dateOfBirth ?? \"\" }\n : {}),\n ...(acceptTerms === true ? { acceptTerms: true } : {}),\n ...(typeof healthConsent === \"boolean\" ? { healthConsent } : {}),\n ...(language !== undefined ? { language: language ?? \"\" } : {}),\n },\n undefined,\n requiredToken(customerToken),\n ),\n\n getProductFeedback: async ({ productId, customerToken }) =>\n call<PublicProductFeedback>(\n `products/${segment(productId, \"productId\")}/feedback`,\n {},\n undefined,\n token(customerToken),\n ),\n getProductComments: async ({\n productId,\n parentId,\n page,\n limit,\n customerToken,\n }) =>\n call<PublicProductCommentsPage>(\n parentId\n ? `products/${segment(productId, \"productId\")}/comments/${segment(parentId, \"parentId\")}/replies`\n : `products/${segment(productId, \"productId\")}/comments`,\n historyQuery(page, limit),\n undefined,\n token(customerToken),\n ),\n createProductComment: async ({\n customerToken,\n productId,\n body,\n parentId,\n vote,\n }) =>\n send<PublicProductComment>(\n \"POST\",\n `products/${segment(productId, \"productId\")}/comments`,\n {},\n {\n body: textOf(body, \"body\", COMMENT_MAX_LENGTH),\n ...(parentId ? { parentId: segment(parentId, \"parentId\") } : {}),\n // A vote rides on a root comment only - a reply is not a review.\n ...(vote != null && !parentId\n ? { vote: voteValue(vote, false) }\n : {}),\n },\n undefined,\n requiredToken(customerToken),\n ),\n deleteProductComment: async ({ customerToken, productId, commentId }) =>\n send<void>(\n \"DELETE\",\n `products/${segment(productId, \"productId\")}/comments/${segment(commentId, \"commentId\")}`,\n {},\n undefined,\n undefined,\n requiredToken(customerToken),\n ),\n\n rateProduct: async ({ customerToken, productId, value }) =>\n send<PublicProductRating>(\n \"PUT\",\n `products/${segment(productId, \"productId\")}/rating`,\n {},\n { value: voteValue(value, false) },\n undefined,\n requiredToken(customerToken),\n ),\n unrateProduct: async ({ customerToken, productId }) =>\n send<PublicProductRating>(\n \"DELETE\",\n `products/${segment(productId, \"productId\")}/rating`,\n {},\n undefined,\n undefined,\n requiredToken(customerToken),\n ),\n voteProductComment: async ({\n customerToken,\n productId,\n commentId,\n value,\n }) =>\n send<PublicCommentVoteResult>(\n \"PUT\",\n `products/${segment(productId, \"productId\")}/comments/${segment(commentId, \"commentId\")}/vote`,\n {},\n { value: voteValue(value, true) },\n undefined,\n requiredToken(customerToken),\n ),\n\n createCart: async () => send<PublicCart>(\"POST\", \"cart\"),\n getCart: async (params) => call<PublicCart>(\"cart\", cart(params.cartId)),\n addCartItem: async (params) =>\n send<PublicCart>(\n \"POST\",\n \"cart/items\",\n cart(params.cartId),\n params.comboId\n ? {\n comboId: segment(params.comboId, \"comboId\"),\n picks: (params.picks ?? []).map(pick),\n quantity: quantity(params.quantity ?? 1, 1),\n }\n : {\n productId: segment(params.productId, \"productId\"),\n quantity: quantity(params.quantity ?? 1, 1),\n ...(params.variantId\n ? { variantId: segment(params.variantId, \"variantId\") }\n : {}),\n variant: typeof params.variant === \"string\" ? params.variant : \"\",\n },\n ),\n setCartItemQuantity: async (params) =>\n send<PublicCart>(\n \"PATCH\",\n `cart/items/${segment(params.cartItemId, \"cartItemId\")}`,\n cart(params.cartId),\n { quantity: quantity(params.quantity, 0) },\n ),\n removeCartItem: async (params) =>\n send<PublicCart>(\n \"DELETE\",\n `cart/items/${segment(params.cartItemId, \"cartItemId\")}`,\n cart(params.cartId),\n ),\n setCartBooking: async (params) =>\n send<PublicCart>(\"PUT\", \"cart/booking\", cart(params.cartId), {\n bookingId: params.bookingId\n ? segment(params.bookingId, \"bookingId\")\n : null,\n }),\n destroyCart: async (params) => {\n await send<void>(\"DELETE\", \"cart\", cart(params.cartId));\n },\n\n getCheckout: async (params) =>\n call<PublicCheckoutSession>(\n `hosted-checkout/${segment(params.checkoutId, \"checkoutId\")}`,\n {},\n // Reads the session back from Stripe, so it waits on the same network the write does.\n STRIPE_TIMEOUT_MS,\n ),\n\n trackOrder: async (params) =>\n call<PublicCustomerOrderDetail>(\"orders/track\", trackQuery(params)),\n\n setCheckoutEmail: async (params) => {\n // The same check as `createCheckout`'s, but required: there is nothing to set without it.\n const email = customerEmail(params.email).customerEmail;\n\n if (!email) throw new Error(\"invalid email\");\n\n return send<PublicCheckoutSession>(\n \"PUT\",\n `hosted-checkout/${segment(params.checkoutId, \"checkoutId\")}/email`,\n {},\n { email },\n STRIPE_TIMEOUT_MS,\n );\n },\n\n createCheckout: async (params) =>\n send<PublicCheckout>(\n \"POST\",\n \"checkout\",\n {},\n {\n cartId: segment(params.cartId, \"cartId\"),\n ...customerEmail(params.customerEmail),\n ...(params.customerPhone?.trim()\n ? { customerPhone: params.customerPhone.trim().slice(0, 32) }\n : {}),\n ...(params.notes?.trim()\n ? { notes: params.notes.trim().slice(0, 500) }\n : {}),\n ...returnUrl(\"successUrl\", params.successUrl),\n ...returnUrl(\"cancelUrl\", params.cancelUrl),\n ...(params.locationId\n ? { locationId: segment(params.locationId, \"locationId\") }\n : {}),\n ...(params.orderType ? { orderType: params.orderType } : {}),\n ...(params.scheduledFor ? { scheduledFor: params.scheduledFor } : {}),\n ...(params.bookingId\n ? { bookingId: segment(params.bookingId, \"bookingId\") }\n : {}),\n ...(params.tableId\n ? { tableId: segment(params.tableId, \"tableId\") }\n : {}),\n ...(params.tableCode ? { tableCode: params.tableCode } : {}),\n ...(params.allowTimeChoice === false\n ? { allowTimeChoice: false }\n : {}),\n ...(params.allowOrderTypeChoice === false\n ? { allowOrderTypeChoice: false }\n : {}),\n ...(params.allowPaymentMethodChoice === false\n ? { allowPaymentMethodChoice: false }\n : {}),\n ...(params.paymentMethod\n ? { paymentMethod: params.paymentMethod }\n : {}),\n ...(params.promoCode?.trim()\n ? { promoCode: params.promoCode.trim() }\n : {}),\n // The language the payment page will be written in, and the one the line names are\n // snapshotted in. Defaulted to the language this client is reading in rather than\n // left to each site to remember: a shopper who got this far in Russian has already\n // been answered in Russian by every other call, and a checkout in English after that\n // is a page that changed language at the till.\n ...(await checkoutLanguage(config, params.language)),\n },\n STRIPE_TIMEOUT_MS,\n token(params.customerToken),\n ),\n };\n\n /** The cart id as a query parameter, validated like any other id from a caller. */\n function cart(cartId: string): Record<string, string> {\n return { cartId: segment(cartId, \"cartId\") };\n }\n\n /**\n * Everything the client knows, minus the thing a caller must never be handed back. The API\n * no longer sends the key on this route; this stays so a server that regressed could not\n * put it in front of a page.\n */\n function strip(company: CompanyRecord): PublicCompany {\n const { apiKey: _key, ...rest } = company;\n\n return rest;\n }\n}\n\n/**\n * `price`, as a number.\n *\n * It arrives as a STRING \u2014 `\"13.00\"`, not `13`. The column is a Postgres `decimal`, and a\n * decimal comes back from the driver as text because binary floating point cannot hold every\n * value one can: the API is being careful with money, and the string is that care surviving\n * as far as the wire.\n *\n * Which makes it this client's problem rather than every page's. `PublicProduct.price` is\n * declared `number`, so a page reasonably writes `typeof price === \"number\" ? price : 0` and\n * renders $0.00 for a catalogue that has prices on every row \u2014 a wrong number, displayed\n * confidently, which is worse than a missing one. Converting here is what makes the published\n * type true.\n *\n * A value that is neither a number nor a numeric string is left ABSENT rather than coerced to\n * zero. A product with no price is an ordinary thing; a product that costs nothing is not, and\n * the caller can only tell those apart if this does not invent a figure.\n */\nfunction priced(product: PublicProduct): PublicProduct {\n // Each variant's price arrives as the same decimal string, and is converted the same way.\n const withVariants = product?.variants\n ? { ...product, variants: product.variants.map(pricedVariant) }\n : product;\n\n return pricedPrice(withVariants);\n}\n\nfunction pricedVariant(variant: PublicProductVariant): PublicProductVariant {\n return pricedPrice(variant);\n}\n\n/** `price` as a number, or absent \u2014 see `priced`. */\nfunction pricedPrice<T extends { price?: number }>(item: T): T {\n const raw: unknown = item?.price;\n\n if (typeof raw === \"number\") return item;\n\n const parsed = typeof raw === \"string\" ? Number(raw) : Number.NaN;\n\n if (!Number.isFinite(parsed)) {\n if (raw === undefined) return item;\n\n const { price: _dropped, ...rest } = item;\n\n return rest as T;\n }\n\n return { ...item, price: parsed };\n}\n\ninterface CompanyRecord extends PublicCompany {\n /** Not sent by the API any more; a caller never sees it either way \u2014 see `strip()`. */\n apiKey?: string;\n}\n\n/**\n * The key this client authenticates with, read at the moment of the call.\n *\n * Per request rather than once at construction: the site-data client is cached for the life of\n * the process, so a key set later by `setCompanyApiKey()` still has to apply.\n */\nfunction keyFor(config: PublicApiConfig): string {\n const key = config.companyApiKey ?? getCompanyApiKey();\n\n // A product sample is read without a key: the sample's own showcase is the site (a template\n // preview, built with no shop behind it).\n if (!key && !config.productSample) {\n throw new PublicApiError(\"no key - supply companyApiKey\");\n }\n\n return key ?? \"\";\n}\n\n/**\n * Every request, whatever its verb, and the only place a timeout is applied.\n *\n * A service that accepts the connection and never answers would otherwise hold a whole render\n * open with no call to blame.\n *\n * `credentials: \"include\"` for the cart's sake: the server sets the cart id as a cookie, and a\n * browser will not send that back to another origin without this. It costs a GET of the\n * catalogue nothing \u2014 there is no cookie for those \u2014 and it is what lets a returning visitor's\n * basket be found without the page having stored anything.\n */\n/**\n * A read (GET), deduped per render, or any other verb, run once.\n *\n * Every read passes through here, so this is where the per-render dedup lives: without it one page\n * fires the same `getDictionary`/`getSiteInfo` dozens of times, because `React.cache()` \u2014 which the\n * readers rely on \u2014 does nothing under `react-dom/static.prerender`. Mutations are never memoised.\n *\n * CROSS-TENANT SAFETY. The URL alone does NOT identify a tenant \u2014 `getSiteInfo` is `/company` for\n * everyone, and the tenant is the `x-company-api-key` HEADER. So the memo key includes the company\n * key, the product-sample dataset, and the language (both headers), not just the URL. Two tenants\n * therefore never share a cache entry even if the same `store` were ever shared between them \u2014 the\n * dedup no longer relies on the store being per-render-isolated to stay tenant-safe. (It still is:\n * the platform renders each page in its own sandbox process, the multi-tenant RPC server never\n * activates the cache, and the dev server is single-tenant and serialises renders.)\n */\nfunction request<T>(\n config: PublicApiConfig,\n method: string,\n url: string,\n key: string,\n body?: unknown,\n timeoutMs?: number,\n language?: string,\n customerToken?: string,\n): Promise<T> {\n const once = () =>\n fetchOnce<T>(\n config,\n method,\n url,\n key,\n body,\n timeoutMs,\n language,\n customerToken,\n );\n\n const isRead = method === \"GET\" || READ_POSTS.has(resourceOf(url));\n\n if (isRead) {\n // The customer is part of the key: two visitors' accounts are two answers. So is the body\n // of a read sent as a POST - two image lookups for different pictures are two answers.\n const scope = `${key}\\u0000${config.productSample ?? \"\"}\\u0000${language ?? \"\"}\\u0000${customerToken ?? \"\"}\\u0000${method} ${url}${\n method === \"GET\" ? \"\" : `\\u0000${JSON.stringify(body ?? null)}`\n }`;\n\n return memoGet(scope, once);\n }\n\n return once();\n}\n\n/**\n * Reads that go out as a POST only because what they ask about does not fit a URL - the\n * picture lookup takes a list of addresses. They change nothing, so a render shares them\n * like any GET.\n */\nconst READ_POSTS = new Set([\"images/lookup\"]);\n\n/** `images/lookup` from `https://\u2026/api/public/images/lookup?\u2026`. */\nfunction resourceOf(url: string): string {\n const path = url.split(\"?\")[0];\n const at = path.indexOf(\"/api/public/\");\n\n return at === -1 ? \"\" : path.slice(at + \"/api/public/\".length);\n}\n\nasync function fetchOnce<T>(\n config: PublicApiConfig,\n method: string,\n url: string,\n key: string,\n body?: unknown,\n timeoutMs?: number,\n language?: string,\n customerToken?: string,\n): Promise<T> {\n const doFetch = config.fetchImpl ?? fetch;\n const controller = new AbortController();\n /**\n * The LONGER of what the host allows and what the call needs.\n *\n * A host that raises the ceiling is asking for more patience everywhere, and gets it. A host\n * that lowers it is talking about ordinary reads \u2014 it cannot have meant \"give Stripe two\n * seconds\", because no checkout would ever open. So a call that names its own floor keeps\n * it, and a host only ever moves the ceiling up from there.\n */\n const timer = setTimeout(\n () => controller.abort(),\n Math.max(timeoutMs ?? 0, config.timeoutMs ?? DEFAULT_TIMEOUT_MS),\n );\n\n try {\n const response = await doFetch(url, {\n method,\n headers: {\n ...(key ? { \"x-company-api-key\": key } : {}),\n accept: \"application/json\",\n ...(language ? { \"x-language\": language } : {}),\n // Who is signed in, for the calls that take a customer \u2014 see `customerToken`.\n ...(customerToken ? { \"x-customer-token\": customerToken } : {}),\n ...(config.productSample\n ? { \"x-product-sample\": config.productSample }\n : {}),\n ...(config.visitor\n ? {\n \"x-visitor-ip\": config.visitor.ip,\n \"x-api-key\": config.visitor.platformKey,\n }\n : {}),\n ...(body === undefined ? {} : { \"content-type\": \"application/json\" }),\n },\n ...(body === undefined ? {} : { body: JSON.stringify(body) }),\n cache: config.cache ?? \"no-store\",\n credentials: \"include\",\n signal: controller.signal,\n });\n\n if (!response.ok) {\n // Deliberately terse: this message can end up rendered by the page, so it must not\n // describe the internal URL that produced it. The server's OWN sentence rides along as\n // `detail`, where a caller can decide whether its reader should see it \u2014 losing it\n // turned \"your order is under the smallest amount a card payment allows\" into \"that did\n // not work\", which is the difference between a shopper fixing their basket and giving up.\n const { detail, ...refusal } = await refusalOf(response);\n\n throw new PublicApiError(\n String(response.status),\n response.status,\n detail,\n refusal,\n );\n }\n\n // 204 is the honest answer to \"delete this\", and it has no body \u2014 `json()` on one throws.\n if (response.status === 204) return undefined as T;\n\n return (await response.json()) as T;\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * The server's explanation, if it gave one in a shape we recognise: its sentence (`detail`), and\n * the refusal's `code` and `missingFields` where it sent them.\n *\n * Nest answers a refusal with `{ statusCode, message, error }`, where `message` is a sentence\n * or a list of them from the validators. Anything else \u2014 HTML from a proxy, an empty body, a\n * gateway's own page \u2014 has nothing to say and is left alone: an error about the error helps\n * nobody, so this never throws.\n */\nasync function refusalOf(\n response: Response,\n): Promise<RefusalFacts & { detail?: string }> {\n try {\n const body = (await response.json()) as { message?: string | string[] };\n const message = body.message;\n\n return {\n ...refusalFactsOf(body),\n detail: (Array.isArray(message) ? message[0] : message) ?? undefined,\n };\n } catch {\n return {};\n }\n}\n\nfunction get<T>(config: PublicApiConfig, url: string, key: string): Promise<T> {\n return request<T>(config, \"GET\", url, key);\n}\n\n/**\n * The company the key belongs to.\n *\n * `GET public/company` is the server's answer to \"who am I?\" \u2014 the guard finds the company by\n * the key and hands back its name, languages and settings. It is a real request, unlike the\n * two-key exchange it replaces, so it is cached as a PROMISE: parallel callers share one.\n *\n * Cached AGAINST THE KEY. A process that changes key mid-life \u2014 a trusted layer calling\n * `setCompanyApiKey()` again \u2014 must not go on reporting the previous company's name.\n *\n * And only for `COMPANY_TTL_MS`: a site server runs for days, and a shop that switches email\n * sign-in or bookings on in the dashboard must see its site follow without a restart. Kept for\n * the life of the process, the answer the server first got was the only one it ever gave.\n */\nconst COMPANY_TTL_MS = 30_000;\n\nfunction companyResolver(\n config: PublicApiConfig,\n): () => Promise<CompanyRecord> {\n let cachedKey: string | null = null;\n let cached: Promise<CompanyRecord> | null = null;\n let cachedAt = 0;\n\n return function companyRecord(): Promise<CompanyRecord> {\n const key = keyFor(config);\n\n if (cached && cachedKey === key && Date.now() - cachedAt < COMPANY_TTL_MS) {\n return cached;\n }\n\n const pending = get<CompanyRecord>(\n config,\n `${trimSlash(config.baseUrl)}/api/public/company`,\n key,\n );\n\n // A failed lookup must not be remembered: the next render should try again rather than\n // replay an outage for the life of the process.\n pending.catch(() => {\n if (cached === pending) {\n cached = null;\n cachedKey = null;\n }\n });\n cached = pending;\n cachedKey = key;\n cachedAt = Date.now();\n\n return pending;\n };\n}\n\nfunction requester(config: PublicApiConfig) {\n return async function call<T>(\n resource: string,\n query: Record<string, string> = {},\n timeoutMs?: number,\n customerToken?: string,\n ): Promise<T> {\n return dispatch<T>(\n config,\n \"GET\",\n resource,\n query,\n undefined,\n timeoutMs,\n customerToken,\n );\n };\n}\n\n/** The same URL and headers as a read, with a verb and a body. */\nfunction writer(config: PublicApiConfig) {\n return async function send<T>(\n method: string,\n resource: string,\n query: Record<string, string> = {},\n body?: unknown,\n timeoutMs?: number,\n customerToken?: string,\n ): Promise<T> {\n return dispatch<T>(\n config,\n method,\n resource,\n query,\n body,\n timeoutMs,\n customerToken,\n );\n };\n}\n\nasync function dispatch<T>(\n config: PublicApiConfig,\n method: string,\n resource: string,\n query: Record<string, string>,\n body?: unknown,\n timeoutMs?: number,\n customerToken?: string,\n): Promise<T> {\n const key = keyFor(config);\n // Asked per call: which language a visitor reads is per request, not per process.\n const language =\n config.language === null\n ? undefined\n : (config.language ?? (await resolveLanguage()));\n const search = new URLSearchParams(query).toString();\n const base = `${trimSlash(config.baseUrl)}/api/public/${resource}`;\n\n return request<T>(\n config,\n method,\n search ? `${base}?${search}` : base,\n key,\n body,\n timeoutMs,\n language,\n customerToken ??\n (config.customerToken === null\n ? undefined\n : (config.customerToken ?? resolveCustomerToken())),\n );\n}\n\n/**\n * What language to bake into a checkout: the caller's word, else the one this request reads in.\n *\n * Absent from the body when neither answers, which leaves the shop's own default \u2014 what every\n * site did before a checkout carried a language at all.\n */\nasync function checkoutLanguage(\n config: PublicApiConfig,\n wanted?: string,\n): Promise<Record<string, string>> {\n const asked = typeof wanted === \"string\" ? wanted.trim() : \"\";\n const language =\n asked ||\n config.language ||\n (config.language === null ? undefined : await resolveLanguage());\n\n return language ? { language } : {};\n}\n\n/**\n * A quantity from a caller, bounded.\n *\n * Page code inside a sandbox can send any JSON at all, and `NaN` or `1e9` reaching the server\n * is either a 400 a visitor sees or a row nobody meant. `floor` too: a fractional quantity is\n * a mistake in every case, not an order for half a pizza.\n */\nfunction quantity(value: unknown, min: number): number {\n const parsed = Math.floor(Number(value));\n\n if (!Number.isFinite(parsed) || parsed < min) {\n throw new Error(\"invalid quantity\");\n }\n\n return Math.min(parsed, MAX_QUANTITY);\n}\n\n/**\n * An email from a caller, or left out \u2014 the checkout page asks for it then.\n *\n * Checked for the one shape the server insists on before it spends a request finding out. The\n * server validates it properly; this only refuses the obviously wrong.\n */\nfunction customerEmail(value: unknown): { customerEmail?: string } {\n if (value === undefined || value === null || value === \"\") return {};\n\n const raw = typeof value === \"string\" ? value.trim() : \"\";\n\n if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(raw) || raw.length > 320) {\n throw new Error(\"invalid customerEmail\");\n }\n\n return { customerEmail: raw };\n}\n\n/**\n * `trackOrder`'s query: a checkout id alone, or a tracking number with the order's email -\n * checked for shape so an obviously wrong call is refused before it spends one of the visitor's\n * tries.\n */\nfunction trackQuery(params: TrackOrderParams): Record<string, string> {\n const checkoutId =\n typeof params?.checkoutId === \"string\" ? params.checkoutId.trim() : \"\";\n\n if (checkoutId) return { checkoutId: segment(checkoutId, \"checkoutId\") };\n\n const code = typeof params?.code === \"string\" ? params.code.trim() : \"\";\n\n if (!code || code.length > 16) throw new Error(\"invalid code\");\n\n let email: string | undefined;\n\n try {\n email = customerEmail(params?.email).customerEmail;\n } catch {\n email = undefined;\n }\n\n if (!email) throw new Error(\"invalid email\");\n\n return { code, email };\n}\n\n/** One combo pick, its ids validated like any other id from a caller. */\nfunction pick(value: ComboPick): ComboPick {\n return {\n slotId: segment(value?.slotId, \"slotId\"),\n productId: segment(value?.productId, \"productId\"),\n ...(value?.variantId\n ? { variantId: segment(value.variantId, \"variantId\") }\n : {}),\n ...(typeof value?.variant === \"string\" ? { variant: value.variant } : {}),\n };\n}\n\n/** A return address for the checkout page: absolute http(s), or left out. */\nfunction returnUrl(key: string, value: unknown): Record<string, string> {\n if (value === undefined || value === null || value === \"\") return {};\n\n if (typeof value !== \"string\" || !/^https?:\\/\\/\\S+$/.test(value)) {\n throw new Error(`invalid ${key}`);\n }\n\n return { [key]: value };\n}\n\n/** A customer token from a caller, or left out. Only its shape is checked; the server verifies it. */\nfunction token(value: unknown): string | undefined {\n if (value === undefined || value === null || value === \"\") return undefined;\n\n return requiredToken(value);\n}\n\nfunction requiredToken(value: unknown): string {\n if (\n typeof value !== \"string\" ||\n !value.trim() ||\n value.length > 4096 ||\n /\\s/.test(value.trim())\n ) {\n throw new Error(\"invalid customerToken\");\n }\n\n return value.trim();\n}\n\nfunction requiredEmail(value: unknown): string {\n const email = customerEmail(value).customerEmail;\n\n if (!email) throw new Error(\"invalid email\");\n\n return email;\n}\n\n/** The six digits from the sign-in email, spaces a visitor typed between them dropped. */\nfunction signInCode(value: unknown): string {\n const code = String(value ?? \"\").replace(/\\s/g, \"\");\n\n if (!/^\\d{6}$/.test(code)) throw new Error(\"invalid code\");\n\n return code;\n}\n\nfunction textOf(value: unknown, name: string, max: number): string {\n if (typeof value !== \"string\" || !value.trim() || value.length > max) {\n throw new Error(`invalid ${name}`);\n }\n\n return value.trim();\n}\n\n/**\n * A vote from a caller: a whole number from -1 (a dislike) up to ten stars - which of them the\n * shop takes is the server's to say. 0 only where it means \"take it back\".\n */\nfunction voteValue(value: unknown, allowZero: boolean): number {\n const vote = Number(value);\n\n if (\n !Number.isInteger(vote) ||\n vote < -1 ||\n vote > 10 ||\n (vote === 0 && !allowZero)\n ) {\n throw new Error(\"invalid vote\");\n }\n\n return vote;\n}\n\n/** A history page's query: whole numbers in range, or left out. */\nfunction historyQuery(page: unknown, limit: unknown): Record<string, string> {\n return {\n ...whole(\"page\", page, 1, 100_000),\n ...whole(\"limit\", limit, 1, 50),\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,111 @@
1
+ import {
2
+ PublicApiError,
3
+ refusalFactsOf
4
+ } from "./chunk-GJZ7EZEF.js";
5
+
6
+ // packages/api/src/bridgeClient.ts
7
+ function bridge() {
8
+ const fn = globalThis.__service;
9
+ if (typeof fn !== "function") {
10
+ throw new PublicApiError(
11
+ "data bridge unavailable - no __service in this sandbox"
12
+ );
13
+ }
14
+ return fn;
15
+ }
16
+ function call(method, params = {}) {
17
+ return bridge()(method, params).catch((err) => {
18
+ const status = err?.status;
19
+ if (typeof status !== "number") throw err;
20
+ const text = err instanceof Error ? err.message : String(err);
21
+ throw new PublicApiError(
22
+ String(status),
23
+ status,
24
+ text || void 0,
25
+ refusalFactsOf(err)
26
+ );
27
+ });
28
+ }
29
+ function createBridgeClient() {
30
+ return {
31
+ getCompany: () => call("getCompany"),
32
+ getSiteInfo: () => call("getSiteInfo"),
33
+ getCategories: (params) => call("getCategories", params ?? {}),
34
+ getCategory: (params) => call("getCategory", params),
35
+ getProducts: (params) => call("getProducts", params ?? {}),
36
+ getProduct: (params) => call("getProduct", params),
37
+ getProductSettings: (params) => call(
38
+ "getProductSettings",
39
+ params ?? {}
40
+ ),
41
+ listDictionaries: () => call("listDictionaries"),
42
+ getDictionary: (params) => call("getDictionary", params),
43
+ getDictionaries: (params) => call("getDictionaries", params),
44
+ lookupImages: (params) => call("lookupImages", params),
45
+ getLocations: () => call("getLocations"),
46
+ getDiningTable: (params) => call("getDiningTable", params),
47
+ verifyDiningTableCode: (params) => call("verifyDiningTableCode", params),
48
+ getTerms: (params) => call("getTerms", params ?? {}),
49
+ getOrderTimes: (params = {}) => call("getOrderTimes", params),
50
+ getBookingSlots: (params) => call("getBookingSlots", params),
51
+ getBookingPlan: (params) => call("getBookingPlan", params),
52
+ createBooking: (params) => call("createBooking", params),
53
+ requestSignInCode: (params) => call("requestSignInCode", params),
54
+ verifySignInCode: (params) => call("verifySignInCode", params),
55
+ signInWithGoogle: (params) => call("signInWithGoogle", params),
56
+ signInWithApple: (params) => call("signInWithApple", params),
57
+ refreshCustomerToken: (params) => call("refreshCustomerToken", params),
58
+ signOutCustomer: (params) => call("signOutCustomer", params),
59
+ getCustomerAccount: (params) => call("getCustomerAccount", params),
60
+ getCustomerOrders: (params) => call("getCustomerOrders", params),
61
+ getCustomerOrder: (params) => call("getCustomerOrder", params),
62
+ getCustomerBookings: (params) => call("getCustomerBookings", params),
63
+ cancelCustomerBooking: (params) => call("cancelCustomerBooking", params),
64
+ setCustomerBookingPreorder: (params) => call(
65
+ "setCustomerBookingPreorder",
66
+ params
67
+ ),
68
+ getCustomerAddresses: (params) => call("getCustomerAddresses", params),
69
+ addCustomerAddress: (params) => call("addCustomerAddress", params),
70
+ deleteCustomerAddress: (params) => call("deleteCustomerAddress", params),
71
+ getCustomerPaymentMethods: (params) => call(
72
+ "getCustomerPaymentMethods",
73
+ params
74
+ ),
75
+ deleteCustomerPaymentMethod: (params) => call("deleteCustomerPaymentMethod", params),
76
+ getCustomerFavourites: (params) => call("getCustomerFavourites", params),
77
+ getCustomerFavouriteIds: (params) => call("getCustomerFavouriteIds", params),
78
+ addCustomerFavourite: (params) => call("addCustomerFavourite", params),
79
+ removeCustomerFavourite: (params) => call("removeCustomerFavourite", params),
80
+ updateCustomerProfile: (params) => call("updateCustomerProfile", params),
81
+ getProductFeedback: (params) => call("getProductFeedback", params),
82
+ getProductComments: (params) => call("getProductComments", params),
83
+ createProductComment: (params) => call("createProductComment", params),
84
+ deleteProductComment: (params) => call("deleteProductComment", params),
85
+ rateProduct: (params) => call("rateProduct", params),
86
+ unrateProduct: (params) => call("unrateProduct", params),
87
+ voteProductComment: (params) => call("voteProductComment", params),
88
+ getCombos: (params) => call("getCombos", params ?? {}),
89
+ getDiscountRules: () => call("getDiscountRules"),
90
+ createCart: () => call("createCart"),
91
+ getCart: (params) => call("getCart", params),
92
+ addCartItem: (params) => call("addCartItem", params),
93
+ setCartItemQuantity: (params) => call("setCartItemQuantity", params),
94
+ removeCartItem: (params) => call("removeCartItem", params),
95
+ setCartBooking: (params) => call("setCartBooking", params),
96
+ destroyCart: (params) => call("destroyCart", params),
97
+ createCheckout: (params) => call("createCheckout", params),
98
+ getCheckout: (params) => call("getCheckout", params),
99
+ setCheckoutEmail: (params) => call("setCheckoutEmail", params),
100
+ trackOrder: (params) => call("trackOrder", params)
101
+ };
102
+ }
103
+ function hasServiceBridge() {
104
+ return typeof globalThis.__service === "function";
105
+ }
106
+
107
+ export {
108
+ createBridgeClient,
109
+ hasServiceBridge
110
+ };
111
+ //# sourceMappingURL=chunk-DUVULZ6N.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../packages/api/src/bridgeClient.ts"],
4
+ "sourcesContent": ["import type {\n AddCartItemParams,\n CreateCheckoutParams,\n GetCartParams,\n GetCategoryParams,\n GetCheckoutParams,\n TrackOrderParams,\n GetDictionaryParams,\n GetProductParams,\n ListCategoriesParams,\n ListCombosParams,\n ListProductsParams,\n Paginated,\n PublicCart,\n PublicCategory,\n PublicCheckout,\n PublicCheckoutSession,\n PublicCombo,\n PublicCompany,\n PublicDictionary,\n PublicDictionarySummary,\n PublicDiscountRule,\n PublicProduct,\n PublicProductSettingDefinition,\n PublicSiteInfo,\n RemoveCartItemParams,\n SetCartBookingParams,\n SetCartItemQuantityParams,\n SetCheckoutEmailParams,\n PublicStoreLocation,\n PublicTerms,\n PublicImage,\n CreateBookingParams,\n GetBookingPlanParams,\n GetBookingSlotsParams,\n GetOrderTimesParams,\n PublicBooking,\n PublicBookingPlan,\n PublicBookingSlots,\n PublicOrderTimes,\n CustomerTokenParams,\n PublicCustomer,\n PublicCustomerAccount,\n PublicCustomerBooking,\n PublicBookingPreorder,\n SetBookingPreorderParams,\n PublicCustomerOrder,\n PublicCustomerOrderDetail,\n PublicCustomerSession,\n CustomerPage,\n CustomerHistoryParams,\n CustomerBookingsParams,\n AddCustomerAddressParams,\n PublicCustomerAddress,\n PublicCustomerPaymentMethod,\n CreateProductCommentParams,\n DeleteProductCommentParams,\n GetProductCommentsParams,\n GetProductFeedbackParams,\n PublicProductComment,\n PublicProductCommentsPage,\n PublicProductFeedback,\n PublicCommentVoteResult,\n PublicProductRating,\n RateProductParams,\n UnrateProductParams,\n VoteProductCommentParams,\n RequestSignInCodeParams,\n SignInWithAppleParams,\n SignInWithGoogleParams,\n RefreshCustomerTokenParams,\n UpdateCustomerProfileParams,\n VerifySignInCodeParams,\n PublicDiningTable,\n} from \"./types\";\nimport type { PublicApiClient } from \"./client\";\n\nimport { PublicApiError, refusalFactsOf } from \"./errors\";\n\n/**\n * The `@estoreclub/api` client that holds NO key and makes NO network call.\n *\n * It is what runs inside the render sandbox. Every read is forwarded, by method name, to the\n * trusted parent through `globalThis.__service(method, params)` \u2014 an IPC bridge the sandbox\n * host installs. The parent holds the company key (resolved per domain), runs the real\n * `createPublicApiClient` call, and sends back only the data.\n *\n * Why this exists at all: the fetch-based client (`createPublicApiClient`) needs\n * `COMPANY_API_KEY` in the sandbox's environment to sign its requests, which means page code \u2014\n * untrusted \u2014 can read its own site's key and bake it into the rendered HTML. The bridge moves\n * the key out of the sandbox entirely: page code sends a method name and JSON params and gets\n * data, never a URL, never a header, never the key. See the preview render pipeline.\n *\n * The method names are the `PublicApiClient` method names verbatim, so the parent's capability\n * registry is a straight map from name to the same-named call on the real client \u2014 one\n * contract, no translation layer to drift.\n */\n\n/** The shape the sandbox host installs. Resolves the data, or rejects with the call's error. */\ntype ServiceBridge = (method: string, params: unknown) => Promise<unknown>;\n\nfunction bridge(): ServiceBridge {\n const fn = (globalThis as { __service?: ServiceBridge }).__service;\n\n if (typeof fn !== \"function\") {\n // Only reached if this client is selected without a host to answer it \u2014 a wiring mistake,\n // not something page code can cause. `siteData` picks the bridge only when `__service`\n // exists, so this is a guard, not a runtime path.\n throw new PublicApiError(\n \"data bridge unavailable - no __service in this sandbox\",\n );\n }\n\n return fn;\n}\n\n/**\n * Forward one call. The parent tags failures; here they surface as a rejected promise - a\n * `PublicApiError` with the API's status, as the direct client throws, so page code that checks\n * `error.status === 401` (a shop open to signed-in customers only) reads the same in both - and\n * the refusal's `code` and `missingFields`, which the host relays beside it.\n */\nfunction call<T>(method: string, params: unknown = {}): Promise<T> {\n return (bridge()(method, params) as Promise<T>).catch((err: unknown) => {\n const status = (err as { status?: unknown } | null)?.status;\n\n if (typeof status !== \"number\") throw err;\n\n const text = err instanceof Error ? err.message : String(err);\n\n throw new PublicApiError(\n String(status),\n status,\n text || undefined,\n refusalFactsOf(err),\n );\n });\n}\n\n/**\n * A `PublicApiClient` that forwards every method over the bridge.\n *\n * Same surface as `createPublicApiClient`, so `siteData` can return either one and page code\n * cannot tell which it got.\n */\nexport function createBridgeClient(): PublicApiClient {\n return {\n getCompany: () => call<PublicCompany>(\"getCompany\"),\n getSiteInfo: () => call<PublicSiteInfo>(\"getSiteInfo\"),\n getCategories: (params?: ListCategoriesParams) =>\n call<PublicCategory[]>(\"getCategories\", params ?? {}),\n getCategory: (params: GetCategoryParams) =>\n call<PublicCategory>(\"getCategory\", params),\n getProducts: (params?: ListProductsParams) =>\n call<Paginated<PublicProduct>>(\"getProducts\", params ?? {}),\n getProduct: (params: GetProductParams) =>\n call<PublicProduct>(\"getProduct\", params),\n getProductSettings: (params?: {\n categoryId?: string;\n tagsOnly?: boolean;\n }) =>\n call<PublicProductSettingDefinition[]>(\n \"getProductSettings\",\n params ?? {},\n ),\n listDictionaries: () => call<PublicDictionarySummary[]>(\"listDictionaries\"),\n getDictionary: (params: GetDictionaryParams) =>\n call<PublicDictionary>(\"getDictionary\", params),\n getDictionaries: (params: { identifiers: string[] }) =>\n call<PublicDictionary[]>(\"getDictionaries\", params),\n lookupImages: (params: { urls: string[] }) =>\n call<PublicImage[]>(\"lookupImages\", params),\n getLocations: () => call<PublicStoreLocation[]>(\"getLocations\"),\n getDiningTable: (params: { tableId: string }) =>\n call<PublicDiningTable>(\"getDiningTable\", params),\n verifyDiningTableCode: (params: { tableId: string; code: string }) =>\n call<void>(\"verifyDiningTableCode\", params),\n getTerms: (params?: { language?: string }) =>\n call<PublicTerms>(\"getTerms\", params ?? {}),\n getOrderTimes: (params: GetOrderTimesParams = {}) =>\n call<PublicOrderTimes>(\"getOrderTimes\", params),\n getBookingSlots: (params: GetBookingSlotsParams) =>\n call<PublicBookingSlots>(\"getBookingSlots\", params),\n getBookingPlan: (params: GetBookingPlanParams) =>\n call<PublicBookingPlan>(\"getBookingPlan\", params),\n createBooking: (params: CreateBookingParams) =>\n call<PublicBooking>(\"createBooking\", params),\n requestSignInCode: (params: RequestSignInCodeParams) =>\n call<{ expiresIn: number }>(\"requestSignInCode\", params),\n verifySignInCode: (params: VerifySignInCodeParams) =>\n call<PublicCustomerSession>(\"verifySignInCode\", params),\n signInWithGoogle: (params: SignInWithGoogleParams) =>\n call<PublicCustomerSession>(\"signInWithGoogle\", params),\n signInWithApple: (params: SignInWithAppleParams) =>\n call<PublicCustomerSession>(\"signInWithApple\", params),\n refreshCustomerToken: (params: RefreshCustomerTokenParams) =>\n call<PublicCustomerSession>(\"refreshCustomerToken\", params),\n signOutCustomer: (params: RefreshCustomerTokenParams) =>\n call<void>(\"signOutCustomer\", params),\n getCustomerAccount: (params: CustomerTokenParams) =>\n call<PublicCustomerAccount>(\"getCustomerAccount\", params),\n getCustomerOrders: (params: CustomerTokenParams & CustomerHistoryParams) =>\n call<CustomerPage<PublicCustomerOrder>>(\"getCustomerOrders\", params),\n getCustomerOrder: (params: CustomerTokenParams & { orderId: string }) =>\n call<PublicCustomerOrderDetail>(\"getCustomerOrder\", params),\n getCustomerBookings: (\n params: CustomerTokenParams & CustomerBookingsParams,\n ) =>\n call<CustomerPage<PublicCustomerBooking>>(\"getCustomerBookings\", params),\n cancelCustomerBooking: (\n params: CustomerTokenParams & { bookingId: string },\n ) => call<PublicCustomerBooking>(\"cancelCustomerBooking\", params),\n setCustomerBookingPreorder: (params: SetBookingPreorderParams) =>\n call<{ preorder: PublicBookingPreorder | null }>(\n \"setCustomerBookingPreorder\",\n params,\n ),\n getCustomerAddresses: (params: CustomerTokenParams) =>\n call<{ data: PublicCustomerAddress[] }>(\"getCustomerAddresses\", params),\n addCustomerAddress: (params: AddCustomerAddressParams) =>\n call<PublicCustomerAddress>(\"addCustomerAddress\", params),\n deleteCustomerAddress: (\n params: CustomerTokenParams & { customerAddressId: string },\n ) => call<void>(\"deleteCustomerAddress\", params),\n getCustomerPaymentMethods: (params: CustomerTokenParams) =>\n call<{ data: PublicCustomerPaymentMethod[] }>(\n \"getCustomerPaymentMethods\",\n params,\n ),\n deleteCustomerPaymentMethod: (\n params: CustomerTokenParams & { paymentMethodId: string },\n ) => call<void>(\"deleteCustomerPaymentMethod\", params),\n getCustomerFavourites: (params: CustomerTokenParams & ListProductsParams) =>\n call<Paginated<PublicProduct>>(\"getCustomerFavourites\", params),\n getCustomerFavouriteIds: (params: CustomerTokenParams) =>\n call<{ productIds: string[] }>(\"getCustomerFavouriteIds\", params),\n addCustomerFavourite: (\n params: CustomerTokenParams & { productId: string },\n ) => call<void>(\"addCustomerFavourite\", params),\n removeCustomerFavourite: (\n params: CustomerTokenParams & { productId: string },\n ) => call<void>(\"removeCustomerFavourite\", params),\n updateCustomerProfile: (params: UpdateCustomerProfileParams) =>\n call<PublicCustomer>(\"updateCustomerProfile\", params),\n getProductFeedback: (params: GetProductFeedbackParams) =>\n call<PublicProductFeedback>(\"getProductFeedback\", params),\n getProductComments: (params: GetProductCommentsParams) =>\n call<PublicProductCommentsPage>(\"getProductComments\", params),\n createProductComment: (params: CreateProductCommentParams) =>\n call<PublicProductComment>(\"createProductComment\", params),\n deleteProductComment: (params: DeleteProductCommentParams) =>\n call<void>(\"deleteProductComment\", params),\n rateProduct: (params: RateProductParams) =>\n call<PublicProductRating>(\"rateProduct\", params),\n unrateProduct: (params: UnrateProductParams) =>\n call<PublicProductRating>(\"unrateProduct\", params),\n voteProductComment: (params: VoteProductCommentParams) =>\n call<PublicCommentVoteResult>(\"voteProductComment\", params),\n getCombos: (params?: ListCombosParams) =>\n call<PublicCombo[]>(\"getCombos\", params ?? {}),\n getDiscountRules: () => call<PublicDiscountRule[]>(\"getDiscountRules\"),\n createCart: () => call<PublicCart>(\"createCart\"),\n getCart: (params: GetCartParams) => call<PublicCart>(\"getCart\", params),\n addCartItem: (params: AddCartItemParams) =>\n call<PublicCart>(\"addCartItem\", params),\n setCartItemQuantity: (params: SetCartItemQuantityParams) =>\n call<PublicCart>(\"setCartItemQuantity\", params),\n removeCartItem: (params: RemoveCartItemParams) =>\n call<PublicCart>(\"removeCartItem\", params),\n setCartBooking: (params: SetCartBookingParams) =>\n call<PublicCart>(\"setCartBooking\", params),\n destroyCart: (params: GetCartParams) => call<void>(\"destroyCart\", params),\n createCheckout: (params: CreateCheckoutParams) =>\n call<PublicCheckout>(\"createCheckout\", params),\n getCheckout: (params: GetCheckoutParams) =>\n call<PublicCheckoutSession>(\"getCheckout\", params),\n setCheckoutEmail: (params: SetCheckoutEmailParams) =>\n call<PublicCheckoutSession>(\"setCheckoutEmail\", params),\n trackOrder: (params: TrackOrderParams) =>\n call<PublicCustomerOrderDetail>(\"trackOrder\", params),\n };\n}\n\n/** Is a data bridge installed in this global? Then no key belongs here \u2014 use the bridge. */\nexport function hasServiceBridge(): boolean {\n return (\n typeof (globalThis as { __service?: unknown }).__service === \"function\"\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,25 @@
1
+ // packages/api/src/errors.ts
2
+ function refusalFactsOf(body) {
3
+ if (!body || typeof body !== "object") return {};
4
+ const { code, missingFields } = body;
5
+ return {
6
+ ...typeof code === "string" && code ? { code } : {},
7
+ ...Array.isArray(missingFields) && missingFields.every((field) => typeof field === "string") ? { missingFields } : {}
8
+ };
9
+ }
10
+ var PublicApiError = class extends Error {
11
+ constructor(reason, status, detail, refusal = {}) {
12
+ super(`data unavailable (${reason})`);
13
+ this.name = "PublicApiError";
14
+ this.status = status;
15
+ this.detail = detail;
16
+ this.code = refusal.code;
17
+ this.missingFields = refusal.missingFields;
18
+ }
19
+ };
20
+
21
+ export {
22
+ refusalFactsOf,
23
+ PublicApiError
24
+ };
25
+ //# sourceMappingURL=chunk-GJZ7EZEF.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../packages/api/src/errors.ts"],
4
+ "sourcesContent": ["/**\n * One error type, and deliberately uninformative.\n *\n * The message can end up rendered by a page \u2014 the runtime hands it straight to page code as\n * the reason a capability failed \u2014 so it names a status and nothing else. The internal URL,\n * the base host and the key are exactly what must not travel with it.\n */\n/** What a refusal says beyond its status and sentence - see `PublicApiError`. */\nexport interface RefusalFacts {\n code?: string;\n missingFields?: string[];\n}\n\n/** The refusal facts in an API answer's body (or a relayed error), keeping only well-formed ones. */\nexport function refusalFactsOf(body: unknown): RefusalFacts {\n if (!body || typeof body !== \"object\") return {};\n\n const { code, missingFields } = body as {\n code?: unknown;\n missingFields?: unknown;\n };\n\n return {\n ...(typeof code === \"string\" && code ? { code } : {}),\n ...(Array.isArray(missingFields) &&\n missingFields.every((field) => typeof field === \"string\")\n ? { missingFields: missingFields as string[] }\n : {}),\n };\n}\n\nexport class PublicApiError extends Error {\n readonly status?: number;\n /**\n * What the SERVER said, when it said anything.\n *\n * Kept apart from `message`, which stays terse and safe to render anywhere. This is the\n * server's own sentence \u2014 \"Amount must convert to at least 50 cents\", \"One or more products\n * not found\" \u2014 and it is the only part that tells a caller what to do differently. Without\n * it a page could say nothing better than \"that did not work\", while the reason sat in a\n * log nobody was reading.\n *\n * Shown at the CALLER's discretion, because only the caller knows who is reading. A shop's\n * own admin screen can print it; a page facing a shopper should decide case by case.\n */\n readonly detail?: string;\n /**\n * The refusal's machine-readable `code` (`customer_sign_in_required`, `customer_details_required`),\n * when the API gave one - what a page branches on, unlike the sentence in `detail`.\n */\n readonly code?: string;\n /**\n * The details a signed-in customer still owes, with `customer_details_required` - so a page asks\n * for exactly those without reading the account first.\n */\n readonly missingFields?: string[];\n\n constructor(\n reason: string,\n status?: number,\n detail?: string,\n refusal: RefusalFacts = {},\n ) {\n super(`data unavailable (${reason})`);\n this.name = \"PublicApiError\";\n this.status = status;\n this.detail = detail;\n this.code = refusal.code;\n this.missingFields = refusal.missingFields;\n }\n}\n"],
5
+ "mappings": ";AAcO,SAAS,eAAe,MAA6B;AAC1D,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO,CAAC;AAE/C,QAAM,EAAE,MAAM,cAAc,IAAI;AAKhC,SAAO;AAAA,IACL,GAAI,OAAO,SAAS,YAAY,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,IACnD,GAAI,MAAM,QAAQ,aAAa,KAC/B,cAAc,MAAM,CAAC,UAAU,OAAO,UAAU,QAAQ,IACpD,EAAE,cAAyC,IAC3C,CAAC;AAAA,EACP;AACF;AAEO,IAAM,iBAAN,cAA6B,MAAM;AAAA,EA0BxC,YACE,QACA,QACA,QACA,UAAwB,CAAC,GACzB;AACA,UAAM,qBAAqB,MAAM,GAAG;AACpC,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,OAAO,QAAQ;AACpB,SAAK,gBAAgB,QAAQ;AAAA,EAC/B;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,24 @@
1
+ // packages/api/src/language.ts
2
+ var resolver = null;
3
+ function setLanguageResolver(next) {
4
+ resolver = next;
5
+ }
6
+ function getLanguageResolver() {
7
+ return resolver;
8
+ }
9
+ async function resolveLanguage() {
10
+ if (!resolver) return void 0;
11
+ try {
12
+ const language = await resolver();
13
+ return typeof language === "string" && language.trim() ? language.trim() : void 0;
14
+ } catch {
15
+ return void 0;
16
+ }
17
+ }
18
+
19
+ export {
20
+ setLanguageResolver,
21
+ getLanguageResolver,
22
+ resolveLanguage
23
+ };
24
+ //# sourceMappingURL=chunk-HFEQWXG6.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../packages/api/src/language.ts"],
4
+ "sourcesContent": ["/**\n * The language the site is being read in, for the calls that answer in one.\n *\n * The public API resolves every name, description and dictionary entry into the language named\n * by the `x-language` header, and falls back to English without it \u2014 so a site that never said\n * which language it was in was an English site, whatever the shop wrote in.\n *\n * Which language a visitor is reading is the SITE's knowledge \u2014 a cookie, a path segment, a\n * header of its own \u2014 and it is per request, not per process. So the site hands in a resolver,\n * asked at the moment of each call, the same way the key is supplied: once, where the site sets\n * itself up, rather than as a parameter every call has to remember.\n *\n * The resolver is not asked for the company lookup (`getSiteInfo`), which needs no language,\n * so it may itself read the company's default language without looping.\n */\nexport type LanguageResolver = () =>\n | string\n | null\n | undefined\n | Promise<string | null | undefined>;\n\nlet resolver: LanguageResolver | null = null;\n\nexport function setLanguageResolver(next: LanguageResolver | null): void {\n resolver = next;\n}\n\n/**\n * The resolver in force, so a caller can override it for one render and put it back.\n *\n * The render tier does this: it sets a resolver that returns the request's language, renders, and\n * restores the site's own resolver in a `finally`. Without the getter there is no way to restore\n * exactly what was there before.\n */\nexport function getLanguageResolver(): LanguageResolver | null {\n return resolver;\n}\n\n/** The language to send, or undefined for the API's default. Never throws. */\nexport async function resolveLanguage(): Promise<string | undefined> {\n if (!resolver) return undefined;\n\n try {\n const language = await resolver();\n\n return typeof language === \"string\" && language.trim()\n ? language.trim()\n : undefined;\n } catch {\n return undefined;\n }\n}\n"],
5
+ "mappings": ";AAqBA,IAAI,WAAoC;AAEjC,SAAS,oBAAoB,MAAqC;AACvE,aAAW;AACb;AASO,SAAS,sBAA+C;AAC7D,SAAO;AACT;AAGA,eAAsB,kBAA+C;AACnE,MAAI,CAAC,SAAU,QAAO;AAEtB,MAAI;AACF,UAAM,WAAW,MAAM,SAAS;AAEhC,WAAO,OAAO,aAAa,YAAY,SAAS,KAAK,IACjD,SAAS,KAAK,IACd;AAAA,EACN,QAAQ;AACN,WAAO;AAAA,EACT;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,24 @@
1
+ // packages/api/src/customerToken.ts
2
+ var resolver = null;
3
+ function setCustomerTokenResolver(next) {
4
+ resolver = next;
5
+ }
6
+ function getCustomerTokenResolver() {
7
+ return resolver;
8
+ }
9
+ function resolveCustomerToken() {
10
+ if (!resolver) return void 0;
11
+ try {
12
+ const token = resolver();
13
+ return typeof token === "string" && token.trim() ? token.trim() : void 0;
14
+ } catch {
15
+ return void 0;
16
+ }
17
+ }
18
+
19
+ export {
20
+ setCustomerTokenResolver,
21
+ getCustomerTokenResolver,
22
+ resolveCustomerToken
23
+ };
24
+ //# sourceMappingURL=chunk-OFFTL6RC.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../packages/api/src/customerToken.ts"],
4
+ "sourcesContent": ["/**\n * The signed-in customer a render is made for, for every call it makes.\n *\n * A shop may show itself to signed-in customers only (`customerAccess: signed_in`): the API then\n * refuses a guest its catalogue, cart, checkout and bookings. A page's reads are made on the\n * server, which knows the visitor only by the request's cookie - so the render tier reads the\n * token from that cookie and sets a resolver here for the length of one render, the same way it\n * sets the language (`language.ts`). Every call then carries `x-customer-token` without page\n * code passing anything - page code never sees the token.\n *\n * A call that names its own `customerToken` keeps it; nothing set here means a guest's calls.\n */\nexport type CustomerTokenResolver = () => string | null | undefined;\n\nlet resolver: CustomerTokenResolver | null = null;\n\nexport function setCustomerTokenResolver(\n next: CustomerTokenResolver | null,\n): void {\n resolver = next;\n}\n\n/** The resolver in force, so the render tier can put back exactly what was there. */\nexport function getCustomerTokenResolver(): CustomerTokenResolver | null {\n return resolver;\n}\n\n/** The token to send, or undefined for a guest. Never throws. */\nexport function resolveCustomerToken(): string | undefined {\n if (!resolver) return undefined;\n\n try {\n const token = resolver();\n\n return typeof token === \"string\" && token.trim() ? token.trim() : undefined;\n } catch {\n return undefined;\n }\n}\n"],
5
+ "mappings": ";AAcA,IAAI,WAAyC;AAEtC,SAAS,yBACd,MACM;AACN,aAAW;AACb;AAGO,SAAS,2BAAyD;AACvE,SAAO;AACT;AAGO,SAAS,uBAA2C;AACzD,MAAI,CAAC,SAAU,QAAO;AAEtB,MAAI;AACF,UAAM,QAAQ,SAAS;AAEvB,WAAO,OAAO,UAAU,YAAY,MAAM,KAAK,IAAI,MAAM,KAAK,IAAI;AAAA,EACpE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,15 @@
1
+ // packages/api/src/companyApiKey.ts
2
+ var companyApiKey = null;
3
+ function setCompanyApiKey(key) {
4
+ const trimmed = typeof key === "string" ? key.trim() : "";
5
+ companyApiKey = trimmed ? trimmed : null;
6
+ }
7
+ function getCompanyApiKey() {
8
+ return companyApiKey;
9
+ }
10
+
11
+ export {
12
+ setCompanyApiKey,
13
+ getCompanyApiKey
14
+ };
15
+ //# sourceMappingURL=chunk-TSERNR4R.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../packages/api/src/companyApiKey.ts"],
4
+ "sourcesContent": ["/**\n * The company's own API key, set once and sent as `x-company-api-key` on every call.\n *\n * This is the key every public endpoint authenticates with \u2014 `CompanyApiKeyGuard` expects it\n * on everything under `/public/*`, and resolves the company from it, which is why nothing here\n * carries a domain. A client can be handed one in its config, and a standalone process can put\n * one in `COMPANY_API_KEY`; this is the third way in, for the case neither covers: a TRUSTED\n * layer that learns the key at RUNTIME and then renders page code which imports the four flat\n * reads and never builds a client of its own.\n *\n * That is the whole shape of it \u2014 the preview's route handler, or a site's server, resolves a\n * deployment id to a company key with the platform key it holds, calls this, and everything\n * downstream inherits a key scoped to the one site being rendered. The platform key never\n * leaves the trusted layer.\n *\n * Read at REQUEST time, not at construction: the site-data client is built lazily and cached\n * for the life of the process, so a key set after the first call still has to apply \u2014 and\n * setting one MUST take precedence over an exchange that has already been made, otherwise the\n * process would go on using whatever it resolved first.\n *\n * Process-wide, so a process that serves more than one company must not use it: set it and\n * every render that follows reads with that key. Those callers pass `companyApiKey` per\n * client instead, which wins over this.\n */\nlet companyApiKey: string | null = null;\n\n/** Set it, or pass null/empty to fall back to the config and the environment. */\nexport function setCompanyApiKey(key: string | null | undefined): void {\n const trimmed = typeof key === \"string\" ? key.trim() : \"\";\n\n companyApiKey = trimmed ? trimmed : null;\n}\n\n/**\n * What is currently set, or null.\n *\n * Returns the key itself, so treat it as the secret it is: it belongs in a request header,\n * never in a log line, an error message or anything a page renders.\n */\nexport function getCompanyApiKey(): string | null {\n return companyApiKey;\n}\n"],
5
+ "mappings": ";AAwBA,IAAI,gBAA+B;AAG5B,SAAS,iBAAiB,KAAsC;AACrE,QAAM,UAAU,OAAO,QAAQ,WAAW,IAAI,KAAK,IAAI;AAEvD,kBAAgB,UAAU,UAAU;AACtC;AAQO,SAAS,mBAAkC;AAChD,SAAO;AACT;",
6
+ "names": []
7
+ }