@net-protocol/storage 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -224,6 +224,9 @@ import {
224
224
  assembleChunks,
225
225
  parseNetReferences,
226
226
  processDataForStorage,
227
+ fileToDataUri,
228
+ detectFileTypeFromBase64,
229
+ base64ToDataUri,
227
230
  } from "@net-protocol/storage";
228
231
 
229
232
  // Generate storage key bytes
@@ -242,6 +245,32 @@ const references = parseNetReferences('<net k="hash" v="0.0.1" />');
242
245
  const result = processDataForStorage(data, operatorAddress);
243
246
  ```
244
247
 
248
+ ### File Utilities
249
+
250
+ ```typescript
251
+ import {
252
+ fileToDataUri,
253
+ detectFileTypeFromBase64,
254
+ base64ToDataUri,
255
+ } from "@net-protocol/storage";
256
+
257
+ // Convert File/Blob to data URI (browser-only)
258
+ // Note: fileToDataUri requires browser APIs (FileReader) and should only be used in browser environments
259
+ const file = event.target.files[0];
260
+ const dataUri = await fileToDataUri(file);
261
+ // Returns: "data:application/pdf;base64,JVBERi0xLjQK..."
262
+
263
+ // Detect file type from raw base64 data (works in both browser and Node.js)
264
+ const base64Data = "JVBERi0xLjQK..."; // Raw base64 without prefix
265
+ const mimeType = detectFileTypeFromBase64(base64Data);
266
+ // Returns: "application/pdf"
267
+
268
+ // Convert raw base64 to data URI with automatic type detection (works in both browser and Node.js)
269
+ const dataUri = base64ToDataUri(base64Data);
270
+ // Returns: "data:application/pdf;base64,JVBERi0xLjQK..."
271
+ // Falls back to "application/octet-stream" if type cannot be detected
272
+ ```
273
+
245
274
  ## API Reference
246
275
 
247
276
  ### React Hooks
package/dist/index.d.mts CHANGED
@@ -484,6 +484,56 @@ declare function processDataForStorage(data: string, operatorAddress: string, st
484
484
  error?: string;
485
485
  };
486
486
 
487
+ /**
488
+ * File utilities for converting files to data URIs and detecting file types from base64 data.
489
+ */
490
+ /**
491
+ * Converts a File or Blob to a data URI string.
492
+ * Uses FileReader API to read the file and returns the full data URI including prefix.
493
+ *
494
+ * @param file - The File or Blob object to convert
495
+ * @returns Promise that resolves to a data URI string (e.g., "data:application/pdf;base64,...")
496
+ * @throws Error if FileReader fails to read the file
497
+ *
498
+ * @example
499
+ * ```typescript
500
+ * const file = event.target.files[0];
501
+ * const dataUri = await fileToDataUri(file);
502
+ * // Returns: "data:application/pdf;base64,JVBERi0xLjQK..."
503
+ * ```
504
+ */
505
+ declare function fileToDataUri(file: File | Blob): Promise<string>;
506
+ /**
507
+ * Detects the MIME type from raw base64 data by checking magic bytes (file signatures).
508
+ * Supports common file types: PDF, PNG, JPEG, GIF, WebP, SVG, HTML, MP3, MP4, ZIP, JSON.
509
+ *
510
+ * @param base64Data - Raw base64 string (without data URI prefix)
511
+ * @returns MIME type string (e.g., "application/pdf") or undefined if type cannot be detected
512
+ *
513
+ * @example
514
+ * ```typescript
515
+ * const base64Data = "JVBERi0xLjQK..."; // Raw PDF base64
516
+ * const mimeType = detectFileTypeFromBase64(base64Data);
517
+ * // Returns: "application/pdf"
518
+ * ```
519
+ */
520
+ declare function detectFileTypeFromBase64(base64Data: string): string | undefined;
521
+ /**
522
+ * Converts raw base64 data to a data URI by detecting the file type and adding the appropriate prefix.
523
+ * Falls back to "application/octet-stream" if the file type cannot be detected.
524
+ *
525
+ * @param base64Data - Raw base64 string (without data URI prefix)
526
+ * @returns Complete data URI string (e.g., "data:application/pdf;base64,...")
527
+ *
528
+ * @example
529
+ * ```typescript
530
+ * const base64Data = "JVBERi0xLjQK..."; // Raw PDF base64
531
+ * const dataUri = base64ToDataUri(base64Data);
532
+ * // Returns: "data:application/pdf;base64,JVBERi0xLjQK..."
533
+ * ```
534
+ */
535
+ declare function base64ToDataUri(base64Data: string): string;
536
+
487
537
  declare const STORAGE_CONTRACT: {
488
538
  abi: Abi;
489
539
  address: `0x${string}`;
@@ -519,4 +569,4 @@ declare const CONCURRENT_XML_FETCHES = 3;
519
569
  */
520
570
  declare function resolveXmlRecursive(content: string, defaultOperator: string, client: PublicClient, maxDepth: number, visited?: Set<string>, inheritedOperator?: string): Promise<string>;
521
571
 
522
- export { type BulkStorageKey, CHUNKED_STORAGE_CONTRACT, CHUNKED_STORAGE_READER_CONTRACT, CONCURRENT_XML_FETCHES, type ChunkedMetadata, MAX_XML_DEPTH, SAFE_STORAGE_READER_CONTRACT, STORAGE_CONTRACT, STORAGE_ROUTER_CONTRACT, StorageClient, type StorageClientOptions, type StorageData, type UseStorageOptions, type UseXmlStorageOptions, type XmlReference$1 as XmlReference, assembleChunks, chunkData, chunkDataForStorage, computeTopLevelHash, containsXmlReferences, detectStorageType, encodeStorageKeyForUrl, formatStorageKeyForDisplay, generateStorageEmbedTag, generateXmlMetadata, generateXmlMetadataWithSource, getChunkCount, getReferenceKey, getStorageKeyBytes, parseNetReferences, processDataForStorage, resolveOperator, resolveXmlRecursive, shouldSuggestXmlStorage, useBulkStorage, useStorage, useStorageForOperator, useStorageForOperatorAndKey, useStorageFromRouter, useStorageTotalWrites, useXmlStorage, validateDataSize };
572
+ export { type BulkStorageKey, CHUNKED_STORAGE_CONTRACT, CHUNKED_STORAGE_READER_CONTRACT, CONCURRENT_XML_FETCHES, type ChunkedMetadata, MAX_XML_DEPTH, SAFE_STORAGE_READER_CONTRACT, STORAGE_CONTRACT, STORAGE_ROUTER_CONTRACT, StorageClient, type StorageClientOptions, type StorageData, type UseStorageOptions, type UseXmlStorageOptions, type XmlReference$1 as XmlReference, assembleChunks, base64ToDataUri, chunkData, chunkDataForStorage, computeTopLevelHash, containsXmlReferences, detectFileTypeFromBase64, detectStorageType, encodeStorageKeyForUrl, fileToDataUri, formatStorageKeyForDisplay, generateStorageEmbedTag, generateXmlMetadata, generateXmlMetadataWithSource, getChunkCount, getReferenceKey, getStorageKeyBytes, parseNetReferences, processDataForStorage, resolveOperator, resolveXmlRecursive, shouldSuggestXmlStorage, useBulkStorage, useStorage, useStorageForOperator, useStorageForOperatorAndKey, useStorageFromRouter, useStorageTotalWrites, useXmlStorage, validateDataSize };
package/dist/index.d.ts CHANGED
@@ -484,6 +484,56 @@ declare function processDataForStorage(data: string, operatorAddress: string, st
484
484
  error?: string;
485
485
  };
486
486
 
487
+ /**
488
+ * File utilities for converting files to data URIs and detecting file types from base64 data.
489
+ */
490
+ /**
491
+ * Converts a File or Blob to a data URI string.
492
+ * Uses FileReader API to read the file and returns the full data URI including prefix.
493
+ *
494
+ * @param file - The File or Blob object to convert
495
+ * @returns Promise that resolves to a data URI string (e.g., "data:application/pdf;base64,...")
496
+ * @throws Error if FileReader fails to read the file
497
+ *
498
+ * @example
499
+ * ```typescript
500
+ * const file = event.target.files[0];
501
+ * const dataUri = await fileToDataUri(file);
502
+ * // Returns: "data:application/pdf;base64,JVBERi0xLjQK..."
503
+ * ```
504
+ */
505
+ declare function fileToDataUri(file: File | Blob): Promise<string>;
506
+ /**
507
+ * Detects the MIME type from raw base64 data by checking magic bytes (file signatures).
508
+ * Supports common file types: PDF, PNG, JPEG, GIF, WebP, SVG, HTML, MP3, MP4, ZIP, JSON.
509
+ *
510
+ * @param base64Data - Raw base64 string (without data URI prefix)
511
+ * @returns MIME type string (e.g., "application/pdf") or undefined if type cannot be detected
512
+ *
513
+ * @example
514
+ * ```typescript
515
+ * const base64Data = "JVBERi0xLjQK..."; // Raw PDF base64
516
+ * const mimeType = detectFileTypeFromBase64(base64Data);
517
+ * // Returns: "application/pdf"
518
+ * ```
519
+ */
520
+ declare function detectFileTypeFromBase64(base64Data: string): string | undefined;
521
+ /**
522
+ * Converts raw base64 data to a data URI by detecting the file type and adding the appropriate prefix.
523
+ * Falls back to "application/octet-stream" if the file type cannot be detected.
524
+ *
525
+ * @param base64Data - Raw base64 string (without data URI prefix)
526
+ * @returns Complete data URI string (e.g., "data:application/pdf;base64,...")
527
+ *
528
+ * @example
529
+ * ```typescript
530
+ * const base64Data = "JVBERi0xLjQK..."; // Raw PDF base64
531
+ * const dataUri = base64ToDataUri(base64Data);
532
+ * // Returns: "data:application/pdf;base64,JVBERi0xLjQK..."
533
+ * ```
534
+ */
535
+ declare function base64ToDataUri(base64Data: string): string;
536
+
487
537
  declare const STORAGE_CONTRACT: {
488
538
  abi: Abi;
489
539
  address: `0x${string}`;
@@ -519,4 +569,4 @@ declare const CONCURRENT_XML_FETCHES = 3;
519
569
  */
520
570
  declare function resolveXmlRecursive(content: string, defaultOperator: string, client: PublicClient, maxDepth: number, visited?: Set<string>, inheritedOperator?: string): Promise<string>;
521
571
 
522
- export { type BulkStorageKey, CHUNKED_STORAGE_CONTRACT, CHUNKED_STORAGE_READER_CONTRACT, CONCURRENT_XML_FETCHES, type ChunkedMetadata, MAX_XML_DEPTH, SAFE_STORAGE_READER_CONTRACT, STORAGE_CONTRACT, STORAGE_ROUTER_CONTRACT, StorageClient, type StorageClientOptions, type StorageData, type UseStorageOptions, type UseXmlStorageOptions, type XmlReference$1 as XmlReference, assembleChunks, chunkData, chunkDataForStorage, computeTopLevelHash, containsXmlReferences, detectStorageType, encodeStorageKeyForUrl, formatStorageKeyForDisplay, generateStorageEmbedTag, generateXmlMetadata, generateXmlMetadataWithSource, getChunkCount, getReferenceKey, getStorageKeyBytes, parseNetReferences, processDataForStorage, resolveOperator, resolveXmlRecursive, shouldSuggestXmlStorage, useBulkStorage, useStorage, useStorageForOperator, useStorageForOperatorAndKey, useStorageFromRouter, useStorageTotalWrites, useXmlStorage, validateDataSize };
572
+ export { type BulkStorageKey, CHUNKED_STORAGE_CONTRACT, CHUNKED_STORAGE_READER_CONTRACT, CONCURRENT_XML_FETCHES, type ChunkedMetadata, MAX_XML_DEPTH, SAFE_STORAGE_READER_CONTRACT, STORAGE_CONTRACT, STORAGE_ROUTER_CONTRACT, StorageClient, type StorageClientOptions, type StorageData, type UseStorageOptions, type UseXmlStorageOptions, type XmlReference$1 as XmlReference, assembleChunks, base64ToDataUri, chunkData, chunkDataForStorage, computeTopLevelHash, containsXmlReferences, detectFileTypeFromBase64, detectStorageType, encodeStorageKeyForUrl, fileToDataUri, formatStorageKeyForDisplay, generateStorageEmbedTag, generateXmlMetadata, generateXmlMetadataWithSource, getChunkCount, getReferenceKey, getStorageKeyBytes, parseNetReferences, processDataForStorage, resolveOperator, resolveXmlRecursive, shouldSuggestXmlStorage, useBulkStorage, useStorage, useStorageForOperator, useStorageForOperatorAndKey, useStorageFromRouter, useStorageTotalWrites, useXmlStorage, validateDataSize };
package/dist/index.js CHANGED
@@ -2072,6 +2072,110 @@ var StorageClient = class {
2072
2072
  }
2073
2073
  };
2074
2074
 
2075
+ // src/utils/fileUtils.ts
2076
+ var PDF_MAGIC_BYTES = "JVBERi";
2077
+ var PNG_MAGIC_BYTES = "iVBORw0KGgo";
2078
+ var JPEG_MAGIC_BYTES = "/9j/";
2079
+ var GIF_MAGIC_BYTES = "R0lGODlh";
2080
+ var WEBP_MAGIC_BYTES = "UklGRi";
2081
+ var ZIP_MAGIC_BYTES = "UEsDB";
2082
+ function fileToDataUri(file) {
2083
+ return new Promise((resolve, reject) => {
2084
+ const reader = new FileReader();
2085
+ reader.onloadend = () => {
2086
+ const result = reader.result;
2087
+ if (typeof result === "string") {
2088
+ resolve(result);
2089
+ } else {
2090
+ reject(new Error("FileReader did not return a string result"));
2091
+ }
2092
+ };
2093
+ reader.onerror = () => {
2094
+ reject(new Error("Failed to read file"));
2095
+ };
2096
+ reader.readAsDataURL(file);
2097
+ });
2098
+ }
2099
+ function detectFileTypeFromBase64(base64Data) {
2100
+ if (!base64Data || base64Data.length === 0) {
2101
+ return void 0;
2102
+ }
2103
+ try {
2104
+ if (base64Data.startsWith(PDF_MAGIC_BYTES)) {
2105
+ return "application/pdf";
2106
+ }
2107
+ if (base64Data.startsWith(PNG_MAGIC_BYTES)) {
2108
+ return "image/png";
2109
+ }
2110
+ if (base64Data.startsWith(JPEG_MAGIC_BYTES)) {
2111
+ return "image/jpeg";
2112
+ }
2113
+ if (base64Data.startsWith(GIF_MAGIC_BYTES)) {
2114
+ return "image/gif";
2115
+ }
2116
+ if (base64Data.startsWith(WEBP_MAGIC_BYTES) && base64Data.length >= 20) {
2117
+ try {
2118
+ const decoded = atob(base64Data.substring(0, 20));
2119
+ if (decoded.includes("WEBP")) {
2120
+ return "image/webp";
2121
+ }
2122
+ } catch {
2123
+ }
2124
+ }
2125
+ if (base64Data.length > 10) {
2126
+ try {
2127
+ const decoded = atob(base64Data.substring(0, Math.min(200, base64Data.length)));
2128
+ if (decoded.includes("<svg") || decoded.includes("<SVG")) {
2129
+ return "image/svg+xml";
2130
+ }
2131
+ } catch {
2132
+ }
2133
+ }
2134
+ if (base64Data.length > 10) {
2135
+ try {
2136
+ const decoded = atob(base64Data.substring(0, Math.min(200, base64Data.length)));
2137
+ const lowerDecoded = decoded.toLowerCase();
2138
+ if (lowerDecoded.includes("<html") || lowerDecoded.includes("<!doctype")) {
2139
+ return "text/html";
2140
+ }
2141
+ } catch {
2142
+ }
2143
+ }
2144
+ if (base64Data.startsWith("SUQz") || base64Data.startsWith("/9s=")) {
2145
+ return "audio/mpeg";
2146
+ }
2147
+ if (base64Data.length > 20) {
2148
+ try {
2149
+ const decoded = atob(base64Data.substring(0, Math.min(50, base64Data.length)));
2150
+ if (decoded.includes("ftyp")) {
2151
+ return "video/mp4";
2152
+ }
2153
+ } catch {
2154
+ }
2155
+ }
2156
+ if (base64Data.startsWith(ZIP_MAGIC_BYTES)) {
2157
+ return "application/zip";
2158
+ }
2159
+ if (base64Data.length > 2) {
2160
+ try {
2161
+ const decoded = atob(base64Data.substring(0, Math.min(10, base64Data.length)));
2162
+ const trimmed = decoded.trim();
2163
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
2164
+ return "application/json";
2165
+ }
2166
+ } catch {
2167
+ }
2168
+ }
2169
+ return void 0;
2170
+ } catch (error) {
2171
+ return void 0;
2172
+ }
2173
+ }
2174
+ function base64ToDataUri(base64Data) {
2175
+ const mimeType = detectFileTypeFromBase64(base64Data) || "application/octet-stream";
2176
+ return `data:${mimeType};base64,${base64Data}`;
2177
+ }
2178
+
2075
2179
  exports.CHUNKED_STORAGE_CONTRACT = CHUNKED_STORAGE_CONTRACT;
2076
2180
  exports.CHUNKED_STORAGE_READER_CONTRACT = CHUNKED_STORAGE_READER_CONTRACT;
2077
2181
  exports.CONCURRENT_XML_FETCHES = CONCURRENT_XML_FETCHES;
@@ -2081,12 +2185,15 @@ exports.STORAGE_CONTRACT = STORAGE_CONTRACT;
2081
2185
  exports.STORAGE_ROUTER_CONTRACT = STORAGE_ROUTER_CONTRACT;
2082
2186
  exports.StorageClient = StorageClient;
2083
2187
  exports.assembleChunks = assembleChunks;
2188
+ exports.base64ToDataUri = base64ToDataUri;
2084
2189
  exports.chunkData = chunkData;
2085
2190
  exports.chunkDataForStorage = chunkDataForStorage;
2086
2191
  exports.computeTopLevelHash = computeTopLevelHash;
2087
2192
  exports.containsXmlReferences = containsXmlReferences;
2193
+ exports.detectFileTypeFromBase64 = detectFileTypeFromBase64;
2088
2194
  exports.detectStorageType = detectStorageType;
2089
2195
  exports.encodeStorageKeyForUrl = encodeStorageKeyForUrl;
2196
+ exports.fileToDataUri = fileToDataUri;
2090
2197
  exports.formatStorageKeyForDisplay = formatStorageKeyForDisplay;
2091
2198
  exports.generateStorageEmbedTag = generateStorageEmbedTag;
2092
2199
  exports.generateXmlMetadata = generateXmlMetadata;