@sayren/storefront-sdk 0.20.7 → 0.20.9

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 { Bt as ApiError, t as createStorefrontClient } from "../client-vjq513VD.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,92 @@ 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
+ /**
589
+ * 주문 전체 행동 결과(#115) — 같은 행동을 주문의 주문상품마다 실행한다. 한 주문상품의 실패가 다른 주문상품을 되돌리지 않는다(부분 실행).
590
+ * 묶음 진행이면 한 번 실행이 묶음의 주문상품을 함께 움직인다(COMPLETED로 함께 나온다). 그 행동이 없는 주문상품은 SKIPPED다
591
+ */
592
+ const orderFlowActionResultSchema = z.object({
593
+ orderId: z.string(),
594
+ key: z.string(),
595
+ results: z.array(z.object({
596
+ orderItemId: z.string(),
597
+ status: z.enum([
598
+ "COMPLETED",
599
+ "SKIPPED",
600
+ "FAILED"
601
+ ]).describe("COMPLETED 실행 · SKIPPED 이 주문상품에는 그 행동이 없다 · FAILED 실행하다 거절됐다"),
602
+ reason: z.string().optional().describe("SKIPPED·FAILED의 이유 — 꺼진 이유(EXPIRED·CONDITION·NOT_IN_STATE) 또는 오류 코드"),
603
+ message: z.string().optional()
604
+ }))
605
+ });
606
+ //#endregion
519
607
  //#region src/schemas/consent.ts
520
608
  /**
521
609
  * 동의 종류 — 이용약관(`TERMS`)·개인정보 수집이용(`PRIVACY`)은 가입 필수, 마케팅 수신(`MARKETING`)은 선택이다.
@@ -711,7 +799,10 @@ const myOrderItemSchema = z.object({
711
799
  }).nullable().optional().default(null).describe("배송 없는 상품의 제공 기록(이슈 #48). 제공 전이거나 배송 상품이면 null이다. 배송 없는 상품의 `DELIVERED`는 제공 완료로 표시한다. 서버는 항상 싣는다"),
712
800
  claimStatus: z.string().nullable(),
713
801
  reviewWritten: z.boolean(),
714
- autoDecisionDate: z.string().nullable()
802
+ autoDecisionDate: z.string().nullable(),
803
+ flowState: flowStateSchema.optional().describe("주문 플로우의 지금 상태(이슈 #115). 플로우가 없는 주문상품은 없다"),
804
+ actions: z.array(flowActionSchema).optional().describe("지금 할 수 있는 행동. 화면은 이 목록으로 버튼을 그린다(상태 이름으로 분기하지 않는다)"),
805
+ flowBranches: z.array(flowStateSchema).optional().describe("진행 위치가 둘 이상(병렬 진행·하위 흐름)이면 각 위치의 상태. `flowState`는 그 가운데 가장 앞 단계다")
715
806
  });
716
807
  /**
717
808
  * 주문 응답의 배송지 — 결제 요청 시 저장된 스냅샷. 요청 스키마(`shippingAddressInputSchema`)와 분리한 응답 스키마라
@@ -728,6 +819,7 @@ const orderShippingAddressSchema = z.object({
728
819
  });
729
820
  const myOrderSchema = z.object({
730
821
  orderId: z.string(),
822
+ progressStatus: orderItemStatusSchema.optional().describe("진행 중 주문상품 가운데 가장 앞 단계(취소 제외, 모두 취소면 CANCELED, #115). 섞인 주문에서 아직 기다리는 단계다. 서버는 항상 싣는다"),
731
823
  orderNo: commerceNumberField("주문번호(이슈 #107) — 숫자 14자리, 생성 후 바뀌지 않습니다. 구매자 화면에는 `formatOrderNo`(4자리 하이픈)로 표시하십시오. 비회원 주문 조회 경로에도 쓸 수 있습니다"),
732
824
  orderedAt: z.string(),
733
825
  items: z.array(myOrderItemSchema),
@@ -1051,6 +1143,11 @@ get: () => http.request("GET", "/store", storefrontStoreSchema) },
1051
1143
  /** 상품 리뷰 목록 — `variantId`로 옵션(조합)별 리뷰만 받는다(상품 상세 `variants[].variantId`) */
