@sayren/store-sdk 0.40.0 → 0.42.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/index.d.mts +178 -80
- package/dist/index.mjs +214 -507
- package/dist/server.d.mts +2 -2
- package/dist/server.mjs +2 -2
- package/dist/webhook-headers-D0E3wPpS.mjs +437 -0
- package/package.json +1 -1
- package/src/client.ts +16 -6
- package/src/http.ts +8 -1
- package/src/index.ts +2 -0
- package/src/member-delegation.ts +21 -17
- package/src/schemas/ai.ts +101 -42
- package/src/schemas/apps.ts +18 -15
- package/src/schemas/audit.ts +6 -3
- package/src/schemas/category.ts +36 -31
- package/src/schemas/claim.ts +14 -11
- package/src/schemas/collection.ts +75 -64
- package/src/schemas/commerce-flow.ts +106 -85
- package/src/schemas/coupon.ts +87 -79
- package/src/schemas/customer-delegation.ts +30 -27
- package/src/schemas/customer.ts +9 -6
- package/src/schemas/inventory.ts +28 -23
- package/src/schemas/login.ts +17 -10
- package/src/schemas/misc.ts +6 -3
- package/src/schemas/order.ts +69 -58
- package/src/schemas/payment.ts +108 -89
- package/src/schemas/points.ts +32 -27
- package/src/schemas/product-info.ts +12 -9
- package/src/schemas/product.ts +17 -14
- package/src/schemas/saved-option-set.ts +5 -5
- package/src/schemas/starter.ts +15 -12
- package/src/schemas/stay.ts +15 -12
- package/src/schemas/store.ts +122 -111
- package/src/schemas/storefront-hosting.ts +271 -219
- package/src/schemas/strict.ts +84 -0
- package/src/schemas/upload.ts +15 -12
- package/src/session.ts +8 -5
- package/dist/webhook-headers-ap_exsb9.mjs +0 -22
package/dist/index.mjs
CHANGED
|
@@ -1,337 +1,5 @@
|
|
|
1
|
-
import { a as WEBHOOK_HEADERS, i as WEBHOOK_EVENT_TYPE_HEADER, n as WEBHOOK_DELIVERY_ID_HEADER, o as WEBHOOK_SIGNATURE_HEADER, r as WEBHOOK_EVENT_ID_HEADER, s as WEBHOOK_USER_AGENT, t as WEBHOOK_DEFAULT_TOLERANCE_SEC } from "./webhook-headers-
|
|
1
|
+
import { A as auditLogPageSchema, C as approvalPageSchema, D as auditActorTypeSchema, E as auditActorSchema, F as strictRequest, M as auditLogSourceSchema, N as writeDryRunResultSchema, O as auditLogListQuerySchema, P as writePreviewSchema, S as approvalListQuerySchema, T as approvalStatusSchema, _ as resolveToken, a as WEBHOOK_HEADERS, b as agentPolicyDecisionSchema, c as APPROVAL_ALREADY_DECIDED_CODE, d as ApprovalPendingError, f as SAYREN_API_BASE_URL, g as path, h as createHttp, i as WEBHOOK_EVENT_TYPE_HEADER, j as auditLogSchema, k as auditLogOutcomeSchema, l as APPROVAL_REQUIRED_CODE, m as buildQuery, n as WEBHOOK_DELIVERY_ID_HEADER, o as WEBHOOK_SIGNATURE_HEADER, p as SAYREN_API_ORIGIN, r as WEBHOOK_EVENT_ID_HEADER, s as WEBHOOK_USER_AGENT, t as WEBHOOK_DEFAULT_TOLERANCE_SEC, u as ApiError, v as toApiError, w as approvalRequestSchema, x as approvalDecisionRequestSchema, y as unwrapData } from "./webhook-headers-D0E3wPpS.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
//#region src/schemas/audit.ts
|
|
4
|
-
/**
|
|
5
|
-
* 감사 로그와 승인 요청 — `/v1/audit-logs`, `/v1/approval-requests` (이슈 #36).
|
|
6
|
-
*
|
|
7
|
-
* 관리 API 쓰기(`/v1/**`의 GET 외 요청)는 모두 요청 단위 기록(`source: REQUEST`) 한 줄을 남긴다. 환불·직권취소 같은
|
|
8
|
-
* 도메인 동작은 그 안에서 변경 전후를 담은 기록(`source: DOMAIN`)을 따로 남기고 `requestId`로 요청 기록과 이어진다.
|
|
9
|
-
*/
|
|
10
|
-
const auditActorTypeSchema = z.enum([
|
|
11
|
-
"USER",
|
|
12
|
-
"AGENT",
|
|
13
|
-
"APP",
|
|
14
|
-
"TOKEN",
|
|
15
|
-
"SYSTEM"
|
|
16
|
-
]).describe("행위자 유형. `USER`=상점 플랫폼 사용자, `AGENT`=AI 에이전트(MCP·에이전트용 API 토큰), `APP`=앱(OAuth 클라이언트·M2M), `TOKEN`=API 토큰, `SYSTEM`=자동화(주기 잡)");
|
|
17
|
-
const auditActorSchema = z.object({
|
|
18
|
-
type: auditActorTypeSchema,
|
|
19
|
-
id: z.string().describe("행위자 ID. `USER`=userId, `TOKEN`·`AGENT`(API 토큰)=`pat:{tokenId}`, `APP`=`client:{clientId}`, `SYSTEM`=`system`. 사람이 앱에 위임한 호출은 `APP`이고 위임한 사람은 `metadata.onBehalfOf`에 있다"),
|
|
20
|
-
name: z.string().nullable().describe("기록 시점의 표시 이름. 알 수 없으면 null")
|
|
21
|
-
});
|
|
22
|
-
const auditLogSourceSchema = z.enum(["REQUEST", "DOMAIN"]).describe("기록 단위. `REQUEST`=관리 API 쓰기 요청 한 건, `DOMAIN`=환불·취소 같은 도메인 동작의 상세");
|
|
23
|
-
const auditLogOutcomeSchema = z.enum([
|
|
24
|
-
"SUCCEEDED",
|
|
25
|
-
"FAILED",
|
|
26
|
-
"PENDING_APPROVAL",
|
|
27
|
-
"DENIED",
|
|
28
|
-
"DRY_RUN"
|
|
29
|
-
]).describe("요청 결과. `PENDING_APPROVAL`=승인 대기로 보류(202), `DENIED`=에이전트 정책으로 거부(403 `AGENT_OPERATION_DENIED`), `DRY_RUN`=드라이런(`x-sayren-dry-run: 1`)이라 실행하지 않음");
|
|
30
|
-
const auditLogSchema = z.object({
|
|
31
|
-
auditId: z.string().describe("감사 로그 ID"),
|
|
32
|
-
occurredAt: z.string().describe("기록 일시 (ISO 8601)"),
|
|
33
|
-
source: auditLogSourceSchema,
|
|
34
|
-
action: z.string().describe("동작. `REQUEST`는 오퍼레이션 ID(OpenAPI `operationId`, 예: `ProductsController_patch`), `DOMAIN`은 도메인 코드(예: `ORDER_ITEM_CANCELED_BY_SELLER`)"),
|
|
35
|
-
actor: auditActorSchema,
|
|
36
|
-
actorRole: z.string().nullable().describe("요청 시점의 상점 역할. 역할이 없는 토큰·자동화는 null"),
|
|
37
|
-
target: z.object({
|
|
38
|
-
type: z.string().describe("대상 리소스 유형 (예: `products`, `order-items`, `claim`)"),
|
|
39
|
-
id: z.string().nullable().describe("대상 리소스 ID. 목록 대상 요청처럼 하나로 정할 수 없으면 null")
|
|
40
|
-
}),
|
|
41
|
-
requestId: z.string().nullable().describe("요청 ID. 같은 요청에서 나온 `REQUEST`·`DOMAIN` 기록이 같은 값을 가진다. 자동화는 null"),
|
|
42
|
-
method: z.string().nullable().describe("HTTP 메서드 (`REQUEST`만)"),
|
|
43
|
-
path: z.string().nullable().describe("요청 경로와 쿼리 (`REQUEST`만). 민감한 쿼리 값은 `***`로 가린다"),
|
|
44
|
-
statusCode: z.number().int().nullable().describe("응답 HTTP 상태 코드 (`REQUEST`만)"),
|
|
45
|
-
outcome: auditLogOutcomeSchema.nullable().describe("요청 결과 (`REQUEST`만)"),
|
|
46
|
-
errorCode: z.string().nullable().describe("에러 응답의 `error.code` (실패한 요청만)"),
|
|
47
|
-
traceId: z.string().nullable().describe("추적 ID. 에러 응답의 `error.traceId`와 같다"),
|
|
48
|
-
idempotencyKey: z.string().nullable().describe("요청의 멱등키"),
|
|
49
|
-
approvalId: z.string().nullable().describe("승인 요청 ID. 승인 대기로 보류된 요청과 승인 뒤 실행된 요청에 실린다"),
|
|
50
|
-
metadata: z.record(z.string(), z.unknown()).describe("부가 정보. 도메인 기록은 변경 전후 값·사유를, 승인 실행 기록은 승인자(`approvedBy`)를 싣는다")
|
|
51
|
-
});
|
|
52
|
-
/** 쉼표 구분 목록 쿼리 → 배열 */
|
|
53
|
-
function commaList(item) {
|
|
54
|
-
return z.union([z.string(), z.array(z.string())]).transform((value) => (Array.isArray(value) ? value : [value]).flatMap((part) => part.split(",")).map((part) => part.trim()).filter((part) => part.length > 0)).pipe(z.array(item).min(1));
|
|
55
|
-
}
|
|
56
|
-
/** 감사 로그 조회 쿼리 — `GET /audit-logs` */
|
|
57
|
-
const auditLogListQuerySchema = z.object({
|
|
58
|
-
from: z.string().optional().describe("조회 시작 일시 (ISO 8601, 포함)"),
|
|
59
|
-
to: z.string().optional().describe("조회 종료 일시 (ISO 8601, 미포함)"),
|
|
60
|
-
actorType: commaList(auditActorTypeSchema).optional().describe("행위자 유형 필터. 여러 개는 쉼표로 구분한다 (예: `AGENT,APP`)"),
|
|
61
|
-
actorId: z.string().optional().describe("행위자 ID 필터 (정확히 일치)"),
|
|
62
|
-
action: z.string().optional().describe("동작 필터 (정확히 일치)"),
|
|
63
|
-
targetType: z.string().optional().describe("대상 유형 필터 (정확히 일치)"),
|
|
64
|
-
targetId: z.string().optional().describe("대상 ID 필터 (정확히 일치)"),
|
|
65
|
-
source: auditLogSourceSchema.optional(),
|
|
66
|
-
outcome: auditLogOutcomeSchema.optional(),
|
|
67
|
-
requestId: z.string().optional().describe("요청 ID 필터 — 한 요청의 요청·도메인 기록을 함께 본다"),
|
|
68
|
-
approvalId: z.string().optional().describe("승인 요청 ID 필터"),
|
|
69
|
-
cursor: z.string().optional().describe("이전 응답의 `nextCursor`. 생략하면 가장 최신부터"),
|
|
70
|
-
limit: z.coerce.number().int().min(1).max(100).optional().describe("최대 건수 (1~100, 기본 50)")
|
|
71
|
-
});
|
|
72
|
-
const auditLogPageSchema = z.object({
|
|
73
|
-
items: z.array(auditLogSchema),
|
|
74
|
-
nextCursor: z.string().nullable().describe("다음 페이지 커서. 마지막 페이지면 null")
|
|
75
|
-
});
|
|
76
|
-
const agentPolicyDecisionSchema = z.enum([
|
|
77
|
-
"ALLOW",
|
|
78
|
-
"APPROVAL_REQUIRED",
|
|
79
|
-
"DENIED"
|
|
80
|
-
]).describe("에이전트 쓰기 판정. `ALLOW`=바로 실행, `APPROVAL_REQUIRED`=상점 플랫폼 승인 뒤 실행, `DENIED`=에이전트는 실행할 수 없음");
|
|
81
|
-
const previewValueSchema = z.union([
|
|
82
|
-
z.string(),
|
|
83
|
-
z.number(),
|
|
84
|
-
z.boolean(),
|
|
85
|
-
z.null()
|
|
86
|
-
]);
|
|
87
|
-
const writePreviewSchema = z.object({
|
|
88
|
-
operationId: z.string().describe("오퍼레이션 ID"),
|
|
89
|
-
method: z.string(),
|
|
90
|
-
path: z.string(),
|
|
91
|
-
target: z.object({
|
|
92
|
-
type: z.string(),
|
|
93
|
-
id: z.string().nullable()
|
|
94
|
-
}),
|
|
95
|
-
targetName: z.string().nullable().optional().describe("대상 이름(상품명·쿠폰명·흐름 이름·구매자 이름 등). 읽을 수 없으면 null"),
|
|
96
|
-
changes: z.array(z.object({
|
|
97
|
-
field: z.string().describe("바뀌는 필드"),
|
|
98
|
-
before: z.unknown().describe("현재 값. 새로 만드는 요청이거나 읽을 수 없으면 null"),
|
|
99
|
-
after: z.unknown().describe("요청이 넣을 값")
|
|
100
|
-
})).describe("값이 달라지는 필드. 서버가 현재 값과 비교할 수 있는 오퍼레이션만 채운다"),
|
|
101
|
-
facts: z.record(z.string(), previewValueSchema).describe("영향 요약 (예: 취소 수량·주문상품 금액·예상 환불액). 오퍼레이션마다 다르다")
|
|
102
|
-
});
|
|
103
|
-
/** `x-sayren-dry-run: 1`을 실은 쓰기 요청의 응답(200) — 실행하지 않고 판정과 영향만 돌려준다 */
|
|
104
|
-
const writeDryRunResultSchema = z.object({
|
|
105
|
-
dryRun: z.literal(true),
|
|
106
|
-
decision: agentPolicyDecisionSchema,
|
|
107
|
-
reason: z.string().nullable().describe("승인 필요·거부 사유. `ALLOW`면 null"),
|
|
108
|
-
preview: writePreviewSchema
|
|
109
|
-
});
|
|
110
|
-
const approvalStatusSchema = z.enum([
|
|
111
|
-
"PENDING",
|
|
112
|
-
"EXECUTING",
|
|
113
|
-
"SUCCEEDED",
|
|
114
|
-
"FAILED",
|
|
115
|
-
"UNKNOWN",
|
|
116
|
-
"REJECTED",
|
|
117
|
-
"EXPIRED"
|
|
118
|
-
]).describe("승인 요청 상태. `PENDING` 승인 대기 → 승인하면 `EXECUTING`(원 요청 실행 중) → `SUCCEEDED`·`FAILED`(원 요청의 응답 기준), 거절하면 `REJECTED`, 기한이 지나면 `EXPIRED`. 실행 응답을 받지 못했으면(타임아웃·서버 종료) `UNKNOWN`이다 — 서버가 감사 로그로 결과를 확정하면 `SUCCEEDED`·`FAILED`로 바뀌고, 확정하지 못하면 `UNKNOWN`에 남는다. `UNKNOWN`은 다시 실행하지 않는다(이미 실행됐을 수 있다)");
|
|
119
|
-
const approvalRequestSchema = z.object({
|
|
120
|
-
approvalId: z.string().describe("승인 요청 ID"),
|
|
121
|
-
status: approvalStatusSchema,
|
|
122
|
-
operationId: z.string().describe("보류된 오퍼레이션 ID"),
|
|
123
|
-
operationName: z.string().nullable().optional().describe("작업 이름(예: 흐름 게시, 구매자 적립금 지급·차감). API 문서의 요약과 같다. 모르면 null"),
|
|
124
|
-
method: z.string().describe("HTTP 메서드"),
|
|
125
|
-
path: z.string().describe("요청 경로와 쿼리"),
|
|
126
|
-
body: z.unknown().describe("요청 본문. 승인하면 이 본문 그대로 실행한다. 없으면 null"),
|
|
127
|
-
idempotencyKey: z.string().nullable().describe("원 요청의 멱등키"),
|
|
128
|
-
reason: z.string().describe("승인이 필요한 이유"),
|
|
129
|
-
actor: auditActorSchema.describe("요청한 행위자"),
|
|
130
|
-
preview: writePreviewSchema.nullable().describe("요청 시점에 서버가 계산한 영향 미리보기"),
|
|
131
|
-
createdAt: z.string().describe("요청 일시 (ISO 8601)"),
|
|
132
|
-
expiresAt: z.string().describe("승인 기한 (ISO 8601). 지나면 `EXPIRED`가 된다"),
|
|
133
|
-
decidedAt: z.string().nullable().describe("승인·거절 일시"),
|
|
134
|
-
decidedBy: z.object({
|
|
135
|
-
id: z.string(),
|
|
136
|
-
name: z.string().nullable()
|
|
137
|
-
}).nullable().describe("승인·거절한 상점 플랫폼 사용자"),
|
|
138
|
-
decisionNote: z.string().nullable().describe("승인·거절 메모"),
|
|
139
|
-
executedAt: z.string().nullable().describe("원 요청 실행을 마친 일시"),
|
|
140
|
-
result: z.object({
|
|
141
|
-
statusCode: z.number().int().describe("원 요청의 응답 상태 코드"),
|
|
142
|
-
data: z.unknown().describe("성공 응답의 `data` (큰 응답은 잘린다)"),
|
|
143
|
-
error: z.object({
|
|
144
|
-
code: z.string(),
|
|
145
|
-
message: z.string()
|
|
146
|
-
}).nullable().describe("실패 응답의 `error` 요약")
|
|
147
|
-
}).nullable().describe("실행 결과. `SUCCEEDED`·`FAILED`·`UNKNOWN`에서 값이 있다. 감사 로그로 확정한 결과는 `data`가 null이다"),
|
|
148
|
-
approvalUrl: z.string().nullable().describe("상점 플랫폼의 승인 화면 주소. 이 배포의 상점 플랫폼 주소를 알 수 없으면 null")
|
|
149
|
-
});
|
|
150
|
-
const approvalListQuerySchema = z.object({
|
|
151
|
-
status: commaList(approvalStatusSchema).optional().describe("상태 필터. 여러 개는 쉼표로 구분한다 (예: `PENDING,EXECUTING`)"),
|
|
152
|
-
cursor: z.string().optional().describe("이전 응답의 `nextCursor`. 생략하면 가장 최신부터"),
|
|
153
|
-
limit: z.coerce.number().int().min(1).max(100).optional().describe("최대 건수 (1~100, 기본 50)")
|
|
154
|
-
});
|
|
155
|
-
const approvalPageSchema = z.object({
|
|
156
|
-
items: z.array(approvalRequestSchema),
|
|
157
|
-
nextCursor: z.string().nullable().describe("다음 페이지 커서. 마지막 페이지면 null")
|
|
158
|
-
});
|
|
159
|
-
const approvalDecisionRequestSchema = z.object({ note: z.string().trim().max(500).optional().describe("승인·거절 메모 (최대 500자)") });
|
|
160
|
-
//#endregion
|
|
161
|
-
//#region src/http.ts
|
|
162
|
-
/** 표준 엔벨로프의 $.error 상세 */
|
|
163
|
-
const errorDetailSchema = z.object({
|
|
164
|
-
code: z.string(),
|
|
165
|
-
message: z.string(),
|
|
166
|
-
traceId: z.string().optional(),
|
|
167
|
-
/**
|
|
168
|
-
* 이 에러 코드를 설명하는 문서 URL(선택). 서버가 코드별 매핑을 가진 코드에만 실린다 —
|
|
169
|
-
* 없으면 필드가 아예 없으므로 소비측은 있을 때만 쓴다
|
|
170
|
-
*/
|
|
171
|
-
docs: z.url().optional().catch(void 0),
|
|
172
|
-
/**
|
|
173
|
-
* 에러 코드별 보조 데이터(선택). 예: 관리 API `LIVE_GATE_NOT_MET`의
|
|
174
|
-
* `{ conditions: LiveGateCondition[] }`. 형태는 에러 코드마다 다르므로 소비측이 코드별 스키마로 다시 파싱한다
|
|
175
|
-
*/
|
|
176
|
-
details: z.record(z.string(), z.unknown()).optional().catch(void 0)
|
|
177
|
-
});
|
|
178
|
-
/** 표준 응답 엔벨로프 — $.meta / $.data / $.error */
|
|
179
|
-
const envelopeSchema = z.object({
|
|
180
|
-
meta: z.object({
|
|
181
|
-
status: z.number(),
|
|
182
|
-
code: z.string(),
|
|
183
|
-
message: z.string(),
|
|
184
|
-
isSuccess: z.boolean()
|
|
185
|
-
}),
|
|
186
|
-
data: z.unknown().optional(),
|
|
187
|
-
/** 구형 필드 — data로 개명되기 전 응답과의 전환기 호환 */
|
|
188
|
-
content: z.unknown().optional(),
|
|
189
|
-
error: errorDetailSchema.nullable()
|
|
190
|
-
});
|
|
191
|
-
/** OAuth 프로토콜 표면의 평면 에러 (RFC 6749 §5.2, RFC 7591 §3.2.2) */
|
|
192
|
-
const oauthErrorSchema = z.object({
|
|
193
|
-
error: z.string(),
|
|
194
|
-
error_description: z.string().optional()
|
|
195
|
-
});
|
|
196
|
-
/** 표준 엔벨로프면 $.data(구형 $.content)를, 아니면(평면 응답) 본문 전체를 반환 */
|
|
197
|
-
function unwrapData(json) {
|
|
198
|
-
const envelope = envelopeSchema.safeParse(json);
|
|
199
|
-
if (!envelope.success) return json;
|
|
200
|
-
return envelope.data.data ?? envelope.data.content ?? null;
|
|
201
|
-
}
|
|
202
|
-
var ApiError = class extends Error {
|
|
203
|
-
status;
|
|
204
|
-
code;
|
|
205
|
-
traceId;
|
|
206
|
-
body;
|
|
207
|
-
details;
|
|
208
|
-
docs;
|
|
209
|
-
constructor(status, code, message, traceId, body, details, docs) {
|
|
210
|
-
super(message);
|
|
211
|
-
this.status = status;
|
|
212
|
-
this.code = code;
|
|
213
|
-
this.traceId = traceId;
|
|
214
|
-
this.body = body;
|
|
215
|
-
this.details = details;
|
|
216
|
-
this.docs = docs;
|
|
217
|
-
this.name = "ApiError";
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
/** 에이전트 쓰기가 승인 대기로 보류됐다(202) */
|
|
221
|
-
const APPROVAL_REQUIRED_CODE = "APPROVAL_REQUIRED";
|
|
222
|
-
/** 같은 멱등키의 승인 요청이 이미 끝났다(200) — 결과는 승인 요청의 `status`·`result`다 */
|
|
223
|
-
const APPROVAL_ALREADY_DECIDED_CODE = "APPROVAL_ALREADY_DECIDED";
|
|
224
|
-
/**
|
|
225
|
-
* 쓰기 요청이 실행되지 않고 승인 흐름에 걸렸다 (이슈 #36). 응답 `data`가 요청한 리소스가 아니라 승인 요청이라
|
|
226
|
-
* 성공 값으로 돌려주지 않는다 — 돌려주면 호출부가 승인 요청을 상품·주문으로 읽는다.
|
|
227
|
-
*
|
|
228
|
-
* - `code = APPROVAL_REQUIRED`(202): 에이전트의 고위험 쓰기가 보류됐다. 아직 아무것도 바뀌지 않았다.
|
|
229
|
-
* 셀러가 상점 플랫폼(`approval.approvalUrl`)에서 승인하면 서버가 원 요청을 실행한다. 같은 요청을 다시 보내지 말고
|
|
230
|
-
* `approvalRequests.get(approvalId)`로 결과를 확인한다.
|
|
231
|
-
* - `code = APPROVAL_ALREADY_DECIDED`(200): 같은 멱등키로 보낸 요청의 승인이 이미 끝났다. `status`가
|
|
232
|
-
* `SUCCEEDED`·`FAILED`·`UNKNOWN`이면 실행 결과(`approval.result`)를 보고, `REJECTED`·`EXPIRED`면 새 멱등키로 다시 요청한다.
|
|
233
|
-
*/
|
|
234
|
-
var ApprovalPendingError = class extends Error {
|
|
235
|
-
code;
|
|
236
|
-
httpStatus;
|
|
237
|
-
approval;
|
|
238
|
-
approvalId;
|
|
239
|
-
/** 승인 요청 상태 */
|
|
240
|
-
status;
|
|
241
|
-
constructor(code, httpStatus, approval, message) {
|
|
242
|
-
super(message);
|
|
243
|
-
this.code = code;
|
|
244
|
-
this.httpStatus = httpStatus;
|
|
245
|
-
this.approval = approval;
|
|
246
|
-
this.name = "ApprovalPendingError";
|
|
247
|
-
this.approvalId = approval.approvalId;
|
|
248
|
-
this.status = approval.status;
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
/** 성공 엔벨로프가 승인 흐름 응답이면 ApprovalPendingError. 그 밖(다른 202 등)은 null */
|
|
252
|
-
function approvalErrorOf(status, json) {
|
|
253
|
-
const envelope = envelopeSchema.safeParse(json);
|
|
254
|
-
if (!envelope.success) return null;
|
|
255
|
-
const { code, message } = envelope.data.meta;
|
|
256
|
-
if (code !== "APPROVAL_REQUIRED" && code !== "APPROVAL_ALREADY_DECIDED") return null;
|
|
257
|
-
const approval = approvalRequestSchema.safeParse(envelope.data.data);
|
|
258
|
-
if (!approval.success) return null;
|
|
259
|
-
return new ApprovalPendingError(code, status, approval.data, message);
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* 에러 응답 본문 → ApiError 구성 (에러 형태의 단일 원천).
|
|
263
|
-
* 표준 엔벨로프($.error) 우선, 구형 평면 에러({ code, message }), OAuth 평면 에러
|
|
264
|
-
* ({ error, error_description } → code=error, message=error_description) 순으로 폴백하고,
|
|
265
|
-
* 모두 아니면 UNKNOWN. createHttp의 send와 세션(userinfo 등 raw fetch 경로)이 동일한 에러 모양을 내도록 공유한다.
|
|
266
|
-
*/
|
|
267
|
-
function toApiError(status, raw) {
|
|
268
|
-
const envelope = envelopeSchema.safeParse(raw);
|
|
269
|
-
const detail = envelope.success ? envelope.data.error : errorDetailSchema.safeParse(raw).data ?? null;
|
|
270
|
-
if (detail) return new ApiError(status, detail.code, detail.message, detail.traceId, raw, detail.details, detail.docs);
|
|
271
|
-
const oauth = envelope.success ? null : oauthErrorSchema.safeParse(raw).data;
|
|
272
|
-
if (oauth) return new ApiError(status, oauth.error, oauth.error_description ?? oauth.error, void 0, raw);
|
|
273
|
-
return new ApiError(status, "UNKNOWN", `HTTP ${status}`, void 0, raw);
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* 경로 템플릿 태그 — 보간 값(경로 파라미터)마다 encodeURIComponent를 적용한다.
|
|
277
|
-
* `/`·`?`·`#` 등이 섞인 id가 다른 경로·쿼리로 해석되지 않게 한다. 예: path`/products/${id}`
|
|
278
|
-
*/
|
|
279
|
-
function path(strings, ...params) {
|
|
280
|
-
return strings.reduce((acc, part, i) => acc + part + (i < params.length ? encodeURIComponent(String(params[i])) : ""), "");
|
|
281
|
-
}
|
|
282
|
-
function resolveToken(source) {
|
|
283
|
-
return (typeof source === "function" ? source() : source) ?? null;
|
|
284
|
-
}
|
|
285
|
-
function buildQuery(query) {
|
|
286
|
-
if (!query) return "";
|
|
287
|
-
const params = new URLSearchParams();
|
|
288
|
-
for (const [key, value] of Object.entries(query)) if (value !== void 0) params.set(key, String(value));
|
|
289
|
-
const qs = params.toString();
|
|
290
|
-
return qs ? `?${qs}` : "";
|
|
291
|
-
}
|
|
292
|
-
function createHttp(options) {
|
|
293
|
-
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
294
|
-
async function send(method, path, request, retried = false) {
|
|
295
|
-
const url = `${options.baseUrl}${path}${buildQuery(request?.query)}`;
|
|
296
|
-
const headers = {
|
|
297
|
-
...request?.body !== void 0 ? { "content-type": "application/json" } : {},
|
|
298
|
-
...options.headers?.(),
|
|
299
|
-
...request?.headers
|
|
300
|
-
};
|
|
301
|
-
const response = await fetchFn(url, {
|
|
302
|
-
method,
|
|
303
|
-
headers,
|
|
304
|
-
body: request?.body !== void 0 ? JSON.stringify(request.body) : void 0
|
|
305
|
-
});
|
|
306
|
-
options.onResponse?.(response);
|
|
307
|
-
if (response.status === 401 && !retried && options.refresh) {
|
|
308
|
-
if (await options.refresh()) return send(method, path, request, true);
|
|
309
|
-
}
|
|
310
|
-
if (!response.ok) {
|
|
311
|
-
if (response.status === 401) options.onUnauthorized?.();
|
|
312
|
-
const raw = await response.json().catch(() => null);
|
|
313
|
-
throw toApiError(response.status, raw);
|
|
314
|
-
}
|
|
315
|
-
return response;
|
|
316
|
-
}
|
|
317
|
-
return {
|
|
318
|
-
async request(method, path, schema, request) {
|
|
319
|
-
const response = await send(method, path, request);
|
|
320
|
-
const json = await response.json();
|
|
321
|
-
const pending = approvalErrorOf(response.status, json);
|
|
322
|
-
if (pending) throw pending;
|
|
323
|
-
return schema.parse(unwrapData(json));
|
|
324
|
-
},
|
|
325
|
-
async requestVoid(method, path, request) {
|
|
326
|
-
const response = await send(method, path, request);
|
|
327
|
-
if (response.status === 204) return;
|
|
328
|
-
const json = await response.json().catch(() => null);
|
|
329
|
-
const pending = approvalErrorOf(response.status, json);
|
|
330
|
-
if (pending) throw pending;
|
|
331
|
-
}
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
//#endregion
|
|
335
3
|
//#region src/schemas/auth.ts
|
|
336
4
|
const storeRoleSchema = z.enum([
|
|
337
5
|
"OWNER",
|
|
@@ -1693,7 +1361,7 @@ const businessInfoResponseShape = {
|
|
|
1693
1361
|
const autoDeliverDaysDescription = "발송 후 자동 배송완료까지의 일수(0~30, 기본 7). 발송(`DISPATCHED`)·배송중(`DELIVERING`) 주문상품을 이 기간이 지나면 배송완료(`DELIVERED`)로 바꾼다. `0`이면 자동 배송완료를 하지 않는다";
|
|
1694
1362
|
const autoConfirmDaysDescription = "배송완료 후 자동 구매확정까지의 일수(0~30, 기본 7). 배송완료 시점에 구매확정 예정일(`autoDecisionDate`)을 이 값으로 잡고, 그 날짜가 지나면 구매확정(`PURCHASE_DECIDED`)으로 바꾼다. 진행 중인 클레임이 있으면 건너뛴다. `0`이면 자동 구매확정을 하지 않는다";
|
|
1695
1363
|
/** `PATCH /v1/store` 본문 — 바꿀 필드만 보낸다 */
|
|
1696
|
-
const updateStoreRequestSchema = z.object({
|
|
1364
|
+
const updateStoreRequestSchema = strictRequest(z.object({
|
|
1697
1365
|
name: z.string().min(2).max(50).optional(),
|
|
1698
1366
|
logoUrl: z.url().optional(),
|
|
1699
1367
|
customerCenterPhone: z.string().nullable().optional().describe("고객센터 전화번호. `null`을 주면 지운다"),
|
|
@@ -1712,7 +1380,7 @@ const updateStoreRequestSchema = z.object({
|
|
|
1712
1380
|
termsUrl: policyDocumentUrlSchema.optional().describe("이용약관 문서 주소(https). 동의 시점의 값이 동의 이력에 복사된다. `null`을 주면 지운다"),
|
|
1713
1381
|
privacyUrl: policyDocumentUrlSchema.optional().describe("개인정보 수집이용 동의 문서 주소(https). `null`을 주면 지운다"),
|
|
1714
1382
|
defaultLocale: localeCodeSchema.optional().describe("상점 기본 언어(이슈 #134). 상품·카테고리 필드가 이 언어 값이고 번역이 없는 칸은 이 값으로 보인다. 바꿔도 저장된 값은 그대로다")
|
|
1715
|
-
}).refine((value) => Object.values(value).some((v) => v !== void 0), { message: "최소 1개 필드가 필요합니다" });
|
|
1383
|
+
}).refine((value) => Object.values(value).some((v) => v !== void 0), { message: "최소 1개 필드가 필요합니다" }));
|
|
1716
1384
|
const storeSchema = z.object({
|
|
1717
1385
|
storeId: z.string(),
|
|
1718
1386
|
name: z.string(),
|
|
@@ -1789,12 +1457,12 @@ const invitationSchema = z.object({
|
|
|
1789
1457
|
acceptedAt: z.string().nullable().default(null)
|
|
1790
1458
|
});
|
|
1791
1459
|
/** `POST /v1/store/invitations` 요청 — ADMIN 초대는 OWNER만 할 수 있다 */
|
|
1792
|
-
const inviteMemberRequestSchema = z.object({
|
|
1460
|
+
const inviteMemberRequestSchema = strictRequest(z.object({
|
|
1793
1461
|
email: z.email(),
|
|
1794
1462
|
role: z.enum(["ADMIN", "STAFF"])
|
|
1795
|
-
});
|
|
1463
|
+
}));
|
|
1796
1464
|
/** `PATCH /v1/store/members/{userId}` 요청 */
|
|
1797
|
-
const updateMemberRoleRequestSchema = z.object({ role: z.enum(["ADMIN", "STAFF"]) });
|
|
1465
|
+
const updateMemberRoleRequestSchema = strictRequest(z.object({ role: z.enum(["ADMIN", "STAFF"]) }));
|
|
1798
1466
|
/** `GET /v1/store/invitations` 쿼리 — OpenAPI 문서용 형태 */
|
|
1799
1467
|
const invitationListQuerySchema = z.object({ status: invitationSchema.shape.status.optional().describe("초대 상태 필터") });
|
|
1800
1468
|
/** `PATCH /v1/store/members/{userId}` 응답 — 바뀐 역할 */
|
|
@@ -1821,7 +1489,7 @@ const sellerAddressSchema = z.object({
|
|
|
1821
1489
|
inventoryLocationId: z.string().nullable().optional().describe("이 주소의 재고 위치 ID — 출고지면 배송 주문을 이 위치 재고로 팔고, 반품지면 반품을 이 위치로 들인다. 위치를 하나만 쓰는 상점은 기본 위치다"),
|
|
1822
1490
|
createdAt: z.string()
|
|
1823
1491
|
});
|
|
1824
|
-
const sellerAddressRequestSchema = z.object({
|
|
1492
|
+
const sellerAddressRequestSchema = strictRequest(z.object({
|
|
1825
1493
|
type: addressTypeSchema,
|
|
1826
1494
|
name: z.string().min(1).max(50),
|
|
1827
1495
|
contactName: z.string().min(1),
|
|
@@ -1830,7 +1498,7 @@ const sellerAddressRequestSchema = z.object({
|
|
|
1830
1498
|
address1: z.string().min(1),
|
|
1831
1499
|
address2: z.string().optional(),
|
|
1832
1500
|
inventoryLocationId: z.string().min(1).optional().describe("재고 위치 ID. 등록에서 생략하면 기본 위치, 수정에서 생략하면 지금 연결을 유지한다")
|
|
1833
|
-
});
|
|
1501
|
+
}));
|
|
1834
1502
|
//#endregion
|
|
1835
1503
|
//#region src/schemas/storefront-hosting.ts
|
|
1836
1504
|
/**
|
|
@@ -1994,11 +1662,11 @@ const TEMPLATE_STORE_LOCKED_BUSINESS_FIELDS = [
|
|
|
1994
1662
|
"customerCenterPhone",
|
|
1995
1663
|
"customerCenterEmail"
|
|
1996
1664
|
];
|
|
1997
|
-
const updateStoreTemplateRequestSchema = z.object({
|
|
1665
|
+
const updateStoreTemplateRequestSchema = strictRequest(z.object({
|
|
1998
1666
|
name: z.string().trim().min(1).max(40).describe("템플릿 이름(1~40자)"),
|
|
1999
1667
|
description: z.string().trim().max(200).describe("템플릿 소개(200자까지)"),
|
|
2000
1668
|
thumbnailUrl: z.url({ protocol: /^https$/ }).max(2048).nullable().describe("썸네일 이미지 주소(https). 이미지 업로드(`POST /v1/uploads`)로 받은 주소를 쓴다. 없으면 null")
|
|
2001
|
-
});
|
|
1669
|
+
}));
|
|
2002
1670
|
/**
|
|
2003
1671
|
* 버전 상태 — 템플릿 버전(`source: TEMPLATE`)은 템플릿 산출물을 그대로 쓰므로 만들 때 곧바로 `READY`다. 편집 버전
|
|
2004
1672
|
* (`source: EDIT`, M2b)은 작업 트리 스냅샷을 빌드하는 동안 `BUILDING`이고, 빌드·규칙 검증을 통과하면 `READY`, 실패하면
|
|
@@ -2159,11 +1827,11 @@ const storefrontDeploymentSchema = z.object({
|
|
|
2159
1827
|
attempts: z.number().int().describe("연속 실패 횟수"),
|
|
2160
1828
|
nextAttemptAt: z.string().nullable().describe("다음 자동 시도 시각 (ISO 8601)")
|
|
2161
1829
|
});
|
|
2162
|
-
const createStorefrontSiteRequestSchema = z.object({
|
|
1830
|
+
const createStorefrontSiteRequestSchema = strictRequest(z.object({
|
|
2163
1831
|
templateId: z.string().min(1).max(64).describe("템플릿 id"),
|
|
2164
1832
|
slug: storefrontSlugSchema.optional().describe("주소 슬러그. 생략하면 상점 코드"),
|
|
2165
1833
|
copyContent: z.boolean().optional().describe("템플릿 상점의 템플릿일 때만 — true면 템플릿 상점의 콘텐츠(레이아웃, 상품·카테고리·컬렉션·주문 흐름·배송·환불 정책)를 이 상점으로 복사한다. 쿠폰·적립금·리뷰는 복사하지 않는다. 생략하거나 false면 레이아웃 콘텐츠를 비우고 빌드한다")
|
|
2166
|
-
});
|
|
1834
|
+
}));
|
|
2167
1835
|
/** @deprecated 템플릿 변경은 지원하지 않는다(항상 409 `TEMPLATE_CHANGE_NOT_SUPPORTED`). 호환을 위해 스키마만 남겼다 */
|
|
2168
1836
|
const changeStorefrontTemplateRequestSchema = z.object({
|
|
2169
1837
|
templateId: z.string().min(1).max(64).describe("바꿀 템플릿 id"),
|
|
@@ -2175,28 +1843,28 @@ const changeStorefrontTemplateRequestSchema = z.object({
|
|
|
2175
1843
|
* 지금 발행 버전이 그 값일 때만 바꾼다(화면을 본 뒤 다른 사람이 바꿨으면 409 `STOREFRONT_SITE_CHANGED`).
|
|
2176
1844
|
* 이미 그 버전이 발행돼 있으면 아무것도 바꾸지 않고 200이다(같은 요청의 재실행이 안전하다).
|
|
2177
1845
|
*/
|
|
2178
|
-
const publishStorefrontVersionRequestSchema = z.object({ expectedPublishedVersionId: z.string().nullable().optional().describe("화면에서 본 발행 버전 id (발행 전이었으면 null). 생략하면 확인하지 않는다") });
|
|
2179
|
-
const rollbackStorefrontRequestSchema = z.object({
|
|
1846
|
+
const publishStorefrontVersionRequestSchema = strictRequest(z.object({ expectedPublishedVersionId: z.string().nullable().optional().describe("화면에서 본 발행 버전 id (발행 전이었으면 null). 생략하면 확인하지 않는다") }));
|
|
1847
|
+
const rollbackStorefrontRequestSchema = strictRequest(z.object({
|
|
2180
1848
|
versionId: z.string().optional().describe("되돌릴 버전. 생략하면 지금 버전 직전에 발행했던 버전"),
|
|
2181
1849
|
expectedPublishedVersionId: z.string().nullable().optional()
|
|
2182
|
-
});
|
|
2183
|
-
const changeStorefrontSlugRequestSchema = z.object({ slug: storefrontSlugSchema });
|
|
2184
|
-
const setStorefrontVisibilityRequestSchema = z.object({
|
|
1850
|
+
}));
|
|
1851
|
+
const changeStorefrontSlugRequestSchema = strictRequest(z.object({ slug: storefrontSlugSchema }));
|
|
1852
|
+
const setStorefrontVisibilityRequestSchema = strictRequest(z.object({
|
|
2185
1853
|
visibility: storefrontVisibilitySchema,
|
|
2186
1854
|
expectedVisibility: storefrontVisibilitySchema.optional().describe("화면에서 본 공개 상태. 주면 지금 값이 같을 때만 바꾼다")
|
|
2187
|
-
});
|
|
1855
|
+
}));
|
|
2188
1856
|
/** 호스팅 끄기 — 사이트를 닫고(`CLOSED`) 슬러그를 보류한다. 확인 입력은 받지 않는다(2026-10-22) */
|
|
2189
|
-
const disableStorefrontHostingRequestSchema = z.object({ confirmSlug: z.string().max(200).optional().describe("쓰지 않는다 — 보내도 무시한다(옛 확인 입력)") });
|
|
1857
|
+
const disableStorefrontHostingRequestSchema = strictRequest(z.object({ confirmSlug: z.string().max(200).optional().describe("쓰지 않는다 — 보내도 무시한다(옛 확인 입력)") }));
|
|
2190
1858
|
const storefrontSlugAvailabilityQuerySchema = z.object({ slug: z.string().describe("확인할 슬러그") });
|
|
2191
1859
|
/**
|
|
2192
1860
|
* 버전 미리보기 링크 — 상점 플랫폼에서 로그인한 OWNER·ADMIN만 받는다(PAT·에이전트 불가). 버전마다 미리보기 전용 주소가 있고
|
|
2193
1861
|
* (오픈 준비 중이어도 실제 화면), 링크를 5분 안에 열면 그 브라우저에 그 주소 전용 12시간 쿠키가 생긴다. 사이트 주소는 오픈 전이면
|
|
2194
1862
|
* 누구에게나 「오픈 준비 중」이다. 미리보기 주소에 쿠키 없이 들어오면 상점 플랫폼 로그인과 OWNER·ADMIN 확인을 거친다.
|
|
2195
1863
|
*/
|
|
2196
|
-
const createStorefrontPreviewLinkRequestSchema = z.object({
|
|
1864
|
+
const createStorefrontPreviewLinkRequestSchema = strictRequest(z.object({
|
|
2197
1865
|
path: z.string().max(512).optional().describe("열 경로 (`/`로 시작). 생략하면 `/`"),
|
|
2198
1866
|
versionId: z.string().max(64).optional().describe("볼 버전. 생략하면 발행 버전이다. 보관 기간이 지난 버전(`previewable: false`)은 409 `STOREFRONT_VERSION_NOT_PREVIEWABLE`")
|
|
2199
|
-
});
|
|
1867
|
+
}));
|
|
2200
1868
|
const storefrontPreviewLinkSchema = z.object({
|
|
2201
1869
|
url: z.string().describe("미리보기 링크 — 5분 안에 연다"),
|
|
2202
1870
|
editorUrl: z.string().optional().describe("편집 미리보기만: AI 편집 패널이 있는 미리보기 화면 링크(5분). 사이트는 그 안에 따로 뜨고 AI 자격은 사이트 코드에 닿지 않는다"),
|
|
@@ -2382,7 +2050,7 @@ const storefrontSiteDomainsSchema = z.object({
|
|
|
2382
2050
|
target: z.string().describe("CNAME 대상 (예: `sites.sayren.co`)"),
|
|
2383
2051
|
domains: z.array(storefrontSiteDomainSchema).describe("대표 주소 먼저, 그다음 추가한 순서")
|
|
2384
2052
|
});
|
|
2385
|
-
const addStorefrontDomainRequestSchema = z.object({ hostname: z.string().min(1).max(300).describe("연결할 도메인 (예: `shop.brand.com`). 서버가 소문자·punycode로 정규화한다") });
|
|
2053
|
+
const addStorefrontDomainRequestSchema = strictRequest(z.object({ hostname: z.string().min(1).max(300).describe("연결할 도메인 (예: `shop.brand.com`). 서버가 소문자·punycode로 정규화한다") }));
|
|
2386
2054
|
/** 플랫폼 전체 동시 편집 환경 상한 */
|
|
2387
2055
|
const STOREFRONT_EDIT_CAPACITY = 20;
|
|
2388
2056
|
/** 활동이 없으면 편집 환경이 잠드는 시간(분). 작업 트리는 보존된다 */
|
|
@@ -2475,11 +2143,11 @@ const storefrontEditSessionSchema = z.object({
|
|
|
2475
2143
|
* 편집 환경이 켜져 있지 않으면 409 `EDIT_SESSION_REQUIRED`
|
|
2476
2144
|
*/
|
|
2477
2145
|
/** `POST /v1/storefront/site/editing/git/merge` — 켜진 편집 환경 작업 트리에 운영 브랜치 최신 커밋을 합친다(#138, Git 원천 사이트) */
|
|
2478
|
-
const storefrontGitMergeRequestSchema = z.object({ action: z.enum([
|
|
2146
|
+
const storefrontGitMergeRequestSchema = strictRequest(z.object({ action: z.enum([
|
|
2479
2147
|
"merge",
|
|
2480
2148
|
"continue",
|
|
2481
2149
|
"abort"
|
|
2482
|
-
]).default("merge").describe("`merge` 최신 운영 브랜치를 합친다 · `continue` 충돌 표시를 고친 뒤 합치기를 끝낸다 · `abort` 합치기를 취소하고 합치기 전으로 돌린다") });
|
|
2150
|
+
]).default("merge").describe("`merge` 최신 운영 브랜치를 합친다 · `continue` 충돌 표시를 고친 뒤 합치기를 끝낸다 · `abort` 합치기를 취소하고 합치기 전으로 돌린다") }));
|
|
2483
2151
|
const storefrontGitMergeSchema = z.object({
|
|
2484
2152
|
status: z.enum([
|
|
2485
2153
|
"MERGED",
|
|
@@ -2554,12 +2222,12 @@ const storefrontFileContentSchema = z.object({
|
|
|
2554
2222
|
* 해시가 같아야 한다. 조건을 **모두** 확인한 뒤 쓰고, 하나라도 어긋나면 아무것도 쓰지 않는다(409 `FILE_CHANGED`,
|
|
2555
2223
|
* `error.details.conflicts`).
|
|
2556
2224
|
*/
|
|
2557
|
-
const writeStorefrontFilesRequestSchema = z.object({ files: z.array(z.object({
|
|
2225
|
+
const writeStorefrontFilesRequestSchema = strictRequest(z.object({ files: z.array(z.object({
|
|
2558
2226
|
path: storefrontFilePathSchema,
|
|
2559
2227
|
content: z.string().describe("내용 (`encoding`에 따라 텍스트 또는 base64)"),
|
|
2560
2228
|
encoding: storefrontFileEncodingSchema.optional().describe("기본 `utf8`"),
|
|
2561
2229
|
expectedHash: storefrontFileHashSchema.nullable().optional().describe("쓰기 조건. 생략 = 조건 없음 · null = 새 파일 · 값 = 지금 해시가 같을 때만")
|
|
2562
|
-
})).min(1).max(50).refine((files) => new Set(files.map((file) => file.path)).size === files.length, { message: "같은 경로를 두 번 실을 수 없습니다" }) });
|
|
2230
|
+
})).min(1).max(50).refine((files) => new Set(files.map((file) => file.path)).size === files.length, { message: "같은 경로를 두 번 실을 수 없습니다" }) }));
|
|
2563
2231
|
const storefrontFileWriteResultSchema = z.object({ files: z.array(storefrontFileEntrySchema).describe("쓴 파일의 새 해시·크기 (요청 순서)") });
|
|
2564
2232
|
/** 409 `FILE_CHANGED`의 `error.details` */
|
|
2565
2233
|
const storefrontFileConflictDetailsSchema = z.object({ conflicts: z.array(z.object({
|
|
@@ -2567,21 +2235,21 @@ const storefrontFileConflictDetailsSchema = z.object({ conflicts: z.array(z.obje
|
|
|
2567
2235
|
currentHash: storefrontFileHashSchema.nullable().describe("지금 해시. 파일이 없으면 null")
|
|
2568
2236
|
})) });
|
|
2569
2237
|
/** `POST /v1/storefront/site/files/delete` — 없는 파일이면 `deleted: false`(조건을 주면 409 `FILE_CHANGED`) */
|
|
2570
|
-
const deleteStorefrontFileRequestSchema = z.object({
|
|
2238
|
+
const deleteStorefrontFileRequestSchema = strictRequest(z.object({
|
|
2571
2239
|
path: storefrontFilePathSchema,
|
|
2572
2240
|
expectedHash: storefrontFileHashSchema.optional().describe("주면 지금 해시가 같을 때만 지운다")
|
|
2573
|
-
});
|
|
2241
|
+
}));
|
|
2574
2242
|
const storefrontFileDeleteResultSchema = z.object({
|
|
2575
2243
|
path: z.string(),
|
|
2576
2244
|
deleted: z.boolean()
|
|
2577
2245
|
});
|
|
2578
2246
|
/** `POST /v1/storefront/site/files/move` — 이름 바꾸기·옮기기 */
|
|
2579
|
-
const moveStorefrontFileRequestSchema = z.object({
|
|
2247
|
+
const moveStorefrontFileRequestSchema = strictRequest(z.object({
|
|
2580
2248
|
from: storefrontFilePathSchema,
|
|
2581
2249
|
to: storefrontFilePathSchema,
|
|
2582
2250
|
expectedHash: storefrontFileHashSchema.optional().describe("주면 `from`의 지금 해시가 같을 때만"),
|
|
2583
2251
|
overwrite: z.boolean().optional().describe("`to`에 파일이 있으면 덮는가 (기본 false → 409 `FILE_EXISTS`)")
|
|
2584
|
-
});
|
|
2252
|
+
}));
|
|
2585
2253
|
const storefrontFileMoveResultSchema = z.object({
|
|
2586
2254
|
from: z.string(),
|
|
2587
2255
|
to: z.string(),
|
|
@@ -2591,7 +2259,7 @@ const storefrontFileMoveResultSchema = z.object({
|
|
|
2591
2259
|
/** `POST /v1/storefront/site/files/search` — 텍스트 파일 내용 검색(편집 환경이 없어도 된다) */
|
|
2592
2260
|
/** 정규식 검색의 패턴 길이 상한 — 편집 Sandbox가 실행 비용을 막으려고 더 좁게 받는다(sandbox-api §4.6) */
|
|
2593
2261
|
const STOREFRONT_SEARCH_REGEX_MAX_LENGTH = 100;
|
|
2594
|
-
const searchStorefrontFilesRequestSchema = z.object({
|
|
2262
|
+
const searchStorefrontFilesRequestSchema = strictRequest(z.object({
|
|
2595
2263
|
query: z.string().min(1).max(200),
|
|
2596
2264
|
regex: z.boolean().optional().describe("`query`를 정규식으로 본다 (기본 false = 글자 그대로). 정규식은 100자까지이고 중첩 수량자(`(a+)+`)·반복되는 선택(`(a|b)+`)·역참조·뒤 보기, 가변 수량자(`*`·`+`·`?`·`{n,m}`, 넓은 범위는 2로 센다) 차수 4 초과는 400 `INVALID_REQUEST`다. 차수가 클수록 긴 줄은 건너뛰고 비용이 크면 `truncated`로 끊는다"),
|
|
2597
2265
|
caseSensitive: z.boolean().optional().describe("대소문자를 가리는가 (기본 false)"),
|
|
@@ -2600,7 +2268,7 @@ const searchStorefrontFilesRequestSchema = z.object({
|
|
|
2600
2268
|
}).refine((body) => !body.regex || body.query.length <= 100, {
|
|
2601
2269
|
message: `정규식은 100자까지입니다`,
|
|
2602
2270
|
path: ["query"]
|
|
2603
|
-
});
|
|
2271
|
+
}));
|
|
2604
2272
|
const storefrontFileSearchResultSchema = z.object({
|
|
2605
2273
|
matches: z.array(z.object({
|
|
2606
2274
|
path: z.string(),
|
|
@@ -2616,11 +2284,11 @@ const storefrontFileSearchResultSchema = z.object({
|
|
|
2616
2284
|
* `GET /v1/storefront/site/checks/{checkId}`로 조회한다(권장 2~3초 간격). 사이트당 끝나지 않은 검사는 하나다 — 같은 종류가 돌고
|
|
2617
2285
|
* 있으면 그 검사를 다시 돌려주고, 다른 종류면 409 `CHECK_RUNNING`(`error.details.checkId`)이다. 출력은 꼬리만 준다.
|
|
2618
2286
|
*/
|
|
2619
|
-
const runStorefrontCheckRequestSchema = z.object({ check: z.enum([
|
|
2287
|
+
const runStorefrontCheckRequestSchema = strictRequest(z.object({ check: z.enum([
|
|
2620
2288
|
"typecheck",
|
|
2621
2289
|
"lint",
|
|
2622
2290
|
"test"
|
|
2623
|
-
]) });
|
|
2291
|
+
]) }));
|
|
2624
2292
|
const storefrontCheckStatusSchema = z.enum([
|
|
2625
2293
|
"QUEUED",
|
|
2626
2294
|
"RUNNING",
|
|
@@ -2768,10 +2436,10 @@ const storefrontBuildListQuerySchema = z.object({ limit: z.coerce.number().int()
|
|
|
2768
2436
|
* `POST /v1/storefront/site/versions` — 지금 작업 트리를 고정해 버전을 만든다(빌드 시작). 사이트당 끝나지 않은 빌드는
|
|
2769
2437
|
* 하나다(409 `STOREFRONT_BUILD_IN_PROGRESS`). 편집 환경이 없어도 된다.
|
|
2770
2438
|
*/
|
|
2771
|
-
const createStorefrontVersionRequestSchema = z.object({
|
|
2439
|
+
const createStorefrontVersionRequestSchema = strictRequest(z.object({
|
|
2772
2440
|
message: z.string().max(200).optional().describe("버전 메모 (에이전트는 바꾼 내용 요약)"),
|
|
2773
2441
|
expectedSourceRef: z.string().max(200).optional().describe("고정할 작업 트리 (`PUT /v1/storefront/site/source`의 `sourceRef`). 주면 지금 작업 트리가 이 값일 때만 버전을 만든다(다르면 409 `SOURCE_CHANGED`)")
|
|
2774
|
-
});
|
|
2442
|
+
}));
|
|
2775
2443
|
/** 버전 만들기 응답 (201) — 버전은 `BUILDING`, 빌드는 `QUEUED`로 시작한다. 결과는 `GET builds/{buildId}`로 본다 */
|
|
2776
2444
|
const storefrontVersionCreatedSchema = z.object({
|
|
2777
2445
|
version: storefrontVersionSchema,
|
|
@@ -2782,7 +2450,7 @@ const storefrontVersionCreatedSchema = z.object({
|
|
|
2782
2450
|
* 받는다(PAT·에이전트 불가). 5분 안에 열면 그 브라우저에 미리보기 호스트 전용 쿠키(12시간)가 생긴다. 편집 환경이
|
|
2783
2451
|
* 없으면 409 `EDIT_SESSION_REQUIRED`다(편집 환경이 `STARTING`이면 링크는 주고, 미리보기 화면이 기동 대기를 보여 준다).
|
|
2784
2452
|
*/
|
|
2785
|
-
const createStorefrontEditPreviewLinkRequestSchema = z.object({ path: z.string().max(512).optional().describe("열 경로 (`/`로 시작). 생략하면 `/`") });
|
|
2453
|
+
const createStorefrontEditPreviewLinkRequestSchema = strictRequest(z.object({ path: z.string().max(512).optional().describe("열 경로 (`/`로 시작). 생략하면 `/`") }));
|
|
2786
2454
|
/** 압축 파일 조각 하나의 최대 크기(바이트) */
|
|
2787
2455
|
const STOREFRONT_SOURCE_PART_BYTES = 4194304;
|
|
2788
2456
|
/** 내용 올리기 한 번의 최대 파일 수 */
|
|
@@ -2824,10 +2492,10 @@ const storefrontSourceArchivePartSchema = z.object({
|
|
|
2824
2492
|
content: z.string().describe("조각 내용 (base64)")
|
|
2825
2493
|
});
|
|
2826
2494
|
/** `POST /v1/storefront/site/source/blobs` — 파일 내용 올리기(해시 키, 다시 올려도 안전하다). 작업 트리는 바뀌지 않는다 */
|
|
2827
|
-
const uploadStorefrontSourceBlobsRequestSchema = z.object({ blobs: z.array(z.object({
|
|
2495
|
+
const uploadStorefrontSourceBlobsRequestSchema = strictRequest(z.object({ blobs: z.array(z.object({
|
|
2828
2496
|
hash: storefrontFileHashSchema,
|
|
2829
2497
|
content: z.string().describe("파일 내용 (base64, 1MiB까지)")
|
|
2830
|
-
})).min(1).max(200) });
|
|
2498
|
+
})).min(1).max(200) }));
|
|
2831
2499
|
const storefrontSourceBlobsResultSchema = z.object({
|
|
2832
2500
|
stored: z.number().int().min(0).describe("새로 올린 수"),
|
|
2833
2501
|
existing: z.number().int().min(0).describe("이미 있던 수")
|
|
@@ -2836,7 +2504,7 @@ const storefrontSourceBlobsResultSchema = z.object({
|
|
|
2836
2504
|
* `PUT /v1/storefront/site/source` — 작업 트리 전체를 이 목록으로 바꾼다(없는 경로는 지운다). 전부 아니면 전무다.
|
|
2837
2505
|
* `package.json`·`pnpm-lock.yaml`도 바꿀 수 있고 의존성은 허용 목록 안이어야 한다. `.env*`·작업 트리 밖 경로는 받지 않는다.
|
|
2838
2506
|
*/
|
|
2839
|
-
const replaceStorefrontSourceRequestSchema = z.object({
|
|
2507
|
+
const replaceStorefrontSourceRequestSchema = strictRequest(z.object({
|
|
2840
2508
|
expectedBaseRef: storefrontSourceRefSchema.optional().describe("내려받은 작업 트리. 그 뒤 작업 트리가 바뀌었으면 이 트리를 기준으로 3-way 병합하고, 같은 곳을 고쳤으면 409 `SOURCE_CHANGED`다. 생략하면 조건 없이 덮어쓴다"),
|
|
2841
2509
|
files: z.array(z.object({
|
|
2842
2510
|
path: storefrontFilePathSchema,
|
|
@@ -2846,7 +2514,7 @@ const replaceStorefrontSourceRequestSchema = z.object({
|
|
|
2846
2514
|
endEditSession: z.boolean().optional().describe("열린 편집 환경을 끄고 진행한다 (기본 false — 열려 있으면 409 `EDIT_SESSION_OPEN`)"),
|
|
2847
2515
|
packageJson: z.string().max(STOREFRONT_FILE_MAX_BYTES).optional().describe("`files`에 `package.json`이 있으면 그 내용(utf8). 서버가 의존성을 판정한다. 해시가 목록과 다르면 400 `DEPENDENCY_FILES_MISMATCH`"),
|
|
2848
2516
|
lockfile: z.string().max(STOREFRONT_FILE_MAX_BYTES).optional().describe("`files`에 `pnpm-lock.yaml`이 있으면 그 내용(utf8)")
|
|
2849
|
-
});
|
|
2517
|
+
}));
|
|
2850
2518
|
const storefrontSourceReplacedSchema = z.object({
|
|
2851
2519
|
sourceRef: storefrontSourceRefSchema.describe("새 작업 트리(버전 만들기의 `expectedSourceRef`). 다음 올리기의 기준은 `uploadedRef`다"),
|
|
2852
2520
|
previousRef: z.string().describe("바꾸기 전 작업 트리"),
|
|
@@ -2888,25 +2556,25 @@ const storefrontGitRepositorySchema = z.object({
|
|
|
2888
2556
|
defaultBranch: z.string()
|
|
2889
2557
|
});
|
|
2890
2558
|
/** `POST /v1/storefront/site/git/installations` — GitHub App 설치 화면에서 돌아온 값(`installation_id`·`code`) */
|
|
2891
|
-
const linkStorefrontGitInstallationRequestSchema = z.object({
|
|
2559
|
+
const linkStorefrontGitInstallationRequestSchema = strictRequest(z.object({
|
|
2892
2560
|
installationId: z.number().int().positive(),
|
|
2893
2561
|
code: z.string().min(1).max(200).describe("설치 화면이 돌려준 GitHub 사용자 인증 코드(한 번만 쓴다)"),
|
|
2894
2562
|
state: z.string().min(1).max(200).describe("설치 화면으로 보내기 전에 받은 연결 state(`POST …/git/installations/state`, 한 번만 쓴다)")
|
|
2895
|
-
});
|
|
2563
|
+
}));
|
|
2896
2564
|
/** `POST /v1/storefront/site/git/installations/state` — GitHub 설치 화면에 싣는 1회용 state(이 상점·사용자, 10분) */
|
|
2897
2565
|
const storefrontGitConnectStateSchema = z.object({
|
|
2898
2566
|
state: z.string(),
|
|
2899
2567
|
expiresAt: z.string()
|
|
2900
2568
|
});
|
|
2901
2569
|
/** `POST /v1/storefront/site/git/connect` */
|
|
2902
|
-
const connectStorefrontGitRequestSchema = z.object({
|
|
2570
|
+
const connectStorefrontGitRequestSchema = strictRequest(z.object({
|
|
2903
2571
|
installationId: z.number().int().positive(),
|
|
2904
2572
|
repoId: z.number().int().positive(),
|
|
2905
2573
|
productionBranch: z.string().min(1).max(200).regex(/^[A-Za-z0-9._-]+(\/[A-Za-z0-9._-]+)*$/).optional().describe("운영 배포 브랜치(생략하면 저장소 기본 브랜치)"),
|
|
2906
2574
|
rootDirectory: z.string().max(200).regex(/^$|^[A-Za-z0-9._-]+(\/[A-Za-z0-9._-]+)*$/).refine((v) => !v.split("/").some((seg) => seg === "." || seg === ".."), "상대 경로만").optional().describe("저장소 안 사이트 루트(생략하면 저장소 루트)")
|
|
2907
|
-
});
|
|
2575
|
+
}));
|
|
2908
2576
|
/** `PUT /v1/storefront/site/deploy-approval` — 승인 없이 배포(#138) */
|
|
2909
|
-
const setStorefrontDeployApprovalRequestSchema = z.object({ deployWithoutApproval: z.boolean() });
|
|
2577
|
+
const setStorefrontDeployApprovalRequestSchema = strictRequest(z.object({ deployWithoutApproval: z.boolean() }));
|
|
2910
2578
|
//#endregion
|
|
2911
2579
|
//#region src/schemas/ai.ts
|
|
2912
2580
|
/**
|
|
@@ -2987,9 +2655,14 @@ const aiActivitySchema = z.enum([
|
|
|
2987
2655
|
"version",
|
|
2988
2656
|
"preview"
|
|
2989
2657
|
]);
|
|
2658
|
+
/** 바뀐 줄 미리보기 한 줄의 최대 길이 — 서버가 이 길이로 자르고 화면은 이보다 긴 줄을 앞부분으로 비교한다 */
|
|
2659
|
+
const AI_TOOL_CHANGE_LINE_MAX = 300;
|
|
2660
|
+
/** 바뀐 줄 범위(`lines`) 개수 상한 */
|
|
2661
|
+
const AI_TOOL_CHANGE_RANGES_MAX = 200;
|
|
2990
2662
|
/**
|
|
2991
2663
|
* 도구가 바꾼 파일 하나(2026-10-13, AI 상점 도우미 작업 공간의 수정 중인 코드) — 서버가 도구 입력으로 계산한다.
|
|
2992
|
-
* `edit`는 바꾼 부분의 줄 비교, `write`는 새로 쓴 내용(이전 내용을 모르므로 모두 추가로 센다). `preview`는 바뀐 줄 앞부분 12
|
|
2664
|
+
* `edit`는 바꾼 부분의 줄 비교, `write`는 새로 쓴 내용(이전 내용을 모르므로 모두 추가로 센다). `preview`는 바뀐 줄 앞부분 12줄까지다.
|
|
2665
|
+
* `lines`는 바꾼 뒤 파일에서 추가된 줄의 범위(1부터, 양끝 포함)다 — `edit`가 성공한 뒤에만 실행기가 채운다(옛 기록·`write`에는 없다)
|
|
2993
2666
|
*/
|
|
2994
2667
|
const aiToolChangeSchema = z.object({
|
|
2995
2668
|
path: z.string().max(300),
|
|
@@ -2999,7 +2672,8 @@ const aiToolChangeSchema = z.object({
|
|
|
2999
2672
|
preview: z.array(z.object({
|
|
3000
2673
|
kind: z.enum(["added", "removed"]),
|
|
3001
2674
|
text: z.string().max(300)
|
|
3002
|
-
})).max(12)
|
|
2675
|
+
})).max(12),
|
|
2676
|
+
lines: z.array(z.tuple([z.number().int().min(1), z.number().int().min(1)])).max(200).optional()
|
|
3003
2677
|
});
|
|
3004
2678
|
/**
|
|
3005
2679
|
* 에이전트 작업 단계(2026-10-13, AI 상점 도우미 작업 공간) — 에이전트가 패널 도구로 알린다.
|
|
@@ -3015,29 +2689,49 @@ const AI_AGENT_PHASES = [
|
|
|
3015
2689
|
];
|
|
3016
2690
|
const aiAgentPhaseSchema = z.enum(AI_AGENT_PHASES);
|
|
3017
2691
|
/**
|
|
3018
|
-
* AI 상점 도우미의 작업 메모 폴더(2026-10-14) — 회차마다 읽는 숨은 규칙(`rules.md`)과 디자인 계획(`design.md`).
|
|
3019
|
-
*
|
|
2692
|
+
* AI 상점 도우미의 작업 메모 폴더(2026-10-14) — 회차마다 읽는 숨은 규칙(`rules.md`)과 디자인 계획(`design.md`). 편집 Sandbox가 점(.)으로 시작하는
|
|
2693
|
+
* 경로를 받지 않아 작업 트리의 `src` 아래에 둔다(앱이 import하지 않는 문서라 빌드에 들어가지 않는다). 숨은 규칙은 셀러 화면(타임라인·코드 탭·변경 기록)에
|
|
2694
|
+
* 보이지 않는다. 디자인 계획은 2026-10-24부터 셀러 문서(작업 공간 문서 탭의 「디자인 가이드라인」)라 숨기지 않는다(`AI_DESIGN_GUIDE_PATH`)
|
|
3020
2695
|
*/
|
|
3021
2696
|
const AI_AGENT_NOTES_DIR = "src/site/agent";
|
|
2697
|
+
/** 디자인 가이드라인(디자인 계획) — 작업 메모 폴더에 있지만 셀러가 읽는 문서다 */
|
|
2698
|
+
const AI_DESIGN_GUIDE_PATH = `${AI_AGENT_NOTES_DIR}/design.md`;
|
|
2699
|
+
/** 사이트맵 — 에이전트가 쓰는 화면 구성 문서(`{version:1,pages:[…]}`) */
|
|
2700
|
+
const AI_SITEMAP_PATH = "src/site/sitemap.json";
|
|
2701
|
+
/** 작업 공간 문서 탭의 문서 파일인가(사이트맵·디자인 가이드라인) — 앱 코드가 아니라서 코드 탭·미리보기 점검·코드 변경 판정에서 뺀다 */
|
|
2702
|
+
function isAiWorkspaceDocPath(path) {
|
|
2703
|
+
return path === "src/site/sitemap.json" || path === AI_DESIGN_GUIDE_PATH;
|
|
2704
|
+
}
|
|
2705
|
+
/** 「이어서 진행」 버튼(실패한 실행 잇기)이 보내는 선택 값 — 선택지 답처럼 같은 할 일 목록을 잇는다 */
|
|
2706
|
+
const AI_RUN_RESUME_CHOICE = "run:resume";
|
|
3022
2707
|
/**
|
|
3023
2708
|
* 에이전트의 할 일 목록(2026-10-14, Claude Code의 TaskCreate·TaskUpdate·TaskList와 같다) — 에이전트가 패널 도구로 할 일을 만들고 상태를 바꾼다.
|
|
3024
|
-
* 이벤트·조각은 그 시점의 목록 전체이고 작업 공간
|
|
2709
|
+
* 이벤트·조각은 그 시점의 목록 전체이고 작업 공간 로드맵 탭이 마지막 목록을 칸반으로 그린다. 진행중은 한 번에 하나다.
|
|
2710
|
+
* 목록은 셀러 요청 하나(사이클)의 일이다 — 새 요청이면 빈 목록에서 시작하고 선택지 답이면 잇는다(2026-10-24). 개수 상한은 없다
|
|
2711
|
+
* (옛 30개 상한은 대화 전체에 할 일이 쌓여 넘쳤다 — 크기는 사이클 범위가, 폭주는 턴 예산이 막는다).
|
|
2712
|
+
* `blocked`는 같은 문제를 거듭 고쳐도 남아 멈춘 일이고 `note`가 그 사유다(이어 가기 리마인더가 남은 일로 세지 않는다)
|
|
3025
2713
|
*/
|
|
3026
2714
|
const AI_TODO_STATUSES = [
|
|
3027
2715
|
"pending",
|
|
3028
2716
|
"in_progress",
|
|
3029
|
-
"completed"
|
|
2717
|
+
"completed",
|
|
2718
|
+
"blocked"
|
|
3030
2719
|
];
|
|
3031
2720
|
const aiTodoSchema = z.object({
|
|
3032
|
-
/** 할 일 번호(
|
|
2721
|
+
/** 할 일 번호(사이클 안에서 1부터) — 옛 조각에는 없다 */
|
|
3033
2722
|
id: z.string().max(10).optional(),
|
|
3034
2723
|
content: z.string().min(1).max(200),
|
|
3035
2724
|
status: z.enum(AI_TODO_STATUSES),
|
|
3036
2725
|
/** 이 할 일이 속한 작업 단계 — 진행중이 되면 실행기가 단계를 알린다(2026-10-14, 모델이 단계 알림을 빠뜨렸다) */
|
|
3037
|
-
phase: aiAgentPhaseSchema.optional()
|
|
2726
|
+
phase: aiAgentPhaseSchema.optional(),
|
|
2727
|
+
/** 막힌 사유(`blocked`일 때만) */
|
|
2728
|
+
note: z.string().max(300).optional()
|
|
3038
2729
|
});
|
|
2730
|
+
/** @deprecated 할 일 개수 상한은 없앴다(2026-10-24). 공개 export라 값만 남긴다 */
|
|
3039
2731
|
const AI_TODOS_MAX = 30;
|
|
2732
|
+
/** 셀러에게 보이지 않는 작업 메모인가 — 작업 메모 폴더에서 디자인 가이드라인을 뺀 나머지다 */
|
|
3040
2733
|
function isAiAgentNotesPath(path) {
|
|
2734
|
+
if (path === AI_DESIGN_GUIDE_PATH) return false;
|
|
3041
2735
|
return path === "src/site/agent" || path.startsWith(`src/site/agent/`);
|
|
3042
2736
|
}
|
|
3043
2737
|
/**
|
|
@@ -3148,7 +2842,9 @@ const AI_DESIGN_CONFIRM_APPROVE = "design:approve";
|
|
|
3148
2842
|
const aiMessagePartSchema = z.discriminatedUnion("type", [
|
|
3149
2843
|
z.object({
|
|
3150
2844
|
type: z.literal("text"),
|
|
3151
|
-
text: z.string()
|
|
2845
|
+
text: z.string(),
|
|
2846
|
+
/** 셀러가 선택지 버튼으로 보낸 답의 값(사용자 메시지만) — 할 일 목록(사이클)을 잇는 기준(`isAiChoiceAnswer`) */
|
|
2847
|
+
choice: z.string().max(200).optional()
|
|
3152
2848
|
}),
|
|
3153
2849
|
z.object({
|
|
3154
2850
|
type: z.literal("tool"),
|
|
@@ -3213,7 +2909,7 @@ const aiMessagePartSchema = z.discriminatedUnion("type", [
|
|
|
3213
2909
|
}),
|
|
3214
2910
|
z.object({
|
|
3215
2911
|
type: z.literal("todos"),
|
|
3216
|
-
todos: z.array(aiTodoSchema)
|
|
2912
|
+
todos: z.array(aiTodoSchema)
|
|
3217
2913
|
})
|
|
3218
2914
|
]);
|
|
3219
2915
|
const aiMessageSchema = z.object({
|
|
@@ -3249,18 +2945,18 @@ const storeSetupBriefSchema = z.object({
|
|
|
3249
2945
|
heroProduct: z.string().trim().max(500).describe("첫 화면에 크게 걸 상품 (비우면 AI가 정한다)"),
|
|
3250
2946
|
slug: storefrontSlugSchema.optional().describe("바라는 스토어프론트 주소")
|
|
3251
2947
|
});
|
|
3252
|
-
const createAiConversationRequestSchema = z.object({
|
|
2948
|
+
const createAiConversationRequestSchema = strictRequest(z.object({
|
|
3253
2949
|
/** 웹사이트에서 남긴 초안(#124 M2) — 연결한 사용자만 쓴다. 주면 첫 메시지로 실행을 시작한다 */
|
|
3254
2950
|
draftId: z.string().max(64).optional(),
|
|
3255
2951
|
/** 질문 화면의 답 — `draftId`와 함께만 쓴다. 초안 앞에 붙어 첫 메시지가 된다 */
|
|
3256
2952
|
brief: storeSetupBriefSchema.optional()
|
|
3257
|
-
});
|
|
2953
|
+
}));
|
|
3258
2954
|
const createAiConversationResponseSchema = z.object({
|
|
3259
2955
|
conversation: aiConversationSummarySchema,
|
|
3260
2956
|
/** `draftId`로 시작했으면 첫 실행 */
|
|
3261
2957
|
run: aiStreamAccessSchema.nullable()
|
|
3262
2958
|
});
|
|
3263
|
-
const sendAiMessageRequestSchema = z.object({
|
|
2959
|
+
const sendAiMessageRequestSchema = strictRequest(z.object({
|
|
3264
2960
|
text: z.string().trim().max(AI_MESSAGE_MAX_CHARS),
|
|
3265
2961
|
attachments: z.array(aiAttachmentSchema).max(5).default([]),
|
|
3266
2962
|
/** 선택지 버튼으로 보낸 답이면 그 값(화면 표시는 `text`) */
|
|
@@ -3269,7 +2965,7 @@ const sendAiMessageRequestSchema = z.object({
|
|
|
3269
2965
|
selection: aiPreviewSelectionSchema.optional(),
|
|
3270
2966
|
/** 디자인 탭에서 고른 아트보드(2026-10-14) — 모델은 그 아트보드를 기준으로 고친다 */
|
|
3271
2967
|
designSelection: aiDesignSelectionSchema.optional()
|
|
3272
|
-
}).refine((body) => body.text.length > 0 || body.attachments.length > 0, { message: "내용이나 첨부가 있어야 합니다" });
|
|
2968
|
+
}).refine((body) => body.text.length > 0 || body.attachments.length > 0, { message: "내용이나 첨부가 있어야 합니다" }));
|
|
3273
2969
|
const sendAiMessageResponseSchema = aiStreamAccessSchema.extend({ messageId: z.string() });
|
|
3274
2970
|
/**
|
|
3275
2971
|
* AI가 바꾸는 화면 영역 — 쓰기 도구가 시작되면 이벤트에 싣고, 패널이 그 화면으로 옮겨 반영된 데이터를 다시 읽는다(셀러가 AI가 하는 일을 같이 본다).
|
|
@@ -3374,7 +3070,7 @@ const aiStreamEventSchema = z.discriminatedUnion("type", [
|
|
|
3374
3070
|
z.object({
|
|
3375
3071
|
type: z.literal("todos"),
|
|
3376
3072
|
messageId: z.string(),
|
|
3377
|
-
todos: z.array(aiTodoSchema)
|
|
3073
|
+
todos: z.array(aiTodoSchema)
|
|
3378
3074
|
}),
|
|
3379
3075
|
z.object({
|
|
3380
3076
|
type: z.literal("tool_start"),
|
|
@@ -3398,7 +3094,9 @@ const aiStreamEventSchema = z.discriminatedUnion("type", [
|
|
|
3398
3094
|
"error",
|
|
3399
3095
|
"unknown"
|
|
3400
3096
|
]),
|
|
3401
|
-
summary: z.string().nullable()
|
|
3097
|
+
summary: z.string().nullable(),
|
|
3098
|
+
/** 결과로 확정한 변경(바뀐 줄 범위 포함) — 있으면 `tool_start`의 `changes`를 바꾼다 */
|
|
3099
|
+
changes: z.array(aiToolChangeSchema).max(10).optional()
|
|
3402
3100
|
}),
|
|
3403
3101
|
z.object({
|
|
3404
3102
|
type: z.literal("choices"),
|
|
@@ -3452,13 +3150,13 @@ const STORE_DRAFT_MAX_ATTACHMENTS = 5;
|
|
|
3452
3150
|
const STORE_DRAFT_ATTACHMENT_MAX_BYTES = 10485760;
|
|
3453
3151
|
/** 연결하지 않은 초안을 지우기까지 */
|
|
3454
3152
|
const STORE_DRAFT_RETENTION_DAYS = 7;
|
|
3455
|
-
const createStoreDraftRequestSchema = z.object({
|
|
3153
|
+
const createStoreDraftRequestSchema = strictRequest(z.object({
|
|
3456
3154
|
text: z.string().trim().min(1).max(AI_MESSAGE_MAX_CHARS),
|
|
3457
3155
|
attachments: z.array(z.object({
|
|
3458
3156
|
filename: z.string().trim().min(1).max(200),
|
|
3459
3157
|
size: z.number().int().positive().max(STORE_DRAFT_ATTACHMENT_MAX_BYTES)
|
|
3460
3158
|
})).max(5).default([])
|
|
3461
|
-
});
|
|
3159
|
+
}));
|
|
3462
3160
|
const createStoreDraftResponseSchema = z.object({
|
|
3463
3161
|
draftId: z.string(),
|
|
3464
3162
|
/** 첨부마다 브라우저가 파일을 그대로 PUT할 자리(요청 순서와 같다) */
|
|
@@ -3489,6 +3187,14 @@ const storeDraftPreviewSchema = z.object({
|
|
|
3489
3187
|
/** 이미 상점에서 쓴 초안이면 true(다시 시작할 수 없다) */
|
|
3490
3188
|
used: z.boolean()
|
|
3491
3189
|
});
|
|
3190
|
+
/**
|
|
3191
|
+
* 셀러 메시지가 선택지에서 고른 답인가(조각에 `choice`가 있다) — 할 일 목록은 셀러 요청 하나(사이클)의 일이고, 고른 답(선택지·만들기 확인·계획 승인·발행 확인·
|
|
3192
|
+
* 「이어서 진행」)은 같은 사이클을 잇고 새로 쓴 글은 새 사이클이다(2026-10-24). api(`currentCycleRows`)와 상점 플랫폼(로드맵)이 이 판정 하나를 쓴다.
|
|
3193
|
+
* 직전 답에 선택지가 있었는지로 가르면 선택지를 무시하고 새 요청을 쓴 경우도 옛 사이클에 묶였다
|
|
3194
|
+
*/
|
|
3195
|
+
function isAiChoiceAnswer(parts) {
|
|
3196
|
+
return parts.some((part) => part.type === "text" && Boolean(part.choice));
|
|
3197
|
+
}
|
|
3492
3198
|
//#endregion
|
|
3493
3199
|
//#region src/schemas/analytics.ts
|
|
3494
3200
|
/**
|
|
@@ -4135,7 +3841,7 @@ const claimHoldResultSchema = z.object({
|
|
|
4135
3841
|
claimId: z.string(),
|
|
4136
3842
|
holdExpiresAt: z.string()
|
|
4137
3843
|
});
|
|
4138
|
-
const rejectClaimRequestSchema = z.object({
|
|
3844
|
+
const rejectClaimRequestSchema = strictRequest(z.object({
|
|
4139
3845
|
reason: z.enum([
|
|
4140
3846
|
"USED_PRODUCT",
|
|
4141
3847
|
"MISSING_COMPONENT",
|
|
@@ -4145,7 +3851,7 @@ const rejectClaimRequestSchema = z.object({
|
|
|
4145
3851
|
]),
|
|
4146
3852
|
detail: z.string().min(10).max(1e3),
|
|
4147
3853
|
evidenceImages: z.array(z.url()).max(5).optional()
|
|
4148
|
-
});
|
|
3854
|
+
}));
|
|
4149
3855
|
const approveClaimResultSchema = z.object({
|
|
4150
3856
|
claimId: z.string(),
|
|
4151
3857
|
refundAmount: z.number().int().describe("실제 환불한 금액 — 수량 비율 상품 실결제 금액(쿠폰 배분을 뺀 금액) + 배송비 환불 − 반품 배송비 − 조건부 무료배송 미달 차감 − 쿠폰 조건 미달 차감(`couponChargeAmount`) + 되돌린 쿠폰 차감(`couponChargeRefundAmount`) − 추가 차감(`deductAmount`)"),
|
|
@@ -4328,12 +4034,12 @@ const storePointPolicySchema = z.object({
|
|
|
4328
4034
|
* `PUT /v1/store/point-policy` 본문 — 준 항목만 바꾼다(생략 = 저장된 값 유지). 리뷰 적립·구매 적립 중 하나라도 켜면 유효 기간이 있어야 한다
|
|
4329
4035
|
* (본문이나 저장된 값, 없으면 400 `POINT_EXPIRY_REQUIRED`).
|
|
4330
4036
|
*/
|
|
4331
|
-
const updatePointPolicyRequestSchema = z.object({
|
|
4037
|
+
const updatePointPolicyRequestSchema = strictRequest(z.object({
|
|
4332
4038
|
reviewReward: reviewRewardPolicySchema.optional(),
|
|
4333
4039
|
purchaseEarn: purchaseEarnPolicySchema.optional(),
|
|
4334
4040
|
use: pointUsePolicySchema.optional(),
|
|
4335
4041
|
expiryDays: expiryDays.optional()
|
|
4336
|
-
});
|
|
4042
|
+
}));
|
|
4337
4043
|
/** 응답의 원장 유형 — 값이 추가될 수 있어 문자열로 받는다 */
|
|
4338
4044
|
const responsePointEntryTypeSchema = z.union([z.enum(POINT_ENTRY_TYPES), z.string()]).describe("유형. `EARN_REVIEW` 리뷰 적립 · `REVOKE_REVIEW` 리뷰 삭제 회수 · `EARN_PURCHASE` 구매 적립 · `EXPIRE` 소멸 · `ADJUST` 셀러 지급·차감 · `OPENING` 기존 잔액 이전 · `USE_RESERVE` 결제 사용(결제 시작 때 빠짐) · `USE_RELEASE` 결제가 실패·만료되어 되돌림 · `REFUND_RESTORE` 취소·반품 환불로 반환. 값이 추가될 수 있어 문자열로 받는다");
|
|
4339
4045
|
/** 원장 항목 — 셀러 조회용(사유·행위자 포함) */
|
|
@@ -4380,14 +4086,14 @@ const POINT_ADJUSTMENT_MAX = 1e7;
|
|
|
4380
4086
|
* 지급의 소멸 시각은 `expiresAt`(생략하면 정책 유효 기간, 정책이 없으면 400 `POINT_EXPIRY_REQUIRED`), 차감은 소멸이 이른 적립금부터 뺀다
|
|
4381
4087
|
* (잔액보다 많으면 409 `POINT_BALANCE_INSUFFICIENT`).
|
|
4382
4088
|
*/
|
|
4383
|
-
const pointAdjustmentRequestSchema = z.object({
|
|
4089
|
+
const pointAdjustmentRequestSchema = strictRequest(z.object({
|
|
4384
4090
|
amount: z.number().int().min(-1e7).max(POINT_ADJUSTMENT_MAX).refine((value) => value !== 0, "0원은 조정할 수 없습니다").describe("지급은 양수, 차감은 음수(원)"),
|
|
4385
4091
|
reason: z.string().trim().min(1).max(200).describe("사유(필수). 구매자에게는 보이지 않는다"),
|
|
4386
4092
|
expiresAt: z.iso.datetime({ offset: true }).optional().describe("지급분의 소멸 시각. 생략하면 정책 유효 기간(`expiryDays`)으로 정한다. **정책 유효 기간이 없으면 지급에 필수다**(없으면 400 `POINT_EXPIRY_REQUIRED`). 차감에는 주지 않는다")
|
|
4387
4093
|
}).refine((value) => !(value.amount < 0 && value.expiresAt), {
|
|
4388
4094
|
message: "차감에는 소멸 시각을 줄 수 없습니다",
|
|
4389
4095
|
path: ["expiresAt"]
|
|
4390
|
-
});
|
|
4096
|
+
}));
|
|
4391
4097
|
const pointAdjustmentResultSchema = z.object({
|
|
4392
4098
|
entry: pointEntrySchema,
|
|
4393
4099
|
balance: z.number().int().describe("조정 뒤 잔액")
|
|
@@ -4478,7 +4184,7 @@ const productNoticeSchema = z.object({
|
|
|
4478
4184
|
values: z.record(z.string(), z.string()).describe("칸 키 → 셀러가 적은 값. 비운 칸은 없다")
|
|
4479
4185
|
});
|
|
4480
4186
|
const MAX_NOTICE_VALUE_LENGTH = 1500;
|
|
4481
|
-
const productNoticeRequestSchema = z.
|
|
4187
|
+
const productNoticeRequestSchema = z.strictObject({
|
|
4482
4188
|
schemaId: z.string().trim().min(1).max(50).describe("품목군 코드(`GET /v1/info-schemas`)"),
|
|
4483
4189
|
version: z.number().int().positive().optional().describe("품목군 버전. 생략하면 현재 버전"),
|
|
4484
4190
|
values: z.record(z.string().max(50), z.string().max(MAX_NOTICE_VALUE_LENGTH)).default({}).describe("칸 키 → 값. 출처가 `legal`인 칸은 받지 않는다(400). 빈 문자열은 비운 칸으로 저장하지 않는다. 칸 길이는 스키마 `maxLength`")
|
|
@@ -4502,13 +4208,13 @@ const productCertificationsSchema = z.object({
|
|
|
4502
4208
|
number: z.string().describe("인증 번호")
|
|
4503
4209
|
})).describe("인증서. 배열 순서가 표시 순서다")
|
|
4504
4210
|
});
|
|
4505
|
-
const productCertificationsRequestSchema = z.
|
|
4506
|
-
subjects: z.array(z.
|
|
4211
|
+
const productCertificationsRequestSchema = z.strictObject({
|
|
4212
|
+
subjects: z.array(z.strictObject({
|
|
4507
4213
|
subject: z.string().trim().min(1).max(50),
|
|
4508
4214
|
status: z.enum(CERTIFICATION_STATUSES),
|
|
4509
4215
|
exemption: z.string().trim().min(1).max(50).nullish()
|
|
4510
4216
|
})).max(20).default([]).describe("인증 대상 여부. `REQUIRED`인데 그 대상의 인증 종류(`attrs.kinds`) 인증서가 `items`에 없으면 400 `CERTIFICATION_REQUIRED`, `EXEMPT`인데 사유가 없거나 대상이 허용하지 않는 사유면 400 `CERTIFICATION_EXEMPTION_INVALID`"),
|
|
4511
|
-
items: z.array(z.
|
|
4217
|
+
items: z.array(z.strictObject({
|
|
4512
4218
|
kind: z.string().trim().min(1).max(50),
|
|
4513
4219
|
agency: z.string().trim().max(100).nullish(),
|
|
4514
4220
|
number: z.string().trim().min(1).max(100)
|
|
@@ -4530,11 +4236,11 @@ const infoSectionSchema = z.object({
|
|
|
4530
4236
|
createdAt: z.string(),
|
|
4531
4237
|
updatedAt: z.string()
|
|
4532
4238
|
});
|
|
4533
|
-
const infoSectionRequestSchema = z.object({
|
|
4239
|
+
const infoSectionRequestSchema = strictRequest(z.object({
|
|
4534
4240
|
title: z.string().trim().min(1).max(100),
|
|
4535
4241
|
body: z.string().default(""),
|
|
4536
4242
|
bodyJson: z.string().nullable().optional()
|
|
4537
|
-
});
|
|
4243
|
+
}));
|
|
4538
4244
|
/**
|
|
4539
4245
|
* 안내 섹션 번역 (이슈 #134) — 언어 하나의 제목·본문. 섹션 필드는 상점 기본 언어 값이다. 비운 칸(null)은 스토어프론트가 기본 언어 값으로 대체한다.
|
|
4540
4246
|
* 섹션을 연결한 모든 상품이 같은 번역을 보인다.
|
|
@@ -4607,14 +4313,14 @@ const calendarQuerySchema = z.object({
|
|
|
4607
4313
|
* 달력 설정 — 기간의 날짜마다 재고·가격을 덮어쓴다(없는 날은 만든다). `stock`·`price`는 준 것만 바꾸고, `price: null`은 조합 가격으로
|
|
4608
4314
|
* 되돌린다. `daysOfWeek`(0=일~6=토)를 주면 그 요일만 바꾼다
|
|
4609
4315
|
*/
|
|
4610
|
-
const setCalendarRequestSchema = z.object({
|
|
4316
|
+
const setCalendarRequestSchema = strictRequest(z.object({
|
|
4611
4317
|
variantIds: z.array(z.string()).min(1).max(50),
|
|
4612
4318
|
from: calendarDateSchema,
|
|
4613
4319
|
to: calendarDateSchema,
|
|
4614
4320
|
stock: z.number().int().min(0).max(1e5).optional(),
|
|
4615
4321
|
price: z.number().int().min(0).multipleOf(10).nullable().optional(),
|
|
4616
4322
|
daysOfWeek: z.array(z.number().int().min(0).max(6)).min(1).max(7).optional()
|
|
4617
|
-
}).refine((value) => value.stock !== void 0 || value.price !== void 0, { message: "stock이나 price 중 하나는 있어야 합니다" });
|
|
4323
|
+
}).refine((value) => value.stock !== void 0 || value.price !== void 0, { message: "stock이나 price 중 하나는 있어야 합니다" }));
|
|
4618
4324
|
//#endregion
|
|
4619
4325
|
//#region src/schemas/upload.ts
|
|
4620
4326
|
/**
|
|
@@ -4720,11 +4426,11 @@ function uploadRejection(purpose, filename, size) {
|
|
|
4720
4426
|
* 끝나면 `url`이 공개 주소가 된다. 서버가 객체 키를 정하므로 요청은 파일명만 보낸다
|
|
4721
4427
|
* (확장자만 쓰이고 이름 자체는 저장되지 않는다).
|
|
4722
4428
|
*/
|
|
4723
|
-
const uploadRequestSchema = z.object({
|
|
4429
|
+
const uploadRequestSchema = strictRequest(z.object({
|
|
4724
4430
|
filename: z.string().min(1).max(255),
|
|
4725
4431
|
purpose: uploadPurposeSchema.default("description").describe("업로드 용도. 허용 확장자와 크기 상한이 용도별로 다르다"),
|
|
4726
4432
|
size: z.number().int().positive().optional().describe("파일 바이트 크기. 주면 용도별 상한을 발급 전에 검사한다")
|
|
4727
|
-
});
|
|
4433
|
+
}));
|
|
4728
4434
|
const uploadTicketSchema = z.object({
|
|
4729
4435
|
/** 업로드 완료 후 공개될 주소 */
|
|
4730
4436
|
url: z.url(),
|
|
@@ -4905,7 +4611,7 @@ function customInputLabelForbiddenWord(label) {
|
|
|
4905
4611
|
}
|
|
4906
4612
|
/** 옵션명·값 이름 — 앞뒤 공백을 지우고 빈 값은 받지 않는다 */
|
|
4907
4613
|
const optionNameSchema = z.string().trim().min(1).max(50);
|
|
4908
|
-
const addonValueRequestSchema = z.
|
|
4614
|
+
const addonValueRequestSchema = z.strictObject({
|
|
4909
4615
|
/** 전달 시 기존 값 행을 유지(UPDATE). 생략하면 신규 발급 */
|
|
4910
4616
|
valueId: z.string().optional(),
|
|
4911
4617
|
name: optionNameSchema,
|
|
@@ -4913,14 +4619,14 @@ const addonValueRequestSchema = z.object({
|
|
|
4913
4619
|
prices: additionalCurrencyPricesSchema.optional(),
|
|
4914
4620
|
usable: z.boolean().default(true)
|
|
4915
4621
|
});
|
|
4916
|
-
const addonGroupRequestSchema = z.
|
|
4622
|
+
const addonGroupRequestSchema = z.strictObject({
|
|
4917
4623
|
/** 전달 시 기존 옵션명 행을 유지(UPDATE). 조합 옵션명의 id는 줄 수 없다(방식을 바꾸려면 새 옵션명으로 보낸다) */
|
|
4918
4624
|
groupId: z.string().optional(),
|
|
4919
4625
|
name: optionNameSchema,
|
|
4920
4626
|
required: z.boolean().default(false),
|
|
4921
4627
|
values: z.array(addonValueRequestSchema).min(1).max(100)
|
|
4922
4628
|
});
|
|
4923
|
-
const customInputRequestSchema = z.
|
|
4629
|
+
const customInputRequestSchema = z.strictObject({
|
|
4924
4630
|
/** 전달 시 기존 항목 행을 유지(UPDATE). 생략하면 신규 발급 */
|
|
4925
4631
|
inputId: z.string().optional(),
|
|
4926
4632
|
label: z.string().trim().min(1).max(30),
|
|
@@ -5048,18 +4754,18 @@ function productImageRejection(url) {
|
|
|
5048
4754
|
* (`WHERE ... is not null`)의 판정이 갈려 409 대신 500이 나간다.
|
|
5049
4755
|
*/
|
|
5050
4756
|
const codeSchema = z.string().trim().min(1).max(64);
|
|
5051
|
-
const optionValueRequestSchema = z.
|
|
4757
|
+
const optionValueRequestSchema = z.strictObject({
|
|
5052
4758
|
/** 전달 시 기존 값 행을 유지(UPDATE). 생략하면 신규 발급 */
|
|
5053
4759
|
valueId: z.string().optional(),
|
|
5054
4760
|
name: z.string().min(1).max(50)
|
|
5055
4761
|
});
|
|
5056
|
-
const optionGroupRequestSchema = z.
|
|
4762
|
+
const optionGroupRequestSchema = z.strictObject({
|
|
5057
4763
|
/** 전달 시 기존 축 행을 유지(UPDATE). 생략하면 신규 발급 */
|
|
5058
4764
|
groupId: z.string().optional(),
|
|
5059
4765
|
name: z.string().min(1).max(50),
|
|
5060
4766
|
values: z.array(optionValueRequestSchema).min(1).max(100)
|
|
5061
4767
|
});
|
|
5062
|
-
const productVariantRequestSchema = z.
|
|
4768
|
+
const productVariantRequestSchema = z.strictObject({
|
|
5063
4769
|
/** 기존 variant 유지 시 전달. 생략하면 신규 생성 */
|
|
5064
4770
|
variantId: z.string().optional(),
|
|
5065
4771
|
/** optionGroups 순서대로 각 축에서 고른 값 이름. 서버가 이름 → valueId를 해석한다 */
|
|
@@ -5081,7 +4787,7 @@ const productVariantRequestSchema = z.object({
|
|
|
5081
4787
|
attributes: z.record(z.string().regex(/^[a-z][a-zA-Z0-9_]{0,39}$/), z.string().max(100)).refine((value) => Object.keys(value).length <= 10, { message: "조합 속성은 10개까지입니다" }).optional().describe("조합 속성(이슈 #115) — 키 → 값 문자열(예: 회차 일시 `showAt`). 플로우가 `item.option.<키>`로 읽고 타입(날짜·숫자 등)은 플로우가 선언한다. 생략하면 지금 값 유지(새 조합은 없음), `{}`면 비운다")
|
|
5082
4788
|
});
|
|
5083
4789
|
/** 축 × 값 → variant 전체 교체 요청 (PUT /products/{productId}/options) */
|
|
5084
|
-
const optionModelRequestSchema = z.
|
|
4790
|
+
const optionModelRequestSchema = z.strictObject({
|
|
5085
4791
|
optionGroups: z.array(optionGroupRequestSchema).max(3).default([]),
|
|
5086
4792
|
variants: z.array(productVariantRequestSchema).min(1).max(500),
|
|
5087
4793
|
addonGroups: z.array(addonGroupRequestSchema).max(5).optional().describe("추가 선택 옵션명 전체(이슈 #59). 주면 통째로 바꾸고, 생략하면 등록은 없음·수정은 현재 값을 그대로 둔다. 끄려면 빈 배열을 보낸다"),
|
|
@@ -5141,7 +4847,7 @@ const productWriteShape = {
|
|
|
5141
4847
|
*/
|
|
5142
4848
|
descriptionJson: z.string().nullable().optional(),
|
|
5143
4849
|
images: productImagesRequestSchema.optional().describe("상품 이미지 주소 목록. 첫 장이 대표 이미지(썸네일)다"),
|
|
5144
|
-
attributes: z.array(z.
|
|
4850
|
+
attributes: z.array(z.strictObject({
|
|
5145
4851
|
attributeId: z.string(),
|
|
5146
4852
|
value: z.string()
|
|
5147
4853
|
})).optional(),
|
|
@@ -5192,12 +4898,12 @@ const productListQuerySchema = z.object({
|
|
|
5192
4898
|
sort: productSortSchema.optional().describe("정렬 (기본 createdAt.desc)"),
|
|
5193
4899
|
...pageQueryShape()
|
|
5194
4900
|
});
|
|
5195
|
-
const discountRequestSchema = z.object({
|
|
4901
|
+
const discountRequestSchema = strictRequest(z.object({
|
|
5196
4902
|
discountType: z.enum(["RATE", "AMOUNT"]),
|
|
5197
4903
|
discountValue: z.number().int().min(1),
|
|
5198
4904
|
startAt: z.string().optional(),
|
|
5199
4905
|
endAt: z.string().optional()
|
|
5200
|
-
});
|
|
4906
|
+
}));
|
|
5201
4907
|
//#endregion
|
|
5202
4908
|
//#region src/schemas/webhook-event.ts
|
|
5203
4909
|
const envelopeFields = {
|
|
@@ -6190,7 +5896,7 @@ const webhookDeliveryListQuerySchema = z.object({
|
|
|
6190
5896
|
});
|
|
6191
5897
|
/** 실패 건 일괄 재전송 응답 — `POST /webhooks/{id}/deliveries/redeliver-failed` */
|
|
6192
5898
|
const webhookRedeliverFailedResultSchema = z.object({ queued: z.number().int().min(0).describe("재전송 대기열에 올린 건수. 최근 72시간의 `FAILED` 중 아직 재전송되지 않은 건이 대상이며 최대 500건이다") });
|
|
6193
|
-
const webhookTestRequestSchema = z.object({ eventType: eventTypeSchema.describe("샘플 페이로드로 보낼 이벤트 타입") });
|
|
5899
|
+
const webhookTestRequestSchema = strictRequest(z.object({ eventType: eventTypeSchema.describe("샘플 페이로드로 보낼 이벤트 타입") }));
|
|
6194
5900
|
/** 테스트 이벤트 발송 결과 (동기 반환). 재시도·정지 판정·전송 기록이 없다 */
|
|
6195
5901
|
const webhookTestResultSchema = z.object({
|
|
6196
5902
|
responseStatusCode: z.number().int().nullable().describe("수신 서버의 HTTP 응답 코드. 연결 실패·타임아웃·차단이면 null"),
|
|
@@ -6406,10 +6112,10 @@ const appInstallationActivitySchema = z.object({
|
|
|
6406
6112
|
* - `{ result }`: accounts 설치 동의 결과(1회용 JWT). 개발자 포털 [내 상점에 설치]가 이 길로 온다
|
|
6407
6113
|
* - `{ appId, settings }`: 상점 플랫폼 앱 목록 › 설치 화면에서 동의하고 설정까지 채워 바로 설치한다
|
|
6408
6114
|
*/
|
|
6409
|
-
const appInstallRequestSchema = z.union([z.object({ result: z.string().min(1).describe("accounts가 발급한 설치 결과 JWT(`typ: sayren-install+jwt`)") }), z.object({
|
|
6115
|
+
const appInstallRequestSchema = strictRequest(z.union([z.object({ result: z.string().min(1).describe("accounts가 발급한 설치 결과 JWT(`typ: sayren-install+jwt`)") }), z.object({
|
|
6410
6116
|
appId: z.string().min(1),
|
|
6411
6117
|
settings: z.record(z.string(), settingsValueSchema).default({}).describe("설치와 함께 저장할 설정. 비밀 필드도 여기서 넣는다")
|
|
6412
|
-
})]);
|
|
6118
|
+
})]));
|
|
6413
6119
|
/** 앱 목록 정보 — 현재 버전이 올린 아이콘·README(없으면 매니페스트 `iconUrl`) */
|
|
6414
6120
|
const appListingSchema = z.object({
|
|
6415
6121
|
description: z.string().nullable(),
|
|
@@ -6773,7 +6479,7 @@ const categoryAttributeSchema = z.object({
|
|
|
6773
6479
|
unit: z.string().nullable(),
|
|
6774
6480
|
allowedValues: z.array(z.string()).optional()
|
|
6775
6481
|
});
|
|
6776
|
-
const categoryCreateRequestSchema = z.object({
|
|
6482
|
+
const categoryCreateRequestSchema = strictRequest(z.object({
|
|
6777
6483
|
name: z.string().min(1).max(100),
|
|
6778
6484
|
parentId: z.string().nullable().optional(),
|
|
6779
6485
|
sortOrder: z.number().int().optional(),
|
|
@@ -6784,8 +6490,8 @@ const categoryCreateRequestSchema = z.object({
|
|
|
6784
6490
|
metaTitle: z.string().max(100).nullable().optional(),
|
|
6785
6491
|
metaDescription: z.string().max(300).nullable().optional(),
|
|
6786
6492
|
metaKeywords: z.string().max(200).nullable().optional()
|
|
6787
|
-
});
|
|
6788
|
-
const categoryPatchRequestSchema = z.object({
|
|
6493
|
+
}));
|
|
6494
|
+
const categoryPatchRequestSchema = strictRequest(z.object({
|
|
6789
6495
|
name: z.string().min(1).max(100).optional(),
|
|
6790
6496
|
parentId: z.string().nullable().optional(),
|
|
6791
6497
|
sortOrder: z.number().int().optional(),
|
|
@@ -6797,7 +6503,7 @@ const categoryPatchRequestSchema = z.object({
|
|
|
6797
6503
|
metaDescription: z.string().max(300).nullable().optional(),
|
|
6798
6504
|
metaKeywords: z.string().max(200).nullable().optional(),
|
|
6799
6505
|
flowId: z.string().nullable().optional().describe("주문 흐름(이슈 #115) — 게시한 흐름 id, null이면 기본 흐름. 맨 아래 카테고리에만 지정한다(400 `CATEGORY_NOT_LEAF`). 게시하지 않은 흐름은 409 `FLOW_NOT_PUBLISHED`")
|
|
6800
|
-
});
|
|
6506
|
+
}));
|
|
6801
6507
|
const categoryDeleteStrategySchema = z.enum(["reparent", "cascade"]);
|
|
6802
6508
|
/**
|
|
6803
6509
|
* `GET /v1/categories` 쿼리 — OpenAPI 문서용 형태(값은 쿼리 문자열). 응답 형태가 쿼리로 갈린다:
|
|
@@ -7120,7 +6826,7 @@ const periodRefine = (body, ctx) => {
|
|
|
7120
6826
|
* 직접 선택(`MANUAL`)은 `productIds`가 처음 담을 상품과 순서다. 조건 자동(`AUTOMATIC`)은 `rules`가 있어야 하고 `productIds`를 받지 않는다.
|
|
7121
6827
|
* `productSort`를 생략하면 직접 선택은 `MANUAL`, 조건 자동은 `LATEST`(판매량 상위 조건이 있으면 `BEST_SELLING`)다. 조건 자동은 `MANUAL`을 쓸 수 없다.
|
|
7122
6828
|
*/
|
|
7123
|
-
const collectionCreateRequestSchema = z.object({
|
|
6829
|
+
const collectionCreateRequestSchema = strictRequest(z.object({
|
|
7124
6830
|
title: z.string().trim().min(1).max(60).describe("제목"),
|
|
7125
6831
|
slug: slugField.optional(),
|
|
7126
6832
|
type: z.enum(COLLECTION_TYPES).default("MANUAL").describe("유형. `MANUAL`(직접 선택)·`AUTOMATIC`(조건 자동). 만든 뒤 바꿀 수 없다"),
|
|
@@ -7135,12 +6841,12 @@ const collectionCreateRequestSchema = z.object({
|
|
|
7135
6841
|
metaTitle: commonFields.metaTitle.optional(),
|
|
7136
6842
|
metaDescription: commonFields.metaDescription.optional(),
|
|
7137
6843
|
productIds: productIdsField.optional()
|
|
7138
|
-
}).superRefine(periodRefine);
|
|
6844
|
+
}).superRefine(periodRefine));
|
|
7139
6845
|
/**
|
|
7140
6846
|
* `PATCH /v1/collections/{collectionId}` — 준 항목만 바뀐다. `type`을 주면 400 `COLLECTION_TYPE_IMMUTABLE`이다.
|
|
7141
6847
|
* `revision`을 주면 그 번호일 때만 바뀌고, 그 사이 다른 수정이 있었으면 409 `COLLECTION_CHANGED`다.
|
|
7142
6848
|
*/
|
|
7143
|
-
const collectionPatchRequestSchema = z.object({
|
|
6849
|
+
const collectionPatchRequestSchema = strictRequest(z.object({
|
|
7144
6850
|
title: z.string().trim().min(1).max(60).optional(),
|
|
7145
6851
|
slug: slugField.optional(),
|
|
7146
6852
|
type: z.string().optional().describe("바꿀 수 없다. 주면 400 `COLLECTION_TYPE_IMMUTABLE`"),
|
|
@@ -7155,14 +6861,14 @@ const collectionPatchRequestSchema = z.object({
|
|
|
7155
6861
|
metaTitle: commonFields.metaTitle.optional(),
|
|
7156
6862
|
metaDescription: commonFields.metaDescription.optional(),
|
|
7157
6863
|
revision: z.number().int().min(0).optional().describe("읽은 수정 번호")
|
|
7158
|
-
}).superRefine(periodRefine);
|
|
6864
|
+
}).superRefine(periodRefine));
|
|
7159
6865
|
/** `PUT /v1/collections/{collectionId}/products` — 담긴 상품을 통째로 바꾼다(순서 포함) */
|
|
7160
|
-
const collectionProductsReplaceRequestSchema = z.object({
|
|
6866
|
+
const collectionProductsReplaceRequestSchema = strictRequest(z.object({
|
|
7161
6867
|
productIds: productIdsField,
|
|
7162
6868
|
revision: z.number().int().min(0).optional().describe("읽은 수정 번호")
|
|
7163
|
-
});
|
|
6869
|
+
}));
|
|
7164
6870
|
/** `POST /v1/collections/{collectionId}/products` — 뒤에 붙인다. 이미 담긴 상품은 그 자리에 둔다 */
|
|
7165
|
-
const collectionProductsAddRequestSchema = z.object({ productIds: z.array(z.string().min(1)).min(1).max(500) });
|
|
6871
|
+
const collectionProductsAddRequestSchema = strictRequest(z.object({ productIds: z.array(z.string().min(1)).min(1).max(500) }));
|
|
7166
6872
|
/** 컬렉션에 담긴 상품 한 줄 */
|
|
7167
6873
|
const collectionProductSchema = z.object({
|
|
7168
6874
|
productId: z.string(),
|
|
@@ -7199,10 +6905,10 @@ const collectionProductListQuerySchema = z.object({ ...pageQueryShape({
|
|
|
7199
6905
|
maxSize: MAX_COLLECTION_PRODUCTS
|
|
7200
6906
|
}) });
|
|
7201
6907
|
/** `POST /v1/collections/preview` — 저장하지 않고 조건으로 나오는 상품을 본다 */
|
|
7202
|
-
const collectionPreviewRequestSchema = z.object({
|
|
6908
|
+
const collectionPreviewRequestSchema = strictRequest(z.object({
|
|
7203
6909
|
rules: collectionRulesSchema,
|
|
7204
6910
|
productSort: collectionProductSortRequestSchema.optional().describe("미리보기 순서. 생략하면 `LATEST`(판매량 상위 조건이 있으면 `BEST_SELLING`)이고, `MANUAL`이면 `LATEST`다")
|
|
7205
|
-
});
|
|
6911
|
+
}));
|
|
7206
6912
|
/** 미리보기 응답 — 조건을 만족하는 판매 중 상품 수와 앞 20개 */
|
|
7207
6913
|
const collectionPreviewSchema = z.object({
|
|
7208
6914
|
count: z.number().int().describe("조건을 만족하는 판매 중 상품 수(조회 시각 기준)"),
|
|
@@ -7333,10 +7039,10 @@ const orderItemFlowSchema = z.object({
|
|
|
7333
7039
|
branches: z.array(flowStateSchema).optional().describe("활성 위치가 둘 이상(병렬 가지·하위 흐름)이면 각 위치의 상태. `flowState`는 그 가운데 가장 앞 단계다")
|
|
7334
7040
|
});
|
|
7335
7041
|
/** 상태 직접 이동(#115) — 연결선을 지나지 않고 다른 상태로 옮긴다. 블록(재고·환불·송장)은 실행하지 않는다 */
|
|
7336
|
-
const moveFlowStateRequestSchema = z.object({
|
|
7042
|
+
const moveFlowStateRequestSchema = strictRequest(z.object({
|
|
7337
7043
|
to: z.string().min(1).describe("옮길 상태 키(`moveTargets[].key`)"),
|
|
7338
7044
|
reason: z.string().trim().max(200).optional().describe("옮긴 사유(실행 기록에 남는다)")
|
|
7339
|
-
});
|
|
7045
|
+
}));
|
|
7340
7046
|
const flowRunStepSchema = z.object({
|
|
7341
7047
|
step: z.number().int(),
|
|
7342
7048
|
block: z.string().describe("실행한 블록 종류"),
|
|
@@ -7432,7 +7138,7 @@ const commerceFlowSchema = commerceFlowSummarySchema.extend({
|
|
|
7432
7138
|
}))
|
|
7433
7139
|
});
|
|
7434
7140
|
/** 진행 중 주문을 활성 버전으로 옮기기(#115) — 한 번에 `limit`개까지. 남으면 다시 부른다 */
|
|
7435
|
-
const migrateFlowVersionRequestSchema = z.object({ limit: z.number().int().min(1).max(500).optional().describe("한 번에 옮길 흐름 수(기본 100)") });
|
|
7141
|
+
const migrateFlowVersionRequestSchema = strictRequest(z.object({ limit: z.number().int().min(1).max(500).optional().describe("한 번에 옮길 흐름 수(기본 100)") }));
|
|
7436
7142
|
const migrateFlowVersionResultSchema = z.object({
|
|
7437
7143
|
fromVersion: z.number().int(),
|
|
7438
7144
|
toVersion: z.number().int(),
|
|
@@ -7444,19 +7150,19 @@ const migrateFlowVersionResultSchema = z.object({
|
|
|
7444
7150
|
})).describe("이번에 옮기지 못한 흐름(그 버전에 남는다)"),
|
|
7445
7151
|
remaining: z.number().int().describe("아직 이 버전에 남은 진행 중 흐름 수(건너뛴 것 포함)")
|
|
7446
7152
|
});
|
|
7447
|
-
const createCommerceFlowRequestSchema = z.object({
|
|
7153
|
+
const createCommerceFlowRequestSchema = strictRequest(z.object({
|
|
7448
7154
|
key: z.string().regex(/^[a-z][a-z0-9-]{1,48}$/).describe("상점 안 유일한 키(소문자·숫자·하이픈)"),
|
|
7449
7155
|
name: z.string().min(1).max(60).optional(),
|
|
7450
7156
|
presetKey: z.string().optional().describe("출발한 프리셋(출처로 남는다). 없으면 빈 플로우"),
|
|
7451
7157
|
graph: flowDocumentSchema.optional().describe("편집기에서 고친 그래프(#115). 없으면 프리셋 그래프 그대로, 프리셋도 없으면 빈 흐름(결제 완료 노드 하나)이다"),
|
|
7452
7158
|
definition: flowDocumentSchema.optional().describe("흐름 설정 `requires`(progression·groupClaim·fulfillmentMethods). 없으면 프리셋의 설정"),
|
|
7453
7159
|
variables: z.record(z.string(), z.unknown()).optional().describe("쓰지 않는다(무시). 값은 그래프의 노드 설정 안에 있다(#115)")
|
|
7454
|
-
});
|
|
7455
|
-
const saveFlowDraftRequestSchema = z.object({
|
|
7160
|
+
}));
|
|
7161
|
+
const saveFlowDraftRequestSchema = strictRequest(z.object({
|
|
7456
7162
|
graph: flowDocumentSchema,
|
|
7457
7163
|
definition: flowDocumentSchema.optional().describe("흐름 설정 `requires`(progression·groupClaim·fulfillmentMethods)"),
|
|
7458
7164
|
variables: z.record(z.string(), z.unknown()).optional().describe("쓰지 않는다(무시). 값은 그래프의 노드 설정 안에 있다(#115)")
|
|
7459
|
-
});
|
|
7165
|
+
}));
|
|
7460
7166
|
const flowIssueSchema = z.object({
|
|
7461
7167
|
code: z.string(),
|
|
7462
7168
|
message: z.string(),
|
|
@@ -7545,7 +7251,7 @@ const flowDraftOperationSchema = z.discriminatedUnion("op", [
|
|
|
7545
7251
|
])).optional()
|
|
7546
7252
|
}).describe("흐름 설정(진행 단위·묶음 클레임·이행 방식) 바꾸기")
|
|
7547
7253
|
]);
|
|
7548
|
-
const applyFlowOperationsRequestSchema = z.object({ operations: z.array(flowDraftOperationSchema).min(1).describe("차례대로 적용한다. 묶음은 원자적이다 — 하나라도 형식이 틀리면 아무것도 바꾸지 않는다(400)") });
|
|
7254
|
+
const applyFlowOperationsRequestSchema = strictRequest(z.object({ operations: z.array(flowDraftOperationSchema).min(1).describe("차례대로 적용한다. 묶음은 원자적이다 — 하나라도 형식이 틀리면 아무것도 바꾸지 않는다(400)") }));
|
|
7549
7255
|
const flowOperationsResultSchema = z.object({
|
|
7550
7256
|
revision: z.number().int().describe("저장 뒤 초안 revision — 다음 조작의 If-Match"),
|
|
7551
7257
|
changed: z.object({
|
|
@@ -7576,10 +7282,10 @@ const flowSecretSchema = z.object({
|
|
|
7576
7282
|
headerNames: z.array(z.string()).describe("저장한 헤더 이름(값은 보이지 않는다)"),
|
|
7577
7283
|
updatedAt: z.string()
|
|
7578
7284
|
});
|
|
7579
|
-
const saveFlowSecretRequestSchema = z.object({
|
|
7285
|
+
const saveFlowSecretRequestSchema = strictRequest(z.object({
|
|
7580
7286
|
url: z.url().refine((value) => value.startsWith("https://"), { message: "https 주소만 받습니다" }).describe("요청 주소. https만, 사설·루프백 주소는 400 `FLOW_SECRET_URL_INVALID`"),
|
|
7581
7287
|
headers: z.record(z.string().regex(/^[A-Za-z0-9-]{1,64}$/), z.string().max(2e3)).refine((value) => Object.keys(value).length <= 10, { message: "헤더는 10개까지입니다" }).default({}).describe("함께 보낼 헤더(인증 등). 값은 암호화해 두고 다시 보여 주지 않는다")
|
|
7582
|
-
});
|
|
7288
|
+
}));
|
|
7583
7289
|
/**
|
|
7584
7290
|
* 주문 전체 행동 결과(#115) — 같은 행동을 주문의 주문상품마다 실행한다. 한 주문상품의 실패가 다른 주문상품을 되돌리지 않는다(부분 실행).
|
|
7585
7291
|
* 묶음 진행이면 한 번 실행이 묶음의 주문상품을 함께 움직인다(COMPLETED로 함께 나온다). 그 행동이 없는 주문상품은 SKIPPED다
|
|
@@ -7608,11 +7314,11 @@ const simulationEventSchema = z.object({
|
|
|
7608
7314
|
]).describe("start 결제 승인 · seller.action 셀러 버튼 · buyer.action 구매자 버튼 · event 사건 · timer 타이머 키"),
|
|
7609
7315
|
key: z.string().optional().describe("행동·사건·타이머 키(start는 없음)")
|
|
7610
7316
|
});
|
|
7611
|
-
const simulateFlowRequestSchema = z.object({
|
|
7317
|
+
const simulateFlowRequestSchema = strictRequest(z.object({
|
|
7612
7318
|
startAt: z.iso.datetime({ offset: true }).optional().describe("가상 시계 시작(기본: 지금)"),
|
|
7613
7319
|
context: z.record(z.string(), z.unknown()).optional().describe("식이 읽을 값(item·order·buyer·product). 비우면 견본 주문 값"),
|
|
7614
7320
|
steps: z.array(z.union([z.object({ event: simulationEventSchema }), z.object({ advance: z.string().regex(/^P/).describe("시간 경과(ISO 8601 기간)") })])).min(1).max(100)
|
|
7615
|
-
});
|
|
7321
|
+
}));
|
|
7616
7322
|
const simulationStepSchema = z.object({
|
|
7617
7323
|
step: z.number().int(),
|
|
7618
7324
|
input: z.record(z.string(), z.unknown()).describe("넣은 사건(`event`) 또는 시간 경과(`advance`)"),
|
|
@@ -7638,7 +7344,7 @@ const simulateFlowResultSchema = z.object({
|
|
|
7638
7344
|
errors: z.array(flowIssueSchema),
|
|
7639
7345
|
trace: z.array(simulationStepSchema)
|
|
7640
7346
|
});
|
|
7641
|
-
const replayFlowRequestSchema = z.object({ orderItemId: z.string().describe("재생할 주문상품 — 그 흐름의 실행 기록을 초안으로 다시 돌린다") });
|
|
7347
|
+
const replayFlowRequestSchema = strictRequest(z.object({ orderItemId: z.string().describe("재생할 주문상품 — 그 흐름의 실행 기록을 초안으로 다시 돌린다") }));
|
|
7642
7348
|
const replayFlowResultSchema = z.object({
|
|
7643
7349
|
orderItemId: z.string(),
|
|
7644
7350
|
compiled: z.boolean(),
|
|
@@ -7786,7 +7492,7 @@ const flowEditSessionViewSchema = z.object({
|
|
|
7786
7492
|
streamToken: z.string()
|
|
7787
7493
|
}).nullable().describe("흐름 채널 구독(SSE, `Authorization: Bearer streamToken`) — session·ops·saved·released 이벤트. 중계가 없는 환경이면 null")
|
|
7788
7494
|
});
|
|
7789
|
-
const claimFlowEditSessionRequestSchema = z.object({ takeover: z.boolean().optional().describe("다른 주체가 잡고 있어도 넘겨받는다. 앞 주체의 저장하지 않은 수정은 사라지고, AI 도우미면 그 실행이 멈춘다") });
|
|
7495
|
+
const claimFlowEditSessionRequestSchema = strictRequest(z.object({ takeover: z.boolean().optional().describe("다른 주체가 잡고 있어도 넘겨받는다. 앞 주체의 저장하지 않은 수정은 사라지고, AI 도우미면 그 실행이 멈춘다") }));
|
|
7790
7496
|
//#endregion
|
|
7791
7497
|
//#region src/schemas/promotion.ts
|
|
7792
7498
|
/**
|
|
@@ -8465,7 +8171,7 @@ const couponTargetInputSchema = z.strictObject({
|
|
|
8465
8171
|
});
|
|
8466
8172
|
const couponTimeField = (description) => z.iso.datetime({ offset: true }).nullable().optional().describe(description);
|
|
8467
8173
|
/** `POST /v1/coupons` */
|
|
8468
|
-
const createCouponRequestSchema = z.strictObject({
|
|
8174
|
+
const createCouponRequestSchema = strictRequest(z.strictObject({
|
|
8469
8175
|
name: z.string().trim().min(1).max(60).describe(descriptions.name),
|
|
8470
8176
|
description: z.string().max(300).nullable().optional().describe(descriptions.description),
|
|
8471
8177
|
kind: couponKindSchema,
|
|
@@ -8496,12 +8202,12 @@ const createCouponRequestSchema = z.strictObject({
|
|
|
8496
8202
|
if (body.issueMethod !== "CODE" && body.perMemberUseLimit != null) issue("perMemberUseLimit", "발급형 쿠폰은 발급 한 장이 한 번 쓰입니다. 1인 발급 수 한도를 사용하십시오");
|
|
8497
8203
|
if (!(body.conditions?.memberOnly ?? COUPON_CONDITIONS_DEFAULTS.memberOnly) && (body.issueMethod !== "CODE" || body.perMemberUseLimit != null)) issue("conditions", "비회원에게 여는 쿠폰은 코드 입력형이면서 1인 사용 한도가 없어야 합니다");
|
|
8498
8204
|
if (body.startsAt && body.endsAt && Date.parse(body.endsAt) <= Date.parse(body.startsAt)) issue("endsAt", "종료 시각은 시작 시각보다 뒤여야 합니다");
|
|
8499
|
-
});
|
|
8205
|
+
}));
|
|
8500
8206
|
/**
|
|
8501
8207
|
* `PATCH /v1/coupons/{couponId}` — 준 항목만 바뀐다. 발급·사용이 시작된 쿠폰(`locked`)은 이름·설명·종료일 연장·
|
|
8502
8208
|
* 한도 상향만 받고, 그 밖의 항목이 현재 값과 다르면 409 `COUPON_LOCKED`다. 종류·발급 방식은 바꿀 수 없다.
|
|
8503
8209
|
*/
|
|
8504
|
-
const updateCouponRequestSchema = z.strictObject({
|
|
8210
|
+
const updateCouponRequestSchema = strictRequest(z.strictObject({
|
|
8505
8211
|
name: z.string().trim().min(1).max(60).optional().describe(descriptions.name),
|
|
8506
8212
|
description: z.string().max(300).nullable().optional().describe(descriptions.description),
|
|
8507
8213
|
benefit: couponBenefitSchema.optional(),
|
|
@@ -8515,7 +8221,7 @@ const updateCouponRequestSchema = z.strictObject({
|
|
|
8515
8221
|
totalUseLimit: limitField(descriptions.totalUseLimit),
|
|
8516
8222
|
perMemberIssueLimit: limitField(descriptions.perMemberIssueLimit),
|
|
8517
8223
|
perMemberUseLimit: limitField(descriptions.perMemberUseLimit)
|
|
8518
|
-
});
|
|
8224
|
+
}));
|
|
8519
8225
|
/** 쿠폰 응답 */
|
|
8520
8226
|
const couponSchema = z.object({
|
|
8521
8227
|
couponId: z.string(),
|
|
@@ -8783,7 +8489,7 @@ const customerOrderSchema = z.object({
|
|
|
8783
8489
|
}))
|
|
8784
8490
|
});
|
|
8785
8491
|
/** `POST /v1/customers/{id}/withdraw` 본문 */
|
|
8786
|
-
const withdrawCustomerRequestSchema = z.object({
|
|
8492
|
+
const withdrawCustomerRequestSchema = strictRequest(z.object({
|
|
8787
8493
|
reason: z.enum([
|
|
8788
8494
|
"BUYER_REQUEST",
|
|
8789
8495
|
"DORMANT",
|
|
@@ -8791,7 +8497,7 @@ const withdrawCustomerRequestSchema = z.object({
|
|
|
8791
8497
|
"OTHER"
|
|
8792
8498
|
]).describe("처리 사유 — 구매자 요청·장기 미이용·부정 이용·기타. 감사 로그에 남는다"),
|
|
8793
8499
|
memo: z.string().max(200).optional().describe("사유 보충(선택)")
|
|
8794
|
-
});
|
|
8500
|
+
}));
|
|
8795
8501
|
/** `WITHDRAWAL_BLOCKED`의 `error.details` — 탈퇴를 막는 항목 수(스토어프론트 탈퇴와 같다) */
|
|
8796
8502
|
const customerWithdrawalBlockedDetailsSchema = z.object({
|
|
8797
8503
|
inProgressOrderItems: z.number().int(),
|
|
@@ -8932,15 +8638,15 @@ const inventoryOperationResultSchema = z.object({
|
|
|
8932
8638
|
createdAt: z.string()
|
|
8933
8639
|
});
|
|
8934
8640
|
/** 수거 완료의 재입고 지정(Q3) — 생략하면 조합은 할당 순서(교환 → 판매), 위치는 반품지에 연결된 위치 → 할당 위치다 */
|
|
8935
|
-
const claimCollectCompleteRequestSchema = z.object({ restock: z.object({
|
|
8641
|
+
const claimCollectCompleteRequestSchema = strictRequest(z.object({ restock: z.object({
|
|
8936
8642
|
optionId: z.string().min(1).optional().describe("돌아온 조합 — 그 주문상품의 할당 조합이어야 한다(아니면 400 `INVALID_RESTOCK_OPTION`)"),
|
|
8937
8643
|
inventoryLocationId: z.string().min(1).optional().describe("재입고할 재고 위치")
|
|
8938
|
-
}).optional() });
|
|
8939
|
-
const claimRedeliveryRequestSchema = z.object({
|
|
8644
|
+
}).optional() }));
|
|
8645
|
+
const claimRedeliveryRequestSchema = strictRequest(z.object({
|
|
8940
8646
|
carrierCode: z.string().min(1),
|
|
8941
8647
|
trackingNumber: z.string().min(1),
|
|
8942
8648
|
inventoryLocationId: z.string().min(1).optional().describe("교환품을 보낼 재고 위치. 생략하면 그 상품의 기준 위치")
|
|
8943
|
-
});
|
|
8649
|
+
}));
|
|
8944
8650
|
//#endregion
|
|
8945
8651
|
//#region src/schemas/login.ts
|
|
8946
8652
|
/** 소셜 로그인 공급자 */
|
|
@@ -8973,14 +8679,14 @@ const loginSettingsSchema = z.object({
|
|
|
8973
8679
|
providers: z.array(loginProviderStatusSchema)
|
|
8974
8680
|
});
|
|
8975
8681
|
/** `PATCH /v1/store/login-settings` */
|
|
8976
|
-
const updateLoginSettingsRequestSchema = z.object({ passwordLoginEnabled: z.boolean() });
|
|
8682
|
+
const updateLoginSettingsRequestSchema = strictRequest(z.object({ passwordLoginEnabled: z.boolean() }));
|
|
8977
8683
|
/** `PUT /v1/store/auth-providers/{provider}` — 저장 전에 연결 테스트를 한다 */
|
|
8978
|
-
const saveLoginProviderRequestSchema = z.object({
|
|
8684
|
+
const saveLoginProviderRequestSchema = strictRequest(z.object({
|
|
8979
8685
|
clientId: z.string().trim().min(1).max(200),
|
|
8980
8686
|
clientSecret: z.string().trim().min(1).max(500)
|
|
8981
|
-
});
|
|
8687
|
+
}));
|
|
8982
8688
|
/** `PATCH /v1/store/auth-providers/{provider}` */
|
|
8983
|
-
const updateLoginProviderRequestSchema = z.object({ enabled: z.boolean() });
|
|
8689
|
+
const updateLoginProviderRequestSchema = strictRequest(z.object({ enabled: z.boolean() }));
|
|
8984
8690
|
/** 연결 테스트 결과 */
|
|
8985
8691
|
const loginProviderTestSchema = z.object({
|
|
8986
8692
|
ok: z.boolean(),
|
|
@@ -9170,36 +8876,36 @@ const payPalCredentialsInputSchema = z.object({
|
|
|
9170
8876
|
clientSecret: secretInput().optional().describe("Secret. 비밀 값. 최초 연결 시 필수, 수정 시 생략하면 기존 값을 유지한다")
|
|
9171
8877
|
});
|
|
9172
8878
|
const upsertEnvironment = () => pgEnvironmentSchema.describe("저장할 자격 증명 세트. PG마다 `TEST`(샌드박스)·`LIVE`(실결제) 세트를 따로 둔다. 어느 세트로 결제할지는 이 값이 아니라 샌드박스 스위치(`sandboxMode`)가 정한다");
|
|
9173
|
-
const upsertTossPaymentsProviderRequestSchema = z.object({
|
|
8879
|
+
const upsertTossPaymentsProviderRequestSchema = strictRequest(z.object({
|
|
9174
8880
|
environment: upsertEnvironment(),
|
|
9175
8881
|
credentials: tossPaymentsCredentialsInputSchema
|
|
9176
|
-
});
|
|
9177
|
-
const upsertPortOneProviderRequestSchema = z.object({
|
|
8882
|
+
}));
|
|
8883
|
+
const upsertPortOneProviderRequestSchema = strictRequest(z.object({
|
|
9178
8884
|
environment: upsertEnvironment(),
|
|
9179
8885
|
credentials: portOneCredentialsInputSchema
|
|
9180
|
-
});
|
|
9181
|
-
const upsertKakaoPayProviderRequestSchema = z.object({
|
|
8886
|
+
}));
|
|
8887
|
+
const upsertKakaoPayProviderRequestSchema = strictRequest(z.object({
|
|
9182
8888
|
environment: upsertEnvironment(),
|
|
9183
8889
|
credentials: kakaoPayCredentialsInputSchema
|
|
9184
|
-
});
|
|
9185
|
-
const upsertNaverPayProviderRequestSchema = z.object({
|
|
8890
|
+
}));
|
|
8891
|
+
const upsertNaverPayProviderRequestSchema = strictRequest(z.object({
|
|
9186
8892
|
environment: upsertEnvironment(),
|
|
9187
8893
|
credentials: naverPayCredentialsInputSchema
|
|
9188
|
-
});
|
|
9189
|
-
const upsertPayPalProviderRequestSchema = z.object({
|
|
8894
|
+
}));
|
|
8895
|
+
const upsertPayPalProviderRequestSchema = strictRequest(z.object({
|
|
9190
8896
|
environment: upsertEnvironment(),
|
|
9191
8897
|
credentials: payPalCredentialsInputSchema
|
|
9192
|
-
});
|
|
9193
|
-
const updatePaymentProviderRequestSchema = z.object({
|
|
8898
|
+
}));
|
|
8899
|
+
const updatePaymentProviderRequestSchema = strictRequest(z.object({
|
|
9194
8900
|
enabled: z.boolean().optional().describe("사용 여부. 켜려면 활성 환경(샌드박스면 TEST, 아니면 LIVE) 자격 증명이 모두 저장돼 있어야 한다(`PAYMENT_PROVIDER_INCOMPLETE`)"),
|
|
9195
8901
|
sandboxMode: z.boolean().optional().describe("샌드박스 스위치. `true`면 새 결제에 TEST 세트를 쓴다(항상 허용). `false`(라이브 전환)는 라이브 개방 조건을 모두 충족해야 한다(`LIVE_GATE_NOT_MET`)"),
|
|
9196
8902
|
easyPayProviders: z.array(easyPayProviderSchema).max(easyPayProviderSchema.options.length).optional().describe("이 PG로 받는 간편결제사 — 통째로 바꾼다. PG 계약(포트원은 채널)에 추가한 간편결제만 켠다. 켠 간편결제사마다 스토어프론트 결제 옵션이 하나씩 생긴다(포트원은 간편결제를 받는 채널이 있어야 한다)")
|
|
9197
|
-
}).refine((body) => body.enabled !== void 0 || body.sandboxMode !== void 0 || body.easyPayProviders !== void 0, { message: "enabled·sandboxMode·easyPayProviders 중 하나는 보내야 합니다" });
|
|
9198
|
-
const verifyPaymentProviderRequestSchema = z.object({ environment: pgEnvironmentSchema.optional().describe("연결 테스트할 자격 증명 세트. 생략하면 활성 환경(샌드박스면 TEST, 아니면 LIVE)") });
|
|
9199
|
-
const updatePaymentSettingsRequestSchema = z.object({
|
|
8903
|
+
}).refine((body) => body.enabled !== void 0 || body.sandboxMode !== void 0 || body.easyPayProviders !== void 0, { message: "enabled·sandboxMode·easyPayProviders 중 하나는 보내야 합니다" }));
|
|
8904
|
+
const verifyPaymentProviderRequestSchema = strictRequest(z.object({ environment: pgEnvironmentSchema.optional().describe("연결 테스트할 자격 증명 세트. 생략하면 활성 환경(샌드박스면 TEST, 아니면 LIVE)") }));
|
|
8905
|
+
const updatePaymentSettingsRequestSchema = strictRequest(z.object({
|
|
9200
8906
|
priority: z.array(pgProviderSchema).min(1).max(50).optional().describe("PG 우선순위(앞이 1순위) — 스토어프론트 결제 옵션 목록의 PG 순서다. 연결된 PG 수만큼 **모두 한 번씩** 나열한다(길이 상한 50은 안전장치다). 빠지거나 중복되거나 연결되지 않은 PG가 있으면 `INVALID_PRIORITY`"),
|
|
9201
8907
|
checkoutOrigins: z.array(z.string().max(200)).max(20).optional().describe("결제 도메인 — 통째로 바꾼다. 결제를 마친 구매자가 돌아올 스토어프론트 origin(`https://shop.example.com`, https·경로 없음). 결제 시작의 `returnUrl`은 이 목록 안이어야 한다. 비어 있으면 실결제를 시작할 수 없다(테스트 결제는 localhost 허용). 같은 도메인을 PG 가맹 정보에도 등록한다. 형식이 틀리면 `INVALID_CHECKOUT_ORIGIN`")
|
|
9202
|
-
}).refine((body) => body.priority !== void 0 || body.checkoutOrigins !== void 0, { message: "priority 또는 checkoutOrigins 중 하나는 보내야 합니다" });
|
|
8908
|
+
}).refine((body) => body.priority !== void 0 || body.checkoutOrigins !== void 0, { message: "priority 또는 checkoutOrigins 중 하나는 보내야 합니다" }));
|
|
9203
8909
|
const maskedSecretSchema = z.object({
|
|
9204
8910
|
field: z.string().describe("비밀 필드 이름 (`secretKey`·`apiSecret`·`webhookSecret`)"),
|
|
9205
8911
|
configured: z.boolean().describe("값이 저장돼 있는가"),
|
|
@@ -9279,7 +8985,7 @@ const paymentProviderSchema = z.object({
|
|
|
9279
8985
|
platformTestKeysAvailable: z.boolean().optional().default(false).describe("이 PG에 sayren 지정 테스트 키가 있어 테스트모드 키를 켤 수 있는가"),
|
|
9280
8986
|
easyPayProviders: z.array(easyPayProviderResponseSchema).describe("이 PG로 받는 간편결제사. 연결되지 않았으면 빈 목록. 현재 값은 `NAVERPAY`·`KAKAOPAY`·`TOSSPAY`·`PAYCO`이고 값이 추가될 수 있어 문자열로 받는다"),
|
|
9281
8987
|
retiredCredentialCount: z.number().int().describe("보관된(가맹점 교체·연결 해제로 새 결제에 더 쓰이지 않는) 자격 증명 수. 그 가맹점으로 받은 결제의 환불·대사에 계속 쓰인다"),
|
|
9282
|
-
routingExclusion: z.string().nullable().optional().default(null).describe("지금 새 결제의 후보가 아닌 사유. 후보면 null. 판정 원천은 서버 라우팅이다(상점 플랫폼이 다시 계산하지 않는다). 후보가 아닌 PG에는 항상 사유 코드를 붙인다(연결 안 된 PG 포함) — 모든 PG는 `candidates`에 있거나 이 값이 null이 아니다. 현재 값: `NOT_CONNECTED`(연결 안 됨) · `DISABLED`(사용 중지) · `CREDENTIAL_MISSING`(활성 환경 자격 증명 없음) · `SANDBOX_IN_LIVE_STORE`(
|
|
8988
|
+
routingExclusion: z.string().nullable().optional().default(null).describe("지금 새 결제의 후보가 아닌 사유. 후보면 null. 판정 원천은 서버 라우팅이다(상점 플랫폼이 다시 계산하지 않는다). 후보가 아닌 PG에는 항상 사유 코드를 붙인다(연결 안 된 PG 포함) — 모든 PG는 `candidates`에 있거나 이 값이 null이 아니다. 현재 값: `NOT_CONNECTED`(연결 안 됨) · `DISABLED`(사용 중지) · `CREDENTIAL_MISSING`(활성 환경 자격 증명 없음) · `SANDBOX_IN_LIVE_STORE`(더는 반환하지 않음 — PG는 각자 쓰인다) · `PLATFORM_BLOCKED`(플랫폼이 실결제를 막음) · `MODE_MISMATCH`(라이브를 연 서버 모드와 현재 모드가 다름). 값이 추가될 수 있어 문자열로 받는다 — 모르는 값은 후보 아님으로 다룬다. 서버는 항상 싣는다. 이 필드가 없는 이전 서버 응답은 기본값(null)으로 읽는다")
|
|
9283
8989
|
});
|
|
9284
8990
|
/**
|
|
9285
8991
|
* `PaymentProvider.routingExclusion`의 현재 값 — 응답 스키마는 서버가 사유를 추가해도 파싱이 깨지지 않게 문자열로 받는다.
|
|
@@ -9495,7 +9201,7 @@ const paymentListQuerySchema = z.object({
|
|
|
9495
9201
|
size: z.string().optional().describe("페이지 크기 (기본 20, 최대 100)")
|
|
9496
9202
|
});
|
|
9497
9203
|
/** 테스트모드 키 활성화 요청(2026-10-14) — `PUT /v1/store/payment-providers/{provider}/platform-test-keys` */
|
|
9498
|
-
const setPlatformTestKeysRequestSchema = z.object({ enabled: z.boolean().describe("`true`면 sayren 지정 테스트 키를 TEST 세트로 저장하고 PG를 켠다. `false`면 고정만 푼다(TEST 세트는 그대로)") });
|
|
9204
|
+
const setPlatformTestKeysRequestSchema = strictRequest(z.object({ enabled: z.boolean().describe("`true`면 sayren 지정 테스트 키를 TEST 세트로 저장하고 PG를 켠다. `false`면 고정만 푼다(TEST 세트는 그대로)") }));
|
|
9499
9205
|
/** 결제 상태 PG 한 줄 — 비밀 값·공개 키 없이 연결·사용·환경·테스트모드 키만 */
|
|
9500
9206
|
const paymentStatusProviderSchema = z.object({
|
|
9501
9207
|
provider: pgProviderResponseSchema,
|
|
@@ -9669,7 +9375,7 @@ const deliveryMethodSchema = z.enum([
|
|
|
9669
9375
|
"QUICK",
|
|
9670
9376
|
"NOTHING"
|
|
9671
9377
|
]);
|
|
9672
|
-
const dispatchRequestSchema = z.object({
|
|
9378
|
+
const dispatchRequestSchema = strictRequest(z.object({
|
|
9673
9379
|
deliveryMethod: deliveryMethodSchema,
|
|
9674
9380
|
carrierCode: z.string().optional(),
|
|
9675
9381
|
trackingNumber: z.string().optional(),
|
|
@@ -9681,7 +9387,7 @@ const dispatchRequestSchema = z.object({
|
|
|
9681
9387
|
* 잡 전체를 멈출 수 있어 입력에서 좁혔다. 검증을 통과한 값도 저장 전에 UTC ISO로 정규화한다.
|
|
9682
9388
|
*/
|
|
9683
9389
|
dispatchedAt: z.iso.datetime({ offset: true }).optional()
|
|
9684
|
-
}).refine((value) => value.deliveryMethod === "DIRECT" || value.deliveryMethod === "NOTHING" ? true : !!value.carrierCode && !!value.trackingNumber, { message: "COURIER/QUICK 발송은 carrierCode와 trackingNumber가 필수입니다" });
|
|
9390
|
+
}).refine((value) => value.deliveryMethod === "DIRECT" || value.deliveryMethod === "NOTHING" ? true : !!value.carrierCode && !!value.trackingNumber, { message: "COURIER/QUICK 발송은 carrierCode와 trackingNumber가 필수입니다" }));
|
|
9685
9391
|
const deliveryInfoSchema = z.object({
|
|
9686
9392
|
orderItemId: z.string(),
|
|
9687
9393
|
deliveryMethod: deliveryMethodSchema,
|
|
@@ -9728,7 +9434,7 @@ const carrierSchema = z.object({
|
|
|
9728
9434
|
name: z.string(),
|
|
9729
9435
|
trackingUrlTemplate: z.string()
|
|
9730
9436
|
});
|
|
9731
|
-
const holdOrderItemRequestSchema = z.object({
|
|
9437
|
+
const holdOrderItemRequestSchema = strictRequest(z.object({
|
|
9732
9438
|
reason: z.enum([
|
|
9733
9439
|
"OUT_OF_STOCK",
|
|
9734
9440
|
"CUSTOMER_REQUEST",
|
|
@@ -9737,8 +9443,8 @@ const holdOrderItemRequestSchema = z.object({
|
|
|
9737
9443
|
]),
|
|
9738
9444
|
detail: z.string().max(500).optional(),
|
|
9739
9445
|
expectedDispatchDate: z.string()
|
|
9740
|
-
});
|
|
9741
|
-
const cancelBySellerRequestSchema = z.object({
|
|
9446
|
+
}));
|
|
9447
|
+
const cancelBySellerRequestSchema = strictRequest(z.object({
|
|
9742
9448
|
reason: z.enum([
|
|
9743
9449
|
"OUT_OF_STOCK",
|
|
9744
9450
|
"PRICE_ERROR",
|
|
@@ -9748,17 +9454,17 @@ const cancelBySellerRequestSchema = z.object({
|
|
|
9748
9454
|
detail: z.string().max(500).optional(),
|
|
9749
9455
|
quantity: z.number().int().min(1).optional().describe("취소할 수량. 생략하면 남은 수량 전체다. 남은 수량보다 크면 400 `INVALID_QUANTITY`. 일부만 취소하면 주문상품은 상태를 유지한 채 `canceledQuantity`가 늘고, 전 수량이 소진되면 `CANCELED`가 된다"),
|
|
9750
9456
|
holdRefund: z.boolean().optional().describe("true면 주문만 취소하고 결제 환불은 대기로 남긴다(#115). 정산·재고·적립금 반환은 그대로 하고, PG 환불은 결제 상세의 `POST /v1/payments/refunds/{refundId}/process`로 따로 한다. 생략하면 취소와 함께 환불한다")
|
|
9751
|
-
});
|
|
9457
|
+
}));
|
|
9752
9458
|
/**
|
|
9753
9459
|
* 제공 처리 요청 (이슈 #48) — `POST /v1/order-items/{orderItemId}/fulfill`. 배송 없는 주문상품(`MANUAL`)을
|
|
9754
9460
|
* 제공 완료(`DELIVERED`)로 바꾼다.
|
|
9755
9461
|
*/
|
|
9756
|
-
const fulfillRequestSchema = z.object({ note: z.string().trim().max(1e3).optional().describe("구매자에게 보일 이용 안내(예: 예약 방법, 수령 장소). 주문 상세에 실린다") });
|
|
9462
|
+
const fulfillRequestSchema = strictRequest(z.object({ note: z.string().trim().max(1e3).optional().describe("구매자에게 보일 이용 안내(예: 예약 방법, 수령 장소). 주문 상세에 실린다") }));
|
|
9757
9463
|
/** 제공 처리 일괄 요청 — `POST /v1/order-items/fulfill` */
|
|
9758
|
-
const fulfillBulkRequestSchema = z.object({
|
|
9464
|
+
const fulfillBulkRequestSchema = strictRequest(z.object({
|
|
9759
9465
|
orderItemIds: z.array(z.string()).min(1).max(100),
|
|
9760
9466
|
note: fulfillRequestSchema.shape.note
|
|
9761
|
-
});
|
|
9467
|
+
}));
|
|
9762
9468
|
/** `POST /v1/order-items/{orderItemId}/cancel` 응답 — 셀러 직권취소 환불 결과 */
|
|
9763
9469
|
const cancelBySellerResultSchema = z.object({
|
|
9764
9470
|
orderItemId: z.string(),
|
|
@@ -10116,17 +9822,17 @@ const savedOptionSetSchema = z.object({
|
|
|
10116
9822
|
createdAt: z.string(),
|
|
10117
9823
|
updatedAt: z.string()
|
|
10118
9824
|
});
|
|
10119
|
-
const savedOptionValueRequestSchema = z.
|
|
9825
|
+
const savedOptionValueRequestSchema = z.strictObject({
|
|
10120
9826
|
name: nameSchema,
|
|
10121
9827
|
additionalPrice: z.number().int().min(0).default(0)
|
|
10122
9828
|
});
|
|
10123
|
-
const savedOptionGroupRequestSchema = z.
|
|
9829
|
+
const savedOptionGroupRequestSchema = z.strictObject({
|
|
10124
9830
|
name: nameSchema,
|
|
10125
9831
|
kind: optionGroupKindSchema,
|
|
10126
9832
|
required: z.boolean().default(false).describe("추가 선택만 쓴다. 조합 옵션명에 true를 주면 400이다"),
|
|
10127
9833
|
values: z.array(savedOptionValueRequestSchema).min(1).max(100)
|
|
10128
9834
|
});
|
|
10129
|
-
const savedCustomInputRequestSchema = z.
|
|
9835
|
+
const savedCustomInputRequestSchema = z.strictObject({
|
|
10130
9836
|
label: z.string().trim().min(1).max(30),
|
|
10131
9837
|
placeholder: z.string().trim().max(100).nullish(),
|
|
10132
9838
|
maxLength: z.number().int().min(1).max(200),
|
|
@@ -10140,7 +9846,7 @@ const savedCustomInputRequestSchema = z.object({
|
|
|
10140
9846
|
* 저장 옵션 만들기·수정 본문. 조합 옵션명은 최대 `MAX_OPTION_GROUPS`개, 추가 선택은 최대 `MAX_ADDON_GROUPS`개이고
|
|
10141
9847
|
* 옵션명과 직접 입력 항목이 모두 비면 400이다. 수정(PUT)은 통째로 바꾼다.
|
|
10142
9848
|
*/
|
|
10143
|
-
const savedOptionSetRequestSchema = z.
|
|
9849
|
+
const savedOptionSetRequestSchema = z.strictObject({
|
|
10144
9850
|
name: z.string().trim().min(1).max(50),
|
|
10145
9851
|
optionSort: optionSortSchema.default("REGISTERED"),
|
|
10146
9852
|
groups: z.array(savedOptionGroupRequestSchema).max(8).default([]),
|
|
@@ -10152,7 +9858,7 @@ const savedOptionSetRequestSchema = z.object({
|
|
|
10152
9858
|
* 조합 추가금이 값별 추가금의 합으로 되돌려지면 값별로 저장하고, 조합마다 제각각이면 추가금을 빼고
|
|
10153
9859
|
* 응답 `additionalPriceDropped: true`로 알린다. `replaceOptionSetId`를 주면 그 저장 옵션을 덮어쓴다(이름 중복의 덮어쓰기).
|
|
10154
9860
|
*/
|
|
10155
|
-
const savedOptionSetFromProductRequestSchema = z.
|
|
9861
|
+
const savedOptionSetFromProductRequestSchema = z.strictObject({
|
|
10156
9862
|
productId: z.string(),
|
|
10157
9863
|
name: z.string().trim().min(1).max(50),
|
|
10158
9864
|
includeOptions: z.boolean().default(true).describe("옵션명(조합·추가 선택)을 저장하는가"),
|
|
@@ -10270,14 +9976,14 @@ const brandBriefSchema = z.object({
|
|
|
10270
9976
|
notes: z.string().trim().max(4e3).nullable().describe("인터뷰 메모 (타깃 고객, 판매 방식, 셀러가 강조한 요구)")
|
|
10271
9977
|
});
|
|
10272
9978
|
/** `PUT /v1/storefront/brand-brief` — 브리프 전체를 바꾼다. 생략한 항목은 비운다 */
|
|
10273
|
-
const putBrandBriefRequestSchema = z.object({
|
|
9979
|
+
const putBrandBriefRequestSchema = strictRequest(z.object({
|
|
10274
9980
|
industry: storeIndustrySchema.nullable().default(null),
|
|
10275
9981
|
mood: z.string().trim().max(200).nullable().default(null),
|
|
10276
9982
|
pointColor: z.string().regex(/^#[0-9a-fA-F]{6}$/, "#RRGGBB 형식이어야 합니다").nullable().default(null),
|
|
10277
9983
|
references: z.array(brandBriefReferenceSchema).max(5).default([]),
|
|
10278
9984
|
productSource: brandBriefProductSourceSchema.nullable().default(null),
|
|
10279
9985
|
notes: z.string().trim().max(4e3).nullable().default(null)
|
|
10280
|
-
});
|
|
9986
|
+
}));
|
|
10281
9987
|
/** `GET·PUT /v1/storefront/brand-brief` 응답 — 저장한 적이 없으면 `brief`·`updatedAt`이 null이다 */
|
|
10282
9988
|
const brandBriefViewSchema = z.object({
|
|
10283
9989
|
brief: brandBriefSchema.nullable(),
|
|
@@ -10348,7 +10054,7 @@ const starterStatusSchema = z.object({
|
|
|
10348
10054
|
//#endregion
|
|
10349
10055
|
//#region src/client.ts
|
|
10350
10056
|
function createStoreClient(options) {
|
|
10351
|
-
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
10057
|
+
const fetchFn = options.fetch ?? ((input, init) => globalThis.fetch(input, init));
|
|
10352
10058
|
const { session } = options;
|
|
10353
10059
|
const tokenSource = options.accessToken ?? (session ? () => session.getToken() : void 0);
|
|
10354
10060
|
const refresh = options.refresh ?? (session ? () => session.refresh() : void 0);
|
|
@@ -10359,7 +10065,7 @@ function createStoreClient(options) {
|
|
|
10359
10065
|
}
|
|
10360
10066
|
/** 계정 API(`/me/*`) — 상점을 고르지 않는다 */
|
|
10361
10067
|
const userHttp = createHttp({
|
|
10362
|
-
baseUrl: options.baseUrl,
|
|
10068
|
+
baseUrl: options.baseUrl ?? "https://api.sayren.io/v1",
|
|
10363
10069
|
fetch: fetchFn,
|
|
10364
10070
|
headers: bearer,
|
|
10365
10071
|
refresh,
|
|
@@ -10367,7 +10073,7 @@ function createStoreClient(options) {
|
|
|
10367
10073
|
});
|
|
10368
10074
|
/** 상점 API — 같은 계정 토큰 + `X-Store-Id` */
|
|
10369
10075
|
const storeHttp = createHttp({
|
|
10370
|
-
baseUrl: options.baseUrl,
|
|
10076
|
+
baseUrl: options.baseUrl ?? "https://api.sayren.io/v1",
|
|
10371
10077
|
fetch: fetchFn,
|
|
10372
10078
|
headers: () => {
|
|
10373
10079
|
const storeId = resolveToken(options.storeId);
|
|
@@ -11479,7 +11185,7 @@ async function refreshUserToken(options) {
|
|
|
11479
11185
|
...options.resource ? { resource: options.resource } : {}
|
|
11480
11186
|
}, options.fetch);
|
|
11481
11187
|
}
|
|
11482
|
-
const customerDelegationRequestSchema = z.object({
|
|
11188
|
+
const customerDelegationRequestSchema = strictRequest(z.object({
|
|
11483
11189
|
uid: z.string().regex(/^[A-Za-z0-9._:@|-]{1,128}$/).optional().describe("셀러 자체 인증의 사용자 id(1~128자, 영문·숫자·`._:@|-`). 처음 보는 id면 구매자를 만든다"),
|
|
11484
11190
|
email: z.email().max(254).optional().describe("uid가 없으면 이메일로 지목한다. uid와 함께 주면 처음 만들 때의 이메일이다"),
|
|
11485
11191
|
name: z.string().max(50).optional().describe("처음 만들 때의 이름"),
|
|
@@ -11487,7 +11193,7 @@ const customerDelegationRequestSchema = z.object({
|
|
|
11487
11193
|
}).refine((value) => Boolean(value.uid || value.email), {
|
|
11488
11194
|
message: "uid 또는 email이 필요합니다",
|
|
11489
11195
|
path: ["uid"]
|
|
11490
|
-
}).describe("구매자 위임 요청");
|
|
11196
|
+
}).describe("구매자 위임 요청"));
|
|
11491
11197
|
const customerDelegationSchema = z.object({
|
|
11492
11198
|
accessToken: z.string().describe("구매자 액세스 토큰(스토어프론트 API Bearer)"),
|
|
11493
11199
|
tokenType: z.literal("Bearer"),
|
|
@@ -11549,9 +11255,10 @@ const REVOKE_TIMEOUT_MS = 5e3;
|
|
|
11549
11255
|
/** Web Locks 이름 — 탭 간 refresh 회전 직렬화용 */
|
|
11550
11256
|
const REFRESH_LOCK = STORE_SESSION_KEYS.refresh;
|
|
11551
11257
|
function createStoreSession(options) {
|
|
11552
|
-
const {
|
|
11258
|
+
const { clientId, storage, authServer } = options;
|
|
11259
|
+
const baseUrl = options.baseUrl ?? "https://api.sayren.io/v1";
|
|
11553
11260
|
const { revokeUrl, tokenUrl, resource } = authServer;
|
|
11554
|
-
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
11261
|
+
const fetchFn = options.fetch ?? ((input, init) => globalThis.fetch(input, init));
|
|
11555
11262
|
const listeners = /* @__PURE__ */ new Set();
|
|
11556
11263
|
function notify() {
|
|
11557
11264
|
for (const listener of listeners) listener();
|
|
@@ -11712,4 +11419,4 @@ function createStoreSession(options) {
|
|
|
11712
11419
|
};
|
|
11713
11420
|
}
|
|
11714
11421
|
//#endregion
|
|
11715
|
-
export { AI_AGENT_NOTES_DIR, AI_AGENT_PHASES, AI_DESIGN_BOARDS_MAX, AI_DESIGN_BOARD_FILE_PATTERN, AI_DESIGN_BOARD_KINDS, AI_DESIGN_CANVAS_PATH, AI_DESIGN_CONFIRM_APPROVE, AI_DESIGN_DIR, AI_DESIGN_VIEWPORTS, AI_MESSAGE_MAX_ATTACHMENTS, AI_MESSAGE_MAX_CHARS, AI_RUN_ACTIVE_STATUSES, AI_RUN_FILE_CHANGES_RETENTION_DAYS, AI_SETUP_CONFIRM_APPROVE, AI_TODOS_MAX, AI_TODO_STATUSES, APPROVAL_ALREADY_DECIDED_CODE, APPROVAL_REQUIRED_CODE, APP_CAPABILITIES, APP_DEPLOY_KEY_PATTERN, APP_DEPLOY_KEY_PREFIX, APP_EVENTS_MAX, APP_EVENT_SCOPES, APP_EVENT_TYPES, APP_FLOW_EVENT_PATTERN, APP_FLOW_ITEMS_MAX, APP_FLOW_NOTIFICATION_PATTERN, APP_HANDLE_PATTERN, APP_HTTP_KEY_PATTERN, APP_ICON_CONTENT_TYPES, APP_ICON_MAX_BYTES, APP_ICON_MIN_PX, APP_LIFECYCLE_EVENT_TYPES, APP_NETWORK_DENIED_SUFFIXES, APP_NETWORK_HOSTS_MAX, APP_PUBLIC_HTTP_MAX, APP_README_MAX_BYTES, APP_RESERVED_HANDLES, APP_SCHEDULES_MAX, APP_SCHEDULE_INTERVALS, APP_SCHEDULE_NAME_PATTERN, APP_SECRETS_MAX, APP_SECRET_NAME_PATTERN, APP_SECRET_PATTERNS, APP_SERVER_BUNDLE_MAX_GZIP_BYTES, APP_SETTINGS_MAX_FIELDS, APP_SETTING_FIELD_TYPES, APP_SETTING_KEY_PATTERN, APP_STORAGE_KEY_PATTERN, APP_STORAGE_MAX_BYTES, APP_STORAGE_MAX_KEYS, APP_TOOL_NAME_PATTERN, APP_UI_MAX_BYTES, APP_UI_MAX_FILES, ApiError, ApprovalPendingError, BASE_CURRENCY, BRAND_BRIEF_MAX_REFERENCES, BUSINESS_INFO_MAX_LENGTH, BUSINESS_NUMBER_PATTERN, CASH_RECEIPT_STATUS_VALUES, CERTIFICATION_STATUSES, COLLECTION_BEST_SELLING_DAYS, COLLECTION_PREVIEW_SIZE, COLLECTION_PRODUCT_SORTS, COLLECTION_SALES_SORT_DEFAULT_DAYS, COLLECTION_SLUG_PATTERN, COLLECTION_TYPES, COUPON_CODE_PATTERN, COUPON_CONDITIONS_DEFAULTS, COUPON_TARGET_ALL, COUPON_TARGET_LIST_MAX, CURRENCIES, CURRENCY_CODES, CUSTOM_INPUT_FORBIDDEN_WORDS, CUSTOM_INPUT_TYPES, DEDICATED_EASY_PAY_PROVIDER, DEFAULT_STORE_LOCALE, FULFILLMENT_METHODS, FULFILLMENT_METHODS_BY_TYPE, FULFILLMENT_METHOD_RULES, FULFILLMENT_RULES, INSTALLABLE_SCOPES, InvalidPriceUnitError, KAKAOPAY_TEST_CID, KNOWN_WEBHOOK_EVENT_TYPES, KRW_MONEY_RULES, MAX_ADDON_GROUPS, MAX_ANALYTICS_ALLOWED_ORIGINS, MAX_AUTO_TRANSITION_DAYS, MAX_CALENDAR_DAYS, MAX_CERTIFICATION_ITEMS, MAX_COLLECTIONS, MAX_COLLECTION_BEST_SELLING_TOP, MAX_COLLECTION_CREATED_WITHIN_DAYS, MAX_COLLECTION_DESCRIPTION, MAX_COLLECTION_PRODUCTS, MAX_COLLECTION_PRODUCTS_PER_ADD, MAX_COLLECTION_RULES, MAX_COLLECTION_RULE_CATEGORIES, MAX_COLLECTION_TITLE, MAX_CUSTOM_INPUTS, MAX_CUSTOM_INPUT_LENGTH, MAX_INFO_SECTION_TITLE, MAX_INVENTORY_OPERATION_LINES, MAX_NOTICE_VALUE_LENGTH, MAX_OPTION_GROUPS, MAX_PICKUP_LOCATIONS, MAX_PRODUCT_IMAGES, MAX_PRODUCT_INFO_SECTIONS, MAX_SAVED_OPTION_SETS, MAX_SAVED_OPTION_SET_NAME, MAX_STAY_NIGHTS, MAX_VALUES_PER_GROUP, MAX_VARIANTS, MCP_TELEMETRY_MAX_RESULTS, MIN_PAYMENT_AMOUNT, NON_INSTALLABLE_SCOPES, NO_COUPON_SETTLEMENT, NO_SHIPPING_BUNDLE_KEY, PAYMENT_ROUTING_EXCLUSION_CODES, PAYPAL_CURRENCIES, PLATFORM_CODE_SETS, POINT_ADJUSTMENT_MAX, POINT_EARN_RATE_BP_MAX, POINT_ENTRY_TYPES, POINT_EXPIRY_DAYS_MAX, POINT_EXPIRY_DAYS_MIN, POINT_LOT_SOURCES, POINT_POLICY_DEFAULTS, POINT_REVIEW_REWARD_MAX, POINT_USE_UNITS, PORTONE_CHANNEL_NAME_MAX_LENGTH, PORTONE_MAX_CHANNELS, PORTONE_MIN_CHANNELS, REFUND_POLICY_DEFAULTS, REFUND_POLICY_DELIVERY_FEE_KEYS, REMOTE_AREA_ZIP_RANGES, RESERVED_STOREFRONT_SLUGS, RESERVED_STORE_CODES, SCOPE_DESCRIPTIONS, SHIPPING_POLICY_DEFAULTS, STARTER_SELLER_TASKS, STARTER_STAGES, STOREFRONT_BLOCKED_PATH_SEGMENTS, STOREFRONT_BUILD_STAGES, STOREFRONT_BUILD_TERMINAL_STATUSES, STOREFRONT_CHECK_TERMINAL_STATUSES, STOREFRONT_CLOSED_SITE_HOLD_DAYS, STOREFRONT_CUSTOM_DOMAIN_LIMIT_DEFAULT, STOREFRONT_DOMAIN_DNS_GRACE_DAYS, STOREFRONT_DOMAIN_DNS_WAIT_DAYS, STOREFRONT_DOMAIN_TXT_LABEL, STOREFRONT_EDIT_ACTIVITY_TIMEOUT_MINUTES, STOREFRONT_EDIT_CAPACITY, STOREFRONT_EDIT_IDLE_MINUTES, STOREFRONT_EDIT_PREVIEW_SUFFIX, STOREFRONT_EDIT_START_STAGES, STOREFRONT_FILE_BATCH_MAX, STOREFRONT_FILE_MAX_BYTES, STOREFRONT_PATH_SEGMENT_PATTERN, STOREFRONT_PLATFORM_DOMAINS, STOREFRONT_PUBLIC_SUFFIXES, STOREFRONT_SEARCH_REGEX_MAX_LENGTH, STOREFRONT_SHOWCASE_SLUG_PREFIX, STOREFRONT_SITE_CREATE_LIMIT, STOREFRONT_SLUG_CHANGE_LIMIT, STOREFRONT_SLUG_CHANGE_WINDOW_DAYS, STOREFRONT_SLUG_HOLD_DAYS, STOREFRONT_SLUG_PATTERN, STOREFRONT_SOURCE_BLOB_BATCH_MAX, STOREFRONT_SOURCE_PART_BYTES, STOREFRONT_WORKSPACE_MAX_BYTES, STOREFRONT_WORKSPACE_MAX_FILES, STORE_CODE_PATTERN, STORE_DRAFT_ATTACHMENT_MAX_BYTES, STORE_DRAFT_MAX_ATTACHMENTS, STORE_DRAFT_RETENTION_DAYS, STORE_ROLE_SCOPES, STORE_SCOPE_RESOURCES, STORE_SESSION_KEYS, STORE_SHOP_TYPES, TEMPLATE_STORE_LOCKED_BUSINESS_FIELDS, TOSS_WIDGET_CLIENT_KEY_PATTERN, TOSS_WIDGET_KEY_MESSAGE, TOSS_WIDGET_SECRET_KEY_PATTERN, UPLOAD_PURPOSE_LIMITS, VARIANT_COUNT_WARNING, VARIANT_STOCK_EXCLUSIVE_MESSAGE, WEBHOOK_DEFAULT_TOLERANCE_SEC, WEBHOOK_DELIVERY_ID_HEADER, WEBHOOK_EVENT_ID_HEADER, WEBHOOK_EVENT_TYPE_HEADER, WEBHOOK_FAILURE_REASONS, WEBHOOK_HEADERS, WEBHOOK_PAYLOAD_EXCERPT_MAX_BYTES, WEBHOOK_RESOURCE_TYPES, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_USER_AGENT, addStorefrontDomainRequestSchema, additionalCurrencyPriceSchema, additionalCurrencyPricesSchema, addonGroupRequestSchema, addonGroupSchema, addonValueRequestSchema, addonValueSchema, addressChangeRequestListSchema, addressTypeSchema, agentPolicyDecisionSchema, aiActivitySchema, aiAgentPhaseSchema, aiAttachmentSchema, aiChoiceOptionSchema, aiConversationFileChangesSchema, aiConversationSchema, aiConversationSummarySchema, aiDesignBoardSchema, aiDesignCanvasSchema, aiDesignConfirmBoardSchema, aiDesignSelectionSchema, aiFileChangeKindSchema, aiFocusAreaSchema, aiFocusSchema, aiMessagePartSchema, aiMessageSchema, aiPreviewSelectionSchema, aiRunChangesSchema, aiRunChangesStatusSchema, aiRunFileDiffSchema, aiRunRevertConflictDetailsSchema, aiRunRevertResultSchema, aiRunSchema, aiRunStatusSchema, aiSetupConfirmItemSchema, aiStreamAccessSchema, aiStreamEventSchema, aiStreamRecordSchema, aiTodoSchema, aiToolChangeSchema, allocateByWeight, analyticsChannelSchema, analyticsCheckoutOutcomeSchema, analyticsCheckoutSchema, analyticsDeviceRowSchema, analyticsDevicesSchema, analyticsFunnelStepSchema, analyticsOriginSchema, analyticsOverviewSchema, analyticsPagesQuerySchema, analyticsPagesSchema, analyticsProductRowSchema, analyticsProductSortSchema, analyticsProductsQuerySchema, analyticsProductsSchema, analyticsRangeQuerySchema, analyticsRealtimeSchema, analyticsSearchQuerySchema, analyticsSearchSchema, analyticsSourceGroupBySchema, analyticsSourceRowSchema, analyticsSourcesQuerySchema, analyticsSourcesSchema, analyticsTotalsSchema, apiLogErrorSchema, apiLogListQuerySchema, apiLogPageSchema, apiLogPrincipalSchema, apiLogPrincipalTypeSchema, apiLogSchema, apiLogStatusFilterSchema, apiLogSummarySchema, appArtifactUploadSchema, appBuildSchema, appBuildStageSchema, appCapabilitiesOf, appDeployKeyCreateSchema, appDeployKeyCreatedSchema, appDeployKeySchema, appDevTokenSchema, appDistributionSchema, appEventTypeSchema, appFlowEventSchema, appFlowEventSummarySchema, appFlowNotificationSchema, appFlowNotificationSummarySchema, appFlowParamSchema, appFlowSummaryOf, appHandleSchema, appHttpKeyMatches, appIconProblem, appInstallRequestSchema, appInstallationActivitySchema, appInstallationAppSchema, appInstallationRunSchema, appInstallationSchema, appInstallationSelfSchema, appInstallationSettingsSchema, appInstallationSettingsUpdateSchema, appInstallationStatusSchema, appInvocationSchema, appListingReviewSchema, appListingReviewStatusSchema, appListingSchema, appManifestProblems, appManifestSchema, appManifestWidens, appNetworkHostProblem, appNetworkHostSchema, appReleaseResultSchema, appRuntimeSchema, appScheduleIntervalLabel, appScheduleListOf, appScheduleSummarySchema, appScopeSchema, appSecretSummarySchema, appSessionSchema, appSettingFieldSchema, appStatusSchema, appStorageEntrySchema, appStorageKeysSchema, appStorageListQuerySchema, appStoragePutSchema, appToolCallSchema, appToolInputSchema, appToolListOf, appToolResultSchema, appToolSchema, appToolSummarySchema, appVersionSchema, appVersionStatusSchema, appVisibilitySchema, applyFlowOperationsRequestSchema, approvalDecisionRequestSchema, approvalListQuerySchema, approvalPageSchema, approvalRequestSchema, approvalStatusSchema, approveClaimResultSchema, assertSaleUnit, auditActorSchema, auditActorTypeSchema, auditLogListQuerySchema, auditLogOutcomeSchema, auditLogPageSchema, auditLogSchema, auditLogSourceSchema, bestSellingRuleOf, brandBriefProductSourceSchema, brandBriefReferenceSchema, brandBriefSchema, brandBriefViewSchema, buildAuthorizeUrl, buildQuery, bulkResultSchema, businessInfoPatchShape, businessInfoResponseShape, businessNumberSchema, calendarDateSchema, calendarDaySchema, calendarQuerySchema, cancelBySellerRequestSchema, cancelBySellerResultSchema, carrierSchema, cashReceiptSchema, categoryAttributeSchema, categoryCreateRequestSchema, categoryDeleteQuerySchema, categoryDeleteStrategySchema, categoryListQuerySchema, categoryLocalizationRequestSchema, categoryLocalizationSchema, categoryPatchRequestSchema, categoryProductSortSchema, categorySchema, categorySearchResultSchema, categoryTreeNodeSchema, categoryWithPathSchema, changeStorefrontSlugRequestSchema, changeStorefrontTemplateRequestSchema, changeTypeSchema, claimCollectCompleteRequestSchema, claimDetailSchema, claimFlowEditSessionRequestSchema, claimHoldResultSchema, claimListQuerySchema, claimReasonSchema, claimRedeliveryRequestSchema, claimReturnAddressSchema, claimSchema, claimStatusSchema, claimTypeSchema, claimWebhookEventDataSchema, claimWebhookEventSchema, collectionCreateRequestSchema, collectionListQuerySchema, collectionLocalizationRequestSchema, collectionLocalizationSchema, collectionPageSchema, collectionPatchRequestSchema, collectionPreviewRequestSchema, collectionPreviewSchema, collectionProductListQuerySchema, collectionProductSchema, collectionProductSortRequestSchema, collectionProductsAddRequestSchema, collectionProductsReplaceRequestSchema, collectionRuleCategoryIds, collectionRuleSchema, collectionRuleViewSchema, collectionRulesPredicate, collectionRulesSchema, collectionSchema, collectionStateCountsSchema, collectionStateOf, collectionStateSchema, commerceFlowCheckSchema, commerceFlowSchema, commerceFlowSummarySchema, commerceFlowVersionViewSchema, commerceNumberField, compareBySales, connectStorefrontGitRequestSchema, consentActionSchema, consentKindSchema, consentSourceSchema, couponBenefitSchema, couponConditionsInputSchema, couponConditionsSchema, couponDiscountOf, couponIssueListQuerySchema, couponIssueMethodSchema, couponIssueSchema, couponIssueStatusSchema, couponKindSchema, couponListQuerySchema, couponRedemptionListQuerySchema, couponRedemptionSchema, couponRejectReasonSchema, couponRuleSchema, couponSchema, couponStatsSchema, couponStatusSchema, couponTargetInputSchema, couponTargetSchema, createAiConversationRequestSchema, createAiConversationResponseSchema, createCommerceFlowRequestSchema, createCouponRequestSchema, createMarketRequestSchema, createPkcePair, createStoreClient, createStoreDraftRequestSchema, createStoreDraftResponseSchema, createStoreSession, createStorefrontEditPreviewLinkRequestSchema, createStorefrontPreviewLinkRequestSchema, createStorefrontSiteRequestSchema, createStorefrontVersionRequestSchema, currencyCodeSchema, currencyRefundFeesSchema, currencyShippingPolicySchema, currencySpecOf, customInputLabelForbiddenWord, customInputRequestSchema, customInputSchema, customInputValueSchema, customerAddressSchema, customerConsentListQuerySchema, customerConsentSchema, customerConsentStateSchema, customerConsentsSchema, customerCouponSchema, customerDelegationRequestSchema, customerDelegationSchema, customerDetailSchema, customerInquiryCategorySchema, customerInquiryListQuerySchema, customerListQuerySchema, customerOrderSchema, customerPointsSchema, customerSortSchema, customerStatsSchema, customerSummarySchema, customerWithdrawalBlockedDetailsSchema, defaultFulfillmentMethodOf, deleteStorefrontFileRequestSchema, deliveryBundleKeyOf, deliveryFeeWaiverSchema, deliveryInfoSchema, deliveryMethodSchema, deliveryStatusSchema, deliveryTypeSchema, descendantCategoryIdsOf, describeScope, devStoreSchema, developerAppCreateSchema, developerAppSchema, developerInstallationSchema, developerOrgSchema, developerStoreSchema, disableStorefrontHostingRequestSchema, discountRequestSchema, discountSchema, dispatchRequestSchema, easyPayProviderResponseSchema, easyPayProviderSchema, eventTypeSchema, exchangeAuthorizationCode, floorToSaleUnit, flowActionRequestSchema, flowActionResultSchema, flowActionSchema, flowAuthoringGuideSchema, flowDraftEdgesSchema, flowDraftNodeSchema, flowDraftNodesSchema, flowDraftOperationSchema, flowEditSessionViewSchema, flowFieldValueSchema, flowInputFieldSchema, flowIssueSchema, flowNodeIdSchema, flowNodeTypeDetailSchema, flowNodeTypesSchema, flowNotificationWebhookEventDataSchema, flowNotificationWebhookEventSchema, flowOperationsResultSchema, flowPresetDetailSchema, flowPresetSummarySchema, flowRunSchema, flowRunStepSchema, flowSecretNameSchema, flowSecretSchema, flowStateChangedWebhookEventDataSchema, flowStateChangedWebhookEventSchema, flowStateSchema, formatOrderNo, fromDecimalString, fulfillBulkRequestSchema, fulfillRequestSchema, fulfillmentMethodOf, fulfillmentMethodSchema, fulfillmentMethodsOf, fulfillmentRuleOf, fulfillmentTypeOf, fulfillmentTypeResponseSchema, fulfillmentTypeSchema, holdOrderItemRequestSchema, infoFieldSourceSchema, infoSchemaFieldSchema, infoSchemaSchema, infoSectionLocalizationRequestSchema, infoSectionLocalizationSchema, infoSectionRequestSchema, infoSectionSchema, inquiryListQuerySchema, inquirySchema, inquiryWebhookEventDataSchema, inquiryWebhookEventSchema, inventoryAdjustmentLineSchema, inventoryAdjustmentReasonSchema, inventoryAdjustmentRequestSchema, inventoryChangedWebhookEventDataSchema, inventoryChangedWebhookEventSchema, inventoryLevelListQuerySchema, inventoryLevelPageSchema, inventoryLevelSchema, inventoryLocationRequestSchema, inventoryLocationSchema, inventoryModeSchema, inventoryMovementKindSchema, inventoryMovementListQuerySchema, inventoryMovementPageSchema, inventoryMovementSchema, inventoryOperationResultSchema, inventoryTransferRequestSchema, invitationDeliveryStatusSchema, invitationListQuerySchema, invitationSchema, inviteMemberRequestSchema, isAiAgentNotesPath, isAiDesignPath, isCouponTargetLine, isCurrencyCode, isEditableStorefrontPath, isInstallableScope, isReservedStoreCode, isReservedStorefrontSlug, isSaleUnitPrice, isShowcaseStorefrontSlug, isStoreScope, isWebOrigin, issueCouponRequestSchema, issueCouponResultSchema, kakaoPayCredentialsInputSchema, linkStorefrontGitInstallationRequestSchema, liveGateConditionCodeSchema, liveGateConditionSchema, liveGateErrorDetailsSchema, liveGateSchema, localeCodeSchema, loginProviderSchema, loginProviderStatusSchema, loginProviderTestSchema, loginSettingsSchema, marketSchema, maskedSecretSchema, matchesCollectionRules, mcpRuleResultSchema, mcpToolEventSchema, migrateFlowVersionRequestSchema, migrateFlowVersionResultSchema, minPaymentOf, minorToMajor, moneyRulesOf, moveFlowStateRequestSchema, moveStorefrontFileRequestSchema, myAccountSchema, myStoreSchema, naverPayCredentialsInputSchema, nightsOf, normalizeBusinessNumber, normalizeCouponCode, normalizeLocale, normalizeStorefrontHostname, normalizeStorefrontPath, oauthTokenResponseSchema, openFulfillmentUnion, optionGroupKindSchema, optionGroupRequestSchema, optionGroupSchema, optionModelRequestSchema, optionModelSchema, optionSelectionSchema, optionSortSchema, optionValueRequestSchema, optionValueSchema, orderCanceledWebhookEventDataSchema, orderCanceledWebhookEventSchema, orderDiscountSchema, orderFlowActionResultSchema, orderFulfilledWebhookEventDataSchema, orderFulfilledWebhookEventSchema, orderItemFlowSchema, orderItemFulfillmentSchema, orderItemFulfillmentSnapshotResponseSchema, orderItemFulfillmentSnapshotSchema, orderItemListQuerySchema, orderItemMemoResultSchema, orderItemPageSchema, orderItemSchema, orderItemStatusSchema, orderListQuerySchema, orderSchema, orderSummaryPageSchema, orderSummarySchema, orderWebhookEventDataSchema, orderWebhookEventSchema, pageInfoSchema, pageQueryShape, pageSchema, parseOrderNo, parseWebhookEvent, payPalCredentialsInputSchema, paymentAttemptRecordSchema, paymentAttemptStatusSchema, paymentCredentialSetSchema, paymentFailureWarningSchema, paymentListQuerySchema, paymentProviderSchema, paymentProviderVerificationSchema, paymentRecordDetailSchema, paymentRecordPageSchema, paymentRecordSchema, paymentRecordStatusSchema, paymentRefundRecordSchema, paymentSettingsSchema, paymentStatusProviderSchema, paymentStatusSchema, pgEnvironmentSchema, pgPaymentMethodSchema, pgProviderResponseSchema, pgProviderSchema, pgVerificationResultSchema, pickupLocationRequestSchema, pickupLocationSchema, pickupLocationSnapshotSchema, planCodeSchema, planEntitlementsSchema, planErrorDetailsSchema, platformCodeSchema, pointAdjustmentRequestSchema, pointAdjustmentResultSchema, pointEarnOf, pointEarnRateBpSchema, pointEarningEnabled, pointEntrySchema, pointExpiresAtOf, pointHistoryQuerySchema, pointLotSchema, pointPolicyNoticeSchema, pointPolicySchema, pointRestoreExpiresAtOf, pointUseOf, pointUsePolicySchema, policyDocumentUrlSchema, policyVersionSchema, portOneChannelSchema, portOneCredentialsInputSchema, productCertificationsRequestSchema, productCertificationsSchema, productCreateRequestSchema, productCurrencyPriceSchema, productCurrencyPricesSchema, productFulfillmentCreateSchema, productFulfillmentResponseSchema, productFulfillmentSchema, productFulfillmentUpdateSchema, productImageRejection, productImageUrlSchema, productListQuerySchema, productLocalizationNeedsTranslation, productLocalizationRequestSchema, productLocalizationSchema, productNoticeRequestSchema, productNoticeSchema, productOutOfStockWebhookEventDataSchema, productOutOfStockWebhookEventSchema, productPatchRequestSchema, productRefundPolicyOverride, productRefundPolicyPatchSchema, productReplaceRequestSchema, productSchema, productSortSchema, productStatusSchema, productSummarySchema, productVariantRequestSchema, productVariantSchema, proratedPaidRefundBase, proratedPointRefund, proratedRefundBase, publicPlanSchema, publicPlansSchema, publishStorefrontVersionRequestSchema, purchaseDecisionExtendResultSchema, purchaseDecisionRequestResultSchema, purchaseEarnPolicySchema, purchaseEarnRateOf, putBrandBriefRequestSchema, quoteDelivery, quotePricing, rankBestSelling, refreshUserToken, refundPolicyPatchSchema, refundPolicySchema, rejectClaimRequestSchema, remoteAreaLabelOf, remoteAreaOf, remoteAreaSchema, remoteSurchargeOf, replaceStorefrontSourceRequestSchema, replayFlowRequestSchema, replayFlowResultSchema, requiresCollection, requiresShipping, resolvePointPolicy, resolveRefundPolicy, resolveShippingPolicy, resolvedFlowSchema, responsePlanCodeSchema, responsePointEntryTypeSchema, reviewListQuerySchema, reviewReportResultSchema, reviewRewardPointOf, reviewRewardPolicySchema, reviewSchema, reviewSortSchema, reviewWebhookEventDataSchema, reviewWebhookEventSchema, rollbackStorefrontRequestSchema, runStorefrontCheckRequestSchema, salesReportCurrencySchema, salesReportGroupBySchema, salesReportQuerySchema, salesReportRowSchema, salesReportSchema, salesTotalsSchema, saveFlowDraftRequestSchema, saveFlowSecretRequestSchema, saveLoginProviderRequestSchema, savedCustomInputRequestSchema, savedCustomInputSchema, savedOptionGroupRequestSchema, savedOptionGroupSchema, savedOptionSetCompositionSchema, savedOptionSetFromProductRequestSchema, savedOptionSetFromProductResultSchema, savedOptionSetListQuerySchema, savedOptionSetLocalizationRequestSchema, savedOptionSetLocalizationSchema, savedOptionSetRequestSchema, savedOptionSetSchema, savedOptionSetSortSchema, savedOptionValueRequestSchema, savedOptionValueSchema, scopeAccessSchema, scopesCoverEvent, searchStorefrontFilesRequestSchema, sellerAddressListQuerySchema, sellerAddressRequestSchema, sellerAddressSchema, sellerCancelPreviewSchema, sellerCustomerInquirySchema, sendAiMessageRequestSchema, sendAiMessageResponseSchema, setCalendarRequestSchema, setPlatformTestKeysRequestSchema, setStorefrontDeployApprovalRequestSchema, setStorefrontVisibilityRequestSchema, settleCouponShortfall, settlementDetailQuerySchema, settlementDetailSchema, settlementListQuerySchema, settlementStatusSchema, settlementSummarySchema, settlementWithDetailsSchema, shippingAddressSchema, shippingCurrencyPriceSchema, shippingCurrencyPricesSchema, shippingPolicyPatchSchema, shippingPolicySchema, simulateFlowRequestSchema, simulateFlowResultSchema, simulationStepSchema, splitRefund, starterSellerTaskSchema, starterStageSchema, starterStatusSchema, starterStoreInfoFieldSchema, stayRangeSchema, staySnapshotSchema, storeAppDetailSchema, storeAppSchema, storeCodeSchema, storeDraftPreviewSchema, storeDraftSchema, storeIndustrySchema, storeMemberRoleUpdatedSchema, storeMemberSchema, storePointPolicySchema, storeRoleSchema, storeSchema, storeScopeResourceSchema, storeSetupBriefSchema, storeShopTypeSchema, storeSubscriptionSchema, storeTemplateSchema, storedAdditionalCurrencyPriceSchema, storedProductCurrencyPriceSchema, storedShippingCurrencyPriceSchema, storefrontBuildDependenciesSchema, storefrontBuildListQuerySchema, storefrontBuildSchema, storefrontBuildStatusSchema, storefrontCheckSchema, storefrontCheckStatusSchema, storefrontCustomDomainStatusSchema, storefrontCustomHostnameProblem, storefrontDependencyFindingSchema, storefrontDeploymentLogSchema, storefrontDeploymentSchema, storefrontDeploymentStepSchema, storefrontDevLogsSchema, storefrontDnsRecordSchema, storefrontDomainSchema, storefrontDomainTxtNameOf, storefrontEditFailureSchema, storefrontEditPreviewLabelOf, storefrontEditPreviewSchema, storefrontEditSessionSchema, storefrontEditSessionStatusSchema, storefrontEditingSchema, storefrontFileConflictDetailsSchema, storefrontFileContentQuerySchema, storefrontFileContentSchema, storefrontFileDeleteResultSchema, storefrontFileEncodingSchema, storefrontFileEntrySchema, storefrontFileHashSchema, storefrontFileListQuerySchema, storefrontFileListSchema, storefrontFileMoveResultSchema, storefrontFilePathSchema, storefrontFileSearchResultSchema, storefrontFileWriteResultSchema, storefrontGitConnectStateSchema, storefrontGitMergeRequestSchema, storefrontGitMergeSchema, storefrontGitRepositorySchema, storefrontGitStatusSchema, storefrontHostingSchema, storefrontPreviewLinkSchema, storefrontProvisioningSchema, storefrontRuleResultSchema, storefrontRuleSeveritySchema, storefrontSiteDomainSchema, storefrontSiteDomainsSchema, storefrontSiteSchema, storefrontSiteSnapshotSchema, storefrontSiteStatusSchema, storefrontSlugAvailabilityQuerySchema, storefrontSlugAvailabilitySchema, storefrontSlugSchema, storefrontSourceArchivePartSchema, storefrontSourceArchiveQuerySchema, storefrontSourceBlobsResultSchema, storefrontSourceModeSchema, storefrontSourceRefSchema, storefrontSourceReplacedSchema, storefrontSourceSchema, storefrontSuspensionSchema, storefrontTemplateSchema, storefrontVerifyReportSchema, storefrontVersionCreatedSchema, storefrontVersionPreviewLabelOf, storefrontVersionSchema, storefrontVersionStatusSchema, storefrontVisibilitySchema, subscriptionLimitsSchema, subscriptionStatusSchema, subscriptionUsageSchema, toDecimalString, toMinor, tossPaymentsCredentialsInputSchema, trackingStageResponseSchema, trackingUpdateResultSchema, unknownWebhookEventSchema, updateCouponRequestSchema, updateLoginProviderRequestSchema, updateLoginSettingsRequestSchema, updateMarketRequestSchema, updateMemberRoleRequestSchema, updatePaymentProviderRequestSchema, updatePaymentSettingsRequestSchema, updatePointPolicyRequestSchema, updateStoreRequestSchema, updateStoreTemplateRequestSchema, uploadExtensionOf, uploadPurposeSchema, uploadRejection, uploadRequestSchema, uploadStorefrontSourceBlobsRequestSchema, uploadTicketSchema, upsertKakaoPayProviderRequestSchema, upsertNaverPayProviderRequestSchema, upsertPayPalProviderRequestSchema, upsertPortOneProviderRequestSchema, upsertTossPaymentsProviderRequestSchema, variantStockRequestSchema, variantStockSchema, verifyPaymentProviderRequestSchema, webhookCreatedSchema, webhookDeliveryDetailSchema, webhookDeliveryErrorCodeSchema, webhookDeliveryListQuerySchema, webhookDeliveryResourceSchema, webhookDeliverySchema, webhookDeliveryStatusSchema, webhookEventSchema, webhookFailureReasonSchema, webhookRedeliverFailedResultSchema, webhookRequestHeaderSchema, webhookRequestSchema, webhookResourceTypeSchema, webhookSchema, webhookSecretRotatedSchema, webhookStatusSchema, webhookTestRequestSchema, webhookTestResultSchema, withdrawCustomerRequestSchema, writeDryRunResultSchema, writePreviewSchema, writeStorefrontFilesRequestSchema };
|
|
11422
|
+
export { AI_AGENT_NOTES_DIR, AI_AGENT_PHASES, AI_DESIGN_BOARDS_MAX, AI_DESIGN_BOARD_FILE_PATTERN, AI_DESIGN_BOARD_KINDS, AI_DESIGN_CANVAS_PATH, AI_DESIGN_CONFIRM_APPROVE, AI_DESIGN_DIR, AI_DESIGN_GUIDE_PATH, AI_DESIGN_VIEWPORTS, AI_MESSAGE_MAX_ATTACHMENTS, AI_MESSAGE_MAX_CHARS, AI_RUN_ACTIVE_STATUSES, AI_RUN_FILE_CHANGES_RETENTION_DAYS, AI_RUN_RESUME_CHOICE, AI_SETUP_CONFIRM_APPROVE, AI_SITEMAP_PATH, AI_TODOS_MAX, AI_TODO_STATUSES, AI_TOOL_CHANGE_LINE_MAX, AI_TOOL_CHANGE_RANGES_MAX, APPROVAL_ALREADY_DECIDED_CODE, APPROVAL_REQUIRED_CODE, APP_CAPABILITIES, APP_DEPLOY_KEY_PATTERN, APP_DEPLOY_KEY_PREFIX, APP_EVENTS_MAX, APP_EVENT_SCOPES, APP_EVENT_TYPES, APP_FLOW_EVENT_PATTERN, APP_FLOW_ITEMS_MAX, APP_FLOW_NOTIFICATION_PATTERN, APP_HANDLE_PATTERN, APP_HTTP_KEY_PATTERN, APP_ICON_CONTENT_TYPES, APP_ICON_MAX_BYTES, APP_ICON_MIN_PX, APP_LIFECYCLE_EVENT_TYPES, APP_NETWORK_DENIED_SUFFIXES, APP_NETWORK_HOSTS_MAX, APP_PUBLIC_HTTP_MAX, APP_README_MAX_BYTES, APP_RESERVED_HANDLES, APP_SCHEDULES_MAX, APP_SCHEDULE_INTERVALS, APP_SCHEDULE_NAME_PATTERN, APP_SECRETS_MAX, APP_SECRET_NAME_PATTERN, APP_SECRET_PATTERNS, APP_SERVER_BUNDLE_MAX_GZIP_BYTES, APP_SETTINGS_MAX_FIELDS, APP_SETTING_FIELD_TYPES, APP_SETTING_KEY_PATTERN, APP_STORAGE_KEY_PATTERN, APP_STORAGE_MAX_BYTES, APP_STORAGE_MAX_KEYS, APP_TOOL_NAME_PATTERN, APP_UI_MAX_BYTES, APP_UI_MAX_FILES, ApiError, ApprovalPendingError, BASE_CURRENCY, BRAND_BRIEF_MAX_REFERENCES, BUSINESS_INFO_MAX_LENGTH, BUSINESS_NUMBER_PATTERN, CASH_RECEIPT_STATUS_VALUES, CERTIFICATION_STATUSES, COLLECTION_BEST_SELLING_DAYS, COLLECTION_PREVIEW_SIZE, COLLECTION_PRODUCT_SORTS, COLLECTION_SALES_SORT_DEFAULT_DAYS, COLLECTION_SLUG_PATTERN, COLLECTION_TYPES, COUPON_CODE_PATTERN, COUPON_CONDITIONS_DEFAULTS, COUPON_TARGET_ALL, COUPON_TARGET_LIST_MAX, CURRENCIES, CURRENCY_CODES, CUSTOM_INPUT_FORBIDDEN_WORDS, CUSTOM_INPUT_TYPES, DEDICATED_EASY_PAY_PROVIDER, DEFAULT_STORE_LOCALE, FULFILLMENT_METHODS, FULFILLMENT_METHODS_BY_TYPE, FULFILLMENT_METHOD_RULES, FULFILLMENT_RULES, INSTALLABLE_SCOPES, InvalidPriceUnitError, KAKAOPAY_TEST_CID, KNOWN_WEBHOOK_EVENT_TYPES, KRW_MONEY_RULES, MAX_ADDON_GROUPS, MAX_ANALYTICS_ALLOWED_ORIGINS, MAX_AUTO_TRANSITION_DAYS, MAX_CALENDAR_DAYS, MAX_CERTIFICATION_ITEMS, MAX_COLLECTIONS, MAX_COLLECTION_BEST_SELLING_TOP, MAX_COLLECTION_CREATED_WITHIN_DAYS, MAX_COLLECTION_DESCRIPTION, MAX_COLLECTION_PRODUCTS, MAX_COLLECTION_PRODUCTS_PER_ADD, MAX_COLLECTION_RULES, MAX_COLLECTION_RULE_CATEGORIES, MAX_COLLECTION_TITLE, MAX_CUSTOM_INPUTS, MAX_CUSTOM_INPUT_LENGTH, MAX_INFO_SECTION_TITLE, MAX_INVENTORY_OPERATION_LINES, MAX_NOTICE_VALUE_LENGTH, MAX_OPTION_GROUPS, MAX_PICKUP_LOCATIONS, MAX_PRODUCT_IMAGES, MAX_PRODUCT_INFO_SECTIONS, MAX_SAVED_OPTION_SETS, MAX_SAVED_OPTION_SET_NAME, MAX_STAY_NIGHTS, MAX_VALUES_PER_GROUP, MAX_VARIANTS, MCP_TELEMETRY_MAX_RESULTS, MIN_PAYMENT_AMOUNT, NON_INSTALLABLE_SCOPES, NO_COUPON_SETTLEMENT, NO_SHIPPING_BUNDLE_KEY, PAYMENT_ROUTING_EXCLUSION_CODES, PAYPAL_CURRENCIES, PLATFORM_CODE_SETS, POINT_ADJUSTMENT_MAX, POINT_EARN_RATE_BP_MAX, POINT_ENTRY_TYPES, POINT_EXPIRY_DAYS_MAX, POINT_EXPIRY_DAYS_MIN, POINT_LOT_SOURCES, POINT_POLICY_DEFAULTS, POINT_REVIEW_REWARD_MAX, POINT_USE_UNITS, PORTONE_CHANNEL_NAME_MAX_LENGTH, PORTONE_MAX_CHANNELS, PORTONE_MIN_CHANNELS, REFUND_POLICY_DEFAULTS, REFUND_POLICY_DELIVERY_FEE_KEYS, REMOTE_AREA_ZIP_RANGES, RESERVED_STOREFRONT_SLUGS, RESERVED_STORE_CODES, SAYREN_API_BASE_URL, SAYREN_API_ORIGIN, SCOPE_DESCRIPTIONS, SHIPPING_POLICY_DEFAULTS, STARTER_SELLER_TASKS, STARTER_STAGES, STOREFRONT_BLOCKED_PATH_SEGMENTS, STOREFRONT_BUILD_STAGES, STOREFRONT_BUILD_TERMINAL_STATUSES, STOREFRONT_CHECK_TERMINAL_STATUSES, STOREFRONT_CLOSED_SITE_HOLD_DAYS, STOREFRONT_CUSTOM_DOMAIN_LIMIT_DEFAULT, STOREFRONT_DOMAIN_DNS_GRACE_DAYS, STOREFRONT_DOMAIN_DNS_WAIT_DAYS, STOREFRONT_DOMAIN_TXT_LABEL, STOREFRONT_EDIT_ACTIVITY_TIMEOUT_MINUTES, STOREFRONT_EDIT_CAPACITY, STOREFRONT_EDIT_IDLE_MINUTES, STOREFRONT_EDIT_PREVIEW_SUFFIX, STOREFRONT_EDIT_START_STAGES, STOREFRONT_FILE_BATCH_MAX, STOREFRONT_FILE_MAX_BYTES, STOREFRONT_PATH_SEGMENT_PATTERN, STOREFRONT_PLATFORM_DOMAINS, STOREFRONT_PUBLIC_SUFFIXES, STOREFRONT_SEARCH_REGEX_MAX_LENGTH, STOREFRONT_SHOWCASE_SLUG_PREFIX, STOREFRONT_SITE_CREATE_LIMIT, STOREFRONT_SLUG_CHANGE_LIMIT, STOREFRONT_SLUG_CHANGE_WINDOW_DAYS, STOREFRONT_SLUG_HOLD_DAYS, STOREFRONT_SLUG_PATTERN, STOREFRONT_SOURCE_BLOB_BATCH_MAX, STOREFRONT_SOURCE_PART_BYTES, STOREFRONT_WORKSPACE_MAX_BYTES, STOREFRONT_WORKSPACE_MAX_FILES, STORE_CODE_PATTERN, STORE_DRAFT_ATTACHMENT_MAX_BYTES, STORE_DRAFT_MAX_ATTACHMENTS, STORE_DRAFT_RETENTION_DAYS, STORE_ROLE_SCOPES, STORE_SCOPE_RESOURCES, STORE_SESSION_KEYS, STORE_SHOP_TYPES, TEMPLATE_STORE_LOCKED_BUSINESS_FIELDS, TOSS_WIDGET_CLIENT_KEY_PATTERN, TOSS_WIDGET_KEY_MESSAGE, TOSS_WIDGET_SECRET_KEY_PATTERN, UPLOAD_PURPOSE_LIMITS, VARIANT_COUNT_WARNING, VARIANT_STOCK_EXCLUSIVE_MESSAGE, WEBHOOK_DEFAULT_TOLERANCE_SEC, WEBHOOK_DELIVERY_ID_HEADER, WEBHOOK_EVENT_ID_HEADER, WEBHOOK_EVENT_TYPE_HEADER, WEBHOOK_FAILURE_REASONS, WEBHOOK_HEADERS, WEBHOOK_PAYLOAD_EXCERPT_MAX_BYTES, WEBHOOK_RESOURCE_TYPES, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_USER_AGENT, addStorefrontDomainRequestSchema, additionalCurrencyPriceSchema, additionalCurrencyPricesSchema, addonGroupRequestSchema, addonGroupSchema, addonValueRequestSchema, addonValueSchema, addressChangeRequestListSchema, addressTypeSchema, agentPolicyDecisionSchema, aiActivitySchema, aiAgentPhaseSchema, aiAttachmentSchema, aiChoiceOptionSchema, aiConversationFileChangesSchema, aiConversationSchema, aiConversationSummarySchema, aiDesignBoardSchema, aiDesignCanvasSchema, aiDesignConfirmBoardSchema, aiDesignSelectionSchema, aiFileChangeKindSchema, aiFocusAreaSchema, aiFocusSchema, aiMessagePartSchema, aiMessageSchema, aiPreviewSelectionSchema, aiRunChangesSchema, aiRunChangesStatusSchema, aiRunFileDiffSchema, aiRunRevertConflictDetailsSchema, aiRunRevertResultSchema, aiRunSchema, aiRunStatusSchema, aiSetupConfirmItemSchema, aiStreamAccessSchema, aiStreamEventSchema, aiStreamRecordSchema, aiTodoSchema, aiToolChangeSchema, allocateByWeight, analyticsChannelSchema, analyticsCheckoutOutcomeSchema, analyticsCheckoutSchema, analyticsDeviceRowSchema, analyticsDevicesSchema, analyticsFunnelStepSchema, analyticsOriginSchema, analyticsOverviewSchema, analyticsPagesQuerySchema, analyticsPagesSchema, analyticsProductRowSchema, analyticsProductSortSchema, analyticsProductsQuerySchema, analyticsProductsSchema, analyticsRangeQuerySchema, analyticsRealtimeSchema, analyticsSearchQuerySchema, analyticsSearchSchema, analyticsSourceGroupBySchema, analyticsSourceRowSchema, analyticsSourcesQuerySchema, analyticsSourcesSchema, analyticsTotalsSchema, apiLogErrorSchema, apiLogListQuerySchema, apiLogPageSchema, apiLogPrincipalSchema, apiLogPrincipalTypeSchema, apiLogSchema, apiLogStatusFilterSchema, apiLogSummarySchema, appArtifactUploadSchema, appBuildSchema, appBuildStageSchema, appCapabilitiesOf, appDeployKeyCreateSchema, appDeployKeyCreatedSchema, appDeployKeySchema, appDevTokenSchema, appDistributionSchema, appEventTypeSchema, appFlowEventSchema, appFlowEventSummarySchema, appFlowNotificationSchema, appFlowNotificationSummarySchema, appFlowParamSchema, appFlowSummaryOf, appHandleSchema, appHttpKeyMatches, appIconProblem, appInstallRequestSchema, appInstallationActivitySchema, appInstallationAppSchema, appInstallationRunSchema, appInstallationSchema, appInstallationSelfSchema, appInstallationSettingsSchema, appInstallationSettingsUpdateSchema, appInstallationStatusSchema, appInvocationSchema, appListingReviewSchema, appListingReviewStatusSchema, appListingSchema, appManifestProblems, appManifestSchema, appManifestWidens, appNetworkHostProblem, appNetworkHostSchema, appReleaseResultSchema, appRuntimeSchema, appScheduleIntervalLabel, appScheduleListOf, appScheduleSummarySchema, appScopeSchema, appSecretSummarySchema, appSessionSchema, appSettingFieldSchema, appStatusSchema, appStorageEntrySchema, appStorageKeysSchema, appStorageListQuerySchema, appStoragePutSchema, appToolCallSchema, appToolInputSchema, appToolListOf, appToolResultSchema, appToolSchema, appToolSummarySchema, appVersionSchema, appVersionStatusSchema, appVisibilitySchema, applyFlowOperationsRequestSchema, approvalDecisionRequestSchema, approvalListQuerySchema, approvalPageSchema, approvalRequestSchema, approvalStatusSchema, approveClaimResultSchema, assertSaleUnit, auditActorSchema, auditActorTypeSchema, auditLogListQuerySchema, auditLogOutcomeSchema, auditLogPageSchema, auditLogSchema, auditLogSourceSchema, bestSellingRuleOf, brandBriefProductSourceSchema, brandBriefReferenceSchema, brandBriefSchema, brandBriefViewSchema, buildAuthorizeUrl, buildQuery, bulkResultSchema, businessInfoPatchShape, businessInfoResponseShape, businessNumberSchema, calendarDateSchema, calendarDaySchema, calendarQuerySchema, cancelBySellerRequestSchema, cancelBySellerResultSchema, carrierSchema, cashReceiptSchema, categoryAttributeSchema, categoryCreateRequestSchema, categoryDeleteQuerySchema, categoryDeleteStrategySchema, categoryListQuerySchema, categoryLocalizationRequestSchema, categoryLocalizationSchema, categoryPatchRequestSchema, categoryProductSortSchema, categorySchema, categorySearchResultSchema, categoryTreeNodeSchema, categoryWithPathSchema, changeStorefrontSlugRequestSchema, changeStorefrontTemplateRequestSchema, changeTypeSchema, claimCollectCompleteRequestSchema, claimDetailSchema, claimFlowEditSessionRequestSchema, claimHoldResultSchema, claimListQuerySchema, claimReasonSchema, claimRedeliveryRequestSchema, claimReturnAddressSchema, claimSchema, claimStatusSchema, claimTypeSchema, claimWebhookEventDataSchema, claimWebhookEventSchema, collectionCreateRequestSchema, collectionListQuerySchema, collectionLocalizationRequestSchema, collectionLocalizationSchema, collectionPageSchema, collectionPatchRequestSchema, collectionPreviewRequestSchema, collectionPreviewSchema, collectionProductListQuerySchema, collectionProductSchema, collectionProductSortRequestSchema, collectionProductsAddRequestSchema, collectionProductsReplaceRequestSchema, collectionRuleCategoryIds, collectionRuleSchema, collectionRuleViewSchema, collectionRulesPredicate, collectionRulesSchema, collectionSchema, collectionStateCountsSchema, collectionStateOf, collectionStateSchema, commerceFlowCheckSchema, commerceFlowSchema, commerceFlowSummarySchema, commerceFlowVersionViewSchema, commerceNumberField, compareBySales, connectStorefrontGitRequestSchema, consentActionSchema, consentKindSchema, consentSourceSchema, couponBenefitSchema, couponConditionsInputSchema, couponConditionsSchema, couponDiscountOf, couponIssueListQuerySchema, couponIssueMethodSchema, couponIssueSchema, couponIssueStatusSchema, couponKindSchema, couponListQuerySchema, couponRedemptionListQuerySchema, couponRedemptionSchema, couponRejectReasonSchema, couponRuleSchema, couponSchema, couponStatsSchema, couponStatusSchema, couponTargetInputSchema, couponTargetSchema, createAiConversationRequestSchema, createAiConversationResponseSchema, createCommerceFlowRequestSchema, createCouponRequestSchema, createMarketRequestSchema, createPkcePair, createStoreClient, createStoreDraftRequestSchema, createStoreDraftResponseSchema, createStoreSession, createStorefrontEditPreviewLinkRequestSchema, createStorefrontPreviewLinkRequestSchema, createStorefrontSiteRequestSchema, createStorefrontVersionRequestSchema, currencyCodeSchema, currencyRefundFeesSchema, currencyShippingPolicySchema, currencySpecOf, customInputLabelForbiddenWord, customInputRequestSchema, customInputSchema, customInputValueSchema, customerAddressSchema, customerConsentListQuerySchema, customerConsentSchema, customerConsentStateSchema, customerConsentsSchema, customerCouponSchema, customerDelegationRequestSchema, customerDelegationSchema, customerDetailSchema, customerInquiryCategorySchema, customerInquiryListQuerySchema, customerListQuerySchema, customerOrderSchema, customerPointsSchema, customerSortSchema, customerStatsSchema, customerSummarySchema, customerWithdrawalBlockedDetailsSchema, defaultFulfillmentMethodOf, deleteStorefrontFileRequestSchema, deliveryBundleKeyOf, deliveryFeeWaiverSchema, deliveryInfoSchema, deliveryMethodSchema, deliveryStatusSchema, deliveryTypeSchema, descendantCategoryIdsOf, describeScope, devStoreSchema, developerAppCreateSchema, developerAppSchema, developerInstallationSchema, developerOrgSchema, developerStoreSchema, disableStorefrontHostingRequestSchema, discountRequestSchema, discountSchema, dispatchRequestSchema, easyPayProviderResponseSchema, easyPayProviderSchema, eventTypeSchema, exchangeAuthorizationCode, floorToSaleUnit, flowActionRequestSchema, flowActionResultSchema, flowActionSchema, flowAuthoringGuideSchema, flowDraftEdgesSchema, flowDraftNodeSchema, flowDraftNodesSchema, flowDraftOperationSchema, flowEditSessionViewSchema, flowFieldValueSchema, flowInputFieldSchema, flowIssueSchema, flowNodeIdSchema, flowNodeTypeDetailSchema, flowNodeTypesSchema, flowNotificationWebhookEventDataSchema, flowNotificationWebhookEventSchema, flowOperationsResultSchema, flowPresetDetailSchema, flowPresetSummarySchema, flowRunSchema, flowRunStepSchema, flowSecretNameSchema, flowSecretSchema, flowStateChangedWebhookEventDataSchema, flowStateChangedWebhookEventSchema, flowStateSchema, formatOrderNo, fromDecimalString, fulfillBulkRequestSchema, fulfillRequestSchema, fulfillmentMethodOf, fulfillmentMethodSchema, fulfillmentMethodsOf, fulfillmentRuleOf, fulfillmentTypeOf, fulfillmentTypeResponseSchema, fulfillmentTypeSchema, holdOrderItemRequestSchema, infoFieldSourceSchema, infoSchemaFieldSchema, infoSchemaSchema, infoSectionLocalizationRequestSchema, infoSectionLocalizationSchema, infoSectionRequestSchema, infoSectionSchema, inquiryListQuerySchema, inquirySchema, inquiryWebhookEventDataSchema, inquiryWebhookEventSchema, inventoryAdjustmentLineSchema, inventoryAdjustmentReasonSchema, inventoryAdjustmentRequestSchema, inventoryChangedWebhookEventDataSchema, inventoryChangedWebhookEventSchema, inventoryLevelListQuerySchema, inventoryLevelPageSchema, inventoryLevelSchema, inventoryLocationRequestSchema, inventoryLocationSchema, inventoryModeSchema, inventoryMovementKindSchema, inventoryMovementListQuerySchema, inventoryMovementPageSchema, inventoryMovementSchema, inventoryOperationResultSchema, inventoryTransferRequestSchema, invitationDeliveryStatusSchema, invitationListQuerySchema, invitationSchema, inviteMemberRequestSchema, isAiAgentNotesPath, isAiChoiceAnswer, isAiDesignPath, isAiWorkspaceDocPath, isCouponTargetLine, isCurrencyCode, isEditableStorefrontPath, isInstallableScope, isReservedStoreCode, isReservedStorefrontSlug, isSaleUnitPrice, isShowcaseStorefrontSlug, isStoreScope, isWebOrigin, issueCouponRequestSchema, issueCouponResultSchema, kakaoPayCredentialsInputSchema, linkStorefrontGitInstallationRequestSchema, liveGateConditionCodeSchema, liveGateConditionSchema, liveGateErrorDetailsSchema, liveGateSchema, localeCodeSchema, loginProviderSchema, loginProviderStatusSchema, loginProviderTestSchema, loginSettingsSchema, marketSchema, maskedSecretSchema, matchesCollectionRules, mcpRuleResultSchema, mcpToolEventSchema, migrateFlowVersionRequestSchema, migrateFlowVersionResultSchema, minPaymentOf, minorToMajor, moneyRulesOf, moveFlowStateRequestSchema, moveStorefrontFileRequestSchema, myAccountSchema, myStoreSchema, naverPayCredentialsInputSchema, nightsOf, normalizeBusinessNumber, normalizeCouponCode, normalizeLocale, normalizeStorefrontHostname, normalizeStorefrontPath, oauthTokenResponseSchema, openFulfillmentUnion, optionGroupKindSchema, optionGroupRequestSchema, optionGroupSchema, optionModelRequestSchema, optionModelSchema, optionSelectionSchema, optionSortSchema, optionValueRequestSchema, optionValueSchema, orderCanceledWebhookEventDataSchema, orderCanceledWebhookEventSchema, orderDiscountSchema, orderFlowActionResultSchema, orderFulfilledWebhookEventDataSchema, orderFulfilledWebhookEventSchema, orderItemFlowSchema, orderItemFulfillmentSchema, orderItemFulfillmentSnapshotResponseSchema, orderItemFulfillmentSnapshotSchema, orderItemListQuerySchema, orderItemMemoResultSchema, orderItemPageSchema, orderItemSchema, orderItemStatusSchema, orderListQuerySchema, orderSchema, orderSummaryPageSchema, orderSummarySchema, orderWebhookEventDataSchema, orderWebhookEventSchema, pageInfoSchema, pageQueryShape, pageSchema, parseOrderNo, parseWebhookEvent, payPalCredentialsInputSchema, paymentAttemptRecordSchema, paymentAttemptStatusSchema, paymentCredentialSetSchema, paymentFailureWarningSchema, paymentListQuerySchema, paymentProviderSchema, paymentProviderVerificationSchema, paymentRecordDetailSchema, paymentRecordPageSchema, paymentRecordSchema, paymentRecordStatusSchema, paymentRefundRecordSchema, paymentSettingsSchema, paymentStatusProviderSchema, paymentStatusSchema, pgEnvironmentSchema, pgPaymentMethodSchema, pgProviderResponseSchema, pgProviderSchema, pgVerificationResultSchema, pickupLocationRequestSchema, pickupLocationSchema, pickupLocationSnapshotSchema, planCodeSchema, planEntitlementsSchema, planErrorDetailsSchema, platformCodeSchema, pointAdjustmentRequestSchema, pointAdjustmentResultSchema, pointEarnOf, pointEarnRateBpSchema, pointEarningEnabled, pointEntrySchema, pointExpiresAtOf, pointHistoryQuerySchema, pointLotSchema, pointPolicyNoticeSchema, pointPolicySchema, pointRestoreExpiresAtOf, pointUseOf, pointUsePolicySchema, policyDocumentUrlSchema, policyVersionSchema, portOneChannelSchema, portOneCredentialsInputSchema, productCertificationsRequestSchema, productCertificationsSchema, productCreateRequestSchema, productCurrencyPriceSchema, productCurrencyPricesSchema, productFulfillmentCreateSchema, productFulfillmentResponseSchema, productFulfillmentSchema, productFulfillmentUpdateSchema, productImageRejection, productImageUrlSchema, productListQuerySchema, productLocalizationNeedsTranslation, productLocalizationRequestSchema, productLocalizationSchema, productNoticeRequestSchema, productNoticeSchema, productOutOfStockWebhookEventDataSchema, productOutOfStockWebhookEventSchema, productPatchRequestSchema, productRefundPolicyOverride, productRefundPolicyPatchSchema, productReplaceRequestSchema, productSchema, productSortSchema, productStatusSchema, productSummarySchema, productVariantRequestSchema, productVariantSchema, proratedPaidRefundBase, proratedPointRefund, proratedRefundBase, publicPlanSchema, publicPlansSchema, publishStorefrontVersionRequestSchema, purchaseDecisionExtendResultSchema, purchaseDecisionRequestResultSchema, purchaseEarnPolicySchema, purchaseEarnRateOf, putBrandBriefRequestSchema, quoteDelivery, quotePricing, rankBestSelling, refreshUserToken, refundPolicyPatchSchema, refundPolicySchema, rejectClaimRequestSchema, remoteAreaLabelOf, remoteAreaOf, remoteAreaSchema, remoteSurchargeOf, replaceStorefrontSourceRequestSchema, replayFlowRequestSchema, replayFlowResultSchema, requiresCollection, requiresShipping, resolvePointPolicy, resolveRefundPolicy, resolveShippingPolicy, resolvedFlowSchema, responsePlanCodeSchema, responsePointEntryTypeSchema, reviewListQuerySchema, reviewReportResultSchema, reviewRewardPointOf, reviewRewardPolicySchema, reviewSchema, reviewSortSchema, reviewWebhookEventDataSchema, reviewWebhookEventSchema, rollbackStorefrontRequestSchema, runStorefrontCheckRequestSchema, salesReportCurrencySchema, salesReportGroupBySchema, salesReportQuerySchema, salesReportRowSchema, salesReportSchema, salesTotalsSchema, saveFlowDraftRequestSchema, saveFlowSecretRequestSchema, saveLoginProviderRequestSchema, savedCustomInputRequestSchema, savedCustomInputSchema, savedOptionGroupRequestSchema, savedOptionGroupSchema, savedOptionSetCompositionSchema, savedOptionSetFromProductRequestSchema, savedOptionSetFromProductResultSchema, savedOptionSetListQuerySchema, savedOptionSetLocalizationRequestSchema, savedOptionSetLocalizationSchema, savedOptionSetRequestSchema, savedOptionSetSchema, savedOptionSetSortSchema, savedOptionValueRequestSchema, savedOptionValueSchema, scopeAccessSchema, scopesCoverEvent, searchStorefrontFilesRequestSchema, sellerAddressListQuerySchema, sellerAddressRequestSchema, sellerAddressSchema, sellerCancelPreviewSchema, sellerCustomerInquirySchema, sendAiMessageRequestSchema, sendAiMessageResponseSchema, setCalendarRequestSchema, setPlatformTestKeysRequestSchema, setStorefrontDeployApprovalRequestSchema, setStorefrontVisibilityRequestSchema, settleCouponShortfall, settlementDetailQuerySchema, settlementDetailSchema, settlementListQuerySchema, settlementStatusSchema, settlementSummarySchema, settlementWithDetailsSchema, shippingAddressSchema, shippingCurrencyPriceSchema, shippingCurrencyPricesSchema, shippingPolicyPatchSchema, shippingPolicySchema, simulateFlowRequestSchema, simulateFlowResultSchema, simulationStepSchema, splitRefund, starterSellerTaskSchema, starterStageSchema, starterStatusSchema, starterStoreInfoFieldSchema, stayRangeSchema, staySnapshotSchema, storeAppDetailSchema, storeAppSchema, storeCodeSchema, storeDraftPreviewSchema, storeDraftSchema, storeIndustrySchema, storeMemberRoleUpdatedSchema, storeMemberSchema, storePointPolicySchema, storeRoleSchema, storeSchema, storeScopeResourceSchema, storeSetupBriefSchema, storeShopTypeSchema, storeSubscriptionSchema, storeTemplateSchema, storedAdditionalCurrencyPriceSchema, storedProductCurrencyPriceSchema, storedShippingCurrencyPriceSchema, storefrontBuildDependenciesSchema, storefrontBuildListQuerySchema, storefrontBuildSchema, storefrontBuildStatusSchema, storefrontCheckSchema, storefrontCheckStatusSchema, storefrontCustomDomainStatusSchema, storefrontCustomHostnameProblem, storefrontDependencyFindingSchema, storefrontDeploymentLogSchema, storefrontDeploymentSchema, storefrontDeploymentStepSchema, storefrontDevLogsSchema, storefrontDnsRecordSchema, storefrontDomainSchema, storefrontDomainTxtNameOf, storefrontEditFailureSchema, storefrontEditPreviewLabelOf, storefrontEditPreviewSchema, storefrontEditSessionSchema, storefrontEditSessionStatusSchema, storefrontEditingSchema, storefrontFileConflictDetailsSchema, storefrontFileContentQuerySchema, storefrontFileContentSchema, storefrontFileDeleteResultSchema, storefrontFileEncodingSchema, storefrontFileEntrySchema, storefrontFileHashSchema, storefrontFileListQuerySchema, storefrontFileListSchema, storefrontFileMoveResultSchema, storefrontFilePathSchema, storefrontFileSearchResultSchema, storefrontFileWriteResultSchema, storefrontGitConnectStateSchema, storefrontGitMergeRequestSchema, storefrontGitMergeSchema, storefrontGitRepositorySchema, storefrontGitStatusSchema, storefrontHostingSchema, storefrontPreviewLinkSchema, storefrontProvisioningSchema, storefrontRuleResultSchema, storefrontRuleSeveritySchema, storefrontSiteDomainSchema, storefrontSiteDomainsSchema, storefrontSiteSchema, storefrontSiteSnapshotSchema, storefrontSiteStatusSchema, storefrontSlugAvailabilityQuerySchema, storefrontSlugAvailabilitySchema, storefrontSlugSchema, storefrontSourceArchivePartSchema, storefrontSourceArchiveQuerySchema, storefrontSourceBlobsResultSchema, storefrontSourceModeSchema, storefrontSourceRefSchema, storefrontSourceReplacedSchema, storefrontSourceSchema, storefrontSuspensionSchema, storefrontTemplateSchema, storefrontVerifyReportSchema, storefrontVersionCreatedSchema, storefrontVersionPreviewLabelOf, storefrontVersionSchema, storefrontVersionStatusSchema, storefrontVisibilitySchema, subscriptionLimitsSchema, subscriptionStatusSchema, subscriptionUsageSchema, toDecimalString, toMinor, tossPaymentsCredentialsInputSchema, trackingStageResponseSchema, trackingUpdateResultSchema, unknownWebhookEventSchema, updateCouponRequestSchema, updateLoginProviderRequestSchema, updateLoginSettingsRequestSchema, updateMarketRequestSchema, updateMemberRoleRequestSchema, updatePaymentProviderRequestSchema, updatePaymentSettingsRequestSchema, updatePointPolicyRequestSchema, updateStoreRequestSchema, updateStoreTemplateRequestSchema, uploadExtensionOf, uploadPurposeSchema, uploadRejection, uploadRequestSchema, uploadStorefrontSourceBlobsRequestSchema, uploadTicketSchema, upsertKakaoPayProviderRequestSchema, upsertNaverPayProviderRequestSchema, upsertPayPalProviderRequestSchema, upsertPortOneProviderRequestSchema, upsertTossPaymentsProviderRequestSchema, variantStockRequestSchema, variantStockSchema, verifyPaymentProviderRequestSchema, webhookCreatedSchema, webhookDeliveryDetailSchema, webhookDeliveryErrorCodeSchema, webhookDeliveryListQuerySchema, webhookDeliveryResourceSchema, webhookDeliverySchema, webhookDeliveryStatusSchema, webhookEventSchema, webhookFailureReasonSchema, webhookRedeliverFailedResultSchema, webhookRequestHeaderSchema, webhookRequestSchema, webhookResourceTypeSchema, webhookSchema, webhookSecretRotatedSchema, webhookStatusSchema, webhookTestRequestSchema, webhookTestResultSchema, withdrawCustomerRequestSchema, writeDryRunResultSchema, writePreviewSchema, writeStorefrontFilesRequestSchema };
|