gencow 0.1.85 → 0.1.87

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
@@ -1476,10 +1476,10 @@ ${BOLD}BaaS commands (login required):${RESET}
1476
1476
  ${DIM}--prod Deploy to production (confirmation required)${RESET}
1477
1477
  ${DIM}--name, -n Specify app name${RESET}
1478
1478
  ${DIM}--static [dir] Deploy static files (dist/, out/, build/)${RESET}
1479
- ${GREEN}env list${RESET} List cloud env vars ${DIM}(--local for local dev server)${RESET}
1480
- ${GREEN}env set K=V${RESET} Set cloud env var ${DIM}(--local for local)${RESET}
1481
- ${GREEN}env unset KEY${RESET} Remove cloud env var ${DIM}(--local for local)${RESET}
1482
- ${GREEN}env push${RESET} Push .env to cloud ${DIM}(--local for local)${RESET}
1479
+ ${GREEN}env list${RESET} List cloud env vars
1480
+ ${GREEN}env set K=V${RESET} Set cloud env var ${DIM}(hot-reload, no restart)${RESET}
1481
+ ${GREEN}env unset KEY${RESET} Remove cloud env var
1482
+ ${GREEN}env push${RESET} Push .env to cloud
1483
1483
  ${GREEN}domain set${RESET} Connect custom domain ${DIM}(myapp.com)${RESET}
1484
1484
  ${GREEN}domain status${RESET} Check domain DNS/TLS status
1485
1485
  ${GREEN}domain remove${RESET} Disconnect custom domain
@@ -3170,150 +3170,16 @@ process.exit(0);
3170
3170
  });
3171
3171
  },
3172
3172
 
