order3000 0.21.0 → 0.23.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,30 @@ 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). `captionByLocale` / `altByLocale` expose the raw per-locale records for editor surfaces.
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
+ captionByLocale: {
243
+ [key: string]: unknown;
244
+ };
245
+ altByLocale: {
246
+ [key: string]: unknown;
247
+ };
248
+ };
221
249
  /**
222
250
  * Article
223
- * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire.
251
+ * @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
252
  */
225
253
  Article: {
226
254
  id: string;
@@ -233,25 +261,27 @@ interface components {
233
261
  [key: string]: string;
234
262
  };
235
263
  excerpt: {
236
- [key: string]: string;
237
- } | null;
264
+ [key: string]: {
265
+ [key: string]: unknown;
266
+ };
267
+ };
238
268
  content: {
239
269
  [key: string]: unknown;
240
270
  } | null;
241
271
  tags: string[];
242
- featuredImageId: string | null;
243
272
  isActive: boolean;
244
273
  isFeatured: boolean;
245
274
  priority: number;
246
275
  publishedAt: unknown;
247
276
  createdAt: unknown;
248
277
  updatedAt: unknown;
278
+ featureImage: components["schemas"]["FeatureImage"] | null;
249
279
  };
250
280
  /** ListArticlesResponse */
251
281
  ListArticlesResponse: components["schemas"]["Article"][];
252
282
  /**
253
283
  * GetArticleResponse
254
- * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire.
284
+ * @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
285
  */
256
286
  GetArticleResponse: {
257
287
  id: string;
@@ -264,19 +294,21 @@ interface components {
264
294
  [key: string]: string;
265
295
  };
266
296
  excerpt: {
267
- [key: string]: string;
268
- } | null;
297
+ [key: string]: {
298
+ [key: string]: unknown;
299
+ };
300
+ };
269
301
  content: {
270
302
  [key: string]: unknown;
271
303
  } | null;
272
304
  tags: string[];
273
- featuredImageId: string | null;
274
305
  isActive: boolean;
275
306
  isFeatured: boolean;
276
307
  priority: number;
277
308
  publishedAt: unknown;
278
309
  createdAt: unknown;
279
310
  updatedAt: unknown;
311
+ featureImage: components["schemas"]["FeatureImage"] | null;
280
312
  };
281
313
  /** PatchArticleRequest */
282
314
  PatchArticleRequest: {
@@ -287,20 +319,21 @@ interface components {
287
319
  [key: string]: string;
288
320
  };
289
321
  excerpt?: {
290
- [key: string]: string;
322
+ [key: string]: string | {
323
+ [key: string]: unknown;
324
+ };
291
325
  };
292
326
  content?: {
293
327
  [key: string]: unknown;
294
328
  };
295
329
  tags?: string[];
296
- featuredImageId?: string | null;
297
330
  isActive?: boolean;
298
331
  isFeatured?: boolean;
299
332
  priority?: number;
300
333
  };
301
334
  /**
302
335
  * PatchArticleResponse
303
- * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire.
336
+ * @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
337
  */
305
338
  PatchArticleResponse: {
306
339
  id: string;
@@ -313,19 +346,38 @@ interface components {
313
346
  [key: string]: string;
314
347
  };
315
348
  excerpt: {
316
- [key: string]: string;
317
- } | null;
349
+ [key: string]: {
350
+ [key: string]: unknown;
351
+ };
352
+ };
318
353
  content: {
319
354
  [key: string]: unknown;
320
355
  } | null;
321
356
  tags: string[];
322
- featuredImageId: string | null;
323
357
  isActive: boolean;
324
358
  isFeatured: boolean;
325
359
  priority: number;
326
360
  publishedAt: unknown;
327
361
  createdAt: unknown;
328
362
  updatedAt: unknown;
363
+ featureImage: components["schemas"]["FeatureImage"] | null;
364
+ };
365
+ /** UploadFeatureImageRequest */
366
+ UploadFeatureImageRequest: {
367
+ /** @description Image file (multipart/form-data field) */
368
+ file: unknown;
369
+ };
370
+ /**
371
+ * PatchFeatureImageRequest
372
+ * @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`.
373
+ */
374
+ PatchFeatureImageRequest: {
375
+ caption?: {
376
+ [key: string]: unknown;
377
+ };
378
+ alt?: {
379
+ [key: string]: unknown;
380
+ };
329
381
  };
