@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 CHANGED
@@ -71,6 +71,7 @@ export declare class File {
71
71
  toJSON(): FileData;
72
72
  static getCacheDir(): string;
73
73
  private _getCachePath;
74
+ private _decodeDataUri;
74
75
  private _downloadUrl;
75
76
  private _populateMetadata;
76
77
  }
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 (isUrl(file.uri)) {
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inferencesh/app",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "App framework for building inference.sh apps — File handling, output metadata, storage utilities",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",