@shipstatic/ship 0.3.2 → 0.3.4
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/README.md +65 -10
- package/dist/browser.d.ts +95 -5
- package/dist/browser.js +4 -4
- package/dist/browser.js.map +1 -1
- package/dist/cli.cjs +21 -21
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +91 -1
- package/dist/index.d.ts +91 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -5,9 +5,10 @@ A modern, lightweight SDK and CLI for deploying static files, designed for both
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- **🚀 Modern Resource API**: Clean `ship.deployments.create()` interface - no legacy wrappers
|
|
8
|
-
- **🌍 Universal**: Automatic environment detection (Node.js/Browser) with optimized implementations
|
|
8
|
+
- **🌍 Universal**: Automatic environment detection (Node.js/Browser) with optimized implementations
|
|
9
9
|
- **📡 Event System**: Complete observability with request, response, and error events
|
|
10
10
|
- **🔧 Dynamic Configuration**: Automatically fetches platform limits from API
|
|
11
|
+
- **✅ Client-Side Validation**: Validate files before upload (size, count, MIME types)
|
|
11
12
|
- **📁 Flexible Input**: File paths (Node.js) or File objects (Browser/drag-drop)
|
|
12
13
|
- **🔐 Secure**: MD5 checksums and data integrity validation
|
|
13
14
|
- **📊 Progress Tracking**: Real-time deployment progress and statistics
|
|
@@ -133,6 +134,56 @@ const ship = new Ship({ apiKey: 'ship-your-key' });
|
|
|
133
134
|
- **Always current** - SDK always uses current platform limits
|
|
134
135
|
- **Fail fast** - SDK fails if unable to fetch valid configuration
|
|
135
136
|
|
|
137
|
+
## Client-Side File Validation
|
|
138
|
+
|
|
139
|
+
Ship SDK provides utilities for validating files before upload. Validation is **atomic** - if any file is invalid, the entire upload is rejected.
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import { validateFiles, formatFileSize } from '@shipstatic/ship';
|
|
143
|
+
|
|
144
|
+
// Get platform configuration
|
|
145
|
+
const config = await ship.getConfig();
|
|
146
|
+
|
|
147
|
+
// Validate files before upload
|
|
148
|
+
const result = validateFiles(files, config);
|
|
149
|
+
|
|
150
|
+
if (result.error) {
|
|
151
|
+
// Global summary
|
|
152
|
+
console.error(result.error.details); // "2 files failed validation"
|
|
153
|
+
|
|
154
|
+
// All specific errors
|
|
155
|
+
result.error.errors.forEach(err => console.error(err));
|
|
156
|
+
// "file1.wasm: File type 'application/wasm' is not allowed"
|
|
157
|
+
// "file2.txt: File size (10 MB) exceeds limit of 5 MB"
|
|
158
|
+
|
|
159
|
+
// Per-file status (all files marked failed in atomic validation)
|
|
160
|
+
result.files.forEach(f => {
|
|
161
|
+
console.log(`${f.name}: ${f.statusMessage}`);
|
|
162
|
+
});
|
|
163
|
+
} else {
|
|
164
|
+
console.log(`${result.validFiles.length} files ready to upload`);
|
|
165
|
+
await ship.deployments.create(result.validFiles);
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Validation checks:**
|
|
170
|
+
- File count limit
|
|
171
|
+
- Individual file size limit
|
|
172
|
+
- Total deployment size limit
|
|
173
|
+
- MIME type validation (against allowed categories)
|
|
174
|
+
- Empty file detection
|
|
175
|
+
|
|
176
|
+
**Error handling:**
|
|
177
|
+
- `error.details` - Human-readable summary ("2 files failed validation")
|
|
178
|
+
- `error.errors` - Array of all validation errors for detailed display
|
|
179
|
+
- `file.statusMessage` - Individual file status for UI highlighting
|
|
180
|
+
|
|
181
|
+
**Utilities:**
|
|
182
|
+
- `validateFiles(files, config)` - Validate files against config limits
|
|
183
|
+
- `formatFileSize(bytes, decimals?)` - Format bytes to human-readable string
|
|
184
|
+
- `getValidFiles(files)` - Filter files with `READY` status
|
|
185
|
+
- `FILE_VALIDATION_STATUS` - Status constants for file processing
|
|
186
|
+
|
|
136
187
|
## API Reference
|
|
137
188
|
|
|
138
189
|
### Ship Class
|
|
@@ -180,14 +231,21 @@ await ship.deployments.get(id)
|
|
|
180
231
|
|
|
181
232
|
#### Deploy Input Types
|
|
182
233
|
|
|
183
|
-
**Node.js Environment:**
|
|
184
234
|
```typescript
|
|
185
|
-
type
|
|
235
|
+
type DeployInput = File[] | string | string[];
|
|
186
236
|
```
|
|
187
237
|
|
|
238
|
+
**Node.js Environment:**
|
|
239
|
+
- `string` - Single file or directory path
|
|
240
|
+
- `string[]` - Multiple file/directory paths
|
|
241
|
+
|
|
188
242
|
**Browser Environment:**
|
|
243
|
+
- `File[]` - Array of File objects
|
|
244
|
+
|
|
245
|
+
**Note:** For `<input type="file">` elements, convert FileList to File[]:
|
|
189
246
|
```typescript
|
|
190
|
-
|
|
247
|
+
const files = Array.from(fileInput.files);
|
|
248
|
+
await ship.deploy(files);
|
|
191
249
|
```
|
|
192
250
|
|
|
193
251
|
#### Deploy Options
|
|
@@ -284,17 +342,14 @@ const ship = new Ship({
|
|
|
284
342
|
apiKey: 'ship-your-64-char-hex-string' // 69 chars total
|
|
285
343
|
});
|
|
286
344
|
|
|
287
|
-
// From file input
|
|
345
|
+
// From file input - convert FileList to File[]
|
|
288
346
|
const fileInput = document.getElementById('fileInput') as HTMLInputElement;
|
|
289
|
-
const
|
|
347
|
+
const files: File[] = Array.from(fileInput.files || []);
|
|
348
|
+
const result = await ship.deployments.create(files, {
|
|
290
349
|
onProgress: (progress) => {
|
|
291
350
|
document.getElementById('progress').textContent = `${progress}%`;
|
|
292
351
|
}
|
|
293
352
|
});
|
|
294
|
-
|
|
295
|
-
// From File objects
|
|
296
|
-
const files: File[] = Array.from(fileInput.files || []);
|
|
297
|
-
const result2 = await ship.deployments.create(files);
|
|
298
353
|
```
|
|
299
354
|
|
|
300
355
|
## Event System
|
package/dist/browser.d.ts
CHANGED
|
@@ -439,6 +439,96 @@ declare function __setTestEnvironment(env: ExecutionEnvironment | null): void;
|
|
|
439
439
|
*/
|
|
440
440
|
declare function getENV(): ExecutionEnvironment;
|
|
441
441
|
|
|
442
|
+
/**
|
|
443
|
+
* @file File validation utilities for Ship SDK
|
|
444
|
+
* Provides client-side validation for file uploads before deployment
|
|
445
|
+
*/
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* File status constants for validation state tracking
|
|
449
|
+
*/
|
|
450
|
+
declare const FILE_VALIDATION_STATUS: {
|
|
451
|
+
readonly PENDING: "pending";
|
|
452
|
+
readonly PROCESSING_ERROR: "processing_error";
|
|
453
|
+
readonly EMPTY_FILE: "empty_file";
|
|
454
|
+
readonly VALIDATION_FAILED: "validation_failed";
|
|
455
|
+
readonly READY: "ready";
|
|
456
|
+
};
|
|
457
|
+
type FileValidationStatus = (typeof FILE_VALIDATION_STATUS)[keyof typeof FILE_VALIDATION_STATUS];
|
|
458
|
+
/**
|
|
459
|
+
* Client-side validation error structure
|
|
460
|
+
*/
|
|
461
|
+
interface ValidationError {
|
|
462
|
+
error: string;
|
|
463
|
+
details: string;
|
|
464
|
+
errors: string[];
|
|
465
|
+
isClientError: true;
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Minimal file interface required for validation
|
|
469
|
+
*/
|
|
470
|
+
interface ValidatableFile {
|
|
471
|
+
name: string;
|
|
472
|
+
size: number;
|
|
473
|
+
type: string;
|
|
474
|
+
status?: string;
|
|
475
|
+
statusMessage?: string;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* File validation result
|
|
479
|
+
*
|
|
480
|
+
* NOTE: Validation is ATOMIC - if any file fails validation, ALL files are rejected.
|
|
481
|
+
* This ensures deployments are all-or-nothing for data integrity.
|
|
482
|
+
*/
|
|
483
|
+
interface FileValidationResult<T extends ValidatableFile> {
|
|
484
|
+
/** All files with updated status */
|
|
485
|
+
files: T[];
|
|
486
|
+
/** Files that passed validation (empty if ANY file failed - atomic validation) */
|
|
487
|
+
validFiles: T[];
|
|
488
|
+
/** Validation error if any files failed */
|
|
489
|
+
error: ValidationError | null;
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Format file size to human-readable string
|
|
493
|
+
*/
|
|
494
|
+
declare function formatFileSize(bytes: number, decimals?: number): string;
|
|
495
|
+
/**
|
|
496
|
+
* Validate files against configuration limits
|
|
497
|
+
*
|
|
498
|
+
* ATOMIC VALIDATION: If ANY file fails validation, ALL files are rejected.
|
|
499
|
+
* This ensures deployments are all-or-nothing for data integrity.
|
|
500
|
+
*
|
|
501
|
+
* @param files - Array of files to validate
|
|
502
|
+
* @param config - Validation configuration from ship.getConfig()
|
|
503
|
+
* @returns Validation result with updated file status
|
|
504
|
+
*
|
|
505
|
+
* @example
|
|
506
|
+
* ```typescript
|
|
507
|
+
* const config = await ship.getConfig();
|
|
508
|
+
* const result = validateFiles(files, config);
|
|
509
|
+
*
|
|
510
|
+
* if (result.error) {
|
|
511
|
+
* // Validation failed - result.validFiles will be empty
|
|
512
|
+
* console.error(result.error.details);
|
|
513
|
+
* // Show individual file errors:
|
|
514
|
+
* result.files.forEach(f => console.log(`${f.name}: ${f.statusMessage}`));
|
|
515
|
+
* } else {
|
|
516
|
+
* // All files valid - safe to upload
|
|
517
|
+
* await ship.deploy(result.validFiles);
|
|
518
|
+
* }
|
|
519
|
+
* ```
|
|
520
|
+
*/
|
|
521
|
+
declare function validateFiles<T extends ValidatableFile>(files: T[], config: ConfigResponse): FileValidationResult<T>;
|
|
522
|
+
/**
|
|
523
|
+
* Get only the valid files from validation results
|
|
524
|
+
*/
|
|
525
|
+
declare function getValidFiles<T extends ValidatableFile>(files: T[]): T[];
|
|
526
|
+
/**
|
|
527
|
+
* Check if all valid files have required properties for upload
|
|
528
|
+
* (Can be extended to check for MD5, etc.)
|
|
529
|
+
*/
|
|
530
|
+
declare function allValidFilesReady<T extends ValidatableFile>(files: T[]): boolean;
|
|
531
|
+
|
|
442
532
|
/**
|
|
443
533
|
* @file Browser configuration implementation - no file system access.
|
|
444
534
|
* Browser environment receives all config through constructor options.
|
|
@@ -471,15 +561,15 @@ declare function getCurrentConfig(): ConfigResponse;
|
|
|
471
561
|
*/
|
|
472
562
|
|
|
473
563
|
/**
|
|
474
|
-
* Processes browser files
|
|
564
|
+
* Processes browser files into an array of StaticFile objects ready for deploy.
|
|
475
565
|
* Calculates MD5, filters junk files, and applies automatic path optimization.
|
|
476
566
|
*
|
|
477
|
-
* @param browserFiles -
|
|
567
|
+
* @param browserFiles - File[] to process for deploy.
|
|
478
568
|
* @param options - Processing options including pathDetect for automatic path optimization.
|
|
479
569
|
* @returns Promise resolving to an array of StaticFile objects.
|
|
480
570
|
* @throws {ShipClientError} If called outside a browser or with invalid input.
|
|
481
571
|
*/
|
|
482
|
-
declare function processFilesForBrowser(browserFiles:
|
|
572
|
+
declare function processFilesForBrowser(browserFiles: File[], options?: DeploymentOptions): Promise<StaticFile[]>;
|
|
483
573
|
|
|
484
574
|
/**
|
|
485
575
|
* @file Ship SDK for browser environments with streamlined configuration.
|
|
@@ -500,7 +590,7 @@ declare function processFilesForBrowser(browserFiles: FileList | File[], options
|
|
|
500
590
|
* });
|
|
501
591
|
*
|
|
502
592
|
* // Deploy files from input element
|
|
503
|
-
* const files = fileInput.files;
|
|
593
|
+
* const files = Array.from(fileInput.files);
|
|
504
594
|
* await ship.deploy(files);
|
|
505
595
|
* ```
|
|
506
596
|
*/
|
|
@@ -512,4 +602,4 @@ declare class Ship extends Ship$1 {
|
|
|
512
602
|
protected processInput(input: DeployInput, options: DeploymentOptions): Promise<StaticFile[]>;
|
|
513
603
|
}
|
|
514
604
|
|
|
515
|
-
export { type ApiDeployOptions, ApiHttp, type Config, type DeployFile, type DeploymentOptions, type ExecutionEnvironment, JUNK_DIRECTORIES, type MD5Result, type ProgressStats, Ship, type ShipClientOptions, type ShipEvents, __setTestEnvironment, calculateMD5, createAccountResource, createDeploymentResource, createDomainResource, createTokenResource, Ship as default, filterJunk, getCurrentConfig, getENV, loadConfig, mergeDeployOptions, optimizeDeployPaths, pluralize, processFilesForBrowser, resolveConfig, setConfig as setPlatformConfig };
|
|
605
|
+
export { type ApiDeployOptions, ApiHttp, type Config, type DeployFile, type DeploymentOptions, type ExecutionEnvironment, FILE_VALIDATION_STATUS, type FileValidationResult, type FileValidationStatus, JUNK_DIRECTORIES, type MD5Result, type ProgressStats, Ship, type ShipClientOptions, type ShipEvents, type ValidatableFile, type ValidationError, __setTestEnvironment, allValidFilesReady, calculateMD5, createAccountResource, createDeploymentResource, createDomainResource, createTokenResource, Ship as default, filterJunk, formatFileSize, getCurrentConfig, getENV, getValidFiles, loadConfig, mergeDeployOptions, optimizeDeployPaths, pluralize, processFilesForBrowser, resolveConfig, setConfig as setPlatformConfig, validateFiles };
|