@shipstatic/types 0.3.1 → 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
@@ -256,6 +256,8 @@ export interface ConfigResponse {
256
256
  maxFilesCount: number;
257
257
  /** Maximum total deployment size in bytes */
258
258
  maxTotalSize: number;
259
+ /** Allowed MIME type categories for file validation */
260
+ allowedMimeTypes: string[];
259
261
  }
260
262
  /**
261
263
  * Generic success response wrapper
@@ -367,11 +369,12 @@ export interface PlatformConfig {
367
369
  /** Default API URL if not otherwise configured. */
368
370
  export declare const DEFAULT_API = "https://api.shipstatic.com";
369
371
  /**
370
- * Universal deploy input type for all environments.
371
- * - File[] | FileList: Browser environments (file upload)
372
- * - 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
373
376
  */
374
- export type DeployInput = File[] | FileList | string;
377
+ export type DeployInput = File[] | string | string[];
375
378
  /**
376
379
  * Deployment resource interface - the contract all implementations must follow
377
380
  */
@@ -427,6 +430,50 @@ export interface KeysResource {
427
430
  apiKey: string;
428
431
  }>;
429
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
+ }
430
477
  /**
431
478
  * Represents a file that has been uploaded and stored
432
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.1",
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,
@@ -407,6 +407,8 @@ export interface ConfigResponse {
407
407
  maxFilesCount: number;
408
408
  /** Maximum total deployment size in bytes */
409
409
  maxTotalSize: number;
410
+ /** Allowed MIME type categories for file validation */
411
+ allowedMimeTypes: string[];
410
412
  }
411
413
 
412
414
  // =============================================================================
@@ -447,7 +449,7 @@ export const DEPLOY_TOKEN_TOTAL_LENGTH = DEPLOY_TOKEN_PREFIX.length + DEPLOY_TOK
447
449
  // Authentication Method Constants
448
450
  export const AuthMethod = {
449
451
  JWT: 'jwt',
450
- API_KEY: 'apiKey',
452
+ API_KEY: 'apiKey',
451
453
  TOKEN: 'token'
452
454
  } as const;
453
455
 
@@ -467,11 +469,11 @@ export function validateApiKey(apiKey: string): void {
467
469
  if (!apiKey.startsWith(API_KEY_PREFIX)) {
468
470
  throw ShipError.validation(`API key must start with "${API_KEY_PREFIX}"`);
469
471
  }
470
-
472
+
471
473
  if (apiKey.length !== API_KEY_TOTAL_LENGTH) {
472
474
  throw ShipError.validation(`API key must be ${API_KEY_TOTAL_LENGTH} characters total (${API_KEY_PREFIX} + ${API_KEY_HEX_LENGTH} hex chars)`);
473
475
  }
474
-
476
+
475
477
  const hexPart = apiKey.slice(API_KEY_PREFIX.length);
476
478
  if (!/^[a-f0-9]{64}$/i.test(hexPart)) {
477
479
  throw ShipError.validation(`API key must contain ${API_KEY_HEX_LENGTH} hexadecimal characters after "${API_KEY_PREFIX}" prefix`);
@@ -485,11 +487,11 @@ export function validateDeployToken(deployToken: string): void {
485
487
  if (!deployToken.startsWith(DEPLOY_TOKEN_PREFIX)) {
486
488
  throw ShipError.validation(`Deploy token must start with "${DEPLOY_TOKEN_PREFIX}"`);
487
489
  }
488
-
490
+
489
491
  if (deployToken.length !== DEPLOY_TOKEN_TOTAL_LENGTH) {
490
492
  throw ShipError.validation(`Deploy token must be ${DEPLOY_TOKEN_TOTAL_LENGTH} characters total (${DEPLOY_TOKEN_PREFIX} + ${DEPLOY_TOKEN_HEX_LENGTH} hex chars)`);
491
493
  }
492
-
494
+
493
495
  const hexPart = deployToken.slice(DEPLOY_TOKEN_PREFIX.length);
494
496
  if (!/^[a-f0-9]{64}$/i.test(hexPart)) {
495
497
  throw ShipError.validation(`Deploy token must contain ${DEPLOY_TOKEN_HEX_LENGTH} hexadecimal characters after "${DEPLOY_TOKEN_PREFIX}" prefix`);
@@ -502,15 +504,15 @@ export function validateDeployToken(deployToken: string): void {
502
504
  export function validateApiUrl(apiUrl: string): void {
503
505
  try {
504
506
  const url = new URL(apiUrl);
505
-
507
+
506
508
  if (!['http:', 'https:'].includes(url.protocol)) {
507
509
  throw ShipError.validation('API URL must use http:// or https:// protocol');
508
510
  }
509
-
511
+
510
512
  if (url.pathname !== '/' && url.pathname !== '') {
511
513
  throw ShipError.validation('API URL must not contain a path');
512
514
  }
513
-
515
+
514
516
  if (url.search || url.hash) {
515
517
  throw ShipError.validation('API URL must not contain query parameters or fragments');
516
518
  }
@@ -618,11 +620,12 @@ export const DEFAULT_API = 'https://api.shipstatic.com';
618
620
  // =============================================================================
619
621
 
620
622
  /**
621
- * Universal deploy input type for all environments.
622
- * - File[] | FileList: Browser environments (file upload)
623
- * - 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
624
627
  */
625
- export type DeployInput = File[] | FileList | string;
628
+ export type DeployInput = File[] | string | string[];
626
629
 
627
630
  /**
628
631
  * Deployment resource interface - the contract all implementations must follow
@@ -675,6 +678,55 @@ export interface KeysResource {
675
678
  // FILE UPLOAD TYPES
676
679
  // =============================================================================
677
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
+
678
730
  /**
679
731
  * Represents a file that has been uploaded and stored
680
732
  */