@sayren/store-sdk 0.5.0 → 0.6.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 +43 -16
- package/dist/index.mjs +34 -25
- package/package.json +1 -1
- package/src/client.ts +11 -3
- package/src/schemas/analytics.ts +1 -1
- package/src/schemas/claim.ts +10 -2
- package/src/schemas/customer.ts +1 -1
- package/src/schemas/login.ts +1 -1
- package/src/schemas/product.ts +21 -10
- package/src/schemas/store.ts +6 -6
package/dist/index.d.mts
CHANGED
|
@@ -976,11 +976,14 @@ export declare const claimSchema: z.ZodObject<{
|
|
|
976
976
|
}, z.core.$strip>>;
|
|
977
977
|
requestedAt: z.ZodString;
|
|
978
978
|
completedAt: z.ZodNullable<z.ZodString>;
|
|
979
|
+
holdExpiresAt: z.ZodNullable<z.ZodString>;
|
|
980
|
+
holdUsed: z.ZodBoolean;
|
|
979
981
|
}, z.core.$strip>;
|
|
980
982
|
export type Claim = z.infer<typeof claimSchema>;
|
|
981
983
|
export interface ClaimListParams extends PageParams {
|
|
982
984
|
type?: ClaimType;
|
|
983
|
-
|
|
985
|
+
/** 여러 상태를 한 번에 거를 수 있다(처리 대기 목록 등) */
|
|
986
|
+
status?: ClaimStatus | ClaimStatus[];
|
|
984
987
|
orderItemId?: string;
|
|
985
988
|
requestedFrom?: string;
|
|
986
989
|
requestedTo?: string;
|
|
@@ -994,17 +997,7 @@ export declare const claimListQuerySchema: z.ZodObject<{
|
|
|
994
997
|
EXCHANGE: "EXCHANGE";
|
|
995
998
|
CANCEL: "CANCEL";
|
|
996
999
|
}>>;
|
|
997
|
-
status: z.ZodOptional<z.
|
|
998
|
-
REQUESTED: "REQUESTED";
|
|
999
|
-
HELD: "HELD";
|
|
1000
|
-
COLLECTING: "COLLECTING";
|
|
1001
|
-
COLLECTED: "COLLECTED";
|
|
1002
|
-
REDELIVERING: "REDELIVERING";
|
|
1003
|
-
APPROVED: "APPROVED";
|
|
1004
|
-
REJECTED: "REJECTED";
|
|
1005
|
-
COMPLETED: "COMPLETED";
|
|
1006
|
-
WITHDRAWN: "WITHDRAWN";
|
|
1007
|
-
}>>;
|
|
1000
|
+
status: z.ZodOptional<z.ZodString>;
|
|
1008
1001
|
orderItemId: z.ZodOptional<z.ZodString>;
|
|
1009
1002
|
requestedFrom: z.ZodOptional<z.ZodString>;
|
|
1010
1003
|
requestedTo: z.ZodOptional<z.ZodString>;
|
|
@@ -1061,6 +1054,8 @@ export declare const claimDetailSchema: z.ZodObject<{
|
|
|
1061
1054
|
}, z.core.$strip>>;
|
|
1062
1055
|
requestedAt: z.ZodString;
|
|
1063
1056
|
completedAt: z.ZodNullable<z.ZodString>;
|
|
1057
|
+
holdExpiresAt: z.ZodNullable<z.ZodString>;
|
|
1058
|
+
holdUsed: z.ZodBoolean;
|
|
1064
1059
|
histories: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1065
1060
|
status: z.ZodEnum<{
|
|
1066
1061
|
REQUESTED: "REQUESTED";
|
|
@@ -1245,7 +1240,7 @@ export declare const withdrawCustomerRequestSchema: z.ZodObject<{
|
|
|
1245
1240
|
memo: z.ZodOptional<z.ZodString>;
|
|
1246
1241
|
}, z.core.$strip>;
|
|
1247
1242
|
export type WithdrawCustomerRequest = z.infer<typeof withdrawCustomerRequestSchema>;
|
|
1248
|
-
/** `WITHDRAWAL_BLOCKED`의 `error.details` — 탈퇴를 막는 항목 수(
|
|
1243
|
+
/** `WITHDRAWAL_BLOCKED`의 `error.details` — 탈퇴를 막는 항목 수(스토어프론트 탈퇴와 같다) */
|
|
1249
1244
|
export declare const customerWithdrawalBlockedDetailsSchema: z.ZodObject<{
|
|
1250
1245
|
inProgressOrderItems: z.ZodNumber;
|
|
1251
1246
|
openClaims: z.ZodNumber;
|
|
@@ -3542,7 +3537,7 @@ export declare function isReservedStoreCode(code: string): boolean;
|
|
|
3542
3537
|
export declare const storeCodeSchema: z.ZodString;
|
|
3543
3538
|
/** `https://shop.example.com`처럼 경로·쿼리 없는 http(s) 오리진인가 */
|
|
3544
3539
|
export declare function isWebOrigin(value: string): boolean;
|
|
3545
|
-
/** 방문 분석을 보낼 수 있는
|
|
3540
|
+
/** 방문 분석을 보낼 수 있는 스토어프론트 오리진 — 스킴·호스트(·포트)만. 서버가 소문자·끝 슬래시 제거로 정규화한다 */
|
|
3546
3541
|
export declare const analyticsOriginSchema: z.ZodString;
|
|
3547
3542
|
/** 허용 오리진 상한 */
|
|
3548
3543
|
export declare const MAX_ANALYTICS_ALLOWED_ORIGINS = 20;
|
|
@@ -4589,6 +4584,8 @@ export declare function createStoreClient(options: StoreClientOptions): {
|
|
|
4589
4584
|
} | null;
|
|
4590
4585
|
requestedAt: string;
|
|
4591
4586
|
completedAt: string | null;
|
|
4587
|
+
holdExpiresAt: string | null;
|
|
4588
|
+
holdUsed: boolean;
|
|
4592
4589
|
}[];
|
|
4593
4590
|
}>;
|
|
4594
4591
|
get: (claimId: string) => Promise<{
|
|
@@ -4615,6 +4612,8 @@ export declare function createStoreClient(options: StoreClientOptions): {
|
|
|
4615
4612
|
} | null;
|
|
4616
4613
|
requestedAt: string;
|
|
4617
4614
|
completedAt: string | null;
|
|
4615
|
+
holdExpiresAt: string | null;
|
|
4616
|
+
holdUsed: boolean;
|
|
4618
4617
|
histories?: {
|
|
4619
4618
|
status: "REQUESTED" | "HELD" | "COLLECTING" | "COLLECTED" | "REDELIVERING" | "APPROVED" | "REJECTED" | "COMPLETED" | "WITHDRAWN";
|
|
4620
4619
|
actor: "BUYER" | "SELLER" | "SYSTEM";
|
|
@@ -4639,6 +4638,34 @@ export declare function createStoreClient(options: StoreClientOptions): {
|
|
|
4639
4638
|
holdExpiresAt: string;
|
|
4640
4639
|
}>;
|
|
4641
4640
|
releaseHold: (claimId: string) => Promise<void>;
|
|
4641
|
+
/** 교환 완료 — 재배송 중인 교환을 셀러가 명시적으로 끝낸다 */
|
|
4642
|
+
completeExchange: (claimId: string) => Promise<{
|
|
4643
|
+
claimId: string;
|
|
4644
|
+
type: "RETURN" | "EXCHANGE" | "CANCEL";
|
|
4645
|
+
status: "REQUESTED" | "HELD" | "COLLECTING" | "COLLECTED" | "REDELIVERING" | "APPROVED" | "REJECTED" | "COMPLETED" | "WITHDRAWN";
|
|
4646
|
+
orderId: string;
|
|
4647
|
+
orderItemId: string;
|
|
4648
|
+
productName: string;
|
|
4649
|
+
quantity: number;
|
|
4650
|
+
reason: "CHANGE_OF_MIND" | "WRONG_ORDER" | "DEFECTIVE" | "WRONG_DELIVERY" | "DIFFERENT_FROM_PAGE" | "DELAY";
|
|
4651
|
+
reasonDetail: string | null;
|
|
4652
|
+
responsibility: "BUYER" | "SELLER";
|
|
4653
|
+
claimDeliveryFee: number;
|
|
4654
|
+
expectedRefundAmount: number | null;
|
|
4655
|
+
exchangeOption: {
|
|
4656
|
+
optionId: string;
|
|
4657
|
+
optionName: string;
|
|
4658
|
+
} | null;
|
|
4659
|
+
collect: {
|
|
4660
|
+
method: "SELLER_PICKUP" | "BUYER_SEND";
|
|
4661
|
+
carrierCode: string | null;
|
|
4662
|
+
trackingNumber: string | null;
|
|
4663
|
+
} | null;
|
|
4664
|
+
requestedAt: string;
|
|
4665
|
+
completedAt: string | null;
|
|
4666
|
+
holdExpiresAt: string | null;
|
|
4667
|
+
holdUsed: boolean;
|
|
4668
|
+
}>;
|
|
4642
4669
|
};
|
|
4643
4670
|
inquiries: {
|
|
4644
4671
|
list: (params?: PageParams & {
|
|
@@ -4993,7 +5020,7 @@ export declare function createStoreClient(options: StoreClientOptions): {
|
|
|
4993
5020
|
}>;
|
|
4994
5021
|
};
|
|
4995
5022
|
/**
|
|
4996
|
-
* 방문 분석 — 스코프 `analytics:r`.
|
|
5023
|
+
* 방문 분석 — 스코프 `analytics:r`. 스토어프론트가 `@sayren/storefront-sdk`로 수집한 이벤트를 Asia/Seoul 날짜별로
|
|
4997
5024
|
* 집계한 값이다. 집계는 주기적으로 갱신되고 응답 `lastComputedAt`이 마지막 집계 시각이다. 봇 세션은 빠진다.
|
|
4998
5025
|
* 기간은 양끝 포함 최대 92일이고, 테스트 결제 구매는 `includeTest: "true"`일 때만 포함한다.
|
|
4999
5026
|
*/
|
|
@@ -6124,7 +6151,7 @@ export declare function createStoreClient(options: StoreClientOptions): {
|
|
|
6124
6151
|
}>;
|
|
6125
6152
|
/**
|
|
6126
6153
|
* `PATCH /v1/store` — 스코프 `store:rw`. 바꿀 필드만 보낸다. `analyticsAllowedOrigins`는 방문 분석 수집을 받을
|
|
6127
|
-
*
|
|
6154
|
+
* 스토어프론트 오리진 목록이다(빈 배열이면 모든 오리진 허용).
|
|
6128
6155
|
*/
|
|
6129
6156
|
update: (body: UpdateStoreRequest) => Promise<{
|
|
6130
6157
|
storeId: string;
|
package/dist/index.mjs
CHANGED
|
@@ -150,7 +150,7 @@ function createHttp(options) {
|
|
|
150
150
|
/**
|
|
151
151
|
* 방문 분석 조회 (관리 API `/v1/analytics/*`, 스코프 `analytics:r`).
|
|
152
152
|
*
|
|
153
|
-
*
|
|
153
|
+
* 스토어프론트가 `@sayren/storefront-sdk`로 수집한 이벤트를 서버가 날짜(Asia/Seoul)별로 집계한 값이다. 집계는 주기적으로
|
|
154
154
|
* 갱신되므로 오늘 값은 `lastComputedAt` 시점까지 반영돼 있다. 봇·자동화 브라우저의 세션은 모든 집계에서 빠진다.
|
|
155
155
|
*/
|
|
156
156
|
const reportDate$1 = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "날짜 형식은 YYYY-MM-DD 입니다");
|
|
@@ -654,12 +654,16 @@ const claimSchema = z.object({
|
|
|
654
654
|
trackingNumber: z.string().nullable()
|
|
655
655
|
}).nullable(),
|
|
656
656
|
requestedAt: z.string(),
|
|
657
|
-
completedAt: z.string().nullable()
|
|
657
|
+
completedAt: z.string().nullable(),
|
|
658
|
+
/** 보류 중이면 자동 해제 시각(ISO 8601), 아니면 null */
|
|
659
|
+
holdExpiresAt: z.string().nullable(),
|
|
660
|
+
/** 보류를 이미 썼는지 — 보류는 클레임당 1회라 해제·만료 뒤에도 true */
|
|
661
|
+
holdUsed: z.boolean()
|
|
658
662
|
});
|
|
659
663
|
/** `GET /v1/claims` 쿼리 — OpenAPI 문서용 형태(값은 쿼리 문자열) */
|
|
660
664
|
const claimListQuerySchema = z.object({
|
|
661
665
|
type: claimTypeSchema.optional().describe("클레임 유형 필터"),
|
|
662
|
-
status:
|
|
666
|
+
status: z.string().optional().describe("클레임 상태 필터. 쉼표로 여러 개를 줄 수 있다 (예: `REQUESTED,HELD,COLLECTED`)"),
|
|
663
667
|
orderItemId: z.string().optional().describe("주문상품 id 필터"),
|
|
664
668
|
requestedFrom: z.string().optional().describe("요청 시각 조회 시작 (ISO 8601, 포함)"),
|
|
665
669
|
requestedTo: z.string().optional().describe("요청 시각 조회 끝 (ISO 8601, 포함)"),
|
|
@@ -798,7 +802,7 @@ const withdrawCustomerRequestSchema = z.object({
|
|
|
798
802
|
]).describe("처리 사유 — 구매자 요청·장기 미이용·부정 이용·기타. 감사 로그에 남는다"),
|
|
799
803
|
memo: z.string().max(200).optional().describe("사유 보충(선택)")
|
|
800
804
|
});
|
|
801
|
-
/** `WITHDRAWAL_BLOCKED`의 `error.details` — 탈퇴를 막는 항목 수(
|
|
805
|
+
/** `WITHDRAWAL_BLOCKED`의 `error.details` — 탈퇴를 막는 항목 수(스토어프론트 탈퇴와 같다) */
|
|
802
806
|
const customerWithdrawalBlockedDetailsSchema = z.object({
|
|
803
807
|
inProgressOrderItems: z.number().int(),
|
|
804
808
|
openClaims: z.number().int(),
|
|
@@ -816,7 +820,7 @@ const loginProviderSchema = z.enum([
|
|
|
816
820
|
const loginProviderStatusSchema = z.object({
|
|
817
821
|
provider: loginProviderSchema,
|
|
818
822
|
connected: z.boolean(),
|
|
819
|
-
/**
|
|
823
|
+
/** 스토어프론트에서 사용 중인지. 연결 안 됐으면 false */
|
|
820
824
|
enabled: z.boolean(),
|
|
821
825
|
clientIdPrefix: z.string().nullable().describe("클라이언트 ID(카카오 REST API 키) 앞 4자리"),
|
|
822
826
|
secretPrefix: z.string().nullable(),
|
|
@@ -1600,10 +1604,10 @@ const productSummarySchema = z.object({
|
|
|
1600
1604
|
productId: z.string(),
|
|
1601
1605
|
name: z.string(),
|
|
1602
1606
|
status: productStatusSchema,
|
|
1603
|
-
salePrice: z.number().int(),
|
|
1604
|
-
discountedPrice: z.number().int().nullable(),
|
|
1607
|
+
salePrice: z.number().int().describe("판매가. 원(KRW) 단위 정수"),
|
|
1608
|
+
discountedPrice: z.number().int().nullable().describe("즉시 할인 적용가. 원 단위. 할인이 없으면 null"),
|
|
1605
1609
|
/** usable variant 재고 합계 (서버 계산) */
|
|
1606
|
-
stockQuantity: z.number().int(),
|
|
1610
|
+
stockQuantity: z.number().int().describe("판매 가능한 옵션 재고의 합계. 서버가 계산한다"),
|
|
1607
1611
|
categoryId: z.string().nullable(),
|
|
1608
1612
|
thumbnailUrl: z.url().optional(),
|
|
1609
1613
|
/** optionGroups.length > 0 */
|
|
@@ -1740,8 +1744,8 @@ const variantStockSchema = z.object({
|
|
|
1740
1744
|
const productCreateRequestSchema = z.object({
|
|
1741
1745
|
name: z.string().min(1).max(100),
|
|
1742
1746
|
categoryId: z.string().min(1, "카테고리를 선택해주세요"),
|
|
1743
|
-
salePrice: z.number().int().min(10).multipleOf(10, "판매가는 10원 단위여야 합니다 (INVALID_PRICE_UNIT)"),
|
|
1744
|
-
originalPrice: z.number().int().optional(),
|
|
1747
|
+
salePrice: z.number().int().min(10).multipleOf(10, "판매가는 10원 단위여야 합니다 (INVALID_PRICE_UNIT)").describe("판매가. 원(KRW) 단위 정수, 최소 10원, 10원 단위"),
|
|
1748
|
+
originalPrice: z.number().int().optional().describe("정가(할인 전 표시 가격). 원 단위"),
|
|
1745
1749
|
description: z.string().optional(),
|
|
1746
1750
|
/**
|
|
1747
1751
|
* 상세설명 에디터(@avarlabs/editor)의 직렬화 상태. 재편집 때 이 값으로 문서를 복원한다.
|
|
@@ -1753,11 +1757,11 @@ const productCreateRequestSchema = z.object({
|
|
|
1753
1757
|
attributeId: z.string(),
|
|
1754
1758
|
value: z.string()
|
|
1755
1759
|
})).optional(),
|
|
1756
|
-
deliveryType: deliveryTypeSchema.default("PAID"),
|
|
1757
|
-
deliveryFee: z.number().int().default(0),
|
|
1758
|
-
conditionalFreeAmount: z.number().int().optional(),
|
|
1759
|
-
returnFee: z.number().int().default(0),
|
|
1760
|
-
exchangeFee: z.number().int().default(0),
|
|
1760
|
+
deliveryType: deliveryTypeSchema.default("PAID").describe("배송비 유형. FREE 무료, PAID 유료, CONDITIONAL_FREE 조건부 무료"),
|
|
1761
|
+
deliveryFee: z.number().int().default(0).describe("배송비. 원 단위"),
|
|
1762
|
+
conditionalFreeAmount: z.number().int().optional().describe("CONDITIONAL_FREE일 때 무료 배송이 되는 주문 금액. 원 단위"),
|
|
1763
|
+
returnFee: z.number().int().default(0).describe("반품 배송비. 원 단위"),
|
|
1764
|
+
exchangeFee: z.number().int().default(0).describe("교환 배송비. 원 단위"),
|
|
1761
1765
|
shippingAddressId: z.string().optional(),
|
|
1762
1766
|
returnAddressId: z.string().optional()
|
|
1763
1767
|
}).extend(optionModelRequestSchema.shape);
|
|
@@ -1873,8 +1877,8 @@ function isWebOrigin(value) {
|
|
|
1873
1877
|
return false;
|
|
1874
1878
|
}
|
|
1875
1879
|
}
|
|
1876
|
-
/** 방문 분석을 보낼 수 있는
|
|
1877
|
-
const analyticsOriginSchema = z.string().trim().max(255).refine(isWebOrigin, "https://shop.example.com 형식(경로 없이)으로 입력해 주세요").describe("
|
|
1880
|
+
/** 방문 분석을 보낼 수 있는 스토어프론트 오리진 — 스킴·호스트(·포트)만. 서버가 소문자·끝 슬래시 제거로 정규화한다 */
|
|
1881
|
+
const analyticsOriginSchema = z.string().trim().max(255).refine(isWebOrigin, "https://shop.example.com 형식(경로 없이)으로 입력해 주세요").describe("스토어프론트 오리진. 예: `https://shop.example.com`");
|
|
1878
1882
|
/** 허용 오리진 상한 */
|
|
1879
1883
|
const MAX_ANALYTICS_ALLOWED_ORIGINS = 20;
|
|
1880
1884
|
/** `PATCH /v1/store` 본문 — 바꿀 필드만 보낸다 */
|
|
@@ -1883,8 +1887,8 @@ const updateStoreRequestSchema = z.object({
|
|
|
1883
1887
|
logoUrl: z.url().optional(),
|
|
1884
1888
|
customerCenterPhone: z.string().optional(),
|
|
1885
1889
|
businessHours: z.string().max(100).optional(),
|
|
1886
|
-
analyticsAllowedOrigins: z.array(analyticsOriginSchema).max(20).optional().describe("@deprecated `storefrontOrigins`를 쓴다(같은 목록). 방문 분석 수집을 받을
|
|
1887
|
-
storefrontOrigins: z.array(analyticsOriginSchema).max(20).optional().describe("
|
|
1890
|
+
analyticsAllowedOrigins: z.array(analyticsOriginSchema).max(20).optional().describe("@deprecated `storefrontOrigins`를 쓴다(같은 목록). 방문 분석 수집을 받을 스토어프론트 오리진(최대 20개). 비우면 모든 오리진에서 받는다. 넣으면 목록에 없는 오리진의 수집 요청은 403 `ORIGIN_NOT_ALLOWED`이고, 페이지 URL이 목록 밖인 이벤트는 버린다"),
|
|
1891
|
+
storefrontOrigins: z.array(analyticsOriginSchema).max(20).optional().describe("스토어프론트 도메인(최대 20개) — 소셜 로그인 뒤 돌아갈 주소와 방문 분석 수집을 함께 제한한다. `analyticsAllowedOrigins`와 같은 목록이다(둘 다 주면 이 값이 이긴다)"),
|
|
1888
1892
|
guestCheckoutEnabled: z.boolean().optional().describe("비회원 주문 허용. false(회원만)면 로그인하지 않은 구매자의 주문서 생성·결제 요청이 403 `GUEST_CHECKOUT_DISABLED`다. 장바구니 담기와 이미 받은 비회원 주문의 조회·취소는 막지 않는다")
|
|
1889
1893
|
}).refine((value) => Object.values(value).some((v) => v !== void 0), { message: "최소 1개 필드가 필요합니다" });
|
|
1890
1894
|
const storeSchema = z.object({
|
|
@@ -1900,8 +1904,8 @@ const storeSchema = z.object({
|
|
|
1900
1904
|
logoUrl: z.url().nullable(),
|
|
1901
1905
|
businessNumber: z.string().nullable(),
|
|
1902
1906
|
customerCenterPhone: z.string().nullable(),
|
|
1903
|
-
analyticsAllowedOrigins: z.array(z.string()).describe("방문 분석 수집을 받는
|
|
1904
|
-
storefrontOrigins: z.array(z.string()).describe("
|
|
1907
|
+
analyticsAllowedOrigins: z.array(z.string()).describe("방문 분석 수집을 받는 스토어프론트 오리진. 비어 있으면 모든 오리진에서 받는다"),
|
|
1908
|
+
storefrontOrigins: z.array(z.string()).describe("스토어프론트 도메인 — 소셜 로그인 리디렉트와 방문 분석 수집이 함께 쓴다(`analyticsAllowedOrigins`와 같은 값)"),
|
|
1905
1909
|
guestCheckoutEnabled: z.boolean().describe("비회원 주문 허용. false면 회원만 주문할 수 있다"),
|
|
1906
1910
|
memberCount: z.number().int(),
|
|
1907
1911
|
createdAt: z.string()
|
|
@@ -2188,7 +2192,10 @@ function createStoreClient(options) {
|
|
|
2188
2192
|
},
|
|
2189
2193
|
carriers: { list: () => storeHttp.request("GET", "/carriers", z.array(carrierSchema)) },
|
|
2190
2194
|
claims: {
|
|
2191
|
-
list: (params) => storeHttp.request("GET", "/claims", pageSchema(claimSchema), { query:
|
|
2195
|
+
list: (params) => storeHttp.request("GET", "/claims", pageSchema(claimSchema), { query: {
|
|
2196
|
+
...params,
|
|
2197
|
+
status: Array.isArray(params?.status) ? params.status.join(",") : params?.status
|
|
2198
|
+
} }),
|
|
2192
2199
|
get: (claimId) => storeHttp.request("GET", path`/claims/${claimId}`, claimDetailSchema),
|
|
2193
2200
|
approve: (claimId, deductAmount, idempotencyKey) => storeHttp.request("POST", path`/claims/${claimId}/approve`, approveClaimResultSchema, {
|
|
2194
2201
|
body: deductAmount !== void 0 ? { deductAmount } : {},
|
|
@@ -2202,7 +2209,9 @@ function createStoreClient(options) {
|
|
|
2202
2209
|
trackingNumber
|
|
2203
2210
|
} }),
|
|
2204
2211
|
hold: (claimId, reason) => storeHttp.request("POST", path`/claims/${claimId}/hold`, claimHoldResultSchema, { body: { reason } }),
|
|
2205
|
-
releaseHold: (claimId) => storeHttp.requestVoid("DELETE", path`/claims/${claimId}/hold`)
|
|
2212
|
+
releaseHold: (claimId) => storeHttp.requestVoid("DELETE", path`/claims/${claimId}/hold`),
|
|
2213
|
+
/** 교환 완료 — 재배송 중인 교환을 셀러가 명시적으로 끝낸다 */
|
|
2214
|
+
completeExchange: (claimId) => storeHttp.request("POST", path`/claims/${claimId}/complete-exchange`, claimSchema)
|
|
2206
2215
|
},
|
|
2207
2216
|
inquiries: {
|
|
2208
2217
|
list: (params) => storeHttp.request("GET", "/inquiries", pageSchema(inquirySchema), { query: params }),
|
|
@@ -2258,7 +2267,7 @@ function createStoreClient(options) {
|
|
|
2258
2267
|
*/
|
|
2259
2268
|
get: (params) => storeHttp.request("GET", "/sales-report", salesReportSchema, { query: salesReportQuerySchema.parse(params) }) },
|
|
2260
2269
|
/**
|
|
2261
|
-
* 방문 분석 — 스코프 `analytics:r`.
|
|
2270
|
+
* 방문 분석 — 스코프 `analytics:r`. 스토어프론트가 `@sayren/storefront-sdk`로 수집한 이벤트를 Asia/Seoul 날짜별로
|
|
2262
2271
|
* 집계한 값이다. 집계는 주기적으로 갱신되고 응답 `lastComputedAt`이 마지막 집계 시각이다. 봇 세션은 빠진다.
|
|
2263
2272
|
* 기간은 양끝 포함 최대 92일이고, 테스트 결제 구매는 `includeTest: "true"`일 때만 포함한다.
|
|
2264
2273
|
*/
|
|
@@ -2414,7 +2423,7 @@ get: (params) => storeHttp.request("GET", "/sales-report", salesReportSchema, {
|
|
|
2414
2423
|
get: () => storeHttp.request("GET", "/store", storeSchema),
|
|
2415
2424
|
/**
|
|
2416
2425
|
* `PATCH /v1/store` — 스코프 `store:rw`. 바꿀 필드만 보낸다. `analyticsAllowedOrigins`는 방문 분석 수집을 받을
|
|
2417
|
-
*
|
|
2426
|
+
* 스토어프론트 오리진 목록이다(빈 배열이면 모든 오리진 허용).
|
|
2418
2427
|
*/
|
|
2419
2428
|
update: (body) => storeHttp.request("PATCH", "/store", storeSchema, { body: updateStoreRequestSchema.parse(body) }),
|
|
2420
2429
|
listMembers: () => storeHttp.request("GET", "/store/members", z.array(storeMemberSchema)),
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -533,7 +533,12 @@ export function createStoreClient(options: StoreClientOptions) {
|
|
|
533
533
|
|
|
534
534
|
claims: {
|
|
535
535
|
list: (params?: ClaimListParams) =>
|
|
536
|
-
storeHttp.request("GET", "/claims", pageSchema(claimSchema), {
|
|
536
|
+
storeHttp.request("GET", "/claims", pageSchema(claimSchema), {
|
|
537
|
+
query: {
|
|
538
|
+
...params,
|
|
539
|
+
status: Array.isArray(params?.status) ? params.status.join(",") : params?.status,
|
|
540
|
+
} as Query,
|
|
541
|
+
}),
|
|
537
542
|
get: (claimId: string) =>
|
|
538
543
|
storeHttp.request("GET", path`/claims/${claimId}`, claimDetailSchema),
|
|
539
544
|
approve: (claimId: string, deductAmount?: number, idempotencyKey?: string) =>
|
|
@@ -561,6 +566,9 @@ export function createStoreClient(options: StoreClientOptions) {
|
|
|
561
566
|
}),
|
|
562
567
|
releaseHold: (claimId: string) =>
|
|
563
568
|
storeHttp.requestVoid("DELETE", path`/claims/${claimId}/hold`),
|
|
569
|
+
/** 교환 완료 — 재배송 중인 교환을 셀러가 명시적으로 끝낸다 */
|
|
570
|
+
completeExchange: (claimId: string) =>
|
|
571
|
+
storeHttp.request("POST", path`/claims/${claimId}/complete-exchange`, claimSchema),
|
|
564
572
|
},
|
|
565
573
|
|
|
566
574
|
inquiries: {
|
|
@@ -691,7 +699,7 @@ export function createStoreClient(options: StoreClientOptions) {
|
|
|
691
699
|
},
|
|
692
700
|
|
|
693
701
|
/**
|
|
694
|
-
* 방문 분석 — 스코프 `analytics:r`.
|
|
702
|
+
* 방문 분석 — 스코프 `analytics:r`. 스토어프론트가 `@sayren/storefront-sdk`로 수집한 이벤트를 Asia/Seoul 날짜별로
|
|
695
703
|
* 집계한 값이다. 집계는 주기적으로 갱신되고 응답 `lastComputedAt`이 마지막 집계 시각이다. 봇 세션은 빠진다.
|
|
696
704
|
* 기간은 양끝 포함 최대 92일이고, 테스트 결제 구매는 `includeTest: "true"`일 때만 포함한다.
|
|
697
705
|
*/
|
|
@@ -944,7 +952,7 @@ export function createStoreClient(options: StoreClientOptions) {
|
|
|
944
952
|
get: () => storeHttp.request("GET", "/store", storeSchema),
|
|
945
953
|
/**
|
|
946
954
|
* `PATCH /v1/store` — 스코프 `store:rw`. 바꿀 필드만 보낸다. `analyticsAllowedOrigins`는 방문 분석 수집을 받을
|
|
947
|
-
*
|
|
955
|
+
* 스토어프론트 오리진 목록이다(빈 배열이면 모든 오리진 허용).
|
|
948
956
|
*/
|
|
949
957
|
update: (body: UpdateStoreRequest) =>
|
|
950
958
|
storeHttp.request("PATCH", "/store", storeSchema, {
|
package/src/schemas/analytics.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { z } from "zod";
|
|
|
3
3
|
/**
|
|
4
4
|
* 방문 분석 조회 (관리 API `/v1/analytics/*`, 스코프 `analytics:r`).
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* 스토어프론트가 `@sayren/storefront-sdk`로 수집한 이벤트를 서버가 날짜(Asia/Seoul)별로 집계한 값이다. 집계는 주기적으로
|
|
7
7
|
* 갱신되므로 오늘 값은 `lastComputedAt` 시점까지 반영돼 있다. 봇·자동화 브라우저의 세션은 모든 집계에서 빠진다.
|
|
8
8
|
*/
|
|
9
9
|
|
package/src/schemas/claim.ts
CHANGED
|
@@ -53,13 +53,18 @@ export const claimSchema = z.object({
|
|
|
53
53
|
.nullable(),
|
|
54
54
|
requestedAt: z.string(),
|
|
55
55
|
completedAt: z.string().nullable(),
|
|
56
|
+
/** 보류 중이면 자동 해제 시각(ISO 8601), 아니면 null */
|
|
57
|
+
holdExpiresAt: z.string().nullable(),
|
|
58
|
+
/** 보류를 이미 썼는지 — 보류는 클레임당 1회라 해제·만료 뒤에도 true */
|
|
59
|
+
holdUsed: z.boolean(),
|
|
56
60
|
});
|
|
57
61
|
|
|
58
62
|
export type Claim = z.infer<typeof claimSchema>;
|
|
59
63
|
|
|
60
64
|
export interface ClaimListParams extends PageParams {
|
|
61
65
|
type?: ClaimType;
|
|
62
|
-
|
|
66
|
+
/** 여러 상태를 한 번에 거를 수 있다(처리 대기 목록 등) */
|
|
67
|
+
status?: ClaimStatus | ClaimStatus[];
|
|
63
68
|
orderItemId?: string;
|
|
64
69
|
requestedFrom?: string;
|
|
65
70
|
requestedTo?: string;
|
|
@@ -68,7 +73,10 @@ export interface ClaimListParams extends PageParams {
|
|
|
68
73
|
/** `GET /v1/claims` 쿼리 — OpenAPI 문서용 형태(값은 쿼리 문자열) */
|
|
69
74
|
export const claimListQuerySchema = z.object({
|
|
70
75
|
type: claimTypeSchema.optional().describe("클레임 유형 필터"),
|
|
71
|
-
status:
|
|
76
|
+
status: z
|
|
77
|
+
.string()
|
|
78
|
+
.optional()
|
|
79
|
+
.describe("클레임 상태 필터. 쉼표로 여러 개를 줄 수 있다 (예: `REQUESTED,HELD,COLLECTED`)"),
|
|
72
80
|
orderItemId: z.string().optional().describe("주문상품 id 필터"),
|
|
73
81
|
requestedFrom: z.string().optional().describe("요청 시각 조회 시작 (ISO 8601, 포함)"),
|
|
74
82
|
requestedTo: z.string().optional().describe("요청 시각 조회 끝 (ISO 8601, 포함)"),
|
package/src/schemas/customer.ts
CHANGED
|
@@ -115,7 +115,7 @@ export const withdrawCustomerRequestSchema = z.object({
|
|
|
115
115
|
});
|
|
116
116
|
export type WithdrawCustomerRequest = z.infer<typeof withdrawCustomerRequestSchema>;
|
|
117
117
|
|
|
118
|
-
/** `WITHDRAWAL_BLOCKED`의 `error.details` — 탈퇴를 막는 항목 수(
|
|
118
|
+
/** `WITHDRAWAL_BLOCKED`의 `error.details` — 탈퇴를 막는 항목 수(스토어프론트 탈퇴와 같다) */
|
|
119
119
|
export const customerWithdrawalBlockedDetailsSchema = z.object({
|
|
120
120
|
inProgressOrderItems: z.number().int(),
|
|
121
121
|
openClaims: z.number().int(),
|
package/src/schemas/login.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type LoginProvider = z.infer<typeof loginProviderSchema>;
|
|
|
8
8
|
export const loginProviderStatusSchema = z.object({
|
|
9
9
|
provider: loginProviderSchema,
|
|
10
10
|
connected: z.boolean(),
|
|
11
|
-
/**
|
|
11
|
+
/** 스토어프론트에서 사용 중인지. 연결 안 됐으면 false */
|
|
12
12
|
enabled: z.boolean(),
|
|
13
13
|
clientIdPrefix: z.string().nullable().describe("클라이언트 ID(카카오 REST API 키) 앞 4자리"),
|
|
14
14
|
secretPrefix: z.string().nullable(),
|
package/src/schemas/product.ts
CHANGED
|
@@ -13,10 +13,14 @@ export const productSummarySchema = z.object({
|
|
|
13
13
|
productId: z.string(),
|
|
14
14
|
name: z.string(),
|
|
15
15
|
status: productStatusSchema,
|
|
16
|
-
salePrice: z.number().int(),
|
|
17
|
-
discountedPrice: z
|
|
16
|
+
salePrice: z.number().int().describe("판매가. 원(KRW) 단위 정수"),
|
|
17
|
+
discountedPrice: z
|
|
18
|
+
.number()
|
|
19
|
+
.int()
|
|
20
|
+
.nullable()
|
|
21
|
+
.describe("즉시 할인 적용가. 원 단위. 할인이 없으면 null"),
|
|
18
22
|
/** usable variant 재고 합계 (서버 계산) */
|
|
19
|
-
stockQuantity: z.number().int(),
|
|
23
|
+
stockQuantity: z.number().int().describe("판매 가능한 옵션 재고의 합계. 서버가 계산한다"),
|
|
20
24
|
categoryId: z.string().nullable(),
|
|
21
25
|
thumbnailUrl: z.url().optional(),
|
|
22
26
|
/** optionGroups.length > 0 */
|
|
@@ -199,8 +203,9 @@ export const productCreateRequestSchema = z
|
|
|
199
203
|
.number()
|
|
200
204
|
.int()
|
|
201
205
|
.min(10)
|
|
202
|
-
.multipleOf(10, "판매가는 10원 단위여야 합니다 (INVALID_PRICE_UNIT)")
|
|
203
|
-
|
|
206
|
+
.multipleOf(10, "판매가는 10원 단위여야 합니다 (INVALID_PRICE_UNIT)")
|
|
207
|
+
.describe("판매가. 원(KRW) 단위 정수, 최소 10원, 10원 단위"),
|
|
208
|
+
originalPrice: z.number().int().optional().describe("정가(할인 전 표시 가격). 원 단위"),
|
|
204
209
|
description: z.string().optional(),
|
|
205
210
|
/**
|
|
206
211
|
* 상세설명 에디터(@avarlabs/editor)의 직렬화 상태. 재편집 때 이 값으로 문서를 복원한다.
|
|
@@ -209,11 +214,17 @@ export const productCreateRequestSchema = z
|
|
|
209
214
|
descriptionJson: z.string().nullable().optional(),
|
|
210
215
|
images: z.array(z.url()).min(1).max(10).optional(),
|
|
211
216
|
attributes: z.array(z.object({ attributeId: z.string(), value: z.string() })).optional(),
|
|
212
|
-
deliveryType: deliveryTypeSchema
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
+
deliveryType: deliveryTypeSchema
|
|
218
|
+
.default("PAID")
|
|
219
|
+
.describe("배송비 유형. FREE 무료, PAID 유료, CONDITIONAL_FREE 조건부 무료"),
|
|
220
|
+
deliveryFee: z.number().int().default(0).describe("배송비. 원 단위"),
|
|
221
|
+
conditionalFreeAmount: z
|
|
222
|
+
.number()
|
|
223
|
+
.int()
|
|
224
|
+
.optional()
|
|
225
|
+
.describe("CONDITIONAL_FREE일 때 무료 배송이 되는 주문 금액. 원 단위"),
|
|
226
|
+
returnFee: z.number().int().default(0).describe("반품 배송비. 원 단위"),
|
|
227
|
+
exchangeFee: z.number().int().default(0).describe("교환 배송비. 원 단위"),
|
|
217
228
|
shippingAddressId: z.string().optional(),
|
|
218
229
|
returnAddressId: z.string().optional(),
|
|
219
230
|
})
|
package/src/schemas/store.ts
CHANGED
|
@@ -91,13 +91,13 @@ export function isWebOrigin(value: string): boolean {
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
/** 방문 분석을 보낼 수 있는
|
|
94
|
+
/** 방문 분석을 보낼 수 있는 스토어프론트 오리진 — 스킴·호스트(·포트)만. 서버가 소문자·끝 슬래시 제거로 정규화한다 */
|
|
95
95
|
export const analyticsOriginSchema = z
|
|
96
96
|
.string()
|
|
97
97
|
.trim()
|
|
98
98
|
.max(255)
|
|
99
99
|
.refine(isWebOrigin, "https://shop.example.com 형식(경로 없이)으로 입력해 주세요")
|
|
100
|
-
.describe("
|
|
100
|
+
.describe("스토어프론트 오리진. 예: `https://shop.example.com`");
|
|
101
101
|
|
|
102
102
|
/** 허용 오리진 상한 */
|
|
103
103
|
export const MAX_ANALYTICS_ALLOWED_ORIGINS = 20;
|
|
@@ -114,7 +114,7 @@ export const updateStoreRequestSchema = z
|
|
|
114
114
|
.max(MAX_ANALYTICS_ALLOWED_ORIGINS)
|
|
115
115
|
.optional()
|
|
116
116
|
.describe(
|
|
117
|
-
"@deprecated `storefrontOrigins`를 쓴다(같은 목록). 방문 분석 수집을 받을
|
|
117
|
+
"@deprecated `storefrontOrigins`를 쓴다(같은 목록). 방문 분석 수집을 받을 스토어프론트 오리진(최대 20개). 비우면 모든 오리진에서 받는다. " +
|
|
118
118
|
"넣으면 목록에 없는 오리진의 수집 요청은 403 `ORIGIN_NOT_ALLOWED`이고, 페이지 URL이 목록 밖인 이벤트는 버린다",
|
|
119
119
|
),
|
|
120
120
|
storefrontOrigins: z
|
|
@@ -122,7 +122,7 @@ export const updateStoreRequestSchema = z
|
|
|
122
122
|
.max(MAX_ANALYTICS_ALLOWED_ORIGINS)
|
|
123
123
|
.optional()
|
|
124
124
|
.describe(
|
|
125
|
-
"
|
|
125
|
+
"스토어프론트 도메인(최대 20개) — 소셜 로그인 뒤 돌아갈 주소와 방문 분석 수집을 함께 제한한다. " +
|
|
126
126
|
"`analyticsAllowedOrigins`와 같은 목록이다(둘 다 주면 이 값이 이긴다)",
|
|
127
127
|
),
|
|
128
128
|
guestCheckoutEnabled: z
|
|
@@ -149,11 +149,11 @@ export const storeSchema = z.object({
|
|
|
149
149
|
customerCenterPhone: z.string().nullable(),
|
|
150
150
|
analyticsAllowedOrigins: z
|
|
151
151
|
.array(z.string())
|
|
152
|
-
.describe("방문 분석 수집을 받는
|
|
152
|
+
.describe("방문 분석 수집을 받는 스토어프론트 오리진. 비어 있으면 모든 오리진에서 받는다"),
|
|
153
153
|
storefrontOrigins: z
|
|
154
154
|
.array(z.string())
|
|
155
155
|
.describe(
|
|
156
|
-
"
|
|
156
|
+
"스토어프론트 도메인 — 소셜 로그인 리디렉트와 방문 분석 수집이 함께 쓴다(`analyticsAllowedOrigins`와 같은 값)",
|
|
157
157
|
),
|
|
158
158
|
guestCheckoutEnabled: z.boolean().describe("비회원 주문 허용. false면 회원만 주문할 수 있다"),
|
|
159
159
|
memberCount: z.number().int(),
|