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.
Files changed (2) hide show
  1. package/bin/chiwaa.js +20 -6
  2. 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("로그인이 필요합니다. 먼저 `chiwaa login` 을 실행하세요.");
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 = slug(args.name || path.basename(path.resolve(dir)));
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
- const a = await ask(`사이트 이름 ${c.dim(`(${name}.chiwaa.com)`)}: `);
276
- if (a) name = slug(a);
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("로그인이 필요합니다. `chiwaa login` 을 하거나 CHIWAA_TOKEN 을 넣어 주세요.");
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 slug(args.name);
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 <이름> 을 붙여 주세요.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chiwaa",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "chiwaa.kr 에 사이트를 터미널에서 바로 올리는 도구",
5
5
  "bin": {
6
6
  "chiwaa": "bin/chiwaa.js"