parsefy 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -45,8 +45,8 @@ if (!error && object) {
45
45
  console.log(object.invoice_number); // Fully typed!
46
46
 
47
47
  // Access field-level confidence and evidence
48
- console.log(`Overall confidence: ${metadata.confidenceScore}`);
49
- metadata.fieldConfidence.forEach((fc) => {
48
+ console.log(`Overall confidence: ${metadata.confidence_score}`);
49
+ metadata.field_confidence.forEach((fc) => {
50
50
  console.log(`${fc.field}: ${fc.score} (${fc.reason}) - "${fc.text}"`);
51
51
  });
52
52
  }
@@ -111,15 +111,15 @@ interface ExtractResult<T> {
111
111
 
112
112
  // Metadata about the extraction
113
113
  metadata: {
114
- processingTimeMs: number; // Processing time in milliseconds
115
- inputTokens: number; // Input tokens used
116
- outputTokens: number; // Output tokens generated
114
+ processing_time_ms: number; // Processing time in milliseconds
115
+ input_tokens: number; // Input tokens used
116
+ output_tokens: number; // Output tokens generated
117
117
  credits: number; // Credits consumed (1 credit = 1 page)
118
- fallbackTriggered: boolean; // Whether fallback model was used
118
+ fallback_triggered: boolean; // Whether fallback model was used
119
119
 
120
120
  // 🆕 Field-level confidence and evidence
121
- confidenceScore: number; // Overall confidence (0.0 to 1.0)
122
- fieldConfidence: Array<{
121
+ confidence_score: number; // Overall confidence (0.0 to 1.0)
122
+ field_confidence: Array<{
123
123
  field: string; // JSON path (e.g., "$.invoice_number")
124
124
  score: number; // Confidence score (0.0 to 1.0)
125
125
  reason: string; // "Exact match", "Inferred from header", etc.
@@ -150,9 +150,9 @@ const { object, metadata } = await client.extract({ file, schema });
150
150
  vendor: "Acme Corp"
151
151
  }
152
152
 
153
- // metadata.confidenceScore: 0.94
153
+ // metadata.confidence_score: 0.94
154
154
 
155
- // metadata.fieldConfidence:
155
+ // metadata.field_confidence:
156
156
  [
157
157
  { field: "$.invoice_number", score: 0.98, reason: "Exact match", page: 1, text: "Invoice # INV-2024-0042" },
158
158
  { field: "$.date", score: 0.95, reason: "Exact match", page: 1, text: "Date: 01/15/2024" },
@@ -286,8 +286,8 @@ app.post('/extract', upload.single('document'), async (req, res) => {
286
286
 
287
287
  res.json({
288
288
  data: object,
289
- confidence: metadata.confidenceScore,
290
- fieldDetails: metadata.fieldConfidence,
289
+ confidence: metadata.confidence_score,
290
+ fieldDetails: metadata.field_confidence,
291
291
  error,
292
292
  });
293
293
  });
@@ -313,7 +313,7 @@ app.post('/extract', async (c) => {
313
313
 
314
314
  return c.json({
315
315
  data: object,
316
- confidence: metadata.confidenceScore,
316
+ confidence: metadata.confidence_score,
317
317
  issues: metadata.issues,
318
318
  error,
319
319
  });
@@ -334,13 +334,13 @@ try {
334
334
  // Extraction-level errors (request succeeded, but extraction failed)
335
335
  if (error) {
336
336
  console.error(`Extraction failed: [${error.code}] ${error.message}`);
337
- console.log(`Fallback triggered: ${metadata.fallbackTriggered}`);
337
+ console.log(`Fallback triggered: ${metadata.fallback_triggered}`);
338
338
  console.log(`Issues: ${metadata.issues.join(', ')}`);
339
339
  return;
340
340
  }
341
341
 
342
342
  // Check for low confidence fields
343
- const lowConfidence = metadata.fieldConfidence.filter((fc) => fc.score < 0.80);
343
+ const lowConfidence = metadata.field_confidence.filter((fc) => fc.score < 0.80);
344
344
  if (lowConfidence.length > 0) {
345
345
  console.warn('Low confidence fields:', lowConfidence);
346
346
  }
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var zodToJsonSchema=require('zod-to-json-schema');var u=.85,d={".pdf":"application/pdf",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document"},l=10*1024*1024,g="https://api.parsefy.io",x=6e4;var s=class extends Error{constructor(e,r){super(e),this.name="ParsefyError",this.code=r,typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,this.constructor);}},p=class extends s{constructor(e,r,o){super(e),this.name="APIError",this.statusCode=r,this.response=o;}},y=class extends s{constructor(e,r,o){super(e,r),this.name="ExtractionError",this.metadata=o;}},a=class extends s{constructor(e){super(e),this.name="ValidationError";}};function h(){return typeof process<"u"&&process.versions?.node!==void 0}function R(t){let e=zodToJsonSchema.zodToJsonSchema(t,{$refStrategy:"none",target:"jsonSchema7"});return "$schema"in e&&delete e.$schema,e}function b(t){let e=t.toLowerCase().match(/\.[^.]+$/)?.[0];return e&&d[e]||null}function w(t){if(!b(t)){let r=Object.keys(d).join(", ");throw new a(`Unsupported file type. Supported types: ${r}`)}}function m(t){if(t===0)throw new a("File is empty");if(t>l){let e=l/1048576;throw new a(`File size exceeds maximum limit of ${e}MB`)}}function F(t){let e=t._meta||{confidence_score:1,field_confidence:[],issues:[]};return {object:t.object,metadata:{processingTimeMs:t.metadata.processing_time_ms,inputTokens:t.metadata.input_tokens,outputTokens:t.metadata.output_tokens,credits:t.metadata.credits,fallbackTriggered:t.metadata.fallback_triggered,confidenceScore:e.confidence_score,fieldConfidence:e.field_confidence.map(r=>({field:r.field,score:r.score,reason:r.reason,page:r.page,text:r.text})),issues:e.issues},error:t.error}}function T(t,e){let r=b(e)||"application/octet-stream",o=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength);return typeof File<"u"?new File([o],e,{type:r}):new Blob([o],{type:r})}async function I(t){if(!h())throw new a("File path strings are only supported in Node.js. Use File or Blob in the browser.");let e=await import('fs'),r=await import('path');if(!e.existsSync(t))throw new a(`File not found: ${t}`);let o=r.basename(t);w(o);let c=e.readFileSync(t);return m(c.length),{buffer:c,filename:o}}async function _(t){if(typeof t=="string"){let{buffer:e,filename:r}=await I(t);return T(e,r)}if(Buffer.isBuffer(t))return m(t.length),T(t,"document.pdf");if(t instanceof File)return w(t.name),m(t.size),t;if(t instanceof Blob)return m(t.size),t;throw new a("Invalid file input. Expected File, Blob, Buffer, or file path string.")}function P(t){return new Promise(e=>setTimeout(e,t))}function S(t,e=1e3){let r=e*Math.pow(2,t),o=Math.random()*.1*r;return Math.min(r+o,3e4)}var E=class{constructor(e){this.maxRetries=3;let r={};if(typeof e=="string"?r={apiKey:e}:e&&(r=e),this.apiKey=r.apiKey||this.getEnvApiKey(),!this.apiKey)throw new a("API key is required. Provide it in the constructor or set the PARSEFY_API_KEY environment variable.");this.baseUrl=r.baseUrl||g,this.timeout=r.timeout||x;}getEnvApiKey(){return h()&&process.env.PARSEFY_API_KEY||""}async extract(e){let{file:r,schema:o,confidenceThreshold:c}=e,n=R(o),f=await _(r),i=new FormData;return i.append("file",f),i.append("output_schema",JSON.stringify(n)),i.append("confidence_threshold",String(c??.85)),this.makeRequestWithRetry(i)}async makeRequestWithRetry(e,r=0){try{return await this.makeRequest(e)}catch(o){if(o instanceof p&&o.statusCode===429&&r<this.maxRetries){let c=S(r);return await P(c),this.makeRequestWithRetry(e,r+1)}throw o}}async makeRequest(e){let r=`${this.baseUrl}/v1/extract`,o=new AbortController,c=setTimeout(()=>o.abort(),this.timeout);try{let n=await fetch(r,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`},body:e,signal:o.signal});if(clearTimeout(c),!n.ok){let i=await this.parseErrorResponse(n);throw new p(i.message||`API request failed with status ${n.status}`,n.status,i)}let f;try{f=await n.json();}catch{throw new s("Failed to parse API response as JSON. The API may have returned an invalid response.","PARSE_ERROR")}try{return F(f)}catch(i){throw new s(`Failed to transform API response: ${i instanceof Error?i.message:String(i)}`,"TRANSFORM_ERROR")}}catch(n){throw clearTimeout(c),n instanceof Error&&n.name==="AbortError"?new s(`Request timed out after ${this.timeout}ms`,"TIMEOUT"):n instanceof s?n:n instanceof TypeError&&n.message.includes("fetch")?new s(`Network error: Unable to connect to the Parsefy API. ${n.message}`,"NETWORK_ERROR"):n instanceof TypeError?new s(`Type error: ${n.message}. This may indicate an API response format issue.`,"TYPE_ERROR"):new s(`Unexpected error: ${n instanceof Error?n.message:String(n)}`,"UNKNOWN_ERROR")}}async parseErrorResponse(e){try{return await e.json()}catch{try{return {message:await e.text()||e.statusText}}catch{return {message:e.statusText}}}}};
1
+ 'use strict';var zodToJsonSchema=require('zod-to-json-schema');var u=.85,d={".pdf":"application/pdf",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document"},l=10*1024*1024,g="https://api.parsefy.io",x=6e4;var s=class extends Error{constructor(e,r){super(e),this.name="ParsefyError",this.code=r,typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,this.constructor);}},p=class extends s{constructor(e,r,o){super(e),this.name="APIError",this.statusCode=r,this.response=o;}},y=class extends s{constructor(e,r,o){super(e,r),this.name="ExtractionError",this.metadata=o;}},a=class extends s{constructor(e){super(e),this.name="ValidationError";}};function h(){return typeof process<"u"&&process.versions?.node!==void 0}function T(t){let e=zodToJsonSchema.zodToJsonSchema(t,{$refStrategy:"none",target:"jsonSchema7"});return "$schema"in e&&delete e.$schema,e}function b(t){let e=t.toLowerCase().match(/\.[^.]+$/)?.[0];return e&&d[e]||null}function _(t){if(!b(t)){let r=Object.keys(d).join(", ");throw new a(`Unsupported file type. Supported types: ${r}`)}}function m(t){if(t===0)throw new a("File is empty");if(t>l){let e=l/1048576;throw new a(`File size exceeds maximum limit of ${e}MB`)}}function w(t){let e=t._meta||{confidence_score:1,field_confidence:[],issues:[]};return {object:t.object,metadata:{processing_time_ms:t.metadata.processing_time_ms,input_tokens:t.metadata.input_tokens,output_tokens:t.metadata.output_tokens,credits:t.metadata.credits,fallback_triggered:t.metadata.fallback_triggered,confidence_score:e.confidence_score,field_confidence:e.field_confidence.map(r=>({field:r.field,score:r.score,reason:r.reason,page:r.page,text:r.text})),issues:e.issues},error:t.error}}function R(t,e){let r=b(e)||"application/octet-stream",o=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength);return typeof File<"u"?new File([o],e,{type:r}):new Blob([o],{type:r})}async function I(t){if(!h())throw new a("File path strings are only supported in Node.js. Use File or Blob in the browser.");let e=await import('fs'),r=await import('path');if(!e.existsSync(t))throw new a(`File not found: ${t}`);let o=r.basename(t);_(o);let c=e.readFileSync(t);return m(c.length),{buffer:c,filename:o}}async function F(t){if(typeof t=="string"){let{buffer:e,filename:r}=await I(t);return R(e,r)}if(Buffer.isBuffer(t))return m(t.length),R(t,"document.pdf");if(t instanceof File)return _(t.name),m(t.size),t;if(t instanceof Blob)return m(t.size),t;throw new a("Invalid file input. Expected File, Blob, Buffer, or file path string.")}function P(t){return new Promise(e=>setTimeout(e,t))}function A(t,e=1e3){let r=e*Math.pow(2,t),o=Math.random()*.1*r;return Math.min(r+o,3e4)}var E=class{constructor(e){this.maxRetries=3;let r={};if(typeof e=="string"?r={apiKey:e}:e&&(r=e),this.apiKey=r.apiKey||this.getEnvApiKey(),!this.apiKey)throw new a("API key is required. Provide it in the constructor or set the PARSEFY_API_KEY environment variable.");this.baseUrl=r.baseUrl||g,this.timeout=r.timeout||x;}getEnvApiKey(){return h()&&process.env.PARSEFY_API_KEY||""}async extract(e){let{file:r,schema:o,confidenceThreshold:c}=e,n=T(o),f=await F(r),i=new FormData;return i.append("file",f),i.append("output_schema",JSON.stringify(n)),i.append("confidence_threshold",String(c??.85)),this.makeRequestWithRetry(i)}async makeRequestWithRetry(e,r=0){try{return await this.makeRequest(e)}catch(o){if(o instanceof p&&o.statusCode===429&&r<this.maxRetries){let c=A(r);return await P(c),this.makeRequestWithRetry(e,r+1)}throw o}}async makeRequest(e){let r=`${this.baseUrl}/v1/extract`,o=new AbortController,c=setTimeout(()=>o.abort(),this.timeout);try{let n=await fetch(r,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`},body:e,signal:o.signal});if(clearTimeout(c),!n.ok){let i=await this.parseErrorResponse(n);throw new p(i.message||`API request failed with status ${n.status}`,n.status,i)}let f;try{f=await n.json();}catch{throw new s("Failed to parse API response as JSON. The API may have returned an invalid response.","PARSE_ERROR")}try{return w(f)}catch(i){throw new s(`Failed to transform API response: ${i instanceof Error?i.message:String(i)}`,"TRANSFORM_ERROR")}}catch(n){throw clearTimeout(c),n instanceof Error&&n.name==="AbortError"?new s(`Request timed out after ${this.timeout}ms`,"TIMEOUT"):n instanceof s?n:n instanceof TypeError&&n.message.includes("fetch")?new s(`Network error: Unable to connect to the Parsefy API. ${n.message}`,"NETWORK_ERROR"):n instanceof TypeError?new s(`Type error: ${n.message}. This may indicate an API response format issue.`,"TYPE_ERROR"):new s(`Unexpected error: ${n instanceof Error?n.message:String(n)}`,"UNKNOWN_ERROR")}}async parseErrorResponse(e){try{return await e.json()}catch{try{return {message:await e.text()||e.statusText}}catch{return {message:e.statusText}}}}};
2
2
  exports.APIError=p;exports.DEFAULT_CONFIDENCE_THRESHOLD=u;exports.ExtractionError=y;exports.Parsefy=E;exports.ParsefyError=s;exports.ValidationError=a;
package/dist/index.d.cts CHANGED
@@ -59,19 +59,19 @@ interface FieldConfidence {
59
59
  */
60
60
  interface ExtractionMetadata {
61
61
  /** Time taken to process the document in milliseconds. */
62
- processingTimeMs: number;
62
+ processing_time_ms: number;
63
63
  /** Number of input tokens used. */
64
- inputTokens: number;
64
+ input_tokens: number;
65
65
  /** Number of output tokens generated. */
66
- outputTokens: number;
66
+ output_tokens: number;
67
67
  /** Number of credits consumed (1 credit = 1 page). */
68
68
  credits: number;
69
69
  /** Whether the fallback model was triggered for higher accuracy. */
70
- fallbackTriggered: boolean;
70
+ fallback_triggered: boolean;
71
71
  /** Overall confidence score for the extraction (0.0 to 1.0). */
72
- confidenceScore: number;
72
+ confidence_score: number;
73
73
  /** Per-field confidence details with evidence and explanations. */
74
- fieldConfidence: FieldConfidence[];
74
+ field_confidence: FieldConfidence[];
75
75
  /** List of issues or warnings encountered during extraction. */
76
76
  issues: string[];
77
77
  }
@@ -126,7 +126,7 @@ interface ExtractResult<T> {
126
126
  * });
127
127
  *
128
128
  * // Check per-field confidence and evidence
129
- * metadata.fieldConfidence.forEach((fc) => {
129
+ * metadata.field_confidence.forEach((fc) => {
130
130
  * console.log(`${fc.field}: ${fc.score} - "${fc.text}"`);
131
131
  * });
132
132
  * ```
@@ -194,8 +194,8 @@ declare class Parsefy {
194
194
  * console.log(object.invoice_number); // Fully typed!
195
195
  *
196
196
  * // Access field-level confidence and evidence
197
- * console.log(`Overall confidence: ${metadata.confidenceScore}`);
198
- * metadata.fieldConfidence.forEach((fc) => {
197
+ * console.log(`Overall confidence: ${metadata.confidence_score}`);
198
+ * metadata.field_confidence.forEach((fc) => {
199
199
  * console.log(`${fc.field}: ${fc.score} (${fc.reason}) - "${fc.text}"`);
200
200
  * });
201
201
  * }
package/dist/index.d.mts CHANGED
@@ -59,19 +59,19 @@ interface FieldConfidence {
59
59
  */
60
60
  interface ExtractionMetadata {
61
61
  /** Time taken to process the document in milliseconds. */
62
- processingTimeMs: number;
62
+ processing_time_ms: number;
63
63
  /** Number of input tokens used. */
64
- inputTokens: number;
64
+ input_tokens: number;
65
65
  /** Number of output tokens generated. */
66
- outputTokens: number;
66
+ output_tokens: number;
67
67
  /** Number of credits consumed (1 credit = 1 page). */
68
68
  credits: number;
69
69
  /** Whether the fallback model was triggered for higher accuracy. */
70
- fallbackTriggered: boolean;
70
+ fallback_triggered: boolean;
71
71
  /** Overall confidence score for the extraction (0.0 to 1.0). */
72
- confidenceScore: number;
72
+ confidence_score: number;
73
73
  /** Per-field confidence details with evidence and explanations. */
74
- fieldConfidence: FieldConfidence[];
74
+ field_confidence: FieldConfidence[];
75
75
  /** List of issues or warnings encountered during extraction. */
76
76
  issues: string[];
77
77
  }
@@ -126,7 +126,7 @@ interface ExtractResult<T> {
126
126
  * });
127
127
  *
128
128
  * // Check per-field confidence and evidence
129
- * metadata.fieldConfidence.forEach((fc) => {
129
+ * metadata.field_confidence.forEach((fc) => {
130
130
  * console.log(`${fc.field}: ${fc.score} - "${fc.text}"`);
131
131
  * });
132
132
  * ```
@@ -194,8 +194,8 @@ declare class Parsefy {
194
194
  * console.log(object.invoice_number); // Fully typed!
195
195
  *
196
196
  * // Access field-level confidence and evidence
197
- * console.log(`Overall confidence: ${metadata.confidenceScore}`);
198
- * metadata.fieldConfidence.forEach((fc) => {
197
+ * console.log(`Overall confidence: ${metadata.confidence_score}`);
198
+ * metadata.field_confidence.forEach((fc) => {
199
199
  * console.log(`${fc.field}: ${fc.score} (${fc.reason}) - "${fc.text}"`);
200
200
  * });
201
201
  * }
package/dist/index.d.ts CHANGED
@@ -59,19 +59,19 @@ interface FieldConfidence {
59
59
  */
60
60
  interface ExtractionMetadata {
61
61
  /** Time taken to process the document in milliseconds. */
62
- processingTimeMs: number;
62
+ processing_time_ms: number;
63
63
  /** Number of input tokens used. */
64
- inputTokens: number;
64
+ input_tokens: number;
65
65
  /** Number of output tokens generated. */
66
- outputTokens: number;
66
+ output_tokens: number;
67
67
  /** Number of credits consumed (1 credit = 1 page). */
68
68
  credits: number;
69
69
  /** Whether the fallback model was triggered for higher accuracy. */
70
- fallbackTriggered: boolean;
70
+ fallback_triggered: boolean;
71
71
  /** Overall confidence score for the extraction (0.0 to 1.0). */
72
- confidenceScore: number;
72
+ confidence_score: number;
73
73
  /** Per-field confidence details with evidence and explanations. */
74
- fieldConfidence: FieldConfidence[];
74
+ field_confidence: FieldConfidence[];
75
75
  /** List of issues or warnings encountered during extraction. */
76
76
  issues: string[];
77
77
  }
@@ -126,7 +126,7 @@ interface ExtractResult<T> {
126
126
  * });
127
127
  *
128
128
  * // Check per-field confidence and evidence
129
- * metadata.fieldConfidence.forEach((fc) => {
129
+ * metadata.field_confidence.forEach((fc) => {
130
130
  * console.log(`${fc.field}: ${fc.score} - "${fc.text}"`);
131
131
  * });
132
132
  * ```
@@ -194,8 +194,8 @@ declare class Parsefy {
194
194
  * console.log(object.invoice_number); // Fully typed!
195
195
  *
196
196
  * // Access field-level confidence and evidence
197
- * console.log(`Overall confidence: ${metadata.confidenceScore}`);
198
- * metadata.fieldConfidence.forEach((fc) => {
197
+ * console.log(`Overall confidence: ${metadata.confidence_score}`);
198
+ * metadata.field_confidence.forEach((fc) => {
199
199
  * console.log(`${fc.field}: ${fc.score} (${fc.reason}) - "${fc.text}"`);
200
200
  * });
201
201
  * }
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import {zodToJsonSchema}from'zod-to-json-schema';var u=.85,d={".pdf":"application/pdf",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document"},l=10*1024*1024,g="https://api.parsefy.io",x=6e4;var s=class extends Error{constructor(e,r){super(e),this.name="ParsefyError",this.code=r,typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,this.constructor);}},p=class extends s{constructor(e,r,o){super(e),this.name="APIError",this.statusCode=r,this.response=o;}},y=class extends s{constructor(e,r,o){super(e,r),this.name="ExtractionError",this.metadata=o;}},a=class extends s{constructor(e){super(e),this.name="ValidationError";}};function h(){return typeof process<"u"&&process.versions?.node!==void 0}function R(t){let e=zodToJsonSchema(t,{$refStrategy:"none",target:"jsonSchema7"});return "$schema"in e&&delete e.$schema,e}function b(t){let e=t.toLowerCase().match(/\.[^.]+$/)?.[0];return e&&d[e]||null}function w(t){if(!b(t)){let r=Object.keys(d).join(", ");throw new a(`Unsupported file type. Supported types: ${r}`)}}function m(t){if(t===0)throw new a("File is empty");if(t>l){let e=l/1048576;throw new a(`File size exceeds maximum limit of ${e}MB`)}}function F(t){let e=t._meta||{confidence_score:1,field_confidence:[],issues:[]};return {object:t.object,metadata:{processingTimeMs:t.metadata.processing_time_ms,inputTokens:t.metadata.input_tokens,outputTokens:t.metadata.output_tokens,credits:t.metadata.credits,fallbackTriggered:t.metadata.fallback_triggered,confidenceScore:e.confidence_score,fieldConfidence:e.field_confidence.map(r=>({field:r.field,score:r.score,reason:r.reason,page:r.page,text:r.text})),issues:e.issues},error:t.error}}function T(t,e){let r=b(e)||"application/octet-stream",o=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength);return typeof File<"u"?new File([o],e,{type:r}):new Blob([o],{type:r})}async function I(t){if(!h())throw new a("File path strings are only supported in Node.js. Use File or Blob in the browser.");let e=await import('fs'),r=await import('path');if(!e.existsSync(t))throw new a(`File not found: ${t}`);let o=r.basename(t);w(o);let c=e.readFileSync(t);return m(c.length),{buffer:c,filename:o}}async function _(t){if(typeof t=="string"){let{buffer:e,filename:r}=await I(t);return T(e,r)}if(Buffer.isBuffer(t))return m(t.length),T(t,"document.pdf");if(t instanceof File)return w(t.name),m(t.size),t;if(t instanceof Blob)return m(t.size),t;throw new a("Invalid file input. Expected File, Blob, Buffer, or file path string.")}function P(t){return new Promise(e=>setTimeout(e,t))}function S(t,e=1e3){let r=e*Math.pow(2,t),o=Math.random()*.1*r;return Math.min(r+o,3e4)}var E=class{constructor(e){this.maxRetries=3;let r={};if(typeof e=="string"?r={apiKey:e}:e&&(r=e),this.apiKey=r.apiKey||this.getEnvApiKey(),!this.apiKey)throw new a("API key is required. Provide it in the constructor or set the PARSEFY_API_KEY environment variable.");this.baseUrl=r.baseUrl||g,this.timeout=r.timeout||x;}getEnvApiKey(){return h()&&process.env.PARSEFY_API_KEY||""}async extract(e){let{file:r,schema:o,confidenceThreshold:c}=e,n=R(o),f=await _(r),i=new FormData;return i.append("file",f),i.append("output_schema",JSON.stringify(n)),i.append("confidence_threshold",String(c??.85)),this.makeRequestWithRetry(i)}async makeRequestWithRetry(e,r=0){try{return await this.makeRequest(e)}catch(o){if(o instanceof p&&o.statusCode===429&&r<this.maxRetries){let c=S(r);return await P(c),this.makeRequestWithRetry(e,r+1)}throw o}}async makeRequest(e){let r=`${this.baseUrl}/v1/extract`,o=new AbortController,c=setTimeout(()=>o.abort(),this.timeout);try{let n=await fetch(r,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`},body:e,signal:o.signal});if(clearTimeout(c),!n.ok){let i=await this.parseErrorResponse(n);throw new p(i.message||`API request failed with status ${n.status}`,n.status,i)}let f;try{f=await n.json();}catch{throw new s("Failed to parse API response as JSON. The API may have returned an invalid response.","PARSE_ERROR")}try{return F(f)}catch(i){throw new s(`Failed to transform API response: ${i instanceof Error?i.message:String(i)}`,"TRANSFORM_ERROR")}}catch(n){throw clearTimeout(c),n instanceof Error&&n.name==="AbortError"?new s(`Request timed out after ${this.timeout}ms`,"TIMEOUT"):n instanceof s?n:n instanceof TypeError&&n.message.includes("fetch")?new s(`Network error: Unable to connect to the Parsefy API. ${n.message}`,"NETWORK_ERROR"):n instanceof TypeError?new s(`Type error: ${n.message}. This may indicate an API response format issue.`,"TYPE_ERROR"):new s(`Unexpected error: ${n instanceof Error?n.message:String(n)}`,"UNKNOWN_ERROR")}}async parseErrorResponse(e){try{return await e.json()}catch{try{return {message:await e.text()||e.statusText}}catch{return {message:e.statusText}}}}};
1
+ import {zodToJsonSchema}from'zod-to-json-schema';var u=.85,d={".pdf":"application/pdf",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document"},l=10*1024*1024,g="https://api.parsefy.io",x=6e4;var s=class extends Error{constructor(e,r){super(e),this.name="ParsefyError",this.code=r,typeof Error.captureStackTrace=="function"&&Error.captureStackTrace(this,this.constructor);}},p=class extends s{constructor(e,r,o){super(e),this.name="APIError",this.statusCode=r,this.response=o;}},y=class extends s{constructor(e,r,o){super(e,r),this.name="ExtractionError",this.metadata=o;}},a=class extends s{constructor(e){super(e),this.name="ValidationError";}};function h(){return typeof process<"u"&&process.versions?.node!==void 0}function T(t){let e=zodToJsonSchema(t,{$refStrategy:"none",target:"jsonSchema7"});return "$schema"in e&&delete e.$schema,e}function b(t){let e=t.toLowerCase().match(/\.[^.]+$/)?.[0];return e&&d[e]||null}function _(t){if(!b(t)){let r=Object.keys(d).join(", ");throw new a(`Unsupported file type. Supported types: ${r}`)}}function m(t){if(t===0)throw new a("File is empty");if(t>l){let e=l/1048576;throw new a(`File size exceeds maximum limit of ${e}MB`)}}function w(t){let e=t._meta||{confidence_score:1,field_confidence:[],issues:[]};return {object:t.object,metadata:{processing_time_ms:t.metadata.processing_time_ms,input_tokens:t.metadata.input_tokens,output_tokens:t.metadata.output_tokens,credits:t.metadata.credits,fallback_triggered:t.metadata.fallback_triggered,confidence_score:e.confidence_score,field_confidence:e.field_confidence.map(r=>({field:r.field,score:r.score,reason:r.reason,page:r.page,text:r.text})),issues:e.issues},error:t.error}}function R(t,e){let r=b(e)||"application/octet-stream",o=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength);return typeof File<"u"?new File([o],e,{type:r}):new Blob([o],{type:r})}async function I(t){if(!h())throw new a("File path strings are only supported in Node.js. Use File or Blob in the browser.");let e=await import('fs'),r=await import('path');if(!e.existsSync(t))throw new a(`File not found: ${t}`);let o=r.basename(t);_(o);let c=e.readFileSync(t);return m(c.length),{buffer:c,filename:o}}async function F(t){if(typeof t=="string"){let{buffer:e,filename:r}=await I(t);return R(e,r)}if(Buffer.isBuffer(t))return m(t.length),R(t,"document.pdf");if(t instanceof File)return _(t.name),m(t.size),t;if(t instanceof Blob)return m(t.size),t;throw new a("Invalid file input. Expected File, Blob, Buffer, or file path string.")}function P(t){return new Promise(e=>setTimeout(e,t))}function A(t,e=1e3){let r=e*Math.pow(2,t),o=Math.random()*.1*r;return Math.min(r+o,3e4)}var E=class{constructor(e){this.maxRetries=3;let r={};if(typeof e=="string"?r={apiKey:e}:e&&(r=e),this.apiKey=r.apiKey||this.getEnvApiKey(),!this.apiKey)throw new a("API key is required. Provide it in the constructor or set the PARSEFY_API_KEY environment variable.");this.baseUrl=r.baseUrl||g,this.timeout=r.timeout||x;}getEnvApiKey(){return h()&&process.env.PARSEFY_API_KEY||""}async extract(e){let{file:r,schema:o,confidenceThreshold:c}=e,n=T(o),f=await F(r),i=new FormData;return i.append("file",f),i.append("output_schema",JSON.stringify(n)),i.append("confidence_threshold",String(c??.85)),this.makeRequestWithRetry(i)}async makeRequestWithRetry(e,r=0){try{return await this.makeRequest(e)}catch(o){if(o instanceof p&&o.statusCode===429&&r<this.maxRetries){let c=A(r);return await P(c),this.makeRequestWithRetry(e,r+1)}throw o}}async makeRequest(e){let r=`${this.baseUrl}/v1/extract`,o=new AbortController,c=setTimeout(()=>o.abort(),this.timeout);try{let n=await fetch(r,{method:"POST",headers:{Authorization:`Bearer ${this.apiKey}`},body:e,signal:o.signal});if(clearTimeout(c),!n.ok){let i=await this.parseErrorResponse(n);throw new p(i.message||`API request failed with status ${n.status}`,n.status,i)}let f;try{f=await n.json();}catch{throw new s("Failed to parse API response as JSON. The API may have returned an invalid response.","PARSE_ERROR")}try{return w(f)}catch(i){throw new s(`Failed to transform API response: ${i instanceof Error?i.message:String(i)}`,"TRANSFORM_ERROR")}}catch(n){throw clearTimeout(c),n instanceof Error&&n.name==="AbortError"?new s(`Request timed out after ${this.timeout}ms`,"TIMEOUT"):n instanceof s?n:n instanceof TypeError&&n.message.includes("fetch")?new s(`Network error: Unable to connect to the Parsefy API. ${n.message}`,"NETWORK_ERROR"):n instanceof TypeError?new s(`Type error: ${n.message}. This may indicate an API response format issue.`,"TYPE_ERROR"):new s(`Unexpected error: ${n instanceof Error?n.message:String(n)}`,"UNKNOWN_ERROR")}}async parseErrorResponse(e){try{return await e.json()}catch{try{return {message:await e.text()||e.statusText}}catch{return {message:e.statusText}}}}};
2
2
  export{p as APIError,u as DEFAULT_CONFIDENCE_THRESHOLD,y as ExtractionError,E as Parsefy,s as ParsefyError,a as ValidationError};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "parsefy",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Official TypeScript SDK for Parsefy - Financial Document Infrastructure for Developers",
5
5
  "author": "",
6
6
  "license": "MIT",