1052
1144
  listProductReviews: (productId, params) => http.request("GET", path`/products/${productId}/reviews`, reviewPageSchema, { query: params }),
1053
1145
  listProductInquiries: (productId, params) => http.request("GET", path`/products/${productId}/inquiries`, pageSchema(publicInquirySchema), { query: params }),
1146
+ /**
1147
+ * `GET /products/{productId}/calendar` — 날짜별 재고 상품(상세 `inventoryMode: "DATED"`, 이슈 #118)의 날마다 예약 가능 여부·가격.
1148
+ * 기간은 포함이고 최대 120일이다. `variantId`를 생략하면 기본 조합이다
1149
+ */
1150
+ getProductCalendar: (productId, params) => http.request("GET", path`/products/${productId}/calendar`, z.array(calendarDayViewSchema), { query: params }),
1054
1151
  createInquiry: (productId, body) => http.requestVoid("POST", path`/products/${productId}/inquiries`, { body }),
1055
1152
  /** 노출 중인 컬렉션(노출 켜짐 + 기간 안) — 셀러가 정한 순서 */
1056
1153
  listCollections: (params) => http.request("GET", "/collections", pageSchema(storefrontCollectionSchema), { query: params }),
@@ -1064,6 +1161,8 @@ get: () => http.request("GET", "/store", storefrontStoreSchema) },
1064
1161
  /** 컬렉션 상품(판매 중만). `sort`를 생략하면 컬렉션의 기본 정렬이다 */
1065
1162
  listCollectionProducts: (slug, params) => http.request("GET", path`/collections/${slug}/products`, collectionProductPageSchema, { query: params })
1066
1163
  },
1164
+ /** `GET /pickup-locations` — 방문 수령 장소(이슈 #115). 주문서의 `pickupLocationId`로 고른다 */
1165
+ pickupLocations: { list: () => http.request("GET", "/pickup-locations", z.array(pickupLocationViewSchema)) },
1067
1166
  cart: {
1068
1167
  get: () => http.request("GET", "/cart", cartSchema),
1069
1168
  addItem: (body) => http.request("POST", "/cart/items", cartSchema, { body: addCartItemRequestSchema.parse(body) }),
@@ -1134,7 +1233,21 @@ get: () => http.request("GET", "/store", storefrontStoreSchema) },
1134
1233
  */
1135
1234
  getGuestOrder: (orderId, body) => http.request("POST", path`/guest/orders/${orderId}`, myOrderSchema, { body }),
