UNPKG

grix-connector

Version:

Connect local AI coding agents (Claude, Codex, Gemini, Qwen, DeepSeek, Cursor, OpenCode, Pi, OpenHuman, Reasonix) to the Grix scheduling platform. Also serves as an OpenClaw plugin for Grix channel transport.

2 lines (1 loc) 2.66 kB
import i from"node:path";import{readFile as l,stat as u}from"node:fs/promises";import{normalizeString as n}from"../util/normalize-string.js";const f=50*1024*1024,d=new Set(["pdf","doc","docx","xls","xlsx","ppt","pptx","txt","md","csv","json","xml","zip","rar","7z","tar","gz","jpg","jpeg","png","webp","gif","bmp","heic","heif","mp4","mov","m4v","webm","mkv","avi"]);function c(t){const e=i.extname(n(t)).toLowerCase();return e.startsWith(".")?e.slice(1):e}function x(t){const e=n(t).toLowerCase();return e.startsWith("image/")?"image":e.startsWith("video/")?"video":"file"}function h(t){switch(c(t)){case"jpg":case"jpeg":return"image/jpeg";case"png":return"image/png";case"webp":return"image/webp";case"gif":return"image/gif";case"bmp":return"image/bmp";case"heic":return"image/heic";case"heif":return"image/heif";case"mp4":return"video/mp4";case"mov":return"video/quicktime";case"m4v":return"video/x-m4v";case"webm":return"video/webm";case"mkv":return"video/x-matroska";case"avi":return"video/x-msvideo";case"pdf":return"application/pdf";case"doc":return"application/msword";case"docx":return"application/vnd.openxmlformats-officedocument.wordprocessingml.document";case"xls":return"application/vnd.ms-excel";case"xlsx":return"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";case"ppt":return"application/vnd.ms-powerpoint";case"pptx":return"application/vnd.openxmlformats-officedocument.presentationml.presentation";case"txt":return"text/plain";case"md":return"text/markdown";case"csv":return"text/csv";case"json":return"application/json";case"xml":return"application/xml";case"zip":return"application/zip";case"rar":return"application/vnd.rar";case"7z":return"application/x-7z-compressed";case"tar":return"application/x-tar";case"gz":return"application/gzip";default:return"application/octet-stream"}}async function b(t){const e=n(t);if(!e)throw new Error("file path must be a non-empty absolute path");if(!i.isAbsolute(e))throw new Error(`file requires an absolute path: ${e}`);const a=await u(e);if(!a.isFile())throw new Error(`path is not a file: ${e}`);if(a.size<=0)throw new Error(`file is empty: ${e}`);if(a.size>f)throw new Error(`file exceeds 50MB: ${e}`);const r=i.basename(e),o=c(r);if(!o||!d.has(o))throw new Error(`unsupported file type: ${r}`);const s=h(r),p=x(s),m=await l(e);return{file_path:e,file_name:r,content_type:s,attachment_type:p,bytes:m}}function y(t){const e={media_url:n(t.accessURL),attachment_type:n(t.attachmentType),file_name:n(t.fileName),content_type:n(t.contentType)};return{...e,attachments:[e]}}export{y as buildAttachmentExtra,b as readReplyFile,x as resolveAttachmentType,h as resolveContentType};