@shipstatic/types 2.4.2-beta.0 → 2.5.0-beta.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/dist/index.d.ts CHANGED
@@ -522,7 +522,7 @@ export declare function hasUnbuiltMarker(filePath: string): boolean;
522
522
  export interface PingResponse {
523
523
  /** Always true if service is healthy */
524
524
  success: boolean;
525
- /** Optional timestamp */
525
+ /** Server time in unix seconds — the one wire unit for timestamps. */
526
526
  timestamp?: number;
527
527
  }
528
528
  /**
@@ -727,20 +727,6 @@ export interface StaticFile {
727
727
  /** The size of the file in bytes. */
728
728
  size: number;
729
729
  }
730
- /**
731
- * Progress information for deploy/upload operations.
732
- * Provides consistent percentage-based progress with byte-level details.
733
- */
734
- export interface ProgressInfo {
735
- /** Progress percentage (0-100) */
736
- percent: number;
737
- /** Number of bytes loaded so far */
738
- loaded: number;
739
- /** Total number of bytes to load. May be 0 if unknown initially */
740
- total: number;
741
- /** Current file being processed (optional) */
742
- file?: string;
743
- }
744
730
  /** Default API URL if not otherwise configured. */
745
731
  export declare const DEFAULT_API = "https://api.shipstatic.com";
746
732
  /**
@@ -784,11 +770,28 @@ export interface DeploymentUploadOptions {
784
770
  captcha?: string;
785
771
  }
786
772
  /**
787
- * Deployment resource interface - the contract all implementations must follow
773
+ * Pagination options for the paginated list endpoints (`GET /deployments`,
774
+ * `GET /domains`). The response's `cursor` feeds the next request; a `null`
775
+ * cursor on the response means the last page. Omitting both returns the
776
+ * server's default first page.
788
777
  */
