artifacty 0.1.2 → 0.2.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/src/server.js CHANGED
@@ -410,12 +410,13 @@ export async function handleRequest({ request, response, store, host, port, secu
410
410
  });
411
411
 
412
412
  if (pathname.endsWith("/raw")) {
413
+ const raw = rawArtifactResponse(artifact);
413
414
  response.writeHead(200, {
414
- "content-type": artifact.version.contentType,
415
+ "content-type": raw.contentType,
415
416
  "cache-control": "no-store",
416
417
  "x-content-type-options": "nosniff"
417
418
  });
418
- response.end(headOnly ? undefined : artifact.content);
419
+ response.end(headOnly ? undefined : raw.body);
419
420
  return;
420
421
  }
421
422
 
@@ -514,6 +515,44 @@ export function sendHtml(response, html, statusCode = 200, headOnly = false, con
514
515
  response.end(headOnly ? undefined : html);
515
516
  }
516
517
 
518
+ function rawArtifactResponse(artifact) {
519
+ if (artifact.version.format === "image" || artifact.version.format === "video") {
520
+ const decoded = decodeMediaContent(artifact.content);
521
+ if (decoded) {
522
+ return {
523
+ body: decoded,
524
+ contentType: mediaContentType(artifact)
525
+ };
526
+ }
527
+ }
528
+ return {
529
+ body: artifact.content,
530
+ contentType: artifact.version.contentType
531
+ };
532
+ }
533
+
534
+ function mediaContentType(artifact) {
535
+ const metadataType = String(artifact.version.metadata?.mimeType || "").toLowerCase();
536
+ if (metadataType.startsWith("image/") || metadataType.startsWith("video/")) {
537
+ return metadataType;
538
+ }
539
+ const versionType = String(artifact.version.contentType || "").toLowerCase().split(";")[0];
540
+ if (versionType.startsWith("image/") || versionType.startsWith("video/")) {
541
+ return versionType;
542
+ }
543
+ return artifact.version.format === "video" ? "video/mp4" : "image/png";
544
+ }
545
+
546
+ function decodeMediaContent(content) {
547
+ const value = String(content || "").trim();
548
+ const dataUrl = /^data:[^;,]+;base64,([A-Za-z0-9+/=_-\s]+)$/i.exec(value);
549
+ const base64 = (dataUrl ? dataUrl[1] : value).replace(/\s+/g, "").replaceAll("-", "+").replaceAll("_", "/");
550
+ if (!base64 || !/^[A-Za-z0-9+/]+={0,2}$/.test(base64)) {
551
+ return null;
552
+ }
553
+ return Buffer.from(base64, "base64");
554
+ }
555
+
517
556
  function defaultContentSecurityPolicy() {
518
557
  return [
519
558
  "default-src 'self' data: blob:",