order3000 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.cjs CHANGED
@@ -134,6 +134,38 @@ class BaseResource {
134
134
  }
135
135
  return response.json();
136
136
  }
137
+ /**
138
+ * Multipart counterpart to `request`. Skips the JSON Content-Type
139
+ * default — `fetch` sets `multipart/form-data; boundary=…`
140
+ * automatically when the body is a `FormData`. Use for binary uploads
141
+ * (e.g. article feature image).
142
+ */
143
+ async requestMultipart(method, path, formData) {
144
+ const token = await this.tokenManager.getToken();
145
+ const venueId = this.tokenManager.getVenueId();
146
+ const url = `${this.baseUrl}/venues/${venueId}${this.resourcePath}${path}`;
147
+ const response = await fetch(url, {
148
+ method,
149
+ headers: {
150
+ Authorization: `Bearer ${token}`
151
+ // Intentionally NO Content-Type — fetch sets the boundary.
152
+ },
153
+ body: formData,
154
+ cache: "no-store",
155
+ signal: AbortSignal.timeout(36e4)
156
+ });
157
+ if (!response.ok) {
158
+ let body = "";
159
+ try {
160
+ body = await response.text();
161
+ } catch {
162
+ }
163
+ throw new Error(
164
+ `HTTP ${response.status}: ${response.statusText}${body ? ` \u2014 ${body}` : ""}`
165
+ );
166
+ }
167
+ return response.json();
168
+ }
137
169
  }
138
170
 
139
171
  class AreasResource extends BaseResource {
@@ -231,6 +263,59 @@ class ArticlesResource extends BaseResource {
231
263
  body
232
264
  );
233
265
  }
266
+ /**
267
+ * Read the article's resolved feature image — asset id, public URL,
268
+ * matched locale, plus the FULL per-locale caption + alt records.
269
+ * Returns null when the article has no feature image yet (the wire
270
+ * 404 is mapped here for ergonomic null-checking on the caller side).
271
+ */
272
+ async getFeatureImage(idOrAccessor, options) {
273
+ const params = new URLSearchParams();
274
+ if (options?.locale) params.set("locale", options.locale);
275
+ const qs = params.toString();
276
+ const path = `/${encodeURIComponent(idOrAccessor)}/feature-image${qs ? `?${qs}` : ""}`;
277
+ try {
278
+ return await this.request("GET", path);
279
+ } catch (err) {
280
+ if (err instanceof Error && err.message.includes("HTTP 404")) {
281
+ return null;
282
+ }
283
+ throw err;
284
+ }
285
+ }
286
+ /**
287
+ * Upload a new feature image. Replaces any existing feature image
288
+ * for the venue's primary locale (the previous one is demoted to
289
+ * `role='inline'`). The SDK builds the multipart body internally —
290
+ * pass a Buffer/Uint8Array, the original filename, and the MIME
291
+ * type.
292
+ */
293
+ async uploadFeatureImage(idOrAccessor, file) {
294
+ const form = new FormData();
295
+ form.append(
296
+ "file",
297
+ new Blob([new Uint8Array(file.data)], { type: file.contentType }),
298
+ file.filename
299
+ );
300
+ return this.requestMultipart(
301
+ "POST",
302
+ `/${encodeURIComponent(idOrAccessor)}/feature-image`,
303
+ form
304
+ );
305
+ }
306
+ /**
307
+ * Update per-locale caption / alt on the article's feature image.
308
+ * Locale-keyed merge — `{ caption: { en: '…' } }` does not touch
309
+ * `de`. Plain-string locale values are server-side wrapped into
310
+ * minimal TipTap docs (the storage shape).
311
+ */
312
+ async patchFeatureImage(idOrAccessor, body) {
313
+ return this.request(
314
+ "PATCH",
315
+ `/${encodeURIComponent(idOrAccessor)}/feature-image`,
316
+ body
317
+ );
318
+ }
234
319
  }
235
320
 
