chiwaa 0.1.0 → 0.1.1
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/bin/chiwaa.js +20 -6
- package/package.json +1 -1
package/bin/chiwaa.js
CHANGED
|
@@ -63,7 +63,7 @@ async function api(method, p, { body, headers = {}, auth = true } = {}) {
|
|
|
63
63
|
const h = { "User-Agent": `chiwaa-cli/${VERSION}`, ...headers };
|
|
64
64
|
if (auth) {
|
|
65
65
|
const t = token();
|
|
66
|
-
if (!t) fail("로그인이 필요합니다. 먼저
|
|
66
|
+
if (!t) fail("로그인이 필요합니다. 먼저 아래 명령으로 로그인하세요(브라우저에서 승인).\n\n npx chiwaa login\n");
|
|
67
67
|
h.Authorization = `Bearer ${t}`;
|
|
68
68
|
}
|
|
69
69
|
let payload = body;
|
|
@@ -254,6 +254,16 @@ function buildIfNeeded(dir, args) {
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
// ---------- 사이트 정하기 ----------
|
|
257
|
+
// 사용자가 직접 정한 이름은 바꾸지 않는다 — 규칙에 안 맞으면 거절한다(대문자만 소문자로)
|
|
258
|
+
const NAME_RULE = "사이트 이름은 영문 소문자·숫자·하이픈(-)으로 2~30자, 첫 글자는 영문이나 숫자여야 합니다. 예: my-shop, cafe2026";
|
|
259
|
+
function checkName(s) {
|
|
260
|
+
const n = String(s).trim().toLowerCase();
|
|
261
|
+
if (!/^[a-z0-9][a-z0-9-]{1,29}$/.test(n)) fail(`쓸 수 없는 사이트 이름입니다: ${s}
|
|
262
|
+
${NAME_RULE}`);
|
|
263
|
+
return n;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// 폴더 이름으로 기본 이름을 지어 줄 때만 쓴다
|
|
257
267
|
function slug(s) {
|
|
258
268
|
let n = String(s).toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").replace(/-{2,}/g, "-").slice(0, 30);
|
|
259
269
|
if (n.length < 2) n = `site-${n}`.replace(/-$/, "");
|
|
@@ -267,13 +277,17 @@ async function resolveSite(dir, args) {
|
|
|
267
277
|
if (r.status === 200) return linkSite(dir, r.data);
|
|
268
278
|
console.log(c.dim(`${LINK_FILE} 의 사이트(${link.site})를 찾지 못해 새로 정합니다.`));
|
|
269
279
|
}
|
|
270
|
-
let name =
|
|
280
|
+
let name = args.name ? checkName(args.name) : slug(path.basename(path.resolve(dir)));
|
|
271
281
|
if (args.name) {
|
|
272
282
|
const r = await api("GET", `/api/v1/sites/${encodeURIComponent(name)}`);
|
|
273
283
|
if (r.status === 200) return linkSite(dir, r.data);
|
|
274
284
|
} else if (TTY && !args.yes) {
|
|
275
|
-
|
|
276
|
-
|
|
285
|
+
for (;;) {
|
|
286
|
+
const a = await ask(`사이트 이름 ${c.dim(`(엔터 = ${name}.chiwaa.com)`)}: `);
|
|
287
|
+
if (!a) break;
|
|
288
|
+
if (/^[a-z0-9][a-z0-9-]{1,29}$/.test(a.toLowerCase())) { name = a.toLowerCase(); break; }
|
|
289
|
+
console.log(c.red("✗"), NAME_RULE);
|
|
290
|
+
}
|
|
277
291
|
const r = await api("GET", `/api/v1/sites/${encodeURIComponent(name)}`);
|
|
278
292
|
if (r.status === 200) return linkSite(dir, r.data);
|
|
279
293
|
}
|
|
@@ -301,7 +315,7 @@ async function deploy(args) {
|
|
|
301
315
|
const dir = path.resolve(args._[1] || ".");
|
|
302
316
|
if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) fail(`폴더가 없습니다: ${dir}`);
|
|
303
317
|
if (!token()) {
|
|
304
|
-
if (!TTY) fail("로그인이 필요합니다.
|
|
318
|
+
if (!TTY) fail("로그인이 필요합니다. 먼저 아래 명령으로 로그인하고(브라우저에서 승인), 같은 배포 명령을 다시 실행하세요.\n\n npx chiwaa login\n\n (자동화·AI 도구에서는 환경변수 CHIWAA_TOKEN 으로도 됩니다)");
|
|
305
319
|
await login(args);
|
|
306
320
|
}
|
|
307
321
|
const site = await resolveSite(dir, args);
|
|
@@ -331,7 +345,7 @@ async function list() {
|
|
|
331
345
|
}
|
|
332
346
|
|
|
333
347
|
async function siteName(args) {
|
|
334
|
-
if (args.name) return
|
|
348
|
+
if (args.name) return checkName(args.name);
|
|
335
349
|
const link = readJSON(path.join(process.cwd(), LINK_FILE));
|
|
336
350
|
if (link && link.site) return link.site;
|
|
337
351
|
fail(`어느 사이트인지 모릅니다. 사이트 폴더에서 실행하거나 --name <이름> 을 붙여 주세요.`);
|