mygensite 1.2.0 → 1.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/README.en.md CHANGED
@@ -301,11 +301,32 @@ const site = await mygensite.deploy({
301
301
  access: 'public',
302
302
  files: [
303
303
  { name: 'index.html', content: '<h1>Hello World</h1>' },
304
- { name: 'style.css', content: 'body { font-family: sans-serif; }' },
304
+ { name: 'assets/style.css', content: 'body { font-family: sans-serif; }' },
305
305
  ],
306
306
  });
307
307
  ```
308
308
 
309
+ #### Deploy with curl
310
+
311
+ Multipart `filename` strips directory paths (e.g. `assets/style.css` becomes `style.css`). Use the `filepaths` JSON field to preserve directory structure:
312
+
313
+ ```bash
314
+ # Flat files (no subdirectories) — filepaths not needed
315
+ curl -X POST https://mygen.site/api/deploy \
316
+ -F slug=demo -F access='{"mode":"public"}' \
317
+ -F files=@index.html -F files=@style.css
318
+
319
+ # With subdirectories — filepaths required
320
+ curl -X POST https://mygen.site/api/deploy \
321
+ -F slug=demo -F access='{"mode":"public"}' \
322
+ -F 'filepaths=["index.html","assets/style.css","assets/js/app.js"]' \
323
+ -F files=@index.html \
324
+ -F files=@assets/style.css \
325
+ -F files=@assets/js/app.js
326
+ ```
327
+
328
+ The `filepaths` field is a JSON array where each element corresponds to the `files` field in order. The server uses these paths instead of the multipart filename.
329
+
309
330
  ### Site instance
310
331
 
311
332
  The returned object contains the deployment result plus convenience methods:
@@ -329,6 +350,34 @@ The returned object contains the deployment result plus convenience methods:
329
350
  | `redeploy(directory)` | directory path (string) | Upload new files, replacing all existing files. Returns a Promise. |
330
351
  | `delete(purge?)` | purge (boolean) | Delete the site. `false` = soft delete (files kept), `true` = purge S3 files. Returns a Promise. |
331
352
 
353
+ ### mygensite.manage(options)
354
+
355
+ Create a management handle for an existing service when you already have the `slug` and `admin_token` (e.g. saved from a previous deploy). **Do not redeploy just to get a management object** — use this instead.
356
+
357
+ ```js
358
+ const mygensite = require('mygensite');
359
+
360
+ const site = mygensite.manage({
361
+ slug: 'demo',
362
+ admin_token: 'tok_xxx', // from the original deploy/tunnel response
363
+ host: 'https://mygen.site', // optional
364
+ });
365
+
366
+ // Same methods as deploy result
367
+ await site.updateAccess({ mode: 'public' });
368
+ await site.extendTTL(86400);
369
+ await site.redeploy('./dist-v2');
370
+ await site.delete();
371
+ ```
372
+
373
+ #### Options
374
+
375
+ | option | type | required | default | description |
376
+ | --- | --- | --- | --- | --- |
377
+ | `slug` | string | yes | — | The service slug |
378
+ | `admin_token` | string | yes | — | The admin token from the original deploy/tunnel response |
379
+ | `host` | string | | `https://mygen.site` | Server URL |
380
+
332
381
  ### Deploy management examples
333
382
 
334
383
  ```js
package/README.ko.md CHANGED
@@ -301,11 +301,32 @@ const site = await mygensite.deploy({
301
301
  access: 'public',
302
302
  files: [
303
303
  { name: 'index.html', content: '<h1>Hello World</h1>' },
304
- { name: 'style.css', content: 'body { font-family: sans-serif; }' },
304
+ { name: 'assets/style.css', content: 'body { font-family: sans-serif; }' },
305
305
  ],
306
306
  });
307
307
  ```
308
308
 