236
321
  class BasketsResource extends BaseResource {
package/dist/client.d.cts CHANGED
@@ -51,6 +51,13 @@ declare abstract class BaseResource {
51
51
  protected readonly resourcePath: string;
52
52
  constructor(tokenManager: TokenManager, baseUrl: string, resourcePath: string);
53
53
  protected request<T>(method: 'GET' | 'POST' | 'PATCH' | 'DELETE', path: string, data?: unknown, cacheOptions?: RequestCacheOptions): Promise<T>;
54
+ /**
55
+ * Multipart counterpart to `request`. Skips the JSON Content-Type
56
+ * default — `fetch` sets `multipart/form-data; boundary=…`
57
+ * automatically when the body is a `FormData`. Use for binary uploads
58
+ * (e.g. article feature image).
59
+ */
60
+ protected requestMultipart<T>(method: 'POST' | 'PATCH' | 'PUT', path: string, formData: FormData): Promise<T>;
54
61
  }
55
62
 
56
63
  interface components {
@@ -218,9 +225,24 @@ interface components {
218
225
  createdAt: string | null;
219
226
  updatedAt: string | null;
220
227
  };
228
+ /**
229
+ * FeatureImage
230
+ * @description An article's resolved feature image. `caption` / `alt` are per-locale TipTap docs (PATCH accepts plain strings — server normalises).
231
+ */
232
+ FeatureImage: {
233
+ id: string;
234
+ publicUrl: string | null;
235
+ locale: string;
236
+ caption: {
237
+ [key: string]: unknown;
238
+ } | null;
239
+ alt: {
240
+ [key: string]: unknown;
241
+ } | null;
242
+ };
221
243
  /**
222
244
  * Article
223
- * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire.
245
+ * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire. `featureImage` is resolved per-locale with a fallback to the venue's primary locale.
224
246
  */
225
247
  Article: {
226
248
  id: string;
@@ -239,19 +261,19 @@ interface components {
239
261
  [key: string]: unknown;
240
262
  } | null;
241
263
  tags: string[];
242
- featuredImageId: string | null;
243
264
  isActive: boolean;
244
265
  isFeatured: boolean;
245
266
  priority: number;
246
267
  publishedAt: unknown;
247
268
  createdAt: unknown;
248
269
  updatedAt: unknown;
270
+ featureImage: components["schemas"]["FeatureImage"] | null;
249
271
  };
250
272
  /** ListArticlesResponse */
251
273
  ListArticlesResponse: components["schemas"]["Article"][];
252
274
  /**
253
275
  * GetArticleResponse
254
- * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire.
276
+ * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire. `featureImage` is resolved per-locale with a fallback to the venue's primary locale.
255
277
  */
256
278
  GetArticleResponse: {
257
279
  id: string;
@@ -270,13 +292,13 @@ interface components {
270
292
  [key: string]: unknown;
271
293
  } | null;
272
294
  tags: string[];
273
- featuredImageId: string | null;
274
295
  isActive: boolean;
275
296
  isFeatured: boolean;
276
297
  priority: number;
277
298
  publishedAt: unknown;
278
299
  createdAt: unknown;
279
300
  updatedAt: unknown;
301
+ featureImage: components["schemas"]["FeatureImage"] | null;
280
302
  };
281
303
  /** PatchArticleRequest */
282
304
  PatchArticleRequest: {
@@ -293,14 +315,13 @@ interface components {
293
315
  [key: string]: unknown;
294
316
  };
295
317
  tags?: string[];
296
- featuredImageId?: string | null;
297
318
  isActive?: boolean;
298
319
  isFeatured?: boolean;
299
320
  priority?: number;
300
321
  };
301
322
  /**
302
323
  * PatchArticleResponse
303
- * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire.
324
+ * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire. `featureImage` is resolved per-locale with a fallback to the venue's primary locale.
304
325
  */
305
326
  PatchArticleResponse: {
306
327
  id: string;
@@ -319,13 +340,30 @@ interface components {
319
340
  [key: string]: unknown;
320
341
  } | null;
321
342
  tags: string[];
322
- featuredImageId: string | null;
323
343
  isActive: boolean;
324
344
  isFeatured: boolean;
325
345
  priority: number;
326
346
  publishedAt: unknown;
327
347
  createdAt: unknown;
328
348
  updatedAt: unknown;
349
+ featureImage: components["schemas"]["FeatureImage"] | null;
350
+ };
351
+ /** UploadFeatureImageRequest */
352
+ UploadFeatureImageRequest: {
353
+ /** @description Image file (multipart/form-data field) */
354
+ file: unknown;
355
+ };
356
+ /**
357
+ * PatchFeatureImageRequest
358
+ * @description Locale-keyed merge of the asset-side `caption` and `alt` records. Each locale value may be a plain string OR a TipTap doc; strings are wrapped server-side. Setting `en` does not touch `de`.
359
+ */
360
+ PatchFeatureImageRequest: {
361
+ caption?: {
362
+ [key: string]: unknown;
363
+ };
364
+ alt?: {
365
+ [key: string]: unknown;
366
+ };
329
367
  };
330
368
  /**
331
369
  * AddToBasketRequest
@@ -1208,6 +1246,19 @@ type ListArticlesResponse = schemas['ListArticlesResponse'];
1208
1246
  type GetArticleResponse = schemas['GetArticleResponse'];
1209
1247
  type PatchArticleRequest = schemas['PatchArticleRequest'];
1210
1248
  type PatchArticleResponse = schemas['PatchArticleResponse'];
1249
+ type FeatureImage = schemas['FeatureImage'];
1250
+ type PatchFeatureImageRequest = schemas['PatchFeatureImageRequest'];
1251
+ /**
1252
+ * Args for `client.articles.uploadFeatureImage()`. The SDK accepts a
1253
+ * `Buffer` or `Uint8Array` payload + filename + content-type — it
1254
+ * builds the FormData internally so callers don't have to know about
1255
+ * multipart wire encoding.
1256
+ */
1257
+ interface UploadFeatureImageArgs {
1258
+ data: Buffer | Uint8Array;
1259
+ filename: string;
1260
+ contentType: string;
1261
+ }
1211
1262
  interface ListArticlesOptions {
1212
1263
  /** Only return articles whose `tags` array contains this value. */
1213
1264
  tag?: string;
@@ -2019,6 +2070,30 @@ declare class ArticlesResource extends BaseResource {
2019
2070
  * Returns the resulting article.
2020
2071
  */
2021
2072
  patch(idOrAccessor: string, body: PatchArticleRequest): Promise<Article>;
2073
+ /**
2074
+ * Read the article's resolved feature image — asset id, public URL,
2075
+ * matched locale, plus the FULL per-locale caption + alt records.
2076
+ * Returns null when the article has no feature image yet (the wire
2077
+ * 404 is mapped here for ergonomic null-checking on the caller side).
2078
+ */
2079
+ getFeatureImage(idOrAccessor: string, options?: {
2080
+ locale?: string;
2081
+ }): Promise<FeatureImage | null>;
2082
+ /**
2083
+ * Upload a new feature image. Replaces any existing feature image
2084
+ * for the venue's primary locale (the previous one is demoted to
2085
+ * `role='inline'`). The SDK builds the multipart body internally —
2086
+ * pass a Buffer/Uint8Array, the original filename, and the MIME
2087
+ * type.
2088
+ */
2089
+ uploadFeatureImage(idOrAccessor: string, file: UploadFeatureImageArgs): Promise<FeatureImage>;
2090
+ /**
2091
+ * Update per-locale caption / alt on the article's feature image.
2092
+ * Locale-keyed merge — `{ caption: { en: '…' } }` does not touch
2093
+ * `de`. Plain-string locale values are server-side wrapped into
2094
+ * minimal TipTap docs (the storage shape).
2095
+ */
2096
+ patchFeatureImage(idOrAccessor: string, body: PatchFeatureImageRequest): Promise<FeatureImage>;
2022
2097
  }
2023
2098
 
2024
2099
  declare class BasketsResource extends BaseResource {
@@ -2904,4 +2979,4 @@ declare class Order3000Client {
2904
2979
  }
2905
2980
 
2906
2981
  export { Order3000Client, fulfillmentTypeEnum, getScheduleInfo, participantStatusEnum, paymentMethodEnum, teamOrderStatusEnum };
2907
- export type { AddToBasketRequest, AddToBasketResponse, Area, AreaAsset, AreaAvailabilityResponse, AreaAvailabilityWindow, AreaBookingMode, AreaBookingRequestResponse, AreaBookingRequestSource, AreaBookingRequestStatus, AreaBookingStatus, AreaFeature, Article, Basket, BasketItem, BasketItemDeposit, BasketItemMenuItemRef, BasketItemMetadata, BasketStatus, BasketTotals, CancelTeamOrderResponse, ConfirmOrderRequest, ConfirmOrderResponse, CreateDeltaPaymentIntentRequest, CreateDeltaPaymentIntentResponse, CreatePaymentIntentRequest, CreatePaymentIntentResponse, CreateTeamOrderRequest, CreateTeamOrderResponse, CropArea, Currency, DayOfWeek, DeclaredReturn, Event, EventByAccessor, EventMenu, EventPoster, EventRow, ExtendDeadlineResponse as ExtendTeamOrderDeadlineResponse, FetchTeamOrderResponse, GetAreaAvailabilityOptions, GetAreaOptions, GetArticleResponse, GetEventOptions, GetMenuOptions, GetVenueResponse, JoinTeamOrderRequest, JoinTeamOrderResponse, LatestOrder, ListArticlesOptions, ListArticlesResponse, ListEventsOptions, ListEventsResponse, Menu, MenuAsset, MenuBeverage, MenuBundle, MenuBundleDeposit, MenuDish, MenuItem, MenuItemRow, MenuItemType, MenuSubscription, MenuSubscriptionPoster, Order3000ClientConfig, OrderFulfillmentType, OrderStatus, PatchArticleRequest, PatchArticleResponse, PaymentStatus, PlaceOrderRequest, Promotion, RealtimeConfig, RealtimeEvent, RealtimeSubscription, RemoveFromBasketResponse, Schedule, ScheduleInfo, ScheduleOverride, ScheduleOverrideRow, ScheduleRow, ScheduleTimeSlot, ScheduleWithTimeSlots, SubmitAreaBookingRequestPayload, SubmitTeamOrderResponse, SubscribeRequest, SubscribeResponse, SubscriberStatus, SubscriptionCredit, SubscriptionCreditStatus, SubscriptionOptions, SubscriptionPeriod, SwitchFulfillmentResponse as SwitchTeamOrderFulfillmentResponse, TeamDeliveryAddress, TeamOrderBasketItem, TeamOrderBasketItemMenuItemRef, FulfillmentType as TeamOrderFulfillmentType, TeamOrderParticipant, ParticipantStatus as TeamOrderParticipantStatus, PaymentMethod as TeamOrderPaymentMethod, TeamOrderStatus, ThresholdCheck as TeamOrderThresholdCheck, TimeSlot, Unit, UpdateDeliveryAddressResponse as UpdateTeamOrderDeliveryAddressResponse, Venue };
2982
+ export type { AddToBasketRequest, AddToBasketResponse, Area, AreaAsset, AreaAvailabilityResponse, AreaAvailabilityWindow, AreaBookingMode, AreaBookingRequestResponse, AreaBookingRequestSource, AreaBookingRequestStatus, AreaBookingStatus, AreaFeature, Article, Basket, BasketItem, BasketItemDeposit, BasketItemMenuItemRef, BasketItemMetadata, BasketStatus, BasketTotals, CancelTeamOrderResponse, ConfirmOrderRequest, ConfirmOrderResponse, CreateDeltaPaymentIntentRequest, CreateDeltaPaymentIntentResponse, CreatePaymentIntentRequest, CreatePaymentIntentResponse, CreateTeamOrderRequest, CreateTeamOrderResponse, CropArea, Currency, DayOfWeek, DeclaredReturn, Event, EventByAccessor, EventMenu, EventPoster, EventRow, ExtendDeadlineResponse as ExtendTeamOrderDeadlineResponse, FeatureImage, FetchTeamOrderResponse, GetAreaAvailabilityOptions, GetAreaOptions, GetArticleResponse, GetEventOptions, GetMenuOptions, GetVenueResponse, JoinTeamOrderRequest, JoinTeamOrderResponse, LatestOrder, ListArticlesOptions, ListArticlesResponse, ListEventsOptions, ListEventsResponse, Menu, MenuAsset, MenuBeverage, MenuBundle, MenuBundleDeposit, MenuDish, MenuItem, MenuItemRow, MenuItemType, MenuSubscription, MenuSubscriptionPoster, Order3000ClientConfig, OrderFulfillmentType, OrderStatus, PatchArticleRequest, PatchArticleResponse, PatchFeatureImageRequest, PaymentStatus, PlaceOrderRequest, Promotion, RealtimeConfig, RealtimeEvent, RealtimeSubscription, RemoveFromBasketResponse, Schedule, ScheduleInfo, ScheduleOverride, ScheduleOverrideRow, ScheduleRow, ScheduleTimeSlot, ScheduleWithTimeSlots, SubmitAreaBookingRequestPayload, SubmitTeamOrderResponse, SubscribeRequest, SubscribeResponse, SubscriberStatus, SubscriptionCredit, SubscriptionCreditStatus, SubscriptionOptions, SubscriptionPeriod, SwitchFulfillmentResponse as SwitchTeamOrderFulfillmentResponse, TeamDeliveryAddress, TeamOrderBasketItem, TeamOrderBasketItemMenuItemRef, FulfillmentType as TeamOrderFulfillmentType, TeamOrderParticipant, ParticipantStatus as TeamOrderParticipantStatus, PaymentMethod as TeamOrderPaymentMethod, TeamOrderStatus, ThresholdCheck as TeamOrderThresholdCheck, TimeSlot, Unit, UpdateDeliveryAddressResponse as UpdateTeamOrderDeliveryAddressResponse, UploadFeatureImageArgs, Venue };
package/dist/client.d.mts CHANGED
@@ -51,6 +51,13 @@ declare abstract class BaseResource {
51
51
  protected readonly resourcePath: string;
52
52
  constructor(tokenManager: TokenManager, baseUrl: string, resourcePath: string);
53
53
  protected request<T>(method: 'GET' | 'POST' | 'PATCH' | 'DELETE', path: string, data?: unknown, cacheOptions?: RequestCacheOptions): Promise<T>;
54
+ /**
55
+ * Multipart counterpart to `request`. Skips the JSON Content-Type
56
+ * default — `fetch` sets `multipart/form-data; boundary=…`
57
+ * automatically when the body is a `FormData`. Use for binary uploads
58
+ * (e.g. article feature image).
59
+ */
60
+ protected requestMultipart<T>(method: 'POST' | 'PATCH' | 'PUT', path: string, formData: FormData): Promise<T>;
54
61
  }
55
62
 
56
63
  interface components {
@@ -218,9 +225,24 @@ interface components {
218
225
  createdAt: string | null;
219
226
  updatedAt: string | null;
220
227
  };
228
+ /**
229
+ * FeatureImage
230
+ * @description An article's resolved feature image. `caption` / `alt` are per-locale TipTap docs (PATCH accepts plain strings — server normalises).
231
+ */
232
+ FeatureImage: {
233
+ id: string;
234
+ publicUrl: string | null;
235
+ locale: string;
236
+ caption: {
237
+ [key: string]: unknown;
238
+ } | null;
239
+ alt: {
240
+ [key: string]: unknown;
241
+ } | null;
242
+ };
221
243
  /**
222
244
  * Article
223
- * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire.
245
+ * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire. `featureImage` is resolved per-locale with a fallback to the venue's primary locale.
224
246
  */
225
247
  Article: {
226
248
  id: string;
@@ -239,19 +261,19 @@ interface components {
239
261
  [key: string]: unknown;
240
262
  } | null;
241
263
  tags: string[];
242
- featuredImageId: string | null;
243
264
  isActive: boolean;
244
265
  isFeatured: boolean;
245
266
  priority: number;
246
267
  publishedAt: unknown;
247
268
  createdAt: unknown;
248
269
  updatedAt: unknown;
270
+ featureImage: components["schemas"]["FeatureImage"] | null;
249
271
  };
250
272
  /** ListArticlesResponse */
251
273
  ListArticlesResponse: components["schemas"]["Article"][];
252
274
  /**
253
275
  * GetArticleResponse
254
- * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire.
276
+ * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire. `featureImage` is resolved per-locale with a fallback to the venue's primary locale.
255
277
  */
256
278
  GetArticleResponse: {
257
279
  id: string;
@@ -270,13 +292,13 @@ interface components {
270
292
  [key: string]: unknown;
271
293
  } | null;
272
294
  tags: string[];
273
- featuredImageId: string | null;
274
295
  isActive: boolean;
275
296
  isFeatured: boolean;
276
297
  priority: number;
277
298
  publishedAt: unknown;
278
299
  createdAt: unknown;
279
300
  updatedAt: unknown;
301
+ featureImage: components["schemas"]["FeatureImage"] | null;
280
302
  };
281
303
  /** PatchArticleRequest */
282
304
  PatchArticleRequest: {
@@ -293,14 +315,13 @@ interface components {
293
315
  [key: string]: unknown;
294
316
  };
295
317
  tags?: string[];
296
- featuredImageId?: string | null;
297
318
  isActive?: boolean;
298
319
  isFeatured?: boolean;
299
320
  priority?: number;
300
321
  };
301
322
  /**
302
323
  * PatchArticleResponse
303
- * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire.
324
+ * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire. `featureImage` is resolved per-locale with a fallback to the venue's primary locale.
304
325
  */
305
326
  PatchArticleResponse: {
306
327
  id: string;
@@ -319,13 +340,30 @@ interface components {
319
340
  [key: string]: unknown;
320
341
  } | null;
321
342
  tags: string[];
322
- featuredImageId: string | null;
323
343
  isActive: boolean;
324
344
  isFeatured: boolean;
325
345
  priority: number;
326
346
  publishedAt: unknown;
327
347
  createdAt: unknown;
328
348
  updatedAt: unknown;
349
+ featureImage: components["schemas"]["FeatureImage"] | null;
350
+ };
351
+ /** UploadFeatureImageRequest */
352
+ UploadFeatureImageRequest: {
353
+ /** @description Image file (multipart/form-data field) */
354
+ file: unknown;
355
+ };
356
+ /**
357
+ * PatchFeatureImageRequest
358
+ * @description Locale-keyed merge of the asset-side `caption` and `alt` records. Each locale value may be a plain string OR a TipTap doc; strings are wrapped server-side. Setting `en` does not touch `de`.
359
+ */
360
+ PatchFeatureImageRequest: {
361
+ caption?: {
362
+ [key: string]: unknown;
363
+ };
364
+ alt?: {
365
+ [key: string]: unknown;
366
+ };
329
367
  };
330
368
  /**
331
369
  * AddToBasketRequest
@@ -1208,6 +1246,19 @@ type ListArticlesResponse = schemas['ListArticlesResponse'];
1208
1246
  type GetArticleResponse = schemas['GetArticleResponse'];
1209
1247
  type PatchArticleRequest = schemas['PatchArticleRequest'];
1210
1248
  type PatchArticleResponse = schemas['PatchArticleResponse'];
1249
+ type FeatureImage = schemas['FeatureImage'];
1250
+ type PatchFeatureImageRequest = schemas['PatchFeatureImageRequest'];
1251
+ /**
1252
+ * Args for `client.articles.uploadFeatureImage()`. The SDK accepts a
1253
+ * `Buffer` or `Uint8Array` payload + filename + content-type — it
1254
+ * builds the FormData internally so callers don't have to know about
1255
+ * multipart wire encoding.
1256
+ */
1257
+ interface UploadFeatureImageArgs {
1258
+ data: Buffer | Uint8Array;
1259
+ filename: string;
1260
+ contentType: string;
1261
+ }
1211
1262
  interface ListArticlesOptions {
1212
1263
  /** Only return articles whose `tags` array contains this value. */
1213
1264
  tag?: string;
@@ -2019,6 +2070,30 @@ declare class ArticlesResource extends BaseResource {
2019
2070
  * Returns the resulting article.
2020
2071
  */
2021
2072
  patch(idOrAccessor: string, body: PatchArticleRequest): Promise<Article>;
2073
+ /**
2074
+ * Read the article's resolved feature image — asset id, public URL,
2075
+ * matched locale, plus the FULL per-locale caption + alt records.
2076
+ * Returns null when the article has no feature image yet (the wire
2077
+ * 404 is mapped here for ergonomic null-checking on the caller side).
2078
+ */
2079
+ getFeatureImage(idOrAccessor: string, options?: {
2080
+ locale?: string;
2081
+ }): Promise<FeatureImage | null>;
2082
+ /**
2083
+ * Upload a new feature image. Replaces any existing feature image
2084
+ * for the venue's primary locale (the previous one is demoted to
2085
+ * `role='inline'`). The SDK builds the multipart body internally —
2086
+ * pass a Buffer/Uint8Array, the original filename, and the MIME
2087
+ * type.
2088
+ */
2089
+ uploadFeatureImage(idOrAccessor: string, file: UploadFeatureImageArgs): Promise<FeatureImage>;
2090
+ /**
2091
+ * Update per-locale caption / alt on the article's feature image.
2092
+ * Locale-keyed merge — `{ caption: { en: '…' } }` does not touch
2093
+ * `de`. Plain-string locale values are server-side wrapped into
2094
+ * minimal TipTap docs (the storage shape).
2095
+ */
2096
+ patchFeatureImage(idOrAccessor: string, body: PatchFeatureImageRequest): Promise<FeatureImage>;
2022
2097
  }
2023
2098
 
2024
2099
  declare class BasketsResource extends BaseResource {
@@ -2904,4 +2979,4 @@ declare class Order3000Client {
2904
2979
  }
2905
2980
 
2906
2981
  export { Order3000Client, fulfillmentTypeEnum, getScheduleInfo, participantStatusEnum, paymentMethodEnum, teamOrderStatusEnum };
2907
- export type { AddToBasketRequest, AddToBasketResponse, Area, AreaAsset, AreaAvailabilityResponse, AreaAvailabilityWindow, AreaBookingMode, AreaBookingRequestResponse, AreaBookingRequestSource, AreaBookingRequestStatus, AreaBookingStatus, AreaFeature, Article, Basket, BasketItem, BasketItemDeposit, BasketItemMenuItemRef, BasketItemMetadata, BasketStatus, BasketTotals, CancelTeamOrderResponse, ConfirmOrderRequest, ConfirmOrderResponse, CreateDeltaPaymentIntentRequest, CreateDeltaPaymentIntentResponse, CreatePaymentIntentRequest, CreatePaymentIntentResponse, CreateTeamOrderRequest, CreateTeamOrderResponse, CropArea, Currency, DayOfWeek, DeclaredReturn, Event, EventByAccessor, EventMenu, EventPoster, EventRow, ExtendDeadlineResponse as ExtendTeamOrderDeadlineResponse, FetchTeamOrderResponse, GetAreaAvailabilityOptions, GetAreaOptions, GetArticleResponse, GetEventOptions, GetMenuOptions, GetVenueResponse, JoinTeamOrderRequest, JoinTeamOrderResponse, LatestOrder, ListArticlesOptions, ListArticlesResponse, ListEventsOptions, ListEventsResponse, Menu, MenuAsset, MenuBeverage, MenuBundle, MenuBundleDeposit, MenuDish, MenuItem, MenuItemRow, MenuItemType, MenuSubscription, MenuSubscriptionPoster, Order3000ClientConfig, OrderFulfillmentType, OrderStatus, PatchArticleRequest, PatchArticleResponse, PaymentStatus, PlaceOrderRequest, Promotion, RealtimeConfig, RealtimeEvent, RealtimeSubscription, RemoveFromBasketResponse, Schedule, ScheduleInfo, ScheduleOverride, ScheduleOverrideRow, ScheduleRow, ScheduleTimeSlot, ScheduleWithTimeSlots, SubmitAreaBookingRequestPayload, SubmitTeamOrderResponse, SubscribeRequest, SubscribeResponse, SubscriberStatus, SubscriptionCredit, SubscriptionCreditStatus, SubscriptionOptions, SubscriptionPeriod, SwitchFulfillmentResponse as SwitchTeamOrderFulfillmentResponse, TeamDeliveryAddress, TeamOrderBasketItem, TeamOrderBasketItemMenuItemRef, FulfillmentType as TeamOrderFulfillmentType, TeamOrderParticipant, ParticipantStatus as TeamOrderParticipantStatus, PaymentMethod as TeamOrderPaymentMethod, TeamOrderStatus, ThresholdCheck as TeamOrderThresholdCheck, TimeSlot, Unit, UpdateDeliveryAddressResponse as UpdateTeamOrderDeliveryAddressResponse, Venue };
2982
+ export type { AddToBasketRequest, AddToBasketResponse, Area, AreaAsset, AreaAvailabilityResponse, AreaAvailabilityWindow, AreaBookingMode, AreaBookingRequestResponse, AreaBookingRequestSource, AreaBookingRequestStatus, AreaBookingStatus, AreaFeature, Article, Basket, BasketItem, BasketItemDeposit, BasketItemMenuItemRef, BasketItemMetadata, BasketStatus, BasketTotals, CancelTeamOrderResponse, ConfirmOrderRequest, ConfirmOrderResponse, CreateDeltaPaymentIntentRequest, CreateDeltaPaymentIntentResponse, CreatePaymentIntentRequest, CreatePaymentIntentResponse, CreateTeamOrderRequest, CreateTeamOrderResponse, CropArea, Currency, DayOfWeek, DeclaredReturn, Event, EventByAccessor, EventMenu, EventPoster, EventRow, ExtendDeadlineResponse as ExtendTeamOrderDeadlineResponse, FeatureImage, FetchTeamOrderResponse, GetAreaAvailabilityOptions, GetAreaOptions, GetArticleResponse, GetEventOptions, GetMenuOptions, GetVenueResponse, JoinTeamOrderRequest, JoinTeamOrderResponse, LatestOrder, ListArticlesOptions, ListArticlesResponse, ListEventsOptions, ListEventsResponse, Menu, MenuAsset, MenuBeverage, MenuBundle, MenuBundleDeposit, MenuDish, MenuItem, MenuItemRow, MenuItemType, MenuSubscription, MenuSubscriptionPoster, Order3000ClientConfig, OrderFulfillmentType, OrderStatus, PatchArticleRequest, PatchArticleResponse, PatchFeatureImageRequest, PaymentStatus, PlaceOrderRequest, Promotion, RealtimeConfig, RealtimeEvent, RealtimeSubscription, RemoveFromBasketResponse, Schedule, ScheduleInfo, ScheduleOverride, ScheduleOverrideRow, ScheduleRow, ScheduleTimeSlot, ScheduleWithTimeSlots, SubmitAreaBookingRequestPayload, SubmitTeamOrderResponse, SubscribeRequest, SubscribeResponse, SubscriberStatus, SubscriptionCredit, SubscriptionCreditStatus, SubscriptionOptions, SubscriptionPeriod, SwitchFulfillmentResponse as SwitchTeamOrderFulfillmentResponse, TeamDeliveryAddress, TeamOrderBasketItem, TeamOrderBasketItemMenuItemRef, FulfillmentType as TeamOrderFulfillmentType, TeamOrderParticipant, ParticipantStatus as TeamOrderParticipantStatus, PaymentMethod as TeamOrderPaymentMethod, TeamOrderStatus, ThresholdCheck as TeamOrderThresholdCheck, TimeSlot, Unit, UpdateDeliveryAddressResponse as UpdateTeamOrderDeliveryAddressResponse, UploadFeatureImageArgs, Venue };
package/dist/client.mjs CHANGED
@@ -132,6 +132,38 @@ class BaseResource {
132
132
  }
133
133
  return response.json();
134
134
  }
135
+ /**
136
+ * Multipart counterpart to `request`. Skips the JSON Content-Type
137
+ * default — `fetch` sets `multipart/form-data; boundary=…`
138
+ * automatically when the body is a `FormData`. Use for binary uploads
139
+ * (e.g. article feature image).
140
+ */
141
+ async requestMultipart(method, path, formData) {
142
+ const token = await this.tokenManager.getToken();
143
+ const venueId = this.tokenManager.getVenueId();
144
+ const url = `${this.baseUrl}/venues/${venueId}${this.resourcePath}${path}`;
145
+ const response = await fetch(url, {
146
+ method,
147
+ headers: {
148
+ Authorization: `Bearer ${token}`
149
+ // Intentionally NO Content-Type — fetch sets the boundary.
150
+ },
151
+ body: formData,
152
+ cache: "no-store",
153
+ signal: AbortSignal.timeout(36e4)
154
+ });
155
+ if (!response.ok) {
156
+ let body = "";
157
+ try {
158
+ body = await response.text();
159
+ } catch {
160
+ }
161
+ throw new Error(
162
+ `HTTP ${response.status}: ${response.statusText}${body ? ` \u2014 ${body}` : ""}`
163
+ );
164
+ }
165
+ return response.json();
166
+ }
135
167
  }
136
168
 
137
169
  class AreasResource extends BaseResource {
@@ -229,6 +261,59 @@ class ArticlesResource extends BaseResource {
229
261
  body
230
262
  );
231
263
  }
264
+ /**
265
+ * Read the article's resolved feature image — asset id, public URL,
266
+ * matched locale, plus the FULL per-locale caption + alt records.
267
+ * Returns null when the article has no feature image yet (the wire
268
+ * 404 is mapped here for ergonomic null-checking on the caller side).
269
+ */
270
+ async getFeatureImage(idOrAccessor, options) {
271
+ const params = new URLSearchParams();
272
+ if (options?.locale) params.set("locale", options.locale);
273
+ const qs = params.toString();
274
+ const path = `/${encodeURIComponent(idOrAccessor)}/feature-image${qs ? `?${qs}` : ""}`;
275
+ try {
276
+ return await this.request("GET", path);
277
+ } catch (err) {
278
+ if (err instanceof Error && err.message.includes("HTTP 404")) {
279
+ return null;
280
+ }
281
+ throw err;
282
+ }
283
+ }
284
+ /**
285
+ * Upload a new feature image. Replaces any existing feature image
286
+ * for the venue's primary locale (the previous one is demoted to
287
+ * `role='inline'`). The SDK builds the multipart body internally —
288
+ * pass a Buffer/Uint8Array, the original filename, and the MIME
289
+ * type.
290
+ */
291
+ async uploadFeatureImage(idOrAccessor, file) {
292
+ const form = new FormData();
293
+ form.append(
294
+ "file",
295
+ new Blob([new Uint8Array(file.data)], { type: file.contentType }),
296
+ file.filename
297
+ );
298
+ return this.requestMultipart(
299
+ "POST",
300
+ `/${encodeURIComponent(idOrAccessor)}/feature-image`,
301
+ form
302
+ );
303
+ }
304
+ /**
305
+ * Update per-locale caption / alt on the article's feature image.
306
+ * Locale-keyed merge — `{ caption: { en: '…' } }` does not touch
307
+ * `de`. Plain-string locale values are server-side wrapped into
308
+ * minimal TipTap docs (the storage shape).
309
+ */
310
+ async patchFeatureImage(idOrAccessor, body) {
311
+ return this.request(
312
+ "PATCH",
313
+ `/${encodeURIComponent(idOrAccessor)}/feature-image`,
314
+ body
315
+ );
316
+ }
232
317
  }
233
318
 
234
319
  class BasketsResource extends BaseResource {
package/dist/schemas.cjs CHANGED
@@ -9,11 +9,14 @@ const GetAreaAvailabilityResponse = zod.z.object({ from: zod.z.string().regex(/^
9
9
  const SubmitAreaBookingRequest = zod.z.object({ requestedDate: zod.z.string().regex(/^\d{4}-\d{2}-\d{2}$/), requestedStartTime: zod.z.string().regex(/^\d{2}:\d{2}(:\d{2})?$/).optional(), requestedEndTime: zod.z.string().regex(/^\d{2}:\d{2}(:\d{2})?$/).optional(), partySize: zod.z.number().int().lte(9007199254740991), customerFirstName: zod.z.string().min(1), customerLastName: zod.z.string().min(1), customerEmail: zod.z.string().regex(/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/).email(), customerPhone: zod.z.string().optional(), message: zod.z.string().optional(), source: zod.z.enum(["website", "phone", "walk_in"]).optional() }).strict();
10
10
  const SubmitAreaBookingResponse = zod.z.object({ id: zod.z.string(), venueId: zod.z.string(), areaId: zod.z.string(), requestedDate: zod.z.string().regex(/^\d{4}-\d{2}-\d{2}$/), requestedStartTime: zod.z.string().regex(/^\d{2}:\d{2}(:\d{2})?$/).nullable(), requestedEndTime: zod.z.string().regex(/^\d{2}:\d{2}(:\d{2})?$/).nullable(), partySize: zod.z.number().int().gte(-9007199254740991).lte(9007199254740991), customerFirstName: zod.z.string(), customerLastName: zod.z.string(), customerEmail: zod.z.string(), customerPhone: zod.z.string().nullable(), message: zod.z.string().nullable(), source: zod.z.enum(["website", "phone", "walk_in"]), status: zod.z.enum(["pending", "approved", "rejected", "cancelled"]), areaBookingId: zod.z.string().nullable(), createdAt: zod.z.string().nullable(), updatedAt: zod.z.string().nullable() }).strict();
11
11
  const includeDrafts = zod.z.union([zod.z.literal("true"), zod.z.literal("false")]).optional();
12
- const Article = zod.z.object({ id: zod.z.string(), venueId: zod.z.string(), accessor: zod.z.string(), slug: zod.z.record(zod.z.string()), title: zod.z.record(zod.z.string()), excerpt: zod.z.record(zod.z.string()).nullable(), content: zod.z.object({}).partial().strict().passthrough().nullable(), tags: zod.z.array(zod.z.string()), featuredImageId: zod.z.string().nullable(), isActive: zod.z.boolean(), isFeatured: zod.z.boolean(), priority: zod.z.number().int().gte(-2147483648).lte(2147483647), publishedAt: zod.z.unknown().nullable(), createdAt: zod.z.unknown().nullable(), updatedAt: zod.z.unknown().nullable() }).strict();
12
+ const FeatureImage = zod.z.object({ id: zod.z.string(), publicUrl: zod.z.string().nullable(), locale: zod.z.string(), caption: zod.z.object({}).partial().strict().passthrough().nullable(), alt: zod.z.object({}).partial().strict().passthrough().nullable() }).strict();
13
+ const Article = zod.z.object({ id: zod.z.string(), venueId: zod.z.string(), accessor: zod.z.string(), slug: zod.z.record(zod.z.string()), title: zod.z.record(zod.z.string()), excerpt: zod.z.record(zod.z.string()).nullable(), content: zod.z.object({}).partial().strict().passthrough().nullable(), tags: zod.z.array(zod.z.string()), isActive: zod.z.boolean(), isFeatured: zod.z.boolean(), priority: zod.z.number().int().gte(-2147483648).lte(2147483647), publishedAt: zod.z.unknown().nullable(), createdAt: zod.z.unknown().nullable(), updatedAt: zod.z.unknown().nullable(), featureImage: FeatureImage.nullable() }).strict();
13
14
  const ListArticlesResponse = zod.z.array(Article);
14
- const GetArticleResponse = zod.z.object({ id: zod.z.string(), venueId: zod.z.string(), accessor: zod.z.string(), slug: zod.z.record(zod.z.string()), title: zod.z.record(zod.z.string()), excerpt: zod.z.record(zod.z.string()).nullable(), content: zod.z.object({}).partial().strict().passthrough().nullable(), tags: zod.z.array(zod.z.string()), featuredImageId: zod.z.string().nullable(), isActive: zod.z.boolean(), isFeatured: zod.z.boolean(), priority: zod.z.number().int().gte(-2147483648).lte(2147483647), publishedAt: zod.z.unknown().nullable(), createdAt: zod.z.unknown().nullable(), updatedAt: zod.z.unknown().nullable() }).strict();
15
- const PatchArticleRequest = zod.z.object({ slug: zod.z.record(zod.z.string()), title: zod.z.record(zod.z.string()), excerpt: zod.z.record(zod.z.string()), content: zod.z.object({}).partial().strict().passthrough(), tags: zod.z.array(zod.z.string()), featuredImageId: zod.z.string().nullable(), isActive: zod.z.boolean(), isFeatured: zod.z.boolean(), priority: zod.z.number().int().gte(-9007199254740991).lte(9007199254740991) }).partial().strict();
16
- const PatchArticleResponse = zod.z.object({ id: zod.z.string(), venueId: zod.z.string(), accessor: zod.z.string(), slug: zod.z.record(zod.z.string()), title: zod.z.record(zod.z.string()), excerpt: zod.z.record(zod.z.string()).nullable(), content: zod.z.object({}).partial().strict().passthrough().nullable(), tags: zod.z.array(zod.z.string()), featuredImageId: zod.z.string().nullable(), isActive: zod.z.boolean(), isFeatured: zod.z.boolean(), priority: zod.z.number().int().gte(-2147483648).lte(2147483647), publishedAt: zod.z.unknown().nullable(), createdAt: zod.z.unknown().nullable(), updatedAt: zod.z.unknown().nullable() }).strict();
15
+ const GetArticleResponse = zod.z.object({ id: zod.z.string(), venueId: zod.z.string(), accessor: zod.z.string(), slug: zod.z.record(zod.z.string()), title: zod.z.record(zod.z.string()), excerpt: zod.z.record(zod.z.string()).nullable(), content: zod.z.object({}).partial().strict().passthrough().nullable(), tags: zod.z.array(zod.z.string()), isActive: zod.z.boolean(), isFeatured: zod.z.boolean(), priority: zod.z.number().int().gte(-2147483648).lte(2147483647), publishedAt: zod.z.unknown().nullable(), createdAt: zod.z.unknown().nullable(), updatedAt: zod.z.unknown().nullable(), featureImage: FeatureImage.nullable() }).strict();
16
+ const PatchArticleRequest = zod.z.object({ slug: zod.z.record(zod.z.string()), title: zod.z.record(zod.z.string()), excerpt: zod.z.record(zod.z.string()), content: zod.z.object({}).partial().strict().passthrough(), tags: zod.z.array(zod.z.string()), isActive: zod.z.boolean(), isFeatured: zod.z.boolean(), priority: zod.z.number().int().gte(-9007199254740991).lte(9007199254740991) }).partial().strict();
17
+ const PatchArticleResponse = zod.z.object({ id: zod.z.string(), venueId: zod.z.string(), accessor: zod.z.string(), slug: zod.z.record(zod.z.string()), title: zod.z.record(zod.z.string()), excerpt: zod.z.record(zod.z.string()).nullable(), content: zod.z.object({}).partial().strict().passthrough().nullable(), tags: zod.z.array(zod.z.string()), isActive: zod.z.boolean(), isFeatured: zod.z.boolean(), priority: zod.z.number().int().gte(-2147483648).lte(2147483647), publishedAt: zod.z.unknown().nullable(), createdAt: zod.z.unknown().nullable(), updatedAt: zod.z.unknown().nullable(), featureImage: FeatureImage.nullable() }).strict();
18
+ const UploadFeatureImageRequest = zod.z.object({ file: zod.z.unknown() }).strict();
19
+ const PatchFeatureImageRequest = zod.z.object({ caption: zod.z.object({}).partial().strict().passthrough(), alt: zod.z.object({}).partial().strict().passthrough() }).partial().strict();
17
20
  const AddToBasketRequest = zod.z.object({ venueId: zod.z.string().regex(/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/).uuid(), sessionId: zod.z.string().min(1), menuItems: zod.z.array(zod.z.object({ menuItemId: zod.z.string().min(1), role: zod.z.string().optional(), quantity: zod.z.number().gt(0).optional(), unit: zod.z.enum(["grams", "kilograms", "liters", "milliliters", "pieces"]).optional() }).strict()).min(1), metadata: zod.z.object({}).partial().strict().passthrough().optional() }).strict();
18
21
  const AddToBasketResponse = zod.z.object({ basketItemId: zod.z.string().regex(/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/).uuid(), itemCount: zod.z.number().int().gte(0).lte(9007199254740991), deposit: zod.z.object({ depositwareTemplateId: zod.z.string(), name: zod.z.record(zod.z.string()), amount: zod.z.number().int().gte(0).lte(9007199254740991), currency: zod.z.enum(["EUR", "CHF"]) }).strict().nullable(), totals: zod.z.object({ currency: zod.z.enum(["EUR", "CHF"]), itemsTotal: zod.z.number().int().gte(0).lte(9007199254740991), taxAmount: zod.z.number().int().gte(0).lte(9007199254740991), depositCharge: zod.z.number().int().gte(0).lte(9007199254740991), grossTotal: zod.z.number().int().gte(0).lte(9007199254740991), depositCredit: zod.z.number().int().gte(0).lte(9007199254740991), effectiveTotal: zod.z.number().int().gte(0).lte(9007199254740991), cashRefund: zod.z.number().int().gte(0).lte(9007199254740991), returnable: zod.z.array(zod.z.object({ depositwareTemplateId: zod.z.string(), count: zod.z.number().int().gte(0).lte(9007199254740991) }).strict()) }).strict() }).strict();
19
22
  const RemoveFromBasketResponse = zod.z.object({ success: zod.z.boolean(), basketItemId: zod.z.string().regex(/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/).uuid(), itemCount: zod.z.number().int().gte(0).lte(9007199254740991), totals: zod.z.object({ currency: zod.z.enum(["EUR", "CHF"]), itemsTotal: zod.z.number().int().gte(0).lte(9007199254740991), taxAmount: zod.z.number().int().gte(0).lte(9007199254740991), depositCharge: zod.z.number().int().gte(0).lte(9007199254740991), grossTotal: zod.z.number().int().gte(0).lte(9007199254740991), depositCredit: zod.z.number().int().gte(0).lte(9007199254740991), effectiveTotal: zod.z.number().int().gte(0).lte(9007199254740991), cashRefund: zod.z.number().int().gte(0).lte(9007199254740991), returnable: zod.z.array(zod.z.object({ depositwareTemplateId: zod.z.string(), count: zod.z.number().int().gte(0).lte(9007199254740991) }).strict()) }).strict().nullable() }).strict();
@@ -74,11 +77,14 @@ const schemas = {
74
77
  SubmitAreaBookingRequest,
75
78
  SubmitAreaBookingResponse,
76
79
  includeDrafts,
80
+ FeatureImage,
77
81
  Article,
78
82
  ListArticlesResponse,
79
83
  GetArticleResponse,
80
84
  PatchArticleRequest,
81
85
  PatchArticleResponse,
86
+ UploadFeatureImageRequest,
87
+ PatchFeatureImageRequest,
82
88
  AddToBasketRequest,
83
89
  AddToBasketResponse,
84
90
  RemoveFromBasketResponse,