@shipstatic/ship 2.2.0-beta.7 → 2.2.0-beta.9
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 +36 -1
- package/SKILL.md +26 -1
- package/THIRD-PARTY-LICENSES.md +1 -57
- package/dist/browser.d.ts +182 -66
- package/dist/browser.js +1 -1
- package/dist/browser.js.map +1 -1
- package/dist/cli.cjs +136 -147
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +177 -59
- package/dist/index.d.ts +177 -59
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -6
- package/dist/metafile-cjs.json +0 -1
- package/dist/metafile-esm.json +0 -1
package/README.md
CHANGED
|
@@ -48,6 +48,7 @@ const ship = new Ship({ token: 'ship-...' });
|
|
|
48
48
|
```bash
|
|
49
49
|
ship ./dist # Deploy (shortcut)
|
|
50
50
|
ship ./dist --domain www.example.com # Deploy and serve it there
|
|
51
|
+
ship ./dist --ttl 1h # Expires in an hour
|
|
51
52
|
ship ./dist --label production --label v1.0.0 # Deploy with labels
|
|
52
53
|
ship deployments list
|
|
53
54
|
ship deployments list --limit 20 # Page size; a hint shows the next cursor
|
|
@@ -106,7 +107,7 @@ ship.domains.set('www.münchen.de'); // → Unicode supported
|
|
|
106
107
|
### Tokens
|
|
107
108
|
|
|
108
109
|
```bash
|
|
109
|
-
ship tokens create --ttl
|
|
110
|
+
ship tokens create --ttl 30d --label ci # Or 3600, 90s, 1h — one grammar
|
|
110
111
|
ship tokens list
|
|
111
112
|
ship tokens get <token>
|
|
112
113
|
ship tokens delete <token>
|
|
@@ -153,6 +154,27 @@ open https://$(ship ./dist -q)
|
|
|
153
154
|
ship deployments list -q | xargs -I{} ship deployments delete {} -q
|
|
154
155
|
```
|
|
155
156
|
|
|
157
|
+
### Ephemeral deployments
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
ship ./dist --ttl 1h # gone in an hour
|
|
161
|
+
ship ./dist --ttl 7d # a week-long preview
|
|
162
|
+
ship ./dist --ttl 3600 # bare seconds work too
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The platform reclaims the deployment when the time is up. Seconds, or a
|
|
166
|
+
`<n><unit>` duration (`s`/`m`/`h`/`d`) — the same grammar `ship tokens create
|
|
167
|
+
--ttl` uses. Bounded at one year.
|
|
168
|
+
|
|
169
|
+
Two rules, both refused before anything uploads. It **needs a token**: an
|
|
170
|
+
anonymous deployment already expires on the platform's own schedule, so there
|
|
171
|
+
is no deployer to choose a different one. And it **cannot be combined with
|
|
172
|
+
`--domain`**: a domain is a commitment and a deadline is its opposite, so the
|
|
173
|
+
API refuses to point a domain at a deployment that expires.
|
|
174
|
+
|
|
175
|
+
To keep something longer, deploy it again — there is no way to extend a
|
|
176
|
+
deployment's life, and no way to shorten it after the fact.
|
|
177
|
+
|
|
156
178
|
`--domain` is the same two calls as one command:
|
|
157
179
|
|
|
158
180
|
```bash
|
|
@@ -192,6 +214,7 @@ Available on `ship <path>` and `ship deployments upload`:
|
|
|
192
214
|
| `--domain <domain>` | Serve this deployment at that domain — creates or repoints it. Needs a token |
|
|
193
215
|
| `--label <label>` | Add label (repeatable) |
|
|
194
216
|
| `--password <password>` | Password-protect this deployment (6–128 chars) |
|
|
217
|
+
| `--ttl <duration>` | Expire this deployment after that long — `3600`, `90s`, `30m`, `1h`, `7d`. Needs a token; cannot be combined with `--domain` |
|
|
195
218
|
| `--no-path-detect` | Disable automatic path optimization |
|
|
196
219
|
| `--no-spa-detect` | Disable automatic SPA detection |
|
|
197
220
|
|
|
@@ -255,6 +278,7 @@ own `signal` (`AbortSignal.timeout(ms)`), which is never retried past.
|
|
|
255
278
|
ship.deploy(input, {
|
|
256
279
|
labels?: string[],
|
|
257
280
|
password?: string, // Password-protect the deployment (6–128 chars)
|
|
281
|
+
ttl?: number, // Seconds until it expires (needs a token; max 1 year)
|
|
258
282
|
signal?: AbortSignal, // Abort to cancel the deploy
|
|
259
283
|
pathDetect?: boolean, // Auto-optimize paths (default: true)
|
|
260
284
|
spaDetect?: boolean, // Auto-detect SPA (default: true)
|
|
@@ -262,6 +286,17 @@ ship.deploy(input, {
|
|
|
262
286
|
});
|
|
263
287
|
```
|
|
264
288
|
|
|
289
|
+
#### Expiring deployments
|
|
290
|
+
|
|
291
|
+
Pass `ttl` in **seconds** and the platform reclaims the deployment when the time is up — 1 second to one year. The wire carries the duration and the API stamps `expires` against its own clock, so the answer says when:
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
const result = await ship.deploy('./dist', { ttl: 3600 });
|
|
295
|
+
// result.expires → unix seconds, one hour after result.created
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Needs a credential — an anonymous deployment already expires on the platform's own schedule. And a deployment carrying a ttl cannot be linked to a domain: the API refuses, which is what stops a domain pointing at something that is about to be reclaimed. There is no way to extend or shorten a deployment after the fact; redeploy instead.
|
|
299
|
+
|
|
265
300
|
#### Password protection
|
|
266
301
|
|
|
267
302
|
Pass `password` (6–128 characters) to gate the deployment behind a prompt. Visitors are asked for the password before they can view the site, including on any custom domains pointing at it. To remove protection, redeploy without a password.
|
package/SKILL.md
CHANGED
|
@@ -43,6 +43,27 @@ Without credentials, deployments are public and expire in 3 days. **Always show
|
|
|
43
43
|
|
|
44
44
|
The deployment ID **is** the URL hostname. Use the full ID (e.g. `happy-cat-abc1234.shipstatic.com`) as the argument to all other commands. The site lives at `https://<deployment>`.
|
|
45
45
|
|
|
46
|
+
### Deployments that clean themselves up
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
ship ./dist --ttl 1h # gone in an hour
|
|
50
|
+
ship ./dist --ttl 7d # a week-long preview
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
For a preview nobody needs to keep — a draft, a diff, a one-off render. The
|
|
54
|
+
platform reclaims it when the time is up, so nothing accumulates in the user's
|
|
55
|
+
account and nobody has to remember to delete it. Seconds or a `<n><unit>`
|
|
56
|
+
duration (`s`/`m`/`h`/`d`), up to a year.
|
|
57
|
+
|
|
58
|
+
**It needs a token.** Without one the deploy is anonymous and already expires
|
|
59
|
+
in 3 days on the platform's own schedule — there is no deployer to choose a
|
|
60
|
+
different lifetime, and the CLI refuses before uploading anything. **It cannot
|
|
61
|
+
be combined with `--domain`**, because a domain must not point at something
|
|
62
|
+
about to be reclaimed.
|
|
63
|
+
|
|
64
|
+
The response's `expires` is the answer, in unix seconds — read it there rather
|
|
65
|
+
than computing it, since the platform stamps it against its own clock.
|
|
66
|
+
|
|
46
67
|
### Parsing output
|
|
47
68
|
|
|
48
69
|
```bash
|
|
@@ -238,6 +259,7 @@ List commands return `{"<resource>s": [...], "cursor": null}`. A non-null `curso
|
|
|
238
259
|
```bash
|
|
239
260
|
ship ./dist # Deploy (shortcut)
|
|
240
261
|
ship ./dist --domain <name> # Deploy and serve it at that domain
|
|
262
|
+
ship ./dist --ttl 1h # Expires in an hour (needs a token)
|
|
241
263
|
ship deployments upload <path> # Deploy (explicit)
|
|
242
264
|
ship deployments list # List all
|
|
243
265
|
ship deployments get <deployment> # Details
|
|
@@ -265,7 +287,7 @@ ship domains delete <name> # Delete
|
|
|
265
287
|
ship whoami # Account info
|
|
266
288
|
ship ping # Connectivity check
|
|
267
289
|
ship tokens create # New deploy token (shown once)
|
|
268
|
-
ship tokens create --ttl
|
|
290
|
+
ship tokens create --ttl 30d # With expiry — 3600, 90s, 1h, 30d
|
|
269
291
|
ship tokens list # List tokens
|
|
270
292
|
ship tokens get <token> # Details for one token
|
|
271
293
|
ship tokens delete <token> # Delete (revokes immediately)
|
|
@@ -281,6 +303,7 @@ ship tokens delete <token> # Delete (revokes immediately)
|
|
|
281
303
|
| `--domain <domain>` | Deploy and serve it there — creates or repoints. Needs a token |
|
|
282
304
|
| `--label <label>` | Set label (repeatable, replaces all) |
|
|
283
305
|
| `--password <pwd>` | Password-protect deployment (6–128 chars) |
|
|
306
|
+
| `--ttl <duration>` | Expire after that long — `3600`, `90s`, `1h`, `7d`. Needs a token; not with `--domain` |
|
|
284
307
|
| `--no-path-detect` | Skip build output auto-detection |
|
|
285
308
|
| `--no-spa-detect` | Skip SPA rewrite auto-configuration |
|
|
286
309
|
| `--no-color` | Disable colors |
|
|
@@ -295,6 +318,8 @@ ship tokens delete <token> # Delete (revokes immediately)
|
|
|
295
318
|
| `not found` | No such resource | Verify the ID/name |
|
|
296
319
|
| `path does not exist` | Bad deploy path | Check file/directory |
|
|
297
320
|
| `invalid domain name` | Not a subdomain | Use `www.example.com`, not `example.com` |
|
|
321
|
+
| `--ttl sets an expiry, which needs a token` | `--ttl` without credentials | Set an API key, or drop `--ttl` |
|
|
322
|
+
| `--ttl and --domain cannot be combined` | Both flags given | A domain cannot point at an expiring deployment — pick one |
|
|
298
323
|
| `<resource> limit reached` | Plan caps hit (deployments, domains) | Suggest upgrading the plan; do not retry |
|
|
299
324
|
| `Account has been deleted` / `Account terminated` | Account is gone | Stop; the account cannot deploy |
|
|
300
325
|
| `DNS information is only available for external domains` | DNS op on internal domain | Only custom domains need DNS |
|
package/THIRD-PARTY-LICENSES.md
CHANGED
|
@@ -5,7 +5,7 @@ Their copyright notices travel with that copy, and are reproduced here in
|
|
|
5
5
|
full. This file is GENERATED from the build's own metafile — edit the
|
|
6
6
|
bundle, not this list.
|
|
7
7
|
|
|
8
|
-
## @shipstatic/types 2.7.0-beta.
|
|
8
|
+
## @shipstatic/types 2.7.0-beta.4
|
|
9
9
|
|
|
10
10
|
License: MIT
|
|
11
11
|
|
|
@@ -160,62 +160,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
160
160
|
THE SOFTWARE.
|
|
161
161
|
```
|
|
162
162
|
|
|
163
|
-
## form-data-encoder 4.1.0
|
|
164
|
-
|
|
165
|
-
License: MIT
|
|
166
|
-
|
|
167
|
-
```
|
|
168
|
-
The MIT License (MIT)
|
|
169
|
-
|
|
170
|
-
Copyright (c) 2021-present Nick K.
|
|
171
|
-
|
|
172
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
173
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
174
|
-
in the Software without restriction, including without limitation the rights
|
|
175
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
176
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
177
|
-
furnished to do so, subject to the following conditions:
|
|
178
|
-
|
|
179
|
-
The above copyright notice and this permission notice shall be included in all
|
|
180
|
-
copies or substantial portions of the Software.
|
|
181
|
-
|
|
182
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
183
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
184
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
185
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
186
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
187
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
188
|
-
SOFTWARE.
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
## formdata-node 6.0.3
|
|
192
|
-
|
|
193
|
-
License: MIT
|
|
194
|
-
|
|
195
|
-
```
|
|
196
|
-
The MIT License (MIT)
|
|
197
|
-
|
|
198
|
-
Copyright (c) 2017-present Nick K.
|
|
199
|
-
|
|
200
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
201
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
202
|
-
in the Software without restriction, including without limitation the rights
|
|
203
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
204
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
205
|
-
furnished to do so, subject to the following conditions:
|
|
206
|
-
|
|
207
|
-
The above copyright notice and this permission notice shall be included in all
|
|
208
|
-
copies or substantial portions of the Software.
|
|
209
|
-
|
|
210
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
211
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
212
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
213
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
214
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
215
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
216
|
-
SOFTWARE.
|
|
217
|
-
```
|
|
218
|
-
|
|
219
163
|
## junk 4.0.1
|
|
220
164
|
|
|
221
165
|
License: MIT
|
package/dist/browser.d.ts
CHANGED
|
@@ -671,6 +671,12 @@ declare const DEPLOY_FIELDS: {
|
|
|
671
671
|
readonly VIA: "via";
|
|
672
672
|
/** Plaintext password — the API hashes it server-side. */
|
|
673
673
|
readonly PASSWORD: "password";
|
|
674
|
+
/**
|
|
675
|
+
* Requested lifetime in SECONDS — a duration, never an instant. The API
|
|
676
|
+
* computes and stores the expiry, so the wire carries no client clock.
|
|
677
|
+
* See {@link validateTtl}.
|
|
678
|
+
*/
|
|
679
|
+
readonly TTL: "ttl";
|
|
674
680
|
/** @internal Server-processing flag — first-party `/upload` only. */
|
|
675
681
|
readonly BUILD: "build";
|
|
676
682
|
/** @internal Server-processing flag — first-party `/upload` only. */
|
|
@@ -1259,6 +1265,47 @@ declare function validateApiUrl(apiUrl: string): void;
|
|
|
1259
1265
|
* Example: "happy-cat-abc1234.shipstatic.com"
|
|
1260
1266
|
*/
|
|
1261
1267
|
declare function isDeployment(input: string): boolean;
|
|
1268
|
+
/**
|
|
1269
|
+
* The envelope a requested lifetime must fit — one word, one grammar, wherever
|
|
1270
|
+
* the platform lets a caller choose how long something lives.
|
|
1271
|
+
*
|
|
1272
|
+
* Two resources wear it: `TokenCreateOptions.ttl` and
|
|
1273
|
+
* `DeploymentUploadOptions.ttl`. It lives here rather than on the server by
|
|
1274
|
+
* the format-vs-policy rule — a client can decide offline whether a duration
|
|
1275
|
+
* is well-formed, and the API rejects the same value the same way. What is
|
|
1276
|
+
* NOT here is any per-plan ceiling: no such policy exists, and one delivered
|
|
1277
|
+
* speculatively through `/limits` would be an owner for a decision nobody has
|
|
1278
|
+
* made.
|
|
1279
|
+
*/
|
|
1280
|
+
declare const TTL_CONSTRAINTS: {
|
|
1281
|
+
/**
|
|
1282
|
+
* Shortest requestable lifetime, in seconds. One rather than zero: a
|
|
1283
|
+
* deployment that expires the instant it is created is not a shorter lease,
|
|
1284
|
+
* it is a deploy that was never live, and `0` is how an unset variable
|
|
1285
|
+
* arrives.
|
|
1286
|
+
*/
|
|
1287
|
+
readonly MIN_SECONDS: 1;
|
|
1288
|
+
/** Longest requestable lifetime, in seconds — one year. */
|
|
1289
|
+
readonly MAX_SECONDS: number;
|
|
1290
|
+
};
|
|
1291
|
+
/**
|
|
1292
|
+
* Validate a requested lifetime in SECONDS and return it, or `undefined` when
|
|
1293
|
+
* none was asked for.
|
|
1294
|
+
*
|
|
1295
|
+
* **A duration, never an instant.** The caller says how long; the server owns
|
|
1296
|
+
* what time it is and stamps the expiry — so a client's clock, however wrong,
|
|
1297
|
+
* cannot shorten or extend a lease. That is the tokens precedent, and it is
|
|
1298
|
+
* why this rule measures a count of seconds rather than checking a timestamp
|
|
1299
|
+
* against `now`.
|
|
1300
|
+
*
|
|
1301
|
+
* Fractions are refused rather than rounded: a caller who wrote `1.5` meant
|
|
1302
|
+
* something the wire cannot carry, and silently choosing `1` or `2` for them
|
|
1303
|
+
* is a decision the platform has no standing to make.
|
|
1304
|
+
*
|
|
1305
|
+
* Single source of truth shared by the API (the tokens route and the deploy
|
|
1306
|
+
* schema), the SDK's request boundary, and the CLI's parser.
|
|
1307
|
+
*/
|
|
1308
|
+
declare function validateTtl(value: unknown): number | undefined;
|
|
1262
1309
|
/**
|
|
1263
1310
|
* Request payload for SPA check endpoint
|
|
1264
1311
|
*/
|
|
@@ -1391,6 +1438,27 @@ interface DeploymentUploadOptions {
|
|
|
1391
1438
|
* into missing analytics rather than an error. See {@link DeploymentVia}.
|
|
1392
1439
|
*/
|
|
1393
1440
|
via?: DeploymentViaType;
|
|
1441
|
+
/**
|
|
1442
|
+
* Seconds until this deployment expires; omit for one that never does.
|
|
1443
|
+
*
|
|
1444
|
+
* The platform reclaims it when the time is up — an ephemeral deployment,
|
|
1445
|
+
* chosen by the deployer rather than by the identity. The same word and the
|
|
1446
|
+
* same grammar as {@link TokenCreateOptions.ttl}, bounded by
|
|
1447
|
+
* {@link TTL_CONSTRAINTS}.
|
|
1448
|
+
*
|
|
1449
|
+
* **Requires a credential.** An anonymous deploy has no deployer, and the
|
|
1450
|
+
* platform owns anonymous lifetime as policy
|
|
1451
|
+
* ({@link PUBLIC_DEPLOYMENT_TTL_SECONDS}) — so a ttl on one is refused
|
|
1452
|
+
* rather than honoured or ignored.
|
|
1453
|
+
*
|
|
1454
|
+
* **A deployment carrying one cannot be linked to a domain.** A domain is a
|
|
1455
|
+
* commitment and a deadline is its opposite; the API refuses the link, which
|
|
1456
|
+
* is what keeps the reaper from tearing a live domain's target away.
|
|
1457
|
+
*
|
|
1458
|
+
* Immutable, like every other field of a deployment: to keep something
|
|
1459
|
+
* longer, redeploy.
|
|
1460
|
+
*/
|
|
1461
|
+
ttl?: number;
|
|
1394
1462
|
/**
|
|
1395
1463
|
* Optional password that protects this deployment.
|
|
1396
1464
|
*
|
|
@@ -1829,14 +1897,6 @@ interface DeploymentOptions extends DeploymentUploadOptions {
|
|
|
1829
1897
|
spaDetect?: boolean;
|
|
1830
1898
|
}
|
|
1831
1899
|
type ApiDeployOptions = Omit<DeploymentOptions, 'pathDetect'>;
|
|
1832
|
-
/**
|
|
1833
|
-
* Prepared request body for deployment.
|
|
1834
|
-
* Created by platform-specific code, consumed by HTTP client.
|
|
1835
|
-
*/
|
|
1836
|
-
interface DeployBody {
|
|
1837
|
-
body: FormData | ArrayBuffer;
|
|
1838
|
-
headers: Record<string, string>;
|
|
1839
|
-
}
|
|
1840
1900
|
/**
|
|
1841
1901
|
* Context passed to the deploy body creator — everything that becomes a
|
|
1842
1902
|
* form field alongside the files themselves.
|
|
@@ -1860,6 +1920,11 @@ interface DeployBodyContext {
|
|
|
1860
1920
|
* characters. Whitespace is preserved verbatim — significant.
|
|
1861
1921
|
*/
|
|
1862
1922
|
password?: string;
|
|
1923
|
+
/**
|
|
1924
|
+
* Requested lifetime in SECONDS — a duration, never an instant, bounded by
|
|
1925
|
+
* `TTL_CONSTRAINTS`. The API stamps the expiry against its own clock.
|
|
1926
|
+
*/
|
|
1927
|
+
ttl?: number;
|
|
1863
1928
|
/** @internal Server-side processing flags. */
|
|
1864
1929
|
flags?: {
|
|
1865
1930
|
build?: boolean;
|
|
@@ -1869,11 +1934,6 @@ interface DeployBodyContext {
|
|
|
1869
1934
|
/** @internal reCAPTCHA proof for the anonymous human deploy channel (/upload). */
|
|
1870
1935
|
captcha?: string;
|
|
1871
1936
|
}
|
|
1872
|
-
/**
|
|
1873
|
-
* Function that creates a deploy request body from files.
|
|
1874
|
-
* Implemented differently for Node.js and Browser.
|
|
1875
|
-
*/
|
|
1876
|
-
type DeployBodyCreator = (files: StaticFile[], context?: DeployBodyContext) => Promise<DeployBody>;
|
|
1877
1937
|
/** Standard `fetch` signature — the type of the `fetch` client option. */
|
|
1878
1938
|
type Fetch = typeof fetch;
|
|
1879
1939
|
/**
|
|
@@ -2071,28 +2131,72 @@ declare class SimpleEvents {
|
|
|
2071
2131
|
emit<K extends keyof ShipEvents>(event: K, ...args: ShipEvents[K]): void;
|
|
2072
2132
|
}
|
|
2073
2133
|
|
|
2074
|
-
/**
|
|
2075
|
-
* @file HTTP client for Ship API.
|
|
2076
|
-
*/
|
|
2077
|
-
|
|
2078
2134
|
interface ApiHttpOptions extends ShipClientOptions {
|
|
2079
2135
|
/** Resolves the credential slot per request — async so token providers can mint/refresh. */
|
|
2080
2136
|
getAuthHeaders: () => Record<string, string> | Promise<Record<string, string>>;
|
|
2081
|
-
createDeployBody: DeployBodyCreator;
|
|
2082
2137
|
}
|
|
2083
|
-
|
|
2138
|
+
interface RequestResult<T> {
|
|
2139
|
+
data: T;
|
|
2140
|
+
status: number;
|
|
2141
|
+
}
|
|
2142
|
+
/**
|
|
2143
|
+
* The deploy's CARRIAGE — the two facts about a deploy that are transport's
|
|
2144
|
+
* rather than the deployment resource's.
|
|
2145
|
+
*
|
|
2146
|
+
* The numbers are transport's because a budget for how long to wait on a wire
|
|
2147
|
+
* is nothing else, and the endpoint is transport's because `deployEndpoint` is
|
|
2148
|
+
* a client option that redirects the route. The CHOICE between the two
|
|
2149
|
+
* ceilings is the resource's, because only it knows that `build`/`prerender`
|
|
2150
|
+
* wait on work the server does after the upload lands.
|
|
2151
|
+
*/
|
|
2152
|
+
interface DeployTransport {
|
|
2153
|
+
/** `/deployments`, or `/upload` where the `@internal` option redirects it. */
|
|
2154
|
+
readonly endpoint: string;
|
|
2155
|
+
/** The ordinary deploy ceiling. */
|
|
2156
|
+
readonly timeout: number;
|
|
2157
|
+
/** The ceiling when the server will also build. */
|
|
2158
|
+
readonly buildTimeout: number;
|
|
2159
|
+
}
|
|
2160
|
+
/**
|
|
2161
|
+
* What a resource may ask of the transport: carry this request, and tell me
|
|
2162
|
+
* what came back.
|
|
2163
|
+
*
|
|
2164
|
+
* This interface is the whole seam. `resources.ts` states WHICH request — the
|
|
2165
|
+
* path, the verb, the body, the response type — and hands it here; nothing
|
|
2166
|
+
* above this line knows the base URL, the credential, the retry policy or the
|
|
2167
|
+
* event vocabulary, and nothing below knows what a domain is.
|
|
2168
|
+
*/
|
|
2169
|
+
interface Transport {
|
|
2170
|
+
request<T>(path: string, options: ShipRequestInit, operationName: string, timeoutMs?: number): Promise<T>;
|
|
2171
|
+
requestWithStatus<T>(path: string, options: ShipRequestInit, operationName: string): Promise<RequestResult<T>>;
|
|
2172
|
+
readonly deploy: DeployTransport;
|
|
2173
|
+
}
|
|
2174
|
+
/**
|
|
2175
|
+
* A request as THIS client composes one.
|
|
2176
|
+
*
|
|
2177
|
+
* Identical to `RequestInit` but for the headers, which are narrowed from the
|
|
2178
|
+
* DOM's three-shaped `HeadersInit` to the one shape every call site here
|
|
2179
|
+
* actually builds. That narrowing is load-bearing twice over: `mergeHeaders`
|
|
2180
|
+
* used to reach its record through an `as` cast, and `hasIdempotencyKey` used
|
|
2181
|
+
* to walk all three shapes to find a key that only ever arrives in one of
|
|
2182
|
+
* them. Narrowing at RUNTIME instead would have turned an unreachable case
|
|
2183
|
+
* into a SILENT no-retry — a deploy that quietly stopped replaying because
|
|
2184
|
+
* someone handed the transport a `Headers`. Here that is a compile error.
|
|
2185
|
+
*/
|
|
2186
|
+
type ShipRequestInit = Omit<RequestInit, 'headers'> & {
|
|
2187
|
+
headers?: Record<string, string>;
|
|
2188
|
+
};
|
|
2189
|
+
declare class ApiHttp extends SimpleEvents implements Transport {
|
|
2084
2190
|
private readonly apiUrl;
|
|
2085
2191
|
private readonly getAuthHeadersCallback;
|
|
2086
2192
|
private readonly session;
|
|
2087
2193
|
private readonly caller;
|
|
2088
2194
|
private readonly timeout;
|
|
2089
2195
|
private readonly maxRetries;
|
|
2090
|
-
private readonly deployTimeout;
|
|
2091
|
-
private readonly deployBuildTimeout;
|
|
2092
2196
|
private readonly fetch;
|
|
2093
|
-
private readonly createDeployBody;
|
|
2094
|
-
private readonly deployEndpoint;
|
|
2095
2197
|
private globalHeaders;
|
|
2198
|
+
/** @see DeployTransport — the carriage facts the deployment resource reads. */
|
|
2199
|
+
readonly deploy: DeployTransport;
|
|
2096
2200
|
constructor(options: ApiHttpOptions);
|
|
2097
2201
|
/**
|
|
2098
2202
|
* Set global headers included in every request.
|
|
@@ -2131,7 +2235,13 @@ declare class ApiHttp extends SimpleEvents {
|
|
|
2131
2235
|
* is one that may be sent twice.
|
|
2132
2236
|
*/
|
|
2133
2237
|
private isRetryable;
|
|
2134
|
-
/**
|
|
2238
|
+
/**
|
|
2239
|
+
* Did this request carry the header that makes a repeat safe?
|
|
2240
|
+
*
|
|
2241
|
+
* Case-insensitively, because HTTP field names are — the CLI's env tier and
|
|
2242
|
+
* the SDK option both spell it canonically, but a caller composing headers
|
|
2243
|
+
* by hand is entitled not to.
|
|
2244
|
+
*/
|
|
2135
2245
|
private hasIdempotencyKey;
|
|
2136
2246
|
/**
|
|
2137
2247
|
* One attempt: headers, timeout signal, the `request`/`response` events, and
|
|
@@ -2143,51 +2253,56 @@ declare class ApiHttp extends SimpleEvents {
|
|
|
2143
2253
|
*/
|
|
2144
2254
|
private attemptOnce;
|
|
2145
2255
|
/**
|
|
2146
|
-
*
|
|
2256
|
+
* Send it; resolve what came back.
|
|
2257
|
+
*
|
|
2258
|
+
* Takes a PATH, not a URL: the base is this client's and nothing above needs
|
|
2259
|
+
* to know it. Twenty-two call sites wrote `${this.apiUrl}${API_PATHS.X}` by
|
|
2260
|
+
* hand before the endpoints moved out, which is twenty-two chances to
|
|
2261
|
+
* assemble it differently.
|
|
2147
2262
|
*/
|
|
2148
|
-
|
|
2263
|
+
request<T>(path: string, options: ShipRequestInit, operationName: string, timeoutMs?: number): Promise<T>;
|
|
2149
2264
|
/**
|
|
2150
|
-
*
|
|
2265
|
+
* The same, plus the HTTP status — for the one operation where the status IS
|
|
2266
|
+
* the answer: a domain upsert says create-or-update in its 201/200 and
|
|
2267
|
+
* nowhere else in the response.
|
|
2151
2268
|
*/
|
|
2152
|
-
|
|
2269
|
+
requestWithStatus<T>(path: string, options: ShipRequestInit, operationName: string): Promise<RequestResult<T>>;
|
|
2153
2270
|
private mergeHeaders;
|
|
2154
2271
|
private createTimeoutSignal;
|
|
2155
2272
|
private safeClone;
|
|
2156
2273
|
private parseResponse;
|
|
2157
|
-
deploy(files: StaticFile[], options?: ApiDeployOptions): Promise<DeploymentCreateResponse>;
|
|
2158
|
-
listDeployments(options?: ListOptions): Promise<DeploymentListResponse>;
|
|
2159
|
-
getDeployment(id: string): Promise<Deployment>;
|
|
2160
|
-
updateDeploymentLabels(id: string, labels: string[]): Promise<Deployment>;
|
|
2161
|
-
deleteDeployment(id: string): Promise<DeploymentDeleteResponse>;
|
|
2162
|
-
setDomain(name: string, deployment?: string, labels?: string[]): Promise<DomainSetResult>;
|
|
2163
|
-
listDomains(options?: ListOptions): Promise<DomainListResponse>;
|
|
2164
|
-
getDomain(name: string): Promise<Domain>;
|
|
2165
|
-
deleteDomain(name: string): Promise<DomainDeleteResponse>;
|
|
2166
|
-
verifyDomain(name: string): Promise<DomainVerifyResponse>;
|
|
2167
|
-
getDomainDns(name: string): Promise<DomainDnsResponse>;
|
|
2168
|
-
getDomainRecords(name: string): Promise<DomainRecordsResponse>;
|
|
2169
|
-
getDomainShare(name: string): Promise<DomainShareResponse>;
|
|
2170
|
-
validateDomain(name: string): Promise<DomainValidateResponse>;
|
|
2171
|
-
createToken(ttl?: number, labels?: string[]): Promise<TokenCreateResponse>;
|
|
2172
|
-
listTokens(options?: ListOptions): Promise<TokenListResponse>;
|
|
2173
|
-
deleteToken(token: string): Promise<TokenDeleteResponse>;
|
|
2174
|
-
getToken(token: string): Promise<Token>;
|
|
2175
|
-
getAccount(): Promise<AccountGetResponse>;
|
|
2176
|
-
getLimits(): Promise<PlatformLimits>;
|
|
2177
|
-
ping(): Promise<PingResponse>;
|
|
2178
|
-
checkSPA(files: StaticFile[], _options?: ApiDeployOptions): Promise<boolean>;
|
|
2179
2274
|
}
|
|
2180
2275
|
|
|
2181
2276
|
/**
|
|
2182
|
-
*
|
|
2277
|
+
* @file The SDK's vocabulary — every request it can make, stated once.
|
|
2278
|
+
*
|
|
2279
|
+
* A resource method IS its endpoint: the path, the verb, the body, the
|
|
2280
|
+
* response type. It hands that to the transport, which knows how to carry a
|
|
2281
|
+
* request and nothing about what one means.
|
|
2282
|
+
*
|
|
2283
|
+
* **These were two layers until 2026-08-12.** `ApiHttp` carried eighteen
|
|
2284
|
+
* endpoint methods and every factory below wrapped one of them 1:1 —
|
|
2285
|
+
* `get: async (name) => getApi().getDomain(name)` — because this SDK mirrors
|
|
2286
|
+
* the wire one method per endpoint BY DESIGN (see CLAUDE.md, "Recorded
|
|
2287
|
+
* absences"). That design is exactly what made the second layer a restatement
|
|
2288
|
+
* rather than an adapter: the two could not diverge without one of them being
|
|
2289
|
+
* wrong. Folding DOWN rather than up is what keeps the public grouping and the
|
|
2290
|
+
* transport separate, which was the whole point of having two files.
|
|
2291
|
+
*
|
|
2292
|
+
* The `*Resource` interfaces come from `@shipstatic/types` and did not move.
|
|
2293
|
+
* They are the published contract; this file is how it is met.
|
|
2183
2294
|
*/
|
|
2184
2295
|
|
|
2185
2296
|
/**
|
|
2186
2297
|
* Shared context for all resource factories.
|
|
2298
|
+
*
|
|
2299
|
+
* A factory receives the callbacks it needs and nothing else — which is what
|
|
2300
|
+
* lets `getApi()` be a THUNK rather than an instance: the transport is built
|
|
2301
|
+
* once in the constructor, but reading it lazily is what keeps the resources
|
|
2302
|
+
* constructible before it exists and swappable in tests.
|
|
2187
2303
|
*/
|
|
2188
2304
|
interface ResourceContext {
|
|
2189
|
-
getApi: () =>
|
|
2190
|
-
ensureInit: () => Promise<void>;
|
|
2305
|
+
getApi: () => Transport;
|
|
2191
2306
|
}
|
|
2192
2307
|
/**
|
|
2193
2308
|
* Extended context for deployment resource.
|
|
@@ -2236,7 +2351,6 @@ declare abstract class Ship$1 {
|
|
|
2236
2351
|
private credential;
|
|
2237
2352
|
constructor(options?: ShipClientOptions);
|
|
2238
2353
|
protected abstract processInput(input: DeployInput, options: DeploymentOptions): Promise<StaticFile[]>;
|
|
2239
|
-
protected abstract getDeployBodyCreator(): DeployBodyCreator;
|
|
2240
2354
|
/**
|
|
2241
2355
|
* Lazy initialization — fetches platform limits (file size / count caps) once,
|
|
2242
2356
|
* on the first API call. Subsequent calls reuse the resolved promise.
|
|
@@ -2601,23 +2715,26 @@ declare function validateDeployFile(input: FileRuleInput, limits: PlatformLimits
|
|
|
2601
2715
|
declare function pluralize(count: number, singular: string, plural: string, includeCount?: boolean): string;
|
|
2602
2716
|
|
|
2603
2717
|
/**
|
|
2604
|
-
* @file
|
|
2605
|
-
* Provides helpers for processing browser files into deploy-ready objects.
|
|
2718
|
+
* @file The browser half of the deploy pipeline: reading paths off `File`s.
|
|
2606
2719
|
*
|
|
2607
|
-
*
|
|
2608
|
-
*
|
|
2609
|
-
*
|
|
2610
|
-
*
|
|
2720
|
+
* Everything after is shared (`shared/core/deploy-files.ts`) — path
|
|
2721
|
+
* optimization, junk filtering, the platform's rules, the checksums. What is
|
|
2722
|
+
* genuinely browser here is one line: a directory drop carries
|
|
2723
|
+
* `webkitRelativePath`, a file picker does not.
|
|
2611
2724
|
*
|
|
2612
|
-
*
|
|
2725
|
+
* There is no size to look up and no content to fetch, because a `File`
|
|
2726
|
+
* already is both. That is the whole of this platform's collection step, and
|
|
2727
|
+
* it is why the seam the Node side needs (`size` before `read()`) costs
|
|
2728
|
+
* nothing on this one.
|
|
2613
2729
|
*/
|
|
2614
2730
|
|
|
2615
2731
|
/**
|
|
2616
2732
|
* Processes browser files into an array of StaticFile objects ready for deploy.
|
|
2617
|
-
* Calculates MD5, filters junk files, validates sizes, and applies path optimization.
|
|
2618
2733
|
*
|
|
2619
|
-
* For server-processed uploads (build
|
|
2620
|
-
*
|
|
2734
|
+
* For server-processed uploads (`build`/`prerender`), the shared processor
|
|
2735
|
+
* skips deploy validation — the build service produces and validates the
|
|
2736
|
+
* actual deployment output. Those flags are `@internal` and this is their only
|
|
2737
|
+
* platform: `web/my` and `web/www` set them through `/upload`.
|
|
2621
2738
|
*
|
|
2622
2739
|
* @param browserFiles - File[] to process for deploy.
|
|
2623
2740
|
* @param options - Processing options including pathDetect for automatic path optimization.
|
|
@@ -2666,7 +2783,6 @@ declare class Ship extends Ship$1 {
|
|
|
2666
2783
|
*/
|
|
2667
2784
|
deploy(input: File[], options?: DeploymentOptions): Promise<DeploymentCreateResponse>;
|
|
2668
2785
|
protected processInput(input: DeployInput, options: DeploymentOptions): Promise<StaticFile[]>;
|
|
2669
|
-
protected getDeployBodyCreator(): DeployBodyCreator;
|
|
2670
2786
|
}
|
|
2671
2787
|
|
|
2672
|
-
export { API_KEY, API_PATHS, AUTH_BASE_PATH, type Account, type AccountDeleteResponse, type AccountGetResponse, type AccountKeyResponse, type AccountOverrides, AccountPlan, type AccountPlanType, type AccountResource, type AccountUsage, type Activity, type ActivityEvent, type ActivityListResponse, type ActivityMeta, type ApiDeployOptions, ApiHttp, type ApiHttpOptions, AuthMethod, type AuthMethodType, type BillingCancelResponse, type BillingStatus, CALLER, type CheckoutSession, DEFAULT_API, DEPLOYMENT_CONFIG_FILENAME, DEPLOY_FIELDS, DEPLOY_TOKEN, type
|
|
2788
|
+
export { API_KEY, API_PATHS, AUTH_BASE_PATH, type Account, type AccountDeleteResponse, type AccountGetResponse, type AccountKeyResponse, type AccountOverrides, AccountPlan, type AccountPlanType, type AccountResource, type AccountUsage, type Activity, type ActivityEvent, type ActivityListResponse, type ActivityMeta, type ApiDeployOptions, ApiHttp, type ApiHttpOptions, AuthMethod, type AuthMethodType, type BillingCancelResponse, type BillingStatus, CALLER, type CheckoutSession, DEFAULT_API, DEPLOYMENT_CONFIG_FILENAME, DEPLOY_FIELDS, DEPLOY_TOKEN, type DeployBodyContext, type DeployFile, type DeployInput, type DeployTransport, type Deployment, type DeploymentCreateResponse, type DeploymentDeleteResponse, type DeploymentListResponse, type DeploymentOptions, type DeploymentResource, type DeploymentResourceContext, type DeploymentSetOptions, DeploymentStatus, type DeploymentStatusType, type DeploymentUploadOptions, DeploymentVia, type DeploymentViaType, type DnsLookup, type DnsProvider, type DnsRecord, type DnsRecordType, type Domain, type DomainDeleteResponse, type DomainDnsResponse, type DomainListResponse, type DomainRecordsResponse, type DomainResource, type DomainSetOptions, type DomainSetResult, type DomainShareResponse, DomainStatus, type DomainStatusType, type DomainValidateResponse, type DomainVerifyResponse, type ErrorResponse, ErrorType, type ExecutionEnvironment, FileValidationStatus as FILE_VALIDATION_STATUS, type Fetch, type FileValidationResult, FileValidationStatus, type FileValidationStatusType, IDEMPOTENCY_KEY_CONSTRAINTS, JUNK_DIRECTORIES, LABEL_CONSTRAINTS, LABEL_PATTERN, type LabelsResponse, type ListOptions, type ListResponse, type MD5Result, MY_API_KEY_URL, OAuthScope, type OAuthScopeType, PASSWORD_CONSTRAINTS, PUBLIC_DEPLOYMENT_TTL_SECONDS, type PingResponse, type PlatformLimits, type RequestResult, type ResourceContext, SHIP_ENV, type SPACheckDebug, type SPACheckRequest, type SPACheckResponse, SPA_CHECK_CONSTRAINTS, SPA_DEFAULT_CONFIG, type SetupInstructionsResponse, Ship, type ShipClientOptions, ShipError, type ShipEvents, type ShipRequestInit, type StaticFile, TTL_CONSTRAINTS, type Token, type TokenCreateOptions, type TokenCreateResponse, type TokenDeleteResponse, TokenKind, type TokenKindType, type TokenListResponse, type TokenProvider, type TokenResource, type Transport, UNBUILT_PROJECT_MARKERS, UNSAFE_FILENAME_CHARS, type UploadedFile, type UserVisibleActivityEvent, type ValidatableFile, type ValidationIssue, WEB_FILE_ACCEPT, __setTestEnvironment, allValidFilesReady, assertShipJsonSyntax, calculateMD5, classifyToken, createAccountResource, createDeploymentResource, createDomainResource, createTokenResource, Ship as default, deserializeLabels, extractSubdomain, filterJunk, formatFileSize, generateDeploymentUrl, generateDomainUrl, getENV, getValidFiles, hasUnbuiltMarker, hasUnsafeChars, isBlockedExtension, isCustomDomain, isDeployment, isPlatformDomain, isShipError, normalizeVia, optimizeDeployPaths, pluralize, processFilesForBrowser, serializeLabels, validateApiKey, validateApiUrl, validateCaller, validateDeployFile, validateDeployPath, validateDeployToken, validateFileName, validateFiles, validateIdempotencyKey, validatePassword, validateToken, validateTtl };
|