330
382
  /**
331
383
  * AddToBasketRequest
@@ -1208,6 +1260,19 @@ type ListArticlesResponse = schemas['ListArticlesResponse'];
1208
1260
  type GetArticleResponse = schemas['GetArticleResponse'];
1209
1261
  type PatchArticleRequest = schemas['PatchArticleRequest'];
1210
1262
  type PatchArticleResponse = schemas['PatchArticleResponse'];
1263
+ type FeatureImage = schemas['FeatureImage'];
1264
+ type PatchFeatureImageRequest = schemas['PatchFeatureImageRequest'];
1265
+ /**
1266
+ * Args for `client.articles.uploadFeatureImage()`. The SDK accepts a
1267
+ * `Buffer` or `Uint8Array` payload + filename + content-type — it
1268
+ * builds the FormData internally so callers don't have to know about
1269
+ * multipart wire encoding.
1270
+ */
1271
+ interface UploadFeatureImageArgs {
1272
+ data: Buffer | Uint8Array;
1273
+ filename: string;
1274
+ contentType: string;
1275
+ }
1211
1276
  interface ListArticlesOptions {
1212
1277
  /** Only return articles whose `tags` array contains this value. */
1213
1278
  tag?: string;
@@ -2019,6 +2084,30 @@ declare class ArticlesResource extends BaseResource {
2019
2084
  * Returns the resulting article.
2020
2085
  */
2021
2086
  patch(idOrAccessor: string, body: PatchArticleRequest): Promise<Article>;
2087
+ /**
2088
+ * Read the article's resolved feature image — asset id, public URL,
2089
+ * matched locale, plus the FULL per-locale caption + alt records.
2090
+ * Returns null when the article has no feature image yet (the wire
2091
+ * 404 is mapped here for ergonomic null-checking on the caller side).
2092
+ */
2093
+ getFeatureImage(idOrAccessor: string, options?: {
2094
+ locale?: string;
2095
+ }): Promise<FeatureImage | null>;
2096
+ /**
2097
+ * Upload a new feature image. Replaces any existing feature image
2098
+ * for the venue's primary locale (the previous one is demoted to
2099
+ * `role='inline'`). The SDK builds the multipart body internally —
2100
+ * pass a Buffer/Uint8Array, the original filename, and the MIME
2101
+ * type.
2102
+ */
2103
+ uploadFeatureImage(idOrAccessor: string, file: UploadFeatureImageArgs): Promise<FeatureImage>;
2104
+ /**
2105
+ * Update per-locale caption / alt on the article's feature image.
2106
+ * Locale-keyed merge — `{ caption: { en: '…' } }` does not touch
2107
+ * `de`. Plain-string locale values are server-side wrapped into
2108
+ * minimal TipTap docs (the storage shape).
2109
+ */
2110
+ patchFeatureImage(idOrAccessor: string, body: PatchFeatureImageRequest): Promise<FeatureImage>;
2022
2111
  }
2023
2112
 
2024
2113
  declare class BasketsResource extends BaseResource {
@@ -2904,4 +2993,4 @@ declare class Order3000Client {
2904
2993
  }
2905
2994
 
2906
2995
  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 };
2996
+ 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,30 @@ 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). `captionByLocale` / `altByLocale` expose the raw per-locale records for editor surfaces.
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
+ captionByLocale: {
243
+ [key: string]: unknown;
244
+ };
245
+ altByLocale: {
246
+ [key: string]: unknown;
247
+ };
248
+ };
221
249
  /**
222
250
  * Article
223
- * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire.
251
+ * @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
252
  */
225
253
  Article: {
226
254
  id: string;
@@ -233,25 +261,27 @@ interface components {
233
261
  [key: string]: string;
234
262
  };
235
263
  excerpt: {
236
- [key: string]: string;
237
- } | null;
264
+ [key: string]: {
265
+ [key: string]: unknown;
266
+ };
267
+ };
238
268
  content: {
239
269
  [key: string]: unknown;
240
270
  } | null;
241
271
  tags: string[];
242
- featuredImageId: string | null;
243
272
  isActive: boolean;
244
273
  isFeatured: boolean;
245
274
  priority: number;
246
275
  publishedAt: unknown;
247
276
  createdAt: unknown;
248
277
  updatedAt: unknown;
278
+ featureImage: components["schemas"]["FeatureImage"] | null;
249
279
  };
250
280
  /** ListArticlesResponse */
251
281
  ListArticlesResponse: components["schemas"]["Article"][];
252
282
  /**
253
283
  * GetArticleResponse
254
- * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire.
284
+ * @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
285
  */
256
286
  GetArticleResponse: {
257
287
  id: string;
@@ -264,19 +294,21 @@ interface components {
264
294
  [key: string]: string;
265
295
  };
266
296
  excerpt: {
267
- [key: string]: string;
268
- } | null;
297
+ [key: string]: {
298
+ [key: string]: unknown;
299
+ };
300
+ };
269
301
  content: {
270
302
  [key: string]: unknown;
271
303
  } | null;
272
304
  tags: string[];
273
- featuredImageId: string | null;
274
305
  isActive: boolean;
275
306
  isFeatured: boolean;
276
307
  priority: number;
277
308
  publishedAt: unknown;
278
309
  createdAt: unknown;
279
310
  updatedAt: unknown;
311
+ featureImage: components["schemas"]["FeatureImage"] | null;
280
312
  };
281
313
  /** PatchArticleRequest */
