@shipstatic/ship 2.0.0-beta.9 → 2.1.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.md +12 -2
- package/SKILL.md +2 -0
- package/dist/browser.d.ts +305 -95
- package/dist/browser.js +1 -1
- package/dist/browser.js.map +1 -1
- package/dist/cli.cjs +138 -26
- 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 +305 -95
- package/dist/index.d.ts +305 -95
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +12 -6
- package/dist/completions/ship.bash +0 -117
- package/dist/completions/ship.fish +0 -87
- package/dist/completions/ship.zsh +0 -126
package/README.md
CHANGED
|
@@ -129,7 +129,7 @@ ship ping
|
|
|
129
129
|
|
|
130
130
|
```typescript
|
|
131
131
|
ship.account.get() // → whoami
|
|
132
|
-
ship.ping() // →
|
|
132
|
+
ship.ping() // → { timestamp } (server clock; reachability is the absence of a throw)
|
|
133
133
|
ship.getLimits() // → platform plan limits (cached)
|
|
134
134
|
```
|
|
135
135
|
|
|
@@ -139,6 +139,8 @@ ship.getLimits() // → platform plan limits (cached)
|
|
|
139
139
|
|
|
140
140
|
The `-q` flag outputs only the resource identifier — perfect for piping and scripting:
|
|
141
141
|
|
|
142
|
+
`ship tokens create -q` is the one exception: it prints the token **secret**, which is shown once and never again.
|
|
143
|
+
|
|
142
144
|
```bash
|
|
143
145
|
# Deploy and link domain in one pipe
|
|
144
146
|
ship ./dist -q | ship domains set www.example.com
|
|
@@ -318,7 +320,15 @@ The **CLI** (`ship`) resolves its token in this order:
|
|
|
318
320
|
|
|
319
321
|
1. CLI flag: `--token`
|
|
320
322
|
2. Environment variable: `SHIP_TOKEN`
|
|
321
|
-
3. Config
|
|
323
|
+
3. Config file: `~/.shiprc` (run `ship config` to create one)
|
|
324
|
+
|
|
325
|
+
`--config <file>` reads any path you name instead of `~/.shiprc`, which is how per-environment
|
|
326
|
+
configs work (`ship --config dev.shiprc ...`). The file is strict JSON; an empty one means "no
|
|
327
|
+
config".
|
|
328
|
+
|
|
329
|
+
**No repository file is ever read.** A `.shiprc` or `package.json` `"ship"` key in your working
|
|
330
|
+
directory is ignored — cloning a repo can never change which account you deploy to, or which
|
|
331
|
+
host your token is sent to.
|
|
322
332
|
|
|
323
333
|
The **SDK** (`new Ship(...)`) resolves its token in this order:
|
|
324
334
|
|
package/SKILL.md
CHANGED
|
@@ -223,6 +223,8 @@ Every command supports three modes:
|
|
|
223
223
|
| `--json` | JSON on stdout | Parsing programmatically |
|
|
224
224
|
| `-q` | Identifier only | Piping between commands |
|
|
225
225
|
|
|
226
|
+
`-q` prints the resource identifier — except `tokens create -q`, which prints the token **secret** (shown once, never again).
|
|
227
|
+
|
|
226
228
|
Errors go to stderr in all modes. Exit 0 = success, 1 = error.
|
|
227
229
|
|
|
228
230
|
List commands return `{"<resource>s": [...], "cursor": null}`. A non-null `cursor` means more pages remain — pass it back with `--cursor` to continue, and size pages with `--limit`. There is no total; a count is an aggregate over a collection, not a property of one page. `domains list` text mode omits status — use `--json` to see `pending` vs `success`.
|
package/dist/browser.d.ts
CHANGED
|
@@ -12,6 +12,28 @@ declare const DeploymentStatus: {
|
|
|
12
12
|
readonly DELETING: "deleting";
|
|
13
13
|
};
|
|
14
14
|
type DeploymentStatusType = (typeof DeploymentStatus)[keyof typeof DeploymentStatus];
|
|
15
|
+
/**
|
|
16
|
+
* Which client made a deployment — the origin-tracking vocabulary.
|
|
17
|
+
*
|
|
18
|
+
* A closed set with many authors: the CLI, the SDK, the dashboard, both MCP
|
|
19
|
+
* transports, the GitHub Action, the n8n node and the VS Code extension each
|
|
20
|
+
* name themselves here. It lived in the API's config until 2026-08-06, where
|
|
21
|
+
* being server-side made it unenforceable in the one direction that matters —
|
|
22
|
+
* every client wrote a bare string, and a value outside the set was **silently
|
|
23
|
+
* dropped** by the server, so a typo did not fail anywhere. It stopped
|
|
24
|
+
* recording where deploys came from and said nothing.
|
|
25
|
+
*/
|
|
26
|
+
declare const DeploymentVia: {
|
|
27
|
+
readonly WEB: "web";
|
|
28
|
+
readonly SDK: "sdk";
|
|
29
|
+
readonly CLI: "cli";
|
|
30
|
+
readonly MCP: "mcp";
|
|
31
|
+
readonly GIT: "git";
|
|
32
|
+
readonly N8N: "n8n";
|
|
33
|
+
readonly GPT: "gpt";
|
|
34
|
+
readonly VSC: "vsc";
|
|
35
|
+
};
|
|
36
|
+
type DeploymentViaType = (typeof DeploymentVia)[keyof typeof DeploymentVia];
|
|
15
37
|
/**
|
|
16
38
|
* Core deployment object - used in both API responses and SDK
|
|
17
39
|
*/
|
|
@@ -32,7 +54,15 @@ interface Deployment {
|
|
|
32
54
|
readonly password: boolean;
|
|
33
55
|
/** Labels for categorization and filtering (lowercase, alphanumeric with separators). Always present, empty array when none. */
|
|
34
56
|
labels: string[];
|
|
35
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* The client/tool that created this deployment, null if unknown.
|
|
59
|
+
*
|
|
60
|
+
* Deliberately wider than {@link DeploymentViaType}: this is stored data,
|
|
61
|
+
* and rows predate the vocabulary being closed. Narrowing the ENTITY would
|
|
62
|
+
* be a claim about every row already in the database; narrowing the
|
|
63
|
+
* REQUEST option ({@link DeploymentUploadOptions.via}) is a claim about
|
|
64
|
+
* what a client may send, which is ours to make.
|
|
65
|
+
*/
|
|
36
66
|
readonly via: string | null;
|
|
37
67
|
/** Unix timestamp (seconds) when deployment was created */
|
|
38
68
|
readonly created: number;
|
|
@@ -49,62 +79,6 @@ interface DeploymentCreateResponse extends Deployment {
|
|
|
49
79
|
/** Claim URL for public deployments. Present when deployed without credentials. */
|
|
50
80
|
readonly claim?: string;
|
|
51
81
|
}
|
|
52
|
-
/**
|
|
53
|
-
* Every path the public API answers on, declared once.
|
|
54
|
-
*
|
|
55
|
-
* The URL surface was written out in four places — the API's mounts, the
|
|
56
|
-
* SDK's client, the dashboard's client, and the post-deploy smoke — so a
|
|
57
|
-
* rename meant finding all four. The first three now read this table.
|
|
58
|
-
*
|
|
59
|
-
* The smoke (`cloudflare/api/smoke.mjs`) deliberately still spells its own:
|
|
60
|
-
* five of its nine paths are `/admin/*`, which this table excludes by
|
|
61
|
-
* design, and splitting one list between a registry and literals reads worse
|
|
62
|
-
* than keeping it uniform.
|
|
63
|
-
*
|
|
64
|
-
* **What this guarantees, exactly.** Collection paths are mounted from here,
|
|
65
|
-
* so producer and consumer cannot diverge. Item paths are declared here and
|
|
66
|
-
* consumed by clients, but the API spells them relative to their mount
|
|
67
|
-
* (`/:deployment/config`), so the table does not *generate* them — it is
|
|
68
|
-
* held to them by `api/tests/architecture/api-paths.test.ts`, which fails if
|
|
69
|
-
* any entry names a path no route answers. Some entries have no client yet
|
|
70
|
-
* (`DEPLOYMENT_CONFIG`, `DOMAIN_PROPAGATION` — endpoints the SDK
|
|
71
|
-
* deliberately does not reach); the fence is what keeps those honest rather
|
|
72
|
-
* than merely asserted.
|
|
73
|
-
*
|
|
74
|
-
* **The operator surface is deliberately absent.** `/admin/*` paths belong
|
|
75
|
-
* to `web/my`, for the same reason its row types do: this package is
|
|
76
|
-
* published, and the operator surface is not public (see `CLAUDE.md`, "Admin
|
|
77
|
-
* types"). A path here is a promise to every npm consumer; `/admin` is a
|
|
78
|
-
* promise to one dashboard.
|
|
79
|
-
*
|
|
80
|
-
* Item paths are functions rather than templates so the key is interpolated
|
|
81
|
-
* in one place, encoded the same way by every caller.
|
|
82
|
-
*/
|
|
83
|
-
declare const API_PATHS: {
|
|
84
|
-
readonly DEPLOYMENTS: "/deployments";
|
|
85
|
-
readonly DEPLOYMENT: (deployment: string) => string;
|
|
86
|
-
readonly DEPLOYMENT_CONFIG: (deployment: string) => string;
|
|
87
|
-
readonly DOMAINS: "/domains";
|
|
88
|
-
readonly DOMAIN: (domain: string) => string;
|
|
89
|
-
readonly DOMAIN_VERIFY: (domain: string) => string;
|
|
90
|
-
readonly DOMAIN_DNS: (domain: string) => string;
|
|
91
|
-
readonly DOMAIN_RECORDS: (domain: string) => string;
|
|
92
|
-
readonly DOMAIN_SHARE: (domain: string) => string;
|
|
93
|
-
readonly DOMAIN_PROPAGATION: (domain: string) => string;
|
|
94
|
-
readonly DOMAINS_VALIDATE: "/domains/validate";
|
|
95
|
-
readonly TOKENS: "/tokens";
|
|
96
|
-
readonly TOKEN: (token: string) => string;
|
|
97
|
-
readonly ACCOUNT: "/account";
|
|
98
|
-
readonly ACCOUNT_KEY: "/account/key";
|
|
99
|
-
readonly ACCOUNT_CLAIM: "/account/claim";
|
|
100
|
-
readonly ACTIVITIES: "/activities";
|
|
101
|
-
readonly LABELS: "/labels";
|
|
102
|
-
readonly LIMITS: "/limits";
|
|
103
|
-
readonly PING: "/ping";
|
|
104
|
-
readonly SETUP: "/setup";
|
|
105
|
-
readonly SPA_CHECK: "/spa-check";
|
|
106
|
-
readonly UPLOAD: "/upload";
|
|
107
|
-
};
|
|
108
82
|
/**
|
|
109
83
|
* The half of a list response that is identical on every list.
|
|
110
84
|
*
|
|
@@ -123,6 +97,28 @@ interface ListResponse {
|
|
|
123
97
|
/** Opaque cursor from this page; `null` on the last page. */
|
|
124
98
|
cursor: string | null;
|
|
125
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Pagination options for every list endpoint. The response's `cursor` feeds
|
|
102
|
+
* the next request; a `null` cursor means the last page. Omitting both
|
|
103
|
+
* returns the server's default first page.
|
|
104
|
+
*
|
|
105
|
+
* A list answers `{ <collection>, cursor }` and nothing else — `cursor`
|
|
106
|
+
* carries the entire has-more signal, so no redundant boolean, and no
|
|
107
|
+
* `total`. **A count is an aggregate over a collection, not a property of a
|
|
108
|
+
* page:** including one makes every read pay for a full scan it did not ask
|
|
109
|
+
* for, which is precisely the cost keyset pagination exists to avoid.
|
|
110
|
+
*
|
|
111
|
+
* Counts therefore live on the summary resource that owns them —
|
|
112
|
+
* `GET /account` (`usage`) for a caller's own totals, `GET /admin/stats` for
|
|
113
|
+
* platform-wide ones. Ask for a count when you want a count; ask for a page
|
|
114
|
+
* when you want a page.
|
|
115
|
+
*/
|
|
116
|
+
interface ListOptions {
|
|
117
|
+
/** Maximum number of items to return in one page. */
|
|
118
|
+
limit?: number;
|
|
119
|
+
/** Opaque cursor from the previous page's response. */
|
|
120
|
+
cursor?: string;
|
|
121
|
+
}
|
|
126
122
|
/**
|
|
127
123
|
* Response for listing deployments
|
|
128
124
|
*/
|
|
@@ -324,10 +320,33 @@ interface DomainRecordsResponse {
|
|
|
324
320
|
* API would reject the same value the same way.
|
|
325
321
|
*/
|
|
326
322
|
declare const IDEMPOTENCY_KEY_CONSTRAINTS: {
|
|
323
|
+
/**
|
|
324
|
+
* HTTP header name. Here for the same reason {@link CALLER.HEADER} is: a
|
|
325
|
+
* wire header has two ends, and the package that owns the value's format
|
|
326
|
+
* is the only place both ends can read its name from.
|
|
327
|
+
*/
|
|
328
|
+
readonly HEADER: "Idempotency-Key";
|
|
327
329
|
readonly MAX_LENGTH: 256;
|
|
328
330
|
/** How long a stored 201 stays replayable. */
|
|
329
331
|
readonly WINDOW_SECONDS: number;
|
|
330
332
|
};
|
|
333
|
+
/**
|
|
334
|
+
* Normalize a `via` value from any transport — trimmed, lowercased, and a
|
|
335
|
+
* member of {@link DeploymentVia}, or `undefined`.
|
|
336
|
+
*
|
|
337
|
+
* A format rule by this package's own test: a client can decide offline
|
|
338
|
+
* whether a value is well-formed, and the API reaches the same verdict on the
|
|
339
|
+
* same input. It lived server-side until 2026-08-06, which meant clients could
|
|
340
|
+
* only learn their label was unusable by noticing analytics had gone quiet.
|
|
341
|
+
*
|
|
342
|
+
* **Not knowing your `via` is not an error** — an unrecognized value yields
|
|
343
|
+
* `undefined` rather than throwing, because origin tracking is telemetry and a
|
|
344
|
+
* deploy must never fail over it. A caller that has an honest default should
|
|
345
|
+
* prefer it (`normalizeVia(process.env.SHIP_VIA) ?? DeploymentVia.CLI`): the
|
|
346
|
+
* deploy really did come from the CLI, so recording that beats recording
|
|
347
|
+
* nothing.
|
|
348
|
+
*/
|
|
349
|
+
declare function normalizeVia(value: unknown): DeploymentViaType | undefined;
|
|
331
350
|
/**
|
|
332
351
|
* Validate an idempotency key, returning the trimmed value or `undefined`
|
|
333
352
|
* when none was supplied. Throws {@link ShipError.validation} when the value
|
|
@@ -570,6 +589,97 @@ interface AccountOverrides {
|
|
|
570
589
|
/** Override for maximum total deployment size in bytes */
|
|
571
590
|
totalSize?: number;
|
|
572
591
|
}
|
|
592
|
+
/**
|
|
593
|
+
* Every path the public API answers on, declared once.
|
|
594
|
+
*
|
|
595
|
+
* The URL surface was written out in four places — the API's mounts, the
|
|
596
|
+
* SDK's client, the dashboard's client, and the post-deploy smoke — so a
|
|
597
|
+
* rename meant finding all four. The first three now read this table.
|
|
598
|
+
*
|
|
599
|
+
* The smoke (`cloudflare/api/smoke.mjs`) deliberately still spells its own:
|
|
600
|
+
* five of its nine paths are `/admin/*`, which this table excludes by
|
|
601
|
+
* design, and splitting one list between a registry and literals reads worse
|
|
602
|
+
* than keeping it uniform.
|
|
603
|
+
*
|
|
604
|
+
* **What this guarantees, exactly.** Collection paths are mounted from here,
|
|
605
|
+
* so producer and consumer cannot diverge. Item paths are declared here and
|
|
606
|
+
* consumed by clients, but the API spells them relative to their mount
|
|
607
|
+
* (`/:deployment/config`), so the table does not *generate* them — it is
|
|
608
|
+
* held to them by `api/tests/architecture/api-paths.test.ts`, which fails if
|
|
609
|
+
* any entry names a path no route answers. Some entries have no client yet
|
|
610
|
+
* (`DEPLOYMENT_CONFIG`, `DOMAIN_PROPAGATION` — endpoints the SDK
|
|
611
|
+
* deliberately does not reach); the fence is what keeps those honest rather
|
|
612
|
+
* than merely asserted.
|
|
613
|
+
*
|
|
614
|
+
* **The operator surface is deliberately absent.** `/admin/*` paths belong
|
|
615
|
+
* to `web/my`, for the same reason its row types do: this package is
|
|
616
|
+
* published, and the operator surface is not public (see `CLAUDE.md`, "Admin
|
|
617
|
+
* types"). A path here is a promise to every npm consumer; `/admin` is a
|
|
618
|
+
* promise to one dashboard.
|
|
619
|
+
*
|
|
620
|
+
* Item paths are functions rather than templates so the key is interpolated
|
|
621
|
+
* in one place, encoded the same way by every caller.
|
|
622
|
+
*/
|
|
623
|
+
declare const API_PATHS: {
|
|
624
|
+
readonly DEPLOYMENTS: "/deployments";
|
|
625
|
+
readonly DEPLOYMENT: (deployment: string) => string;
|
|
626
|
+
readonly DEPLOYMENT_CONFIG: (deployment: string) => string;
|
|
627
|
+
readonly DOMAINS: "/domains";
|
|
628
|
+
readonly DOMAIN: (domain: string) => string;
|
|
629
|
+
readonly DOMAIN_VERIFY: (domain: string) => string;
|
|
630
|
+
readonly DOMAIN_DNS: (domain: string) => string;
|
|
631
|
+
readonly DOMAIN_RECORDS: (domain: string) => string;
|
|
632
|
+
readonly DOMAIN_SHARE: (domain: string) => string;
|
|
633
|
+
readonly DOMAIN_PROPAGATION: (domain: string) => string;
|
|
634
|
+
readonly DOMAINS_VALIDATE: "/domains/validate";
|
|
635
|
+
readonly TOKENS: "/tokens";
|
|
636
|
+
readonly TOKEN: (token: string) => string;
|
|
637
|
+
readonly ACCOUNT: "/account";
|
|
638
|
+
readonly ACCOUNT_KEY: "/account/key";
|
|
639
|
+
readonly ACCOUNT_CLAIM: "/account/claim";
|
|
640
|
+
readonly ACTIVITIES: "/activities";
|
|
641
|
+
readonly LABELS: "/labels";
|
|
642
|
+
readonly LIMITS: "/limits";
|
|
643
|
+
readonly PING: "/ping";
|
|
644
|
+
readonly SETUP: "/setup";
|
|
645
|
+
readonly SPA_CHECK: "/spa-check";
|
|
646
|
+
readonly UPLOAD: "/upload";
|
|
647
|
+
};
|
|
648
|
+
/**
|
|
649
|
+
* The deploy request's multipart field names — the other half of the wire
|
|
650
|
+
* surface beside {@link API_PATHS}. `POST /deployments` (and the first-party
|
|
651
|
+
* `/upload`) is multipart/form-data, and these are the names the API reads.
|
|
652
|
+
*
|
|
653
|
+
* Declared once because the body has three independent WRITERS — the SDK's
|
|
654
|
+
* Node and browser body builders, and the n8n community node's hand-rolled
|
|
655
|
+
* client (which cannot import this under n8n Cloud's zero-dependency rule,
|
|
656
|
+
* and fences its restated copy instead) — and until this export every writer
|
|
657
|
+
* restated the strings the API parses, with nothing comparing them.
|
|
658
|
+
*
|
|
659
|
+
* `FILES` carries one entry per file (the API reads it with `getAll`); every
|
|
660
|
+
* other field is single. The `@internal` flags are serialized as the literal
|
|
661
|
+
* string `'true'` and belong to first-party surfaces only.
|
|
662
|
+
*/
|
|
663
|
+
declare const DEPLOY_FIELDS: {
|
|
664
|
+
/** One entry per file — read with `getAll`. */
|
|
665
|
+
readonly FILES: "files[]";
|
|
666
|
+
/** JSON array of MD5 hex digests, index-aligned with `FILES`. */
|
|
667
|
+
readonly CHECKSUMS: "checksums";
|
|
668
|
+
/** JSON array of label strings. */
|
|
669
|
+
readonly LABELS: "labels";
|
|
670
|
+
/** The deploying surface's {@link DeploymentVia} member. */
|
|
671
|
+
readonly VIA: "via";
|
|
672
|
+
/** Plaintext password — the API hashes it server-side. */
|
|
673
|
+
readonly PASSWORD: "password";
|
|
674
|
+
/** @internal Server-processing flag — first-party `/upload` only. */
|
|
675
|
+
readonly BUILD: "build";
|
|
676
|
+
/** @internal Server-processing flag — first-party `/upload` only. */
|
|
677
|
+
readonly PRERENDER: "prerender";
|
|
678
|
+
/** @internal Server-processing flag — first-party `/upload` only. */
|
|
679
|
+
readonly SPA: "spa";
|
|
680
|
+
/** @internal reCAPTCHA proof — `web/www`'s public uploader only. */
|
|
681
|
+
readonly CAPTCHA: "captcha";
|
|
682
|
+
};
|
|
573
683
|
/**
|
|
574
684
|
* All possible error types in the ShipStatic platform.
|
|
575
685
|
*
|
|
@@ -602,6 +712,17 @@ declare const ErrorType: {
|
|
|
602
712
|
readonly Business: "business_logic_error";
|
|
603
713
|
/** API server error (500). Generic server-side fault. */
|
|
604
714
|
readonly Api: "internal_server_error";
|
|
715
|
+
/**
|
|
716
|
+
* The platform is closed for maintenance (503). A deliberate operator
|
|
717
|
+
* state, not a fault — nothing errored; the API is refusing work on
|
|
718
|
+
* purpose, and deployed sites keep serving throughout.
|
|
719
|
+
*
|
|
720
|
+
* Distinct from `Api` at 503, which the platform already uses for a
|
|
721
|
+
* dependency that failed (moderation unavailable). A consumer has to tell
|
|
722
|
+
* "we closed the door" from "something broke": the two get opposite words
|
|
723
|
+
* and opposite retry behaviour.
|
|
724
|
+
*/
|
|
725
|
+
readonly Maintenance: "maintenance";
|
|
605
726
|
/** Network/connection error. Client-side only — set by HTTP clients on fetch failure; never produced server-side. */
|
|
606
727
|
readonly Network: "network_error";
|
|
607
728
|
/** Operation was cancelled. Client-side only — set on `AbortSignal` abort; never produced server-side. */
|
|
@@ -668,7 +789,8 @@ declare class ShipError extends Error {
|
|
|
668
789
|
* Routing:
|
|
669
790
|
* - Already a `ShipError` → returned as-is (caller's intent preserved)
|
|
670
791
|
* - `AbortError` → `ShipError.cancelled(...)`
|
|
671
|
-
* -
|
|
792
|
+
* - A transport failure → `ShipError.network(...)` — see `isTransportFailure`
|
|
793
|
+
* for what each runtime offers as evidence
|
|
672
794
|
* - Any other `Error` → `ShipError(Api, ...)` (no HTTP status — fetch never reached the server)
|
|
673
795
|
* - Anything else (string, undefined, etc.) → `ShipError(Api, ...)`
|
|
674
796
|
*
|
|
@@ -701,6 +823,16 @@ declare class ShipError extends Error {
|
|
|
701
823
|
static file(message: string, details?: unknown): ShipError;
|
|
702
824
|
static config(message: string, details?: unknown): ShipError;
|
|
703
825
|
static api(message: string, status?: number, details?: unknown): ShipError;
|
|
826
|
+
/**
|
|
827
|
+
* The platform is closed for maintenance (503).
|
|
828
|
+
*
|
|
829
|
+
* `message` is REQUIRED and has no default here. The API is the only
|
|
830
|
+
* producer of that sentence, and a default in this file would be a second
|
|
831
|
+
* owner of one fact — see CLAUDE.md, "The Constellation Law" (stopping
|
|
832
|
+
* rule). It is also the one factory whose status is fixed rather than
|
|
833
|
+
* defaulted: a maintenance refusal is 503 or it is not this error.
|
|
834
|
+
*/
|
|
835
|
+
static maintenance(message: string, details?: unknown): ShipError;
|
|
704
836
|
/**
|
|
705
837
|
* The caller is at fault — by HTTP's own definition of a 4xx, or by a type
|
|
706
838
|
* that is client-attributable without ever having a status (`Config`,
|
|
@@ -775,6 +907,28 @@ declare const BLOCKED_EXTENSIONS: ReadonlySet<string>;
|
|
|
775
907
|
* isBlockedExtension('README') // false
|
|
776
908
|
*/
|
|
777
909
|
declare function isBlockedExtension(filename: string): boolean;
|
|
910
|
+
/**
|
|
911
|
+
* The `accept` attribute value for a browser file picker offering web files.
|
|
912
|
+
*
|
|
913
|
+
* **This is a hint, never a rule.** `BLOCKED_EXTENSIONS` is the platform's
|
|
914
|
+
* gate and the only thing that decides what may be hosted; this constant
|
|
915
|
+
* decides what a *file dialog* shows first. The two are not two halves of one
|
|
916
|
+
* policy, and this one must never be consulted to accept or reject a file.
|
|
917
|
+
*
|
|
918
|
+
* The distinction is structural, not stylistic. `accept` can express only an
|
|
919
|
+
* allowlist, while the platform's rule is a blocklist — so this list is
|
|
920
|
+
* necessarily *narrower* than what the platform hosts, and reading it as
|
|
921
|
+
* authority would reject files the platform serves happily. It is also not
|
|
922
|
+
* enforcement in the browser's own terms: every file dialog offers an
|
|
923
|
+
* all-files escape, and **drag-and-drop ignores `accept` entirely**. The
|
|
924
|
+
* dropzone and the picker must reach the same verdict on the same files, and
|
|
925
|
+
* they do — because the verdict is `validateFiles`, downstream of both.
|
|
926
|
+
*
|
|
927
|
+
* Kept beside `BLOCKED_EXTENSIONS` so one file holds both, which is what lets
|
|
928
|
+
* `tests/validation-constants.test.ts` fence the invariant that matters: the
|
|
929
|
+
* picker must never offer a file the platform will refuse.
|
|
930
|
+
*/
|
|
931
|
+
declare const WEB_FILE_ACCEPT: string;
|
|
778
932
|
/**
|
|
779
933
|
* Characters that are unsafe in filenames for static hosting.
|
|
780
934
|
*
|
|
@@ -855,30 +1009,35 @@ declare const AuthMethod: {
|
|
|
855
1009
|
};
|
|
856
1010
|
type AuthMethodType = (typeof AuthMethod)[keyof typeof AuthMethod];
|
|
857
1011
|
/**
|
|
858
|
-
* Shape constants for API keys (`ship-{
|
|
1012
|
+
* Shape constants for API keys (`ship-{32 hex chars}`).
|
|
859
1013
|
* Single source of truth used by validation utilities and auth middleware.
|
|
860
1014
|
*/
|
|
861
1015
|
declare const API_KEY: {
|
|
862
1016
|
/** Prefix that identifies an API key. */
|
|
863
1017
|
readonly PREFIX: "ship-";
|
|
864
1018
|
/** Number of hex characters following the prefix. */
|
|
865
|
-
readonly HEX_LENGTH:
|
|
866
|
-
/** Total length of an API key including prefix (`PREFIX.length + HEX_LENGTH =
|
|
867
|
-
readonly TOTAL_LENGTH:
|
|
1019
|
+
readonly HEX_LENGTH: 32;
|
|
1020
|
+
/** Total length of an API key including prefix (`PREFIX.length + HEX_LENGTH = 37`). */
|
|
1021
|
+
readonly TOTAL_LENGTH: 37;
|
|
868
1022
|
/** Number of trailing characters used to display a redacted hint (e.g. last 4). */
|
|
869
1023
|
readonly HINT_LENGTH: 4;
|
|
870
1024
|
};
|
|
871
1025
|
/**
|
|
872
|
-
* Shape constants for deploy tokens (`deploy-{
|
|
1026
|
+
* Shape constants for deploy tokens (`deploy-{32 hex chars}`).
|
|
873
1027
|
* Single source of truth used by validation utilities and auth middleware.
|
|
1028
|
+
*
|
|
1029
|
+
* Deliberately the same width as `API_KEY`: both are minted by one generator
|
|
1030
|
+
* and classified by prefix alone, so a length that differed between them
|
|
1031
|
+
* would be a second thing to know about a credential whose prefix already
|
|
1032
|
+
* says what it is.
|
|
874
1033
|
*/
|
|
875
1034
|
declare const DEPLOY_TOKEN: {
|
|
876
1035
|
/** Prefix that identifies a deploy token. */
|
|
877
1036
|
readonly PREFIX: "deploy-";
|
|
878
1037
|
/** Number of hex characters following the prefix. */
|
|
879
|
-
readonly HEX_LENGTH:
|
|
880
|
-
/** Total length of a deploy token including prefix (`PREFIX.length + HEX_LENGTH =
|
|
881
|
-
readonly TOTAL_LENGTH:
|
|
1038
|
+
readonly HEX_LENGTH: 32;
|
|
1039
|
+
/** Total length of a deploy token including prefix (`PREFIX.length + HEX_LENGTH = 39`). */
|
|
1040
|
+
readonly TOTAL_LENGTH: 39;
|
|
882
1041
|
};
|
|
883
1042
|
/**
|
|
884
1043
|
* Shape constants for caller identifiers (the `X-Caller` instance-identity
|
|
@@ -947,6 +1106,26 @@ declare const SPA_DEFAULT_CONFIG: {
|
|
|
947
1106
|
readonly destination: "/index.html";
|
|
948
1107
|
}];
|
|
949
1108
|
};
|
|
1109
|
+
/**
|
|
1110
|
+
* The `/spa-check` pre-flight's client-side envelope: which file is the
|
|
1111
|
+
* check's subject, and how large it may be before a client skips the call.
|
|
1112
|
+
*
|
|
1113
|
+
* One fact with three holders until this export — the API's config declared
|
|
1114
|
+
* the cap, the SDK's `checkSPA` hardcoded `100 * 1024`, and prose restated
|
|
1115
|
+
* "100KB". `INDEX_FILE` is the selection rule (the file whose content rides
|
|
1116
|
+
* `SPACheckRequest.index`), restated by every client that builds the request.
|
|
1117
|
+
*
|
|
1118
|
+
* Neither member is a validation boundary: a client over the cap simply
|
|
1119
|
+
* skips the pre-flight, because the server answers an oversized index
|
|
1120
|
+
* `isSPA: false` anyway. A consumer that cannot import this (n8n) needs no
|
|
1121
|
+
* size copy at all — outcome parity is the server's, not the client's.
|
|
1122
|
+
*/
|
|
1123
|
+
declare const SPA_CHECK_CONSTRAINTS: {
|
|
1124
|
+
/** The file whose content is the check's subject. */
|
|
1125
|
+
readonly INDEX_FILE: "index.html";
|
|
1126
|
+
/** Skip the pre-flight above this size — the server would answer false. */
|
|
1127
|
+
readonly MAX_INDEX_BYTES: number;
|
|
1128
|
+
};
|
|
950
1129
|
/**
|
|
951
1130
|
* Assert that a ship.json file is *syntactically* loadable. Syntax only —
|
|
952
1131
|
* never schema.
|
|
@@ -1071,6 +1250,50 @@ interface StaticFile {
|
|
|
1071
1250
|
}
|
|
1072
1251
|
/** Default API URL if not otherwise configured. */
|
|
1073
1252
|
declare const DEFAULT_API = "https://api.shipstatic.com";
|
|
1253
|
+
/**
|
|
1254
|
+
* The Node SDK's ambient configuration pair — the ONLY environment variables
|
|
1255
|
+
* the SDK reads, and therefore the COMPLETE list an embedding host must
|
|
1256
|
+
* scrub (per `npm/ship`'s strict-isolation contract, scrubbing is the host's
|
|
1257
|
+
* job, not the SDK's). A host that derives its scrub from this object's
|
|
1258
|
+
* values — as the VS Code extension's child-process env block does — picks
|
|
1259
|
+
* up a grown contract at the next pin bump instead of by remembered prose.
|
|
1260
|
+
*
|
|
1261
|
+
* Browser builds read no environment at all, and the CLI-only variables
|
|
1262
|
+
* (`SHIP_PASSWORD`, `SHIP_VIA`) are deliberately NOT here: they are the
|
|
1263
|
+
* CLI's operational levers, not the SDK's ambient contract — see
|
|
1264
|
+
* `npm/ship/CLAUDE.md`, "CLI-only env vars".
|
|
1265
|
+
*/
|
|
1266
|
+
declare const SHIP_ENV: {
|
|
1267
|
+
/** The one credential slot — any platform token. */
|
|
1268
|
+
readonly TOKEN: "SHIP_TOKEN";
|
|
1269
|
+
/** The API endpoint override. */
|
|
1270
|
+
readonly API_URL: "SHIP_API_URL";
|
|
1271
|
+
};
|
|
1272
|
+
/**
|
|
1273
|
+
* Where a human creates an API key — the console deep link quoted by every
|
|
1274
|
+
* surface that teaches authentication (the CLI's config wizard, the VS Code
|
|
1275
|
+
* and n8n listings, the n8n rate-limit hint and credential copy). Written
|
|
1276
|
+
* out in five files across three repos until this export.
|
|
1277
|
+
*
|
|
1278
|
+
* Production-branded by design: published artifacts name the product, never
|
|
1279
|
+
* an environment (root `CLAUDE.md`, "Environment-Aware URLs").
|
|
1280
|
+
*/
|
|
1281
|
+
declare const MY_API_KEY_URL = "https://my.shipstatic.com/api-key";
|
|
1282
|
+
/**
|
|
1283
|
+
* How long an anonymous deployment lives before it expires.
|
|
1284
|
+
*
|
|
1285
|
+
* The lifetime of the public tier, and one fact with several readers. The API
|
|
1286
|
+
* stamps a deployment's `expires` from it and gives a claim code exactly the
|
|
1287
|
+
* same window — a live site with a dead claim link is a coherence bug, so the
|
|
1288
|
+
* two are one constant rather than two that agree. Both MCP transports quote
|
|
1289
|
+
* the duration in prose an agent reads, and derive it from here rather than
|
|
1290
|
+
* writing it out, which they did in eight places until this export existed.
|
|
1291
|
+
*
|
|
1292
|
+
* Seconds, spelled in the name: this platform has both second- and
|
|
1293
|
+
* millisecond-valued durations, and the pair is only safe when each says which
|
|
1294
|
+
* it is.
|
|
1295
|
+
*/
|
|
1296
|
+
declare const PUBLIC_DEPLOYMENT_TTL_SECONDS: number;
|
|
1074
1297
|
/**
|
|
1075
1298
|
* Universal deploy input — the union of every shape the SDK accepts.
|
|
1076
1299
|
*
|
|
@@ -1089,8 +1312,12 @@ type DeployInput = File[] | string | string[];
|
|
|
1089
1312
|
interface DeploymentUploadOptions {
|
|
1090
1313
|
/** Optional labels for categorization and filtering */
|
|
1091
1314
|
labels?: string[];
|
|
1092
|
-
/**
|
|
1093
|
-
|
|
1315
|
+
/**
|
|
1316
|
+
* Which client is making this deploy. Closed, because the server silently
|
|
1317
|
+
* ignores anything outside the set — so an unchecked string turned a typo
|
|
1318
|
+
* into missing analytics rather than an error. See {@link DeploymentVia}.
|
|
1319
|
+
*/
|
|
1320
|
+
via?: DeploymentViaType;
|
|
1094
1321
|
/**
|
|
1095
1322
|
* Optional password that protects this deployment.
|
|
1096
1323
|
*
|
|
@@ -1122,36 +1349,14 @@ interface DeploymentUploadOptions {
|
|
|
1122
1349
|
*
|
|
1123
1350
|
* **Agents are the audience.** A human notices a duplicate; an automated
|
|
1124
1351
|
* retry does not. Pick a key that identifies the ATTEMPT — a run id, a
|
|
1125
|
-
* commit sha, a uuid minted before the first try — never one
|
|
1126
|
-
*
|
|
1352
|
+
* commit sha, a uuid minted before the first try — never one minted fresh
|
|
1353
|
+
* on each retry, which would defeat the point.
|
|
1127
1354
|
*
|
|
1128
1355
|
* The replay is per-caller, and it stores successes only: a failed deploy
|
|
1129
1356
|
* retries fresh under the same key.
|
|
1130
1357
|
*/
|
|
1131
1358
|
idempotencyKey?: string;
|
|
1132
1359
|
}
|
|
1133
|
-
/**
|
|
1134
|
-
* Pagination options for every list endpoint. The response's `cursor` feeds
|
|
1135
|
-
* the next request; a `null` cursor means the last page. Omitting both
|
|
1136
|
-
* returns the server's default first page.
|
|
1137
|
-
*
|
|
1138
|
-
* A list answers `{ <collection>, cursor }` and nothing else — `cursor`
|
|
1139
|
-
* carries the entire has-more signal, so no redundant boolean, and no
|
|
1140
|
-
* `total`. **A count is an aggregate over a collection, not a property of a
|
|
1141
|
-
* page:** including one makes every read pay for a full scan it did not ask
|
|
1142
|
-
* for, which is precisely the cost keyset pagination exists to avoid.
|
|
1143
|
-
*
|
|
1144
|
-
* Counts therefore live on the summary resource that owns them —
|
|
1145
|
-
* `GET /account` (`usage`) for a caller's own totals, `GET /admin/stats` for
|
|
1146
|
-
* platform-wide ones. Ask for a count when you want a count; ask for a page
|
|
1147
|
-
* when you want a page.
|
|
1148
|
-
*/
|
|
1149
|
-
interface ListOptions {
|
|
1150
|
-
/** Maximum number of items to return in one page. */
|
|
1151
|
-
limit?: number;
|
|
1152
|
-
/** Opaque cursor from the previous page's response. */
|
|
1153
|
-
cursor?: string;
|
|
1154
|
-
}
|
|
1155
1360
|
/**
|
|
1156
1361
|
* What a caller may change on an existing deployment.
|
|
1157
1362
|
*
|
|
@@ -1569,8 +1774,13 @@ interface DeployBodyContext {
|
|
|
1569
1774
|
* `LABEL_CONSTRAINTS` (length and pattern, lowercased+trimmed).
|
|
1570
1775
|
*/
|
|
1571
1776
|
labels?: string[];
|
|
1572
|
-
/**
|
|
1573
|
-
|
|
1777
|
+
/**
|
|
1778
|
+
* Which client is deploying — the same closed vocabulary the public option
|
|
1779
|
+
* carries, not a second `string`. This context receives an already-narrowed
|
|
1780
|
+
* value and passed it on widened, which made the narrowing stop one seam
|
|
1781
|
+
* short of the wire.
|
|
1782
|
+
*/
|
|
1783
|
+
via?: DeploymentViaType;
|
|
1574
1784
|
/**
|
|
1575
1785
|
* Optional plaintext password to protect the deployment.
|
|
1576
1786
|
* Length: `PASSWORD_CONSTRAINTS.MIN_LENGTH` to `PASSWORD_CONSTRAINTS.MAX_LENGTH`
|
|
@@ -2238,4 +2448,4 @@ declare class Ship extends Ship$1 {
|
|
|
2238
2448
|
protected getDeployBodyCreator(): DeployBodyCreator;
|
|
2239
2449
|
}
|
|
2240
2450
|
|
|
2241
|
-
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, BLOCKED_EXTENSIONS, type BillingCancelResponse, type BillingStatus, CALLER, type CheckoutSession, DEFAULT_API, DEPLOYMENT_CONFIG_FILENAME, DEPLOY_TOKEN, type DeployBody, type DeployBodyContext, type DeployBodyCreator, type DeployFile, type DeployInput, type Deployment, type DeploymentCreateResponse, type DeploymentDeleteResponse, type DeploymentListResponse, type DeploymentOptions, type DeploymentResource, type DeploymentResourceContext, type DeploymentSetOptions, DeploymentStatus, type DeploymentStatusType, type DeploymentUploadOptions, 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, OAuthScope, type OAuthScopeType, PASSWORD_CONSTRAINTS, type PingResponse, type PlatformLimits, type ResourceContext, type SPACheckDebug, type SPACheckRequest, type SPACheckResponse, SPA_DEFAULT_CONFIG, type SetupInstructionsResponse, Ship, type ShipClientOptions, ShipError, type ShipEvents, type StaticFile, type Token, type TokenCreateOptions, type TokenCreateResponse, type TokenDeleteResponse, TokenKind, type TokenKindType, type TokenListResponse, type TokenProvider, type TokenResource, UNBUILT_PROJECT_MARKERS, UNSAFE_FILENAME_CHARS, type UploadedFile, type UserVisibleActivityEvent, type ValidatableFile, type ValidationIssue, __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, optimizeDeployPaths, pluralize, processFilesForBrowser, serializeLabels, validateApiKey, validateApiUrl, validateCaller, validateDeployFile, validateDeployPath, validateDeployToken, validateFileName, validateFiles, validateIdempotencyKey, validatePassword, validateToken };
|
|
2451
|
+
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, BLOCKED_EXTENSIONS, type BillingCancelResponse, type BillingStatus, CALLER, type CheckoutSession, DEFAULT_API, DEPLOYMENT_CONFIG_FILENAME, DEPLOY_FIELDS, DEPLOY_TOKEN, type DeployBody, type DeployBodyContext, type DeployBodyCreator, type DeployFile, type DeployInput, 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 ResourceContext, SHIP_ENV, type SPACheckDebug, type SPACheckRequest, type SPACheckResponse, SPA_CHECK_CONSTRAINTS, SPA_DEFAULT_CONFIG, type SetupInstructionsResponse, Ship, type ShipClientOptions, ShipError, type ShipEvents, type StaticFile, type Token, type TokenCreateOptions, type TokenCreateResponse, type TokenDeleteResponse, TokenKind, type TokenKindType, type TokenListResponse, type TokenProvider, type TokenResource, 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 };
|