@shipstatic/types 0.3.2 → 0.3.3

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
@@ -369,11 +369,12 @@ export interface PlatformConfig {
369
369
  /** Default API URL if not otherwise configured. */
370
370
  export declare const DEFAULT_API = "https://api.shipstatic.com";
371
371
  /**
372
- * Universal deploy input type for all environments.
373
- * - File[] | FileList: Browser environments (file upload)
374
- * - string: Node.js environments (file/directory path)
372
+ * Deploy input type - environment-specific
373
+ *
374
+ * Browser: File[] - array of File objects
375
+ * Node.js: string | string[] - file/directory paths
375
376
  */
376
- export type DeployInput = File[] | FileList | string;
377
+ export type DeployInput = File[] | string | string[];
377
378
  /**
378
379
  * Deployment resource interface - the contract all implementations must follow
379
380
  */
@@ -429,6 +430,50 @@ export interface KeysResource {
429
430
  apiKey: string;
430
431
  }>;
431
432
  }
433
+ /**
434
+ * File status constants for validation state tracking
435
+ */
436
+ export declare const FileValidationStatus: {
437
+ readonly PENDING: "pending";
438
+ readonly PROCESSING_ERROR: "processing_error";
439
+ readonly EMPTY_FILE: "empty_file";
440
+ readonly VALIDATION_FAILED: "validation_failed";
441
+ readonly READY: "ready";
442
+ };
443
+ export type FileValidationStatusType = typeof FileValidationStatus[keyof typeof FileValidationStatus];
444
+ /**
445
+ * Client-side validation error structure
446
+ */
447
+ export interface ValidationError {
448
+ error: string;
449
+ details: string;
450
+ errors: string[];
451
+ isClientError: true;
452
+ }
453
+ /**
454
+ * Minimal file interface required for validation
455
+ */
456
+ export interface ValidatableFile {
457
+ name: string;
458
+ size: number;
459
+ type: string;
460
+ status?: string;
461
+ statusMessage?: string;
462
+ }
463
+ /**
464
+ * File validation result
465
+ *
466
+ * NOTE: Validation is ATOMIC - if any file fails validation, ALL files are rejected.
467
+ * This ensures deployments are all-or-nothing for data integrity.
468
+ */
469
+ export interface FileValidationResult<T extends ValidatableFile> {
470
+ /** All files with updated status */
471
+ files: T[];
472
+ /** Files that passed validation (empty if ANY file failed - atomic validation) */
473
+ validFiles: T[];
474
+ /** Validation error if any files failed */
475
+ error: ValidationError | null;
476
+ }
432
477
  /**
433
478
  * Represents a file that has been uploaded and stored
434
479
  */
