@shipstatic/types 0.1.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/LICENSE +21 -0
- package/README.md +275 -0
- package/dist/index.d.ts +209 -0
- package/dist/index.js +152 -0
- package/package.json +32 -0
- package/src/index.ts +347 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 shipstatic
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# Shipstatic Types
|
|
2
|
+
|
|
3
|
+
Shared TypeScript types and constants for the Shipstatic platform. This package provides a single source of truth for types, errors, and configuration across the Shipstatic ecosystem.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package contains all shared types used between:
|
|
8
|
+
- **Shipstatic API** (`/cloudflare/api`) - Backend API on Cloudflare Workers
|
|
9
|
+
- **Shipstatic SDK** (`/ship`) - Universal SDK for Node.js and Browser
|
|
10
|
+
- **Shipstatic CLI** - Command-line interface
|
|
11
|
+
|
|
12
|
+
## Core Types
|
|
13
|
+
|
|
14
|
+
### Deployment Types
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
// Core deployment object
|
|
18
|
+
interface Deployment {
|
|
19
|
+
deployment: string; // Deployment ID
|
|
20
|
+
filesCount: number; // Number of files
|
|
21
|
+
totalSize: number; // Total size in bytes
|
|
22
|
+
status: 'pending' | 'success' | 'failed';
|
|
23
|
+
createdAt: number; // Unix timestamp
|
|
24
|
+
expiresAt?: number; // Unix timestamp
|
|
25
|
+
verifiedAt?: number; // Unix timestamp
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Successful deployment response
|
|
29
|
+
interface DeploySuccessResponse {
|
|
30
|
+
success: true;
|
|
31
|
+
deployment: string;
|
|
32
|
+
expiresAt: number;
|
|
33
|
+
filesCount: number;
|
|
34
|
+
totalSize: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Deployment list response
|
|
38
|
+
interface DeploymentListResponse {
|
|
39
|
+
deployments: Deployment[];
|
|
40
|
+
cursor?: string;
|
|
41
|
+
total?: number;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Alias Types
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// Core alias object
|
|
49
|
+
interface Alias {
|
|
50
|
+
alias: string; // Alias name
|
|
51
|
+
deploymentName: string; // Target deployment name
|
|
52
|
+
status: 'pending' | 'success' | 'failed';
|
|
53
|
+
createdAt: number; // Unix timestamp
|
|
54
|
+
confirmedAt?: number; // Unix timestamp
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Alias list response
|
|
58
|
+
interface AliasListResponse {
|
|
59
|
+
aliases: Alias[];
|
|
60
|
+
cursor?: string;
|
|
61
|
+
total?: number;
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Account Types
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
// Core account object
|
|
69
|
+
interface Account {
|
|
70
|
+
email: string;
|
|
71
|
+
name: string;
|
|
72
|
+
picture?: string;
|
|
73
|
+
subscription: 'free' | 'active' | 'suspended';
|
|
74
|
+
createdAt: number; // Unix timestamp
|
|
75
|
+
subscribedAt?: number; // Unix timestamp
|
|
76
|
+
suspendedAt?: number; // Unix timestamp
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Platform Configuration
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// Dynamic platform configuration from API
|
|
84
|
+
interface ConfigResponse {
|
|
85
|
+
maxFileSize: number; // Maximum file size in bytes
|
|
86
|
+
maxFilesCount: number; // Maximum files per deployment
|
|
87
|
+
maxTotalSize: number; // Maximum total deployment size
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Error System
|
|
92
|
+
|
|
93
|
+
### Unified Error Handling
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
// All possible error types
|
|
97
|
+
enum ErrorType {
|
|
98
|
+
Validation = "validation_failed",
|
|
99
|
+
NotFound = "not_found",
|
|
100
|
+
RateLimit = "rate_limit_exceeded",
|
|
101
|
+
Authentication = "authentication_failed",
|
|
102
|
+
Business = "business_logic_error",
|
|
103
|
+
Api = "internal_server_error",
|
|
104
|
+
Network = "network_error",
|
|
105
|
+
Cancelled = "operation_cancelled",
|
|
106
|
+
File = "file_error",
|
|
107
|
+
Config = "config_error"
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Standard error response format
|
|
111
|
+
interface ErrorResponse {
|
|
112
|
+
error: ErrorType;
|
|
113
|
+
message: string;
|
|
114
|
+
status?: number;
|
|
115
|
+
details?: any;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Unified error class for both API and SDK
|
|
119
|
+
class ShipError extends Error {
|
|
120
|
+
constructor(
|
|
121
|
+
public readonly type: ErrorType,
|
|
122
|
+
message: string,
|
|
123
|
+
public readonly status?: number,
|
|
124
|
+
public readonly details?: any
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
// Factory methods
|
|
128
|
+
static validation(message: string, details?: any): ShipError;
|
|
129
|
+
static notFound(resource: string, id?: string): ShipError;
|
|
130
|
+
static authentication(message?: string): ShipError;
|
|
131
|
+
static client(message: string, details?: any): ShipError;
|
|
132
|
+
|
|
133
|
+
// Helper methods
|
|
134
|
+
isClientError(): boolean;
|
|
135
|
+
isNetworkError(): boolean;
|
|
136
|
+
isAuthError(): boolean;
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Platform Configuration
|
|
141
|
+
|
|
142
|
+
### Shared Constants
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// Server-side platform configuration
|
|
146
|
+
export const serverConfig = {
|
|
147
|
+
/** Maximum individual file size in bytes (10MB) */
|
|
148
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
149
|
+
/** Maximum number of files per deployment */
|
|
150
|
+
maxFilesCount: 1000,
|
|
151
|
+
/** Maximum total deployment size in bytes (100MB) */
|
|
152
|
+
maxTotalSize: 100 * 1024 * 1024,
|
|
153
|
+
/** Deployment expiry in hours */
|
|
154
|
+
deploymentExpiryHours: 168, // 7 days
|
|
155
|
+
/** Pagination limits */
|
|
156
|
+
defaultLimit: 50,
|
|
157
|
+
maxLimit: 100,
|
|
158
|
+
} as const;
|
|
159
|
+
|
|
160
|
+
// Client-side configuration - conservative defaults for SDK/CLI
|
|
161
|
+
export const clientConfig = {
|
|
162
|
+
/** Conservative file size limit for client validation (5MB) */
|
|
163
|
+
maxFileSize: 5 * 1024 * 1024,
|
|
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;
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Dynamic Configuration
|
|
172
|
+
|
|
173
|
+
The platform provides dynamic configuration through the API's `/config` endpoint:
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"maxFileSize": 10485760, // 10MB
|
|
178
|
+
"maxFilesCount": 1000, // Files per deployment
|
|
179
|
+
"maxTotalSize": 104857600 // 100MB total
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Benefits:**
|
|
184
|
+
- **Single source of truth** - Configuration defined once in `serverConfig`
|
|
185
|
+
- **Dynamic updates** - API can adjust limits without code changes
|
|
186
|
+
- **SDK synchronization** - SDK automatically fetches current limits
|
|
187
|
+
- **Type safety** - Shared `ConfigResponse` interface ensures consistency
|
|
188
|
+
|
|
189
|
+
## Usage
|
|
190
|
+
|
|
191
|
+
### In Ship API
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
import { serverConfig, ShipError, type ConfigResponse } from '@shipstatic/types';
|
|
195
|
+
|
|
196
|
+
// Use shared configuration constants
|
|
197
|
+
const config: ConfigResponse = {
|
|
198
|
+
maxFileSize: serverConfig.maxFileSize,
|
|
199
|
+
maxFilesCount: serverConfig.maxFilesCount,
|
|
200
|
+
maxTotalSize: serverConfig.maxTotalSize,
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
// Use unified error handling
|
|
204
|
+
throw ShipError.validation('File too large', { maxSize: serverConfig.maxFileSize });
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### In Ship SDK
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
import { ShipError, type ConfigResponse, type DeploySuccessResponse } from '@shipstatic/types';
|
|
211
|
+
|
|
212
|
+
// Receive platform configuration
|
|
213
|
+
const config: ConfigResponse = await api.getConfig();
|
|
214
|
+
|
|
215
|
+
// Handle errors consistently
|
|
216
|
+
try {
|
|
217
|
+
const result: DeploySuccessResponse = await deploy(files);
|
|
218
|
+
} catch (error) {
|
|
219
|
+
if (error instanceof ShipError) {
|
|
220
|
+
// Handle Ship-specific errors
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Installation
|
|
226
|
+
|
|
227
|
+
This package is automatically installed as a dependency of the Ship SDK and API:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# Direct installation (if needed)
|
|
231
|
+
npm install @shipstatic/types
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Architecture
|
|
235
|
+
|
|
236
|
+
### Design Principles
|
|
237
|
+
|
|
238
|
+
- **Single source of truth** - All types defined once, used everywhere
|
|
239
|
+
- **Type safety** - Strict TypeScript with no `any` types
|
|
240
|
+
- **Wire format compatibility** - Types match API request/response formats
|
|
241
|
+
- **Error consistency** - Unified error handling across all components
|
|
242
|
+
- **Configuration sharing** - Shared constants prevent drift
|
|
243
|
+
|
|
244
|
+
### Package Structure
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
/types/src/
|
|
248
|
+
└── index.ts # All types and exports in single file
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Type Organization
|
|
252
|
+
|
|
253
|
+
All types are organized in a single `index.ts` file by category:
|
|
254
|
+
|
|
255
|
+
- **Core entities** - Deployment, Alias, Account objects
|
|
256
|
+
- **API responses** - Success/error response wrappers
|
|
257
|
+
- **Configuration** - `serverConfig` and `clientConfig` with platform limits
|
|
258
|
+
- **Error system** - Unified `ShipError` class with factory methods
|
|
259
|
+
- **Common patterns** - Shared response formats and interfaces
|
|
260
|
+
|
|
261
|
+
## Philosophy
|
|
262
|
+
|
|
263
|
+
This package follows the **"Impossible Simplicity"** principle:
|
|
264
|
+
|
|
265
|
+
- **Do more with less** - Maximum type safety with minimal complexity
|
|
266
|
+
- **Single source of truth** - Types defined once, used everywhere
|
|
267
|
+
- **Wire format compatibility** - Types match actual API contracts
|
|
268
|
+
- **Developer experience** - Clear, predictable type interfaces
|
|
269
|
+
- **Maintainability** - Easy to update types across entire platform
|
|
270
|
+
|
|
271
|
+
**Result:** Type-safe development across the entire Ship platform with zero type drift between components.
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
**Ship Types** - Shared types for the Ship platform 🚢
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Shared types for Shipstatic platform
|
|
3
|
+
* Simple, clean types that both API and SDK agree on
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Core deployment object - used in both API responses and SDK
|
|
7
|
+
*/
|
|
8
|
+
export interface Deployment {
|
|
9
|
+
/** The deployment ID */
|
|
10
|
+
deployment: string;
|
|
11
|
+
/** Number of files in this deployment */
|
|
12
|
+
filesCount: number;
|
|
13
|
+
/** Total size of all files in bytes */
|
|
14
|
+
totalSize: number;
|
|
15
|
+
/** Current deployment status */
|
|
16
|
+
status: 'pending' | 'success' | 'failed';
|
|
17
|
+
/** Unix timestamp (seconds) when deployment was created */
|
|
18
|
+
createdAt: number;
|
|
19
|
+
/** Unix timestamp (seconds) when deployment expires */
|
|
20
|
+
expiresAt?: number;
|
|
21
|
+
/** Unix timestamp (seconds) when deployment was verified */
|
|
22
|
+
verifiedAt?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Response for listing deployments
|
|
26
|
+
*/
|
|
27
|
+
export interface DeploymentListResponse {
|
|
28
|
+
/** Array of deployments */
|
|
29
|
+
deployments: Deployment[];
|
|
30
|
+
/** Optional cursor for pagination */
|
|
31
|
+
cursor?: string;
|
|
32
|
+
/** Total number of deployments if available */
|
|
33
|
+
total?: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Core alias object - used in both API responses and SDK
|
|
37
|
+
*/
|
|
38
|
+
export interface Alias {
|
|
39
|
+
/** The alias name */
|
|
40
|
+
alias: string;
|
|
41
|
+
/** The deployment name this alias points to */
|
|
42
|
+
deploymentName: string;
|
|
43
|
+
/** Current alias status */
|
|
44
|
+
status: 'pending' | 'success' | 'failed';
|
|
45
|
+
/** Unix timestamp (seconds) when alias was created */
|
|
46
|
+
createdAt: number;
|
|
47
|
+
/** Unix timestamp (seconds) when alias was confirmed */
|
|
48
|
+
confirmedAt?: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Response for listing aliases
|
|
52
|
+
*/
|
|
53
|
+
export interface AliasListResponse {
|
|
54
|
+
/** Array of aliases */
|
|
55
|
+
aliases: Alias[];
|
|
56
|
+
/** Optional cursor for pagination */
|
|
57
|
+
cursor?: string;
|
|
58
|
+
/** Total number of aliases if available */
|
|
59
|
+
total?: number;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Response for deployment removal
|
|
63
|
+
*/
|
|
64
|
+
export interface DeploymentRemoveResponse {
|
|
65
|
+
/** Operation success status */
|
|
66
|
+
success: boolean;
|
|
67
|
+
/** The deployment ID */
|
|
68
|
+
deployment: string;
|
|
69
|
+
/** Human-readable message */
|
|
70
|
+
message?: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Core account object - used in both API responses and SDK
|
|
74
|
+
*/
|
|
75
|
+
export interface Account {
|
|
76
|
+
/** User email address */
|
|
77
|
+
email: string;
|
|
78
|
+
/** User display name */
|
|
79
|
+
name: string;
|
|
80
|
+
/** User profile picture URL */
|
|
81
|
+
picture?: string;
|
|
82
|
+
/** Account subscription status */
|
|
83
|
+
subscription: 'free' | 'active' | 'suspended';
|
|
84
|
+
/** Unix timestamp (seconds) when account was created */
|
|
85
|
+
createdAt: number;
|
|
86
|
+
/** Unix timestamp (seconds) when subscription started */
|
|
87
|
+
subscribedAt?: number;
|
|
88
|
+
/** Unix timestamp (seconds) when account was suspended */
|
|
89
|
+
suspendedAt?: number;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* All possible error types in the Shipstatic platform
|
|
93
|
+
* Names are developer-friendly while wire format stays consistent
|
|
94
|
+
*/
|
|
95
|
+
export declare enum ErrorType {
|
|
96
|
+
/** Validation failed (400) */
|
|
97
|
+
Validation = "validation_failed",
|
|
98
|
+
/** Resource not found (404) */
|
|
99
|
+
NotFound = "not_found",
|
|
100
|
+
/** Rate limit exceeded (429) */
|
|
101
|
+
RateLimit = "rate_limit_exceeded",
|
|
102
|
+
/** Authentication required (401) */
|
|
103
|
+
Authentication = "authentication_failed",
|
|
104
|
+
/** Business logic error (400) */
|
|
105
|
+
Business = "business_logic_error",
|
|
106
|
+
/** API server error (500) - renamed from Internal for clarity */
|
|
107
|
+
Api = "internal_server_error",
|
|
108
|
+
/** Network/connection error */
|
|
109
|
+
Network = "network_error",
|
|
110
|
+
/** Operation was cancelled */
|
|
111
|
+
Cancelled = "operation_cancelled",
|
|
112
|
+
/** File operation error */
|
|
113
|
+
File = "file_error",
|
|
114
|
+
/** Configuration error */
|
|
115
|
+
Config = "config_error"
|
|
116
|
+
}
|
|
117
|
+
/** @deprecated Use ErrorType instead. Kept for backward compatibility. */
|
|
118
|
+
export declare const ShipErrorType: typeof ErrorType;
|
|
119
|
+
/**
|
|
120
|
+
* Standard error response format used everywhere
|
|
121
|
+
*/
|
|
122
|
+
export interface ErrorResponse {
|
|
123
|
+
/** Error type identifier */
|
|
124
|
+
error: ErrorType;
|
|
125
|
+
/** Human-readable error message */
|
|
126
|
+
message: string;
|
|
127
|
+
/** HTTP status code (API contexts) */
|
|
128
|
+
status?: number;
|
|
129
|
+
/** Optional additional error details */
|
|
130
|
+
details?: any;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Simple unified error class for both API and SDK
|
|
134
|
+
*/
|
|
135
|
+
export declare class ShipError extends Error {
|
|
136
|
+
readonly type: ErrorType;
|
|
137
|
+
readonly status?: number | undefined;
|
|
138
|
+
readonly details?: any | undefined;
|
|
139
|
+
constructor(type: ErrorType, message: string, status?: number | undefined, details?: any | undefined);
|
|
140
|
+
/** Convert to wire format */
|
|
141
|
+
toResponse(): ErrorResponse;
|
|
142
|
+
/** Create from wire format */
|
|
143
|
+
static fromResponse(response: ErrorResponse): ShipError;
|
|
144
|
+
static validation(message: string, details?: any): ShipError;
|
|
145
|
+
static notFound(resource: string, id?: string): ShipError;
|
|
146
|
+
static rateLimit(message?: string): ShipError;
|
|
147
|
+
static authentication(message?: string): ShipError;
|
|
148
|
+
static business(message: string, status?: number): ShipError;
|
|
149
|
+
static network(message: string, cause?: Error): ShipError;
|
|
150
|
+
static cancelled(message: string): ShipError;
|
|
151
|
+
static file(message: string, filePath?: string): ShipError;
|
|
152
|
+
static config(message: string, details?: any): ShipError;
|
|
153
|
+
static api(message: string, status?: number, code?: string, data?: any): ShipError;
|
|
154
|
+
get filePath(): string | undefined;
|
|
155
|
+
get code(): string | undefined;
|
|
156
|
+
isClientError(): boolean;
|
|
157
|
+
isNetworkError(): boolean;
|
|
158
|
+
isAuthError(): boolean;
|
|
159
|
+
isValidationError(): boolean;
|
|
160
|
+
isFileError(): boolean;
|
|
161
|
+
isConfigError(): boolean;
|
|
162
|
+
isType(errorType: ErrorType): boolean;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Server-side platform configuration - enforced limits on the platform
|
|
166
|
+
*/
|
|
167
|
+
export declare const serverConfig: {
|
|
168
|
+
/** Maximum individual file size in bytes (10MB) */
|
|
169
|
+
readonly maxFileSize: number;
|
|
170
|
+
/** Maximum number of files per deployment */
|
|
171
|
+
readonly maxFilesCount: 1000;
|
|
172
|
+
/** Maximum total deployment size in bytes (100MB) */
|
|
173
|
+
readonly maxTotalSize: number;
|
|
174
|
+
/** Deployment expiry in hours */
|
|
175
|
+
readonly deploymentExpiryHours: 168;
|
|
176
|
+
/** Pagination limits */
|
|
177
|
+
readonly defaultLimit: 50;
|
|
178
|
+
readonly maxLimit: 100;
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
* Platform configuration response from API
|
|
182
|
+
*/
|
|
183
|
+
export interface ConfigResponse {
|
|
184
|
+
/** Maximum individual file size in bytes */
|
|
185
|
+
maxFileSize: number;
|
|
186
|
+
/** Maximum number of files per deployment */
|
|
187
|
+
maxFilesCount: number;
|
|
188
|
+
/** Maximum total deployment size in bytes */
|
|
189
|
+
maxTotalSize: number;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Generic success response wrapper
|
|
193
|
+
*/
|
|
194
|
+
export interface SuccessResponse<T = any> {
|
|
195
|
+
/** Always true for success */
|
|
196
|
+
success: true;
|
|
197
|
+
/** Response data */
|
|
198
|
+
data: T;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Simple ping response for health checks
|
|
202
|
+
*/
|
|
203
|
+
export interface PingResponse {
|
|
204
|
+
/** Always true if service is healthy */
|
|
205
|
+
success: boolean;
|
|
206
|
+
/** Optional timestamp */
|
|
207
|
+
timestamp?: number;
|
|
208
|
+
}
|
|
209
|
+
export declare const API_KEY_PREFIX = "ship-";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// ERROR SYSTEM
|
|
4
|
+
// =============================================================================
|
|
5
|
+
/**
|
|
6
|
+
* All possible error types in the Shipstatic platform
|
|
7
|
+
* Names are developer-friendly while wire format stays consistent
|
|
8
|
+
*/
|
|
9
|
+
export var ErrorType;
|
|
10
|
+
(function (ErrorType) {
|
|
11
|
+
/** Validation failed (400) */
|
|
12
|
+
ErrorType["Validation"] = "validation_failed";
|
|
13
|
+
/** Resource not found (404) */
|
|
14
|
+
ErrorType["NotFound"] = "not_found";
|
|
15
|
+
/** Rate limit exceeded (429) */
|
|
16
|
+
ErrorType["RateLimit"] = "rate_limit_exceeded";
|
|
17
|
+
/** Authentication required (401) */
|
|
18
|
+
ErrorType["Authentication"] = "authentication_failed";
|
|
19
|
+
/** Business logic error (400) */
|
|
20
|
+
ErrorType["Business"] = "business_logic_error";
|
|
21
|
+
/** API server error (500) - renamed from Internal for clarity */
|
|
22
|
+
ErrorType["Api"] = "internal_server_error";
|
|
23
|
+
/** Network/connection error */
|
|
24
|
+
ErrorType["Network"] = "network_error";
|
|
25
|
+
/** Operation was cancelled */
|
|
26
|
+
ErrorType["Cancelled"] = "operation_cancelled";
|
|
27
|
+
/** File operation error */
|
|
28
|
+
ErrorType["File"] = "file_error";
|
|
29
|
+
/** Configuration error */
|
|
30
|
+
ErrorType["Config"] = "config_error";
|
|
31
|
+
})(ErrorType || (ErrorType = {}));
|
|
32
|
+
/** @deprecated Use ErrorType instead. Kept for backward compatibility. */
|
|
33
|
+
export const ShipErrorType = ErrorType;
|
|
34
|
+
/**
|
|
35
|
+
* Categorizes error types for better type checking
|
|
36
|
+
*/
|
|
37
|
+
const ERROR_CATEGORIES = {
|
|
38
|
+
client: new Set([ErrorType.Business, ErrorType.Config, ErrorType.File, ErrorType.Validation]),
|
|
39
|
+
network: new Set([ErrorType.Network]),
|
|
40
|
+
auth: new Set([ErrorType.Authentication]),
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Simple unified error class for both API and SDK
|
|
44
|
+
*/
|
|
45
|
+
export class ShipError extends Error {
|
|
46
|
+
type;
|
|
47
|
+
status;
|
|
48
|
+
details;
|
|
49
|
+
constructor(type, message, status, details) {
|
|
50
|
+
super(message);
|
|
51
|
+
this.type = type;
|
|
52
|
+
this.status = status;
|
|
53
|
+
this.details = details;
|
|
54
|
+
this.name = 'ShipError';
|
|
55
|
+
}
|
|
56
|
+
/** Convert to wire format */
|
|
57
|
+
toResponse() {
|
|
58
|
+
return {
|
|
59
|
+
error: this.type,
|
|
60
|
+
message: this.message,
|
|
61
|
+
status: this.status,
|
|
62
|
+
details: this.details
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/** Create from wire format */
|
|
66
|
+
static fromResponse(response) {
|
|
67
|
+
return new ShipError(response.error, response.message, response.status, response.details);
|
|
68
|
+
}
|
|
69
|
+
// Factory methods for common errors
|
|
70
|
+
static validation(message, details) {
|
|
71
|
+
return new ShipError(ErrorType.Validation, message, 400, details);
|
|
72
|
+
}
|
|
73
|
+
static notFound(resource, id) {
|
|
74
|
+
const message = id ? `${resource} ${id} not found` : `${resource} not found`;
|
|
75
|
+
return new ShipError(ErrorType.NotFound, message, 404);
|
|
76
|
+
}
|
|
77
|
+
static rateLimit(message = "Too many requests") {
|
|
78
|
+
return new ShipError(ErrorType.RateLimit, message, 429);
|
|
79
|
+
}
|
|
80
|
+
static authentication(message = "Authentication required") {
|
|
81
|
+
return new ShipError(ErrorType.Authentication, message, 401);
|
|
82
|
+
}
|
|
83
|
+
static business(message, status = 400) {
|
|
84
|
+
return new ShipError(ErrorType.Business, message, status);
|
|
85
|
+
}
|
|
86
|
+
static network(message, cause) {
|
|
87
|
+
return new ShipError(ErrorType.Network, message, undefined, { cause });
|
|
88
|
+
}
|
|
89
|
+
static cancelled(message) {
|
|
90
|
+
return new ShipError(ErrorType.Cancelled, message);
|
|
91
|
+
}
|
|
92
|
+
static file(message, filePath) {
|
|
93
|
+
return new ShipError(ErrorType.File, message, undefined, { filePath });
|
|
94
|
+
}
|
|
95
|
+
static config(message, details) {
|
|
96
|
+
return new ShipError(ErrorType.Config, message, undefined, details);
|
|
97
|
+
}
|
|
98
|
+
static api(message, status = 500, code, data) {
|
|
99
|
+
return new ShipError(ErrorType.Api, message, status, { code, data });
|
|
100
|
+
}
|
|
101
|
+
// Helper getters for accessing common detail properties
|
|
102
|
+
get filePath() {
|
|
103
|
+
return this.details?.filePath;
|
|
104
|
+
}
|
|
105
|
+
get code() {
|
|
106
|
+
return this.details?.code;
|
|
107
|
+
}
|
|
108
|
+
// Helper methods for error type checking using categorization
|
|
109
|
+
isClientError() {
|
|
110
|
+
return ERROR_CATEGORIES.client.has(this.type);
|
|
111
|
+
}
|
|
112
|
+
isNetworkError() {
|
|
113
|
+
return ERROR_CATEGORIES.network.has(this.type);
|
|
114
|
+
}
|
|
115
|
+
isAuthError() {
|
|
116
|
+
return ERROR_CATEGORIES.auth.has(this.type);
|
|
117
|
+
}
|
|
118
|
+
isValidationError() {
|
|
119
|
+
return this.type === ErrorType.Validation;
|
|
120
|
+
}
|
|
121
|
+
isFileError() {
|
|
122
|
+
return this.type === ErrorType.File;
|
|
123
|
+
}
|
|
124
|
+
isConfigError() {
|
|
125
|
+
return this.type === ErrorType.Config;
|
|
126
|
+
}
|
|
127
|
+
// Generic type checker
|
|
128
|
+
isType(errorType) {
|
|
129
|
+
return this.type === errorType;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// =============================================================================
|
|
133
|
+
// CONFIGURATION CONSTANTS
|
|
134
|
+
// =============================================================================
|
|
135
|
+
/**
|
|
136
|
+
* Server-side platform configuration - enforced limits on the platform
|
|
137
|
+
*/
|
|
138
|
+
export const serverConfig = {
|
|
139
|
+
/** Maximum individual file size in bytes (10MB) */
|
|
140
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
141
|
+
/** Maximum number of files per deployment */
|
|
142
|
+
maxFilesCount: 1000,
|
|
143
|
+
/** Maximum total deployment size in bytes (100MB) */
|
|
144
|
+
maxTotalSize: 100 * 1024 * 1024,
|
|
145
|
+
/** Deployment expiry in hours */
|
|
146
|
+
deploymentExpiryHours: 168, // 7 days
|
|
147
|
+
/** Pagination limits */
|
|
148
|
+
defaultLimit: 50,
|
|
149
|
+
maxLimit: 100,
|
|
150
|
+
};
|
|
151
|
+
// API Key Configuration
|
|
152
|
+
export const API_KEY_PREFIX = 'ship-';
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shipstatic/types",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Shared types for Shipstatic platform",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"src"
|
|
17
|
+
],
|
|
18
|
+
"keywords": [
|
|
19
|
+
"types",
|
|
20
|
+
"shipstatic"
|
|
21
|
+
],
|
|
22
|
+
"author": "ShipStatic",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"typescript": "^5.8.3",
|
|
26
|
+
"@cloudflare/workers-types": "^4.20241218.0"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsc",
|
|
30
|
+
"clean": "rm -rf dist"
|
|
31
|
+
}
|
|
32
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Shared types for Shipstatic platform
|
|
5
|
+
* Simple, clean types that both API and SDK agree on
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// DEPLOYMENT TYPES
|
|
10
|
+
// =============================================================================
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Core deployment object - used in both API responses and SDK
|
|
14
|
+
*/
|
|
15
|
+
export interface Deployment {
|
|
16
|
+
/** The deployment ID */
|
|
17
|
+
deployment: string;
|
|
18
|
+
/** Number of files in this deployment */
|
|
19
|
+
filesCount: number;
|
|
20
|
+
/** Total size of all files in bytes */
|
|
21
|
+
totalSize: number;
|
|
22
|
+
/** Current deployment status */
|
|
23
|
+
status: 'pending' | 'success' | 'failed';
|
|
24
|
+
/** Unix timestamp (seconds) when deployment was created */
|
|
25
|
+
createdAt: number;
|
|
26
|
+
/** Unix timestamp (seconds) when deployment expires */
|
|
27
|
+
expiresAt?: number;
|
|
28
|
+
/** Unix timestamp (seconds) when deployment was verified */
|
|
29
|
+
verifiedAt?: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Response for listing deployments
|
|
35
|
+
*/
|
|
36
|
+
export interface DeploymentListResponse {
|
|
37
|
+
/** Array of deployments */
|
|
38
|
+
deployments: Deployment[];
|
|
39
|
+
/** Optional cursor for pagination */
|
|
40
|
+
cursor?: string;
|
|
41
|
+
/** Total number of deployments if available */
|
|
42
|
+
total?: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// =============================================================================
|
|
46
|
+
// ALIAS TYPES
|
|
47
|
+
// =============================================================================
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Core alias object - used in both API responses and SDK
|
|
51
|
+
*/
|
|
52
|
+
export interface Alias {
|
|
53
|
+
/** The alias name */
|
|
54
|
+
alias: string;
|
|
55
|
+
/** The deployment name this alias points to */
|
|
56
|
+
deploymentName: string;
|
|
57
|
+
/** Current alias status */
|
|
58
|
+
status: 'pending' | 'success' | 'failed';
|
|
59
|
+
/** Unix timestamp (seconds) when alias was created */
|
|
60
|
+
createdAt: number;
|
|
61
|
+
/** Unix timestamp (seconds) when alias was confirmed */
|
|
62
|
+
confirmedAt?: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Response for listing aliases
|
|
67
|
+
*/
|
|
68
|
+
export interface AliasListResponse {
|
|
69
|
+
/** Array of aliases */
|
|
70
|
+
aliases: Alias[];
|
|
71
|
+
/** Optional cursor for pagination */
|
|
72
|
+
cursor?: string;
|
|
73
|
+
/** Total number of aliases if available */
|
|
74
|
+
total?: number;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Response for deployment removal
|
|
79
|
+
*/
|
|
80
|
+
export interface DeploymentRemoveResponse {
|
|
81
|
+
/** Operation success status */
|
|
82
|
+
success: boolean;
|
|
83
|
+
/** The deployment ID */
|
|
84
|
+
deployment: string;
|
|
85
|
+
/** Human-readable message */
|
|
86
|
+
message?: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// =============================================================================
|
|
90
|
+
// ACCOUNT TYPES
|
|
91
|
+
// =============================================================================
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Core account object - used in both API responses and SDK
|
|
95
|
+
*/
|
|
96
|
+
export interface Account {
|
|
97
|
+
/** User email address */
|
|
98
|
+
email: string;
|
|
99
|
+
/** User display name */
|
|
100
|
+
name: string;
|
|
101
|
+
/** User profile picture URL */
|
|
102
|
+
picture?: string;
|
|
103
|
+
/** Account subscription status */
|
|
104
|
+
subscription: 'free' | 'active' | 'suspended';
|
|
105
|
+
/** Unix timestamp (seconds) when account was created */
|
|
106
|
+
createdAt: number;
|
|
107
|
+
/** Unix timestamp (seconds) when subscription started */
|
|
108
|
+
subscribedAt?: number;
|
|
109
|
+
/** Unix timestamp (seconds) when account was suspended */
|
|
110
|
+
suspendedAt?: number;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// =============================================================================
|
|
114
|
+
// ERROR SYSTEM
|
|
115
|
+
// =============================================================================
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* All possible error types in the Shipstatic platform
|
|
119
|
+
* Names are developer-friendly while wire format stays consistent
|
|
120
|
+
*/
|
|
121
|
+
export enum ErrorType {
|
|
122
|
+
/** Validation failed (400) */
|
|
123
|
+
Validation = "validation_failed",
|
|
124
|
+
/** Resource not found (404) */
|
|
125
|
+
NotFound = "not_found",
|
|
126
|
+
/** Rate limit exceeded (429) */
|
|
127
|
+
RateLimit = "rate_limit_exceeded",
|
|
128
|
+
/** Authentication required (401) */
|
|
129
|
+
Authentication = "authentication_failed",
|
|
130
|
+
/** Business logic error (400) */
|
|
131
|
+
Business = "business_logic_error",
|
|
132
|
+
/** API server error (500) - renamed from Internal for clarity */
|
|
133
|
+
Api = "internal_server_error",
|
|
134
|
+
/** Network/connection error */
|
|
135
|
+
Network = "network_error",
|
|
136
|
+
/** Operation was cancelled */
|
|
137
|
+
Cancelled = "operation_cancelled",
|
|
138
|
+
/** File operation error */
|
|
139
|
+
File = "file_error",
|
|
140
|
+
/** Configuration error */
|
|
141
|
+
Config = "config_error"
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** @deprecated Use ErrorType instead. Kept for backward compatibility. */
|
|
145
|
+
export const ShipErrorType = ErrorType;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Categorizes error types for better type checking
|
|
149
|
+
*/
|
|
150
|
+
const ERROR_CATEGORIES = {
|
|
151
|
+
client: new Set([ErrorType.Business, ErrorType.Config, ErrorType.File, ErrorType.Validation]),
|
|
152
|
+
network: new Set([ErrorType.Network]),
|
|
153
|
+
auth: new Set([ErrorType.Authentication]),
|
|
154
|
+
} as const;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Standard error response format used everywhere
|
|
158
|
+
*/
|
|
159
|
+
export interface ErrorResponse {
|
|
160
|
+
/** Error type identifier */
|
|
161
|
+
error: ErrorType;
|
|
162
|
+
/** Human-readable error message */
|
|
163
|
+
message: string;
|
|
164
|
+
/** HTTP status code (API contexts) */
|
|
165
|
+
status?: number;
|
|
166
|
+
/** Optional additional error details */
|
|
167
|
+
details?: any;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Simple unified error class for both API and SDK
|
|
172
|
+
*/
|
|
173
|
+
export class ShipError extends Error {
|
|
174
|
+
constructor(
|
|
175
|
+
public readonly type: ErrorType,
|
|
176
|
+
message: string,
|
|
177
|
+
public readonly status?: number,
|
|
178
|
+
public readonly details?: any
|
|
179
|
+
) {
|
|
180
|
+
super(message);
|
|
181
|
+
this.name = 'ShipError';
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** Convert to wire format */
|
|
185
|
+
toResponse(): ErrorResponse {
|
|
186
|
+
return {
|
|
187
|
+
error: this.type,
|
|
188
|
+
message: this.message,
|
|
189
|
+
status: this.status,
|
|
190
|
+
details: this.details
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Create from wire format */
|
|
195
|
+
static fromResponse(response: ErrorResponse): ShipError {
|
|
196
|
+
return new ShipError(response.error, response.message, response.status, response.details);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Factory methods for common errors
|
|
200
|
+
static validation(message: string, details?: any): ShipError {
|
|
201
|
+
return new ShipError(ErrorType.Validation, message, 400, details);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
static notFound(resource: string, id?: string): ShipError {
|
|
205
|
+
const message = id ? `${resource} ${id} not found` : `${resource} not found`;
|
|
206
|
+
return new ShipError(ErrorType.NotFound, message, 404);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
static rateLimit(message: string = "Too many requests"): ShipError {
|
|
210
|
+
return new ShipError(ErrorType.RateLimit, message, 429);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
static authentication(message: string = "Authentication required"): ShipError {
|
|
214
|
+
return new ShipError(ErrorType.Authentication, message, 401);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
static business(message: string, status: number = 400): ShipError {
|
|
219
|
+
return new ShipError(ErrorType.Business, message, status);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
static network(message: string, cause?: Error): ShipError {
|
|
223
|
+
return new ShipError(ErrorType.Network, message, undefined, { cause });
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
static cancelled(message: string): ShipError {
|
|
227
|
+
return new ShipError(ErrorType.Cancelled, message);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
static file(message: string, filePath?: string): ShipError {
|
|
231
|
+
return new ShipError(ErrorType.File, message, undefined, { filePath });
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
static config(message: string, details?: any): ShipError {
|
|
235
|
+
return new ShipError(ErrorType.Config, message, undefined, details);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
static api(message: string, status: number = 500, code?: string, data?: any): ShipError {
|
|
239
|
+
return new ShipError(ErrorType.Api, message, status, { code, data });
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Helper getters for accessing common detail properties
|
|
243
|
+
get filePath(): string | undefined {
|
|
244
|
+
return this.details?.filePath;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
get code(): string | undefined {
|
|
248
|
+
return this.details?.code;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Helper methods for error type checking using categorization
|
|
252
|
+
isClientError(): boolean {
|
|
253
|
+
return ERROR_CATEGORIES.client.has(this.type);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
isNetworkError(): boolean {
|
|
257
|
+
return ERROR_CATEGORIES.network.has(this.type);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
isAuthError(): boolean {
|
|
261
|
+
return ERROR_CATEGORIES.auth.has(this.type);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
isValidationError(): boolean {
|
|
265
|
+
return this.type === ErrorType.Validation;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
isFileError(): boolean {
|
|
269
|
+
return this.type === ErrorType.File;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
isConfigError(): boolean {
|
|
273
|
+
return this.type === ErrorType.Config;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Generic type checker
|
|
277
|
+
isType(errorType: ErrorType): boolean {
|
|
278
|
+
return this.type === errorType;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// =============================================================================
|
|
283
|
+
// CONFIGURATION CONSTANTS
|
|
284
|
+
// =============================================================================
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Server-side platform configuration - enforced limits on the platform
|
|
288
|
+
*/
|
|
289
|
+
export const serverConfig = {
|
|
290
|
+
/** Maximum individual file size in bytes (10MB) */
|
|
291
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
292
|
+
/** Maximum number of files per deployment */
|
|
293
|
+
maxFilesCount: 1000,
|
|
294
|
+
/** Maximum total deployment size in bytes (100MB) */
|
|
295
|
+
maxTotalSize: 100 * 1024 * 1024,
|
|
296
|
+
/** Deployment expiry in hours */
|
|
297
|
+
deploymentExpiryHours: 168, // 7 days
|
|
298
|
+
/** Pagination limits */
|
|
299
|
+
defaultLimit: 50,
|
|
300
|
+
maxLimit: 100,
|
|
301
|
+
} as const;
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
// =============================================================================
|
|
306
|
+
// CONFIG TYPES
|
|
307
|
+
// =============================================================================
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Platform configuration response from API
|
|
311
|
+
*/
|
|
312
|
+
export interface ConfigResponse {
|
|
313
|
+
/** Maximum individual file size in bytes */
|
|
314
|
+
maxFileSize: number;
|
|
315
|
+
/** Maximum number of files per deployment */
|
|
316
|
+
maxFilesCount: number;
|
|
317
|
+
/** Maximum total deployment size in bytes */
|
|
318
|
+
maxTotalSize: number;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// =============================================================================
|
|
322
|
+
// COMMON RESPONSE PATTERNS
|
|
323
|
+
// =============================================================================
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Generic success response wrapper
|
|
327
|
+
*/
|
|
328
|
+
export interface SuccessResponse<T = any> {
|
|
329
|
+
/** Always true for success */
|
|
330
|
+
success: true;
|
|
331
|
+
/** Response data */
|
|
332
|
+
data: T;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Simple ping response for health checks
|
|
337
|
+
*/
|
|
338
|
+
export interface PingResponse {
|
|
339
|
+
/** Always true if service is healthy */
|
|
340
|
+
success: boolean;
|
|
341
|
+
/** Optional timestamp */
|
|
342
|
+
timestamp?: number;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
// API Key Configuration
|
|
347
|
+
export const API_KEY_PREFIX = 'ship-';
|