From f3a290cb72eb76730c872be4173b4c70aa9aaf2c Mon Sep 17 00:00:00 2001 From: DhanshCOSQ Date: Tue, 1 Apr 2025 22:23:00 +0530 Subject: [PATCH] Added function to send email for invoice --- .vscode/launch.json | 10 ++ functions/package-lock.json | 237 +++++++++++++++++++++++++++++++++--- functions/package.json | 8 +- functions/src/index.ts | 76 +++++++++++- functions/tsconfig.json | 2 +- package-lock.json | 72 +++++++++++ package.json | 9 ++ 7 files changed, 392 insertions(+), 22 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..cbfc888 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,10 @@ +{ + "configurations": [ + { + "type": "node", + "request": "attach", + "name": "Debug", + "port": 9229 + } + ] +} \ No newline at end of file diff --git a/functions/package-lock.json b/functions/package-lock.json index a2c4591..ac67f4d 100644 --- a/functions/package-lock.json +++ b/functions/package-lock.json @@ -8,15 +8,21 @@ "name": "functions", "version": "0.0.0", "dependencies": { + "@types/node-fetch": "^2.6.12", + "axios": "^1.8.4", "firebase-admin": "^12.6.0", "firebase-functions": "^6.0.1", "form-data": "^4.0.1", "html-to-text": "^9.0.5", - "long": "4.0.0", + "long": "^4.0.0", "mailgun.js": "^10.4.0", + "node-fetch": "^2.7.0", + "pdfjs-dist": "^5.0.375", "twilio": "^5.4.0" }, "devDependencies": { + "@types/long": "^5.0.0", + "@types/node": "^22.13.14", "firebase-functions-test": "^3.1.0", "typescript": "^5.8.2" }, @@ -1156,6 +1162,177 @@ "url": "https://opencollective.com/js-sdsl" } }, + "node_modules/@napi-rs/canvas": { + "version": "0.1.68", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.68.tgz", + "integrity": "sha512-LQESrePLEBLvhuFkXx9jjBXRC2ClYsO5mqQ1m/puth5z9SOuM3N/B3vDuqnC3RJFktDktyK9khGvo7dTkqO9uQ==", + "optional": true, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@napi-rs/canvas-android-arm64": "0.1.68", + "@napi-rs/canvas-darwin-arm64": "0.1.68", + "@napi-rs/canvas-darwin-x64": "0.1.68", + "@napi-rs/canvas-linux-arm-gnueabihf": "0.1.68", + "@napi-rs/canvas-linux-arm64-gnu": "0.1.68", + "@napi-rs/canvas-linux-arm64-musl": "0.1.68", + "@napi-rs/canvas-linux-riscv64-gnu": "0.1.68", + "@napi-rs/canvas-linux-x64-gnu": "0.1.68", + "@napi-rs/canvas-linux-x64-musl": "0.1.68", + "@napi-rs/canvas-win32-x64-msvc": "0.1.68" + } + }, + "node_modules/@napi-rs/canvas-android-arm64": { + "version": "0.1.68", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-android-arm64/-/canvas-android-arm64-0.1.68.tgz", + "integrity": "sha512-h1KcSR4LKLfRfzeBH65xMxbWOGa1OtMFQbCMVlxPCkN1Zr+2gK+70pXO5ktojIYcUrP6KDcOwoc8clho5ccM/w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-darwin-arm64": { + "version": "0.1.68", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-arm64/-/canvas-darwin-arm64-0.1.68.tgz", + "integrity": "sha512-/VURlrAD4gDoxW1GT/b0nP3fRz/fhxmHI/xznTq2FTwkQLPOlLkDLCvTmQ7v6LtGKdc2Ed6rvYpRan+JXThInQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-darwin-x64": { + "version": "0.1.68", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-darwin-x64/-/canvas-darwin-x64-0.1.68.tgz", + "integrity": "sha512-tEpvGR6vCLTo1Tx9wmDnoOKROpw57wiCWwCpDOuVlj/7rqEJOUYr9ixW4aRJgmeGBrZHgevI0EURys2ER6whmg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-arm-gnueabihf": { + "version": "0.1.68", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm-gnueabihf/-/canvas-linux-arm-gnueabihf-0.1.68.tgz", + "integrity": "sha512-U9xbJsumPOiAYeAFZMlHf62b9dGs2HJ6Q5xt7xTB0uEyPeurwhgYBWGgabdsEidyj38YuzI/c3LGBbSQB3vagw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-gnu": { + "version": "0.1.68", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-gnu/-/canvas-linux-arm64-gnu-0.1.68.tgz", + "integrity": "sha512-KFkn8wEm3mPnWD4l8+OUUkxylSJuN5q9PnJRZJgv15RtCA1bgxIwTkBhI/+xuyVMcHqON9sXq7cDkEJtHm35dg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-arm64-musl": { + "version": "0.1.68", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-arm64-musl/-/canvas-linux-arm64-musl-0.1.68.tgz", + "integrity": "sha512-IQzts91rCdOALXBWQxLZRCEDrfFTGDtNRJMNu+2SKZ1uT8cmPQkPwVk5rycvFpvgAcmiFiOSCp1aRrlfU8KPpQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-riscv64-gnu": { + "version": "0.1.68", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-riscv64-gnu/-/canvas-linux-riscv64-gnu-0.1.68.tgz", + "integrity": "sha512-e9AS5UttoIKqXSmBzKZdd3NErSVyOEYzJfNOCGtafGk1//gibTwQXGlSXmAKuErqMp09pyk9aqQRSYzm1AQfBw==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-gnu": { + "version": "0.1.68", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-gnu/-/canvas-linux-x64-gnu-0.1.68.tgz", + "integrity": "sha512-Pa/I36VE3j57I3Obhrr+J48KGFfkZk2cJN/2NmW/vCgmoF7kCP6aTVq5n+cGdGWLd/cN9CJ9JvNwEoMRDghu0g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-linux-x64-musl": { + "version": "0.1.68", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-linux-x64-musl/-/canvas-linux-x64-musl-0.1.68.tgz", + "integrity": "sha512-9c6rkc5195wNxuUHJdf4/mmnq433OQey9TNvQ9LspJazvHbfSkTij8wtKjASVQsJyPDva4fkWOeV/OQ7cLw0GQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/canvas-win32-x64-msvc": { + "version": "0.1.68", + "resolved": "https://registry.npmjs.org/@napi-rs/canvas-win32-x64-msvc/-/canvas-win32-x64-msvc-0.1.68.tgz", + "integrity": "sha512-Fc5Dez23u0FoSATurT6/w1oMytiRnKWEinHivdMvXpge6nG4YvhrASrtqMk8dGJMVQpHr8QJYF45rOrx2YU2Aw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@opentelemetry/api": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", @@ -1423,10 +1600,14 @@ "dev": true }, "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==", - "optional": true + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/long/-/long-5.0.0.tgz", + "integrity": "sha512-eQs9RsucA/LNjnMoJvWG/nXa7Pot/RbBzilF/QRIU/xRl+0ApxrSUFsV5lmf01SvSlqMzJ7Zwxe440wmz2SJGA==", + "deprecated": "This is a stub types definition. long provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "long": "*" + } }, "node_modules/@types/mime": { "version": "1.3.5", @@ -1439,13 +1620,22 @@ "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==" }, "node_modules/@types/node": { - "version": "22.13.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.10.tgz", - "integrity": "sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==", + "version": "22.13.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.14.tgz", + "integrity": "sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w==", "dependencies": { "undici-types": "~6.20.0" } }, + "node_modules/@types/node-fetch": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", + "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.0" + } + }, "node_modules/@types/qs": { "version": "6.9.18", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", @@ -1659,9 +1849,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.3.tgz", - "integrity": "sha512-iP4DebzoNlP/YN2dpwCgb8zoCmhtkajzS48JvwmkSkXvPI3DHc7m+XYL5tGnSlJtR6nImXZmdCuN5aP8dh1d8A==", + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", + "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -3085,6 +3275,12 @@ "node": ">=14" } }, + "node_modules/google-gax/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==", + "optional": true + }, "node_modules/google-gax/node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", @@ -4710,7 +4906,6 @@ "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==", - "optional": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -4970,6 +5165,17 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" }, + "node_modules/pdfjs-dist": { + "version": "5.0.375", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-5.0.375.tgz", + "integrity": "sha512-QDRlEVldf/cX88CElGAyRhjqNOO69kmB3HZlalDAfqJ/IvmqJNkipomhBZy4cWATfLVlkQTXE3H4yFvMF2uPsg==", + "engines": { + "node": ">=20" + }, + "optionalDependencies": { + "@napi-rs/canvas": "^0.1.67" + } + }, "node_modules/peberminta": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz", @@ -5824,8 +6030,7 @@ "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "optional": true + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/ts-deepmerge": { "version": "2.0.7", @@ -6058,8 +6263,7 @@ "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==", - "optional": true + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/websocket-driver": { "version": "0.7.4", @@ -6086,7 +6290,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "optional": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" diff --git a/functions/package.json b/functions/package.json index d7c10c4..5c20815 100644 --- a/functions/package.json +++ b/functions/package.json @@ -15,15 +15,21 @@ }, "main": "lib/index.js", "dependencies": { + "@types/node-fetch": "^2.6.12", + "axios": "^1.8.4", "firebase-admin": "^12.6.0", "firebase-functions": "^6.0.1", "form-data": "^4.0.1", "html-to-text": "^9.0.5", - "long": "4.0.0", + "long": "^4.0.0", "mailgun.js": "^10.4.0", + "node-fetch": "^2.7.0", + "pdfjs-dist": "^5.0.375", "twilio": "^5.4.0" }, "devDependencies": { + "@types/long": "^5.0.0", + "@types/node": "^22.13.14", "firebase-functions-test": "^3.1.0", "typescript": "^5.8.2" }, diff --git a/functions/src/index.ts b/functions/src/index.ts index 65b4ecd..33a2aa5 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -4,12 +4,79 @@ import * as admin from 'firebase-admin'; import * as express from "express"; import * as logger from "firebase-functions/logger"; import { onDocumentCreated } from "firebase-functions/firestore"; - +import * as os from 'os'; +import * as path from 'path'; +import * as fs from 'fs'; +import * as https from 'https'; const formData = require('form-data'); const Mailgun = require('mailgun.js'); const { convert } = require('html-to-text'); -const twilio = require('twilio') +const twilio = require('twilio'); + +if (!admin.apps.length) { + admin.initializeApp(); +} +export const sendEmailWithAttachment = onRequest({ + region: '#{SERVICES_RGN}#' +}, async (request: Request, response: express.Response) => { + try { + const { toAddress, subject, message, fileUrl, fileName } = request.body; + + if (!toAddress || !subject || !message || !fileUrl) { + response.status(400).json({ + error: 'Missing required fields (toAddress, subject, message, fileUrl)' + }); + return; + } + const tempFilePath = path.join(os.tmpdir(), fileName || 'attachment.pdf'); + await new Promise((resolve, reject) => { + const file = fs.createWriteStream(tempFilePath); + https.get(fileUrl, (res) => { + res.pipe(file); + file.on('finish', () => { + file.close(); + resolve(); + }); + }).on('error', (err) => { + fs.unlink(tempFilePath, () => { }); + reject(err); + }); + }); + + const mailgun = new Mailgun(formData); + const client = mailgun.client({ username: 'api', key: process.env.MAILGUN_API_KEY }); + + const options = { + wordwrap: 130, + }; + const textMessage = convert(message, options); + const fileBuffer = fs.readFileSync(tempFilePath); + const attachmentFilename = fileName || path.basename(fileUrl.split('?')[0]); + + const data = { + from: process.env.MAILGUN_FROM_ADDRESS, + to: toAddress, + subject: subject, + text: textMessage, + html: message, + attachment: { + data: fileBuffer, + filename: attachmentFilename, + contentType: 'application/pdf', + } + }; + + const result = await client.messages.create(process.env.MAILGUN_SERVER, data); + fs.unlinkSync(tempFilePath); + + logger.info('Email with attachment from URL sent successfully'); + response.json({ success: true, result }); + } catch (error) { + logger.error('Error sending email with attachment from URL:', error); + response.status(500).json({ success: false, error: error instanceof Error ? error.message : String(error) }); + } +}); export const sendEmailMessage = onRequest({ region: '#{SERVICES_RGN}#' }, (request: Request, response: express.Response) => { @@ -135,4 +202,7 @@ export const notifyInvitation = onDocumentCreated({ console.error('Error sending invitation notification:', error); return null; } -}); \ No newline at end of file +}); + + + diff --git a/functions/tsconfig.json b/functions/tsconfig.json index 2924892..752b2ab 100644 --- a/functions/tsconfig.json +++ b/functions/tsconfig.json @@ -15,4 +15,4 @@ "include": [ "src" ] -} +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..6c1f8fe --- /dev/null +++ b/package-lock.json @@ -0,0 +1,72 @@ +{ + "name": "fitlien-services", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@types/busboy": "^1.5.4", + "busboy": "^1.6.0" + }, + "devDependencies": { + "@types/long": "^5.0.0" + } + }, + "node_modules/@types/busboy": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-1.5.4.tgz", + "integrity": "sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/long": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/long/-/long-5.0.0.tgz", + "integrity": "sha512-eQs9RsucA/LNjnMoJvWG/nXa7Pot/RbBzilF/QRIU/xRl+0ApxrSUFsV5lmf01SvSlqMzJ7Zwxe440wmz2SJGA==", + "deprecated": "This is a stub types definition. long provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "long": "*" + } + }, + "node_modules/@types/node": { + "version": "22.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", + "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/long": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.1.tgz", + "integrity": "sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==", + "dev": true + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..5f79027 --- /dev/null +++ b/package.json @@ -0,0 +1,9 @@ +{ + "dependencies": { + "@types/busboy": "^1.5.4", + "busboy": "^1.6.0" + }, + "devDependencies": { + "@types/long": "^5.0.0" + } +} -- 2.43.0