789
- export interface DeploymentResource {
790
- upload: (input: DeployInput, options?: DeploymentUploadOptions) => Promise<DeploymentCreateResponse>;
791
- list: () => Promise<DeploymentListResponse>;
778
+ export interface ListOptions {
779
+ /** Maximum number of items to return in one page. */
780
+ limit?: number;
781
+ /** Opaque cursor from the previous page's response. */
782
+ cursor?: string;
783
+ }
784
+ /**
785
+ * Deployment resource interface - the contract all implementations must follow.
786
+ *
787
+ * The interface defines the minimal wire contract; SDK implementations may
788
+ * extend the upload options with runtime concerns (timeout, signal, progress
789
+ * callbacks) by parameterizing: `DeploymentResource<MyUploadOptions>`. The
790
+ * default keeps plain `DeploymentResource` valid for wire-only consumers.
791
+ */
792
+ export interface DeploymentResource<UploadOptions extends DeploymentUploadOptions = DeploymentUploadOptions> {
793
+ upload: (input: DeployInput, options?: UploadOptions) => Promise<DeploymentCreateResponse>;
794
+ list: (options?: ListOptions) => Promise<DeploymentListResponse>;
792
795
  get: (id: string) => Promise<Deployment>;
793
796
  set: (id: string, options: {
794
797
  labels: string[];
@@ -803,7 +806,7 @@ export interface DomainResource {
803
806
  deployment?: string;
804
807
  labels?: string[];
805
808
  }) => Promise<DomainSetResult>;
806
- list: () => Promise<DomainListResponse>;
809
+ list: (options?: ListOptions) => Promise<DomainListResponse>;
807
810
  get: (name: string) => Promise<Domain>;
808
811
  remove: (name: string) => Promise<void>;
809
812
  verify: (name: string) => Promise<{
@@ -886,6 +889,12 @@ export interface Activity {
886
889
  /**
887
890
  * Parsed activity metadata.
888
891
  * Different events populate different fields.
892
+ *
893
+ * Naming convention: meta booleans are event-scoped predicates and carry
894
+ * their prefix (`isUpdate`, `wasVerified`, `hasConfig`, `hasPassword`),
895
+ * while entity booleans are bare nouns (`Deployment.config`,
896
+ * `Deployment.password`). Two vocabularies, each internally consistent —
897
+ * deliberate, not drift.
889
898
  */
890
899
  export interface ActivityMeta {
891
900
  /** Number of files in deployment */
package/dist/index.js CHANGED
@@ -197,6 +197,23 @@ export class ShipError extends Error {
197
197
  catch {
198
198
  // Body unreadable; fall through to operationName-derived message.
199
199
  }
200
+ // Rate-limit (and 503) timing rides the `Retry-After` HEADER, which a
201
+ // body-only reader would drop. Lift it into `details` as seconds so
202
+ // consumers can back off from the typed error alone, without keeping the
203
+ // raw Response around. Body-carried fields are preserved and win.
204
+ const retryAfterHeader = response.headers.get('retry-after');
205
+ if (retryAfterHeader !== null) {
206
+ const value = retryAfterHeader.trim();
207
+ const seconds = /^\d+$/.test(value)
208
+ ? Number(value)
209
+ : Math.ceil((Date.parse(value) - Date.now()) / 1000);
210
+ if (Number.isFinite(seconds) && seconds >= 0) {
211
+ const existing = details && typeof details === 'object' ? details : {};
212
+ if (existing.retryAfter === undefined) {
213
+ details = { ...existing, retryAfter: seconds };
214
+ }
215
+ }
216
+ }
200
217
  message = message || `${operationName || 'Request'} failed with status ${response.status}`;
201
218
  const type = bodyType ??
202
219
  (response.status === 401
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipstatic/types",
3
- "version": "2.4.2-beta.0",
3
+ "version": "2.5.0-beta.1",
4
4
  "description": "Shared types for ShipStatic platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/index.ts CHANGED
@@ -512,6 +512,25 @@ export class ShipError extends Error {
512
512
  // Body unreadable; fall through to operationName-derived message.
513
513
  }
514
514
 
515
+ // Rate-limit (and 503) timing rides the `Retry-After` HEADER, which a
516
+ // body-only reader would drop. Lift it into `details` as seconds so
517
+ // consumers can back off from the typed error alone, without keeping the
518
+ // raw Response around. Body-carried fields are preserved and win.
519
+ const retryAfterHeader = response.headers.get('retry-after');
520
+ if (retryAfterHeader !== null) {
521
+ const value = retryAfterHeader.trim();
522
+ const seconds = /^\d+$/.test(value)
523
+ ? Number(value)
524
+ : Math.ceil((Date.parse(value) - Date.now()) / 1000);
525
+ if (Number.isFinite(seconds) && seconds >= 0) {
526
+ const existing =
527
+ details && typeof details === 'object' ? (details as Record<string, unknown>) : {};
528
+ if (existing.retryAfter === undefined) {
529
+ details = { ...existing, retryAfter: seconds };
530
+ }
531
+ }
532
+ }
533
+
515
534
  message = message || `${operationName || 'Request'} failed with status ${response.status}`;
516
535
 
517
536
  const type =
@@ -834,7 +853,7 @@ export function hasUnbuiltMarker(filePath: string): boolean {
834
853
  export interface PingResponse {
835
854
  /** Always true if service is healthy */
836
855
  success: boolean;
837
- /** Optional timestamp */
856
+ /** Server time in unix seconds — the one wire unit for timestamps. */
838
857
  timestamp?: number;
839
858
  }
840
859
 
@@ -1160,25 +1179,6 @@ export interface StaticFile {
1160
1179
  size: number;
1161
1180
  }
1162
1181
 
1163
- // =============================================================================
1164
- // PROGRESS TRACKING
1165
- // =============================================================================
1166
-
1167
- /**
1168
- * Progress information for deploy/upload operations.
1169
- * Provides consistent percentage-based progress with byte-level details.
1170
- */
1171
- export interface ProgressInfo {
1172
- /** Progress percentage (0-100) */
1173
- percent: number;
1174
- /** Number of bytes loaded so far */
1175
- loaded: number;
1176
- /** Total number of bytes to load. May be 0 if unknown initially */
1177
- total: number;
1178
- /** Current file being processed (optional) */
1179
- file?: string;
1180
- }
1181
-
1182
1182
  // =============================================================================
1183
1183
  // PLATFORM CONSTANTS
1184
1184
  // =============================================================================
@@ -1233,14 +1233,31 @@ export interface DeploymentUploadOptions {
1233
1233
  }
1234
1234
 
1235
1235
  /**
1236
- * Deployment resource interface - the contract all implementations must follow
1236
+ * Pagination options for the paginated list endpoints (`GET /deployments`,
1237
+ * `GET /domains`). The response's `cursor` feeds the next request; a `null`
1238
+ * cursor on the response means the last page. Omitting both returns the
1239
+ * server's default first page.
1237
1240
  */
1238
- export interface DeploymentResource {
1239
- upload: (
1240
- input: DeployInput,
1241
- options?: DeploymentUploadOptions,
1242
- ) => Promise<DeploymentCreateResponse>;
1243
- list: () => Promise<DeploymentListResponse>;
1241
+ export interface ListOptions {
1242
+ /** Maximum number of items to return in one page. */
1243
+ limit?: number;
1244
+ /** Opaque cursor from the previous page's response. */
1245
+ cursor?: string;
1246
+ }
1247
+
1248
+ /**
1249
+ * Deployment resource interface - the contract all implementations must follow.
1250
+ *
1251
+ * The interface defines the minimal wire contract; SDK implementations may
1252
+ * extend the upload options with runtime concerns (timeout, signal, progress
1253
+ * callbacks) by parameterizing: `DeploymentResource<MyUploadOptions>`. The
1254
+ * default keeps plain `DeploymentResource` valid for wire-only consumers.
1255
+ */
1256
+ export interface DeploymentResource<
1257
+ UploadOptions extends DeploymentUploadOptions = DeploymentUploadOptions,
1258
+ > {
1259
+ upload: (input: DeployInput, options?: UploadOptions) => Promise<DeploymentCreateResponse>;
1260
+ list: (options?: ListOptions) => Promise<DeploymentListResponse>;
1244
1261
  get: (id: string) => Promise<Deployment>;
1245
1262
  set: (id: string, options: { labels: string[] }) => Promise<Deployment>;
1246
1263
  remove: (id: string) => Promise<void>;
@@ -1254,7 +1271,7 @@ export interface DomainResource {
1254
1271
  name: string,
1255
1272
  options?: { deployment?: string; labels?: string[] },
1256
1273
  ) => Promise<DomainSetResult>;
1257
- list: () => Promise<DomainListResponse>;
1274
+ list: (options?: ListOptions) => Promise<DomainListResponse>;
1258
1275
  get: (name: string) => Promise<Domain>;
1259
1276
  remove: (name: string) => Promise<void>;
1260
1277
  verify: (name: string) => Promise<{ message: string }>;
@@ -1411,6 +1428,12 @@ export interface Activity {
1411
1428
  /**
1412
1429
  * Parsed activity metadata.
1413
1430
  * Different events populate different fields.
1431
+ *
1432
+ * Naming convention: meta booleans are event-scoped predicates and carry
1433
+ * their prefix (`isUpdate`, `wasVerified`, `hasConfig`, `hasPassword`),
1434
+ * while entity booleans are bare nouns (`Deployment.config`,
1435
+ * `Deployment.password`). Two vocabularies, each internally consistent —
1436
+ * deliberate, not drift.
1414
1437
  */
1415
1438
  export interface ActivityMeta {
1416
1439
  // Deployment events