3173
- // ── env — 환경변수 관리 (Cloud-First + --local) ─────────
3173
+ // ── env — 환경변수 관리 (Cloud only) ─────────
3174
3174
  async env(...envArgs) {
3175
- // ── --local 플래그 파싱 ──
3176
- const isLocal = envArgs.includes("--local");
3177
3175
  const filteredArgs = envArgs.filter(a => a !== "--local");
3178
3176
  const subcmd = filteredArgs[0] || "list";
3179
3177
 
3180
- // ── 로컬 모드: 기존 localhost 로직 ──
3181
- if (isLocal) {
3182
- const config = loadConfig();
3183
- const port = process.env.PORT || config.port || 5456;
3184
- const base = `http://localhost:${port}/_admin/settings/env-vars`;
3185
-
3186
- // ── local env list ──
3187
- if (subcmd === "list") {
3188
- try {
3189
- const res = await fetch(base);
3190
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
3191
- const vars = await res.json();
3192
-
3193
- log(`\n${BOLD}Environment Variables${RESET} ${DIM}(local, ${vars.length} total)${RESET}\n`);
3194
-
3195
- if (vars.length === 0) {
3196
- info("No environment variables configured.");
3197
- info(`Use ${GREEN}gencow env set --local KEY=VALUE${RESET} to add one.`);
3198
- } else {
3199
- const maxLen = Math.max(...vars.map(v => v.name.length), 4);
3200
- log(` ${DIM}${"NAME".padEnd(maxLen)} VALUE${RESET}`);
3201
- log(` ${DIM}${"─".repeat(maxLen)} ${"─".repeat(20)}${RESET}`);
3202
- for (const v of vars) {
3203
- log(` ${BOLD}${v.name.padEnd(maxLen)}${RESET} ${DIM}${v.maskedValue}${RESET}`);
3204
- }
3205
- }
3206
- log("");
3207
- } catch (e) {
3208
- error(`Failed to fetch env vars: ${e.message}`);
3209
- info(`Make sure the local dev server is running (gencow dev --local)`);
3210
- }
3211
- return;
3212
- }
3213
-
3214
- // ── local env set KEY=VALUE ──
3215
- if (subcmd === "set") {
3216
- const pairs = filteredArgs.slice(1);
3217
- if (pairs.length === 0) {
3218
- error("Usage: gencow env set --local KEY=VALUE [KEY2=VALUE2 ...]");
3219
- return;
3220
- }
3221
- for (const pair of pairs) {
3222
- const eqIdx = pair.indexOf("=");
3223
- if (eqIdx < 1) { error(`Invalid format: ${pair}. Use KEY=VALUE`); continue; }
3224
- const name = pair.slice(0, eqIdx).trim();
3225
- const value = pair.slice(eqIdx + 1).trim();
3226
- if (!name) { error("Key name cannot be empty"); continue; }
3227
- if (!value) { error(`Value for ${name} cannot be empty`); continue; }
3228
-
3229
- try {
3230
- const res = await fetch(base, {
3231
- method: "POST",
3232
- headers: { "Content-Type": "application/json" },
3233
- body: JSON.stringify({ name, value }),
3234
- });
3235
- if (!res.ok) {
3236
- const body = await res.json().catch(() => ({}));
3237
- throw new Error(body.error || `HTTP ${res.status}`);
3238
- }
3239
- success(`Set ${BOLD}${name}${RESET} ${DIM}(local)${RESET}`);
3240
- } catch (e) {
3241
- error(`Failed to set ${name}: ${e.message}`);
3242
- }
3243
- }
3244
- log(`\n ${DIM}⚠ Restart local server to apply changes${RESET}\n`);
3245
- return;
3246
- }
3247
-
3248
- // ── local env unset KEY ──
3249
- if (subcmd === "unset" || subcmd === "remove" || subcmd === "delete") {
3250
- const keys = filteredArgs.slice(1);
3251
- if (keys.length === 0) { error("Usage: gencow env unset --local KEY [KEY2 ...]"); return; }
3252
- for (const key of keys) {
3253
- try {
3254
- const res = await fetch(`${base}/${encodeURIComponent(key)}`, { method: "DELETE" });
3255
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
3256
- success(`Removed ${BOLD}${key}${RESET} ${DIM}(local)${RESET}`);
3257
- } catch (e) {
3258
- error(`Failed to remove ${key}: ${e.message}`);
3259
- }
3260
- }
3261
- log(`\n ${DIM}⚠ Restart local server to apply changes${RESET}\n`);
3262
- return;
3263
- }
3264
-
3265
- // ── local env push ──
3266
- if (subcmd === "push") {
3267
- const envPath = resolve(process.cwd(), ".env");
3268
- if (!existsSync(envPath)) { error("No .env file found in current directory"); return; }
3269
-
3270
- const content = readFileSync(envPath, "utf-8");
3271
- const pairs = [];
3272
- for (const line of content.split("\n")) {
3273
- const trimmed = line.trim();
3274
- if (!trimmed || trimmed.startsWith("#")) continue;
3275
- const eqIdx = trimmed.indexOf("=");
3276
- if (eqIdx < 1) continue;
3277
- const key = trimmed.slice(0, eqIdx).trim();
3278
- let val = trimmed.slice(eqIdx + 1).trim();
3279
- if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) {
3280
- val = val.slice(1, -1);
3281
- }
3282
- if (key && val) pairs.push({ key, val });
3283
- }
3284
-
3285
- if (pairs.length === 0) { warn("No valid KEY=VALUE pairs found in .env"); return; }
3286
-
3287
- log(`\n${BOLD}Pushing .env${RESET} ${DIM}(local, ${pairs.length} variables)${RESET}\n`);
3288
-
3289
- let ok = 0, fail = 0;
3290
- for (const { key, val } of pairs) {
3291
- try {
3292
- const res = await fetch(base, {
3293
- method: "POST",
3294
- headers: { "Content-Type": "application/json" },
3295
- body: JSON.stringify({ name: key, value: val }),
3296
- });
3297
- if (!res.ok) throw new Error(`HTTP ${res.status}`);
3298
- success(`${key}`);
3299
- ok++;
3300
- } catch {
3301
- error(`${key}`);
3302
- fail++;
3303
- }
3304
- }
3305
-
3306
- log(`\n ${GREEN}${ok} set${RESET}${fail > 0 ? `, ${RED}${fail} failed${RESET}` : ""}`);
3307
- log(` ${DIM}⚠ Restart local server to apply changes${RESET}\n`);
3308
- return;
3309
- }
3310
-
3311
- error(`Unknown env subcommand: ${subcmd}`);
3312
- log(`\n ${BOLD}Usage (local):${RESET}`);
3313
- log(` gencow env list --local List local env vars`);
3314
- log(` gencow env set --local K=V Set local variable(s)`);
3315
- log(` gencow env unset --local KEY Remove local variable(s)`);
3316
- log(` gencow env push --local Push .env to local server\n`);
3178
+ // --local 사용 .env 파일 사용 안내
3179
+ if (envArgs.includes("--local")) {
3180
+ warn(`--local flag has been removed.`);
3181
+ info(`For local development, use .env file directly.`);
3182
+ info(`Changes in .env are loaded automatically when running ${GREEN}gencow dev${RESET}.\n`);
3317
3183
  return;
3318
3184
  }
3319
3185
 
@@ -3331,7 +3197,7 @@ process.exit(0);
3331
3197
  if (!appId) {
3332
3198
  error("No gencow.json found. Cannot determine cloud app.");
3333
3199
  info(`Run ${GREEN}gencow deploy${RESET} first to create a cloud app.`);
3334
- info(`Or use ${GREEN}gencow env set --local KEY=VALUE${RESET} for local dev server.`);
3200
+ info(`Or use ${GREEN}.env${RESET} file for local development.`);
3335
3201
  return;
3336
3202
  }
3337
3203
 
@@ -3422,7 +3288,7 @@ process.exit(0);
3422
3288
  error(`Failed to remove ${key}: ${e.message}`);
3423
3289
  }
