@sayren/storefront-sdk 0.20.7 → 0.20.8

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.
@@ -1,4 +1,4 @@
1
- import { Mt as ApiError, t as createStorefrontClient } from "../client-Dn_JdIqv.mjs";
1
+ import { t as createStorefrontClient, zt as ApiError } from "../client-S_gOAeBM.mjs";
2
2
  //#region src/auth/index.ts
3
3
  /** 소셜 로그인 실패 — 구매자가 취소했거나(`access_denied`) state가 맞지 않는다 */
4
4
  var IdpCallbackError = class extends Error {
@@ -21,6 +21,7 @@ function openUnion(known) {
21
21
  requiresShipping: value.requiresShipping
22
22
  }))]);
23
23
  }
24
+ const methodsViewSchema = z.array(z.string()).optional().describe("고를 수 있는 이행 방식(이슈 #115). 현재 값은 `CARRIER`(택배)·`DIRECT`(직접 배달)·`PICKUP`(방문 수령)·`PROVIDED`(제공 처리)이고 값이 추가될 수 있어 문자열로 받는다. 첫 값이 기본이다. 서버는 항상 싣는다");
24
25
  const requiresShippingDescription = "택배 배송이 필요한가. false면 배송비가 없고 주문서가 배송지를 받지 않는다";
25
26
  /** 상품 카드(목록·찜)의 이행 — 유형과 배송 필요 여부만. 배송비·환불 정책은 상세에서 본다 */
26
27
  const productCardFulfillmentSchema = z.object({
@@ -38,29 +39,70 @@ const productFulfillmentViewSchema = openUnion(z.discriminatedUnion("type", [z.o
38
39
  estimatedDays: z.string().describe("예상 배송 기간 안내 문구"),
39
40
  returnDeliveryFee: z.number().int().describe("단순 변심 반품 배송비(유효 환불 정책). 원 단위"),
40
41
  exchangeDeliveryFee: z.number().int().describe("단순 변심 교환 배송비(유효 환불 정책). 원 단위")
41
- })
42
+ }),
43
+ methods: methodsViewSchema
42
44
  }), z.object({
43
45
  type: z.literal("MANUAL"),
44
- requiresShipping: z.literal(false)
46
+ requiresShipping: z.literal(false),
47
+ methods: methodsViewSchema
45
48
  })])).describe("상품 이행. `type`이 유형이고 같은 이름의 키가 유형별 안내다. 값이 추가될 수 있어 SDK는 모르는 유형을 `OTHER`로 읽는다");
46
49
  /** 장바구니 줄·주문서 줄의 이행 — 주문서 줄은 주문서 시점 스냅샷이다 */
47
50
  const lineFulfillmentSchema = z.object({
48
51
  type: z.string().describe("상품 유형. 값이 추가될 수 있어 문자열로 받는다"),
49
52
  requiresShipping: z.boolean().describe(requiresShippingDescription),
53
+ method: z.string().optional().describe("이행 방식(이슈 #115). 주문서 줄은 고른 방식, 장바구니 줄은 기본 방식이다. 값이 추가될 수 있어 문자열로 받는다"),
50
54
  withdrawalRestricted: z.boolean().optional().describe("**Deprecated** — 항상 false다. 청약철회 제한 기능을 없앴고(이슈 #48) storefront-sdk 0.15 이하 호환으로만 싣는다. 게시된 스토어프론트가 0.16 이상으로 넘어간 뒤 다음 릴리스에서 뺀다")
51
55
  });
56
+ /** 픽업 장소 — 방문 수령(`PICKUP`) 주문서에서 고른다 */
57
+ const pickupLocationViewSchema = z.object({
58
+ locationId: z.string(),
59
+ name: z.string(),
60
+ address: z.string(),
61
+ phone: z.string().nullable(),
62
+ hours: z.string().nullable().describe("수령 가능 시간 안내")
63
+ });
64
+ const snapshotMethodSchema = z.string().optional().describe("주문 시점 이행 방식(이슈 #115). 값이 추가될 수 있어 문자열로 받는다. `requiresShipping`은 유형 규칙이고, 방문 수령(`PICKUP`)이면 배송지가 없다");
65
+ const snapshotPickupSchema = pickupLocationViewSchema.optional().describe("방문 수령에서 고른 장소(주문 시점 값). 없으면 생략");
52
66
  /**
53
67
  * 내 주문 주문상품의 주문 시점 이행 스냅샷. 상품을 나중에 고쳐도 바뀌지 않는다. 제공 기록(제공 시각·판매자 안내)은
54
68
  * 주문상품의 `fulfillment`다.
55
69
  */
56
70
  const myOrderItemFulfillmentSnapshotSchema = openUnion(z.discriminatedUnion("type", [z.object({
57
71
  type: z.literal("SHIPPING"),
58
- requiresShipping: z.literal(true)
72
+ requiresShipping: z.literal(true),
73
+ method: snapshotMethodSchema,
74
+ pickupLocation: snapshotPickupSchema
59
75
  }), z.object({
60
76
  type: z.literal("MANUAL"),
61
- requiresShipping: z.literal(false)
77
+ requiresShipping: z.literal(false),
78
+ method: snapshotMethodSchema,
79
+ pickupLocation: snapshotPickupSchema
62
80
  })])).describe("주문 시점 이행 스냅샷. 값이 추가될 수 있어 SDK는 모르는 유형을 `OTHER`로 읽는다");
