From 12a37414df6501297e096d5733afe2157965dc60 Mon Sep 17 00:00:00 2001 From: Pushpak Sharma Date: Thu, 5 Oct 2023 16:27:51 +0530 Subject: [PATCH 01/16] Added API for OCR --- intelliserver/api/index.js | 2 ++ intelliserver/api/ocr/index.js | 62 ++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 intelliserver/api/ocr/index.js diff --git a/intelliserver/api/index.js b/intelliserver/api/index.js index 9d77f7a..6523aa9 100644 --- a/intelliserver/api/index.js +++ b/intelliserver/api/index.js @@ -42,6 +42,7 @@ const semanticRouter = require('./functions/semanticsearch'); const evaluateRouter = require('./functions/evaluate'); const chatContextRouter = require('./functions/chatcontext'); const parserRoute = require('./parser/index'); +const ocrRoute = require('./ocr/index'); // # api routers @@ -71,6 +72,7 @@ app.use('/evaluate', evaluateRouter); app.use('/chatcontext', chatContextRouter); app.use('/parser', parserRoute) +app.use('/ocr', ocrRoute) /* ### deploy the app ### */ var port = process.env.PORT || '80'; diff --git a/intelliserver/api/ocr/index.js b/intelliserver/api/ocr/index.js new file mode 100644 index 0000000..12e6359 --- /dev/null +++ b/intelliserver/api/ocr/index.js @@ -0,0 +1,62 @@ +const express = require('express'); +const multer = require('multer'); + +const AWS = require('aws-sdk'); +const { ImageAnnotatorClient } = require('@google-cloud/vision'); + +const router = express.Router(); +const upload = multer(); + +router.post('/aws', upload.single('image'), async (req, res) => { + const { buffer } = req.file; + try { + const awsOcr = async (imageBuffer) => { + const rekognition = new AWS.Rekognition(); + + const params = { + Image: { + Bytes: imageBuffer, + }, + }; + + const response = await rekognition.detectText(params).promise(); + const detectedText = response.TextDetections.map((textDetection) => textDetection.DetectedText); + + return detectedText; + } + + const detectedText = await awsOcr(buffer); + const response = { + status: 'OK', + data: { + text: detectedText + }, + }; + res.json(response); + } catch (error) { + res.status(500).json({ status: 'ERROR', message: error.message }); + } +}); + +router.post('/google', upload.single('image'), async (req, res) => { + const { buffer } = req.file; + try { + const googleOcr = async (imageBuffer) => { + const client = new ImageAnnotatorClient(); + const [result] = await client.textDetection(imageBuffer); + const detectedText = result.textAnnotations.map((annotation) => annotation.description); + return detectedText; + }; + + const detectedText = await googleOcr(buffer); + const response = { + status: 'OK', + data: { + text: detectedText + }, + }; + res.json(response); + } catch (error) { + res.status(500).json({ status: 'ERROR', message: error.message }); + } +}); \ No newline at end of file From a0192212301779d202691deec0232765854f2e79 Mon Sep 17 00:00:00 2001 From: Pushpak Sharma Date: Thu, 5 Oct 2023 16:36:21 +0530 Subject: [PATCH 02/16] Added export --- intelliserver/api/ocr/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/intelliserver/api/ocr/index.js b/intelliserver/api/ocr/index.js index 12e6359..e8c6966 100644 --- a/intelliserver/api/ocr/index.js +++ b/intelliserver/api/ocr/index.js @@ -59,4 +59,6 @@ router.post('/google', upload.single('image'), async (req, res) => { } catch (error) { res.status(500).json({ status: 'ERROR', message: error.message }); } -}); \ No newline at end of file +}); + +module.exports = router; From fc3b515fa73c910d03468c300193ea321a7e62a7 Mon Sep 17 00:00:00 2001 From: Pushpak Sharma Date: Fri, 6 Oct 2023 23:55:30 +0530 Subject: [PATCH 03/16] Added image url middleware --- intelliserver/api/ocr/index.js | 10 ++--- .../middleware/getImageFromUrlOrFile.js | 34 +++++++++++++++ intelliserver/package-lock.json | 43 ++++++++++++++++++- intelliserver/package.json | 6 ++- 4 files changed, 84 insertions(+), 9 deletions(-) create mode 100644 intelliserver/middleware/getImageFromUrlOrFile.js diff --git a/intelliserver/api/ocr/index.js b/intelliserver/api/ocr/index.js index e8c6966..ae10d78 100644 --- a/intelliserver/api/ocr/index.js +++ b/intelliserver/api/ocr/index.js @@ -1,13 +1,13 @@ const express = require('express'); -const multer = require('multer'); - const AWS = require('aws-sdk'); + const { ImageAnnotatorClient } = require('@google-cloud/vision'); +const getImageFromUrlOrFile = require('../../middleware/getImageFromUrlOrFile'); + const router = express.Router(); -const upload = multer(); -router.post('/aws', upload.single('image'), async (req, res) => { +router.post('/aws', getImageFromUrlOrFile, async (req, res) => { const { buffer } = req.file; try { const awsOcr = async (imageBuffer) => { @@ -38,7 +38,7 @@ router.post('/aws', upload.single('image'), async (req, res) => { } }); -router.post('/google', upload.single('image'), async (req, res) => { +router.post('/google', getImageFromUrlOrFile, async (req, res) => { const { buffer } = req.file; try { const googleOcr = async (imageBuffer) => { diff --git a/intelliserver/middleware/getImageFromUrlOrFile.js b/intelliserver/middleware/getImageFromUrlOrFile.js new file mode 100644 index 0000000..48b2339 --- /dev/null +++ b/intelliserver/middleware/getImageFromUrlOrFile.js @@ -0,0 +1,34 @@ +const multer = require('multer'); +const fetch = require('node-fetch'); // For making HTTP requests + +// Configure multer for file uploads +const upload = multer(); + +// Middleware function to fetch and add image buffer to req.file +const getImageFromUrlOrFile = async (req, res, next) => { + try { + // Check if 'imageUrl' is present in the request body + const imageUrl = req.body.imageUrl; + + if (imageUrl) { + // Fetch the image using the provided URL + const response = await fetch(imageUrl); + + if (!response.ok) { + throw new Error('Failed to fetch the image'); + } + + const imageBuffer = await response.buffer(); + + // Add the image buffer to req.file + req.file = { fieldname: 'image', originalname: 'image', buffer: imageBuffer }; + } + } catch (error) { + res.status(500).json({ status: 'ERROR', message: error.message }); + } + + // Continue to the file upload middleware (upload.single('image')) + upload.single('image')(req, res, next); +}; + +module.exports = getImageFromUrlOrFile; diff --git a/intelliserver/package-lock.json b/intelliserver/package-lock.json index 177b28c..2fb59e2 100644 --- a/intelliserver/package-lock.json +++ b/intelliserver/package-lock.json @@ -1,12 +1,12 @@ { "name": "intelliserver", - "version": "0.0.1", + "version": "0.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "intelliserver", - "version": "0.0.1", + "version": "0.0.2", "dependencies": { "cookie-parser": "~1.4.4", "debug": "~2.6.9", @@ -17,6 +17,7 @@ "mammoth": "^1.6.0", "morgan": "~1.9.1", "multer": "^1.4.5-lts.1", + "node-fetch": "^2.7.0", "pdf-parse": "^1.1.1", "swagger-jsdoc": "^6.2.8", "swagger-ui-express": "^5.0.0" @@ -999,6 +1000,25 @@ "resolved": "https://registry.npmjs.org/node-ensure/-/node-ensure-0.0.0.tgz", "integrity": "sha512-DRI60hzo2oKN1ma0ckc6nQWlHU69RH6xN0sjQTjMpChPfTYvKZdcQFfdYK2RWbJcKyUizSIy/l8OTGxMAM1QDw==" }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -1356,6 +1376,11 @@ "node": ">=0.6" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1415,6 +1440,20 @@ "node": ">= 0.8" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/intelliserver/package.json b/intelliserver/package.json index 1bd3048..27928da 100644 --- a/intelliserver/package.json +++ b/intelliserver/package.json @@ -3,7 +3,8 @@ "version": "0.0.2", "private": true, "scripts": { - "start": "node ./bin/www" + "start": "node ./bin/www", + "dev": "nodemon ./bin/www" }, "dependencies": { "cookie-parser": "~1.4.4", @@ -11,11 +12,12 @@ "dotenv": "^16.3.1", "express": "^4.18.2", "fs": "^0.0.1-security", + "intellinode": "^1.4.4", "mammoth": "^1.6.0", "morgan": "~1.9.1", "multer": "^1.4.5-lts.1", + "node-fetch": "^2.7.0", "pdf-parse": "^1.1.1", - "intellinode": "^1.4.4", "swagger-jsdoc": "^6.2.8", "swagger-ui-express": "^5.0.0" } From 27e93fab917003e7e6b48abb2fcaea7790a74fc5 Mon Sep 17 00:00:00 2001 From: Pushpak Sharma Date: Wed, 11 Oct 2023 23:09:32 +0530 Subject: [PATCH 04/16] Added swagger hub documentation --- intelliserver/api/ocr/index.js | 101 ++++++++++++- intelliserver/config.js | 3 + ...Intellinode Server.postman_collection.json | 139 ++++++++++++++++++ 3 files changed, 239 insertions(+), 4 deletions(-) diff --git a/intelliserver/api/ocr/index.js b/intelliserver/api/ocr/index.js index ae10d78..9c10308 100644 --- a/intelliserver/api/ocr/index.js +++ b/intelliserver/api/ocr/index.js @@ -4,14 +4,62 @@ const AWS = require('aws-sdk'); const { ImageAnnotatorClient } = require('@google-cloud/vision'); const getImageFromUrlOrFile = require('../../middleware/getImageFromUrlOrFile'); +const config = require('../../config'); const router = express.Router(); +/** + * @swagger + * /ocr/aws: + * post: + * summary: Perform OCR on an image using AWS Rekognition. + * tags: + * - OCR + * requestBody: + * required: true + * content: + * multipart/form-data: + * schema: + * type: object + * properties: + * image: + * type: string + * format: binary + * description: Image to be used for OCR (upload a file). + * parameters: + * - in: body + * name: imageUrl + * type: string + * description: The URL of the image to perform OCR on. This should be included in the JSON request body. + * responses: + * 200: + * description: OCR results. + * content: + * application/json: + * schema: + * type: object + * properties: + * status: + * type: string + * description: The status of the OCR operation (e.g., "OK"). + * data: + * type: object + * properties: + * text: + * type: string + * description: The extracted text from the image. + * 400: + * description: Invalid request or image format. + * 500: + * description: Internal server error. + */ router.post('/aws', getImageFromUrlOrFile, async (req, res) => { - const { buffer } = req.file; try { + const { buffer } = req.file; const awsOcr = async (imageBuffer) => { - const rekognition = new AWS.Rekognition(); + const rekognition = new AWS.Rekognition({ + region: config.AWS_DEFAULT_REGION + }); const params = { Image: { @@ -38,9 +86,54 @@ router.post('/aws', getImageFromUrlOrFile, async (req, res) => { } }); +/** + * @swagger + * /ocr/google: + * post: + * summary: Perform OCR on an image using Google Cloud Vision API. + * tags: + * - OCR + * requestBody: + * required: true + * content: + * multipart/form-data: + * schema: + * type: object + * properties: + * image: + * type: string + * format: binary + * description: Image to be used for OCR (upload a file). + * parameters: + * - in: body + * name: imageUrl + * type: string + * description: The URL of the image to perform OCR on. This should be included in the JSON request body. + * responses: + * 200: + * description: OCR results. + * content: + * application/json: + * schema: + * type: object + * properties: + * status: + * type: string + * description: The status of the OCR operation (e.g., "OK"). + * data: + * type: object + * properties: + * text: + * type: string + * description: The extracted text from the image. + * 400: + * description: Invalid request or image URL. + * 500: + * description: Internal server error. + */ router.post('/google', getImageFromUrlOrFile, async (req, res) => { - const { buffer } = req.file; try { + const { buffer } = req.file; const googleOcr = async (imageBuffer) => { const client = new ImageAnnotatorClient(); const [result] = await client.textDetection(imageBuffer); @@ -61,4 +154,4 @@ router.post('/google', getImageFromUrlOrFile, async (req, res) => { } }); -module.exports = router; +module.exports = router; \ No newline at end of file diff --git a/intelliserver/config.js b/intelliserver/config.js index fcd6cca..fe8eaea 100644 --- a/intelliserver/config.js +++ b/intelliserver/config.js @@ -9,4 +9,7 @@ module.exports = { USE_API_AUTH: true, /* show swagger docs */ SHOW_SWAGGER: process.env.SHOW_SWAGGER !== 'false', + + /* AWS DEFAULT REGION */ + AWS_DEFAULT_REGION: process.env.AWS_DEFAULT_REGION }; \ No newline at end of file diff --git a/postman/Intellinode Server.postman_collection.json b/postman/Intellinode Server.postman_collection.json index 275f654..732aa7a 100644 --- a/postman/Intellinode Server.postman_collection.json +++ b/postman/Intellinode Server.postman_collection.json @@ -880,6 +880,145 @@ "response": [] } ] + }, + { + "name": "ocr", + "item": [ + { + "name": "aws", + "request": { + "method": "POST", + "header": [ + { + "key": "X-API-KEY", + "value": "root", + "type": "text" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "image", + "type": "file", + "src": [] + } + ] + }, + "url": { + "raw": "{{url}}/ocr/aws", + "host": [ + "{{url}}" + ], + "path": [ + "ocr", + "aws" + ] + } + }, + "response": [] + }, + { + "name": "aws body", + "request": { + "method": "POST", + "header": [ + { + "key": "X-API-KEY", + "value": "root", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"imageUrl\": \"\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}/ocr/aws", + "host": [ + "{{url}}" + ], + "path": [ + "ocr", + "aws" + ] + } + }, + "response": [] + }, + { + "name": "google", + "request": { + "method": "POST", + "header": [ + { + "key": "X-API-KEY", + "value": "root", + "type": "text" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "image", + "type": "file", + "src": [] + } + ] + }, + "url": { + "raw": "{{url}}/ocr/google", + "host": [ + "{{url}}" + ], + "path": [ + "ocr", + "google" + ] + } + }, + "response": [] + }, + { + "name": "google body", + "request": { + "method": "POST", + "header": [ + { + "key": "X-API-KEY", + "value": "root", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"imageUrl\": \"\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{url}}/ocr/google", + "host": [ + "{{url}}" + ], + "path": [ + "ocr", + "google" + ] + } + }, + "response": [] + } + ] } ], "event": [ From 53b5293f1dcf30997fb9de0b5970c93f014c8cb1 Mon Sep 17 00:00:00 2001 From: Pushpak Sharma Date: Tue, 17 Oct 2023 13:38:39 +0530 Subject: [PATCH 05/16] Completed AWS Test case --- intelliserver/api/ocr/index.js | 102 ++++++++++++++++++++++++++++----- intelliserver/config.js | 4 +- 2 files changed, 92 insertions(+), 14 deletions(-) diff --git a/intelliserver/api/ocr/index.js b/intelliserver/api/ocr/index.js index 9c10308..ff6c13c 100644 --- a/intelliserver/api/ocr/index.js +++ b/intelliserver/api/ocr/index.js @@ -8,6 +8,14 @@ const config = require('../../config'); const router = express.Router(); +// Set up AWS SDK configuration +AWS.config.update({ + accessKeyId: config.AWS_ACCESS_KEY, + secretAccessKey: config.AWS_ACCESS_SECRET, + region: config.AWS_DEFAULT_REGION +}); + + /** * @swagger * /ocr/aws: @@ -26,11 +34,6 @@ const router = express.Router(); * type: string * format: binary * description: Image to be used for OCR (upload a file). - * parameters: - * - in: body - * name: imageUrl - * type: string - * description: The URL of the image to perform OCR on. This should be included in the JSON request body. * responses: * 200: * description: OCR results. @@ -53,13 +56,50 @@ const router = express.Router(); * 500: * description: Internal server error. */ +/** + * @swagger + * /ocr/aws: + * post: + * summary: Perform OCR on an image using AWS Rekognition. + * tags: + * - OCR + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * imageUrl: + * type: string + * description: The URL of the image to perform OCR on. + * responses: + * 200: + * description: OCR results. + * content: + * application/json: + * schema: + * type: object + * properties: + * status: + * type: string + * description: The status of the OCR operation (e.g., "OK"). + * data: + * type: object + * properties: + * text: + * type: string + * description: The extracted text from the image. + * 400: + * description: Invalid request or image URL. + * 500: + * description: Internal server error. + */ router.post('/aws', getImageFromUrlOrFile, async (req, res) => { try { const { buffer } = req.file; const awsOcr = async (imageBuffer) => { - const rekognition = new AWS.Rekognition({ - region: config.AWS_DEFAULT_REGION - }); + const rekognition = new AWS.Rekognition(); const params = { Image: { @@ -104,11 +144,46 @@ router.post('/aws', getImageFromUrlOrFile, async (req, res) => { * type: string * format: binary * description: Image to be used for OCR (upload a file). - * parameters: - * - in: body - * name: imageUrl - * type: string - * description: The URL of the image to perform OCR on. This should be included in the JSON request body. + * responses: + * 200: + * description: OCR results. + * content: + * application/json: + * schema: + * type: object + * properties: + * status: + * type: string + * description: The status of the OCR operation (e.g., "OK"). + * data: + * type: object + * properties: + * text: + * type: string + * description: The extracted text from the image. + * 400: + * description: Invalid request or image format. + * 500: + * description: Internal server error. + */ + +/** + * @swagger + * /ocr/google: + * post: + * summary: Perform OCR on an image using Google Cloud Vision API. + * tags: + * - OCR + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * properties: + * imageUrl: + * type: string + * description: The URL of the image to perform OCR on. * responses: * 200: * description: OCR results. @@ -131,6 +206,7 @@ router.post('/aws', getImageFromUrlOrFile, async (req, res) => { * 500: * description: Internal server error. */ + router.post('/google', getImageFromUrlOrFile, async (req, res) => { try { const { buffer } = req.file; diff --git a/intelliserver/config.js b/intelliserver/config.js index fe8eaea..c9e2e4c 100644 --- a/intelliserver/config.js +++ b/intelliserver/config.js @@ -11,5 +11,7 @@ module.exports = { SHOW_SWAGGER: process.env.SHOW_SWAGGER !== 'false', /* AWS DEFAULT REGION */ - AWS_DEFAULT_REGION: process.env.AWS_DEFAULT_REGION + AWS_DEFAULT_REGION: process.env.AWS_DEFAULT_REGION, + AWS_ACCESS_SECRET: process.env.AWS_ACCESS_SECRET, + AWS_ACCESS_KEY: process.env.AWS_ACCESS_KEY, }; \ No newline at end of file From 57dd3da8a82199cc05321e7ae8ce02b2c9e4cbf7 Mon Sep 17 00:00:00 2001 From: Pushpak Sharma Date: Tue, 17 Oct 2023 13:42:03 +0530 Subject: [PATCH 06/16] Changed response type --- intelliserver/api/ocr/index.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/intelliserver/api/ocr/index.js b/intelliserver/api/ocr/index.js index ff6c13c..e1934c3 100644 --- a/intelliserver/api/ocr/index.js +++ b/intelliserver/api/ocr/index.js @@ -88,7 +88,9 @@ AWS.config.update({ * type: object * properties: * text: - * type: string + * type: array + * items: + * type: string * description: The extracted text from the image. * 400: * description: Invalid request or image URL. @@ -159,7 +161,9 @@ router.post('/aws', getImageFromUrlOrFile, async (req, res) => { * type: object * properties: * text: - * type: string + * type: array + * items: + * type: string * description: The extracted text from the image. * 400: * description: Invalid request or image format. From 291e6a68fe92da87782ccfb9b27153bd7bbb9eb2 Mon Sep 17 00:00:00 2001 From: Pushpak Sharma Date: Tue, 24 Oct 2023 17:15:26 +0530 Subject: [PATCH 07/16] Upgraded API to support keys from headers --- intelliserver/api/ocr/index.js | 83 ++++++++++++++++++- intelliserver/middleware/awsConfigProvider.js | 21 +++++ ...Intellinode Server.postman_collection.json | 30 +++++++ 3 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 intelliserver/middleware/awsConfigProvider.js diff --git a/intelliserver/api/ocr/index.js b/intelliserver/api/ocr/index.js index e1934c3..010977b 100644 --- a/intelliserver/api/ocr/index.js +++ b/intelliserver/api/ocr/index.js @@ -5,6 +5,7 @@ const { ImageAnnotatorClient } = require('@google-cloud/vision'); const getImageFromUrlOrFile = require('../../middleware/getImageFromUrlOrFile'); const config = require('../../config'); +const awsConfigProvider = require('../../middleware/awsConfigProvider'); const router = express.Router(); @@ -15,7 +16,6 @@ AWS.config.update({ region: config.AWS_DEFAULT_REGION }); - /** * @swagger * /ocr/aws: @@ -55,7 +55,27 @@ AWS.config.update({ * description: Invalid request or image format. * 500: * description: Internal server error. + * parameters: + * - in: header + * name: X-aws-access-Key + * schema: + * type: string + * required: false + * description: Optional AWS access key for this specific request. + * - in: header + * name: X-aws-secret-Key + * schema: + * type: string + * required: false + * description: Optional AWS secret key for this specific request. + * - in: header + * name: X-aws-region + * schema: + * type: string + * required: false + * description: Optional AWS region for this specific request. */ + /** * @swagger * /ocr/aws: @@ -95,9 +115,28 @@ AWS.config.update({ * 400: * description: Invalid request or image URL. * 500: - * description: Internal server error. + * description: Internal server error.\ + * parameters: + * - in: header + * name: X-aws-access-Key + * schema: + * type: string + * required: false + * description: Optional AWS access key for this specific request. + * - in: header + * name: X-aws-secret-Key + * schema: + * type: string + * required: false + * description: Optional AWS secret key for this specific request. + * - in: header + * name: X-aws-region + * schema: + * type: string + * required: false + * description: Optional AWS region for this specific request. */ -router.post('/aws', getImageFromUrlOrFile, async (req, res) => { +router.post('/aws', awsConfigProvider, getImageFromUrlOrFile, async (req, res) => { try { const { buffer } = req.file; const awsOcr = async (imageBuffer) => { @@ -169,6 +208,25 @@ router.post('/aws', getImageFromUrlOrFile, async (req, res) => { * description: Invalid request or image format. * 500: * description: Internal server error. + * parameters: + * - in: header + * name: X-aws-access-Key + * schema: + * type: string + * required: false + * description: Optional AWS access key for this specific request. + * - in: header + * name: X-aws-secret-Key + * schema: + * type: string + * required: false + * description: Optional AWS secret key for this specific request. + * - in: header + * name: X-aws-region + * schema: + * type: string + * required: false + * description: Optional AWS region for this specific request. */ /** @@ -209,6 +267,25 @@ router.post('/aws', getImageFromUrlOrFile, async (req, res) => { * description: Invalid request or image URL. * 500: * description: Internal server error. + * parameters: + * - in: header + * name: X-aws-access-Key + * schema: + * type: string + * required: false + * description: Optional AWS access key for this specific request. + * - in: header + * name: X-aws-secret-Key + * schema: + * type: string + * required: false + * description: Optional AWS secret key for this specific request. + * - in: header + * name: X-aws-region + * schema: + * type: string + * required: false + * description: Optional AWS region for this specific request. */ router.post('/google', getImageFromUrlOrFile, async (req, res) => { diff --git a/intelliserver/middleware/awsConfigProvider.js b/intelliserver/middleware/awsConfigProvider.js new file mode 100644 index 0000000..2e4a529 --- /dev/null +++ b/intelliserver/middleware/awsConfigProvider.js @@ -0,0 +1,21 @@ +// awsConfigMiddleware.js +const AWS = require('aws-sdk'); +const config = require('../config'); + +const awsConfigProvider = (req, res, next) => { + const accessKeyId = req.header('X-aws-access-Key'); + const secretAccessKey = req.header('X-aws-secret-Key'); + const region = req.header('X-aws-region'); + + if (accessKeyId && secretAccessKey) { + // Set up AWS SDK configuration with user-provided access key and secret + AWS.config.update({ + accessKeyId, + secretAccessKey, + region: region ?? config.AWS_DEFAULT_REGION + }); + } + next(); // Continue with the next middleware or route handler +}; + +module.exports = awsConfigProvider; \ No newline at end of file diff --git a/postman/Intellinode Server.postman_collection.json b/postman/Intellinode Server.postman_collection.json index 732aa7a..bc5a97f 100644 --- a/postman/Intellinode Server.postman_collection.json +++ b/postman/Intellinode Server.postman_collection.json @@ -893,6 +893,21 @@ "key": "X-API-KEY", "value": "root", "type": "text" + }, + { + "key": "X-aws-access-Key", + "value": "", + "type": "text" + }, + { + "key": "X-aws-secret-Key", + "value": "", + "type": "text" + }, + { + "key": "X-aws-region", + "value": "", + "type": "text" } ], "body": { @@ -927,6 +942,21 @@ "key": "X-API-KEY", "value": "root", "type": "text" + }, + { + "key": "X-aws-access-Key", + "value": "", + "type": "text" + }, + { + "key": "X-aws-secret-Key", + "value": "", + "type": "text" + }, + { + "key": "X-aws-region", + "value": "", + "type": "text" } ], "body": { From de8bf35fedc9cf765971bca5365116045bc1db73 Mon Sep 17 00:00:00 2001 From: Pushpak Sharma Date: Thu, 26 Oct 2023 15:19:12 +0530 Subject: [PATCH 08/16] Added condition provider for aws --- intelliserver/api/ocr/index.js | 8 -------- intelliserver/middleware/awsConfigProvider.js | 13 +++++++++++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/intelliserver/api/ocr/index.js b/intelliserver/api/ocr/index.js index 010977b..b766d68 100644 --- a/intelliserver/api/ocr/index.js +++ b/intelliserver/api/ocr/index.js @@ -4,18 +4,10 @@ const AWS = require('aws-sdk'); const { ImageAnnotatorClient } = require('@google-cloud/vision'); const getImageFromUrlOrFile = require('../../middleware/getImageFromUrlOrFile'); -const config = require('../../config'); const awsConfigProvider = require('../../middleware/awsConfigProvider'); const router = express.Router(); -// Set up AWS SDK configuration -AWS.config.update({ - accessKeyId: config.AWS_ACCESS_KEY, - secretAccessKey: config.AWS_ACCESS_SECRET, - region: config.AWS_DEFAULT_REGION -}); - /** * @swagger * /ocr/aws: diff --git a/intelliserver/middleware/awsConfigProvider.js b/intelliserver/middleware/awsConfigProvider.js index 2e4a529..171a164 100644 --- a/intelliserver/middleware/awsConfigProvider.js +++ b/intelliserver/middleware/awsConfigProvider.js @@ -1,19 +1,28 @@ // awsConfigMiddleware.js const AWS = require('aws-sdk'); -const config = require('../config'); +const path = require('path'); + +const config = require(path.join(global.__basedir, 'config')); const awsConfigProvider = (req, res, next) => { const accessKeyId = req.header('X-aws-access-Key'); const secretAccessKey = req.header('X-aws-secret-Key'); const region = req.header('X-aws-region'); - if (accessKeyId && secretAccessKey) { + if (config.USE_DEFAULT_KEYS && !(accessKeyId && secretAccessKey)) { // Set up AWS SDK configuration with user-provided access key and secret AWS.config.update({ accessKeyId, secretAccessKey, region: region ?? config.AWS_DEFAULT_REGION }); + } else { + // Set up AWS SDK configuration + AWS.config.update({ + accessKeyId: config.AWS_ACCESS_KEY, + secretAccessKey: config.AWS_ACCESS_SECRET, + region: config.AWS_DEFAULT_REGION + }); } next(); // Continue with the next middleware or route handler }; From bc2d254b85e1b28e8b53bd29e184496919e7eede Mon Sep 17 00:00:00 2001 From: Pushpak Sharma Date: Thu, 26 Oct 2023 15:46:16 +0530 Subject: [PATCH 09/16] completed google ocr request --- intelliserver/api/ocr/index.js | 67 +++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/intelliserver/api/ocr/index.js b/intelliserver/api/ocr/index.js index b766d68..bde84e0 100644 --- a/intelliserver/api/ocr/index.js +++ b/intelliserver/api/ocr/index.js @@ -1,5 +1,6 @@ const express = require('express'); const AWS = require('aws-sdk'); +const fetch = require('node-fetch'); // For making HTTP requests const { ImageAnnotatorClient } = require('@google-cloud/vision'); @@ -158,7 +159,6 @@ router.post('/aws', awsConfigProvider, getImageFromUrlOrFile, async (req, res) = res.status(500).json({ status: 'ERROR', message: error.message }); } }); - /** * @swagger * /ocr/google: @@ -177,6 +177,10 @@ router.post('/aws', awsConfigProvider, getImageFromUrlOrFile, async (req, res) = * type: string * format: binary * description: Image to be used for OCR (upload a file). + * apiKey: + * type: string + * required: false + * description: Optional API key for this specific request. * responses: * 200: * description: OCR results. @@ -193,8 +197,8 @@ router.post('/aws', awsConfigProvider, getImageFromUrlOrFile, async (req, res) = * properties: * text: * type: array - * items: - * type: string + * items: + * type: string * description: The extracted text from the image. * 400: * description: Invalid request or image format. @@ -220,7 +224,6 @@ router.post('/aws', awsConfigProvider, getImageFromUrlOrFile, async (req, res) = * required: false * description: Optional AWS region for this specific request. */ - /** * @swagger * /ocr/google: @@ -238,6 +241,10 @@ router.post('/aws', awsConfigProvider, getImageFromUrlOrFile, async (req, res) = * imageUrl: * type: string * description: The URL of the image to perform OCR on. + * apiKey: + * type: string + * required: false + * description: Optional API key for this specific request. * responses: * 200: * description: OCR results. @@ -279,25 +286,67 @@ router.post('/aws', awsConfigProvider, getImageFromUrlOrFile, async (req, res) = * required: false * description: Optional AWS region for this specific request. */ - router.post('/google', getImageFromUrlOrFile, async (req, res) => { try { const { buffer } = req.file; + const { apiKey } = req.body + const googleOcr = async (imageBuffer) => { const client = new ImageAnnotatorClient(); const [result] = await client.textDetection(imageBuffer); const detectedText = result.textAnnotations.map((annotation) => annotation.description); return detectedText; }; + const fetchOcr = async (imageBuffer) => { + // Define the Vision API endpoint + const endpoint = `https://vision.googleapis.com/v1/images:annotate?key=${apiKey}`; + // Prepare the request data + const requestData = { + requests: [ + { + image: { + content: buffer.toString('base64'), + }, + features: [{ type: 'TEXT_DETECTION' }], + }, + ], + }; + // Make a POST request to the Vision API using node-fetch + const response = await fetch(endpoint, { + method: 'POST', + body: JSON.stringify(requestData), + headers: { 'Content-Type': 'application/json' }, + }); - const detectedText = await googleOcr(buffer); - const response = { + // Check the response status + if (response.status !== 200) { + throw new Error(`Vision API request failed with status code ${response.status}`); + } + + // Parse the JSON response + const responseData = await response.json(); + + // Extract detected text from the response + const detectedText = responseData.responses[0].textAnnotations.map(annotation => annotation.description); + + return detectedText; + }; + + let detectedText + if(apiKey) { + detectedText = await fetchOcr(buffer) + } else { + detectedText = await googleOcr(buffer) + } + + const responseBody = { status: 'OK', data: { - text: detectedText + text: detectedText, }, }; - res.json(response); + + res.json(responseBody); } catch (error) { res.status(500).json({ status: 'ERROR', message: error.message }); } From b6ee3435336c606bbff7bdd22911e5cb5e682087 Mon Sep 17 00:00:00 2001 From: Pushpak Sharma Date: Thu, 26 Oct 2023 15:49:12 +0530 Subject: [PATCH 10/16] updated postman collection for google ocr --- postman/Intellinode Server.postman_collection.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/postman/Intellinode Server.postman_collection.json b/postman/Intellinode Server.postman_collection.json index bc5a97f..aa66b65 100644 --- a/postman/Intellinode Server.postman_collection.json +++ b/postman/Intellinode Server.postman_collection.json @@ -999,6 +999,11 @@ "key": "image", "type": "file", "src": [] + }, + { + "key": "apiKey", + "value": "", + "type": "text" } ] }, @@ -1028,7 +1033,7 @@ ], "body": { "mode": "raw", - "raw": "{\r\n \"imageUrl\": \"\"\r\n}", + "raw": "{\r\n \"imageUrl\": \"\",\r\n \"apiKey\": \"\"\r\n}", "options": { "raw": { "language": "json" From 65736b5e53bba34babd32fbc3f7f55ae53bafab5 Mon Sep 17 00:00:00 2001 From: Ahmad Barqawi Date: Mon, 30 Oct 2023 19:44:27 +0000 Subject: [PATCH 11/16] fix dependency issues --- intelliserver/api/ocr/index.js | 126 +- intelliserver/middleware/awsConfigProvider.js | 3 +- intelliserver/package-lock.json | 1128 ++++++++++++++++- intelliserver/package.json | 2 + 4 files changed, 1113 insertions(+), 146 deletions(-) diff --git a/intelliserver/api/ocr/index.js b/intelliserver/api/ocr/index.js index bde84e0..e8aeb4f 100644 --- a/intelliserver/api/ocr/index.js +++ b/intelliserver/api/ocr/index.js @@ -9,66 +9,6 @@ const awsConfigProvider = require('../../middleware/awsConfigProvider'); const router = express.Router(); -/** - * @swagger - * /ocr/aws: - * post: - * summary: Perform OCR on an image using AWS Rekognition. - * tags: - * - OCR - * requestBody: - * required: true - * content: - * multipart/form-data: - * schema: - * type: object - * properties: - * image: - * type: string - * format: binary - * description: Image to be used for OCR (upload a file). - * responses: - * 200: - * description: OCR results. - * content: - * application/json: - * schema: - * type: object - * properties: - * status: - * type: string - * description: The status of the OCR operation (e.g., "OK"). - * data: - * type: object - * properties: - * text: - * type: string - * description: The extracted text from the image. - * 400: - * description: Invalid request or image format. - * 500: - * description: Internal server error. - * parameters: - * - in: header - * name: X-aws-access-Key - * schema: - * type: string - * required: false - * description: Optional AWS access key for this specific request. - * - in: header - * name: X-aws-secret-Key - * schema: - * type: string - * required: false - * description: Optional AWS secret key for this specific request. - * - in: header - * name: X-aws-region - * schema: - * type: string - * required: false - * description: Optional AWS region for this specific request. - */ - /** * @swagger * /ocr/aws: @@ -159,71 +99,7 @@ router.post('/aws', awsConfigProvider, getImageFromUrlOrFile, async (req, res) = res.status(500).json({ status: 'ERROR', message: error.message }); } }); -/** - * @swagger - * /ocr/google: - * post: - * summary: Perform OCR on an image using Google Cloud Vision API. - * tags: - * - OCR - * requestBody: - * required: true - * content: - * multipart/form-data: - * schema: - * type: object - * properties: - * image: - * type: string - * format: binary - * description: Image to be used for OCR (upload a file). - * apiKey: - * type: string - * required: false - * description: Optional API key for this specific request. - * responses: - * 200: - * description: OCR results. - * content: - * application/json: - * schema: - * type: object - * properties: - * status: - * type: string - * description: The status of the OCR operation (e.g., "OK"). - * data: - * type: object - * properties: - * text: - * type: array - * items: - * type: string - * description: The extracted text from the image. - * 400: - * description: Invalid request or image format. - * 500: - * description: Internal server error. - * parameters: - * - in: header - * name: X-aws-access-Key - * schema: - * type: string - * required: false - * description: Optional AWS access key for this specific request. - * - in: header - * name: X-aws-secret-Key - * schema: - * type: string - * required: false - * description: Optional AWS secret key for this specific request. - * - in: header - * name: X-aws-region - * schema: - * type: string - * required: false - * description: Optional AWS region for this specific request. - */ + /** * @swagger * /ocr/google: diff --git a/intelliserver/middleware/awsConfigProvider.js b/intelliserver/middleware/awsConfigProvider.js index 171a164..f27ed55 100644 --- a/intelliserver/middleware/awsConfigProvider.js +++ b/intelliserver/middleware/awsConfigProvider.js @@ -9,7 +9,7 @@ const awsConfigProvider = (req, res, next) => { const secretAccessKey = req.header('X-aws-secret-Key'); const region = req.header('X-aws-region'); - if (config.USE_DEFAULT_KEYS && !(accessKeyId && secretAccessKey)) { + if (accessKeyId && secretAccessKey) { // Set up AWS SDK configuration with user-provided access key and secret AWS.config.update({ accessKeyId, @@ -17,6 +17,7 @@ const awsConfigProvider = (req, res, next) => { region: region ?? config.AWS_DEFAULT_REGION }); } else { + console.log('AWS load local values') // Set up AWS SDK configuration AWS.config.update({ accessKeyId: config.AWS_ACCESS_KEY, diff --git a/intelliserver/package-lock.json b/intelliserver/package-lock.json index 2fb59e2..c4dcc53 100644 --- a/intelliserver/package-lock.json +++ b/intelliserver/package-lock.json @@ -8,6 +8,8 @@ "name": "intelliserver", "version": "0.0.2", "dependencies": { + "@google-cloud/vision": "^4.0.2", + "aws-sdk": "^2.1483.0", "cookie-parser": "~1.4.4", "debug": "~2.6.9", "dotenv": "^16.3.1", @@ -63,16 +65,175 @@ "openapi-types": ">=7" } }, + "node_modules/@google-cloud/promisify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz", + "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/vision": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/vision/-/vision-4.0.2.tgz", + "integrity": "sha512-VhYcxDXmkbQjCtAfPiQcW8bB4a+H5lFks2vDG4WQabKWa3VveyOmmbqHpNlH6JVD/sdYHz3h8koCcyHxE13oEA==", + "dependencies": { + "@google-cloud/promisify": "^4.0.0", + "google-gax": "^4.0.3", + "is": "^3.3.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.9.8", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.8.tgz", + "integrity": "sha512-FFPzDS333Vw8hvf+1FaEsaCYVPBdNdUCw7zArTiF7+6gOzln967b4GBCBekKGqoKEgna8d3Ayxv8t+IvazXG3g==", + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", + "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.4", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@jsdevtools/ono": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@types/caseless": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.4.tgz", + "integrity": "sha512-2in/lrHRNmDvHPgyormtEralhPcN3An1gLjJzj2Bw145VBxkQ75JEXW6CTdMAwShiHQcYsl2d10IjQSdJSJz4g==" + }, "node_modules/@types/json-schema": { "version": "7.0.12", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==" }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" + }, + "node_modules/@types/node": { + "version": "20.8.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.9.tgz", + "integrity": "sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/request": { + "version": "2.48.11", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.11.tgz", + "integrity": "sha512-HuihY1+Vss5RS9ZHzRyTGIzwPTdrJBkCm/mAeLRYrOQu/MGqyezKXWOK1VhCnR+SDbp9G2mRUP+OVEqCrzpcfA==", + "dependencies": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "node_modules/@types/request/node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.4.tgz", + "integrity": "sha512-95Sfz4nvMAb0Nl9DTxN3j64adfwfbBPEYq14VN7zT5J5O2M9V6iZMIIQU1U+pJyl9agHYHNCqhCXgyEtIRRa5A==" + }, "node_modules/@xmldom/xmldom": { "version": "0.8.10", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", @@ -81,6 +242,17 @@ "node": ">=10.0.0" } }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -93,6 +265,60 @@ "node": ">= 0.6" } }, + "node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/append-field": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", @@ -113,6 +339,37 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sdk": { + "version": "2.1483.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1483.0.tgz", + "integrity": "sha512-u1DVpvBd2UeYLXwXgY8tO/SjbdFEE6nRkQWiLaDJaBoHycHpe+DjPtGl1KaLiOIMaDZ+cnIzf3/aRSss/mCeBQ==", + "dependencies": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.16.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "util": "^0.12.4", + "uuid": "8.0.0", + "xml2js": "0.5.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/axios": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz", @@ -158,6 +415,14 @@ "node": ">= 0.8" } }, + "node_modules/bignumber.js": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", + "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", + "engines": { + "node": "*" + } + }, "node_modules/bluebird": { "version": "3.4.7", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", @@ -214,6 +479,21 @@ "concat-map": "0.0.1" } }, + "node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -239,12 +519,13 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -255,6 +536,35 @@ "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==" }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -369,6 +679,19 @@ "ms": "2.0.0" } }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -429,11 +752,48 @@ "underscore": "^1.13.1" } }, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/duplexify/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -442,6 +802,22 @@ "node": ">= 0.8" } }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -463,6 +839,22 @@ "node": ">= 0.6" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/express": { "version": "4.18.2", "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", @@ -550,6 +942,11 @@ } ] }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, "node_modules/finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", @@ -597,6 +994,14 @@ } } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -637,19 +1042,56 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gaxios": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.1.1.tgz", + "integrity": "sha512-bw8smrX+XlAoo9o1JAksBwX+hi/RG15J+NTSxmNPIclKC3ZVK6C2afwY8OSdRvOK0+ZLecUJYtj2MmjOt3Dm0w==", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gcp-metadata": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.0.0.tgz", + "integrity": "sha512-Ozxyi23/1Ar51wjUT2RDklK+3HxqDr8TLBNK8rBBFQ7T85iIGnXnVusauj06QyqCXRFZig8LZC+TUddWbndlpQ==", + "dependencies": { + "gaxios": "^6.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } }, "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -674,15 +1116,75 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "node_modules/google-auth-library": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.2.0.tgz", + "integrity": "sha512-1oV3p0JhNEhVbj26eF3FAJcv9MXXQt4S0wcvKZaDbl4oHq5V3UJoSbsGZGQNcjoCdhW4kDSwOs11wLlHog3fgQ==", "dependencies": { - "function-bind": "^1.1.1" + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.0.0", + "gcp-metadata": "^6.0.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" }, "engines": { - "node": ">= 0.4.0" + "node": ">=14" + } + }, + "node_modules/google-gax": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.0.5.tgz", + "integrity": "sha512-yLoYtp4zE+8OQA74oBEbNkbzI6c95W01JSL7RqC8XERKpRvj3ytZp1dgnbA6G9aRsc8pZB25xWYBcCmrbYOEhA==", + "dependencies": { + "@grpc/grpc-js": "~1.9.6", + "@grpc/proto-loader": "^0.7.0", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "google-auth-library": "^9.0.0", + "node-fetch": "^2.6.1", + "object-hash": "^3.0.0", + "proto3-json-serializer": "^2.0.0", + "protobufjs": "7.2.5", + "retry-request": "^7.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gtoken": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.0.1.tgz", + "integrity": "sha512-KcFVtoP1CVFtQu0aSk3AyAt2og66PFhZAlkUOuWKwzMLoulHXG5W5wE5xAnHb+yl3/wEFoqGW7/cDGMU8igDZQ==", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { @@ -707,6 +1209,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -730,6 +1257,84 @@ "node": ">= 0.8" } }, + "node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-agent/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/http-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/http-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -741,6 +1346,11 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, "node_modules/immediate": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", @@ -778,11 +1388,100 @@ "node": ">= 0.10" } }, + "node_modules/is": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz", + "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==", + "engines": { + "node": "*" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, + "node_modules/jmespath": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -794,6 +1493,14 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/jszip": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", @@ -805,6 +1512,25 @@ "setimmediate": "^1.0.5" } }, + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, "node_modules/lie": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", @@ -813,6 +1539,11 @@ "immediate": "~3.0.5" } }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -828,6 +1559,11 @@ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, "node_modules/lop": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/lop/-/lop-0.4.1.tgz", @@ -1027,6 +1763,14 @@ "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.12.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", @@ -1129,6 +1873,40 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "node_modules/proto3-json-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.0.tgz", + "integrity": "sha512-FB/YaNrpiPkyQNSNPilpn8qn0KdEfkgmJ9JP93PQyF/U4bAiXY5BiUdDhiDO4S48uSQ6AesklgVlrKiqZPzegw==", + "dependencies": { + "protobufjs": "^7.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/protobufjs": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", + "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -1146,6 +1924,11 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -1160,6 +1943,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -1196,6 +1988,49 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/retry-request": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.1.tgz", + "integrity": "sha512-ZI6vJp9rfB71mrZpw+n9p/B6HCsd7QJlSEQftZ+xfJzr3cQ9EPGKw1FF0BnViJ0fYREX6FhymBD2CARpmsFciQ==", + "dependencies": { + "@types/request": "^2.48.8", + "debug": "^4.1.1", + "extend": "^3.0.2", + "teeny-request": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/retry-request/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/retry-request/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -1206,6 +2041,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" + }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -1267,6 +2107,20 @@ "node": ">= 0.8.0" } }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -1303,6 +2157,19 @@ "node": ">= 0.8" } }, + "node_modules/stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "dependencies": { + "stubs": "^3.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -1319,6 +2186,35 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==" + }, "node_modules/swagger-jsdoc": { "version": "6.2.8", "resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-6.2.8.tgz", @@ -1368,6 +2264,77 @@ "express": ">=4.0.0 || >=5.0.0-beta" } }, + "node_modules/teeny-request": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz", + "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==", + "dependencies": { + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.9", + "stream-events": "^1.0.5", + "uuid": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/teeny-request/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/teeny-request/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/teeny-request/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/teeny-request/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/teeny-request/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -1403,6 +2370,11 @@ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==" }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1411,6 +2383,27 @@ "node": ">= 0.8" } }, + "node_modules/url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -1424,6 +2417,14 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", + "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/validator": { "version": "13.11.0", "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", @@ -1454,11 +2455,65 @@ "webidl-conversions": "^3.0.0" } }, + "node_modules/which-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xml2js/node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, "node_modules/xmlbuilder": { "version": "10.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-10.1.1.tgz", @@ -1475,6 +2530,14 @@ "node": ">=0.4" } }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, "node_modules/yaml": { "version": "2.0.0-1", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.0.0-1.tgz", @@ -1483,6 +2546,31 @@ "node": ">= 6" } }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + }, "node_modules/z-schema": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", diff --git a/intelliserver/package.json b/intelliserver/package.json index 27928da..a99937a 100644 --- a/intelliserver/package.json +++ b/intelliserver/package.json @@ -7,6 +7,8 @@ "dev": "nodemon ./bin/www" }, "dependencies": { + "@google-cloud/vision": "^4.0.2", + "aws-sdk": "^2.1483.0", "cookie-parser": "~1.4.4", "debug": "~2.6.9", "dotenv": "^16.3.1", From 2a858b1158aed62f821bd768234d1ae1f9979352 Mon Sep 17 00:00:00 2001 From: Ahmad Barqawi Date: Mon, 30 Oct 2023 20:05:28 +0000 Subject: [PATCH 12/16] fix google key --- intelliserver/api/ocr/index.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/intelliserver/api/ocr/index.js b/intelliserver/api/ocr/index.js index e8aeb4f..1166fba 100644 --- a/intelliserver/api/ocr/index.js +++ b/intelliserver/api/ocr/index.js @@ -1,14 +1,23 @@ const express = require('express'); const AWS = require('aws-sdk'); +const path = require('path'); const fetch = require('node-fetch'); // For making HTTP requests - const { ImageAnnotatorClient } = require('@google-cloud/vision'); - const getImageFromUrlOrFile = require('../../middleware/getImageFromUrlOrFile'); const awsConfigProvider = require('../../middleware/awsConfigProvider'); +const { USE_DEFAULT_KEYS } = require(path.join(global.__basedir, 'config')); const router = express.Router(); + +function getGoogleKey(req) { + if (USE_DEFAULT_KEYS && !req.body.api_key) { + return process.env.GOOGLE_KEY; + } else { + return req.body.api_key; + } +} + /** * @swagger * /ocr/aws: @@ -165,7 +174,7 @@ router.post('/aws', awsConfigProvider, getImageFromUrlOrFile, async (req, res) = router.post('/google', getImageFromUrlOrFile, async (req, res) => { try { const { buffer } = req.file; - const { apiKey } = req.body + const apiKey = getGoogleKey(req); const googleOcr = async (imageBuffer) => { const client = new ImageAnnotatorClient(); From 28841bd16b1e32c12f47d5403138e5470d61c22c Mon Sep 17 00:00:00 2001 From: Ahmad Barqawi Date: Mon, 30 Oct 2023 22:44:24 +0000 Subject: [PATCH 13/16] fix AWS scope --- intelliserver/api/ocr/index.js | 7 +++++-- intelliserver/middleware/awsConfigProvider.js | 18 +++++++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/intelliserver/api/ocr/index.js b/intelliserver/api/ocr/index.js index 1166fba..3816dd0 100644 --- a/intelliserver/api/ocr/index.js +++ b/intelliserver/api/ocr/index.js @@ -82,7 +82,11 @@ router.post('/aws', awsConfigProvider, getImageFromUrlOrFile, async (req, res) = try { const { buffer } = req.file; const awsOcr = async (imageBuffer) => { - const rekognition = new AWS.Rekognition(); + const rekognition = new AWS.Rekognition({ + accessKeyId: req.awsConfig.accessKeyId, + secretAccessKey: req.awsConfig.secretAccessKey, + region : req.awsConfig.region + }); const params = { Image: { @@ -92,7 +96,6 @@ router.post('/aws', awsConfigProvider, getImageFromUrlOrFile, async (req, res) = const response = await rekognition.detectText(params).promise(); const detectedText = response.TextDetections.map((textDetection) => textDetection.DetectedText); - return detectedText; } diff --git a/intelliserver/middleware/awsConfigProvider.js b/intelliserver/middleware/awsConfigProvider.js index f27ed55..8a8256c 100644 --- a/intelliserver/middleware/awsConfigProvider.js +++ b/intelliserver/middleware/awsConfigProvider.js @@ -9,23 +9,23 @@ const awsConfigProvider = (req, res, next) => { const secretAccessKey = req.header('X-aws-secret-Key'); const region = req.header('X-aws-region'); - if (accessKeyId && secretAccessKey) { - // Set up AWS SDK configuration with user-provided access key and secret - AWS.config.update({ + req.awsConfig = {}; + if (config.USE_DEFAULT_KEYS && accessKeyId && secretAccessKey) { + req.awsConfig = { accessKeyId, secretAccessKey, region: region ?? config.AWS_DEFAULT_REGION - }); + }; } else { - console.log('AWS load local values') - // Set up AWS SDK configuration - AWS.config.update({ + req.awsConfig = { accessKeyId: config.AWS_ACCESS_KEY, secretAccessKey: config.AWS_ACCESS_SECRET, region: config.AWS_DEFAULT_REGION - }); + }; } - next(); // Continue with the next middleware or route handler + + // Continue with the next middleware or route handler + next(); }; module.exports = awsConfigProvider; \ No newline at end of file From 7bc6ab8153de7be1df615b7bb4ca181520e0d285 Mon Sep 17 00:00:00 2001 From: Ahmad Barqawi Date: Mon, 30 Oct 2023 22:50:26 +0000 Subject: [PATCH 14/16] add ocr postman --- postman/Intellinode Server.postman_collection.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/postman/Intellinode Server.postman_collection.json b/postman/Intellinode Server.postman_collection.json index aa66b65..d549427 100644 --- a/postman/Intellinode Server.postman_collection.json +++ b/postman/Intellinode Server.postman_collection.json @@ -1001,9 +1001,10 @@ "src": [] }, { - "key": "apiKey", + "key": "api_key", "value": "", - "type": "text" + "type": "text", + "disabled": true } ] }, From 73fc32a9eb012c26fe1e14a6b0a7bc9710666bc3 Mon Sep 17 00:00:00 2001 From: Ahmad Barqawi Date: Mon, 30 Oct 2023 22:58:35 +0000 Subject: [PATCH 15/16] improve the release image size --- intelliserver/.dockerignore | 11 +++++++++++ intelliserver/Dockerfile | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/intelliserver/.dockerignore b/intelliserver/.dockerignore index 292211f..0164fdc 100644 --- a/intelliserver/.dockerignore +++ b/intelliserver/.dockerignore @@ -13,3 +13,14 @@ lerna-debug.log* .env.test.local .env.production.local .env.local + + +# general +node_modules +npm-debug.log +Dockerfile +.dockerignore +.git +.gitignore +README.md +LICENSE \ No newline at end of file diff --git a/intelliserver/Dockerfile b/intelliserver/Dockerfile index 426c44e..91b4b67 100644 --- a/intelliserver/Dockerfile +++ b/intelliserver/Dockerfile @@ -1,5 +1,5 @@ # base image -FROM node:14 +FROM node:14-alpine # work directory WORKDIR /app @@ -8,7 +8,7 @@ WORKDIR /app COPY package*.json ./ # install app dependencies -RUN npm install +RUN npm install --only=production # copy app source COPY . . From c1ba9cafe346d63e136bf3b004cc66fd3c7b8806 Mon Sep 17 00:00:00 2001 From: Ahmad Barqawi Date: Mon, 30 Oct 2023 23:01:44 +0000 Subject: [PATCH 16/16] update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9ca878f..5ad8753 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Intelliserver is a microservice providing unified access to multiple AI models, - **Image Generation**: generate quality images based on described contexts using diffusion image models. - **Chat Context**: get the relevant messages for the chatbot conversation. - **Parsers**: convert documents to text such as PDF and word. +- **OCR**: extract text from images using AWS or Google vision. ## Installation