gencow 0.1.119 → 0.1.120

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/gencow.mjs CHANGED
@@ -303,7 +303,8 @@ function _ensureEsbuildConsistency() {
303
303
  }
304
304
 
305
305
  /**
306
- * 모노레포 루트의 .npmrc에 esbuild hoisting 차단 규칙을 추가.
306
+ * 모노레포 루트의 .pnpmrc에 esbuild hoisting 차단 규칙을 추가.
307
+ * (.npmrc가 아닌 .pnpmrc — hoist-pattern은 pnpm 전용이므로 npm 경고 방지)
307
308
  * 이미 존재하면 스킵.
308
309
  */
309
310
  function _patchNpmrcForEsbuild(cwd) {
@@ -312,8 +313,9 @@ function _patchNpmrcForEsbuild(cwd) {
312
313
  let dir = cwd;
313
314
  for (let i = 0; i < 10; i++) {
314
315
  if (existsSync(resolve(dir, "pnpm-workspace.yaml"))) {
315
- const npmrcPath = resolve(dir, ".npmrc");
316
- const content = existsSync(npmrcPath) ? readFileSync(npmrcPath, "utf8") : "";
316
+ // .pnpmrc 대상 (pnpm 전용 설정 → npm "Unknown project config" 경고 방지)
317
+ const pnpmrcPath = resolve(dir, ".pnpmrc");
318
+ const content = existsSync(pnpmrcPath) ? readFileSync(pnpmrcPath, "utf8") : "";
317
319
  if (!content.includes("hoist-pattern[]=!@esbuild/*")) {
318
320
  const patch = [
319
321
  "",
@@ -323,8 +325,8 @@ function _patchNpmrcForEsbuild(cwd) {
323
325
  "hoist-pattern[]=!esbuild",
324
326
  "",
325
327
  ].join("\n");
326
- appendFileSync(npmrcPath, patch);
327
- info(".npmrc에 esbuild hoisting 차단 규칙을 추가했습니다.");
328
+ appendFileSync(pnpmrcPath, patch);
329
+ info(".pnpmrc에 esbuild hoisting 차단 규칙을 추가했습니다.");
328
330
  info("다음 pnpm install 시 영구 적용됩니다.");
329
331
  }
330
332
  return;
@@ -333,7 +335,7 @@ function _patchNpmrcForEsbuild(cwd) {
333
335
  if (parent === dir) break;
334
336
  dir = parent;
335
337
  }
336
- } catch { /* .npmrc 수정 실패 — 무시 (즉시 우회로 이번 실행은 문제 없음) */ }
338
+ } catch { /* .pnpmrc 수정 실패 — 무시 (즉시 우회로 이번 실행은 문제 없음) */ }
337
339
  }
338
340
 
339
341
  function findServerRoot() {
@@ -1197,7 +1199,7 @@ ${hasPrompt ? `
1197
1199
 
1198
1200
  if (!appId) {
1199
1201
  error("Cloud app not found — gencow.json이 없거나 appId가 설정되지 않았습니다.");
1200
- info(`${DIM}먼저 gencow deploy 를 실행하세요.${RESET}`);
1202
+ info(`${DIM}먼저 gencow dev 를 실행하세요.${RESET}`);
1201
1203
  info(`${DIM}로컬 서버에 seed하려면: gencow db:seed --local${RESET}`);
1202
1204
  log("");
1203
1205
  return;
@@ -1218,7 +1220,7 @@ ${hasPrompt ? `
1218
1220
  if (!statusRes || !statusRes.ok) {
1219
1221
  error(`Cloud app "${appId}" is not running`);
1220
1222
  info(`${DIM}Dashboard → Apps → ${appId} → Resume 으로 앱을 시작하세요.${RESET}`);
1221
- info(`${DIM}또는: gencow deploy배포 후 시도하세요.${RESET}`);
1223
+ info(`${DIM}또는: gencow dev 생성 후 시도하세요.${RESET}`);
1222
1224
  log("");
1223
1225
  return;
1224
1226
  }
@@ -1236,7 +1238,7 @@ ${hasPrompt ? `
1236
1238
  log(` ${DIM}export default async function seed(ctx) {${RESET}`);
1237
1239
  log(` ${DIM} await ctx.db.insert(tasks).values([...]);${RESET}`);
1238
1240
  log(` ${DIM}};${RESET}\n`);
1239
- info(`${DIM}After creating seed.ts: gencow deploy && gencow db:seed${RESET}`);
1241
+ info(`${DIM}After creating seed.ts: gencow dev 실행 gencow db:seed${RESET}`);
1240
1242
  } else if (!res.ok) {
1241
1243
  error(`Cloud seed failed: ${data.error || "Unknown error"}`);
1242
1244
  } else {
@@ -1555,7 +1557,7 @@ ${hasPrompt ? `
1555
1557
 
1556
1558
  if (!appId) {
1557
1559
  error("Cloud app not found — gencow.json이 없거나 appId가 설정되지 않았습니다.");
1558
- info(`${DIM}먼저 gencow deploy 를 실행하세요.${RESET}`);
1560
+ info(`${DIM}먼저 gencow dev 를 실행하세요.${RESET}`);
1559
1561
  info(`${DIM}로컬 DB에 push하려면: gencow db:push --local${RESET}`);
1560
1562
  log("");
1561
1563
  return;
@@ -1564,7 +1566,7 @@ ${hasPrompt ? `
1564
1566
  // ── Cloud 모드: Platform API를 통해 Cloud DB에 schema push ──
1565
1567
  const creds = requireCreds();
1566
1568
  log(`\n${BOLD}${CYAN}Gencow DB Push${RESET} ${DIM}(cloud: ${appId})${RESET}\n`);
1567
- warn("명령어 실행 전 먼저 gencow deploy 를 통해 최신 코드가 배포되어 있어야 합니다.");
1569
+ warn("명령어 실행 전 먼저 gencow dev 를 통해 최신 코드가 배포되어 있어야 합니다.");
1568
1570
  log("");
1569
1571
  info("Pushing schema.ts → cloud database...");
1570
1572
 
@@ -1805,10 +1807,11 @@ ${BOLD}BaaS commands (login required):${RESET}
1805
1807
  ${GREEN}login${RESET} Login to Gencow Platform ${DIM}(browser → token)${RESET}
1806
1808
  ${GREEN}logout${RESET} Clear credentials
1807
1809
  ${GREEN}whoami${RESET} Show current user info
1808
- ${GREEN}deploy${RESET} Bundle gencow/ and deploy to platform
1809
- ${DIM}--static [dir] Deploy static files (dist/, out/, build/)${RESET}
1810
- ${DIM}--no-backend Skip backend auto-deploy in --static mode${RESET}
1811
- ${DIM}--prod Deploy to production app (Pro+, auto-creates)${RESET}
1810
+ ${GREEN}static [dir]${RESET} Deploy static files to dev ${DIM}(dist/, out/, build/)${RESET}
1811
+ ${DIM}--no-backend Skip backend auto-deploy${RESET}
1812
+ ${DIM}--force, -f Skip dependency audit${RESET}
1813
+ ${GREEN}deploy${RESET} Deploy to production ${DIM}(Pro+ only)${RESET}
1814
+ ${DIM}--static [dir] Deploy static files to production${RESET}
1812
1815
  ${DIM}--rollback Rollback to previous deployment${RESET}
1813
1816
  ${DIM}--force, -f Skip dependency audit${RESET}
1814
1817
  ${GREEN}env list${RESET} List cloud env vars ${DIM}(--prod for production)${RESET}
@@ -1985,14 +1988,55 @@ ${BOLD}Examples:${RESET}
1985
1988
  }
1986
1989
  },
1987
1990
 
1988
- // ── deploy ────────────────────────────────────────────
1991
+ // ── static — dev 정적 파일 배포 (독립 명령어) ─────────
1992
+ async static(...staticArgs) {
1993
+ const creds = requireCreds();
1994
+
1995
+ let staticDir = null;
1996
+ let forceDeploy = false;
1997
+ let noBackend = false;
1998
+ let appId = null;
1999
+
2000
+ for (let i = 0; i < staticArgs.length; i++) {
2001
+ const a = staticArgs[i];
2002
+ if (a === "--force" || a === "-f") forceDeploy = true;
2003
+ else if (a === "--no-backend") noBackend = true;
2004
+ else if (a === "--app" || a === "-a") appId = staticArgs[++i];
2005
+ else if (!a.startsWith("-")) {
2006
+ staticDir = a;
2007
+ }
2008
+ }
2009
+
2010
+ // gencow.json에서 appId 로드
2011
+ const gencowJsonPath = resolve(process.cwd(), "gencow.json");
2012
+ if (!appId && existsSync(gencowJsonPath)) {
2013
+ const gencowJson = JSON.parse(readFileSync(gencowJsonPath, "utf8"));
2014
+ appId = gencowJson.appId || gencowJson.appName;
2015
+ }
2016
+
2017
+ // displayName
2018
+ let displayName = null;
2019
+ const configPath = resolve(process.cwd(), "gencow.config.ts");
2020
+ if (existsSync(configPath)) {
2021
+ const content = readFileSync(configPath, "utf8");
2022
+ const match = content.match(/name:\s*["']([^"']+)["']/);
2023
+ if (match) displayName = match[1];
2024
+ }
2025
+ if (!displayName) displayName = basename(process.cwd());
2026
+
2027
+ return await this._deployStatic(creds, appId, displayName, staticDir, gencowJsonPath, {
2028
+ forceDeploy, noBackend, envTarget: "dev",
2029
+ });
2030
+ },
2031
+
2032
+ // ── deploy — 프로덕션 배포 (Pro+ only) ───────────────
1989
2033
  async deploy(...deployArgs) {
1990
2034
  const creds = requireCreds();
1991
2035
 
1992
2036
  // gencow.json에서 앱 ID 확인 (자동 생성된 유니크 ID)
1993
2037
  let appId = null;
1994
2038
  let displayName = null;
1995
- let envTarget = "dev";
2039
+ let envTarget = "prod"; // v0.1.120: deploy = prod 기본값
1996
2040
  let staticDir = null; // --static 옵션
1997
2041
  let isStatic = false;
1998
2042
  let forceDeploy = false; // --force: skip dependency audit
@@ -2061,7 +2105,12 @@ ${BOLD}Examples:${RESET}
2061
2105
 
2062
2106
  for (let i = 0; i < deployArgs.length; i++) {
2063
2107
  const a = deployArgs[i];
2064
- if (a === "--prod") envTarget = "prod";
2108
+ if (a === "--prod") {
2109
+ // deprecated: deploy는 이미 prod 기본값
2110
+ warn(`${YELLOW}--prod 플래그는 더 이상 필요하지 않습니다.${RESET}`);
2111
+ info(`gencow deploy는 기본적으로 프로덕션에 배포합니다.`);
2112
+ envTarget = "prod";
2113
+ }
2065
2114
  else if (a === "--force" || a === "-f") forceDeploy = true;
2066
2115
  else if (a === "--no-backend") noBackend = true;
2067
2116
  else if (a === "--rollback") isRollback = true;
@@ -2080,13 +2129,16 @@ ${BOLD}Examples:${RESET}
2080
2129
  error(`알 수 없는 deploy 인자: "${a}"`);
2081
2130
  log("");
2082
2131
  info(`사용법: gencow deploy [옵션]`);
2083
- info(` gencow deploy 백엔드 배포`);
2084
- info(` gencow deploy --static 정적 파일 배포`);
2132
+ info(` gencow deploy 프로덕션 배포 (Pro+)`);
2133
+ info(` gencow deploy --static 프로덕션 정적 배포 (Pro+)`);
2085
2134
  info(` gencow deploy --rollback 이전 버전으로 롤백`);
2086
- info(` gencow deploy --prod 프로덕션 배포`);
2087
2135
  info(` gencow deploy logs 서버 로그 조회`);
2088
2136
  info(` gencow deploy status 앱 상태 확인`);
2089
2137
  info(` gencow deploy --force 의존성 감사 스킵`);
2138
+ log("");
2139
+ info(`💡 개발 환경 배포:`);
2140
+ info(` gencow dev 백엔드 실시간 배포`);
2141
+ info(` gencow static [dir] 정적 파일 배포`);
2090
2142
  process.exit(1);
2091
2143
  }
2092
2144
  }
@@ -2199,8 +2251,18 @@ ${BOLD}Examples:${RESET}
2199
2251
  if (!createProdRes.ok) {
2200
2252
  const errData = await createProdRes.json().catch(() => ({}));
2201
2253
  if (createProdRes.status === 403) {
2202
- error(errData.error || "Production deploys require Pro plan or higher.");
2203
- info("Run: gencow upgrade");
2254
+ log("");
2255
+ log(` ${RED}⛔ Production Deploy — Pro 플랜 이상 필요${RESET}`);
2256
+ log("");
2257
+ log(` ${DIM}gencow deploy는 프로덕션 환경에 배포하는 명령어입니다.${RESET}`);
2258
+ log("");
2259
+ log(` ${BOLD}💡 개발 환경 배포:${RESET}`);
2260
+ log(` ${GREEN}gencow dev${RESET} ${DIM}← 백엔드 실시간 배포 + 라이브 로그${RESET}`);
2261
+ log(` ${GREEN}gencow static dist/${RESET} ${DIM}← 정적 파일(dist/) 배포${RESET}`);
2262
+ log("");
2263
+ log(` ${BOLD}🚀 프로덕션 배포 잠금 해제:${RESET}`);
2264
+ log(` ${GREEN}gencow upgrade${RESET} ${DIM}← Pro 플랜으로 업그레이드${RESET}`);
2265
+ log("");
2204
2266
  } else {
2205
2267
  error(`Prod 앱 생성 실패: ${errData.error || createProdRes.statusText}`);
2206
2268
  }
@@ -2635,7 +2697,7 @@ ${BOLD}Examples:${RESET}
2635
2697
  if (!targetDir || !existsSync(resolve(process.cwd(), targetDir))) {
2636
2698
  error(`정적 파일 폴더를 찾을 수 없습니다.`);
2637
2699
  info(`자동 감지 순서: ${AUTO_DETECT.join(", ")}`);
2638
- info(`수동 지정: gencow deploy --static <dir>`);
2700
+ info(`수동 지정: gencow static <dir>`);
2639
2701
  process.exit(1);
2640
2702
  }
2641
2703
 
@@ -3069,7 +3131,7 @@ ${BOLD}Examples:${RESET}
3069
3131
 
3070
3132
  // --prod인데 prod 앱이 없는 경우
3071
3133
  if (envTarget === "prod" && appId && !appId.endsWith("-prod")) {
3072
- error("Prod 앱이 아직 없습니다. gencow deploy --prod를 먼저 실행하세요.");
3134
+ error("Prod 앱이 아직 없습니다. gencow deploy를 먼저 실행하세요.");
3073
3135
  return;
3074
3136
  }
3075
3137