connectbase-client 0.1.1 → 0.1.3

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.
Files changed (3) hide show
  1. package/README.md +77 -0
  2. package/dist/cli.js +368 -0
  3. package/package.json +8 -2
package/README.md CHANGED
@@ -51,6 +51,83 @@ const state = await gameClient.createRoom({
51
51
  - **Push Notifications**: Cross-platform push notification support
52
52
  - **WebRTC**: Real-time audio/video communication
53
53
  - **Payments**: Subscription and one-time payment support
54
+ - **CLI**: Command-line tool for deploying web storage
55
+
56
+ ## CLI
57
+
58
+ Deploy your web application to Connect Base Web Storage with a single command.
59
+
60
+ ### Basic Usage
61
+
62
+ ```bash
63
+ # Deploy a directory
64
+ npx connectbase-client deploy ./dist -s <storage-id> -k <api-key>
65
+
66
+ # Deploy current directory
67
+ npx connectbase-client deploy . -s <storage-id> -k <api-key>
68
+ ```
69
+
70
+ ### Options
71
+
72
+ | Option | Alias | Description |
73
+ |--------|-------|-------------|
74
+ | `--storage <id>` | `-s` | Storage ID (required) |
75
+ | `--api-key <key>` | `-k` | API Key (required) |
76
+ | `--base-url <url>` | `-u` | Custom server URL |
77
+ | `--help` | `-h` | Show help |
78
+ | `--version` | `-v` | Show version |
79
+
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
+ ### Configuration File
93
+
94
+ Create a `.connectbaserc` file in your project root:
95
+
96
+ ```json
97
+ {
98
+ "apiKey": "your-api-key",
99
+ "storageId": "your-storage-id"
100
+ }
101
+ ```
102
+
103
+ Then deploy:
104
+
105
+ ```bash
106
+ npx connectbase-client deploy ./dist
107
+ ```
108
+
109
+ ### npm Scripts
110
+
111
+ Add to your `package.json`:
112
+
113
+ ```json
114
+ {
115
+ "scripts": {
116
+ "deploy": "connectbase-client deploy ./dist"
117
+ }
118
+ }
119
+ ```
120
+
121
+ Then run:
122
+
123
+ ```bash
124
+ npm run deploy
125
+ ```
126
+
127
+ ### Requirements
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.
54
131
 
55
132
  ## API Reference
56
133
 
package/dist/cli.js ADDED
@@ -0,0 +1,368 @@
1
+ #!/usr/bin/env node
2
+ #!/usr/bin/env node
3
+ "use strict";
4
+ var __create = Object.create;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
19
+ // If the importer is in node compatibility mode or this is not an ESM
20
+ // file that has been converted to a CommonJS file using a Babel-
21
+ // compatible transform (i.e. "__esModule" has not been set), then set
22
+ // "default" to the CommonJS "module.exports" for node compatibility.
23
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
+ mod
25
+ ));
26
+
27
+ // src/cli.ts
28
+ var fs = __toESM(require("fs"));
29
+ var path = __toESM(require("path"));
30
+ var https = __toESM(require("https"));
31
+ var http = __toESM(require("http"));
32
+ var VERSION = "0.1.3";
33
+ var DEFAULT_BASE_URL = "https://api.connectbase.world";
34
+ var colors = {
35
+ reset: "\x1B[0m",
36
+ green: "\x1B[32m",
37
+ red: "\x1B[31m",
38
+ yellow: "\x1B[33m",
39
+ blue: "\x1B[34m",
40
+ cyan: "\x1B[36m",
41
+ dim: "\x1B[2m"
42
+ };
43
+ function log(message) {
44
+ console.log(message);
45
+ }
46
+ function success(message) {
47
+ console.log(`${colors.green}\u2713${colors.reset} ${message}`);
48
+ }
49
+ function error(message) {
50
+ console.error(`${colors.red}\u2717${colors.reset} ${message}`);
51
+ }
52
+ function info(message) {
53
+ console.log(`${colors.blue}\u2139${colors.reset} ${message}`);
54
+ }
55
+ function warn(message) {
56
+ console.log(`${colors.yellow}\u26A0${colors.reset} ${message}`);
57
+ }
58
+ var ALLOWED_EXTENSIONS = /* @__PURE__ */ new Set([
59
+ ".html",
60
+ ".htm",
61
+ ".css",
62
+ ".js",
63
+ ".mjs",
64
+ ".json",
65
+ ".svg",
66
+ ".png",
67
+ ".jpg",
68
+ ".jpeg",
69
+ ".gif",
70
+ ".webp",
71
+ ".avif",
72
+ ".ico",
73
+ ".woff",
74
+ ".woff2",
75
+ ".ttf",
76
+ ".eot",
77
+ ".otf",
78
+ ".mp3",
79
+ ".wav",
80
+ ".ogg",
81
+ ".mp4",
82
+ ".webm",
83
+ ".pdf",
84
+ ".zip",
85
+ ".txt",
86
+ ".xml",
87
+ ".webmanifest",
88
+ ".map",
89
+ ".wasm"
90
+ ]);
91
+ var BINARY_EXTENSIONS = /* @__PURE__ */ new Set([
92
+ ".png",
93
+ ".jpg",
94
+ ".jpeg",
95
+ ".gif",
96
+ ".webp",
97
+ ".avif",
98
+ ".ico",
99
+ ".woff",
100
+ ".woff2",
101
+ ".ttf",
102
+ ".eot",
103
+ ".otf",
104
+ ".mp3",
105
+ ".wav",
106
+ ".ogg",
107
+ ".mp4",
108
+ ".webm",
109
+ ".pdf",
110
+ ".zip",
111
+ ".wasm"
112
+ ]);
113
+ function loadConfig() {
114
+ const config = {
115
+ apiKey: process.env.CONNECTBASE_API_KEY,
116
+ storageId: process.env.CONNECTBASE_STORAGE_ID,
117
+ baseUrl: process.env.CONNECTBASE_BASE_URL || DEFAULT_BASE_URL
118
+ };
119
+ const rcPath = path.join(process.cwd(), ".connectbaserc");
120
+ if (fs.existsSync(rcPath)) {
121
+ try {
122
+ const rcContent = JSON.parse(fs.readFileSync(rcPath, "utf-8"));
123
+ if (rcContent.apiKey) config.apiKey = rcContent.apiKey;
124
+ if (rcContent.storageId) config.storageId = rcContent.storageId;
125
+ if (rcContent.baseUrl) config.baseUrl = rcContent.baseUrl;
126
+ } catch {
127
+ warn(".connectbaserc \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4");
128
+ }
129
+ }
130
+ return config;
131
+ }
132
+ function collectFiles(dir, baseDir = dir) {
133
+ const files = [];
134
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
135
+ for (const entry of entries) {
136
+ const fullPath = path.join(dir, entry.name);
137
+ const relativePath = path.relative(baseDir, fullPath);
138
+ if (entry.isDirectory()) {
139
+ if (!entry.name.startsWith(".")) {
140
+ files.push(...collectFiles(fullPath, baseDir));
141
+ }
142
+ } else if (entry.isFile()) {
143
+ const ext = path.extname(entry.name).toLowerCase();
144
+ if (!ALLOWED_EXTENSIONS.has(ext)) {
145
+ continue;
146
+ }
147
+ if (entry.name.startsWith(".")) {
148
+ continue;
149
+ }
150
+ const isBinary = BINARY_EXTENSIONS.has(ext);
151
+ let content;
152
+ if (isBinary) {
153
+ content = fs.readFileSync(fullPath).toString("base64");
154
+ } else {
155
+ content = fs.readFileSync(fullPath, "utf-8");
156
+ }
157
+ files.push({
158
+ path: relativePath.replace(/\\/g, "/"),
159
+ // Windows 경로 변환
160
+ content,
161
+ isBinary
162
+ });
163
+ }
164
+ }
165
+ return files;
166
+ }
167
+ function makeRequest(url, method, headers, body) {
168
+ return new Promise((resolve2, reject) => {
169
+ const parsedUrl = new URL(url);
170
+ const isHttps = parsedUrl.protocol === "https:";
171
+ const lib = isHttps ? https : http;
172
+ const options = {
173
+ hostname: parsedUrl.hostname,
174
+ port: parsedUrl.port || (isHttps ? 443 : 80),
175
+ path: parsedUrl.pathname + parsedUrl.search,
176
+ method,
177
+ headers: {
178
+ ...headers,
179
+ "Content-Type": "application/json"
180
+ }
181
+ };
182
+ const req = lib.request(options, (res) => {
183
+ let data = "";
184
+ res.on("data", (chunk) => data += chunk);
185
+ res.on("end", () => {
186
+ try {
187
+ resolve2({
188
+ status: res.statusCode || 0,
189
+ data: data ? JSON.parse(data) : null
190
+ });
191
+ } catch {
192
+ resolve2({ status: res.statusCode || 0, data });
193
+ }
194
+ });
195
+ });
196
+ req.on("error", reject);
197
+ if (body) {
198
+ req.write(body);
199
+ }
200
+ req.end();
201
+ });
202
+ }
203
+ async function deploy(directory, config) {
204
+ const dir = path.resolve(directory);
205
+ if (!fs.existsSync(dir)) {
206
+ error(`\uB514\uB809\uD1A0\uB9AC\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${dir}`);
207
+ process.exit(1);
208
+ }
209
+ if (!fs.statSync(dir).isDirectory()) {
210
+ error(`${dir}\uB294 \uB514\uB809\uD1A0\uB9AC\uAC00 \uC544\uB2D9\uB2C8\uB2E4`);
211
+ process.exit(1);
212
+ }
213
+ const indexPath = path.join(dir, "index.html");
214
+ if (!fs.existsSync(indexPath)) {
215
+ error("index.html \uD30C\uC77C\uC774 \uD544\uC694\uD569\uB2C8\uB2E4");
216
+ process.exit(1);
217
+ }
218
+ info(`\uBC30\uD3EC \uC900\uBE44 \uC911... ${dir}`);
219
+ const files = collectFiles(dir);
220
+ if (files.length === 0) {
221
+ error("\uBC30\uD3EC\uD560 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4");
222
+ process.exit(1);
223
+ }
224
+ log(`${colors.dim}${files.length}\uAC1C \uD30C\uC77C \uBC1C\uACAC${colors.reset}`);
225
+ const url = `${config.baseUrl}/v1/storages/webs/${config.storageId}/deploy`;
226
+ info("\uBC30\uD3EC \uC911...");
227
+ try {
228
+ const response = await makeRequest(
229
+ url,
230
+ "POST",
231
+ {
232
+ "X-API-Key": config.apiKey
233
+ },
234
+ JSON.stringify({
235
+ files: files.map((f) => ({
236
+ path: f.path,
237
+ content: f.content,
238
+ is_binary: f.isBinary
239
+ }))
240
+ })
241
+ );
242
+ if (response.status >= 200 && response.status < 300) {
243
+ success("\uBC30\uD3EC \uC644\uB8CC!");
244
+ const data = response.data;
245
+ if (data?.url) {
246
+ log(`
247
+ ${colors.cyan}URL: ${data.url}${colors.reset}
248
+ `);
249
+ }
250
+ } else {
251
+ const data = response.data;
252
+ error(`\uBC30\uD3EC \uC2E4\uD328: ${data?.message || data?.error || "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`);
253
+ process.exit(1);
254
+ }
255
+ } catch (err) {
256
+ error(`\uB124\uD2B8\uC6CC\uD06C \uC624\uB958: ${err instanceof Error ? err.message : err}`);
257
+ process.exit(1);
258
+ }
259
+ }
260
+ function showHelp() {
261
+ log(`
262
+ ${colors.cyan}connectbase-client${colors.reset} - Connect Base SDK & CLI
263
+
264
+ ${colors.yellow}\uC0AC\uC6A9\uBC95:${colors.reset}
265
+ npx connectbase-client <command> [options]
266
+
267
+ ${colors.yellow}\uBA85\uB839\uC5B4:${colors.reset}
268
+ deploy <directory> \uC6F9 \uC2A4\uD1A0\uB9AC\uC9C0\uC5D0 \uD30C\uC77C \uBC30\uD3EC
269
+
270
+ ${colors.yellow}\uC635\uC158:${colors.reset}
271
+ -s, --storage <id> \uC2A4\uD1A0\uB9AC\uC9C0 ID
272
+ -k, --api-key <key> API Key
273
+ -u, --base-url <url> \uC11C\uBC84 URL (\uAE30\uBCF8: ${DEFAULT_BASE_URL})
274
+ -h, --help \uB3C4\uC6C0\uB9D0 \uD45C\uC2DC
275
+ -v, --version \uBC84\uC804 \uD45C\uC2DC
276
+
277
+ ${colors.yellow}\uD658\uACBD\uBCC0\uC218:${colors.reset}
278
+ CONNECTBASE_API_KEY API Key
279
+ CONNECTBASE_STORAGE_ID \uC2A4\uD1A0\uB9AC\uC9C0 ID
280
+ CONNECTBASE_BASE_URL \uC11C\uBC84 URL
281
+
282
+ ${colors.yellow}\uC124\uC815 \uD30C\uC77C (.connectbaserc):${colors.reset}
283
+ {
284
+ "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"
300
+ }
301
+ `);
302
+ }
303
+ function parseArgs(args) {
304
+ const result = {
305
+ options: {},
306
+ args: []
307
+ };
308
+ let i = 0;
309
+ while (i < args.length) {
310
+ const arg = args[i];
311
+ if (arg === "-s" || arg === "--storage") {
312
+ result.options.storageId = args[++i];
313
+ } else if (arg === "-k" || arg === "--api-key") {
314
+ result.options.apiKey = args[++i];
315
+ } else if (arg === "-u" || arg === "--base-url") {
316
+ result.options.baseUrl = args[++i];
317
+ } else if (arg === "-h" || arg === "--help") {
318
+ result.options.help = "true";
319
+ } else if (arg === "-v" || arg === "--version") {
320
+ result.options.version = "true";
321
+ } else if (!arg.startsWith("-")) {
322
+ if (!result.command) {
323
+ result.command = arg;
324
+ } else {
325
+ result.args.push(arg);
326
+ }
327
+ }
328
+ i++;
329
+ }
330
+ return result;
331
+ }
332
+ async function main() {
333
+ const parsed = parseArgs(process.argv.slice(2));
334
+ if (parsed.options.version) {
335
+ log(`connectbase-client v${VERSION}`);
336
+ return;
337
+ }
338
+ if (parsed.options.help || !parsed.command) {
339
+ showHelp();
340
+ return;
341
+ }
342
+ const fileConfig = loadConfig();
343
+ const config = {
344
+ apiKey: parsed.options.apiKey || fileConfig.apiKey,
345
+ storageId: parsed.options.storageId || fileConfig.storageId,
346
+ baseUrl: parsed.options.baseUrl || fileConfig.baseUrl || DEFAULT_BASE_URL
347
+ };
348
+ if (parsed.command === "deploy") {
349
+ const directory = parsed.args[0] || ".";
350
+ if (!config.apiKey) {
351
+ error("API Key\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4 (-k \uC635\uC158 \uB610\uB294 CONNECTBASE_API_KEY \uD658\uACBD\uBCC0\uC218)");
352
+ process.exit(1);
353
+ }
354
+ if (!config.storageId) {
355
+ error("\uC2A4\uD1A0\uB9AC\uC9C0 ID\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4 (-s \uC635\uC158 \uB610\uB294 CONNECTBASE_STORAGE_ID \uD658\uACBD\uBCC0\uC218)");
356
+ process.exit(1);
357
+ }
358
+ await deploy(directory, config);
359
+ } else {
360
+ error(`\uC54C \uC218 \uC5C6\uB294 \uBA85\uB839\uC5B4: ${parsed.command}`);
361
+ showHelp();
362
+ process.exit(1);
363
+ }
364
+ }
365
+ main().catch((err) => {
366
+ error(err.message);
367
+ process.exit(1);
368
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "connectbase-client",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Connect Base JavaScript/TypeScript SDK for browser and Node.js",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,6 +15,9 @@
15
15
  "types": "dist/index.d.ts",
16
16
  "browser": "dist/connect-base.umd.js",
17
17
  "unpkg": "dist/connect-base.umd.js",
18
+ "bin": {
19
+ "connectbase-client": "./dist/cli.js"
20
+ },
18
21
  "exports": {
19
22
  ".": {
20
23
  "types": "./dist/index.d.ts",
@@ -36,11 +39,14 @@
36
39
  "backend-as-a-service",
37
40
  "database",
38
41
  "storage",
39
- "sdk"
42
+ "sdk",
43
+ "cli",
44
+ "deploy"
40
45
  ],
41
46
  "author": "",
42
47
  "license": "MIT",
43
48
  "devDependencies": {
49
+ "@types/node": "^22.15.18",
44
50
  "tsup": "^8.5.1",
45
51
  "typescript": "^5.9.3"
46
52
  },