309
+ #### curl로 배포
310
+
311
+ Multipart의 `filename`은 디렉토리 경로를 제거합니다 (예: `assets/style.css` &rarr; `style.css`). 서브디렉토리가 있으면 `filepaths` JSON 필드를 사용하세요:
312
+
313
+ ```bash
314
+ # 플랫 파일 (서브디렉토리 없음) - filepaths 불필요
315
+ curl -X POST https://mygen.site/api/deploy \
316
+ -F slug=demo -F access='{"mode":"public"}' \
317
+ -F files=@index.html -F files=@style.css
318
+
319
+ # 서브디렉토리 있음 - filepaths 필수
320
+ curl -X POST https://mygen.site/api/deploy \
321
+ -F slug=demo -F access='{"mode":"public"}' \
322
+ -F 'filepaths=["index.html","assets/style.css","assets/js/app.js"]' \
323
+ -F files=@index.html \
324
+ -F files=@assets/style.css \
325
+ -F files=@assets/js/app.js
326
+ ```
327
+
328
+ `filepaths`는 JSON 배열로, 각 원소가 `files` 필드와 순서대로 대응됩니다. 서버는 multipart filename 대신 이 경로를 사용합니다.
329
+
309
330
  ### Site 인스턴스
310
331
 
311
332
  반환 객체에 배포 결과와 편의 메서드가 포함됩니다:
