@shipstatic/types 2.5.0-beta.16 → 2.5.0-beta.17
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 +22 -0
- package/dist/index.js +119 -0
- package/package.json +1 -1
- package/src/index.ts +122 -0
package/dist/index.d.ts
CHANGED
|
@@ -775,6 +775,28 @@ export declare const BLOCKED_EXTENSIONS: ReadonlySet<string>;
|
|
|
775
775
|
* isBlockedExtension('README') // false
|
|
776
776
|
*/
|
|
777
777
|
export declare function isBlockedExtension(filename: string): boolean;
|
|
778
|
+
/**
|
|
779
|
+
* The `accept` attribute value for a browser file picker offering web files.
|
|
780
|
+
*
|
|
781
|
+
* **This is a hint, never a rule.** `BLOCKED_EXTENSIONS` is the platform's
|
|
782
|
+
* gate and the only thing that decides what may be hosted; this constant
|
|
783
|
+
* decides what a *file dialog* shows first. The two are not two halves of one
|
|
784
|
+
* policy, and this one must never be consulted to accept or reject a file.
|
|
785
|
+
*
|
|
786
|
+
* The distinction is structural, not stylistic. `accept` can express only an
|
|
787
|
+
* allowlist, while the platform's rule is a blocklist — so this list is
|
|
788
|
+
* necessarily *narrower* than what the platform hosts, and reading it as
|
|
789
|
+
* authority would reject files the platform serves happily. It is also not
|
|
790
|
+
* enforcement in the browser's own terms: every file dialog offers an
|
|
791
|
+
* all-files escape, and **drag-and-drop ignores `accept` entirely**. The
|
|
792
|
+
* dropzone and the picker must reach the same verdict on the same files, and
|
|
793
|
+
* they do — because the verdict is `validateFiles`, downstream of both.
|
|
794
|
+
*
|
|
795
|
+
* Kept beside `BLOCKED_EXTENSIONS` so one file holds both, which is what lets
|
|
796
|
+
* `tests/validation-constants.test.ts` fence the invariant that matters: the
|
|
797
|
+
* picker must never offer a file the platform will refuse.
|
|
798
|
+
*/
|
|
799
|
+
export declare const WEB_FILE_ACCEPT: string;
|
|
778
800
|
/**
|
|
779
801
|
* Characters that are unsafe in filenames for static hosting.
|
|
780
802
|
*
|
package/dist/index.js
CHANGED
|
@@ -560,6 +560,125 @@ export function isBlockedExtension(filename) {
|
|
|
560
560
|
return BLOCKED_EXTENSIONS.has(ext);
|
|
561
561
|
}
|
|
562
562
|
// =============================================================================
|
|
563
|
+
// PICKER ACCEPT HINT
|
|
564
|
+
// =============================================================================
|
|
565
|
+
/**
|
|
566
|
+
* The extensions a browser file picker offers by default, grouped by role.
|
|
567
|
+
*
|
|
568
|
+
* Private on purpose: the only published form is `WEB_FILE_ACCEPT`, the
|
|
569
|
+
* attribute value itself. A published set would invite a call site to ask it
|
|
570
|
+
* whether a file is allowed — which is the one thing this list must never
|
|
571
|
+
* answer. See `WEB_FILE_ACCEPT`.
|
|
572
|
+
*
|
|
573
|
+
* Extensionless files (`LICENSE`, most `.well-known` entries) are inexpressible
|
|
574
|
+
* in `accept`, and reach a deployment by folder pick, ZIP, or drag-and-drop.
|
|
575
|
+
*/
|
|
576
|
+
const WEB_FILE_EXTENSIONS = [
|
|
577
|
+
// Markup & documents
|
|
578
|
+
'html',
|
|
579
|
+
'htm',
|
|
580
|
+
'xhtml',
|
|
581
|
+
'xml',
|
|
582
|
+
'txt',
|
|
583
|
+
'md',
|
|
584
|
+
'markdown',
|
|
585
|
+
'pdf',
|
|
586
|
+
'csv',
|
|
587
|
+
// Data & config
|
|
588
|
+
'json',
|
|
589
|
+
'jsonc',
|
|
590
|
+
'webmanifest',
|
|
591
|
+
'map',
|
|
592
|
+
'toml',
|
|
593
|
+
'yaml',
|
|
594
|
+
'yml',
|
|
595
|
+
'rss',
|
|
596
|
+
'atom',
|
|
597
|
+
// Styles
|
|
598
|
+
'css',
|
|
599
|
+
'scss',
|
|
600
|
+
'sass',
|
|
601
|
+
'less',
|
|
602
|
+
// Scripts & modules
|
|
603
|
+
'js',
|
|
604
|
+
'mjs',
|
|
605
|
+
'cjs',
|
|
606
|
+
'jsx',
|
|
607
|
+
'ts',
|
|
608
|
+
'tsx',
|
|
609
|
+
'wasm',
|
|
610
|
+
'vue',
|
|
611
|
+
'svelte',
|
|
612
|
+
// Images
|
|
613
|
+
'png',
|
|
614
|
+
'jpg',
|
|
615
|
+
'jpeg',
|
|
616
|
+
'gif',
|
|
617
|
+
'webp',
|
|
618
|
+
'avif',
|
|
619
|
+
'svg',
|
|
620
|
+
'ico',
|
|
621
|
+
'bmp',
|
|
622
|
+
'tif',
|
|
623
|
+
'tiff',
|
|
624
|
+
'heic',
|
|
625
|
+
'heif',
|
|
626
|
+
// Fonts
|
|
627
|
+
'woff',
|
|
628
|
+
'woff2',
|
|
629
|
+
'ttf',
|
|
630
|
+
'otf',
|
|
631
|
+
'eot',
|
|
632
|
+
// Audio
|
|
633
|
+
'mp3',
|
|
634
|
+
'wav',
|
|
635
|
+
'ogg',
|
|
636
|
+
'oga',
|
|
637
|
+
'opus',
|
|
638
|
+
'm4a',
|
|
639
|
+
'aac',
|
|
640
|
+
'flac',
|
|
641
|
+
'weba',
|
|
642
|
+
// Video
|
|
643
|
+
'mp4',
|
|
644
|
+
'webm',
|
|
645
|
+
'ogv',
|
|
646
|
+
'mov',
|
|
647
|
+
'm4v',
|
|
648
|
+
'avi',
|
|
649
|
+
// 3D models
|
|
650
|
+
'glb',
|
|
651
|
+
'gltf',
|
|
652
|
+
'usdz',
|
|
653
|
+
// Text tracks
|
|
654
|
+
'vtt',
|
|
655
|
+
'srt',
|
|
656
|
+
// Archive — a whole site in one file
|
|
657
|
+
'zip',
|
|
658
|
+
];
|
|
659
|
+
/**
|
|
660
|
+
* The `accept` attribute value for a browser file picker offering web files.
|
|
661
|
+
*
|
|
662
|
+
* **This is a hint, never a rule.** `BLOCKED_EXTENSIONS` is the platform's
|
|
663
|
+
* gate and the only thing that decides what may be hosted; this constant
|
|
664
|
+
* decides what a *file dialog* shows first. The two are not two halves of one
|
|
665
|
+
* policy, and this one must never be consulted to accept or reject a file.
|
|
666
|
+
*
|
|
667
|
+
* The distinction is structural, not stylistic. `accept` can express only an
|
|
668
|
+
* allowlist, while the platform's rule is a blocklist — so this list is
|
|
669
|
+
* necessarily *narrower* than what the platform hosts, and reading it as
|
|
670
|
+
* authority would reject files the platform serves happily. It is also not
|
|
671
|
+
* enforcement in the browser's own terms: every file dialog offers an
|
|
672
|
+
* all-files escape, and **drag-and-drop ignores `accept` entirely**. The
|
|
673
|
+
* dropzone and the picker must reach the same verdict on the same files, and
|
|
674
|
+
* they do — because the verdict is `validateFiles`, downstream of both.
|
|
675
|
+
*
|
|
676
|
+
* Kept beside `BLOCKED_EXTENSIONS` so one file holds both, which is what lets
|
|
677
|
+
* `tests/validation-constants.test.ts` fence the invariant that matters: the
|
|
678
|
+
* picker must never offer a file the platform will refuse.
|
|
679
|
+
*/
|
|
680
|
+
export const WEB_FILE_ACCEPT = WEB_FILE_EXTENSIONS.map((ext) => `.${ext}`).join(',');
|
|
681
|
+
// =============================================================================
|
|
563
682
|
// FILENAME CHARACTER VALIDATION
|
|
564
683
|
// =============================================================================
|
|
565
684
|
/**
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1147,6 +1147,128 @@ export function isBlockedExtension(filename: string): boolean {
|
|
|
1147
1147
|
return BLOCKED_EXTENSIONS.has(ext);
|
|
1148
1148
|
}
|
|
1149
1149
|
|
|
1150
|
+
// =============================================================================
|
|
1151
|
+
// PICKER ACCEPT HINT
|
|
1152
|
+
// =============================================================================
|
|
1153
|
+
|
|
1154
|
+
/**
|
|
1155
|
+
* The extensions a browser file picker offers by default, grouped by role.
|
|
1156
|
+
*
|
|
1157
|
+
* Private on purpose: the only published form is `WEB_FILE_ACCEPT`, the
|
|
1158
|
+
* attribute value itself. A published set would invite a call site to ask it
|
|
1159
|
+
* whether a file is allowed — which is the one thing this list must never
|
|
1160
|
+
* answer. See `WEB_FILE_ACCEPT`.
|
|
1161
|
+
*
|
|
1162
|
+
* Extensionless files (`LICENSE`, most `.well-known` entries) are inexpressible
|
|
1163
|
+
* in `accept`, and reach a deployment by folder pick, ZIP, or drag-and-drop.
|
|
1164
|
+
*/
|
|
1165
|
+
const WEB_FILE_EXTENSIONS = [
|
|
1166
|
+
// Markup & documents
|
|
1167
|
+
'html',
|
|
1168
|
+
'htm',
|
|
1169
|
+
'xhtml',
|
|
1170
|
+
'xml',
|
|
1171
|
+
'txt',
|
|
1172
|
+
'md',
|
|
1173
|
+
'markdown',
|
|
1174
|
+
'pdf',
|
|
1175
|
+
'csv',
|
|
1176
|
+
// Data & config
|
|
1177
|
+
'json',
|
|
1178
|
+
'jsonc',
|
|
1179
|
+
'webmanifest',
|
|
1180
|
+
'map',
|
|
1181
|
+
'toml',
|
|
1182
|
+
'yaml',
|
|
1183
|
+
'yml',
|
|
1184
|
+
'rss',
|
|
1185
|
+
'atom',
|
|
1186
|
+
// Styles
|
|
1187
|
+
'css',
|
|
1188
|
+
'scss',
|
|
1189
|
+
'sass',
|
|
1190
|
+
'less',
|
|
1191
|
+
// Scripts & modules
|
|
1192
|
+
'js',
|
|
1193
|
+
'mjs',
|
|
1194
|
+
'cjs',
|
|
1195
|
+
'jsx',
|
|
1196
|
+
'ts',
|
|
1197
|
+
'tsx',
|
|
1198
|
+
'wasm',
|
|
1199
|
+
'vue',
|
|
1200
|
+
'svelte',
|
|
1201
|
+
// Images
|
|
1202
|
+
'png',
|
|
1203
|
+
'jpg',
|
|
1204
|
+
'jpeg',
|
|
1205
|
+
'gif',
|
|
1206
|
+
'webp',
|
|
1207
|
+
'avif',
|
|
1208
|
+
'svg',
|
|
1209
|
+
'ico',
|
|
1210
|
+
'bmp',
|
|
1211
|
+
'tif',
|
|
1212
|
+
'tiff',
|
|
1213
|
+
'heic',
|
|
1214
|
+
'heif',
|
|
1215
|
+
// Fonts
|
|
1216
|
+
'woff',
|
|
1217
|
+
'woff2',
|
|
1218
|
+
'ttf',
|
|
1219
|
+
'otf',
|
|
1220
|
+
'eot',
|
|
1221
|
+
// Audio
|
|
1222
|
+
'mp3',
|
|
1223
|
+
'wav',
|
|
1224
|
+
'ogg',
|
|
1225
|
+
'oga',
|
|
1226
|
+
'opus',
|
|
1227
|
+
'm4a',
|
|
1228
|
+
'aac',
|
|
1229
|
+
'flac',
|
|
1230
|
+
'weba',
|
|
1231
|
+
// Video
|
|
1232
|
+
'mp4',
|
|
1233
|
+
'webm',
|
|
1234
|
+
'ogv',
|
|
1235
|
+
'mov',
|
|
1236
|
+
'm4v',
|
|
1237
|
+
'avi',
|
|
1238
|
+
// 3D models
|
|
1239
|
+
'glb',
|
|
1240
|
+
'gltf',
|
|
1241
|
+
'usdz',
|
|
1242
|
+
// Text tracks
|
|
1243
|
+
'vtt',
|
|
1244
|
+
'srt',
|
|
1245
|
+
// Archive — a whole site in one file
|
|
1246
|
+
'zip',
|
|
1247
|
+
] as const;
|
|
1248
|
+
|
|
1249
|
+
/**
|
|
1250
|
+
* The `accept` attribute value for a browser file picker offering web files.
|
|
1251
|
+
*
|
|
1252
|
+
* **This is a hint, never a rule.** `BLOCKED_EXTENSIONS` is the platform's
|
|
1253
|
+
* gate and the only thing that decides what may be hosted; this constant
|
|
1254
|
+
* decides what a *file dialog* shows first. The two are not two halves of one
|
|
1255
|
+
* policy, and this one must never be consulted to accept or reject a file.
|
|
1256
|
+
*
|
|
1257
|
+
* The distinction is structural, not stylistic. `accept` can express only an
|
|
1258
|
+
* allowlist, while the platform's rule is a blocklist — so this list is
|
|
1259
|
+
* necessarily *narrower* than what the platform hosts, and reading it as
|
|
1260
|
+
* authority would reject files the platform serves happily. It is also not
|
|
1261
|
+
* enforcement in the browser's own terms: every file dialog offers an
|
|
1262
|
+
* all-files escape, and **drag-and-drop ignores `accept` entirely**. The
|
|
1263
|
+
* dropzone and the picker must reach the same verdict on the same files, and
|
|
1264
|
+
* they do — because the verdict is `validateFiles`, downstream of both.
|
|
1265
|
+
*
|
|
1266
|
+
* Kept beside `BLOCKED_EXTENSIONS` so one file holds both, which is what lets
|
|
1267
|
+
* `tests/validation-constants.test.ts` fence the invariant that matters: the
|
|
1268
|
+
* picker must never offer a file the platform will refuse.
|
|
1269
|
+
*/
|
|
1270
|
+
export const WEB_FILE_ACCEPT: string = WEB_FILE_EXTENSIONS.map((ext) => `.${ext}`).join(',');
|
|
1271
|
+
|
|
1150
1272
|
// =============================================================================
|
|
1151
1273
|
// FILENAME CHARACTER VALIDATION
|
|
1152
1274
|
// =============================================================================
|