@fgv/ts-web-extras 5.0.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/.rush/temp/86c9c1ad46e237e0b957c2442bf0355cf39babba.tar.log +121 -0
- package/.rush/temp/chunked-rush-logs/ts-web-extras.build.chunks.jsonl +40 -0
- package/.rush/temp/operation/build/all.log +40 -0
- package/.rush/temp/operation/build/log-chunks.jsonl +40 -0
- package/.rush/temp/operation/build/state.json +3 -0
- package/.rush/temp/shrinkwrap-deps.json +624 -0
- package/config/api-extractor.json +343 -0
- package/config/jest.config.json +16 -0
- package/config/rig.json +16 -0
- package/dist/ts-web-extras.d.ts +574 -0
- package/dist/tsdoc-metadata.json +11 -0
- package/docs/index.md +34 -0
- package/docs/ts-web-extras.browserhashprovider.hashparts.md +88 -0
- package/docs/ts-web-extras.browserhashprovider.hashstring.md +72 -0
- package/docs/ts-web-extras.browserhashprovider.md +66 -0
- package/docs/ts-web-extras.exportasjson.md +70 -0
- package/docs/ts-web-extras.exportusingfilesystemapi.md +104 -0
- package/docs/ts-web-extras.extractdirectorypath.md +52 -0
- package/docs/ts-web-extras.fileapitreeaccessors.create.md +72 -0
- package/docs/ts-web-extras.fileapitreeaccessors.extractfilemetadata.md +54 -0
- package/docs/ts-web-extras.fileapitreeaccessors.fromdirectoryupload.md +72 -0
- package/docs/ts-web-extras.fileapitreeaccessors.fromfilelist.md +72 -0
- package/docs/ts-web-extras.fileapitreeaccessors.getoriginalfile.md +72 -0
- package/docs/ts-web-extras.fileapitreeaccessors.md +114 -0
- package/docs/ts-web-extras.filepickeraccepttype.accept.md +11 -0
- package/docs/ts-web-extras.filepickeraccepttype.description.md +11 -0
- package/docs/ts-web-extras.filepickeraccepttype.md +75 -0
- package/docs/ts-web-extras.filesystemcreatewritableoptions_2.keepexistingdata.md +11 -0
- package/docs/ts-web-extras.filesystemcreatewritableoptions_2.md +58 -0
- package/docs/ts-web-extras.filesystemdirectoryhandle_2._symbol.asynciterator_.md +15 -0
- package/docs/ts-web-extras.filesystemdirectoryhandle_2.entries.md +15 -0
- package/docs/ts-web-extras.filesystemdirectoryhandle_2.getdirectoryhandle.md +66 -0
- package/docs/ts-web-extras.filesystemdirectoryhandle_2.getfilehandle.md +66 -0
- package/docs/ts-web-extras.filesystemdirectoryhandle_2.keys.md +15 -0
- package/docs/ts-web-extras.filesystemdirectoryhandle_2.kind.md +11 -0
- package/docs/ts-web-extras.filesystemdirectoryhandle_2.md +146 -0
- package/docs/ts-web-extras.filesystemdirectoryhandle_2.removeentry.md +66 -0
- package/docs/ts-web-extras.filesystemdirectoryhandle_2.resolve.md +50 -0
- package/docs/ts-web-extras.filesystemdirectoryhandle_2.values.md +15 -0
- package/docs/ts-web-extras.filesystemfilehandle_2.createwritable.md +52 -0
- package/docs/ts-web-extras.filesystemfilehandle_2.getfile.md +15 -0
- package/docs/ts-web-extras.filesystemfilehandle_2.kind.md +11 -0
- package/docs/ts-web-extras.filesystemfilehandle_2.md +92 -0
- package/docs/ts-web-extras.filesystemgetdirectoryoptions_2.create.md +11 -0
- package/docs/ts-web-extras.filesystemgetdirectoryoptions_2.md +58 -0
- package/docs/ts-web-extras.filesystemgetfileoptions_2.create.md +11 -0
- package/docs/ts-web-extras.filesystemgetfileoptions_2.md +58 -0
- package/docs/ts-web-extras.filesystemhandle_2.issameentry.md +50 -0
- package/docs/ts-web-extras.filesystemhandle_2.kind.md +11 -0
- package/docs/ts-web-extras.filesystemhandle_2.md +119 -0
- package/docs/ts-web-extras.filesystemhandle_2.name.md +11 -0
- package/docs/ts-web-extras.filesystemhandle_2.querypermission.md +52 -0
- package/docs/ts-web-extras.filesystemhandle_2.requestpermission.md +52 -0
- package/docs/ts-web-extras.filesystemhandlepermissiondescriptor.md +58 -0
- package/docs/ts-web-extras.filesystemhandlepermissiondescriptor.mode.md +11 -0
- package/docs/ts-web-extras.filesystemremoveoptions_2.md +58 -0
- package/docs/ts-web-extras.filesystemremoveoptions_2.recursive.md +11 -0
- package/docs/ts-web-extras.filesystemwritablefilestream_2.md +57 -0
- package/docs/ts-web-extras.filesystemwritablefilestream_2.seek.md +50 -0
- package/docs/ts-web-extras.filesystemwritablefilestream_2.truncate.md +50 -0
- package/docs/ts-web-extras.filesystemwritablefilestream_2.write.md +50 -0
- package/docs/ts-web-extras.filetreehelpers.defaultfileapitreeinitparams.md +13 -0
- package/docs/ts-web-extras.filetreehelpers.extractfilelistmetadata.md +56 -0
- package/docs/ts-web-extras.filetreehelpers.extractfilemetadata.md +56 -0
- package/docs/ts-web-extras.filetreehelpers.fromdirectoryupload.md +76 -0
- package/docs/ts-web-extras.filetreehelpers.fromfilelist.md +76 -0
- package/docs/ts-web-extras.filetreehelpers.getoriginalfile.md +72 -0
- package/docs/ts-web-extras.filetreehelpers.md +102 -0
- package/docs/ts-web-extras.idirectoryhandletreeinitializer.dirhandles.md +11 -0
- package/docs/ts-web-extras.idirectoryhandletreeinitializer.md +100 -0
- package/docs/ts-web-extras.idirectoryhandletreeinitializer.nonrecursive.md +11 -0
- package/docs/ts-web-extras.idirectoryhandletreeinitializer.prefix.md +11 -0
- package/docs/ts-web-extras.ifilehandletreeinitializer.filehandles.md +11 -0
- package/docs/ts-web-extras.ifilehandletreeinitializer.md +79 -0
- package/docs/ts-web-extras.ifilehandletreeinitializer.prefix.md +11 -0
- package/docs/ts-web-extras.ifilelisttreeinitializer.filelist.md +11 -0
- package/docs/ts-web-extras.ifilelisttreeinitializer.md +58 -0
- package/docs/ts-web-extras.ifilemetadata.lastmodified.md +11 -0
- package/docs/ts-web-extras.ifilemetadata.md +124 -0
- package/docs/ts-web-extras.ifilemetadata.name.md +11 -0
- package/docs/ts-web-extras.ifilemetadata.path.md +11 -0
- package/docs/ts-web-extras.ifilemetadata.size.md +11 -0
- package/docs/ts-web-extras.ifilemetadata.type.md +11 -0
- package/docs/ts-web-extras.ifsaccessapis.md +56 -0
- package/docs/ts-web-extras.ifsaccessapis.showdirectorypicker.md +52 -0
- package/docs/ts-web-extras.ifsaccessapis.showopenfilepicker.md +52 -0
- package/docs/ts-web-extras.ifsaccessapis.showsavefilepicker.md +52 -0
- package/docs/ts-web-extras.isdirectoryhandle.md +56 -0
- package/docs/ts-web-extras.isfilehandle.md +56 -0
- package/docs/ts-web-extras.isfilepath.md +52 -0
- package/docs/ts-web-extras.iurlconfigoptions.config.md +13 -0
- package/docs/ts-web-extras.iurlconfigoptions.configstartdir.md +13 -0
- package/docs/ts-web-extras.iurlconfigoptions.contextfilter.md +13 -0
- package/docs/ts-web-extras.iurlconfigoptions.input.md +13 -0
- package/docs/ts-web-extras.iurlconfigoptions.inputstartdir.md +13 -0
- package/docs/ts-web-extras.iurlconfigoptions.interactive.md +13 -0
- package/docs/ts-web-extras.iurlconfigoptions.loadzip.md +13 -0
- package/docs/ts-web-extras.iurlconfigoptions.maxdistance.md +13 -0
- package/docs/ts-web-extras.iurlconfigoptions.md +286 -0
- package/docs/ts-web-extras.iurlconfigoptions.qualifierdefaults.md +13 -0
- package/docs/ts-web-extras.iurlconfigoptions.reducequalifiers.md +13 -0
- package/docs/ts-web-extras.iurlconfigoptions.resourcetypes.md +13 -0
- package/docs/ts-web-extras.iurlconfigoptions.zipfile.md +13 -0
- package/docs/ts-web-extras.iurlconfigoptions.zippath.md +13 -0
- package/docs/ts-web-extras.md +512 -0
- package/docs/ts-web-extras.parsecontextfilter.md +52 -0
- package/docs/ts-web-extras.parsequalifierdefaults.md +52 -0
- package/docs/ts-web-extras.parseresourcetypes.md +52 -0
- package/docs/ts-web-extras.parseurlparameters.md +17 -0
- package/docs/ts-web-extras.safeshowdirectorypicker.md +72 -0
- package/docs/ts-web-extras.safeshowopenfilepicker.md +72 -0
- package/docs/ts-web-extras.safeshowsavefilepicker.md +72 -0
- package/docs/ts-web-extras.showdirectorypickeroptions.id.md +11 -0
- package/docs/ts-web-extras.showdirectorypickeroptions.md +96 -0
- package/docs/ts-web-extras.showdirectorypickeroptions.mode.md +11 -0
- package/docs/ts-web-extras.showdirectorypickeroptions.startin.md +11 -0
- package/docs/ts-web-extras.showopenfilepickeroptions.excludeacceptalloption.md +11 -0
- package/docs/ts-web-extras.showopenfilepickeroptions.id.md +11 -0
- package/docs/ts-web-extras.showopenfilepickeroptions.md +134 -0
- package/docs/ts-web-extras.showopenfilepickeroptions.multiple.md +11 -0
- package/docs/ts-web-extras.showopenfilepickeroptions.startin.md +11 -0
- package/docs/ts-web-extras.showopenfilepickeroptions.types.md +11 -0
- package/docs/ts-web-extras.showsavefilepickeroptions.excludeacceptalloption.md +11 -0
- package/docs/ts-web-extras.showsavefilepickeroptions.id.md +11 -0
- package/docs/ts-web-extras.showsavefilepickeroptions.md +134 -0
- package/docs/ts-web-extras.showsavefilepickeroptions.startin.md +11 -0
- package/docs/ts-web-extras.showsavefilepickeroptions.suggestedname.md +11 -0
- package/docs/ts-web-extras.showsavefilepickeroptions.types.md +11 -0
- package/docs/ts-web-extras.supportsfilesystemaccess.md +56 -0
- package/docs/ts-web-extras.treeinitializer.md +15 -0
- package/docs/ts-web-extras.wellknowndirectory.md +13 -0
- package/docs/ts-web-extras.windowwithfsaccess.md +15 -0
- package/etc/ts-web-extras.api.md +310 -0
- package/lib/index.d.ts +16 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +58 -0
- package/lib/index.js.map +1 -0
- package/lib/packlets/crypto/browserHashProvider.d.ts +24 -0
- package/lib/packlets/crypto/browserHashProvider.d.ts.map +1 -0
- package/lib/packlets/crypto/browserHashProvider.js +70 -0
- package/lib/packlets/crypto/browserHashProvider.js.map +1 -0
- package/lib/packlets/crypto/index.d.ts +6 -0
- package/lib/packlets/crypto/index.d.ts.map +1 -0
- package/lib/packlets/crypto/index.js +43 -0
- package/lib/packlets/crypto/index.js.map +1 -0
- package/lib/packlets/file-api-types/index.d.ts +205 -0
- package/lib/packlets/file-api-types/index.d.ts.map +1 -0
- package/lib/packlets/file-api-types/index.js +166 -0
- package/lib/packlets/file-api-types/index.js.map +1 -0
- package/lib/packlets/file-tree/fileApiTreeAccessors.d.ts +129 -0
- package/lib/packlets/file-tree/fileApiTreeAccessors.d.ts.map +1 -0
- package/lib/packlets/file-tree/fileApiTreeAccessors.js +334 -0
- package/lib/packlets/file-tree/fileApiTreeAccessors.js.map +1 -0
- package/lib/packlets/file-tree/index.d.ts +6 -0
- package/lib/packlets/file-tree/index.d.ts.map +1 -0
- package/lib/packlets/file-tree/index.js +43 -0
- package/lib/packlets/file-tree/index.js.map +1 -0
- package/lib/packlets/helpers/fileTreeHelpers.d.ts +60 -0
- package/lib/packlets/helpers/fileTreeHelpers.d.ts.map +1 -0
- package/lib/packlets/helpers/fileTreeHelpers.js +102 -0
- package/lib/packlets/helpers/fileTreeHelpers.js.map +1 -0
- package/lib/packlets/helpers/index.d.ts +6 -0
- package/lib/packlets/helpers/index.d.ts.map +1 -0
- package/lib/packlets/helpers/index.js +63 -0
- package/lib/packlets/helpers/index.js.map +1 -0
- package/lib/packlets/url-utils/index.d.ts +6 -0
- package/lib/packlets/url-utils/index.d.ts.map +1 -0
- package/lib/packlets/url-utils/index.js +43 -0
- package/lib/packlets/url-utils/index.js.map +1 -0
- package/lib/packlets/url-utils/urlParams.d.ts +94 -0
- package/lib/packlets/url-utils/urlParams.d.ts.map +1 -0
- package/lib/packlets/url-utils/urlParams.js +165 -0
- package/lib/packlets/url-utils/urlParams.js.map +1 -0
- package/lib/test/setupTests.d.ts +2 -0
- package/lib/test/setupTests.d.ts.map +1 -0
- package/lib/test/setupTests.js +76 -0
- package/lib/test/setupTests.js.map +1 -0
- package/lib/test/unit/browserHashProvider.test.d.ts +2 -0
- package/lib/test/unit/browserHashProvider.test.d.ts.map +1 -0
- package/lib/test/unit/browserHashProvider.test.js +142 -0
- package/lib/test/unit/browserHashProvider.test.js.map +1 -0
- package/lib/test/unit/fileApiTreeAccessors.test.d.ts +2 -0
- package/lib/test/unit/fileApiTreeAccessors.test.d.ts.map +1 -0
- package/lib/test/unit/fileApiTreeAccessors.test.js +1139 -0
- package/lib/test/unit/fileApiTreeAccessors.test.js.map +1 -0
- package/lib/test/unit/fileApiTypes.test.d.ts +2 -0
- package/lib/test/unit/fileApiTypes.test.d.ts.map +1 -0
- package/lib/test/unit/fileApiTypes.test.js +444 -0
- package/lib/test/unit/fileApiTypes.test.js.map +1 -0
- package/lib/test/unit/fileTreeHelpers.test.d.ts +2 -0
- package/lib/test/unit/fileTreeHelpers.test.d.ts.map +1 -0
- package/lib/test/unit/fileTreeHelpers.test.js +592 -0
- package/lib/test/unit/fileTreeHelpers.test.js.map +1 -0
- package/lib/test/unit/urlParams.test.d.ts +2 -0
- package/lib/test/unit/urlParams.test.d.ts.map +1 -0
- package/lib/test/unit/urlParams.test.js +395 -0
- package/lib/test/unit/urlParams.test.js.map +1 -0
- package/lib/test/utils/testHelpers.d.ts +51 -0
- package/lib/test/utils/testHelpers.d.ts.map +1 -0
- package/lib/test/utils/testHelpers.js +133 -0
- package/lib/test/utils/testHelpers.js.map +1 -0
- package/package.json +68 -0
- package/rush-logs/ts-web-extras.build.cache.log +3 -0
- package/rush-logs/ts-web-extras.build.log +40 -0
- package/src/index.ts +47 -0
- package/src/packlets/crypto/browserHashProvider.ts +73 -0
- package/src/packlets/crypto/index.ts +28 -0
- package/src/packlets/file-api-types/index.ts +345 -0
- package/src/packlets/file-tree/fileApiTreeAccessors.ts +420 -0
- package/src/packlets/file-tree/index.ts +28 -0
- package/src/packlets/helpers/fileTreeHelpers.ts +107 -0
- package/src/packlets/helpers/index.ts +28 -0
- package/src/packlets/url-utils/index.ts +28 -0
- package/src/packlets/url-utils/urlParams.ts +245 -0
- package/src/test/setupTests.ts +87 -0
- package/src/test/unit/browserHashProvider.test.ts +155 -0
- package/src/test/unit/browserHashProvider.test.ts.bak +376 -0
- package/src/test/unit/fileApiTreeAccessors.test.ts +1318 -0
- package/src/test/unit/fileApiTypes.test.ts +551 -0
- package/src/test/unit/fileTreeHelpers.test.ts +694 -0
- package/src/test/unit/urlParams.test.ts +464 -0
- package/src/test/utils/testHelpers.ts +155 -0
- package/temp/build/typescript/ts_l9Fw4VUO.json +1 -0
- package/temp/coverage/base.css +224 -0
- package/temp/coverage/block-navigation.js +87 -0
- package/temp/coverage/crypto/browserHashProvider.ts.html +304 -0
- package/temp/coverage/crypto/index.html +116 -0
- package/temp/coverage/favicon.png +0 -0
- package/temp/coverage/file-tree/fileApiTreeAccessors.ts.html +1345 -0
- package/temp/coverage/file-tree/index.html +116 -0
- package/temp/coverage/helpers/fileTreeHelpers.ts.html +406 -0
- package/temp/coverage/helpers/index.html +116 -0
- package/temp/coverage/index.html +161 -0
- package/temp/coverage/lcov-report/base.css +224 -0
- package/temp/coverage/lcov-report/block-navigation.js +87 -0
- package/temp/coverage/lcov-report/crypto/browserHashProvider.ts.html +304 -0
- package/temp/coverage/lcov-report/crypto/index.html +116 -0
- package/temp/coverage/lcov-report/favicon.png +0 -0
- package/temp/coverage/lcov-report/file-tree/fileApiTreeAccessors.ts.html +1345 -0
- package/temp/coverage/lcov-report/file-tree/index.html +116 -0
- package/temp/coverage/lcov-report/helpers/fileTreeHelpers.ts.html +406 -0
- package/temp/coverage/lcov-report/helpers/index.html +116 -0
- package/temp/coverage/lcov-report/index.html +161 -0
- package/temp/coverage/lcov-report/prettify.css +1 -0
- package/temp/coverage/lcov-report/prettify.js +2 -0
- package/temp/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/temp/coverage/lcov-report/sorter.js +210 -0
- package/temp/coverage/lcov-report/url-utils/index.html +116 -0
- package/temp/coverage/lcov-report/url-utils/urlParams.ts.html +820 -0
- package/temp/coverage/lcov.info +1096 -0
- package/temp/coverage/prettify.css +1 -0
- package/temp/coverage/prettify.js +2 -0
- package/temp/coverage/sort-arrow-sprite.png +0 -0
- package/temp/coverage/sorter.js +210 -0
- package/temp/coverage/url-utils/index.html +116 -0
- package/temp/coverage/url-utils/urlParams.ts.html +820 -0
- package/temp/test/jest/haste-map-7492f1b44480e0cdd1f220078fb3afd8-c8dd6c3430605adeb2f1cadf4f75e791-8c9336785555d572065b28c111982ba4 +0 -0
- package/temp/test/jest/jest-transform-cache-7492f1b44480e0cdd1f220078fb3afd8-79ef2876fae7ca75eedb2aa53dc48338/63/package_63a8257b0e4d0e7ff33f927d75f27a75 +53 -0
- package/temp/test/jest/perf-cache-7492f1b44480e0cdd1f220078fb3afd8-da39a3ee5e6b4b0d3255bfef95601890 +1 -0
- package/temp/ts-web-extras.api.json +5040 -0
- package/temp/ts-web-extras.api.md +310 -0
- package/tsconfig.json +7 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test utilities for mocking browser APIs
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Mock file data structure
|
|
6
|
+
*/
|
|
7
|
+
export interface MockFileData {
|
|
8
|
+
name: string;
|
|
9
|
+
content: string;
|
|
10
|
+
type?: string;
|
|
11
|
+
lastModified?: number;
|
|
12
|
+
webkitRelativePath?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Create a mock File object with all necessary properties and methods
|
|
16
|
+
*/
|
|
17
|
+
export declare function createMockFile(data: MockFileData): File;
|
|
18
|
+
/**
|
|
19
|
+
* Create a mock FileList using DataTransfer API
|
|
20
|
+
* This is the most reliable method for creating FileList objects in tests
|
|
21
|
+
*/
|
|
22
|
+
export declare function createMockFileList(files: MockFileData[]): FileList;
|
|
23
|
+
/**
|
|
24
|
+
* Create a mock FileList for directory upload simulation
|
|
25
|
+
* Includes webkitRelativePath for each file
|
|
26
|
+
*/
|
|
27
|
+
export declare function createMockDirectoryFileList(directoryStructure: Array<{
|
|
28
|
+
path: string;
|
|
29
|
+
content: string;
|
|
30
|
+
type?: string;
|
|
31
|
+
}>): FileList;
|
|
32
|
+
/**
|
|
33
|
+
* Helper to create a promise that resolves after a delay
|
|
34
|
+
* Useful for testing async operations
|
|
35
|
+
*/
|
|
36
|
+
export declare function delay(ms: number): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Helper to verify File API text() method works correctly
|
|
39
|
+
* Since we're using Blob/File polyfills, this ensures they have the right methods
|
|
40
|
+
*/
|
|
41
|
+
export declare function verifyFileAPI(file: File): Promise<boolean>;
|
|
42
|
+
/**
|
|
43
|
+
* Mock Web Crypto digest result for testing
|
|
44
|
+
* Creates a deterministic hash-like ArrayBuffer
|
|
45
|
+
*/
|
|
46
|
+
export declare function createMockDigest(input: string, algorithm?: string): ArrayBuffer;
|
|
47
|
+
/**
|
|
48
|
+
* Convert ArrayBuffer to hex string for comparison in tests
|
|
49
|
+
*/
|
|
50
|
+
export declare function arrayBufferToHex(buffer: ArrayBuffer): string;
|
|
51
|
+
//# sourceMappingURL=testHelpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testHelpers.d.ts","sourceRoot":"","sources":["../../../src/test/utils/testHelpers.ts"],"names":[],"mappings":"AAsBA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CA0BvD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,QAAQ,CAUlE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,kBAAkB,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAC1E,QAAQ,CASV;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAYhE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,MAAkB,GAAG,WAAW,CAa1F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAK5D"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025 Erik Fortune
|
|
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.
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.createMockFile = createMockFile;
|
|
25
|
+
exports.createMockFileList = createMockFileList;
|
|
26
|
+
exports.createMockDirectoryFileList = createMockDirectoryFileList;
|
|
27
|
+
exports.delay = delay;
|
|
28
|
+
exports.verifyFileAPI = verifyFileAPI;
|
|
29
|
+
exports.createMockDigest = createMockDigest;
|
|
30
|
+
exports.arrayBufferToHex = arrayBufferToHex;
|
|
31
|
+
/**
|
|
32
|
+
* Create a mock File object with all necessary properties and methods
|
|
33
|
+
*/
|
|
34
|
+
function createMockFile(data) {
|
|
35
|
+
const blob = new Blob([data.content], { type: data.type || 'text/plain' });
|
|
36
|
+
const file = new File([blob], data.name, {
|
|
37
|
+
type: data.type || 'text/plain',
|
|
38
|
+
lastModified: data.lastModified || Date.now()
|
|
39
|
+
});
|
|
40
|
+
// Add webkitRelativePath if provided (for directory uploads)
|
|
41
|
+
if (data.webkitRelativePath) {
|
|
42
|
+
Object.defineProperty(file, 'webkitRelativePath', {
|
|
43
|
+
value: data.webkitRelativePath,
|
|
44
|
+
writable: false,
|
|
45
|
+
configurable: true
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// Ensure text() method works properly
|
|
49
|
+
if (!file.text || typeof file.text !== 'function') {
|
|
50
|
+
Object.defineProperty(file, 'text', {
|
|
51
|
+
value: () => Promise.resolve(data.content),
|
|
52
|
+
writable: false,
|
|
53
|
+
configurable: true
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return file;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Create a mock FileList using DataTransfer API
|
|
60
|
+
* This is the most reliable method for creating FileList objects in tests
|
|
61
|
+
*/
|
|
62
|
+
function createMockFileList(files) {
|
|
63
|
+
// Use DataTransfer to create a proper FileList
|
|
64
|
+
const dt = new DataTransfer();
|
|
65
|
+
files.forEach((fileData) => {
|
|
66
|
+
const file = createMockFile(fileData);
|
|
67
|
+
dt.items.add(file);
|
|
68
|
+
});
|
|
69
|
+
return dt.files;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create a mock FileList for directory upload simulation
|
|
73
|
+
* Includes webkitRelativePath for each file
|
|
74
|
+
*/
|
|
75
|
+
function createMockDirectoryFileList(directoryStructure) {
|
|
76
|
+
const files = directoryStructure.map((item) => ({
|
|
77
|
+
name: item.path.split('/').pop() || '',
|
|
78
|
+
content: item.content,
|
|
79
|
+
type: item.type,
|
|
80
|
+
webkitRelativePath: item.path
|
|
81
|
+
}));
|
|
82
|
+
return createMockFileList(files);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Helper to create a promise that resolves after a delay
|
|
86
|
+
* Useful for testing async operations
|
|
87
|
+
*/
|
|
88
|
+
function delay(ms) {
|
|
89
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Helper to verify File API text() method works correctly
|
|
93
|
+
* Since we're using Blob/File polyfills, this ensures they have the right methods
|
|
94
|
+
*/
|
|
95
|
+
async function verifyFileAPI(file) {
|
|
96
|
+
try {
|
|
97
|
+
// Check if text() method exists and works
|
|
98
|
+
if (typeof file.text !== 'function') {
|
|
99
|
+
throw new Error('File.text() method not available');
|
|
100
|
+
}
|
|
101
|
+
const text = await file.text();
|
|
102
|
+
return typeof text === 'string';
|
|
103
|
+
}
|
|
104
|
+
catch (_a) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Mock Web Crypto digest result for testing
|
|
110
|
+
* Creates a deterministic hash-like ArrayBuffer
|
|
111
|
+
*/
|
|
112
|
+
function createMockDigest(input, algorithm = 'SHA-256') {
|
|
113
|
+
// Create a deterministic "hash" based on input for testing
|
|
114
|
+
// This is not a real hash but good enough for testing
|
|
115
|
+
const hashLength = algorithm.includes('256') ? 32 : algorithm.includes('512') ? 64 : 20;
|
|
116
|
+
const buffer = new ArrayBuffer(hashLength);
|
|
117
|
+
const view = new Uint8Array(buffer);
|
|
118
|
+
// Fill with deterministic values based on input
|
|
119
|
+
for (let i = 0; i < hashLength; i++) {
|
|
120
|
+
view[i] = (input.charCodeAt(i % input.length) + i) % 256;
|
|
121
|
+
}
|
|
122
|
+
return buffer;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Convert ArrayBuffer to hex string for comparison in tests
|
|
126
|
+
*/
|
|
127
|
+
function arrayBufferToHex(buffer) {
|
|
128
|
+
const view = new Uint8Array(buffer);
|
|
129
|
+
return Array.from(view)
|
|
130
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
131
|
+
.join('');
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=testHelpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testHelpers.js","sourceRoot":"","sources":["../../../src/test/utils/testHelpers.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n/**\n * Test utilities for mocking browser APIs\n */\n\n/**\n * Mock file data structure\n */\nexport interface MockFileData {\n name: string;\n content: string;\n type?: string;\n lastModified?: number;\n webkitRelativePath?: string;\n}\n\n/**\n * Create a mock File object with all necessary properties and methods\n */\nexport function createMockFile(data: MockFileData): File {\n const blob = new Blob([data.content], { type: data.type || 'text/plain' });\n const file = new File([blob], data.name, {\n type: data.type || 'text/plain',\n lastModified: data.lastModified || Date.now()\n });\n\n // Add webkitRelativePath if provided (for directory uploads)\n if (data.webkitRelativePath) {\n Object.defineProperty(file, 'webkitRelativePath', {\n value: data.webkitRelativePath,\n writable: false,\n configurable: true\n });\n }\n\n // Ensure text() method works properly\n if (!file.text || typeof file.text !== 'function') {\n Object.defineProperty(file, 'text', {\n value: () => Promise.resolve(data.content),\n writable: false,\n configurable: true\n });\n }\n\n return file;\n}\n\n/**\n * Create a mock FileList using DataTransfer API\n * This is the most reliable method for creating FileList objects in tests\n */\nexport function createMockFileList(files: MockFileData[]): FileList {\n // Use DataTransfer to create a proper FileList\n const dt = new DataTransfer();\n\n files.forEach((fileData) => {\n const file = createMockFile(fileData);\n dt.items.add(file);\n });\n\n return dt.files;\n}\n\n/**\n * Create a mock FileList for directory upload simulation\n * Includes webkitRelativePath for each file\n */\nexport function createMockDirectoryFileList(\n directoryStructure: Array<{ path: string; content: string; type?: string }>\n): FileList {\n const files = directoryStructure.map((item) => ({\n name: item.path.split('/').pop() || '',\n content: item.content,\n type: item.type,\n webkitRelativePath: item.path\n }));\n\n return createMockFileList(files);\n}\n\n/**\n * Helper to create a promise that resolves after a delay\n * Useful for testing async operations\n */\nexport function delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Helper to verify File API text() method works correctly\n * Since we're using Blob/File polyfills, this ensures they have the right methods\n */\nexport async function verifyFileAPI(file: File): Promise<boolean> {\n try {\n // Check if text() method exists and works\n if (typeof file.text !== 'function') {\n throw new Error('File.text() method not available');\n }\n\n const text = await file.text();\n return typeof text === 'string';\n } catch {\n return false;\n }\n}\n\n/**\n * Mock Web Crypto digest result for testing\n * Creates a deterministic hash-like ArrayBuffer\n */\nexport function createMockDigest(input: string, algorithm: string = 'SHA-256'): ArrayBuffer {\n // Create a deterministic \"hash\" based on input for testing\n // This is not a real hash but good enough for testing\n const hashLength = algorithm.includes('256') ? 32 : algorithm.includes('512') ? 64 : 20;\n const buffer = new ArrayBuffer(hashLength);\n const view = new Uint8Array(buffer);\n\n // Fill with deterministic values based on input\n for (let i = 0; i < hashLength; i++) {\n view[i] = (input.charCodeAt(i % input.length) + i) % 256;\n }\n\n return buffer;\n}\n\n/**\n * Convert ArrayBuffer to hex string for comparison in tests\n */\nexport function arrayBufferToHex(buffer: ArrayBuffer): string {\n const view = new Uint8Array(buffer);\n return Array.from(view)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fgv/ts-web-extras",
|
|
3
|
+
"version": "5.0.0",
|
|
4
|
+
"description": "Browser-compatible utilities and FileTree implementations",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "dist/ts-web-extras.d.ts",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"keywords": [
|
|
9
|
+
"browser",
|
|
10
|
+
"web",
|
|
11
|
+
"filetree",
|
|
12
|
+
"crypto",
|
|
13
|
+
"typescript"
|
|
14
|
+
],
|
|
15
|
+
"author": "Erik Fortune",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/ErikFortune/fgv/issues"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/ErikFortune/fgv/tree/main/libraries/ts-web-extras#readme",
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@microsoft/api-documenter": "^7.26.31",
|
|
23
|
+
"@microsoft/api-extractor": "^7.52.10",
|
|
24
|
+
"@types/jest": "^29.5.14",
|
|
25
|
+
"@types/node": "^20.14.9",
|
|
26
|
+
"@typescript-eslint/eslint-plugin": "^8.42.0",
|
|
27
|
+
"@typescript-eslint/parser": "^8.42.0",
|
|
28
|
+
"eslint": "^9.35.0",
|
|
29
|
+
"eslint-plugin-import": "^2.32.0",
|
|
30
|
+
"eslint-plugin-node": "^11.1.0",
|
|
31
|
+
"eslint-plugin-promise": "^7.2.1",
|
|
32
|
+
"jest": "^29.7.0",
|
|
33
|
+
"jest-extended": "^4.0.2",
|
|
34
|
+
"rimraf": "^6.0.1",
|
|
35
|
+
"ts-jest": "^29.4.1",
|
|
36
|
+
"ts-node": "^10.9.2",
|
|
37
|
+
"typescript": "5.8.3",
|
|
38
|
+
"eslint-plugin-n": "^17.21.3",
|
|
39
|
+
"@rushstack/eslint-config": "4.4.0",
|
|
40
|
+
"@rushstack/heft": "0.74.4",
|
|
41
|
+
"@rushstack/heft-jest-plugin": "0.16.13",
|
|
42
|
+
"@rushstack/heft-node-rig": "2.9.5",
|
|
43
|
+
"@types/heft-jest": "1.0.6",
|
|
44
|
+
"eslint-plugin-tsdoc": "~0.4.0",
|
|
45
|
+
"@rushstack/eslint-patch": "~1.12.0",
|
|
46
|
+
"@types/react": "~19.1.10",
|
|
47
|
+
"@fgv/ts-utils": "5.0.0-31",
|
|
48
|
+
"@fgv/ts-json-base": "5.0.0-31",
|
|
49
|
+
"@fgv/ts-utils-jest": "5.0.0-31"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"react": "~19.1.1",
|
|
53
|
+
"@fgv/ts-utils": "5.0.0-31",
|
|
54
|
+
"@fgv/ts-json-base": "5.0.0-31"
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "heft test --clean",
|
|
58
|
+
"clean": "heft clean",
|
|
59
|
+
"test": "heft test --clean",
|
|
60
|
+
"build-docs": "api-documenter markdown --input-folder ./temp --output-folder docs",
|
|
61
|
+
"build-all": "rushx build; rushx build-docs",
|
|
62
|
+
"test-handles": "jest --runInBand --detectOpenHandles",
|
|
63
|
+
"clean-jest": "jest --clear-cache",
|
|
64
|
+
"coverage": "jest --coverage",
|
|
65
|
+
"lint": "eslint src --ext .ts",
|
|
66
|
+
"fixlint": "eslint src --ext .ts --fix"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
Invoking: heft test --clean
|
|
2
|
+
---- build started ----
|
|
3
|
+
[build:typescript] Using TypeScript version 5.8.3
|
|
4
|
+
[build:api-extractor] Using API Extractor version 7.52.12
|
|
5
|
+
[build:api-extractor] Analysis will use the bundled TypeScript version 5.8.2
|
|
6
|
+
---- build finished (23.041s) ----
|
|
7
|
+
---- test started ----
|
|
8
|
+
[test:jest] Using Jest version 29.5.0
|
|
9
|
+
[test:jest]
|
|
10
|
+
[test:jest] Run start. 5 test suites
|
|
11
|
+
[test:jest] START lib/test/unit/fileApiTreeAccessors.test.js
|
|
12
|
+
[test:jest] START lib/test/unit/fileTreeHelpers.test.js
|
|
13
|
+
[test:jest] START lib/test/unit/fileApiTypes.test.js
|
|
14
|
+
[test:jest] START lib/test/unit/urlParams.test.js
|
|
15
|
+
[test:jest] PASS lib/test/unit/fileApiTreeAccessors.test.js (duration: 1.740s, 63 passed, 0 failed)
|
|
16
|
+
[test:jest] START lib/test/unit/browserHashProvider.test.js
|
|
17
|
+
[test:jest] PASS lib/test/unit/urlParams.test.js (duration: 0.589s, 60 passed, 0 failed)
|
|
18
|
+
[test:jest] PASS lib/test/unit/fileApiTypes.test.js (duration: 1.906s, 33 passed, 0 failed)
|
|
19
|
+
[test:jest] PASS lib/test/unit/fileTreeHelpers.test.js (duration: 2.165s, 35 passed, 0 failed)
|
|
20
|
+
[test:jest] PASS lib/test/unit/browserHashProvider.test.js (duration: 0.609s, 15 passed, 0 failed)
|
|
21
|
+
[test:jest]
|
|
22
|
+
[test:jest] Tests finished:
|
|
23
|
+
[test:jest] Successes: 206
|
|
24
|
+
[test:jest] Failures: 0
|
|
25
|
+
[test:jest] Total: 207
|
|
26
|
+
--------------------------|---------|----------|---------|---------|-------------------
|
|
27
|
+
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
|
|
28
|
+
--------------------------|---------|----------|---------|---------|-------------------
|
|
29
|
+
All files | 100 | 100 | 100 | 100 |
|
|
30
|
+
crypto | 100 | 100 | 100 | 100 |
|
|
31
|
+
browserHashProvider.ts | 100 | 100 | 100 | 100 |
|
|
32
|
+
file-tree | 100 | 100 | 100 | 100 |
|
|
33
|
+
fileApiTreeAccessors.ts | 100 | 100 | 100 | 100 |
|
|
34
|
+
helpers | 100 | 100 | 100 | 100 |
|
|
35
|
+
fileTreeHelpers.ts | 100 | 100 | 100 | 100 |
|
|
36
|
+
url-utils | 100 | 100 | 100 | 100 |
|
|
37
|
+
urlParams.ts | 100 | 100 | 100 | 100 |
|
|
38
|
+
--------------------------|---------|----------|---------|---------|-------------------
|
|
39
|
+
---- test finished (5.486s) ----
|
|
40
|
+
-------------------- Finished (28.542s) --------------------
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 Erik Fortune
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Browser-compatible utilities and FileTree implementations.
|
|
25
|
+
*
|
|
26
|
+
* This library provides browser-compatible alternatives to Node.js-specific functionality,
|
|
27
|
+
* including Web Crypto API-based hashing, File API-based file tree implementations,
|
|
28
|
+
* and URL parameter parsing utilities.
|
|
29
|
+
* All exports are designed to be tree-shakeable for optimal bundle size.
|
|
30
|
+
*
|
|
31
|
+
* @packageDocumentation
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
// Export crypto functionality
|
|
35
|
+
export * from './packlets/crypto';
|
|
36
|
+
|
|
37
|
+
// Export file tree functionality
|
|
38
|
+
export * from './packlets/file-tree';
|
|
39
|
+
|
|
40
|
+
// Export helper functions
|
|
41
|
+
export * from './packlets/helpers';
|
|
42
|
+
|
|
43
|
+
// Export File System Access API types
|
|
44
|
+
export * from './packlets/file-api-types';
|
|
45
|
+
|
|
46
|
+
// Export URL utilities
|
|
47
|
+
export * from './packlets/url-utils';
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 Erik Fortune
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { Result, succeed, fail } from '@fgv/ts-utils';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Browser-compatible hash provider using the Web Crypto API.
|
|
27
|
+
* Supports common hash algorithms available in browsers.
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export class BrowserHashProvider {
|
|
31
|
+
/**
|
|
32
|
+
* Hash a string using the specified algorithm.
|
|
33
|
+
* @param data - The string to hash
|
|
34
|
+
* @param algorithm - The hash algorithm to use
|
|
35
|
+
* @returns Promise resolving to the hex-encoded hash
|
|
36
|
+
*/
|
|
37
|
+
public static async hashString(data: string, algorithm: string = 'SHA-256'): Promise<Result<string>> {
|
|
38
|
+
try {
|
|
39
|
+
/* c8 ignore next 3 - defense in depth */
|
|
40
|
+
if (!crypto.subtle) {
|
|
41
|
+
return fail('Web Crypto API not available in this environment');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const encoder = new TextEncoder();
|
|
45
|
+
const dataBuffer = encoder.encode(data);
|
|
46
|
+
const hashBuffer = await crypto.subtle.digest(algorithm, dataBuffer);
|
|
47
|
+
const hashArray = new Uint8Array(hashBuffer);
|
|
48
|
+
const hashHex = Array.from(hashArray)
|
|
49
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
50
|
+
.join('');
|
|
51
|
+
|
|
52
|
+
return succeed(hashHex);
|
|
53
|
+
} catch (error) {
|
|
54
|
+
return fail(`Hash computation failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Hash multiple strings concatenated with a separator.
|
|
60
|
+
* @param parts - Array of strings to concatenate and hash
|
|
61
|
+
* @param algorithm - The hash algorithm to use
|
|
62
|
+
* @param separator - Separator to use between parts (default: '|')
|
|
63
|
+
* @returns Promise resolving to the hex-encoded hash
|
|
64
|
+
*/
|
|
65
|
+
public static async hashParts(
|
|
66
|
+
parts: string[],
|
|
67
|
+
algorithm: string = 'SHA-256',
|
|
68
|
+
separator: string = '|'
|
|
69
|
+
): Promise<Result<string>> {
|
|
70
|
+
const combined = parts.join(separator);
|
|
71
|
+
return this.hashString(combined, algorithm);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 Erik Fortune
|
|
3
|
+
*
|
|
4
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
* in the Software without restriction, including without limitation the rights
|
|
7
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
* furnished to do so, subject to the following conditions:
|
|
10
|
+
*
|
|
11
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
* copies or substantial portions of the Software.
|
|
13
|
+
*
|
|
14
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
* SOFTWARE.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Browser-compatible cryptographic utilities using the Web Crypto API.
|
|
25
|
+
* @packageDocumentation
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
export * from './browserHashProvider';
|