63
81
  //#endregion
82
+ //#region src/schemas/stay.ts
83
+ /**
84
+ * 숙박 기간·날짜별 달력(이슈 #118) — 날짜별 재고 상품(상품 상세 `inventoryMode: "DATED"`)은 담기·바로 구매에 기간을 함께 보내고,
85
+ * 가격은 박마다 달력의 가격을 더한 값이다. 날짜는 한국 날짜 `YYYY-MM-DD`다.
86
+ */
87
+ const stayRequestSchema = z.object({
88
+ checkIn: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
89
+ checkOut: z.string().regex(/^\d{4}-\d{2}-\d{2}$/)
90
+ }).describe("숙박 기간(날짜별 재고 상품만). 체크인 날부터 체크아웃 전날까지 박마다 재고·가격을 본다. 최대 30박. 날짜별 재고 상품에 빠지면 400 `STAY_REQUIRED`, 다른 상품에 주면 400 `STAY_NOT_APPLICABLE`, 재고가 없는 날이 있으면 409 `DATES_UNAVAILABLE`");
91
+ const stayViewSchema = z.object({
92
+ checkIn: z.string(),
93
+ checkOut: z.string(),
94
+ nights: z.array(z.object({
95
+ date: z.string(),
96
+ price: z.number().int()
97
+ })).describe("박마다 날짜·가격(객실 1개 기준). 합이 줄 단가다")
98
+ });
99
+ /** 구매자 달력 한 칸 — 재고 수는 보이지 않고 예약 가능 여부만 */
100
+ const calendarDayViewSchema = z.object({
101
+ date: z.string(),
102
+ available: z.boolean(),
103
+ price: z.number().int().describe("그날 가격(원)")
104
+ });
105
+ //#endregion
64
106
  //#region src/schemas/product-options.ts
65
107
  /**
66
108
  * 추가 선택·직접 입력 (이슈 #59) — 상품 상세의 옵션 표시, 장바구니 담기·바로 구매 요청, 줄 스냅샷의 공통 모양.
@@ -83,9 +125,39 @@ const customInputViewSchema = z.object({
83
125
  label: z.string().describe("항목명"),
84
126
  placeholder: z.string().nullable().describe("입력 안내. 없으면 null"),
85
127
  maxLength: z.number().int().describe("최대 글자 수"),
86
- required: z.boolean()
128
+ required: z.boolean(),
129
+ key: z.string().nullable().optional().describe("고정 키. 없으면 null"),
130
+ type: z.string().optional().describe("입력 타입. 현재 값은 `text`·`number`(정수)·`select`·`date`(`YYYY-MM-DD`, 한국 날짜)·`datetime`(오프셋 있는 ISO 8601)·`image`(업로드 주소 목록, `maxLength`가 최대 장수)이고 값이 추가될 수 있어 문자열로 받는다. 없으면 `text`"),
131
+ options: z.array(z.string()).nullable().optional().describe("`select`의 선택지. 그 밖의 타입은 null")
87
132
  });
88
133
  /**
134
+ * 직접 입력값을 타입대로 검사하고 저장할 모양으로 바꾼다(정규화 뒤 값). 서버 판정(400 `CUSTOM_INPUT_INVALID`)과 스토어프론트
135
+ * 입력 검사가 이 함수 하나를 쓴다. 모르는 타입은 `text`로 본다. 맞지 않으면 null
136
+ */
137
+ function parseCustomInputValue(type, options, raw) {
138
+ const value = normalizeCustomInputValue(raw);
139
+ switch (type) {
140
+ case "number": return /^-?\d{1,15}$/.test(value) ? String(Number(value)) : null;
141
+ case "select": return options?.includes(value) ? value : null;
142
+ case "date": {
143
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value)) return null;
144
+ const date = /* @__PURE__ */ new Date(`${value}T00:00:00Z`);
145
+ return !Number.isNaN(date.getTime()) && date.toISOString().slice(0, 10) === value ? value : null;
146
+ }
147
+ case "image": {
148
+ const urls = value.split(/\s+/).filter(Boolean);
149
+ if (urls.length === 0 || !urls.every((url) => /^https:\/\/\S+$/.test(url))) return null;
150
+ return [...new Set(urls)].join("\n");
151
+ }
152
+ case "datetime": {
153
+ if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}(\.\d{1,3})?)?(Z|[+-]\d{2}:\d{2})$/.test(value)) return null;
154
+ const time = new Date(value);
155
+ return Number.isNaN(time.getTime()) ? null : time.toISOString();
156
+ }
157
+ default: return value;
158
+ }
159
+ }
160
+ /**
89
161
  * 직접 입력값 정규화 — NFC로 모으고, 제어 문자(C0·C1·줄바꿈·줄·문단 구분자)는 공백으로, 제로폭·양방향 제어 문자는 지운 뒤
90
162
  * 앞뒤 공백을 지운다. 서버가 저장하는 값이 이것이다. 빈 문자열이면 입력하지 않은 것으로 본다.
91
163
  * (양방향 제어 문자를 두면 셀러 주문 화면의 각인 문구가 뒤집혀 보이게 할 수 있다.)
@@ -113,7 +185,8 @@ const addonSelectionSchema = z.object({
113
185
  /** 요청의 추가 선택·직접 입력 필드 — 담기·장바구니 수정·바로 구매가 같은 이름을 쓴다 */
