@shipstatic/types 0.4.24 → 0.5.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/dist/index.d.ts +38 -47
- package/dist/index.js +66 -24
- package/package.json +5 -3
- package/src/index.ts +91 -64
package/dist/index.d.ts
CHANGED
|
@@ -26,8 +26,8 @@ export interface Deployment {
|
|
|
26
26
|
status: DeploymentStatusType;
|
|
27
27
|
/** Whether deployment has configuration */
|
|
28
28
|
readonly config?: boolean;
|
|
29
|
-
/** Optional array of
|
|
30
|
-
|
|
29
|
+
/** Optional array of labels for categorization and filtering (lowercase, alphanumeric with separators) */
|
|
30
|
+
labels?: string[];
|
|
31
31
|
/** The client/tool used to create this deployment (e.g., 'web', 'sdk', 'cli') */
|
|
32
32
|
readonly via?: string;
|
|
33
33
|
/** The deployment URL */
|
|
@@ -75,8 +75,8 @@ export interface Domain {
|
|
|
75
75
|
deployment: string | null;
|
|
76
76
|
/** Current domain status */
|
|
77
77
|
status: DomainStatusType;
|
|
78
|
-
/** Optional array of
|
|
79
|
-
|
|
78
|
+
/** Optional array of labels for categorization and filtering (lowercase, alphanumeric with separators) */
|
|
79
|
+
labels?: string[];
|
|
80
80
|
/** The domain URL - internal (subdomain) or external (custom domain) */
|
|
81
81
|
readonly url: string;
|
|
82
82
|
/** Unix timestamp (seconds) when domain was created */
|
|
@@ -177,8 +177,8 @@ export interface Token {
|
|
|
177
177
|
readonly account: string;
|
|
178
178
|
/** Optional IP address locking for security */
|
|
179
179
|
readonly ip?: string;
|
|
180
|
-
/** Optional array of
|
|
181
|
-
|
|
180
|
+
/** Optional array of labels for categorization and filtering (lowercase, alphanumeric with separators) */
|
|
181
|
+
labels?: string[];
|
|
182
182
|
/** Unix timestamp (seconds) when token was created */
|
|
183
183
|
readonly created: number;
|
|
184
184
|
/** Unix timestamp (seconds) when token expires, or null for never */
|
|
@@ -417,7 +417,7 @@ export interface ConfigResponse {
|
|
|
417
417
|
* - Explicit allowlist (only approved formats, reject unknown)
|
|
418
418
|
* ============================================================================
|
|
419
419
|
*/
|
|
420
|
-
export declare const ALLOWED_MIME_TYPES: readonly ["text/html", "text/css", "text/plain", "text/markdown", "text/xml", "text/csv", "text/yaml", "text/vtt", "text/calendar", "text/javascript", "text/typescript", "text/tsx", "text/jsx", "text/x-scss", "text/x-sass", "text/less", "text/x-less", "text/stylus", "text/x-vue", "text/x-svelte", "image/", "audio/", "video/", "font/", "application/javascript", "application/ecmascript", "application/x-javascript", "application/wasm", "application/json", "application/ld+json", "application/manifest+json", "application/source-map", "application/xml", "application/xhtml+xml", "application/rss+xml", "application/atom+xml", "application/yaml", "application/toml", "application/pdf", "model/gltf+json", "model/gltf-binary", "application/mp4", "application/font-woff", "application/font-woff2", "application/x-font-woff", "application/x-woff", "application/vnd.ms-fontobject", "application/x-font-ttf", "application/x-font-truetype", "application/x-font-otf", "application/x-font-opentype"];
|
|
420
|
+
export declare const ALLOWED_MIME_TYPES: readonly ["text/html", "text/css", "text/plain", "text/markdown", "text/xml", "text/csv", "text/tab-separated-values", "text/yaml", "text/vcard", "text/mdx", "text/x-mdx", "text/vtt", "text/srt", "text/calendar", "text/javascript", "text/typescript", "application/x-typescript", "text/tsx", "text/jsx", "text/x-scss", "text/x-sass", "text/less", "text/x-less", "text/stylus", "text/x-vue", "text/x-svelte", "text/x-sql", "text/x-diff", "text/x-patch", "text/x-protobuf", "text/x-ini", "text/x-tex", "text/x-latex", "text/x-bibtex", "text/x-r-markdown", "image/", "audio/", "video/", "font/", "application/javascript", "application/ecmascript", "application/x-javascript", "application/wasm", "application/json", "application/ld+json", "application/geo+json", "application/manifest+json", "application/x-ipynb+json", "application/x-ndjson", "application/ndjson", "text/x-ndjson", "application/jsonl", "text/jsonl", "application/json5", "text/json5", "application/schema+json", "application/source-map", "application/xml", "application/xhtml+xml", "application/rss+xml", "application/atom+xml", "application/feed+json", "application/vnd.google-earth.kml+xml", "application/yaml", "application/toml", "application/pdf", "application/x-subrip", "application/sql", "application/graphql", "application/graphql+json", "application/x-protobuf", "application/x-ini", "application/x-tex", "application/x-bibtex", "model/gltf+json", "model/gltf-binary", "application/mp4", "application/font-woff", "application/font-woff2", "application/x-font-woff", "application/x-woff", "application/vnd.ms-fontobject", "application/x-font-ttf", "application/x-font-truetype", "application/x-font-otf", "application/x-font-opentype"];
|
|
421
421
|
/**
|
|
422
422
|
* Check if a MIME type is allowed for upload.
|
|
423
423
|
*
|
|
@@ -581,8 +581,8 @@ export type DeployInput = File[] | string | string[];
|
|
|
581
581
|
* SDK implementations may extend with additional options (timeout, signal, callbacks, etc.).
|
|
582
582
|
*/
|
|
583
583
|
export interface DeploymentCreateOptions {
|
|
584
|
-
/** Optional
|
|
585
|
-
|
|
584
|
+
/** Optional labels for categorization and filtering */
|
|
585
|
+
labels?: string[];
|
|
586
586
|
/** Optional subdomain suggestion for the deployment */
|
|
587
587
|
subdomain?: string;
|
|
588
588
|
/** Client identifier (e.g., 'cli', 'sdk', 'web') */
|
|
@@ -596,7 +596,7 @@ export interface DeploymentResource {
|
|
|
596
596
|
list: () => Promise<DeploymentListResponse>;
|
|
597
597
|
get: (id: string) => Promise<Deployment>;
|
|
598
598
|
set: (id: string, options: {
|
|
599
|
-
|
|
599
|
+
labels: string[];
|
|
600
600
|
}) => Promise<Deployment>;
|
|
601
601
|
remove: (id: string) => Promise<void>;
|
|
602
602
|
}
|
|
@@ -606,7 +606,7 @@ export interface DeploymentResource {
|
|
|
606
606
|
export interface DomainResource {
|
|
607
607
|
set: (name: string, options?: {
|
|
608
608
|
deployment?: string;
|
|
609
|
-
|
|
609
|
+
labels?: string[];
|
|
610
610
|
}) => Promise<Domain>;
|
|
611
611
|
list: () => Promise<DomainListResponse>;
|
|
612
612
|
get: (name: string) => Promise<Domain>;
|
|
@@ -634,7 +634,7 @@ export interface AccountResource {
|
|
|
634
634
|
export interface TokenResource {
|
|
635
635
|
create: (options?: {
|
|
636
636
|
ttl?: number;
|
|
637
|
-
|
|
637
|
+
labels?: string[];
|
|
638
638
|
}) => Promise<TokenCreateResponse>;
|
|
639
639
|
list: () => Promise<TokenListResponse>;
|
|
640
640
|
remove: (token: string) => Promise<void>;
|
|
@@ -696,7 +696,7 @@ export interface KeysResource {
|
|
|
696
696
|
* All activity event types logged in the system.
|
|
697
697
|
* Uses dot notation consistently: {resource}.{action}
|
|
698
698
|
*/
|
|
699
|
-
export type ActivityEvent = 'account.create' | 'account.update' | 'account.delete' | 'account.key.generate' | 'account.plan.paid' | 'account.plan.transition' | 'account.suspended' | 'deployment.create' | 'deployment.update' | 'deployment.delete' | 'deployment.claim' | 'domain.create' | 'domain.update' | 'domain.delete' | 'domain.verify' | 'token.create' | 'token.consume' | 'admin.account.plan.update' | 'admin.account.ref.update' | 'admin.account.billing.update' | 'admin.account.
|
|
699
|
+
export type ActivityEvent = 'account.create' | 'account.update' | 'account.delete' | 'account.key.generate' | 'account.plan.paid' | 'account.plan.transition' | 'account.suspended' | 'deployment.create' | 'deployment.update' | 'deployment.delete' | 'deployment.claim' | 'domain.create' | 'domain.update' | 'domain.delete' | 'domain.verify' | 'token.create' | 'token.consume' | 'admin.account.plan.update' | 'admin.account.ref.update' | 'admin.account.billing.update' | 'admin.account.labels.update' | 'admin.deployment.delete' | 'admin.domain.delete' | 'admin.billing.sync' | 'admin.billing.terminated' | 'billing.active' | 'billing.canceled' | 'billing.paused' | 'billing.expired' | 'billing.paid' | 'billing.trialing' | 'billing.scheduled_cancel' | 'billing.unpaid' | 'billing.update' | 'billing.past_due' | 'refund.created' | 'dispute.created';
|
|
700
700
|
/**
|
|
701
701
|
* Activity events visible to users in the dashboard
|
|
702
702
|
*/
|
|
@@ -733,8 +733,8 @@ export interface ActivityMeta {
|
|
|
733
733
|
wasVerified?: boolean;
|
|
734
734
|
/** Previous deployment ID before relinking */
|
|
735
735
|
previousDeployment?: string;
|
|
736
|
-
/**
|
|
737
|
-
|
|
736
|
+
/** Labels that were set/updated */
|
|
737
|
+
labels?: string[];
|
|
738
738
|
/** OAuth provider name */
|
|
739
739
|
provider?: string;
|
|
740
740
|
/** Account email */
|
|
@@ -772,24 +772,15 @@ export declare const FileValidationStatus: {
|
|
|
772
772
|
};
|
|
773
773
|
export type FileValidationStatusType = typeof FileValidationStatus[keyof typeof FileValidationStatus];
|
|
774
774
|
/**
|
|
775
|
-
*
|
|
776
|
-
*/
|
|
777
|
-
export type ValidationIssueType = 'empty_file' | 'file_too_large' | 'total_size_exceeded' | 'invalid_mime_type' | 'invalid_filename' | 'mime_extension_mismatch' | 'file_count_exceeded' | 'processing_error';
|
|
778
|
-
/**
|
|
779
|
-
* A validation issue with severity level
|
|
775
|
+
* A validation issue with a display-ready message
|
|
780
776
|
*
|
|
781
|
-
* Issues are
|
|
782
|
-
* -
|
|
783
|
-
* - **warning**: Excludes file but allows deployment to proceed
|
|
777
|
+
* Issues are either errors (in errors[] array) or warnings (in warnings[] array).
|
|
778
|
+
* The array position determines severity - no need to duplicate it in the object.
|
|
784
779
|
*/
|
|
785
780
|
export interface ValidationIssue {
|
|
786
781
|
/** File path that triggered this issue */
|
|
787
782
|
file: string;
|
|
788
|
-
/**
|
|
789
|
-
severity: 'error' | 'warning';
|
|
790
|
-
/** Issue type for programmatic handling */
|
|
791
|
-
type: ValidationIssueType;
|
|
792
|
-
/** Human-readable message explaining the issue */
|
|
783
|
+
/** Display-ready message explaining the issue */
|
|
793
784
|
message: string;
|
|
794
785
|
}
|
|
795
786
|
/**
|
|
@@ -892,43 +883,43 @@ export declare function generateDeploymentUrl(deployment: string, platformDomain
|
|
|
892
883
|
*/
|
|
893
884
|
export declare function generateDomainUrl(domain: string): string;
|
|
894
885
|
/**
|
|
895
|
-
*
|
|
896
|
-
* These rules define the single source of truth for
|
|
886
|
+
* Label validation constraints shared across UI and API.
|
|
887
|
+
* These rules define the single source of truth for label validation.
|
|
897
888
|
*/
|
|
898
|
-
export declare const
|
|
899
|
-
/** Minimum
|
|
889
|
+
export declare const LABEL_CONSTRAINTS: {
|
|
890
|
+
/** Minimum label length in characters */
|
|
900
891
|
readonly MIN_LENGTH: 3;
|
|
901
|
-
/** Maximum
|
|
892
|
+
/** Maximum label length in characters (concise labels, matches Stack Overflow's original limit) */
|
|
902
893
|
readonly MAX_LENGTH: 25;
|
|
903
|
-
/** Maximum number of
|
|
894
|
+
/** Maximum number of labels allowed per resource */
|
|
904
895
|
readonly MAX_COUNT: 10;
|
|
905
|
-
/** Allowed separator characters between
|
|
896
|
+
/** Allowed separator characters between label segments */
|
|
906
897
|
readonly SEPARATORS: "._-";
|
|
907
898
|
};
|
|
908
899
|
/**
|
|
909
|
-
*
|
|
900
|
+
* Label validation pattern.
|
|
910
901
|
* Must start and end with alphanumeric (a-z, 0-9).
|
|
911
902
|
* Can contain separators (. _ -) between segments, but not consecutive.
|
|
912
903
|
*
|
|
913
904
|
* Valid examples: 'production', 'v1.2.3', 'api_v2', 'us-east-1'
|
|
914
905
|
* Invalid examples: 'ab' (too short), '-prod' (starts with separator), 'foo--bar' (consecutive separators)
|
|
915
906
|
*/
|
|
916
|
-
export declare const
|
|
907
|
+
export declare const LABEL_PATTERN: RegExp;
|
|
917
908
|
/**
|
|
918
|
-
* Serialize
|
|
909
|
+
* Serialize labels array to JSON string for database storage.
|
|
919
910
|
* Returns null for empty or undefined arrays.
|
|
920
911
|
*
|
|
921
|
-
* @example
|
|
922
|
-
* @example
|
|
923
|
-
* @example
|
|
912
|
+
* @example serializeLabels(['web', 'production']) → '["web","production"]'
|
|
913
|
+
* @example serializeLabels([]) → null
|
|
914
|
+
* @example serializeLabels(undefined) → null
|
|
924
915
|
*/
|
|
925
|
-
export declare function
|
|
916
|
+
export declare function serializeLabels(labels: string[] | undefined): string | null;
|
|
926
917
|
/**
|
|
927
|
-
* Deserialize
|
|
918
|
+
* Deserialize labels from JSON string to array.
|
|
928
919
|
* Returns undefined for null/empty strings.
|
|
929
920
|
*
|
|
930
|
-
* @example
|
|
931
|
-
* @example
|
|
932
|
-
* @example
|
|
921
|
+
* @example deserializeLabels('["web","production"]') → ['web', 'production']
|
|
922
|
+
* @example deserializeLabels(null) → undefined
|
|
923
|
+
* @example deserializeLabels('') → undefined
|
|
933
924
|
*/
|
|
934
|
-
export declare function
|
|
925
|
+
export declare function deserializeLabels(labelsJson: string | null): string[] | undefined;
|
package/dist/index.js
CHANGED
|
@@ -277,14 +277,21 @@ export const ALLOWED_MIME_TYPES = [
|
|
|
277
277
|
'text/xml', // XML files
|
|
278
278
|
// Data formats
|
|
279
279
|
'text/csv', // CSV data files
|
|
280
|
+
'text/tab-separated-values', // TSV data files
|
|
280
281
|
'text/yaml', // YAML config files
|
|
282
|
+
'text/vcard', // VCard contact files (.vcf)
|
|
283
|
+
// Modern documentation formats
|
|
284
|
+
'text/mdx', // MDX (Markdown with JSX) - Next.js, Docusaurus, Nextra
|
|
285
|
+
'text/x-mdx', // MDX (alternative MIME type)
|
|
281
286
|
// Web-specific formats
|
|
282
287
|
'text/vtt', // WebVTT video subtitles/captions (accessibility)
|
|
288
|
+
'text/srt', // SRT subtitles (SubRip format, legacy video captions)
|
|
283
289
|
'text/calendar', // iCalendar (.ics) event files
|
|
284
290
|
// JavaScript (legacy MIME type, still widely used by ~50% of servers)
|
|
285
291
|
'text/javascript',
|
|
286
292
|
// Modern web development formats (uncompiled source)
|
|
287
293
|
'text/typescript', // TypeScript source (.ts)
|
|
294
|
+
'application/x-typescript', // TypeScript (alternative MIME type, .d.ts declarations)
|
|
288
295
|
'text/tsx', // TypeScript JSX (.tsx)
|
|
289
296
|
'text/jsx', // React JSX (.jsx)
|
|
290
297
|
'text/x-scss', // SCSS preprocessor
|
|
@@ -294,6 +301,17 @@ export const ALLOWED_MIME_TYPES = [
|
|
|
294
301
|
'text/stylus', // Stylus preprocessor
|
|
295
302
|
'text/x-vue', // Vue single-file components (.vue)
|
|
296
303
|
'text/x-svelte', // Svelte components (.svelte)
|
|
304
|
+
// Developer documentation formats
|
|
305
|
+
'text/x-sql', // SQL files (database schemas, migrations)
|
|
306
|
+
'text/x-diff', // Diff files (code comparisons, patches)
|
|
307
|
+
'text/x-patch', // Patch files (version upgrades, migrations)
|
|
308
|
+
'text/x-protobuf', // Protocol Buffers text format (gRPC schemas)
|
|
309
|
+
'text/x-ini', // INI configuration files
|
|
310
|
+
// Academic/research formats
|
|
311
|
+
'text/x-tex', // LaTeX documents
|
|
312
|
+
'text/x-latex', // LaTeX documents (alternative)
|
|
313
|
+
'text/x-bibtex', // BibTeX citations
|
|
314
|
+
'text/x-r-markdown', // R Markdown (statistical documentation)
|
|
297
315
|
// =========================================================================
|
|
298
316
|
// MEDIA (prefix matching - covers all common subtypes)
|
|
299
317
|
// =========================================================================
|
|
@@ -317,7 +335,18 @@ export const ALLOWED_MIME_TYPES = [
|
|
|
317
335
|
// JSON and structured data
|
|
318
336
|
'application/json',
|
|
319
337
|
'application/ld+json', // JSON-LD for structured data / SEO (Schema.org, Open Graph)
|
|
338
|
+
'application/geo+json', // GeoJSON for mapping (Leaflet, Mapbox)
|
|
320
339
|
'application/manifest+json', // PWA web app manifests
|
|
340
|
+
'application/x-ipynb+json', // Jupyter Notebooks (data science, ML tutorials)
|
|
341
|
+
// JSON variants (AI/ML, streaming data, configs)
|
|
342
|
+
'application/x-ndjson', // Newline-Delimited JSON (training datasets, logs)
|
|
343
|
+
'application/ndjson', // NDJSON (alternative MIME type)
|
|
344
|
+
'text/x-ndjson', // NDJSON (text variant)
|
|
345
|
+
'application/jsonl', // JSON Lines (Hugging Face, OpenAI fine-tuning)
|
|
346
|
+
'text/jsonl', // JSON Lines (text variant)
|
|
347
|
+
'application/json5', // JSON5 (JSON with comments, trailing commas)
|
|
348
|
+
'text/json5', // JSON5 (text variant)
|
|
349
|
+
'application/schema+json', // JSON Schema (API specs, model definitions)
|
|
321
350
|
// Development tools
|
|
322
351
|
'application/source-map', // Source maps (.js.map, .css.map) for debugging
|
|
323
352
|
// XML and feeds
|
|
@@ -325,11 +354,24 @@ export const ALLOWED_MIME_TYPES = [
|
|
|
325
354
|
'application/xhtml+xml', // XHTML - XML-compliant HTML (legacy sites)
|
|
326
355
|
'application/rss+xml', // RSS feeds (blogs, podcasts)
|
|
327
356
|
'application/atom+xml', // Atom feeds
|
|
357
|
+
'application/feed+json', // JSON Feed (modern RSS alternative)
|
|
358
|
+
'application/vnd.google-earth.kml+xml', // KML for mapping (Google Earth, GIS)
|
|
328
359
|
// Configuration formats
|
|
329
360
|
'application/yaml', // YAML configs (static site generators)
|
|
330
361
|
'application/toml', // TOML configs (Cargo, Netlify, Rust projects)
|
|
331
362
|
// Documents
|
|
332
363
|
'application/pdf', // PDF documents
|
|
364
|
+
// Media metadata
|
|
365
|
+
'application/x-subrip', // SRT subtitles (SubRip format)
|
|
366
|
+
// Developer tools and schemas
|
|
367
|
+
'application/sql', // SQL files (database schemas, queries)
|
|
368
|
+
'application/graphql', // GraphQL schemas (API documentation)
|
|
369
|
+
'application/graphql+json', // GraphQL with JSON encoding
|
|
370
|
+
'application/x-protobuf', // Protocol Buffers binary (gRPC)
|
|
371
|
+
'application/x-ini', // INI configuration files
|
|
372
|
+
// Academic formats
|
|
373
|
+
'application/x-tex', // LaTeX documents
|
|
374
|
+
'application/x-bibtex', // BibTeX citations
|
|
333
375
|
// =========================================================================
|
|
334
376
|
// 3D FORMATS (industry standard only)
|
|
335
377
|
// =========================================================================
|
|
@@ -522,57 +564,57 @@ export function generateDomainUrl(domain) {
|
|
|
522
564
|
return `https://${domain}`;
|
|
523
565
|
}
|
|
524
566
|
// =============================================================================
|
|
525
|
-
//
|
|
567
|
+
// LABEL UTILITIES
|
|
526
568
|
// =============================================================================
|
|
527
569
|
/**
|
|
528
|
-
*
|
|
529
|
-
* These rules define the single source of truth for
|
|
570
|
+
* Label validation constraints shared across UI and API.
|
|
571
|
+
* These rules define the single source of truth for label validation.
|
|
530
572
|
*/
|
|
531
|
-
export const
|
|
532
|
-
/** Minimum
|
|
573
|
+
export const LABEL_CONSTRAINTS = {
|
|
574
|
+
/** Minimum label length in characters */
|
|
533
575
|
MIN_LENGTH: 3,
|
|
534
|
-
/** Maximum
|
|
576
|
+
/** Maximum label length in characters (concise labels, matches Stack Overflow's original limit) */
|
|
535
577
|
MAX_LENGTH: 25,
|
|
536
|
-
/** Maximum number of
|
|
578
|
+
/** Maximum number of labels allowed per resource */
|
|
537
579
|
MAX_COUNT: 10,
|
|
538
|
-
/** Allowed separator characters between
|
|
580
|
+
/** Allowed separator characters between label segments */
|
|
539
581
|
SEPARATORS: '._-',
|
|
540
582
|
};
|
|
541
583
|
/**
|
|
542
|
-
*
|
|
584
|
+
* Label validation pattern.
|
|
543
585
|
* Must start and end with alphanumeric (a-z, 0-9).
|
|
544
586
|
* Can contain separators (. _ -) between segments, but not consecutive.
|
|
545
587
|
*
|
|
546
588
|
* Valid examples: 'production', 'v1.2.3', 'api_v2', 'us-east-1'
|
|
547
589
|
* Invalid examples: 'ab' (too short), '-prod' (starts with separator), 'foo--bar' (consecutive separators)
|
|
548
590
|
*/
|
|
549
|
-
export const
|
|
591
|
+
export const LABEL_PATTERN = /^[a-z0-9]+(?:[._-][a-z0-9]+)*$/;
|
|
550
592
|
/**
|
|
551
|
-
* Serialize
|
|
593
|
+
* Serialize labels array to JSON string for database storage.
|
|
552
594
|
* Returns null for empty or undefined arrays.
|
|
553
595
|
*
|
|
554
|
-
* @example
|
|
555
|
-
* @example
|
|
556
|
-
* @example
|
|
596
|
+
* @example serializeLabels(['web', 'production']) → '["web","production"]'
|
|
597
|
+
* @example serializeLabels([]) → null
|
|
598
|
+
* @example serializeLabels(undefined) → null
|
|
557
599
|
*/
|
|
558
|
-
export function
|
|
559
|
-
if (!
|
|
600
|
+
export function serializeLabels(labels) {
|
|
601
|
+
if (!labels || labels.length === 0)
|
|
560
602
|
return null;
|
|
561
|
-
return JSON.stringify(
|
|
603
|
+
return JSON.stringify(labels);
|
|
562
604
|
}
|
|
563
605
|
/**
|
|
564
|
-
* Deserialize
|
|
606
|
+
* Deserialize labels from JSON string to array.
|
|
565
607
|
* Returns undefined for null/empty strings.
|
|
566
608
|
*
|
|
567
|
-
* @example
|
|
568
|
-
* @example
|
|
569
|
-
* @example
|
|
609
|
+
* @example deserializeLabels('["web","production"]') → ['web', 'production']
|
|
610
|
+
* @example deserializeLabels(null) → undefined
|
|
611
|
+
* @example deserializeLabels('') → undefined
|
|
570
612
|
*/
|
|
571
|
-
export function
|
|
572
|
-
if (!
|
|
613
|
+
export function deserializeLabels(labelsJson) {
|
|
614
|
+
if (!labelsJson)
|
|
573
615
|
return undefined;
|
|
574
616
|
try {
|
|
575
|
-
const parsed = JSON.parse(
|
|
617
|
+
const parsed = JSON.parse(labelsJson);
|
|
576
618
|
return Array.isArray(parsed) && parsed.length > 0 ? parsed : undefined;
|
|
577
619
|
}
|
|
578
620
|
catch {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipstatic/types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Shared types for Shipstatic platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -34,10 +34,12 @@
|
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "^24.10.9",
|
|
37
|
-
"typescript": "^5.9.3"
|
|
37
|
+
"typescript": "^5.9.3",
|
|
38
|
+
"vitest": "^2.1.8"
|
|
38
39
|
},
|
|
39
40
|
"scripts": {
|
|
40
41
|
"build": "tsc",
|
|
41
|
-
"clean": "rm -rf dist"
|
|
42
|
+
"clean": "rm -rf dist",
|
|
43
|
+
"test": "vitest"
|
|
42
44
|
}
|
|
43
45
|
}
|
package/src/index.ts
CHANGED
|
@@ -33,8 +33,8 @@ export interface Deployment {
|
|
|
33
33
|
status: DeploymentStatusType; // Mutable - can be updated
|
|
34
34
|
/** Whether deployment has configuration */
|
|
35
35
|
readonly config?: boolean;
|
|
36
|
-
/** Optional array of
|
|
37
|
-
|
|
36
|
+
/** Optional array of labels for categorization and filtering (lowercase, alphanumeric with separators) */
|
|
37
|
+
labels?: string[];
|
|
38
38
|
/** The client/tool used to create this deployment (e.g., 'web', 'sdk', 'cli') */
|
|
39
39
|
readonly via?: string;
|
|
40
40
|
/** The deployment URL */
|
|
@@ -91,8 +91,8 @@ export interface Domain {
|
|
|
91
91
|
deployment: string | null; // Mutable - can be updated to point to different deployment
|
|
92
92
|
/** Current domain status */
|
|
93
93
|
status: DomainStatusType; // Mutable - can be updated
|
|
94
|
-
/** Optional array of
|
|
95
|
-
|
|
94
|
+
/** Optional array of labels for categorization and filtering (lowercase, alphanumeric with separators) */
|
|
95
|
+
labels?: string[];
|
|
96
96
|
/** The domain URL - internal (subdomain) or external (custom domain) */
|
|
97
97
|
readonly url: string;
|
|
98
98
|
/** Unix timestamp (seconds) when domain was created */
|
|
@@ -204,8 +204,8 @@ export interface Token {
|
|
|
204
204
|
readonly account: string;
|
|
205
205
|
/** Optional IP address locking for security */
|
|
206
206
|
readonly ip?: string;
|
|
207
|
-
/** Optional array of
|
|
208
|
-
|
|
207
|
+
/** Optional array of labels for categorization and filtering (lowercase, alphanumeric with separators) */
|
|
208
|
+
labels?: string[];
|
|
209
209
|
/** Unix timestamp (seconds) when token was created */
|
|
210
210
|
readonly created: number;
|
|
211
211
|
/** Unix timestamp (seconds) when token expires, or null for never */
|
|
@@ -585,10 +585,17 @@ export const ALLOWED_MIME_TYPES = [
|
|
|
585
585
|
|
|
586
586
|
// Data formats
|
|
587
587
|
'text/csv', // CSV data files
|
|
588
|
+
'text/tab-separated-values', // TSV data files
|
|
588
589
|
'text/yaml', // YAML config files
|
|
590
|
+
'text/vcard', // VCard contact files (.vcf)
|
|
591
|
+
|
|
592
|
+
// Modern documentation formats
|
|
593
|
+
'text/mdx', // MDX (Markdown with JSX) - Next.js, Docusaurus, Nextra
|
|
594
|
+
'text/x-mdx', // MDX (alternative MIME type)
|
|
589
595
|
|
|
590
596
|
// Web-specific formats
|
|
591
597
|
'text/vtt', // WebVTT video subtitles/captions (accessibility)
|
|
598
|
+
'text/srt', // SRT subtitles (SubRip format, legacy video captions)
|
|
592
599
|
'text/calendar', // iCalendar (.ics) event files
|
|
593
600
|
|
|
594
601
|
// JavaScript (legacy MIME type, still widely used by ~50% of servers)
|
|
@@ -596,6 +603,7 @@ export const ALLOWED_MIME_TYPES = [
|
|
|
596
603
|
|
|
597
604
|
// Modern web development formats (uncompiled source)
|
|
598
605
|
'text/typescript', // TypeScript source (.ts)
|
|
606
|
+
'application/x-typescript', // TypeScript (alternative MIME type, .d.ts declarations)
|
|
599
607
|
'text/tsx', // TypeScript JSX (.tsx)
|
|
600
608
|
'text/jsx', // React JSX (.jsx)
|
|
601
609
|
'text/x-scss', // SCSS preprocessor
|
|
@@ -606,6 +614,19 @@ export const ALLOWED_MIME_TYPES = [
|
|
|
606
614
|
'text/x-vue', // Vue single-file components (.vue)
|
|
607
615
|
'text/x-svelte', // Svelte components (.svelte)
|
|
608
616
|
|
|
617
|
+
// Developer documentation formats
|
|
618
|
+
'text/x-sql', // SQL files (database schemas, migrations)
|
|
619
|
+
'text/x-diff', // Diff files (code comparisons, patches)
|
|
620
|
+
'text/x-patch', // Patch files (version upgrades, migrations)
|
|
621
|
+
'text/x-protobuf', // Protocol Buffers text format (gRPC schemas)
|
|
622
|
+
'text/x-ini', // INI configuration files
|
|
623
|
+
|
|
624
|
+
// Academic/research formats
|
|
625
|
+
'text/x-tex', // LaTeX documents
|
|
626
|
+
'text/x-latex', // LaTeX documents (alternative)
|
|
627
|
+
'text/x-bibtex', // BibTeX citations
|
|
628
|
+
'text/x-r-markdown', // R Markdown (statistical documentation)
|
|
629
|
+
|
|
609
630
|
// =========================================================================
|
|
610
631
|
// MEDIA (prefix matching - covers all common subtypes)
|
|
611
632
|
// =========================================================================
|
|
@@ -637,7 +658,19 @@ export const ALLOWED_MIME_TYPES = [
|
|
|
637
658
|
// JSON and structured data
|
|
638
659
|
'application/json',
|
|
639
660
|
'application/ld+json', // JSON-LD for structured data / SEO (Schema.org, Open Graph)
|
|
661
|
+
'application/geo+json', // GeoJSON for mapping (Leaflet, Mapbox)
|
|
640
662
|
'application/manifest+json', // PWA web app manifests
|
|
663
|
+
'application/x-ipynb+json', // Jupyter Notebooks (data science, ML tutorials)
|
|
664
|
+
|
|
665
|
+
// JSON variants (AI/ML, streaming data, configs)
|
|
666
|
+
'application/x-ndjson', // Newline-Delimited JSON (training datasets, logs)
|
|
667
|
+
'application/ndjson', // NDJSON (alternative MIME type)
|
|
668
|
+
'text/x-ndjson', // NDJSON (text variant)
|
|
669
|
+
'application/jsonl', // JSON Lines (Hugging Face, OpenAI fine-tuning)
|
|
670
|
+
'text/jsonl', // JSON Lines (text variant)
|
|
671
|
+
'application/json5', // JSON5 (JSON with comments, trailing commas)
|
|
672
|
+
'text/json5', // JSON5 (text variant)
|
|
673
|
+
'application/schema+json', // JSON Schema (API specs, model definitions)
|
|
641
674
|
|
|
642
675
|
// Development tools
|
|
643
676
|
'application/source-map', // Source maps (.js.map, .css.map) for debugging
|
|
@@ -647,6 +680,8 @@ export const ALLOWED_MIME_TYPES = [
|
|
|
647
680
|
'application/xhtml+xml', // XHTML - XML-compliant HTML (legacy sites)
|
|
648
681
|
'application/rss+xml', // RSS feeds (blogs, podcasts)
|
|
649
682
|
'application/atom+xml', // Atom feeds
|
|
683
|
+
'application/feed+json', // JSON Feed (modern RSS alternative)
|
|
684
|
+
'application/vnd.google-earth.kml+xml', // KML for mapping (Google Earth, GIS)
|
|
650
685
|
|
|
651
686
|
// Configuration formats
|
|
652
687
|
'application/yaml', // YAML configs (static site generators)
|
|
@@ -655,6 +690,20 @@ export const ALLOWED_MIME_TYPES = [
|
|
|
655
690
|
// Documents
|
|
656
691
|
'application/pdf', // PDF documents
|
|
657
692
|
|
|
693
|
+
// Media metadata
|
|
694
|
+
'application/x-subrip', // SRT subtitles (SubRip format)
|
|
695
|
+
|
|
696
|
+
// Developer tools and schemas
|
|
697
|
+
'application/sql', // SQL files (database schemas, queries)
|
|
698
|
+
'application/graphql', // GraphQL schemas (API documentation)
|
|
699
|
+
'application/graphql+json', // GraphQL with JSON encoding
|
|
700
|
+
'application/x-protobuf', // Protocol Buffers binary (gRPC)
|
|
701
|
+
'application/x-ini', // INI configuration files
|
|
702
|
+
|
|
703
|
+
// Academic formats
|
|
704
|
+
'application/x-tex', // LaTeX documents
|
|
705
|
+
'application/x-bibtex', // BibTeX citations
|
|
706
|
+
|
|
658
707
|
// =========================================================================
|
|
659
708
|
// 3D FORMATS (industry standard only)
|
|
660
709
|
// =========================================================================
|
|
@@ -954,8 +1003,8 @@ export type DeployInput = File[] | string | string[];
|
|
|
954
1003
|
* SDK implementations may extend with additional options (timeout, signal, callbacks, etc.).
|
|
955
1004
|
*/
|
|
956
1005
|
export interface DeploymentCreateOptions {
|
|
957
|
-
/** Optional
|
|
958
|
-
|
|
1006
|
+
/** Optional labels for categorization and filtering */
|
|
1007
|
+
labels?: string[];
|
|
959
1008
|
/** Optional subdomain suggestion for the deployment */
|
|
960
1009
|
subdomain?: string;
|
|
961
1010
|
/** Client identifier (e.g., 'cli', 'sdk', 'web') */
|
|
@@ -969,7 +1018,7 @@ export interface DeploymentResource {
|
|
|
969
1018
|
create: (input: DeployInput, options?: DeploymentCreateOptions) => Promise<Deployment>;
|
|
970
1019
|
list: () => Promise<DeploymentListResponse>;
|
|
971
1020
|
get: (id: string) => Promise<Deployment>;
|
|
972
|
-
set: (id: string, options: {
|
|
1021
|
+
set: (id: string, options: { labels: string[] }) => Promise<Deployment>;
|
|
973
1022
|
remove: (id: string) => Promise<void>;
|
|
974
1023
|
}
|
|
975
1024
|
|
|
@@ -977,7 +1026,7 @@ export interface DeploymentResource {
|
|
|
977
1026
|
* Domain resource interface - the contract all implementations must follow
|
|
978
1027
|
*/
|
|
979
1028
|
export interface DomainResource {
|
|
980
|
-
set: (name: string, options?: { deployment?: string;
|
|
1029
|
+
set: (name: string, options?: { deployment?: string; labels?: string[] }) => Promise<Domain>;
|
|
981
1030
|
list: () => Promise<DomainListResponse>;
|
|
982
1031
|
get: (name: string) => Promise<Domain>;
|
|
983
1032
|
remove: (name: string) => Promise<void>;
|
|
@@ -999,7 +1048,7 @@ export interface AccountResource {
|
|
|
999
1048
|
* Token resource interface - the contract all implementations must follow
|
|
1000
1049
|
*/
|
|
1001
1050
|
export interface TokenResource {
|
|
1002
|
-
create: (options?: { ttl?: number;
|
|
1051
|
+
create: (options?: { ttl?: number; labels?: string[] }) => Promise<TokenCreateResponse>;
|
|
1003
1052
|
list: () => Promise<TokenListResponse>;
|
|
1004
1053
|
remove: (token: string) => Promise<void>;
|
|
1005
1054
|
}
|
|
@@ -1100,7 +1149,7 @@ export type ActivityEvent =
|
|
|
1100
1149
|
| 'admin.account.plan.update'
|
|
1101
1150
|
| 'admin.account.ref.update'
|
|
1102
1151
|
| 'admin.account.billing.update'
|
|
1103
|
-
| 'admin.account.
|
|
1152
|
+
| 'admin.account.labels.update'
|
|
1104
1153
|
| 'admin.deployment.delete'
|
|
1105
1154
|
| 'admin.domain.delete'
|
|
1106
1155
|
| 'admin.billing.sync'
|
|
@@ -1175,8 +1224,8 @@ export interface ActivityMeta {
|
|
|
1175
1224
|
wasVerified?: boolean;
|
|
1176
1225
|
/** Previous deployment ID before relinking */
|
|
1177
1226
|
previousDeployment?: string;
|
|
1178
|
-
/**
|
|
1179
|
-
|
|
1227
|
+
/** Labels that were set/updated */
|
|
1228
|
+
labels?: string[];
|
|
1180
1229
|
|
|
1181
1230
|
// Account events
|
|
1182
1231
|
/** OAuth provider name */
|
|
@@ -1226,40 +1275,18 @@ export const FileValidationStatus = {
|
|
|
1226
1275
|
|
|
1227
1276
|
export type FileValidationStatusType = typeof FileValidationStatus[keyof typeof FileValidationStatus];
|
|
1228
1277
|
|
|
1229
|
-
/**
|
|
1230
|
-
* Types of validation issues that can occur during file validation
|
|
1231
|
-
*/
|
|
1232
|
-
export type ValidationIssueType =
|
|
1233
|
-
// Warnings (exclude file but don't block deployment)
|
|
1234
|
-
| 'empty_file'
|
|
1235
|
-
|
|
1236
|
-
// Errors (block deployment)
|
|
1237
|
-
| 'file_too_large'
|
|
1238
|
-
| 'total_size_exceeded'
|
|
1239
|
-
| 'invalid_mime_type'
|
|
1240
|
-
| 'invalid_filename'
|
|
1241
|
-
| 'mime_extension_mismatch'
|
|
1242
|
-
| 'file_count_exceeded'
|
|
1243
|
-
| 'processing_error';
|
|
1244
1278
|
|
|
1245
1279
|
/**
|
|
1246
|
-
* A validation issue with
|
|
1280
|
+
* A validation issue with a display-ready message
|
|
1247
1281
|
*
|
|
1248
|
-
* Issues are
|
|
1249
|
-
* -
|
|
1250
|
-
* - **warning**: Excludes file but allows deployment to proceed
|
|
1282
|
+
* Issues are either errors (in errors[] array) or warnings (in warnings[] array).
|
|
1283
|
+
* The array position determines severity - no need to duplicate it in the object.
|
|
1251
1284
|
*/
|
|
1252
1285
|
export interface ValidationIssue {
|
|
1253
1286
|
/** File path that triggered this issue */
|
|
1254
1287
|
file: string;
|
|
1255
1288
|
|
|
1256
|
-
/**
|
|
1257
|
-
severity: 'error' | 'warning';
|
|
1258
|
-
|
|
1259
|
-
/** Issue type for programmatic handling */
|
|
1260
|
-
type: ValidationIssueType;
|
|
1261
|
-
|
|
1262
|
-
/** Human-readable message explaining the issue */
|
|
1289
|
+
/** Display-ready message explaining the issue */
|
|
1263
1290
|
message: string;
|
|
1264
1291
|
}
|
|
1265
1292
|
|
|
@@ -1394,59 +1421,59 @@ export function generateDomainUrl(domain: string): string {
|
|
|
1394
1421
|
}
|
|
1395
1422
|
|
|
1396
1423
|
// =============================================================================
|
|
1397
|
-
//
|
|
1424
|
+
// LABEL UTILITIES
|
|
1398
1425
|
// =============================================================================
|
|
1399
1426
|
|
|
1400
1427
|
/**
|
|
1401
|
-
*
|
|
1402
|
-
* These rules define the single source of truth for
|
|
1428
|
+
* Label validation constraints shared across UI and API.
|
|
1429
|
+
* These rules define the single source of truth for label validation.
|
|
1403
1430
|
*/
|
|
1404
|
-
export const
|
|
1405
|
-
/** Minimum
|
|
1431
|
+
export const LABEL_CONSTRAINTS = {
|
|
1432
|
+
/** Minimum label length in characters */
|
|
1406
1433
|
MIN_LENGTH: 3,
|
|
1407
|
-
/** Maximum
|
|
1434
|
+
/** Maximum label length in characters (concise labels, matches Stack Overflow's original limit) */
|
|
1408
1435
|
MAX_LENGTH: 25,
|
|
1409
|
-
/** Maximum number of
|
|
1436
|
+
/** Maximum number of labels allowed per resource */
|
|
1410
1437
|
MAX_COUNT: 10,
|
|
1411
|
-
/** Allowed separator characters between
|
|
1438
|
+
/** Allowed separator characters between label segments */
|
|
1412
1439
|
SEPARATORS: '._-',
|
|
1413
1440
|
} as const;
|
|
1414
1441
|
|
|
1415
1442
|
/**
|
|
1416
|
-
*
|
|
1443
|
+
* Label validation pattern.
|
|
1417
1444
|
* Must start and end with alphanumeric (a-z, 0-9).
|
|
1418
1445
|
* Can contain separators (. _ -) between segments, but not consecutive.
|
|
1419
1446
|
*
|
|
1420
1447
|
* Valid examples: 'production', 'v1.2.3', 'api_v2', 'us-east-1'
|
|
1421
1448
|
* Invalid examples: 'ab' (too short), '-prod' (starts with separator), 'foo--bar' (consecutive separators)
|
|
1422
1449
|
*/
|
|
1423
|
-
export const
|
|
1450
|
+
export const LABEL_PATTERN = /^[a-z0-9]+(?:[._-][a-z0-9]+)*$/;
|
|
1424
1451
|
|
|
1425
1452
|
/**
|
|
1426
|
-
* Serialize
|
|
1453
|
+
* Serialize labels array to JSON string for database storage.
|
|
1427
1454
|
* Returns null for empty or undefined arrays.
|
|
1428
1455
|
*
|
|
1429
|
-
* @example
|
|
1430
|
-
* @example
|
|
1431
|
-
* @example
|
|
1456
|
+
* @example serializeLabels(['web', 'production']) → '["web","production"]'
|
|
1457
|
+
* @example serializeLabels([]) → null
|
|
1458
|
+
* @example serializeLabels(undefined) → null
|
|
1432
1459
|
*/
|
|
1433
|
-
export function
|
|
1434
|
-
if (!
|
|
1435
|
-
return JSON.stringify(
|
|
1460
|
+
export function serializeLabels(labels: string[] | undefined): string | null {
|
|
1461
|
+
if (!labels || labels.length === 0) return null;
|
|
1462
|
+
return JSON.stringify(labels);
|
|
1436
1463
|
}
|
|
1437
1464
|
|
|
1438
1465
|
/**
|
|
1439
|
-
* Deserialize
|
|
1466
|
+
* Deserialize labels from JSON string to array.
|
|
1440
1467
|
* Returns undefined for null/empty strings.
|
|
1441
1468
|
*
|
|
1442
|
-
* @example
|
|
1443
|
-
* @example
|
|
1444
|
-
* @example
|
|
1469
|
+
* @example deserializeLabels('["web","production"]') → ['web', 'production']
|
|
1470
|
+
* @example deserializeLabels(null) → undefined
|
|
1471
|
+
* @example deserializeLabels('') → undefined
|
|
1445
1472
|
*/
|
|
1446
|
-
export function
|
|
1447
|
-
if (!
|
|
1473
|
+
export function deserializeLabels(labelsJson: string | null): string[] | undefined {
|
|
1474
|
+
if (!labelsJson) return undefined;
|
|
1448
1475
|
try {
|
|
1449
|
-
const parsed = JSON.parse(
|
|
1476
|
+
const parsed = JSON.parse(labelsJson);
|
|
1450
1477
|
return Array.isArray(parsed) && parsed.length > 0 ? parsed : undefined;
|
|
1451
1478
|
} catch {
|
|
1452
1479
|
return undefined;
|