diff --git a/.all-contributorsrc b/.all-contributorsrc
index 09effa6a78..546f299ab1 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -1019,6 +1019,42 @@
"contributions": [
"plugin"
]
+ },
+ {
+ "login": "LevwTech",
+ "name": "Abdelrahman Mostafa ",
+ "avatar_url": "https://avatars.githubusercontent.com/u/69399787?v=4",
+ "profile": "https://github.com/LevwTech",
+ "contributions": [
+ "plugin"
+ ]
+ },
+ {
+ "login": "HamzaZagha",
+ "name": "Hamza Zagha",
+ "avatar_url": "https://avatars.githubusercontent.com/u/45468866?v=4",
+ "profile": "https://github.com/HamzaZagha",
+ "contributions": [
+ "bug"
+ ]
+ },
+ {
+ "login": "founderblocks-sils",
+ "name": "Lasse Schuirmann",
+ "avatar_url": "https://avatars.githubusercontent.com/u/88160672?v=4",
+ "profile": "https://founderblocks.io/",
+ "contributions": [
+ "plugin"
+ ]
+ },
+ {
+ "login": "Startouf",
+ "name": "Cyril Duchon-Doris",
+ "avatar_url": "https://avatars.githubusercontent.com/u/7388889?v=4",
+ "profile": "https://about.me/cyril_duchon_doris",
+ "contributions": [
+ "plugin"
+ ]
}
],
"commitType": "docs"
diff --git a/Dockerfile b/Dockerfile
index d7fed2b006..a636143756 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -49,8 +49,8 @@ COPY . .
COPY .npmrc package.json package-lock.json ./
RUN npm ci
-RUN npx nx run-many --target=build --projects=server-api --configuration production --skip-nx-cache
-RUN npx nx run-many --target=build --projects=ui-core --configuration production --skip-nx-cache
+RUN npx nx run-many --target=build --projects=server-api --configuration production
+RUN npx nx run-many --target=build --projects=ui-core --configuration production
# Install backend production dependencies
RUN cd dist/packages/server/api && npm install --production --force
diff --git a/README.md b/README.md
index 8b9e159c81..691c2ee41e 100644
--- a/README.md
+++ b/README.md
@@ -275,6 +275,12 @@ Not into coding but still interested in contributing? Come join our [Discord](ht
![Mohamed Hassan](https://avatars.githubusercontent.com/u/50884619?v=4?s=100) Mohamed Hassan ๐ |
![Christian Schab](https://avatars.githubusercontent.com/u/17610709?v=4?s=100) Christian Schab ๐ |
![Pratik Kinage](https://avatars.githubusercontent.com/u/37847256?v=4?s=100) Pratik Kinage ๐ |
+ ![Abdelrahman Mostafa](https://avatars.githubusercontent.com/u/69399787?v=4?s=100) Abdelrahman Mostafa ๐ |
+
+
+ ![Hamza Zagha](https://avatars.githubusercontent.com/u/45468866?v=4?s=100) Hamza Zagha ๐ |
+ ![Lasse Schuirmann](https://avatars.githubusercontent.com/u/88160672?v=4?s=100) Lasse Schuirmann ๐ |
+ ![Cyril Duchon-Doris](https://avatars.githubusercontent.com/u/7388889?v=4?s=100) Cyril Duchon-Doris ๐ |
diff --git a/docker-compose.yml b/docker-compose.yml
index dfaf607c43..325b914c33 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,7 +1,7 @@
version: '3.0'
services:
activepieces:
- image: ghcr.io/activepieces/activepieces:0.25.1
+ image: ghcr.io/activepieces/activepieces:0.26.0
container_name: activepieces
restart: unless-stopped
## Enable the following line if you already use AP_EXECUTION_MODE with SANDBOXED or old activepieces, checking the breaking change documentation for more info.
diff --git a/docs/about/changelog.mdx b/docs/about/changelog.mdx
index 134b3a417a..344cef5292 100755
--- a/docs/about/changelog.mdx
+++ b/docs/about/changelog.mdx
@@ -14,6 +14,171 @@ Semantic versioning is a standardized way of versioning software projects. It us
Here's the revised text with improved grammar and spelling:
+### 13/05/2024
+
+**โจ Exciting New Features**
+
+* feat: no-code friendly JSON viewer for steps output / input (#4586) @AbdulTheActivePiecer
+* feat: add connections filters (by name and by piece) (#4507) @islamaf
+* feat: increase webhook throughput via queued worker processing (#4543) @abuaboud
+* feat: add listener to zoom on ctrl+mouse wheel (#4534) @islamaf
+* feat: add platform role to user (#4481) @abuaboud
+
+**๐งฉ Pieces**
+
+* fix(notion): new updated trigger (#4670) @abuaboud
+* feat(whatsapp-business): add sendMessage, sendMedia actions (#4639) @LevwTech
+* feat(webhook): introduce production & testing url (#4635) @islamaf
+* feat(openai): Extract Data from Text Action (#4636) @kishanprmr
+* feat(wordpress): Add ACF field option for create/update post actions (#4637) @kishanprmr
+* fix(trello): fix boards dropdown error (#4648) @kishanprmr
+* feat(todoist): update task, find task and mark task completed action (#4641) @kishanprmr
+* fix(github): load more than 100 repo (#4644) @kishanprmr
+* feat(poper): New Lead Trigger (#4642) @thirstycode
+* feat(zerobounce): validate email action (#4626) @abuaboud
+* feat(queue): clear queue action (#4622) @AbdullahBitar
+* feat(queue): pull items / push items into queue (#4620) @AbdullahBitar
+* feat(slack): add reaction to message action (#4618) @kishanprmr
+* feat(google-sheets): Updated Row Trigger Based on User Provided Column (#4604) @kishanprmr
+* fix(webflow): show collection fields in all items actions (#4597) @kishanprmr
+* feat(mailjet): send action (#4606) @christian-schab
+* fix(apitable): Fix Boolean Field Not Updating Issue (#4603) @kishanprmr
+* feat(segment): identify user (#4602) @abuaboud
+* fix(moxie-crm): Fix Test Trigger Payload Issue (#4581) @kishanprmr
+* fix(apitable): fail step on API error (#4577) @kishanprmr
+* feat(google-calendar): Add Attendees to Event Action (#4579) @kishanprmr
+* feat(google-calendar): event color option for create/update event action (#4572) @javix64
+* feat(wordpress): update post action (#4558) @kishanprmr
+* feat(slack): add bot integration steps for channel actions/triggers (#4556) @kishanprmr
+* feat(google-docs): find document action (#4557) @kishanprmr
+* feat(gmail-dev): new email trigger in gmail developer edition piece (#4544) @kishanprmr
+* feat(notion): find database item by property value action (#4546) @kishanprmr
+* fix(store): fix append value action for RUN scope (#4545) @kishanprmr
+* fix(google-sheets): fix missing option for other trigger (#4533) @AdamSelene
+
+**๐ Bug Fixes**
+
+* fix(webhook): distinguish test webhooks to run when flow not published/enabled (#4662) @islamaf
+* fix: flow table pieces icons were being duplicated (#4656) @AbdulTheActivePiecer
+* fix: continue flow on pause (#4651) @islamaf
+* fix: change the step run duration to seconds (#4654) @islamaf
+* fix: show dynamic input toggle for arrays (#4632) @AbdulTheActivePiecer
+* fix: delay step were failing after loop (#4619) @abuaboud
+* fix: github name can be nullable (#4593) @abuaboud
+* fix: list cloud platform template (#4568) @abuaboud
+* fix: list templates (#4567) @abuaboud
+* fix: resolve platform id for managed login (#4566) @abuaboud
+* fix: show data pills inside array inputs, instead of "Custom Code" (#4561) @AbdulTheActivePiecer
+* fix: enhance runs list inside the builder by using better icons and making them clickable (#4560) @AbdulTheActivePiecer
+* fix: allow copying and pasting data pills and undoing/redoing that (#4559) @AbdulTheActivePiecer
+* fix: enhance panning in the builder using laptops touchpads (#4550) @AbdulTheActivePiecer
+
+**๐จ Enhancements & Polish**
+
+* feat(webhook): introduce production & testing url (#4635) @islamaf
+* feat: delete flow on git when deleted on user interface (#4615) @abuaboud
+* chore: add different colors for step output values depending on their types. (#4596) @AbdulTheActivePiecer
+
+**๐ Documentation**
+
+* docs: add HamzaZagha as a contributor for bug (#4672) @allcontributors
+* docs: add LevwTech as a contributor for plugin (#4653) @allcontributors
+* docs: add thirstycode as a contributor for plugin (#4645) @allcontributors
+* docs: add christian-schab as a contributor for plugin (#4608) @allcontributors
+* docs: add MohamedHassan499 as a contributor for bug (#4594) @allcontributors
+* docs: reset password instructions for sqlite3 (#4592) @abuaboud
+* docs: add code snippets (#4589) @abuaboud
+* docs: add javix64 as a contributor for plugin (#4582) @allcontributors
+
+**๐งน Maintenance & Dev Experience**
+
+* chore: security upgrade pdf-text-reader from 4.0.1 to 5.0.0 (#4643) @abuaboud
+* chore(deps): bump pdfjs-dist and pdf-text-reader (#4646) @dependabot
+* chore(deps): bump ejs from 3.1.9 to 3.1.10 (#4607) @dependabot
+* chore(apollo): bump package json (#4609) @abuaboud
+* chore: change table header background color (#4576) @abuaboud
+* refactor: unify cloud database entities with enterprise (#4570) @abuaboud
+* refactor: platform restrictions and login for platform (#4563) @abuaboud
+* refactor: add logging for token expired (#4554) @abuaboud
+* chore: add domain name on request trial + telemetry (#4553) @abuaboud
+
+**Thanks โค๏ธ**
+@AbdulTheActivePiecer, @AbdullahBitar, @AdamSelene, @LevwTech, @abuaboud, @allcontributors, @allcontributors[bot], @christian-schab, @dependabot, @dependabot[bot], @islamaf, @javix64, @kishanprmr, @snyk-bot, @thirstycode and root
+
+
+### 23/04/2024
+
+**โจ Exciting New Features**
+
+* feat(google-sheets): new and updated Row Trigger and Insert Multiple Rows Action (#4483) @kishanprmr
+* feat(admin-console): release notifications & updates history (#4487) @islamaf
+* feat: add report issue to connection dialog for unknown errors (#4465) @abuaboud
+* feat: show updates in admin console (#4467) @islamaf
+
+**๐งฉ Pieces**
+
+* fix(notion): button field causing errors in rendering database properties (#4517) @kishanprmr
+* feat(slack): Improve load sample data, find user by email, create channel and update profile action (#4498) @kishanprmr
+* feat(google-sheets): New/Updated Row Trigger and Insert Multiple Rows Action (#4483) @kishanprmr
+* feat(http): add proxy capabilities to the "send request" action (#4480) @pfernandez98
+* feat(straico): Ask AI and Custom API Call Action (#4489) @dennisrongo
+* feat(google-drive): Move file and set file as public action (#4479) @pfernandez98
+* fix(google-drive): exclude folders from file polling (#4477) @AbdullahBitar
+* feat(todoist): add section_id to create task action (#4456) @rendyt1
+* feat(google-drive): allow new file trigger to include content (#4342) @AbdullahBitar
+* fix(todoist): wrong authorization header for custom API call (#4436) @rendyt1
+* fix(google-sheets): Add row number in response and fix find rows action (#4529) @kishanprmr
+
+**๐ Bug Fixes**
+
+
+* fix: render array of properties (#4530) @AbdulTheActivePiecer
+* fix(embed-sdk): stop opening new window in embedding after duplicating a flow (#4525) @AbdulTheActivePiecer
+* fix: create new folder api (#4508) @abuaboud
+* fix: retry update flow request (#4505) @abuaboud
+* fix: inserting suggestions was always invalid (#4497) @AbdulTheActivePiecer
+* fix(audit-logs): table had issues loading (#4490) @AbdulTheActivePiecer
+* fix: hide unrequired auth for actions (#4491) @AbdulTheActivePiecer
+* fix: triggering saving in read-only mode (#4473) @AbdulTheActivePiecer
+* fix(embed-sdk): add connection iframe only when used (#4469) @AbdulTheActivePiecer
+* fix(embed-sdk): allow copying and pasting inside embedding (#4468) @AbdulTheActivePiecer
+* fix: export template not showing correct json (#4447) @abuaboud
+
+**๐จ Enhancements & Polish**
+
+* chore: improve viewed dates in versions list and icons indicating version status (Draft/Published) (#4526) @AbdulTheActivePiecer
+* feat: reordering items in the array property (#4513) @islamaf
+* feat(embed-sdk): add custom navigation handler (#4485) @AbdulTheActivePiecer
+* feat: new date and time format (#4502) @abuaboud
+* chore: style copy webhook url button and add a better note for testing core webhook trigger (#4501) @AbdulTheActivePiecer
+* feat: add folder name to flow api (#4499) @abuaboud
+* feat: self serve custom domains (#4474) @islamaf
+* fix: change reset zoom icon (#4478) @uniqueeest
+* fix: more typos in the code (#4449) @szepeviktor
+
+**๐ Documentation**
+
+* docs(embed-sdk): add changelog (#4503) @abuaboud
+* docs: improve building pieces section (#4509) @abuaboud
+* docs: add uniqueeest as a contributor for code (#4486) @allcontributors
+* docs: add islamaf as a contributor for bug (#4464) @allcontributors
+* docs: add rendyt1 as a contributor for plugin (#4454) @allcontributors
+* docs: add szepeviktor as a contributor for code (#4452) @allcontributors
+* docs: fix typos & improve embedding documentation (#4448) @abuaboud
+* docs: improve embed docs and document project pieces filter (#4433) @abuaboud
+
+**๐งน Maintenance & Dev Experience**
+
+* refactor: move sandbox files to server-worker (#4514) @abuaboud
+* chore: remove unique email and platform null constraints (#4476) @abuaboud
+* chore: security upgrade ngx-markdown from 16.0.0 to 17.0.0 (#4470) @abuaboud
+* refactor: move all ui ee packages to folder ee/ui (#4466) @abuaboud
+* fix: change pulumi project name in package.json (#4463) @islamaf
+
+**Thanks โค๏ธ**
+@AbdulTheActivePiecer, @AbdullahBitar, @AdamSelene, @abuaboud, @allcontributors, @allcontributors[bot], @dennisrongo, @islamaf, @kishanprmr, @pfernandez98, @rendyt1, @snyk-bot, @szepeviktor, @tintinthedev and @uniqueeest
+
+
### 12/04/2024
diff --git a/package-lock.json b/package-lock.json
index 1778664370..2df8803657 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "activepieces",
- "version": "0.25.1",
+ "version": "0.26.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "activepieces",
- "version": "0.25.1",
+ "version": "0.26.1",
"dependencies": {
"@angular/animations": "17.1.3",
"@angular/cdk": "17.1.2",
@@ -69,7 +69,7 @@
"axios": "1.6.7",
"bcrypt": "5.1.1",
"buffer": "6.0.3",
- "bullmq": "5.3.3",
+ "bullmq": "5.4.2",
"cheerio": "1.0.0-rc.12",
"clarifai-nodejs-grpc": "9.7.0",
"cli-table3": "0.6.3",
@@ -147,7 +147,7 @@
"openai": "4.17.5",
"papaparse": "5.4.1",
"pdf-parse": "1.1.1",
- "pdf-text-reader": "5.0.0",
+ "pdf-text-reader": "4.1.0",
"pg": "8.11.3",
"pickleparser": "0.1.0",
"pino-loki": "2.1.3",
@@ -11544,11 +11544,6 @@
"npm": ">= 8.6.0"
}
},
- "node_modules/@slack/web-api/node_modules/eventemitter3": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
- "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="
- },
"node_modules/@slack/web-api/node_modules/is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -17028,6 +17023,30 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
+ "node_modules/@verdaccio/auth": {
+ "version": "7.0.0-next-7.15",
+ "resolved": "https://registry.npmjs.org/@verdaccio/auth/-/auth-7.0.0-next-7.15.tgz",
+ "integrity": "sha512-BWexr0derpjjJh3fNh59aVen5pssvMTLRMTnBi9vmmn1Ndn6cOjeO6a16EhGixFdeef9YFrDMFRY7t96l4QrPQ==",
+ "dev": true,
+ "dependencies": {
+ "@verdaccio/config": "7.0.0-next-7.15",
+ "@verdaccio/core": "7.0.0-next-7.15",
+ "@verdaccio/loaders": "7.0.0-next-7.15",
+ "@verdaccio/logger": "7.0.0-next-7.15",
+ "@verdaccio/signature": "7.0.0-next-7.5",
+ "@verdaccio/utils": "7.0.0-next-7.15",
+ "debug": "4.3.4",
+ "lodash": "4.17.21",
+ "verdaccio-htpasswd": "12.0.0-next-7.15"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/verdaccio"
+ }
+ },
"node_modules/@verdaccio/commons-api": {
"version": "10.2.0",
"resolved": "https://registry.npmjs.org/@verdaccio/commons-api/-/commons-api-10.2.0.tgz",
@@ -17046,13 +17065,13 @@
}
},
"node_modules/@verdaccio/config": {
- "version": "7.0.0-next-7.13",
- "resolved": "https://registry.npmjs.org/@verdaccio/config/-/config-7.0.0-next-7.13.tgz",
- "integrity": "sha512-QM0uvbLoK8IJMXCr9yYTlR9ZfoO26/sPt0ZGtzEp6yLZ4CZnI4C+eC6KlV/jPTSYf3s8GFAE9ZPvhnQyhX2DoA==",
+ "version": "7.0.0-next-7.15",
+ "resolved": "https://registry.npmjs.org/@verdaccio/config/-/config-7.0.0-next-7.15.tgz",
+ "integrity": "sha512-hXPfDakeyPz2YUo7ORGukKBqOPrNuOpohzWB1GSx6pNDYEepZiRbtpkOTNINiFbFbaXRU42co55PGEsMC3jyPg==",
"dev": true,
"dependencies": {
- "@verdaccio/core": "7.0.0-next-7.13",
- "@verdaccio/utils": "7.0.0-next-7.13",
+ "@verdaccio/core": "7.0.0-next-7.15",
+ "@verdaccio/utils": "7.0.0-next-7.15",
"debug": "4.3.4",
"js-yaml": "4.1.0",
"lodash": "4.17.21",
@@ -17110,9 +17129,9 @@
}
},
"node_modules/@verdaccio/core": {
- "version": "7.0.0-next-7.13",
- "resolved": "https://registry.npmjs.org/@verdaccio/core/-/core-7.0.0-next-7.13.tgz",
- "integrity": "sha512-95cSbuXc3GMaDjlSAEOkDIbN8YaYVq0E4yj/M6oIu4N4XK7DdbuB6k7YAr/TeUJU+2KFPHk3caDEj2a129jNCA==",
+ "version": "7.0.0-next-7.15",
+ "resolved": "https://registry.npmjs.org/@verdaccio/core/-/core-7.0.0-next-7.15.tgz",
+ "integrity": "sha512-BsClg5xGXZi755BvzYBrdOQOUNtyXyyslsnehGesy9ryKSRVSpGDi63/bZNHm10hMOkayPH5JE/tjtARX1AfRA==",
"dev": true,
"dependencies": {
"ajv": "8.12.0",
@@ -17169,6 +17188,24 @@
"url": "https://opencollective.com/verdaccio"
}
},
+ "node_modules/@verdaccio/loaders": {
+ "version": "7.0.0-next-7.15",
+ "resolved": "https://registry.npmjs.org/@verdaccio/loaders/-/loaders-7.0.0-next-7.15.tgz",
+ "integrity": "sha512-X1lgV1DaXkPkEUJzqSZ6ojK4x2TJ+qUkzsyA9s6sBg6MxAe3bCxs9gOytEBA9fPy5f5nTXR63n9+EKaCgOLf2Q==",
+ "dev": true,
+ "dependencies": {
+ "@verdaccio/logger": "7.0.0-next-7.15",
+ "debug": "4.3.4",
+ "lodash": "4.17.21"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/verdaccio"
+ }
+ },
"node_modules/@verdaccio/local-storage-legacy": {
"version": "11.0.2",
"resolved": "https://registry.npmjs.org/@verdaccio/local-storage-legacy/-/local-storage-legacy-11.0.2.tgz",
@@ -17210,13 +17247,30 @@
"node": ">=10"
}
},
+ "node_modules/@verdaccio/logger": {
+ "version": "7.0.0-next-7.15",
+ "resolved": "https://registry.npmjs.org/@verdaccio/logger/-/logger-7.0.0-next-7.15.tgz",
+ "integrity": "sha512-Ch/dMJ5MV/gw18PFhFMZ0GyvRDzRctlL6XhQpP3p2ZFPiXVAqy/lgRZVQCk8UrKxZYgG6UVXGJMKJT827+esdw==",
+ "dev": true,
+ "dependencies": {
+ "@verdaccio/logger-commons": "7.0.0-next-7.15",
+ "pino": "8.17.2"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/verdaccio"
+ }
+ },
"node_modules/@verdaccio/logger-7": {
- "version": "7.0.0-next-7.13",
- "resolved": "https://registry.npmjs.org/@verdaccio/logger-7/-/logger-7-7.0.0-next-7.13.tgz",
- "integrity": "sha512-uiKIC6rSarSdYVdGKSw1JnDC04xCv6kKvqCjVV4GN9QeIaMzMBpPUZRwEEmq7Emc6tm+VPURVtbUy1aLRxWsmQ==",
+ "version": "7.0.0-next-7.15",
+ "resolved": "https://registry.npmjs.org/@verdaccio/logger-7/-/logger-7-7.0.0-next-7.15.tgz",
+ "integrity": "sha512-yC9WNI9TG5L/Q7J5zoVqRSZoZpbSiib5TL6jztufJ7UFsGz/2TU6f2Vny/w/Mmg6fVl4ddUQeaBnTRV0HDyriQ==",
"dev": true,
"dependencies": {
- "@verdaccio/logger-commons": "7.0.0-next-7.13",
+ "@verdaccio/logger-commons": "7.0.0-next-7.15",
"pino": "7.11.0"
},
"engines": {
@@ -17314,12 +17368,12 @@
}
},
"node_modules/@verdaccio/logger-commons": {
- "version": "7.0.0-next-7.13",
- "resolved": "https://registry.npmjs.org/@verdaccio/logger-commons/-/logger-commons-7.0.0-next-7.13.tgz",
- "integrity": "sha512-C45E+e/yMc54hXzRkiUZjl/fXObfcAGE1EMXxZjIqjPUx4gnAWEuTpT1NVRxZbMU6HdpOOKrgijwYkBpo5pgCg==",
+ "version": "7.0.0-next-7.15",
+ "resolved": "https://registry.npmjs.org/@verdaccio/logger-commons/-/logger-commons-7.0.0-next-7.15.tgz",
+ "integrity": "sha512-MeAaU2IMdZSwdO/hrh7aTg1ax3iKlPf6eLVf0JpNYKDxN8OCsi2o5+Q014rGyEG8++Pri3D4DIxMJA7TA+t15g==",
"dev": true,
"dependencies": {
- "@verdaccio/core": "7.0.0-next-7.13",
+ "@verdaccio/core": "7.0.0-next-7.15",
"@verdaccio/logger-prettify": "7.0.0-next-7.2",
"colorette": "2.0.20",
"debug": "4.3.4"
@@ -17358,16 +17412,44 @@
"integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==",
"dev": true
},
+ "node_modules/@verdaccio/logger/node_modules/pino": {
+ "version": "8.17.2",
+ "resolved": "https://registry.npmjs.org/pino/-/pino-8.17.2.tgz",
+ "integrity": "sha512-LA6qKgeDMLr2ux2y/YiUt47EfgQ+S9LznBWOJdN3q1dx2sv0ziDLUBeVpyVv17TEcGCBuWf0zNtg3M5m1NhhWQ==",
+ "dev": true,
+ "dependencies": {
+ "atomic-sleep": "^1.0.0",
+ "fast-redact": "^3.1.1",
+ "on-exit-leak-free": "^2.1.0",
+ "pino-abstract-transport": "v1.1.0",
+ "pino-std-serializers": "^6.0.0",
+ "process-warning": "^3.0.0",
+ "quick-format-unescaped": "^4.0.3",
+ "real-require": "^0.2.0",
+ "safe-stable-stringify": "^2.3.1",
+ "sonic-boom": "^3.7.0",
+ "thread-stream": "^2.0.0"
+ },
+ "bin": {
+ "pino": "bin.js"
+ }
+ },
+ "node_modules/@verdaccio/logger/node_modules/process-warning": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz",
+ "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==",
+ "dev": true
+ },
"node_modules/@verdaccio/middleware": {
- "version": "7.0.0-next-7.13",
- "resolved": "https://registry.npmjs.org/@verdaccio/middleware/-/middleware-7.0.0-next-7.13.tgz",
- "integrity": "sha512-SwStOZeOJ9GFgJEeOhXP3AZpx35HNl66Ru8zKUb0VrOw8mna/4d+/wL+5bAaYfG/k5uO1eOJoTBMQLJkFfQyZA==",
+ "version": "7.0.0-next-7.15",
+ "resolved": "https://registry.npmjs.org/@verdaccio/middleware/-/middleware-7.0.0-next-7.15.tgz",
+ "integrity": "sha512-54VA3/TbHpb7gIaq3RV9nqR6s4FtuKa5gnpwJEwU/SCdZrZiS2r6+doeQQz96xthrFzpBS1rp0IrRCcRcDs/Uw==",
"dev": true,
"dependencies": {
- "@verdaccio/config": "7.0.0-next-7.13",
- "@verdaccio/core": "7.0.0-next-7.13",
- "@verdaccio/url": "12.0.0-next-7.13",
- "@verdaccio/utils": "7.0.0-next-7.13",
+ "@verdaccio/config": "7.0.0-next-7.15",
+ "@verdaccio/core": "7.0.0-next-7.15",
+ "@verdaccio/url": "12.0.0-next-7.15",
+ "@verdaccio/utils": "7.0.0-next-7.15",
"debug": "4.3.4",
"express": "4.18.3",
"express-rate-limit": "5.5.1",
@@ -17546,16 +17628,16 @@
}
},
"node_modules/@verdaccio/signature": {
- "version": "7.0.0-next.3",
- "resolved": "https://registry.npmjs.org/@verdaccio/signature/-/signature-7.0.0-next.3.tgz",
- "integrity": "sha512-egs1VmEe+COUUZ83I6gzDy79Jo3b/AExPvp9EDuJHkmwxJj+9gb231Rv4wk+UoNPrQRNLljUepQwVrDmbqP5DQ==",
+ "version": "7.0.0-next-7.5",
+ "resolved": "https://registry.npmjs.org/@verdaccio/signature/-/signature-7.0.0-next-7.5.tgz",
+ "integrity": "sha512-xF0xGi10HOAQ7Mkwf6dC2fjaBrdxxqXE/HMh/l/O5/LpWoGFZ6xsm/3ZieVRJtIq/qvL5pmmO5Tn8lPS7pm5SQ==",
"dev": true,
"dependencies": {
"debug": "4.3.4",
"jsonwebtoken": "9.0.2"
},
"engines": {
- "node": ">=12"
+ "node": ">=14"
},
"funding": {
"type": "opencollective",
@@ -17620,14 +17702,14 @@
}
},
"node_modules/@verdaccio/tarball": {
- "version": "12.0.0-next-7.13",
- "resolved": "https://registry.npmjs.org/@verdaccio/tarball/-/tarball-12.0.0-next-7.13.tgz",
- "integrity": "sha512-O74anmOdpeUL52LtYRso8UQMKKRqDsnEaTLRACOEQevhyBp/ySs2XwVLPoHymDaXiUQfKUP06HekujdedTpO+A==",
+ "version": "12.0.0-next-7.15",
+ "resolved": "https://registry.npmjs.org/@verdaccio/tarball/-/tarball-12.0.0-next-7.15.tgz",
+ "integrity": "sha512-wjAbLHUxg9FxVmGoW+qvLbv2eWy61MrRkJQWm2+1Zq4JBC6BdKsGZ3AXrpEc+MYi3U1b7Nmi28zXJ9gJ0/HaLQ==",
"dev": true,
"dependencies": {
- "@verdaccio/core": "7.0.0-next-7.13",
- "@verdaccio/url": "12.0.0-next-7.13",
- "@verdaccio/utils": "7.0.0-next-7.13",
+ "@verdaccio/core": "7.0.0-next-7.15",
+ "@verdaccio/url": "12.0.0-next-7.15",
+ "@verdaccio/utils": "7.0.0-next-7.15",
"debug": "4.3.4",
"lodash": "4.17.21"
},
@@ -17640,18 +17722,18 @@
}
},
"node_modules/@verdaccio/ui-theme": {
- "version": "7.0.0-next-7.13",
- "resolved": "https://registry.npmjs.org/@verdaccio/ui-theme/-/ui-theme-7.0.0-next-7.13.tgz",
- "integrity": "sha512-qRIGVahav3y70fIX35iqUxvyzhJ6fQmGZP+b0ODu0zCOn3zFCwS5bkTXuRITIACo26pZIMauw9LTqqsb1GPmLA==",
+ "version": "7.0.0-next-7.15",
+ "resolved": "https://registry.npmjs.org/@verdaccio/ui-theme/-/ui-theme-7.0.0-next-7.15.tgz",
+ "integrity": "sha512-4kQr+OKTe+j1ZNBukBsQ4x1GwkM+3qfVuLk0fdGCjPRL+hf6o6piTgIrXsujcJDzSx+lQL6KEqkrmAUsHhjKag==",
"dev": true
},
"node_modules/@verdaccio/url": {
- "version": "12.0.0-next-7.13",
- "resolved": "https://registry.npmjs.org/@verdaccio/url/-/url-12.0.0-next-7.13.tgz",
- "integrity": "sha512-Ag2sF4Q6DewKJtFIayo21KCgp9azdfsgvgjM8nlQkuWduHYgack5w/paTX5z2hfyFtbXyO648DvBBvmkjcBjbA==",
+ "version": "12.0.0-next-7.15",
+ "resolved": "https://registry.npmjs.org/@verdaccio/url/-/url-12.0.0-next-7.15.tgz",
+ "integrity": "sha512-VyfRKdQv3Urbj8sgUp3xfnm85EHtiTrco1Ve9UbXB0u0SfSpOihUw3TfFzUjLfkyeZE8oBJ8JLZIKmkOm9ZF+w==",
"dev": true,
"dependencies": {
- "@verdaccio/core": "7.0.0-next-7.13",
+ "@verdaccio/core": "7.0.0-next-7.15",
"debug": "4.3.4",
"lodash": "4.17.21",
"validator": "13.11.0"
@@ -17664,13 +17746,22 @@
"url": "https://opencollective.com/verdaccio"
}
},
+ "node_modules/@verdaccio/url/node_modules/validator": {
+ "version": "13.11.0",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz",
+ "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
"node_modules/@verdaccio/utils": {
- "version": "7.0.0-next-7.13",
- "resolved": "https://registry.npmjs.org/@verdaccio/utils/-/utils-7.0.0-next-7.13.tgz",
- "integrity": "sha512-ZtQZjUyxHZHQSjbajncdPLuJt5D0k3r6RQ8Wg0jM5LAoAJM5L+ISC0lcDZI3VRY6mq/LhU6hKfUygBK8o7VQmQ==",
+ "version": "7.0.0-next-7.15",
+ "resolved": "https://registry.npmjs.org/@verdaccio/utils/-/utils-7.0.0-next-7.15.tgz",
+ "integrity": "sha512-J0X/SFiCgty5hSI9ghjj4ZG5nf6+txfVWGzuFjlR3UPP1VvpqTu+oya/45sBwZcC/uvfm1LwKCT6tVbcQYlScg==",
"dev": true,
"dependencies": {
- "@verdaccio/core": "7.0.0-next-7.13",
+ "@verdaccio/core": "7.0.0-next-7.15",
"lodash": "4.17.21",
"minimatch": "7.4.6",
"semver": "7.6.0"
@@ -19614,15 +19705,13 @@
}
},
"node_modules/bullmq": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.3.3.tgz",
- "integrity": "sha512-Gc/68HxiCHLMPBiGIqtINxcf8HER/5wvBYMY/6x3tFejlvldUBFaAErMTLDv4TnPsTyzNPrfBKmFCEM58uVnJg==",
+ "version": "5.4.2",
+ "resolved": "https://registry.npmjs.org/bullmq/-/bullmq-5.4.2.tgz",
+ "integrity": "sha512-dkR/KGUw18miLe3QWtvSlmGvEe08aZF+w1jZyqEHMWFW3RP4162qp6OGud0/QCAOjusiRI8UOxUhbnortPY+rA==",
"dependencies": {
"cron-parser": "^4.6.0",
- "fast-glob": "^3.3.2",
"ioredis": "^5.3.2",
"lodash": "^4.17.21",
- "minimatch": "^9.0.3",
"msgpackr": "^1.10.1",
"node-abort-controller": "^3.1.1",
"semver": "^7.5.4",
@@ -19630,43 +19719,6 @@
"uuid": "^9.0.0"
}
},
- "node_modules/bullmq/node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/bullmq/node_modules/fast-glob": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
- "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.4"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/bullmq/node_modules/minimatch": {
- "version": "9.0.3",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
- "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
- "dependencies": {
- "brace-expansion": "^2.0.1"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@@ -21005,19 +21057,6 @@
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
"integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw=="
},
- "node_modules/cookies": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz",
- "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==",
- "dev": true,
- "dependencies": {
- "depd": "~2.0.0",
- "keygrip": "~1.1.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/copy-anything": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz",
@@ -23354,9 +23393,9 @@
}
},
"node_modules/envinfo": {
- "version": "7.11.1",
- "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz",
- "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==",
+ "version": "7.13.0",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz",
+ "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==",
"dev": true,
"bin": {
"envinfo": "dist/cli.js"
@@ -24227,9 +24266,9 @@
}
},
"node_modules/eventemitter3": {
- "version": "4.0.7",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
- "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
+ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="
},
"node_modules/events": {
"version": "3.3.0",
@@ -26593,6 +26632,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/http-proxy/node_modules/eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+ "dev": true
+ },
"node_modules/http-server": {
"version": "14.1.1",
"resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz",
@@ -29731,18 +29776,6 @@
"node": ">= 12"
}
},
- "node_modules/keygrip": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz",
- "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==",
- "dev": true,
- "dependencies": {
- "tsscmp": "1.0.6"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -30768,12 +30801,6 @@
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true
},
- "node_modules/listr2/node_modules/eventemitter3": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
- "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
- "dev": true
- },
"node_modules/listr2/node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
@@ -34152,6 +34179,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/p-queue/node_modules/eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
+ },
"node_modules/p-retry": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz",
@@ -34473,13 +34505,13 @@
"node": ">=8"
}
},
- "node_modules/path2d": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/path2d/-/path2d-0.2.0.tgz",
- "integrity": "sha512-KdPAykQX6kmLSOO6Jpu2KNcCED7CKjmaBNGGNuctOsG0hgYO1OdYQaan6cYXJiG0WmXOwZZPILPBimu5QAIw3A==",
+ "node_modules/path2d-polyfill": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path2d-polyfill/-/path2d-polyfill-2.0.1.tgz",
+ "integrity": "sha512-ad/3bsalbbWhmBo0D6FZ4RNMwsLsPpL6gnvhuSaU5Vm7b06Kr5ubSltQQ0T7YKsiJQO+g22zJ4dJKNTXIyOXtA==",
"optional": true,
"engines": {
- "node": ">=6"
+ "node": ">=8"
}
},
"node_modules/pause-stream": {
@@ -34512,23 +34544,23 @@
}
},
"node_modules/pdf-text-reader": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/pdf-text-reader/-/pdf-text-reader-5.0.0.tgz",
- "integrity": "sha512-OthaaaSutojBNll4LMiD4oMRP2RoRxA7FQamvBGr9LFoXa2R5E2rwaKXrABddy/O+I7nAR5qrGO/pOjZrMNvog==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/pdf-text-reader/-/pdf-text-reader-4.1.0.tgz",
+ "integrity": "sha512-De2EnUEI+w626PNHMY01Yqdafr6GG5Il8cIplgKsthsc4Uoailq6LNbBhAoFcvLCwzgS/HX/5jajXSL0A0tTcw==",
"dependencies": {
- "pdfjs-dist": "4.2.67"
+ "pdfjs-dist": "3.9.179"
}
},
"node_modules/pdfjs-dist": {
- "version": "4.2.67",
- "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.2.67.tgz",
- "integrity": "sha512-rJmuBDFpD7cqC8WIkQUEClyB4UAH05K4AsyewToMTp2gSy3Rrx8c1ydAVqlJlGv3yZSOrhEERQU/4ScQQFlLHA==",
+ "version": "3.9.179",
+ "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-3.9.179.tgz",
+ "integrity": "sha512-AZBEIAORYDaOAlM0/A4Zg465+XF3ugYDdgrVmioVvNW5tH3xs3RpGFBYOG5PM9/vLM3M/wNncsMLTgyIKdqMKg==",
"engines": {
"node": ">=18"
},
"optionalDependencies": {
"canvas": "^2.11.2",
- "path2d": "^0.2.0"
+ "path2d-polyfill": "^2.0.1"
}
},
"node_modules/peberminta": {
@@ -41363,15 +41395,6 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
- "node_modules/tsscmp": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz",
- "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==",
- "dev": true,
- "engines": {
- "node": ">=0.6.x"
- }
- },
"node_modules/tsutils": {
"version": "3.21.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
@@ -42285,9 +42308,9 @@
}
},
"node_modules/validator": {
- "version": "13.11.0",
- "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz",
- "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==",
+ "version": "13.12.0",
+ "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz",
+ "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==",
"dev": true,
"engines": {
"node": ">= 0.10"
@@ -42310,32 +42333,32 @@
}
},
"node_modules/verdaccio": {
- "version": "5.30.3",
- "resolved": "https://registry.npmjs.org/verdaccio/-/verdaccio-5.30.3.tgz",
- "integrity": "sha512-s/ZhSRBusW2o+ZkERyzEIbVL3zo8QLpTQPVoB/pn/Yv6+ngflP+anK4xCYiXXQJhqEdBz3cwApa8UgOEaNSS4Q==",
+ "version": "5.31.0",
+ "resolved": "https://registry.npmjs.org/verdaccio/-/verdaccio-5.31.0.tgz",
+ "integrity": "sha512-jqBUlvFVArgv5AwtrwUQHDEI9rJHbr8YhA+Wzl56hBZ3Egso9dG9XUiDV+Pbl0yjf7CFghKKuWtQ2Bo6neZXqw==",
"dev": true,
"dependencies": {
"@cypress/request": "3.0.1",
- "@verdaccio/config": "7.0.0-next-7.13",
- "@verdaccio/core": "7.0.0-next-7.13",
+ "@verdaccio/auth": "7.0.0-next-7.15",
+ "@verdaccio/config": "7.0.0-next-7.15",
+ "@verdaccio/core": "7.0.0-next-7.15",
"@verdaccio/local-storage-legacy": "11.0.2",
- "@verdaccio/logger-7": "7.0.0-next-7.13",
- "@verdaccio/middleware": "7.0.0-next-7.13",
+ "@verdaccio/logger-7": "7.0.0-next-7.15",
+ "@verdaccio/middleware": "7.0.0-next-7.15",
"@verdaccio/search-indexer": "7.0.0-next-7.2",
- "@verdaccio/signature": "7.0.0-next.3",
+ "@verdaccio/signature": "7.0.0-next-7.5",
"@verdaccio/streams": "10.2.1",
- "@verdaccio/tarball": "12.0.0-next-7.13",
- "@verdaccio/ui-theme": "7.0.0-next-7.13",
- "@verdaccio/url": "12.0.0-next-7.13",
- "@verdaccio/utils": "7.0.0-next-7.13",
+ "@verdaccio/tarball": "12.0.0-next-7.15",
+ "@verdaccio/ui-theme": "7.0.0-next-7.15",
+ "@verdaccio/url": "12.0.0-next-7.15",
+ "@verdaccio/utils": "7.0.0-next-7.15",
"async": "3.2.5",
"clipanion": "3.2.1",
"compression": "1.7.4",
- "cookies": "0.9.1",
"cors": "2.8.5",
"debug": "^4.3.4",
- "envinfo": "7.11.1",
- "express": "4.18.3",
+ "envinfo": "7.13.0",
+ "express": "4.19.2",
"express-rate-limit": "5.5.1",
"fast-safe-stringify": "2.1.1",
"handlebars": "4.7.8",
@@ -42349,10 +42372,10 @@
"mkdirp": "1.0.4",
"mv": "2.1.1",
"pkginfo": "0.4.1",
- "semver": "7.6.0",
- "validator": "13.11.0",
- "verdaccio-audit": "12.0.0-next-7.13",
- "verdaccio-htpasswd": "12.0.0-next-7.13"
+ "semver": "7.6.2",
+ "validator": "13.12.0",
+ "verdaccio-audit": "12.0.0-next-7.15",
+ "verdaccio-htpasswd": "12.0.0-next-7.15"
},
"bin": {
"verdaccio": "bin/verdaccio"
@@ -42366,13 +42389,13 @@
}
},
"node_modules/verdaccio-audit": {
- "version": "12.0.0-next-7.13",
- "resolved": "https://registry.npmjs.org/verdaccio-audit/-/verdaccio-audit-12.0.0-next-7.13.tgz",
- "integrity": "sha512-vmq0DQjgieEV0oXmNKeQQKLxNSOlWmDP3o4tDSH39o54aDLZLfQ9+xUpZjguJxWvDjZyWmBCpHnJdjAyp2VAiA==",
+ "version": "12.0.0-next-7.15",
+ "resolved": "https://registry.npmjs.org/verdaccio-audit/-/verdaccio-audit-12.0.0-next-7.15.tgz",
+ "integrity": "sha512-ylUxj3VZljYyCpAUFa3THFb29UyHCVv8qgte0LI/20+5EptcZuayHtVP5sd5mnMiMqCO4TUylm30EdXSIvqk4A==",
"dev": true,
"dependencies": {
- "@verdaccio/config": "7.0.0-next-7.13",
- "@verdaccio/core": "7.0.0-next-7.13",
+ "@verdaccio/config": "7.0.0-next-7.15",
+ "@verdaccio/core": "7.0.0-next-7.15",
"express": "4.18.3",
"https-proxy-agent": "5.0.1",
"node-fetch": "cjs"
@@ -42505,12 +42528,12 @@
]
},
"node_modules/verdaccio-htpasswd": {
- "version": "12.0.0-next-7.13",
- "resolved": "https://registry.npmjs.org/verdaccio-htpasswd/-/verdaccio-htpasswd-12.0.0-next-7.13.tgz",
- "integrity": "sha512-1xhKuDYRTPHv1NPeTb83thkApmM1zrvKz9pZk4F6rjlWfkIO1pBslaRXO/Qo6VrvCRSIaw+Qqbci86GCyFaLKg==",
+ "version": "12.0.0-next-7.15",
+ "resolved": "https://registry.npmjs.org/verdaccio-htpasswd/-/verdaccio-htpasswd-12.0.0-next-7.15.tgz",
+ "integrity": "sha512-m8yXFdYi8FQfP9VeZA3Rdecgkn3QWeeMVEV7bA49w0rpC2DBgOfUcKGNMfZZL4C4gv8M3spCZgJH2adKEFbfbw==",
"dev": true,
"dependencies": {
- "@verdaccio/core": "7.0.0-next-7.13",
+ "@verdaccio/core": "7.0.0-next-7.15",
"@verdaccio/file-locking": "12.0.0-next.1",
"apache-md5": "1.1.8",
"bcryptjs": "2.4.3",
@@ -42560,105 +42583,6 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
- "node_modules/verdaccio/node_modules/cookie": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
- "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
- "dev": true,
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/verdaccio/node_modules/express": {
- "version": "4.18.3",
- "resolved": "https://registry.npmjs.org/express/-/express-4.18.3.tgz",
- "integrity": "sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==",
- "dev": true,
- "dependencies": {
- "accepts": "~1.3.8",
- "array-flatten": "1.1.1",
- "body-parser": "1.20.2",
- "content-disposition": "0.5.4",
- "content-type": "~1.0.4",
- "cookie": "0.5.0",
- "cookie-signature": "1.0.6",
- "debug": "2.6.9",
- "depd": "2.0.0",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "etag": "~1.8.1",
- "finalhandler": "1.2.0",
- "fresh": "0.5.2",
- "http-errors": "2.0.0",
- "merge-descriptors": "1.0.1",
- "methods": "~1.1.2",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "path-to-regexp": "0.1.7",
- "proxy-addr": "~2.0.7",
- "qs": "6.11.0",
- "range-parser": "~1.2.1",
- "safe-buffer": "5.2.1",
- "send": "0.18.0",
- "serve-static": "1.15.0",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "type-is": "~1.6.18",
- "utils-merge": "1.0.1",
- "vary": "~1.1.2"
- },
- "engines": {
- "node": ">= 0.10.0"
- }
- },
- "node_modules/verdaccio/node_modules/express/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/verdaccio/node_modules/express/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "dev": true
- },
- "node_modules/verdaccio/node_modules/finalhandler": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
- "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
- "dev": true,
- "dependencies": {
- "debug": "2.6.9",
- "encodeurl": "~1.0.2",
- "escape-html": "~1.0.3",
- "on-finished": "2.4.1",
- "parseurl": "~1.3.3",
- "statuses": "2.0.1",
- "unpipe": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/verdaccio/node_modules/finalhandler/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/verdaccio/node_modules/finalhandler/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "dev": true
- },
"node_modules/verdaccio/node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@@ -42756,21 +42680,6 @@
"node": ">=10"
}
},
- "node_modules/verdaccio/node_modules/qs": {
- "version": "6.11.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
- "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
- "dev": true,
- "dependencies": {
- "side-channel": "^1.0.4"
- },
- "engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/verdaccio/node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -42791,6 +42700,18 @@
}
]
},
+ "node_modules/verdaccio/node_modules/semver": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
diff --git a/package.json b/package.json
index dda3b1bb62..0ff07edfe0 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "activepieces",
- "version": "0.25.1",
- "rcVersion": "0.26.0-rc.3",
+ "version": "0.26.1",
+ "rcVersion": "0.27.0-rc.0",
"scripts": {
"prepare": "husky install",
"serve:frontend": "nx serve ui-core",
@@ -82,7 +82,7 @@
"axios": "1.6.7",
"bcrypt": "5.1.1",
"buffer": "6.0.3",
- "bullmq": "5.3.3",
+ "bullmq": "5.4.2",
"cheerio": "1.0.0-rc.12",
"clarifai-nodejs-grpc": "9.7.0",
"cli-table3": "0.6.3",
@@ -160,7 +160,7 @@
"openai": "4.17.5",
"papaparse": "5.4.1",
"pdf-parse": "1.1.1",
- "pdf-text-reader": "5.0.0",
+ "pdf-text-reader": "4.1.0",
"pg": "8.11.3",
"pickleparser": "0.1.0",
"pino-loki": "2.1.3",
diff --git a/packages/pieces/community/clickup/package.json b/packages/pieces/community/clickup/package.json
index 8b422a21da..42ab8852d1 100644
--- a/packages/pieces/community/clickup/package.json
+++ b/packages/pieces/community/clickup/package.json
@@ -1,4 +1,4 @@
{
"name": "@activepieces/piece-clickup",
- "version": "0.5.11"
+ "version": "0.5.12"
}
\ No newline at end of file
diff --git a/packages/pieces/community/clickup/src/lib/actions/comments/create-task-comment.ts b/packages/pieces/community/clickup/src/lib/actions/comments/create-task-comment.ts
index 7b9eef820c..8c4488c3db 100644
--- a/packages/pieces/community/clickup/src/lib/actions/comments/create-task-comment.ts
+++ b/packages/pieces/community/clickup/src/lib/actions/comments/create-task-comment.ts
@@ -18,19 +18,30 @@ export const createClickupTaskComment = createAction({
displayName: 'Comment',
required: true,
}),
+ assignee_id: clickupCommon.single_assignee_id(
+ false,
+ 'Assignee Id',
+ 'ID of assignee for Task Comment'
+ ),
},
async run(configValue) {
const { task_id, comment } = configValue.propsValue;
- const user_request = await callClickUpApi(
- HttpMethod.GET,
- `/user`,
- getAccessTokenOrThrow(configValue.auth),
- {}
- );
+ let assignee_id = configValue.propsValue.assignee_id;
+
+ if (!assignee_id) {
+ const user_request = await callClickUpApi(
+ HttpMethod.GET,
+ `/user`,
+ getAccessTokenOrThrow(configValue.auth),
+ {}
+ );
+
+ if (user_request.body['user'] === undefined) {
+ throw 'Please connect to your ClickUp account';
+ }
- if (user_request.body['user'] === undefined) {
- throw 'Please connect to your ClickUp account';
+ assignee_id = user_request.body['user']['id'];
}
const response = await callClickUpApi(
@@ -39,7 +50,7 @@ export const createClickupTaskComment = createAction({
getAccessTokenOrThrow(configValue.auth),
{
comment_text: comment,
- assignee: user_request.body['user']['id'],
+ assignee: assignee_id,
notify_all: true,
}
);
diff --git a/packages/pieces/community/clickup/src/lib/common/index.ts b/packages/pieces/community/clickup/src/lib/common/index.ts
index 1313e4533c..e8853f0a9f 100644
--- a/packages/pieces/community/clickup/src/lib/common/index.ts
+++ b/packages/pieces/community/clickup/src/lib/common/index.ts
@@ -45,7 +45,7 @@ export const clickupCommon = {
},
}),
space_id: (required = true, multi = false) => {
- const Dropdown = multi ? Property.MultiSelectDropdown : Property.Dropdown
+ const Dropdown = multi ? Property.MultiSelectDropdown : Property.Dropdown;
return Dropdown({
description: 'The ID of the ClickUp space to create the task in',
displayName: 'Space',
@@ -71,10 +71,10 @@ export const clickupCommon = {
}),
};
},
- })
+ });
},
list_id: (required = true, multi = false) => {
- const Dropdown = multi ? Property.MultiSelectDropdown : Property.Dropdown
+ const Dropdown = multi ? Property.MultiSelectDropdown : Property.Dropdown;
return Dropdown({
description: 'The ID of the ClickUp space to create the task in',
displayName: 'List',
@@ -88,9 +88,12 @@ export const clickupCommon = {
options: [],
};
}
-
+
const accessToken = getAccessTokenOrThrow(auth as OAuth2PropertyValue);
- const lists: {name:string, id:string}[] = await listAllLists(accessToken, space_id as string)
+ const lists: { name: string; id: string }[] = await listAllLists(
+ accessToken,
+ space_id as string
+ );
return {
disabled: false,
@@ -102,9 +105,9 @@ export const clickupCommon = {
}),
};
},
- })
+ });
},
- task_id: (required=true, label:string|undefined = undefined) =>
+ task_id: (required = true, label: string | undefined = undefined) =>
Property.Dropdown({
description: 'The ID of the ClickUp task',
displayName: label ?? 'Task Id',
@@ -134,7 +137,7 @@ export const clickupCommon = {
},
}),
folder_id: (required = false, multi = false) => {
- const Dropdown = multi ? Property.MultiSelectDropdown : Property.Dropdown
+ const Dropdown = multi ? Property.MultiSelectDropdown : Property.Dropdown;
return Dropdown({
description: 'The ID of the ClickUp folder',
displayName: 'Folder Id',
@@ -161,7 +164,7 @@ export const clickupCommon = {
}),
};
},
- })
+ });
},
field_id: (required = false) =>
Property.Dropdown({
@@ -174,13 +177,15 @@ export const clickupCommon = {
if (!auth || !task_id || !list_id) {
return {
disabled: true,
- placeholder:
- 'connect your account first and select a task',
+ placeholder: 'connect your account first and select a task',
options: [],
};
}
const accessToken = getAccessTokenOrThrow(auth as OAuth2PropertyValue);
- const response = await listAccessibleCustomFields(accessToken, list_id as string);
+ const response = await listAccessibleCustomFields(
+ accessToken,
+ list_id as string
+ );
return {
disabled: false,
options: response.fields.map((field) => {
@@ -193,7 +198,7 @@ export const clickupCommon = {
},
}),
status_id: (required = false, multi = false) => {
- const Dropdown = multi ? Property.MultiSelectDropdown : Property.Dropdown
+ const Dropdown = multi ? Property.MultiSelectDropdown : Property.Dropdown;
return Dropdown({
description: 'The ID of Clickup Issue Status',
displayName: 'Status Id',
@@ -226,7 +231,7 @@ export const clickupCommon = {
}),
};
},
- })
+ });
},
priority_id: (required = false) =>
Property.StaticDropdown({
@@ -296,6 +301,47 @@ export const clickupCommon = {
};
},
}),
+ single_assignee_id: (
+ required = false,
+ displayName = 'Assignee Id',
+ description: string
+ ) =>
+ Property.Dropdown({
+ displayName: displayName,
+ description: description,
+ required,
+ refreshers: ['workspace_id'],
+ options: async ({ auth, workspace_id }) => {
+ if (!auth) {
+ return {
+ disabled: true,
+ placeholder: 'conncet your account first',
+ options: [],
+ };
+ }
+ if (!workspace_id) {
+ return {
+ disabled: true,
+ placeholder: 'select workspace',
+ options: [],
+ };
+ }
+ const accessToken = getAccessTokenOrThrow(auth as OAuth2PropertyValue);
+ const response = await listWorkspaceMembers(
+ accessToken,
+ workspace_id as string
+ );
+ return {
+ disabled: false,
+ options: response.map((member) => {
+ return {
+ label: member.user.username,
+ value: member.user.id,
+ };
+ }),
+ };
+ },
+ }),
template_id: (required = false) =>
Property.Dropdown({
displayName: 'Template Id',
@@ -388,10 +434,7 @@ export async function listSpaces(accessToken: string, workspaceId: string) {
}
export async function listAllLists(accessToken: string, spaceId: string) {
- const responseFolders = await listFolders(
- accessToken,
- spaceId as string
- );
+ const responseFolders = await listFolders(accessToken, spaceId as string);
const promises: Promise<{ lists: { id: string; name: string }[] }>[] = [
listFolderlessList(accessToken, spaceId as string),
];
@@ -405,7 +448,7 @@ export async function listAllLists(accessToken: string, spaceId: string) {
lists = [...lists, ...listsResponses[i].lists];
}
- return lists
+ return lists;
}
export async function listLists(accessToken: string, folderId: string) {
@@ -440,22 +483,24 @@ export async function listFolders(accessToken: string, spaceId: string) {
).body;
}
-export async function listAccessibleCustomFields(accessToken: string, listId: string) {
+export async function listAccessibleCustomFields(
+ accessToken: string,
+ listId: string
+) {
return (
await callClickUpApi<{
fields: {
id: string;
name: string;
type: string;
- type_config: Record
+ type_config: Record;
date_created: string;
- hide_from_guests: false
+ hide_from_guests: false;
}[];
}>(HttpMethod.GET, `list/${listId}/field`, accessToken, undefined)
).body;
}
-
async function listFolderlessList(accessToken: string, spaceId: string) {
return (
await callClickUpApi<{
@@ -504,9 +549,9 @@ export async function callClickUpApi(
method: HttpMethod,
apiUrl: string,
accessToken: string,
- body: any|undefined,
- queryParams: any|undefined = undefined,
- headers: any|undefined = undefined
+ body: any | undefined,
+ queryParams: any | undefined = undefined,
+ headers: any | undefined = undefined
): Promise> {
return await httpClient.sendRequest({
method: method,
@@ -517,6 +562,6 @@ export async function callClickUpApi(
},
headers,
body,
- queryParams
- })
+ queryParams,
+ });
}
diff --git a/packages/pieces/community/formbricks/package.json b/packages/pieces/community/formbricks/package.json
index e9859c29e1..68b654247a 100644
--- a/packages/pieces/community/formbricks/package.json
+++ b/packages/pieces/community/formbricks/package.json
@@ -1,4 +1,4 @@
{
"name": "@activepieces/piece-formbricks",
- "version": "0.0.5"
+ "version": "0.1.0"
}
\ No newline at end of file
diff --git a/packages/pieces/community/formbricks/src/index.ts b/packages/pieces/community/formbricks/src/index.ts
index 2c752b3057..7fd33288a4 100644
--- a/packages/pieces/community/formbricks/src/index.ts
+++ b/packages/pieces/community/formbricks/src/index.ts
@@ -1,5 +1,5 @@
import { createCustomApiCallAction } from '@activepieces/pieces-common';
-import { createPiece, PieceAuth } from '@activepieces/pieces-framework';
+import { createPiece, PieceAuth, Property } from '@activepieces/pieces-framework';
import { PieceCategory } from '@activepieces/shared';
import { triggers } from './lib/triggers';
@@ -10,16 +10,41 @@ const markdownPropertyDescription = `
3. Select 'Product Settings'
4. On the left, select 'API Keys'
5. Click on 'Add Production API Key'
- 6. On the popup form, Enter the 'API Key Label' to name the Key
+ 6. On the popup form, enter the 'API Key Label' to name the Key
7. Copy the API key and paste it below.
+
+ **APP URL:**
+ - The API URL for Formbricks example the cloud is at https://app.formbricks.com
+ - **Note: make sure there is no trailing slash and no /api**
`;
-export const formBricksAuth = PieceAuth.SecretText({
- displayName: 'Token',
- description: markdownPropertyDescription,
+export type FormBricksAuthType = {
+ appUrl: string;
+ apiKey: string;
+}
+
+export const formBricksAuth = PieceAuth.CustomAuth({
required: true,
+ description: markdownPropertyDescription,
+ props: {
+ appUrl: Property.ShortText({
+ displayName: 'APP URL',
+ required: true,
+ defaultValue: 'https://app.formbricks.com',
+ }),
+ apiKey: Property.ShortText({
+ displayName: 'API Key',
+ required: true,
+ }),
+ },
+ validate: async () => {
+ return {
+ valid: true
+ }
+ },
});
+
export const formbricks = createPiece({
displayName: 'Formbricks',
description: 'Open source Survey Platform',
@@ -33,10 +58,10 @@ export const formbricks = createPiece({
auth: formBricksAuth,
authMapping(auth) {
return {
- 'x-Api-Key': auth as string,
+ 'x-Api-Key': (auth as FormBricksAuthType).apiKey,
};
},
- baseUrl: () => 'https://api.formbricks.com/v1',
+ baseUrl: (auth) => `${(auth as FormBricksAuthType).appUrl}/api/v1`,
}),
],
triggers,
diff --git a/packages/pieces/community/formbricks/src/lib/triggers/register.ts b/packages/pieces/community/formbricks/src/lib/triggers/register.ts
index 3ea63dd372..e6399d452a 100644
--- a/packages/pieces/community/formbricks/src/lib/triggers/register.ts
+++ b/packages/pieces/community/formbricks/src/lib/triggers/register.ts
@@ -8,7 +8,7 @@ import {
HttpRequest,
HttpMethod,
} from '@activepieces/pieces-common';
-import { formBricksAuth } from '../..';
+import { FormBricksAuthType, formBricksAuth } from '../..';
export const formBricksRegisterTrigger = ({
name,
@@ -46,7 +46,7 @@ export const formBricksRegisterTrigger = ({
const response = await httpClient.sendRequest<{ data: Survey[] }>({
method: HttpMethod.GET,
- url: `https://app.formbricks.com/api/v1/management/surveys`,
+ url: `${(auth as FormBricksAuthType).appUrl}/api/v1/management/surveys`,
headers: {
'x-Api-Key': auth as unknown as string,
},
@@ -77,7 +77,7 @@ export const formBricksRegisterTrigger = ({
async onEnable(context) {
const response = await httpClient.sendRequest({
method: HttpMethod.POST,
- url: `https://app.formbricks.com/api/v1/webhooks`,
+ url: `${context.auth.appUrl}/api/v1/webhooks`,
body: {
url: context.webhookUrl,
triggers: [eventType],
@@ -99,7 +99,7 @@ export const formBricksRegisterTrigger = ({
if (webhook != null) {
const request: HttpRequest = {
method: HttpMethod.DELETE,
- url: `https://app.formbricks.com/api/v1/webhooks/${webhook.webhookId}`,
+ url: `${context.auth.appUrl}/api/v1/webhooks/${webhook.webhookId}`,
headers: {
'x-Api-Key': context.auth as unknown as string,
},
diff --git a/packages/pieces/community/framework/package.json b/packages/pieces/community/framework/package.json
index 5862be4300..33707d9ffc 100644
--- a/packages/pieces/community/framework/package.json
+++ b/packages/pieces/community/framework/package.json
@@ -1,5 +1,5 @@
{
"name": "@activepieces/pieces-framework",
- "version": "0.7.29",
+ "version": "0.7.30",
"type": "commonjs"
}
\ No newline at end of file
diff --git a/packages/pieces/community/framework/src/lib/property/index.ts b/packages/pieces/community/framework/src/lib/property/index.ts
index e36478086f..6d6f1a0e62 100644
--- a/packages/pieces/community/framework/src/lib/property/index.ts
+++ b/packages/pieces/community/framework/src/lib/property/index.ts
@@ -2,12 +2,12 @@ import { InputProperty } from './input';
import { PieceAuthProperty } from './authentication';
import { Type } from '@sinclair/typebox';
-// EXPORTED
+// EXPORTED
export { ApFile } from './input/file-property';
export { DropdownProperty, MultiSelectDropdownProperty } from './input/dropdown/dropdown-prop';
export { DropdownState } from './input/dropdown/common';
-export { DynamicProperties } from './input/dynamic-prop';
+export { DynamicProperties, DynamicProp } from './input/dynamic-prop';
export { PropertyType } from './input/property-type';
export { Property } from './input';
export { PieceAuth } from './authentication';
diff --git a/packages/pieces/community/framework/src/lib/property/input/dynamic-prop.ts b/packages/pieces/community/framework/src/lib/property/input/dynamic-prop.ts
index 95272c356e..e0794146ee 100644
--- a/packages/pieces/community/framework/src/lib/property/input/dynamic-prop.ts
+++ b/packages/pieces/community/framework/src/lib/property/input/dynamic-prop.ts
@@ -6,13 +6,13 @@ import { PropertyContext } from "../../context";
import { ValidationInputType } from "../../validators/types";
import { PropertyType } from "./property-type";
-const DynamicProp = Type.Union([
+export const DynamicProp = Type.Union([
ShortTextProperty,
StaticDropdownProperty,
StaticMultiSelectDropdownProperty,
])
-type DynamicProp =
+export type DynamicProp =
| ShortTextProperty
| StaticDropdownProperty
| StaticMultiSelectDropdownProperty;
diff --git a/packages/pieces/community/framework/src/lib/property/input/text-property.ts b/packages/pieces/community/framework/src/lib/property/input/text-property.ts
index 92ca95c84d..50bf2ef018 100644
--- a/packages/pieces/community/framework/src/lib/property/input/text-property.ts
+++ b/packages/pieces/community/framework/src/lib/property/input/text-property.ts
@@ -20,4 +20,4 @@ export const LongTextProperty = Type.Composite([
])
export type LongTextProperty = BasePropertySchema &
- TPropertyValue;
\ No newline at end of file
+ TPropertyValue;
diff --git a/packages/pieces/community/lever/package.json b/packages/pieces/community/lever/package.json
index 06fb46b668..a481c79369 100644
--- a/packages/pieces/community/lever/package.json
+++ b/packages/pieces/community/lever/package.json
@@ -1,4 +1,4 @@
{
"name": "@activepieces/piece-lever",
- "version": "0.0.1"
+ "version": "0.0.2"
}
diff --git a/packages/pieces/community/lever/src/index.ts b/packages/pieces/community/lever/src/index.ts
index 637397ef71..f3c0da8ab8 100644
--- a/packages/pieces/community/lever/src/index.ts
+++ b/packages/pieces/community/lever/src/index.ts
@@ -3,6 +3,8 @@ import { createCustomApiCallAction } from '@activepieces/pieces-common';
import { getOpportunity } from './lib/actions/get-opportunity';
import { updateOpportunityStage } from './lib/actions/update-opportunity-stage';
import { listOpportunityForms } from './lib/actions/list-opportunity-forms';
+import { listOpportunityFeedback } from './lib/actions/list-opportunity-feedback';
+import { addFeedbackToOpportunity } from './lib/actions/add-feedback-to-opportunity';
export const LEVER_BASE_URL = 'https://api.lever.co/v1';
@@ -29,6 +31,8 @@ export const lever = createPiece({
getOpportunity,
updateOpportunityStage,
listOpportunityForms,
+ listOpportunityFeedback,
+ addFeedbackToOpportunity,
createCustomApiCallAction({
baseUrl: () => {
return LEVER_BASE_URL;
diff --git a/packages/pieces/community/lever/src/lib/actions/add-feedback-to-opportunity.ts b/packages/pieces/community/lever/src/lib/actions/add-feedback-to-opportunity.ts
new file mode 100644
index 0000000000..f56dd3788d
--- /dev/null
+++ b/packages/pieces/community/lever/src/lib/actions/add-feedback-to-opportunity.ts
@@ -0,0 +1,288 @@
+import {
+ createAction,
+ DynamicPropsValue,
+ Property,
+} from '@activepieces/pieces-framework';
+import { LEVER_BASE_URL, LeverAuth, leverAuth } from '../..';
+import {
+ AuthenticationType,
+ httpClient,
+ HttpMethod,
+} from '@activepieces/pieces-common';
+import { LeverFieldMapping } from '../common';
+
+export const addFeedbackToOpportunity = createAction({
+ // auth: check https://www.activepieces.com/docs/developers/piece-reference/authentication,
+ name: 'addFeedbackToOpportunity',
+ displayName: 'Add feedback to opportunity',
+ description: 'Provide feedback to a candidate after an interview',
+ auth: leverAuth,
+ props: {
+ performAs: Property.Dropdown({
+ displayName: 'Feedback author',
+ required: true,
+ refreshers: ['auth'],
+ options: async ({ auth }) => {
+ if (!auth) {
+ return {
+ disabled: true,
+ placeholder: 'Please connect first.',
+ options: [],
+ };
+ }
+
+ const users = [];
+ let cursor = undefined;
+ do {
+ const queryParams: Record = {
+ include: 'name',
+ };
+ if (cursor) {
+ queryParams['offset'] = cursor;
+ }
+
+ const response = await httpClient.sendRequest({
+ method: HttpMethod.GET,
+ url: `${LEVER_BASE_URL}/users`,
+ queryParams: queryParams,
+ authentication: {
+ type: AuthenticationType.BASIC,
+ username: (auth as LeverAuth).apiKey,
+ password: '',
+ },
+ });
+ cursor = response.body.next;
+ const usersPage = response.body.data.map(
+ (user: { id: string; name: string }) => {
+ return {
+ label: user.name,
+ value: user.id,
+ };
+ }
+ );
+ users.push(...usersPage);
+ } while (cursor !== undefined);
+
+ return {
+ options: users,
+ };
+ },
+ }),
+ opportunityId: Property.ShortText({
+ displayName: 'Opportunity ID',
+ required: true,
+ }),
+ panelId: Property.Dropdown({
+ displayName: 'Interview panel',
+ required: false,
+ refreshers: ['auth', 'opportunityId'],
+ options: async ({ auth, opportunityId }) => {
+ if (!auth) {
+ return {
+ disabled: true,
+ placeholder: 'Please connect first.',
+ options: [],
+ };
+ }
+ if (!opportunityId) {
+ return {
+ disabled: true,
+ placeholder: 'Please select a candidate (opportunity).',
+ options: [],
+ };
+ }
+ const response = await httpClient.sendRequest({
+ method: HttpMethod.GET,
+ url: `${LEVER_BASE_URL}/opportunities/${opportunityId}/panels?expand=stage&include=id&include=stage&include=start`,
+ authentication: {
+ type: AuthenticationType.BASIC,
+ username: (auth as LeverAuth).apiKey,
+ password: '',
+ },
+ });
+ return {
+ options: response.body.data.map(
+ (panel: { id: string; start: number; stage: { text: string } }) => {
+ const interviewDate = new Date(panel.start);
+ return {
+ label: `${interviewDate.toLocaleDateString()} - ${
+ panel.stage.text
+ }`,
+ value: panel.id,
+ };
+ }
+ ),
+ };
+ },
+ }),
+ interviewId: Property.Dropdown({
+ displayName: 'Interview',
+ required: false,
+ refreshers: ['auth', 'opportunityId', 'panelId'],
+ options: async ({ auth, opportunityId, panelId }) => {
+ if (!auth) {
+ return {
+ disabled: true,
+ placeholder: 'Please connect first.',
+ options: [],
+ };
+ }
+ if (!opportunityId) {
+ return {
+ disabled: true,
+ placeholder: 'Please select a candidate (opportunity).',
+ options: [],
+ };
+ }
+ if (!panelId) {
+ return {
+ disabled: true,
+ placeholder: 'Please select an interview panel.',
+ options: [],
+ };
+ }
+ const response = await httpClient.sendRequest({
+ method: HttpMethod.GET,
+ url: `${LEVER_BASE_URL}/opportunities/${opportunityId}/panels/${panelId}?include=interviews`,
+ authentication: {
+ type: AuthenticationType.BASIC,
+ username: (auth as LeverAuth).apiKey,
+ password: '',
+ },
+ });
+ return {
+ options: response.body.data.interviews.map(
+ (interview: { id: string; subject: string }) => {
+ return { label: interview.subject, value: interview.id };
+ }
+ ),
+ };
+ },
+ }),
+ feedbackFields: Property.DynamicProperties({
+ displayName: 'Fields',
+ required: true,
+ refreshers: ['auth', 'opportunityId', 'panelId', 'interviewId'],
+ props: async ({ auth, opportunityId, panelId, interviewId }) => {
+ if (!auth || !opportunityId || !panelId || !interviewId) {
+ return {
+ disabled: true,
+ placeholder:
+ 'Please connect your Lever account first and select an interview',
+ options: [],
+ };
+ }
+ const fields: DynamicPropsValue = {};
+ try {
+ const interviewResponse = await httpClient.sendRequest({
+ method: HttpMethod.GET,
+ url: `${LEVER_BASE_URL}/opportunities/${opportunityId}/panels/${panelId}?include=interviews`,
+ authentication: {
+ type: AuthenticationType.BASIC,
+ username: (auth as LeverAuth).apiKey,
+ password: '',
+ },
+ });
+ const interview = interviewResponse.body.data.interviews.find(
+ (interview: { id: string }) =>
+ interview.id === (interviewId as unknown as string)
+ );
+ const feedbackTemplateResponse = await httpClient.sendRequest({
+ method: HttpMethod.GET,
+ url: `${LEVER_BASE_URL}/feedback_templates/${interview.feedbackTemplate}`,
+ authentication: {
+ type: AuthenticationType.BASIC,
+ username: (auth as LeverAuth).apiKey,
+ password: '',
+ },
+ });
+ feedbackTemplateResponse.body.data.fields.map(
+ (field: {
+ id: string;
+ text: string;
+ description: string;
+ required: boolean;
+ type: string;
+ options?: { text: string; optionId: string }[];
+ scores?: { text: string; description: string }[];
+ }) => {
+ const mappedField =
+ LeverFieldMapping[field.type] || LeverFieldMapping['default'];
+ mappedField.buildActivepieceType(fields, field);
+ }
+ );
+ } catch (e) {
+ console.error(
+ 'Unexpected error while building dynamic properties',
+ e
+ );
+ }
+ return fields;
+ },
+ }),
+ },
+ async run({ auth, propsValue }) {
+ const interviewResponse = await httpClient.sendRequest({
+ method: HttpMethod.GET,
+ url: `${LEVER_BASE_URL}/opportunities/${propsValue.opportunityId}/panels/${propsValue.panelId}?include=interviews`,
+ authentication: {
+ type: AuthenticationType.BASIC,
+ username: (auth as LeverAuth).apiKey,
+ password: '',
+ },
+ });
+ const interview = interviewResponse.body.data.interviews.find(
+ (interview: { id: string }) =>
+ interview.id === (propsValue.interviewId as unknown as string)
+ );
+
+ const feedbackTemplateResponse = await httpClient.sendRequest({
+ method: HttpMethod.GET,
+ url: `${LEVER_BASE_URL}/feedback_templates/${interview.feedbackTemplate}`,
+ authentication: {
+ type: AuthenticationType.BASIC,
+ username: (auth as LeverAuth).apiKey,
+ password: '',
+ },
+ });
+
+ const templateFields = feedbackTemplateResponse.body.data.fields;
+ const groupedValues = Object.entries(propsValue.feedbackFields).reduce<
+ Record
+ >((values, [fieldId, fieldValue]: [string, DynamicPropsValue]) => {
+ const canonicalId = fieldId.substring(0, 36);
+ values[canonicalId] = values[canonicalId] ?? [];
+ values[canonicalId].push(fieldValue);
+ return values;
+ }, {});
+
+ const payload = {
+ baseTemplateId: interview.feedbackTemplate,
+ panel: propsValue.panelId,
+ interview: propsValue.interviewId,
+ fieldValues: Object.entries(groupedValues).map(([fieldId, values]) => {
+ const templateField = templateFields.find(
+ (tf: { id: string }) => tf.id === fieldId
+ );
+ const mappedField =
+ templateField.type in LeverFieldMapping
+ ? LeverFieldMapping[templateField.type]
+ : LeverFieldMapping['default'];
+ return mappedField.buildLeverType(fieldId, values);
+ }),
+ };
+
+ const response = await httpClient.sendRequest({
+ method: HttpMethod.POST,
+ url: `${LEVER_BASE_URL}/opportunities/${propsValue.opportunityId}/feedback?perform_as=${propsValue.performAs}`,
+ authentication: {
+ type: AuthenticationType.BASIC,
+ username: auth.apiKey,
+ password: '',
+ },
+ body: payload,
+ });
+
+ return response.body.data;
+ },
+});
diff --git a/packages/pieces/community/lever/src/lib/actions/list-opportunity-feedback.ts b/packages/pieces/community/lever/src/lib/actions/list-opportunity-feedback.ts
new file mode 100644
index 0000000000..e88a7cb308
--- /dev/null
+++ b/packages/pieces/community/lever/src/lib/actions/list-opportunity-feedback.ts
@@ -0,0 +1,70 @@
+import { createAction, Property } from '@activepieces/pieces-framework';
+import { LEVER_BASE_URL, LeverAuth, leverAuth } from '../..';
+import {
+ AuthenticationType,
+ httpClient,
+ HttpMethod,
+} from '@activepieces/pieces-common';
+
+export const listOpportunityFeedback = createAction({
+ name: 'listOpportunityFeedback',
+ displayName: 'List opportunity feedback',
+ description:
+ 'Get all feedback for a given opportunity, optionally for a given template',
+ auth: leverAuth,
+ props: {
+ opportunityId: Property.ShortText({
+ displayName: 'Opportunity ID',
+ required: true,
+ }),
+ template: Property.Dropdown({
+ displayName: 'Feedback template',
+ required: false,
+ refreshers: ['auth'],
+ options: async ({ auth }) => {
+ if (!auth) {
+ return {
+ disabled: true,
+ placeholder: 'Please connect first.',
+ options: [],
+ };
+ }
+ const response = await httpClient.sendRequest({
+ method: HttpMethod.GET,
+ url: `${LEVER_BASE_URL}/feedback_templates?include=text`,
+ authentication: {
+ type: AuthenticationType.BASIC,
+ username: (auth as LeverAuth).apiKey,
+ password: '',
+ },
+ });
+ return {
+ options: response.body.data.map(
+ (template: { text: string; id: string }) => {
+ return { label: template.text, value: template.id };
+ }
+ ),
+ };
+ },
+ }),
+ },
+ async run({ auth, propsValue }) {
+ const response = await httpClient.sendRequest({
+ method: HttpMethod.GET,
+ url: `${LEVER_BASE_URL}/opportunities/${propsValue.opportunityId}/feedback`,
+ authentication: {
+ type: AuthenticationType.BASIC,
+ username: auth.apiKey,
+ password: '',
+ },
+ });
+ const feedback = response.body.data;
+ if (propsValue.template) {
+ return feedback.filter(
+ (form: { baseTemplateId: string }) =>
+ form.baseTemplateId === propsValue.template
+ );
+ }
+ return feedback;
+ },
+});
diff --git a/packages/pieces/community/lever/src/lib/actions/update-opportunity-stage.ts b/packages/pieces/community/lever/src/lib/actions/update-opportunity-stage.ts
index 19037e029a..9bb1ba8ede 100644
--- a/packages/pieces/community/lever/src/lib/actions/update-opportunity-stage.ts
+++ b/packages/pieces/community/lever/src/lib/actions/update-opportunity-stage.ts
@@ -58,6 +58,7 @@ export const updateOpportunityStage = createAction({
},
body: { stage: propsValue.stage },
});
+
return response.body.data;
},
});
diff --git a/packages/pieces/community/lever/src/lib/common.ts b/packages/pieces/community/lever/src/lib/common.ts
new file mode 100644
index 0000000000..7bf4d7d4a2
--- /dev/null
+++ b/packages/pieces/community/lever/src/lib/common.ts
@@ -0,0 +1,135 @@
+import { DynamicPropsValue, Property } from '@activepieces/pieces-framework';
+
+export type LeverFieldType = {
+ id: string;
+ text: string;
+ description: string;
+ required: boolean;
+ type: string;
+ options?: { text: string; optionId: string }[];
+ scores?: { text: string; description: string }[];
+};
+
+export const LeverFieldMapping: Record<
+ string,
+ {
+ buildActivepieceType: (
+ fields: DynamicPropsValue,
+ field: LeverFieldType
+ ) => void;
+ buildLeverType: (
+ id: string,
+ propsValues: DynamicPropsValue[]
+ ) => {
+ id: string;
+ value:
+ | string
+ | string[]
+ | number
+ | number[]
+ | { score: number; comment?: string }[];
+ };
+ }
+> = {
+ default: {
+ buildActivepieceType: (fields, field) =>
+ (fields[field.id] = Property.ShortText({
+ displayName: field.text,
+ description: field.description,
+ required: field.required,
+ })),
+ buildLeverType: (id, propsValues) => ({
+ id,
+ value: propsValues[0] as unknown as string,
+ }),
+ },
+ textarea: {
+ buildActivepieceType: (fields, field) =>
+ (fields[field.id] = Property.LongText({
+ displayName: field.text,
+ description: field.description,
+ required: field.required,
+ })),
+ buildLeverType: (id, propsValues) => ({
+ id,
+ value: propsValues[0] as unknown as string,
+ }),
+ },
+ 'text-no': {
+ buildActivepieceType: (fields, field) =>
+ (fields[field.id] = Property.Checkbox({
+ displayName: field.text,
+ description: field.description,
+ required: field.required,
+ })),
+ buildLeverType: (id, propsValues) => ({
+ id,
+ value: propsValues[0] as unknown as string,
+ }),
+ },
+ 'multiple-select': {
+ buildActivepieceType: (fields, field) =>
+ (fields[field.id] = Property.StaticMultiSelectDropdown({
+ displayName: field.text,
+ description: field.description,
+ required: field.required,
+ options: {
+ disabled: false,
+ options:
+ field.options?.map((option: { text: string; optionId: string }) => {
+ return { value: option.text, label: option.text };
+ }) || [],
+ },
+ })),
+ buildLeverType: (id, propsValues) => ({
+ id,
+ value: propsValues[0] as unknown as string,
+ }),
+ },
+ 'score-system': {
+ buildActivepieceType: (fields, field) =>
+ (fields[field.id] = Property.StaticDropdown({
+ displayName: field.text,
+ description: field.description,
+ required: field.required,
+ options: {
+ options:
+ field.options?.map((option) => {
+ return { value: option.text, label: option.text };
+ }) || [],
+ },
+ })),
+ buildLeverType: (id, propsValues) => ({
+ id,
+ value: propsValues[0] as unknown as string,
+ }),
+ },
+ scorecard: {
+ buildActivepieceType: (fields, field) =>
+ field.scores?.map((score, index) => {
+ fields[`${field.id}-${index}`] = Property.StaticDropdown({
+ displayName: score.text,
+ description: score.description,
+ required: field.required,
+ options: {
+ options: [
+ { label: 'n.a.', value: 0 },
+ { label: '๐๐', value: 1 },
+ { label: '๐', value: 2 },
+ { label: '๐', value: 3 },
+ { label: '๐๐', value: 4 },
+ ],
+ },
+ });
+ }),
+ buildLeverType: (id, propsValues) => ({
+ id,
+ value: propsValues.map((propsValue: DynamicPropsValue) => {
+ return {
+ score: propsValue as unknown as number,
+ comment: '',
+ };
+ }),
+ }),
+ },
+};
diff --git a/packages/pieces/community/notion/package.json b/packages/pieces/community/notion/package.json
index a55daadcf0..0fcf17e575 100644
--- a/packages/pieces/community/notion/package.json
+++ b/packages/pieces/community/notion/package.json
@@ -1,4 +1,4 @@
{
"name": "@activepieces/piece-notion",
- "version": "0.2.12"
+ "version": "0.2.13"
}
\ No newline at end of file
diff --git a/packages/pieces/community/notion/src/lib/triggers/updated-database-item.ts b/packages/pieces/community/notion/src/lib/triggers/updated-database-item.ts
index ba86360b3b..72fff717f3 100644
--- a/packages/pieces/community/notion/src/lib/triggers/updated-database-item.ts
+++ b/packages/pieces/community/notion/src/lib/triggers/updated-database-item.ts
@@ -128,9 +128,9 @@ const polling: Polling<
lastFetchEpochMS === 0 ? null : dayjs(lastFetchEpochMS).toISOString()
);
return items.results.map((item) => {
- const object = item as { created_time: string };
+ const object = item as { last_edited_time: string };
return {
- epochMilliSeconds: dayjs(object.created_time).valueOf(),
+ epochMilliSeconds: dayjs(object.last_edited_time).valueOf(),
data: item,
};
});
diff --git a/packages/pieces/community/openai/package.json b/packages/pieces/community/openai/package.json
index b956d5a1f9..f4068e4900 100644
--- a/packages/pieces/community/openai/package.json
+++ b/packages/pieces/community/openai/package.json
@@ -1,4 +1,4 @@
{
"name": "@activepieces/piece-openai",
- "version": "0.3.23"
+ "version": "0.3.24"
}
\ No newline at end of file
diff --git a/packages/pieces/community/openai/src/lib/actions/extract-structure-data.action.ts b/packages/pieces/community/openai/src/lib/actions/extract-structure-data.action.ts
index eddd8d59e0..4539d103f9 100644
--- a/packages/pieces/community/openai/src/lib/actions/extract-structure-data.action.ts
+++ b/packages/pieces/community/openai/src/lib/actions/extract-structure-data.action.ts
@@ -51,26 +51,20 @@ export const extractStructuredDataAction = createAction({
displayName: 'Unstructured Text',
required: true,
}),
- prompt: Property.LongText({
- displayName: 'Prompt',
- description:
- 'Provide a brief description of what sort of data you want extracted from the unstructured text.',
- required: true,
- }),
params: Property.Array({
- displayName: 'Structured Data Definition',
+ displayName: 'Data Definition',
required: true,
properties: {
propName: Property.ShortText({
displayName: 'Name',
description:
- 'Provide the name of the values you want to extract from the unstructured text. Name should be unique and short. ',
+ 'Provide the name of the value you want to extract from the unstructured text. The name should be unique and short. ',
required: true,
}),
propDescription: Property.LongText({
displayName: 'Description',
description:
- 'Brief description of the parameter, defining what data will be extracted to this parameter.',
+ 'Brief description of the data, this hints for the AI on what to look for',
required: false,
}),
propDataType: Property.StaticDropdown({
@@ -88,29 +82,28 @@ export const extractStructuredDataAction = createAction({
},
}),
propIsRequired: Property.Checkbox({
- displayName: 'Is Property Required?',
- description: 'If the property must be present, the action will fail if it is not found.',
+ displayName: 'Fail if Not present?',
required: true,
- defaultValue: true,
+ defaultValue: false,
}),
},
}),
},
async run(context) {
- const { model, text, prompt } = context.propsValue;
+ const { model, text } = context.propsValue;
const paramInputArray = context.propsValue.params as ParamInput[];
const functionParams: Record = {};
const requiredFunctionParams: string[] = [];
for (const param of paramInputArray) {
functionParams[param.propName] = {
type: param.propDataType,
- description: param.propDescription,
+ description: param.propDescription ?? param.propName,
};
if (param.propIsRequired) {
requiredFunctionParams.push(param.propName);
}
}
-
+ const prompt = 'Extract the following data from the provided text'
const openai = new OpenAI({
apiKey: context.auth,
});
@@ -138,8 +131,8 @@ export const extractStructuredDataAction = createAction({
if (toolCallsResponse) {
return JSON.parse(toolCallsResponse[0].function.arguments);
} else {
- throw Error(JSON.stringify({
- message: 'Unable to extract data. Please provide valid params and text.'
+ throw new Error(JSON.stringify({
+ message: "OpenAI couldn't extract the fields from the above text."
}));
}
},
diff --git a/packages/pieces/community/pdf/package.json b/packages/pieces/community/pdf/package.json
index 6c38c0d693..a6f0e7b593 100644
--- a/packages/pieces/community/pdf/package.json
+++ b/packages/pieces/community/pdf/package.json
@@ -3,7 +3,7 @@
"version": "0.0.1",
"dependencies": {
"@activepieces/pieces-framework": "*",
- "pdf-text-reader": "4.0.1",
+ "pdf-text-reader": "4.1.0",
"tslib": "2.6.2"
},
"main": "./src/index.js",
diff --git a/packages/pieces/community/taskade/.eslintrc.json b/packages/pieces/community/taskade/.eslintrc.json
new file mode 100644
index 0000000000..4a4e695c54
--- /dev/null
+++ b/packages/pieces/community/taskade/.eslintrc.json
@@ -0,0 +1,33 @@
+{
+ "extends": [
+ "../../../../.eslintrc.base.json"
+ ],
+ "ignorePatterns": [
+ "!**/*"
+ ],
+ "overrides": [
+ {
+ "files": [
+ "*.ts",
+ "*.tsx",
+ "*.js",
+ "*.jsx"
+ ],
+ "rules": {}
+ },
+ {
+ "files": [
+ "*.ts",
+ "*.tsx"
+ ],
+ "rules": {}
+ },
+ {
+ "files": [
+ "*.js",
+ "*.jsx"
+ ],
+ "rules": {}
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/pieces/community/taskade/README.md b/packages/pieces/community/taskade/README.md
new file mode 100644
index 0000000000..32ad3fcc9f
--- /dev/null
+++ b/packages/pieces/community/taskade/README.md
@@ -0,0 +1,7 @@
+# pieces-taskade
+
+This library was generated with [Nx](https://nx.dev).
+
+## Building
+
+Run `nx build pieces-taskade` to build the library.
diff --git a/packages/pieces/community/taskade/package.json b/packages/pieces/community/taskade/package.json
new file mode 100644
index 0000000000..f865af36f7
--- /dev/null
+++ b/packages/pieces/community/taskade/package.json
@@ -0,0 +1,4 @@
+{
+ "name": "@activepieces/piece-taskade",
+ "version": "0.0.1"
+}
diff --git a/packages/pieces/community/taskade/project.json b/packages/pieces/community/taskade/project.json
new file mode 100644
index 0000000000..f33717b16d
--- /dev/null
+++ b/packages/pieces/community/taskade/project.json
@@ -0,0 +1,38 @@
+{
+ "name": "pieces-taskade",
+ "$schema": "../../../../node_modules/nx/schemas/project-schema.json",
+ "sourceRoot": "packages/pieces/community/taskade/src",
+ "projectType": "library",
+ "targets": {
+ "build": {
+ "executor": "@nx/js:tsc",
+ "outputs": [
+ "{options.outputPath}"
+ ],
+ "options": {
+ "outputPath": "dist/packages/pieces/community/taskade",
+ "tsConfig": "packages/pieces/community/taskade/tsconfig.lib.json",
+ "packageJson": "packages/pieces/community/taskade/package.json",
+ "main": "packages/pieces/community/taskade/src/index.ts",
+ "assets": [
+ "packages/pieces/community/taskade/*.md"
+ ],
+ "buildableProjectDepsInPackageJsonType": "dependencies",
+ "updateBuildableProjectDepsInPackageJson": true
+ }
+ },
+ "publish": {
+ "command": "node tools/scripts/publish.mjs pieces-taskade {args.ver} {args.tag}",
+ "dependsOn": [
+ "build"
+ ]
+ },
+ "lint": {
+ "executor": "@nx/eslint:lint",
+ "outputs": [
+ "{options.outputFile}"
+ ]
+ }
+ },
+ "tags": []
+}
\ No newline at end of file
diff --git a/packages/pieces/community/taskade/src/index.ts b/packages/pieces/community/taskade/src/index.ts
new file mode 100644
index 0000000000..32b2796930
--- /dev/null
+++ b/packages/pieces/community/taskade/src/index.ts
@@ -0,0 +1,35 @@
+import { createPiece, PieceAuth } from '@activepieces/pieces-framework';
+import { createTaskAction } from './lib/actions/create-task.action';
+import { PieceCategory } from '@activepieces/shared';
+import { completeTaskAction } from './lib/actions/complete-task.action';
+import { deleteTaskAction } from './lib/actions/delete-task.action';
+import { createCustomApiCallAction } from '@activepieces/pieces-common';
+
+export const taskadeAuth = PieceAuth.SecretText({
+ displayName: 'Personal Token',
+ required: true,
+ description: `
+ 1. Navigate to https://taskade.com/settings/password and scroll down to Personal Access Tokens.
+ 2. Create your personal access token with any name.`,
+});
+
+export const taskade = createPiece({
+ displayName: 'Taskade',
+ auth: taskadeAuth,
+ minimumSupportedRelease: '0.20.0',
+ categories: [PieceCategory.PRODUCTIVITY],
+ description: 'collaboration platform for remote teams to organize and manage projects',
+ logoUrl: 'https://cdn.activepieces.com/pieces/taskade.png',
+ authors: ['kishanprmr'],
+ actions: [
+ createTaskAction,
+ completeTaskAction,
+ deleteTaskAction,
+ createCustomApiCallAction({
+ baseUrl: () => 'https://www.taskade.com/api/v1',
+ auth: taskadeAuth,
+ authMapping: (auth) => ({ Authorization: `Bearer ${auth as string}` }),
+ }),
+ ],
+ triggers: [],
+});
diff --git a/packages/pieces/community/taskade/src/lib/actions/complete-task.action.ts b/packages/pieces/community/taskade/src/lib/actions/complete-task.action.ts
new file mode 100644
index 0000000000..e7155cd3ae
--- /dev/null
+++ b/packages/pieces/community/taskade/src/lib/actions/complete-task.action.ts
@@ -0,0 +1,24 @@
+import { taskadeAuth } from '../../';
+import { createAction } from '@activepieces/pieces-framework';
+import { taskadeProps } from '../common/props';
+import { TaskadeAPIClient } from '../common/client';
+
+export const completeTaskAction = createAction({
+ auth: taskadeAuth,
+ name: 'taskade-complete-task',
+ displayName: 'Complete Task',
+ description: 'Complete a task in a project.',
+ props: {
+ workspace_id: taskadeProps.workspace_id,
+ folder_id: taskadeProps.folder_id,
+ project_id: taskadeProps.project_id,
+ task_id: taskadeProps.task_id,
+ },
+ async run(context) {
+ const { project_id, task_id } = context.propsValue;
+
+ const client = new TaskadeAPIClient(context.auth);
+
+ return await client.completeTask(project_id, task_id);
+ },
+});
diff --git a/packages/pieces/community/taskade/src/lib/actions/create-task.action.ts b/packages/pieces/community/taskade/src/lib/actions/create-task.action.ts
new file mode 100644
index 0000000000..6f9fe53b46
--- /dev/null
+++ b/packages/pieces/community/taskade/src/lib/actions/create-task.action.ts
@@ -0,0 +1,68 @@
+import { taskadeAuth } from '../../';
+import { createAction, Property } from '@activepieces/pieces-framework';
+import { taskadeProps } from '../common/props';
+import { TaskadeAPIClient } from '../common/client';
+
+export const createTaskAction = createAction({
+ auth: taskadeAuth,
+ name: 'taskade-create-task',
+ displayName: 'Create Task',
+ description: 'Creates a new task.',
+ props: {
+ workspace_id: taskadeProps.workspace_id,
+ folder_id: taskadeProps.folder_id,
+ project_id: taskadeProps.project_id,
+ content_type: Property.StaticDropdown({
+ displayName: 'Content Type',
+ required: true,
+ defaultValue: 'text/markdown',
+ options: {
+ disabled: false,
+ options: [
+ {
+ label: 'text/markdown',
+ value: 'text/markdown',
+ },
+ {
+ label: 'text/plain',
+ value: 'text/plain',
+ },
+ ],
+ },
+ }),
+ content: Property.LongText({
+ displayName: 'Task Content',
+ required: true,
+ }),
+ placement: Property.StaticDropdown({
+ displayName: 'Placement',
+ description: 'Placement of task in block',
+ required: true,
+ defaultValue: 'afterbegin',
+ options: {
+ disabled: false,
+ options: [
+ {
+ label: 'afterbegin',
+ value: 'afterbegin',
+ },
+ {
+ label: 'beforeend',
+ value: 'beforeend',
+ },
+ ],
+ },
+ }),
+ },
+ async run(context) {
+ const { project_id, content_type, content, placement } = context.propsValue;
+
+ const client = new TaskadeAPIClient(context.auth);
+
+ return await client.createTask(project_id, {
+ content,
+ contentType: content_type,
+ placement,
+ });
+ },
+});
diff --git a/packages/pieces/community/taskade/src/lib/actions/delete-task.action.ts b/packages/pieces/community/taskade/src/lib/actions/delete-task.action.ts
new file mode 100644
index 0000000000..82361f79bb
--- /dev/null
+++ b/packages/pieces/community/taskade/src/lib/actions/delete-task.action.ts
@@ -0,0 +1,24 @@
+import { taskadeAuth } from '../../';
+import { createAction } from '@activepieces/pieces-framework';
+import { taskadeProps } from '../common/props';
+import { TaskadeAPIClient } from '../common/client';
+
+export const deleteTaskAction = createAction({
+ auth: taskadeAuth,
+ name: 'taskade-delete-task',
+ displayName: 'Delete Task',
+ description: 'Delete an existing task in a project.',
+ props: {
+ workspace_id: taskadeProps.workspace_id,
+ folder_id: taskadeProps.folder_id,
+ project_id: taskadeProps.project_id,
+ task_id: taskadeProps.task_id,
+ },
+ async run(context) {
+ const { project_id, task_id } = context.propsValue;
+
+ const client = new TaskadeAPIClient(context.auth);
+
+ return await client.deleteTask(project_id, task_id);
+ },
+});
diff --git a/packages/pieces/community/taskade/src/lib/common/client.ts b/packages/pieces/community/taskade/src/lib/common/client.ts
new file mode 100644
index 0000000000..9cdeff7b62
--- /dev/null
+++ b/packages/pieces/community/taskade/src/lib/common/client.ts
@@ -0,0 +1,105 @@
+import {
+ HttpMessageBody,
+ HttpMethod,
+ QueryParams,
+ httpClient,
+ HttpRequest,
+ AuthenticationType,
+} from '@activepieces/pieces-common';
+import {
+ CreateTaskDateParams,
+ CreateTaskParams,
+ ListAPIResponse,
+ ProjectResponse,
+ CreateTaskResponse,
+ WorkspaceFolderResponse,
+ WorkspaceResponse,
+ TaskResponse,
+} from './types';
+
+type RequestParams = Record;
+
+export class TaskadeAPIClient {
+ constructor(private personalToken: string) {}
+
+ async makeRequest(
+ method: HttpMethod,
+ resourceUri: string,
+ query?: RequestParams,
+ body: any | undefined = undefined,
+ ): Promise {
+ const baseUrl = 'https://www.taskade.com/api/v1';
+ const qs: QueryParams = {};
+
+ if (query) {
+ for (const [key, value] of Object.entries(query)) {
+ if (value !== null && value !== undefined) {
+ qs[key] = String(value);
+ }
+ }
+ }
+
+ const request: HttpRequest = {
+ method,
+ url: baseUrl + resourceUri,
+ authentication: {
+ type: AuthenticationType.BEARER_TOKEN,
+ token: this.personalToken,
+ },
+ queryParams: qs,
+ body,
+ };
+
+ const response = await httpClient.sendRequest(request);
+ return response.body;
+ }
+
+ async listWorkspaces(): Promise> {
+ return await this.makeRequest(HttpMethod.GET, '/workspaces');
+ }
+
+ async listWorkspaceFolders(
+ workspace_id: string,
+ ): Promise> {
+ return await this.makeRequest(HttpMethod.GET, `/workspaces/${workspace_id}/folders`);
+ }
+
+ async listProjects(folder_id: string): Promise> {
+ return await this.makeRequest(HttpMethod.GET, `/folders/${folder_id}/projects`);
+ }
+
+ async createTask(projectId: string, params: CreateTaskParams): Promise {
+ return await this.makeRequest(HttpMethod.POST, `/projects/${projectId}/tasks`, undefined, {
+ tasks: [params],
+ });
+ }
+
+ async createTaskDate(projectId: string, taskId: string, params: CreateTaskDateParams) {
+ return await this.makeRequest(
+ HttpMethod.PUT,
+ `/projects/${projectId}/tasks/${taskId}/date`,
+ undefined,
+ params,
+ );
+ }
+
+ async listTasks(
+ projectId: string,
+ params: RequestParams,
+ ): Promise> {
+ return await this.makeRequest(HttpMethod.GET, `/projects/${projectId}/tasks`, params);
+ }
+
+ async completeTask(projectId: string, taskId: string) {
+ return await this.makeRequest(
+ HttpMethod.POST,
+ `/projects/${projectId}/tasks/${taskId}/complete`,
+ undefined,
+ {},
+ );
+ }
+
+ async deleteTask(projectId: string, taskId: string) {
+ return await this.makeRequest(HttpMethod.DELETE, `/projects/${projectId}/tasks/${taskId}`);
+ }
+}
diff --git a/packages/pieces/community/taskade/src/lib/common/props.ts b/packages/pieces/community/taskade/src/lib/common/props.ts
new file mode 100644
index 0000000000..25bb75d09f
--- /dev/null
+++ b/packages/pieces/community/taskade/src/lib/common/props.ts
@@ -0,0 +1,128 @@
+import { DropdownOption, Property } from '@activepieces/pieces-framework';
+import { TaskadeAPIClient } from './client';
+
+const createEmptyOptions = (placeholder: string) => {
+ return {
+ disabled: true,
+ options: [],
+ placeholder,
+ };
+};
+
+export const taskadeProps = {
+ workspace_id: Property.Dropdown({
+ displayName: 'Workspace',
+ refreshers: [],
+ required: true,
+ options: async ({ auth }) => {
+ if (!auth) {
+ return createEmptyOptions('Please connect account first.');
+ }
+
+ const client = new TaskadeAPIClient(auth as string);
+ const response = await client.listWorkspaces();
+
+ const options: DropdownOption[] = [];
+
+ for (const workspace of response.items) {
+ options.push({ label: workspace.name, value: workspace.id });
+ }
+
+ return {
+ disabled: false,
+ options,
+ };
+ },
+ }),
+ folder_id: Property.Dropdown({
+ displayName: 'Folder',
+ refreshers: ['workspace_id'],
+ required: false,
+ options: async ({ auth, workspace_id }) => {
+ if (!auth) {
+ return createEmptyOptions('Please connect account first.');
+ }
+ if (!workspace_id) {
+ return createEmptyOptions('Please select workspace.');
+ }
+
+ const client = new TaskadeAPIClient(auth as string);
+ const response = await client.listWorkspaceFolders(workspace_id as string);
+
+ const options: DropdownOption[] = [];
+
+ for (const folder of response.items) {
+ options.push({ label: folder.name, value: folder.id });
+ }
+
+ return {
+ disabled: false,
+ options,
+ };
+ },
+ }),
+ project_id: Property.Dropdown({
+ displayName: 'Project',
+ refreshers: ['workspace_id', 'folder_id'],
+ required: true,
+ options: async ({ auth, workspace_id, folder_id }) => {
+ if (!auth) {
+ return createEmptyOptions('Please connect account first.');
+ }
+ if (!workspace_id) {
+ return createEmptyOptions('Please select workspace.');
+ }
+
+ const workspaceId = workspace_id as string;
+ const folderId = (folder_id as string) ?? workspaceId;
+
+ const client = new TaskadeAPIClient(auth as string);
+ const response = await client.listProjects(folderId as string);
+
+ const options: DropdownOption[] = [];
+
+ for (const project of response.items) {
+ options.push({ label: project.name, value: project.id });
+ }
+
+ return {
+ disabled: false,
+ options,
+ };
+ },
+ }),
+ task_id: Property.Dropdown({
+ displayName: 'Task',
+ refreshers: ['project_id'],
+ required: true,
+ options: async ({ auth, project_id }) => {
+ if (!auth) {
+ return createEmptyOptions('Please connect account first.');
+ }
+ if (!project_id) {
+ return createEmptyOptions('Please select project.');
+ }
+
+ const client = new TaskadeAPIClient(auth as string);
+ const options: DropdownOption[] = [];
+
+ let after;
+ let moreTasks = true;
+ while (moreTasks) {
+ const response = await client.listTasks(project_id as string, { limit: 100, after });
+ if (response.items.length === 0) {
+ moreTasks = false;
+ } else {
+ after = response.items[response.items.length - 1].id;
+ for (const task of response.items) {
+ options.push({ label: task.text, value: task.id });
+ }
+ }
+ }
+ return {
+ disabled: false,
+ options,
+ };
+ },
+ }),
+};
diff --git a/packages/pieces/community/taskade/src/lib/common/types.ts b/packages/pieces/community/taskade/src/lib/common/types.ts
new file mode 100644
index 0000000000..23463504a0
--- /dev/null
+++ b/packages/pieces/community/taskade/src/lib/common/types.ts
@@ -0,0 +1,42 @@
+export interface ListAPIResponse {
+ ok: boolean;
+ items: Array;
+}
+
+export interface BaseResponse {
+ id: string;
+ name: string;
+}
+
+export type WorkspaceResponse = BaseResponse;
+export type WorkspaceFolderResponse = BaseResponse;
+export type ProjectResponse = BaseResponse;
+
+export interface CreateTaskParams {
+ contentType: string;
+ content: string;
+ placement: string;
+}
+
+export interface TaskResponse {
+ id: string;
+ parentId: string;
+ text: string;
+ completed: boolean;
+}
+
+export interface CreateTaskResponse {
+ ok: boolean;
+ item: TaskResponse[];
+}
+
+export interface CreateTaskDateParams {
+ start: {
+ date: string;
+ time: string;
+ };
+ end?: {
+ date: string;
+ time: string;
+ };
+}
diff --git a/packages/pieces/community/taskade/tsconfig.json b/packages/pieces/community/taskade/tsconfig.json
new file mode 100644
index 0000000000..059cd81661
--- /dev/null
+++ b/packages/pieces/community/taskade/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "extends": "../../../../tsconfig.base.json",
+ "compilerOptions": {
+ "module": "commonjs",
+ "forceConsistentCasingInFileNames": true,
+ "strict": true,
+ "noImplicitOverride": true,
+ "noPropertyAccessFromIndexSignature": true,
+ "noImplicitReturns": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "files": [],
+ "include": [],
+ "references": [
+ {
+ "path": "./tsconfig.lib.json"
+ }
+ ]
+}
diff --git a/packages/pieces/community/taskade/tsconfig.lib.json b/packages/pieces/community/taskade/tsconfig.lib.json
new file mode 100644
index 0000000000..28369ef762
--- /dev/null
+++ b/packages/pieces/community/taskade/tsconfig.lib.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "module": "commonjs",
+ "outDir": "../../../../dist/out-tsc",
+ "declaration": true,
+ "types": ["node"]
+ },
+ "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
+ "include": ["src/**/*.ts"]
+}
diff --git a/packages/pieces/community/webhook/package.json b/packages/pieces/community/webhook/package.json
index 2cb8dfae35..63f73a93d1 100644
--- a/packages/pieces/community/webhook/package.json
+++ b/packages/pieces/community/webhook/package.json
@@ -1,4 +1,4 @@
{
"name": "@activepieces/piece-webhook",
- "version": "0.1.2"
-}
\ No newline at end of file
+ "version": "0.1.3"
+}
diff --git a/packages/pieces/community/webhook/src/index.ts b/packages/pieces/community/webhook/src/index.ts
index cfc6e926d7..3a62c1952a 100644
--- a/packages/pieces/community/webhook/src/index.ts
+++ b/packages/pieces/community/webhook/src/index.ts
@@ -7,7 +7,7 @@ export const webhook = createPiece({
description: 'Receive HTTP requests and trigger flows using unique URLs.',
auth: PieceAuth.None(),
categories: [PieceCategory.CORE],
- minimumSupportedRelease: '0.22.0',
+ minimumSupportedRelease: '0.26.0',
logoUrl: 'https://cdn.activepieces.com/pieces/webhook.svg',
authors: ['abuaboud', 'pfernandez98'],
actions: [],
diff --git a/packages/pieces/community/webhook/src/lib/triggers/catch-hook.ts b/packages/pieces/community/webhook/src/lib/triggers/catch-hook.ts
index 4c413d1a38..a4a4128d0c 100644
--- a/packages/pieces/community/webhook/src/lib/triggers/catch-hook.ts
+++ b/packages/pieces/community/webhook/src/lib/triggers/catch-hook.ts
@@ -7,17 +7,21 @@ import {
import { assertNotNullOrUndefined } from '@activepieces/shared';
const message = `
-URL:
+**Production URL:**
\`\`\`text
{{webhookUrl}}
\`\`\`
-If you are expecting a reply from this webhook, append **/sync** to the URL.
-
-In that case, you will also have to add an HTTP step with **return response** at the end of your flow.
+**Testing URL:**
+\`\`\`text
+{{webhookUrl}}/test
+\`\`\`
+***Use this URL for testing the webhook and saving sample data. It won't start the flow***.
-If the flow takes more than **30 seconds**, it will give a **408 Request Timeout** response.
+**Notes:**
+- If you are expecting a reply from this webhook, append **/sync** to the URL in that case, you will also have to add an HTTP step with **return response** at the end of your flow.
+- If the flow takes more than **30 seconds**, it will give a **408 Request Timeout** response.
`;
enum AuthType {
diff --git a/packages/pieces/community/whatsapp/.eslintrc.json b/packages/pieces/community/whatsapp/.eslintrc.json
new file mode 100644
index 0000000000..4a4e695c54
--- /dev/null
+++ b/packages/pieces/community/whatsapp/.eslintrc.json
@@ -0,0 +1,33 @@
+{
+ "extends": [
+ "../../../../.eslintrc.base.json"
+ ],
+ "ignorePatterns": [
+ "!**/*"
+ ],
+ "overrides": [
+ {
+ "files": [
+ "*.ts",
+ "*.tsx",
+ "*.js",
+ "*.jsx"
+ ],
+ "rules": {}
+ },
+ {
+ "files": [
+ "*.ts",
+ "*.tsx"
+ ],
+ "rules": {}
+ },
+ {
+ "files": [
+ "*.js",
+ "*.jsx"
+ ],
+ "rules": {}
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/pieces/community/whatsapp/README.md b/packages/pieces/community/whatsapp/README.md
new file mode 100644
index 0000000000..85a4a45abf
--- /dev/null
+++ b/packages/pieces/community/whatsapp/README.md
@@ -0,0 +1,7 @@
+# pieces-whatsapp
+
+This library was generated with [Nx](https://nx.dev).
+
+## Building
+
+Run `nx build pieces-whatsapp` to build the library.
diff --git a/packages/pieces/community/whatsapp/package.json b/packages/pieces/community/whatsapp/package.json
new file mode 100644
index 0000000000..7ddc589990
--- /dev/null
+++ b/packages/pieces/community/whatsapp/package.json
@@ -0,0 +1,4 @@
+{
+ "name": "@activepieces/piece-whatsapp",
+ "version": "0.0.1"
+}
diff --git a/packages/pieces/community/whatsapp/project.json b/packages/pieces/community/whatsapp/project.json
new file mode 100644
index 0000000000..adad8436e1
--- /dev/null
+++ b/packages/pieces/community/whatsapp/project.json
@@ -0,0 +1,38 @@
+{
+ "name": "pieces-whatsapp",
+ "$schema": "../../../../node_modules/nx/schemas/project-schema.json",
+ "sourceRoot": "packages/pieces/community/whatsapp/src",
+ "projectType": "library",
+ "targets": {
+ "build": {
+ "executor": "@nx/js:tsc",
+ "outputs": [
+ "{options.outputPath}"
+ ],
+ "options": {
+ "outputPath": "dist/packages/pieces/community/whatsapp",
+ "tsConfig": "packages/pieces/community/whatsapp/tsconfig.lib.json",
+ "packageJson": "packages/pieces/community/whatsapp/package.json",
+ "main": "packages/pieces/community/whatsapp/src/index.ts",
+ "assets": [
+ "packages/pieces/community/whatsapp/*.md"
+ ],
+ "buildableProjectDepsInPackageJsonType": "dependencies",
+ "updateBuildableProjectDepsInPackageJson": true
+ }
+ },
+ "publish": {
+ "command": "node tools/scripts/publish.mjs pieces-whatsapp {args.ver} {args.tag}",
+ "dependsOn": [
+ "build"
+ ]
+ },
+ "lint": {
+ "executor": "@nx/eslint:lint",
+ "outputs": [
+ "{options.outputFile}"
+ ]
+ }
+ },
+ "tags": []
+}
\ No newline at end of file
diff --git a/packages/pieces/community/whatsapp/src/index.ts b/packages/pieces/community/whatsapp/src/index.ts
new file mode 100644
index 0000000000..a856dea7e3
--- /dev/null
+++ b/packages/pieces/community/whatsapp/src/index.ts
@@ -0,0 +1,47 @@
+
+import { createPiece, PieceAuth, Property } from "@activepieces/pieces-framework";
+import { sendMessage } from "./lib/actions/send-message";
+import { sendMedia } from "./lib/actions/send-media";
+
+const markdown = `
+To Obtain a Phone Number ID and a Permanent System User Access Token, follow these steps:
+
+1. Go to https://developers.facebook.com/
+2. Make a new app, Select Other for usecase.
+3. Choose Business as the type of app.
+4. Add new Product -> WhatsApp.
+5. Navigate to WhatsApp Settings > API Setup.
+6. Select a phone number and copy its Phone number ID.
+7. Login to your [Meta Business Manager](https://business.facebook.com/).
+8. Click on Settings.
+9. Create a new System User with access over the app and copy the access token.
+`;
+
+export const whatsappAuth = PieceAuth.CustomAuth({
+ required: true,
+ description: markdown,
+ props: {
+ access_token: PieceAuth.SecretText({
+ displayName: 'System User Access Token',
+ description: 'The system user access token of your WhatsApp business account',
+ required: true,
+ }),
+ phoneNumberId: Property.ShortText({
+ displayName: 'Phone Number ID',
+ description: 'The phone number ID of your WhatsApp business account',
+ required: true,
+ }),
+ },
+});
+
+
+export const whatsapp = createPiece({
+ displayName: "WhatsApp Business",
+ description: 'Manage your WhatsApp business account',
+ auth: whatsappAuth,
+ minimumSupportedRelease: '0.20.0',
+ logoUrl: "https://cdn.activepieces.com/pieces/whatsapp.png",
+ authors: ["LevwTech"],
+ actions: [sendMessage, sendMedia],
+ triggers: [],
+});
diff --git a/packages/pieces/community/whatsapp/src/lib/actions/send-media.ts b/packages/pieces/community/whatsapp/src/lib/actions/send-media.ts
new file mode 100644
index 0000000000..a200ccfacf
--- /dev/null
+++ b/packages/pieces/community/whatsapp/src/lib/actions/send-media.ts
@@ -0,0 +1,70 @@
+import { createAction, Property } from '@activepieces/pieces-framework';
+import { httpClient, HttpMethod } from '@activepieces/pieces-common';
+import { whatsappAuth } from '../..';
+import { supportedMediaTypes, capitalizeFirstLetter, mediaTypeSupportsCaption } from '../common/utils';
+
+export const sendMedia = createAction({
+ auth: whatsappAuth,
+ name: 'sendMedia',
+ displayName: 'Send Media',
+ description: 'Send a media message through WhatsApp',
+ props: {
+ to: Property.ShortText({
+ displayName: 'To',
+ description: 'The recipient of the message',
+ required: true,
+ }),
+ type: Property.Dropdown({
+ displayName: 'Type',
+ description: 'The type of media to send',
+ required: true,
+ options: async () => {
+ return {
+ options: supportedMediaTypes.map((type) => ({
+ label: capitalizeFirstLetter(type),
+ value: type,
+ })),
+ };
+ },
+ refreshers: []
+ }),
+ media: Property.ShortText({
+ displayName: 'Media URL',
+ description: 'The URL of the media to send',
+ required: true,
+ }),
+ caption: Property.LongText({
+ displayName: 'Caption',
+ description: 'A caption for the media',
+ required: false,
+ }),
+ filename: Property.LongText({
+ displayName: 'Filename',
+ description: 'Filename of the document to send',
+ required: false,
+ }),
+ },
+ async run(context) {
+ const { to, caption, media, type, filename } = context.propsValue;
+ const { access_token, phoneNumberId } = context.auth;
+ const body = {
+ messaging_product: "whatsapp",
+ recipient_type: "individual",
+ to,
+ type,
+ [type]: {
+ link: media,
+ }
+ }
+ if (caption && mediaTypeSupportsCaption(type)) (body[type] as any).caption = caption;
+ if (filename && type === 'document') (body[type] as any).filename = filename;
+ return await httpClient.sendRequest({
+ method: HttpMethod.POST,
+ url: `https://graph.facebook.com/v17.0/${phoneNumberId}/messages`,
+ headers: {
+ Authorization: 'Bearer ' + access_token,
+ },
+ body,
+ });
+ },
+});
\ No newline at end of file
diff --git a/packages/pieces/community/whatsapp/src/lib/actions/send-message.ts b/packages/pieces/community/whatsapp/src/lib/actions/send-message.ts
new file mode 100644
index 0000000000..2aba8ac46a
--- /dev/null
+++ b/packages/pieces/community/whatsapp/src/lib/actions/send-message.ts
@@ -0,0 +1,43 @@
+import { createAction, Property } from '@activepieces/pieces-framework';
+import { httpClient, HttpMethod } from '@activepieces/pieces-common';
+import { whatsappAuth } from '../..';
+
+
+export const sendMessage = createAction({
+ auth: whatsappAuth,
+ name: 'sendMessage',
+ displayName: 'Send Message',
+ description: 'Send a text message through WhatsApp',
+ props: {
+ to: Property.ShortText({
+ displayName: 'To',
+ description: 'The recipient of the message',
+ required: true,
+ }),
+ text: Property.LongText({
+ displayName: 'Message',
+ description: 'The message to send',
+ required: true,
+ }),
+ },
+ async run(context) {
+ const { to, text } = context.propsValue;
+ const { access_token, phoneNumberId } = context.auth;
+ return await httpClient.sendRequest({
+ method: HttpMethod.POST,
+ url: `https://graph.facebook.com/v17.0/${phoneNumberId}/messages`,
+ headers: {
+ Authorization: 'Bearer ' + access_token,
+ },
+ body: {
+ messaging_product: "whatsapp",
+ recipient_type: "individual",
+ to,
+ type: "text",
+ text: {
+ body: text
+ }
+ }
+ });
+ },
+});
diff --git a/packages/pieces/community/whatsapp/src/lib/common/utils.ts b/packages/pieces/community/whatsapp/src/lib/common/utils.ts
new file mode 100644
index 0000000000..1e327b8d8a
--- /dev/null
+++ b/packages/pieces/community/whatsapp/src/lib/common/utils.ts
@@ -0,0 +1,3 @@
+export const supportedMediaTypes = ['image', 'audio', 'document', 'sticker', 'video'];
+export const capitalizeFirstLetter = (word: string) => word.charAt(0).toUpperCase() + word.slice(1);
+export const mediaTypeSupportsCaption = (type: string) => ['image', 'video', 'document'].includes(type);
\ No newline at end of file
diff --git a/packages/pieces/community/whatsapp/tsconfig.json b/packages/pieces/community/whatsapp/tsconfig.json
new file mode 100644
index 0000000000..059cd81661
--- /dev/null
+++ b/packages/pieces/community/whatsapp/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "extends": "../../../../tsconfig.base.json",
+ "compilerOptions": {
+ "module": "commonjs",
+ "forceConsistentCasingInFileNames": true,
+ "strict": true,
+ "noImplicitOverride": true,
+ "noPropertyAccessFromIndexSignature": true,
+ "noImplicitReturns": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "files": [],
+ "include": [],
+ "references": [
+ {
+ "path": "./tsconfig.lib.json"
+ }
+ ]
+}
diff --git a/packages/pieces/community/whatsapp/tsconfig.lib.json b/packages/pieces/community/whatsapp/tsconfig.lib.json
new file mode 100644
index 0000000000..0fe2205530
--- /dev/null
+++ b/packages/pieces/community/whatsapp/tsconfig.lib.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "module": "commonjs",
+ "outDir": "../../../../dist/out-tsc",
+ "declaration": true,
+ "types": ["node"]
+ },
+ "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
+ "include": ["src/**/*.ts", "src/lib/actions/common/utils.ts"]
+}
diff --git a/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts b/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts
index fc968cd194..3b50004bac 100644
--- a/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts
+++ b/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts
@@ -9,7 +9,8 @@ import { slack } from '@activepieces/piece-slack'
import { square } from '@activepieces/piece-square'
import { Piece } from '@activepieces/pieces-framework'
import { logger, rejectedPromiseHandler } from '@activepieces/server-shared'
-import { ActivepiecesError, ALL_PRINCIPAL_TYPES,
+import {
+ ActivepiecesError, ALL_PRINCIPAL_TYPES,
ErrorCode,
EventPayload,
isNil,
diff --git a/packages/server/api/src/app/core/security/authz/project-authz-handler.ts b/packages/server/api/src/app/core/security/authz/project-authz-handler.ts
index d4cb817995..a351d13b0f 100644
--- a/packages/server/api/src/app/core/security/authz/project-authz-handler.ts
+++ b/packages/server/api/src/app/core/security/authz/project-authz-handler.ts
@@ -11,7 +11,7 @@ export class ProjectAuthzHandler extends BaseSecurityHandler {
'/v1/users/projects/:projectId/token',
'/v1/webhooks',
'/v1/webhooks/:flowId',
- '/v1/webhooks/:flowId/simulate',
+ '/v1/webhooks/:flowId/test',
'/v1/webhooks/:flowId/sync',
]
diff --git a/packages/server/api/src/app/flows/flow-run/flow-run-service.ts b/packages/server/api/src/app/flows/flow-run/flow-run-service.ts
index 0282e52894..a60db820c0 100644
--- a/packages/server/api/src/app/flows/flow-run/flow-run-service.ts
+++ b/packages/server/api/src/app/flows/flow-run/flow-run-service.ts
@@ -78,6 +78,31 @@ async function updateFlowRunToLatestFlowVersionId(
})
}
+function returnHandlerId(pauseMetadata: PauseMetadata | undefined, requestId: string | undefined): string {
+ const handlerId = engineResponseWatcher.getHandlerId()
+ if (isNil(pauseMetadata)) {
+ return handlerId
+ }
+
+ if (pauseMetadata.type === PauseType.WEBHOOK && requestId === pauseMetadata.requestId && pauseMetadata.handlerId) {
+ return pauseMetadata.handlerId
+ }
+ else {
+ return handlerId
+ }
+}
+
+function modifyPauseMetadata(pauseMetadata: PauseMetadata): PauseMetadata {
+ if (pauseMetadata.type === PauseType.WEBHOOK) {
+ return {
+ ...pauseMetadata,
+ handlerId: engineResponseWatcher.getHandlerId(),
+ }
+ }
+
+ return pauseMetadata
+}
+
export const flowRunService = {
async list({
projectId,
@@ -173,6 +198,8 @@ export const flowRunService = {
flowRunId: flowRunToResume.id,
projectId: flowRunToResume.projectId,
flowVersionId: flowRunToResume.flowVersionId,
+ synchronousHandlerId: returnHandlerId(pauseMetadata, requestId),
+ hookType: HookType.AFTER_LOG,
executionType,
environment: RunEnvironment.PRODUCTION,
})
@@ -292,7 +319,7 @@ export const flowRunService = {
status: FlowRunStatus.PAUSED,
logsFileId: logFileId,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
- pauseMetadata: pauseMetadata as any,
+ pauseMetadata: modifyPauseMetadata(pauseMetadata) as any,
})
const flowRun = await flowRunRepo.findOneByOrFail({ id: flowRunId })
diff --git a/packages/server/api/src/app/flows/flow.module.ts b/packages/server/api/src/app/flows/flow.module.ts
index 6cfb78e397..88ec6c480e 100644
--- a/packages/server/api/src/app/flows/flow.module.ts
+++ b/packages/server/api/src/app/flows/flow.module.ts
@@ -10,7 +10,7 @@ import { folderController } from './folder/folder.controller'
import { stepRunService } from './step-run/step-run-service'
import { testTriggerController } from './test-trigger/test-trigger-controller'
import { logger } from '@activepieces/server-shared'
-import { CreateStepRunRequestBody, StepRunResponse, TestFlowRunRequestBody, WebsocketClientEvent, WebsocketServerEvent } from '@activepieces/shared'
+import { CreateStepRunRequestBody, isFlowStateTerminal, StepRunResponse, TestFlowRunRequestBody, WebsocketClientEvent, WebsocketServerEvent } from '@activepieces/shared'
export const flowModule: FastifyPluginAsyncTypebox = async (app) => {
await app.register(flowWorkerController, { prefix: '/v1/worker/flows' })
@@ -25,9 +25,21 @@ export const flowModule: FastifyPluginAsyncTypebox = async (app) => {
projectId: principal.projectId,
flowVersionId: data.flowVersionId,
})
+
socket.emit(WebsocketClientEvent.TEST_FLOW_RUN_STARTED, flowRun)
- await engineResponseWatcher.listen(flowRun.id, false)
- socket.emit(WebsocketClientEvent.TEST_FLOW_RUN_FINISHED, flowRun)
+ const eventEmitter = engineResponseWatcher.listen(flowRun.id)
+ eventEmitter.on(async (data) => {
+ const flowRun = await flowRunService.getOneOrThrow({
+ id: data.requestId,
+ projectId: principal.projectId,
+ })
+
+ if (isFlowStateTerminal(flowRun.status)) {
+ engineResponseWatcher.removeListener(flowRun.id)
+ }
+ socket.emit(WebsocketClientEvent.TEST_FLOW_RUN_PROGRESS, flowRun)
+ })
+
}
})
websocketService.addListener(WebsocketServerEvent.TEST_STEP_RUN, (socket) => {
diff --git a/packages/server/api/src/app/webhooks/webhook-controller.ts b/packages/server/api/src/app/webhooks/webhook-controller.ts
index 228d377fa0..7abe7f1041 100644
--- a/packages/server/api/src/app/webhooks/webhook-controller.ts
+++ b/packages/server/api/src/app/webhooks/webhook-controller.ts
@@ -65,7 +65,7 @@ export const webhookController: FastifyPluginAsyncTypebox = async (app) => {
.send(response.body)
})
- app.all('/:flowId/simulate', WEBHOOK_PARAMS, async (request, reply) => {
+ app.all('/:flowId/test', WEBHOOK_PARAMS, async (request, reply) => {
const response = await handleWebhook({
request,
flowId: request.params.flowId,
@@ -104,7 +104,7 @@ async function handleWebhook({ request, flowId, async, simulate }: { request: Fa
headers: {},
}
}
- return engineResponseWatcher.listen(requestId, true)
+ return engineResponseWatcher.oneTimeListener(requestId, true)
}
async function convertRequest(request: FastifyRequest): Promise {
diff --git a/packages/server/api/src/app/webhooks/webhook-service.ts b/packages/server/api/src/app/webhooks/webhook-service.ts
index 8c28f79133..e9e52342c5 100644
--- a/packages/server/api/src/app/webhooks/webhook-service.ts
+++ b/packages/server/api/src/app/webhooks/webhook-service.ts
@@ -1,4 +1,3 @@
-import { flowService } from '../flows/flow/flow.service'
import { flowRunService, HookType } from '../flows/flow-run/flow-run-service'
import { flowVersionService } from '../flows/flow-version/flow-version.service'
import { triggerHooks } from '../flows/trigger'
@@ -66,32 +65,16 @@ export const webhookService = {
const { projectId } = flow
- if (isNil(flow.publishedVersionId)) {
+ if (flow.status !== FlowStatus.ENABLED || isNil(flow.publishedVersionId)) {
logger.info(
- `[WebhookService#callback] flowInstance not found, flowId=${flow.id}`,
+ `[WebhookService#callback] flowInstance not found or not enabled ignoring the webhook, flowId=${flow.id}`,
)
- const flowVersion = (
- await flowService.getOnePopulatedOrThrow({
- projectId,
+ throw new ActivepiecesError({
+ code: ErrorCode.FLOW_NOT_FOUND,
+ params: {
id: flow.id,
- })
- ).version
- const payloads: unknown[] = await triggerHooks.executeTrigger({
- projectId,
- flowVersion,
- payload,
- simulate: false,
+ },
})
- payloads.forEach((resultPayload) => {
- saveSampleDataForWebhookTesting(flow, resultPayload)
- })
- return []
- }
- if (flow.status !== FlowStatus.ENABLED) {
- logger.info(
- `[WebhookService#callback] flowInstance not found or not enabled ignoring the webhook, flowId=${flow.id}`,
- )
- return []
}
const flowVersion = await flowVersionService.getOneOrThrow(
@@ -104,20 +87,20 @@ export const webhookService = {
simulate: false,
})
- payloads.forEach((payload) => {
- triggerEventService
- .saveEvent({
- flowId: flow.id,
- payload,
- projectId,
- })
- .catch((e) =>
- logger.error(
- e,
- '[WebhookService#callback] triggerEventService.saveEvent',
- ),
- )
- })
+ const savePayloads = payloads.map((payload) =>
+ triggerEventService.saveEvent({
+ flowId: flow.id,
+ payload,
+ projectId,
+ }).catch((e) =>
+ logger.error(
+ e,
+ '[WebhookService#callback] triggerEventService.saveEvent',
+ ),
+ ),
+ )
+
+ await Promise.all(savePayloads)
const filterPayloads = await dedupeService.filterUniquePayloads(
flowVersion.id,
@@ -180,7 +163,7 @@ export const webhookService = {
flowId,
simulate,
}: GetWebhookUrlParams): Promise {
- const suffix: WebhookUrlSuffix = simulate ? '/simulate' : ''
+ const suffix: WebhookUrlSuffix = simulate ? '/test' : ''
const webhookPrefix = await this.getWebhookPrefix()
return `${webhookPrefix}/${flowId}${suffix}`
},
@@ -211,22 +194,7 @@ const getLatestFlowVersionOrThrow = async (
return flowVersion
}
-function saveSampleDataForWebhookTesting(flow: Flow, payload: unknown): void {
- triggerEventService
- .saveEvent({
- flowId: flow.id,
- payload,
- projectId: flow.projectId,
- })
- .catch((e) =>
- logger.error(
- e,
- '[WebhookService#saveSampleDataForWebhookTesting] triggerEventService.saveEvent',
- ),
- )
-}
-
-type WebhookUrlSuffix = '' | '/simulate'
+type WebhookUrlSuffix = '' | '/test'
type GetWebhookUrlParams = {
flowId: FlowId
diff --git a/packages/server/api/src/app/webhooks/webhook-simulation/webhook-simulation-service.ts b/packages/server/api/src/app/webhooks/webhook-simulation/webhook-simulation-service.ts
index 4e4dc92e83..61dfd76872 100644
--- a/packages/server/api/src/app/webhooks/webhook-simulation/webhook-simulation-service.ts
+++ b/packages/server/api/src/app/webhooks/webhook-simulation/webhook-simulation-service.ts
@@ -49,7 +49,7 @@ export const webhookSimulationService = {
})
try {
- const webhookSimulationExists = await webhookSimulationRepo.exist({
+ const webhookSimulationExists = await webhookSimulationRepo.exists({
where: { flowId },
})
diff --git a/packages/server/api/src/app/workers/flow-worker/consumer/webook-consumer.ts b/packages/server/api/src/app/workers/flow-worker/consumer/webook-consumer.ts
index 96eddd9757..36b54a574c 100644
--- a/packages/server/api/src/app/workers/flow-worker/consumer/webook-consumer.ts
+++ b/packages/server/api/src/app/workers/flow-worker/consumer/webook-consumer.ts
@@ -3,7 +3,7 @@ import { flowService } from '../../../flows/flow/flow.service'
import { webhookService } from '../../../webhooks/webhook-service'
import { EngineHttpResponse, engineResponseWatcher } from '../engine-response-watcher'
import { WebhookJobData } from '../job-data'
-import { isNil } from '@activepieces/shared'
+import { FlowStatus, isNil } from '@activepieces/shared'
export const webhookConsumer = {
async consumeWebhook(data: WebhookJobData): Promise {
@@ -17,6 +17,14 @@ export const webhookConsumer = {
})
return
}
+ if (flow.status !== FlowStatus.ENABLED && !simulate) {
+ await stopAndReply(data, {
+ status: StatusCodes.NOT_FOUND,
+ body: {},
+ headers: {},
+ })
+ return
+ }
const handshakeResponse = await webhookService.handshake({
flow,
payload,
@@ -51,7 +59,7 @@ export const webhookConsumer = {
return
}
const firstRun = runs[0]
- const response = await engineResponseWatcher.listen(firstRun.id, true)
+ const response = await engineResponseWatcher.oneTimeListener(firstRun.id, true)
await stopAndReply(data, response)
},
diff --git a/packages/server/api/src/app/workers/flow-worker/engine-response-watcher.ts b/packages/server/api/src/app/workers/flow-worker/engine-response-watcher.ts
index aae19a1b6e..2975cc1afb 100644
--- a/packages/server/api/src/app/workers/flow-worker/engine-response-watcher.ts
+++ b/packages/server/api/src/app/workers/flow-worker/engine-response-watcher.ts
@@ -1,10 +1,10 @@
import { logger } from '@sentry/utils'
import { StatusCodes } from 'http-status-codes'
import { pubSub } from '../../helper/pubsub'
-import { system, SystemProp } from '@activepieces/server-shared'
+import { system, SystemProp, TypedEventEmitter } from '@activepieces/server-shared'
import { apId } from '@activepieces/shared'
-const listeners = new Map void>()
+const listeners = new Map void>()
export type EngineHttpResponse = {
status: number
@@ -12,7 +12,7 @@ export type EngineHttpResponse = {
headers: Record
}
-type EngineResponseWithId = {
+export type EngineResponseWithId = {
requestId: string
httpResponse: EngineHttpResponse
}
@@ -24,6 +24,9 @@ export const engineResponseWatcher = {
getHandlerId(): string {
return HANDLER_ID
},
+ removeListener(requestId: string): void {
+ listeners.delete(requestId)
+ },
async init(): Promise {
logger.info('[engineWatcher#init] Initializing engine run watcher')
@@ -33,8 +36,7 @@ export const engineResponseWatcher = {
const parsedMessasge: EngineResponseWithId = JSON.parse(message)
const listener = listeners.get(parsedMessasge.requestId)
if (listener) {
- listener(parsedMessasge.httpResponse)
- listeners.delete(parsedMessasge.requestId)
+ listener(parsedMessasge)
}
logger.info(
`[engineWatcher#init] message=${parsedMessasge.requestId}`,
@@ -42,28 +44,37 @@ export const engineResponseWatcher = {
},
)
},
- async listen(requestId: string, timeoutRequest: boolean): Promise {
+ listen(requestId: string): TypedEventEmitter {
+ const eventEmitter = new TypedEventEmitter()
+ listeners.set(requestId, (data) => {
+ eventEmitter.emit(data)
+ })
+ return eventEmitter
+ },
+ async oneTimeListener(requestId: string, timeoutRequest: boolean): Promise {
logger.info(`[engineWatcher#listen] requestId=${requestId}`)
return new Promise((resolve) => {
- const defaultResponse: EngineHttpResponse = {
- status: StatusCodes.NO_CONTENT,
- body: {},
- headers: {},
- }
- const responseHandler = (flowResponse: EngineHttpResponse) => {
- clearTimeout(timeout)
- resolve(flowResponse)
- }
let timeout: NodeJS.Timeout
- if (!timeoutRequest) {
- listeners.set(requestId, resolve)
- }
- else {
+ if (timeoutRequest) {
+ const defaultResponse: EngineHttpResponse = {
+ status: StatusCodes.NO_CONTENT,
+ body: {},
+ headers: {},
+ }
timeout = setTimeout(() => {
+ this.removeListener(requestId)
resolve(defaultResponse)
}, WEBHOOK_TIMEOUT_MS)
- listeners.set(requestId, responseHandler)
+
+ }
+ const responseHandler = (flowResponse: EngineResponseWithId) => {
+ if (timeout) {
+ clearTimeout(timeout)
+ }
+ this.removeListener(requestId)
+ resolve(flowResponse.httpResponse)
}
+ listeners.set(requestId, responseHandler)
})
},
async publish(
diff --git a/packages/server/shared/package.json b/packages/server/shared/package.json
index ef59338eff..8dbc4602ec 100644
--- a/packages/server/shared/package.json
+++ b/packages/server/shared/package.json
@@ -6,7 +6,8 @@
"@sentry/node": "7.64.0",
"pino": "8.18.0",
"pino-loki": "2.1.3",
- "@activepieces/shared": "*"
+ "@activepieces/shared": "*",
+ "events": "3.3.0"
},
"type": "commonjs",
"main": "./src/index.js",
diff --git a/packages/server/shared/src/index.ts b/packages/server/shared/src/index.ts
index 9b0e318118..2821662697 100644
--- a/packages/server/shared/src/index.ts
+++ b/packages/server/shared/src/index.ts
@@ -1,3 +1,5 @@
+export * from './lib/exception-handler'
+export * from './lib/typed-event-emitter'
export * from './lib/semaphore'
export * from './lib/file-compressor'
export * from './lib/file-system'
@@ -5,5 +7,4 @@ export * from './lib/package-manager'
export * from './lib/system/system'
export * from './lib/system/system-prop'
export * from './lib/promise-handler'
-export * from './lib/logger'
-export * from './lib/exception-handler'
\ No newline at end of file
+export * from './lib/logger'
\ No newline at end of file
diff --git a/packages/server/shared/src/lib/typed-event-emitter.ts b/packages/server/shared/src/lib/typed-event-emitter.ts
new file mode 100644
index 0000000000..46b6c74a45
--- /dev/null
+++ b/packages/server/shared/src/lib/typed-event-emitter.ts
@@ -0,0 +1,17 @@
+import EventEmitter from 'events'
+
+export class TypedEventEmitter {
+ private emitter = new EventEmitter()
+
+ emit(eventArg: TEventData) {
+ this.emitter.emit('event', eventArg)
+ }
+
+ on(handler: (eventArg: TEventData) => void) {
+ this.emitter.on('event', handler)
+ }
+
+ off(handler: (eventArg: TEventData) => void) {
+ this.emitter.off('event', handler)
+ }
+}
diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts
index 93a9663be2..879918c2ba 100755
--- a/packages/shared/src/index.ts
+++ b/packages/shared/src/index.ts
@@ -60,6 +60,7 @@ export { DelayPauseMetadata, PauseMetadata, WebhookPauseMetadata } from './lib/f
export * from './lib/federated-authn'
export { STORE_KEY_MAX_LENGTH } from './lib/store-entry/store-entry'
export { RetryFlowRequestBody } from './lib/flow-run/test-flow-run-request'
+export * from './lib/flow-run/flow-status'
export * from './lib/flows/dto/flow-template-request'
// Look at https://github.com/sinclairzx81/typebox/issues/350
TypeSystem.ExactOptionalPropertyTypes = false
diff --git a/packages/shared/src/lib/flow-run/execution/flow-execution.ts b/packages/shared/src/lib/flow-run/execution/flow-execution.ts
index a1adc6e3a5..cbca52894e 100644
--- a/packages/shared/src/lib/flow-run/execution/flow-execution.ts
+++ b/packages/shared/src/lib/flow-run/execution/flow-execution.ts
@@ -29,6 +29,7 @@ export const WebhookPauseMetadata = Type.Object({
type: Type.Literal(PauseType.WEBHOOK),
requestId: Type.String(),
response: Type.Unknown(),
+ handlerId: Type.Optional(Type.String({})),
})
export type WebhookPauseMetadata = Static
diff --git a/packages/shared/src/lib/flow-run/flow-status.ts b/packages/shared/src/lib/flow-run/flow-status.ts
new file mode 100644
index 0000000000..24411d3909
--- /dev/null
+++ b/packages/shared/src/lib/flow-run/flow-status.ts
@@ -0,0 +1,5 @@
+import { FlowRunStatus } from './execution/flow-execution'
+
+export const isFlowStateTerminal = (status: FlowRunStatus): boolean => {
+ return status === FlowRunStatus.SUCCEEDED || status === FlowRunStatus.FAILED || status === FlowRunStatus.INTERNAL_ERROR || status === FlowRunStatus.QUOTA_EXCEEDED
+}
\ No newline at end of file
diff --git a/packages/shared/src/lib/websocket/index.ts b/packages/shared/src/lib/websocket/index.ts
index cc85d14a77..34156832c2 100644
--- a/packages/shared/src/lib/websocket/index.ts
+++ b/packages/shared/src/lib/websocket/index.ts
@@ -2,7 +2,7 @@
export enum WebsocketClientEvent {
TEST_FLOW_RUN_STARTED = 'TEST_FLOW_RUN_STARTED',
- TEST_FLOW_RUN_FINISHED = 'TEST_FLOW_RUN_FINISHED',
+ TEST_FLOW_RUN_PROGRESS = 'TEST_FLOW_RUN_PROGRESS',
GENERATE_CODE_FINISHED = 'GENERATE_CODE_FINIISHED',
TEST_STEP_FINISHED = 'TEST_STEP_FINISHED',
}
diff --git a/packages/ui/feature-builder-canvas/src/lib/components/widgets/test-flow-widget/test-flow-widget.component.ts b/packages/ui/feature-builder-canvas/src/lib/components/widgets/test-flow-widget/test-flow-widget.component.ts
index 8d161b2119..56d34955ba 100644
--- a/packages/ui/feature-builder-canvas/src/lib/components/widgets/test-flow-widget/test-flow-widget.component.ts
+++ b/packages/ui/feature-builder-canvas/src/lib/components/widgets/test-flow-widget/test-flow-widget.component.ts
@@ -112,7 +112,7 @@ export class TestFlowWidgetComponent implements OnInit {
);
this.testResult$ = this.websockService.socket
- .fromEvent(WebsocketClientEvent.TEST_FLOW_RUN_FINISHED)
+ .fromEvent(WebsocketClientEvent.TEST_FLOW_RUN_PROGRESS)
.pipe(
switchMap((flowRun) => {
return this.instanceRunService.get(flowRun.id);
diff --git a/packages/ui/feature-builder-form-controls/src/lib/components/new-piece-properties-form/piece-properties-form.component.html b/packages/ui/feature-builder-form-controls/src/lib/components/new-piece-properties-form/piece-properties-form.component.html
index 01b1338bf0..751e174b9d 100644
--- a/packages/ui/feature-builder-form-controls/src/lib/components/new-piece-properties-form/piece-properties-form.component.html
+++ b/packages/ui/feature-builder-form-controls/src/lib/components/new-piece-properties-form/piece-properties-form.component.html
@@ -1,6 +1,6 @@