114
186
  const lineSelectionRequestShape = {
115
187
  addons: z.array(addonSelectionSchema).max(20).optional().describe("고른 추가 선택(옵션명마다 하나, 고르지 않은 옵션명은 빼고 보낸다). 필수 옵션명을 빼면 400 `ADDON_OPTION_REQUIRED`, 없거나 꺼진 값이거나 한 옵션명에서 둘을 고르면 400 `ADDON_OPTION_NOT_FOUND`"),
116
- customInputs: z.array(customInputEntrySchema).max(20).optional().describe("직접 입력값. 필수 항목을 비우면 400 `CUSTOM_INPUT_REQUIRED`, 최대 글자 수를 넘으면 400 `CUSTOM_INPUT_TOO_LONG`, 없는 항목이면 400 `CUSTOM_INPUT_NOT_FOUND`")
188
+ customInputs: z.array(customInputEntrySchema).max(20).optional().describe("직접 입력값. 필수 항목을 비우면 400 `CUSTOM_INPUT_REQUIRED`, 최대 글자 수를 넘으면 400 `CUSTOM_INPUT_TOO_LONG`, 없는 항목이면 400 `CUSTOM_INPUT_NOT_FOUND`, 항목 타입에 맞지 않으면 400 `CUSTOM_INPUT_INVALID`"),
189
+ stay: stayRequestSchema.optional()
117
190
  };
118
191
  /** 줄의 옵션 선택 스냅샷 한 칸 — 조합 옵션은 옵션명마다 한 칸이고 추가금이 0이다(조합 추가금은 단가에 들어 있다) */
