connectbase-client 6.0.1 → 6.3.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/CHANGELOG.md +230 -4
- package/README.md +130 -13
- package/dist/cli.js +250 -168
- package/dist/connect-base.umd.js +5 -5
- package/dist/index.d.mts +964 -22
- package/dist/index.d.ts +964 -22
- package/dist/index.js +629 -7
- package/dist/index.mjs +628 -7
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -41,7 +41,8 @@ __export(cli_exports, {
|
|
|
41
41
|
normalizeRelativePath: () => normalizeRelativePath,
|
|
42
42
|
parseArgs: () => parseArgs,
|
|
43
43
|
registerEndpointBinding: () => registerEndpointBinding,
|
|
44
|
-
sha256Hex: () => sha256Hex
|
|
44
|
+
sha256Hex: () => sha256Hex,
|
|
45
|
+
storageAdminHeaders: () => storageAdminHeaders
|
|
45
46
|
});
|
|
46
47
|
module.exports = __toCommonJS(cli_exports);
|
|
47
48
|
var crypto = __toESM(require("crypto"));
|
|
@@ -146,18 +147,7 @@ function handleTunnelError(msg, appId, localPort) {
|
|
|
146
147
|
}
|
|
147
148
|
|
|
148
149
|
// src/cli.ts
|
|
149
|
-
|
|
150
|
-
try {
|
|
151
|
-
const pkgPath = path2.join(__dirname, "..", "package.json");
|
|
152
|
-
if (fs2.existsSync(pkgPath)) {
|
|
153
|
-
const pkg = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"));
|
|
154
|
-
return pkg.version || "0.0.0";
|
|
155
|
-
}
|
|
156
|
-
} catch {
|
|
157
|
-
}
|
|
158
|
-
return "3.25.1";
|
|
159
|
-
}
|
|
160
|
-
var VERSION = getPackageVersion();
|
|
150
|
+
var VERSION = "6.3.0" ? "6.3.0" : getPackageVersion();
|
|
161
151
|
var DEFAULT_BASE_URL = "https://api.connectbase.world";
|
|
162
152
|
var colors = {
|
|
163
153
|
reset: "\x1B[0m",
|
|
@@ -295,6 +285,41 @@ function normalizeRelativePath(relativePath) {
|
|
|
295
285
|
if (!p.startsWith("/")) p = `/${p}`;
|
|
296
286
|
return p;
|
|
297
287
|
}
|
|
288
|
+
function storageAdminHeaders(config) {
|
|
289
|
+
const headers = {
|
|
290
|
+
"X-Public-Key": config.publicKey
|
|
291
|
+
};
|
|
292
|
+
if (config.secretKey) {
|
|
293
|
+
headers["X-User-Secret-Key"] = config.secretKey;
|
|
294
|
+
headers.Authorization = `Bearer ${config.secretKey}`;
|
|
295
|
+
return headers;
|
|
296
|
+
}
|
|
297
|
+
warn("Secret Key(cb_sk_)\uAC00 \uC124\uC815\uB3FC \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.");
|
|
298
|
+
log(
|
|
299
|
+
" Public Key \uB294 \uBE0C\uB77C\uC6B0\uC800 \uBC88\uB4E4\uC5D0 \uACF5\uAC1C\uB418\uB294 \uAC12\uC774\uB77C \uBC30\uD3EC/\uC2B9\uACA9\uC758 \uC790\uACA9\uC99D\uBA85\uC774 \uB420 \uC218 \uC5C6\uC5B4,"
|
|
300
|
+
);
|
|
301
|
+
log(" \uACE7 \uC11C\uBC84\uAC00 Secret Key \uB97C \uC694\uAD6C\uD569\uB2C8\uB2E4. \uC9C0\uAE08 \uC124\uC815\uD574 \uB450\uC138\uC694.");
|
|
302
|
+
log(
|
|
303
|
+
` ${colors.cyan}npx connectbase-client init${colors.reset} \uC774 \uBC1C\uAE09\uD574 .connectbaserc \uC5D0 \uC800\uC7A5\uD569\uB2C8\uB2E4.`
|
|
304
|
+
);
|
|
305
|
+
log(
|
|
306
|
+
` \uC774\uBBF8 \uD0A4\uAC00 \uC788\uB2E4\uBA74 ${colors.cyan}CONNECTBASE_SECRET_KEY${colors.reset} \uD658\uACBD\uBCC0\uC218\uB85C \uC9C0\uC815\uD558\uC138\uC694.`
|
|
307
|
+
);
|
|
308
|
+
log(" CI \uC5D0\uC11C\uB294 \uC800\uC7A5\uC18C \uC2DC\uD06C\uB9BF\uC5D0 \uB123\uC73C\uC138\uC694 \u2014 \uC800\uC7A5\uC18C\uC5D0 \uCEE4\uBC0B\uD558\uBA74 \uC548 \uB429\uB2C8\uB2E4.");
|
|
309
|
+
return headers;
|
|
310
|
+
}
|
|
311
|
+
function reportDeployAuthError(status, data) {
|
|
312
|
+
if (status !== 401) return false;
|
|
313
|
+
const detail = data?.error;
|
|
314
|
+
if (detail?.code !== "SECRET_KEY_REQUIRED") return false;
|
|
315
|
+
error(detail.message || "\uC774 \uC694\uCCAD\uC5D0\uB294 Secret Key \uAC00 \uD544\uC694\uD569\uB2C8\uB2E4.");
|
|
316
|
+
if (detail.suggestion) {
|
|
317
|
+
log("");
|
|
318
|
+
log(` ${detail.suggestion}`);
|
|
319
|
+
}
|
|
320
|
+
log("");
|
|
321
|
+
return true;
|
|
322
|
+
}
|
|
298
323
|
function loadConfig() {
|
|
299
324
|
const config = {
|
|
300
325
|
publicKey: process.env.CONNECTBASE_PUBLIC_KEY,
|
|
@@ -631,10 +656,10 @@ async function deploy(directory, config, isDev = false, deployOpts = {}) {
|
|
|
631
656
|
const pkg = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"));
|
|
632
657
|
if (pkg.scripts?.build) {
|
|
633
658
|
warn(
|
|
634
|
-
`\uBC30\uD3EC \uC804 \uBE4C\uB4DC\uB97C \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694: ${colors.cyan}npm run build && npx connectbase deploy${colors.reset}`
|
|
659
|
+
`\uBC30\uD3EC \uC804 \uBE4C\uB4DC\uB97C \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694: ${colors.cyan}npm run build && npx connectbase-client deploy${colors.reset}`
|
|
635
660
|
);
|
|
636
661
|
warn(
|
|
637
|
-
`\uB610\uB294 package.json\uC5D0 deploy \uC2A4\uD06C\uB9BD\uD2B8\uB97C \uB4F1\uB85D\uD558\uC138\uC694: ${colors.cyan}npx connectbase init${colors.reset}`
|
|
662
|
+
`\uB610\uB294 package.json\uC5D0 deploy \uC2A4\uD06C\uB9BD\uD2B8\uB97C \uB4F1\uB85D\uD558\uC138\uC694: ${colors.cyan}npx connectbase-client init${colors.reset}`
|
|
638
663
|
);
|
|
639
664
|
}
|
|
640
665
|
} catch {
|
|
@@ -666,11 +691,11 @@ async function deploy(directory, config, isDev = false, deployOpts = {}) {
|
|
|
666
691
|
const envLabel = isDev ? "QA" : "Prod";
|
|
667
692
|
if (isDev) {
|
|
668
693
|
warn(
|
|
669
|
-
`${colors.yellow}--dev \uB294 deprecated${colors.reset} \uC785\uB2C8\uB2E4 \u2014 QA \uCC44\uB110\uB85C \uBC30\uD3EC\uD569\uB2C8\uB2E4(production \uBBF8\uBC18\uC601). \uC774\uD6C4 ${colors.cyan}npx connectbase promote${colors.reset} \uB85C production \uC5D0 \uBC18\uC601\uD558\uC138\uC694. promote_mode=manual \uC774\uBA74 \uC77C\uBC18 ${colors.cyan}deploy${colors.reset} \uB3C4 \uB3D9\uC77C\uD558\uAC8C QA \uB85C \uBC30\uD3EC\uB429\uB2C8\uB2E4.`
|
|
694
|
+
`${colors.yellow}--dev \uB294 deprecated${colors.reset} \uC785\uB2C8\uB2E4 \u2014 QA \uCC44\uB110\uB85C \uBC30\uD3EC\uD569\uB2C8\uB2E4(production \uBBF8\uBC18\uC601). \uC774\uD6C4 ${colors.cyan}npx connectbase-client promote${colors.reset} \uB85C production \uC5D0 \uBC18\uC601\uD558\uC138\uC694. promote_mode=manual \uC774\uBA74 \uC77C\uBC18 ${colors.cyan}deploy${colors.reset} \uB3C4 \uB3D9\uC77C\uD558\uAC8C QA \uB85C \uBC30\uD3EC\uB429\uB2C8\uB2E4.`
|
|
670
695
|
);
|
|
671
696
|
}
|
|
672
697
|
const baseStorageUrl = `${config.baseUrl}/v1/public/storages/webs/${config.storageId}`;
|
|
673
|
-
const headers =
|
|
698
|
+
const headers = storageAdminHeaders(config);
|
|
674
699
|
const timeoutMs = computeDeployTimeout(totalSize, deployOpts.timeoutMs);
|
|
675
700
|
log(
|
|
676
701
|
`${colors.dim}\uD0C0\uC784\uC544\uC6C3: ${Math.round(timeoutMs / 1e3)}\uCD08${colors.reset}`
|
|
@@ -882,7 +907,7 @@ ${colors.cyan}Production: ${dep.production_url}${colors.reset}`
|
|
|
882
907
|
log(`
|
|
883
908
|
${colors.yellow}QA URL: ${dep.qa_url}${colors.reset}`);
|
|
884
909
|
log(
|
|
885
|
-
`${colors.dim}\uAC80\uC99D \uD6C4 \uBC18\uC601: ${colors.cyan}npx connectbase promote${colors.reset}
|
|
910
|
+
`${colors.dim}\uAC80\uC99D \uD6C4 \uBC18\uC601: ${colors.cyan}npx connectbase-client promote${colors.reset}
|
|
886
911
|
`
|
|
887
912
|
);
|
|
888
913
|
}
|
|
@@ -897,13 +922,15 @@ ${colors.cyan}URL: ${data.url}${colors.reset}
|
|
|
897
922
|
} else {
|
|
898
923
|
const data = response.data;
|
|
899
924
|
const errorMsg = typeof data === "object" && data !== null ? data.message || data.error || JSON.stringify(data) : typeof data === "string" ? data : `HTTP ${response.status}`;
|
|
900
|
-
|
|
925
|
+
if (!reportDeployAuthError(response.status, response.data)) {
|
|
926
|
+
error(`\uBC30\uD3EC \uC2E4\uD328: ${errorMsg}`);
|
|
927
|
+
}
|
|
901
928
|
process.exit(1);
|
|
902
929
|
}
|
|
903
930
|
}
|
|
904
931
|
async function promote(config, deploymentId) {
|
|
905
932
|
const baseStorageUrl = `${config.baseUrl}/v1/public/storages/webs/${config.storageId}`;
|
|
906
|
-
const headers =
|
|
933
|
+
const headers = storageAdminHeaders(config);
|
|
907
934
|
info(
|
|
908
935
|
deploymentId ? `release ${deploymentId} \uB97C production \uC73C\uB85C \uC2B9\uACA9\uD569\uB2C8\uB2E4...` : "\uCD5C\uC2E0 \uBC30\uD3EC\uB97C production \uC73C\uB85C \uC2B9\uACA9\uD569\uB2C8\uB2E4..."
|
|
909
936
|
);
|
|
@@ -925,7 +952,9 @@ async function promote(config, deploymentId) {
|
|
|
925
952
|
if (res.status < 200 || res.status >= 300) {
|
|
926
953
|
const data2 = res.data;
|
|
927
954
|
const msg = typeof data2 === "object" && data2 !== null ? data2.error || data2.message || JSON.stringify(data2) : `HTTP ${res.status}`;
|
|
928
|
-
|
|
955
|
+
if (!reportDeployAuthError(res.status, res.data)) {
|
|
956
|
+
error(`promote \uC2E4\uD328: ${msg}`);
|
|
957
|
+
}
|
|
929
958
|
process.exit(1);
|
|
930
959
|
}
|
|
931
960
|
const data = res.data;
|
|
@@ -938,7 +967,7 @@ ${colors.cyan}Production: ${data.production_url}${colors.reset}
|
|
|
938
967
|
}
|
|
939
968
|
async function listReleases(config) {
|
|
940
969
|
const baseStorageUrl = `${config.baseUrl}/v1/public/storages/webs/${config.storageId}`;
|
|
941
|
-
const headers =
|
|
970
|
+
const headers = storageAdminHeaders(config);
|
|
942
971
|
const res = await makeRequest(
|
|
943
972
|
`${baseStorageUrl}/deployments`,
|
|
944
973
|
"GET",
|
|
@@ -947,7 +976,9 @@ async function listReleases(config) {
|
|
|
947
976
|
if (res.status < 200 || res.status >= 300) {
|
|
948
977
|
const data2 = res.data;
|
|
949
978
|
const msg = typeof data2 === "object" && data2 !== null ? data2.error || data2.message || JSON.stringify(data2) : `HTTP ${res.status}`;
|
|
950
|
-
|
|
979
|
+
if (!reportDeployAuthError(res.status, res.data)) {
|
|
980
|
+
error(`\uBC30\uD3EC \uC774\uB825 \uC870\uD68C \uC2E4\uD328: ${msg}`);
|
|
981
|
+
}
|
|
951
982
|
process.exit(1);
|
|
952
983
|
}
|
|
953
984
|
const data = res.data;
|
|
@@ -977,7 +1008,7 @@ ${colors.cyan}\uBC30\uD3EC \uC774\uB825${colors.reset} (promote_mode: ${data.pro
|
|
|
977
1008
|
if (data.qa_url)
|
|
978
1009
|
log(`${colors.yellow}QA: ${data.qa_url}${colors.reset}`);
|
|
979
1010
|
log(
|
|
980
|
-
`${colors.dim}\uB864\uBC31: npx connectbase promote <deployment_id>${colors.reset}
|
|
1011
|
+
`${colors.dim}\uB864\uBC31: npx connectbase-client promote <deployment_id>${colors.reset}
|
|
981
1012
|
`
|
|
982
1013
|
);
|
|
983
1014
|
}
|
|
@@ -1044,7 +1075,9 @@ function getProjectRoot() {
|
|
|
1044
1075
|
const gitRoot = getGitRoot();
|
|
1045
1076
|
return gitRoot || process.cwd();
|
|
1046
1077
|
}
|
|
1047
|
-
|
|
1078
|
+
function consoleUrlFor(baseUrl) {
|
|
1079
|
+
return baseUrl.replace("api.", "");
|
|
1080
|
+
}
|
|
1048
1081
|
function openBrowser(url) {
|
|
1049
1082
|
const { exec } = require("child_process");
|
|
1050
1083
|
const platform2 = process.platform;
|
|
@@ -1059,10 +1092,10 @@ function openBrowser(url) {
|
|
|
1059
1092
|
exec(command, () => {
|
|
1060
1093
|
});
|
|
1061
1094
|
}
|
|
1062
|
-
async function browserAuthFlow() {
|
|
1095
|
+
async function browserAuthFlow(baseUrl = DEFAULT_BASE_URL) {
|
|
1063
1096
|
info("\uBE0C\uB77C\uC6B0\uC800 \uC778\uC99D \uC138\uC158\uC744 \uC2DC\uC791\uD569\uB2C8\uB2E4...");
|
|
1064
1097
|
const startRes = await makeRequest(
|
|
1065
|
-
`${
|
|
1098
|
+
`${baseUrl}/v1/public/cli-auth/start`,
|
|
1066
1099
|
"POST",
|
|
1067
1100
|
{}
|
|
1068
1101
|
);
|
|
@@ -1073,7 +1106,7 @@ async function browserAuthFlow() {
|
|
|
1073
1106
|
process.exit(1);
|
|
1074
1107
|
}
|
|
1075
1108
|
const { session_id } = startRes.data;
|
|
1076
|
-
const authUrl = `${
|
|
1109
|
+
const authUrl = `${consoleUrlFor(baseUrl)}/auth/cli-auth?session=${session_id}`;
|
|
1077
1110
|
log(`
|
|
1078
1111
|
${colors.cyan}\uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uB85C\uADF8\uC778\uD558\uC138\uC694:${colors.reset}`);
|
|
1079
1112
|
log(`${colors.dim}${authUrl}${colors.reset}
|
|
@@ -1093,7 +1126,7 @@ ${colors.cyan}\uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uB85C\uADF8\uC778\uD558\uC13
|
|
|
1093
1126
|
await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
|
|
1094
1127
|
try {
|
|
1095
1128
|
const pollRes = await makeRequest(
|
|
1096
|
-
`${
|
|
1129
|
+
`${baseUrl}/v1/public/cli-auth/poll/${session_id}`,
|
|
1097
1130
|
"GET",
|
|
1098
1131
|
{}
|
|
1099
1132
|
);
|
|
@@ -1140,10 +1173,73 @@ ${colors.cyan}\uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uB85C\uADF8\uC778\uD558\uC13
|
|
|
1140
1173
|
error("\uC778\uC99D \uC2DC\uAC04\uC774 \uCD08\uACFC\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.");
|
|
1141
1174
|
process.exit(1);
|
|
1142
1175
|
}
|
|
1176
|
+
async function promptForSecretKey(baseUrl = DEFAULT_BASE_URL) {
|
|
1177
|
+
log(`
|
|
1178
|
+
${colors.dim}\uC778\uC99D \uBC29\uC2DD\uC744 \uC120\uD0DD\uD558\uC138\uC694:${colors.reset}`);
|
|
1179
|
+
log(` ${colors.cyan}1${colors.reset}) Secret Key \uC9C1\uC811 \uC785\uB825 (cb_sk_...)`);
|
|
1180
|
+
log(` ${colors.cyan}2${colors.reset}) \uBE0C\uB77C\uC6B0\uC800 \uB85C\uADF8\uC778\uC73C\uB85C \uC790\uB3D9 \uBC1C\uAE09
|
|
1181
|
+
`);
|
|
1182
|
+
const authChoice = await prompt(
|
|
1183
|
+
`${colors.blue}?${colors.reset} \uC120\uD0DD (1/2): `
|
|
1184
|
+
);
|
|
1185
|
+
if (authChoice === "2") {
|
|
1186
|
+
try {
|
|
1187
|
+
return await browserAuthFlow(baseUrl);
|
|
1188
|
+
} catch (err) {
|
|
1189
|
+
error(`\uB124\uD2B8\uC6CC\uD06C \uC624\uB958: ${err instanceof Error ? err.message : err}`);
|
|
1190
|
+
info(
|
|
1191
|
+
"\uC778\uD130\uB137 \uC5F0\uACB0\uC744 \uD655\uC778\uD558\uAC70\uB098, Secret Key \uC9C1\uC811 \uC785\uB825(\uC635\uC158 1)\uC744 \uC2DC\uB3C4\uD558\uC138\uC694"
|
|
1192
|
+
);
|
|
1193
|
+
process.exit(1);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
log(
|
|
1197
|
+
`${colors.dim}Secret Key (cb_sk_): \uCF58\uC194 > \uD504\uB85C\uD544 > \uC2DC\uD06C\uB9BF \uD0A4 \uD0ED\uC5D0\uC11C \uBC1C\uAE09${colors.reset}
|
|
1198
|
+
`
|
|
1199
|
+
);
|
|
1200
|
+
const entered = await promptSecret(
|
|
1201
|
+
`${colors.blue}?${colors.reset} Secret Key: `
|
|
1202
|
+
);
|
|
1203
|
+
if (!entered) {
|
|
1204
|
+
error("Secret Key\uB294 \uD544\uC218\uC785\uB2C8\uB2E4");
|
|
1205
|
+
process.exit(1);
|
|
1206
|
+
}
|
|
1207
|
+
if (entered.startsWith("cb_pk_")) {
|
|
1208
|
+
error("Public Key\uAC00 \uC544\uB2CC Secret Key(cb_sk_)\uB97C \uC785\uB825\uD558\uC138\uC694");
|
|
1209
|
+
info("Secret Key\uB294 \uCF58\uC194 > \uD504\uB85C\uD544 > \uC2DC\uD06C\uB9BF \uD0A4 \uD0ED\uC5D0\uC11C \uC0DD\uC131\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4");
|
|
1210
|
+
process.exit(1);
|
|
1211
|
+
}
|
|
1212
|
+
if (!entered.startsWith("cb_sk_")) {
|
|
1213
|
+
error(
|
|
1214
|
+
"\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD0A4 \uD615\uC2DD\uC785\uB2C8\uB2E4. cb_sk_\uB85C \uC2DC\uC791\uD558\uB294 Secret Key\uB97C \uC785\uB825\uD558\uC138\uC694"
|
|
1215
|
+
);
|
|
1216
|
+
process.exit(1);
|
|
1217
|
+
}
|
|
1218
|
+
return entered;
|
|
1219
|
+
}
|
|
1220
|
+
function saveSecretKeyToRc(secretKey, dir = process.cwd()) {
|
|
1221
|
+
const rcPath = path2.join(dir, ".connectbaserc");
|
|
1222
|
+
let rcData = {};
|
|
1223
|
+
if (fs2.existsSync(rcPath)) {
|
|
1224
|
+
try {
|
|
1225
|
+
rcData = JSON.parse(fs2.readFileSync(rcPath, "utf-8"));
|
|
1226
|
+
} catch {
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
rcData.secretKey = secretKey;
|
|
1230
|
+
fs2.writeFileSync(rcPath, `${JSON.stringify(rcData, null, 2)}
|
|
1231
|
+
`);
|
|
1232
|
+
}
|
|
1233
|
+
async function fetchAppsWithSecretKey(baseUrl, secretKey) {
|
|
1234
|
+
return makeRequest(`${baseUrl}/v1/public/cli/apps`, "GET", {
|
|
1235
|
+
"X-Public-Key": secretKey
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1143
1238
|
async function init(config = {}, opts = {}) {
|
|
1144
1239
|
log(`
|
|
1145
1240
|
${colors.cyan}Connect Base \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654${colors.reset}
|
|
1146
1241
|
`);
|
|
1242
|
+
const baseUrl = config.baseUrl || DEFAULT_BASE_URL;
|
|
1147
1243
|
const cwd = process.cwd();
|
|
1148
1244
|
const projectRoot = getProjectRoot();
|
|
1149
1245
|
if (cwd !== projectRoot) {
|
|
@@ -1157,7 +1253,7 @@ ${colors.cyan}Connect Base \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654${colors.r
|
|
|
1157
1253
|
if (!process.stdin.isTTY && !nonInteractive) {
|
|
1158
1254
|
error("\uBE44\uB300\uD654\uD615 \uD658\uACBD\uC785\uB2C8\uB2E4. --yes \uD50C\uB798\uADF8\uC640 \uD568\uAED8 \uD544\uC694\uD55C \uAC12\uC744 \uC9C0\uC815\uD558\uC138\uC694");
|
|
1159
1255
|
log(
|
|
1160
|
-
`${colors.dim}\uC608: npx connectbase init --yes --secret-key cb_sk_... [--app <\uC571ID>] [--storage <\uC2A4\uD1A0\uB9AC\uC9C0ID>] [--deploy-dir ./dist]${colors.reset}`
|
|
1256
|
+
`${colors.dim}\uC608: npx connectbase-client init --yes --secret-key cb_sk_... [--app <\uC571ID>] [--storage <\uC2A4\uD1A0\uB9AC\uC9C0ID>] [--deploy-dir ./dist]${colors.reset}`
|
|
1161
1257
|
);
|
|
1162
1258
|
log(
|
|
1163
1259
|
`${colors.dim}Secret Key\uB294 CONNECTBASE_SECRET_KEY \uD658\uACBD\uBCC0\uC218\uB85C\uB3C4 \uC804\uB2EC\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4${colors.reset}`
|
|
@@ -1179,10 +1275,14 @@ ${colors.cyan}Connect Base \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654${colors.r
|
|
|
1179
1275
|
process.exit(1);
|
|
1180
1276
|
}
|
|
1181
1277
|
} else {
|
|
1278
|
+
info(
|
|
1279
|
+
".connectbaserc\uAC00 \uC774\uBBF8 \uC788\uC2B5\uB2C8\uB2E4 \u2014 \uAE30\uC874 \uC571/\uD0A4 \uC124\uC815\uC744 \uC7AC\uC0AC\uC6A9\uD574 \uB2E4\uC2DC \uAD6C\uC131\uD569\uB2C8\uB2E4"
|
|
1280
|
+
);
|
|
1182
1281
|
const overwrite = await prompt(
|
|
1183
|
-
`${colors.
|
|
1282
|
+
`${colors.blue}?${colors.reset} \uACC4\uC18D\uD560\uAE4C\uC694? (Y/n): `
|
|
1184
1283
|
);
|
|
1185
|
-
|
|
1284
|
+
const answer = overwrite.toLowerCase();
|
|
1285
|
+
if (answer === "n" || answer === "no") {
|
|
1186
1286
|
info("\uCD08\uAE30\uD654\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4");
|
|
1187
1287
|
return;
|
|
1188
1288
|
}
|
|
@@ -1196,57 +1296,14 @@ ${colors.cyan}Connect Base \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654${colors.r
|
|
|
1196
1296
|
);
|
|
1197
1297
|
process.exit(1);
|
|
1198
1298
|
}
|
|
1199
|
-
info("Secret Key \
|
|
1299
|
+
info("\uC800\uC7A5\uB41C Secret Key \uC0AC\uC6A9 (\uD50C\uB798\uADF8/\uD658\uACBD\uBCC0\uC218/.connectbaserc)");
|
|
1200
1300
|
} else if (nonInteractive) {
|
|
1201
1301
|
error(
|
|
1202
1302
|
"Secret Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4: --secret-key cb_sk_... \uB610\uB294 CONNECTBASE_SECRET_KEY \uD658\uACBD\uBCC0\uC218"
|
|
1203
1303
|
);
|
|
1204
1304
|
process.exit(1);
|
|
1205
1305
|
} else {
|
|
1206
|
-
|
|
1207
|
-
${colors.dim}\uC778\uC99D \uBC29\uC2DD\uC744 \uC120\uD0DD\uD558\uC138\uC694:${colors.reset}`);
|
|
1208
|
-
log(` ${colors.cyan}1${colors.reset}) Secret Key \uC9C1\uC811 \uC785\uB825 (cb_sk_...)`);
|
|
1209
|
-
log(` ${colors.cyan}2${colors.reset}) \uBE0C\uB77C\uC6B0\uC800 \uB85C\uADF8\uC778\uC73C\uB85C \uC790\uB3D9 \uBC1C\uAE09
|
|
1210
|
-
`);
|
|
1211
|
-
const authChoice = await prompt(
|
|
1212
|
-
`${colors.blue}?${colors.reset} \uC120\uD0DD (1/2): `
|
|
1213
|
-
);
|
|
1214
|
-
if (authChoice === "2") {
|
|
1215
|
-
try {
|
|
1216
|
-
secretKey = await browserAuthFlow();
|
|
1217
|
-
} catch (err) {
|
|
1218
|
-
error(`\uB124\uD2B8\uC6CC\uD06C \uC624\uB958: ${err instanceof Error ? err.message : err}`);
|
|
1219
|
-
info(
|
|
1220
|
-
"\uC778\uD130\uB137 \uC5F0\uACB0\uC744 \uD655\uC778\uD558\uAC70\uB098, Secret Key \uC9C1\uC811 \uC785\uB825(\uC635\uC158 1)\uC744 \uC2DC\uB3C4\uD558\uC138\uC694"
|
|
1221
|
-
);
|
|
1222
|
-
process.exit(1);
|
|
1223
|
-
}
|
|
1224
|
-
} else {
|
|
1225
|
-
log(
|
|
1226
|
-
`${colors.dim}Secret Key (cb_sk_): \uCF58\uC194 > \uD504\uB85C\uD544 > \uC2DC\uD06C\uB9BF \uD0A4 \uD0ED\uC5D0\uC11C \uBC1C\uAE09${colors.reset}
|
|
1227
|
-
`
|
|
1228
|
-
);
|
|
1229
|
-
secretKey = await promptSecret(
|
|
1230
|
-
`${colors.blue}?${colors.reset} Secret Key: `
|
|
1231
|
-
);
|
|
1232
|
-
if (!secretKey) {
|
|
1233
|
-
error("Secret Key\uB294 \uD544\uC218\uC785\uB2C8\uB2E4");
|
|
1234
|
-
process.exit(1);
|
|
1235
|
-
}
|
|
1236
|
-
if (secretKey.startsWith("cb_pk_")) {
|
|
1237
|
-
error("Public Key\uAC00 \uC544\uB2CC Secret Key(cb_sk_)\uB97C \uC785\uB825\uD558\uC138\uC694");
|
|
1238
|
-
info(
|
|
1239
|
-
"Secret Key\uB294 \uCF58\uC194 > \uD504\uB85C\uD544 > \uC2DC\uD06C\uB9BF \uD0A4 \uD0ED\uC5D0\uC11C \uC0DD\uC131\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4"
|
|
1240
|
-
);
|
|
1241
|
-
process.exit(1);
|
|
1242
|
-
}
|
|
1243
|
-
if (!secretKey.startsWith("cb_sk_")) {
|
|
1244
|
-
error(
|
|
1245
|
-
"\uC720\uD6A8\uD558\uC9C0 \uC54A\uC740 \uD0A4 \uD615\uC2DD\uC785\uB2C8\uB2E4. cb_sk_\uB85C \uC2DC\uC791\uD558\uB294 Secret Key\uB97C \uC785\uB825\uD558\uC138\uC694"
|
|
1246
|
-
);
|
|
1247
|
-
process.exit(1);
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1306
|
+
secretKey = await promptForSecretKey(baseUrl);
|
|
1250
1307
|
}
|
|
1251
1308
|
let appId = "";
|
|
1252
1309
|
let publicKey = "";
|
|
@@ -1262,7 +1319,7 @@ ${colors.dim}\uC778\uC99D \uBC29\uC2DD\uC744 \uC120\uD0DD\uD558\uC138\uC694:${co
|
|
|
1262
1319
|
const issuePublicKey = async (targetAppId) => {
|
|
1263
1320
|
info("Public Key \uC0DD\uC131 \uC911...");
|
|
1264
1321
|
const newKeyRes = await makeRequest(
|
|
1265
|
-
`${
|
|
1322
|
+
`${baseUrl}/v1/public/cli/apps/${targetAppId}/public-keys`,
|
|
1266
1323
|
"POST",
|
|
1267
1324
|
{ "X-Public-Key": secretKey },
|
|
1268
1325
|
JSON.stringify({})
|
|
@@ -1277,14 +1334,26 @@ ${colors.dim}\uC778\uC99D \uBC29\uC2DD\uC744 \uC120\uD0DD\uD558\uC138\uC694:${co
|
|
|
1277
1334
|
};
|
|
1278
1335
|
try {
|
|
1279
1336
|
info("\uC571 \uBAA9\uB85D \uC870\uD68C \uC911...");
|
|
1280
|
-
|
|
1281
|
-
`${DEFAULT_BASE_URL}/v1/public/cli/apps`,
|
|
1282
|
-
"GET",
|
|
1283
|
-
{ "X-Public-Key": secretKey }
|
|
1284
|
-
);
|
|
1337
|
+
let appsRes = await fetchAppsWithSecretKey(baseUrl, secretKey);
|
|
1285
1338
|
if (appsRes.status === 401) {
|
|
1286
|
-
|
|
1287
|
-
|
|
1339
|
+
warn("\uC800\uC7A5\uB41C Secret Key\uAC00 \uB354 \uC774\uC0C1 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 (\uB9CC\uB8CC \uB610\uB294 \uCDE8\uC18C)");
|
|
1340
|
+
if (nonInteractive) {
|
|
1341
|
+
error(
|
|
1342
|
+
"\uC0C8 Secret Key\uB97C --secret-key cb_sk_... \uB610\uB294 CONNECTBASE_SECRET_KEY \uB85C \uC804\uB2EC\uD558\uC138\uC694"
|
|
1343
|
+
);
|
|
1344
|
+
process.exit(1);
|
|
1345
|
+
}
|
|
1346
|
+
info("\uC0C8 Secret Key\uB85C \uB2E4\uC2DC \uC778\uC99D\uD569\uB2C8\uB2E4");
|
|
1347
|
+
secretKey = await promptForSecretKey(baseUrl);
|
|
1348
|
+
appsRes = await fetchAppsWithSecretKey(baseUrl, secretKey);
|
|
1349
|
+
if (appsRes.status === 401) {
|
|
1350
|
+
error(
|
|
1351
|
+
"\uC0C8\uB85C \uBC1B\uC740 Secret Key\uB3C4 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uCF58\uC194 > \uD504\uB85C\uD544 > \uC2DC\uD06C\uB9BF \uD0A4 \uD0ED\uC5D0\uC11C \uD0A4 \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uC138\uC694"
|
|
1352
|
+
);
|
|
1353
|
+
process.exit(1);
|
|
1354
|
+
}
|
|
1355
|
+
saveSecretKeyToRc(secretKey, cwd);
|
|
1356
|
+
success("\uC0C8 Secret Key\uB97C .connectbaserc\uC5D0 \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4");
|
|
1288
1357
|
}
|
|
1289
1358
|
if (appsRes.status !== 200) {
|
|
1290
1359
|
throw new Error(`HTTP ${appsRes.status}`);
|
|
@@ -1334,7 +1403,7 @@ ${colors.blue}?${colors.reset} \uC120\uD0DD (\uBC88\uD638): `
|
|
|
1334
1403
|
) || projectName;
|
|
1335
1404
|
info("\uC571 \uC0DD\uC131 \uC911...");
|
|
1336
1405
|
const createRes = await makeRequest(
|
|
1337
|
-
`${
|
|
1406
|
+
`${baseUrl}/v1/public/cli/apps`,
|
|
1338
1407
|
"POST",
|
|
1339
1408
|
{ "X-Public-Key": secretKey },
|
|
1340
1409
|
JSON.stringify({ name: appName })
|
|
@@ -1389,9 +1458,13 @@ ${colors.blue}?${colors.reset} \uC120\uD0DD (\uBC88\uD638): `
|
|
|
1389
1458
|
try {
|
|
1390
1459
|
info("\uC6F9 \uC2A4\uD1A0\uB9AC\uC9C0 \uC870\uD68C \uC911...");
|
|
1391
1460
|
const listRes = await makeRequest(
|
|
1392
|
-
`${
|
|
1461
|
+
`${baseUrl}/v1/public/storages/webs`,
|
|
1393
1462
|
"GET",
|
|
1394
|
-
{
|
|
1463
|
+
{
|
|
1464
|
+
"X-Public-Key": publicKeyForSdk,
|
|
1465
|
+
"X-User-Secret-Key": secretKey,
|
|
1466
|
+
Authorization: `Bearer ${secretKey}`
|
|
1467
|
+
}
|
|
1395
1468
|
);
|
|
1396
1469
|
if (listRes.status === 200) {
|
|
1397
1470
|
const listData = listRes.data;
|
|
@@ -1427,9 +1500,13 @@ ${colors.blue}?${colors.reset} \uC120\uD0DD (\uBC88\uD638): `
|
|
|
1427
1500
|
) || projectName;
|
|
1428
1501
|
info("\uC6F9 \uC2A4\uD1A0\uB9AC\uC9C0 \uC0DD\uC131 \uC911...");
|
|
1429
1502
|
const createRes = await makeRequest(
|
|
1430
|
-
`${
|
|
1503
|
+
`${baseUrl}/v1/public/storages/webs`,
|
|
1431
1504
|
"POST",
|
|
1432
|
-
{
|
|
1505
|
+
{
|
|
1506
|
+
"X-Public-Key": publicKeyForSdk,
|
|
1507
|
+
"X-User-Secret-Key": secretKey,
|
|
1508
|
+
Authorization: `Bearer ${secretKey}`
|
|
1509
|
+
},
|
|
1433
1510
|
JSON.stringify({ name })
|
|
1434
1511
|
);
|
|
1435
1512
|
if (createRes.status !== 200) {
|
|
@@ -1479,12 +1556,17 @@ ${colors.blue}?${colors.reset} \uC120\uD0DD (\uBC88\uD638): `
|
|
|
1479
1556
|
`);
|
|
1480
1557
|
success(".connectbaserc \uC0DD\uC131 \uC644\uB8CC");
|
|
1481
1558
|
addToGitignore(".connectbaserc");
|
|
1482
|
-
addDeployScript(deployDir);
|
|
1483
|
-
await setupClaudeCode(secretKey, projectRoot);
|
|
1559
|
+
const { needsInstall } = addDeployScript(deployDir);
|
|
1560
|
+
await setupClaudeCode(secretKey, projectRoot, baseUrl);
|
|
1484
1561
|
log(`
|
|
1485
1562
|
${colors.green}\uCD08\uAE30\uD654 \uC644\uB8CC!${colors.reset}
|
|
1486
1563
|
`);
|
|
1487
1564
|
log(`${colors.dim}\uBC30\uD3EC\uD558\uB824\uBA74:${colors.reset}`);
|
|
1565
|
+
if (needsInstall) {
|
|
1566
|
+
log(
|
|
1567
|
+
` ${colors.cyan}npm install${colors.reset} ${colors.dim}# connectbase-client (CLI \uD3EC\uD568) \uC124\uCE58${colors.reset}`
|
|
1568
|
+
);
|
|
1569
|
+
}
|
|
1488
1570
|
log(` ${colors.cyan}npm run deploy${colors.reset}`);
|
|
1489
1571
|
log(`
|
|
1490
1572
|
${colors.dim}Claude Code\uC5D0\uC11C MCP\uAC00 \uC790\uB3D9 \uC5F0\uACB0\uB429\uB2C8\uB2E4${colors.reset}
|
|
@@ -1539,31 +1621,46 @@ function addDeployScript(deployDir) {
|
|
|
1539
1621
|
const pkgPath = path2.join(process.cwd(), "package.json");
|
|
1540
1622
|
if (!fs2.existsSync(pkgPath)) {
|
|
1541
1623
|
warn("package.json\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4 deploy \uC2A4\uD06C\uB9BD\uD2B8\uB97C \uCD94\uAC00\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4");
|
|
1542
|
-
return;
|
|
1624
|
+
return { needsInstall: false };
|
|
1543
1625
|
}
|
|
1544
1626
|
try {
|
|
1545
1627
|
const pkg = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"));
|
|
1546
1628
|
if (!pkg.scripts) pkg.scripts = {};
|
|
1629
|
+
const declared = (name) => Boolean(pkg.dependencies?.[name] || pkg.devDependencies?.[name]);
|
|
1630
|
+
let needsInstall = false;
|
|
1631
|
+
if (!declared("connectbase-client")) {
|
|
1632
|
+
if (!pkg.devDependencies) pkg.devDependencies = {};
|
|
1633
|
+
pkg.devDependencies["connectbase-client"] = VERSION === "0.0.0" ? "latest" : `^${VERSION}`;
|
|
1634
|
+
needsInstall = true;
|
|
1635
|
+
}
|
|
1547
1636
|
if (pkg.scripts.deploy) {
|
|
1548
1637
|
info(
|
|
1549
1638
|
`package.json\uC5D0 \uC774\uBBF8 deploy \uC2A4\uD06C\uB9BD\uD2B8\uAC00 \uC788\uC2B5\uB2C8\uB2E4: "${pkg.scripts.deploy}"`
|
|
1550
1639
|
);
|
|
1551
|
-
|
|
1640
|
+
} else {
|
|
1641
|
+
const deployCmd = `connectbase deploy ${deployDir}`;
|
|
1642
|
+
pkg.scripts.deploy = pkg.scripts.build ? `npm run build && ${deployCmd}` : deployCmd;
|
|
1643
|
+
success("package.json\uC5D0 deploy \uC2A4\uD06C\uB9BD\uD2B8 \uCD94\uAC00 \uC644\uB8CC");
|
|
1552
1644
|
}
|
|
1553
|
-
const deployCmd = `connectbase deploy ${deployDir}`;
|
|
1554
|
-
pkg.scripts.deploy = pkg.scripts.build ? `${pkg.scripts.build} && ${deployCmd}` : deployCmd;
|
|
1555
1645
|
fs2.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
1556
1646
|
`);
|
|
1557
|
-
|
|
1647
|
+
if (needsInstall) {
|
|
1648
|
+
success(
|
|
1649
|
+
`package.json devDependencies\uC5D0 connectbase-client@${pkg.devDependencies["connectbase-client"]} \uCD94\uAC00 \uC644\uB8CC`
|
|
1650
|
+
);
|
|
1651
|
+
}
|
|
1652
|
+
return { needsInstall };
|
|
1558
1653
|
} catch {
|
|
1559
1654
|
warn("package.json \uC218\uC815\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4");
|
|
1655
|
+
return { needsInstall: false };
|
|
1560
1656
|
}
|
|
1561
1657
|
}
|
|
1562
1658
|
function getGitRoot() {
|
|
1563
1659
|
try {
|
|
1564
1660
|
const { execSync } = require("child_process");
|
|
1565
1661
|
return execSync("git rev-parse --show-toplevel", {
|
|
1566
|
-
encoding: "utf-8"
|
|
1662
|
+
encoding: "utf-8",
|
|
1663
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
1567
1664
|
}).trim();
|
|
1568
1665
|
} catch {
|
|
1569
1666
|
return null;
|
|
@@ -1665,6 +1762,7 @@ var LEGACY_DOC_FILES = [
|
|
|
1665
1762
|
];
|
|
1666
1763
|
async function downloadDocs(baseDir, opts = {}) {
|
|
1667
1764
|
const quiet = opts.quiet === true;
|
|
1765
|
+
const baseUrl = opts.baseUrl || DEFAULT_BASE_URL;
|
|
1668
1766
|
if (!baseDir) {
|
|
1669
1767
|
baseDir = getProjectRoot();
|
|
1670
1768
|
}
|
|
@@ -1686,7 +1784,7 @@ async function downloadDocs(baseDir, opts = {}) {
|
|
|
1686
1784
|
if (!quiet) info("SDK \uAC1C\uBC1C \uAC00\uC774\uB4DC \uB2E4\uC6B4\uB85C\uB4DC \uC911...");
|
|
1687
1785
|
try {
|
|
1688
1786
|
const res = await makeRequest(
|
|
1689
|
-
`${
|
|
1787
|
+
`${baseUrl}/v1/storages/webs/claude-md?template=rules&format=sections`,
|
|
1690
1788
|
"GET",
|
|
1691
1789
|
{}
|
|
1692
1790
|
);
|
|
@@ -1719,7 +1817,7 @@ async function downloadDocs(baseDir, opts = {}) {
|
|
|
1719
1817
|
}
|
|
1720
1818
|
return "unchanged";
|
|
1721
1819
|
}
|
|
1722
|
-
const stamp = `<!-- generated by connectbase-cli v${VERSION} (${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}) \u2014 \uC790\uB3D9 \uC0DD\uC131 \uD30C\uC77C\uC785\uB2C8\uB2E4. \uC9C1\uC811 \uC218\uC815\uD558\uC9C0 \uB9D0\uACE0 'npx connectbase update'\uB85C \uAC31\uC2E0\uD558\uC138\uC694 -->
|
|
1820
|
+
const stamp = `<!-- generated by connectbase-cli v${VERSION} (${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}) \u2014 \uC790\uB3D9 \uC0DD\uC131 \uD30C\uC77C\uC785\uB2C8\uB2E4. \uC9C1\uC811 \uC218\uC815\uD558\uC9C0 \uB9D0\uACE0 'npx connectbase-client update'\uB85C \uAC31\uC2E0\uD558\uC138\uC694 -->
|
|
1723
1821
|
|
|
1724
1822
|
`;
|
|
1725
1823
|
for (const section of sections) {
|
|
@@ -1799,7 +1897,7 @@ function updateRootClaudeMd(claudeMdPath, quiet = false) {
|
|
|
1799
1897
|
|
|
1800
1898
|
1. \uC704\uC5D0 import\uB41C project-rules.md\uC758 \uAE30\uB2A5 \uB9E4\uD551\uD45C\xB7\uBCF4\uC548 \uADDC\uCE59\uC744 \uB530\uB974\uC138\uC694
|
|
1801
1899
|
2. \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uAE30 \uC804 \`search_sdk_docs("\uD0A4\uC6CC\uB4DC")\`\uB85C SDK \uAD6C\uD604 \uBC29\uBC95\uC744 \uAC80\uC0C9\uD558\uACE0, \uAC80\uC0C9 \uACB0\uACFC\uC758 \uCF54\uB4DC \uD328\uD134\uC744 \uADF8\uB300\uB85C \uB530\uB974\uC138\uC694
|
|
1802
|
-
3. \`search_sdk_docs\` \uB3C4\uAD6C\uAC00 \uBCF4\uC774\uC9C0 \uC54A\uC73C\uBA74 MCP\uAC00 \uC5F0\uACB0\uB418\uC9C0 \uC54A\uC740 \uC0C1\uD0DC\uC785\uB2C8\uB2E4 \u2014 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \`npx connectbase mcp\` \uC2E4\uD589\uC744 \uC548\uB0B4\uD558\uC138\uC694 (Secret Key \uD544\uC694)
|
|
1900
|
+
3. \`search_sdk_docs\` \uB3C4\uAD6C\uAC00 \uBCF4\uC774\uC9C0 \uC54A\uC73C\uBA74 MCP\uAC00 \uC5F0\uACB0\uB418\uC9C0 \uC54A\uC740 \uC0C1\uD0DC\uC785\uB2C8\uB2E4 \u2014 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \`npx connectbase-client mcp\` \uC2E4\uD589\uC744 \uC548\uB0B4\uD558\uC138\uC694 (Secret Key \uD544\uC694)
|
|
1803
1901
|
${endMarker}`;
|
|
1804
1902
|
if (fs2.existsSync(claudeMdPath)) {
|
|
1805
1903
|
let content = fs2.readFileSync(claudeMdPath, "utf-8");
|
|
@@ -1835,7 +1933,7 @@ function createSubPackageClaudeMd(subClaudeMdPath, gitRoot, quiet = false) {
|
|
|
1835
1933
|
|
|
1836
1934
|
1. \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC758 \`${relPath}/.claude/docs/project-rules.md\`\uC758 \uAE30\uB2A5 \uB9E4\uD551\uD45C\xB7\uBCF4\uC548 \uADDC\uCE59\uC744 \uB530\uB974\uC138\uC694
|
|
1837
1935
|
2. \uCF54\uB4DC\uB97C \uC791\uC131\uD558\uAE30 \uC804 \`search_sdk_docs("\uD0A4\uC6CC\uB4DC")\`\uB85C SDK \uAD6C\uD604 \uBC29\uBC95\uC744 \uAC80\uC0C9\uD558\uC138\uC694
|
|
1838
|
-
3. \`search_sdk_docs\` \uB3C4\uAD6C\uAC00 \uBCF4\uC774\uC9C0 \uC54A\uC73C\uBA74 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \`npx connectbase mcp\` \uC2E4\uD589\uC744 \uC548\uB0B4\uD558\uC138\uC694
|
|
1936
|
+
3. \`search_sdk_docs\` \uB3C4\uAD6C\uAC00 \uBCF4\uC774\uC9C0 \uC54A\uC73C\uBA74 \uC0AC\uC6A9\uC790\uC5D0\uAC8C \`npx connectbase-client mcp\` \uC2E4\uD589\uC744 \uC548\uB0B4\uD558\uC138\uC694
|
|
1839
1937
|
${endMarker}`;
|
|
1840
1938
|
if (fs2.existsSync(subClaudeMdPath)) {
|
|
1841
1939
|
let content = fs2.readFileSync(subClaudeMdPath, "utf-8");
|
|
@@ -1863,7 +1961,7 @@ ${subBlock}
|
|
|
1863
1961
|
}
|
|
1864
1962
|
if (!quiet) success(`\uC11C\uBE0C \uD328\uD0A4\uC9C0 CLAUDE.md \uC0DD\uC131 \uC644\uB8CC: ${subClaudeMdPath}`);
|
|
1865
1963
|
}
|
|
1866
|
-
async function setupMcp(secretKey) {
|
|
1964
|
+
async function setupMcp(secretKey, baseUrl = DEFAULT_BASE_URL) {
|
|
1867
1965
|
const gitRoot = getGitRoot();
|
|
1868
1966
|
const root = gitRoot || process.cwd();
|
|
1869
1967
|
const monorepo = detectMonorepo(root);
|
|
@@ -1874,51 +1972,31 @@ async function setupMcp(secretKey) {
|
|
|
1874
1972
|
}
|
|
1875
1973
|
}
|
|
1876
1974
|
const mcpConfigPath = path2.join(root, ".mcp.json");
|
|
1975
|
+
if (secretKey) {
|
|
1976
|
+
const check = await fetchAppsWithSecretKey(baseUrl, secretKey).catch(
|
|
1977
|
+
() => null
|
|
1978
|
+
);
|
|
1979
|
+
if (check?.status === 401) {
|
|
1980
|
+
warn("\uC800\uC7A5\uB41C Secret Key\uAC00 \uB354 \uC774\uC0C1 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 (\uB9CC\uB8CC \uB610\uB294 \uCDE8\uC18C)");
|
|
1981
|
+
secretKey = "";
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1877
1984
|
if (!secretKey) {
|
|
1878
1985
|
if (!process.stdin.isTTY) {
|
|
1879
|
-
error("Secret Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4 (\uBE44\uB300\uD654\uD615 \uD658\uACBD)");
|
|
1986
|
+
error("\uC720\uD6A8\uD55C Secret Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4 (\uBE44\uB300\uD654\uD615 \uD658\uACBD)");
|
|
1880
1987
|
log(`${colors.dim}\uB2E4\uC74C \uC911 \uD558\uB098\uB85C \uD0A4\uB97C \uC804\uB2EC\uD558\uC138\uC694:${colors.reset}`);
|
|
1881
1988
|
log(
|
|
1882
|
-
` ${colors.cyan}npx connectbase mcp --secret-key cb_sk_...${colors.reset}`
|
|
1989
|
+
` ${colors.cyan}npx connectbase-client mcp --secret-key cb_sk_...${colors.reset}`
|
|
1883
1990
|
);
|
|
1884
1991
|
log(
|
|
1885
|
-
` ${colors.cyan}CONNECTBASE_SECRET_KEY=cb_sk_... npx connectbase mcp${colors.reset}`
|
|
1992
|
+
` ${colors.cyan}CONNECTBASE_SECRET_KEY=cb_sk_... npx connectbase-client mcp${colors.reset}`
|
|
1886
1993
|
);
|
|
1887
1994
|
process.exit(1);
|
|
1888
1995
|
}
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
`);
|
|
1894
|
-
const authChoice = await prompt(
|
|
1895
|
-
`${colors.blue}?${colors.reset} \uC120\uD0DD (1/2): `
|
|
1896
|
-
);
|
|
1897
|
-
if (authChoice === "2") {
|
|
1898
|
-
try {
|
|
1899
|
-
secretKey = await browserAuthFlow();
|
|
1900
|
-
const skRcPath = path2.join(process.cwd(), ".connectbaserc");
|
|
1901
|
-
let rcData = {};
|
|
1902
|
-
if (fs2.existsSync(skRcPath)) {
|
|
1903
|
-
try {
|
|
1904
|
-
rcData = JSON.parse(fs2.readFileSync(skRcPath, "utf-8"));
|
|
1905
|
-
} catch {
|
|
1906
|
-
}
|
|
1907
|
-
}
|
|
1908
|
-
rcData.secretKey = secretKey;
|
|
1909
|
-
fs2.writeFileSync(skRcPath, `${JSON.stringify(rcData, null, 2)}
|
|
1910
|
-
`);
|
|
1911
|
-
addToGitignore(".connectbaserc", root);
|
|
1912
|
-
success("Secret Key \uBC1C\uAE09 \uBC0F \uC800\uC7A5 \uC644\uB8CC");
|
|
1913
|
-
} catch (err) {
|
|
1914
|
-
error(`\uC778\uC99D \uC2E4\uD328: ${err instanceof Error ? err.message : err}`);
|
|
1915
|
-
process.exit(1);
|
|
1916
|
-
}
|
|
1917
|
-
} else {
|
|
1918
|
-
secretKey = await promptSecret(
|
|
1919
|
-
`${colors.blue}?${colors.reset} Secret Key: `
|
|
1920
|
-
);
|
|
1921
|
-
}
|
|
1996
|
+
secretKey = await promptForSecretKey(baseUrl);
|
|
1997
|
+
saveSecretKeyToRc(secretKey);
|
|
1998
|
+
addToGitignore(".connectbaserc", root);
|
|
1999
|
+
success("Secret Key\uB97C .connectbaserc\uC5D0 \uC800\uC7A5\uD588\uC2B5\uB2C8\uB2E4");
|
|
1922
2000
|
}
|
|
1923
2001
|
const mcpEntry = {
|
|
1924
2002
|
type: "http",
|
|
@@ -1957,10 +2035,10 @@ ${colors.dim}\uC778\uC99D \uBC29\uC2DD\uC744 \uC120\uD0DD\uD558\uC138\uC694:${co
|
|
|
1957
2035
|
${colors.dim}Claude Code\uC5D0\uC11C ConnectBase MCP \uB3C4\uAD6C\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.${colors.reset}`
|
|
1958
2036
|
);
|
|
1959
2037
|
}
|
|
1960
|
-
async function setupClaudeCode(secretKey, projectRoot) {
|
|
2038
|
+
async function setupClaudeCode(secretKey, projectRoot, baseUrl = DEFAULT_BASE_URL) {
|
|
1961
2039
|
const root = projectRoot || getProjectRoot();
|
|
1962
|
-
await downloadDocs(root);
|
|
1963
|
-
await setupMcp(secretKey);
|
|
2040
|
+
await downloadDocs(root, { baseUrl });
|
|
2041
|
+
await setupMcp(secretKey, baseUrl);
|
|
1964
2042
|
}
|
|
1965
2043
|
async function fetchLatestVersion(packageName) {
|
|
1966
2044
|
try {
|
|
@@ -2068,7 +2146,7 @@ ${colors.cyan}ConnectBase Update${colors.reset}
|
|
|
2068
2146
|
if (!opts.skipDocs) {
|
|
2069
2147
|
log("");
|
|
2070
2148
|
info("SDK \uBB38\uC11C \uC5C5\uB370\uC774\uD2B8 \uC911...");
|
|
2071
|
-
await downloadDocs(projectRoot);
|
|
2149
|
+
await downloadDocs(projectRoot, { baseUrl: config.baseUrl });
|
|
2072
2150
|
}
|
|
2073
2151
|
if (!opts.skipMcp) {
|
|
2074
2152
|
log("");
|
|
@@ -2153,15 +2231,15 @@ function setupMonorepoRoot(projectRoot, monorepo) {
|
|
|
2153
2231
|
if (!pkg.scripts) pkg.scripts = {};
|
|
2154
2232
|
let changed = false;
|
|
2155
2233
|
if (!pkg.scripts["cb:update"]) {
|
|
2156
|
-
pkg.scripts["cb:update"] = "npx connectbase update";
|
|
2234
|
+
pkg.scripts["cb:update"] = "npx connectbase-client update";
|
|
2157
2235
|
changed = true;
|
|
2158
2236
|
}
|
|
2159
2237
|
if (!pkg.scripts["cb:docs"]) {
|
|
2160
|
-
pkg.scripts["cb:docs"] = "npx connectbase docs";
|
|
2238
|
+
pkg.scripts["cb:docs"] = "npx connectbase-client docs";
|
|
2161
2239
|
changed = true;
|
|
2162
2240
|
}
|
|
2163
2241
|
if (!pkg.scripts["cb:mcp"]) {
|
|
2164
|
-
pkg.scripts["cb:mcp"] = "npx connectbase mcp";
|
|
2242
|
+
pkg.scripts["cb:mcp"] = "npx connectbase-client mcp";
|
|
2165
2243
|
changed = true;
|
|
2166
2244
|
}
|
|
2167
2245
|
if (changed) {
|
|
@@ -3353,7 +3431,7 @@ function showHelp() {
|
|
|
3353
3431
|
${colors.cyan}connectbase${colors.reset} - Connect Base SDK & CLI
|
|
3354
3432
|
|
|
3355
3433
|
${colors.yellow}\uC0AC\uC6A9\uBC95:${colors.reset}
|
|
3356
|
-
npx connectbase <command> [options]
|
|
3434
|
+
npx connectbase-client <command> [options]
|
|
3357
3435
|
|
|
3358
3436
|
${colors.yellow}\uBA85\uB839\uC5B4:${colors.reset}
|
|
3359
3437
|
init \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654 (\uC571 \uC0DD\uC131, MCP \uC124\uC815, SDK \uBB38\uC11C \uB2E4\uC6B4\uB85C\uB4DC)
|
|
@@ -3401,40 +3479,40 @@ ${colors.yellow}\uC635\uC158:${colors.reset}
|
|
|
3401
3479
|
|
|
3402
3480
|
${colors.yellow}\uBE60\uB978 \uC2DC\uC791:${colors.reset}
|
|
3403
3481
|
${colors.dim}# 1. \uCD08\uAE30\uD654 (\uCD5C\uCD08 1\uD68C)${colors.reset}
|
|
3404
|
-
npx connectbase init
|
|
3482
|
+
npx connectbase-client init
|
|
3405
3483
|
|
|
3406
3484
|
${colors.dim}# 1-1. \uBE44\uB300\uD654\uD615 \uCD08\uAE30\uD654 (CI/AI \uC5D0\uC774\uC804\uD2B8)${colors.reset}
|
|
3407
|
-
npx connectbase init --yes --secret-key cb_sk_...
|
|
3485
|
+
npx connectbase-client init --yes --secret-key cb_sk_...
|
|
3408
3486
|
|
|
3409
3487
|
${colors.dim}# 2. SDK \uC804\uCCB4 \uC5C5\uB370\uC774\uD2B8 (\uBC84\uC804 \uCCB4\uD06C + \uBB38\uC11C + MCP)${colors.reset}
|
|
3410
|
-
npx connectbase update
|
|
3488
|
+
npx connectbase-client update
|
|
3411
3489
|
|
|
3412
3490
|
${colors.dim}# 2-1. \uBAA8\uB178\uB808\uD3EC \uB8E8\uD2B8\uC5D0 \uD3B8\uC758 \uC2A4\uD06C\uB9BD\uD2B8 \uC124\uCE58${colors.reset}
|
|
3413
|
-
npx connectbase update --setup-root
|
|
3491
|
+
npx connectbase-client update --setup-root
|
|
3414
3492
|
|
|
3415
3493
|
${colors.dim}# 3. SDK \uBB38\uC11C\uB9CC \uC5C5\uB370\uC774\uD2B8${colors.reset}
|
|
3416
|
-
npx connectbase docs
|
|
3494
|
+
npx connectbase-client docs
|
|
3417
3495
|
|
|
3418
3496
|
${colors.dim}# 4. MCP \uC11C\uBC84 \uC124\uC815${colors.reset}
|
|
3419
|
-
npx connectbase mcp
|
|
3497
|
+
npx connectbase-client mcp
|
|
3420
3498
|
|
|
3421
3499
|
${colors.dim}# 4. Prod \uBC30\uD3EC${colors.reset}
|
|
3422
3500
|
npm run deploy
|
|
3423
3501
|
|
|
3424
3502
|
${colors.dim}# 4-1. QA \uC6CC\uD06C\uD50C\uB85C\uC6B0 (\uC2E0\uADDC \uC2A4\uD1A0\uB9AC\uC9C0 \uAE30\uBCF8 promote_mode=manual)${colors.reset}
|
|
3425
|
-
npx connectbase deploy ./dist ${colors.dim}# QA \uD658\uACBD\uC5D0\uB9CC \uBC30\uD3EC${colors.reset}
|
|
3426
|
-
npx connectbase releases ${colors.dim}# \uBC30\uD3EC \uC774\uB825 \uD655\uC778${colors.reset}
|
|
3427
|
-
npx connectbase promote ${colors.dim}# QA \uAC80\uC99D \uD6C4 production \uBC18\uC601${colors.reset}
|
|
3503
|
+
npx connectbase-client deploy ./dist ${colors.dim}# QA \uD658\uACBD\uC5D0\uB9CC \uBC30\uD3EC${colors.reset}
|
|
3504
|
+
npx connectbase-client releases ${colors.dim}# \uBC30\uD3EC \uC774\uB825 \uD655\uC778${colors.reset}
|
|
3505
|
+
npx connectbase-client promote ${colors.dim}# QA \uAC80\uC99D \uD6C4 production \uBC18\uC601${colors.reset}
|
|
3428
3506
|
|
|
3429
3507
|
${colors.dim}# 5. \uD130\uB110 (\uAE30\uBCF8)${colors.reset}
|
|
3430
|
-
npx connectbase tunnel 3000
|
|
3508
|
+
npx connectbase-client tunnel 3000
|
|
3431
3509
|
|
|
3432
3510
|
${colors.dim}# 6. \uD130\uB110 (GPU \uC11C\uBC84 \uB4F1 \uAE34 \uC751\uB2F5 \uC2DC)${colors.reset}
|
|
3433
|
-
npx connectbase tunnel 7860 --timeout 300 --max-body 50
|
|
3511
|
+
npx connectbase-client tunnel 7860 --timeout 300 --max-body 50
|
|
3434
3512
|
|
|
3435
3513
|
${colors.yellow}\uD658\uACBD\uBCC0\uC218:${colors.reset}
|
|
3436
3514
|
CONNECTBASE_PUBLIC_KEY Public Key (cb_pk_*)
|
|
3437
|
-
CONNECTBASE_SECRET_KEY Secret Key (cb_sk_
|
|
3515
|
+
CONNECTBASE_SECRET_KEY Secret Key (cb_sk_*) \u2014 \uBC30\uD3EC/\uC2B9\uACA9/\uD130\uB110\uC5D0 \uD544\uC218
|
|
3438
3516
|
CONNECTBASE_PUBLIC_KEY (deprecated) \uB808\uAC70\uC2DC \u2014 publicKey \uB610\uB294 secretKey \uB85C \uC0AC\uC6A9
|
|
3439
3517
|
CONNECTBASE_STORAGE_ID \uC2A4\uD1A0\uB9AC\uC9C0 ID
|
|
3440
3518
|
CONNECTBASE_BASE_URL \uC11C\uBC84 URL
|
|
@@ -3544,20 +3622,20 @@ async function main() {
|
|
|
3544
3622
|
setupRoot: parsed.options.setupRoot === "true"
|
|
3545
3623
|
});
|
|
3546
3624
|
} else if (parsed.command === "docs") {
|
|
3547
|
-
await downloadDocs();
|
|
3625
|
+
await downloadDocs(void 0, { baseUrl: config.baseUrl });
|
|
3548
3626
|
} else if (parsed.command === "mcp") {
|
|
3549
|
-
await setupMcp(config.secretKey);
|
|
3627
|
+
await setupMcp(config.secretKey, config.baseUrl);
|
|
3550
3628
|
} else if (parsed.command === "deploy") {
|
|
3551
3629
|
const directory = parsed.args[0] || fileConfig.deployDir || ".";
|
|
3552
3630
|
if (!config.publicKey) {
|
|
3553
3631
|
error(
|
|
3554
|
-
'Public Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -k \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694'
|
|
3632
|
+
'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'
|
|
3555
3633
|
);
|
|
3556
3634
|
process.exit(1);
|
|
3557
3635
|
}
|
|
3558
3636
|
if (!config.storageId) {
|
|
3559
3637
|
error(
|
|
3560
|
-
'\uC2A4\uD1A0\uB9AC\uC9C0 ID\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -s \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694'
|
|
3638
|
+
'\uC2A4\uD1A0\uB9AC\uC9C0 ID\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase-client init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -s \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694'
|
|
3561
3639
|
);
|
|
3562
3640
|
process.exit(1);
|
|
3563
3641
|
}
|
|
@@ -3578,7 +3656,10 @@ async function main() {
|
|
|
3578
3656
|
if (fs2.existsSync(
|
|
3579
3657
|
path2.join(docsRoot, ".claude", "docs", DOCS_MANIFEST_FILE)
|
|
3580
3658
|
)) {
|
|
3581
|
-
const refreshed = await downloadDocs(docsRoot, {
|
|
3659
|
+
const refreshed = await downloadDocs(docsRoot, {
|
|
3660
|
+
quiet: true,
|
|
3661
|
+
baseUrl: config.baseUrl
|
|
3662
|
+
});
|
|
3582
3663
|
if (refreshed === "updated") {
|
|
3583
3664
|
info("SDK \uBB38\uC11C\uAC00 \uC0C8 \uBC84\uC804\uC73C\uB85C \uAC31\uC2E0\uB418\uC5C8\uC2B5\uB2C8\uB2E4 (.claude/docs/)");
|
|
3584
3665
|
}
|
|
@@ -3589,13 +3670,13 @@ async function main() {
|
|
|
3589
3670
|
} else if (parsed.command === "promote" || parsed.command === "releases") {
|
|
3590
3671
|
if (!config.publicKey) {
|
|
3591
3672
|
error(
|
|
3592
|
-
'Public Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -k \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694'
|
|
3673
|
+
'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'
|
|
3593
3674
|
);
|
|
3594
3675
|
process.exit(1);
|
|
3595
3676
|
}
|
|
3596
3677
|
if (!config.storageId) {
|
|
3597
3678
|
error(
|
|
3598
|
-
'\uC2A4\uD1A0\uB9AC\uC9C0 ID\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -s \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694'
|
|
3679
|
+
'\uC2A4\uD1A0\uB9AC\uC9C0 ID\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. "npx connectbase-client init"\uC73C\uB85C \uC124\uC815\uD558\uAC70\uB098 -s \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uC138\uC694'
|
|
3599
3680
|
);
|
|
3600
3681
|
process.exit(1);
|
|
3601
3682
|
}
|
|
@@ -3607,7 +3688,7 @@ async function main() {
|
|
|
3607
3688
|
} else if (parsed.command === "tunnel") {
|
|
3608
3689
|
const portStr = parsed.args[0];
|
|
3609
3690
|
if (!portStr) {
|
|
3610
|
-
error("\uD3EC\uD2B8 \uBC88\uD638\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. \uC608: npx connectbase tunnel 8084");
|
|
3691
|
+
error("\uD3EC\uD2B8 \uBC88\uD638\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. \uC608: npx connectbase-client tunnel 8084");
|
|
3611
3692
|
process.exit(1);
|
|
3612
3693
|
}
|
|
3613
3694
|
const port = parseInt(portStr, 10);
|
|
@@ -3672,5 +3753,6 @@ main().catch((err) => {
|
|
|
3672
3753
|
normalizeRelativePath,
|
|
3673
3754
|
parseArgs,
|
|
3674
3755
|
registerEndpointBinding,
|
|
3675
|
-
sha256Hex
|
|
3756
|
+
sha256Hex,
|
|
3757
|
+
storageAdminHeaders
|
|
3676
3758
|
});
|