@shipstatic/types 2.5.0-beta.20 → 2.5.0-beta.22
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/dist/index.d.ts +162 -78
- package/dist/index.js +144 -57
- package/package.json +1 -1
- package/src/index.ts +174 -82
package/dist/index.d.ts
CHANGED
|
@@ -79,62 +79,6 @@ export interface DeploymentCreateResponse extends Deployment {
|
|
|
79
79
|
/** Claim URL for public deployments. Present when deployed without credentials. */
|
|
80
80
|
readonly claim?: string;
|
|
81
81
|
}
|
|
82
|
-
/**
|
|
83
|
-
* Every path the public API answers on, declared once.
|
|
84
|
-
*
|
|
85
|
-
* The URL surface was written out in four places — the API's mounts, the
|
|
86
|
-
* SDK's client, the dashboard's client, and the post-deploy smoke — so a
|
|
87
|
-
* rename meant finding all four. The first three now read this table.
|
|
88
|
-
*
|
|
89
|
-
* The smoke (`cloudflare/api/smoke.mjs`) deliberately still spells its own:
|
|
90
|
-
* five of its nine paths are `/admin/*`, which this table excludes by
|
|
91
|
-
* design, and splitting one list between a registry and literals reads worse
|
|
92
|
-
* than keeping it uniform.
|
|
93
|
-
*
|
|
94
|
-
* **What this guarantees, exactly.** Collection paths are mounted from here,
|
|
95
|
-
* so producer and consumer cannot diverge. Item paths are declared here and
|
|
96
|
-
* consumed by clients, but the API spells them relative to their mount
|
|
97
|
-
* (`/:deployment/config`), so the table does not *generate* them — it is
|
|
98
|
-
* held to them by `api/tests/architecture/api-paths.test.ts`, which fails if
|
|
99
|
-
* any entry names a path no route answers. Some entries have no client yet
|
|
100
|
-
* (`DEPLOYMENT_CONFIG`, `DOMAIN_PROPAGATION` — endpoints the SDK
|
|
101
|
-
* deliberately does not reach); the fence is what keeps those honest rather
|
|
102
|
-
* than merely asserted.
|
|
103
|
-
*
|
|
104
|
-
* **The operator surface is deliberately absent.** `/admin/*` paths belong
|
|
105
|
-
* to `web/my`, for the same reason its row types do: this package is
|
|
106
|
-
* published, and the operator surface is not public (see `CLAUDE.md`, "Admin
|
|
107
|
-
* types"). A path here is a promise to every npm consumer; `/admin` is a
|
|
108
|
-
* promise to one dashboard.
|
|
109
|
-
*
|
|
110
|
-
* Item paths are functions rather than templates so the key is interpolated
|
|
111
|
-
* in one place, encoded the same way by every caller.
|
|
112
|
-
*/
|
|
113
|
-
export declare const API_PATHS: {
|
|
114
|
-
readonly DEPLOYMENTS: "/deployments";
|
|
115
|
-
readonly DEPLOYMENT: (deployment: string) => string;
|
|
116
|
-
readonly DEPLOYMENT_CONFIG: (deployment: string) => string;
|
|
117
|
-
readonly DOMAINS: "/domains";
|
|
118
|
-
readonly DOMAIN: (domain: string) => string;
|
|
119
|
-
readonly DOMAIN_VERIFY: (domain: string) => string;
|
|
120
|
-
readonly DOMAIN_DNS: (domain: string) => string;
|
|
121
|
-
readonly DOMAIN_RECORDS: (domain: string) => string;
|
|
122
|
-
readonly DOMAIN_SHARE: (domain: string) => string;
|
|
123
|
-
readonly DOMAIN_PROPAGATION: (domain: string) => string;
|
|
124
|
-
readonly DOMAINS_VALIDATE: "/domains/validate";
|
|
125
|
-
readonly TOKENS: "/tokens";
|
|
126
|
-
readonly TOKEN: (token: string) => string;
|
|
127
|
-
readonly ACCOUNT: "/account";
|
|
128
|
-
readonly ACCOUNT_KEY: "/account/key";
|
|
129
|
-
readonly ACCOUNT_CLAIM: "/account/claim";
|
|
130
|
-
readonly ACTIVITIES: "/activities";
|
|
131
|
-
readonly LABELS: "/labels";
|
|
132
|
-
readonly LIMITS: "/limits";
|
|
133
|
-
readonly PING: "/ping";
|
|
134
|
-
readonly SETUP: "/setup";
|
|
135
|
-
readonly SPA_CHECK: "/spa-check";
|
|
136
|
-
readonly UPLOAD: "/upload";
|
|
137
|
-
};
|
|
138
82
|
/**
|
|
139
83
|
* The half of a list response that is identical on every list.
|
|
140
84
|
*
|
|
@@ -153,6 +97,28 @@ export interface ListResponse {
|
|
|
153
97
|
/** Opaque cursor from this page; `null` on the last page. */
|
|
154
98
|
cursor: string | null;
|
|
155
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
|
+
export 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
|
+
}
|
|
156
122
|
/**
|
|
157
123
|
* Response for listing deployments
|
|
158
124
|
*/
|
|
@@ -623,6 +589,97 @@ export interface AccountOverrides {
|
|
|
623
589
|
/** Override for maximum total deployment size in bytes */
|
|
624
590
|
totalSize?: number;
|
|
625
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
|
+
export 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
|
+
export 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
|
+
};
|
|
626
683
|
/**
|
|
627
684
|
* All possible error types in the ShipStatic platform.
|
|
628
685
|
*
|
|
@@ -1023,6 +1080,26 @@ export declare const SPA_DEFAULT_CONFIG: {
|
|
|
1023
1080
|
readonly destination: "/index.html";
|
|
1024
1081
|
}];
|
|
1025
1082
|
};
|
|
1083
|
+
/**
|
|
1084
|
+
* The `/spa-check` pre-flight's client-side envelope: which file is the
|
|
1085
|
+
* check's subject, and how large it may be before a client skips the call.
|
|
1086
|
+
*
|
|
1087
|
+
* One fact with three holders until this export — the API's config declared
|
|
1088
|
+
* the cap, the SDK's `checkSPA` hardcoded `100 * 1024`, and prose restated
|
|
1089
|
+
* "100KB". `INDEX_FILE` is the selection rule (the file whose content rides
|
|
1090
|
+
* `SPACheckRequest.index`), restated by every client that builds the request.
|
|
1091
|
+
*
|
|
1092
|
+
* Neither member is a validation boundary: a client over the cap simply
|
|
1093
|
+
* skips the pre-flight, because the server answers an oversized index
|
|
1094
|
+
* `isSPA: false` anyway. A consumer that cannot import this (n8n) needs no
|
|
1095
|
+
* size copy at all — outcome parity is the server's, not the client's.
|
|
1096
|
+
*/
|
|
1097
|
+
export declare const SPA_CHECK_CONSTRAINTS: {
|
|
1098
|
+
/** The file whose content is the check's subject. */
|
|
1099
|
+
readonly INDEX_FILE: "index.html";
|
|
1100
|
+
/** Skip the pre-flight above this size — the server would answer false. */
|
|
1101
|
+
readonly MAX_INDEX_BYTES: number;
|
|
1102
|
+
};
|
|
1026
1103
|
/**
|
|
1027
1104
|
* Assert that a ship.json file is *syntactically* loadable. Syntax only —
|
|
1028
1105
|
* never schema.
|
|
@@ -1147,6 +1224,35 @@ export interface StaticFile {
|
|
|
1147
1224
|
}
|
|
1148
1225
|
/** Default API URL if not otherwise configured. */
|
|
1149
1226
|
export declare const DEFAULT_API = "https://api.shipstatic.com";
|
|
1227
|
+
/**
|
|
1228
|
+
* The Node SDK's ambient configuration pair — the ONLY environment variables
|
|
1229
|
+
* the SDK reads, and therefore the COMPLETE list an embedding host must
|
|
1230
|
+
* scrub (per `npm/ship`'s strict-isolation contract, scrubbing is the host's
|
|
1231
|
+
* job, not the SDK's). A host that derives its scrub from this object's
|
|
1232
|
+
* values — as the VS Code extension's child-process env block does — picks
|
|
1233
|
+
* up a grown contract at the next pin bump instead of by remembered prose.
|
|
1234
|
+
*
|
|
1235
|
+
* Browser builds read no environment at all, and the CLI-only variables
|
|
1236
|
+
* (`SHIP_PASSWORD`, `SHIP_VIA`) are deliberately NOT here: they are the
|
|
1237
|
+
* CLI's operational levers, not the SDK's ambient contract — see
|
|
1238
|
+
* `npm/ship/CLAUDE.md`, "CLI-only env vars".
|
|
1239
|
+
*/
|
|
1240
|
+
export declare const SHIP_ENV: {
|
|
1241
|
+
/** The one credential slot — any platform token. */
|
|
1242
|
+
readonly TOKEN: "SHIP_TOKEN";
|
|
1243
|
+
/** The API endpoint override. */
|
|
1244
|
+
readonly API_URL: "SHIP_API_URL";
|
|
1245
|
+
};
|
|
1246
|
+
/**
|
|
1247
|
+
* Where a human creates an API key — the console deep link quoted by every
|
|
1248
|
+
* surface that teaches authentication (the CLI's config wizard, the VS Code
|
|
1249
|
+
* and n8n listings, the n8n rate-limit hint and credential copy). Written
|
|
1250
|
+
* out in five files across three repos until this export.
|
|
1251
|
+
*
|
|
1252
|
+
* Production-branded by design: published artifacts name the product, never
|
|
1253
|
+
* an environment (root `CLAUDE.md`, "Environment-Aware URLs").
|
|
1254
|
+
*/
|
|
1255
|
+
export declare const MY_API_KEY_URL = "https://my.shipstatic.com/api-key";
|
|
1150
1256
|
/**
|
|
1151
1257
|
* How long an anonymous deployment lives before it expires.
|
|
1152
1258
|
*
|
|
@@ -1225,28 +1331,6 @@ export interface DeploymentUploadOptions {
|
|
|
1225
1331
|
*/
|
|
1226
1332
|
idempotencyKey?: string;
|
|
1227
1333
|
}
|
|
1228
|
-
/**
|
|
1229
|
-
* Pagination options for every list endpoint. The response's `cursor` feeds
|
|
1230
|
-
* the next request; a `null` cursor means the last page. Omitting both
|
|
1231
|
-
* returns the server's default first page.
|
|
1232
|
-
*
|
|
1233
|
-
* A list answers `{ <collection>, cursor }` and nothing else — `cursor`
|
|
1234
|
-
* carries the entire has-more signal, so no redundant boolean, and no
|
|
1235
|
-
* `total`. **A count is an aggregate over a collection, not a property of a
|
|
1236
|
-
* page:** including one makes every read pay for a full scan it did not ask
|
|
1237
|
-
* for, which is precisely the cost keyset pagination exists to avoid.
|
|
1238
|
-
*
|
|
1239
|
-
* Counts therefore live on the summary resource that owns them —
|
|
1240
|
-
* `GET /account` (`usage`) for a caller's own totals, `GET /admin/stats` for
|
|
1241
|
-
* platform-wide ones. Ask for a count when you want a count; ask for a page
|
|
1242
|
-
* when you want a page.
|
|
1243
|
-
*/
|
|
1244
|
-
export interface ListOptions {
|
|
1245
|
-
/** Maximum number of items to return in one page. */
|
|
1246
|
-
limit?: number;
|
|
1247
|
-
/** Opaque cursor from the previous page's response. */
|
|
1248
|
-
cursor?: string;
|
|
1249
|
-
}
|
|
1250
1334
|
/**
|
|
1251
1335
|
* What a caller may change on an existing deployment.
|
|
1252
1336
|
*
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* This package is the single source of truth for all shared data structures.
|
|
4
4
|
*/
|
|
5
5
|
// =============================================================================
|
|
6
|
-
//
|
|
6
|
+
// DEPLOYMENT TYPES
|
|
7
7
|
// =============================================================================
|
|
8
8
|
/**
|
|
9
9
|
* Deployment status constants
|
|
@@ -35,62 +35,6 @@ export const DeploymentVia = {
|
|
|
35
35
|
GPT: 'gpt',
|
|
36
36
|
VSC: 'vsc',
|
|
37
37
|
};
|
|
38
|
-
/**
|
|
39
|
-
* Every path the public API answers on, declared once.
|
|
40
|
-
*
|
|
41
|
-
* The URL surface was written out in four places — the API's mounts, the
|
|
42
|
-
* SDK's client, the dashboard's client, and the post-deploy smoke — so a
|
|
43
|
-
* rename meant finding all four. The first three now read this table.
|
|
44
|
-
*
|
|
45
|
-
* The smoke (`cloudflare/api/smoke.mjs`) deliberately still spells its own:
|
|
46
|
-
* five of its nine paths are `/admin/*`, which this table excludes by
|
|
47
|
-
* design, and splitting one list between a registry and literals reads worse
|
|
48
|
-
* than keeping it uniform.
|
|
49
|
-
*
|
|
50
|
-
* **What this guarantees, exactly.** Collection paths are mounted from here,
|
|
51
|
-
* so producer and consumer cannot diverge. Item paths are declared here and
|
|
52
|
-
* consumed by clients, but the API spells them relative to their mount
|
|
53
|
-
* (`/:deployment/config`), so the table does not *generate* them — it is
|
|
54
|
-
* held to them by `api/tests/architecture/api-paths.test.ts`, which fails if
|
|
55
|
-
* any entry names a path no route answers. Some entries have no client yet
|
|
56
|
-
* (`DEPLOYMENT_CONFIG`, `DOMAIN_PROPAGATION` — endpoints the SDK
|
|
57
|
-
* deliberately does not reach); the fence is what keeps those honest rather
|
|
58
|
-
* than merely asserted.
|
|
59
|
-
*
|
|
60
|
-
* **The operator surface is deliberately absent.** `/admin/*` paths belong
|
|
61
|
-
* to `web/my`, for the same reason its row types do: this package is
|
|
62
|
-
* published, and the operator surface is not public (see `CLAUDE.md`, "Admin
|
|
63
|
-
* types"). A path here is a promise to every npm consumer; `/admin` is a
|
|
64
|
-
* promise to one dashboard.
|
|
65
|
-
*
|
|
66
|
-
* Item paths are functions rather than templates so the key is interpolated
|
|
67
|
-
* in one place, encoded the same way by every caller.
|
|
68
|
-
*/
|
|
69
|
-
export const API_PATHS = {
|
|
70
|
-
DEPLOYMENTS: '/deployments',
|
|
71
|
-
DEPLOYMENT: (deployment) => `/deployments/${deployment}`,
|
|
72
|
-
DEPLOYMENT_CONFIG: (deployment) => `/deployments/${deployment}/config`,
|
|
73
|
-
DOMAINS: '/domains',
|
|
74
|
-
DOMAIN: (domain) => `/domains/${domain}`,
|
|
75
|
-
DOMAIN_VERIFY: (domain) => `/domains/${domain}/verify`,
|
|
76
|
-
DOMAIN_DNS: (domain) => `/domains/${domain}/dns`,
|
|
77
|
-
DOMAIN_RECORDS: (domain) => `/domains/${domain}/records`,
|
|
78
|
-
DOMAIN_SHARE: (domain) => `/domains/${domain}/share`,
|
|
79
|
-
DOMAIN_PROPAGATION: (domain) => `/domains/${domain}/propagation`,
|
|
80
|
-
DOMAINS_VALIDATE: '/domains/validate',
|
|
81
|
-
TOKENS: '/tokens',
|
|
82
|
-
TOKEN: (token) => `/tokens/${token}`,
|
|
83
|
-
ACCOUNT: '/account',
|
|
84
|
-
ACCOUNT_KEY: '/account/key',
|
|
85
|
-
ACCOUNT_CLAIM: '/account/claim',
|
|
86
|
-
ACTIVITIES: '/activities',
|
|
87
|
-
LABELS: '/labels',
|
|
88
|
-
LIMITS: '/limits',
|
|
89
|
-
PING: '/ping',
|
|
90
|
-
SETUP: '/setup',
|
|
91
|
-
SPA_CHECK: '/spa-check',
|
|
92
|
-
UPLOAD: '/upload',
|
|
93
|
-
};
|
|
94
38
|
// =============================================================================
|
|
95
39
|
// DOMAIN TYPES
|
|
96
40
|
// =============================================================================
|
|
@@ -186,6 +130,100 @@ export const AccountPlan = {
|
|
|
186
130
|
TERMINATED: 'terminated',
|
|
187
131
|
};
|
|
188
132
|
// =============================================================================
|
|
133
|
+
// WIRE SURFACE
|
|
134
|
+
// =============================================================================
|
|
135
|
+
/**
|
|
136
|
+
* Every path the public API answers on, declared once.
|
|
137
|
+
*
|
|
138
|
+
* The URL surface was written out in four places — the API's mounts, the
|
|
139
|
+
* SDK's client, the dashboard's client, and the post-deploy smoke — so a
|
|
140
|
+
* rename meant finding all four. The first three now read this table.
|
|
141
|
+
*
|
|
142
|
+
* The smoke (`cloudflare/api/smoke.mjs`) deliberately still spells its own:
|
|
143
|
+
* five of its nine paths are `/admin/*`, which this table excludes by
|
|
144
|
+
* design, and splitting one list between a registry and literals reads worse
|
|
145
|
+
* than keeping it uniform.
|
|
146
|
+
*
|
|
147
|
+
* **What this guarantees, exactly.** Collection paths are mounted from here,
|
|
148
|
+
* so producer and consumer cannot diverge. Item paths are declared here and
|
|
149
|
+
* consumed by clients, but the API spells them relative to their mount
|
|
150
|
+
* (`/:deployment/config`), so the table does not *generate* them — it is
|
|
151
|
+
* held to them by `api/tests/architecture/api-paths.test.ts`, which fails if
|
|
152
|
+
* any entry names a path no route answers. Some entries have no client yet
|
|
153
|
+
* (`DEPLOYMENT_CONFIG`, `DOMAIN_PROPAGATION` — endpoints the SDK
|
|
154
|
+
* deliberately does not reach); the fence is what keeps those honest rather
|
|
155
|
+
* than merely asserted.
|
|
156
|
+
*
|
|
157
|
+
* **The operator surface is deliberately absent.** `/admin/*` paths belong
|
|
158
|
+
* to `web/my`, for the same reason its row types do: this package is
|
|
159
|
+
* published, and the operator surface is not public (see `CLAUDE.md`, "Admin
|
|
160
|
+
* types"). A path here is a promise to every npm consumer; `/admin` is a
|
|
161
|
+
* promise to one dashboard.
|
|
162
|
+
*
|
|
163
|
+
* Item paths are functions rather than templates so the key is interpolated
|
|
164
|
+
* in one place, encoded the same way by every caller.
|
|
165
|
+
*/
|
|
166
|
+
export const API_PATHS = {
|
|
167
|
+
DEPLOYMENTS: '/deployments',
|
|
168
|
+
DEPLOYMENT: (deployment) => `/deployments/${deployment}`,
|
|
169
|
+
DEPLOYMENT_CONFIG: (deployment) => `/deployments/${deployment}/config`,
|
|
170
|
+
DOMAINS: '/domains',
|
|
171
|
+
DOMAIN: (domain) => `/domains/${domain}`,
|
|
172
|
+
DOMAIN_VERIFY: (domain) => `/domains/${domain}/verify`,
|
|
173
|
+
DOMAIN_DNS: (domain) => `/domains/${domain}/dns`,
|
|
174
|
+
DOMAIN_RECORDS: (domain) => `/domains/${domain}/records`,
|
|
175
|
+
DOMAIN_SHARE: (domain) => `/domains/${domain}/share`,
|
|
176
|
+
DOMAIN_PROPAGATION: (domain) => `/domains/${domain}/propagation`,
|
|
177
|
+
DOMAINS_VALIDATE: '/domains/validate',
|
|
178
|
+
TOKENS: '/tokens',
|
|
179
|
+
TOKEN: (token) => `/tokens/${token}`,
|
|
180
|
+
ACCOUNT: '/account',
|
|
181
|
+
ACCOUNT_KEY: '/account/key',
|
|
182
|
+
ACCOUNT_CLAIM: '/account/claim',
|
|
183
|
+
ACTIVITIES: '/activities',
|
|
184
|
+
LABELS: '/labels',
|
|
185
|
+
LIMITS: '/limits',
|
|
186
|
+
PING: '/ping',
|
|
187
|
+
SETUP: '/setup',
|
|
188
|
+
SPA_CHECK: '/spa-check',
|
|
189
|
+
UPLOAD: '/upload',
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* The deploy request's multipart field names — the other half of the wire
|
|
193
|
+
* surface beside {@link API_PATHS}. `POST /deployments` (and the first-party
|
|
194
|
+
* `/upload`) is multipart/form-data, and these are the names the API reads.
|
|
195
|
+
*
|
|
196
|
+
* Declared once because the body has three independent WRITERS — the SDK's
|
|
197
|
+
* Node and browser body builders, and the n8n community node's hand-rolled
|
|
198
|
+
* client (which cannot import this under n8n Cloud's zero-dependency rule,
|
|
199
|
+
* and fences its restated copy instead) — and until this export every writer
|
|
200
|
+
* restated the strings the API parses, with nothing comparing them.
|
|
201
|
+
*
|
|
202
|
+
* `FILES` carries one entry per file (the API reads it with `getAll`); every
|
|
203
|
+
* other field is single. The `@internal` flags are serialized as the literal
|
|
204
|
+
* string `'true'` and belong to first-party surfaces only.
|
|
205
|
+
*/
|
|
206
|
+
export const DEPLOY_FIELDS = {
|
|
207
|
+
/** One entry per file — read with `getAll`. */
|
|
208
|
+
FILES: 'files[]',
|
|
209
|
+
/** JSON array of MD5 hex digests, index-aligned with `FILES`. */
|
|
210
|
+
CHECKSUMS: 'checksums',
|
|
211
|
+
/** JSON array of label strings. */
|
|
212
|
+
LABELS: 'labels',
|
|
213
|
+
/** The deploying surface's {@link DeploymentVia} member. */
|
|
214
|
+
VIA: 'via',
|
|
215
|
+
/** Plaintext password — the API hashes it server-side. */
|
|
216
|
+
PASSWORD: 'password',
|
|
217
|
+
/** @internal Server-processing flag — first-party `/upload` only. */
|
|
218
|
+
BUILD: 'build',
|
|
219
|
+
/** @internal Server-processing flag — first-party `/upload` only. */
|
|
220
|
+
PRERENDER: 'prerender',
|
|
221
|
+
/** @internal Server-processing flag — first-party `/upload` only. */
|
|
222
|
+
SPA: 'spa',
|
|
223
|
+
/** @internal reCAPTCHA proof — `web/www`'s public uploader only. */
|
|
224
|
+
CAPTCHA: 'captcha',
|
|
225
|
+
};
|
|
226
|
+
// =============================================================================
|
|
189
227
|
// ERROR SYSTEM
|
|
190
228
|
// =============================================================================
|
|
191
229
|
/**
|
|
@@ -948,6 +986,26 @@ export const DEPLOYMENT_CONFIG_FILENAME = 'ship.json';
|
|
|
948
986
|
export const SPA_DEFAULT_CONFIG = {
|
|
949
987
|
rewrites: [{ source: '/(.*)', destination: '/index.html' }],
|
|
950
988
|
};
|
|
989
|
+
/**
|
|
990
|
+
* The `/spa-check` pre-flight's client-side envelope: which file is the
|
|
991
|
+
* check's subject, and how large it may be before a client skips the call.
|
|
992
|
+
*
|
|
993
|
+
* One fact with three holders until this export — the API's config declared
|
|
994
|
+
* the cap, the SDK's `checkSPA` hardcoded `100 * 1024`, and prose restated
|
|
995
|
+
* "100KB". `INDEX_FILE` is the selection rule (the file whose content rides
|
|
996
|
+
* `SPACheckRequest.index`), restated by every client that builds the request.
|
|
997
|
+
*
|
|
998
|
+
* Neither member is a validation boundary: a client over the cap simply
|
|
999
|
+
* skips the pre-flight, because the server answers an oversized index
|
|
1000
|
+
* `isSPA: false` anyway. A consumer that cannot import this (n8n) needs no
|
|
1001
|
+
* size copy at all — outcome parity is the server's, not the client's.
|
|
1002
|
+
*/
|
|
1003
|
+
export const SPA_CHECK_CONSTRAINTS = {
|
|
1004
|
+
/** The file whose content is the check's subject. */
|
|
1005
|
+
INDEX_FILE: 'index.html',
|
|
1006
|
+
/** Skip the pre-flight above this size — the server would answer false. */
|
|
1007
|
+
MAX_INDEX_BYTES: 100 * 1024,
|
|
1008
|
+
};
|
|
951
1009
|
/**
|
|
952
1010
|
* Assert that a ship.json file is *syntactically* loadable. Syntax only —
|
|
953
1011
|
* never schema.
|
|
@@ -1090,6 +1148,35 @@ export function isDeployment(input) {
|
|
|
1090
1148
|
// =============================================================================
|
|
1091
1149
|
/** Default API URL if not otherwise configured. */
|
|
1092
1150
|
export const DEFAULT_API = 'https://api.shipstatic.com';
|
|
1151
|
+
/**
|
|
1152
|
+
* The Node SDK's ambient configuration pair — the ONLY environment variables
|
|
1153
|
+
* the SDK reads, and therefore the COMPLETE list an embedding host must
|
|
1154
|
+
* scrub (per `npm/ship`'s strict-isolation contract, scrubbing is the host's
|
|
1155
|
+
* job, not the SDK's). A host that derives its scrub from this object's
|
|
1156
|
+
* values — as the VS Code extension's child-process env block does — picks
|
|
1157
|
+
* up a grown contract at the next pin bump instead of by remembered prose.
|
|
1158
|
+
*
|
|
1159
|
+
* Browser builds read no environment at all, and the CLI-only variables
|
|
1160
|
+
* (`SHIP_PASSWORD`, `SHIP_VIA`) are deliberately NOT here: they are the
|
|
1161
|
+
* CLI's operational levers, not the SDK's ambient contract — see
|
|
1162
|
+
* `npm/ship/CLAUDE.md`, "CLI-only env vars".
|
|
1163
|
+
*/
|
|
1164
|
+
export const SHIP_ENV = {
|
|
1165
|
+
/** The one credential slot — any platform token. */
|
|
1166
|
+
TOKEN: 'SHIP_TOKEN',
|
|
1167
|
+
/** The API endpoint override. */
|
|
1168
|
+
API_URL: 'SHIP_API_URL',
|
|
1169
|
+
};
|
|
1170
|
+
/**
|
|
1171
|
+
* Where a human creates an API key — the console deep link quoted by every
|
|
1172
|
+
* surface that teaches authentication (the CLI's config wizard, the VS Code
|
|
1173
|
+
* and n8n listings, the n8n rate-limit hint and credential copy). Written
|
|
1174
|
+
* out in five files across three repos until this export.
|
|
1175
|
+
*
|
|
1176
|
+
* Production-branded by design: published artifacts name the product, never
|
|
1177
|
+
* an environment (root `CLAUDE.md`, "Environment-Aware URLs").
|
|
1178
|
+
*/
|
|
1179
|
+
export const MY_API_KEY_URL = 'https://my.shipstatic.com/api-key';
|
|
1093
1180
|
/**
|
|
1094
1181
|
* How long an anonymous deployment lives before it expires.
|
|
1095
1182
|
*
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// =============================================================================
|
|
7
|
-
//
|
|
7
|
+
// DEPLOYMENT TYPES
|
|
8
8
|
// =============================================================================
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -90,63 +90,6 @@ export interface DeploymentCreateResponse extends Deployment {
|
|
|
90
90
|
readonly claim?: string;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
/**
|
|
94
|
-
* Every path the public API answers on, declared once.
|
|
95
|
-
*
|
|
96
|
-
* The URL surface was written out in four places — the API's mounts, the
|
|
97
|
-
* SDK's client, the dashboard's client, and the post-deploy smoke — so a
|
|
98
|
-
* rename meant finding all four. The first three now read this table.
|
|
99
|
-
*
|
|
100
|
-
* The smoke (`cloudflare/api/smoke.mjs`) deliberately still spells its own:
|
|
101
|
-
* five of its nine paths are `/admin/*`, which this table excludes by
|
|
102
|
-
* design, and splitting one list between a registry and literals reads worse
|
|
103
|
-
* than keeping it uniform.
|
|
104
|
-
*
|
|
105
|
-
* **What this guarantees, exactly.** Collection paths are mounted from here,
|
|
106
|
-
* so producer and consumer cannot diverge. Item paths are declared here and
|
|
107
|
-
* consumed by clients, but the API spells them relative to their mount
|
|
108
|
-
* (`/:deployment/config`), so the table does not *generate* them — it is
|
|
109
|
-
* held to them by `api/tests/architecture/api-paths.test.ts`, which fails if
|
|
110
|
-
* any entry names a path no route answers. Some entries have no client yet
|
|
111
|
-
* (`DEPLOYMENT_CONFIG`, `DOMAIN_PROPAGATION` — endpoints the SDK
|
|
112
|
-
* deliberately does not reach); the fence is what keeps those honest rather
|
|
113
|
-
* than merely asserted.
|
|
114
|
-
*
|
|
115
|
-
* **The operator surface is deliberately absent.** `/admin/*` paths belong
|
|
116
|
-
* to `web/my`, for the same reason its row types do: this package is
|
|
117
|
-
* published, and the operator surface is not public (see `CLAUDE.md`, "Admin
|
|
118
|
-
* types"). A path here is a promise to every npm consumer; `/admin` is a
|
|
119
|
-
* promise to one dashboard.
|
|
120
|
-
*
|
|
121
|
-
* Item paths are functions rather than templates so the key is interpolated
|
|
122
|
-
* in one place, encoded the same way by every caller.
|
|
123
|
-
*/
|
|
124
|
-
export const API_PATHS = {
|
|
125
|
-
DEPLOYMENTS: '/deployments',
|
|
126
|
-
DEPLOYMENT: (deployment: string) => `/deployments/${deployment}`,
|
|
127
|
-
DEPLOYMENT_CONFIG: (deployment: string) => `/deployments/${deployment}/config`,
|
|
128
|
-
DOMAINS: '/domains',
|
|
129
|
-
DOMAIN: (domain: string) => `/domains/${domain}`,
|
|
130
|
-
DOMAIN_VERIFY: (domain: string) => `/domains/${domain}/verify`,
|
|
131
|
-
DOMAIN_DNS: (domain: string) => `/domains/${domain}/dns`,
|
|
132
|
-
DOMAIN_RECORDS: (domain: string) => `/domains/${domain}/records`,
|
|
133
|
-
DOMAIN_SHARE: (domain: string) => `/domains/${domain}/share`,
|
|
134
|
-
DOMAIN_PROPAGATION: (domain: string) => `/domains/${domain}/propagation`,
|
|
135
|
-
DOMAINS_VALIDATE: '/domains/validate',
|
|
136
|
-
TOKENS: '/tokens',
|
|
137
|
-
TOKEN: (token: string) => `/tokens/${token}`,
|
|
138
|
-
ACCOUNT: '/account',
|
|
139
|
-
ACCOUNT_KEY: '/account/key',
|
|
140
|
-
ACCOUNT_CLAIM: '/account/claim',
|
|
141
|
-
ACTIVITIES: '/activities',
|
|
142
|
-
LABELS: '/labels',
|
|
143
|
-
LIMITS: '/limits',
|
|
144
|
-
PING: '/ping',
|
|
145
|
-
SETUP: '/setup',
|
|
146
|
-
SPA_CHECK: '/spa-check',
|
|
147
|
-
UPLOAD: '/upload',
|
|
148
|
-
} as const;
|
|
149
|
-
|
|
150
93
|
/**
|
|
151
94
|
* The half of a list response that is identical on every list.
|
|
152
95
|
*
|
|
@@ -166,6 +109,29 @@ export interface ListResponse {
|
|
|
166
109
|
cursor: string | null;
|
|
167
110
|
}
|
|
168
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Pagination options for every list endpoint. The response's `cursor` feeds
|
|
114
|
+
* the next request; a `null` cursor means the last page. Omitting both
|
|
115
|
+
* returns the server's default first page.
|
|
116
|
+
*
|
|
117
|
+
* A list answers `{ <collection>, cursor }` and nothing else — `cursor`
|
|
118
|
+
* carries the entire has-more signal, so no redundant boolean, and no
|
|
119
|
+
* `total`. **A count is an aggregate over a collection, not a property of a
|
|
120
|
+
* page:** including one makes every read pay for a full scan it did not ask
|
|
121
|
+
* for, which is precisely the cost keyset pagination exists to avoid.
|
|
122
|
+
*
|
|
123
|
+
* Counts therefore live on the summary resource that owns them —
|
|
124
|
+
* `GET /account` (`usage`) for a caller's own totals, `GET /admin/stats` for
|
|
125
|
+
* platform-wide ones. Ask for a count when you want a count; ask for a page
|
|
126
|
+
* when you want a page.
|
|
127
|
+
*/
|
|
128
|
+
export interface ListOptions {
|
|
129
|
+
/** Maximum number of items to return in one page. */
|
|
130
|
+
limit?: number;
|
|
131
|
+
/** Opaque cursor from the previous page's response. */
|
|
132
|
+
cursor?: string;
|
|
133
|
+
}
|
|
134
|
+
|
|
169
135
|
/**
|
|
170
136
|
* Response for listing deployments
|
|
171
137
|
*/
|
|
@@ -703,6 +669,103 @@ export interface AccountOverrides {
|
|
|
703
669
|
totalSize?: number;
|
|
704
670
|
}
|
|
705
671
|
|
|
672
|
+
// =============================================================================
|
|
673
|
+
// WIRE SURFACE
|
|
674
|
+
// =============================================================================
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* Every path the public API answers on, declared once.
|
|
678
|
+
*
|
|
679
|
+
* The URL surface was written out in four places — the API's mounts, the
|
|
680
|
+
* SDK's client, the dashboard's client, and the post-deploy smoke — so a
|
|
681
|
+
* rename meant finding all four. The first three now read this table.
|
|
682
|
+
*
|
|
683
|
+
* The smoke (`cloudflare/api/smoke.mjs`) deliberately still spells its own:
|
|
684
|
+
* five of its nine paths are `/admin/*`, which this table excludes by
|
|
685
|
+
* design, and splitting one list between a registry and literals reads worse
|
|
686
|
+
* than keeping it uniform.
|
|
687
|
+
*
|
|
688
|
+
* **What this guarantees, exactly.** Collection paths are mounted from here,
|
|
689
|
+
* so producer and consumer cannot diverge. Item paths are declared here and
|
|
690
|
+
* consumed by clients, but the API spells them relative to their mount
|
|
691
|
+
* (`/:deployment/config`), so the table does not *generate* them — it is
|
|
692
|
+
* held to them by `api/tests/architecture/api-paths.test.ts`, which fails if
|
|
693
|
+
* any entry names a path no route answers. Some entries have no client yet
|
|
694
|
+
* (`DEPLOYMENT_CONFIG`, `DOMAIN_PROPAGATION` — endpoints the SDK
|
|
695
|
+
* deliberately does not reach); the fence is what keeps those honest rather
|
|
696
|
+
* than merely asserted.
|
|
697
|
+
*
|
|
698
|
+
* **The operator surface is deliberately absent.** `/admin/*` paths belong
|
|
699
|
+
* to `web/my`, for the same reason its row types do: this package is
|
|
700
|
+
* published, and the operator surface is not public (see `CLAUDE.md`, "Admin
|
|
701
|
+
* types"). A path here is a promise to every npm consumer; `/admin` is a
|
|
702
|
+
* promise to one dashboard.
|
|
703
|
+
*
|
|
704
|
+
* Item paths are functions rather than templates so the key is interpolated
|
|
705
|
+
* in one place, encoded the same way by every caller.
|
|
706
|
+
*/
|
|
707
|
+
export const API_PATHS = {
|
|
708
|
+
DEPLOYMENTS: '/deployments',
|
|
709
|
+
DEPLOYMENT: (deployment: string) => `/deployments/${deployment}`,
|
|
710
|
+
DEPLOYMENT_CONFIG: (deployment: string) => `/deployments/${deployment}/config`,
|
|
711
|
+
DOMAINS: '/domains',
|
|
712
|
+
DOMAIN: (domain: string) => `/domains/${domain}`,
|
|
713
|
+
DOMAIN_VERIFY: (domain: string) => `/domains/${domain}/verify`,
|
|
714
|
+
DOMAIN_DNS: (domain: string) => `/domains/${domain}/dns`,
|
|
715
|
+
DOMAIN_RECORDS: (domain: string) => `/domains/${domain}/records`,
|
|
716
|
+
DOMAIN_SHARE: (domain: string) => `/domains/${domain}/share`,
|
|
717
|
+
DOMAIN_PROPAGATION: (domain: string) => `/domains/${domain}/propagation`,
|
|
718
|
+
DOMAINS_VALIDATE: '/domains/validate',
|
|
719
|
+
TOKENS: '/tokens',
|
|
720
|
+
TOKEN: (token: string) => `/tokens/${token}`,
|
|
721
|
+
ACCOUNT: '/account',
|
|
722
|
+
ACCOUNT_KEY: '/account/key',
|
|
723
|
+
ACCOUNT_CLAIM: '/account/claim',
|
|
724
|
+
ACTIVITIES: '/activities',
|
|
725
|
+
LABELS: '/labels',
|
|
726
|
+
LIMITS: '/limits',
|
|
727
|
+
PING: '/ping',
|
|
728
|
+
SETUP: '/setup',
|
|
729
|
+
SPA_CHECK: '/spa-check',
|
|
730
|
+
UPLOAD: '/upload',
|
|
731
|
+
} as const;
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* The deploy request's multipart field names — the other half of the wire
|
|
735
|
+
* surface beside {@link API_PATHS}. `POST /deployments` (and the first-party
|
|
736
|
+
* `/upload`) is multipart/form-data, and these are the names the API reads.
|
|
737
|
+
*
|
|
738
|
+
* Declared once because the body has three independent WRITERS — the SDK's
|
|
739
|
+
* Node and browser body builders, and the n8n community node's hand-rolled
|
|
740
|
+
* client (which cannot import this under n8n Cloud's zero-dependency rule,
|
|
741
|
+
* and fences its restated copy instead) — and until this export every writer
|
|
742
|
+
* restated the strings the API parses, with nothing comparing them.
|
|
743
|
+
*
|
|
744
|
+
* `FILES` carries one entry per file (the API reads it with `getAll`); every
|
|
745
|
+
* other field is single. The `@internal` flags are serialized as the literal
|
|
746
|
+
* string `'true'` and belong to first-party surfaces only.
|
|
747
|
+
*/
|
|
748
|
+
export const DEPLOY_FIELDS = {
|
|
749
|
+
/** One entry per file — read with `getAll`. */
|
|
750
|
+
FILES: 'files[]',
|
|
751
|
+
/** JSON array of MD5 hex digests, index-aligned with `FILES`. */
|
|
752
|
+
CHECKSUMS: 'checksums',
|
|
753
|
+
/** JSON array of label strings. */
|
|
754
|
+
LABELS: 'labels',
|
|
755
|
+
/** The deploying surface's {@link DeploymentVia} member. */
|
|
756
|
+
VIA: 'via',
|
|
757
|
+
/** Plaintext password — the API hashes it server-side. */
|
|
758
|
+
PASSWORD: 'password',
|
|
759
|
+
/** @internal Server-processing flag — first-party `/upload` only. */
|
|
760
|
+
BUILD: 'build',
|
|
761
|
+
/** @internal Server-processing flag — first-party `/upload` only. */
|
|
762
|
+
PRERENDER: 'prerender',
|
|
763
|
+
/** @internal Server-processing flag — first-party `/upload` only. */
|
|
764
|
+
SPA: 'spa',
|
|
765
|
+
/** @internal reCAPTCHA proof — `web/www`'s public uploader only. */
|
|
766
|
+
CAPTCHA: 'captcha',
|
|
767
|
+
} as const;
|
|
768
|
+
|
|
706
769
|
// =============================================================================
|
|
707
770
|
// ERROR SYSTEM
|
|
708
771
|
// =============================================================================
|
|
@@ -1143,7 +1206,7 @@ export function isShipError(error: unknown): error is ShipError {
|
|
|
1143
1206
|
}
|
|
1144
1207
|
|
|
1145
1208
|
// =============================================================================
|
|
1146
|
-
//
|
|
1209
|
+
// PLATFORM LIMITS
|
|
1147
1210
|
// =============================================================================
|
|
1148
1211
|
|
|
1149
1212
|
/**
|
|
@@ -1593,6 +1656,27 @@ export const SPA_DEFAULT_CONFIG = {
|
|
|
1593
1656
|
rewrites: [{ source: '/(.*)', destination: '/index.html' }],
|
|
1594
1657
|
} as const;
|
|
1595
1658
|
|
|
1659
|
+
/**
|
|
1660
|
+
* The `/spa-check` pre-flight's client-side envelope: which file is the
|
|
1661
|
+
* check's subject, and how large it may be before a client skips the call.
|
|
1662
|
+
*
|
|
1663
|
+
* One fact with three holders until this export — the API's config declared
|
|
1664
|
+
* the cap, the SDK's `checkSPA` hardcoded `100 * 1024`, and prose restated
|
|
1665
|
+
* "100KB". `INDEX_FILE` is the selection rule (the file whose content rides
|
|
1666
|
+
* `SPACheckRequest.index`), restated by every client that builds the request.
|
|
1667
|
+
*
|
|
1668
|
+
* Neither member is a validation boundary: a client over the cap simply
|
|
1669
|
+
* skips the pre-flight, because the server answers an oversized index
|
|
1670
|
+
* `isSPA: false` anyway. A consumer that cannot import this (n8n) needs no
|
|
1671
|
+
* size copy at all — outcome parity is the server's, not the client's.
|
|
1672
|
+
*/
|
|
1673
|
+
export const SPA_CHECK_CONSTRAINTS = {
|
|
1674
|
+
/** The file whose content is the check's subject. */
|
|
1675
|
+
INDEX_FILE: 'index.html',
|
|
1676
|
+
/** Skip the pre-flight above this size — the server would answer false. */
|
|
1677
|
+
MAX_INDEX_BYTES: 100 * 1024,
|
|
1678
|
+
} as const;
|
|
1679
|
+
|
|
1596
1680
|
/**
|
|
1597
1681
|
* Assert that a ship.json file is *syntactically* loadable. Syntax only —
|
|
1598
1682
|
* never schema.
|
|
@@ -1834,6 +1918,37 @@ export interface StaticFile {
|
|
|
1834
1918
|
/** Default API URL if not otherwise configured. */
|
|
1835
1919
|
export const DEFAULT_API = 'https://api.shipstatic.com';
|
|
1836
1920
|
|
|
1921
|
+
/**
|
|
1922
|
+
* The Node SDK's ambient configuration pair — the ONLY environment variables
|
|
1923
|
+
* the SDK reads, and therefore the COMPLETE list an embedding host must
|
|
1924
|
+
* scrub (per `npm/ship`'s strict-isolation contract, scrubbing is the host's
|
|
1925
|
+
* job, not the SDK's). A host that derives its scrub from this object's
|
|
1926
|
+
* values — as the VS Code extension's child-process env block does — picks
|
|
1927
|
+
* up a grown contract at the next pin bump instead of by remembered prose.
|
|
1928
|
+
*
|
|
1929
|
+
* Browser builds read no environment at all, and the CLI-only variables
|
|
1930
|
+
* (`SHIP_PASSWORD`, `SHIP_VIA`) are deliberately NOT here: they are the
|
|
1931
|
+
* CLI's operational levers, not the SDK's ambient contract — see
|
|
1932
|
+
* `npm/ship/CLAUDE.md`, "CLI-only env vars".
|
|
1933
|
+
*/
|
|
1934
|
+
export const SHIP_ENV = {
|
|
1935
|
+
/** The one credential slot — any platform token. */
|
|
1936
|
+
TOKEN: 'SHIP_TOKEN',
|
|
1937
|
+
/** The API endpoint override. */
|
|
1938
|
+
API_URL: 'SHIP_API_URL',
|
|
1939
|
+
} as const;
|
|
1940
|
+
|
|
1941
|
+
/**
|
|
1942
|
+
* Where a human creates an API key — the console deep link quoted by every
|
|
1943
|
+
* surface that teaches authentication (the CLI's config wizard, the VS Code
|
|
1944
|
+
* and n8n listings, the n8n rate-limit hint and credential copy). Written
|
|
1945
|
+
* out in five files across three repos until this export.
|
|
1946
|
+
*
|
|
1947
|
+
* Production-branded by design: published artifacts name the product, never
|
|
1948
|
+
* an environment (root `CLAUDE.md`, "Environment-Aware URLs").
|
|
1949
|
+
*/
|
|
1950
|
+
export const MY_API_KEY_URL = 'https://my.shipstatic.com/api-key';
|
|
1951
|
+
|
|
1837
1952
|
/**
|
|
1838
1953
|
* How long an anonymous deployment lives before it expires.
|
|
1839
1954
|
*
|
|
@@ -1919,29 +2034,6 @@ export interface DeploymentUploadOptions {
|
|
|
1919
2034
|
idempotencyKey?: string;
|
|
1920
2035
|
}
|
|
1921
2036
|
|
|
1922
|
-
/**
|
|
1923
|
-
* Pagination options for every list endpoint. The response's `cursor` feeds
|
|
1924
|
-
* the next request; a `null` cursor means the last page. Omitting both
|
|
1925
|
-
* returns the server's default first page.
|
|
1926
|
-
*
|
|
1927
|
-
* A list answers `{ <collection>, cursor }` and nothing else — `cursor`
|
|
1928
|
-
* carries the entire has-more signal, so no redundant boolean, and no
|
|
1929
|
-
* `total`. **A count is an aggregate over a collection, not a property of a
|
|
1930
|
-
* page:** including one makes every read pay for a full scan it did not ask
|
|
1931
|
-
* for, which is precisely the cost keyset pagination exists to avoid.
|
|
1932
|
-
*
|
|
1933
|
-
* Counts therefore live on the summary resource that owns them —
|
|
1934
|
-
* `GET /account` (`usage`) for a caller's own totals, `GET /admin/stats` for
|
|
1935
|
-
* platform-wide ones. Ask for a count when you want a count; ask for a page
|
|
1936
|
-
* when you want a page.
|
|
1937
|
-
*/
|
|
1938
|
-
export interface ListOptions {
|
|
1939
|
-
/** Maximum number of items to return in one page. */
|
|
1940
|
-
limit?: number;
|
|
1941
|
-
/** Opaque cursor from the previous page's response. */
|
|
1942
|
-
cursor?: string;
|
|
1943
|
-
}
|
|
1944
|
-
|
|
1945
2037
|
/**
|
|
1946
2038
|
* What a caller may change on an existing deployment.
|
|
1947
2039
|
*
|