119
192
  const optionSelectionViewSchema = z.object({
@@ -124,13 +197,21 @@ const optionSelectionViewSchema = z.object({
124
197
  });
125
198
  const customInputValueViewSchema = z.object({
126
199
  label: z.string().describe("항목명"),
127
- value: z.string().describe("구매자가 적은 값")
200
+ value: z.string().describe("구매자가 적은 값(타입별 정규화 뒤 값, `datetime`은 UTC ISO 8601)"),
201
+ key: z.string().nullable().optional().describe("항목의 고정 키(주문 시점). 없으면 null"),
202
+ type: z.string().optional().describe("항목의 입력 타입(주문 시점). 없으면 `text`")
128
203
  });
129
204
  /** 응답 줄의 표시 필드 — 장바구니·주문서·주문상품이 같은 이름을 쓴다 */
130
205
  const lineSelectionResponseShape = {
131
206
  optionSelections: z.array(optionSelectionViewSchema).optional().default([]).describe("옵션 선택(조합 옵션 + 추가 선택). 옵션이 없으면 빈 배열. 서버는 항상 싣는다"),
132
- customInputs: z.array(customInputValueViewSchema).optional().default([]).describe("직접 입력값(항목명과 값). 없으면 빈 배열. 서버는 항상 싣는다")
207
+ customInputs: z.array(customInputValueViewSchema).optional().default([]).describe("직접 입력값(항목명과 값). 없으면 빈 배열. 서버는 항상 싣는다"),
208
+ stay: stayViewSchema.optional().describe("숙박 기간과 박별 가격(날짜별 재고 상품만, 이슈 #118)")
133
209
  };
210
+ /** 주문 입력 이미지 업로드 자리 요청(#115 E4) — 파일명은 확장자만 쓰인다 */
211
+ const orderInputUploadRequestSchema = z.object({
212
+ filename: z.string().min(1).max(200),
213
+ size: z.number().int().positive().optional().describe("바이트. 주면 상한을 넘을 때 미리 거절한다")
214
+ });
134
215
  //#endregion
135
216
  //#region src/schemas/coupon.ts
136
217
  /**
@@ -284,7 +365,14 @@ const createCheckoutRequestSchema = z.object({
284
365
  optionId: z.string().optional(),
285
366
  quantity: z.number().int().min(1),
286
367
  ...lineSelectionRequestShape
287
- }).optional()
368
+ }).optional(),
369
+ fulfillmentMethod: z.enum([
370
+ "CARRIER",
371
+ "DIRECT",
372
+ "PICKUP",
373
+ "PROVIDED"
374
+ ]).optional().describe("이행 방식(이슈 #115). 모든 줄에 같은 방식을 적용하고, 상품 `fulfillment.methods`에 없는 줄이 있으면 400 `FULFILLMENT_METHOD_NOT_ALLOWED`다. 생략하면 줄마다 상품 허용 방식의 첫 값이다. 방문 수령(`PICKUP`)은 배송지·배송비가 없다"),
375
+ pickupLocationId: z.string().optional().describe("방문 수령 장소(`GET /pickup-locations`). 방식이 `PICKUP`이고 상점에 픽업 장소가 있으면 필수(400 `PICKUP_LOCATION_REQUIRED`), 없거나 쓰지 않는 장소면 400 `PICKUP_LOCATION_NOT_FOUND`. 다른 방식에 주면 400 `PICKUP_LOCATION_NOT_APPLICABLE`")
288
376
  }).refine((value) => value.cartItemIds ? !value.directItem : !!value.directItem, { message: "cartItemIds와 directItem 중 하나만 전달해야 합니다" });
289
377
  /** 지역 추가 배송비 구분 — 우편번호로 판정한다 */
290
378
  const remoteAreaSchema = z.enum([
@@ -622,4 +710,4 @@ const paymentMessageSchema = z.object({
622
710
  orderId: z.string().optional()
623
711
  });
624
712
  //#endregion
625
- export { customInputViewSchema as $, retryPaymentRequestSchema as A, couponBenefitViewSchema as B, paymentOptionSchema as C, remoteAreaSchema as D, pgProviderSchema as E, applicableCouponSchema as F, storefrontCouponListQuerySchema as G, myCouponListQuerySchema as H, checkoutPricingRequestSchema as I, addonGroupViewSchema as J, storefrontCouponSchema as K, checkoutPricingSchema as L, startPaymentRequestSchema as M, MAX_COUPONS_PER_CHECKOUT as N, residentNumberLike as O, MIN_PAYMENT_AMOUNT as P, customInputValueViewSchema as Q, couponApplicationListSchema as R, paymentOptionListSchema as S, paymentStatusSchema as T, myCouponSchema as U, couponResultSchema as V, pricingAmountsSchema as W, customInputEntrySchema as X, addonSelectionSchema as Y, customInputLength as Z, guestInfoSchema as _, availablePaymentOptionSchema as a, myOrderItemFulfillmentSnapshotSchema as at, paymentMethodSchema as b, cashReceiptRequestSchema as c, checkoutSessionSchema as d, lineSelectionRequestShape as et, createCheckoutRequestSchema as f, easyPayProviderSchema as g, easyPayProviderResponseSchema as h, PAYMENT_STATUS_VALUES as i, lineFulfillmentSchema as it, shippingAddressInputSchema as j, responsePaymentMethodSchema as k, cashReceiptTypeSchema as l, deliveryQuoteSchema as m, PAYMENT_RESULT_VALUES as n, normalizeCustomInputValue as nt, cashReceiptAvailable as o, productCardFulfillmentSchema as ot, deliveryQuoteRequestSchema as p, storefrontCouponTargetSchema as q, PAYMENT_START_STATUS_VALUES as r, optionSelectionViewSchema as rt, cashReceiptIdentityTypeOf as s, productFulfillmentViewSchema as st, CASH_RECEIPT_METHODS as t, lineSelectionResponseShape as tt, checkoutDeliverySchema as u, paymentFailureCategorySchema as v, paymentStartSchema as w, paymentOptionKey as x, paymentMessageSchema as y, couponApplicationSchema as z };
713
+ export { customInputViewSchema as $, retryPaymentRequestSchema as A, couponBenefitViewSchema as B, paymentOptionSchema as C, remoteAreaSchema as D, pgProviderSchema as E, applicableCouponSchema as F, storefrontCouponListQuerySchema as G, myCouponListQuerySchema as H, checkoutPricingRequestSchema as I, addonGroupViewSchema as J, storefrontCouponSchema as K, checkoutPricingSchema as L, startPaymentRequestSchema as M, MAX_COUPONS_PER_CHECKOUT as N, residentNumberLike as O, MIN_PAYMENT_AMOUNT as P, customInputValueViewSchema as Q, couponApplicationListSchema as R, paymentOptionListSchema as S, paymentStatusSchema as T, myCouponSchema as U, couponResultSchema as V, pricingAmountsSchema as W, customInputEntrySchema as X, addonSelectionSchema as Y, customInputLength as Z, guestInfoSchema as _, availablePaymentOptionSchema as a, parseCustomInputValue as at, paymentMethodSchema as b, cashReceiptRequestSchema as c, stayViewSchema as ct, checkoutSessionSchema as d, pickupLocationViewSchema as dt, lineSelectionRequestShape as et, createCheckoutRequestSchema as f, productCardFulfillmentSchema as ft, easyPayProviderSchema as g, easyPayProviderResponseSchema as h, PAYMENT_STATUS_VALUES as i, orderInputUploadRequestSchema as it, shippingAddressInputSchema as j, responsePaymentMethodSchema as k, cashReceiptTypeSchema as l, lineFulfillmentSchema as lt, deliveryQuoteSchema as m, PAYMENT_RESULT_VALUES as n, normalizeCustomInputValue as nt, cashReceiptAvailable as o, calendarDayViewSchema as ot, deliveryQuoteRequestSchema as p, productFulfillmentViewSchema as pt, storefrontCouponTargetSchema as q, PAYMENT_START_STATUS_VALUES as r, optionSelectionViewSchema as rt, cashReceiptIdentityTypeOf as s, stayRequestSchema as st, CASH_RECEIPT_METHODS as t, lineSelectionResponseShape as tt, checkoutDeliverySchema as u, myOrderItemFulfillmentSnapshotSchema as ut, paymentFailureCategorySchema as v, paymentStartSchema as w, paymentOptionKey as x, paymentMessageSchema as y, couponApplicationSchema as z };
@@ -1,5 +1,5 @@
1
1
  import { a as ANALYTICS_VISITOR_HEADER, r as ANALYTICS_SESSION_HEADER } from "./analytics-CgD70OqH.mjs";
2
- import { $ as customInputViewSchema, A as retryPaymentRequestSchema, F as applicableCouponSchema, I as checkoutPricingRequestSchema, J as addonGroupViewSchema, K as storefrontCouponSchema, L as checkoutPricingSchema, M as startPaymentRequestSchema, T as paymentStatusSchema, U as myCouponSchema, at as myOrderItemFulfillmentSnapshotSchema, d as checkoutSessionSchema, et as lineSelectionRequestShape, f as createCheckoutRequestSchema, h as easyPayProviderResponseSchema, it as lineFulfillmentSchema, k as responsePaymentMethodSchema, m as deliveryQuoteSchema, ot as productCardFulfillmentSchema, p as deliveryQuoteRequestSchema, st as productFulfillmentViewSchema, tt as lineSelectionResponseShape, w as paymentStartSchema } from "./checkout-Bt6j2eDw.mjs";
2
+ import { $ as customInputViewSchema, A as retryPaymentRequestSchema, F as applicableCouponSchema, I as checkoutPricingRequestSchema, J as addonGroupViewSchema, K as storefrontCouponSchema, L as checkoutPricingSchema, M as startPaymentRequestSchema, T as paymentStatusSchema, U as myCouponSchema, d as checkoutSessionSchema, dt as pickupLocationViewSchema, et as lineSelectionRequestShape, f as createCheckoutRequestSchema, ft as productCardFulfillmentSchema, h as easyPayProviderResponseSchema, k as responsePaymentMethodSchema, lt as lineFulfillmentSchema, m as deliveryQuoteSchema, ot as calendarDayViewSchema, p as deliveryQuoteRequestSchema, pt as productFulfillmentViewSchema, tt as lineSelectionResponseShape, ut as myOrderItemFulfillmentSnapshotSchema, w as paymentStartSchema } from "./checkout-BjJ4Efbn.mjs";
3
3
  import { z } from "zod";
4
4
  //#region src/http.ts
5
5
  /** 표준 엔벨로프의 $.error 상세 */
@@ -353,9 +353,11 @@ const productDetailSchema = productCardSchema.extend({
353
353
  /** 값 이름을 " / "로 이은 표시명. 옵션 없으면 "" */
354
354
  name: z.string(),
355
355
  additionalPrice: z.number().int(),
356
- soldOut: z.boolean()
356
+ soldOut: z.boolean(),
357
+ attributes: z.record(z.string(), z.string()).optional().describe("조합 속성(이슈 #115, 예: 회차 일시 `showAt`). 없으면 생략")
357
358
  })),
358
359
  addonGroups: z.array(addonGroupViewSchema).optional().default([]).describe("추가 선택 옵션명(이슈 #59). 배열 순서가 표시 순서다. 담기·바로 구매의 `addons`로 `{groupId, valueId}`를 보낸다. 없으면 빈 배열. 서버는 항상 싣는다"),
360
+ inventoryMode: z.string().optional().describe("재고 방식(이슈 #118). `DATED`면 날짜별 재고 상품이다 — 달력(`GET /products/{id}/calendar`)으로 날짜를 고르고 담기·바로 구매에 `stay`를 보낸다. 없으면 일반 상품"),
359
361
  customInputs: z.array(customInputViewSchema).optional().default([]).describe("직접 입력 항목(이슈 #59). 배열 순서가 표시 순서다. 담기·바로 구매의 `customInputs`로 값을 보낸다. 없으면 빈 배열. 서버는 항상 싣는다"),
360
362
  fulfillment: productFulfillmentViewSchema,
361
363
  returnPeriodDays: z.number().int().describe("반품·교환을 받는 기간(수령·제공일부터 일수)"),
@@ -516,6 +518,74 @@ const myClaimSchema = z.object({
516
518
  completedAt: z.string().nullable()
517
519
  });
518
520
  //#endregion
521
+ //#region src/schemas/commerce-flow.ts
522
+ /**
523
+ * 커머스 플로우(이슈 #115) — 구매자가 보는 주문상품의 지금 상태와 할 수 있는 행동. 화면은 이 값만 그리고 상태 이름(`key`)으로
524
+ * 분기하지 않는다. 행동 키·필드 키·꺼진 이유는 열린 문자열이다(모르는 값도 파싱한다). 공개 상태(`coreStatus`)만 닫힌 값이다.
525
+ */
526
+ const flowInputFieldSchema = z.object({
527
+ key: z.string(),
528
+ type: z.string().describe("text · number · select · date · datetime · image (늘어날 수 있다)"),
529
+ required: z.boolean(),
530
+ label: z.string(),
531
+ maxLength: z.number().int().optional(),
532
+ maxFiles: z.number().int().optional(),
533
+ options: z.array(z.union([z.string(), z.number()])).optional()
534
+ });
535
+ const flowActionSchema = z.object({
536
+ key: z.string(),
537
+ label: z.string().describe("버튼에 쓸 이름"),
538
+ mode: z.enum([
539
+ "INSTANT",
540
+ "REQUEST",
541
+ "VIEW"
542
+ ]),
543
+ enabled: z.boolean(),
544
+ disabled: z.object({
545
+ reason: z.string(),
546
+ message: z.string().optional()
547
+ }).optional(),
548
+ availableUntil: z.string().optional().describe("이 시각까지만 할 수 있다(ISO 8601)"),
549
+ subflow: z.string().optional().describe("취소·반품·교환 요청처럼 하위 플로우를 시작하는 행동. 지금은 클레임 API(`POST /me/order-items/{id}/claims`)로 실행한다"),
550
+ input: z.array(flowInputFieldSchema).optional().describe("받는 입력 폼"),
551
+ partialQuantity: z.union([z.boolean(), z.literal("UNIT")]).optional()
552
+ });
553
+ /** 커스텀 필드 값 — 문자열(날짜·일시는 ISO 8601)·숫자·참거짓·null, 수량 단위 필드는 문자열 배열 */
554
+ const flowFieldValueSchema = z.union([
555
+ z.string(),
556
+ z.number(),
557
+ z.boolean(),
558
+ z.null(),
559
+ z.array(z.string())
560
+ ]);
561
+ const flowStateSchema = z.object({
562
+ key: z.string(),
563
+ label: z.string().describe("구매자에게 보여 줄 상태 이름"),
564
+ coreStatus: orderItemStatusSchema.optional(),
565
+ message: z.string().optional().describe("구매자 안내문"),
566
+ enteredAt: z.string(),
567
+ deadlineAt: z.string().optional().describe("가장 가까운 기한(ISO 8601)"),
568
+ attachments: z.array(z.string()).optional().describe("가장 최근 행동이 붙인 첨부 주소(시안 등, #115). 없으면 생략"),
569
+ progress: z.boolean().optional(),
570
+ fields: z.record(z.string(), flowFieldValueSchema).describe("구매자 공개 범위의 커스텀 필드")
571
+ });
572
+ const flowActionRequestSchema = z.object({ input: z.record(z.string(), z.unknown()).optional() });
573
+ /** 비회원 행동 — 비회원 주문 조회와 같은 확인(연락처·주문 조회 비밀번호)을 함께 보낸다 */
574
+ const guestFlowActionRequestSchema = flowActionRequestSchema.extend({
575
+ phone: z.string(),
576
+ orderPassword: z.string()
577
+ });
578
+ const flowActionResultSchema = z.object({
579
+ status: z.literal("COMPLETED"),
580
+ flowState: flowStateSchema,
581
+ actions: z.array(flowActionSchema),
582
+ affectedOrderItemIds: z.array(z.string()),
583
+ claim: z.object({
584
+ claimId: z.string(),
585
+ claimNo: z.string().nullable()
586
+ }).optional().describe("취소·반품·교환 행동(하위 플로우 `core.claim.*`)이 접수한 클레임(#115). 클레임 API(`POST /me/order-items/{id}/claims`)와 같은 접수다. 다른 행동은 생략")
587
+ });
588
+ //#endregion
519
589
  //#region src/schemas/consent.ts
520
590
  /**
521
591
  * 동의 종류 — 이용약관(`TERMS`)·개인정보 수집이용(`PRIVACY`)은 가입 필수, 마케팅 수신(`MARKETING`)은 선택이다.
@@ -711,7 +781,9 @@ const myOrderItemSchema = z.object({
711
781
  }).nullable().optional().default(null).describe("배송 없는 상품의 제공 기록(이슈 #48). 제공 전이거나 배송 상품이면 null이다. 배송 없는 상품의 `DELIVERED`는 제공 완료로 표시한다. 서버는 항상 싣는다"),
712
782
  claimStatus: z.string().nullable(),
713
783
  reviewWritten: z.boolean(),
714
- autoDecisionDate: z.string().nullable()
784
+ autoDecisionDate: z.string().nullable(),
785
+ flowState: flowStateSchema.optional().describe("주문 플로우의 지금 상태(이슈 #115). 플로우가 없는 주문상품은 없다"),
786
+ actions: z.array(flowActionSchema).optional().describe("지금 할 수 있는 행동. 화면은 이 목록으로 버튼을 그린다(상태 이름으로 분기하지 않는다)")
715
787
  });
716
788
  /**
717
789
  * 주문 응답의 배송지 — 결제 요청 시 저장된 스냅샷. 요청 스키마(`shippingAddressInputSchema`)와 분리한 응답 스키마라
@@ -1051,6 +1123,11 @@ get: () => http.request("GET", "/store", storefrontStoreSchema) },
1051
1123
  /** 상품 리뷰 목록 — `variantId`로 옵션(조합)별 리뷰만 받는다(상품 상세 `variants[].variantId`) */
1052
1124
  listProductReviews: (productId, params) => http.request("GET", path`/products/${productId}/reviews`, reviewPageSchema, { query: params }),
1053
1125
  listProductInquiries: (productId, params) => http.request("GET", path`/products/${productId}/inquiries`, pageSchema(publicInquirySchema), { query: params }),
1126
+ /**
1127
+ * `GET /products/{productId}/calendar` — 날짜별 재고 상품(상세 `inventoryMode: "DATED"`, 이슈 #118)의 날마다 예약 가능 여부·가격.
1128
+ * 기간은 포함이고 최대 120일이다. `variantId`를 생략하면 기본 조합이다
1129
+ */
1130
+ getProductCalendar: (productId, params) => http.request("GET", path`/products/${productId}/calendar`, z.array(calendarDayViewSchema), { query: params }),
1054
1131
  createInquiry: (productId, body) => http.requestVoid("POST", path`/products/${productId}/inquiries`, { body }),
1055
1132
  /** 노출 중인 컬렉션(노출 켜짐 + 기간 안) — 셀러가 정한 순서 */
1056
1133
  listCollections: (params) => http.request("GET", "/collections", pageSchema(storefrontCollectionSchema), { query: params }),
@@ -1064,6 +1141,8 @@ get: () => http.request("GET", "/store", storefrontStoreSchema) },
1064
1141
  /** 컬렉션 상품(판매 중만). `sort`를 생략하면 컬렉션의 기본 정렬이다 */
1065
1142
  listCollectionProducts: (slug, params) => http.request("GET", path`/collections/${slug}/products`, collectionProductPageSchema, { query: params })
1066
1143
  },
1144
+ /** `GET /pickup-locations` — 방문 수령 장소(이슈 #115). 주문서의 `pickupLocationId`로 고른다 */
1145
+ pickupLocations: { list: () => http.request("GET", "/pickup-locations", z.array(pickupLocationViewSchema)) },
1067
1146
  cart: {
1068
1147
  get: () => http.request("GET", "/cart", cartSchema),
1069
1148
  addItem: (body) => http.request("POST", "/cart/items", cartSchema, { body: addCartItemRequestSchema.parse(body) }),
@@ -1134,7 +1213,14 @@ get: () => http.request("GET", "/store", storefrontStoreSchema) },
1134
1213
  */
1135
1214
  getGuestOrder: (orderId, body) => http.request("POST", path`/guest/orders/${orderId}`, myOrderSchema, { body }),
1136
1215
  getDelivery: (orderItemId) => http.request("GET", path`/me/order-items/${orderItemId}/delivery`, deliveryTrackingSchema),
1137
- decidePurchase: (orderItemId) => http.requestVoid("POST", path`/me/order-items/${orderItemId}/purchase-decision`)
1216
+ decidePurchase: (orderItemId) => http.requestVoid("POST", path`/me/order-items/${orderItemId}/purchase-decision`),
1217
+ /**
1218
+ * `POST /me/order-items/{id}/actions/{key}` — 주문상품 `actions`에 켜진 행동을 실행한다(#115, 시안 승인 등).
1219
+ * 응답의 `flowState`·`actions`로 화면을 바로 바꾼다. 에러: 409 `ACTION_NOT_AVAILABLE`(`details.reason`)
1220
+ */
1221
+ act: (orderItemId, key, input = {}) => http.request("POST", path`/me/order-items/${orderItemId}/actions/${key}`, flowActionResultSchema, { body: flowActionRequestSchema.parse({ input }) }),
1222
+ /** 비회원 행동 — 비회원 주문 조회와 같은 연락처·비밀번호 확인과 시도 한도를 지난다 */
1223
+ guestAct: (orderId, orderItemId, key, body) => http.request("POST", path`/guest/orders/${orderId}/items/${orderItemId}/actions/${key}`, flowActionResultSchema, { body: guestFlowActionRequestSchema.parse(body) })
1138
1224
  },
