connectbase-client 0.10.13 → 0.11.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/cli.js CHANGED
@@ -113,6 +113,8 @@ var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
113
113
  ]);
114
114
  function loadConfig() {
115
115
  const config = {
116
+ publicKey: process.env.CONNECTBASE_PUBLIC_KEY ?? process.env.CONNECTBASE_API_KEY,
117
+ secretKey: process.env.CONNECTBASE_SECRET_KEY,
116
118
  apiKey: process.env.CONNECTBASE_API_KEY,
117
119
  storageId: process.env.CONNECTBASE_STORAGE_ID,
118
120
  baseUrl: process.env.CONNECTBASE_BASE_URL || DEFAULT_BASE_URL
@@ -121,8 +123,16 @@ function loadConfig() {
121
123
  if (fs.existsSync(rcPath)) {
122
124
  try {
123
125
  const rcContent = JSON.parse(fs.readFileSync(rcPath, "utf-8"));
124
- if (rcContent.apiKey) config.apiKey = rcContent.apiKey;
126
+ if (rcContent.publicKey) config.publicKey = rcContent.publicKey;
125
127
  if (rcContent.secretKey) config.secretKey = rcContent.secretKey;
128
+ if (rcContent.apiKey && !config.publicKey && !config.secretKey) {
129
+ if (rcContent.apiKey.startsWith("cb_sk_")) {
130
+ config.secretKey = rcContent.apiKey;
131
+ } else {
132
+ config.publicKey = rcContent.apiKey;
133
+ }
134
+ }
135
+ if (rcContent.apiKey) config.apiKey = rcContent.apiKey;
126
136
  if (rcContent.storageId) config.storageId = rcContent.storageId;
127
137
  if (rcContent.baseUrl) config.baseUrl = rcContent.baseUrl;
128
138
  if (rcContent.deployDir) config.deployDir = rcContent.deployDir;
@@ -256,7 +266,7 @@ async function deploy(directory, config, isDev = false) {
256
266
  url,
257
267
  "POST",
258
268
  {
259
- "X-API-Key": config.apiKey
269
+ "X-Public-Key": config.publicKey ?? config.apiKey
260
270
  },
261
271
  JSON.stringify({
262
272
  files: files.map((f) => ({
@@ -496,7 +506,7 @@ ${colors.dim}\uC778\uC99D \uBC29\uC2DD\uC744 \uC120\uD0DD\uD558\uC138\uC694:${co
496
506
  const appsRes = await makeRequest(
497
507
  `${DEFAULT_BASE_URL}/v1/public/cli/apps`,
498
508
  "GET",
499
- { "X-API-Key": secretKey }
509
+ { "X-Public-Key": secretKey }
500
510
  );
501
511
  if (appsRes.status === 401) {
502
512
  error("Secret Key\uAC00 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uCF58\uC194\uC5D0\uC11C \uD0A4\uB97C \uD655\uC778\uD558\uC138\uC694");
@@ -525,7 +535,7 @@ ${colors.blue}?${colors.reset} \uC120\uD0DD (\uBC88\uD638): `);
525
535
  const newKeyRes = await makeRequest(
526
536
  `${DEFAULT_BASE_URL}/v1/public/cli/apps/${appId}/api-keys/public`,
527
537
  "POST",
528
- { "X-API-Key": secretKey },
538
+ { "X-Public-Key": secretKey },
529
539
  JSON.stringify({})
530
540
  );
531
541
  if (newKeyRes.status === 201) {
@@ -544,7 +554,7 @@ ${colors.blue}?${colors.reset} \uC120\uD0DD (\uBC88\uD638): `);
544
554
  const createRes = await makeRequest(
545
555
  `${DEFAULT_BASE_URL}/v1/public/cli/apps`,
546
556
  "POST",
547
- { "X-API-Key": secretKey },
557
+ { "X-Public-Key": secretKey },
548
558
  JSON.stringify({ name: appName })
549
559
  );
550
560
  if (createRes.status === 402) {
@@ -574,14 +584,14 @@ ${colors.blue}?${colors.reset} \uC120\uD0DD (\uBC88\uD638): `);
574
584
  process.exit(1);
575
585
  }
576
586
  }
577
- const apiKeyForSdk = publicKey || secretKey;
587
+ const publicKeyForSdk = publicKey || secretKey;
578
588
  let storageId = "";
579
589
  try {
580
590
  info("\uC6F9 \uC2A4\uD1A0\uB9AC\uC9C0 \uC870\uD68C \uC911...");
581
591
  const listRes = await makeRequest(
582
592
  `${DEFAULT_BASE_URL}/v1/public/storages/webs`,
583
593
  "GET",
584
- { "X-API-Key": apiKeyForSdk }
594
+ { "X-Public-Key": publicKeyForSdk }
585
595
  );
586
596
  if (listRes.status === 200) {
587
597
  const listData = listRes.data;
@@ -608,7 +618,7 @@ ${colors.blue}?${colors.reset} \uC120\uD0DD (\uBC88\uD638): `);
608
618
  const createRes = await makeRequest(
609
619
  `${DEFAULT_BASE_URL}/v1/public/storages/webs`,
610
620
  "POST",
611
- { "X-API-Key": apiKeyForSdk },
621
+ { "X-Public-Key": publicKeyForSdk },
612
622
  JSON.stringify({ name })
613
623
  );
614
624
  if (createRes.status !== 200) {
@@ -635,7 +645,7 @@ ${colors.blue}?${colors.reset} \uC120\uD0DD (\uBC88\uD638): `);
635
645
  const defaultDir = detectBuildDir();
636
646
  const deployDir = await prompt(`${colors.blue}?${colors.reset} \uBC30\uD3EC \uB514\uB809\uD1A0\uB9AC (${defaultDir}): `) || defaultDir;
637
647
  const config = {
638
- apiKey: publicKey || "",
648
+ publicKey: publicKey || "",
639
649
  storageId,
640
650
  deployDir
641
651
  };
@@ -646,7 +656,7 @@ ${colors.blue}?${colors.reset} \uC120\uD0DD (\uBC88\uD638): `);
646
656
  success(".connectbaserc \uC0DD\uC131 \uC644\uB8CC");
647
657
  addToGitignore(".connectbaserc");
648
658
  addDeployScript(deployDir);
649
- await setupClaudeCode(apiKeyForSdk, secretKey, projectRoot);
659
+ await setupClaudeCode(publicKeyForSdk, secretKey, projectRoot);
650
660
  log(`
651
661
  ${colors.green}\uCD08\uAE30\uD654 \uC644\uB8CC!${colors.reset}
652
662
  `);
@@ -751,7 +761,7 @@ function detectMonorepo(gitRoot) {
751
761
  }
752
762
  return result;
753
763
  }
754
- async function downloadDocs(apiKey, templates, baseDir) {
764
+ async function downloadDocs(publicKey, templates, baseDir) {
755
765
  if (!baseDir) {
756
766
  baseDir = getProjectRoot();
757
767
  }
@@ -775,7 +785,7 @@ async function downloadDocs(apiKey, templates, baseDir) {
775
785
  try {
776
786
  const templateParam = templates.join(",");
777
787
  const res = await makeRequest(
778
- `${DEFAULT_BASE_URL}/v1/storages/webs/claude-md?template=${encodeURIComponent(templateParam)}&format=sections&api_key=${encodeURIComponent(apiKey)}`,
788
+ `${DEFAULT_BASE_URL}/v1/storages/webs/claude-md?template=${encodeURIComponent(templateParam)}&format=sections&public_key=${encodeURIComponent(publicKey)}`,
779
789
  "GET",
780
790
  {}
781
791
  );
@@ -955,9 +965,9 @@ ${colors.dim}\uC778\uC99D \uBC29\uC2DD\uC744 \uC120\uD0DD\uD558\uC138\uC694:${co
955
965
  log(`
956
966
  ${colors.dim}Claude Code\uC5D0\uC11C ConnectBase MCP \uB3C4\uAD6C\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.${colors.reset}`);
957
967
  }
958
- async function setupClaudeCode(apiKey, secretKey, projectRoot) {
968
+ async function setupClaudeCode(publicKey, secretKey, projectRoot) {
959
969
  const root = projectRoot || getProjectRoot();
960
- await downloadDocs(apiKey, void 0, root);
970
+ await downloadDocs(publicKey, void 0, root);
961
971
  await setupMcp(secretKey);
962
972
  }
963
973
  function createWsTextFrame(payload) {
@@ -1074,7 +1084,7 @@ function getTunnelServerUrl(baseUrl) {
1074
1084
  }
1075
1085
  return baseUrl.replace(/:\d+/, ":8090");
1076
1086
  }
1077
- async function resolveAppForTunnel(apiKey, baseUrl, appIdOption) {
1087
+ async function resolveAppForTunnel(secretKey, baseUrl, appIdOption) {
1078
1088
  if (appIdOption) {
1079
1089
  return appIdOption;
1080
1090
  }
@@ -1084,7 +1094,7 @@ async function resolveAppForTunnel(apiKey, baseUrl, appIdOption) {
1084
1094
  const appsRes = await makeRequest(
1085
1095
  `${baseUrl}/v1/public/cli/apps`,
1086
1096
  "GET",
1087
- { "X-API-Key": apiKey }
1097
+ { "X-Public-Key": secretKey }
1088
1098
  );
1089
1099
  if (appsRes.status === 401) {
1090
1100
  error("Secret Key\uAC00 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uCF58\uC194\uC5D0\uC11C \uD0A4\uB97C \uD655\uC778\uD558\uC138\uC694");
@@ -1125,7 +1135,7 @@ ${colors.blue}?${colors.reset} \uC571 \uC120\uD0DD (\uBC88\uD638): `);
1125
1135
  const createRes = await makeRequest(
1126
1136
  `${baseUrl}/v1/public/cli/apps`,
1127
1137
  "POST",
1128
- { "X-API-Key": apiKey },
1138
+ { "X-Public-Key": secretKey },
1129
1139
  JSON.stringify({ name: appName })
1130
1140
  );
1131
1141
  if (createRes.status === 402) {
@@ -1142,7 +1152,7 @@ ${colors.blue}?${colors.reset} \uC571 \uC120\uD0DD (\uBC88\uD638): `);
1142
1152
  return createData.app_id;
1143
1153
  }
1144
1154
  async function startTunnel(port, config, tunnelOpts) {
1145
- const tunnelKey = config.secretKey || (config.apiKey?.startsWith("cb_sk_") ? config.apiKey : "");
1155
+ let tunnelKey = config.secretKey || (config.apiKey?.startsWith("cb_sk_") ? config.apiKey : "");
1146
1156
  if (!tunnelKey) {
1147
1157
  info("Secret Key\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. \uBE0C\uB77C\uC6B0\uC800 \uB85C\uADF8\uC778\uC73C\uB85C \uBC1C\uAE09\uD569\uB2C8\uB2E4...");
1148
1158
  try {
@@ -1159,14 +1169,15 @@ async function startTunnel(port, config, tunnelOpts) {
1159
1169
  fs.writeFileSync(rcPath2, JSON.stringify(rcData, null, 2) + "\n");
1160
1170
  addToGitignore(".connectbaserc");
1161
1171
  success("Secret Key \uBC1C\uAE09 \uBC0F \uC800\uC7A5 \uC644\uB8CC");
1162
- config.apiKey = sk;
1172
+ tunnelKey = sk;
1173
+ config.secretKey = sk;
1163
1174
  } catch (err) {
1164
1175
  error(`\uC778\uC99D \uC2E4\uD328: ${err instanceof Error ? err.message : err}`);
1165
1176
  info("-k \uC635\uC158\uC73C\uB85C Secret Key\uB97C \uC9C1\uC811 \uC804\uB2EC\uD560 \uC218\uB3C4 \uC788\uC2B5\uB2C8\uB2E4");
1166
1177
  process.exit(1);
1167
1178
  }
1168
1179
  } else {
1169
- config.apiKey = tunnelKey;
1180
+ config.secretKey = tunnelKey;
1170
1181
  }
1171
1182
  const rcPath = path.join(process.cwd(), ".connectbaserc");
1172
1183
  let savedAppId = tunnelOpts?.appId || "";
@@ -1177,7 +1188,7 @@ async function startTunnel(port, config, tunnelOpts) {
1177
1188
  } catch {
1178
1189
  }
1179
1190
  }
1180
- const appId = await resolveAppForTunnel(config.apiKey, config.baseUrl, savedAppId);
1191
+ const appId = await resolveAppForTunnel(tunnelKey, config.baseUrl, savedAppId);
1181
1192
  try {
1182
1193
  let rcData = {};
1183
1194
  if (fs.existsSync(rcPath)) {
@@ -1195,7 +1206,7 @@ async function startTunnel(port, config, tunnelOpts) {
1195
1206
  const tunnelServerUrl = getTunnelServerUrl(config.baseUrl);
1196
1207
  const parsedUrl = new URL(tunnelServerUrl);
1197
1208
  const isHttps = parsedUrl.protocol === "https:";
1198
- let wsPath = `/v1/tunnel/connect?app_id=${encodeURIComponent(appId)}`;
1209
+ let wsPath = `/v1/tunnel/connect?app_id=${encodeURIComponent(appId)}&local_port=${port}`;
1199
1210
  if (tunnelOpts?.timeout) {
1200
1211
  wsPath += `&timeout=${tunnelOpts.timeout}`;
1201
1212
  }
@@ -1242,7 +1253,7 @@ ${colors.cyan}ConnectBase Tunnel${colors.reset}`);
1242
1253
  "Connection": "Upgrade",
1243
1254
  "Sec-WebSocket-Key": wsKey,
1244
1255
  "Sec-WebSocket-Version": "13",
1245
- "Authorization": `Bearer ${config.apiKey}`
1256
+ "Authorization": `Bearer ${config.secretKey ?? config.apiKey}`
1246
1257
  }
1247
1258
  };
1248
1259
  const req = lib.request(reqOptions);
@@ -1519,13 +1530,16 @@ ${colors.yellow}\uBE60\uB978 \uC2DC\uC791:${colors.reset}
1519
1530
  npx connectbase tunnel 7860 --timeout 300 --max-body 50
1520
1531
 
1521
1532
  ${colors.yellow}\uD658\uACBD\uBCC0\uC218:${colors.reset}
1522
- CONNECTBASE_API_KEY API Key
1533
+ CONNECTBASE_PUBLIC_KEY Public Key (cb_pk_*)
1534
+ CONNECTBASE_SECRET_KEY Secret Key (cb_sk_*, \uD130\uB110\uC6A9)
1535
+ CONNECTBASE_API_KEY (deprecated) \uB808\uAC70\uC2DC \u2014 publicKey \uB610\uB294 secretKey \uB85C \uC0AC\uC6A9
1523
1536
  CONNECTBASE_STORAGE_ID \uC2A4\uD1A0\uB9AC\uC9C0 ID
1524
1537
  CONNECTBASE_BASE_URL \uC11C\uBC84 URL
1525
1538
 
1526
1539
  ${colors.yellow}\uC124\uC815 \uD30C\uC77C (.connectbaserc):${colors.reset}
1527
1540
  {
1528
- "apiKey": "your-api-key",
1541
+ "publicKey": "cb_pk_...",
1542
+ "secretKey": "cb_sk_...",
1529
1543
  "storageId": "your-storage-id",
1530
1544
  "deployDir": "./dist"
1531
1545
  }
@@ -1541,8 +1555,10 @@ function parseArgs(args) {
1541
1555
  const arg = args[i];
1542
1556
  if (arg === "-s" || arg === "--storage") {
1543
1557
  result.options.storageId = args[++i];
1544
- } else if (arg === "-k" || arg === "--api-key") {
1545
- result.options.apiKey = args[++i];
1558
+ } else if (arg === "-k" || arg === "--public-key" || arg === "--api-key") {
1559
+ result.options.publicKey = args[++i];
1560
+ } else if (arg === "--secret-key") {
1561
+ result.options.secretKey = args[++i];
1546
1562
  } else if (arg === "-u" || arg === "--base-url") {
1547
1563
  result.options.baseUrl = args[++i];
1548
1564
  } else if (arg === "-t" || arg === "--timeout") {
@@ -1580,28 +1596,30 @@ async function main() {
1580
1596
  }
1581
1597
  const fileConfig = loadConfig();
1582
1598
  const config = {
1583
- apiKey: parsed.options.apiKey || fileConfig.apiKey,
1599
+ publicKey: parsed.options.publicKey || fileConfig.publicKey,
1600
+ secretKey: parsed.options.secretKey || fileConfig.secretKey,
1601
+ apiKey: fileConfig.apiKey,
1584
1602
  storageId: parsed.options.storageId || fileConfig.storageId,
1585
1603
  baseUrl: parsed.options.baseUrl || fileConfig.baseUrl || DEFAULT_BASE_URL
1586
1604
  };
1587
1605
  if (parsed.command === "init") {
1588
1606
  await init();
1589
1607
  } else if (parsed.command === "docs") {
1590
- let docsApiKey = config.apiKey;
1591
- if (!docsApiKey) {
1592
- docsApiKey = await prompt(`${colors.blue}?${colors.reset} API Key: `);
1593
- if (!docsApiKey) {
1594
- error("API Key\uB294 \uD544\uC218\uC785\uB2C8\uB2E4");
1608
+ let docsPublicKey = config.publicKey ?? config.apiKey;
1609
+ if (!docsPublicKey) {
1610
+ docsPublicKey = await prompt(`${colors.blue}?${colors.reset} Public Key: `);
1611
+ if (!docsPublicKey) {
1612
+ error("Public Key\uB294 \uD544\uC218\uC785\uB2C8\uB2E4");
1595
1613
  process.exit(1);
1596
1614
  }
1597
1615
  }
1598
- await downloadDocs(docsApiKey);
1616
+ await downloadDocs(docsPublicKey);
1599
1617
  } else if (parsed.command === "mcp") {
1600
1618
  await setupMcp();
1601
1619
  } else if (parsed.command === "deploy") {
1602
1620
  const directory = parsed.args[0] || fileConfig.deployDir || ".";
1603
- if (!config.apiKey) {
1604
- error('API Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase-client init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -k \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694');
1621
+ if (!config.publicKey && !config.apiKey) {
1622
+ error('Public Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase-client init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -k \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694');
1605
1623
  process.exit(1);
1606
1624
  }
1607
1625
  if (!config.storageId) {