@bstage-sdk/core 0.12.0 → 0.13.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.cjs +3 -3
- package/dist/index.js +3 -3
- package/docs/AI_TOOLKIT.md +4 -4
- package/docs/API_REFERENCE.md +2 -2
- package/docs/BUILD_SYSTEM.md +12 -12
- package/docs/DEV_SERVER.md +2 -2
- package/docs/GETTING_STARTED.md +25 -25
- package/docs/LIQUID.md +13 -13
- package/docs/MIGRATION.md +20 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -176,7 +176,7 @@ var HttpTimeoutError = class extends Error {
|
|
|
176
176
|
};
|
|
177
177
|
|
|
178
178
|
// src/version.ts
|
|
179
|
-
var VERSION = "0.
|
|
179
|
+
var VERSION = "0.13.0";
|
|
180
180
|
|
|
181
181
|
// src/frameBridge.ts
|
|
182
182
|
function getFrameBridge() {
|
|
@@ -224,7 +224,7 @@ function warnOnSwappedCredentials(appId, appKey) {
|
|
|
224
224
|
console.warn(
|
|
225
225
|
`[b.stage] appId\uC640 appKey\uAC00 \uC11C\uB85C \uBC14\uB010 \uAC83 \uAC19\uC2B5\uB2C8\uB2E4.
|
|
226
226
|
appId\uB294 "${APP_ID_PREFIX}", appKey\uB294 "${APP_KEY_PREFIX}"\uB85C \uC2DC\uC791\uD574\uC57C \uD569\uB2C8\uB2E4.
|
|
227
|
-
\
|
|
227
|
+
\uCF58\uC194\uC5D0\uC11C \uBC1C\uAE09\uBC1B\uC740 \uAC12\uC744 \uB2E4\uC2DC \uD655\uC778\uD574 \uC8FC\uC138\uC694.`
|
|
228
228
|
);
|
|
229
229
|
}
|
|
230
230
|
function resolveAppKey(config) {
|
|
@@ -234,7 +234,7 @@ function warnOnMissingAppKey(appKey) {
|
|
|
234
234
|
if (appKey !== void 0) return;
|
|
235
235
|
console.warn(
|
|
236
236
|
`[b.stage] appKey\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 X-BSTAGE-APP-KEY \uD5E4\uB354 \uC5C6\uC774 \uD638\uCD9C\uB418\uC5B4 API\uAC00 401\uC744 \uB0C5\uB2C8\uB2E4.
|
|
237
|
-
.env\uC758 VITE_BSTAGE_APP_KEY(\
|
|
237
|
+
.env\uC758 VITE_BSTAGE_APP_KEY(\uCF58\uC194\uC758 APP KEY)\uB97C \uD655\uC778\uD574 \uC8FC\uC138\uC694.`
|
|
238
238
|
);
|
|
239
239
|
}
|
|
240
240
|
var BstageClient = class {
|
package/dist/index.js
CHANGED
|
@@ -119,7 +119,7 @@ var HttpTimeoutError = class extends Error {
|
|
|
119
119
|
};
|
|
120
120
|
|
|
121
121
|
// src/version.ts
|
|
122
|
-
var VERSION = "0.
|
|
122
|
+
var VERSION = "0.13.0";
|
|
123
123
|
|
|
124
124
|
// src/frameBridge.ts
|
|
125
125
|
function getFrameBridge() {
|
|
@@ -167,7 +167,7 @@ function warnOnSwappedCredentials(appId, appKey) {
|
|
|
167
167
|
console.warn(
|
|
168
168
|
`[b.stage] appId\uC640 appKey\uAC00 \uC11C\uB85C \uBC14\uB010 \uAC83 \uAC19\uC2B5\uB2C8\uB2E4.
|
|
169
169
|
appId\uB294 "${APP_ID_PREFIX}", appKey\uB294 "${APP_KEY_PREFIX}"\uB85C \uC2DC\uC791\uD574\uC57C \uD569\uB2C8\uB2E4.
|
|
170
|
-
\
|
|
170
|
+
\uCF58\uC194\uC5D0\uC11C \uBC1C\uAE09\uBC1B\uC740 \uAC12\uC744 \uB2E4\uC2DC \uD655\uC778\uD574 \uC8FC\uC138\uC694.`
|
|
171
171
|
);
|
|
172
172
|
}
|
|
173
173
|
function resolveAppKey(config) {
|
|
@@ -177,7 +177,7 @@ function warnOnMissingAppKey(appKey) {
|
|
|
177
177
|
if (appKey !== void 0) return;
|
|
178
178
|
console.warn(
|
|
179
179
|
`[b.stage] appKey\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 X-BSTAGE-APP-KEY \uD5E4\uB354 \uC5C6\uC774 \uD638\uCD9C\uB418\uC5B4 API\uAC00 401\uC744 \uB0C5\uB2C8\uB2E4.
|
|
180
|
-
.env\uC758 VITE_BSTAGE_APP_KEY(\
|
|
180
|
+
.env\uC758 VITE_BSTAGE_APP_KEY(\uCF58\uC194\uC758 APP KEY)\uB97C \uD655\uC778\uD574 \uC8FC\uC138\uC694.`
|
|
181
181
|
);
|
|
182
182
|
}
|
|
183
183
|
var BstageClient = class {
|
package/docs/AI_TOOLKIT.md
CHANGED
|
@@ -73,18 +73,18 @@ liquid, liquid 파일이 없고 `src/pages|slots/**/template.tsx`가 있거나 S
|
|
|
73
73
|
|
|
74
74
|
프로젝트가 아직 없다면 에이전트에게 이렇게 말하는 것으로 충분합니다.
|
|
75
75
|
|
|
76
|
-
> 이 프로젝트를 처음 만드는데,
|
|
76
|
+
> 이 프로젝트를 처음 만드는데, 콘솔에 올리는 것까지 도와줘.
|
|
77
77
|
|
|
78
78
|
`bstage-onboarding` 스킬이 받아서 진행합니다.
|
|
79
79
|
|
|
80
80
|
1. 결정 세 가지(유저·어드민 / React·liquid / 배포 환경)를 한 번에 묻고 나머지 확인은 에이전트가 합니다.
|
|
81
|
-
2. 프로젝트 생성 → 로컬 실행 → 커밋·push →
|
|
81
|
+
2. 프로젝트 생성 → 로컬 실행 → 커밋·push → 콘솔 화면에서 레포 연결 → `bstage login`·`bstage link` →
|
|
82
82
|
페이지(배치) 만들기(`bstage placement create`, 빌드가 없으면 빌드부터) → 첫 배포(`bstage deploy`) 순서로
|
|
83
83
|
단계마다 **성공 판정 기준을 먼저 말하고** 확인합니다.
|
|
84
84
|
3. 되돌리기 어려운 일(원격 push·배포·게시 전환)은 실행 전에 보여 주고 확인을 받습니다.
|
|
85
85
|
|
|
86
86
|
페이지 배치는 에이전트가 `bstage placement create`로 만듭니다(경로는 사용자에게 확인). 레포 연결, 위젯(슬롯)
|
|
87
|
-
자리에 거는 배치, 배치 삭제는
|
|
87
|
+
자리에 거는 배치, 배치 삭제는 **콘솔 화면에서만** 합니다.
|
|
88
88
|
|
|
89
89
|
## 6. 갱신 규칙
|
|
90
90
|
|
|
@@ -98,4 +98,4 @@ liquid, liquid 파일이 없고 `src/pages|slots/**/template.tsx`가 있거나 S
|
|
|
98
98
|
|
|
99
99
|
## 7. 예정
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
콘솔 측 MCP 서버가 생기면 `bstage ai install`이 그 클라이언트 설정도 함께 놓을 자리입니다.
|
package/docs/API_REFERENCE.md
CHANGED
|
@@ -97,7 +97,7 @@ Platform → Template 이벤트는 `bubbles: false, composed: false`로 해당
|
|
|
97
97
|
|
|
98
98
|
> **경로와 응답 모양의 출처는 게이트웨이 API Reference Doc입니다.** SDK가 OpenAPI 스펙에서 경로 타입을 생성해 자동완성을 제공하던 방식은 걷어냈습니다 — 스펙이 바뀌어도 SDK를 새로 배포해야 반영되는 구조라 실제 API 변경을 따라가지 못했습니다. 응답 타입은 호출 시 제네릭으로 명시하세요.
|
|
99
99
|
|
|
100
|
-
> **지원 범위: 게이트웨이(`/gw`)를 타는 API.** 유저 템플릿은 유저 도메인의 게이트웨이를 PUBLIC 키(`bsp_`)로, 어드민 템플릿은 어드민 도메인의 **어드민 게이트웨이**를 MANAGEMENT 키(`bsm_`) + 어드민 로그인 세션으로 부릅니다. 같은 클라이언트이고 `baseUrl` 기본값이 현재 도메인을 따르므로 코드는 갈리지 않습니다 — 조건·에러는 [GETTING_STARTED.md](./GETTING_STARTED.md) "8. 어드민 템플릿 › API 호출"을 보세요. 어느 쪽이든
|
|
100
|
+
> **지원 범위: 게이트웨이(`/gw`)를 타는 API.** 유저 템플릿은 유저 도메인의 게이트웨이를 PUBLIC 키(`bsp_`)로, 어드민 템플릿은 어드민 도메인의 **어드민 게이트웨이**를 MANAGEMENT 키(`bsm_`) + 어드민 로그인 세션으로 부릅니다. 같은 클라이언트이고 `baseUrl` 기본값이 현재 도메인을 따르므로 코드는 갈리지 않습니다 — 조건·에러는 [GETTING_STARTED.md](./GETTING_STARTED.md) "8. 어드민 템플릿 › API 호출"을 보세요. 어느 쪽이든 **콘솔 API 레퍼런스(유저/운영자 탭)에 있는 경로만** 씁니다. 목록에 없는 API가 필요하면 임의로 경로를 추측해 호출하지 말고 **반드시 사용자에게 먼저 확인**하세요.
|
|
101
101
|
|
|
102
102
|
```typescript
|
|
103
103
|
const client = new BstageClient({
|
|
@@ -112,7 +112,7 @@ const client = new BstageClient({
|
|
|
112
112
|
| 옵션 | 타입 | 설명 |
|
|
113
113
|
| ----------- | --------------------------------------------- | ------------------------------------------------------------ |
|
|
114
114
|
| `appId` | `string` | 앱 식별자 |
|
|
115
|
-
| `appKey` | `string` | 앱 키(APP KEY). `appKey`·`appSecret` 중 하나는 필요합니다.
|
|
115
|
+
| `appKey` | `string` | 앱 키(APP KEY). `appKey`·`appSecret` 중 하나는 필요합니다. 콘솔이 발급하고 게이트웨이 `X-BSTAGE-APP-KEY` 헤더로 검증하는 값. **브라우저에 노출되는 값**으로 비밀값이 아닙니다. 유저 템플릿은 PUBLIC(`bsp_`), 어드민 템플릿은 MANAGEMENT(`bsm_`) 키입니다 |
|
|
116
116
|
| `appSecret` | `string` (deprecated) | `appKey`의 옛 이름. 값은 같습니다. 둘 다 주면 `appKey`가 우선하며, 0.4.0(공개 배포판 `@bstage-sdk/core` 기준)에서 제거됩니다 |
|
|
117
117
|
| `tenantId` | `string` | 테넌트 식별자 |
|
|
118
118
|
| `phase` | `'dev' \| 'qa' \| 'real' \| 'sandbox'` (선택) | 환경. 현재 미사용 (향후 확장용) |
|
package/docs/BUILD_SYSTEM.md
CHANGED
|
@@ -124,7 +124,7 @@ createTemplate(MyTemplate, { name: 'my-space-hello', styles: css })
|
|
|
124
124
|
- `loadTemplate`이 로드 직후 이 값을 조회합니다.
|
|
125
125
|
- 조회에 실패하면 **옛 번들 폴백**을 탑니다. 옛 산출물은 디렉토리 이름이 곧 태그명이었으므로(`dist/{name}/`) URL의 디렉토리 세그먼트를 후보로 삼되, 추측으로 쓰지 않고 `customElements.get()`으로 실제 등록됐는지 확인합니다. 확인까지 실패하면 던집니다. 옛 번들이 전부 재배포되면 걷어낼 수 있습니다.
|
|
126
126
|
|
|
127
|
-
> 예전에는 `manifest.json`이 이 값을 날랐습니다. 호스트 로더는 지금도 manifest를 읽지 않습니다 — 태그명은 위 전역으로 충분합니다. 다만
|
|
127
|
+
> 예전에는 `manifest.json`이 이 값을 날랐습니다. 호스트 로더는 지금도 manifest를 읽지 않습니다 — 태그명은 위 전역으로 충분합니다. 다만 **콘솔**이 iframe 격리 판단에 manifest를 쓰므로 0.9.0부터 다시 생성합니다(아래 "manifest.json").
|
|
128
128
|
|
|
129
129
|
`spaceId` / `type`(user·admin) / `tag`(버전) 같은 상위 경로 세그먼트는 관리도구가 CDN 업로드 단계에서 주입하며, SDK는 관여하지 않습니다. 슬롯 배치와 풀페이지 레이아웃은 관리도구가 소유합니다.
|
|
130
130
|
|
|
@@ -170,13 +170,13 @@ dist/
|
|
|
170
170
|
| `framework` | `react` 등. 소스에서 못 찾으면 번들에 bstage-react가 실렸는지로 정함 |
|
|
171
171
|
| `bridgeProtocol` | 번들에 실린 core가 구현한 격리 브리지 프로토콜 버전. core `package.json`의 `bstage.bridgeProtocol`에서 읽음. 없을 수 있음 |
|
|
172
172
|
|
|
173
|
-
읽는 쪽은
|
|
173
|
+
읽는 쪽은 콘솔입니다. 게시 빌드를 전개할 때 산출물 디렉토리마다 `bridgeProtocol`·`elementName`을 기록하고, 둘 다 있고 `bridgeProtocol`이 1 이상일 때만 그 템플릿의 iframe 격리를 허용합니다. `sdkVersion`은 게이트에 쓰지 않습니다(정보용). 콘솔 빌더는 manifest가 있으면 앞 네 필드를 검증해 틀리면 빌드를 실패시킵니다.
|
|
174
174
|
|
|
175
|
-
> manifest는 **파트너 빌드가 스스로 적는 값**입니다. `bridgeProtocol`은 "이 번들은 격리 프레임에서 돌 수 있다"는 신고일 뿐 보안 근거가 아닙니다 — 격리 자체는 호스트(sandbox iframe·CSP·브리지 정책)가 강제하고, 브리지 호스트 정책은 manifest를 읽지 않습니다. 값이 틀리면 그 템플릿이 프레임 안에서 동작하지 않을 뿐입니다. 반대로 manifest가 없거나 값이 없으면 inline(호스트 origin에서 실행)으로만 배치되므로, 격리를 요구해야 하는 배치는
|
|
175
|
+
> manifest는 **파트너 빌드가 스스로 적는 값**입니다. `bridgeProtocol`은 "이 번들은 격리 프레임에서 돌 수 있다"는 신고일 뿐 보안 근거가 아닙니다 — 격리 자체는 호스트(sandbox iframe·CSP·브리지 정책)가 강제하고, 브리지 호스트 정책은 manifest를 읽지 않습니다. 값이 틀리면 그 템플릿이 프레임 안에서 동작하지 않을 뿐입니다. 반대로 manifest가 없거나 값이 없으면 inline(호스트 origin에서 실행)으로만 배치되므로, 격리를 요구해야 하는 배치는 콘솔이 fail closed로 다룹니다(배치 거부).
|
|
176
176
|
|
|
177
177
|
그래서 CLI는 **검증을 통과할 수 없는 manifest는 쓰지 않고 경고만** 냅니다 — 빌드는 성공하고 그 템플릿은 inline으로만 배치됩니다.
|
|
178
178
|
|
|
179
|
-
- `name`이
|
|
179
|
+
- `name`이 콘솔 규칙 `^[a-z][a-z0-9]*(-[a-z0-9]+)+$`(100자 이하)에 맞지 않을 때 — CLI의 `name` 검증보다 좁습니다(`a--b`, `a-`는 빌드는 되지만 격리 불가)
|
|
180
180
|
- 번들에서 bstage-core 버전을 찾지 못했을 때
|
|
181
181
|
|
|
182
182
|
`bridgeProtocol`은 core가 package.json에 선언합니다.
|
|
@@ -195,7 +195,7 @@ dist/
|
|
|
195
195
|
|
|
196
196
|
## 5. liquid 레포
|
|
197
197
|
|
|
198
|
-
`public/{user|admin}/{이름}/template.liquid` 로 만드는 레포는 **빌드 단계가 없습니다.** 서버(플랫폼)가 liquid를 렌더하므로 번들링할 것이 없고,
|
|
198
|
+
`public/{user|admin}/{이름}/template.liquid` 로 만드는 레포는 **빌드 단계가 없습니다.** 서버(플랫폼)가 liquid를 렌더하므로 번들링할 것이 없고, 콘솔이 push된 커밋의 파일을 그대로 패키징합니다.
|
|
199
199
|
|
|
200
200
|
### `bstage build`는 검증만 합니다
|
|
201
201
|
|
|
@@ -209,33 +209,33 @@ bstage build --json # { "kind": "liquid", "issues": [...] } 한 덩어리
|
|
|
209
209
|
| 수준 | 검사 |
|
|
210
210
|
| ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
211
211
|
| error | `template.liquid` 문법 오류(줄 번호 표시) · `data.json` JSON 파싱 실패 · 폴더 이름 규칙(`^[a-z][a-z0-9-]*$`) 위반 · liquid 템플릿 0개 · (혼합 레포) sdk 페이지 `user`·`admin` |
|
|
212
|
-
| warn | `public/{user\|admin}/{이름}/` 밖이거나 깊이가 다른 `template.liquid`(
|
|
212
|
+
| warn | `public/{user\|admin}/{이름}/` 밖이거나 깊이가 다른 `template.liquid`(콘솔이 무시) · `layout.json` 존재(콘솔이 지움) · 폴더에 `template.liquid`가 아닌 이름만 있음 |
|
|
213
213
|
|
|
214
214
|
같은 검사를 `bstage doctor`도 "liquid 검증" 절에서 보여 줍니다(`--json`의 `liquid.issues`).
|
|
215
215
|
|
|
216
|
-
###
|
|
216
|
+
### 콘솔의 패키징 규약
|
|
217
217
|
|
|
218
218
|
- `public/user/` · `public/admin/` 아래 **한 단계** 폴더만 템플릿으로 인정합니다 — `public/user/events/summer/template.liquid` 는 무시됩니다.
|
|
219
219
|
- 그 폴더를 통째로 복사한 뒤 `data.json` · `layout.json` 을 지웁니다. 두 파일은 로컬 프리뷰와 관리도구의 것이라 배포에 나가지 않습니다 — 배포에 필요한 값을 거기 두지 마세요.
|
|
220
220
|
- 그 밖의 위치에 있는 `template.liquid` 는 무시합니다.
|
|
221
221
|
- sdk(`src/pages` · `src/slots` 의 `template.tsx`)와 섞인 레포(혼합 레포)는 sdk를 빌드한 뒤 liquid를 함께 패키징합니다 — 아래 "혼합 레포"를 참고하세요.
|
|
222
|
-
- 배치는 페이지(PAGE)만 가능합니다. 위젯(SLOT) 자리에 liquid 산출물을 붙이면
|
|
222
|
+
- 배치는 페이지(PAGE)만 가능합니다. 위젯(SLOT) 자리에 liquid 산출물을 붙이면 콘솔이 400을 냅니다 — `bstage deploy` 가 빌드를 만들기 전에 사전조건 오류로 끊습니다.
|
|
223
223
|
|
|
224
224
|
로컬에서 화면을 보려면 `bstage dev`를 씁니다(같은 폴더의 `data.json`으로 렌더). 자세한 내용은 [DEV_SERVER.md](./DEV_SERVER.md)를 참고하세요.
|
|
225
225
|
|
|
226
226
|
### 혼합 레포(sdk + liquid)
|
|
227
227
|
|
|
228
|
-
한 레포에 `src/pages|slots/**/template.tsx`와 `public/{user|admin}/{이름}/template.liquid`가 함께 있으면 **혼합 레포**입니다.
|
|
228
|
+
한 레포에 `src/pages|slots/**/template.tsx`와 `public/{user|admin}/{이름}/template.liquid`가 함께 있으면 **혼합 레포**입니다. 콘솔 빌더는 sdk 경로(의존성 설치 → `bstage build`)를 탄 뒤 liquid 폴더를 함께 `dist/{user|admin}/{이름}/`으로 패키징하고, 콘솔은 산출물 항목마다 종류(`sdk`·`liquid`)를 따로 봅니다.
|
|
229
229
|
|
|
230
230
|
```bash
|
|
231
|
-
bstage build # sdk 엔트리 번들 + liquid 검증 (dist/에 liquid는 넣지 않음 —
|
|
231
|
+
bstage build # sdk 엔트리 번들 + liquid 검증 (dist/에 liquid는 넣지 않음 — 콘솔이 public/에서 패키징)
|
|
232
232
|
bstage build --json # { "kind": "mixed", "issues": [...], "sdk": { "templates": [...], "outputs": [...] }, "liquid": { "templates": [...] } }
|
|
233
233
|
```
|
|
234
234
|
|
|
235
235
|
- 검증(liquid 문법·규약 + 아래 충돌)을 번들보다 먼저 합니다. 오류가 있으면 번들하지 않고 종료코드 `2`, 번들 실패는 sdk 레포와 같이 `1`입니다.
|
|
236
|
-
- **`src/pages/user/…`·`src/pages/admin/…` 페이지는 만들 수 없습니다(대소문자 무시 — `User`도 같습니다).** 산출물이 `dist/user/…`로 나가 liquid 자리와 같은 트리에 놓이고, 같은 디렉터리에 `template.js`와 `template.liquid`가 함께 있으면
|
|
236
|
+
- **`src/pages/user/…`·`src/pages/admin/…` 페이지는 만들 수 없습니다(대소문자 무시 — `User`도 같습니다).** 산출물이 `dist/user/…`로 나가 liquid 자리와 같은 트리에 놓이고, 같은 디렉터리에 `template.js`와 `template.liquid`가 함께 있으면 콘솔이 sdk로만 판정해 liquid가 조용히 사라집니다. `bstage build`와 콘솔 빌더가 모두 여기서 막습니다. 위젯(`src/slots`)은 슬롯 id로 나가므로 해당 없습니다.
|
|
237
237
|
- `--json` 동안 진행 로그는 stderr로 나갑니다 — stdout에는 JSON 객체 하나만 있습니다.
|
|
238
|
-
- `bstage deploy`는 혼합 레포를 그대로 배포합니다(안내 한 줄). 위젯(SLOT) 배치 사전점검은 liquid 전용 레포에서만 하고, 혼합 레포의 항목별 판정은
|
|
238
|
+
- `bstage deploy`는 혼합 레포를 그대로 배포합니다(안내 한 줄). 위젯(SLOT) 배치 사전점검은 liquid 전용 레포에서만 하고, 혼합 레포의 항목별 판정은 콘솔이 합니다.
|
|
239
239
|
|
|
240
240
|
liquid 레포를 만드는 것부터 배포까지의 전체 흐름은 [LIQUID.md](./LIQUID.md)에 정리돼 있습니다.
|
|
241
241
|
|
package/docs/DEV_SERVER.md
CHANGED
|
@@ -337,7 +337,7 @@ packages/cli/src/
|
|
|
337
337
|
|
|
338
338
|
## 7. liquid 프리뷰 (liquid 레포)
|
|
339
339
|
|
|
340
|
-
`public/{user|admin}/{이름}/template.liquid`로 만든 **liquid 템플릿 레포**에서는 `bstage dev`가 Vite 대신 Node `http` + [liquidjs](https://liquidjs.com/) 기반 프리뷰 서버를 띄웁니다. 레포 종류 판정은
|
|
340
|
+
`public/{user|admin}/{이름}/template.liquid`로 만든 **liquid 템플릿 레포**에서는 `bstage dev`가 Vite 대신 Node `http` + [liquidjs](https://liquidjs.com/) 기반 프리뷰 서버를 띄웁니다. 레포 종류 판정은 콘솔 빌더와 같은 규칙(파일 구조)으로 하며, 따로 옵션을 주지 않아도 자동으로 갈립니다.
|
|
341
341
|
|
|
342
342
|
```bash
|
|
343
343
|
bstage dev # liquid 레포면 프리뷰, React(SDK) 레포면 기존 Vite 서버
|
|
@@ -370,7 +370,7 @@ bstage dev -p 5180 # 포트 지정
|
|
|
370
370
|
|
|
371
371
|
### 규약 밖 파일 경고
|
|
372
372
|
|
|
373
|
-
|
|
373
|
+
콘솔 빌더는 `public/{user|admin}/{이름}/template.liquid`, **정확히 이 깊이만** 인정합니다. 목록 화면은 규약을 벗어난 `template.liquid`도 함께 보여 주되 "콘솔이 무시합니다"라고 표시합니다. 프리뷰에서는 보이는데 배포하면 안 나오는 상황을 배포 전에 알아차리기 위한 것입니다.
|
|
374
374
|
|
|
375
375
|
- `public/user/events/summer/template.liquid` — 한 단계 더 깊어 무시됩니다(프리뷰는 렌더해 줍니다).
|
|
376
376
|
- `public/shared/hero/template.liquid` — user·admin 밖이라 무시됩니다(경로만 경고로 표시).
|
package/docs/GETTING_STARTED.md
CHANGED
|
@@ -6,7 +6,7 @@ b.stage 3rd-party 템플릿을 개발하고 배포하는 전체 흐름을 안내
|
|
|
6
6
|
|
|
7
7
|
- **Node.js** v20 이상
|
|
8
8
|
- **npm** 또는 **pnpm**
|
|
9
|
-
- **BstageClient 인증 정보** (선택) — API 호출에 필요한 `appId`, `appKey`(
|
|
9
|
+
- **BstageClient 인증 정보** (선택) — API 호출에 필요한 `appId`, `appKey`(콘솔의 APP KEY)를 콘솔에서 발급받아 두면 프로젝트 생성 시 자동으로 설정됩니다.
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
@@ -38,7 +38,7 @@ b.stage 3rd-party 템플릿은 **Web Component** 기반으로 동작합니다. S
|
|
|
38
38
|
|
|
39
39
|
이 문서를 직접 따라가는 대신 코딩 에이전트에게 맡길 수 있습니다. SDK가 에이전트용 자산을 함께 배포하기 때문입니다 — 프로젝트 규칙과 SDK 사용 규약을 담은 `AGENTS.md`, 작업별 절차서인 `.claude/skills/*/SKILL.md`(온보딩·템플릿 작성·마이그레이션·배포), 그리고 커밋 전에 시크릿을 걸러 내는 pre-commit 가드입니다. `bstage init`이 새 프로젝트에 이미 깔아 두고, 기존 프로젝트는 `npx @bstage-sdk/cli@latest ai install`로 설치합니다. SDK를 올린 뒤에는 `bstage ai update`로 최신화하고, 상태만 보려면 `bstage ai doctor`를 씁니다.
|
|
40
40
|
|
|
41
|
-
프로젝트가 아직 없다면 에이전트에게 "이 프로젝트를 처음 만드는데,
|
|
41
|
+
프로젝트가 아직 없다면 에이전트에게 "이 프로젝트를 처음 만드는데, 콘솔에 올리는 것까지 도와줘"라고 하면 온보딩 스킬이 생성부터 첫 배포까지 단계별로 안내합니다. 이미 프로젝트가 있다면 "이 슬롯에 들어갈 위젯을 만들어 줘"처럼 목적만 말해도 됩니다 — 에이전트가 `AGENTS.md`와 설치된 문서를 읽고 규약에 맞춰 작성합니다. 무엇이 설치되고 어떻게 갱신되는지는 [AI_TOOLKIT.md](./AI_TOOLKIT.md)를 참고하세요.
|
|
42
42
|
|
|
43
43
|
---
|
|
44
44
|
|
|
@@ -283,7 +283,7 @@ export const client = new BstageClient({
|
|
|
283
283
|
})
|
|
284
284
|
```
|
|
285
285
|
|
|
286
|
-
- `appKey`는
|
|
286
|
+
- `appKey`는 콘솔 화면의 **APP KEY**, 게이트웨이 헤더 `X-BSTAGE-APP-KEY`와 같은 값입니다. `VITE_` 환경변수로 번들에 평문으로 실려 브라우저에서 보이는 값이라 **비밀값이 아닙니다** — 접근 범위는 게이트웨이가 앱 단위로 제어합니다. 옛 이름 `appSecret`(`.env`의 `VITE_BSTAGE_APP_SECRET`)은 별칭으로 당분간 동작합니다([마이그레이션 가이드](./MIGRATION.md) 참고).
|
|
287
287
|
|
|
288
288
|
- 게이트웨이 base URL은 클라이언트가 임베드된 **페이지의 origin**(`location.origin + /gw`)으로 자동 결정됩니다. `{tenant}.sandstage.in`에 배포되면 그 환경의 게이트웨이로 가므로 환경별로 다시 빌드·설정할 필요가 없습니다.
|
|
289
289
|
- 로컬 개발에서는 **dev 서버**가 `.env`의 `VITE_BSTAGE_PHASE`(→ `vite.config.ts`의 `bstageDevPlugin`)를 보고 해당 phase 게이트웨이로 프록시합니다. 이 phase는 **dev 서버 설정**이지 `BstageClient`의 옵션이 아닙니다.
|
|
@@ -580,34 +580,34 @@ npx @bstage-sdk/cli@latest init --target admin
|
|
|
580
580
|
| 확인하는 것 | 전달 방식 | 템플릿이 할 일 |
|
|
581
581
|
| --- | --- | --- |
|
|
582
582
|
| 운영자 로그인 여부 | 어드민 로그인 쿠키(같은 도메인이므로 브라우저가 자동으로 보냅니다) | 없음 |
|
|
583
|
-
| 허가된 앱 여부 | `X-BSTAGE-APP-ID`·`X-BSTAGE-APP-KEY` 헤더(**관리자 콘솔용(MANAGEMENT) 키**(`bsm_`)만 통과합니다) | `.env`와
|
|
583
|
+
| 허가된 앱 여부 | `X-BSTAGE-APP-ID`·`X-BSTAGE-APP-KEY` 헤더(**관리자 콘솔용(MANAGEMENT) 키**(`bsm_`)만 통과합니다) | `.env`와 콘솔 빌드 환경변수에 MANAGEMENT 키를 넣습니다 |
|
|
584
584
|
|
|
585
|
-
- **키 발급**:
|
|
586
|
-
- **Surface마다 사용할 키 타입이 정해져 있습니다.** USER에는 PUBLIC(`bsp_`), ADMIN에는 MANAGEMENT(`bsm_`) 키를 사용합니다. PUBLIC 키로 어드민 게이트웨이를 호출하면 `401 KEY_TYPE_NOT_ALLOWED`, 어드민에 로그인하지 않았거나 어드민 도메인 밖에서 호출하면 `401 MISSING_ADMIN_ACCESS_TOKEN`, 허용 Origin이 유저 도메인으로 남아 있으면 `403`입니다. 반대로 MANAGEMENT 키를 유저 템플릿에 넣으면 유저 게이트웨이가 거부하고 키만 노출됩니다. 그래서
|
|
587
|
-
- **MANAGEMENT 키도 빌드 결과물에 평문으로 포함됩니다.** 어드민 화면을 열 수 있는 사람은 개발자 도구로 키를 볼 수 있으므로, 허용 Origin과 스테이지 범위를 좁히는 발급 조건이 키를 보호하는 유일한 수단입니다. 유출이 의심되면
|
|
588
|
-
- **호출할 수 있는 API**는
|
|
589
|
-
-
|
|
590
|
-
- **로컬·미리보기에서는 응답이 오지 않습니다.** `bstage dev`는 어드민 게이트웨이를 프록시하지 않고(어드민 모드에서 어드민 호스트로 가는 것은 로그인뿐),
|
|
585
|
+
- **키 발급**: 콘솔 `조직 › API 키`에서 키 타입 **MANAGEMENT**, 스테이지는 이 화면이 들어갈 **하나**, 허용 Origin은 **어드민 콘솔 도메인**(예: sandbox는 `https://{스테이지ID}.mysandstage.in`)으로 발급합니다. 허용 Origin에 자동으로 채워지는 값은 유저 도메인이므로, 그대로 두면 어드민에서 보낸 호출이 거부됩니다. 변수 이름은 유저 템플릿과 같고 값만 다릅니다(`VITE_BSTAGE_APP_KEY=bsm_…`).
|
|
586
|
+
- **Surface마다 사용할 키 타입이 정해져 있습니다.** USER에는 PUBLIC(`bsp_`), ADMIN에는 MANAGEMENT(`bsm_`) 키를 사용합니다. PUBLIC 키로 어드민 게이트웨이를 호출하면 `401 KEY_TYPE_NOT_ALLOWED`, 어드민에 로그인하지 않았거나 어드민 도메인 밖에서 호출하면 `401 MISSING_ADMIN_ACCESS_TOKEN`, 허용 Origin이 유저 도메인으로 남아 있으면 `403`입니다. 반대로 MANAGEMENT 키를 유저 템플릿에 넣으면 유저 게이트웨이가 거부하고 키만 노출됩니다. 그래서 콘솔은 유저(USER) 레포의 빌드 환경변수에 `bsm_` 값을 저장하지 않습니다(400). 게시한 뒤에는 `bstage doctor`가 키 타입 불일치(`appkey.type_surface`)를 알려 줍니다.
|
|
587
|
+
- **MANAGEMENT 키도 빌드 결과물에 평문으로 포함됩니다.** 어드민 화면을 열 수 있는 사람은 개발자 도구로 키를 볼 수 있으므로, 허용 Origin과 스테이지 범위를 좁히는 발급 조건이 키를 보호하는 유일한 수단입니다. 유출이 의심되면 콘솔에서 키를 회전(새 키 발급 + 옛 키 즉시 만료)한 뒤 빌드 환경변수를 바꾸고 다시 빌드합니다. 회전하면 APP KEY뿐 아니라 **APP ID도 새 값**이므로 둘 다 바꿉니다. 서버용(SIGNING) 키는 어떤 템플릿에도 넣지 않습니다.
|
|
588
|
+
- **호출할 수 있는 API**는 콘솔 개발자 문서의 **API 레퍼런스 › 운영자 탭**에 있는 것뿐입니다. 목록에 없는 경로를 임의로 만들어 호출하지 말고, 필요한 API가 목록에 없으면 b.stage에 요청하세요.
|
|
589
|
+
- **콘솔은 빌드 환경변수 저장 시점에 거부합니다**(400): 키 이름이 `^VITE_[A-Z0-9_]+$`가 아니거나 32개 초과·이름 128자 초과·값 2048자 초과, 앞뒤 공백을 뺀 값이 `bss_`로 시작(모든 레포)하거나 `bsm_`로 시작(유저 레포), APP ID·APP KEY가 그 스테이지 키와 맞지 않음(공백 포함·없는 키·만료/폐기·스테이지 범위 밖·짝이 아닌 KEY. 파트너 조회가 실패하면 이 검사는 건너뜁니다).
|
|
590
|
+
- **로컬·미리보기에서는 응답이 오지 않습니다.** `bstage dev`는 어드민 게이트웨이를 프록시하지 않고(어드민 모드에서 어드민 호스트로 가는 것은 로그인뿐), 콘솔 미리보기는 템플릿의 직접 게이트웨이 호출을 막습니다. 어드민 API 응답은 게시한 뒤 실제 어드민 화면에서 확인하세요.
|
|
591
591
|
|
|
592
592
|
---
|
|
593
593
|
|
|
594
594
|
## 9. 배포
|
|
595
595
|
|
|
596
|
-
배포는
|
|
596
|
+
배포는 콘솔이 이 레포의 기본 브랜치 HEAD를 clone해 빌드하고, 그 산출물을 배치(페이지·슬롯)에 적용하는 것으로 이뤄집니다. SDK는 워크플로우 파일을 생성·관리하지 않습니다. 콘솔 화면에서 하거나, 아래 `bstage deploy`로 터미널에서 합니다.
|
|
597
597
|
|
|
598
598
|
### 9.0 터미널에서 배포하기 — `bstage deploy`
|
|
599
599
|
|
|
600
|
-
|
|
600
|
+
콘솔 화면(`새 버전 빌드` → `버전 변경` → `게시하기`)과 같은 일을 CLI로 합니다. **콘솔은 GitHub 기본 브랜치의 HEAD를 clone해 빌드**하므로 로컬 산출물은 올라가지 않습니다 — 커밋·push가 먼저입니다.
|
|
601
601
|
|
|
602
|
-
1. `npx bstage login` — 터미널에 코드(`XXXX-XXXX`)가 뜨고 브라우저가 열립니다.
|
|
603
|
-
2. CI·브라우저 없는 환경은
|
|
602
|
+
1. `npx bstage login` — 터미널에 코드(`XXXX-XXXX`)가 뜨고 브라우저가 열립니다. 콘솔에 로그인한 뒤 **코드가 같은지 확인**하고 등급(`deploy`)과 스코프(스테이지 선택, 또는 조직 Admin이면 **이 조직의 모든 스테이지**)를 골라 승인하면 터미널이 자동으로 로그인됩니다(토큰은 `~/.config/bstage/credentials.json`에 0600 권한으로 저장되며, 콘솔이 정한 기간이 지나면 만료됩니다 — 만료일은 로그인 완료 시 터미널에 표시됩니다).
|
|
603
|
+
2. CI·브라우저 없는 환경은 콘솔 **설정 › CLI 토큰**에서 발급한 토큰을 `BSTAGE_TOKEN`으로 넘깁니다. 콘솔 주소는 공개 phase(`real`·`sandbox`)는 CLI에 내장돼 있고, 사내 phase(`dev`·`qa`)는 `.env`의 `VITE_BSTAGE_PORTAL_HOST`로 지정합니다 — 어느 phase를 쓸지는 `.env`의 `VITE_BSTAGE_PHASE`(없으면 `sandbox`)로 정해지며 `bstage dev`와 같은 규칙입니다.
|
|
604
604
|
3. 프로젝트 디렉터리에서 `npx bstage link` — 조직·스테이지·연결 레포 선택 (`.bstage/project.json`, gitignore 대상)
|
|
605
|
-
4. 배치가 아직 없으면(새 레포) `npx bstage placement create --template <산출물 이름> --path /<경로>` — 이 레포의 산출물 하나를 페이지 배치로 만듭니다.
|
|
605
|
+
4. 배치가 아직 없으면(새 레포) `npx bstage placement create --template <산출물 이름> --path /<경로>` — 이 레포의 산출물 하나를 페이지 배치로 만듭니다. 콘솔은 레포를 연결해도 스스로 빌드하지 않으므로, 성공한 빌드에 그 산출물이 없으면 이 명령이 push된 커밋으로 빌드부터 하고 끝나면 배치를 만듭니다. 만든 배치는 아직 라이브가 아닙니다.
|
|
606
606
|
5. `git push` 후 `npx bstage deploy` — 더티 트리·브랜치·push 여부 점검 → 빌드 → 로그 → 배치 적용 확인. **`deploy`는 게시까지 하지 않습니다** — 게시 여부를 바꾸려면 `bstage publish on`/`off`를 따로 실행하세요.
|
|
607
607
|
|
|
608
|
-
**조직마다 한 번 로그인합니다.** CLI 토큰은 조직 하나에 묶여 있어, 여러 조직의 스테이지를 오가려면 조직마다 `bstage login` 을 한 번씩 해야 합니다. 자격증명 파일(`~/.config/bstage/credentials.json`)은
|
|
608
|
+
**조직마다 한 번 로그인합니다.** CLI 토큰은 조직 하나에 묶여 있어, 여러 조직의 스테이지를 오가려면 조직마다 `bstage login` 을 한 번씩 해야 합니다. 자격증명 파일(`~/.config/bstage/credentials.json`)은 **콘솔 주소 아래 조직별로** 토큰을 담으므로 두 번째 로그인이 첫 토큰을 덮어쓰지 않습니다. 명령이 쓸 토큰은 `.bstage/project.json` 의 조직으로 골라집니다(CI는 `BSTAGE_ORG`, `link` 는 `--org`). **조직이 정해져 있으면 그 조직 토큰만 씁니다** — 다른 조직 토큰으로 대신하지 않고, 저장된 조직 목록과 "이 조직으로 `bstage login` 하세요" 안내와 함께 종료 코드 3으로 끝납니다. 예외는 하나, 예전 형식(조직을 담지 않던 파일)에서 옮겨 온 토큰이 그 콘솔의 유일한 토큰일 때입니다 — 이때는 그대로 쓰이고, 다음에 그 콘솔로 로그인하면 조직이 붙은 토큰으로 대체됩니다. 무엇이 저장돼 있는지는 `bstage whoami` 가 조직·등급·스코프(`이 조직의 모든 스테이지` 또는 스테이지 개수)·만료로 보여 주고, `bstage logout` 은 기본적으로 그 콘솔의 모든 조직 토큰을 지웁니다(`--org <id>` 로 하나만). 붙여 넣기 경로(`--token`·`BSTAGE_TOKEN`)는 토큰만으로는 어느 조직 것인지 알 수 없어 `--org <id>` 또는 `BSTAGE_ORG` 를 함께 줘야 합니다.
|
|
609
609
|
|
|
610
|
-
|
|
610
|
+
**콘솔 주소는 허용된 곳에서만 옵니다.** `.bstage/project.json`과 `.env`는 저장소 안 파일이라 PR 하나로 바뀝니다 — 토큰을 `Authorization` 헤더로 보내는 주소를 그런 파일이 마음대로 정하면 적대적 PR이 CI 토큰을 다른 서버로 끌어갈 수 있습니다. 그래서 링크 파일의 `portalUrl`은 **허용 목록**(CLI에 내장된 공개 콘솔 주소 + `--portal`로 준 주소 + `BSTAGE_PORTAL_URL` + `BSTAGE_TOKEN`이 없을 때의 `.env` `VITE_BSTAGE_PORTAL_HOST`) 안의 오리진일 때만 쓰이고, 밖이면 요청을 보내지 않고 종료 코드 2로 끝납니다. **`BSTAGE_TOKEN`이 설정된 환경(CI)에서는 한 단계 더 좁아집니다** — 콘솔 주소는 `--portal`·`BSTAGE_PORTAL_URL`·공개 phase 매핑으로만 정해지고, 링크 파일과 `.env`의 주소는 아예 쓰이지 않습니다. CI에서는 `BSTAGE_PORTAL_URL`을 명시하세요. `bstage login`도 링크 파일을 보지 않습니다.
|
|
611
611
|
|
|
612
612
|
CI에서는 `BSTAGE_TOKEN`·`BSTAGE_PORTAL_URL`(또는 `VITE_BSTAGE_PHASE`)·`BSTAGE_ORG`·`BSTAGE_SPACE`·`BSTAGE_REPO`·`BSTAGE_SURFACE`를 환경변수로 주고 `bstage deploy --yes --json`을 실행합니다 — `--yes`는 확인 프롬프트를 생략하고, `--json`은 사람이 읽는 안내 없이 구조화된 결과만 stdout에 남겨 스크립트에서 파싱하기 좋습니다.
|
|
613
613
|
|
|
@@ -625,7 +625,7 @@ CI에서는 `BSTAGE_TOKEN`·`BSTAGE_PORTAL_URL`(또는 `VITE_BSTAGE_PHASE`)·`BS
|
|
|
625
625
|
| `login` / `logout` / `whoami` | 토큰 등록·삭제·확인 |
|
|
626
626
|
| `link` | 디렉터리 ↔ 조직/스테이지/레포 |
|
|
627
627
|
| `list` | 배치 상태·라이브 커밋·최근 빌드 |
|
|
628
|
-
| `doctor [--placement]` | 배치별
|
|
628
|
+
| `doctor [--placement]` | 배치별 콘솔 진단 (문제·조치, `--json`) |
|
|
629
629
|
| `logs [buildId] [-f]` | 빌드 로그 |
|
|
630
630
|
| `deploy [--placement] [--yes] [--no-wait]` | 빌드 → 라이브 적용 |
|
|
631
631
|
| `placement create --template [--path]` | 페이지 배치 만들기 (빌드 없으면 빌드부터) |
|
|
@@ -644,11 +644,11 @@ CI에서는 `BSTAGE_TOKEN`·`BSTAGE_PORTAL_URL`(또는 `VITE_BSTAGE_PHASE`)·`BS
|
|
|
644
644
|
|
|
645
645
|
네 배열은 비어 있어도 항상 나옵니다. 각 항목은 `{ id, label, from?, to?, message? }`이고 `from`·`to`는 라이브 빌드 id입니다(`publish`는 게시 여부만 바꾸므로 없습니다). `bstage logs --json`은 `{ build, log }`이며, `-f`와 함께 써도 진행 중 로그는 stderr로 흐르고 stdout에는 이 객체 하나만 나갑니다.
|
|
646
646
|
|
|
647
|
-
`placement create`의 `--template`은 sdk는 `src/pages/{이름}`, liquid는 `public/{user|admin}/{이름}`의 `{이름}`입니다. `--path`를 생략하면 `/{이름}`이 됩니다. 같은 경로에 이 레포·같은 산출물의 배치가 이미 있으면 새로 만들지 않고 성공(`unchanged`)으로 끝나므로 다시 실행해도 안전하고, 같은 경로를 다른 배치가 쓰고 있으면 종료 코드 4입니다. `--json`(`--yes`와 함께)은 위 요약에 `placement`·`build`·`next`(다음에 실행할 명령)를 더해 냅니다. CLI 토큰은 `deploy` 등급이어야 하고, 사용자는
|
|
647
|
+
`placement create`의 `--template`은 sdk는 `src/pages/{이름}`, liquid는 `public/{user|admin}/{이름}`의 `{이름}`입니다. `--path`를 생략하면 `/{이름}`이 됩니다. 같은 경로에 이 레포·같은 산출물의 배치가 이미 있으면 새로 만들지 않고 성공(`unchanged`)으로 끝나므로 다시 실행해도 안전하고, 같은 경로를 다른 배치가 쓰고 있으면 종료 코드 4입니다. `--json`(`--yes`와 함께)은 위 요약에 `placement`·`build`·`next`(다음에 실행할 명령)를 더해 냅니다. CLI 토큰은 `deploy` 등급이어야 하고, 사용자는 콘솔 화면에서 배치를 만들 때와 같은 권한(스테이지 관리자 이상)이 필요합니다.
|
|
648
648
|
|
|
649
|
-
위젯(슬롯) 배치를 만드는 일과 배치를 지우는 일은
|
|
649
|
+
위젯(슬롯) 배치를 만드는 일과 배치를 지우는 일은 콘솔 화면에서만 합니다.
|
|
650
650
|
|
|
651
|
-
**배포했는데 페이지가 기대와 다르면 `bstage doctor`부터 실행하세요.** 로그인·링크된 디렉터리에서는 로컬 진단 뒤에 "
|
|
651
|
+
**배포했는데 페이지가 기대와 다르면 `bstage doctor`부터 실행하세요.** 로그인·링크된 디렉터리에서는 로컬 진단 뒤에 "콘솔 진단" 절이 붙어, 이 레포의 배치마다 콘솔이 판정한 문제(게시 꺼짐, 게시된 빌드 없음, 만료·불일치한 앱 키, 화면과 맞지 않는 키 타입, 다시 빌드하지 않은 환경변수, 반영 안 된 새 빌드 등)를 조치와 함께 보여 줍니다. 14일 안에 만료되는 키는 경고(`appkey.expiring_soon`)로 미리 알려 줍니다. 배치가 많으면 30개까지만 보고, `--placement <id|경로|슬롯 id>`로 하나만 볼 수 있습니다. `--json`은 `portal.placements[].findings[]`에 `{ id, severity, title, detail?, fix?, evidence? }`를 담고 `id`(예: `appkey.expired`)는 바뀌지 않는 식별자입니다. 진단에 `error` 항목이 있거나 **콘솔 진단 자체가 실패하면**(`portal.status`가 `error` — 이유는 `portal.reason`·`portal.placements[].error`) 종료 코드 1입니다(`warn`·`info`는 종료 코드를 바꾸지 않습니다). 로그인·링크가 없거나 콘솔이 아직 진단을 지원하지 않으면 그 절만 건너뜁니다(단 `--placement`를 줬으면 위 표대로 링크 없음은 2, 토큰 없음은 3이고, 이 레포에 맞는 배치가 없어도 2로 끝납니다).
|
|
652
652
|
|
|
653
653
|
로컬에서 산출물을 확인하고 싶으면 `npx bstage build`를 실행합니다. 페이지는 `dist/{경로}/template.js`, 위젯은 `dist/{슬롯 id}/template.js`로 나옵니다.
|
|
654
654
|
|
|
@@ -669,15 +669,15 @@ CI에서는 `BSTAGE_TOKEN`·`BSTAGE_PORTAL_URL`(또는 `VITE_BSTAGE_PHASE`)·`BS
|
|
|
669
669
|
|
|
670
670
|
### 9.2 배포 전 점검 — 증상으로 원인 되짚기
|
|
671
671
|
|
|
672
|
-
아래 항목은 **빌드 시점에는 감지할 수 없습니다.** 키 형식(`bsa_`/`bsp_`)은 ID·시크릿 구분일 뿐 어느 환경에서 발급했는지를 담지 않고, 나머지는 BE·콘솔 설정이라 코드에 흔적이 없습니다. 게시한 뒤에는 `bstage doctor`의
|
|
672
|
+
아래 항목은 **빌드 시점에는 감지할 수 없습니다.** 키 형식(`bsa_`/`bsp_`)은 ID·시크릿 구분일 뿐 어느 환경에서 발급했는지를 담지 않고, 나머지는 BE·콘솔 설정이라 코드에 흔적이 없습니다. 게시한 뒤에는 `bstage doctor`의 콘솔 진단이 일부(키 문제, 커스텀 템플릿 토글)를 짚어 줍니다. 리얼 배포 후 아래 에러를 만나면 이 표로 되짚으세요.
|
|
673
673
|
|
|
674
674
|
| 증상 | 원인 | 조치 | 소관 |
|
|
675
675
|
| ----------------------- | ---------------------------------------- | -------------------------------------------- | ------------ |
|
|
676
|
-
| `401 Unauthorized` | 다른 환경(QA 등)의 키로 배포 / 키 미발급 / 재발급 전 옛 APP ID | 배포할 환경에서 발급한 사용 중인 appId·appKey인지 확인(`bstage doctor`가 알려 줌) |
|
|
676
|
+
| `401 Unauthorized` | 다른 환경(QA 등)의 키로 배포 / 키 미발급 / 재발급 전 옛 APP ID | 배포할 환경에서 발급한 사용 중인 appId·appKey인지 확인(`bstage doctor`가 알려 줌) | 콘솔 |
|
|
677
677
|
| `403 Forbidden` | Space ID가 프로젝트에 미등록 | BE에 Space ID 등록 요청 | BE |
|
|
678
|
-
| `403 ORIGIN_NOT_ALLOWED` | 키의 허용 Origin에 배포 도메인 없음(끝의 `/`·대문자도 다른 값) | 키 상세에서 허용 Origin에 `https://{도메인}` 그대로 추가, 재빌드 불필요 |
|
|
678
|
+
| `403 ORIGIN_NOT_ALLOWED` | 키의 허용 Origin에 배포 도메인 없음(끝의 `/`·대문자도 다른 값) | 키 상세에서 허용 Origin에 `https://{도메인}` 그대로 추가, 재빌드 불필요 | 콘솔 (키 설정) |
|
|
679
679
|
| 템플릿이 화면에 안 뜸 | 콘솔 "커스텀 템플릿 사용" 토글이 꺼짐 | 콘솔에서 토글 확인 | 콘솔 |
|
|
680
|
-
| 배포 자체가 안 됨 |
|
|
680
|
+
| 배포 자체가 안 됨 | 데브콘솔 접근·리얼 배포 권한 없음 | 권한 요청 | DevOps |
|
|
681
681
|
| 임베드(iframe)가 차단됨 | CSP `frame-ancestors`에 도메인 없음 | 도메인 추가 요청 | BE·보안 |
|
|
682
682
|
|
|
683
683
|
**QA에서 됐다고 리얼에서 되지 않습니다.** 위 항목은 전부 환경마다 따로 설정됩니다. 하나씩 막힐 때마다 요청·대기가 반복되면 며칠이 걸립니다. 처음 리얼로 나갈 때는 위 표의 BE·콘솔 항목을 **한 번에 모아서** 요청하세요.
|
package/docs/LIQUID.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## 1. liquid 방식이란
|
|
6
6
|
|
|
7
|
-
liquid 페이지는 플랫폼(서버)이 데이터를 채워 렌더링하는 [liquidjs](https://liquidjs.com/) 템플릿으로, **목록을 보여 주기만 하는 정적 페이지**에 알맞습니다. 브라우저에서 번들을 실행하지 않으므로 **빌드 산출물이 없습니다.**
|
|
7
|
+
liquid 페이지는 플랫폼(서버)이 데이터를 채워 렌더링하는 [liquidjs](https://liquidjs.com/) 템플릿으로, **목록을 보여 주기만 하는 정적 페이지**에 알맞습니다. 브라우저에서 번들을 실행하지 않으므로 **빌드 산출물이 없습니다.** 콘솔은 push된 커밋의 템플릿 파일을 그대로 패키징합니다.
|
|
8
8
|
|
|
9
9
|
| 항목 | sdk | liquid |
|
|
10
10
|
| ----------- | ------------------------------------------- | ----------------------------------------- |
|
|
@@ -33,7 +33,7 @@ public/
|
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
- **이름 규칙**: 소문자로 시작하고 소문자·숫자·하이픈만 씁니다(`^[a-z][a-z0-9-]*$`). CDN 경로 세그먼트가 되므로 대문자를 쓰면 대소문자를 구분하지 않는 파일시스템에서 로컬과 배포 결과가 달라집니다.
|
|
36
|
-
- **한 세그먼트**여야 합니다. `public/user/events/summer/`처럼 한 단계 더 깊으면
|
|
36
|
+
- **한 세그먼트**여야 합니다. `public/user/events/summer/`처럼 한 단계 더 깊으면 콘솔이 별도 경고 없이 무시합니다.
|
|
37
37
|
- `data.json`은 로컬 전용입니다. 실제 값은 플랫폼이 서버에서 넣습니다. **키 이름은 플랫폼이 정한 이름을 따라야 합니다.** 유저 화면 최상위는 `lounges`·`stories`·`contentSections`·`latestContents`·`shopCategories` 다섯 개입니다. 다른 이름을 쓰면 미리보기에서만 보이고, 배포하면 빈 값이 됩니다. 각 항목의 필드는 계약이 아니라 모양을 보기 위한 예시이므로 실제 렌더 결과로 확인하세요. 어드민 화면이 받는 값은 확인되지 않았습니다.
|
|
38
38
|
- 스캐폴드는 Vite·TypeScript·ESLint·`.env`를 만들지 않습니다. 번들링도 타입 검사도 하지 않기 때문입니다.
|
|
39
39
|
|
|
@@ -56,7 +56,7 @@ bstage dev -p 3000 # 포트 지정 (기본 5173)
|
|
|
56
56
|
|
|
57
57
|
- 파일을 고치면 **자동으로 새로고침**됩니다(미리보기 서버가 넣는 SSE 스크립트로, 배포물과는 무관합니다).
|
|
58
58
|
- 렌더가 실패하면 파일·줄 번호·메시지를 보여 주는 **오류 페이지**가 HTTP 200 상태로 표시됩니다. 파일을 고치면 자동으로 새로고침되어 바로 정상 화면으로 돌아갑니다.
|
|
59
|
-
- 규약을 벗어난 `template.liquid`도 목록에 보여 주되 "
|
|
59
|
+
- 규약을 벗어난 `template.liquid`도 목록에 보여 주되 "콘솔이 무시합니다"라고 표시합니다.
|
|
60
60
|
|
|
61
61
|
**미리보기에 없는 기능**: 인증 프록시 · API 프록시 · phase · 실데이터. `--phase`를 지정해도 무시되며, 그렇다는 안내만 출력됩니다. 상세는 [DEV_SERVER.md §7](./DEV_SERVER.md#7-liquid-프리뷰-liquid-레포)을 참고하세요.
|
|
62
62
|
|
|
@@ -72,25 +72,25 @@ bstage build --json # { "kind": "liquid", "issues": [...] } 한 덩어리
|
|
|
72
72
|
| 등급 | 검사 |
|
|
73
73
|
| ----- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
74
74
|
| error | `template.liquid` 문법 오류(줄 번호 표시) · `data.json` JSON 파싱 실패 · 폴더 이름 규칙 위반 · (혼합 레포) sdk 페이지 이름 `user`·`admin` · liquid 템플릿 0개 |
|
|
75
|
-
| warn | 규약 밖 위치의 `template.liquid`(
|
|
75
|
+
| warn | 규약 밖 위치의 `template.liquid`(콘솔이 무시) · `layout.json` 존재(콘솔이 지움) · 폴더에 `template.liquid`가 아닌 파일만 있음 |
|
|
76
76
|
|
|
77
77
|
같은 결과를 `bstage doctor`가 "liquid 검증" 절에서 보여 줍니다(`--json`에서는 `liquid.issues`). doctor의 liquid 표는 sdk와 다릅니다. 기대 파일은 템플릿 루트(`public/user` 또는 `public/admin`)와 `AGENTS.md`, 기대 스크립트는 `dev`·`build`이고, 권장 의존성 절은 나오지 않습니다. 버전 표도 `@bstage-sdk/cli` 한 줄뿐입니다.
|
|
78
78
|
|
|
79
79
|
## 5. 배포
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
콘솔이 push된 커밋의 `public/{user|admin}/{이름}/`을 **그대로 패키징합니다**(`data.json`·`layout.json`은 제외합니다. 배치는 관리도구에서 설정합니다). 로컬 산출물은 업로드되지 않으므로, 먼저 커밋하고 push해야 합니다.
|
|
82
82
|
|
|
83
|
-
1. **레포 연결만
|
|
83
|
+
1. **레포 연결만 콘솔 화면에서** 합니다. 이어서 `bstage login`·`bstage link` 뒤 `bstage placement create --template <이름>`으로 페이지 배치를 만듭니다(`<이름>`은 `public/{user|admin}/<이름>/`, 성공한 빌드가 없으면 빌드부터 합니다).
|
|
84
84
|
2. 이후에는 터미널에서 `bstage deploy`(빌드 → 라이브 적용) · `bstage rollback`(이전 성공 빌드로 되돌리기) · `bstage publish on|off`(게시 토글)를 씁니다. 로그인·링크·종료 코드 등 공통 절차는 sdk와 같습니다. 자세한 내용은 [GETTING_STARTED.md §9](./GETTING_STARTED.md#9-배포)를 참고하세요.
|
|
85
85
|
3. `bstage list`는 최근 빌드의 산출물 종류(`sdk`·`liquid`) 열을 함께 보여 줍니다. 옛 빌드에는 이 값이 없어 `-`로 나옵니다.
|
|
86
86
|
|
|
87
|
-
> liquid 레포에는 `.env`가 없어 `bstage login`·`bstage link`가 phase를 읽을 곳이 없습니다. sandbox가 아닌
|
|
87
|
+
> liquid 레포에는 `.env`가 없어 `bstage login`·`bstage link`가 phase를 읽을 곳이 없습니다. sandbox가 아닌 콘솔이면 두 명령 모두에 `--phase <phase>`를 주세요(생략하면 sandbox).
|
|
88
88
|
|
|
89
89
|
## 6. 이미지·영상 넣기
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
**콘솔 화면의 스테이지 > 미디어에 올리고, 받은 URL을 템플릿에 절대 주소로 넣습니다.** 이미지와 영상만 올릴 수 있고, 허용 형식·용량 한도는 업로드할 때 화면이 알려 줍니다.
|
|
92
92
|
|
|
93
|
-
레포에 파일을 두고 상대 경로로 참조하면 **배포 후 깨집니다.**
|
|
93
|
+
레포에 파일을 두고 상대 경로로 참조하면 **배포 후 깨집니다.** 콘솔은 템플릿 폴더를 그대로 복사하지만, 렌더된 HTML이 스페이스 도메인 페이지 안으로 들어가므로 상대 경로는 그 도메인 기준으로 해석되어 산출물이 놓인 주소를 가리키지 않습니다.
|
|
94
94
|
|
|
95
95
|
로컬 미리보기는 이 점에서 배포와 **반대로** 동작합니다. 미리보기는 템플릿 폴더의 파일을 함께 서빙하므로 상대 경로 이미지가 잘 보입니다. 미리보기에서 보인다고 해서 배포 후에도 보인다고 판단하지 마세요.
|
|
96
96
|
|
|
@@ -112,11 +112,11 @@ bstage build --json # { "kind": "liquid", "issues": [...] } 한 덩어리
|
|
|
112
112
|
|
|
113
113
|
## 8. 주의할 점
|
|
114
114
|
|
|
115
|
-
- **sdk와 함께 둘 수 있습니다(혼합 레포).** `bstage build`는 sdk 템플릿만 번들하고 liquid는 검증만 하며(`dist/`에 liquid를 넣지 않습니다),
|
|
115
|
+
- **sdk와 함께 둘 수 있습니다(혼합 레포).** `bstage build`는 sdk 템플릿만 번들하고 liquid는 검증만 하며(`dist/`에 liquid를 넣지 않습니다), 콘솔은 sdk를 빌드한 뒤 liquid를 함께 패키징합니다. 단 `src/pages/user`·`src/pages/admin` 페이지는 산출물이 liquid 자리(`dist/{user|admin}/`)와 겹쳐 `bstage build`가 종료 코드 2로 멈춥니다. 폴더 이름을 바꾸세요. `bstage dev`는 혼합 레포에서 기본으로 sdk 미리보기를 실행하고, `--kind liquid`를 주면 liquid 미리보기를 실행합니다.
|
|
116
116
|
- **폴더 깊이가 정해져 있습니다.** `public/{user|admin}/{이름}/template.liquid`, 정확히 이 자리만 인정됩니다. 어긋나면 빌드는 성공하는데 화면에 나오지 않습니다.
|
|
117
|
-
- **페이지(PAGE) 배치만** 됩니다. 위젯 자리에 배치하면
|
|
118
|
-
- **`data.json`·`layout.json`은 로컬 전용입니다.**
|
|
119
|
-
- **파일명은 `template.liquid` 고정입니다.** `index.html`처럼 다른 이름이면
|
|
117
|
+
- **페이지(PAGE) 배치만** 됩니다. 위젯 자리에 배치하면 콘솔이 400 오류를 반환합니다.
|
|
118
|
+
- **`data.json`·`layout.json`은 로컬 전용입니다.** 콘솔이 패키징에서 지우므로 배포에 필요한 값을 여기에 담지 마세요.
|
|
119
|
+
- **파일명은 `template.liquid` 고정입니다.** `index.html`처럼 다른 이름이면 콘솔이 그 폴더를 템플릿으로 보지 않습니다.
|
|
120
120
|
- **파셜(`{% render %}`·`{% include %}`)을 쓰지 않습니다.** 배포에서 빈 문자열이 됩니다. 7절을 참고하세요.
|
|
121
121
|
- **에셋을 레포에 두고 상대 경로로 참조하지 않습니다.** 배포 후 깨집니다. 6절을 참고하세요. 로컬 미리보기에서는 보이므로, 미리보기 결과만으로 판단하지 마세요.
|
|
122
122
|
- **플랫폼이 제공하는 값의 이름을 임의로 만들지 마세요.** 유저 화면 최상위는 `lounges`·`stories`·`contentSections`·`latestContents`·`shopCategories` 다섯 개뿐이고, 그 밖의 이름은 빈 문자열이 됩니다(어드민 화면이 받는 값은 확인되지 않았습니다). `data.json` 샘플도 같은 이름을 써야 미리보기가 배포와 같은 모양이 됩니다.
|
package/docs/MIGRATION.md
CHANGED
|
@@ -51,6 +51,26 @@
|
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
54
|
+
## → cli 0.13.0
|
|
55
|
+
|
|
56
|
+
### 콘솔 기본 주소가 `bskit.*`으로 바뀌었다 — `자동`
|
|
57
|
+
|
|
58
|
+
**영향**
|
|
59
|
+
|
|
60
|
+
- real·sandbox 콘솔에 로그인·배포하는 모든 프로젝트. 할 일은 없다.
|
|
61
|
+
- 관리 도구 이름이 b.stage kit 콘솔로 바뀌면서 주소도 옮겼다. 옛 주소는 콘솔이 리다이렉트하지만, `POST`와 인증 헤더는 리다이렉트를 넘지 못한다. 그래서 CLI가 처음부터 새 주소를 부른다.
|
|
62
|
+
|
|
63
|
+
**변경 내용**
|
|
64
|
+
|
|
65
|
+
- real 기본 주소: `bstage-portal.bstage.in` → `bskit.bstage.in`
|
|
66
|
+
- sandbox 기본 주소: `bstage-portal.sandstage.in` → `bskit.sandstage.in`
|
|
67
|
+
- 옛 주소(`bstage-portal.bstage.in`·`bstage-portal.sandstage.in` 등)로 저장된 `.bstage/project.json`·로그인 토큰·`BSTAGE_PORTAL_URL`·`--portal` 값은 새 주소로 바꿔 읽는다. 다시 `bstage link`·`bstage login` 하지 않아도 된다.
|
|
68
|
+
|
|
69
|
+
**적용**
|
|
70
|
+
|
|
71
|
+
1. (자동) CLI를 올리면 된다.
|
|
72
|
+
2. (확인) CI에서 `BSTAGE_PORTAL_URL`에 옛 주소를 넣었다면 새 주소로 바꾼다. 바꾸지 않아도 새 CLI는 새 주소로 바꿔 읽는다. 옛 CLI도 당분간은 동작한다(옛 주소의 API는 전환 기간 동안 그대로 응답한다).
|
|
73
|
+
|
|
54
74
|
## → ai-toolkit 0.8.6
|
|
55
75
|
|
|
56
76
|
### `bstage doctor` 종료 코드·동작 안내 정정(에이전트 스킬) — `자동`
|