1139
1225
  myClaims: {
1140
1226
  create: (orderItemId, body) => http.request("POST", path`/me/order-items/${orderItemId}/claims`, createClaimResultSchema, { body: createClaimRequestSchema.parse(body) }),
@@ -1194,4 +1280,4 @@ get: () => http.request("GET", "/store", storefrontStoreSchema) },
1194
1280
  };
1195
1281
  }
1196
1282
  //#endregion
1197
- export { categoryNodeSchema as $, wishlistAddResultSchema as A, withdrawRequestSchema as At, consentSourceSchema as B, orderShippingAddressSchema as C, idpTokenRequestSchema as Ct, memberAddressSchema as D, signupRequestSchema as Dt, memberAddressRequestSchema as E, memberIdentitiesSchema as Et, createCustomerInquiryRequestSchema as F, unwrapData as Ft, claimReturnAddressSchema as G, consentUpdateRequestSchema as H, customerInquiryCategorySchema as I, createClaimResultSchema as J, claimTypeSchema as K, customerInquirySchema as L, createInquiryResultSchema as M, ApiError as Mt, productInquiryCategorySchema as N, buildQuery as Nt, memberSchema as O, socialProviderSchema as Ot, publicInquirySchema as P, toApiError as Pt, parseOrderNo as Q, consentActionSchema as R, myOrderSchema as S, idpAuthorizeResponseSchema as St, trackingStageResponseSchema as T, loginRequestSchema as Tt, memberConsentsSchema as U, consentStateSchema as V, claimReasonSchema as W, commerceNumberField as X, myClaimSchema as Y, formatOrderNo as Z, memberPointEntrySchema as _, cartSchema as _t, myReviewSchema as a, productFacetsSchema as at, deliveryTrackingSchema as b, idpAgreementsSchema as bt, publicReviewSchema as c, storefrontCollectionDetailSchema as ct, reviewSummarySchema as d, claimStatusSchema as dt, collectionProductPageSchema as et, updateReviewRequestSchema as f, orderItemStatusSchema as ft, memberPointEntryPageSchema as g, cartItemSchema as gt, writableReviewSchema as h, addCartItemRequestSchema as ht, createReviewResultSchema as i, productDetailSchema as it, createInquiryRequestSchema as j, withdrawalBlockedDetailsSchema as jt, updateProfileRequestSchema as k, tokenPairSchema as kt, reviewImageUploadRequestSchema as l, storefrontCollectionListQuerySchema as lt, uploadTicketSchema as m, pageSchema as mt, storefrontStoreSchema as n, collectionProductSortSchema as nt, productReviewQuerySchema as o, productPageSchema as ot, updateReviewResultSchema as p, pageInfoSchema as pt, createClaimRequestSchema as q, createReviewRequestSchema as r, productCardSchema as rt, productReviewSortSchema as s, productSortSchema as st, createStorefrontClient as t, collectionProductQuerySchema as tt, reviewPageSchema as u, storefrontCollectionSchema as ut, memberPointsSchema as v, updateCartItemRequestSchema as vt, purchaseDecisionResultSchema as w, linkIdentityRequestSchema as wt, myOrderItemSchema as x, idpAuthorizeRequestSchema as xt, storefrontPointPolicySchema as y, anonymousSessionSchema as yt, consentKindSchema as z };
1283
+ export { claimTypeSchema as $, wishlistAddResultSchema as A, idpTokenRequestSchema as At, consentSourceSchema as B, buildQuery as Bt, orderShippingAddressSchema as C, cartItemSchema as Ct, memberAddressSchema as D, idpAgreementsSchema as Dt, memberAddressRequestSchema as E, anonymousSessionSchema as Et, createCustomerInquiryRequestSchema as F, socialProviderSchema as Ft, flowActionResultSchema as G, consentUpdateRequestSchema as H, unwrapData as Ht, customerInquiryCategorySchema as I, tokenPairSchema as It, flowInputFieldSchema as J, flowActionSchema as K, customerInquirySchema as L, withdrawRequestSchema as Lt, createInquiryResultSchema as M, loginRequestSchema as Mt, productInquiryCategorySchema as N, memberIdentitiesSchema as Nt, memberSchema as O, idpAuthorizeRequestSchema as Ot, publicInquirySchema as P, signupRequestSchema as Pt, claimReturnAddressSchema as Q, consentActionSchema as R, withdrawalBlockedDetailsSchema as Rt, myOrderSchema as S, addCartItemRequestSchema as St, trackingStageResponseSchema as T, updateCartItemRequestSchema as Tt, memberConsentsSchema as U, consentStateSchema as V, toApiError as Vt, flowActionRequestSchema as W, guestFlowActionRequestSchema as X, flowStateSchema as Y, claimReasonSchema as Z, memberPointEntrySchema as _, storefrontCollectionSchema as _t, myReviewSchema as a, parseOrderNo as at, deliveryTrackingSchema as b, pageInfoSchema as bt, publicReviewSchema as c, collectionProductQuerySchema as ct, reviewSummarySchema as d, productDetailSchema as dt, createClaimRequestSchema as et, updateReviewRequestSchema as f, productFacetsSchema as ft, memberPointEntryPageSchema as g, storefrontCollectionListQuerySchema as gt, writableReviewSchema as h, storefrontCollectionDetailSchema as ht, createReviewResultSchema as i, formatOrderNo as it, createInquiryRequestSchema as j, linkIdentityRequestSchema as jt, updateProfileRequestSchema as k, idpAuthorizeResponseSchema as kt, reviewImageUploadRequestSchema as l, collectionProductSortSchema as lt, uploadTicketSchema as m, productSortSchema as mt, storefrontStoreSchema as n, myClaimSchema as nt, productReviewQuerySchema as o, categoryNodeSchema as ot, updateReviewResultSchema as p, productPageSchema as pt, flowFieldValueSchema as q, createReviewRequestSchema as r, commerceNumberField as rt, productReviewSortSchema as s, collectionProductPageSchema as st, createStorefrontClient as t, createClaimResultSchema as tt, reviewPageSchema as u, productCardSchema as ut, memberPointsSchema as v, claimStatusSchema as vt, purchaseDecisionResultSchema as w, cartSchema as wt, myOrderItemSchema as x, pageSchema as xt, storefrontPointPolicySchema as y, orderItemStatusSchema as yt, consentKindSchema as z, ApiError as zt };