@sayren/store-sdk 0.57.0 → 0.58.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 +406 -635
- package/dist/index.mjs +15 -100
- package/package.json +1 -1
- package/src/client.ts +3 -28
- package/src/schemas/payment.ts +1 -2
- package/src/schemas/starter.ts +0 -2
- package/src/schemas/storefront-hosting.ts +9 -147
|
@@ -3,10 +3,10 @@ import { RESERVED_STORE_CODES } from "./store";
|
|
|
3
3
|
import { strictRequest } from "./strict";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* 스토어프론트 호스팅 (이슈 #53
|
|
6
|
+
* 스토어프론트 호스팅 (이슈 #53) — 관리 API `/v1/storefront/**`의 계약이다.
|
|
7
7
|
*
|
|
8
|
-
* 셀러는
|
|
9
|
-
* `POST /v1/storefront/site`가 유일한 생성 경로다.
|
|
8
|
+
* 셀러는 사이트를 만들고 `{slug}.{호스팅 도메인}` 주소를 받는다. 상점을 만들어도 사이트는 생기지 않고
|
|
9
|
+
* `POST /v1/storefront/site`가 유일한 생성 경로다. 첫 소스는 `initialSource`(빈 작업 트리·시작 코드)다. 발행은 버전 단위이고,
|
|
10
10
|
* 되돌리기는 이전 버전을 다시 발행하는 것이다(재빌드 없음). 상태의 원천은 api DB이고 Cloudflare 쪽 반영
|
|
11
11
|
* (라우팅 표·사이트 Worker)은 커밋 뒤 비동기다 — 반영 상태는 `provisioning`으로 본다.
|
|
12
12
|
*
|
|
@@ -14,7 +14,7 @@ import { strictRequest } from "./strict";
|
|
|
14
14
|
* 공개 전환·슬러그 변경·호스팅 끄기는 승인(`APPROVAL_REQUIRED`)이다 — 구매자가 보는 화면을 바꾸는 쓰기다.
|
|
15
15
|
*
|
|
16
16
|
* 오류 코드:
|
|
17
|
-
* - 404 `STOREFRONT_SITE_NOT_FOUND` · `
|
|
17
|
+
* - 404 `STOREFRONT_SITE_NOT_FOUND` · `STOREFRONT_VERSION_NOT_FOUND`
|
|
18
18
|
* - 409 `STOREFRONT_SITE_EXISTS` — 이미 사이트가 있다(상점당 1개)
|
|
19
19
|
* - 409 `STOREFRONT_SLUG_TAKEN` — 다른 사이트가 쓰거나 보류 중인 슬러그다
|
|
20
20
|
* - 409 `STOREFRONT_SLUG_CHANGE_LIMIT` — 슬러그는 상점당 30일에 3번까지 바꾼다
|
|
@@ -25,12 +25,11 @@ import { strictRequest } from "./strict";
|
|
|
25
25
|
* - 409 `STOREFRONT_VERSION_NOT_READY` — 빌드가 끝나지 않았거나 실패한 버전은 발행할 수 없다
|
|
26
26
|
* - 409 `STOREFRONT_NO_ROLLBACK_TARGET` — 되돌릴 이전 발행 버전이 없다
|
|
27
27
|
* - 409 `STOREFRONT_NOT_READY` — 공개 전환: 판매 중인 상품(샘플 제외)이 없다(이슈 #70). 상품을 등록한 뒤 공개한다
|
|
28
|
-
* - 409 `TEMPLATE_CHANGE_NOT_SUPPORTED` — 템플릿 변경(`POST /v1/storefront/site/template`, 폐기)은 항상 이 오류다
|
|
29
28
|
* - 503 `STOREFRONT_PREVIEW_NOT_CONFIGURED` — 미리보기 서명 키가 설정되지 않았다
|
|
30
29
|
* - 503 `STOREFRONT_STARTER_UNAVAILABLE` — 시작 코드(`initialSource: "STARTER"`)를 아직 쓸 수 없다. 사이트를 만들지 않았다(한도도 세지 않는다). 잠시 뒤 다시 한다
|
|
31
30
|
*
|
|
32
31
|
* 편집(M2b, `/v1/storefront/site/editing`·`files/**`·`checks/**`·`verify`·`builds/**`, 버전 만들기):
|
|
33
|
-
* - 403 `STOREFRONT_EDITING_DISABLED` — 편집을 쓸 수 없어
|
|
32
|
+
* - 403 `STOREFRONT_EDITING_DISABLED` — 편집을 쓸 수 없어 사이트를 만들 수 없다(사이트 만들기)
|
|
34
33
|
* - 503 `STOREFRONT_EDITING_NOT_CONFIGURED` — 편집 Sandbox가 설정되지 않았다
|
|
35
34
|
* - 409 `EDIT_CAPACITY_FULL` — 플랫폼 전체 동시 편집 상한에 걸렸다. `error.details.retryAfterSeconds` 뒤에 다시 한다
|
|
36
35
|
* - 409 `EDIT_SESSION_REQUIRED` — 편집 미리보기 링크: 편집 환경이 없다
|
|
@@ -94,16 +93,6 @@ export const RESERVED_STOREFRONT_SLUGS: readonly string[] = [
|
|
|
94
93
|
*/
|
|
95
94
|
export const STOREFRONT_EDIT_PREVIEW_SUFFIX = "-preview";
|
|
96
95
|
|
|
97
|
-
/**
|
|
98
|
-
* 공식 쇼케이스 슬러그 접두사(이슈 #72) — `demo-{템플릿 id}`는 템플릿 미리보기용 쇼케이스 사이트 주소다. 쇼케이스로 지정된
|
|
99
|
-
* 상점만 쓸 수 있다(서버가 상점 용도로 판정한다). 공식 미리보기를 흉내 내는 주소를 막는다
|
|
100
|
-
*/
|
|
101
|
-
export const STOREFRONT_SHOWCASE_SLUG_PREFIX = "demo-";
|
|
102
|
-
|
|
103
|
-
export function isShowcaseStorefrontSlug(slug: string): boolean {
|
|
104
|
-
return slug.toLowerCase().startsWith(STOREFRONT_SHOWCASE_SLUG_PREFIX);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
96
|
export function isReservedStorefrontSlug(slug: string): boolean {
|
|
108
97
|
const lower = slug.toLowerCase();
|
|
109
98
|
return (
|
|
@@ -149,94 +138,6 @@ export const STOREFRONT_SLUG_CHANGE_LIMIT = 3;
|
|
|
149
138
|
/** 사이트 만들기 한도 — 같은 창(30일) 안의 횟수(상점 단위). 끄고 만들기를 되풀이해 이름을 묶어 두지 못하게 한다 */
|
|
150
139
|
export const STOREFRONT_SITE_CREATE_LIMIT = 3;
|
|
151
140
|
|
|
152
|
-
// ─── 템플릿 ───────────────────────────────────────────────
|
|
153
|
-
|
|
154
|
-
export const storefrontTemplateSchema = z.object({
|
|
155
|
-
templateId: z.string().describe("템플릿 id (예: `basic`)"),
|
|
156
|
-
name: z.string().describe("템플릿 이름"),
|
|
157
|
-
industry: z.string().describe("업종 (예: `general`·`fashion`·`food`). 목록 필터에 쓴다"),
|
|
158
|
-
description: z.string().describe("템플릿 설명"),
|
|
159
|
-
thumbnailUrl: z.string().nullable().describe("썸네일 이미지 주소. 없으면 null"),
|
|
160
|
-
version: z.string().describe("현재 템플릿 버전. 새 사이트는 이 버전으로 만든다"),
|
|
161
|
-
isDefault: z.boolean().describe("기본 템플릿인가 (상점 생성 시 자동 생성에 쓴다)"),
|
|
162
|
-
tags: z
|
|
163
|
-
.array(z.string())
|
|
164
|
-
.default([])
|
|
165
|
-
.describe(
|
|
166
|
-
"템플릿 특징 태그 (예: `후기 강조`). 목록 카드에 보인다. 옛 서버 응답은 빈 배열로 읽는다",
|
|
167
|
-
),
|
|
168
|
-
supportsCheckout: z
|
|
169
|
-
.boolean()
|
|
170
|
-
.default(true)
|
|
171
|
-
.describe(
|
|
172
|
-
"주문을 받는 템플릿인가. false는 가격·문의 중심의 카탈로그형이다. 옛 서버 응답은 true로 읽는다",
|
|
173
|
-
),
|
|
174
|
-
previewUrl: z
|
|
175
|
-
.string()
|
|
176
|
-
.nullable()
|
|
177
|
-
.default(null)
|
|
178
|
-
.describe(
|
|
179
|
-
"미리보기 사이트 주소. 공식 템플릿은 연결된 쇼케이스, 템플릿 상점의 템플릿은 그 상점의 사이트가 공개 중일 때만 싣고 그 밖에는 null",
|
|
180
|
-
),
|
|
181
|
-
source: z
|
|
182
|
-
.enum(["CATALOG", "STORE"])
|
|
183
|
-
.default("CATALOG")
|
|
184
|
-
.describe(
|
|
185
|
-
"`CATALOG` 공식 템플릿 · `STORE` 템플릿 상점의 템플릿(사이트를 만들 때 `copyContent`로 콘텐츠를 복사할 수 있다). 옛 서버 응답은 `CATALOG`로 읽는다",
|
|
186
|
-
),
|
|
187
|
-
});
|
|
188
|
-
export type StorefrontTemplate = z.infer<typeof storefrontTemplateSchema>;
|
|
189
|
-
|
|
190
|
-
// ─── 템플릿 상점 (#123) ────────────────────────────────────
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* 템플릿 상점의 템플릿 정보 — 상점을 만들 때 템플릿 상점으로 고른 상점만 있다. 발행한 스토어프론트가 템플릿이 되고, 이 이름·소개·
|
|
194
|
-
* 썸네일로 모든 셀러의 템플릿 목록에 보인다
|
|
195
|
-
*/
|
|
196
|
-
export const storeTemplateSchema = z.object({
|
|
197
|
-
templateId: z.string().describe("템플릿 id. 다른 상점이 사이트를 만들 때 이 값을 쓴다"),
|
|
198
|
-
name: z.string().describe("템플릿 이름"),
|
|
199
|
-
description: z.string().describe("템플릿 소개"),
|
|
200
|
-
thumbnailUrl: z.string().nullable().describe("썸네일 이미지 주소. 없으면 null"),
|
|
201
|
-
status: z
|
|
202
|
-
.enum(["DRAFT", "ACTIVE", "RETIRED"])
|
|
203
|
-
.describe(
|
|
204
|
-
"`DRAFT` 아직 편집한 스토어프론트를 발행하지 않아 목록에 보이지 않음 · `ACTIVE` 목록에 보임 · `RETIRED` 상점을 닫아 내려감",
|
|
205
|
-
),
|
|
206
|
-
version: z
|
|
207
|
-
.string()
|
|
208
|
-
.nullable()
|
|
209
|
-
.describe("목록에 보이는 템플릿 버전. 발행한 스토어프론트 버전에서 정해진다. `DRAFT`면 null"),
|
|
210
|
-
});
|
|
211
|
-
export type StoreTemplate = z.infer<typeof storeTemplateSchema>;
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* 템플릿 상점의 고정 사업자 정보 필드 — 상점 수정에서 다른 값을 보내면 409 `TEMPLATE_STORE_BUSINESS_LOCKED`다(값은 플랫폼이 정한다)
|
|
215
|
-
*/
|
|
216
|
-
export const TEMPLATE_STORE_LOCKED_BUSINESS_FIELDS = [
|
|
217
|
-
"businessName",
|
|
218
|
-
"representativeName",
|
|
219
|
-
"businessNumber",
|
|
220
|
-
"mailOrderSalesNumber",
|
|
221
|
-
"customerCenterPhone",
|
|
222
|
-
"customerCenterEmail",
|
|
223
|
-
] as const;
|
|
224
|
-
|
|
225
|
-
export const updateStoreTemplateRequestSchema = strictRequest(
|
|
226
|
-
z.object({
|
|
227
|
-
name: z.string().trim().min(1).max(40).describe("템플릿 이름(1~40자)"),
|
|
228
|
-
description: z.string().trim().max(200).describe("템플릿 소개(200자까지)"),
|
|
229
|
-
thumbnailUrl: z
|
|
230
|
-
.url({ protocol: /^https$/ })
|
|
231
|
-
.max(2048)
|
|
232
|
-
.nullable()
|
|
233
|
-
.describe(
|
|
234
|
-
"썸네일 이미지 주소(https). 이미지 업로드(`POST /v1/uploads`)로 받은 주소를 쓴다. 없으면 null",
|
|
235
|
-
),
|
|
236
|
-
}),
|
|
237
|
-
);
|
|
238
|
-
export type UpdateStoreTemplateRequest = z.infer<typeof updateStoreTemplateRequestSchema>;
|
|
239
|
-
|
|
240
141
|
// ─── 버전 ─────────────────────────────────────────────────
|
|
241
142
|
|
|
242
143
|
/**
|
|
@@ -253,8 +154,6 @@ export type StorefrontVersionStatus = z.infer<typeof storefrontVersionStatusSche
|
|
|
253
154
|
export const storefrontVersionSchema = z.object({
|
|
254
155
|
versionId: z.string(),
|
|
255
156
|
number: z.number().int().min(1).describe("사이트 안에서 1부터 늘어나는 번호 (v1, v2…)"),
|
|
256
|
-
templateId: z.string().describe("이 버전의 기준 템플릿"),
|
|
257
|
-
templateVersion: z.string().describe("이 버전의 기준 템플릿 버전"),
|
|
258
157
|
status: storefrontVersionStatusSchema,
|
|
259
158
|
published: z.boolean().describe("지금 발행된 버전인가"),
|
|
260
159
|
publishedAt: z
|
|
@@ -330,10 +229,6 @@ export const storefrontVisibilitySchema = z
|
|
|
330
229
|
.describe("`COMING_SOON` 오픈 준비 중(방문자에게 준비 중 페이지) · `PUBLIC` 공개");
|
|
331
230
|
export type StorefrontVisibility = z.infer<typeof storefrontVisibilitySchema>;
|
|
332
231
|
|
|
333
|
-
export const storefrontSourceModeSchema = z
|
|
334
|
-
.enum(["MANAGED", "CUSTOM"])
|
|
335
|
-
.describe("`MANAGED` 템플릿 그대로 · `CUSTOM` 한 번이라도 편집함");
|
|
336
|
-
|
|
337
232
|
export const storefrontDomainSchema = z.object({
|
|
338
233
|
hostname: z.string().describe("호스트 이름 (예: `mystore.sayren.co`)"),
|
|
339
234
|
kind: z.enum(["PLATFORM", "CUSTOM"]).describe("`PLATFORM` 슬러그 주소 · `CUSTOM` 내 도메인"),
|
|
@@ -406,8 +301,6 @@ export const storefrontSiteSchema = z.object({
|
|
|
406
301
|
hostname: z.string().describe("대표 호스트 이름"),
|
|
407
302
|
url: z.string().describe("대표 주소 (`https://{hostname}`)"),
|
|
408
303
|
domains: z.array(storefrontDomainSchema).describe("사용 중·보류 중인 호스트 이름"),
|
|
409
|
-
templateId: z.string().describe("지금 발행된 버전의 템플릿 (발행 전이면 만든 템플릿)"),
|
|
410
|
-
sourceMode: storefrontSourceModeSchema,
|
|
411
304
|
status: storefrontSiteStatusSchema,
|
|
412
305
|
visibility: storefrontVisibilitySchema,
|
|
413
306
|
publishedVersion: storefrontVersionSchema.nullable().describe("지금 발행된 버전"),
|
|
@@ -472,7 +365,7 @@ export const storefrontDeploymentLogSchema = z.object({
|
|
|
472
365
|
code: z
|
|
473
366
|
.string()
|
|
474
367
|
.describe(
|
|
475
|
-
"기록 종류 (`SITE_CREATED`·`ADDRESS_RESERVED`·`WAITING`·`SYNCING`·`VERSION_UPLOADED`·`SYNC_FAILED`·`RETRY_SCHEDULED`·`PUBLISHED`, 템플릿
|
|
368
|
+
"기록 종류 (`SITE_CREATED`·`ADDRESS_RESERVED`·`WAITING`·`SYNCING`·`VERSION_UPLOADED`·`SYNC_FAILED`·`RETRY_SCHEDULED`·`PUBLISHED`, 템플릿 없이 만든 사이트는 `BUILDING`·`BUILD_FAILED`, 템플릿 없이 빈 트리로 만든 사이트의 첫 업로드 전은 `WAITING_SOURCE`)",
|
|
476
369
|
),
|
|
477
370
|
message: z.string().describe("사람이 읽는 문장"),
|
|
478
371
|
});
|
|
@@ -498,51 +391,22 @@ export type StorefrontDeployment = z.infer<typeof storefrontDeploymentSchema>;
|
|
|
498
391
|
|
|
499
392
|
// ─── 요청 ─────────────────────────────────────────────────
|
|
500
393
|
|
|
501
|
-
/**
|
|
394
|
+
/** 사이트의 첫 소스(#315) — `NONE` 빈 작업 트리(CLI link) · `STARTER` sayren 시작 코드(웹 시작) */
|
|
502
395
|
export const storefrontInitialSourceSchema = z.enum(["NONE", "STARTER"]);
|
|
503
396
|
export type StorefrontInitialSource = z.infer<typeof storefrontInitialSourceSchema>;
|
|
504
|
-
/** 템플릿 없이 만든 사이트·버전의 응답 `templateId`·`templateVersion` — 옛 SDK가 문자열로 파싱하게 싣는 자리 값(#315 1차) */
|
|
505
|
-
export const STOREFRONT_NO_TEMPLATE_ID = "none";
|
|
506
|
-
export const STOREFRONT_NO_TEMPLATE_VERSION = "0.0.0";
|
|
507
397
|
|
|
508
398
|
export const createStorefrontSiteRequestSchema = strictRequest(
|
|
509
399
|
z.object({
|
|
510
|
-
templateId: z
|
|
511
|
-
.string()
|
|
512
|
-
.min(1)
|
|
513
|
-
.max(64)
|
|
514
|
-
.optional()
|
|
515
|
-
.describe(
|
|
516
|
-
"템플릿 id. 생략하면 템플릿 없이 만든다(오픈 준비 중·발행 버전 없음, 첫 성공 빌드가 발행된다)",
|
|
517
|
-
),
|
|
518
400
|
initialSource: storefrontInitialSourceSchema
|
|
519
401
|
.optional()
|
|
520
402
|
.describe(
|
|
521
|
-
"
|
|
403
|
+
"첫 소스 (기본 `NONE`). `NONE`은 빈 작업 트리로 시작하고 첫 소스 업로드가 첫 소스다. `STARTER`는 sayren 시작 코드의 최신 게시 버전으로 첫 작업 트리를 만들고 빌드한다",
|
|
522
404
|
),
|
|
523
405
|
slug: storefrontSlugSchema.optional().describe("주소 슬러그. 생략하면 상점 코드"),
|
|
524
|
-
copyContent: z
|
|
525
|
-
.boolean()
|
|
526
|
-
.optional()
|
|
527
|
-
.describe(
|
|
528
|
-
"템플릿 상점의 템플릿일 때만 — true면 템플릿 상점의 콘텐츠(레이아웃, 상품·카테고리·컬렉션·주문 흐름·배송·환불 정책)를 이 상점으로 복사한다. 쿠폰·적립금·리뷰는 복사하지 않는다. 생략하거나 false면 레이아웃 콘텐츠를 비우고 빌드한다",
|
|
529
|
-
),
|
|
530
406
|
}),
|
|
531
407
|
);
|
|
532
408
|
export type CreateStorefrontSiteRequest = z.infer<typeof createStorefrontSiteRequestSchema>;
|
|
533
409
|
|
|
534
|
-
/** @deprecated 템플릿 변경은 지원하지 않는다(항상 409 `TEMPLATE_CHANGE_NOT_SUPPORTED`). 호환을 위해 스키마만 남겼다 */
|
|
535
|
-
export const changeStorefrontTemplateRequestSchema = z.object({
|
|
536
|
-
templateId: z.string().min(1).max(64).describe("바꿀 템플릿 id"),
|
|
537
|
-
publish: z
|
|
538
|
-
.boolean()
|
|
539
|
-
.optional()
|
|
540
|
-
.describe("새 버전을 곧바로 발행하는가 (기본 true). false면 버전만 만든다"),
|
|
541
|
-
message: z.string().max(200).optional().describe("버전 메모"),
|
|
542
|
-
});
|
|
543
|
-
/** @deprecated 템플릿 변경은 지원하지 않는다 */
|
|
544
|
-
export type ChangeStorefrontTemplateRequest = z.infer<typeof changeStorefrontTemplateRequestSchema>;
|
|
545
|
-
|
|
546
410
|
/**
|
|
547
411
|
* 발행·되돌리기 — 발행은 사이트의 발행 포인터를 바꾸는 조건부 쓰기다. `expectedPublishedVersionId`를 주면
|
|
548
412
|
* 지금 발행 버전이 그 값일 때만 바꾼다(화면을 본 뒤 다른 사람이 바꿨으면 409 `STOREFRONT_SITE_CHANGED`).
|
|
@@ -1120,9 +984,7 @@ export const storefrontEditingSchema = z.object({
|
|
|
1120
984
|
"편집 미리보기 주소 (사이트의 `editPreview`와 같다)",
|
|
1121
985
|
),
|
|
1122
986
|
workingTree: z.object({
|
|
1123
|
-
modified: z
|
|
1124
|
-
.boolean()
|
|
1125
|
-
.describe("템플릿에서 한 번이라도 고쳤는가 (사이트 `sourceMode`가 `CUSTOM`)"),
|
|
987
|
+
modified: z.boolean().describe("작업 트리를 한 번이라도 고쳤는가"),
|
|
1126
988
|
lastEditedAt: z.string().nullable().describe("마지막으로 파일을 바꾼 시각"),
|
|
1127
989
|
}),
|
|
1128
990
|
// 옛 api 응답에는 없다 — 새 SDK가 배포 전 api와 함께 쓰여도 깨지지 않게 선택 필드다
|