connectbase-client 0.1.5 → 0.1.6
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/README.md +52 -40
- package/dist/cli.js +119 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -57,77 +57,87 @@ const state = await gameClient.createRoom({
|
|
|
57
57
|
|
|
58
58
|
Deploy your web application to Connect Base Web Storage with a single command.
|
|
59
59
|
|
|
60
|
-
###
|
|
60
|
+
### Quick Start
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
|
-
#
|
|
64
|
-
npx connectbase-client
|
|
63
|
+
# 1. Initialize (one-time setup)
|
|
64
|
+
npx connectbase-client init
|
|
65
|
+
|
|
66
|
+
# 2. Deploy
|
|
67
|
+
npm run deploy
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The `init` command will:
|
|
71
|
+
- Ask for your API Key and Storage ID
|
|
72
|
+
- Create a `.connectbaserc` config file
|
|
73
|
+
- Add `.connectbaserc` to `.gitignore`
|
|
74
|
+
- Add a `deploy` script to `package.json`
|
|
65
75
|
|
|
66
|
-
|
|
67
|
-
|
|
76
|
+
### Commands
|
|
77
|
+
|
|
78
|
+
| Command | Description |
|
|
79
|
+
|---------|-------------|
|
|
80
|
+
| `init` | Interactive project setup (creates config, adds deploy script) |
|
|
81
|
+
| `deploy <dir>` | Deploy files to web storage |
|
|
82
|
+
|
|
83
|
+
### Manual Usage
|
|
84
|
+
|
|
85
|
+
If you prefer not to use `init`, you can pass options directly:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npx connectbase-client deploy ./dist -s <storage-id> -k <api-key>
|
|
68
89
|
```
|
|
69
90
|
|
|
70
91
|
### Options
|
|
71
92
|
|
|
72
93
|
| Option | Alias | Description |
|
|
73
94
|
|--------|-------|-------------|
|
|
74
|
-
| `--storage <id>` | `-s` | Storage ID
|
|
75
|
-
| `--api-key <key>` | `-k` | API Key
|
|
95
|
+
| `--storage <id>` | `-s` | Storage ID |
|
|
96
|
+
| `--api-key <key>` | `-k` | API Key |
|
|
76
97
|
| `--base-url <url>` | `-u` | Custom server URL |
|
|
77
98
|
| `--help` | `-h` | Show help |
|
|
78
99
|
| `--version` | `-v` | Show version |
|
|
79
100
|
|
|
80
|
-
### Environment Variables
|
|
81
|
-
|
|
82
|
-
You can set credentials via environment variables:
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
export CONNECTBASE_API_KEY=your-api-key
|
|
86
|
-
export CONNECTBASE_STORAGE_ID=your-storage-id
|
|
87
|
-
|
|
88
|
-
# Then deploy without options
|
|
89
|
-
npx connectbase-client deploy ./dist
|
|
90
|
-
```
|
|
91
|
-
|
|
92
101
|
### Configuration File
|
|
93
102
|
|
|
94
|
-
|
|
103
|
+
The `init` command creates `.connectbaserc` automatically. You can also create it manually:
|
|
95
104
|
|
|
96
105
|
```json
|
|
97
106
|
{
|
|
98
107
|
"apiKey": "your-api-key",
|
|
99
|
-
"storageId": "your-storage-id"
|
|
108
|
+
"storageId": "your-storage-id",
|
|
109
|
+
"deployDir": "./dist"
|
|
100
110
|
}
|
|
101
111
|
```
|
|
102
112
|
|
|
103
|
-
|
|
113
|
+
### Environment Variables
|
|
104
114
|
|
|
105
115
|
```bash
|
|
116
|
+
export CONNECTBASE_API_KEY=your-api-key
|
|
117
|
+
export CONNECTBASE_STORAGE_ID=your-storage-id
|
|
106
118
|
npx connectbase-client deploy ./dist
|
|
107
119
|
```
|
|
108
120
|
|
|
109
|
-
###
|
|
121
|
+
### Requirements
|
|
110
122
|
|
|
111
|
-
|
|
123
|
+
- `index.html` must exist in the root of the deploy directory
|
|
124
|
+
- Supported file types: `.html`, `.css`, `.js`, `.json`, `.svg`, `.png`, `.jpg`, `.gif`, `.webp`, `.woff`, `.woff2`, `.ttf`, `.mp3`, `.mp4`, `.pdf`, `.wasm`, etc.
|
|
112
125
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
"deploy": "connectbase-client deploy ./dist"
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
```
|
|
126
|
+
### SPA Mode
|
|
127
|
+
|
|
128
|
+
Web Storage supports SPA (Single Page Application) mode, which is **enabled by default**. When enabled, requests to non-existent paths return `index.html` instead of 404, allowing client-side routers (React Router, Vue Router, etc.) to handle routing.
|
|
120
129
|
|
|
121
|
-
|
|
130
|
+
You can toggle SPA mode in the Connect Base Console under **Storage > Security Settings**, or via the API:
|
|
122
131
|
|
|
123
132
|
```bash
|
|
124
|
-
|
|
133
|
+
# Disable SPA mode (for static sites)
|
|
134
|
+
curl -X PUT "https://api.connectbase.world/v1/apps/{appID}/storages/webs/{storageID}" \
|
|
135
|
+
-H "Authorization: Bearer <TOKEN>" \
|
|
136
|
+
-H "Content-Type: application/json" \
|
|
137
|
+
-d '{"spa_mode": false}'
|
|
125
138
|
```
|
|
126
139
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
- `index.html` must exist in the root of the deploy directory
|
|
130
|
-
- Supported file types: `.html`, `.css`, `.js`, `.json`, `.svg`, `.png`, `.jpg`, `.gif`, `.webp`, `.woff`, `.woff2`, `.ttf`, `.mp3`, `.mp4`, `.pdf`, `.wasm`, etc.
|
|
140
|
+
> **Important:** When using SPA mode, ensure all asset paths in your HTML are absolute (`/assets/...`), not relative (`./assets/...`). For Vite projects, set `base: '/'` in `vite.config.ts`.
|
|
131
141
|
|
|
132
142
|
## API Reference
|
|
133
143
|
|
|
@@ -339,9 +349,11 @@ const session = await cb.auth.signIn({
|
|
|
339
349
|
password: 'password123'
|
|
340
350
|
})
|
|
341
351
|
|
|
342
|
-
// OAuth login
|
|
343
|
-
|
|
344
|
-
|
|
352
|
+
// OAuth login (리다이렉트 방식)
|
|
353
|
+
await cb.oauth.signIn('google', 'https://myapp.com/oauth/callback')
|
|
354
|
+
|
|
355
|
+
// OAuth login (팝업 방식)
|
|
356
|
+
const result = await cb.oauth.signInWithPopup('google', 'https://myapp.com/oauth/popup-callback')
|
|
345
357
|
|
|
346
358
|
// Get current user
|
|
347
359
|
const user = await cb.auth.getCurrentUser()
|
package/dist/cli.js
CHANGED
|
@@ -29,6 +29,7 @@ var fs = __toESM(require("fs"));
|
|
|
29
29
|
var path = __toESM(require("path"));
|
|
30
30
|
var https = __toESM(require("https"));
|
|
31
31
|
var http = __toESM(require("http"));
|
|
32
|
+
var readline = __toESM(require("readline"));
|
|
32
33
|
var VERSION = "0.1.3";
|
|
33
34
|
var DEFAULT_BASE_URL = "https://api.connectbase.world";
|
|
34
35
|
var colors = {
|
|
@@ -123,6 +124,7 @@ function loadConfig() {
|
|
|
123
124
|
if (rcContent.apiKey) config.apiKey = rcContent.apiKey;
|
|
124
125
|
if (rcContent.storageId) config.storageId = rcContent.storageId;
|
|
125
126
|
if (rcContent.baseUrl) config.baseUrl = rcContent.baseUrl;
|
|
127
|
+
if (rcContent.deployDir) config.deployDir = rcContent.deployDir;
|
|
126
128
|
} catch {
|
|
127
129
|
warn(".connectbaserc \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
|
|
128
130
|
}
|
|
@@ -257,6 +259,107 @@ ${colors.cyan}URL: ${data.url}${colors.reset}
|
|
|
257
259
|
process.exit(1);
|
|
258
260
|
}
|
|
259
261
|
}
|
|
262
|
+
function prompt(question) {
|
|
263
|
+
const rl = readline.createInterface({
|
|
264
|
+
input: process.stdin,
|
|
265
|
+
output: process.stdout
|
|
266
|
+
});
|
|
267
|
+
return new Promise((resolve2) => {
|
|
268
|
+
rl.question(question, (answer) => {
|
|
269
|
+
rl.close();
|
|
270
|
+
resolve2(answer.trim());
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
async function init() {
|
|
275
|
+
log(`
|
|
276
|
+
${colors.cyan}Connect Base \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654${colors.reset}
|
|
277
|
+
`);
|
|
278
|
+
const rcPath = path.join(process.cwd(), ".connectbaserc");
|
|
279
|
+
if (fs.existsSync(rcPath)) {
|
|
280
|
+
const overwrite = await prompt(`${colors.yellow}\u26A0${colors.reset} .connectbaserc\uAC00 \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4. \uB36E\uC5B4\uC4F0\uC2DC\uACA0\uC2B5\uB2C8\uAE4C? (y/N): `);
|
|
281
|
+
if (overwrite.toLowerCase() !== "y") {
|
|
282
|
+
info("\uCD08\uAE30\uD654\uAC00 \uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4");
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
const apiKey = await prompt(`${colors.blue}?${colors.reset} API Key: `);
|
|
287
|
+
if (!apiKey) {
|
|
288
|
+
error("API Key\uB294 \uD544\uC218\uC785\uB2C8\uB2E4");
|
|
289
|
+
process.exit(1);
|
|
290
|
+
}
|
|
291
|
+
const storageId = await prompt(`${colors.blue}?${colors.reset} Storage ID: `);
|
|
292
|
+
if (!storageId) {
|
|
293
|
+
error("Storage ID\uB294 \uD544\uC218\uC785\uB2C8\uB2E4");
|
|
294
|
+
process.exit(1);
|
|
295
|
+
}
|
|
296
|
+
const defaultDir = detectBuildDir();
|
|
297
|
+
const deployDir = await prompt(`${colors.blue}?${colors.reset} \uBC30\uD3EC \uB514\uB809\uD1A0\uB9AC (${defaultDir}): `) || defaultDir;
|
|
298
|
+
const config = {
|
|
299
|
+
apiKey,
|
|
300
|
+
storageId,
|
|
301
|
+
deployDir
|
|
302
|
+
};
|
|
303
|
+
fs.writeFileSync(rcPath, JSON.stringify(config, null, 2) + "\n");
|
|
304
|
+
success(".connectbaserc \uC0DD\uC131 \uC644\uB8CC");
|
|
305
|
+
addToGitignore(".connectbaserc");
|
|
306
|
+
addDeployScript(deployDir);
|
|
307
|
+
log(`
|
|
308
|
+
${colors.green}\uCD08\uAE30\uD654 \uC644\uB8CC!${colors.reset}
|
|
309
|
+
`);
|
|
310
|
+
log(`${colors.dim}\uBC30\uD3EC\uD558\uB824\uBA74:${colors.reset}`);
|
|
311
|
+
log(` ${colors.cyan}npm run deploy${colors.reset}
|
|
312
|
+
`);
|
|
313
|
+
}
|
|
314
|
+
function detectBuildDir() {
|
|
315
|
+
if (fs.existsSync(path.join(process.cwd(), "dist"))) return "./dist";
|
|
316
|
+
if (fs.existsSync(path.join(process.cwd(), "build"))) return "./build";
|
|
317
|
+
if (fs.existsSync(path.join(process.cwd(), "out"))) return "./out";
|
|
318
|
+
if (fs.existsSync(path.join(process.cwd(), ".next"))) return "./out";
|
|
319
|
+
if (fs.existsSync(path.join(process.cwd(), "vite.config.ts")) || fs.existsSync(path.join(process.cwd(), "vite.config.js"))) return "./dist";
|
|
320
|
+
if (fs.existsSync(path.join(process.cwd(), "next.config.js")) || fs.existsSync(path.join(process.cwd(), "next.config.mjs"))) return "./out";
|
|
321
|
+
return "./dist";
|
|
322
|
+
}
|
|
323
|
+
function addToGitignore(entry) {
|
|
324
|
+
const gitignorePath = path.join(process.cwd(), ".gitignore");
|
|
325
|
+
if (fs.existsSync(gitignorePath)) {
|
|
326
|
+
const content = fs.readFileSync(gitignorePath, "utf-8");
|
|
327
|
+
if (!content.includes(entry)) {
|
|
328
|
+
fs.appendFileSync(gitignorePath, `
|
|
329
|
+
# Connect Base
|
|
330
|
+
${entry}
|
|
331
|
+
`);
|
|
332
|
+
success(`.gitignore\uC5D0 ${entry} \uCD94\uAC00 \uC644\uB8CC`);
|
|
333
|
+
} else {
|
|
334
|
+
info(`.gitignore\uC5D0 \uC774\uBBF8 ${entry}\uAC00 \uD3EC\uD568\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4`);
|
|
335
|
+
}
|
|
336
|
+
} else {
|
|
337
|
+
fs.writeFileSync(gitignorePath, `# Connect Base
|
|
338
|
+
${entry}
|
|
339
|
+
`);
|
|
340
|
+
success(".gitignore \uC0DD\uC131 \uC644\uB8CC");
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
function addDeployScript(deployDir) {
|
|
344
|
+
const pkgPath = path.join(process.cwd(), "package.json");
|
|
345
|
+
if (!fs.existsSync(pkgPath)) {
|
|
346
|
+
warn("package.json\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4 deploy \uC2A4\uD06C\uB9BD\uD2B8\uB97C \uCD94\uAC00\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4");
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
try {
|
|
350
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
351
|
+
if (!pkg.scripts) pkg.scripts = {};
|
|
352
|
+
if (pkg.scripts.deploy) {
|
|
353
|
+
info(`package.json\uC5D0 \uC774\uBBF8 deploy \uC2A4\uD06C\uB9BD\uD2B8\uAC00 \uC788\uC2B5\uB2C8\uB2E4: "${pkg.scripts.deploy}"`);
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
pkg.scripts.deploy = `connectbase-client deploy ${deployDir}`;
|
|
357
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
358
|
+
success(`package.json\uC5D0 deploy \uC2A4\uD06C\uB9BD\uD2B8 \uCD94\uAC00 \uC644\uB8CC`);
|
|
359
|
+
} catch {
|
|
360
|
+
warn("package.json \uC218\uC815\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4");
|
|
361
|
+
}
|
|
362
|
+
}
|
|
260
363
|
function showHelp() {
|
|
261
364
|
log(`
|
|
262
365
|
${colors.cyan}connectbase-client${colors.reset} - Connect Base SDK & CLI
|
|
@@ -265,6 +368,7 @@ ${colors.yellow}\uC0AC\uC6A9\uBC95:${colors.reset}
|
|
|
265
368
|
npx connectbase-client <command> [options]
|
|
266
369
|
|
|
267
370
|
${colors.yellow}\uBA85\uB839\uC5B4:${colors.reset}
|
|
371
|
+
init \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654 (\uC124\uC815 \uD30C\uC77C \uC0DD\uC131)
|
|
268
372
|
deploy <directory> \uC6F9 \uC2A4\uD1A0\uB9AC\uC9C0\uC5D0 \uD30C\uC77C \uBC30\uD3EC
|
|
269
373
|
|
|
270
374
|
${colors.yellow}\uC635\uC158:${colors.reset}
|
|
@@ -274,6 +378,13 @@ ${colors.yellow}\uC635\uC158:${colors.reset}
|
|
|
274
378
|
-h, --help \uB3C4\uC6C0\uB9D0 \uD45C\uC2DC
|
|
275
379
|
-v, --version \uBC84\uC804 \uD45C\uC2DC
|
|
276
380
|
|
|
381
|
+
${colors.yellow}\uBE60\uB978 \uC2DC\uC791:${colors.reset}
|
|
382
|
+
${colors.dim}# 1. \uCD08\uAE30\uD654 (\uCD5C\uCD08 1\uD68C)${colors.reset}
|
|
383
|
+
npx connectbase-client init
|
|
384
|
+
|
|
385
|
+
${colors.dim}# 2. \uBC30\uD3EC${colors.reset}
|
|
386
|
+
npm run deploy
|
|
387
|
+
|
|
277
388
|
${colors.yellow}\uD658\uACBD\uBCC0\uC218:${colors.reset}
|
|
278
389
|
CONNECTBASE_API_KEY API Key
|
|
279
390
|
CONNECTBASE_STORAGE_ID \uC2A4\uD1A0\uB9AC\uC9C0 ID
|
|
@@ -282,21 +393,8 @@ ${colors.yellow}\uD658\uACBD\uBCC0\uC218:${colors.reset}
|
|
|
282
393
|
${colors.yellow}\uC124\uC815 \uD30C\uC77C (.connectbaserc):${colors.reset}
|
|
283
394
|
{
|
|
284
395
|
"apiKey": "your-api-key",
|
|
285
|
-
"storageId": "your-storage-id"
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
${colors.yellow}\uC608\uC2DC:${colors.reset}
|
|
289
|
-
${colors.dim}# \uAE30\uBCF8 \uBC30\uD3EC${colors.reset}
|
|
290
|
-
npx connectbase-client deploy ./dist -s <storage-id> -k <api-key>
|
|
291
|
-
|
|
292
|
-
${colors.dim}# \uD658\uACBD\uBCC0\uC218 \uC0AC\uC6A9${colors.reset}
|
|
293
|
-
export CONNECTBASE_API_KEY=your-api-key
|
|
294
|
-
export CONNECTBASE_STORAGE_ID=your-storage-id
|
|
295
|
-
npx connectbase-client deploy ./dist
|
|
296
|
-
|
|
297
|
-
${colors.dim}# package.json scripts\uC5D0\uC11C \uC0AC\uC6A9${colors.reset}
|
|
298
|
-
"scripts": {
|
|
299
|
-
"deploy": "connectbase-client deploy ./dist"
|
|
396
|
+
"storageId": "your-storage-id",
|
|
397
|
+
"deployDir": "./dist"
|
|
300
398
|
}
|
|
301
399
|
`);
|
|
302
400
|
}
|
|
@@ -345,14 +443,16 @@ async function main() {
|
|
|
345
443
|
storageId: parsed.options.storageId || fileConfig.storageId,
|
|
346
444
|
baseUrl: parsed.options.baseUrl || fileConfig.baseUrl || DEFAULT_BASE_URL
|
|
347
445
|
};
|
|
348
|
-
if (parsed.command === "
|
|
349
|
-
|
|
446
|
+
if (parsed.command === "init") {
|
|
447
|
+
await init();
|
|
448
|
+
} else if (parsed.command === "deploy") {
|
|
449
|
+
const directory = parsed.args[0] || fileConfig.deployDir || ".";
|
|
350
450
|
if (!config.apiKey) {
|
|
351
|
-
error(
|
|
451
|
+
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');
|
|
352
452
|
process.exit(1);
|
|
353
453
|
}
|
|
354
454
|
if (!config.storageId) {
|
|
355
|
-
error(
|
|
455
|
+
error('\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');
|
|
356
456
|
process.exit(1);
|
|
357
457
|
}
|
|
358
458
|
await deploy(directory, config);
|