@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 +49 -4
- package/dist/index.js +13 -0
- package/package.json +1 -1
- package/src/index.ts +66 -16
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
|
-
*
|
|
373
|
-
*
|
|
374
|
-
* -
|
|
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[] |
|
|
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
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
|
-
*
|
|
624
|
-
*
|
|
625
|
-
* -
|
|
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[] |
|
|
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
|
*/
|