@shipstatic/types 2.5.0-beta.11 → 2.5.0-beta.12
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 +8 -4
- package/dist/index.d.ts +159 -33
- package/dist/index.js +43 -0
- package/package.json +1 -1
- package/src/index.ts +168 -23
package/README.md
CHANGED
|
@@ -20,13 +20,17 @@ npm install @shipstatic/types
|
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
22
|
import type {
|
|
23
|
-
ListResponse,
|
|
24
|
-
Deployment, DeploymentListResponse, DeploymentDeleteResponse,
|
|
25
|
-
Domain, DomainSetResult, DomainListResponse, DnsRecord, DomainDnsResponse, DomainRecordsResponse, DomainValidateResponse, DomainDeleteResponse, DomainVerifyResponse,
|
|
26
|
-
Token, TokenListResponse, TokenCreateResponse, TokenDeleteResponse,
|
|
23
|
+
ListResponse, ListOptions,
|
|
24
|
+
Deployment, DeploymentListResponse, DeploymentDeleteResponse, DeploymentSetOptions,
|
|
25
|
+
Domain, DomainSetResult, DomainSetOptions, DomainListResponse, DnsRecord, DnsLookup, DomainDnsResponse, DomainRecordsResponse, DomainShareResponse, DomainValidateResponse, DomainDeleteResponse, DomainVerifyResponse,
|
|
26
|
+
Token, TokenListResponse, TokenCreateResponse, TokenCreateOptions, TokenDeleteResponse,
|
|
27
27
|
Account, AccountUsage, AccountOverrides, AccountDeleteResponse, AccountKeyResponse,
|
|
28
|
+
LabelsResponse, SetupInstructionsResponse,
|
|
28
29
|
StaticFile
|
|
29
30
|
} from '@shipstatic/types';
|
|
31
|
+
|
|
32
|
+
// Every public path, declared once — the API mounts from it, clients request against it.
|
|
33
|
+
import { API_PATHS } from '@shipstatic/types';
|
|
30
34
|
```
|
|
31
35
|
|
|
32
36
|
A mutation answers with the resource it affected — the entity when it
|
package/dist/index.d.ts
CHANGED
|
@@ -49,6 +49,49 @@ export interface DeploymentCreateResponse extends Deployment {
|
|
|
49
49
|
/** Claim URL for public deployments. Present when deployed without credentials. */
|
|
50
50
|
readonly claim?: string;
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Every path the public API answers on, declared once.
|
|
54
|
+
*
|
|
55
|
+
* The URL surface used to be written out in four places — the API's mounts,
|
|
56
|
+
* the SDK's client, the dashboard's client, and the post-deploy smoke — so a
|
|
57
|
+
* rename meant finding all four. Here it is one table that the producer
|
|
58
|
+
* mounts from and the consumers request against, which is the only way a
|
|
59
|
+
* path and its handler cannot drift apart.
|
|
60
|
+
*
|
|
61
|
+
* **The operator surface is deliberately absent.** `/admin/*` paths belong
|
|
62
|
+
* to `web/my`, for the same reason its row types do: this package is
|
|
63
|
+
* published, and the operator surface is not public (see `CLAUDE.md`, "Admin
|
|
64
|
+
* types"). A path here is a promise to every npm consumer; `/admin` is a
|
|
65
|
+
* promise to one dashboard.
|
|
66
|
+
*
|
|
67
|
+
* Item paths are functions rather than templates so the key is interpolated
|
|
68
|
+
* in one place, encoded the same way by every caller.
|
|
69
|
+
*/
|
|
70
|
+
export declare const API_PATHS: {
|
|
71
|
+
readonly DEPLOYMENTS: "/deployments";
|
|
72
|
+
readonly DEPLOYMENT: (deployment: string) => string;
|
|
73
|
+
readonly DEPLOYMENT_CONFIG: (deployment: string) => string;
|
|
74
|
+
readonly DOMAINS: "/domains";
|
|
75
|
+
readonly DOMAIN: (domain: string) => string;
|
|
76
|
+
readonly DOMAIN_VERIFY: (domain: string) => string;
|
|
77
|
+
readonly DOMAIN_DNS: (domain: string) => string;
|
|
78
|
+
readonly DOMAIN_RECORDS: (domain: string) => string;
|
|
79
|
+
readonly DOMAIN_SHARE: (domain: string) => string;
|
|
80
|
+
readonly DOMAIN_PROPAGATION: (domain: string) => string;
|
|
81
|
+
readonly DOMAINS_VALIDATE: "/domains/validate";
|
|
82
|
+
readonly TOKENS: "/tokens";
|
|
83
|
+
readonly TOKEN: (token: string) => string;
|
|
84
|
+
readonly ACCOUNT: "/account";
|
|
85
|
+
readonly ACCOUNT_KEY: "/account/key";
|
|
86
|
+
readonly ACCOUNT_CLAIM: "/account/claim";
|
|
87
|
+
readonly ACTIVITIES: "/activities";
|
|
88
|
+
readonly LABELS: "/labels";
|
|
89
|
+
readonly LIMITS: "/limits";
|
|
90
|
+
readonly PING: "/ping";
|
|
91
|
+
readonly SETUP: "/setup";
|
|
92
|
+
readonly SPA_CHECK: "/spa-check";
|
|
93
|
+
readonly UPLOAD: "/upload";
|
|
94
|
+
};
|
|
52
95
|
/**
|
|
53
96
|
* The half of a list response that is identical on every list.
|
|
54
97
|
*
|
|
@@ -86,12 +129,23 @@ export interface DeploymentListResponse extends ListResponse {
|
|
|
86
129
|
* Where the resource is simply gone, the key alone is the whole answer
|
|
87
130
|
* ({@link DomainDeleteResponse}, {@link TokenDeleteResponse}).
|
|
88
131
|
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
132
|
+
* Put positively: **an acknowledgement is a projection of the resource** —
|
|
133
|
+
* its key, plus its own state field where the state changed. That is the
|
|
134
|
+
* test to apply, and it is sharper than "no constant", which this shape
|
|
135
|
+
* would fail on its own terms: `status` here is the literal `'deleting'` on
|
|
136
|
+
* every success, exactly as fixed as a `changed: true` would be.
|
|
137
|
+
*
|
|
138
|
+
* The difference is not how predictable the value is, it is what the field
|
|
139
|
+
* IS. `status` is the deployment's own field — the same one `GET
|
|
140
|
+
* /deployments/:deployment` returns — so this response is `Deployment`
|
|
141
|
+
* narrowed to two members, and a client renders it with the code it already
|
|
142
|
+
* has. `changed: true`, `queued: true` and `success: true` are not fields of
|
|
143
|
+
* any entity; they exist only to assert that the call worked, which the
|
|
144
|
+
* status code already said. Sync versus accepted is likewise the status
|
|
145
|
+
* code's job — 200 versus 202 — not a boolean's.
|
|
146
|
+
*
|
|
147
|
+
* No prose either (`message`): an acknowledgement is data, and each surface
|
|
148
|
+
* composes its own copy.
|
|
95
149
|
*/
|
|
96
150
|
export interface DeploymentDeleteResponse {
|
|
97
151
|
/** The deployment hostname that was marked for removal */
|
|
@@ -200,13 +254,33 @@ export interface DnsProvider {
|
|
|
200
254
|
/**
|
|
201
255
|
* Response for domain DNS provider lookup
|
|
202
256
|
*/
|
|
257
|
+
/**
|
|
258
|
+
* What a DNS lookup found for a domain. An envelope rather than a bare
|
|
259
|
+
* {@link DnsProvider} because a lookup can succeed and learn more than the
|
|
260
|
+
* provider later; the shape is named so a consumer can hold one.
|
|
261
|
+
*/
|
|
262
|
+
export interface DnsLookup {
|
|
263
|
+
/** The provider serving this domain's DNS, absent when unidentified */
|
|
264
|
+
provider?: DnsProvider;
|
|
265
|
+
}
|
|
203
266
|
export interface DomainDnsResponse {
|
|
204
267
|
/** The domain name */
|
|
205
268
|
domain: string;
|
|
206
269
|
/** DNS provider information, null if not yet looked up */
|
|
207
|
-
dns:
|
|
208
|
-
|
|
209
|
-
|
|
270
|
+
dns: DnsLookup | null;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Response for `GET /domains/:domain/share` — the domain plus the salted
|
|
274
|
+
* hash that lets someone else complete its DNS setup without an account.
|
|
275
|
+
*
|
|
276
|
+
* `/admin/domains/:domain/share` answers the same shape, which is the admin
|
|
277
|
+
* law working: the operator surface is the public grammar with a prefix.
|
|
278
|
+
*/
|
|
279
|
+
export interface DomainShareResponse {
|
|
280
|
+
/** The domain the setup link is for */
|
|
281
|
+
readonly domain: string;
|
|
282
|
+
/** The salted setup hash that authorizes the share */
|
|
283
|
+
readonly hash: string;
|
|
210
284
|
}
|
|
211
285
|
/**
|
|
212
286
|
* Response for domain DNS records
|
|
@@ -219,6 +293,35 @@ export interface DomainRecordsResponse {
|
|
|
219
293
|
/** Required DNS records for configuration */
|
|
220
294
|
records: DnsRecord[];
|
|
221
295
|
}
|
|
296
|
+
/**
|
|
297
|
+
* Response for `GET /labels` — every label in use across the caller's
|
|
298
|
+
* deployments, domains and tokens, grouped and ordered by last use.
|
|
299
|
+
*
|
|
300
|
+
* The one plural noun outside the list contract, deliberately: labels have
|
|
301
|
+
* no identity, no row and no `created`, so there is nothing for a keyset
|
|
302
|
+
* cursor to resume after, and its consumer is an autocomplete that wants the
|
|
303
|
+
* whole set. Bounded by `PAGINATION.GLOBAL_LIMIT` rather than paginated.
|
|
304
|
+
*/
|
|
305
|
+
export interface LabelsResponse {
|
|
306
|
+
readonly labels: string[];
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Response for `POST /setup` — the DNS instructions for one domain, written
|
|
310
|
+
* for a human to follow at their registrar.
|
|
311
|
+
*
|
|
312
|
+
* `custom` is the provider-specific walkthrough when the provider is known;
|
|
313
|
+
* `generic` always answers, so a caller never has nothing to show.
|
|
314
|
+
*/
|
|
315
|
+
export interface SetupInstructionsResponse {
|
|
316
|
+
/** One-line summary of what to do */
|
|
317
|
+
readonly tldr: string;
|
|
318
|
+
/** Provider-specific instructions, null when the provider is unknown */
|
|
319
|
+
readonly custom: string | null;
|
|
320
|
+
/** Provider-agnostic instructions — always present */
|
|
321
|
+
readonly generic: string;
|
|
322
|
+
/** The identified DNS provider, null when unknown */
|
|
323
|
+
readonly provider: string | null;
|
|
324
|
+
}
|
|
222
325
|
/**
|
|
223
326
|
* Response for domain validation
|
|
224
327
|
*/
|
|
@@ -839,16 +942,22 @@ export interface SPACheckRequest {
|
|
|
839
942
|
/**
|
|
840
943
|
* Response from SPA check endpoint
|
|
841
944
|
*/
|
|
945
|
+
/**
|
|
946
|
+
* Which of the classifier's tiers reached the verdict, and why. Named rather
|
|
947
|
+
* than inline so the API's own `checkSPA` can return `SPACheckResponse`
|
|
948
|
+
* instead of restating its shape.
|
|
949
|
+
*/
|
|
950
|
+
export interface SPACheckDebug {
|
|
951
|
+
/** Which tier made the detection */
|
|
952
|
+
tier: 'exclusions' | 'inclusions' | 'scoring' | 'ai' | 'fallback';
|
|
953
|
+
/** The reason for the detection result */
|
|
954
|
+
reason: string;
|
|
955
|
+
}
|
|
842
956
|
export interface SPACheckResponse {
|
|
843
957
|
/** Whether the project is detected as a Single Page Application */
|
|
844
958
|
isSPA: boolean;
|
|
845
959
|
/** Debugging information about detection */
|
|
846
|
-
debug:
|
|
847
|
-
/** Which tier made the detection: 'exclusions', 'inclusions', 'scoring', 'ai', or 'fallback' */
|
|
848
|
-
tier: 'exclusions' | 'inclusions' | 'scoring' | 'ai' | 'fallback';
|
|
849
|
-
/** The reason for the detection result */
|
|
850
|
-
reason: string;
|
|
851
|
-
};
|
|
960
|
+
debug: SPACheckDebug;
|
|
852
961
|
}
|
|
853
962
|
/**
|
|
854
963
|
* Represents a file that has been processed and is ready for deploy.
|
|
@@ -943,6 +1052,33 @@ export interface ListOptions {
|
|
|
943
1052
|
/** Opaque cursor from the previous page's response. */
|
|
944
1053
|
cursor?: string;
|
|
945
1054
|
}
|
|
1055
|
+
/**
|
|
1056
|
+
* What a caller may change on an existing deployment.
|
|
1057
|
+
*
|
|
1058
|
+
* Labels and nothing else: a deployment's content is immutable by design, so
|
|
1059
|
+
* this is the whole mutable surface rather than a subset someone chose.
|
|
1060
|
+
*/
|
|
1061
|
+
export interface DeploymentSetOptions {
|
|
1062
|
+
labels: string[];
|
|
1063
|
+
}
|
|
1064
|
+
/**
|
|
1065
|
+
* What `domains.set()` may create or change. Every field is optional because
|
|
1066
|
+
* the call is a natural-key upsert: omitting `deployment` reserves the
|
|
1067
|
+
* domain, naming one links or re-points it, and labels travel either way.
|
|
1068
|
+
*
|
|
1069
|
+
* `deployment` is deliberately not nullable — unlinking is refused (400).
|
|
1070
|
+
* See `npm/ship/CLAUDE.md`, "Domain Write Semantics".
|
|
1071
|
+
*/
|
|
1072
|
+
export interface DomainSetOptions {
|
|
1073
|
+
deployment?: string;
|
|
1074
|
+
labels?: string[];
|
|
1075
|
+
}
|
|
1076
|
+
/** What a caller may set when minting a deploy token. */
|
|
1077
|
+
export interface TokenCreateOptions {
|
|
1078
|
+
/** Seconds until expiry; omit for a token that never expires. */
|
|
1079
|
+
ttl?: number;
|
|
1080
|
+
labels?: string[];
|
|
1081
|
+
}
|
|
946
1082
|
/**
|
|
947
1083
|
* Deployment resource interface - the contract all implementations must follow.
|
|
948
1084
|
*
|
|
@@ -955,30 +1091,22 @@ export interface DeploymentResource<UploadOptions extends DeploymentUploadOption
|
|
|
955
1091
|
upload: (input: DeployInput, options?: UploadOptions) => Promise<DeploymentCreateResponse>;
|
|
956
1092
|
list: (options?: ListOptions) => Promise<DeploymentListResponse>;
|
|
957
1093
|
get: (id: string) => Promise<Deployment>;
|
|
958
|
-
set: (id: string, options:
|
|
959
|
-
|
|
960
|
-
}) => Promise<Deployment>;
|
|
961
|
-
remove: (id: string) => Promise<void>;
|
|
1094
|
+
set: (id: string, options: DeploymentSetOptions) => Promise<Deployment>;
|
|
1095
|
+
remove: (id: string) => Promise<DeploymentDeleteResponse>;
|
|
962
1096
|
}
|
|
963
1097
|
/**
|
|
964
1098
|
* Domain resource interface - the contract all implementations must follow
|
|
965
1099
|
*/
|
|
966
1100
|
export interface DomainResource {
|
|
967
|
-
set: (name: string, options?:
|
|
968
|
-
deployment?: string;
|
|
969
|
-
labels?: string[];
|
|
970
|
-
}) => Promise<DomainSetResult>;
|
|
1101
|
+
set: (name: string, options?: DomainSetOptions) => Promise<DomainSetResult>;
|
|
971
1102
|
list: (options?: ListOptions) => Promise<DomainListResponse>;
|
|
972
1103
|
get: (name: string) => Promise<Domain>;
|
|
973
|
-
remove: (name: string) => Promise<
|
|
1104
|
+
remove: (name: string) => Promise<DomainDeleteResponse>;
|
|
974
1105
|
verify: (name: string) => Promise<DomainVerifyResponse>;
|
|
975
1106
|
validate: (name: string) => Promise<DomainValidateResponse>;
|
|
976
1107
|
dns: (name: string) => Promise<DomainDnsResponse>;
|
|
977
1108
|
records: (name: string) => Promise<DomainRecordsResponse>;
|
|
978
|
-
share: (name: string) => Promise<
|
|
979
|
-
domain: string;
|
|
980
|
-
hash: string;
|
|
981
|
-
}>;
|
|
1109
|
+
share: (name: string) => Promise<DomainShareResponse>;
|
|
982
1110
|
}
|
|
983
1111
|
/**
|
|
984
1112
|
* Account resource interface - the contract all implementations must follow
|
|
@@ -990,12 +1118,10 @@ export interface AccountResource {
|
|
|
990
1118
|
* Token resource interface - the contract all implementations must follow
|
|
991
1119
|
*/
|
|
992
1120
|
export interface TokenResource {
|
|
993
|
-
create: (options?:
|
|
994
|
-
ttl?: number;
|
|
995
|
-
labels?: string[];
|
|
996
|
-
}) => Promise<TokenCreateResponse>;
|
|
1121
|
+
create: (options?: TokenCreateOptions) => Promise<TokenCreateResponse>;
|
|
997
1122
|
list: (options?: ListOptions) => Promise<TokenListResponse>;
|
|
998
|
-
|
|
1123
|
+
get: (token: string) => Promise<Token>;
|
|
1124
|
+
remove: (token: string) => Promise<TokenDeleteResponse>;
|
|
999
1125
|
}
|
|
1000
1126
|
/**
|
|
1001
1127
|
* Billing status response from GET /billing/status
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,49 @@ export const DeploymentStatus = {
|
|
|
14
14
|
FAILED: 'failed',
|
|
15
15
|
DELETING: 'deleting',
|
|
16
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Every path the public API answers on, declared once.
|
|
19
|
+
*
|
|
20
|
+
* The URL surface used to be written out in four places — the API's mounts,
|
|
21
|
+
* the SDK's client, the dashboard's client, and the post-deploy smoke — so a
|
|
22
|
+
* rename meant finding all four. Here it is one table that the producer
|
|
23
|
+
* mounts from and the consumers request against, which is the only way a
|
|
24
|
+
* path and its handler cannot drift apart.
|
|
25
|
+
*
|
|
26
|
+
* **The operator surface is deliberately absent.** `/admin/*` paths belong
|
|
27
|
+
* to `web/my`, for the same reason its row types do: this package is
|
|
28
|
+
* published, and the operator surface is not public (see `CLAUDE.md`, "Admin
|
|
29
|
+
* types"). A path here is a promise to every npm consumer; `/admin` is a
|
|
30
|
+
* promise to one dashboard.
|
|
31
|
+
*
|
|
32
|
+
* Item paths are functions rather than templates so the key is interpolated
|
|
33
|
+
* in one place, encoded the same way by every caller.
|
|
34
|
+
*/
|
|
35
|
+
export const API_PATHS = {
|
|
36
|
+
DEPLOYMENTS: '/deployments',
|
|
37
|
+
DEPLOYMENT: (deployment) => `/deployments/${deployment}`,
|
|
38
|
+
DEPLOYMENT_CONFIG: (deployment) => `/deployments/${deployment}/config`,
|
|
39
|
+
DOMAINS: '/domains',
|
|
40
|
+
DOMAIN: (domain) => `/domains/${domain}`,
|
|
41
|
+
DOMAIN_VERIFY: (domain) => `/domains/${domain}/verify`,
|
|
42
|
+
DOMAIN_DNS: (domain) => `/domains/${domain}/dns`,
|
|
43
|
+
DOMAIN_RECORDS: (domain) => `/domains/${domain}/records`,
|
|
44
|
+
DOMAIN_SHARE: (domain) => `/domains/${domain}/share`,
|
|
45
|
+
DOMAIN_PROPAGATION: (domain) => `/domains/${domain}/propagation`,
|
|
46
|
+
DOMAINS_VALIDATE: '/domains/validate',
|
|
47
|
+
TOKENS: '/tokens',
|
|
48
|
+
TOKEN: (token) => `/tokens/${token}`,
|
|
49
|
+
ACCOUNT: '/account',
|
|
50
|
+
ACCOUNT_KEY: '/account/key',
|
|
51
|
+
ACCOUNT_CLAIM: '/account/claim',
|
|
52
|
+
ACTIVITIES: '/activities',
|
|
53
|
+
LABELS: '/labels',
|
|
54
|
+
LIMITS: '/limits',
|
|
55
|
+
PING: '/ping',
|
|
56
|
+
SETUP: '/setup',
|
|
57
|
+
SPA_CHECK: '/spa-check',
|
|
58
|
+
UPLOAD: '/upload',
|
|
59
|
+
};
|
|
17
60
|
// =============================================================================
|
|
18
61
|
// DOMAIN TYPES
|
|
19
62
|
// =============================================================================
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -58,6 +58,50 @@ export interface DeploymentCreateResponse extends Deployment {
|
|
|
58
58
|
readonly claim?: string;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Every path the public API answers on, declared once.
|
|
63
|
+
*
|
|
64
|
+
* The URL surface used to be written out in four places — the API's mounts,
|
|
65
|
+
* the SDK's client, the dashboard's client, and the post-deploy smoke — so a
|
|
66
|
+
* rename meant finding all four. Here it is one table that the producer
|
|
67
|
+
* mounts from and the consumers request against, which is the only way a
|
|
68
|
+
* path and its handler cannot drift apart.
|
|
69
|
+
*
|
|
70
|
+
* **The operator surface is deliberately absent.** `/admin/*` paths belong
|
|
71
|
+
* to `web/my`, for the same reason its row types do: this package is
|
|
72
|
+
* published, and the operator surface is not public (see `CLAUDE.md`, "Admin
|
|
73
|
+
* types"). A path here is a promise to every npm consumer; `/admin` is a
|
|
74
|
+
* promise to one dashboard.
|
|
75
|
+
*
|
|
76
|
+
* Item paths are functions rather than templates so the key is interpolated
|
|
77
|
+
* in one place, encoded the same way by every caller.
|
|
78
|
+
*/
|
|
79
|
+
export const API_PATHS = {
|
|
80
|
+
DEPLOYMENTS: '/deployments',
|
|
81
|
+
DEPLOYMENT: (deployment: string) => `/deployments/${deployment}`,
|
|
82
|
+
DEPLOYMENT_CONFIG: (deployment: string) => `/deployments/${deployment}/config`,
|
|
83
|
+
DOMAINS: '/domains',
|
|
84
|
+
DOMAIN: (domain: string) => `/domains/${domain}`,
|
|
85
|
+
DOMAIN_VERIFY: (domain: string) => `/domains/${domain}/verify`,
|
|
86
|
+
DOMAIN_DNS: (domain: string) => `/domains/${domain}/dns`,
|
|
87
|
+
DOMAIN_RECORDS: (domain: string) => `/domains/${domain}/records`,
|
|
88
|
+
DOMAIN_SHARE: (domain: string) => `/domains/${domain}/share`,
|
|
89
|
+
DOMAIN_PROPAGATION: (domain: string) => `/domains/${domain}/propagation`,
|
|
90
|
+
DOMAINS_VALIDATE: '/domains/validate',
|
|
91
|
+
TOKENS: '/tokens',
|
|
92
|
+
TOKEN: (token: string) => `/tokens/${token}`,
|
|
93
|
+
ACCOUNT: '/account',
|
|
94
|
+
ACCOUNT_KEY: '/account/key',
|
|
95
|
+
ACCOUNT_CLAIM: '/account/claim',
|
|
96
|
+
ACTIVITIES: '/activities',
|
|
97
|
+
LABELS: '/labels',
|
|
98
|
+
LIMITS: '/limits',
|
|
99
|
+
PING: '/ping',
|
|
100
|
+
SETUP: '/setup',
|
|
101
|
+
SPA_CHECK: '/spa-check',
|
|
102
|
+
UPLOAD: '/upload',
|
|
103
|
+
} as const;
|
|
104
|
+
|
|
61
105
|
/**
|
|
62
106
|
* The half of a list response that is identical on every list.
|
|
63
107
|
*
|
|
@@ -97,12 +141,23 @@ export interface DeploymentListResponse extends ListResponse {
|
|
|
97
141
|
* Where the resource is simply gone, the key alone is the whole answer
|
|
98
142
|
* ({@link DomainDeleteResponse}, {@link TokenDeleteResponse}).
|
|
99
143
|
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
144
|
+
* Put positively: **an acknowledgement is a projection of the resource** —
|
|
145
|
+
* its key, plus its own state field where the state changed. That is the
|
|
146
|
+
* test to apply, and it is sharper than "no constant", which this shape
|
|
147
|
+
* would fail on its own terms: `status` here is the literal `'deleting'` on
|
|
148
|
+
* every success, exactly as fixed as a `changed: true` would be.
|
|
149
|
+
*
|
|
150
|
+
* The difference is not how predictable the value is, it is what the field
|
|
151
|
+
* IS. `status` is the deployment's own field — the same one `GET
|
|
152
|
+
* /deployments/:deployment` returns — so this response is `Deployment`
|
|
153
|
+
* narrowed to two members, and a client renders it with the code it already
|
|
154
|
+
* has. `changed: true`, `queued: true` and `success: true` are not fields of
|
|
155
|
+
* any entity; they exist only to assert that the call worked, which the
|
|
156
|
+
* status code already said. Sync versus accepted is likewise the status
|
|
157
|
+
* code's job — 200 versus 202 — not a boolean's.
|
|
158
|
+
*
|
|
159
|
+
* No prose either (`message`): an acknowledgement is data, and each surface
|
|
160
|
+
* composes its own copy.
|
|
106
161
|
*/
|
|
107
162
|
export interface DeploymentDeleteResponse {
|
|
108
163
|
/** The deployment hostname that was marked for removal */
|
|
@@ -226,11 +281,35 @@ export interface DnsProvider {
|
|
|
226
281
|
/**
|
|
227
282
|
* Response for domain DNS provider lookup
|
|
228
283
|
*/
|
|
284
|
+
/**
|
|
285
|
+
* What a DNS lookup found for a domain. An envelope rather than a bare
|
|
286
|
+
* {@link DnsProvider} because a lookup can succeed and learn more than the
|
|
287
|
+
* provider later; the shape is named so a consumer can hold one.
|
|
288
|
+
*/
|
|
289
|
+
export interface DnsLookup {
|
|
290
|
+
/** The provider serving this domain's DNS, absent when unidentified */
|
|
291
|
+
provider?: DnsProvider;
|
|
292
|
+
}
|
|
293
|
+
|
|
229
294
|
export interface DomainDnsResponse {
|
|
230
295
|
/** The domain name */
|
|
231
296
|
domain: string;
|
|
232
297
|
/** DNS provider information, null if not yet looked up */
|
|
233
|
-
dns:
|
|
298
|
+
dns: DnsLookup | null;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Response for `GET /domains/:domain/share` — the domain plus the salted
|
|
303
|
+
* hash that lets someone else complete its DNS setup without an account.
|
|
304
|
+
*
|
|
305
|
+
* `/admin/domains/:domain/share` answers the same shape, which is the admin
|
|
306
|
+
* law working: the operator surface is the public grammar with a prefix.
|
|
307
|
+
*/
|
|
308
|
+
export interface DomainShareResponse {
|
|
309
|
+
/** The domain the setup link is for */
|
|
310
|
+
readonly domain: string;
|
|
311
|
+
/** The salted setup hash that authorizes the share */
|
|
312
|
+
readonly hash: string;
|
|
234
313
|
}
|
|
235
314
|
|
|
236
315
|
/**
|
|
@@ -245,6 +324,37 @@ export interface DomainRecordsResponse {
|
|
|
245
324
|
records: DnsRecord[];
|
|
246
325
|
}
|
|
247
326
|
|
|
327
|
+
/**
|
|
328
|
+
* Response for `GET /labels` — every label in use across the caller's
|
|
329
|
+
* deployments, domains and tokens, grouped and ordered by last use.
|
|
330
|
+
*
|
|
331
|
+
* The one plural noun outside the list contract, deliberately: labels have
|
|
332
|
+
* no identity, no row and no `created`, so there is nothing for a keyset
|
|
333
|
+
* cursor to resume after, and its consumer is an autocomplete that wants the
|
|
334
|
+
* whole set. Bounded by `PAGINATION.GLOBAL_LIMIT` rather than paginated.
|
|
335
|
+
*/
|
|
336
|
+
export interface LabelsResponse {
|
|
337
|
+
readonly labels: string[];
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Response for `POST /setup` — the DNS instructions for one domain, written
|
|
342
|
+
* for a human to follow at their registrar.
|
|
343
|
+
*
|
|
344
|
+
* `custom` is the provider-specific walkthrough when the provider is known;
|
|
345
|
+
* `generic` always answers, so a caller never has nothing to show.
|
|
346
|
+
*/
|
|
347
|
+
export interface SetupInstructionsResponse {
|
|
348
|
+
/** One-line summary of what to do */
|
|
349
|
+
readonly tldr: string;
|
|
350
|
+
/** Provider-specific instructions, null when the provider is unknown */
|
|
351
|
+
readonly custom: string | null;
|
|
352
|
+
/** Provider-agnostic instructions — always present */
|
|
353
|
+
readonly generic: string;
|
|
354
|
+
/** The identified DNS provider, null when unknown */
|
|
355
|
+
readonly provider: string | null;
|
|
356
|
+
}
|
|
357
|
+
|
|
248
358
|
/**
|
|
249
359
|
* Response for domain validation
|
|
250
360
|
*/
|
|
@@ -1320,16 +1430,23 @@ export interface SPACheckRequest {
|
|
|
1320
1430
|
/**
|
|
1321
1431
|
* Response from SPA check endpoint
|
|
1322
1432
|
*/
|
|
1433
|
+
/**
|
|
1434
|
+
* Which of the classifier's tiers reached the verdict, and why. Named rather
|
|
1435
|
+
* than inline so the API's own `checkSPA` can return `SPACheckResponse`
|
|
1436
|
+
* instead of restating its shape.
|
|
1437
|
+
*/
|
|
1438
|
+
export interface SPACheckDebug {
|
|
1439
|
+
/** Which tier made the detection */
|
|
1440
|
+
tier: 'exclusions' | 'inclusions' | 'scoring' | 'ai' | 'fallback';
|
|
1441
|
+
/** The reason for the detection result */
|
|
1442
|
+
reason: string;
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1323
1445
|
export interface SPACheckResponse {
|
|
1324
1446
|
/** Whether the project is detected as a Single Page Application */
|
|
1325
1447
|
isSPA: boolean;
|
|
1326
1448
|
/** Debugging information about detection */
|
|
1327
|
-
debug:
|
|
1328
|
-
/** Which tier made the detection: 'exclusions', 'inclusions', 'scoring', 'ai', or 'fallback' */
|
|
1329
|
-
tier: 'exclusions' | 'inclusions' | 'scoring' | 'ai' | 'fallback';
|
|
1330
|
-
/** The reason for the detection result */
|
|
1331
|
-
reason: string;
|
|
1332
|
-
};
|
|
1449
|
+
debug: SPACheckDebug;
|
|
1333
1450
|
}
|
|
1334
1451
|
|
|
1335
1452
|
// =============================================================================
|
|
@@ -1442,6 +1559,36 @@ export interface ListOptions {
|
|
|
1442
1559
|
cursor?: string;
|
|
1443
1560
|
}
|
|
1444
1561
|
|
|
1562
|
+
/**
|
|
1563
|
+
* What a caller may change on an existing deployment.
|
|
1564
|
+
*
|
|
1565
|
+
* Labels and nothing else: a deployment's content is immutable by design, so
|
|
1566
|
+
* this is the whole mutable surface rather than a subset someone chose.
|
|
1567
|
+
*/
|
|
1568
|
+
export interface DeploymentSetOptions {
|
|
1569
|
+
labels: string[];
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
/**
|
|
1573
|
+
* What `domains.set()` may create or change. Every field is optional because
|
|
1574
|
+
* the call is a natural-key upsert: omitting `deployment` reserves the
|
|
1575
|
+
* domain, naming one links or re-points it, and labels travel either way.
|
|
1576
|
+
*
|
|
1577
|
+
* `deployment` is deliberately not nullable — unlinking is refused (400).
|
|
1578
|
+
* See `npm/ship/CLAUDE.md`, "Domain Write Semantics".
|
|
1579
|
+
*/
|
|
1580
|
+
export interface DomainSetOptions {
|
|
1581
|
+
deployment?: string;
|
|
1582
|
+
labels?: string[];
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
/** What a caller may set when minting a deploy token. */
|
|
1586
|
+
export interface TokenCreateOptions {
|
|
1587
|
+
/** Seconds until expiry; omit for a token that never expires. */
|
|
1588
|
+
ttl?: number;
|
|
1589
|
+
labels?: string[];
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1445
1592
|
/**
|
|
1446
1593
|
* Deployment resource interface - the contract all implementations must follow.
|
|
1447
1594
|
*
|
|
@@ -1456,26 +1603,23 @@ export interface DeploymentResource<
|
|
|
1456
1603
|
upload: (input: DeployInput, options?: UploadOptions) => Promise<DeploymentCreateResponse>;
|
|
1457
1604
|
list: (options?: ListOptions) => Promise<DeploymentListResponse>;
|
|
1458
1605
|
get: (id: string) => Promise<Deployment>;
|
|
1459
|
-
set: (id: string, options:
|
|
1460
|
-
remove: (id: string) => Promise<
|
|
1606
|
+
set: (id: string, options: DeploymentSetOptions) => Promise<Deployment>;
|
|
1607
|
+
remove: (id: string) => Promise<DeploymentDeleteResponse>;
|
|
1461
1608
|
}
|
|
1462
1609
|
|
|
1463
1610
|
/**
|
|
1464
1611
|
* Domain resource interface - the contract all implementations must follow
|
|
1465
1612
|
*/
|
|
1466
1613
|
export interface DomainResource {
|
|
1467
|
-
set: (
|
|
1468
|
-
name: string,
|
|
1469
|
-
options?: { deployment?: string; labels?: string[] },
|
|
1470
|
-
) => Promise<DomainSetResult>;
|
|
1614
|
+
set: (name: string, options?: DomainSetOptions) => Promise<DomainSetResult>;
|
|
1471
1615
|
list: (options?: ListOptions) => Promise<DomainListResponse>;
|
|
1472
1616
|
get: (name: string) => Promise<Domain>;
|
|
1473
|
-
remove: (name: string) => Promise<
|
|
1617
|
+
remove: (name: string) => Promise<DomainDeleteResponse>;
|
|
1474
1618
|
verify: (name: string) => Promise<DomainVerifyResponse>;
|
|
1475
1619
|
validate: (name: string) => Promise<DomainValidateResponse>;
|
|
1476
1620
|
dns: (name: string) => Promise<DomainDnsResponse>;
|
|
1477
1621
|
records: (name: string) => Promise<DomainRecordsResponse>;
|
|
1478
|
-
share: (name: string) => Promise<
|
|
1622
|
+
share: (name: string) => Promise<DomainShareResponse>;
|
|
1479
1623
|
}
|
|
1480
1624
|
|
|
1481
1625
|
/**
|
|
@@ -1489,9 +1633,10 @@ export interface AccountResource {
|
|
|
1489
1633
|
* Token resource interface - the contract all implementations must follow
|
|
1490
1634
|
*/
|
|
1491
1635
|
export interface TokenResource {
|
|
1492
|
-
create: (options?:
|
|
1636
|
+
create: (options?: TokenCreateOptions) => Promise<TokenCreateResponse>;
|
|
1493
1637
|
list: (options?: ListOptions) => Promise<TokenListResponse>;
|
|
1494
|
-
|
|
1638
|
+
get: (token: string) => Promise<Token>;
|
|
1639
|
+
remove: (token: string) => Promise<TokenDeleteResponse>;
|
|
1495
1640
|
}
|
|
1496
1641
|
|
|
1497
1642
|
// =============================================================================
|