@mappa-ai/mappa-node 1.1.1 → 1.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/dist/index.cjs +5 -1
- package/dist/index.d.cts +57 -16
- package/dist/index.d.mts +57 -16
- package/dist/index.mjs +5 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
let e=require(`@paralleldrive/cuid2`);var t=class extends Error{name=`MappaError`;requestId;code;constructor(e,t){super(e),this.requestId=t?.requestId,this.code=t?.code,this.cause=t?.cause}},n=class extends t{name=`ApiError`;status;details;constructor(e,t){super(e,{requestId:t.requestId,code:t.code}),this.status=t.status,this.details=t.details}},r=class extends n{name=`RateLimitError`;retryAfterMs},i=class extends n{name=`AuthError`},a=class extends n{name=`ValidationError`},o=class extends t{name=`JobFailedError`;jobId;constructor(e,t,n){super(t,n),this.jobId=e}},s=class extends t{name=`JobCanceledError`;jobId;constructor(e,t,n){super(t,n),this.jobId=e}},c=class{constructor(e){this.transport=e}async getBalance(e){return(await this.transport.request({method:`GET`,path:`/v1/credits/balance`,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async listTransactions(e){let t={};return e?.limit!==void 0&&(t.limit=String(e.limit)),e?.offset!==void 0&&(t.offset=String(e.offset)),(await this.transport.request({method:`GET`,path:`/v1/credits/transactions`,query:t,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async*listAllTransactions(e){let t=0,n=e?.limit??50;for(;;){let r=await this.listTransactions({...e,limit:n,offset:t});for(let e of r.transactions)yield e;if(t+=r.transactions.length,t>=r.pagination.total)break}}async getJobUsage(e,n){if(!e)throw new t(`jobId is required`);return(await this.transport.request({method:`GET`,path:`/v1/credits/usage/${encodeURIComponent(e)}`,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}async hasEnough(e,t){return(await this.getBalance(t)).available>=e}async getAvailable(e){return(await this.getBalance(e)).available}};const l=/^[a-zA-Z0-9_-]{1,64}$/,u=10;function d(e){if(typeof e!=`string`)throw new t(`Tags must be strings`);if(!l.test(e))throw new t(`Invalid tag "${e}": must be 1-64 characters, alphanumeric with underscores and hyphens only`)}function f(e){if(!Array.isArray(e))throw new t(`tags must be an array`);if(e.length>10)throw new t(`Too many tags: maximum 10 per request`);for(let t of e)d(t)}var p=class{constructor(e){this.transport=e}async get(e,n){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);return(await this.transport.request({method:`GET`,path:`/v1/entities/${encodeURIComponent(e)}`,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}async list(e){let t={};return e?.tags&&(f(e.tags),t.tags=e.tags.join(`,`)),e?.cursor&&(t.cursor=e.cursor),e?.limit!==void 0&&(t.limit=String(e.limit)),(await this.transport.request({method:`GET`,path:`/v1/entities`,query:t,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async*listAll(e){let t,n=!0;for(;n;){let r=await this.list({...e,cursor:t});for(let e of r.entities)yield e;t=r.cursor,n=r.hasMore}}async getByTag(e,t){return d(e),this.list({...t,tags:[e]})}async addTags(e,n,r){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);if(n.length===0)throw new t(`At least one tag is required`);return f(n),(await this.transport.request({method:`POST`,path:`/v1/entities/${encodeURIComponent(e)}/tags`,body:{tags:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}async removeTags(e,n,r){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);if(n.length===0)throw new t(`At least one tag is required`);return f(n),(await this.transport.request({method:`DELETE`,path:`/v1/entities/${encodeURIComponent(e)}/tags`,body:{tags:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}async setTags(e,n,r){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);return f(n),(await this.transport.request({method:`PUT`,path:`/v1/entities/${encodeURIComponent(e)}/tags`,body:{tags:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}},m=class{constructor(e){this.transport=e}async create(e){if(!!e.reportId==!!e.jobId)throw new t(`Provide exactly one of reportId or jobId`);return(await this.transport.request({method:`POST`,path:`/v1/feedback`,body:e,idempotencyKey:e.idempotencyKey,requestId:e.requestId,signal:e.signal,retryable:!0})).data}},h=class{constructor(e){this.transport=e}async upload(e){if(typeof FormData>`u`)throw new t(`FormData is not available in this runtime; cannot perform multipart upload`);let n=g(e.file,e.filename),r=e.contentType??n;if(!r)throw new t(`contentType is required when it cannot be inferred from file.type or filename`);let i=e.filename??_(e.file)??`upload`,a=await y(e.file,r),o=new FormData;return o.append(`file`,a,i),o.append(`contentType`,r),e.filename&&o.append(`filename`,e.filename),(await this.transport.request({method:`POST`,path:`/v1/files`,body:o,idempotencyKey:e.idempotencyKey,requestId:e.requestId,signal:e.signal,retryable:!0})).data}async get(e,n){if(!e)throw new t(`mediaId is required`);return(await this.transport.request({method:`GET`,path:`/v1/files/${encodeURIComponent(e)}`,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}async list(e){let t={};return e?.limit!==void 0&&(t.limit=String(e.limit)),e?.cursor&&(t.cursor=e.cursor),e?.includeDeleted!==void 0&&(t.includeDeleted=String(e.includeDeleted)),(await this.transport.request({method:`GET`,path:`/v1/files`,query:t,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async*listAll(e){let t,n=!0;for(;n;){let r=await this.list({...e,cursor:t});for(let e of r.files)yield e;t=r.cursor,n=r.hasMore}}async setRetentionLock(e,n,r){if(!e)throw new t(`mediaId is required`);return(await this.transport.request({method:`PATCH`,path:`/v1/files/${encodeURIComponent(e)}/retention`,body:{lock:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}async delete(e,n){if(!e)throw new t(`mediaId is required`);return(await this.transport.request({method:`DELETE`,path:`/v1/files/${encodeURIComponent(e)}`,idempotencyKey:n?.idempotencyKey,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}};function g(e,t){if(typeof Blob<`u`&&e instanceof Blob&&e.type)return e.type;if(t)return v(t)}function _(e){if(typeof Blob<`u`&&e instanceof Blob){let t=e;if(typeof t.name==`string`&&t.name)return t.name}}function v(e){let t=e.lastIndexOf(`.`);if(!(t<0))switch(e.slice(t+1).toLowerCase()){case`mp4`:return`video/mp4`;case`mov`:return`video/quicktime`;case`webm`:return`video/webm`;case`mp3`:return`audio/mpeg`;case`wav`:return`audio/wav`;case`m4a`:return`audio/mp4`;case`png`:return`image/png`;case`jpg`:case`jpeg`:return`image/jpeg`;case`gif`:return`image/gif`;case`webp`:return`image/webp`;case`pdf`:return`application/pdf`;case`json`:return`application/json`;case`txt`:return`text/plain`;default:return}}async function y(e,n){if(typeof Blob<`u`&&e instanceof Blob){if(e.type===n)return e;let t=e;return typeof t.slice==`function`?t.slice(0,e.size,n):e}if(e instanceof ArrayBuffer||e instanceof Uint8Array)return new Blob([e],{type:n});if(typeof ReadableStream<`u`&&e instanceof ReadableStream){if(typeof Response>`u`)throw new t(`ReadableStream upload requires Response to convert stream to Blob`);let r=await new Response(e).blob();return r.slice(0,r.size,n)}throw new t(`Unsupported file type for upload()`)}var b=class{constructor(e){this.transport=e}async ping(){return(await this.transport.request({method:`GET`,path:`/v1/health/ping`,retryable:!0})).data}};const x=(0,e.init)({length:32});function S(e,t){let n=e.get(t);return n===null?void 0:n}function C(e){let t=.8+Math.random()*.4;return Math.floor(e*t)}function w(e,t,n){let r=t*2**Math.max(0,e-1);return Math.min(r,n)}function T(){return Date.now()}function E(e){return!!e&&typeof e.aborted==`boolean`}function D(){let e=Error(`The operation was aborted`);return e.name=`AbortError`,e}function O(e=`req`){return`${e}_${x()}`}var k=class{constructor(e){this.transport=e}async get(e,t){return(await this.transport.request({method:`GET`,path:`/v1/jobs/${encodeURIComponent(e)}`,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async cancel(e,t){return(await this.transport.request({method:`POST`,path:`/v1/jobs/${encodeURIComponent(e)}/cancel`,idempotencyKey:t?.idempotencyKey,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async wait(e,t){let n=t?.timeoutMs??5*6e4,r=t?.pollIntervalMs??1e3,i=t?.maxPollIntervalMs??1e4,a=T(),c=0,l,u;for(;;){if(t?.signal?.aborted)throw D();let d=await this.get(e,{signal:t?.signal});if(d.status!==u&&(u=d.status,t?.onEvent?.({type:`status`,job:d})),d.stage&&d.stage!==l&&(l=d.stage,t?.onEvent?.({type:`stage`,stage:d.stage,progress:d.progress,job:d})),d.status===`succeeded`)return t?.onEvent?.({type:`terminal`,job:d}),d;if(d.status===`failed`)throw t?.onEvent?.({type:`terminal`,job:d}),new o(e,d.error?.message??`Job failed`,{requestId:d.requestId,code:d.error?.code,cause:d.error});if(d.status===`canceled`)throw t?.onEvent?.({type:`terminal`,job:d}),new s(e,`Job canceled`,{requestId:d.requestId,cause:d.error});if(T()-a>n)throw new o(e,`Timed out waiting for job ${e} after ${n}ms`,{cause:{jobId:e,timeoutMs:n}});c+=1;let f=C(w(c,r,i));await new Promise(e=>setTimeout(e,f))}}async*stream(e,t){let n,r;for(;;){if(t?.signal?.aborted)return;let i=await this.get(e,{signal:t?.signal});if(i.status!==r){r=i.status;let e={type:`status`,job:i};t?.onEvent?.(e),yield e}if(i.stage&&i.stage!==n){n=i.stage;let e={type:`stage`,stage:i.stage,progress:i.progress,job:i};t?.onEvent?.(e),yield e}if(i.status===`succeeded`||i.status===`failed`||i.status===`canceled`){let e={type:`terminal`,job:i};t?.onEvent?.(e),yield e;return}await new Promise(e=>setTimeout(e,1e3))}}};function A(e){let n=e;if(!(e=>typeof e==`object`&&!!e)(n))throw new t(`media must be an object`);if(n.url!==void 0)throw new t(`media.url is not supported; pass { mediaId } or use createJobFromUrl()`);let r=n.mediaId;if(typeof r!=`string`||!r)throw new t(`media.mediaId must be a non-empty string`)}var j=class{constructor(e,t,n,r){this.transport=e,this.jobs=t,this.files=n,this.fetchImpl=r}async createJob(e){A(e.media);let t=e.idempotencyKey??this.defaultIdempotencyKey(e),n=await this.transport.request({method:`POST`,path:`/v1/reports/jobs`,body:this.normalizeJobRequest(e),idempotencyKey:t,requestId:e.requestId,retryable:!0}),r={...n.data,requestId:n.requestId??n.data.requestId};return r.handle=this.makeHandle(r.jobId),r}async createJobFromFile(e){let{file:t,contentType:n,filename:r,idempotencyKey:i,requestId:a,signal:o,...s}=e,c=await this.files.upload({file:t,contentType:n,filename:r,idempotencyKey:i,requestId:a,signal:o});return this.createJob({...s,media:{mediaId:c.mediaId},idempotencyKey:i,requestId:a})}async createJobFromUrl(e){let{url:n,contentType:r,filename:i,idempotencyKey:a,requestId:o,signal:s,...c}=e,l;try{l=new URL(n)}catch{throw new t(`url must be a valid URL`)}if(l.protocol!==`http:`&&l.protocol!==`https:`)throw new t(`url must use http: or https:`);let u=await this.fetchImpl(l.toString(),{signal:s});if(!u.ok)throw new t(`Failed to download url (status ${u.status})`);let d=u.headers.get(`content-type`)??void 0,f=r??d;if(!f)throw new t(`contentType is required when it cannot be inferred from the download response`);if(typeof Blob>`u`)throw new t(`Blob is not available in this runtime; cannot download and upload from url`);let p=await u.blob(),m=await this.files.upload({file:p,contentType:f,filename:i,idempotencyKey:a,requestId:o,signal:s});return this.createJob({...c,media:{mediaId:m.mediaId},idempotencyKey:a,requestId:o})}async get(e,t){return(await this.transport.request({method:`GET`,path:`/v1/reports/${encodeURIComponent(e)}`,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async getByJob(e,t){return(await this.transport.request({method:`GET`,path:`/v1/reports/by-job/${encodeURIComponent(e)}`,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async generate(e,n){let r=await this.createJob(e);if(!r.handle)throw new t(`Job receipt is missing handle`);return r.handle.wait(n?.wait)}async generateFromFile(e,n){let r=await this.createJobFromFile(e);if(!r.handle)throw new t(`Job receipt is missing handle`);return r.handle.wait(n?.wait)}async generateFromUrl(e,n){let r=await this.createJobFromUrl(e);if(!r.handle)throw new t(`Job receipt is missing handle`);return r.handle.wait(n?.wait)}makeHandle(e){let n=this;return{jobId:e,stream:t=>n.jobs.stream(e,t),async wait(r){let i=await n.jobs.wait(e,r);if(!i.reportId)throw new t(`Job ${e} succeeded but no reportId was returned`);return n.get(i.reportId)},cancel:()=>n.jobs.cancel(e),job:()=>n.jobs.get(e),report:()=>n.getByJob(e)}}defaultIdempotencyKey(e){return O(`idem`)}normalizeJobRequest(e){let t=e.target;if(!t)return e;let n={strategy:t.strategy};switch(t.onMiss&&(n.on_miss=t.onMiss),t.tags&&t.tags.length>0&&(n.tags=t.tags),t.excludeTags&&t.excludeTags.length>0&&(n.exclude_tags=t.excludeTags),t.strategy){case`dominant`:return{...e,target:n};case`timerange`:{let r=t.timeRange??{};return{...e,target:{...n,timerange:{start_seconds:r.startSeconds??null,end_seconds:r.endSeconds??null}}}}case`entity_id`:return{...e,target:{...n,entity_id:t.entityId}};case`magic_hint`:return{...e,target:{...n,hint:t.hint}};default:return e}}};function M(e,t,n){let r=new URL(t.replace(/^\//,``),e.endsWith(`/`)?e:`${e}/`);if(n)for(let[e,t]of Object.entries(n))t!==void 0&&r.searchParams.set(e,String(t));return r.toString()}async function N(e){let t=await e.text();if(!t)return{parsed:null,text:``};try{return{parsed:JSON.parse(t),text:t}}catch{return{parsed:t,text:t}}}function P(e,t){let o=e.headers.get(`x-request-id`)??void 0,s,c=`Request failed with status ${e.status}`,l=t;if(typeof t==`string`)c=t;else if(t&&typeof t==`object`){let e=t,n=e.error??e;if(n&&typeof n==`object`){let e=n;typeof e.message==`string`&&(c=e.message),typeof e.code==`string`&&(s=e.code),`details`in e&&(l=e.details)}}if(e.status===401||e.status===403)return new i(c,{status:e.status,requestId:o,code:s,details:l});if(e.status===422)return new a(c,{status:e.status,requestId:o,code:s,details:l});if(e.status===429){let t=new r(c,{status:e.status,requestId:o,code:s,details:l}),n=e.headers.get(`retry-after`);if(n){let e=Number(n);Number.isFinite(e)&&e>=0&&(t.retryAfterMs=e*1e3)}return t}return new n(c,{status:e.status,requestId:o,code:s,details:l})}function F(e,t){return e.retryable?t instanceof r?{retry:!0,retryAfterMs:t.retryAfterMs}:t instanceof n?{retry:t.status>=500&&t.status<=599}:t instanceof TypeError?{retry:!0}:{retry:!1}:{retry:!1}}var I=class{fetchImpl;constructor(e){this.opts=e,this.fetchImpl=e.fetch??fetch}async request(e){let t=M(this.opts.baseUrl,e.path,e.query),n=e.requestId??O(`req`),r={"Mappa-Api-Key":this.opts.apiKey,"X-Request-Id":n,...this.opts.userAgent?{"User-Agent":this.opts.userAgent}:{},...this.opts.defaultHeaders??{}};if(e.idempotencyKey&&(r[`Idempotency-Key`]=e.idempotencyKey),e.headers)for(let[t,n]of Object.entries(e.headers))n!==void 0&&(r[t]=n);let i=typeof FormData<`u`&&e.body instanceof FormData;e.body!==void 0&&!i&&(r[`Content-Type`]=`application/json`);let a=e.body===void 0?void 0:i?e.body:JSON.stringify(e.body),o=Math.max(0,this.opts.maxRetries),s=Date.now();for(let i=1;i<=1+o;i++){let c=new AbortController,l=setTimeout(()=>c.abort(D()),this.opts.timeoutMs);if(E(e.signal)){let t=e.signal;if(!t)throw clearTimeout(l),Error(`Unexpected: abort signal missing`);if(t.aborted)throw clearTimeout(l),D();t.addEventListener(`abort`,()=>c.abort(D()),{once:!0})}this.opts.telemetry?.onRequest?.({method:e.method,url:t,requestId:n});try{let l=await this.fetchImpl(t,{method:e.method,headers:r,body:a,signal:c.signal}),u=Date.now()-s,d=S(l.headers,`x-request-id`)??n;if(!l.ok){let{parsed:n}=await N(l),r=P(l,n);this.opts.telemetry?.onError?.({url:t,requestId:d,error:r});let a=F(e,r);if(i<=o+1&&a.retry&&i<=o){let e=a.retryAfterMs??C(w(i,500,4e3));await new Promise(t=>setTimeout(t,e));continue}throw r}let f=l.headers.get(`content-type`)??``,p;return p=f.includes(`application/json`)?await l.json():await l.text(),this.opts.telemetry?.onResponse?.({status:l.status,url:t,requestId:d,durationMs:u}),{data:p,status:l.status,requestId:d,headers:l.headers}}catch(r){this.opts.telemetry?.onError?.({url:t,requestId:n,error:r});let a=F(e,r);if(i<=o&&a.retry){let e=a.retryAfterMs??C(w(i,500,4e3));await new Promise(t=>setTimeout(t,e));continue}throw r}finally{clearTimeout(l)}}throw Error(`Unexpected transport exit`)}};function L(e){return typeof e==`object`&&!!e}var R=class{async verifySignature(e){let t=e.toleranceSec??300,n=z(e.headers,`mappa-signature`);if(!n)throw Error(`Missing mappa-signature header`);let r=B(n),i=Number(r.t);if(!Number.isFinite(i))throw Error(`Invalid signature timestamp`);let a=Math.floor(Date.now()/1e3);if(Math.abs(a-i)>t)throw Error(`Signature timestamp outside tolerance`);let o=`${r.t}.${e.payload}`;if(!U(await V(e.secret,o),r.v1))throw Error(`Invalid signature`);return{ok:!0}}parseEvent(e){let t=JSON.parse(e);if(!L(t))throw Error(`Invalid webhook payload: not an object`);let n=t,r=n.id,i=n.type,a=n.createdAt;if(typeof r!=`string`)throw Error(`Invalid webhook payload: id must be a string`);if(typeof i!=`string`)throw Error(`Invalid webhook payload: type must be a string`);if(typeof a!=`string`)throw Error(`Invalid webhook payload: createdAt must be a string`);return{id:r,type:i,createdAt:a,data:`data`in n?n.data:void 0}}};function z(e,t){let n=Object.keys(e).find(e=>e.toLowerCase()===t.toLowerCase()),r=n?e[n]:void 0;if(r)return Array.isArray(r)?r[0]:r}function B(e){let t={};for(let n of e.split(`,`)){let[e,r]=n.split(`=`);e&&r&&(t[e.trim()]=r.trim())}if(!t.t||!t.v1)throw Error(`Invalid signature format`);return{t:t.t,v1:t.v1}}async function V(e,t){let n=new TextEncoder,r=await crypto.subtle.importKey(`raw`,n.encode(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`]);return H(await crypto.subtle.sign(`HMAC`,r,n.encode(t)))}function H(e){let t=new Uint8Array(e),n=``;for(let e of t)n+=e.toString(16).padStart(2,`0`);return n}function U(e,t){if(e.length!==t.length)return!1;let n=0;for(let r=0;r<e.length;r++)n|=e.charCodeAt(r)^t.charCodeAt(r);return n===0}var W=class e{files;jobs;reports;feedback;credits;entities;webhooks;health;transport;opts;constructor(e){if(!e.apiKey)throw new t(`apiKey is required`);let n=e.baseUrl??`https://api.mappa.ai`,r=e.timeoutMs??3e4,i=e.maxRetries??2;this.opts={...e,apiKey:e.apiKey,baseUrl:n,timeoutMs:r,maxRetries:i},this.transport=new I({apiKey:e.apiKey,baseUrl:n,timeoutMs:r,maxRetries:i,defaultHeaders:e.defaultHeaders,fetch:e.fetch,telemetry:e.telemetry,userAgent:e.userAgent}),this.files=new h(this.transport),this.jobs=new k(this.transport),this.reports=new j(this.transport,this.jobs,this.files,this.opts.fetch??fetch),this.feedback=new m(this.transport),this.credits=new c(this.transport),this.entities=new p(this.transport),this.webhooks=new R,this.health=new b(this.transport)}withOptions(t){return new e({...this.opts,...t,apiKey:t.apiKey??this.opts.apiKey})}close(){}};function G(e){return e.output.type===`markdown`}function K(e){return e.output.type===`json`}function q(e){return e.output.type===`pdf`}function J(e){return e.output.type===`url`}function Y(e){return e.entity!==void 0&&e.entity!==null}function X(e){return e instanceof t}exports.ApiError=n,exports.AuthError=i,exports.JobCanceledError=s,exports.JobFailedError=o,exports.Mappa=W,exports.MappaError=t,exports.RateLimitError=r,exports.ValidationError=a,exports.hasEntity=Y,exports.isJsonReport=K,exports.isMappaError=X,exports.isMarkdownReport=G,exports.isPdfReport=q,exports.isUrlReport=J;
|
|
1
|
+
let e=require(`@paralleldrive/cuid2`);var t=class extends Error{name=`MappaError`;requestId;code;constructor(e,t){super(e),this.requestId=t?.requestId,this.code=t?.code,this.cause=t?.cause}},n=class extends t{name=`ApiError`;status;details;constructor(e,t){super(e,{requestId:t.requestId,code:t.code}),this.status=t.status,this.details=t.details}},r=class extends n{name=`RateLimitError`;retryAfterMs},i=class extends n{name=`AuthError`},a=class extends n{name=`ValidationError`},o=class extends t{name=`JobFailedError`;jobId;constructor(e,t,n){super(t,n),this.jobId=e}},s=class extends t{name=`JobCanceledError`;jobId;constructor(e,t,n){super(t,n),this.jobId=e}},c=class{constructor(e){this.transport=e}async getBalance(e){return(await this.transport.request({method:`GET`,path:`/v1/credits/balance`,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async listTransactions(e){let t={};return e?.limit!==void 0&&(t.limit=String(e.limit)),e?.offset!==void 0&&(t.offset=String(e.offset)),(await this.transport.request({method:`GET`,path:`/v1/credits/transactions`,query:t,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async*listAllTransactions(e){let t=0,n=e?.limit??50;for(;;){let r=await this.listTransactions({...e,limit:n,offset:t});for(let e of r.transactions)yield e;if(t+=r.transactions.length,t>=r.pagination.total)break}}async getJobUsage(e,n){if(!e)throw new t(`jobId is required`);return(await this.transport.request({method:`GET`,path:`/v1/credits/usage/${encodeURIComponent(e)}`,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}async hasEnough(e,t){return(await this.getBalance(t)).available>=e}async getAvailable(e){return(await this.getBalance(e)).available}};const l=/^[a-zA-Z0-9_-]{1,64}$/,u=10;function d(e){if(typeof e!=`string`)throw new t(`Tags must be strings`);if(!l.test(e))throw new t(`Invalid tag "${e}": must be 1-64 characters, alphanumeric with underscores and hyphens only`)}function f(e){if(!Array.isArray(e))throw new t(`tags must be an array`);if(e.length>10)throw new t(`Too many tags: maximum 10 per request`);for(let t of e)d(t)}var p=class{constructor(e){this.transport=e}async get(e,n){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);return(await this.transport.request({method:`GET`,path:`/v1/entities/${encodeURIComponent(e)}`,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}async list(e){let t={};return e?.tags&&(f(e.tags),t.tags=e.tags.join(`,`)),e?.cursor&&(t.cursor=e.cursor),e?.limit!==void 0&&(t.limit=String(e.limit)),(await this.transport.request({method:`GET`,path:`/v1/entities`,query:t,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async*listAll(e){let t,n=!0;for(;n;){let r=await this.list({...e,cursor:t});for(let e of r.entities)yield e;t=r.cursor,n=r.hasMore}}async getByTag(e,t){return d(e),this.list({...t,tags:[e]})}async addTags(e,n,r){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);if(n.length===0)throw new t(`At least one tag is required`);return f(n),(await this.transport.request({method:`POST`,path:`/v1/entities/${encodeURIComponent(e)}/tags`,body:{tags:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}async removeTags(e,n,r){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);if(n.length===0)throw new t(`At least one tag is required`);return f(n),(await this.transport.request({method:`DELETE`,path:`/v1/entities/${encodeURIComponent(e)}/tags`,body:{tags:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}async setTags(e,n,r){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);return f(n),(await this.transport.request({method:`PUT`,path:`/v1/entities/${encodeURIComponent(e)}/tags`,body:{tags:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}},m=class{constructor(e){this.transport=e}async create(e){if(!!e.reportId==!!e.jobId)throw new t(`Provide exactly one of reportId or jobId`);return(await this.transport.request({method:`POST`,path:`/v1/feedback`,body:e,idempotencyKey:e.idempotencyKey,requestId:e.requestId,signal:e.signal,retryable:!0})).data}},h=class{constructor(e){this.transport=e}async upload(e){if(typeof FormData>`u`)throw new t(`FormData is not available in this runtime; cannot perform multipart upload`);let n=g(e.file,e.filename),r=e.contentType??n;if(!r)throw new t(`contentType is required when it cannot be inferred from file.type or filename`);let i=e.filename??_(e.file)??`upload`,a=await y(e.file,r),o=new FormData;return o.append(`file`,a,i),o.append(`contentType`,r),e.filename&&o.append(`filename`,e.filename),(await this.transport.request({method:`POST`,path:`/v1/files`,body:o,idempotencyKey:e.idempotencyKey,requestId:e.requestId,signal:e.signal,retryable:!0})).data}async get(e,n){if(!e)throw new t(`mediaId is required`);return(await this.transport.request({method:`GET`,path:`/v1/files/${encodeURIComponent(e)}`,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}async list(e){let t={};return e?.limit!==void 0&&(t.limit=String(e.limit)),e?.cursor&&(t.cursor=e.cursor),e?.includeDeleted!==void 0&&(t.includeDeleted=String(e.includeDeleted)),(await this.transport.request({method:`GET`,path:`/v1/files`,query:t,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async*listAll(e){let t,n=!0;for(;n;){let r=await this.list({...e,cursor:t});for(let e of r.files)yield e;t=r.cursor,n=r.hasMore}}async setRetentionLock(e,n,r){if(!e)throw new t(`mediaId is required`);return(await this.transport.request({method:`PATCH`,path:`/v1/files/${encodeURIComponent(e)}/retention`,body:{lock:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}async delete(e,n){if(!e)throw new t(`mediaId is required`);return(await this.transport.request({method:`DELETE`,path:`/v1/files/${encodeURIComponent(e)}`,idempotencyKey:n?.idempotencyKey,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}};function g(e,t){if(typeof Blob<`u`&&e instanceof Blob&&e.type)return e.type;if(t)return v(t)}function _(e){if(typeof Blob<`u`&&e instanceof Blob){let t=e;if(typeof t.name==`string`&&t.name)return t.name}}function v(e){let t=e.lastIndexOf(`.`);if(!(t<0))switch(e.slice(t+1).toLowerCase()){case`mp4`:return`video/mp4`;case`mov`:return`video/quicktime`;case`webm`:return`video/webm`;case`mp3`:return`audio/mpeg`;case`wav`:return`audio/wav`;case`m4a`:return`audio/mp4`;case`png`:return`image/png`;case`jpg`:case`jpeg`:return`image/jpeg`;case`gif`:return`image/gif`;case`webp`:return`image/webp`;case`pdf`:return`application/pdf`;case`json`:return`application/json`;case`txt`:return`text/plain`;default:return}}async function y(e,n){if(typeof Blob<`u`&&e instanceof Blob){if(e.type===n)return e;let t=e;return typeof t.slice==`function`?t.slice(0,e.size,n):e}if(e instanceof ArrayBuffer||e instanceof Uint8Array)return new Blob([e],{type:n});if(typeof ReadableStream<`u`&&e instanceof ReadableStream){if(typeof Response>`u`)throw new t(`ReadableStream upload requires Response to convert stream to Blob`);let r=await new Response(e).blob();return r.slice(0,r.size,n)}throw new t(`Unsupported file type for upload()`)}var b=class{constructor(e){this.transport=e}async ping(){return(await this.transport.request({method:`GET`,path:`/v1/health/ping`,retryable:!0})).data}};const x=(0,e.init)({length:32});function S(e,t){let n=e.get(t);return n===null?void 0:n}function C(e){let t=.8+Math.random()*.4;return Math.floor(e*t)}function w(e,t,n){let r=t*2**Math.max(0,e-1);return Math.min(r,n)}function T(e){return!!e&&typeof e.aborted==`boolean`}function E(){let e=Error(`The operation was aborted`);return e.name=`AbortError`,e}function D(e=`req`){return`${e}_${x()}`}var O=class{constructor(e){this.transport=e}async get(e,t){return(await this.transport.request({method:`GET`,path:`/v1/jobs/${encodeURIComponent(e)}`,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async cancel(e,t){return(await this.transport.request({method:`POST`,path:`/v1/jobs/${encodeURIComponent(e)}/cancel`,idempotencyKey:t?.idempotencyKey,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async wait(e,t){let n=t?.timeoutMs??5*6e4,r=new AbortController,i=setTimeout(()=>r.abort(),n);if(t?.signal){if(t.signal.aborted)throw clearTimeout(i),E();t.signal.addEventListener(`abort`,()=>r.abort(),{once:!0})}try{for await(let n of this.stream(e,{signal:r.signal,onEvent:t?.onEvent}))if(n.type===`terminal`){let t=n.job;if(t.status===`succeeded`)return t;if(t.status===`failed`)throw new o(e,t.error?.message??`Job failed`,{requestId:t.requestId,code:t.error?.code,cause:t.error});if(t.status===`canceled`)throw new s(e,`Job canceled`,{requestId:t.requestId,cause:t.error})}throw new o(e,`Timed out waiting for job ${e} after ${n}ms`,{cause:{jobId:e,timeoutMs:n}})}finally{clearTimeout(i)}}async*stream(e,n){let r,i=0;for(;i<3;)try{let a=this.transport.streamSSE(`/v1/jobs/${encodeURIComponent(e)}/stream`,{signal:n?.signal,lastEventId:r});for await(let e of a){if(r=e.id,e.event===`error`){let n=e.data;throw new t(n.error?.message??`Unknown SSE error`,{code:n.error?.code})}if(e.event===`heartbeat`)continue;let a=this.mapSSEToJobEvent(e);if(a&&(n?.onEvent?.(a),yield a,e.event===`terminal`))return;i=0}i++,i<3&&await this.backoff(i)}catch(e){if(n?.signal?.aborted||(i++,i>=3))throw e;await this.backoff(i)}throw new t(`Failed to get status for job ${e} after 3 retries`)}mapSSEToJobEvent(e){let t=e.data;switch(e.event){case`status`:return{type:`status`,job:t.job};case`stage`:return{type:`stage`,stage:t.stage,progress:t.progress,job:t.job};case`terminal`:return{type:`terminal`,job:t.job};default:return{type:`status`,job:t.job}}}async backoff(e){let t=Math.min(1e3*2**e,1e4),n=t*.5*Math.random();await new Promise(e=>setTimeout(e,t+n))}};function k(e){let n=e;if(!(e=>typeof e==`object`&&!!e)(n))throw new t(`media must be an object`);if(n.url!==void 0)throw new t(`media.url is not supported; pass { mediaId } or use createJobFromUrl()`);let r=n.mediaId;if(typeof r!=`string`||!r)throw new t(`media.mediaId must be a non-empty string`)}var A=class{constructor(e,t,n,r){this.transport=e,this.jobs=t,this.files=n,this.fetchImpl=r}async createJob(e){k(e.media);let t=e.idempotencyKey??this.defaultIdempotencyKey(e),n=await this.transport.request({method:`POST`,path:`/v1/reports/jobs`,body:this.normalizeJobRequest(e),idempotencyKey:t,requestId:e.requestId,retryable:!0}),r={...n.data,requestId:n.requestId??n.data.requestId};return r.handle=this.makeHandle(r.jobId),r}async createJobFromFile(e){let{file:t,contentType:n,filename:r,idempotencyKey:i,requestId:a,signal:o,...s}=e,c=await this.files.upload({file:t,contentType:n,filename:r,idempotencyKey:i,requestId:a,signal:o});return this.createJob({...s,media:{mediaId:c.mediaId},idempotencyKey:i,requestId:a})}async createJobFromUrl(e){let{url:n,contentType:r,filename:i,idempotencyKey:a,requestId:o,signal:s,...c}=e,l;try{l=new URL(n)}catch{throw new t(`url must be a valid URL`)}if(l.protocol!==`http:`&&l.protocol!==`https:`)throw new t(`url must use http: or https:`);let u=await this.fetchImpl(l.toString(),{signal:s});if(!u.ok)throw new t(`Failed to download url (status ${u.status})`);let d=u.headers.get(`content-type`)??void 0,f=r??d;if(!f)throw new t(`contentType is required when it cannot be inferred from the download response`);if(typeof Blob>`u`)throw new t(`Blob is not available in this runtime; cannot download and upload from url`);let p=await u.blob(),m=await this.files.upload({file:p,contentType:f,filename:i,idempotencyKey:a,requestId:o,signal:s});return this.createJob({...c,media:{mediaId:m.mediaId},idempotencyKey:a,requestId:o})}async get(e,t){return(await this.transport.request({method:`GET`,path:`/v1/reports/${encodeURIComponent(e)}`,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async getByJob(e,t){return(await this.transport.request({method:`GET`,path:`/v1/reports/by-job/${encodeURIComponent(e)}`,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async generate(e,n){let r=await this.createJob(e);if(!r.handle)throw new t(`Job receipt is missing handle`);return r.handle.wait(n?.wait)}async generateFromFile(e,n){let r=await this.createJobFromFile(e);if(!r.handle)throw new t(`Job receipt is missing handle`);return r.handle.wait(n?.wait)}async generateFromUrl(e,n){let r=await this.createJobFromUrl(e);if(!r.handle)throw new t(`Job receipt is missing handle`);return r.handle.wait(n?.wait)}makeHandle(e){let n=this;return{jobId:e,stream:t=>n.jobs.stream(e,t),async wait(r){let i=await n.jobs.wait(e,r);if(!i.reportId)throw new t(`Job ${e} succeeded but no reportId was returned`);return n.get(i.reportId)},cancel:()=>n.jobs.cancel(e),job:()=>n.jobs.get(e),report:()=>n.getByJob(e)}}defaultIdempotencyKey(e){return D(`idem`)}normalizeJobRequest(e){let t=e.target;if(!t)return e;let n={strategy:t.strategy};switch(t.onMiss&&(n.on_miss=t.onMiss),t.tags&&t.tags.length>0&&(n.tags=t.tags),t.excludeTags&&t.excludeTags.length>0&&(n.exclude_tags=t.excludeTags),t.strategy){case`dominant`:return{...e,target:n};case`timerange`:{let r=t.timeRange??{};return{...e,target:{...n,timerange:{start_seconds:r.startSeconds??null,end_seconds:r.endSeconds??null}}}}case`entity_id`:return{...e,target:{...n,entity_id:t.entityId}};case`magic_hint`:return{...e,target:{...n,hint:t.hint}};default:return e}}};function j(e,t,n){let r=new URL(t.replace(/^\//,``),e.endsWith(`/`)?e:`${e}/`);if(n)for(let[e,t]of Object.entries(n))t!==void 0&&r.searchParams.set(e,String(t));return r.toString()}async function M(e){let t=await e.text();if(!t)return{parsed:null,text:``};try{return{parsed:JSON.parse(t),text:t}}catch{return{parsed:t,text:t}}}function N(e,t){let o=e.headers.get(`x-request-id`)??void 0,s,c=`Request failed with status ${e.status}`,l=t;if(typeof t==`string`)c=t;else if(t&&typeof t==`object`){let e=t,n=e.error??e;if(n&&typeof n==`object`){let e=n;typeof e.message==`string`&&(c=e.message),typeof e.code==`string`&&(s=e.code),`details`in e&&(l=e.details)}}if(e.status===401||e.status===403)return new i(c,{status:e.status,requestId:o,code:s,details:l});if(e.status===422)return new a(c,{status:e.status,requestId:o,code:s,details:l});if(e.status===429){let t=new r(c,{status:e.status,requestId:o,code:s,details:l}),n=e.headers.get(`retry-after`);if(n){let e=Number(n);Number.isFinite(e)&&e>=0&&(t.retryAfterMs=e*1e3)}return t}return new n(c,{status:e.status,requestId:o,code:s,details:l})}function P(e,t){return e.retryable?t instanceof r?{retry:!0,retryAfterMs:t.retryAfterMs}:t instanceof n?{retry:t.status>=500&&t.status<=599}:t instanceof TypeError?{retry:!0}:{retry:!1}:{retry:!1}}var F=class{fetchImpl;constructor(e){this.opts=e,this.fetchImpl=e.fetch??fetch}async*streamSSE(e,n){let r=j(this.opts.baseUrl,e),i=D(`req`),a={Accept:`text/event-stream`,"Cache-Control":`no-cache`,"Mappa-Api-Key":this.opts.apiKey,"X-Request-Id":i,...this.opts.userAgent?{"User-Agent":this.opts.userAgent}:{},...this.opts.defaultHeaders??{}};n?.lastEventId&&(a[`Last-Event-ID`]=n.lastEventId);let o=new AbortController,s=setTimeout(()=>o.abort(E()),this.opts.timeoutMs);if(T(n?.signal)){let e=n?.signal;if(e?.aborted)throw clearTimeout(s),E();e?.addEventListener(`abort`,()=>o.abort(E()),{once:!0})}this.opts.telemetry?.onRequest?.({method:`GET`,url:r,requestId:i});let c;try{c=await this.fetchImpl(r,{method:`GET`,headers:a,signal:o.signal})}catch(e){throw clearTimeout(s),this.opts.telemetry?.onError?.({url:r,requestId:i,error:e}),e}if(!c.ok){clearTimeout(s);let{parsed:e}=await M(c),t=N(c,e);throw this.opts.telemetry?.onError?.({url:r,requestId:i,error:t}),t}if(!c.body)throw clearTimeout(s),new t(`SSE response has no body`);try{yield*this.parseSSEStream(c.body)}finally{clearTimeout(s)}}async*parseSSEStream(e){let t=new TextDecoder,n=e.getReader(),r=``;try{for(;;){let{done:e,value:i}=await n.read();if(e)break;r+=t.decode(i,{stream:!0});let a=r.split(`
|
|
2
|
+
|
|
3
|
+
`);r=a.pop()??``;for(let e of a){if(!e.trim())continue;let t=this.parseSSEEvent(e);t&&(yield t)}}if(r.trim()){let e=this.parseSSEEvent(r);e&&(yield e)}}finally{n.releaseLock()}}parseSSEEvent(e){let t=e.split(`
|
|
4
|
+
`),n,r=`message`,i=``;for(let e of t)e.startsWith(`id:`)?n=e.slice(3).trim():e.startsWith(`event:`)?r=e.slice(6).trim():e.startsWith(`data:`)&&(i&&(i+=`
|
|
5
|
+
`),i+=e.slice(5).trim());if(!i)return null;let a;try{a=JSON.parse(i)}catch{a=i}return{id:n,event:r,data:a}}async request(e){let t=j(this.opts.baseUrl,e.path,e.query),n=e.requestId??D(`req`),r={"Mappa-Api-Key":this.opts.apiKey,"X-Request-Id":n,...this.opts.userAgent?{"User-Agent":this.opts.userAgent}:{},...this.opts.defaultHeaders??{}};if(e.idempotencyKey&&(r[`Idempotency-Key`]=e.idempotencyKey),e.headers)for(let[t,n]of Object.entries(e.headers))n!==void 0&&(r[t]=n);let i=typeof FormData<`u`&&e.body instanceof FormData;e.body!==void 0&&!i&&(r[`Content-Type`]=`application/json`);let a=e.body===void 0?void 0:i?e.body:JSON.stringify(e.body),o=Math.max(0,this.opts.maxRetries),s=Date.now();for(let i=1;i<=1+o;i++){let c=new AbortController,l=setTimeout(()=>c.abort(E()),this.opts.timeoutMs);if(T(e.signal)){let t=e.signal;if(!t)throw clearTimeout(l),Error(`Unexpected: abort signal missing`);if(t.aborted)throw clearTimeout(l),E();t.addEventListener(`abort`,()=>c.abort(E()),{once:!0})}this.opts.telemetry?.onRequest?.({method:e.method,url:t,requestId:n});try{let l=await this.fetchImpl(t,{method:e.method,headers:r,body:a,signal:c.signal}),u=Date.now()-s,d=S(l.headers,`x-request-id`)??n;if(!l.ok){let{parsed:n}=await M(l),r=N(l,n);this.opts.telemetry?.onError?.({url:t,requestId:d,error:r});let a=P(e,r);if(i<=o+1&&a.retry&&i<=o){let e=a.retryAfterMs??C(w(i,500,4e3));await new Promise(t=>setTimeout(t,e));continue}throw r}let f=l.headers.get(`content-type`)??``,p;return p=f.includes(`application/json`)?await l.json():await l.text(),this.opts.telemetry?.onResponse?.({status:l.status,url:t,requestId:d,durationMs:u}),{data:p,status:l.status,requestId:d,headers:l.headers}}catch(r){this.opts.telemetry?.onError?.({url:t,requestId:n,error:r});let a=P(e,r);if(i<=o&&a.retry){let e=a.retryAfterMs??C(w(i,500,4e3));await new Promise(t=>setTimeout(t,e));continue}throw r}finally{clearTimeout(l)}}throw Error(`Unexpected transport exit`)}};function I(e){return typeof e==`object`&&!!e}var L=class{async verifySignature(e){let t=e.toleranceSec??300,n=R(e.headers,`mappa-signature`);if(!n)throw Error(`Missing mappa-signature header`);let r=z(n),i=Number(r.t);if(!Number.isFinite(i))throw Error(`Invalid signature timestamp`);let a=Math.floor(Date.now()/1e3);if(Math.abs(a-i)>t)throw Error(`Signature timestamp outside tolerance`);let o=`${r.t}.${e.payload}`;if(!H(await B(e.secret,o),r.v1))throw Error(`Invalid signature`);return{ok:!0}}parseEvent(e){let t=JSON.parse(e);if(!I(t))throw Error(`Invalid webhook payload: not an object`);let n=t,r=n.id,i=n.type,a=n.createdAt;if(typeof r!=`string`)throw Error(`Invalid webhook payload: id must be a string`);if(typeof i!=`string`)throw Error(`Invalid webhook payload: type must be a string`);if(typeof a!=`string`)throw Error(`Invalid webhook payload: createdAt must be a string`);return{id:r,type:i,createdAt:a,data:`data`in n?n.data:void 0}}};function R(e,t){let n=Object.keys(e).find(e=>e.toLowerCase()===t.toLowerCase()),r=n?e[n]:void 0;if(r)return Array.isArray(r)?r[0]:r}function z(e){let t={};for(let n of e.split(`,`)){let[e,r]=n.split(`=`);e&&r&&(t[e.trim()]=r.trim())}if(!t.t||!t.v1)throw Error(`Invalid signature format`);return{t:t.t,v1:t.v1}}async function B(e,t){let n=new TextEncoder,r=await crypto.subtle.importKey(`raw`,n.encode(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`]);return V(await crypto.subtle.sign(`HMAC`,r,n.encode(t)))}function V(e){let t=new Uint8Array(e),n=``;for(let e of t)n+=e.toString(16).padStart(2,`0`);return n}function H(e,t){if(e.length!==t.length)return!1;let n=0;for(let r=0;r<e.length;r++)n|=e.charCodeAt(r)^t.charCodeAt(r);return n===0}var U=class e{files;jobs;reports;feedback;credits;entities;webhooks;health;transport;opts;constructor(e){if(!e.apiKey)throw new t(`apiKey is required`);let n=e.baseUrl??`https://api.mappa.ai`,r=e.timeoutMs??3e4,i=e.maxRetries??2;this.opts={...e,apiKey:e.apiKey,baseUrl:n,timeoutMs:r,maxRetries:i},this.transport=new F({apiKey:e.apiKey,baseUrl:n,timeoutMs:r,maxRetries:i,defaultHeaders:e.defaultHeaders,fetch:e.fetch,telemetry:e.telemetry,userAgent:e.userAgent}),this.files=new h(this.transport),this.jobs=new O(this.transport),this.reports=new A(this.transport,this.jobs,this.files,this.opts.fetch??fetch),this.feedback=new m(this.transport),this.credits=new c(this.transport),this.entities=new p(this.transport),this.webhooks=new L,this.health=new b(this.transport)}withOptions(t){return new e({...this.opts,...t,apiKey:t.apiKey??this.opts.apiKey})}close(){}};function W(e){return e.output.type===`markdown`}function G(e){return e.output.type===`json`}function K(e){return e.output.type===`pdf`}function q(e){return e.output.type===`url`}function J(e){return e.entity!==void 0&&e.entity!==null}function Y(e){return e instanceof t}exports.ApiError=n,exports.AuthError=i,exports.JobCanceledError=s,exports.JobFailedError=o,exports.Mappa=U,exports.MappaError=t,exports.RateLimitError=r,exports.ValidationError=a,exports.hasEntity=J,exports.isJsonReport=G,exports.isMappaError=Y,exports.isMarkdownReport=W,exports.isPdfReport=K,exports.isUrlReport=q;
|
package/dist/index.d.cts
CHANGED
|
@@ -76,6 +76,21 @@ declare class JobCanceledError extends MappaError {
|
|
|
76
76
|
}
|
|
77
77
|
//#endregion
|
|
78
78
|
//#region src/resources/transport.d.ts
|
|
79
|
+
/**
|
|
80
|
+
* Options for SSE streaming.
|
|
81
|
+
*/
|
|
82
|
+
type SSEStreamOptions = {
|
|
83
|
+
signal?: AbortSignal;
|
|
84
|
+
lastEventId?: string;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* A parsed SSE event.
|
|
88
|
+
*/
|
|
89
|
+
type SSEEvent<T = unknown> = {
|
|
90
|
+
id?: string;
|
|
91
|
+
event: string;
|
|
92
|
+
data: T;
|
|
93
|
+
};
|
|
79
94
|
type Telemetry = {
|
|
80
95
|
onRequest?: (ctx: {
|
|
81
96
|
method: string;
|
|
@@ -125,6 +140,30 @@ declare class Transport {
|
|
|
125
140
|
private readonly opts;
|
|
126
141
|
private readonly fetchImpl;
|
|
127
142
|
constructor(opts: TransportOptions);
|
|
143
|
+
/**
|
|
144
|
+
* Stream SSE events from a given path.
|
|
145
|
+
*
|
|
146
|
+
* Uses native `fetch` with streaming response body (not browser-only `EventSource`).
|
|
147
|
+
* Parses SSE format manually from the `ReadableStream`.
|
|
148
|
+
*/
|
|
149
|
+
streamSSE<T>(path: string, opts?: SSEStreamOptions): AsyncGenerator<SSEEvent<T>>;
|
|
150
|
+
/**
|
|
151
|
+
* Parse SSE events from a ReadableStream.
|
|
152
|
+
*
|
|
153
|
+
* SSE format:
|
|
154
|
+
* ```
|
|
155
|
+
* id: <id>
|
|
156
|
+
* event: <type>
|
|
157
|
+
* data: <json>
|
|
158
|
+
*
|
|
159
|
+
* ```
|
|
160
|
+
* Each event is terminated by an empty line.
|
|
161
|
+
*/
|
|
162
|
+
private parseSSEStream;
|
|
163
|
+
/**
|
|
164
|
+
* Parse a single SSE event from text.
|
|
165
|
+
*/
|
|
166
|
+
private parseSSEEvent;
|
|
128
167
|
request<T>(req: RequestOptions): Promise<TransportResponse<T>>;
|
|
129
168
|
}
|
|
130
169
|
//#endregion
|
|
@@ -489,7 +528,7 @@ type CreditUsage = {
|
|
|
489
528
|
modelVersion?: string;
|
|
490
529
|
};
|
|
491
530
|
/**
|
|
492
|
-
* Options for
|
|
531
|
+
* Options for waiting on job completion.
|
|
493
532
|
*/
|
|
494
533
|
type WaitOptions = {
|
|
495
534
|
/**
|
|
@@ -498,18 +537,6 @@ type WaitOptions = {
|
|
|
498
537
|
* @defaultValue 300000
|
|
499
538
|
*/
|
|
500
539
|
timeoutMs?: number;
|
|
501
|
-
/**
|
|
502
|
-
* Initial polling interval.
|
|
503
|
-
*
|
|
504
|
-
* @defaultValue 1000
|
|
505
|
-
*/
|
|
506
|
-
pollIntervalMs?: number;
|
|
507
|
-
/**
|
|
508
|
-
* Maximum polling interval used with exponential backoff.
|
|
509
|
-
*
|
|
510
|
-
* @defaultValue 10000
|
|
511
|
-
*/
|
|
512
|
-
maxPollIntervalMs?: number;
|
|
513
540
|
/**
|
|
514
541
|
* Optional callback invoked on meaningful job state transitions.
|
|
515
542
|
*/
|
|
@@ -984,16 +1011,30 @@ declare class JobsResource {
|
|
|
984
1011
|
requestId?: string;
|
|
985
1012
|
signal?: AbortSignal;
|
|
986
1013
|
}): Promise<Job>;
|
|
1014
|
+
/**
|
|
1015
|
+
* Wait for a job to reach a terminal state.
|
|
1016
|
+
*
|
|
1017
|
+
* Uses SSE streaming internally for efficient real-time updates.
|
|
1018
|
+
*/
|
|
987
1019
|
wait(jobId: string, opts?: WaitOptions): Promise<Job>;
|
|
988
1020
|
/**
|
|
989
|
-
*
|
|
990
|
-
*
|
|
991
|
-
*
|
|
1021
|
+
* Stream job events via SSE.
|
|
1022
|
+
*
|
|
1023
|
+
* Yields events as they arrive from the server. Use `AbortSignal` to cancel streaming.
|
|
1024
|
+
* Automatically handles reconnection with `Last-Event-ID` for up to 3 retries.
|
|
992
1025
|
*/
|
|
993
1026
|
stream(jobId: string, opts?: {
|
|
994
1027
|
signal?: AbortSignal;
|
|
995
1028
|
onEvent?: (e: JobEvent) => void;
|
|
996
1029
|
}): AsyncIterable<JobEvent>;
|
|
1030
|
+
/**
|
|
1031
|
+
* Map an SSE event to a JobEvent.
|
|
1032
|
+
*/
|
|
1033
|
+
private mapSSEToJobEvent;
|
|
1034
|
+
/**
|
|
1035
|
+
* Exponential backoff with jitter for reconnection.
|
|
1036
|
+
*/
|
|
1037
|
+
private backoff;
|
|
997
1038
|
}
|
|
998
1039
|
//#endregion
|
|
999
1040
|
//#region src/resources/reports.d.ts
|
package/dist/index.d.mts
CHANGED
|
@@ -76,6 +76,21 @@ declare class JobCanceledError extends MappaError {
|
|
|
76
76
|
}
|
|
77
77
|
//#endregion
|
|
78
78
|
//#region src/resources/transport.d.ts
|
|
79
|
+
/**
|
|
80
|
+
* Options for SSE streaming.
|
|
81
|
+
*/
|
|
82
|
+
type SSEStreamOptions = {
|
|
83
|
+
signal?: AbortSignal;
|
|
84
|
+
lastEventId?: string;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* A parsed SSE event.
|
|
88
|
+
*/
|
|
89
|
+
type SSEEvent<T = unknown> = {
|
|
90
|
+
id?: string;
|
|
91
|
+
event: string;
|
|
92
|
+
data: T;
|
|
93
|
+
};
|
|
79
94
|
type Telemetry = {
|
|
80
95
|
onRequest?: (ctx: {
|
|
81
96
|
method: string;
|
|
@@ -125,6 +140,30 @@ declare class Transport {
|
|
|
125
140
|
private readonly opts;
|
|
126
141
|
private readonly fetchImpl;
|
|
127
142
|
constructor(opts: TransportOptions);
|
|
143
|
+
/**
|
|
144
|
+
* Stream SSE events from a given path.
|
|
145
|
+
*
|
|
146
|
+
* Uses native `fetch` with streaming response body (not browser-only `EventSource`).
|
|
147
|
+
* Parses SSE format manually from the `ReadableStream`.
|
|
148
|
+
*/
|
|
149
|
+
streamSSE<T>(path: string, opts?: SSEStreamOptions): AsyncGenerator<SSEEvent<T>>;
|
|
150
|
+
/**
|
|
151
|
+
* Parse SSE events from a ReadableStream.
|
|
152
|
+
*
|
|
153
|
+
* SSE format:
|
|
154
|
+
* ```
|
|
155
|
+
* id: <id>
|
|
156
|
+
* event: <type>
|
|
157
|
+
* data: <json>
|
|
158
|
+
*
|
|
159
|
+
* ```
|
|
160
|
+
* Each event is terminated by an empty line.
|
|
161
|
+
*/
|
|
162
|
+
private parseSSEStream;
|
|
163
|
+
/**
|
|
164
|
+
* Parse a single SSE event from text.
|
|
165
|
+
*/
|
|
166
|
+
private parseSSEEvent;
|
|
128
167
|
request<T>(req: RequestOptions): Promise<TransportResponse<T>>;
|
|
129
168
|
}
|
|
130
169
|
//#endregion
|
|
@@ -489,7 +528,7 @@ type CreditUsage = {
|
|
|
489
528
|
modelVersion?: string;
|
|
490
529
|
};
|
|
491
530
|
/**
|
|
492
|
-
* Options for
|
|
531
|
+
* Options for waiting on job completion.
|
|
493
532
|
*/
|
|
494
533
|
type WaitOptions = {
|
|
495
534
|
/**
|
|
@@ -498,18 +537,6 @@ type WaitOptions = {
|
|
|
498
537
|
* @defaultValue 300000
|
|
499
538
|
*/
|
|
500
539
|
timeoutMs?: number;
|
|
501
|
-
/**
|
|
502
|
-
* Initial polling interval.
|
|
503
|
-
*
|
|
504
|
-
* @defaultValue 1000
|
|
505
|
-
*/
|
|
506
|
-
pollIntervalMs?: number;
|
|
507
|
-
/**
|
|
508
|
-
* Maximum polling interval used with exponential backoff.
|
|
509
|
-
*
|
|
510
|
-
* @defaultValue 10000
|
|
511
|
-
*/
|
|
512
|
-
maxPollIntervalMs?: number;
|
|
513
540
|
/**
|
|
514
541
|
* Optional callback invoked on meaningful job state transitions.
|
|
515
542
|
*/
|
|
@@ -984,16 +1011,30 @@ declare class JobsResource {
|
|
|
984
1011
|
requestId?: string;
|
|
985
1012
|
signal?: AbortSignal;
|
|
986
1013
|
}): Promise<Job>;
|
|
1014
|
+
/**
|
|
1015
|
+
* Wait for a job to reach a terminal state.
|
|
1016
|
+
*
|
|
1017
|
+
* Uses SSE streaming internally for efficient real-time updates.
|
|
1018
|
+
*/
|
|
987
1019
|
wait(jobId: string, opts?: WaitOptions): Promise<Job>;
|
|
988
1020
|
/**
|
|
989
|
-
*
|
|
990
|
-
*
|
|
991
|
-
*
|
|
1021
|
+
* Stream job events via SSE.
|
|
1022
|
+
*
|
|
1023
|
+
* Yields events as they arrive from the server. Use `AbortSignal` to cancel streaming.
|
|
1024
|
+
* Automatically handles reconnection with `Last-Event-ID` for up to 3 retries.
|
|
992
1025
|
*/
|
|
993
1026
|
stream(jobId: string, opts?: {
|
|
994
1027
|
signal?: AbortSignal;
|
|
995
1028
|
onEvent?: (e: JobEvent) => void;
|
|
996
1029
|
}): AsyncIterable<JobEvent>;
|
|
1030
|
+
/**
|
|
1031
|
+
* Map an SSE event to a JobEvent.
|
|
1032
|
+
*/
|
|
1033
|
+
private mapSSEToJobEvent;
|
|
1034
|
+
/**
|
|
1035
|
+
* Exponential backoff with jitter for reconnection.
|
|
1036
|
+
*/
|
|
1037
|
+
private backoff;
|
|
997
1038
|
}
|
|
998
1039
|
//#endregion
|
|
999
1040
|
//#region src/resources/reports.d.ts
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
import{init as e}from"@paralleldrive/cuid2";var t=class extends Error{name=`MappaError`;requestId;code;constructor(e,t){super(e),this.requestId=t?.requestId,this.code=t?.code,this.cause=t?.cause}},n=class extends t{name=`ApiError`;status;details;constructor(e,t){super(e,{requestId:t.requestId,code:t.code}),this.status=t.status,this.details=t.details}},r=class extends n{name=`RateLimitError`;retryAfterMs},i=class extends n{name=`AuthError`},a=class extends n{name=`ValidationError`},o=class extends t{name=`JobFailedError`;jobId;constructor(e,t,n){super(t,n),this.jobId=e}},s=class extends t{name=`JobCanceledError`;jobId;constructor(e,t,n){super(t,n),this.jobId=e}},c=class{constructor(e){this.transport=e}async getBalance(e){return(await this.transport.request({method:`GET`,path:`/v1/credits/balance`,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async listTransactions(e){let t={};return e?.limit!==void 0&&(t.limit=String(e.limit)),e?.offset!==void 0&&(t.offset=String(e.offset)),(await this.transport.request({method:`GET`,path:`/v1/credits/transactions`,query:t,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async*listAllTransactions(e){let t=0,n=e?.limit??50;for(;;){let r=await this.listTransactions({...e,limit:n,offset:t});for(let e of r.transactions)yield e;if(t+=r.transactions.length,t>=r.pagination.total)break}}async getJobUsage(e,n){if(!e)throw new t(`jobId is required`);return(await this.transport.request({method:`GET`,path:`/v1/credits/usage/${encodeURIComponent(e)}`,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}async hasEnough(e,t){return(await this.getBalance(t)).available>=e}async getAvailable(e){return(await this.getBalance(e)).available}};const l=/^[a-zA-Z0-9_-]{1,64}$/;function u(e){if(typeof e!=`string`)throw new t(`Tags must be strings`);if(!l.test(e))throw new t(`Invalid tag "${e}": must be 1-64 characters, alphanumeric with underscores and hyphens only`)}function d(e){if(!Array.isArray(e))throw new t(`tags must be an array`);if(e.length>10)throw new t(`Too many tags: maximum 10 per request`);for(let t of e)u(t)}var f=class{constructor(e){this.transport=e}async get(e,n){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);return(await this.transport.request({method:`GET`,path:`/v1/entities/${encodeURIComponent(e)}`,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}async list(e){let t={};return e?.tags&&(d(e.tags),t.tags=e.tags.join(`,`)),e?.cursor&&(t.cursor=e.cursor),e?.limit!==void 0&&(t.limit=String(e.limit)),(await this.transport.request({method:`GET`,path:`/v1/entities`,query:t,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async*listAll(e){let t,n=!0;for(;n;){let r=await this.list({...e,cursor:t});for(let e of r.entities)yield e;t=r.cursor,n=r.hasMore}}async getByTag(e,t){return u(e),this.list({...t,tags:[e]})}async addTags(e,n,r){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);if(n.length===0)throw new t(`At least one tag is required`);return d(n),(await this.transport.request({method:`POST`,path:`/v1/entities/${encodeURIComponent(e)}/tags`,body:{tags:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}async removeTags(e,n,r){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);if(n.length===0)throw new t(`At least one tag is required`);return d(n),(await this.transport.request({method:`DELETE`,path:`/v1/entities/${encodeURIComponent(e)}/tags`,body:{tags:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}async setTags(e,n,r){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);return d(n),(await this.transport.request({method:`PUT`,path:`/v1/entities/${encodeURIComponent(e)}/tags`,body:{tags:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}},p=class{constructor(e){this.transport=e}async create(e){if(!!e.reportId==!!e.jobId)throw new t(`Provide exactly one of reportId or jobId`);return(await this.transport.request({method:`POST`,path:`/v1/feedback`,body:e,idempotencyKey:e.idempotencyKey,requestId:e.requestId,signal:e.signal,retryable:!0})).data}},m=class{constructor(e){this.transport=e}async upload(e){if(typeof FormData>`u`)throw new t(`FormData is not available in this runtime; cannot perform multipart upload`);let n=h(e.file,e.filename),r=e.contentType??n;if(!r)throw new t(`contentType is required when it cannot be inferred from file.type or filename`);let i=e.filename??g(e.file)??`upload`,a=await v(e.file,r),o=new FormData;return o.append(`file`,a,i),o.append(`contentType`,r),e.filename&&o.append(`filename`,e.filename),(await this.transport.request({method:`POST`,path:`/v1/files`,body:o,idempotencyKey:e.idempotencyKey,requestId:e.requestId,signal:e.signal,retryable:!0})).data}async get(e,n){if(!e)throw new t(`mediaId is required`);return(await this.transport.request({method:`GET`,path:`/v1/files/${encodeURIComponent(e)}`,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}async list(e){let t={};return e?.limit!==void 0&&(t.limit=String(e.limit)),e?.cursor&&(t.cursor=e.cursor),e?.includeDeleted!==void 0&&(t.includeDeleted=String(e.includeDeleted)),(await this.transport.request({method:`GET`,path:`/v1/files`,query:t,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async*listAll(e){let t,n=!0;for(;n;){let r=await this.list({...e,cursor:t});for(let e of r.files)yield e;t=r.cursor,n=r.hasMore}}async setRetentionLock(e,n,r){if(!e)throw new t(`mediaId is required`);return(await this.transport.request({method:`PATCH`,path:`/v1/files/${encodeURIComponent(e)}/retention`,body:{lock:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}async delete(e,n){if(!e)throw new t(`mediaId is required`);return(await this.transport.request({method:`DELETE`,path:`/v1/files/${encodeURIComponent(e)}`,idempotencyKey:n?.idempotencyKey,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}};function h(e,t){if(typeof Blob<`u`&&e instanceof Blob&&e.type)return e.type;if(t)return _(t)}function g(e){if(typeof Blob<`u`&&e instanceof Blob){let t=e;if(typeof t.name==`string`&&t.name)return t.name}}function _(e){let t=e.lastIndexOf(`.`);if(!(t<0))switch(e.slice(t+1).toLowerCase()){case`mp4`:return`video/mp4`;case`mov`:return`video/quicktime`;case`webm`:return`video/webm`;case`mp3`:return`audio/mpeg`;case`wav`:return`audio/wav`;case`m4a`:return`audio/mp4`;case`png`:return`image/png`;case`jpg`:case`jpeg`:return`image/jpeg`;case`gif`:return`image/gif`;case`webp`:return`image/webp`;case`pdf`:return`application/pdf`;case`json`:return`application/json`;case`txt`:return`text/plain`;default:return}}async function v(e,n){if(typeof Blob<`u`&&e instanceof Blob){if(e.type===n)return e;let t=e;return typeof t.slice==`function`?t.slice(0,e.size,n):e}if(e instanceof ArrayBuffer||e instanceof Uint8Array)return new Blob([e],{type:n});if(typeof ReadableStream<`u`&&e instanceof ReadableStream){if(typeof Response>`u`)throw new t(`ReadableStream upload requires Response to convert stream to Blob`);let r=await new Response(e).blob();return r.slice(0,r.size,n)}throw new t(`Unsupported file type for upload()`)}var y=class{constructor(e){this.transport=e}async ping(){return(await this.transport.request({method:`GET`,path:`/v1/health/ping`,retryable:!0})).data}};const b=e({length:32});function x(e,t){let n=e.get(t);return n===null?void 0:n}function S(e){let t=.8+Math.random()*.4;return Math.floor(e*t)}function C(e,t,n){let r=t*2**Math.max(0,e-1);return Math.min(r,n)}function w(){return Date.now()}function T(e){return!!e&&typeof e.aborted==`boolean`}function E(){let e=Error(`The operation was aborted`);return e.name=`AbortError`,e}function D(e=`req`){return`${e}_${b()}`}var O=class{constructor(e){this.transport=e}async get(e,t){return(await this.transport.request({method:`GET`,path:`/v1/jobs/${encodeURIComponent(e)}`,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async cancel(e,t){return(await this.transport.request({method:`POST`,path:`/v1/jobs/${encodeURIComponent(e)}/cancel`,idempotencyKey:t?.idempotencyKey,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async wait(e,t){let n=t?.timeoutMs??5*6e4,r=t?.pollIntervalMs??1e3,i=t?.maxPollIntervalMs??1e4,a=w(),c=0,l,u;for(;;){if(t?.signal?.aborted)throw E();let d=await this.get(e,{signal:t?.signal});if(d.status!==u&&(u=d.status,t?.onEvent?.({type:`status`,job:d})),d.stage&&d.stage!==l&&(l=d.stage,t?.onEvent?.({type:`stage`,stage:d.stage,progress:d.progress,job:d})),d.status===`succeeded`)return t?.onEvent?.({type:`terminal`,job:d}),d;if(d.status===`failed`)throw t?.onEvent?.({type:`terminal`,job:d}),new o(e,d.error?.message??`Job failed`,{requestId:d.requestId,code:d.error?.code,cause:d.error});if(d.status===`canceled`)throw t?.onEvent?.({type:`terminal`,job:d}),new s(e,`Job canceled`,{requestId:d.requestId,cause:d.error});if(w()-a>n)throw new o(e,`Timed out waiting for job ${e} after ${n}ms`,{cause:{jobId:e,timeoutMs:n}});c+=1;let f=S(C(c,r,i));await new Promise(e=>setTimeout(e,f))}}async*stream(e,t){let n,r;for(;;){if(t?.signal?.aborted)return;let i=await this.get(e,{signal:t?.signal});if(i.status!==r){r=i.status;let e={type:`status`,job:i};t?.onEvent?.(e),yield e}if(i.stage&&i.stage!==n){n=i.stage;let e={type:`stage`,stage:i.stage,progress:i.progress,job:i};t?.onEvent?.(e),yield e}if(i.status===`succeeded`||i.status===`failed`||i.status===`canceled`){let e={type:`terminal`,job:i};t?.onEvent?.(e),yield e;return}await new Promise(e=>setTimeout(e,1e3))}}};function k(e){let n=e;if(!(e=>typeof e==`object`&&!!e)(n))throw new t(`media must be an object`);if(n.url!==void 0)throw new t(`media.url is not supported; pass { mediaId } or use createJobFromUrl()`);let r=n.mediaId;if(typeof r!=`string`||!r)throw new t(`media.mediaId must be a non-empty string`)}var A=class{constructor(e,t,n,r){this.transport=e,this.jobs=t,this.files=n,this.fetchImpl=r}async createJob(e){k(e.media);let t=e.idempotencyKey??this.defaultIdempotencyKey(e),n=await this.transport.request({method:`POST`,path:`/v1/reports/jobs`,body:this.normalizeJobRequest(e),idempotencyKey:t,requestId:e.requestId,retryable:!0}),r={...n.data,requestId:n.requestId??n.data.requestId};return r.handle=this.makeHandle(r.jobId),r}async createJobFromFile(e){let{file:t,contentType:n,filename:r,idempotencyKey:i,requestId:a,signal:o,...s}=e,c=await this.files.upload({file:t,contentType:n,filename:r,idempotencyKey:i,requestId:a,signal:o});return this.createJob({...s,media:{mediaId:c.mediaId},idempotencyKey:i,requestId:a})}async createJobFromUrl(e){let{url:n,contentType:r,filename:i,idempotencyKey:a,requestId:o,signal:s,...c}=e,l;try{l=new URL(n)}catch{throw new t(`url must be a valid URL`)}if(l.protocol!==`http:`&&l.protocol!==`https:`)throw new t(`url must use http: or https:`);let u=await this.fetchImpl(l.toString(),{signal:s});if(!u.ok)throw new t(`Failed to download url (status ${u.status})`);let d=u.headers.get(`content-type`)??void 0,f=r??d;if(!f)throw new t(`contentType is required when it cannot be inferred from the download response`);if(typeof Blob>`u`)throw new t(`Blob is not available in this runtime; cannot download and upload from url`);let p=await u.blob(),m=await this.files.upload({file:p,contentType:f,filename:i,idempotencyKey:a,requestId:o,signal:s});return this.createJob({...c,media:{mediaId:m.mediaId},idempotencyKey:a,requestId:o})}async get(e,t){return(await this.transport.request({method:`GET`,path:`/v1/reports/${encodeURIComponent(e)}`,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async getByJob(e,t){return(await this.transport.request({method:`GET`,path:`/v1/reports/by-job/${encodeURIComponent(e)}`,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async generate(e,n){let r=await this.createJob(e);if(!r.handle)throw new t(`Job receipt is missing handle`);return r.handle.wait(n?.wait)}async generateFromFile(e,n){let r=await this.createJobFromFile(e);if(!r.handle)throw new t(`Job receipt is missing handle`);return r.handle.wait(n?.wait)}async generateFromUrl(e,n){let r=await this.createJobFromUrl(e);if(!r.handle)throw new t(`Job receipt is missing handle`);return r.handle.wait(n?.wait)}makeHandle(e){let n=this;return{jobId:e,stream:t=>n.jobs.stream(e,t),async wait(r){let i=await n.jobs.wait(e,r);if(!i.reportId)throw new t(`Job ${e} succeeded but no reportId was returned`);return n.get(i.reportId)},cancel:()=>n.jobs.cancel(e),job:()=>n.jobs.get(e),report:()=>n.getByJob(e)}}defaultIdempotencyKey(e){return D(`idem`)}normalizeJobRequest(e){let t=e.target;if(!t)return e;let n={strategy:t.strategy};switch(t.onMiss&&(n.on_miss=t.onMiss),t.tags&&t.tags.length>0&&(n.tags=t.tags),t.excludeTags&&t.excludeTags.length>0&&(n.exclude_tags=t.excludeTags),t.strategy){case`dominant`:return{...e,target:n};case`timerange`:{let r=t.timeRange??{};return{...e,target:{...n,timerange:{start_seconds:r.startSeconds??null,end_seconds:r.endSeconds??null}}}}case`entity_id`:return{...e,target:{...n,entity_id:t.entityId}};case`magic_hint`:return{...e,target:{...n,hint:t.hint}};default:return e}}};function j(e,t,n){let r=new URL(t.replace(/^\//,``),e.endsWith(`/`)?e:`${e}/`);if(n)for(let[e,t]of Object.entries(n))t!==void 0&&r.searchParams.set(e,String(t));return r.toString()}async function M(e){let t=await e.text();if(!t)return{parsed:null,text:``};try{return{parsed:JSON.parse(t),text:t}}catch{return{parsed:t,text:t}}}function N(e,t){let o=e.headers.get(`x-request-id`)??void 0,s,c=`Request failed with status ${e.status}`,l=t;if(typeof t==`string`)c=t;else if(t&&typeof t==`object`){let e=t,n=e.error??e;if(n&&typeof n==`object`){let e=n;typeof e.message==`string`&&(c=e.message),typeof e.code==`string`&&(s=e.code),`details`in e&&(l=e.details)}}if(e.status===401||e.status===403)return new i(c,{status:e.status,requestId:o,code:s,details:l});if(e.status===422)return new a(c,{status:e.status,requestId:o,code:s,details:l});if(e.status===429){let t=new r(c,{status:e.status,requestId:o,code:s,details:l}),n=e.headers.get(`retry-after`);if(n){let e=Number(n);Number.isFinite(e)&&e>=0&&(t.retryAfterMs=e*1e3)}return t}return new n(c,{status:e.status,requestId:o,code:s,details:l})}function P(e,t){return e.retryable?t instanceof r?{retry:!0,retryAfterMs:t.retryAfterMs}:t instanceof n?{retry:t.status>=500&&t.status<=599}:t instanceof TypeError?{retry:!0}:{retry:!1}:{retry:!1}}var F=class{fetchImpl;constructor(e){this.opts=e,this.fetchImpl=e.fetch??fetch}async request(e){let t=j(this.opts.baseUrl,e.path,e.query),n=e.requestId??D(`req`),r={"Mappa-Api-Key":this.opts.apiKey,"X-Request-Id":n,...this.opts.userAgent?{"User-Agent":this.opts.userAgent}:{},...this.opts.defaultHeaders??{}};if(e.idempotencyKey&&(r[`Idempotency-Key`]=e.idempotencyKey),e.headers)for(let[t,n]of Object.entries(e.headers))n!==void 0&&(r[t]=n);let i=typeof FormData<`u`&&e.body instanceof FormData;e.body!==void 0&&!i&&(r[`Content-Type`]=`application/json`);let a=e.body===void 0?void 0:i?e.body:JSON.stringify(e.body),o=Math.max(0,this.opts.maxRetries),s=Date.now();for(let i=1;i<=1+o;i++){let c=new AbortController,l=setTimeout(()=>c.abort(E()),this.opts.timeoutMs);if(T(e.signal)){let t=e.signal;if(!t)throw clearTimeout(l),Error(`Unexpected: abort signal missing`);if(t.aborted)throw clearTimeout(l),E();t.addEventListener(`abort`,()=>c.abort(E()),{once:!0})}this.opts.telemetry?.onRequest?.({method:e.method,url:t,requestId:n});try{let l=await this.fetchImpl(t,{method:e.method,headers:r,body:a,signal:c.signal}),u=Date.now()-s,d=x(l.headers,`x-request-id`)??n;if(!l.ok){let{parsed:n}=await M(l),r=N(l,n);this.opts.telemetry?.onError?.({url:t,requestId:d,error:r});let a=P(e,r);if(i<=o+1&&a.retry&&i<=o){let e=a.retryAfterMs??S(C(i,500,4e3));await new Promise(t=>setTimeout(t,e));continue}throw r}let f=l.headers.get(`content-type`)??``,p;return p=f.includes(`application/json`)?await l.json():await l.text(),this.opts.telemetry?.onResponse?.({status:l.status,url:t,requestId:d,durationMs:u}),{data:p,status:l.status,requestId:d,headers:l.headers}}catch(r){this.opts.telemetry?.onError?.({url:t,requestId:n,error:r});let a=P(e,r);if(i<=o&&a.retry){let e=a.retryAfterMs??S(C(i,500,4e3));await new Promise(t=>setTimeout(t,e));continue}throw r}finally{clearTimeout(l)}}throw Error(`Unexpected transport exit`)}};function I(e){return typeof e==`object`&&!!e}var L=class{async verifySignature(e){let t=e.toleranceSec??300,n=R(e.headers,`mappa-signature`);if(!n)throw Error(`Missing mappa-signature header`);let r=z(n),i=Number(r.t);if(!Number.isFinite(i))throw Error(`Invalid signature timestamp`);let a=Math.floor(Date.now()/1e3);if(Math.abs(a-i)>t)throw Error(`Signature timestamp outside tolerance`);let o=`${r.t}.${e.payload}`;if(!H(await B(e.secret,o),r.v1))throw Error(`Invalid signature`);return{ok:!0}}parseEvent(e){let t=JSON.parse(e);if(!I(t))throw Error(`Invalid webhook payload: not an object`);let n=t,r=n.id,i=n.type,a=n.createdAt;if(typeof r!=`string`)throw Error(`Invalid webhook payload: id must be a string`);if(typeof i!=`string`)throw Error(`Invalid webhook payload: type must be a string`);if(typeof a!=`string`)throw Error(`Invalid webhook payload: createdAt must be a string`);return{id:r,type:i,createdAt:a,data:`data`in n?n.data:void 0}}};function R(e,t){let n=Object.keys(e).find(e=>e.toLowerCase()===t.toLowerCase()),r=n?e[n]:void 0;if(r)return Array.isArray(r)?r[0]:r}function z(e){let t={};for(let n of e.split(`,`)){let[e,r]=n.split(`=`);e&&r&&(t[e.trim()]=r.trim())}if(!t.t||!t.v1)throw Error(`Invalid signature format`);return{t:t.t,v1:t.v1}}async function B(e,t){let n=new TextEncoder,r=await crypto.subtle.importKey(`raw`,n.encode(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`]);return V(await crypto.subtle.sign(`HMAC`,r,n.encode(t)))}function V(e){let t=new Uint8Array(e),n=``;for(let e of t)n+=e.toString(16).padStart(2,`0`);return n}function H(e,t){if(e.length!==t.length)return!1;let n=0;for(let r=0;r<e.length;r++)n|=e.charCodeAt(r)^t.charCodeAt(r);return n===0}var U=class e{files;jobs;reports;feedback;credits;entities;webhooks;health;transport;opts;constructor(e){if(!e.apiKey)throw new t(`apiKey is required`);let n=e.baseUrl??`https://api.mappa.ai`,r=e.timeoutMs??3e4,i=e.maxRetries??2;this.opts={...e,apiKey:e.apiKey,baseUrl:n,timeoutMs:r,maxRetries:i},this.transport=new F({apiKey:e.apiKey,baseUrl:n,timeoutMs:r,maxRetries:i,defaultHeaders:e.defaultHeaders,fetch:e.fetch,telemetry:e.telemetry,userAgent:e.userAgent}),this.files=new m(this.transport),this.jobs=new O(this.transport),this.reports=new A(this.transport,this.jobs,this.files,this.opts.fetch??fetch),this.feedback=new p(this.transport),this.credits=new c(this.transport),this.entities=new f(this.transport),this.webhooks=new L,this.health=new y(this.transport)}withOptions(t){return new e({...this.opts,...t,apiKey:t.apiKey??this.opts.apiKey})}close(){}};function W(e){return e.output.type===`markdown`}function G(e){return e.output.type===`json`}function K(e){return e.output.type===`pdf`}function q(e){return e.output.type===`url`}function J(e){return e.entity!==void 0&&e.entity!==null}function Y(e){return e instanceof t}export{n as ApiError,i as AuthError,s as JobCanceledError,o as JobFailedError,U as Mappa,t as MappaError,r as RateLimitError,a as ValidationError,J as hasEntity,G as isJsonReport,Y as isMappaError,W as isMarkdownReport,K as isPdfReport,q as isUrlReport};
|
|
1
|
+
import{init as e}from"@paralleldrive/cuid2";var t=class extends Error{name=`MappaError`;requestId;code;constructor(e,t){super(e),this.requestId=t?.requestId,this.code=t?.code,this.cause=t?.cause}},n=class extends t{name=`ApiError`;status;details;constructor(e,t){super(e,{requestId:t.requestId,code:t.code}),this.status=t.status,this.details=t.details}},r=class extends n{name=`RateLimitError`;retryAfterMs},i=class extends n{name=`AuthError`},a=class extends n{name=`ValidationError`},o=class extends t{name=`JobFailedError`;jobId;constructor(e,t,n){super(t,n),this.jobId=e}},s=class extends t{name=`JobCanceledError`;jobId;constructor(e,t,n){super(t,n),this.jobId=e}},c=class{constructor(e){this.transport=e}async getBalance(e){return(await this.transport.request({method:`GET`,path:`/v1/credits/balance`,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async listTransactions(e){let t={};return e?.limit!==void 0&&(t.limit=String(e.limit)),e?.offset!==void 0&&(t.offset=String(e.offset)),(await this.transport.request({method:`GET`,path:`/v1/credits/transactions`,query:t,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async*listAllTransactions(e){let t=0,n=e?.limit??50;for(;;){let r=await this.listTransactions({...e,limit:n,offset:t});for(let e of r.transactions)yield e;if(t+=r.transactions.length,t>=r.pagination.total)break}}async getJobUsage(e,n){if(!e)throw new t(`jobId is required`);return(await this.transport.request({method:`GET`,path:`/v1/credits/usage/${encodeURIComponent(e)}`,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}async hasEnough(e,t){return(await this.getBalance(t)).available>=e}async getAvailable(e){return(await this.getBalance(e)).available}};const l=/^[a-zA-Z0-9_-]{1,64}$/;function u(e){if(typeof e!=`string`)throw new t(`Tags must be strings`);if(!l.test(e))throw new t(`Invalid tag "${e}": must be 1-64 characters, alphanumeric with underscores and hyphens only`)}function d(e){if(!Array.isArray(e))throw new t(`tags must be an array`);if(e.length>10)throw new t(`Too many tags: maximum 10 per request`);for(let t of e)u(t)}var f=class{constructor(e){this.transport=e}async get(e,n){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);return(await this.transport.request({method:`GET`,path:`/v1/entities/${encodeURIComponent(e)}`,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}async list(e){let t={};return e?.tags&&(d(e.tags),t.tags=e.tags.join(`,`)),e?.cursor&&(t.cursor=e.cursor),e?.limit!==void 0&&(t.limit=String(e.limit)),(await this.transport.request({method:`GET`,path:`/v1/entities`,query:t,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async*listAll(e){let t,n=!0;for(;n;){let r=await this.list({...e,cursor:t});for(let e of r.entities)yield e;t=r.cursor,n=r.hasMore}}async getByTag(e,t){return u(e),this.list({...t,tags:[e]})}async addTags(e,n,r){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);if(n.length===0)throw new t(`At least one tag is required`);return d(n),(await this.transport.request({method:`POST`,path:`/v1/entities/${encodeURIComponent(e)}/tags`,body:{tags:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}async removeTags(e,n,r){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);if(n.length===0)throw new t(`At least one tag is required`);return d(n),(await this.transport.request({method:`DELETE`,path:`/v1/entities/${encodeURIComponent(e)}/tags`,body:{tags:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}async setTags(e,n,r){if(!e||typeof e!=`string`)throw new t(`entityId must be a non-empty string`);return d(n),(await this.transport.request({method:`PUT`,path:`/v1/entities/${encodeURIComponent(e)}/tags`,body:{tags:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}},p=class{constructor(e){this.transport=e}async create(e){if(!!e.reportId==!!e.jobId)throw new t(`Provide exactly one of reportId or jobId`);return(await this.transport.request({method:`POST`,path:`/v1/feedback`,body:e,idempotencyKey:e.idempotencyKey,requestId:e.requestId,signal:e.signal,retryable:!0})).data}},m=class{constructor(e){this.transport=e}async upload(e){if(typeof FormData>`u`)throw new t(`FormData is not available in this runtime; cannot perform multipart upload`);let n=h(e.file,e.filename),r=e.contentType??n;if(!r)throw new t(`contentType is required when it cannot be inferred from file.type or filename`);let i=e.filename??g(e.file)??`upload`,a=await v(e.file,r),o=new FormData;return o.append(`file`,a,i),o.append(`contentType`,r),e.filename&&o.append(`filename`,e.filename),(await this.transport.request({method:`POST`,path:`/v1/files`,body:o,idempotencyKey:e.idempotencyKey,requestId:e.requestId,signal:e.signal,retryable:!0})).data}async get(e,n){if(!e)throw new t(`mediaId is required`);return(await this.transport.request({method:`GET`,path:`/v1/files/${encodeURIComponent(e)}`,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}async list(e){let t={};return e?.limit!==void 0&&(t.limit=String(e.limit)),e?.cursor&&(t.cursor=e.cursor),e?.includeDeleted!==void 0&&(t.includeDeleted=String(e.includeDeleted)),(await this.transport.request({method:`GET`,path:`/v1/files`,query:t,requestId:e?.requestId,signal:e?.signal,retryable:!0})).data}async*listAll(e){let t,n=!0;for(;n;){let r=await this.list({...e,cursor:t});for(let e of r.files)yield e;t=r.cursor,n=r.hasMore}}async setRetentionLock(e,n,r){if(!e)throw new t(`mediaId is required`);return(await this.transport.request({method:`PATCH`,path:`/v1/files/${encodeURIComponent(e)}/retention`,body:{lock:n},requestId:r?.requestId,signal:r?.signal,retryable:!0})).data}async delete(e,n){if(!e)throw new t(`mediaId is required`);return(await this.transport.request({method:`DELETE`,path:`/v1/files/${encodeURIComponent(e)}`,idempotencyKey:n?.idempotencyKey,requestId:n?.requestId,signal:n?.signal,retryable:!0})).data}};function h(e,t){if(typeof Blob<`u`&&e instanceof Blob&&e.type)return e.type;if(t)return _(t)}function g(e){if(typeof Blob<`u`&&e instanceof Blob){let t=e;if(typeof t.name==`string`&&t.name)return t.name}}function _(e){let t=e.lastIndexOf(`.`);if(!(t<0))switch(e.slice(t+1).toLowerCase()){case`mp4`:return`video/mp4`;case`mov`:return`video/quicktime`;case`webm`:return`video/webm`;case`mp3`:return`audio/mpeg`;case`wav`:return`audio/wav`;case`m4a`:return`audio/mp4`;case`png`:return`image/png`;case`jpg`:case`jpeg`:return`image/jpeg`;case`gif`:return`image/gif`;case`webp`:return`image/webp`;case`pdf`:return`application/pdf`;case`json`:return`application/json`;case`txt`:return`text/plain`;default:return}}async function v(e,n){if(typeof Blob<`u`&&e instanceof Blob){if(e.type===n)return e;let t=e;return typeof t.slice==`function`?t.slice(0,e.size,n):e}if(e instanceof ArrayBuffer||e instanceof Uint8Array)return new Blob([e],{type:n});if(typeof ReadableStream<`u`&&e instanceof ReadableStream){if(typeof Response>`u`)throw new t(`ReadableStream upload requires Response to convert stream to Blob`);let r=await new Response(e).blob();return r.slice(0,r.size,n)}throw new t(`Unsupported file type for upload()`)}var y=class{constructor(e){this.transport=e}async ping(){return(await this.transport.request({method:`GET`,path:`/v1/health/ping`,retryable:!0})).data}};const b=e({length:32});function x(e,t){let n=e.get(t);return n===null?void 0:n}function S(e){let t=.8+Math.random()*.4;return Math.floor(e*t)}function C(e,t,n){let r=t*2**Math.max(0,e-1);return Math.min(r,n)}function w(e){return!!e&&typeof e.aborted==`boolean`}function T(){let e=Error(`The operation was aborted`);return e.name=`AbortError`,e}function E(e=`req`){return`${e}_${b()}`}var D=class{constructor(e){this.transport=e}async get(e,t){return(await this.transport.request({method:`GET`,path:`/v1/jobs/${encodeURIComponent(e)}`,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async cancel(e,t){return(await this.transport.request({method:`POST`,path:`/v1/jobs/${encodeURIComponent(e)}/cancel`,idempotencyKey:t?.idempotencyKey,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async wait(e,t){let n=t?.timeoutMs??5*6e4,r=new AbortController,i=setTimeout(()=>r.abort(),n);if(t?.signal){if(t.signal.aborted)throw clearTimeout(i),T();t.signal.addEventListener(`abort`,()=>r.abort(),{once:!0})}try{for await(let n of this.stream(e,{signal:r.signal,onEvent:t?.onEvent}))if(n.type===`terminal`){let t=n.job;if(t.status===`succeeded`)return t;if(t.status===`failed`)throw new o(e,t.error?.message??`Job failed`,{requestId:t.requestId,code:t.error?.code,cause:t.error});if(t.status===`canceled`)throw new s(e,`Job canceled`,{requestId:t.requestId,cause:t.error})}throw new o(e,`Timed out waiting for job ${e} after ${n}ms`,{cause:{jobId:e,timeoutMs:n}})}finally{clearTimeout(i)}}async*stream(e,n){let r,i=0;for(;i<3;)try{let a=this.transport.streamSSE(`/v1/jobs/${encodeURIComponent(e)}/stream`,{signal:n?.signal,lastEventId:r});for await(let e of a){if(r=e.id,e.event===`error`){let n=e.data;throw new t(n.error?.message??`Unknown SSE error`,{code:n.error?.code})}if(e.event===`heartbeat`)continue;let a=this.mapSSEToJobEvent(e);if(a&&(n?.onEvent?.(a),yield a,e.event===`terminal`))return;i=0}i++,i<3&&await this.backoff(i)}catch(e){if(n?.signal?.aborted||(i++,i>=3))throw e;await this.backoff(i)}throw new t(`Failed to get status for job ${e} after 3 retries`)}mapSSEToJobEvent(e){let t=e.data;switch(e.event){case`status`:return{type:`status`,job:t.job};case`stage`:return{type:`stage`,stage:t.stage,progress:t.progress,job:t.job};case`terminal`:return{type:`terminal`,job:t.job};default:return{type:`status`,job:t.job}}}async backoff(e){let t=Math.min(1e3*2**e,1e4),n=t*.5*Math.random();await new Promise(e=>setTimeout(e,t+n))}};function O(e){let n=e;if(!(e=>typeof e==`object`&&!!e)(n))throw new t(`media must be an object`);if(n.url!==void 0)throw new t(`media.url is not supported; pass { mediaId } or use createJobFromUrl()`);let r=n.mediaId;if(typeof r!=`string`||!r)throw new t(`media.mediaId must be a non-empty string`)}var k=class{constructor(e,t,n,r){this.transport=e,this.jobs=t,this.files=n,this.fetchImpl=r}async createJob(e){O(e.media);let t=e.idempotencyKey??this.defaultIdempotencyKey(e),n=await this.transport.request({method:`POST`,path:`/v1/reports/jobs`,body:this.normalizeJobRequest(e),idempotencyKey:t,requestId:e.requestId,retryable:!0}),r={...n.data,requestId:n.requestId??n.data.requestId};return r.handle=this.makeHandle(r.jobId),r}async createJobFromFile(e){let{file:t,contentType:n,filename:r,idempotencyKey:i,requestId:a,signal:o,...s}=e,c=await this.files.upload({file:t,contentType:n,filename:r,idempotencyKey:i,requestId:a,signal:o});return this.createJob({...s,media:{mediaId:c.mediaId},idempotencyKey:i,requestId:a})}async createJobFromUrl(e){let{url:n,contentType:r,filename:i,idempotencyKey:a,requestId:o,signal:s,...c}=e,l;try{l=new URL(n)}catch{throw new t(`url must be a valid URL`)}if(l.protocol!==`http:`&&l.protocol!==`https:`)throw new t(`url must use http: or https:`);let u=await this.fetchImpl(l.toString(),{signal:s});if(!u.ok)throw new t(`Failed to download url (status ${u.status})`);let d=u.headers.get(`content-type`)??void 0,f=r??d;if(!f)throw new t(`contentType is required when it cannot be inferred from the download response`);if(typeof Blob>`u`)throw new t(`Blob is not available in this runtime; cannot download and upload from url`);let p=await u.blob(),m=await this.files.upload({file:p,contentType:f,filename:i,idempotencyKey:a,requestId:o,signal:s});return this.createJob({...c,media:{mediaId:m.mediaId},idempotencyKey:a,requestId:o})}async get(e,t){return(await this.transport.request({method:`GET`,path:`/v1/reports/${encodeURIComponent(e)}`,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async getByJob(e,t){return(await this.transport.request({method:`GET`,path:`/v1/reports/by-job/${encodeURIComponent(e)}`,requestId:t?.requestId,signal:t?.signal,retryable:!0})).data}async generate(e,n){let r=await this.createJob(e);if(!r.handle)throw new t(`Job receipt is missing handle`);return r.handle.wait(n?.wait)}async generateFromFile(e,n){let r=await this.createJobFromFile(e);if(!r.handle)throw new t(`Job receipt is missing handle`);return r.handle.wait(n?.wait)}async generateFromUrl(e,n){let r=await this.createJobFromUrl(e);if(!r.handle)throw new t(`Job receipt is missing handle`);return r.handle.wait(n?.wait)}makeHandle(e){let n=this;return{jobId:e,stream:t=>n.jobs.stream(e,t),async wait(r){let i=await n.jobs.wait(e,r);if(!i.reportId)throw new t(`Job ${e} succeeded but no reportId was returned`);return n.get(i.reportId)},cancel:()=>n.jobs.cancel(e),job:()=>n.jobs.get(e),report:()=>n.getByJob(e)}}defaultIdempotencyKey(e){return E(`idem`)}normalizeJobRequest(e){let t=e.target;if(!t)return e;let n={strategy:t.strategy};switch(t.onMiss&&(n.on_miss=t.onMiss),t.tags&&t.tags.length>0&&(n.tags=t.tags),t.excludeTags&&t.excludeTags.length>0&&(n.exclude_tags=t.excludeTags),t.strategy){case`dominant`:return{...e,target:n};case`timerange`:{let r=t.timeRange??{};return{...e,target:{...n,timerange:{start_seconds:r.startSeconds??null,end_seconds:r.endSeconds??null}}}}case`entity_id`:return{...e,target:{...n,entity_id:t.entityId}};case`magic_hint`:return{...e,target:{...n,hint:t.hint}};default:return e}}};function A(e,t,n){let r=new URL(t.replace(/^\//,``),e.endsWith(`/`)?e:`${e}/`);if(n)for(let[e,t]of Object.entries(n))t!==void 0&&r.searchParams.set(e,String(t));return r.toString()}async function j(e){let t=await e.text();if(!t)return{parsed:null,text:``};try{return{parsed:JSON.parse(t),text:t}}catch{return{parsed:t,text:t}}}function M(e,t){let o=e.headers.get(`x-request-id`)??void 0,s,c=`Request failed with status ${e.status}`,l=t;if(typeof t==`string`)c=t;else if(t&&typeof t==`object`){let e=t,n=e.error??e;if(n&&typeof n==`object`){let e=n;typeof e.message==`string`&&(c=e.message),typeof e.code==`string`&&(s=e.code),`details`in e&&(l=e.details)}}if(e.status===401||e.status===403)return new i(c,{status:e.status,requestId:o,code:s,details:l});if(e.status===422)return new a(c,{status:e.status,requestId:o,code:s,details:l});if(e.status===429){let t=new r(c,{status:e.status,requestId:o,code:s,details:l}),n=e.headers.get(`retry-after`);if(n){let e=Number(n);Number.isFinite(e)&&e>=0&&(t.retryAfterMs=e*1e3)}return t}return new n(c,{status:e.status,requestId:o,code:s,details:l})}function N(e,t){return e.retryable?t instanceof r?{retry:!0,retryAfterMs:t.retryAfterMs}:t instanceof n?{retry:t.status>=500&&t.status<=599}:t instanceof TypeError?{retry:!0}:{retry:!1}:{retry:!1}}var P=class{fetchImpl;constructor(e){this.opts=e,this.fetchImpl=e.fetch??fetch}async*streamSSE(e,n){let r=A(this.opts.baseUrl,e),i=E(`req`),a={Accept:`text/event-stream`,"Cache-Control":`no-cache`,"Mappa-Api-Key":this.opts.apiKey,"X-Request-Id":i,...this.opts.userAgent?{"User-Agent":this.opts.userAgent}:{},...this.opts.defaultHeaders??{}};n?.lastEventId&&(a[`Last-Event-ID`]=n.lastEventId);let o=new AbortController,s=setTimeout(()=>o.abort(T()),this.opts.timeoutMs);if(w(n?.signal)){let e=n?.signal;if(e?.aborted)throw clearTimeout(s),T();e?.addEventListener(`abort`,()=>o.abort(T()),{once:!0})}this.opts.telemetry?.onRequest?.({method:`GET`,url:r,requestId:i});let c;try{c=await this.fetchImpl(r,{method:`GET`,headers:a,signal:o.signal})}catch(e){throw clearTimeout(s),this.opts.telemetry?.onError?.({url:r,requestId:i,error:e}),e}if(!c.ok){clearTimeout(s);let{parsed:e}=await j(c),t=M(c,e);throw this.opts.telemetry?.onError?.({url:r,requestId:i,error:t}),t}if(!c.body)throw clearTimeout(s),new t(`SSE response has no body`);try{yield*this.parseSSEStream(c.body)}finally{clearTimeout(s)}}async*parseSSEStream(e){let t=new TextDecoder,n=e.getReader(),r=``;try{for(;;){let{done:e,value:i}=await n.read();if(e)break;r+=t.decode(i,{stream:!0});let a=r.split(`
|
|
2
|
+
|
|
3
|
+
`);r=a.pop()??``;for(let e of a){if(!e.trim())continue;let t=this.parseSSEEvent(e);t&&(yield t)}}if(r.trim()){let e=this.parseSSEEvent(r);e&&(yield e)}}finally{n.releaseLock()}}parseSSEEvent(e){let t=e.split(`
|
|
4
|
+
`),n,r=`message`,i=``;for(let e of t)e.startsWith(`id:`)?n=e.slice(3).trim():e.startsWith(`event:`)?r=e.slice(6).trim():e.startsWith(`data:`)&&(i&&(i+=`
|
|
5
|
+
`),i+=e.slice(5).trim());if(!i)return null;let a;try{a=JSON.parse(i)}catch{a=i}return{id:n,event:r,data:a}}async request(e){let t=A(this.opts.baseUrl,e.path,e.query),n=e.requestId??E(`req`),r={"Mappa-Api-Key":this.opts.apiKey,"X-Request-Id":n,...this.opts.userAgent?{"User-Agent":this.opts.userAgent}:{},...this.opts.defaultHeaders??{}};if(e.idempotencyKey&&(r[`Idempotency-Key`]=e.idempotencyKey),e.headers)for(let[t,n]of Object.entries(e.headers))n!==void 0&&(r[t]=n);let i=typeof FormData<`u`&&e.body instanceof FormData;e.body!==void 0&&!i&&(r[`Content-Type`]=`application/json`);let a=e.body===void 0?void 0:i?e.body:JSON.stringify(e.body),o=Math.max(0,this.opts.maxRetries),s=Date.now();for(let i=1;i<=1+o;i++){let c=new AbortController,l=setTimeout(()=>c.abort(T()),this.opts.timeoutMs);if(w(e.signal)){let t=e.signal;if(!t)throw clearTimeout(l),Error(`Unexpected: abort signal missing`);if(t.aborted)throw clearTimeout(l),T();t.addEventListener(`abort`,()=>c.abort(T()),{once:!0})}this.opts.telemetry?.onRequest?.({method:e.method,url:t,requestId:n});try{let l=await this.fetchImpl(t,{method:e.method,headers:r,body:a,signal:c.signal}),u=Date.now()-s,d=x(l.headers,`x-request-id`)??n;if(!l.ok){let{parsed:n}=await j(l),r=M(l,n);this.opts.telemetry?.onError?.({url:t,requestId:d,error:r});let a=N(e,r);if(i<=o+1&&a.retry&&i<=o){let e=a.retryAfterMs??S(C(i,500,4e3));await new Promise(t=>setTimeout(t,e));continue}throw r}let f=l.headers.get(`content-type`)??``,p;return p=f.includes(`application/json`)?await l.json():await l.text(),this.opts.telemetry?.onResponse?.({status:l.status,url:t,requestId:d,durationMs:u}),{data:p,status:l.status,requestId:d,headers:l.headers}}catch(r){this.opts.telemetry?.onError?.({url:t,requestId:n,error:r});let a=N(e,r);if(i<=o&&a.retry){let e=a.retryAfterMs??S(C(i,500,4e3));await new Promise(t=>setTimeout(t,e));continue}throw r}finally{clearTimeout(l)}}throw Error(`Unexpected transport exit`)}};function F(e){return typeof e==`object`&&!!e}var I=class{async verifySignature(e){let t=e.toleranceSec??300,n=L(e.headers,`mappa-signature`);if(!n)throw Error(`Missing mappa-signature header`);let r=R(n),i=Number(r.t);if(!Number.isFinite(i))throw Error(`Invalid signature timestamp`);let a=Math.floor(Date.now()/1e3);if(Math.abs(a-i)>t)throw Error(`Signature timestamp outside tolerance`);let o=`${r.t}.${e.payload}`;if(!V(await z(e.secret,o),r.v1))throw Error(`Invalid signature`);return{ok:!0}}parseEvent(e){let t=JSON.parse(e);if(!F(t))throw Error(`Invalid webhook payload: not an object`);let n=t,r=n.id,i=n.type,a=n.createdAt;if(typeof r!=`string`)throw Error(`Invalid webhook payload: id must be a string`);if(typeof i!=`string`)throw Error(`Invalid webhook payload: type must be a string`);if(typeof a!=`string`)throw Error(`Invalid webhook payload: createdAt must be a string`);return{id:r,type:i,createdAt:a,data:`data`in n?n.data:void 0}}};function L(e,t){let n=Object.keys(e).find(e=>e.toLowerCase()===t.toLowerCase()),r=n?e[n]:void 0;if(r)return Array.isArray(r)?r[0]:r}function R(e){let t={};for(let n of e.split(`,`)){let[e,r]=n.split(`=`);e&&r&&(t[e.trim()]=r.trim())}if(!t.t||!t.v1)throw Error(`Invalid signature format`);return{t:t.t,v1:t.v1}}async function z(e,t){let n=new TextEncoder,r=await crypto.subtle.importKey(`raw`,n.encode(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`]);return B(await crypto.subtle.sign(`HMAC`,r,n.encode(t)))}function B(e){let t=new Uint8Array(e),n=``;for(let e of t)n+=e.toString(16).padStart(2,`0`);return n}function V(e,t){if(e.length!==t.length)return!1;let n=0;for(let r=0;r<e.length;r++)n|=e.charCodeAt(r)^t.charCodeAt(r);return n===0}var H=class e{files;jobs;reports;feedback;credits;entities;webhooks;health;transport;opts;constructor(e){if(!e.apiKey)throw new t(`apiKey is required`);let n=e.baseUrl??`https://api.mappa.ai`,r=e.timeoutMs??3e4,i=e.maxRetries??2;this.opts={...e,apiKey:e.apiKey,baseUrl:n,timeoutMs:r,maxRetries:i},this.transport=new P({apiKey:e.apiKey,baseUrl:n,timeoutMs:r,maxRetries:i,defaultHeaders:e.defaultHeaders,fetch:e.fetch,telemetry:e.telemetry,userAgent:e.userAgent}),this.files=new m(this.transport),this.jobs=new D(this.transport),this.reports=new k(this.transport,this.jobs,this.files,this.opts.fetch??fetch),this.feedback=new p(this.transport),this.credits=new c(this.transport),this.entities=new f(this.transport),this.webhooks=new I,this.health=new y(this.transport)}withOptions(t){return new e({...this.opts,...t,apiKey:t.apiKey??this.opts.apiKey})}close(){}};function U(e){return e.output.type===`markdown`}function W(e){return e.output.type===`json`}function G(e){return e.output.type===`pdf`}function K(e){return e.output.type===`url`}function q(e){return e.entity!==void 0&&e.entity!==null}function J(e){return e instanceof t}export{n as ApiError,i as AuthError,s as JobCanceledError,o as JobFailedError,H as Mappa,t as MappaError,r as RateLimitError,a as ValidationError,q as hasEntity,W as isJsonReport,J as isMappaError,U as isMarkdownReport,G as isPdfReport,K as isUrlReport};
|