@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 +51 -4
- package/dist/index.js +13 -0
- package/package.json +1 -1
- package/src/index.ts +68 -16
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
|
-
*
|
|
371
|
-
*
|
|
372
|
-
* -
|
|
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[] |
|
|
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
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
|
-
*
|
|
622
|
-
*
|
|
623
|
-
* -
|
|
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[] |
|
|
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
|
*/
|