package/dist/index.js CHANGED
@@ -265,6 +265,19 @@ export function validateSubdomain(input) {
265
265
  /** Default API URL if not otherwise configured. */
266
266
  export const DEFAULT_API = 'https://api.shipstatic.com';
267
267
  // =============================================================================
268
+ // FILE UPLOAD TYPES
269
+ // =============================================================================
270
+ /**
271
+ * File status constants for validation state tracking
272
+ */
273
+ export const FileValidationStatus = {
274
+ PENDING: 'pending',
275
+ PROCESSING_ERROR: 'processing_error',
276
+ EMPTY_FILE: 'empty_file',
277
+ VALIDATION_FAILED: 'validation_failed',
278
+ READY: 'ready',
279
+ };
280
+ // =============================================================================
268
281
  // URL GENERATION UTILITIES
269
282
  // =============================================================================
270
283
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipstatic/types",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Shared types for Shipstatic platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/index.ts CHANGED
@@ -216,7 +216,7 @@ export enum ErrorType {
216
216
  /** Validation failed (400) */
217
217
  Validation = "validation_failed",
218
218
  /** Resource not found (404) */
219
- NotFound = "not_found",
219
+ NotFound = "not_found",
220
220
  /** Rate limit exceeded (429) */
221
221
  RateLimit = "rate_limit_exceeded",
222
222
  /** Authentication required (401) */
@@ -278,10 +278,10 @@ export class ShipError extends Error {
278
278
  /** Convert to wire format */
279
279
  toResponse(): ErrorResponse {
280
280
  // For security, exclude internal details from authentication errors in API responses
281
- const details = this.type === ErrorType.Authentication && this.details?.internal
282
- ? undefined
281
+ const details = this.type === ErrorType.Authentication && this.details?.internal
282
+ ? undefined
283
283
  : this.details;
284
-
284
+
285
285
  return {
286
286
  error: this.type,
287
287
  message: this.message,
@@ -449,7 +449,7 @@ export const DEPLOY_TOKEN_TOTAL_LENGTH = DEPLOY_TOKEN_PREFIX.length + DEPLOY_TOK
449
449
  // Authentication Method Constants
450
450
  export const AuthMethod = {
451
451
  JWT: 'jwt',
452
- API_KEY: 'apiKey',
452
+ API_KEY: 'apiKey',
453
453
  TOKEN: 'token'
454
454
  } as const;
455
455
 
@@ -469,11 +469,11 @@ export function validateApiKey(apiKey: string): void {
469
469
  if (!apiKey.startsWith(API_KEY_PREFIX)) {
470
470
  throw ShipError.validation(`API key must start with "${API_KEY_PREFIX}"`);
471
471
  }
472
-
472
+
473
473
  if (apiKey.length !== API_KEY_TOTAL_LENGTH) {
474
474
  throw ShipError.validation(`API key must be ${API_KEY_TOTAL_LENGTH} characters total (${API_KEY_PREFIX} + ${API_KEY_HEX_LENGTH} hex chars)`);
475
475
  }
476
-
476
+
477
477
  const hexPart = apiKey.slice(API_KEY_PREFIX.length);
478
478
  if (!/^[a-f0-9]{64}$/i.test(hexPart)) {
479
479
  throw ShipError.validation(`API key must contain ${API_KEY_HEX_LENGTH} hexadecimal characters after "${API_KEY_PREFIX}" prefix`);
@@ -487,11 +487,11 @@ export function validateDeployToken(deployToken: string): void {
487
487
  if (!deployToken.startsWith(DEPLOY_TOKEN_PREFIX)) {
488
488
  throw ShipError.validation(`Deploy token must start with "${DEPLOY_TOKEN_PREFIX}"`);
489
489
  }
490
-
490
+
491
491
  if (deployToken.length !== DEPLOY_TOKEN_TOTAL_LENGTH) {
492
492
  throw ShipError.validation(`Deploy token must be ${DEPLOY_TOKEN_TOTAL_LENGTH} characters total (${DEPLOY_TOKEN_PREFIX} + ${DEPLOY_TOKEN_HEX_LENGTH} hex chars)`);
493
493
  }
494
-
494
+
495
495
  const hexPart = deployToken.slice(DEPLOY_TOKEN_PREFIX.length);
496
496
  if (!/^[a-f0-9]{64}$/i.test(hexPart)) {
497
497
  throw ShipError.validation(`Deploy token must contain ${DEPLOY_TOKEN_HEX_LENGTH} hexadecimal characters after "${DEPLOY_TOKEN_PREFIX}" prefix`);
@@ -504,15 +504,15 @@ export function validateDeployToken(deployToken: string): void {
504
504
  export function validateApiUrl(apiUrl: string): void {
505
505
  try {
506
506
  const url = new URL(apiUrl);
507
-
507
+
508
508
  if (!['http:', 'https:'].includes(url.protocol)) {
509
509
  throw ShipError.validation('API URL must use http:// or https:// protocol');
510
510
  }
511
-
511
+
512
512
  if (url.pathname !== '/' && url.pathname !== '') {
513
513
  throw ShipError.validation('API URL must not contain a path');
514
514
  }
515
-
515
+
516
516
  if (url.search || url.hash) {
517
517
  throw ShipError.validation('API URL must not contain query parameters or fragments');
518
518
  }
@@ -620,11 +620,12 @@ export const DEFAULT_API = 'https://api.shipstatic.com';
620
620
  // =============================================================================
621
621
 
622
622
  /**
623
- * Universal deploy input type for all environments.
624
- * - File[] | FileList: Browser environments (file upload)
625
- * - string: Node.js environments (file/directory path)
623
+ * Deploy input type - environment-specific
624
+ *
625
+ * Browser: File[] - array of File objects
626
+ * Node.js: string | string[] - file/directory paths
626
627
  */
627
- export type DeployInput = File[] | FileList | string;
628
+ export type DeployInput = File[] | string | string[];
628
629
 
629
630
  /**
630
631
  * Deployment resource interface - the contract all implementations must follow
@@ -677,6 +678,55 @@ export interface KeysResource {
677
678
  // FILE UPLOAD TYPES
678
679
  // =============================================================================
679
680
 
681
+ /**
682
+ * File status constants for validation state tracking
683
+ */
684
+ export const FileValidationStatus = {
685
+ PENDING: 'pending',
686
+ PROCESSING_ERROR: 'processing_error',
687
+ EMPTY_FILE: 'empty_file',
688
+ VALIDATION_FAILED: 'validation_failed',
689
+ READY: 'ready',
690
+ } as const;
691
+
692
+ export type FileValidationStatusType = typeof FileValidationStatus[keyof typeof FileValidationStatus];
693
+
694
+ /**
695
+ * Client-side validation error structure
696
+ */
697
+ export interface ValidationError {
698
+ error: string;
699
+ details: string;
700
+ errors: string[];
701
+ isClientError: true;
702
+ }
703
+
704
+ /**
705
+ * Minimal file interface required for validation
706
+ */
707
+ export interface ValidatableFile {
708
+ name: string;
709
+ size: number;
710
+ type: string;
711
+ status?: string;
712
+ statusMessage?: string;
713
+ }
714
+
715
+ /**
716
+ * File validation result
717
+ *
718
+ * NOTE: Validation is ATOMIC - if any file fails validation, ALL files are rejected.
719
+ * This ensures deployments are all-or-nothing for data integrity.
720
+ */
721
+ export interface FileValidationResult<T extends ValidatableFile> {
722
+ /** All files with updated status */
723
+ files: T[];
724
+ /** Files that passed validation (empty if ANY file failed - atomic validation) */
725
+ validFiles: T[];
726
+ /** Validation error if any files failed */
727
+ error: ValidationError | null;
728
+ }
729
+
680
730
  /**
681
731
  * Represents a file that has been uploaded and stored
682
732
  */