@inferencesh/app 0.1.3 → 0.1.4
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/file.d.ts +1 -0
- package/dist/file.js +85 -2
- package/package.json +1 -1
package/dist/file.d.ts
CHANGED
package/dist/file.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { createWriteStream, existsSync, mkdirSync, statSync, renameSync, unlinkSync } from "node:fs";
|
|
2
|
+
import { createWriteStream, existsSync, mkdirSync, statSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { basename, resolve, join } from "node:path";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { get as httpsGet } from "node:https";
|
|
@@ -74,7 +74,10 @@ export class File {
|
|
|
74
74
|
const file = new File(options);
|
|
75
75
|
// Resolve URI
|
|
76
76
|
if (file.uri) {
|
|
77
|
-
if (
|
|
77
|
+
if (isDataUri(file.uri)) {
|
|
78
|
+
file._decodeDataUri(file.uri);
|
|
79
|
+
}
|
|
80
|
+
else if (isUrl(file.uri)) {
|
|
78
81
|
await file._downloadUrl(file.uri);
|
|
79
82
|
}
|
|
80
83
|
else {
|
|
@@ -148,6 +151,32 @@ export class File {
|
|
|
148
151
|
mkdirSync(hashDir, { recursive: true });
|
|
149
152
|
return join(hashDir, fname);
|
|
150
153
|
}
|
|
154
|
+
// --- Data URI ---
|
|
155
|
+
_decodeDataUri(uri) {
|
|
156
|
+
const parsed = parseDataUri(uri);
|
|
157
|
+
// Create cache path based on hash
|
|
158
|
+
const hash = createHash("sha256").update(uri).digest("hex").slice(0, 16);
|
|
159
|
+
const cacheDir = join(File.getCacheDir(), "data_uri", hash);
|
|
160
|
+
// Check for existing cached file
|
|
161
|
+
if (existsSync(cacheDir)) {
|
|
162
|
+
const files = require("node:fs").readdirSync(cacheDir);
|
|
163
|
+
if (files.length > 0) {
|
|
164
|
+
this.path = join(cacheDir, files[0]);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Set content type from data URI
|
|
169
|
+
if (!this.contentType) {
|
|
170
|
+
this.contentType = parsed.mediaType;
|
|
171
|
+
}
|
|
172
|
+
// Write to cache
|
|
173
|
+
mkdirSync(cacheDir, { recursive: true });
|
|
174
|
+
const ext = getExtensionForMimeType(parsed.mediaType);
|
|
175
|
+
const filename = `file${ext}`;
|
|
176
|
+
const cachePath = join(cacheDir, filename);
|
|
177
|
+
writeFileSync(cachePath, parsed.data);
|
|
178
|
+
this.path = cachePath;
|
|
179
|
+
}
|
|
151
180
|
// --- Download ---
|
|
152
181
|
async _downloadUrl(url) {
|
|
153
182
|
const cachePath = this._getCachePath(url);
|
|
@@ -191,6 +220,60 @@ export class File {
|
|
|
191
220
|
function isUrl(s) {
|
|
192
221
|
return s.startsWith("http://") || s.startsWith("https://");
|
|
193
222
|
}
|
|
223
|
+
function isDataUri(s) {
|
|
224
|
+
return s.startsWith("data:");
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Parse a data URI and return the media type and decoded data.
|
|
228
|
+
*
|
|
229
|
+
* Supports formats:
|
|
230
|
+
* - data:image/jpeg;base64,/9j/4AAQ...
|
|
231
|
+
* - data:text/plain,Hello%20World
|
|
232
|
+
* - data:;base64,SGVsbG8= (defaults to text/plain)
|
|
233
|
+
*/
|
|
234
|
+
function parseDataUri(uri) {
|
|
235
|
+
const match = uri.match(/^data:([^;,]*)?(?:;(base64))?,(.*)$/s);
|
|
236
|
+
if (!match) {
|
|
237
|
+
throw new Error("Invalid data URI format");
|
|
238
|
+
}
|
|
239
|
+
const mediaType = match[1] || "text/plain";
|
|
240
|
+
const isBase64 = match[2] === "base64";
|
|
241
|
+
let dataStr = match[3];
|
|
242
|
+
if (isBase64) {
|
|
243
|
+
// Handle URL-safe base64 (- and _ instead of + and /)
|
|
244
|
+
dataStr = dataStr.replace(/-/g, "+").replace(/_/g, "/");
|
|
245
|
+
// Add padding if needed
|
|
246
|
+
const padding = 4 - (dataStr.length % 4);
|
|
247
|
+
if (padding !== 4) {
|
|
248
|
+
dataStr += "=".repeat(padding);
|
|
249
|
+
}
|
|
250
|
+
return { mediaType, data: Buffer.from(dataStr, "base64") };
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
// URL-encoded data
|
|
254
|
+
return { mediaType, data: Buffer.from(decodeURIComponent(dataStr), "utf-8") };
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
const EXTENSION_MAP = {
|
|
258
|
+
"image/jpeg": ".jpg",
|
|
259
|
+
"image/png": ".png",
|
|
260
|
+
"image/gif": ".gif",
|
|
261
|
+
"image/webp": ".webp",
|
|
262
|
+
"image/svg+xml": ".svg",
|
|
263
|
+
"video/mp4": ".mp4",
|
|
264
|
+
"video/webm": ".webm",
|
|
265
|
+
"audio/mpeg": ".mp3",
|
|
266
|
+
"audio/wav": ".wav",
|
|
267
|
+
"audio/ogg": ".ogg",
|
|
268
|
+
"application/pdf": ".pdf",
|
|
269
|
+
"application/json": ".json",
|
|
270
|
+
"text/plain": ".txt",
|
|
271
|
+
"text/html": ".html",
|
|
272
|
+
"text/csv": ".csv",
|
|
273
|
+
};
|
|
274
|
+
function getExtensionForMimeType(mimeType) {
|
|
275
|
+
return EXTENSION_MAP[mimeType] || "";
|
|
276
|
+
}
|
|
194
277
|
function downloadToFile(url, destPath) {
|
|
195
278
|
return new Promise((resolve, reject) => {
|
|
196
279
|
const parsed = new URL(url);
|
package/package.json
CHANGED