@shipstatic/types 0.8.10 → 0.9.1
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 +4 -6
- package/dist/index.d.ts +93 -68
- package/dist/index.js +61 -38
- package/package.json +1 -1
- package/src/index.ts +113 -89
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ npm install @shipstatic/types
|
|
|
21
21
|
```typescript
|
|
22
22
|
import type {
|
|
23
23
|
Deployment, DeploymentListResponse,
|
|
24
|
-
Domain, DomainListResponse, DnsRecord, DomainDnsResponse, DomainRecordsResponse, DomainValidateResponse,
|
|
24
|
+
Domain, DomainSetResult, DomainListResponse, DnsRecord, DomainDnsResponse, DomainRecordsResponse, DomainValidateResponse,
|
|
25
25
|
Token, TokenListItem, TokenListResponse, TokenCreateResponse,
|
|
26
26
|
Account, AccountUsage, AccountOverrides,
|
|
27
27
|
StaticFile
|
|
@@ -62,7 +62,7 @@ import {
|
|
|
62
62
|
|
|
63
63
|
```typescript
|
|
64
64
|
import type {
|
|
65
|
-
|
|
65
|
+
PlatformLimits, // plan-based caps from /config (file size, file count, total size)
|
|
66
66
|
BillingStatus,
|
|
67
67
|
CheckoutSession,
|
|
68
68
|
ActivityListResponse,
|
|
@@ -80,8 +80,6 @@ import type {
|
|
|
80
80
|
DomainResource,
|
|
81
81
|
AccountResource,
|
|
82
82
|
TokenResource,
|
|
83
|
-
BillingResource,
|
|
84
|
-
KeysResource,
|
|
85
83
|
} from '@shipstatic/types';
|
|
86
84
|
```
|
|
87
85
|
|
|
@@ -138,8 +136,8 @@ import {
|
|
|
138
136
|
```typescript
|
|
139
137
|
import {
|
|
140
138
|
DEFAULT_API,
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
API_KEY, // { PREFIX, HEX_LENGTH, TOTAL_LENGTH, HINT_LENGTH }
|
|
140
|
+
DEPLOY_TOKEN, // { PREFIX, HEX_LENGTH, TOTAL_LENGTH }
|
|
143
141
|
DEPLOYMENT_CONFIG_FILENAME,
|
|
144
142
|
} from '@shipstatic/types';
|
|
145
143
|
```
|
package/dist/index.d.ts
CHANGED
|
@@ -94,6 +94,20 @@ export interface Domain {
|
|
|
94
94
|
/** Total deployment links */
|
|
95
95
|
links: number;
|
|
96
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Return shape of `domains.set()` — `Domain` plus an SDK-derived flag indicating
|
|
99
|
+
* whether the underlying `PUT /domains/:name` created the record (HTTP 201) or
|
|
100
|
+
* updated an existing one (HTTP 200).
|
|
101
|
+
*
|
|
102
|
+
* `isCreate` is not part of the wire format — the API returns a plain `Domain`
|
|
103
|
+
* body. The SDK derives the flag from the HTTP status code so callers (notably
|
|
104
|
+
* the CLI) can format different output for the create vs repoint paths without
|
|
105
|
+
* a second round-trip.
|
|
106
|
+
*/
|
|
107
|
+
export interface DomainSetResult extends Domain {
|
|
108
|
+
/** `true` when this call created a new domain; `false` when it updated an existing one. */
|
|
109
|
+
isCreate: boolean;
|
|
110
|
+
}
|
|
97
111
|
/**
|
|
98
112
|
* Response for listing domains
|
|
99
113
|
*/
|
|
@@ -282,31 +296,37 @@ export interface AccountOverrides {
|
|
|
282
296
|
totalSize?: number;
|
|
283
297
|
}
|
|
284
298
|
/**
|
|
285
|
-
* All possible error types in the ShipStatic platform
|
|
286
|
-
*
|
|
299
|
+
* All possible error types in the ShipStatic platform.
|
|
300
|
+
*
|
|
301
|
+
* Developer-friendly key names map to stable wire-format string values.
|
|
302
|
+
* Both the value and the type are exported under the same name so callers
|
|
303
|
+
* can use `ErrorType.Validation` (value comparison) and `: ErrorType` (type
|
|
304
|
+
* annotation) without ceremony — matching the pattern other status objects
|
|
305
|
+
* (`DeploymentStatus`, `DomainStatus`, `AccountPlan`, `AuthMethod`) follow.
|
|
287
306
|
*/
|
|
288
|
-
export declare
|
|
307
|
+
export declare const ErrorType: {
|
|
289
308
|
/** Validation failed (400) */
|
|
290
|
-
Validation
|
|
309
|
+
readonly Validation: "validation_failed";
|
|
291
310
|
/** Resource not found (404) */
|
|
292
|
-
NotFound
|
|
311
|
+
readonly NotFound: "not_found";
|
|
293
312
|
/** Rate limit exceeded (429) */
|
|
294
|
-
RateLimit
|
|
313
|
+
readonly RateLimit: "rate_limit_exceeded";
|
|
295
314
|
/** Authentication required (401) */
|
|
296
|
-
Authentication
|
|
315
|
+
readonly Authentication: "authentication_failed";
|
|
297
316
|
/** Business logic error (400) */
|
|
298
|
-
Business
|
|
299
|
-
/** API server error (500)
|
|
300
|
-
Api
|
|
317
|
+
readonly Business: "business_logic_error";
|
|
318
|
+
/** API server error (500) */
|
|
319
|
+
readonly Api: "internal_server_error";
|
|
301
320
|
/** Network/connection error */
|
|
302
|
-
Network
|
|
321
|
+
readonly Network: "network_error";
|
|
303
322
|
/** Operation was cancelled */
|
|
304
|
-
Cancelled
|
|
323
|
+
readonly Cancelled: "operation_cancelled";
|
|
305
324
|
/** File operation error */
|
|
306
|
-
File
|
|
325
|
+
readonly File: "file_error";
|
|
307
326
|
/** Configuration error */
|
|
308
|
-
Config
|
|
309
|
-
}
|
|
327
|
+
readonly Config: "config_error";
|
|
328
|
+
};
|
|
329
|
+
export type ErrorType = typeof ErrorType[keyof typeof ErrorType];
|
|
310
330
|
/**
|
|
311
331
|
* Standard error response format used everywhere
|
|
312
332
|
*/
|
|
@@ -366,12 +386,22 @@ export declare class ShipError extends Error {
|
|
|
366
386
|
*/
|
|
367
387
|
export declare function isShipError(error: unknown): error is ShipError;
|
|
368
388
|
/**
|
|
369
|
-
*
|
|
370
|
-
*
|
|
389
|
+
* Plan-based platform limits returned by the `/config` endpoint.
|
|
390
|
+
*
|
|
391
|
+
* The SDK fetches these once on first API call to drive client-side
|
|
392
|
+
* file-size / file-count / total-size validation that mirrors what the API
|
|
393
|
+
* would enforce server-side. Limits vary by account plan.
|
|
394
|
+
*
|
|
395
|
+
* Distinct from `ResolvedConfig` (which carries the *client's* credentials
|
|
396
|
+
* and API URL after defaulting); this one carries the *platform's* posted
|
|
397
|
+
* caps for the current account.
|
|
371
398
|
*/
|
|
372
|
-
export interface
|
|
399
|
+
export interface PlatformLimits {
|
|
400
|
+
/** Maximum size in bytes for a single file. */
|
|
373
401
|
maxFileSize: number;
|
|
402
|
+
/** Maximum number of files in a single deployment. */
|
|
374
403
|
maxFilesCount: number;
|
|
404
|
+
/** Maximum total size in bytes across all files in a deployment. */
|
|
375
405
|
maxTotalSize: number;
|
|
376
406
|
}
|
|
377
407
|
/**
|
|
@@ -443,13 +473,32 @@ export interface PingResponse {
|
|
|
443
473
|
/** Optional timestamp */
|
|
444
474
|
timestamp?: number;
|
|
445
475
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
export declare const
|
|
451
|
-
|
|
452
|
-
|
|
476
|
+
/**
|
|
477
|
+
* Shape constants for API keys (`ship-{64 hex chars}`).
|
|
478
|
+
* Single source of truth used by validation utilities and auth middleware.
|
|
479
|
+
*/
|
|
480
|
+
export declare const API_KEY: {
|
|
481
|
+
/** Prefix that identifies an API key. */
|
|
482
|
+
readonly PREFIX: "ship-";
|
|
483
|
+
/** Number of hex characters following the prefix. */
|
|
484
|
+
readonly HEX_LENGTH: 64;
|
|
485
|
+
/** Total length of an API key including prefix (`PREFIX.length + HEX_LENGTH = 69`). */
|
|
486
|
+
readonly TOTAL_LENGTH: 69;
|
|
487
|
+
/** Number of trailing characters used to display a redacted hint (e.g. last 4). */
|
|
488
|
+
readonly HINT_LENGTH: 4;
|
|
489
|
+
};
|
|
490
|
+
/**
|
|
491
|
+
* Shape constants for deploy tokens (`token-{64 hex chars}`).
|
|
492
|
+
* Single source of truth used by validation utilities and auth middleware.
|
|
493
|
+
*/
|
|
494
|
+
export declare const DEPLOY_TOKEN: {
|
|
495
|
+
/** Prefix that identifies a deploy token. */
|
|
496
|
+
readonly PREFIX: "token-";
|
|
497
|
+
/** Number of hex characters following the prefix. */
|
|
498
|
+
readonly HEX_LENGTH: 64;
|
|
499
|
+
/** Total length of a deploy token including prefix (`PREFIX.length + HEX_LENGTH = 70`). */
|
|
500
|
+
readonly TOTAL_LENGTH: 70;
|
|
501
|
+
};
|
|
453
502
|
export declare const AuthMethod: {
|
|
454
503
|
readonly JWT: "jwt";
|
|
455
504
|
readonly API_KEY: "apiKey";
|
|
@@ -536,23 +585,21 @@ export interface StaticFile {
|
|
|
536
585
|
size: number;
|
|
537
586
|
}
|
|
538
587
|
/**
|
|
539
|
-
*
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
* Resolved configuration with required apiUrl.
|
|
548
|
-
* This is the normalized config after merging options, env, and config files.
|
|
588
|
+
* Resolved client configuration with `apiUrl` defaulted.
|
|
589
|
+
*
|
|
590
|
+
* Produced by the SDK after layering its credential sources (constructor
|
|
591
|
+
* options on top of `SHIP_*` env vars in Node; constructor options only in
|
|
592
|
+
* Browser) and applying the `DEFAULT_API` fallback. File-based sources
|
|
593
|
+
* (`.shiprc`, `package.json` `"ship"` key) are the CLI's responsibility and
|
|
594
|
+
* are merged in *before* construction — by the time a `ResolvedConfig`
|
|
595
|
+
* exists, every source has already collapsed into the constructor argument.
|
|
549
596
|
*/
|
|
550
597
|
export interface ResolvedConfig {
|
|
551
|
-
/** API URL
|
|
598
|
+
/** API URL — always present after resolution, defaults to `DEFAULT_API`. */
|
|
552
599
|
apiUrl: string;
|
|
553
|
-
/** API key for authenticated deployments */
|
|
600
|
+
/** API key for authenticated deployments. */
|
|
554
601
|
apiKey?: string;
|
|
555
|
-
/** Deploy token for single-use deployments */
|
|
602
|
+
/** Deploy token for single-use deployments. */
|
|
556
603
|
deployToken?: string;
|
|
557
604
|
}
|
|
558
605
|
/**
|
|
@@ -572,10 +619,14 @@ export interface ProgressInfo {
|
|
|
572
619
|
/** Default API URL if not otherwise configured. */
|
|
573
620
|
export declare const DEFAULT_API = "https://api.shipstatic.com";
|
|
574
621
|
/**
|
|
575
|
-
*
|
|
622
|
+
* Universal deploy input — the union of every shape the SDK accepts.
|
|
623
|
+
*
|
|
624
|
+
* - **Browser**: `File[]` (typically from `<input type="file">` or drag-and-drop)
|
|
625
|
+
* - **Node**: `string | string[]` (file or directory path(s) on disk; directories are walked)
|
|
576
626
|
*
|
|
577
|
-
*
|
|
578
|
-
*
|
|
627
|
+
* Each platform's SDK narrows its `deploy()` signature to the relevant shape
|
|
628
|
+
* and rejects anything else at runtime. Use the structural types directly
|
|
629
|
+
* (`File[]`, `string | string[]`) when writing platform-specific code.
|
|
579
630
|
*/
|
|
580
631
|
export type DeployInput = File[] | string | string[];
|
|
581
632
|
/**
|
|
@@ -623,7 +674,7 @@ export interface DomainResource {
|
|
|
623
674
|
set: (name: string, options?: {
|
|
624
675
|
deployment?: string;
|
|
625
676
|
labels?: string[];
|
|
626
|
-
}) => Promise<
|
|
677
|
+
}) => Promise<DomainSetResult>;
|
|
627
678
|
list: () => Promise<DomainListResponse>;
|
|
628
679
|
get: (name: string) => Promise<Domain>;
|
|
629
680
|
remove: (name: string) => Promise<void>;
|
|
@@ -680,32 +731,6 @@ export interface CheckoutSession {
|
|
|
680
731
|
/** URL to redirect user to Creem checkout page */
|
|
681
732
|
url: string;
|
|
682
733
|
}
|
|
683
|
-
/**
|
|
684
|
-
* Billing resource interface - the contract all implementations must follow
|
|
685
|
-
*
|
|
686
|
-
* IMPOSSIBLE SIMPLICITY: No sync() method needed!
|
|
687
|
-
* Webhooks are the single source of truth. Frontend just polls status().
|
|
688
|
-
*/
|
|
689
|
-
export interface BillingResource {
|
|
690
|
-
/**
|
|
691
|
-
* Create a checkout session
|
|
692
|
-
* @returns Checkout session with URL to redirect user
|
|
693
|
-
*/
|
|
694
|
-
checkout: () => Promise<CheckoutSession>;
|
|
695
|
-
/**
|
|
696
|
-
* Get current billing status
|
|
697
|
-
* @returns Billing status and usage information
|
|
698
|
-
*/
|
|
699
|
-
status: () => Promise<BillingStatus>;
|
|
700
|
-
}
|
|
701
|
-
/**
|
|
702
|
-
* Keys resource interface - the contract all implementations must follow
|
|
703
|
-
*/
|
|
704
|
-
export interface KeysResource {
|
|
705
|
-
create: () => Promise<{
|
|
706
|
-
apiKey: string;
|
|
707
|
-
}>;
|
|
708
|
-
}
|
|
709
734
|
/**
|
|
710
735
|
* All activity event types logged in the system.
|
|
711
736
|
* Uses dot notation consistently: {resource}.{action}
|
package/dist/index.js
CHANGED
|
@@ -50,34 +50,40 @@ export const AccountPlan = {
|
|
|
50
50
|
// ERROR SYSTEM
|
|
51
51
|
// =============================================================================
|
|
52
52
|
/**
|
|
53
|
-
* All possible error types in the ShipStatic platform
|
|
54
|
-
*
|
|
53
|
+
* All possible error types in the ShipStatic platform.
|
|
54
|
+
*
|
|
55
|
+
* Developer-friendly key names map to stable wire-format string values.
|
|
56
|
+
* Both the value and the type are exported under the same name so callers
|
|
57
|
+
* can use `ErrorType.Validation` (value comparison) and `: ErrorType` (type
|
|
58
|
+
* annotation) without ceremony — matching the pattern other status objects
|
|
59
|
+
* (`DeploymentStatus`, `DomainStatus`, `AccountPlan`, `AuthMethod`) follow.
|
|
55
60
|
*/
|
|
56
|
-
export
|
|
57
|
-
(function (ErrorType) {
|
|
61
|
+
export const ErrorType = {
|
|
58
62
|
/** Validation failed (400) */
|
|
59
|
-
|
|
63
|
+
Validation: 'validation_failed',
|
|
60
64
|
/** Resource not found (404) */
|
|
61
|
-
|
|
65
|
+
NotFound: 'not_found',
|
|
62
66
|
/** Rate limit exceeded (429) */
|
|
63
|
-
|
|
67
|
+
RateLimit: 'rate_limit_exceeded',
|
|
64
68
|
/** Authentication required (401) */
|
|
65
|
-
|
|
69
|
+
Authentication: 'authentication_failed',
|
|
66
70
|
/** Business logic error (400) */
|
|
67
|
-
|
|
68
|
-
/** API server error (500)
|
|
69
|
-
|
|
71
|
+
Business: 'business_logic_error',
|
|
72
|
+
/** API server error (500) */
|
|
73
|
+
Api: 'internal_server_error',
|
|
70
74
|
/** Network/connection error */
|
|
71
|
-
|
|
75
|
+
Network: 'network_error',
|
|
72
76
|
/** Operation was cancelled */
|
|
73
|
-
|
|
77
|
+
Cancelled: 'operation_cancelled',
|
|
74
78
|
/** File operation error */
|
|
75
|
-
|
|
79
|
+
File: 'file_error',
|
|
76
80
|
/** Configuration error */
|
|
77
|
-
|
|
78
|
-
}
|
|
81
|
+
Config: 'config_error',
|
|
82
|
+
};
|
|
79
83
|
/**
|
|
80
|
-
* Categorizes error types for
|
|
84
|
+
* Categorizes error types for the `isClientError` / `isNetworkError` /
|
|
85
|
+
* `isAuthError` helpers. Each `Set` is typed against the wider `ErrorType`
|
|
86
|
+
* union so `.has(error.type)` accepts any value from the union.
|
|
81
87
|
*/
|
|
82
88
|
const ERROR_CATEGORIES = {
|
|
83
89
|
client: new Set([ErrorType.Business, ErrorType.Config, ErrorType.File, ErrorType.Validation]),
|
|
@@ -299,15 +305,32 @@ export function hasUnbuiltMarker(filePath) {
|
|
|
299
305
|
const segments = filePath.replace(/\\/g, '/').split('/').filter(Boolean);
|
|
300
306
|
return segments.some(s => UNBUILT_PROJECT_MARKERS.has(s));
|
|
301
307
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
export const
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
308
|
+
/**
|
|
309
|
+
* Shape constants for API keys (`ship-{64 hex chars}`).
|
|
310
|
+
* Single source of truth used by validation utilities and auth middleware.
|
|
311
|
+
*/
|
|
312
|
+
export const API_KEY = {
|
|
313
|
+
/** Prefix that identifies an API key. */
|
|
314
|
+
PREFIX: 'ship-',
|
|
315
|
+
/** Number of hex characters following the prefix. */
|
|
316
|
+
HEX_LENGTH: 64,
|
|
317
|
+
/** Total length of an API key including prefix (`PREFIX.length + HEX_LENGTH = 69`). */
|
|
318
|
+
TOTAL_LENGTH: 69,
|
|
319
|
+
/** Number of trailing characters used to display a redacted hint (e.g. last 4). */
|
|
320
|
+
HINT_LENGTH: 4,
|
|
321
|
+
};
|
|
322
|
+
/**
|
|
323
|
+
* Shape constants for deploy tokens (`token-{64 hex chars}`).
|
|
324
|
+
* Single source of truth used by validation utilities and auth middleware.
|
|
325
|
+
*/
|
|
326
|
+
export const DEPLOY_TOKEN = {
|
|
327
|
+
/** Prefix that identifies a deploy token. */
|
|
328
|
+
PREFIX: 'token-',
|
|
329
|
+
/** Number of hex characters following the prefix. */
|
|
330
|
+
HEX_LENGTH: 64,
|
|
331
|
+
/** Total length of a deploy token including prefix (`PREFIX.length + HEX_LENGTH = 70`). */
|
|
332
|
+
TOTAL_LENGTH: 70,
|
|
333
|
+
};
|
|
311
334
|
// Authentication Method Constants
|
|
312
335
|
export const AuthMethod = {
|
|
313
336
|
JWT: 'jwt',
|
|
@@ -327,30 +350,30 @@ export const SPA_DEFAULT_CONFIG = { rewrites: [{ source: '/(.*)', destination: '
|
|
|
327
350
|
* Validate API key format
|
|
328
351
|
*/
|
|
329
352
|
export function validateApiKey(apiKey) {
|
|
330
|
-
if (!apiKey.startsWith(
|
|
331
|
-
throw ShipError.validation(`API key must start with "${
|
|
353
|
+
if (!apiKey.startsWith(API_KEY.PREFIX)) {
|
|
354
|
+
throw ShipError.validation(`API key must start with "${API_KEY.PREFIX}"`);
|
|
332
355
|
}
|
|
333
|
-
if (apiKey.length !==
|
|
334
|
-
throw ShipError.validation(`API key must be ${
|
|
356
|
+
if (apiKey.length !== API_KEY.TOTAL_LENGTH) {
|
|
357
|
+
throw ShipError.validation(`API key must be ${API_KEY.TOTAL_LENGTH} characters total (${API_KEY.PREFIX} + ${API_KEY.HEX_LENGTH} hex chars)`);
|
|
335
358
|
}
|
|
336
|
-
const hexPart = apiKey.slice(
|
|
359
|
+
const hexPart = apiKey.slice(API_KEY.PREFIX.length);
|
|
337
360
|
if (!/^[a-f0-9]{64}$/i.test(hexPart)) {
|
|
338
|
-
throw ShipError.validation(`API key must contain ${
|
|
361
|
+
throw ShipError.validation(`API key must contain ${API_KEY.HEX_LENGTH} hexadecimal characters after "${API_KEY.PREFIX}" prefix`);
|
|
339
362
|
}
|
|
340
363
|
}
|
|
341
364
|
/**
|
|
342
365
|
* Validate deploy token format
|
|
343
366
|
*/
|
|
344
367
|
export function validateDeployToken(deployToken) {
|
|
345
|
-
if (!deployToken.startsWith(
|
|
346
|
-
throw ShipError.validation(`Deploy token must start with "${
|
|
368
|
+
if (!deployToken.startsWith(DEPLOY_TOKEN.PREFIX)) {
|
|
369
|
+
throw ShipError.validation(`Deploy token must start with "${DEPLOY_TOKEN.PREFIX}"`);
|
|
347
370
|
}
|
|
348
|
-
if (deployToken.length !==
|
|
349
|
-
throw ShipError.validation(`Deploy token must be ${
|
|
371
|
+
if (deployToken.length !== DEPLOY_TOKEN.TOTAL_LENGTH) {
|
|
372
|
+
throw ShipError.validation(`Deploy token must be ${DEPLOY_TOKEN.TOTAL_LENGTH} characters total (${DEPLOY_TOKEN.PREFIX} + ${DEPLOY_TOKEN.HEX_LENGTH} hex chars)`);
|
|
350
373
|
}
|
|
351
|
-
const hexPart = deployToken.slice(
|
|
374
|
+
const hexPart = deployToken.slice(DEPLOY_TOKEN.PREFIX.length);
|
|
352
375
|
if (!/^[a-f0-9]{64}$/i.test(hexPart)) {
|
|
353
|
-
throw ShipError.validation(`Deploy token must contain ${
|
|
376
|
+
throw ShipError.validation(`Deploy token must contain ${DEPLOY_TOKEN.HEX_LENGTH} hexadecimal characters after "${DEPLOY_TOKEN.PREFIX}" prefix`);
|
|
354
377
|
}
|
|
355
378
|
}
|
|
356
379
|
/**
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -112,6 +112,21 @@ export interface Domain {
|
|
|
112
112
|
links: number;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Return shape of `domains.set()` — `Domain` plus an SDK-derived flag indicating
|
|
117
|
+
* whether the underlying `PUT /domains/:name` created the record (HTTP 201) or
|
|
118
|
+
* updated an existing one (HTTP 200).
|
|
119
|
+
*
|
|
120
|
+
* `isCreate` is not part of the wire format — the API returns a plain `Domain`
|
|
121
|
+
* body. The SDK derives the flag from the HTTP status code so callers (notably
|
|
122
|
+
* the CLI) can format different output for the create vs repoint paths without
|
|
123
|
+
* a second round-trip.
|
|
124
|
+
*/
|
|
125
|
+
export interface DomainSetResult extends Domain {
|
|
126
|
+
/** `true` when this call created a new domain; `false` when it updated an existing one. */
|
|
127
|
+
isCreate: boolean;
|
|
128
|
+
}
|
|
129
|
+
|
|
115
130
|
/**
|
|
116
131
|
* Response for listing domains
|
|
117
132
|
*/
|
|
@@ -326,39 +341,48 @@ export interface AccountOverrides {
|
|
|
326
341
|
// =============================================================================
|
|
327
342
|
|
|
328
343
|
/**
|
|
329
|
-
* All possible error types in the ShipStatic platform
|
|
330
|
-
*
|
|
344
|
+
* All possible error types in the ShipStatic platform.
|
|
345
|
+
*
|
|
346
|
+
* Developer-friendly key names map to stable wire-format string values.
|
|
347
|
+
* Both the value and the type are exported under the same name so callers
|
|
348
|
+
* can use `ErrorType.Validation` (value comparison) and `: ErrorType` (type
|
|
349
|
+
* annotation) without ceremony — matching the pattern other status objects
|
|
350
|
+
* (`DeploymentStatus`, `DomainStatus`, `AccountPlan`, `AuthMethod`) follow.
|
|
331
351
|
*/
|
|
332
|
-
export
|
|
352
|
+
export const ErrorType = {
|
|
333
353
|
/** Validation failed (400) */
|
|
334
|
-
Validation
|
|
354
|
+
Validation: 'validation_failed',
|
|
335
355
|
/** Resource not found (404) */
|
|
336
|
-
NotFound
|
|
356
|
+
NotFound: 'not_found',
|
|
337
357
|
/** Rate limit exceeded (429) */
|
|
338
|
-
RateLimit
|
|
358
|
+
RateLimit: 'rate_limit_exceeded',
|
|
339
359
|
/** Authentication required (401) */
|
|
340
|
-
Authentication
|
|
360
|
+
Authentication: 'authentication_failed',
|
|
341
361
|
/** Business logic error (400) */
|
|
342
|
-
Business
|
|
343
|
-
/** API server error (500)
|
|
344
|
-
Api
|
|
362
|
+
Business: 'business_logic_error',
|
|
363
|
+
/** API server error (500) */
|
|
364
|
+
Api: 'internal_server_error',
|
|
345
365
|
/** Network/connection error */
|
|
346
|
-
Network
|
|
366
|
+
Network: 'network_error',
|
|
347
367
|
/** Operation was cancelled */
|
|
348
|
-
Cancelled
|
|
368
|
+
Cancelled: 'operation_cancelled',
|
|
349
369
|
/** File operation error */
|
|
350
|
-
File
|
|
370
|
+
File: 'file_error',
|
|
351
371
|
/** Configuration error */
|
|
352
|
-
Config
|
|
353
|
-
}
|
|
372
|
+
Config: 'config_error',
|
|
373
|
+
} as const;
|
|
374
|
+
|
|
375
|
+
export type ErrorType = typeof ErrorType[keyof typeof ErrorType];
|
|
354
376
|
|
|
355
377
|
/**
|
|
356
|
-
* Categorizes error types for
|
|
378
|
+
* Categorizes error types for the `isClientError` / `isNetworkError` /
|
|
379
|
+
* `isAuthError` helpers. Each `Set` is typed against the wider `ErrorType`
|
|
380
|
+
* union so `.has(error.type)` accepts any value from the union.
|
|
357
381
|
*/
|
|
358
382
|
const ERROR_CATEGORIES = {
|
|
359
|
-
client: new Set([ErrorType.Business, ErrorType.Config, ErrorType.File, ErrorType.Validation]),
|
|
360
|
-
network: new Set([ErrorType.Network]),
|
|
361
|
-
auth: new Set([ErrorType.Authentication]),
|
|
383
|
+
client: new Set<ErrorType>([ErrorType.Business, ErrorType.Config, ErrorType.File, ErrorType.Validation]),
|
|
384
|
+
network: new Set<ErrorType>([ErrorType.Network]),
|
|
385
|
+
auth: new Set<ErrorType>([ErrorType.Authentication]),
|
|
362
386
|
} as const;
|
|
363
387
|
|
|
364
388
|
/**
|
|
@@ -521,12 +545,22 @@ export function isShipError(error: unknown): error is ShipError {
|
|
|
521
545
|
// =============================================================================
|
|
522
546
|
|
|
523
547
|
/**
|
|
524
|
-
*
|
|
525
|
-
*
|
|
548
|
+
* Plan-based platform limits returned by the `/config` endpoint.
|
|
549
|
+
*
|
|
550
|
+
* The SDK fetches these once on first API call to drive client-side
|
|
551
|
+
* file-size / file-count / total-size validation that mirrors what the API
|
|
552
|
+
* would enforce server-side. Limits vary by account plan.
|
|
553
|
+
*
|
|
554
|
+
* Distinct from `ResolvedConfig` (which carries the *client's* credentials
|
|
555
|
+
* and API URL after defaulting); this one carries the *platform's* posted
|
|
556
|
+
* caps for the current account.
|
|
526
557
|
*/
|
|
527
|
-
export interface
|
|
558
|
+
export interface PlatformLimits {
|
|
559
|
+
/** Maximum size in bytes for a single file. */
|
|
528
560
|
maxFileSize: number;
|
|
561
|
+
/** Maximum number of files in a single deployment. */
|
|
529
562
|
maxFilesCount: number;
|
|
563
|
+
/** Maximum total size in bytes across all files in a deployment. */
|
|
530
564
|
maxTotalSize: number;
|
|
531
565
|
}
|
|
532
566
|
|
|
@@ -652,16 +686,33 @@ export interface PingResponse {
|
|
|
652
686
|
timestamp?: number;
|
|
653
687
|
}
|
|
654
688
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
export const
|
|
689
|
+
/**
|
|
690
|
+
* Shape constants for API keys (`ship-{64 hex chars}`).
|
|
691
|
+
* Single source of truth used by validation utilities and auth middleware.
|
|
692
|
+
*/
|
|
693
|
+
export const API_KEY = {
|
|
694
|
+
/** Prefix that identifies an API key. */
|
|
695
|
+
PREFIX: 'ship-',
|
|
696
|
+
/** Number of hex characters following the prefix. */
|
|
697
|
+
HEX_LENGTH: 64,
|
|
698
|
+
/** Total length of an API key including prefix (`PREFIX.length + HEX_LENGTH = 69`). */
|
|
699
|
+
TOTAL_LENGTH: 69,
|
|
700
|
+
/** Number of trailing characters used to display a redacted hint (e.g. last 4). */
|
|
701
|
+
HINT_LENGTH: 4,
|
|
702
|
+
} as const;
|
|
660
703
|
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
704
|
+
/**
|
|
705
|
+
* Shape constants for deploy tokens (`token-{64 hex chars}`).
|
|
706
|
+
* Single source of truth used by validation utilities and auth middleware.
|
|
707
|
+
*/
|
|
708
|
+
export const DEPLOY_TOKEN = {
|
|
709
|
+
/** Prefix that identifies a deploy token. */
|
|
710
|
+
PREFIX: 'token-',
|
|
711
|
+
/** Number of hex characters following the prefix. */
|
|
712
|
+
HEX_LENGTH: 64,
|
|
713
|
+
/** Total length of a deploy token including prefix (`PREFIX.length + HEX_LENGTH = 70`). */
|
|
714
|
+
TOTAL_LENGTH: 70,
|
|
715
|
+
} as const;
|
|
665
716
|
|
|
666
717
|
// Authentication Method Constants
|
|
667
718
|
export const AuthMethod = {
|
|
@@ -688,17 +739,17 @@ export const SPA_DEFAULT_CONFIG = { rewrites: [{ source: '/(.*)', destination: '
|
|
|
688
739
|
* Validate API key format
|
|
689
740
|
*/
|
|
690
741
|
export function validateApiKey(apiKey: string): void {
|
|
691
|
-
if (!apiKey.startsWith(
|
|
692
|
-
throw ShipError.validation(`API key must start with "${
|
|
742
|
+
if (!apiKey.startsWith(API_KEY.PREFIX)) {
|
|
743
|
+
throw ShipError.validation(`API key must start with "${API_KEY.PREFIX}"`);
|
|
693
744
|
}
|
|
694
745
|
|
|
695
|
-
if (apiKey.length !==
|
|
696
|
-
throw ShipError.validation(`API key must be ${
|
|
746
|
+
if (apiKey.length !== API_KEY.TOTAL_LENGTH) {
|
|
747
|
+
throw ShipError.validation(`API key must be ${API_KEY.TOTAL_LENGTH} characters total (${API_KEY.PREFIX} + ${API_KEY.HEX_LENGTH} hex chars)`);
|
|
697
748
|
}
|
|
698
749
|
|
|
699
|
-
const hexPart = apiKey.slice(
|
|
750
|
+
const hexPart = apiKey.slice(API_KEY.PREFIX.length);
|
|
700
751
|
if (!/^[a-f0-9]{64}$/i.test(hexPart)) {
|
|
701
|
-
throw ShipError.validation(`API key must contain ${
|
|
752
|
+
throw ShipError.validation(`API key must contain ${API_KEY.HEX_LENGTH} hexadecimal characters after "${API_KEY.PREFIX}" prefix`);
|
|
702
753
|
}
|
|
703
754
|
}
|
|
704
755
|
|
|
@@ -706,17 +757,17 @@ export function validateApiKey(apiKey: string): void {
|
|
|
706
757
|
* Validate deploy token format
|
|
707
758
|
*/
|
|
708
759
|
export function validateDeployToken(deployToken: string): void {
|
|
709
|
-
if (!deployToken.startsWith(
|
|
710
|
-
throw ShipError.validation(`Deploy token must start with "${
|
|
760
|
+
if (!deployToken.startsWith(DEPLOY_TOKEN.PREFIX)) {
|
|
761
|
+
throw ShipError.validation(`Deploy token must start with "${DEPLOY_TOKEN.PREFIX}"`);
|
|
711
762
|
}
|
|
712
763
|
|
|
713
|
-
if (deployToken.length !==
|
|
714
|
-
throw ShipError.validation(`Deploy token must be ${
|
|
764
|
+
if (deployToken.length !== DEPLOY_TOKEN.TOTAL_LENGTH) {
|
|
765
|
+
throw ShipError.validation(`Deploy token must be ${DEPLOY_TOKEN.TOTAL_LENGTH} characters total (${DEPLOY_TOKEN.PREFIX} + ${DEPLOY_TOKEN.HEX_LENGTH} hex chars)`);
|
|
715
766
|
}
|
|
716
767
|
|
|
717
|
-
const hexPart = deployToken.slice(
|
|
768
|
+
const hexPart = deployToken.slice(DEPLOY_TOKEN.PREFIX.length);
|
|
718
769
|
if (!/^[a-f0-9]{64}$/i.test(hexPart)) {
|
|
719
|
-
throw ShipError.validation(`Deploy token must contain ${
|
|
770
|
+
throw ShipError.validation(`Deploy token must contain ${DEPLOY_TOKEN.HEX_LENGTH} hexadecimal characters after "${DEPLOY_TOKEN.PREFIX}" prefix`);
|
|
720
771
|
}
|
|
721
772
|
}
|
|
722
773
|
|
|
@@ -822,24 +873,21 @@ export interface StaticFile {
|
|
|
822
873
|
// =============================================================================
|
|
823
874
|
|
|
824
875
|
/**
|
|
825
|
-
*
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
/**
|
|
834
|
-
* Resolved configuration with required apiUrl.
|
|
835
|
-
* This is the normalized config after merging options, env, and config files.
|
|
876
|
+
* Resolved client configuration with `apiUrl` defaulted.
|
|
877
|
+
*
|
|
878
|
+
* Produced by the SDK after layering its credential sources (constructor
|
|
879
|
+
* options on top of `SHIP_*` env vars in Node; constructor options only in
|
|
880
|
+
* Browser) and applying the `DEFAULT_API` fallback. File-based sources
|
|
881
|
+
* (`.shiprc`, `package.json` `"ship"` key) are the CLI's responsibility and
|
|
882
|
+
* are merged in *before* construction — by the time a `ResolvedConfig`
|
|
883
|
+
* exists, every source has already collapsed into the constructor argument.
|
|
836
884
|
*/
|
|
837
885
|
export interface ResolvedConfig {
|
|
838
|
-
/** API URL
|
|
886
|
+
/** API URL — always present after resolution, defaults to `DEFAULT_API`. */
|
|
839
887
|
apiUrl: string;
|
|
840
|
-
/** API key for authenticated deployments */
|
|
888
|
+
/** API key for authenticated deployments. */
|
|
841
889
|
apiKey?: string;
|
|
842
|
-
/** Deploy token for single-use deployments */
|
|
890
|
+
/** Deploy token for single-use deployments. */
|
|
843
891
|
deployToken?: string;
|
|
844
892
|
}
|
|
845
893
|
|
|
@@ -874,10 +922,14 @@ export const DEFAULT_API = 'https://api.shipstatic.com';
|
|
|
874
922
|
// =============================================================================
|
|
875
923
|
|
|
876
924
|
/**
|
|
877
|
-
*
|
|
925
|
+
* Universal deploy input — the union of every shape the SDK accepts.
|
|
878
926
|
*
|
|
879
|
-
* Browser
|
|
880
|
-
* Node
|
|
927
|
+
* - **Browser**: `File[]` (typically from `<input type="file">` or drag-and-drop)
|
|
928
|
+
* - **Node**: `string | string[]` (file or directory path(s) on disk; directories are walked)
|
|
929
|
+
*
|
|
930
|
+
* Each platform's SDK narrows its `deploy()` signature to the relevant shape
|
|
931
|
+
* and rejects anything else at runtime. Use the structural types directly
|
|
932
|
+
* (`File[]`, `string | string[]`) when writing platform-specific code.
|
|
881
933
|
*/
|
|
882
934
|
export type DeployInput = File[] | string | string[];
|
|
883
935
|
|
|
@@ -923,7 +975,7 @@ export interface DeploymentResource {
|
|
|
923
975
|
* Domain resource interface - the contract all implementations must follow
|
|
924
976
|
*/
|
|
925
977
|
export interface DomainResource {
|
|
926
|
-
set: (name: string, options?: { deployment?: string; labels?: string[] }) => Promise<
|
|
978
|
+
set: (name: string, options?: { deployment?: string; labels?: string[] }) => Promise<DomainSetResult>;
|
|
927
979
|
list: () => Promise<DomainListResponse>;
|
|
928
980
|
get: (name: string) => Promise<Domain>;
|
|
929
981
|
remove: (name: string) => Promise<void>;
|
|
@@ -982,34 +1034,6 @@ export interface CheckoutSession {
|
|
|
982
1034
|
url: string;
|
|
983
1035
|
}
|
|
984
1036
|
|
|
985
|
-
/**
|
|
986
|
-
* Billing resource interface - the contract all implementations must follow
|
|
987
|
-
*
|
|
988
|
-
* IMPOSSIBLE SIMPLICITY: No sync() method needed!
|
|
989
|
-
* Webhooks are the single source of truth. Frontend just polls status().
|
|
990
|
-
*/
|
|
991
|
-
export interface BillingResource {
|
|
992
|
-
/**
|
|
993
|
-
* Create a checkout session
|
|
994
|
-
* @returns Checkout session with URL to redirect user
|
|
995
|
-
*/
|
|
996
|
-
checkout: () => Promise<CheckoutSession>;
|
|
997
|
-
|
|
998
|
-
/**
|
|
999
|
-
* Get current billing status
|
|
1000
|
-
* @returns Billing status and usage information
|
|
1001
|
-
*/
|
|
1002
|
-
status: () => Promise<BillingStatus>;
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
/**
|
|
1007
|
-
* Keys resource interface - the contract all implementations must follow
|
|
1008
|
-
*/
|
|
1009
|
-
export interface KeysResource {
|
|
1010
|
-
create: () => Promise<{ apiKey: string }>;
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
1037
|
// =============================================================================
|
|
1014
1038
|
// ACTIVITY TYPES
|
|
1015
1039
|
// =============================================================================
|