@veryfi/veryfi-sdk 1.2.2 → 1.2.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
@@ -1,11 +1,12 @@
1
1
  # Veryfi SDK for Node.js
2
2
 
3
+ <img src="https://user-images.githubusercontent.com/30125790/212157461-58bdc714-2f89-44c2-8e4d-d42bee74854e.png#gh-dark-mode-only" width="200">
4
+ <img src="https://user-images.githubusercontent.com/30125790/212157486-bfd08c5d-9337-4b78-be6f-230dc63838ba.png#gh-light-mode-only" width="200">
5
+
3
6
  [![Node.js - version](https://img.shields.io/badge/node-%3E%3D%206.0.0-brightgreen)](https://www.npmjs.com/package/@veryfi/veryfi-sdk)
4
7
  [![npm](https://img.shields.io/badge/npm-v7.0.0-blue)](https://www.npmjs.com/package/@veryfi/veryfi-sdk)
5
8
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
6
9
 
7
- ![Veryfi Logo](https://cdn.veryfi.com/logos/veryfi-logo-wide-github.png)
8
-
9
10
  ## Table of Contents
10
11
 
11
12
  - [Veryfi SDK for Node.js](#veryfi-sdk-for-nodejs)
@@ -62,15 +63,17 @@ This submits a document for processing (3-5 seconds for a response)
62
63
 
63
64
  ```js
64
65
  let veryfi_client = new Client(client_id, client_secret, username, api_key);
65
- let response = veryfi_client.process_document(file_path, categories=categories);
66
- console.log(response);
66
+ let response = veryfi_client.process_document(file_path, categories=categories).then(response => {
67
+ console.log(response)
68
+ });
67
69
  ```
68
70
 
69
71
  ...or with a URL
70
72
 
71
73
  ```js
72
- let response = veryfi_client.process_document_url(url, external_id=some_id);
73
- console.log(response);
74
+ let response = veryfi_client.process_document_url(url, external_id=some_id).then(response => {
75
+ console.log(response)
76
+ });
74
77
  ```
75
78
 
76
79
  ### Response
@@ -238,7 +241,10 @@ veryfi_client.update_document(id=12345,
238
241
  'vendor': new_vendor,
239
242
  'category': new_category,
240
243
  'total': new_total
241
- });
244
+ })
245
+ .then(response => {
246
+ console.log(response)
247
+ });
242
248
  ```
243
249
 
244
250
  ## Need help?
package/lib/main.js CHANGED
@@ -1,13 +1,15 @@
1
1
  const {createHmac} = require('crypto');
2
2
  const axios = require('axios').default;
3
3
  const path = require('path');
4
+ const FormData = require('form-data');
4
5
  const fs = require('fs');
6
+ const {promisify} = require("util");
5
7
 
6
8
  /**
7
9
  * Create instance of a Client
8
10
  * @class
9
11
  * @param {string} client_id Your Veryfi client id
10
- * @param {string} client_secret Your Veryfi client secret
12
+ * @param {string | undefined} client_secret Your Veryfi client secret
11
13
  * @param {string} username Your Veryfi username
12
14
  * @param {string} api_key Your Veryfi API key
13
15
  * @param {string} base_url
@@ -21,12 +23,13 @@ function Client(
21
23
  api_key,
22
24
  base_url = "https://api.veryfi.com/",
23
25
  api_version = "v8",
24
- timeout = 120,) {
26
+ timeout = 120) {
25
27
  this.client_id = client_id;
26
28
  this.client_secret = client_secret;
27
29
  this.username = username;
28
30
  this.api_key = api_key;
29
31
  this.base_url = base_url;
32
+ this.timeout = timeout;
30
33
  this.api_version = api_version;
31
34
  this.CATEGORIES = [
32
35
  "Advertising & Marketing",
@@ -50,7 +53,7 @@ function Client(
50
53
  /**
51
54
  * Check api version for w2 documents
52
55
  * @private
53
- * @throws if api_version is different to v8
56
+ * @throws error when api_version is different to v8
54
57
  */
55
58
  Client.prototype._check_w2_version = function () {
56
59
  if (this.api_version !== "v8") throw Error("w2 is only supported on v8")
@@ -64,7 +67,7 @@ Client.prototype._check_w2_version = function () {
64
67
  */
65
68
  Client.prototype._get_headers = function (has_files = false) {
66
69
  let final_headers = {
67
- "User-Agent": "Node.js Veryfi-Nodejs/1.2.0",
70
+ "User-Agent": "Node.js Veryfi-Nodejs/1.2.4",
68
71
  "Accept": "application/json",
69
72
  "Content-Type": "application/json",
70
73
  "Client-Id": this.client_id,
@@ -117,11 +120,10 @@ Client.prototype._generate_signature = function (payload_params, timestamp) {
117
120
  * @param {string} endpoint_name Endpoint name such as 'documents', 'users', etc.
118
121
  * @param {{}} request_arguments JSON payload to send to Veryfi
119
122
  * @param params {{}} query params.
120
- * @param file_stream file stream of the document
123
+ * @param {Boolean} has_files Are there any files to be submitted as binary
121
124
  * @returns {JSON} A JSON of the response data.
122
125
  */
123
- Client.prototype._request = async function (http_verb, endpoint_name, request_arguments, params = {}, file_stream = null) {
124
- let has_files = (Boolean(file_stream));
126
+ Client.prototype._request = async function (http_verb, endpoint_name, request_arguments, params = {}, has_files = false) {
125
127
  let headers = this._get_headers(has_files);
126
128
  let api_url = `${this._get_url()}/partner${endpoint_name}`;
127
129
 
@@ -134,12 +136,21 @@ Client.prototype._request = async function (http_verb, endpoint_name, request_ar
134
136
  });
135
137
  }
136
138
 
137
- if (has_files === false) {
138
- request_arguments = JSON.stringify(request_arguments);
139
+ if (has_files) {
140
+ const formData = new FormData();
141
+ for (const key in request_arguments) {
142
+ if (request_arguments.hasOwnProperty(key)) {
143
+ const value = request_arguments[key];
144
+ formData.append(key, value);
145
+ }
146
+ }
147
+ headers = Object.assign(headers, formData.getHeaders());
148
+ const getLength = promisify(formData.getLength).bind(formData);
149
+ headers['Content-Length'] = await getLength()
150
+ request_arguments = formData;
139
151
  } else {
140
- Object.assign(headers, {...request_arguments});
152
+ request_arguments = JSON.stringify(request_arguments);
141
153
  }
142
-
143
154
  try {
144
155
  return await axios.request({
145
156
  method: http_verb,
@@ -150,9 +161,10 @@ Client.prototype._request = async function (http_verb, endpoint_name, request_ar
150
161
  params: params
151
162
  });
152
163
  } catch (response) {
153
- let errorStatus = response['response']['status'];
154
- let errorInfo = response['response']['data']['error'];
155
- throw new Error(errorStatus + errorInfo);
164
+ let errorStatus = response?.response?.status;
165
+ let errorInfo = response?.response?.data?.error;
166
+ let message = response?.message;
167
+ throw new Error(`Error: ${errorStatus} ${errorInfo} ${message}`);
156
168
  }
157
169
  }
158
170
 
@@ -211,7 +223,7 @@ Client.prototype.process_document = async function (
211
223
  if (!categories) {
212
224
  categories = this.CATEGORIES;
213
225
  }
214
- let file_name = path.basename(file_path)
226
+ let file_name = path.basename(file_path);
215
227
  const image_file = fs.readFileSync(file_path, {encoding: 'base64'});
216
228
  const base64_encoded_string = Buffer.from(image_file).toString('utf-8');
217
229
  let request_arguments = {
@@ -220,29 +232,65 @@ Client.prototype.process_document = async function (
220
232
  "categories": categories,
221
233
  "auto_delete": delete_after_processing,
222
234
  };
223
- request_arguments = Object.assign(request_arguments, kwargs)
224
- let document = await this._request("POST", endpoint_name, request_arguments)
235
+ request_arguments = Object.assign(request_arguments, kwargs);
236
+ let document = await this._request("POST", endpoint_name, request_arguments);
225
237
  return document['data'];
226
238
  }
227
239
 
228
240
  /**
229
241
  * Process a document and extract all the fields from it
230
242
  * @example
231
- * veryfi_client.process_document_buffer('base64_encoded_string',
243
+ * veryfi_client.process_document_stream('ReadStream',
232
244
  * 'receipt.png',
233
245
  * ['Entertainment','Food'],
234
246
  * true,
235
247
  * {'extra': 'parameters'})
236
248
  *
237
249
  * @memberof Client
238
- * @param {String} base64_encoded_string Buffer of a file to submit for data extraction
250
+ * @param {ReadStream} file ReadStream of a file to submit for data extraction
239
251
  * @param {String} file_name The file name including the extension
240
252
  * @param {Array} categories List of categories Veryfi can use to categorize the document
241
253
  * @param {Boolean} delete_after_processing Delete this document from Veryfi after data has been extracted
242
254
  * @param {Object} kwargs Additional request parameters
243
255
  * @returns {JSON} Data extracted from the document
244
256
  */
245
- Client.prototype.process_document_buffer = async function (
257
+ Client.prototype.process_document_stream = async function (
258
+ file,
259
+ file_name,
260
+ delete_after_processing = false,
261
+ {...kwargs} = {}
262
+ ) {
263
+
264
+ let endpoint_name = "/documents/";
265
+
266
+ let request_arguments = {
267
+ "file_name": file_name,
268
+ "file": file,
269
+ "auto_delete": delete_after_processing.toString(),
270
+ };
271
+ request_arguments = Object.assign(request_arguments, kwargs);
272
+ let document = await this._request("POST", endpoint_name, request_arguments, {}, true);
273
+ return document['data'];
274
+ }
275
+
276
+ /**
277
+ * Process a document and extract all the fields from it
278
+ * @example
279
+ * veryfi_client.process_document_base64string('base64_encoded_string',
280
+ * 'receipt.png',
281
+ * ['Entertainment','Food'],
282
+ * true,
283
+ * {'extra': 'parameters'})
284
+ *
285
+ * @memberof Client
286
+ * @param {String} base64_encoded_string Buffer string of a file to submit for data extraction
287
+ * @param {String} file_name The file name including the extension
288
+ * @param {Array} categories List of categories Veryfi can use to categorize the document
289
+ * @param {Boolean} delete_after_processing Delete this document from Veryfi after data has been extracted
290
+ * @param {Object} kwargs Additional request parameters
291
+ * @returns {JSON} Data extracted from the document
292
+ */
293
+ Client.prototype.process_document_base64string = async function (
246
294
  base64_encoded_string,
247
295
  file_name,
248
296
  categories = null,
@@ -260,8 +308,8 @@ Client.prototype.process_document_buffer = async function (
260
308
  "categories": categories,
261
309
  "auto_delete": delete_after_processing,
262
310
  };
263
- request_arguments = Object.assign(request_arguments, kwargs)
264
- let document = await this._request("POST", endpoint_name, request_arguments)
311
+ request_arguments = Object.assign(request_arguments, kwargs);
312
+ let document = await this._request("POST", endpoint_name, request_arguments);
265
313
  return document['data'];
266
314
  }
267
315
 
@@ -304,7 +352,7 @@ Client.prototype.process_document_url = async function (
304
352
  "file_urls": file_urls,
305
353
  "max_pages_to_process": max_pages_to_process,
306
354
  };
307
- request_arguments = Object.assign(request_arguments, kwargs)
355
+ request_arguments = Object.assign(request_arguments, kwargs);
308
356
  let response = await this._request("POST", endpoint_name, request_arguments);
309
357
  return response['data'];
310
358
  }
@@ -344,15 +392,15 @@ Client.prototype.update_document = async function (document_id, {...kwargs} = {}
344
392
  * @return {Array} An array of JSON with all w2 documents.
345
393
  */
346
394
  Client.prototype.get_w2_documents = async function (page = null) {
347
- this._check_w2_version()
348
- let endpoint_name = "/w2s/"
349
- let request_arguments = {}
350
- let params = {}
395
+ this._check_w2_version();
396
+ let endpoint_name = "/w2s/";
397
+ let request_arguments = {};
398
+ let params = {};
351
399
  if (page !== null) {
352
- params = {"page": page}
400
+ params = {"page": page};
353
401
  }
354
- let response = await this._request("GET", endpoint_name, request_arguments, params)
355
- return response['data']['results']
402
+ let response = await this._request("GET", endpoint_name, request_arguments, params);
403
+ return response['data']['results'];
356
404
  }
357
405
 
358
406
  /**
@@ -364,11 +412,11 @@ Client.prototype.get_w2_documents = async function (page = null) {
364
412
  Client.prototype.get_w2_document = async function (
365
413
  document_id,
366
414
  ) {
367
- this._check_w2_version()
368
- let endpoint_name = `/w2s/${document_id}/`
369
- let request_arguments = {"id": document_id}
370
- let response = await this._request("GET", endpoint_name, request_arguments)
371
- return response['data']
415
+ this._check_w2_version();
416
+ let endpoint_name = `/w2s/${document_id}/`;
417
+ let request_arguments = {"id": document_id};
418
+ let response = await this._request("GET", endpoint_name, request_arguments);
419
+ return response['data'];
372
420
  }
373
421
 
374
422
  /**
@@ -396,9 +444,9 @@ Client.prototype.process_w2_document_from_buffer = async function (
396
444
  "auto_delete": delete_after_processing,
397
445
  "max_pages_to_process": max_pages_to_process,
398
446
  }
399
- request_arguments = Object.assign(request_arguments, kwargs)
400
- let response = await this._request("POST", endpoint_name, request_arguments)
401
- return response['data']
447
+ request_arguments = Object.assign(request_arguments, kwargs);
448
+ let response = await this._request("POST", endpoint_name, request_arguments);
449
+ return response['data'];
402
450
  }
403
451
 
404
452
  /**
@@ -424,7 +472,7 @@ Client.prototype.process_w2_document = async function (
424
472
  delete_after_processing,
425
473
  max_pages_to_process,
426
474
  kwargs
427
- )
475
+ );
428
476
  }
429
477
 
430
478
  /**
@@ -456,11 +504,38 @@ Client.prototype.process_w2_document_from_url = async function (
456
504
  "file_urls": file_urls,
457
505
  "max_pages_to_process": max_pages_to_process
458
506
  }
459
- request_arguments = Object.assign(request_arguments, kwargs)
460
- let response = await this._request("POST", endpoint_name, request_arguments)
461
- return response['data']
507
+ request_arguments = Object.assign(request_arguments, kwargs);
508
+ let response = await this._request("POST", endpoint_name, request_arguments);
509
+ return response['data'];
462
510
  }
463
511
 
512
+ /**
513
+ * Add a new tag on an existing document
514
+ *
515
+ * @param {number} document_id ID of the document you'd like to add a Tag
516
+ * @param {string} tag name to add
517
+ * @return {JSON} response about tag added.
518
+ */
519
+ Client.prototype.add_tag = async function (document_id, tag) {
520
+ let endpoint_name = `/documents/${document_id}/tags/`;
521
+ let request_arguments = {"name": tag};
522
+ let response = await this._request("PUT", endpoint_name, request_arguments);
523
+ return response['data'];
524
+ }
525
+
526
+ /**
527
+ * Delete all the tags on an existing document
528
+ *
529
+ * @param {number} document_id ID of the document you'd like to delete tags
530
+ * @return {JSON} response about deleted tags.
531
+ */
532
+ Client.prototype.delete_tags = async function (document_id) {
533
+ let endpoint_name = `/documents/${document_id}/tags/`;
534
+ let request_arguments = {};
535
+ return this._request("DELETE", endpoint_name, request_arguments);
536
+ }
537
+
538
+
464
539
  // Exports
465
540
 
466
541
  module.exports = Client;
@@ -1,3 +1,5 @@
1
+ import fs from "fs";
2
+
1
3
  /**
2
4
  * Additional request parameters type
3
5
  */
@@ -44,6 +46,7 @@ export declare type VeryfiDocument = {
44
46
  payment_display_name?: null | string;
45
47
  payment_terms?: null | string;
46
48
  payment_type?: null | string;
49
+ pdf_url?: null | string;
47
50
  phone_number?: null | string;
48
51
  purchase_order_number?: null | string;
49
52
  rounding?: null | number;
@@ -122,12 +125,17 @@ declare type Payment = {
122
125
  type?: null | string;
123
126
  };
124
127
 
128
+ declare type Tag = {
129
+ id?: null | number;
130
+ name?: null | string;
131
+ };
132
+
125
133
  export declare class Client {
126
134
  /**
127
135
  * Create instance of a Client
128
136
  * @class
129
137
  * @param {string} client_id Your Veryfi client id
130
- * @param {string} client_secret Your Veryfi client secret
138
+ * @param {string | undefined} client_secret Your Veryfi client secret
131
139
  * @param {string} username Your Veryfi username
132
140
  * @param {string} api_key Your Veryfi API key
133
141
  * @param {string} base_url
@@ -136,7 +144,7 @@ export declare class Client {
136
144
  */
137
145
  constructor(
138
146
  client_id: string,
139
- client_secret: string,
147
+ client_secret: string | undefined,
140
148
  username: string,
141
149
  api_key: string,
142
150
  base_url?: string,
@@ -146,7 +154,7 @@ export declare class Client {
146
154
 
147
155
  client_id: string;
148
156
 
149
- client_secret: string;
157
+ client_secret: string | undefined;
150
158
 
151
159
  username: string;
152
160
 
@@ -181,6 +189,56 @@ export declare class Client {
181
189
  */
182
190
  public get_document(document_id: string): Promise<VeryfiDocument>;
183
191
 
192
+ /**
193
+ * Process a document and extract all the fields from it
194
+ * @example
195
+ * veryfi_client.process_document_buffer('buffer',
196
+ * 'receipt.png',
197
+ * ['Entertainment','Food'],
198
+ * true,
199
+ * {'extra': 'parameters'})
200
+ *
201
+ * @memberof Client
202
+ * @param {ReadStream} file ReadStream of a file to submit for data extraction
203
+ * @param {String} file_name The file name including the extension
204
+ * @param {Array} categories List of categories Veryfi can use to categorize the document
205
+ * @param {Boolean} delete_after_processing Delete this document from Veryfi after data has been extracted
206
+ * @param {Object} kwargs Additional request parameters
207
+ * @returns {JSON} Data extracted from the document
208
+ */
209
+ public process_document_stream(
210
+ file: fs.ReadStream,
211
+ file_name: string,
212
+ categories?: string[],
213
+ delete_after_processing?: boolean,
214
+ { ...kwargs }?: VeryfiExtraArgs
215
+ ): Promise<VeryfiDocument>;
216
+
217
+ /**
218
+ * Process a document and extract all the fields from it
219
+ * @example
220
+ * veryfi_client.process_document_buffer_string('base64_encoded_string',
221
+ * 'receipt.png',
222
+ * ['Entertainment','Food'],
223
+ * true,
224
+ * {'extra': 'parameters'})
225
+ *
226
+ * @memberof Client
227
+ * @param {String} base64_encoded_string Buffer string of a file to submit for data extraction
228
+ * @param {String} file_name The file name including the extension
229
+ * @param {Array} categories List of categories Veryfi can use to categorize the document
230
+ * @param {Boolean} delete_after_processing Delete this document from Veryfi after data has been extracted
231
+ * @param {Object} kwargs Additional request parameters
232
+ * @returns {JSON} Data extracted from the document
233
+ */
234
+ public process_document_base64string(
235
+ base64_encoded_string: string,
236
+ file_name: string,
237
+ categories?: string[],
238
+ delete_after_processing?: boolean,
239
+ { ...kwargs }?: VeryfiExtraArgs
240
+ ): Promise<VeryfiDocument>;
241
+
184
242
  /**
185
243
  * Process a document and extract all the fields from it
186
244
  * @example
@@ -234,10 +292,10 @@ export declare class Client {
234
292
  * @param {string} document_id ID of the document you'd like to delete
235
293
  * @returns {Promise<VeryfiDocument>} Object of data extracted from the document
236
294
  */
237
- public delete_document(document_id: string): Promise<VeryfiDocument>;
295
+ public delete_document(document_id: string): Promise<any>;
238
296
 
239
297
  /**
240
- * Update data for a previously processed document, including almost any field like `vendor`, `date`, `notes` and etc.
298
+ * Update data for a previously processed document, including almost any field like `vendor`, `date`, `notes` etc.
241
299
  * @example
242
300
  * veryfi_client.update_document(
243
301
  * id,
@@ -252,13 +310,31 @@ export declare class Client {
252
310
  document_id: string,
253
311
  { ...kwargs }?: VeryfiExtraArgs
254
312
  ): Promise<VeryfiDocument>;
313
+
314
+ /**
315
+ * Add a new tag on an existing document
316
+ *
317
+ * @param {number} document_id ID of the document you'd like to add a Tag
318
+ * @param {string} tag name to add
319
+ * @return {Promise<Tag>} response about tag added.
320
+ */
321
+ public add_tag(document_id: string, tag: string): Promise<Tag>;
322
+
323
+ /**
324
+ * Delete all tags on an existing document
325
+ *
326
+ * @param {number} document_id ID of the document you'd like to delete all Tags
327
+ * @return {Promise<any>} response about deleted tags.
328
+ */
329
+ public delete_tags(document_id: string): Promise<any>;
330
+
255
331
  }
256
332
 
257
333
  /**
258
334
  * Create instance of a Client
259
335
  * @class
260
336
  * @param {string} client_id Your Veryfi client id
261
- * @param {string} client_secret Your Veryfi client secret
337
+ * @param {string | undefined} client_secret Your Veryfi client secret
262
338
  * @param {string} username Your Veryfi username
263
339
  * @param {string} api_key Your Veryfi API key
264
340
  * @param {string} base_url
@@ -267,7 +343,7 @@ export declare class Client {
267
343
  */
268
344
  export declare function Client(
269
345
  client_id: string,
270
- client_secret: string,
346
+ client_secret: string | undefined,
271
347
  username: string,
272
348
  api_key: string,
273
349
  base_url?: string,
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@veryfi/veryfi-sdk",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "description": "Node.js module for communicating with the Veryfi OCR API",
5
5
  "main": "lib/main.js",
6
- "typings": "types/main.d.ts",
6
+ "typings": "lib/types/main.d.ts",
7
7
  "scripts": {
8
8
  "test": "jest",
9
9
  "doc": "jsdoc -d docs --configure jsconf.json main.js",
@@ -35,6 +35,7 @@
35
35
  "@jest/globals": "^29.0.3",
36
36
  "axios": "^0.21.1",
37
37
  "docdash": "^1.2.0",
38
+ "form-data": "^4.0.0",
38
39
  "jest-config": "^29.0.3"
39
40
  },
40
41
  "repository": {