From 4b7688b69cb1ec99bd942c2b0a0209816e7f338f Mon Sep 17 00:00:00 2001 From: Ijlal Ahmad Date: Sat, 7 Dec 2024 22:05:44 +0530 Subject: [PATCH 1/7] added push notification with fcm service for node typescript format (cherry picked from commit d180421cac1f200b70dd687a64d65eb761b36da3) --- .gitignore | 5 +- .../push-notification-with-fcm/.gitignore | 133 ++ .../.prettierrc.json | 6 + .../push-notification-with-fcm/README.md | 118 ++ .../push-notification-with-fcm/env.d.ts | 12 + .../package-lock.json | 1799 +++++++++++++++++ .../push-notification-with-fcm/package.json | 20 + .../push-notification-with-fcm/src/main.ts | 75 + .../push-notification-with-fcm/src/utils.ts | 49 + .../push-notification-with-fcm/tsconfig.json | 19 + 10 files changed, 2235 insertions(+), 1 deletion(-) create mode 100644 node-typescript/push-notification-with-fcm/.gitignore create mode 100644 node-typescript/push-notification-with-fcm/.prettierrc.json create mode 100644 node-typescript/push-notification-with-fcm/README.md create mode 100644 node-typescript/push-notification-with-fcm/env.d.ts create mode 100644 node-typescript/push-notification-with-fcm/package-lock.json create mode 100644 node-typescript/push-notification-with-fcm/package.json create mode 100644 node-typescript/push-notification-with-fcm/src/main.ts create mode 100644 node-typescript/push-notification-with-fcm/src/utils.ts create mode 100644 node-typescript/push-notification-with-fcm/tsconfig.json diff --git a/.gitignore b/.gitignore index 48b11741..71346045 100644 --- a/.gitignore +++ b/.gitignore @@ -132,4 +132,7 @@ dist appwrite.json # VSCode history directory -.history \ No newline at end of file +.history + +# WebStorm Files +.idea \ No newline at end of file diff --git a/node-typescript/push-notification-with-fcm/.gitignore b/node-typescript/push-notification-with-fcm/.gitignore new file mode 100644 index 00000000..46afb6b3 --- /dev/null +++ b/node-typescript/push-notification-with-fcm/.gitignore @@ -0,0 +1,133 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# Directory used by Appwrite CLI for local development +.appwrite \ No newline at end of file diff --git a/node-typescript/push-notification-with-fcm/.prettierrc.json b/node-typescript/push-notification-with-fcm/.prettierrc.json new file mode 100644 index 00000000..0a725205 --- /dev/null +++ b/node-typescript/push-notification-with-fcm/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "trailingComma": "es5", + "tabWidth": 2, + "semi": true, + "singleQuote": true +} diff --git a/node-typescript/push-notification-with-fcm/README.md b/node-typescript/push-notification-with-fcm/README.md new file mode 100644 index 00000000..7e08a112 --- /dev/null +++ b/node-typescript/push-notification-with-fcm/README.md @@ -0,0 +1,118 @@ +# 🔔 Node.js (TypeScript) Push Notifications with FCM Function + +Send push notifications to your users using Firebase Cloud Messaging (FCM). + +## 🧰 Usage + +### POST / + +Send a push notification to a user. + +**Parameters** + +| Name | Description | Location | Type | Sample Value | +| ------------ | ------------------------------------ | -------- | ------------------ | -------------- | +| Content-Type | The content type of the request body | Header | `application/json` | N/A | +| deviceToken | FCM device identifier | Body | String | `642...7cd` | +| message | Message to send | Body | Object | `{"title": "hello","body": "how are you?"}` | +| data | Additional data to pass | Body | Object | `{"greet": "welcome"}` | + +**Request** + +`deviceToken` and `message` are required. `data` is optional. + + +```json +{ + "deviceToken": "642...7cd", + "message": { + "title": "hello", + "body": "how are you?" + }, + "data": { + "greet": "welcome" + } +} +``` + + +**Response** + +Sample `200` Response: + +```json +{ + "ok": true, + "messageId": "as4jg109cbe1" +} +``` + +Sample `400` Response: + +```json +{ + "ok": false, + "error": "Device token and message are required." +} +``` + +Sample `500` Response: + +```json +{ + "ok": false, + "error": "Failed to send the message." +} +``` + +## ⚙️ Configuration + +| Setting | Value | +| ----------------- | ------------- | +| Runtime | Node (18.0) | +| Entrypoint | `src/main.js` | +| Build Commands | `npm install` | +| Permissions | `any` | +| Timeout (Seconds) | 15 | + +## 🔒 Environment Variables + +### FCM_PROJECT_ID + +A unique identifier for your FCM project. + +| Question | Answer | +| ------------- | ---------------------------------------------------------------------------------- | +| Required | Yes | +| Sample Value | `mywebapp-f6e57` | +| Documentation | [FCM: Project ID](https://firebase.google.com/docs/projects/learn-more#project-id) | + +### FCM_CLIENT_EMAIL + +Your FCM service account email. + +| Question | Answer | +| ------------- | ------------------------------------------------------------------------------------------------------------ | +| Required | Yes | +| Sample Value | `fcm-adminsdk-1a0de@test-f6e57.iam.gserviceaccount.com` | +| Documentation | [FCM: SDK Setup](https://firebase.google.com/docs/admin/setup#initialize_the_sdk_in_non-google_environments) | + +### FCM_PRIVATE_KEY + +A unique private key used to authenticate with FCM. + +| Question | Answer | +| ------------- | ------------------------------------------------------------------------------------------------------------ | +| Required | Yes | +| Sample Value | `0b6830cc66d92804e11af2153242d34211d675675` | +| Documentation | [FCM: SDK Setup](https://firebase.google.com/docs/admin/setup#initialize_the_sdk_in_non-google_environments) | + +### FCM_DATABASE_URL + +URL of your FCM database. + +| Question | Answer | +| ------------- | ------------------------------------------------------------------------------------------------------------ | +| Required | Yes | +| Sample Value | `https://my-app-e398e.firebaseio.com` | +| Documentation | [FCM: SDK Setup](https://firebase.google.com/docs/admin/setup#initialize_the_sdk_in_non-google_environments) | diff --git a/node-typescript/push-notification-with-fcm/env.d.ts b/node-typescript/push-notification-with-fcm/env.d.ts new file mode 100644 index 00000000..c382e4aa --- /dev/null +++ b/node-typescript/push-notification-with-fcm/env.d.ts @@ -0,0 +1,12 @@ +declare global { + namespace NodeJS { + interface ProcessEnv { + FCM_PROJECT_ID: string; + FCM_CLIENT_EMAIL: string; + FCM_PRIVATE_KEY: string; + FCM_DATABASE_URL: string; + } + } +} + +export {}; diff --git a/node-typescript/push-notification-with-fcm/package-lock.json b/node-typescript/push-notification-with-fcm/package-lock.json new file mode 100644 index 00000000..600c792e --- /dev/null +++ b/node-typescript/push-notification-with-fcm/package-lock.json @@ -0,0 +1,1799 @@ +{ + "name": "starter-template", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "starter-template", + "version": "1.0.0", + "dependencies": { + "firebase-admin": "^13.0.1", + "typescript": "^5.4.5" + }, + "devDependencies": { + "@types/node": "^20.12.12", + "prettier": "^3.2.5" + } + }, + "node_modules/@fastify/busboy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.1.0.tgz", + "integrity": "sha512-yHmUtGwEbW6HsKpPqT140/L6GpHtquHogRLgtanJFep3UAfDkE0fQfC49U+F9irCAoJVlv3M7VSp4rrtO4LnfA==", + "license": "MIT" + }, + "node_modules/@firebase/app-check-interop-types": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/app-types": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/auth-interop-types": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", + "license": "Apache-2.0" + }, + "node_modules/@firebase/component": { + "version": "0.6.11", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.11.tgz", + "integrity": "sha512-eQbeCgPukLgsKD0Kw5wQgsMDX5LeoI1MIrziNDjmc6XDq5ZQnuUymANQgAb2wp1tSF9zDSXyxJmIUXaKgN58Ug==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/util": "1.10.2", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.10.tgz", + "integrity": "sha512-sWp2g92u7xT4BojGbTXZ80iaSIaL6GAL0pwvM0CO/hb0nHSnABAqsH7AhnWGsGvXuEvbPr7blZylPaR9J+GSuQ==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-compat": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.1.tgz", + "integrity": "sha512-IsFivOjdE1GrjTeKoBU/ZMenESKDXidFDzZzHBPQ/4P20ptGdrl3oLlWrV/QJqJ9lND4IidE3z4Xr5JyfUW1vg==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/component": "0.6.11", + "@firebase/database": "1.0.10", + "@firebase/database-types": "1.0.7", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/database-types": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.7.tgz", + "integrity": "sha512-I7zcLfJXrM0WM+ksFmFdAMdlq/DFmpeMNa+/GNsLyFo5u/lX5zzkPzGe3srVWqaBQBY5KprylDGxOsP6ETfL0A==", + "license": "Apache-2.0", + "dependencies": { + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.10.2" + } + }, + "node_modules/@firebase/logger": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", + "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@firebase/util": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz", + "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@google-cloud/firestore": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.11.0.tgz", + "integrity": "sha512-88uZ+jLsp1aVMj7gh3EKYH1aulTAMFAp8sH/v5a9w8q8iqSG27RiWLoxSAFr/XocZ9hGiWH1kEnBw+zl3xAgNA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@opentelemetry/api": "^1.3.0", + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^4.3.3", + "protobufjs": "^7.2.6" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/paginator": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz", + "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@google-cloud/projectify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz", + "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=14.0.0" + } + }, + "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==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.14.0.tgz", + "integrity": "sha512-H41bPL2cMfSi4EEnFzKvg7XSb7T67ocSXrmF7MPjfgFB0L6CKGzfIYJheAZi1iqXjz6XaCT1OBf6HCG5vDBTOQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@google-cloud/paginator": "^5.0.0", + "@google-cloud/projectify": "^4.0.0", + "@google-cloud/promisify": "^4.0.0", + "abort-controller": "^3.0.0", + "async-retry": "^1.3.3", + "duplexify": "^4.1.3", + "fast-xml-parser": "^4.4.1", + "gaxios": "^6.0.2", + "google-auth-library": "^9.6.3", + "html-entities": "^2.5.2", + "mime": "^3.0.0", + "p-limit": "^3.0.1", + "retry-request": "^7.0.0", + "teeny-request": "^9.0.0", + "uuid": "^8.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@google-cloud/storage/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.12.4.tgz", + "integrity": "sha512-NBhrxEWnFh0FxeA0d//YP95lRFsSx2TNLEUQg4/W+5f/BMxcCjgOOIT24iD+ZB/tZw057j44DaIxja7w4XMrhg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@grpc/proto-loader": "^0.7.13", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", + "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", + "optional": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8.0.0" + } + }, + "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==", + "license": "BSD-3-Clause", + "optional": true + }, + "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==", + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause", + "optional": true + }, + "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==", + "license": "BSD-3-Clause", + "optional": true, + "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==", + "license": "BSD-3-Clause", + "optional": true + }, + "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==", + "license": "BSD-3-Clause", + "optional": true + }, + "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==", + "license": "BSD-3-Clause", + "optional": true + }, + "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==", + "license": "BSD-3-Clause", + "optional": true + }, + "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==", + "license": "BSD-3-Clause", + "optional": true + }, + "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==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/caseless": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", + "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "license": "MIT" + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz", + "integrity": "sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "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==", + "license": "MIT", + "optional": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", + "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/qs": { + "version": "6.9.17", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" + }, + "node_modules/@types/request": { + "version": "2.48.12", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz", + "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "license": "MIT", + "optional": true + }, + "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==", + "license": "MIT", + "optional": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/agent-base": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.2.tgz", + "integrity": "sha512-JVzqkCNRT+VfqzzgPWDPnwvDheSAUdiMUn3NoLXpDJF5lRqeJqyC9iGsAxIOAW+mzIdq+uP1TvcX6bMtrH0agg==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "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==", + "license": "MIT", + "optional": true, + "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==", + "license": "MIT", + "optional": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "license": "MIT", + "optional": true, + "dependencies": { + "retry": "0.13.1" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT", + "optional": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "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==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "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==", + "license": "BSD-3-Clause" + }, + "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==", + "license": "ISC", + "optional": true, + "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==", + "license": "MIT", + "optional": true, + "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==", + "license": "MIT", + "optional": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "optional": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/duplexify": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", + "license": "MIT", + "optional": true, + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.2" + } + }, + "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==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "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==", + "license": "MIT", + "optional": true + }, + "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==", + "license": "MIT", + "optional": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=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==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/farmhash-modern": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/farmhash-modern/-/farmhash-modern-1.1.0.tgz", + "integrity": "sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT", + "optional": true + }, + "node_modules/fast-xml-parser": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", + "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/firebase-admin": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-13.0.1.tgz", + "integrity": "sha512-sKQ/Yw8o/WdC9qTKvuLMBjTbdcBISIXW4+M9PXk0bNjxEbZf1Er7EVq47eRb5+bnKof10xlns6zAIbj4tmSexg==", + "license": "Apache-2.0", + "dependencies": { + "@fastify/busboy": "^3.0.0", + "@firebase/database-compat": "^2.0.0", + "@firebase/database-types": "^1.0.6", + "@types/node": "^22.8.7", + "farmhash-modern": "^1.1.0", + "google-auth-library": "^9.14.2", + "jsonwebtoken": "^9.0.0", + "jwks-rsa": "^3.1.0", + "node-forge": "^1.3.1", + "uuid": "^11.0.2" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@google-cloud/firestore": "^7.10.0", + "@google-cloud/storage": "^7.14.0" + } + }, + "node_modules/firebase-admin/node_modules/@types/node": { + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/firebase-admin/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==", + "license": "MIT" + }, + "node_modules/form-data": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.2.tgz", + "integrity": "sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "license": "MIT", + "optional": true + }, + "node_modules/gaxios": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gaxios/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" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz", + "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==", + "license": "Apache-2.0", + "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==", + "license": "ISC", + "optional": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/google-auth-library": { + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.0.tgz", + "integrity": "sha512-7ccSEJFDFO7exFbO6NRyC+xH8/mZ1GZGG2xxx9iHxZWcjUjJpjWxIMw3cofAKcueZ6DATiukmmprD7yavQHOyQ==", + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^6.1.1", + "gcp-metadata": "^6.1.0", + "gtoken": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.4.1.tgz", + "integrity": "sha512-Phyp9fMfA00J3sZbJxbbB4jC55b7DBjE3F6poyL3wKMEBVKA79q6BGuHcTiM28yOzVql0NDbRL8MLLh8Iwk9Dg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@grpc/grpc-js": "^1.10.9", + "@grpc/proto-loader": "^0.7.13", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "google-auth-library": "^9.3.0", + "node-fetch": "^2.7.0", + "object-hash": "^3.0.0", + "proto3-json-serializer": "^2.0.2", + "protobufjs": "^7.3.2", + "retry-request": "^7.0.0", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/google-gax/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" + ], + "license": "MIT", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/gtoken": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", + "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", + "license": "MIT", + "dependencies": { + "gaxios": "^6.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "optional": true, + "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==", + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC", + "optional": true + }, + "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==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jsonwebtoken/node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jwks-rsa": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz", + "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==", + "license": "MIT", + "dependencies": { + "@types/express": "^4.17.17", + "@types/jsonwebtoken": "^9.0.2", + "debug": "^4.3.4", + "jose": "^4.14.6", + "limiter": "^1.1.5", + "lru-memoizer": "^2.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, + "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==", + "license": "MIT", + "optional": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "license": "MIT" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-memoizer": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", + "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", + "license": "MIT", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "6.0.0" + } + }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "optional": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.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==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "optional": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prettier": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", + "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/proto3-json-serializer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", + "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "protobufjs": "^7.2.5" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/protobufjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "optional": 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/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "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==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/retry-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz", + "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/request": "^2.48.8", + "extend": "^3.0.2", + "teeny-request": "^9.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "license": "MIT", + "optional": true, + "dependencies": { + "stubs": "^3.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "license": "MIT", + "optional": true + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.2.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==", + "license": "MIT", + "optional": true, + "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==", + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "license": "MIT", + "optional": true + }, + "node_modules/stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", + "license": "MIT", + "optional": true + }, + "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==", + "license": "Apache-2.0", + "optional": true, + "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==", + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "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==", + "license": "MIT", + "optional": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "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" + ], + "license": "MIT", + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "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/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT", + "optional": true + }, + "node_modules/uuid": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.3.tgz", + "integrity": "sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "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==", + "license": "BSD-2-Clause" + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "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==", + "license": "MIT", + "optional": true, + "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==", + "license": "ISC", + "optional": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "optional": true, + "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==", + "license": "ISC", + "optional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/node-typescript/push-notification-with-fcm/package.json b/node-typescript/push-notification-with-fcm/package.json new file mode 100644 index 00000000..6f90224e --- /dev/null +++ b/node-typescript/push-notification-with-fcm/package.json @@ -0,0 +1,20 @@ +{ + "name": "starter-template", + "version": "1.0.0", + "description": "", + "main": "dist/main.js", + "type": "module", + "scripts": { + "format": "prettier --write .", + "build": "tsc", + "test": "node test.js" + }, + "dependencies": { + "firebase-admin": "^13.0.1", + "typescript": "^5.4.5" + }, + "devDependencies": { + "@types/node": "^20.12.12", + "prettier": "^3.2.5" + } +} diff --git a/node-typescript/push-notification-with-fcm/src/main.ts b/node-typescript/push-notification-with-fcm/src/main.ts new file mode 100644 index 00000000..a40a24c6 --- /dev/null +++ b/node-typescript/push-notification-with-fcm/src/main.ts @@ -0,0 +1,75 @@ +import { throwIfMissing, sendPushNotification } from './utils.js'; + +interface Request { + body: { + deviceToken: string; + message: { + title: string; + body: string; + }; + data?: Record; + }; + bodyJson: { + deviceToken: string; + message: { + title: string; + body: string; + }; + data?: Record; + }; +} + +interface Response { + json: (body: Record, status?: number) => void; +} + +interface Logger { + (message: string): void; +} + +interface ErrorLogger { + (error: Error): void; +} + +interface Context { + req: Request; + res: Response; + log: Logger; + error: ErrorLogger; +} + +throwIfMissing(process.env, [ + 'FCM_PROJECT_ID', + 'FCM_PRIVATE_KEY', + 'FCM_CLIENT_EMAIL', + 'FCM_DATABASE_URL', +]); + +export default async ({ req, res, log, error }: Context) => { + try { + throwIfMissing(req.bodyJson, ['deviceToken', 'message']); + throwIfMissing(req.bodyJson.message, ['title', 'body']); + } catch (err) { + return res.json({ ok: false, error: (err as Error).message }, 400); + } + + log(`Sending message to device: ${req.bodyJson.deviceToken}`); + + try { + const response = await sendPushNotification({ + notification: { + title: req.bodyJson.message.title, + body: req.bodyJson.message.body, + }, + data: req.bodyJson.data ?? {}, + token: req.bodyJson.deviceToken, + }); + + log(`Successfully sent message: ${response}`); + + return res.json({ ok: true, messageId: response }); + } catch (e) { + error(e as Error); + return res.json({ ok: false, error: 'Failed to send the message' }, 500); + } +}; \ No newline at end of file diff --git a/node-typescript/push-notification-with-fcm/src/utils.ts b/node-typescript/push-notification-with-fcm/src/utils.ts new file mode 100644 index 00000000..509f599e --- /dev/null +++ b/node-typescript/push-notification-with-fcm/src/utils.ts @@ -0,0 +1,49 @@ +import admin from 'firebase-admin'; + +throwIfMissing(process.env, [ + 'FCM_PROJECT_ID', + 'FCM_PRIVATE_KEY', + 'FCM_CLIENT_EMAIL', + 'FCM_DATABASE_URL', +]); + +// initialize firebase app +admin.initializeApp({ + credential: admin.credential.cert({ + projectId: process.env.FCM_PROJECT_ID, + clientEmail: process.env.FCM_CLIENT_EMAIL, + privateKey: process.env.FCM_PRIVATE_KEY, + }), + databaseURL: process.env.FCM_DATABASE_URL, +}); + +/** + * Throws an error if any of the keys are missing from the object + * @param obj - The object to check + * @param keys - The keys to check for + * @throws {Error} + */ +export function throwIfMissing(obj: Record, keys: string[]): void { + const missing: string[] = []; + for (let key of keys) { + if (!(key in obj) || !obj[key]) { + missing.push(key); + } + } + if (missing.length > 0) { + throw new Error(`Missing required fields: ${missing.join(', ')}`); + } +} + +/** + * Sends a push notification + * @param payload - The message payload + * @returns {Promise} + */ +export async function sendPushNotification(payload: admin.messaging.Message): Promise { + try { + return await admin.messaging().send(payload); + } catch (e) { + throw new Error("Error on messaging"); + } +} \ No newline at end of file diff --git a/node-typescript/push-notification-with-fcm/tsconfig.json b/node-typescript/push-notification-with-fcm/tsconfig.json new file mode 100644 index 00000000..8d1b2777 --- /dev/null +++ b/node-typescript/push-notification-with-fcm/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "rootDir": "src", + "resolveJsonModule": true, + "allowJs": true, + "outDir": "dist", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitAny": true, + "skipLibCheck": true + }, + "include": [ + "src/**/*.ts", + "env.d.ts" + ] +} From 471c22fb1d1321b4e33b33b199bdbc186a535844 Mon Sep 17 00:00:00 2001 From: Ijlal Ahmad Date: Sat, 7 Dec 2024 22:06:01 +0530 Subject: [PATCH 2/7] added test script for testing the working of push notification (cherry picked from commit dc73b3979b08897d9d1d12db817bfcaacdace5b7) --- .../push-notification-with-fcm/test.js | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 node-typescript/push-notification-with-fcm/test.js diff --git a/node-typescript/push-notification-with-fcm/test.js b/node-typescript/push-notification-with-fcm/test.js new file mode 100644 index 00000000..aa99e4bb --- /dev/null +++ b/node-typescript/push-notification-with-fcm/test.js @@ -0,0 +1,23 @@ +import main from './src/main.js'; + +main({ + req: { + bodyJson: { + deviceToken: 'deviceToken', + message: { + title: 'title', + body: 'body', + }, + data: { + key: 'value', + }, + }, + }, + res: { + json: (data, status) => { + console.log(data, status); + }, + }, + log: console.log, + error: console.error, +}) \ No newline at end of file From b8202d538847de2ac1627f3778a9df520602492b Mon Sep 17 00:00:00 2001 From: Ijlal Ahmad Date: Sat, 7 Dec 2024 22:07:38 +0530 Subject: [PATCH 3/7] added test script for testing the working of push notification (cherry picked from commit e9a60f10f49f8179cb8a3743e39b8b42ba3c5853) --- node-typescript/push-notification-with-fcm/package.json | 2 +- node-typescript/push-notification-with-fcm/test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/node-typescript/push-notification-with-fcm/package.json b/node-typescript/push-notification-with-fcm/package.json index 6f90224e..6431d489 100644 --- a/node-typescript/push-notification-with-fcm/package.json +++ b/node-typescript/push-notification-with-fcm/package.json @@ -7,7 +7,7 @@ "scripts": { "format": "prettier --write .", "build": "tsc", - "test": "node test.js" + "test": "npm run build && node test.js" }, "dependencies": { "firebase-admin": "^13.0.1", diff --git a/node-typescript/push-notification-with-fcm/test.js b/node-typescript/push-notification-with-fcm/test.js index aa99e4bb..d56df42b 100644 --- a/node-typescript/push-notification-with-fcm/test.js +++ b/node-typescript/push-notification-with-fcm/test.js @@ -1,4 +1,4 @@ -import main from './src/main.js'; +import main from './dist/main.js'; main({ req: { From 254261a9c81cfa7ab7f24b775412941bffef8ab6 Mon Sep 17 00:00:00 2001 From: Ijlal Ahmad Date: Sat, 7 Dec 2024 22:10:55 +0530 Subject: [PATCH 4/7] adjusted global README.md (cherry picked from commit 7a7e75a634c8397b29f6f31326326ddd547982bb) --- README.md | 92 +++++++++++++++++++++++++++---------------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 20ef69e1..944b8366 100644 --- a/README.md +++ b/README.md @@ -10,52 +10,52 @@ Templates for [Appwrite](https://appwrite.io/) Functions. These templates can be # List of Templates -| Template | Node.js | Python | PHP | Node.js (TypeScript) | Bun | Dart | Deno | Ruby | Kotlin | python-ml | C++ | .NET | Java | Swift | -| -------------------------------------- | ----------------------------------------------- | --------------------------------- | ------------------------------ | ------------------------------------------ | ------------------------------ | ------------------------------ | ------------------------------- | ------------------------------- | --------------------------------- | --------------------------------------- | ---------------- | ------------------- | ----------------- | ------------------ | -| Starter | [✅](node/starter) | [✅](python/starter) | [✅](php/starter) | [✅](node-typescript/starter) | [✅](bun/starter) | [✅](dart/starter) | [✅](deno/starter) | [✅](ruby/starter) | [✅](kotlin/starter) | [✅](python-ml/starter) | [✅](cpp/starter) | [✅](dotnet/starter) | [✅](java/starter) | [✅](swift/starter) | -| Sync with Meilisearch | [✅](node/sync-with-meilisearch) | [✅](python/sync_with_meilisearch) | [✅](php/sync-with-meilisearch) | [✅](node-typescript/sync-with-meilisearch) | [✅](bun/sync-with-meilisearch) | 🏗️ | [✅](deno/sync-with-meilisearch) | [✅](ruby/sync_with_meilisearch) | [✅](kotlin/sync-with-meilisearch) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| WhatsApp with Vonage | [✅](node/whatsapp-with-vonage) | [✅](python/whatsapp_with_vonage) | [✅](php/whatsapp-with-vonage) | [✅](node-typescript/whatsapp-with-vonage) | [✅](bun/whatsapp-with-vonage) | [✅](dart/whatsapp_with_vonage) | [✅](deno/whatsapp-with-vonage) | [✅](ruby/whatsapp-with-vonage) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Sync with Qdrant | [✅](node/sync-with-qdrant) | [✅](python/sync_with_qdrant) | 🏗️ | [✅](node-typescript/sync-with-qdrant) | [✅](bun/sync-with-qdrant) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Prompt ChatGPT | [✅](node/prompt-chatgpt) | [✅](python/prompt_chatgpt) | [✅](php/prompt-chatgpt) | 🏗️ | 🏗️ | [✅](dart/prompt_chatgpt) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Censor with Redact | [✅](node/censor-with-redact) | [✅](python/censor_with_redact) | 🏗️ | 🏗️ | 🏗️ | [✅](dart/censor_with_redact) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Email Contact Form | [✅](node/email-contact-form) | [✅](python/email_contact_form) | [✅](php/email-contact-form) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Sync with Algolia | [✅](node/sync-with-algolia) | [✅](python/sync_with_algolia) | [✅](php/sync-with-algolia) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Discord Command Bot | [✅](node/discord-command-bot) | [✅](python/discord_command_bot) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Github Issue Bot | [✅](node/github-issue-bot) | 🏗️ | 🏗️ | [✅](node-typescript/github-issue-bot) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Analyze with PerspectiveAPI | [✅](node/analyze-with-perspectiveapi) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Chat with Anyscale | [✅](node/chat-with-anyscale) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Chat with Perplexity Ai | [✅](node/chat-with-perplexity-ai) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Database Cleaner | [✅](node/database-cleaner) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Generate PDF | [✅](node/generate-pdf) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Generate with Fal.ai | [✅](node/generate-with-fal) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Generate with Replicate | [✅](node/generate-with-replicate) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Generate with Together Ai | [✅](node/generate-with-together-ai) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Image Classification with Hugging Face | [✅](node/image-classification-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Language Translation with Hugging Face | [✅](node/language-translation-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Music Generation with Hugging Face | [✅](node/music-generation-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Object Detection with Hugging Face | [✅](node/object-detection-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Password Expiry | [✅](node/password-expiry) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Payments with Lemon Squeezy | [✅](node/payments-with-lemon-squeezy) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Payments with Stripe | [✅](node/payments-with-stripe) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Push Notification with FCM | [✅](node/push-notification-with-fcm) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Query Mongo Atlas | [✅](node/query-mongo-atlas) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Query Neo4j Auradb | [✅](node/query-neo4j-auradb) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Query Neon Postgres | [✅](node/query-neon-postgres) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Query Redis Labs | [✅](node/query-redis-labs) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Query Upstash Vector | [✅](node/query-upstash-vector) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| RAG with LangChain | [✅](node/rag-with-langchain) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Slack Command Bot | [✅](node/slack-command-bot) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Speak with ElevenLabs | [✅](node/speak-with-elevenlabs) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Speak with Lmnt | [✅](node/speak-with-lmnt) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Speech Recognition with Hugging Face | [✅](node/speech-recognition-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Storage Cleaner | [✅](node/storage-cleaner) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Subscriptions with Lemon Squeezy | [✅](node/subscriptions-with-lemon-squeezy) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Subscriptions with Stripe | [✅](node/subscriptions-with-stripe) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Sync with Pinecone | [✅](node/sync-with-pinecone) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Text Generation with Hugging Face | [✅](node/text-generation-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Text to Speech with Hugging Face | [✅](node/text-to-speech-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| URL Shortener | [✅](node/url-shortener) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Generate with Tensorflow | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | [✅](python-ml/generate_with_tensorflow) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Template | Node.js | Python | PHP | Node.js (TypeScript) | Bun | Dart | Deno | Ruby | Kotlin | python-ml | C++ | .NET | Java | Swift | +| -------------------------------------- | ----------------------------------------------- | --------------------------------- | ------------------------------ |-------------------------------------------------| ------------------------------ | ------------------------------ | ------------------------------- | ------------------------------- | --------------------------------- | --------------------------------------- | ---------------- | ------------------- | ----------------- | ------------------ | +| Starter | [✅](node/starter) | [✅](python/starter) | [✅](php/starter) | [✅](node-typescript/starter) | [✅](bun/starter) | [✅](dart/starter) | [✅](deno/starter) | [✅](ruby/starter) | [✅](kotlin/starter) | [✅](python-ml/starter) | [✅](cpp/starter) | [✅](dotnet/starter) | [✅](java/starter) | [✅](swift/starter) | +| Sync with Meilisearch | [✅](node/sync-with-meilisearch) | [✅](python/sync_with_meilisearch) | [✅](php/sync-with-meilisearch) | [✅](node-typescript/sync-with-meilisearch) | [✅](bun/sync-with-meilisearch) | 🏗️ | [✅](deno/sync-with-meilisearch) | [✅](ruby/sync_with_meilisearch) | [✅](kotlin/sync-with-meilisearch) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| WhatsApp with Vonage | [✅](node/whatsapp-with-vonage) | [✅](python/whatsapp_with_vonage) | [✅](php/whatsapp-with-vonage) | [✅](node-typescript/whatsapp-with-vonage) | [✅](bun/whatsapp-with-vonage) | [✅](dart/whatsapp_with_vonage) | [✅](deno/whatsapp-with-vonage) | [✅](ruby/whatsapp-with-vonage) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Sync with Qdrant | [✅](node/sync-with-qdrant) | [✅](python/sync_with_qdrant) | 🏗️ | [✅](node-typescript/sync-with-qdrant) | [✅](bun/sync-with-qdrant) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Prompt ChatGPT | [✅](node/prompt-chatgpt) | [✅](python/prompt_chatgpt) | [✅](php/prompt-chatgpt) | 🏗️ | 🏗️ | [✅](dart/prompt_chatgpt) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Censor with Redact | [✅](node/censor-with-redact) | [✅](python/censor_with_redact) | 🏗️ | 🏗️ | 🏗️ | [✅](dart/censor_with_redact) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Email Contact Form | [✅](node/email-contact-form) | [✅](python/email_contact_form) | [✅](php/email-contact-form) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Sync with Algolia | [✅](node/sync-with-algolia) | [✅](python/sync_with_algolia) | [✅](php/sync-with-algolia) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Discord Command Bot | [✅](node/discord-command-bot) | [✅](python/discord_command_bot) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Github Issue Bot | [✅](node/github-issue-bot) | 🏗️ | 🏗️ | [✅](node-typescript/github-issue-bot) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Analyze with PerspectiveAPI | [✅](node/analyze-with-perspectiveapi) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Chat with Anyscale | [✅](node/chat-with-anyscale) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Chat with Perplexity Ai | [✅](node/chat-with-perplexity-ai) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Database Cleaner | [✅](node/database-cleaner) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Generate PDF | [✅](node/generate-pdf) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Generate with Fal.ai | [✅](node/generate-with-fal) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Generate with Replicate | [✅](node/generate-with-replicate) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Generate with Together Ai | [✅](node/generate-with-together-ai) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Image Classification with Hugging Face | [✅](node/image-classification-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Language Translation with Hugging Face | [✅](node/language-translation-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Music Generation with Hugging Face | [✅](node/music-generation-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Object Detection with Hugging Face | [✅](node/object-detection-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Password Expiry | [✅](node/password-expiry) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Payments with Lemon Squeezy | [✅](node/payments-with-lemon-squeezy) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Payments with Stripe | [✅](node/payments-with-stripe) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Push Notification with FCM | [✅](node/push-notification-with-fcm) | 🏗️ | 🏗️ | [✅](node-typescript/push-notification-with-fcm) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Query Mongo Atlas | [✅](node/query-mongo-atlas) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Query Neo4j Auradb | [✅](node/query-neo4j-auradb) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Query Neon Postgres | [✅](node/query-neon-postgres) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Query Redis Labs | [✅](node/query-redis-labs) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Query Upstash Vector | [✅](node/query-upstash-vector) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| RAG with LangChain | [✅](node/rag-with-langchain) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Slack Command Bot | [✅](node/slack-command-bot) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Speak with ElevenLabs | [✅](node/speak-with-elevenlabs) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Speak with Lmnt | [✅](node/speak-with-lmnt) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Speech Recognition with Hugging Face | [✅](node/speech-recognition-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Storage Cleaner | [✅](node/storage-cleaner) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Subscriptions with Lemon Squeezy | [✅](node/subscriptions-with-lemon-squeezy) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Subscriptions with Stripe | [✅](node/subscriptions-with-stripe) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Sync with Pinecone | [✅](node/sync-with-pinecone) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Text Generation with Hugging Face | [✅](node/text-generation-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Text to Speech with Hugging Face | [✅](node/text-to-speech-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| URL Shortener | [✅](node/url-shortener) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Generate with Tensorflow | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | [✅](python-ml/generate_with_tensorflow) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | ✅ = Done - Function is implemented in this runtime. From 1f2a7ebb2eaa6f9e1c37c9b522734b4d0d9bacb3 Mon Sep 17 00:00:00 2001 From: Ijlal Ahmad Date: Sat, 7 Dec 2024 22:36:59 +0530 Subject: [PATCH 5/7] formatted changes --- .../push-notification-with-fcm/README.md | 28 +++++++++---------- .../push-notification-with-fcm/src/main.ts | 2 +- .../push-notification-with-fcm/src/utils.ts | 8 ++++-- .../push-notification-with-fcm/test.js | 2 +- .../push-notification-with-fcm/tsconfig.json | 5 +--- 5 files changed, 21 insertions(+), 24 deletions(-) diff --git a/node-typescript/push-notification-with-fcm/README.md b/node-typescript/push-notification-with-fcm/README.md index 7e08a112..17f4b903 100644 --- a/node-typescript/push-notification-with-fcm/README.md +++ b/node-typescript/push-notification-with-fcm/README.md @@ -10,32 +10,30 @@ Send a push notification to a user. **Parameters** -| Name | Description | Location | Type | Sample Value | -| ------------ | ------------------------------------ | -------- | ------------------ | -------------- | -| Content-Type | The content type of the request body | Header | `application/json` | N/A | -| deviceToken | FCM device identifier | Body | String | `642...7cd` | +| Name | Description | Location | Type | Sample Value | +| ------------ | ------------------------------------ | -------- | ------------------ | ------------------------------------------- | +| Content-Type | The content type of the request body | Header | `application/json` | N/A | +| deviceToken | FCM device identifier | Body | String | `642...7cd` | | message | Message to send | Body | Object | `{"title": "hello","body": "how are you?"}` | -| data | Additional data to pass | Body | Object | `{"greet": "welcome"}` | +| data | Additional data to pass | Body | Object | `{"greet": "welcome"}` | **Request** `deviceToken` and `message` are required. `data` is optional. - ```json { - "deviceToken": "642...7cd", - "message": { - "title": "hello", - "body": "how are you?" - }, - "data": { - "greet": "welcome" - } + "deviceToken": "642...7cd", + "message": { + "title": "hello", + "body": "how are you?" + }, + "data": { + "greet": "welcome" + } } ``` - **Response** Sample `200` Response: diff --git a/node-typescript/push-notification-with-fcm/src/main.ts b/node-typescript/push-notification-with-fcm/src/main.ts index a40a24c6..436e33f7 100644 --- a/node-typescript/push-notification-with-fcm/src/main.ts +++ b/node-typescript/push-notification-with-fcm/src/main.ts @@ -72,4 +72,4 @@ export default async ({ req, res, log, error }: Context) => { error(e as Error); return res.json({ ok: false, error: 'Failed to send the message' }, 500); } -}; \ No newline at end of file +}; diff --git a/node-typescript/push-notification-with-fcm/src/utils.ts b/node-typescript/push-notification-with-fcm/src/utils.ts index 509f599e..7e3d139b 100644 --- a/node-typescript/push-notification-with-fcm/src/utils.ts +++ b/node-typescript/push-notification-with-fcm/src/utils.ts @@ -40,10 +40,12 @@ export function throwIfMissing(obj: Record, keys: string[]): void { * @param payload - The message payload * @returns {Promise} */ -export async function sendPushNotification(payload: admin.messaging.Message): Promise { +export async function sendPushNotification( + payload: admin.messaging.Message +): Promise { try { return await admin.messaging().send(payload); } catch (e) { - throw new Error("Error on messaging"); + throw new Error('Error on messaging'); } -} \ No newline at end of file +} diff --git a/node-typescript/push-notification-with-fcm/test.js b/node-typescript/push-notification-with-fcm/test.js index d56df42b..b885f5d3 100644 --- a/node-typescript/push-notification-with-fcm/test.js +++ b/node-typescript/push-notification-with-fcm/test.js @@ -20,4 +20,4 @@ main({ }, log: console.log, error: console.error, -}) \ No newline at end of file +}); diff --git a/node-typescript/push-notification-with-fcm/tsconfig.json b/node-typescript/push-notification-with-fcm/tsconfig.json index 8d1b2777..61242b24 100644 --- a/node-typescript/push-notification-with-fcm/tsconfig.json +++ b/node-typescript/push-notification-with-fcm/tsconfig.json @@ -12,8 +12,5 @@ "noImplicitAny": true, "skipLibCheck": true }, - "include": [ - "src/**/*.ts", - "env.d.ts" - ] + "include": ["src/**/*.ts", "env.d.ts"] } From b0843b857c7675930e9131ca7987936dbe7310fe Mon Sep 17 00:00:00 2001 From: Ijlal Ahmad Date: Sat, 7 Dec 2024 22:55:38 +0530 Subject: [PATCH 6/7] removed FCM_DATABASE_URL as its deprecated from firebase and no longer required in the flow also --- node-typescript/push-notification-with-fcm/README.md | 10 ---------- node-typescript/push-notification-with-fcm/src/main.ts | 1 - .../push-notification-with-fcm/src/utils.ts | 2 -- 3 files changed, 13 deletions(-) diff --git a/node-typescript/push-notification-with-fcm/README.md b/node-typescript/push-notification-with-fcm/README.md index 17f4b903..240fd9e0 100644 --- a/node-typescript/push-notification-with-fcm/README.md +++ b/node-typescript/push-notification-with-fcm/README.md @@ -104,13 +104,3 @@ A unique private key used to authenticate with FCM. | Required | Yes | | Sample Value | `0b6830cc66d92804e11af2153242d34211d675675` | | Documentation | [FCM: SDK Setup](https://firebase.google.com/docs/admin/setup#initialize_the_sdk_in_non-google_environments) | - -### FCM_DATABASE_URL - -URL of your FCM database. - -| Question | Answer | -| ------------- | ------------------------------------------------------------------------------------------------------------ | -| Required | Yes | -| Sample Value | `https://my-app-e398e.firebaseio.com` | -| Documentation | [FCM: SDK Setup](https://firebase.google.com/docs/admin/setup#initialize_the_sdk_in_non-google_environments) | diff --git a/node-typescript/push-notification-with-fcm/src/main.ts b/node-typescript/push-notification-with-fcm/src/main.ts index 436e33f7..966ac753 100644 --- a/node-typescript/push-notification-with-fcm/src/main.ts +++ b/node-typescript/push-notification-with-fcm/src/main.ts @@ -42,7 +42,6 @@ throwIfMissing(process.env, [ 'FCM_PROJECT_ID', 'FCM_PRIVATE_KEY', 'FCM_CLIENT_EMAIL', - 'FCM_DATABASE_URL', ]); export default async ({ req, res, log, error }: Context) => { diff --git a/node-typescript/push-notification-with-fcm/src/utils.ts b/node-typescript/push-notification-with-fcm/src/utils.ts index 7e3d139b..030430ae 100644 --- a/node-typescript/push-notification-with-fcm/src/utils.ts +++ b/node-typescript/push-notification-with-fcm/src/utils.ts @@ -4,7 +4,6 @@ throwIfMissing(process.env, [ 'FCM_PROJECT_ID', 'FCM_PRIVATE_KEY', 'FCM_CLIENT_EMAIL', - 'FCM_DATABASE_URL', ]); // initialize firebase app @@ -14,7 +13,6 @@ admin.initializeApp({ clientEmail: process.env.FCM_CLIENT_EMAIL, privateKey: process.env.FCM_PRIVATE_KEY, }), - databaseURL: process.env.FCM_DATABASE_URL, }); /** From ad614ceb0b0eb26cd937339389de4d87b2cadbd2 Mon Sep 17 00:00:00 2001 From: Ijlal Ahmad Date: Sat, 7 Dec 2024 22:56:05 +0530 Subject: [PATCH 7/7] updated test script to include .env --- node-typescript/push-notification-with-fcm/package.json | 2 +- node-typescript/push-notification-with-fcm/src/utils.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/node-typescript/push-notification-with-fcm/package.json b/node-typescript/push-notification-with-fcm/package.json index 6431d489..04744777 100644 --- a/node-typescript/push-notification-with-fcm/package.json +++ b/node-typescript/push-notification-with-fcm/package.json @@ -7,7 +7,7 @@ "scripts": { "format": "prettier --write .", "build": "tsc", - "test": "npm run build && node test.js" + "test": "npm run build && node --env-file .env test.js" }, "dependencies": { "firebase-admin": "^13.0.1", diff --git a/node-typescript/push-notification-with-fcm/src/utils.ts b/node-typescript/push-notification-with-fcm/src/utils.ts index 030430ae..3039eaa3 100644 --- a/node-typescript/push-notification-with-fcm/src/utils.ts +++ b/node-typescript/push-notification-with-fcm/src/utils.ts @@ -1,4 +1,5 @@ import admin from 'firebase-admin'; +import process from 'process'; throwIfMissing(process.env, [ 'FCM_PROJECT_ID',