3424
3290
  }
3425
- log(`\n ${DIM} Restart app to apply changes${RESET}\n`);
3291
+ log(`\n ${DIM} Changes apply instantly no restart needed${RESET}\n`);
3426
3292
  return;
3427
3293
  }
3428
3294
 
@@ -3470,7 +3336,7 @@ process.exit(0);
3470
3336
  error(`Failed to push env vars: ${e.message}`);
3471
3337
  }
3472
3338
 
3473
- log(` ${DIM} Restart app to apply changes${RESET}\n`);
3339
+ log(` ${DIM} Changes apply instantly no restart needed${RESET}\n`);
3474
3340
  return;
3475
3341
  }
3476
3342
 
@@ -3480,8 +3346,7 @@ process.exit(0);
3480
3346
  log(` gencow env list List cloud env vars`);
3481
3347
  log(` gencow env set K=V Set cloud variable(s)`);
3482
3348
  log(` gencow env unset KEY Remove cloud variable(s)`);
3483
- log(` gencow env push Push .env to cloud`);
3484
- log(` ${DIM}Add --local for local dev server${RESET}\n`);
3349
+ log(` gencow env push Push .env to cloud\n`);
3485
3350
  },
3486
3351
 
3487
3352
  async platform() {
@@ -306,7 +306,7 @@ export function buildAiPrompt(apiObj, namespaces) {
306
306
  md += `- 환경변수는 \`npx gencow env set KEY=VALUE\`로 클라우드에 설정해. 즉시 반영 (재시작 불필요).\n`;
307
307
  md += `- process.env.KEY는 반드시 handler 내부에서 접근해 (모듈 상단 캐싱 시 hot-reload 안 됨).\n`;
308
308
  md += `- .env 파일은 로컬 개발 전용이야. 클라우드에는 gencow env push로 올려.\n`;
309
- md += `- 로컬 dev 서버에 설정하려면 \`gencow env set --local KEY=VALUE\`를 써.\n`;
309
+ md += `- 로컬 개발은 .env 파일 사용 (gencow dev가 자동 로드).\n`;
310
310
  md += `\n`;
311
311
  md += `⚠️ 데이터 격리 (보안 필수):\n`;
312
312
  md += `- 스키마에서 gencowTable()을 사용해. pgTable() 대신.\n`;
@@ -388,8 +388,7 @@ export function buildDeploySection() {
388
388
  md += `| \`gencow env list\` | 클라우드 환경변수 목록 |\n`;
389
389
  md += `| \`gencow env set KEY=VALUE\` | 클라우드 환경변수 추가/수정 (즉시 반영) |\n`;
390
390
  md += `| \`gencow env unset KEY\` | 클라우드 환경변수 삭제 (즉시 반영) |\n`;
391
- md += `| \`gencow env push\` | .env를 클라우드에 일괄 업로드 |\n`;
392
- md += `| \`--local\` 옵션 | 로컬 dev 서버 대상 (예: \`env set --local K=V\`) |\n\n`;
391
+ md += `| \`gencow env push\` | .env를 클라우드에 일괄 업로드 |\n\n`;
393
392
  md += `> ⚡ **Hot-Reload:** 환경변수는 앱 재시작 없이 즉시 반영됩니다.\n`;
394
393
  md += `> 단, \`process.env.KEY\`를 모듈 최상단에서 캐싱하면 반영되지 않습니다.\n`;
395
394
  md += `> 반드시 handler 내부에서 접근하세요:\n\n`;
@@ -502,7 +501,7 @@ export function buildDevTips() {
502
501
  md += `- 로컬 개발: \`gencow dev\` — 로컬 서버 시작\n`;
503
502
  md += `- 배포된 앱: \`https://{앱ID}.gencow.app\` — .env의 VITE_API_URL에 자동 설정됨\n`;
504
503
  md += `- Self-fetch: \`process.env.GENCOW_INTERNAL_URL\` — cron/mutation에서 다른 함수 호출 시 사용 (자동 설정)\n`;
505
- md += `- .env 파일은 로컬 전용. 클라우드에는 \`gencow env push\`로 올리세요. (로컬 서버는 \`--local\`)\n`;
504
+ md += `- .env 파일은 로컬 전용. 클라우드에는 \`gencow env push\`로 올리세요.\n`;
506
505
  return md;
507
506
  }
508
507
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gencow",
3
- "version": "0.1.85",
3
+ "version": "0.1.87",
4
4
  "description": "Gencow — AI Backend Engine",
5
5
  "type": "module",
6
6
  "bin": {