282
314
  PatchArticleRequest: {
@@ -287,20 +319,21 @@ interface components {
287
319
  [key: string]: string;
288
320
  };
289
321
  excerpt?: {
290
- [key: string]: string;
322
+ [key: string]: string | {
323
+ [key: string]: unknown;
324
+ };
291
325
  };
292
326
  content?: {
293
327
  [key: string]: unknown;
294
328
  };
295
329
  tags?: string[];
296
- featuredImageId?: string | null;
297
330
  isActive?: boolean;
298
331
  isFeatured?: boolean;
299
332
  priority?: number;
300
333
  };
301
334
  /**
302
335
  * PatchArticleResponse
303
- * @description A venue's article. `content` is a TipTap JSON document; treat it as opaque on the wire.
336
+ * @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
337
  */
305
338
  PatchArticleResponse: {
306
339
  id: string;
@@ -313,19 +346,38 @@ interface components {
313
346
  [key: string]: string;
314
347
  };
315
348
  excerpt: {
316
- [key: string]: string;
317
- } | null;
349
+ [key: string]: {
350
+ [key: string]: unknown;
351
+ };
352
+ };
318
353
  content: {
319
354
  [key: string]: unknown;
320
355
  } | null;
321
356
  tags: string[];
322
- featuredImageId: string | null;
323
357
  isActive: boolean;
324
358
  isFeatured: boolean;
325
359
  priority: number;
326
360
  publishedAt: unknown;
327
361
  createdAt: unknown;
328
362
  updatedAt: unknown;
363
+ featureImage: components["schemas"]["FeatureImage"] | null;
364
+ };
365
+ /** UploadFeatureImageRequest */
366
+ UploadFeatureImageRequest: {
367
+ /** @description Image file (multipart/form-data field) */
368
+ file: unknown;
369
+ };
370
+ /**
371
+ * PatchFeatureImageRequest
372
+ * @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`.
373
+ */
374
+ PatchFeatureImageRequest: {
375
+ caption?: {
376
+ [key: string]: unknown;
377
+ };
378
+ alt?: {
379
+ [key: string]: unknown;
380
+ };
329
381
  };
330
382
  /**
331
383
  * AddToBasketRequest
@@ -1208,6 +1260,19 @@ type ListArticlesResponse = schemas['ListArticlesResponse'];
1208
1260
  type GetArticleResponse = schemas['GetArticleResponse'];
1209
1261
  type PatchArticleRequest = schemas['PatchArticleRequest'];
1210
1262
  type PatchArticleResponse = schemas['PatchArticleResponse'];
1263
+ type FeatureImage = schemas['FeatureImage'];
1264
+ type PatchFeatureImageRequest = schemas['PatchFeatureImageRequest'];
1265
+ /**
1266
+ * Args for `client.articles.uploadFeatureImage()`. The SDK accepts a
1267
+ * `Buffer` or `Uint8Array` payload + filename + content-type — it
1268
+ * builds the FormData internally so callers don't have to know about
1269
+ * multipart wire encoding.
1270
+ */
1271
+ interface UploadFeatureImageArgs {
1272
+ data: Buffer | Uint8Array;
1273
+ filename: string;
1274
+ contentType: string;
1275
+ }
1211
1276
  interface ListArticlesOptions {
1212
1277
  /** Only return articles whose `tags` array contains this value. */
1213
1278
  tag?: string;
@@ -2019,6 +2084,30 @@ declare class ArticlesResource extends BaseResource {
2019
2084
  * Returns the resulting article.
2020
2085
  */
2021
2086
  patch(idOrAccessor: string, body: PatchArticleRequest): Promise<Article>;
2087
+ /**
2088
+ * Read the article's resolved feature image — asset id, public URL,
2089
+ * matched locale, plus the FULL per-locale caption + alt records.
2090
+ * Returns null when the article has no feature image yet (the wire
2091
+ * 404 is mapped here for ergonomic null-checking on the caller side).
2092
+ */
2093
+ getFeatureImage(idOrAccessor: string, options?: {
2094
+ locale?: string;
2095
+ }): Promise<FeatureImage | null>;
2096
+ /**
2097
+ * Upload a new feature image. Replaces any existing feature image
2098
+ * for the venue's primary locale (the previous one is demoted to
2099
+ * `role='inline'`). The SDK builds the multipart body internally —
2100
+ * pass a Buffer/Uint8Array, the original filename, and the MIME
2101
+ * type.
2102
+ */
2103
+ uploadFeatureImage(idOrAccessor: string, file: UploadFeatureImageArgs): Promise<FeatureImage>;
2104
+ /**
2105
+ * Update per-locale caption / alt on the article's feature image.
2106
+ * Locale-keyed merge — `{ caption: { en: '…' } }` does not touch
2107
+ * `de`. Plain-string locale values are server-side wrapped into
2108
+ * minimal TipTap docs (the storage shape).
2109
+ */
2110
+ patchFeatureImage(idOrAccessor: string, body: PatchFeatureImageRequest): Promise<FeatureImage>;
2022
2111
  }
2023
2112
 
2024
2113
  declare class BasketsResource extends BaseResource {
@@ -2904,4 +2993,4 @@ declare class Order3000Client {
2904
2993
  }
2905
2994
 
2906
2995
  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 };
2996
+ 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 {