@@ -329,6 +350,35 @@ const site = await mygensite.deploy({
329
350
  | `redeploy(directory)` | 디렉토리 경로 (string) | 새 파일로 교체 업로드. Promise 반환. |
330
351
  | `delete(purge?)` | purge (boolean) | 사이트 삭제. `false` = 소프트 삭제 (파일 유지), `true` = S3 파일까지 삭제. Promise 반환. |
331
352
 
353
+ ### mygensite.manage(options)
354
+
355
+ 기존 서비스의 `slug`과 `admin_token`이 있을 때 관리 핸들을 생성합니다 (예: 이전 배포에서 저장해둔 값).
356
+ **관리 객체를 얻기 위해 재배포하지 마세요** — 이 함수를 사용하세요.
357
+
358
+ ```js
359
+ const mygensite = require('mygensite');
360
+
361
+ const site = mygensite.manage({
362
+ slug: 'demo',
363
+ admin_token: 'tok_xxx', // 원래 배포/터널 생성 시 반환된 값
364
+ host: 'https://mygen.site', // 선택
365
+ });
366
+
367
+ // deploy 결과와 동일한 메서드 사용 가능
368
+ await site.updateAccess({ mode: 'public' });
369
+ await site.extendTTL(86400);
370
+ await site.redeploy('./dist-v2');
371
+ await site.delete();
372
+ ```
373
+
374
+ #### 옵션
375
+
376
+ | 옵션 | 타입 | 필수 | 기본값 | 설명 |
377
+ | --- | --- | --- | --- | --- |
378
+ | `slug` | string | 예 | — | 서비스 slug |
379
+ | `admin_token` | string | 예 | — | 원래 배포/터널 생성 시 반환된 admin token |
380
+ | `host` | string | | `https://mygen.site` | 서버 URL |
381
+
332
382
  ### 배포 관리 예제
333
383
 
334
384
  ```js
package/README.md CHANGED
@@ -66,6 +66,27 @@ await site.delete(); // soft delete
66
66
  await site.delete(true); // purge (delete S3 files too)
67
67
  ```
68
68
 
69
+ ## Manage (existing service)
70
+
71
+ Use `manage()` when you already have the `slug` and `admin_token` from a previous deploy or tunnel.
72
+ **Do not redeploy just to get a management object** — use this instead.
73
+
74
+ ```js
75
+ const mygensite = require('mygensite');
76
+
77
+ const site = mygensite.manage({
78
+ slug: 'demo',
79
+ admin_token: 'tok_xxx', // from the original deploy response
80
+ host: 'https://mygen.site', // optional
81
+ });
82
+
83
+ // Same methods as deploy result
84
+ await site.updateAccess({ mode: 'public' });
85
+ await site.extendTTL(86400);
86
+ await site.redeploy('./dist-v2');
87
+ await site.delete();
88
+ ```
89
+
69
90
  ## Access Modes
70
91
 
71
92
  | mode | behavior |
@@ -147,6 +168,25 @@ mygensite deploy -d ./dist -s private-demo --access password --password 'mypass'
147
168
  mygensite deploy -d ./dist-v2 -s demo --admin-token tok_xxx
148
169
  ```
149
170
 
171
+ ## curl Deploy
172
+
173
+ ```bash
174
+ # Simple (flat files)
175
+ curl -X POST https://mygen.site/api/deploy \
176
+ -F slug=demo -F access='{"mode":"public"}' \
177
+ -F files=@index.html -F files=@style.css
178
+
179
+ # With subdirectories — use filepaths to preserve directory structure
180
+ curl -X POST https://mygen.site/api/deploy \
181
+ -F slug=demo -F access='{"mode":"public"}' \
182
+ -F 'filepaths=["index.html","assets/style.css","assets/js/app.js"]' \
183
+ -F files=@index.html \
184
+ -F files=@assets/style.css \
185
+ -F files=@assets/js/app.js
186
+ ```
187
+
188
+ > **Note:** Multipart `filename` strips directory paths. The `filepaths` JSON field tells the server the correct path for each file, in order.
189
+
150
190
  ## Passwords with Special Characters
151
191
 
152
192
  When using the CLI or curl, passwords with special characters (like `!`, `$`, `&`, `\`) may be modified by your shell before reaching the program.
package/lib/deploy.js CHANGED
@@ -170,9 +170,12 @@ async function deploy(options) {
170
170
  }
171
171
  form.append('access', JSON.stringify(accessObj));
172
172
 
173
+ // Send file paths as separate JSON field (busboy strips directories from filename)
174
+ form.append('filepaths', JSON.stringify(fileList.map(f => f.name)));
175
+
173
176
  for (const file of fileList) {
174
177
  form.append('files', file.content, {
175
- filename: file.name,
178
+ filepath: file.name,
176
179
  contentType: file.contentType,
177
180
  });
178
181
  }
@@ -202,4 +205,36 @@ async function deploy(options) {
202
205
  return data;
203
206
  }
204
207
 
208
+ /**
209
+ * Create a management handle for an existing service.
210
+ * Use this when you already have the slug and admin_token (e.g. from a previous deploy).
211
+ *
212
+ * @param {object} options
213
+ * @param {string} options.slug - The service slug
214
+ * @param {string} options.admin_token - The admin token from the original deploy
215
+ * @param {string} [options.host] - API host (default: https://mygen.site)
216
+ * @returns {object} Management object with updateAccess, extendTTL, redeploy, delete methods
217
+ */
218
+ function manage(options) {
219
+ const {
220
+ slug,
221
+ admin_token,
222
+ host = DEFAULT_HOST,
223
+ } = options;
224
+
225
+ if (!slug) throw new Error('slug is required');
226
+ if (!admin_token) throw new Error('admin_token is required');
227
+
228
+ return {
229
+ slug,
230
+ admin_token,
231
+ url: `https://${slug}.${host.replace(/^https?:\/\//, '')}`,
232
+ updateAccess: (access) => patchService(host, slug, admin_token, { access }),
233
+ extendTTL: (ttl) => patchService(host, slug, admin_token, { ttl }),
234
+ redeploy: (dir) => deploy({ host, subdomain: slug, directory: dir, admin_token }),
235
+ delete: (purge) => deleteService(host, slug, admin_token, purge),
236
+ };
237
+ }
238
+
205
239
  module.exports = deploy;
240
+ module.exports.manage = manage;
package/localtunnel.js CHANGED
@@ -16,6 +16,7 @@ function localtunnel(arg1, arg2, arg3) {
16
16
  }
17
17
 
18
18
  localtunnel.deploy = deploy;
19
+ localtunnel.manage = deploy.manage;
19
20
  localtunnel.validate = validate;
20
21
 
21
22
  module.exports = localtunnel;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mygensite",
3
3
  "description": "Expose your localhost to mygen.site with access control",
4
- "version": "1.2.0",
4
+ "version": "1.3.0",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",