@shipstatic/types 0.1.14 → 0.2.0
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 +222 -124
- package/dist/index.d.ts +126 -4
- package/dist/index.js +39 -2
- package/package.json +2 -1
- package/src/index.ts +172 -5
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @shipstatic/types
|
|
2
2
|
|
|
3
|
-
Shared TypeScript types and
|
|
3
|
+
Shared TypeScript types, constants, and utilities for the Shipstatic platform. This package is the single source of truth for all shared data structures used across the API, SDK, and CLI.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
@@ -9,82 +9,146 @@ This package contains all shared types used between:
|
|
|
9
9
|
- **Shipstatic SDK** (`/ship`) - Universal SDK for Node.js and Browser
|
|
10
10
|
- **Shipstatic CLI** - Command-line interface
|
|
11
11
|
|
|
12
|
-
## Core
|
|
12
|
+
## Core Entities
|
|
13
13
|
|
|
14
|
-
### Deployment
|
|
14
|
+
### Deployment
|
|
15
15
|
|
|
16
16
|
```typescript
|
|
17
|
-
// Core deployment object
|
|
18
17
|
interface Deployment {
|
|
19
|
-
deployment: string;
|
|
20
|
-
files: number;
|
|
21
|
-
size: number;
|
|
18
|
+
deployment: string; // Deployment ID (e.g., "happy-cat-abc1234")
|
|
19
|
+
files: number; // Number of files in deployment
|
|
20
|
+
size: number; // Total size in bytes
|
|
21
|
+
status: 'pending' | 'success' | 'failed' | 'deleting';
|
|
22
|
+
config?: boolean; // Whether deployment has ship.json
|
|
23
|
+
url: string; // Deployment URL
|
|
24
|
+
created: number; // Unix timestamp (seconds)
|
|
25
|
+
expires?: number; // Unix timestamp (seconds)
|
|
26
|
+
verified?: number; // Unix timestamp (seconds) when verified
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Alias
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
interface Alias {
|
|
34
|
+
alias: string; // Alias name (subdomain or custom domain)
|
|
35
|
+
deployment: string; // Target deployment ID
|
|
22
36
|
status: 'pending' | 'success' | 'failed';
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
37
|
+
url: string; // Alias URL
|
|
38
|
+
created: number; // Unix timestamp (seconds)
|
|
39
|
+
confirmed?: number; // Unix timestamp (seconds) when confirmed
|
|
40
|
+
isCreate?: boolean; // Present in set operations only
|
|
26
41
|
}
|
|
42
|
+
```
|
|
27
43
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
44
|
+
### Account
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
interface Account {
|
|
48
|
+
email: string; // User email address
|
|
49
|
+
name: string; // User display name
|
|
50
|
+
picture?: string; // Profile picture URL
|
|
51
|
+
plan: 'free' | 'active' | 'suspended'; // Account plan status
|
|
52
|
+
created: number; // Unix timestamp (seconds)
|
|
53
|
+
subscribed?: number; // Unix timestamp (seconds) when plan started
|
|
54
|
+
suspended?: number; // Unix timestamp (seconds) when suspended
|
|
35
55
|
}
|
|
56
|
+
```
|
|
36
57
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
58
|
+
### Static File
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
interface StaticFile {
|
|
62
|
+
content: File | Buffer | Blob; // File content
|
|
63
|
+
path: string; // Server path (e.g., "assets/style.css")
|
|
64
|
+
filePath?: string; // Original filesystem path (Node.js)
|
|
65
|
+
md5?: string; // MD5 hash of content
|
|
66
|
+
size: number; // File size in bytes
|
|
42
67
|
}
|
|
43
68
|
```
|
|
44
69
|
|
|
45
|
-
|
|
70
|
+
## API Response Types
|
|
71
|
+
|
|
72
|
+
### Success Responses
|
|
46
73
|
|
|
47
74
|
```typescript
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
status: 'pending' | 'success' | 'failed';
|
|
53
|
-
created: number; // Unix timestamp
|
|
54
|
-
confirmed?: number; // Unix timestamp
|
|
75
|
+
interface DeploymentListResponse {
|
|
76
|
+
deployments: Deployment[];
|
|
77
|
+
cursor?: string; // Pagination cursor
|
|
78
|
+
total?: number; // Total count if available
|
|
55
79
|
}
|
|
56
80
|
|
|
57
|
-
// Alias list response
|
|
58
81
|
interface AliasListResponse {
|
|
59
82
|
aliases: Alias[];
|
|
60
83
|
cursor?: string;
|
|
61
84
|
total?: number;
|
|
62
85
|
}
|
|
86
|
+
|
|
87
|
+
interface SuccessResponse<T = any> {
|
|
88
|
+
success: true;
|
|
89
|
+
data: T;
|
|
90
|
+
}
|
|
63
91
|
```
|
|
64
92
|
|
|
65
|
-
###
|
|
93
|
+
### Configuration
|
|
66
94
|
|
|
67
95
|
```typescript
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
96
|
+
interface ConfigResponse {
|
|
97
|
+
maxFileSize: number; // Maximum file size in bytes
|
|
98
|
+
maxFilesCount: number; // Maximum files per deployment
|
|
99
|
+
maxTotalSize: number; // Maximum total deployment size
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
interface PlatformConfig {
|
|
103
|
+
apiUrl?: string;
|
|
104
|
+
deployToken?: string;
|
|
105
|
+
apiKey?: string;
|
|
77
106
|
}
|
|
78
107
|
```
|
|
79
108
|
|
|
80
|
-
###
|
|
109
|
+
### SPA Detection
|
|
81
110
|
|
|
82
111
|
```typescript
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
112
|
+
interface SPACheckRequest {
|
|
113
|
+
files: string[]; // Array of file paths
|
|
114
|
+
index: string; // Index file path
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
interface SPACheckResponse {
|
|
118
|
+
isSPA: boolean; // Whether it's detected as SPA
|
|
119
|
+
debug: {
|
|
120
|
+
tier: 'exclusions' | 'inclusions' | 'scoring' | 'ai' | 'fallback';
|
|
121
|
+
reason: string;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Resource Interface Contracts
|
|
127
|
+
|
|
128
|
+
These interfaces define the contracts that all SDK implementations must follow:
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
interface DeploymentResource {
|
|
132
|
+
create: (input: DeployInput, options?: any) => Promise<Deployment>;
|
|
133
|
+
list: () => Promise<DeploymentListResponse>;
|
|
134
|
+
remove: (id: string) => Promise<void>;
|
|
135
|
+
get: (id: string) => Promise<Deployment>;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
interface AliasResource {
|
|
139
|
+
set: (aliasName: string, deployment: string) => Promise<Alias>;
|
|
140
|
+
get: (aliasName: string) => Promise<Alias>;
|
|
141
|
+
list: () => Promise<AliasListResponse>;
|
|
142
|
+
remove: (aliasName: string) => Promise<void>;
|
|
143
|
+
check: (aliasName: string) => Promise<{ message: string }>;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
interface AccountResource {
|
|
147
|
+
get: () => Promise<Account>;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
interface KeysResource {
|
|
151
|
+
create: () => Promise<{ apiKey: string }>;
|
|
88
152
|
}
|
|
89
153
|
```
|
|
90
154
|
|
|
@@ -93,7 +157,6 @@ interface ConfigResponse {
|
|
|
93
157
|
### Unified Error Handling
|
|
94
158
|
|
|
95
159
|
```typescript
|
|
96
|
-
// All possible error types
|
|
97
160
|
enum ErrorType {
|
|
98
161
|
Validation = "validation_failed",
|
|
99
162
|
NotFound = "not_found",
|
|
@@ -107,7 +170,6 @@ enum ErrorType {
|
|
|
107
170
|
Config = "config_error"
|
|
108
171
|
}
|
|
109
172
|
|
|
110
|
-
// Standard error response format
|
|
111
173
|
interface ErrorResponse {
|
|
112
174
|
error: ErrorType;
|
|
113
175
|
message: string;
|
|
@@ -115,7 +177,6 @@ interface ErrorResponse {
|
|
|
115
177
|
details?: any;
|
|
116
178
|
}
|
|
117
179
|
|
|
118
|
-
// Unified error class for both API and SDK
|
|
119
180
|
class ShipError extends Error {
|
|
120
181
|
constructor(
|
|
121
182
|
public readonly type: ErrorType,
|
|
@@ -128,72 +189,102 @@ class ShipError extends Error {
|
|
|
128
189
|
static validation(message: string, details?: any): ShipError;
|
|
129
190
|
static notFound(resource: string, id?: string): ShipError;
|
|
130
191
|
static authentication(message?: string): ShipError;
|
|
131
|
-
static
|
|
192
|
+
static business(message: string, status?: number): ShipError;
|
|
193
|
+
static network(message: string, cause?: Error): ShipError;
|
|
194
|
+
static api(message?: string, status?: number): ShipError;
|
|
132
195
|
|
|
133
196
|
// Helper methods
|
|
134
197
|
isClientError(): boolean;
|
|
135
198
|
isNetworkError(): boolean;
|
|
136
199
|
isAuthError(): boolean;
|
|
200
|
+
toResponse(): ErrorResponse;
|
|
137
201
|
}
|
|
138
202
|
```
|
|
139
203
|
|
|
140
|
-
## Platform
|
|
141
|
-
|
|
142
|
-
### Shared Constants
|
|
204
|
+
## Platform Constants
|
|
143
205
|
|
|
144
206
|
```typescript
|
|
145
|
-
//
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
maxTotalSize: 100 * 1024 * 1024,
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
defaultLimit: 50,
|
|
157
|
-
maxLimit: 100,
|
|
207
|
+
// API configuration
|
|
208
|
+
const DEFAULT_API = 'https://api.shipstatic.com';
|
|
209
|
+
|
|
210
|
+
// Server configuration limits
|
|
211
|
+
const serverConfig = {
|
|
212
|
+
maxFileSize: 10 * 1024 * 1024, // 10MB
|
|
213
|
+
maxFilesCount: 1000, // Files per deployment
|
|
214
|
+
maxTotalSize: 100 * 1024 * 1024, // 100MB total
|
|
215
|
+
deploymentExpiryHours: 168, // 7 days
|
|
216
|
+
defaultLimit: 50, // Pagination default
|
|
217
|
+
maxLimit: 100, // Pagination maximum
|
|
158
218
|
} as const;
|
|
159
219
|
|
|
160
|
-
//
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
/** Conservative file count limit for client validation */
|
|
165
|
-
maxFilesCount: 100,
|
|
166
|
-
/** Conservative total size limit for client validation (25MB) */
|
|
167
|
-
maxTotalSize: 25 * 1024 * 1024,
|
|
168
|
-
} as const;
|
|
220
|
+
// API key format validation
|
|
221
|
+
const API_KEY_PREFIX = 'ship-';
|
|
222
|
+
const API_KEY_HEX_LENGTH = 64;
|
|
223
|
+
const API_KEY_TOTAL_LENGTH = 69; // 'ship-' + 64 hex chars
|
|
169
224
|
```
|
|
170
225
|
|
|
171
|
-
|
|
226
|
+
## Upload Types
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
enum UploadStatus {
|
|
230
|
+
PENDING = 'pending',
|
|
231
|
+
SUCCESS = 'success',
|
|
232
|
+
FAILED = 'failed',
|
|
233
|
+
DELETING = 'deleting'
|
|
234
|
+
}
|
|
172
235
|
|
|
173
|
-
|
|
236
|
+
interface UploadedFile {
|
|
237
|
+
key: string; // Storage key
|
|
238
|
+
etag: string; // ETag from storage
|
|
239
|
+
size: number; // File size in bytes
|
|
240
|
+
validated?: boolean; // Whether file was validated
|
|
241
|
+
}
|
|
174
242
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
"maxFilesCount": 1000, // Files per deployment
|
|
179
|
-
"maxTotalSize": 104857600 // 100MB total
|
|
243
|
+
interface RateLimitData {
|
|
244
|
+
count: number; // Current request count
|
|
245
|
+
timestamp: number; // Window start timestamp
|
|
180
246
|
}
|
|
181
247
|
```
|
|
182
248
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
249
|
+
## Validation Utilities
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
// Validate API key format
|
|
253
|
+
function validateApiKey(apiKey: string): void;
|
|
254
|
+
|
|
255
|
+
// Validate deploy token format
|
|
256
|
+
function validateDeployToken(deployToken: string): void;
|
|
188
257
|
|
|
189
|
-
|
|
258
|
+
// Validate API URL format
|
|
259
|
+
function validateApiUrl(apiUrl: string): void;
|
|
190
260
|
|
|
191
|
-
|
|
261
|
+
// Validate deployment subdomain format
|
|
262
|
+
function validateSubdomain(input: string): boolean;
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## URL Generation
|
|
192
266
|
|
|
193
267
|
```typescript
|
|
194
|
-
|
|
268
|
+
// Generate deployment URL
|
|
269
|
+
function generateDeploymentUrl(deployment: string, sitesDomain?: string): string;
|
|
195
270
|
|
|
196
|
-
//
|
|
271
|
+
// Generate alias URL (handles both subdomains and custom domains)
|
|
272
|
+
function generateAliasUrl(alias: string, sitesDomain?: string): string;
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Usage Examples
|
|
276
|
+
|
|
277
|
+
### In the API
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
import {
|
|
281
|
+
serverConfig,
|
|
282
|
+
ShipError,
|
|
283
|
+
type ConfigResponse,
|
|
284
|
+
type Deployment
|
|
285
|
+
} from '@shipstatic/types';
|
|
286
|
+
|
|
287
|
+
// Use shared configuration
|
|
197
288
|
const config: ConfigResponse = {
|
|
198
289
|
maxFileSize: serverConfig.maxFileSize,
|
|
199
290
|
maxFilesCount: serverConfig.maxFilesCount,
|
|
@@ -201,32 +292,45 @@ const config: ConfigResponse = {
|
|
|
201
292
|
};
|
|
202
293
|
|
|
203
294
|
// Use unified error handling
|
|
204
|
-
throw ShipError.validation('File too large', {
|
|
295
|
+
throw ShipError.validation('File too large', {
|
|
296
|
+
maxSize: serverConfig.maxFileSize
|
|
297
|
+
});
|
|
205
298
|
```
|
|
206
299
|
|
|
207
|
-
### In
|
|
300
|
+
### In the SDK
|
|
208
301
|
|
|
209
302
|
```typescript
|
|
210
|
-
import {
|
|
303
|
+
import {
|
|
304
|
+
ShipError,
|
|
305
|
+
type ConfigResponse,
|
|
306
|
+
type DeploymentListResponse,
|
|
307
|
+
generateDeploymentUrl
|
|
308
|
+
} from '@shipstatic/types';
|
|
211
309
|
|
|
212
|
-
//
|
|
213
|
-
const
|
|
310
|
+
// Handle API responses
|
|
311
|
+
const deployments: DeploymentListResponse = await api.listDeployments();
|
|
312
|
+
|
|
313
|
+
// Generate URLs consistently
|
|
314
|
+
const url = generateDeploymentUrl('happy-cat-abc1234');
|
|
214
315
|
|
|
215
316
|
// Handle errors consistently
|
|
216
317
|
try {
|
|
217
|
-
const result
|
|
318
|
+
const result = await deploy(files);
|
|
218
319
|
} catch (error) {
|
|
219
|
-
if (error instanceof ShipError) {
|
|
220
|
-
// Handle
|
|
320
|
+
if (error instanceof ShipError && error.isClientError()) {
|
|
321
|
+
// Handle client errors
|
|
221
322
|
}
|
|
222
323
|
}
|
|
223
324
|
```
|
|
224
325
|
|
|
225
326
|
## Installation
|
|
226
327
|
|
|
227
|
-
This package is automatically installed as a dependency
|
|
328
|
+
This package is automatically installed as a dependency:
|
|
228
329
|
|
|
229
330
|
```bash
|
|
331
|
+
# Included with Ship SDK
|
|
332
|
+
npm install @shipstatic/ship
|
|
333
|
+
|
|
230
334
|
# Direct installation (if needed)
|
|
231
335
|
npm install @shipstatic/types
|
|
232
336
|
```
|
|
@@ -236,40 +340,34 @@ npm install @shipstatic/types
|
|
|
236
340
|
### Design Principles
|
|
237
341
|
|
|
238
342
|
- **Single source of truth** - All types defined once, used everywhere
|
|
239
|
-
- **Type safety** - Strict TypeScript with
|
|
240
|
-
- **Wire format compatibility** - Types match API
|
|
343
|
+
- **Type safety** - Strict TypeScript with comprehensive validation
|
|
344
|
+
- **Wire format compatibility** - Types match actual API contracts
|
|
241
345
|
- **Error consistency** - Unified error handling across all components
|
|
242
|
-
- **
|
|
243
|
-
|
|
244
|
-
### Package Structure
|
|
245
|
-
|
|
246
|
-
```
|
|
247
|
-
/types/src/
|
|
248
|
-
└── index.ts # All types and exports in single file
|
|
249
|
-
```
|
|
346
|
+
- **Platform contracts** - Resource interfaces define SDK behavior
|
|
250
347
|
|
|
251
348
|
### Type Organization
|
|
252
349
|
|
|
253
|
-
All types are organized in a single `index.ts` file by category:
|
|
350
|
+
All types are organized in a single `src/index.ts` file by category:
|
|
254
351
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
352
|
+
1. **Core entities** - Deployment, Alias, Account objects
|
|
353
|
+
2. **API responses** - Response wrappers and pagination
|
|
354
|
+
3. **Resource contracts** - SDK interface definitions
|
|
355
|
+
4. **Error system** - Unified ShipError class and error types
|
|
356
|
+
5. **Platform configuration** - Shared constants and validation
|
|
357
|
+
6. **Upload types** - File handling and status enums
|
|
358
|
+
7. **Utility functions** - URL generation and validation
|
|
260
359
|
|
|
261
360
|
## Philosophy
|
|
262
361
|
|
|
263
362
|
This package follows the **"Impossible Simplicity"** principle:
|
|
264
363
|
|
|
265
|
-
- **
|
|
266
|
-
- **
|
|
267
|
-
- **
|
|
268
|
-
- **Developer experience** - Clear, predictable type interfaces
|
|
364
|
+
- **Clear contracts** - Types define platform behavior
|
|
365
|
+
- **Zero duplication** - Single source prevents drift
|
|
366
|
+
- **Developer experience** - Predictable, well-documented interfaces
|
|
269
367
|
- **Maintainability** - Easy to update types across entire platform
|
|
270
368
|
|
|
271
|
-
|
|
369
|
+
The result is type-safe development across the entire Shipstatic platform with guaranteed consistency between API, SDK, and CLI components.
|
|
272
370
|
|
|
273
371
|
---
|
|
274
372
|
|
|
275
|
-
**
|
|
373
|
+
**@shipstatic/types** - The foundation of type safety for Shipstatic 🚢
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file Shared types for Shipstatic platform
|
|
3
|
-
*
|
|
2
|
+
* @file Shared TypeScript types, constants, and utilities for the Shipstatic platform.
|
|
3
|
+
* This package is the single source of truth for all shared data structures.
|
|
4
4
|
*/
|
|
5
5
|
/**
|
|
6
6
|
* Core deployment object - used in both API responses and SDK
|
|
@@ -13,7 +13,7 @@ export interface Deployment {
|
|
|
13
13
|
/** Total size of all files in bytes */
|
|
14
14
|
size: number;
|
|
15
15
|
/** Current deployment status */
|
|
16
|
-
status: 'pending' | 'success' | 'failed';
|
|
16
|
+
status: 'pending' | 'success' | 'failed' | 'deleting';
|
|
17
17
|
/** Whether deployment has configuration */
|
|
18
18
|
config?: boolean;
|
|
19
19
|
/** The deployment URL */
|
|
@@ -22,6 +22,8 @@ export interface Deployment {
|
|
|
22
22
|
created: number;
|
|
23
23
|
/** Unix timestamp (seconds) when deployment expires */
|
|
24
24
|
expires?: number;
|
|
25
|
+
/** Unix timestamp (seconds) when deployment was verified and ready */
|
|
26
|
+
verified?: number;
|
|
25
27
|
}
|
|
26
28
|
/**
|
|
27
29
|
* Response for listing deployments
|
|
@@ -243,7 +245,7 @@ export declare function validateSubdomain(input: string): boolean;
|
|
|
243
245
|
export interface SPACheckRequest {
|
|
244
246
|
/** Array of file paths */
|
|
245
247
|
files: string[];
|
|
246
|
-
/**
|
|
248
|
+
/** HTML content of index.html file */
|
|
247
249
|
index: string;
|
|
248
250
|
}
|
|
249
251
|
/**
|
|
@@ -252,4 +254,124 @@ export interface SPACheckRequest {
|
|
|
252
254
|
export interface SPACheckResponse {
|
|
253
255
|
/** Whether the project is detected as a Single Page Application */
|
|
254
256
|
isSPA: boolean;
|
|
257
|
+
/** Debugging information about detection */
|
|
258
|
+
debug: {
|
|
259
|
+
/** Which tier made the detection: 'exclusions', 'inclusions', 'scoring', 'ai', or 'fallback' */
|
|
260
|
+
tier: 'exclusions' | 'inclusions' | 'scoring' | 'ai' | 'fallback';
|
|
261
|
+
/** The reason for the detection result */
|
|
262
|
+
reason: string;
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Represents a file that has been processed and is ready for deploy.
|
|
267
|
+
* Used across the platform (API, SDK, CLI) for file operations.
|
|
268
|
+
*/
|
|
269
|
+
export interface StaticFile {
|
|
270
|
+
/**
|
|
271
|
+
* The content of the file.
|
|
272
|
+
* In Node.js, this is typically a `Buffer`.
|
|
273
|
+
* In the browser, this is typically a `File` or `Blob` object.
|
|
274
|
+
*/
|
|
275
|
+
content: File | Buffer | Blob;
|
|
276
|
+
/**
|
|
277
|
+
* The desired path for the file on the server, relative to the deployment root.
|
|
278
|
+
* Should include the filename, e.g., `images/photo.jpg`.
|
|
279
|
+
*/
|
|
280
|
+
path: string;
|
|
281
|
+
/**
|
|
282
|
+
* The original absolute file system path (primarily used in Node.js environments).
|
|
283
|
+
* This helps in debugging or associating the server path back to its source.
|
|
284
|
+
*/
|
|
285
|
+
filePath?: string;
|
|
286
|
+
/**
|
|
287
|
+
* The MD5 hash (checksum) of the file's content.
|
|
288
|
+
* This is calculated by the SDK before deploy if not provided.
|
|
289
|
+
*/
|
|
290
|
+
md5?: string;
|
|
291
|
+
/** The size of the file in bytes. */
|
|
292
|
+
size: number;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Standard platform configuration format used by all clients
|
|
296
|
+
*/
|
|
297
|
+
export interface PlatformConfig {
|
|
298
|
+
apiUrl?: string;
|
|
299
|
+
deployToken?: string;
|
|
300
|
+
apiKey?: string;
|
|
301
|
+
}
|
|
302
|
+
/** Default API URL if not otherwise configured. */
|
|
303
|
+
export declare const DEFAULT_API = "https://api.shipstatic.com";
|
|
304
|
+
/**
|
|
305
|
+
* Universal deploy input type for all environments.
|
|
306
|
+
* - File[] | FileList: Browser environments (file upload)
|
|
307
|
+
* - string: Node.js environments (file/directory path)
|
|
308
|
+
*/
|
|
309
|
+
export type DeployInput = File[] | FileList | string;
|
|
310
|
+
/**
|
|
311
|
+
* Deployment resource interface - the contract all implementations must follow
|
|
312
|
+
*/
|
|
313
|
+
export interface DeploymentResource {
|
|
314
|
+
create: (input: DeployInput, options?: any) => Promise<Deployment>;
|
|
315
|
+
list: () => Promise<DeploymentListResponse>;
|
|
316
|
+
remove: (id: string) => Promise<void>;
|
|
317
|
+
get: (id: string) => Promise<Deployment>;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Alias resource interface - the contract all implementations must follow
|
|
321
|
+
*/
|
|
322
|
+
export interface AliasResource {
|
|
323
|
+
set: (aliasName: string, deployment: string) => Promise<Alias>;
|
|
324
|
+
get: (aliasName: string) => Promise<Alias>;
|
|
325
|
+
list: () => Promise<AliasListResponse>;
|
|
326
|
+
remove: (aliasName: string) => Promise<void>;
|
|
327
|
+
check: (aliasName: string) => Promise<{
|
|
328
|
+
message: string;
|
|
329
|
+
}>;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Account resource interface - the contract all implementations must follow
|
|
333
|
+
*/
|
|
334
|
+
export interface AccountResource {
|
|
335
|
+
get: () => Promise<Account>;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Keys resource interface - the contract all implementations must follow
|
|
339
|
+
*/
|
|
340
|
+
export interface KeysResource {
|
|
341
|
+
create: () => Promise<{
|
|
342
|
+
apiKey: string;
|
|
343
|
+
}>;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Represents a file that has been uploaded and stored
|
|
347
|
+
*/
|
|
348
|
+
export interface UploadedFile {
|
|
349
|
+
key: string;
|
|
350
|
+
etag: string;
|
|
351
|
+
size: number;
|
|
352
|
+
validated?: boolean;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Upload/deployment status enum
|
|
356
|
+
*/
|
|
357
|
+
export declare enum UploadStatus {
|
|
358
|
+
PENDING = "pending",
|
|
359
|
+
SUCCESS = "success",
|
|
360
|
+
FAILED = "failed",
|
|
361
|
+
DELETING = "deleting"
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Rate limiting data structure
|
|
365
|
+
*/
|
|
366
|
+
export interface RateLimitData {
|
|
367
|
+
count: number;
|
|
368
|
+
timestamp: number;
|
|
255
369
|
}
|
|
370
|
+
/**
|
|
371
|
+
* Generate deployment URL from deployment ID and sites domain
|
|
372
|
+
*/
|
|
373
|
+
export declare function generateDeploymentUrl(deployment: string, sitesDomain?: string): string;
|
|
374
|
+
/**
|
|
375
|
+
* Generate alias URL based on whether it's internal (subdomain) or external (custom domain)
|
|
376
|
+
*/
|
|
377
|
+
export declare function generateAliasUrl(alias: string, sitesDomain?: string): string;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file Shared types for Shipstatic platform
|
|
3
|
-
*
|
|
2
|
+
* @file Shared TypeScript types, constants, and utilities for the Shipstatic platform.
|
|
3
|
+
* This package is the single source of truth for all shared data structures.
|
|
4
4
|
*/
|
|
5
5
|
// =============================================================================
|
|
6
6
|
// ERROR SYSTEM
|
|
@@ -230,3 +230,40 @@ export function validateSubdomain(input) {
|
|
|
230
230
|
// Deployment subdomain format: word-word-7chars (e.g. "happy-cat-abc1234")
|
|
231
231
|
return /^[a-z]+-[a-z]+-[a-z0-9]{7}$/i.test(input);
|
|
232
232
|
}
|
|
233
|
+
// =============================================================================
|
|
234
|
+
// PLATFORM CONSTANTS
|
|
235
|
+
// =============================================================================
|
|
236
|
+
/** Default API URL if not otherwise configured. */
|
|
237
|
+
export const DEFAULT_API = 'https://api.shipstatic.com';
|
|
238
|
+
/**
|
|
239
|
+
* Upload/deployment status enum
|
|
240
|
+
*/
|
|
241
|
+
export var UploadStatus;
|
|
242
|
+
(function (UploadStatus) {
|
|
243
|
+
UploadStatus["PENDING"] = "pending";
|
|
244
|
+
UploadStatus["SUCCESS"] = "success";
|
|
245
|
+
UploadStatus["FAILED"] = "failed";
|
|
246
|
+
UploadStatus["DELETING"] = "deleting";
|
|
247
|
+
})(UploadStatus || (UploadStatus = {}));
|
|
248
|
+
// =============================================================================
|
|
249
|
+
// URL GENERATION UTILITIES
|
|
250
|
+
// =============================================================================
|
|
251
|
+
/**
|
|
252
|
+
* Generate deployment URL from deployment ID and sites domain
|
|
253
|
+
*/
|
|
254
|
+
export function generateDeploymentUrl(deployment, sitesDomain) {
|
|
255
|
+
const domain = sitesDomain || 'statichost.com';
|
|
256
|
+
return `https://${deployment}.${domain}`;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Generate alias URL based on whether it's internal (subdomain) or external (custom domain)
|
|
260
|
+
*/
|
|
261
|
+
export function generateAliasUrl(alias, sitesDomain) {
|
|
262
|
+
// If alias contains dots, it's an external domain
|
|
263
|
+
if (alias.includes('.')) {
|
|
264
|
+
return `https://${alias}`;
|
|
265
|
+
}
|
|
266
|
+
// Otherwise it's an internal subdomain
|
|
267
|
+
const domain = sitesDomain || 'statichost.dev';
|
|
268
|
+
return `https://${alias}.${domain}`;
|
|
269
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipstatic/types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Shared types for Shipstatic platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"node": ">=20.0.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
+
"@types/node": "^24.3.0",
|
|
36
37
|
"typescript": "^5.8.3"
|
|
37
38
|
},
|
|
38
39
|
"scripts": {
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file Shared types for Shipstatic platform
|
|
3
|
-
*
|
|
2
|
+
* @file Shared TypeScript types, constants, and utilities for the Shipstatic platform.
|
|
3
|
+
* This package is the single source of truth for all shared data structures.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// =============================================================================
|
|
7
|
-
//
|
|
7
|
+
// I. CORE ENTITIES
|
|
8
8
|
// =============================================================================
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -18,7 +18,7 @@ export interface Deployment {
|
|
|
18
18
|
/** Total size of all files in bytes */
|
|
19
19
|
size: number;
|
|
20
20
|
/** Current deployment status */
|
|
21
|
-
status: 'pending' | 'success' | 'failed';
|
|
21
|
+
status: 'pending' | 'success' | 'failed' | 'deleting';
|
|
22
22
|
/** Whether deployment has configuration */
|
|
23
23
|
config?: boolean;
|
|
24
24
|
/** The deployment URL */
|
|
@@ -27,6 +27,8 @@ export interface Deployment {
|
|
|
27
27
|
created: number;
|
|
28
28
|
/** Unix timestamp (seconds) when deployment expires */
|
|
29
29
|
expires?: number;
|
|
30
|
+
/** Unix timestamp (seconds) when deployment was verified and ready */
|
|
31
|
+
verified?: number;
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
|
|
@@ -452,7 +454,7 @@ export function validateSubdomain(input: string): boolean {
|
|
|
452
454
|
export interface SPACheckRequest {
|
|
453
455
|
/** Array of file paths */
|
|
454
456
|
files: string[];
|
|
455
|
-
/**
|
|
457
|
+
/** HTML content of index.html file */
|
|
456
458
|
index: string;
|
|
457
459
|
}
|
|
458
460
|
|
|
@@ -462,4 +464,169 @@ export interface SPACheckRequest {
|
|
|
462
464
|
export interface SPACheckResponse {
|
|
463
465
|
/** Whether the project is detected as a Single Page Application */
|
|
464
466
|
isSPA: boolean;
|
|
467
|
+
/** Debugging information about detection */
|
|
468
|
+
debug: {
|
|
469
|
+
/** Which tier made the detection: 'exclusions', 'inclusions', 'scoring', 'ai', or 'fallback' */
|
|
470
|
+
tier: 'exclusions' | 'inclusions' | 'scoring' | 'ai' | 'fallback';
|
|
471
|
+
/** The reason for the detection result */
|
|
472
|
+
reason: string;
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// =============================================================================
|
|
477
|
+
// STATIC FILE REPRESENTATION
|
|
478
|
+
// =============================================================================
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Represents a file that has been processed and is ready for deploy.
|
|
482
|
+
* Used across the platform (API, SDK, CLI) for file operations.
|
|
483
|
+
*/
|
|
484
|
+
export interface StaticFile {
|
|
485
|
+
/**
|
|
486
|
+
* The content of the file.
|
|
487
|
+
* In Node.js, this is typically a `Buffer`.
|
|
488
|
+
* In the browser, this is typically a `File` or `Blob` object.
|
|
489
|
+
*/
|
|
490
|
+
content: File | Buffer | Blob;
|
|
491
|
+
/**
|
|
492
|
+
* The desired path for the file on the server, relative to the deployment root.
|
|
493
|
+
* Should include the filename, e.g., `images/photo.jpg`.
|
|
494
|
+
*/
|
|
495
|
+
path: string;
|
|
496
|
+
/**
|
|
497
|
+
* The original absolute file system path (primarily used in Node.js environments).
|
|
498
|
+
* This helps in debugging or associating the server path back to its source.
|
|
499
|
+
*/
|
|
500
|
+
filePath?: string;
|
|
501
|
+
/**
|
|
502
|
+
* The MD5 hash (checksum) of the file's content.
|
|
503
|
+
* This is calculated by the SDK before deploy if not provided.
|
|
504
|
+
*/
|
|
505
|
+
md5?: string;
|
|
506
|
+
/** The size of the file in bytes. */
|
|
507
|
+
size: number;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// =============================================================================
|
|
511
|
+
// PLATFORM CONFIGURATION
|
|
512
|
+
// =============================================================================
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Standard platform configuration format used by all clients
|
|
516
|
+
*/
|
|
517
|
+
export interface PlatformConfig {
|
|
518
|
+
apiUrl?: string;
|
|
519
|
+
deployToken?: string;
|
|
520
|
+
apiKey?: string;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// =============================================================================
|
|
524
|
+
// PLATFORM CONSTANTS
|
|
525
|
+
// =============================================================================
|
|
526
|
+
|
|
527
|
+
/** Default API URL if not otherwise configured. */
|
|
528
|
+
export const DEFAULT_API = 'https://api.shipstatic.com';
|
|
529
|
+
|
|
530
|
+
// =============================================================================
|
|
531
|
+
// RESOURCE INTERFACE CONTRACTS
|
|
532
|
+
// =============================================================================
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Universal deploy input type for all environments.
|
|
536
|
+
* - File[] | FileList: Browser environments (file upload)
|
|
537
|
+
* - string: Node.js environments (file/directory path)
|
|
538
|
+
*/
|
|
539
|
+
export type DeployInput = File[] | FileList | string;
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Deployment resource interface - the contract all implementations must follow
|
|
543
|
+
*/
|
|
544
|
+
export interface DeploymentResource {
|
|
545
|
+
create: (input: DeployInput, options?: any) => Promise<Deployment>;
|
|
546
|
+
list: () => Promise<DeploymentListResponse>;
|
|
547
|
+
remove: (id: string) => Promise<void>;
|
|
548
|
+
get: (id: string) => Promise<Deployment>;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Alias resource interface - the contract all implementations must follow
|
|
553
|
+
*/
|
|
554
|
+
export interface AliasResource {
|
|
555
|
+
set: (aliasName: string, deployment: string) => Promise<Alias>;
|
|
556
|
+
get: (aliasName: string) => Promise<Alias>;
|
|
557
|
+
list: () => Promise<AliasListResponse>;
|
|
558
|
+
remove: (aliasName: string) => Promise<void>;
|
|
559
|
+
check: (aliasName: string) => Promise<{ message: string }>;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Account resource interface - the contract all implementations must follow
|
|
564
|
+
*/
|
|
565
|
+
export interface AccountResource {
|
|
566
|
+
get: () => Promise<Account>;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* Keys resource interface - the contract all implementations must follow
|
|
571
|
+
*/
|
|
572
|
+
export interface KeysResource {
|
|
573
|
+
create: () => Promise<{ apiKey: string }>;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// =============================================================================
|
|
577
|
+
// FILE UPLOAD TYPES
|
|
578
|
+
// =============================================================================
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Represents a file that has been uploaded and stored
|
|
582
|
+
*/
|
|
583
|
+
export interface UploadedFile {
|
|
584
|
+
key: string;
|
|
585
|
+
etag: string;
|
|
586
|
+
size: number;
|
|
587
|
+
validated?: boolean;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* Upload/deployment status enum
|
|
592
|
+
*/
|
|
593
|
+
export enum UploadStatus {
|
|
594
|
+
PENDING = 'pending',
|
|
595
|
+
SUCCESS = 'success',
|
|
596
|
+
FAILED = 'failed',
|
|
597
|
+
DELETING = 'deleting'
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Rate limiting data structure
|
|
602
|
+
*/
|
|
603
|
+
export interface RateLimitData {
|
|
604
|
+
count: number;
|
|
605
|
+
timestamp: number;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// =============================================================================
|
|
609
|
+
// URL GENERATION UTILITIES
|
|
610
|
+
// =============================================================================
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Generate deployment URL from deployment ID and sites domain
|
|
614
|
+
*/
|
|
615
|
+
export function generateDeploymentUrl(deployment: string, sitesDomain?: string): string {
|
|
616
|
+
const domain = sitesDomain || 'statichost.com';
|
|
617
|
+
return `https://${deployment}.${domain}`;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Generate alias URL based on whether it's internal (subdomain) or external (custom domain)
|
|
622
|
+
*/
|
|
623
|
+
export function generateAliasUrl(alias: string, sitesDomain?: string): string {
|
|
624
|
+
// If alias contains dots, it's an external domain
|
|
625
|
+
if (alias.includes('.')) {
|
|
626
|
+
return `https://${alias}`;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// Otherwise it's an internal subdomain
|
|
630
|
+
const domain = sitesDomain || 'statichost.dev';
|
|
631
|
+
return `https://${alias}.${domain}`;
|
|
465
632
|
}
|