1136
1235
  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`)
1236
+ decidePurchase: (orderItemId) => http.requestVoid("POST", path`/me/order-items/${orderItemId}/purchase-decision`),
1237
+ /**
1238
+ * `POST /me/order-items/{id}/actions/{key}` — 주문상품 `actions`에 켜진 행동을 실행한다(#115, 시안 승인 등).
1239
+ * 응답의 `flowState`·`actions`로 화면을 바로 바꾼다. 에러: 409 `ACTION_NOT_AVAILABLE`(`details.reason`)
1240
+ */
1241
+ act: (orderItemId, key, input = {}) => http.request("POST", path`/me/order-items/${orderItemId}/actions/${key}`, flowActionResultSchema, { body: flowActionRequestSchema.parse({ input }) }),
1242
+ /** 비회원 행동 — 비회원 주문 조회와 같은 연락처·비밀번호 확인과 시도 한도를 지난다 */
1243
+ guestAct: (orderId, orderItemId, key, body) => http.request("POST", path`/guest/orders/${orderId}/items/${orderItemId}/actions/${key}`, flowActionResultSchema, { body: guestFlowActionRequestSchema.parse(body) }),
1244
+ /**
1245
+ * `POST /me/orders/{id}/actions/{key}` — 주문 전체 행동(#115, 예: 주문 전체 취소). 그 행동이 켜진 주문상품마다 실행하고 결과를
1246
+ * 주문상품별로 준다(부분 실행). 켜진 주문상품이 하나도 없으면 409 `ACTION_NOT_AVAILABLE`
1247
+ */
1248
+ actOnOrder: (orderId, key, input = {}) => http.request("POST", path`/me/orders/${orderId}/actions/${key}`, orderFlowActionResultSchema, { body: flowActionRequestSchema.parse({ input }) }),
1249
+ /** 비회원 주문 전체 행동 — 비회원 주문 조회와 같은 확인·시도 한도 */
1250
+ guestActOnOrder: (orderId, key, body) => http.request("POST", path`/guest/orders/${orderId}/actions/${key}`, orderFlowActionResultSchema, { body: guestFlowActionRequestSchema.parse(body) })
1138
1251
  },
1139
1252
  myClaims: {
1140
1253
  create: (orderItemId, body) => http.request("POST", path`/me/order-items/${orderItemId}/claims`, createClaimResultSchema, { body: createClaimRequestSchema.parse(body) }),
@@ -1194,4 +1307,4 @@ get: () => http.request("GET", "/store", storefrontStoreSchema) },
1194
1307
  };
1195
1308
  }
1196
1309
  //#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 };
1310
+ export { claimReturnAddressSchema as $, wishlistAddResultSchema as A, idpAuthorizeResponseSchema as At, consentSourceSchema as B, ApiError as Bt, orderShippingAddressSchema as C, addCartItemRequestSchema as Ct, memberAddressSchema as D, anonymousSessionSchema as Dt, memberAddressRequestSchema as E, updateCartItemRequestSchema as Et, createCustomerInquiryRequestSchema as F, signupRequestSchema as Ft, flowActionResultSchema as G, consentUpdateRequestSchema as H, toApiError as Ht, customerInquiryCategorySchema as I, socialProviderSchema as It, flowInputFieldSchema as J, flowActionSchema as K, customerInquirySchema as L, tokenPairSchema as Lt, createInquiryResultSchema as M, linkIdentityRequestSchema as Mt, productInquiryCategorySchema as N, loginRequestSchema as Nt, memberSchema as O, idpAgreementsSchema as Ot, publicInquirySchema as P, memberIdentitiesSchema as Pt, claimReasonSchema as Q, consentActionSchema as R, withdrawRequestSchema as Rt, myOrderSchema as S, pageSchema as St, trackingStageResponseSchema as T, cartSchema as Tt, memberConsentsSchema as U, unwrapData as Ut, consentStateSchema as V, buildQuery as Vt, flowActionRequestSchema as W, guestFlowActionRequestSchema as X, flowStateSchema as Y, orderFlowActionResultSchema as Z, memberPointEntrySchema as _, storefrontCollectionListQuerySchema as _t, myReviewSchema as a, formatOrderNo as at, deliveryTrackingSchema as b, orderItemStatusSchema as bt, publicReviewSchema as c, collectionProductPageSchema as ct, reviewSummarySchema as d, productCardSchema as dt, claimTypeSchema as et, updateReviewRequestSchema as f, productDetailSchema as ft, memberPointEntryPageSchema as g, storefrontCollectionDetailSchema as gt, writableReviewSchema as h, productSortSchema as ht, createReviewResultSchema as i, commerceNumberField as it, createInquiryRequestSchema as j, idpTokenRequestSchema as jt, updateProfileRequestSchema as k, idpAuthorizeRequestSchema as kt, reviewImageUploadRequestSchema as l, collectionProductQuerySchema as lt, uploadTicketSchema as m, productPageSchema as mt, storefrontStoreSchema as n, createClaimResultSchema as nt, productReviewQuerySchema as o, parseOrderNo as ot, updateReviewResultSchema as p, productFacetsSchema as pt, flowFieldValueSchema as q, createReviewRequestSchema as r, myClaimSchema as rt, productReviewSortSchema as s, categoryNodeSchema as st, createStorefrontClient as t, createClaimRequestSchema as tt, reviewPageSchema as u, collectionProductSortSchema as ut, memberPointsSchema as v, storefrontCollectionSchema as vt, purchaseDecisionResultSchema as w, cartItemSchema as wt, myOrderItemSchema as x, pageInfoSchema as xt, storefrontPointPolicySchema as y, claimStatusSchema as yt, consentKindSchema as z, withdrawalBlockedDetailsSchema as zt };