@shipstatic/ship 0.8.9 → 0.8.11

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 CHANGED
@@ -1,296 +1,228 @@
1
1
  # @shipstatic/ship
2
2
 
3
- Universal SDK and CLI for deploying static sites to ShipStatic. No account required deploy instantly, claim later.
3
+ CLI and SDK for [ShipStatic](https://shipstatic.com) — deploy static websites, landing pages, and prototypes instantly from the terminal or code.
4
4
 
5
- ## Installation
5
+ ## Install
6
6
 
7
7
  ```bash
8
- # CLI (global)
9
8
  npm install -g @shipstatic/ship
10
-
11
- # SDK (project dependency)
12
- npm install @shipstatic/ship
13
9
  ```
14
10
 
15
- ## CLI Usage
11
+ > As a project dependency: `npm install @shipstatic/ship`
12
+
13
+ ## Deploy — Free, No Account Needed
16
14
 
17
15
  ```bash
18
- # Deploy — no account needed, site is live instantly
19
16
  ship ./dist
17
+ ```
20
18
 
21
- # Deploy with labels
22
- ship ./dist --label production --label v1.0.0
19
+ Your site is live instantly on `*.shipstatic.com`. No API key, no sign-up, no configuration.
23
20
 
24
- # Deploy and link to a domain in one pipe
25
- ship ./dist -q | ship domains set www.example.com
26
- ```
21
+ Deployments without an API key are public and expire in 3 days. The output includes a **claim URL** visit it to keep the site permanently.
27
22
 
28
- Without credentials, deployments are public (3-day TTL) with a claim URL. Configure an API key for permanent deployments: `ship config`
23
+ ```javascript
24
+ import Ship from '@shipstatic/ship';
29
25
 
30
- ### Composability
26
+ const ship = new Ship();
27
+ const result = await ship.deploy('./dist');
28
+ // result.deployment → live URL (happy-cat-abc1234.shipstatic.com)
29
+ // result.claim → visit to keep permanently
30
+ ```
31
31
 
32
- The `-q` flag outputs only the resource identifier perfect for piping and scripting:
32
+ ## All CommandsFree API Key
33
33
 
34
- ```bash
35
- # Deploy and link domain
36
- ship ./dist -q | ship domains set www.example.com
34
+ For permanent deployments and full control over your sites and domains, get a free API key from [my.shipstatic.com/api-key](https://my.shipstatic.com/api-key).
37
35
 
38
- # Deploy and open in browser
39
- open https://$(ship ./dist -q)
36
+ ```bash
37
+ ship config # paste your API key when prompted
38
+ ```
40
39
 
41
- # Batch operations
42
- ship deployments list -q | xargs -I{} ship deployments remove {} -q
40
+ ```javascript
41
+ const ship = new Ship({ apiKey: 'ship-...' });
43
42
  ```
44
43
 
45
44
  ### Deployments
46
45
 
47
46
  ```bash
47
+ ship ./dist # Deploy (shortcut)
48
+ ship ./dist --label production --label v1.0.0 # Deploy with labels
48
49
  ship deployments list
49
- ship deployments upload <path> # Upload from file or directory
50
- ship deployments upload <path> --label production # Upload with labels
51
50
  ship deployments get <deployment>
52
51
  ship deployments set <deployment> --label production
53
52
  ship deployments remove <deployment>
54
53
  ```
55
54
 
55
+ ```typescript
56
+ ship.deploy(input, options?) // Shortcut for deployments.upload()
57
+ ship.deployments.upload(input, options?)
58
+ ship.deployments.list()
59
+ ship.deployments.get(deployment)
60
+ ship.deployments.set(deployment, { labels })
61
+ ship.deployments.remove(deployment)
62
+ ```
63
+
56
64
  ### Domains
57
65
 
58
66
  ```bash
59
- ship domains list
60
- ship domains set www.example.com # Reserve domain (no deployment yet)
61
- ship domains set www.example.com <deployment> # Link domain to deployment
62
- ship domains set www.example.com --label prod # Update labels only
67
+ ship domains set www.example.com # Reserve domain (no deployment yet)
68
+ ship domains set www.example.com <deployment> # Link domain to deployment
69
+ ship domains set www.example.com --label prod # Update labels only
63
70
  ship domains get www.example.com
64
- ship domains validate www.example.com # Check if domain is valid and available
65
- ship domains verify www.example.com # Trigger DNS verification
71
+ ship domains list
72
+ ship domains validate www.example.com
73
+ ship domains verify www.example.com
74
+ ship domains records www.example.com
75
+ ship domains dns www.example.com
76
+ ship domains share www.example.com
66
77
  ship domains remove www.example.com
67
78
  ```
68
79
 
69
- ### Tokens
70
-
71
- ```bash
72
- ship tokens list
73
- ship tokens create --ttl 3600 --label ci
74
- ship tokens remove <token>
80
+ ```typescript
81
+ ship.domains.set(name, { deployment?, labels? }) // Upsert — create, repoint, or label
82
+ ship.domains.get(name)
83
+ ship.domains.list()
84
+ ship.domains.validate(name)
85
+ ship.domains.verify(name)
86
+ ship.domains.records(name)
87
+ ship.domains.dns(name)
88
+ ship.domains.share(name)
89
+ ship.domains.remove(name)
75
90
  ```
76
91
 
77
- ### Account & Setup
78
-
79
- ```bash
80
- ship whoami
81
- ship config # Create or update ~/.shiprc
82
- ship ping # Check API connectivity
83
- ```
92
+ `domains.set()` is a merge-upsert — omitted fields are preserved on update, defaulted on create. Once linked, a domain cannot be unlinked (`{ deployment: null }` → 400). Switch deployments or delete the domain instead.
84
93
 
85
- ### Shell Completion
94
+ Domain names are normalized by the API — any case, Unicode accepted:
86
95
 
87
- ```bash
88
- ship completion install
89
- ship completion uninstall
96
+ ```typescript
97
+ ship.domains.set('WWW.Example.COM'); // www.example.com
98
+ ship.domains.set('www.münchen.de'); // Unicode supported
90
99
  ```
91
100
 
92
- ### Global Flags
101
+ ### Tokens
93
102
 
94
103
  ```bash
95
- --api-key <key> API key for authenticated deployments
96
- --deploy-token <token> Deploy token for single-use deployments
97
- --config <file> Custom config file path
98
- --label <label> Add label (repeatable)
99
- --no-path-detect Disable automatic path optimization
100
- --no-spa-detect Disable automatic SPA detection
101
- --no-color Disable colored output
102
- --json Output results in JSON format
103
- -q, --quiet Output only the resource identifier
104
- --version Show version information
104
+ ship tokens create --ttl 3600 --label ci
105
+ ship tokens list
106
+ ship tokens remove <token>
105
107
  ```
106
108
 
107
- ## SDK Usage
108
-
109
- ```javascript
110
- import Ship from '@shipstatic/ship';
111
-
112
- // Deploy — no credentials needed
113
- const ship = new Ship();
114
- const deployment = await ship.deploy('./dist');
115
- console.log(`Live: https://${deployment.deployment}`);
116
- console.log(`Claim: ${deployment.claim}`); // User visits to keep permanently
117
-
118
- // With an API key — deployments are permanent
119
- const ship = new Ship({ apiKey: 'ship-your-api-key' });
120
- const deployment = await ship.deploy('./dist', {
121
- labels: ['production', 'v1.0'],
122
- onProgress: ({ percent }) => console.log(`${percent}%`)
123
- });
124
-
125
- // Manage domains (requires API key)
126
- await ship.domains.set('www.example.com', { deployment: deployment.deployment });
127
- await ship.domains.list();
109
+ ```typescript
110
+ ship.tokens.create({ ttl?, labels? })
111
+ ship.tokens.list()
112
+ ship.tokens.remove(token)
128
113
  ```
129
114
 
130
- ## Browser Usage
131
-
132
- ```javascript
133
- import Ship from '@shipstatic/ship';
134
-
135
- const ship = new Ship({ apiKey: 'ship-your-api-key' });
136
-
137
- // From file input
138
- const files = Array.from(fileInput.files);
139
- const deployment = await ship.deploy(files);
115
+ ### Account
140
116
 
141
- // From StaticFile array
142
- const deployment = await ship.deploy([
143
- { path: 'index.html', content: new Blob(['<html>…</html>']) }
144
- ]);
117
+ ```bash
118
+ ship whoami
119
+ ship config
120
+ ship ping
145
121
  ```
146
122
 
147
- ## Authentication
148
-
149
- Deploying works without credentials. For permanent deployments and account features:
150
-
151
- ```javascript
152
- // API key (persistent access)
153
- const ship = new Ship({
154
- apiKey: 'ship-...' // 69 chars: ship- + 64 hex
155
- });
156
-
157
- // Deploy token (single-use)
158
- const ship = new Ship({
159
- deployToken: 'token-...' // 70 chars: token- + 64 hex
160
- });
161
-
162
- // Set credentials after construction
163
- ship.setApiKey('ship-...');
164
- ship.setDeployToken('token-...');
123
+ ```typescript
124
+ ship.account.get() // → whoami
125
+ ship.ping() // boolean
126
+ ship.getConfig() // → platform config and plan limits (cached)
165
127
  ```
166
128
 
167
- ## Configuration
129
+ ## CLI Reference
168
130
 
169
- **Constructor options** (highest priority):
170
- ```javascript
171
- new Ship({ apiUrl: '...', apiKey: '...' })
172
- ```
131
+ ### Composability
132
+
133
+ The `-q` flag outputs only the resource identifier — perfect for piping and scripting:
173
134
 
174
- **Environment variables** (Node.js):
175
135
  ```bash
176
- SHIP_API_URL=https://api.shipstatic.com
177
- SHIP_API_KEY=ship-your-api-key
178
- ```
136
+ # Deploy and link domain in one pipe
137
+ ship ./dist -q | ship domains set www.example.com
179
138
 
180
- **Config files** (Node.js, in order of precedence):
181
- ```json
182
- // .shiprc or package.json "ship" key
183
- { "apiUrl": "...", "apiKey": "..." }
184
- ```
139
+ # Deploy and open in browser
140
+ open https://$(ship ./dist -q)
185
141
 
186
- ## API Reference
142
+ # Batch remove all deployments
143
+ ship deployments list -q | xargs -I{} ship deployments remove {} -q
144
+ ```
187
145
 
188
- ### Top-level Methods
146
+ ### Shell Completion
189
147
 
190
- ```typescript
191
- ship.deploy(input, options?) // Deploy (shortcut for deployments.upload)
192
- ship.whoami() // Get current account (shortcut for account.get)
193
- ship.ping() // Check API connectivity (returns boolean)
194
- ship.getConfig() // Get platform config and plan limits
195
- ship.on(event, handler) // Add event listener
196
- ship.off(event, handler) // Remove event listener
197
- ship.setApiKey(key) // Set API key after construction
198
- ship.setDeployToken(token) // Set deploy token after construction
148
+ ```bash
149
+ ship completion install
150
+ ship completion uninstall
199
151
  ```
200
152
 
201
- ### Deployments
153
+ ### Global Flags
202
154
 
203
- ```typescript
204
- ship.deployments.upload(input, options?) // Upload new deployment
205
- ship.deployments.list() // List all deployments
206
- ship.deployments.get(deployment) // Get deployment details
207
- ship.deployments.set(deployment, { labels }) // Update deployment labels
208
- ship.deployments.remove(deployment) // Delete deployment
209
- ```
155
+ | Flag | Description |
156
+ |------|-------------|
157
+ | `--api-key <key>` | API key for authenticated requests |
158
+ | `--deploy-token <token>` | Deploy token for single-use deployments |
159
+ | `--config <file>` | Custom config file path |
160
+ | `--label <label>` | Add label (repeatable) |
161
+ | `--no-path-detect` | Disable automatic path optimization |
162
+ | `--no-spa-detect` | Disable automatic SPA detection |
163
+ | `--no-color` | Disable colored output |
164
+ | `--json` | Output results in JSON format |
165
+ | `-q, --quiet` | Output only the resource identifier |
166
+ | `--version` | Show version information |
210
167
 
211
- ### Domains
168
+ ## SDK Reference
212
169
 
213
- ```typescript
214
- ship.domains.set(name, options?) // Create/update domain (see below)
215
- ship.domains.get(name) // Get domain details
216
- ship.domains.list() // List all domains
217
- ship.domains.remove(name) // Delete domain
218
- ship.domains.validate(name) // Pre-flight: check if domain is valid and available
219
- ship.domains.verify(name) // Trigger async DNS verification
220
- ship.domains.dns(name) // Get DNS provider information
221
- ship.domains.records(name) // Get required DNS records
222
- ship.domains.share(name) // Get shareable domain hash
223
- ```
170
+ ### Authentication
224
171
 
225
- ### Tokens
172
+ ```javascript
173
+ // No credentials — deploy only, 3-day expiry
174
+ const ship = new Ship();
226
175
 
227
- ```typescript
228
- ship.tokens.create({ ttl?, labels? }) // Create deploy token
229
- ship.tokens.list() // List all tokens
230
- ship.tokens.remove(token) // Revoke token
231
- ```
176
+ // API key — permanent, full access
177
+ const ship = new Ship({ apiKey: 'ship-...' });
232
178
 
233
- ### Account
179
+ // Deploy token — single-use, consumed on successful deploy
180
+ const ship = new Ship({ deployToken: 'token-...' });
234
181
 
235
- ```typescript
236
- ship.account.get() // Get current account
182
+ // Set credentials after construction
183
+ ship.setApiKey('ship-...');
184
+ ship.setDeployToken('token-...');
237
185
  ```
238
186
 
239
- ### domains.set() Behavior
240
-
241
- `domains.set()` is a single upsert endpoint. Omitted fields are preserved on update and defaulted on create:
187
+ ### Deploy Options
242
188
 
243
189
  ```typescript
244
- // Reserve domain (no deployment yet)
245
- ship.domains.set('www.example.com');
246
-
247
- // Link domain to deployment
248
- ship.domains.set('www.example.com', { deployment: 'happy-cat-abc1234.shipstatic.com' });
249
-
250
- // Switch to a different deployment (atomic)
251
- ship.domains.set('www.example.com', { deployment: 'other-deploy-xyz7890.shipstatic.com' });
252
-
253
- // Update labels only (deployment preserved)
254
- ship.domains.set('www.example.com', { labels: ['prod', 'v2'] });
255
-
256
- // Update both
257
- ship.domains.set('www.example.com', { deployment: 'happy-cat-abc1234.shipstatic.com', labels: ['prod'] });
190
+ ship.deploy(input, {
191
+ labels?: string[],
192
+ onProgress?: ({ percent }) => void,
193
+ signal?: AbortSignal,
194
+ pathDetect?: boolean, // Auto-optimize paths (default: true)
195
+ spaDetect?: boolean, // Auto-detect SPA (default: true)
196
+ maxConcurrency?: number, // Concurrent uploads (default: 4)
197
+ timeout?: number, // Request timeout in ms
198
+ via?: string, // Client identifier
199
+ apiKey?: string, // Per-request API key override
200
+ deployToken?: string, // Per-request deploy token override
201
+ });
258
202
  ```
259
203
 
260
- **No unlinking:** Once a domain is linked, `{ deployment: null }` returns a 400 error. To take a site offline, deploy a maintenance page. To clean up, delete the domain.
204
+ ### Browser Usage
261
205
 
262
- **Domain format:** Domain names are FQDNs. The SDK accepts any format (case-insensitive, Unicode) — the API normalizes:
206
+ ```javascript
207
+ import Ship from '@shipstatic/ship';
263
208
 
264
- ```typescript
265
- ship.domains.set('WWW.Example.COM'); // → normalized to 'www.example.com'
266
- ship.domains.set('www.münchen.de'); // → Unicode supported
267
- ```
209
+ const ship = new Ship({ apiKey: 'ship-...' });
268
210
 
269
- ### Deploy Options
211
+ // From file input
212
+ const deployment = await ship.deploy(fileInput.files);
270
213
 
271
- ```typescript
272
- ship.deploy('./dist', {
273
- labels?: string[], // Labels for the deployment
274
- onProgress?: (info) => void, // Progress callback
275
- signal?: AbortSignal, // Cancellation
276
- pathDetect?: boolean, // Auto-optimize paths (default: true)
277
- spaDetect?: boolean, // Auto-detect SPA (default: true)
278
- maxConcurrency?: number, // Concurrent uploads (default: 4)
279
- timeout?: number, // Request timeout (ms)
280
- via?: string, // Client identifier (e.g. 'sdk', 'cli')
281
- apiKey?: string, // Per-request API key override
282
- deployToken?: string, // Per-request deploy token override
283
- })
214
+ // From StaticFile array
215
+ const deployment = await ship.deploy([
216
+ { path: 'index.html', content: new Blob(['<html>…</html>']) }
217
+ ]);
284
218
  ```
285
219
 
286
220
  ### Events
287
221
 
288
222
  ```javascript
289
- ship.on('request', (url, init) => console.log(`→ ${url}`));
290
- ship.on('response', (response, url) => console.log(`← ${response.status}`));
291
- ship.on('error', (error, url) => console.error(error));
292
-
293
- // Remove listeners
223
+ ship.on('request', (url, init) => {});
224
+ ship.on('response', (response, url) => {});
225
+ ship.on('error', (error, url) => {});
294
226
  ship.off('request', handler);
295
227
  ```
296
228
 
@@ -303,35 +235,35 @@ try {
303
235
  await ship.deploy('./dist');
304
236
  } catch (error) {
305
237
  if (isShipError(error)) {
306
- if (error.isAuthError()) { /* ... */ }
307
- if (error.isValidationError()) { /* ... */ }
308
- if (error.isNetworkError()) { /* ... */ }
238
+ error.isAuthError();
239
+ error.isValidationError();
240
+ error.isNetworkError();
309
241
  }
310
242
  }
311
243
  ```
312
244
 
313
- ## TypeScript
245
+ ## Configuration
246
+
247
+ Resolved in order of precedence:
248
+
249
+ 1. **Constructor options**: `new Ship({ apiUrl, apiKey })`
250
+ 2. **Environment variables**: `SHIP_API_URL`, `SHIP_API_KEY`
251
+ 3. **Config files**: `.shiprc` or `package.json` `"ship"` key
314
252
 
315
- Full TypeScript support with exported types:
253
+ ```bash
254
+ SHIP_API_KEY=ship-... ship deployments list
255
+ ```
256
+
257
+ ## TypeScript
316
258
 
317
259
  ```typescript
318
- import type {
319
- ShipClientOptions,
320
- DeploymentOptions,
321
- ShipEvents
322
- } from '@shipstatic/ship';
323
-
324
- import type {
325
- Deployment,
326
- Domain,
327
- Account,
328
- StaticFile
329
- } from '@shipstatic/types';
260
+ import type { ShipClientOptions, DeploymentOptions, ShipEvents } from '@shipstatic/ship';
261
+ import type { Deployment, Domain, Account, StaticFile } from '@shipstatic/types';
330
262
  ```
331
263
 
332
264
  ## AI Agents
333
265
 
334
- This package includes a [SKILL.md](./SKILL.md) file — a portable skill definition that AI agents (Claude Code, Codex, OpenClaw, etc.) use to deploy sites with `ship` autonomously.
266
+ This package includes a [SKILL.md](./SKILL.md) file — a portable skill definition that AI agents (Claude Code, Codex, etc.) use to deploy sites with `ship` autonomously.
335
267
 
336
268
  ---
337
269