Compare commits

...

300 Commits

Author SHA1 Message Date
Rıdvan Akca
2846dd2bdd feat(trello): add new cards trigger 2023-10-26 15:13:10 +03:00
QAComet
2fceaf2cf4 test: fix flakiness in GH connection test case (#1383) 2023-10-25 11:04:04 +02:00
Ömer Faruk Aydın
d82b50fcdb Merge pull request #1382 from automatisch/fix/delete-current-user
fix: Guard lowercase email for delete user operation
2023-10-25 01:17:52 +02:00
Faruk AYDIN
ab6e49bf4f fix: Guard lowercase email for delete user operation 2023-10-25 01:00:43 +02:00
Rıdvan Akca
ee90422f56 feat(trello): add trello integration (#1380) 2023-10-24 15:13:08 +02:00
Ömer Faruk Aydın
627184f124 Merge pull request #1379 from automatisch/factories/execution-step
test: Implement execution step factory
2023-10-24 13:45:08 +02:00
Rıdvan Akca
fa02edfefc feat(pushover): add send a pushover notification action (#1373) 2023-10-24 13:40:24 +02:00
Faruk AYDIN
61afebc827 test: Implement execution step factory 2023-10-24 12:35:29 +02:00
Faruk AYDIN
a4c22799e7 fix: Correct executions table name for execution factory 2023-10-24 12:35:29 +02:00
Faruk AYDIN
870a110a75 fix: Fetch lastStep directly on the step factory 2023-10-24 12:35:29 +02:00
kattoczko
8c859f9408 feat: introduce admin app configs page (#1335) 2023-10-24 12:19:37 +02:00
Ali BARIN
0a36101da1 feat: close snackbars upon click (#1378) 2023-10-24 12:03:30 +02:00
Ömer Faruk Aydın
c1bf063b12 Merge pull request #1377 from automatisch/factories/execution
test: Implement factory for the execution model
2023-10-23 23:06:45 +02:00
Ömer Faruk Aydın
0da56a800d Merge pull request #1376 from automatisch/factories/step
test: Add factory file for the step model
2023-10-23 23:00:26 +02:00
Faruk AYDIN
4d2172d153 test: Implement factory for the execution model 2023-10-23 22:52:24 +02:00
Faruk AYDIN
d0fab0e1f1 test: Add factory file for the step model 2023-10-23 22:47:19 +02:00
QAComet
4cedbdbc60 test: add tests for git connection (#1289)
* chore: add data-test attributes

* test: add github connection test, add applications modal

* chore: embed test GITHUB_CLIENT_* environment values

---------

Co-authored-by: Ali BARIN <ali.barin53@gmail.com>
2023-10-23 18:48:23 +02:00
Ömer Faruk Aydın
a82d34cbce Merge pull request #1375 from automatisch/factories/flow
test: Add factory file for the flow model
2023-10-23 18:43:14 +02:00
Faruk AYDIN
16d0c243c7 test: Add factory file for the flow model 2023-10-23 18:26:43 +02:00
Ömer Faruk Aydın
855901bd9e Merge pull request #1372 from automatisch/refactor/tests
refactor: Use named exports for factories
2023-10-23 11:09:05 +02:00
Faruk AYDIN
6be8a581d2 refactor: Use named exports for factories 2023-10-23 10:36:44 +02:00
Faruk AYDIN
655deb12c8 refactor: Rename fixtures as factories to differentiate dynamic data 2023-10-23 10:30:27 +02:00
Ömer Faruk Aydın
31b1b9457b Merge pull request #1364 from automatisch/AUT-348
feat(pushover): add pushover integration
2023-10-22 23:13:01 +02:00
Faruk AYDIN
c4394228f2 fix(placetel): Authenticate in case valid user without device 2023-10-22 23:03:46 +02:00
Rıdvan Akca
98e6dbe141 feat(pushover): add pushover integration 2023-10-22 23:03:46 +02:00
Ömer Faruk Aydın
4fac1ef7c4 Merge pull request #1355 from automatisch/AUT-347
feat(youtube): add new video by search trigger
2023-10-21 10:52:31 +02:00
Rıdvan Akca
034bc6a79e refactor(pipedrive): make filterProvidedFields func reusable 2023-10-20 19:06:34 +02:00
Rıdvan Akca
94e64676af refactor(pipedrive): set baseUrl in a seperate file 2023-10-20 18:36:50 +02:00
Rıdvan Akca
3a638220af feat(pipedrive): add create person action 2023-10-20 17:39:24 +02:00
Rıdvan Akca
0772308bf5 feat(pipedrive): add create organization action 2023-10-20 17:12:51 +02:00
Rıdvan Akca
9f5ea80731 feat(youtube): add new video by search trigger 2023-10-20 18:02:44 +03:00
Ömer Faruk Aydın
fb1f520096 Merge pull request #1367 from automatisch/test/connection-fixture
test: Implement connection fixture
2023-10-20 15:53:04 +02:00
Ömer Faruk Aydın
dd36609443 Merge pull request #1353 from automatisch/AUT-344
feat(youtube): add new video in channel trigger
2023-10-20 15:43:06 +02:00
Rıdvan Akca
4eace3fb7e feat(youtube): add new video in channel trigger 2023-10-20 16:35:13 +03:00
Faruk AYDIN
f13e93e2ce test: Implement connection fixture 2023-10-19 23:04:02 +02:00
Ömer Faruk Aydın
da4f8ab529 Merge pull request #1351 from automatisch/AUT-343
feat(youtube): add youtube integration
2023-10-19 15:05:58 +02:00
Ömer Faruk Aydın
b6ff4ec992 Merge pull request #1363 from automatisch/test/get-trial-status
test: Implement tests for get trial status graphQL query
2023-10-19 14:29:59 +02:00
Ömer Faruk Aydın
25f6cac69a Merge pull request #1362 from automatisch/test/get-automatisch-info
test: Add getAutomatischInfo graphQL query tests
2023-10-19 14:23:51 +02:00
Faruk AYDIN
172a8934e3 test: Add restoreAllMocks to global afterEach for spy and replaceProperty 2023-10-19 14:22:00 +02:00
Ali BARIN
aead014bcf refactor: remove additional mock implentation in tests 2023-10-19 13:43:49 +02:00
Faruk AYDIN
59770c80db test: Implement tests for get trial status graphQL query 2023-10-19 01:06:41 +02:00
Faruk AYDIN
6d6b77148d refactor: User fixture to pass additonal params 2023-10-19 01:06:01 +02:00
Faruk AYDIN
c1e8f5765f chore: Use cloud enabled version for test db 2023-10-19 01:05:23 +02:00
Faruk AYDIN
76e442940b test: Add getAutomatischInfo graphQL query tests 2023-10-18 15:47:09 +02:00
Faruk AYDIN
b2205097da test: Implement the structure of mocking appConfig options 2023-10-18 15:47:09 +02:00
Faruk AYDIN
14886d42e8 test: Clear all jest mocks with after each global hook 2023-10-18 15:47:09 +02:00
Ömer Faruk Aydın
2f35403078 Merge pull request #1359 from automatisch/AUT-350
fix(pipedrive): check if there is no data in dynamic-data
2023-10-18 11:42:12 +02:00
Rıdvan Akca
961d55a1c6 fix(pipedrive): check if there is no data in dynamic-data 2023-10-18 12:20:25 +03:00
Ömer Faruk Aydın
0fca0ef734 Merge pull request #1340 from automatisch/AUT-329
feat(invoice-ninja): add create product action
2023-10-18 00:27:05 +02:00
Ömer Faruk Aydın
cc3acd81bc Merge pull request #1357 from automatisch/pipedrive-create-activity-name-correction
fix(pipedrive/create-activity): correct its key
2023-10-18 00:18:30 +02:00
Ali BARIN
69a691c19e fix(pipedrive/create-activity): correct its key 2023-10-17 21:48:58 +02:00
Ömer Faruk Aydın
e0a4f5c9c9 Merge pull request #1356 from automatisch/formatter/format-phone-number
feat(formatter): implement format phone number transformer
2023-10-17 17:02:22 +02:00
Faruk AYDIN
cabf9b8fb8 feat(formatter): implement format phone number transformer 2023-10-17 16:45:56 +02:00
Rıdvan Akca
61e24da07d feat(invoice-ninja): add create product action 2023-10-17 15:27:25 +03:00
Ömer Faruk Aydın
648511dfad Merge pull request #1354 from automatisch/dependabot/npm_and_yarn/babel/traverse-7.23.2
chore(deps): bump @babel/traverse from 7.16.3 to 7.23.2
2023-10-17 12:52:18 +02:00
dependabot[bot]
dfc9efc31a chore(deps): bump @babel/traverse from 7.16.3 to 7.23.2
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.16.3 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-17 10:32:32 +00:00
Ömer Faruk Aydın
b58a22addc Merge pull request #1339 from automatisch/AUT-328
feat(invoice-ninja): add create payment action
2023-10-17 11:37:44 +02:00
Ömer Faruk Aydın
e07a9eeda2 Merge pull request #1338 from automatisch/AUT-327
feat(invoice-ninja): add create invoice action
2023-10-16 17:36:38 +02:00
Rıdvan Akca
f0de42fa63 feat(invoice-ninja): add create payment action 2023-10-16 18:30:10 +03:00
Rıdvan Akca
0121661ad0 feat(invoice-ninja): add create invoice action 2023-10-16 18:22:57 +03:00
Rıdvan Akca
fb6e46bd69 feat(youtube): add youtube integration 2023-10-16 16:27:17 +03:00
Ömer Faruk Aydın
9bd041799b Merge pull request #1350 from automatisch/test/get-config
test: Implement tests for getConfig graphQL query
2023-10-16 15:12:53 +02:00
Ömer Faruk Aydın
9e191c4ed9 Merge pull request #1349 from automatisch/test/get-roles
test: add tests for graphQL getRoles query
2023-10-16 15:12:43 +02:00
Ömer Faruk Aydın
794b4cf26a Merge pull request #1348 from automatisch/tests/get-role
test: Add getRole graphQL query test
2023-10-16 14:52:28 +02:00
Faruk AYDIN
2d8421943f test: Implement tests for getConfig graphQL query 2023-10-15 20:01:05 +02:00
Faruk AYDIN
48dc2312d9 refactor: Remove redundant context variable from getConfig 2023-10-15 20:00:51 +02:00
Faruk AYDIN
cdf7a1adc4 test: Implement config fixture 2023-10-15 20:00:07 +02:00
Faruk AYDIN
99ebd12081 chore: Add IConfig type 2023-10-15 19:59:26 +02:00
Faruk AYDIN
859337b5c1 test: add tests for graphQL getRoles query 2023-10-15 16:55:25 +02:00
Faruk AYDIN
1e601559a0 test: remove roles and permission with global before all hook 2023-10-15 16:54:51 +02:00
Faruk AYDIN
9314cba724 test: Add getRole graphQL query test 2023-10-15 15:22:08 +02:00
Ömer Faruk Aydın
25224f0308 Merge pull request #1346 from automatisch/test/get-users
test: Implement tests for graphQL getUsers query
2023-10-14 21:35:51 +02:00
Faruk AYDIN
9a981d5373 test: Implement tests for graphQL getUsers query 2023-10-14 21:29:24 +02:00
Faruk AYDIN
c7116361ab refactor: No need to interpolate token for getUser test 2023-10-14 21:21:40 +02:00
Ömer Faruk Aydın
1f17236c4f Merge pull request #1345 from automatisch/refactor/tests
test: Correct get current user test descriptions
2023-10-14 21:21:21 +02:00
Ömer Faruk Aydın
67f415de35 Merge pull request #1344 from automatisch/test/healthcheck-query
test: Add test for healthcheck graphQL query
2023-10-14 21:20:55 +02:00
Faruk AYDIN
b890150817 chore: Add verbose flag to yarn test script 2023-10-14 20:13:13 +02:00
Faruk AYDIN
4de1fc49df test: Add test case for unauthorized user for getUser 2023-10-14 20:12:10 +02:00
Faruk AYDIN
fb80d5d70d test: Correct get current user test descriptions 2023-10-14 20:04:49 +02:00
Faruk AYDIN
eaa25e412a test: Add test for healthcheck graphQL query 2023-10-14 17:45:26 +02:00
Faruk AYDIN
706142f98e chore: Change the description of existing graphQL tests 2023-10-14 17:19:25 +02:00
Ömer Faruk Aydın
36a72d0a32 Merge pull request #1334 from automatisch/AUT-326
feat(invoice-ninja): add create client action
2023-10-14 15:36:24 +02:00
Faruk AYDIN
1d44d387ac feat(invoice-ninja): Add static country codes to create client fields 2023-10-14 15:26:58 +02:00
Faruk AYDIN
f93c41f2d8 feat(invoice-ninja): Set instance URL as base URL 2023-10-14 15:26:58 +02:00
Rıdvan Akca
5b13f880c8 feat(invoice-ninja): add create client action 2023-10-14 15:26:58 +02:00
Ömer Faruk Aydın
c4af873036 Merge pull request #1342 from automatisch/lowercase-email
fix: Lowercase user email before insert and update
2023-10-14 13:42:05 +02:00
Faruk AYDIN
fe820fb4fe fix: use lowercase email for user model findOne method 2023-10-13 13:21:55 +02:00
Faruk AYDIN
82ad0735d2 chore: Convert user emails to lowercase 2023-10-13 11:52:31 +02:00
Faruk AYDIN
8b0a421924 fix: Lowercase user email before insert and update 2023-10-13 11:44:52 +02:00
Ömer Faruk Aydın
d44cb3d92e Merge pull request #1341 from automatisch/test/get-current-user
test: Implement getCurrentUser graphQL test
2023-10-13 11:36:38 +02:00
Ömer Faruk Aydın
5f335ef5b3 refactor: Use token without string interpolation for getCurrentUser test
Co-authored-by: Ali BARIN <ali.barin53@gmail.com>
2023-10-13 11:24:54 +02:00
Faruk AYDIN
5831bf9653 test: Implement getCurrentUser graphQL test 2023-10-13 01:04:35 +02:00
Ömer Faruk Aydın
2480dfbb6d Merge pull request #1331 from automatisch/AUT-323
feat(invoice-ninja): add new quotes trigger
2023-10-12 16:03:28 +02:00
Ömer Faruk Aydın
162b352ea5 Merge pull request #1330 from automatisch/AUT-322
feat(invoice-ninja): add new projects trigger
2023-10-12 15:58:49 +02:00
Ömer Faruk Aydın
9f30d7d7ba Merge pull request #1329 from automatisch/AUT-321
feat(invoice-ninja): add new payments trigger
2023-10-12 15:55:44 +02:00
Rıdvan Akca
27c296bb89 feat(invoice-ninja): add new quotes trigger 2023-10-12 14:44:17 +03:00
Rıdvan Akca
ef67908451 feat(invoice-ninja): add new projects trigger 2023-10-12 14:43:39 +03:00
Rıdvan Akca
3dedc3bfc7 feat(invoice-ninja): add new payments trigger 2023-10-12 14:43:06 +03:00
Ömer Faruk Aydın
65d509c97f Merge pull request #1328 from automatisch/AUT-320
feat(invoice-ninja): add new invoices trigger
2023-10-11 16:00:25 +02:00
Rıdvan Akca
11f38c4d3a feat(invoice-ninja): add new invoices trigger 2023-10-11 15:36:20 +02:00
Ömer Faruk Aydın
3bca6497f7 Merge pull request #1327 from automatisch/AUT-319
feat(invoice-ninja): add new credits trigger
2023-10-11 15:34:17 +02:00
Ömer Faruk Aydın
23d79b9265 Merge pull request #1333 from automatisch/backend-tests-ci
feat: Add CI configuration for backend tests
2023-10-11 14:07:01 +02:00
Faruk AYDIN
12c53a3d4d feat: Add CI configuration for backend tests 2023-10-11 13:41:03 +02:00
Ömer Faruk Aydın
1dfe58ec02 Merge pull request #1337 from automatisch/placetel-webhook
fix(placetel): Parse request body inside of run method
2023-10-11 11:24:55 +02:00
Faruk AYDIN
7615e62bbc fix(placetel): Parse request body inside of run method 2023-10-11 11:17:19 +02:00
Faruk AYDIN
53189a6487 fix: Do not parse all requests with json parser 2023-10-10 18:26:53 +02:00
Rıdvan Akca
027b11c3fb feat(invoice-ninja): add new credits trigger 2023-10-10 16:31:42 +03:00
Ömer Faruk Aydın
453ab7de66 Merge pull request #1325 from automatisch/AUT-318
feat(invoice-ninja): add new clients trigger
2023-10-10 12:51:40 +02:00
Rıdvan Akca
58f8ded161 feat(invoice-ninja): add new clients trigger 2023-10-10 13:41:14 +03:00
Ömer Faruk Aydın
497ce2e84f Merge pull request #1323 from automatisch/AUT-315
feat(invoice-ninja): add invoice ninja integration
2023-10-09 16:41:35 +02:00
Faruk AYDIN
3794c6f508 docs(invoice-ninja): Add warning to see API tokens 2023-10-09 16:30:53 +02:00
Rıdvan Akca
ee6c9fa5d4 feat(invoice-ninja): add invoice ninja integration 2023-10-09 16:06:00 +03:00
Ömer Faruk Aydın
1369bb095f Merge pull request #1324 from automatisch/placetel
feat(placetel): Implement app structure with authentication
2023-10-09 14:19:58 +02:00
Faruk AYDIN
c786d7549a refactor(placetel): No need to stringify call ID 2023-10-09 14:11:39 +02:00
Faruk AYDIN
b59840cb77 feat(placetel): Add types to hungup call trigger 2023-10-09 12:49:59 +02:00
Faruk AYDIN
265d57d8b7 refactor(placetel): Remove redundant header variable 2023-10-09 12:18:55 +02:00
Faruk AYDIN
5eed84f9e5 feat: Add run method to placetel hungup trigger 2023-10-09 12:18:11 +02:00
Faruk AYDIN
0a334dff1d docs(placetel): Add connection and triggers pages 2023-10-09 12:17:23 +02:00
Faruk AYDIN
5fff9bdc02 chore(placetel): Add missing type file 2023-10-09 12:17:23 +02:00
Faruk AYDIN
a9fd261bab refactor: Use json parser when content type is not specified 2023-10-09 12:17:23 +02:00
Faruk AYDIN
ef087be4f0 feat(placetel): Add hungup call trigger 2023-10-09 12:17:23 +02:00
Faruk AYDIN
2099978b8f fix: Add fields from substeps to getApps query 2023-10-09 12:17:23 +02:00
Faruk AYDIN
712bee297a feat(placetel): Implement app structure with authentication 2023-10-09 12:17:23 +02:00
Ömer Faruk Aydın
57bba90091 Merge pull request #1332 from automatisch/webhook-body
feat: Add run method to webhook triggers
2023-10-09 12:12:39 +02:00
Faruk AYDIN
d877f5c764 refactor: Use trigger queue for webhook handler 2023-10-09 12:05:45 +02:00
Faruk AYDIN
4c66cc1e33 feat: Adjust webhook handler to work with run method 2023-10-08 15:51:59 +02:00
Faruk AYDIN
27a3edeb93 feat: Add run method to webhook triggers 2023-10-07 18:46:25 +02:00
Ali BARIN
f79fc29203 chore: add mock license server 2023-10-06 14:39:11 +02:00
Ali BARIN
174240a220 refactor: add useEnqueueSnackbar with data-test attr 2023-10-06 12:28:09 +02:00
Ömer Faruk Aydın
60d8af5c16 Merge pull request #1321 from automatisch/AUT-310
feat(pipedrive): add create lead action
2023-10-06 11:40:04 +02:00
Faruk AYDIN
627a5892f1 chore: Add description to Pipedrive create lead fields 2023-10-06 11:33:52 +02:00
Ömer Faruk Aydın
7767f6d9cc Merge pull request #1322 from automatisch/salesforce/api-request
feat(salesforce): Implement execute query action
2023-10-05 16:12:42 +02:00
Faruk AYDIN
9729fd6b15 feat(salesforce): Implement execute query action 2023-10-05 15:23:48 +02:00
Rıdvan Akca
17916f29f6 feat(pipedrive): add create lead action 2023-10-05 14:12:37 +03:00
kattoczko
584b9323ec feat: introduce admin apps page (#1296)
* feat: introduce admin apps page

* feat: add access restriction and fix incorrectly placed key prop
2023-10-05 10:55:00 +02:00
Ömer Faruk Aydın
82c1aadfa9 Merge pull request #1319 from automatisch/refactor-get-user-tests
refactor: Use fixtures for getUser graphQL tests
2023-10-05 10:25:49 +02:00
Faruk AYDIN
bd497af89b test: Add case to getUser to not return user password 2023-10-04 21:01:16 +02:00
Faruk AYDIN
1683c5630a test: Add types to getUser test file 2023-10-04 21:01:16 +02:00
Faruk AYDIN
b5df1a026a chore: Use snake case test mappers for test env 2023-10-04 21:01:16 +02:00
Faruk AYDIN
b290c32aeb refactor: Use shared requestObject for getUser tests 2023-10-04 21:01:16 +02:00
Faruk AYDIN
a29b3c6db4 refactor: Use fixtures for getUser graphQL tests 2023-10-04 21:01:16 +02:00
Faruk AYDIN
ffb2f4f5db refactor: Use unauthorized user describe block for getUser tests 2023-10-04 21:01:16 +02:00
Faruk AYDIN
24c95f4801 refactor: Remove reduntant global knex instance 2023-10-04 21:01:16 +02:00
Ömer Faruk Aydın
1aaec2d555 Merge pull request #1317 from automatisch/AUT-306
feat(pipedrive): add create activity action
2023-10-04 20:55:43 +02:00
Rıdvan Akca
fedb198ae7 feat(pipedrive): add create activity action 2023-10-04 13:31:39 +03:00
Ömer Faruk Aydın
add654ccac Merge pull request #1314 from automatisch/get-user-test
feat: Implement getUser graphQL query test
2023-10-04 12:19:12 +02:00
Faruk AYDIN
5a578643a6 feat: Implement getUser graphQL query test 2023-10-04 11:52:39 +02:00
Faruk AYDIN
f0712bd213 feat: Adjust global hooks to work with both knex and objection 2023-10-04 11:48:38 +02:00
Faruk AYDIN
f490632722 refactor: Login mutation with create auth token helper 2023-10-04 11:46:18 +02:00
Faruk AYDIN
2610b96762 chore: Install supertest and faker libraries for tests 2023-10-04 11:46:18 +02:00
Ömer Faruk Aydın
8d90cb834d Merge pull request #1312 from automatisch/global-test-hooks
feat: Add global hooks for jest
2023-10-04 11:45:37 +02:00
Faruk AYDIN
9d92509796 fix: Disable eslint no-var while overriding global 2023-10-03 23:40:12 +02:00
Faruk AYDIN
04a78ee0ba feat: Add types knex field of global 2023-10-03 23:40:12 +02:00
Faruk AYDIN
3703390268 chore: Adjust global and knex types for global hooks 2023-10-03 23:40:12 +02:00
Faruk AYDIN
4ab6415f49 feat: Migrate test database within pretest script 2023-10-03 23:40:12 +02:00
Faruk AYDIN
9228722147 chore: Use ts migration files also for test env 2023-10-03 23:40:12 +02:00
Faruk AYDIN
0e5529b4ca feat: Add global hooks for jest 2023-10-03 23:40:12 +02:00
Ömer Faruk Aydın
4d454ec932 Merge pull request #1313 from automatisch/AUT-303
feat(pipedrive): add create note action
2023-10-02 17:50:42 +02:00
Rıdvan Akca
a9282ad118 feat(pipedrive): add create note action 2023-10-02 16:19:07 +03:00
Ömer Faruk Aydın
0e959641af Merge pull request #1310 from automatisch/test-setup
feat: Introduce jest for backend tests
2023-09-30 15:02:01 +02:00
Faruk AYDIN
13263eea76 feat: Introduce jest for backend tests 2023-09-30 14:31:01 +02:00
Faruk AYDIN
1a3418de58 chore: Remove ava from test setup 2023-09-30 14:17:47 +02:00
Ömer Faruk Aydın
4402995132 Merge pull request #1133 from automatisch/sandbox-emails
chore: Allow only automatisch emails for non-prod cloud envs
2023-09-30 13:25:18 +02:00
Ömer Faruk Aydın
4e33f9875b Merge pull request #1307 from automatisch/pipedrive-create-deal
feat(pipedrive): add create deal action
2023-09-30 13:20:43 +02:00
Faruk AYDIN
ed2893e37f fix(pipedrive): Add guard for not having any organizations 2023-09-30 13:13:21 +02:00
Rıdvan Akca
c35be241ca feat(pipedrive): add create deal action 2023-09-30 13:05:09 +02:00
Ömer Faruk Aydın
aad0b4ddfe Merge pull request #1302 from automatisch/miro-create-card-widget
feat(miro): add create card widget action
2023-09-30 10:48:25 +02:00
Rıdvan Akca
52f5c7ddb5 feat(miro): add create card widget action 2023-09-29 21:39:30 +02:00
Kasia
a04b933161 refactor: introduce useApps hook 2023-09-29 17:03:36 +02:00
kattoczko
c77e12edbb fix: consider null as value in step parameters (#1282) 2023-09-29 16:33:45 +02:00
Ömer Faruk Aydın
108bd04cf8 Merge pull request #1301 from automatisch/miro-copy-board
feat(miro): add copy board action
2023-09-29 12:52:25 +02:00
Rıdvan Akca
a95b500e42 feat(miro): add copy board action 2023-09-29 12:46:36 +02:00
Ömer Faruk Aydın
c2744c5569 Merge pull request #1300 from automatisch/miro-integration
feat(miro): add create board action
2023-09-29 12:45:05 +02:00
Faruk AYDIN
a1dfd87bbe docs(miro): Add to available apps 2023-09-29 12:31:33 +02:00
Rıdvan Akca
221aa8687f feat(miro): add create board action 2023-09-29 12:17:21 +02:00
Rıdvan Akca
fa8ac0a8ba feat(miro): add miro integration 2023-09-29 12:17:21 +02:00
Ömer Faruk Aydın
cc1f9873cb Merge pull request #1299 from automatisch/pipedrive-new-lead
feat(pipedrive): add new leads trigger
2023-09-29 12:15:28 +02:00
Rıdvan Akca
3cae9ee5d2 feat(pipedrive): add new leads trigger 2023-09-29 12:06:56 +02:00
Ömer Faruk Aydın
f764914adb Merge pull request #1298 from automatisch/pipedrive-new-activity
feat(pipedrive): add new activities trigger
2023-09-29 12:04:29 +02:00
Rıdvan Akca
991250c73f feat(pipedrive): add new activities trigger 2023-09-29 11:57:11 +02:00
Ömer Faruk Aydın
af46cf5ce8 Merge pull request #1297 from automatisch/pipedrive-new-note
feat(pipedrive): add new notes trigger
2023-09-29 11:53:10 +02:00
Faruk AYDIN
dbb1c42c47 fix(pipedrive): Skip adding auth header for refresh token 2023-09-29 11:44:35 +02:00
Rıdvan Akca
991f593b2e feat(pipedrive): add new notes trigger 2023-09-29 11:44:35 +02:00
Ömer Faruk Aydın
e43c083d50 Merge pull request #1305 from automatisch/fix-user-creation
fix: use default role for fallback user creation
2023-09-29 10:39:29 +02:00
Ömer Faruk Aydın
3cd9bdc1d4 Merge pull request #1304 from automatisch/new-calendars
feat(google-calendar): Add max results option to new calendar trigger
2023-09-28 17:00:51 +02:00
Ali BARIN
c0b8e6178d fix: use default role for fallback user creation 2023-09-28 14:49:49 +00:00
Ömer Faruk Aydın
410f9d0af5 Merge pull request #1291 from automatisch/google-calendar-new-event
feat(google-calendar): add new event trigger
2023-09-28 16:16:32 +02:00
Ömer Faruk Aydın
b1fedf28dc Merge branch 'main' into google-calendar-new-event 2023-09-28 16:06:08 +02:00
Faruk AYDIN
b0df03dcd2 feat(google-calendar): Add max results option to new calendar trigger 2023-09-28 15:10:36 +02:00
Ömer Faruk Aydın
2794e50a19 Merge pull request #1294 from automatisch/pipedrive-integration
feat(pipedrive): add new deals trigger
2023-09-28 15:09:17 +02:00
Faruk AYDIN
365ae656f2 fix(pipedrive): Adjust description of OAuth redirect URL 2023-09-28 15:01:35 +02:00
Faruk AYDIN
98649dcba6 fix(pipedrive): Guard new deals response in case there is none 2023-09-28 15:00:34 +02:00
Faruk AYDIN
213c8096d2 fix(pipedrive): Change the order in available apps 2023-09-28 15:00:34 +02:00
Faruk AYDIN
398938f27e feat(pipedrive): Use also company domain for screen name 2023-09-28 15:00:34 +02:00
Faruk AYDIN
6378e62645 docs(pipedrive): Add to available apps 2023-09-28 15:00:34 +02:00
Rıdvan Akca
251885d4be feat(pipedrive): add new deals trigger 2023-09-28 15:00:34 +02:00
Rıdvan Akca
f53909355f feat(pipedrive): add pipedrive integration 2023-09-28 15:00:34 +02:00
Rıdvan Akca
242b68889a feat(google-calendar): add new event trigger 2023-09-28 15:52:53 +03:00
Ömer Faruk Aydın
6a66b65f2a Merge pull request #1290 from automatisch/google-calendar-new-calendar-trigger
feat(google-calendar): add new calendar trigger
2023-09-28 13:45:41 +02:00
Faruk AYDIN
f30ead6bcb docs(google-calendar): Add to available apps 2023-09-28 13:37:32 +02:00
Faruk AYDIN
237ee72ca6 feat(google-calendar): Use etag as internal id instead of id 2023-09-28 13:29:39 +02:00
Faruk AYDIN
3590d84ad6 fix(google-calendar): Reverse order the response data of new calendars 2023-09-28 13:28:58 +02:00
Rıdvan Akca
2dae8c162d feat(google-calendar): add new calendar trigger 2023-09-18 15:17:05 +03:00
Rıdvan Akca
9a192b708e feat(google-calendar): add google calendar integration 2023-09-18 15:12:29 +03:00
Rıdvan Akca
c193f9334f feat(wordpress): add new comment trigger 2023-09-15 18:33:38 +02:00
Rıdvan Akca
6e682dc752 fix(create-role): check isCreator by default when permissioon is checked 2023-09-15 15:32:52 +02:00
Rıdvan Akca
da86fe56bd feat(wordpress): add new page trigger 2023-09-15 13:05:41 +02:00
Ali BARIN
45865d701a chore: embed env. vars. for playwright actions 2023-09-15 12:56:15 +02:00
Ömer Faruk Aydın
a66a31b474 Merge pull request #1284 from automatisch/tests/ava
feat: Introduce backend test suite with ava
2023-09-14 12:43:45 +02:00
Faruk AYDIN
2661e7102f feat: Add env file existince check for test suite 2023-09-14 12:25:09 +02:00
Faruk AYDIN
224965b91e feat: Introduce backend test suite with ava 2023-09-14 11:56:53 +02:00
Ömer Faruk Aydın
a9c7375534 Merge pull request #1279 from automatisch/feature/hubspot
feat(hubspot): Implement create contact action
2023-09-14 11:52:18 +02:00
Faruk AYDIN
e77f7ee0bf docs(hubspot): Order alphabetically & correct connection name typo 2023-09-13 23:39:34 +02:00
Faruk AYDIN
ae5dd0cad6 fix(hubspot): Remove redundant field descriptions 2023-09-13 23:16:23 +02:00
Faruk AYDIN
a128907a4e fix(hubspot): Correct website URL typo and primary color 2023-09-13 23:16:23 +02:00
Faruk AYDIN
d6453a8ed0 chore: Use camelCase convention for hubspot actions 2023-09-13 23:16:23 +02:00
Faruk AYDIN
dd1e8240b8 feat(hubspot): Implement verify credentials for OAuth 2023-09-13 23:16:23 +02:00
Faruk AYDIN
b12f39916f feat(hubspot): Implement generate auth url for OAuth 2023-09-13 23:16:23 +02:00
Faruk AYDIN
aae88fe1ad docs(hubspot): Adjust connection page for OAuth setup 2023-09-13 23:16:23 +02:00
Faruk AYDIN
83bb400df1 chore: Change hubspot auth doc url 2023-09-13 23:16:23 +02:00
Vitalii Mykytiuk
8ea8067788 feat(hubspot): Implement create contact action 2023-09-13 23:16:23 +02:00
Rıdvan Akca
9fbc9d59f5 feat: make authentication role mappings emptiable 2023-09-13 22:32:18 +02:00
Ali BARIN
b96ba69a72 chore: run GH actions on push to main branch 2023-09-13 22:25:20 +02:00
Faruk AYDIN
c4ccab6a5d chore: Run CI builds only for pull requests 2023-09-13 22:25:20 +02:00
Rıdvan Akca
f84f27bb56 feat(user-interface): introduce optimistic response 2023-09-13 22:10:47 +02:00
Ömer Faruk Aydın
416cc0ffa9 Merge pull request #1280 from automatisch/node-version
chore: Add .node-version and .nvmrc files to the root
2023-09-13 12:41:37 +02:00
Faruk AYDIN
1fd5ec4db6 chore: Add .node-version and .nvmrc files to the root 2023-09-13 12:36:20 +02:00
Rıdvan Akca
4795c35c68 feat(create-role): make isCreator condition checked by default (#1276) 2023-09-11 15:28:47 +02:00
Rıdvan Akca
25ce63b86d feat(user-interface): use default config as fallback (#1251)
* feat(user-interface): return default app values

* test: remove skip in UI tests

---------

Co-authored-by: Ali BARIN <ali.barin53@gmail.com>
2023-09-11 14:06:05 +02:00
Ömer Faruk Aydın
5271033d34 Merge pull request #1275 from automatisch/docs/formatter
docs(formatter): Add numbers and date-time actions
2023-09-11 10:05:44 +02:00
Faruk AYDIN
6ba8f33399 docs(formatter): Add numbers and date-time actions 2023-09-11 09:57:50 +02:00
Ali BARIN
7ab79bd815 Merge pull request #1273 from automatisch/role-mappings 2023-09-10 10:48:34 +02:00
Faruk AYDIN
04a0a847c7 fix: Check role mappings data with isEmpty method 2023-09-10 10:43:08 +02:00
Ali BARIN
436fa9af69 Merge pull request #1267 from automatisch/AUT-276
feat(user-interface): add title field
2023-09-08 21:04:58 +02:00
Ali BARIN
ca0bbb0f08 Merge pull request #1270 from automatisch/feat/random-number
feat(formatter): add decimal point to random number transformer
2023-09-08 21:02:10 +02:00
Ali BARIN
88996144a5 Merge pull request #1269 from automatisch/formatter/date-format
feat(formatter): Implement format date time transformer
2023-09-08 17:27:36 +02:00
Faruk AYDIN
44d5eee99e feat(formatter): Implement format date time transformer for date time action 2023-09-08 13:10:09 +00:00
Ali BARIN
0d1ff6074f Merge pull request #1266 from automatisch/numbers/format-number
feat(formatter): Add format number transformer to numbers action
2023-09-08 15:09:21 +02:00
kattoczko
d63757634a feat: introduce role mappings form on authentication page (#1256) 2023-09-08 14:09:53 +02:00
Faruk AYDIN
fd61cf3388 feat(formatter): Add decimal point to random number transformer 2023-09-06 17:06:13 +02:00
Faruk AYDIN
a6a6b63e5a feat(formatter): Add format number transformer to numbers action 2023-09-05 16:10:39 +02:00
Rıdvan Akca
c02c2def29 feat(user-interface): add title field 2023-09-05 17:10:01 +03:00
Ömer Faruk Aydın
ff66548462 feat(formatter): add random number transformer to numbers action (#1265) 2023-09-05 16:08:30 +02:00
Ömer Faruk Aydın
c9f292e252 feat(formatter): add number action with math operation transformer (#1264)
* feat(formatter): Add number action with math operation transformer

* chore: Use different folders for list transform options of formatter
2023-09-05 13:02:43 +02:00
Faruk AYDIN
18cef5f3bd chore: Sort formatter text transformers alphabetically 2023-09-01 18:02:14 +02:00
Faruk AYDIN
e19340f1e0 feat(formatter): Add replace transformer to text action 2023-09-01 18:02:14 +02:00
Ömer Faruk Aydın
feb613cb6d docs: add upgrade guide for docker compose installation (#1262) 2023-09-01 17:53:21 +02:00
Ömer Faruk Aydın
afa6bdfa44 feat(formatter): add trim whitespace transformer to text action (#1261) 2023-09-01 14:07:50 +02:00
Ömer Faruk Aydın
200e6d9905 feat(formatter): add pluralize transformer for text action (#1260) 2023-09-01 13:37:35 +02:00
Ömer Faruk Aydın
70772c49bd feat(formatter): add lowercase to text transformers (#1259) 2023-09-01 13:26:15 +02:00
Ömer Faruk Aydın
762ea97e8b Merge pull request #1258 from automatisch/release/0.9.3
Release v0.9.3
2023-09-01 12:55:35 +02:00
Faruk AYDIN
8156b8b356 Release v0.9.3 2023-09-01 12:35:19 +02:00
Faruk AYDIN
3a2cbae0a0 chore: Update version to 0.9.3 in Dockerfiles 2023-09-01 12:34:25 +02:00
Ömer Faruk Aydın
0ad8da097b fix(rss): get text for internal ID if the guid or id is object (#1257) 2023-09-01 12:10:42 +02:00
Ömer Faruk Aydın
e2dcdd2811 feat(formatter): add extract number transform to text action (#1255) 2023-08-31 16:35:28 +02:00
Ömer Faruk Aydın
8074f9146b Merge pull request #1253 from automatisch/refactor-notifications
refactor: fetch notifications over graphql query
2023-08-29 16:37:37 +02:00
Ali BARIN
df24bac913 refactor: fetch notifications over graphql query 2023-08-28 20:44:55 +00:00
Ali BARIN
4d4091adcc test: write login page tests 2023-08-28 20:11:21 +02:00
Ali BARIN
cac54c41a1 chore: run automatisch in playwright workflow 2023-08-28 20:11:21 +02:00
Ali BARIN
130931d7af fix: use axios with proxy in license check (#1252) 2023-08-28 17:19:19 +02:00
Ömer Faruk Aydın
d35b08b35e Merge pull request #1250 from automatisch/release/0.9.2
Release v0.9.2
2023-08-28 16:54:32 +02:00
Faruk AYDIN
82031da6a6 Release v0.9.2 2023-08-28 16:30:29 +02:00
Faruk AYDIN
9df5ee7b11 chore: Update version to 0.9.2 in Dockerfiles 2023-08-28 16:29:53 +02:00
Ömer Faruk Aydın
2ed1a57cd9 Merge pull request #1249 from automatisch/permission-contions
chore: Convert conditions of permissions to array
2023-08-28 16:27:29 +02:00
Faruk AYDIN
101450cba6 chore: Convert conditions of permissions to array 2023-08-28 16:24:39 +02:00
Ömer Faruk Aydın
6bab5b3f7c Merge pull request #1248 from automatisch/release/0.9.1
Release v0.9.1
2023-08-28 15:15:25 +02:00
Faruk AYDIN
ca3c0e00a7 Release v0.9.1 2023-08-28 14:47:05 +02:00
Faruk AYDIN
6d64daf324 chore: Update version to 0.9.1 in Dockerfiles 2023-08-28 14:46:26 +02:00
Ömer Faruk Aydın
9ae4578e19 Merge pull request #1247 from automatisch/remove-api-url
chore(web): Remove API url env variable
2023-08-28 14:44:41 +02:00
Faruk AYDIN
e06b7ab87a chore(web): Remove API url env variable 2023-08-28 14:37:10 +02:00
Ömer Faruk Aydın
1e2adedcbf Merge pull request #1246 from automatisch/release/0.9.0
Release v0.9.0
2023-08-28 13:34:24 +02:00
Faruk AYDIN
adf763c1b0 Release v0.9.0 2023-08-28 13:13:23 +02:00
Faruk AYDIN
36ee0df256 chore: Update version to 0.9.0 in Dockerfiles 2023-08-28 13:06:20 +02:00
Rıdvan Akca
823d85b24a feat(custom-logo): constraint svg logo dimensions (#1243) 2023-08-25 21:43:53 +02:00
Rıdvan Akca
a3b3038709 test(user-interface-configuration): write initial tests (#1242)
* test(user-interface): add tests with playwright

* test: refactor UI configuration tests

---------

Co-authored-by: Ali BARIN <ali.barin53@gmail.com>
2023-08-25 21:31:02 +02:00
kattoczko
ddeb18f626 feat: introduce authentication page (#1241)
* feat: introduce authentication page

* feat: update page width

* fix(saml): cover non-existing role mapping on onboarding

---------

Co-authored-by: Ali BARIN <ali.barin53@gmail.com>
2023-08-25 15:24:50 +02:00
Rıdvan Akca
90cd11bd38 feat: align admin pages vertically (#1240) 2023-08-24 16:34:18 +02:00
Ömer Faruk Aydın
e9ba37b8de fix: use withSoftDeleted scope to remove user associations permanently (#1239) 2023-08-24 16:34:07 +02:00
Faruk AYDIN
d5e4a1b1ad fix: Soft delete existing associations of soft deleted users 2023-08-24 15:05:54 +02:00
Faruk AYDIN
129e6d60e5 fix: Remove all related records when user is deleted 2023-08-24 15:05:54 +02:00
Faruk AYDIN
4b77f2f590 fix: Remove deleted flows from Redis 2023-08-24 15:05:54 +02:00
Rıdvan Akca
a909966562 feat(executions): display execution step id (#1232)
* feat(executions): display execution step id

* refactor: remove conditional components in execution steps

---------

Co-authored-by: Ali BARIN <ali.barin53@gmail.com>
2023-08-23 21:53:16 +02:00
Ömer Faruk Aydın
fd184239d6 Merge pull request #1233 from automatisch/enhance-variable-coverage
feat: enhance step variable coverage
2023-08-23 12:35:07 +02:00
Ali BARIN
52bc49dc6a feat: enhance step variable coverage 2023-08-22 16:17:20 +02:00
Ali BARIN
b9352ccc06 fix(mutations/update-flow-status): correct permission check 2023-08-22 16:17:20 +02:00
Ali BARIN
525b2baf06 fix(mutations/execute-flow): correct permission check 2023-08-22 16:17:20 +02:00
Ali BARIN
a8edeb2459 fix(mutations/update-step): correct permission check 2023-08-22 16:17:20 +02:00
Ali BARIN
e3830d64e0 feat: add getSamlAuthProviderRoleMappings query (#1229) 2023-08-22 14:50:01 +02:00
Ali BARIN
91f3e2c2b4 feat: make user.role_id not nullable (#1217) 2023-08-22 14:49:53 +02:00
Ali BARIN
77b4408416 chore: correct e2e test results path in GH actions (#1231) 2023-08-22 10:57:40 +03:00
QAComet
cede96f018 test: refactor create flow test cases with test.step (#1228) 2023-08-22 00:27:10 +02:00
dependabot[bot]
8e0a28d238 chore(deps): bump @node-saml/node-saml from 4.0.4 to 4.0.5 (#1227)
Bumps [@node-saml/node-saml](https://github.com/node-saml/node-saml) from 4.0.4 to 4.0.5.
- [Release notes](https://github.com/node-saml/node-saml/releases)
- [Changelog](https://github.com/node-saml/node-saml/blob/v4.0.5/CHANGELOG.md)
- [Commits](https://github.com/node-saml/node-saml/compare/v4.0.4...v4.0.5)

---
updated-dependencies:
- dependency-name: "@node-saml/node-saml"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-21 23:35:38 +02:00
Rıdvan Akca
da5d594428 feat(user-interface): introduce user interface page (#1226) 2023-08-21 23:11:25 +02:00
kattoczko
9f9ee0bb58 feat: create clear button for ControlledCustomAutocomplete (#1222)
Co-authored-by: Ali BARIN <ali.barin53@gmail.com>
2023-08-21 22:52:59 +02:00
Rıdvan Akca
163aca6179 feat(user-list): add pagination (#1219)
* feat(user-list): add pagination

* feat: add actual total count in getUsers

---------

Co-authored-by: Ali BARIN <ali.barin53@gmail.com>
2023-08-21 21:15:07 +02:00
Ali BARIN
cb06d3b0ae test: add in-between assertions and more fixtures (#1224) 2023-08-18 18:34:52 +02:00
Ali BARIN
dbe18dd100 chore: configure login env. vars. in e2e test workflow (#1221) 2023-08-18 09:48:41 +02:00
Ali BARIN
217970667a chore: make e2e tests manually triggerable (#1220) 2023-08-18 10:25:43 +03:00
Rıdvan Akca
dace794167 feat: introduce playwright (#1194)
* feat: introduce playwright

* test: migrate apps folder to playwright (#1201)

* test: rewrite connections tests with playwright (#1203)

* test: rewrite executions tests with playwright (#1207)

* test: rewrite flow editor tests with playwright (#1212)

* test(flow-editor): rewrite tests using serial mode (#1218)

* test: update custom connection creation paths

* test: move login logic to page fixture

* test: remove cypress tests and deps

---------

Co-authored-by: Ali BARIN <ali.barin53@gmail.com>
2023-08-17 23:31:38 +02:00
Faruk AYDIN
337d22bbf4 chore: Allow only automatisch emails for non-prod cloud envs 2023-06-08 11:58:14 +02:00
455 changed files with 18094 additions and 4247 deletions

View File

@@ -29,7 +29,6 @@ rm -rf .env
echo "
PORT=$WEB_PORT
REACT_APP_GRAPHQL_URL=http://localhost:$BACKEND_PORT/graphql
REACT_APP_NOTIFICATIONS_URL=https://notifications.automatisch.io
" >> .env
cd $CURRENT_DIR

48
.github/workflows/backend.yml vendored Normal file
View File

@@ -0,0 +1,48 @@
name: Automatisch Backend Tests
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
jobs:
test:
timeout-minutes: 60
runs-on:
- ubuntu-latest
services:
postgres:
image: postgres:14.5-alpine
env:
POSTGRES_DB: automatisch_test
POSTGRES_USER: automatisch_test_user
POSTGRES_PASSWORD: automatisch_test_user_password
options: >-
--health-cmd "pg_isready -U automatisch_test_user -d automatisch_test"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis:7.0.4-alpine
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: cd packages/backend && yarn
- name: Copy .env-example.test file to .env.test
run: cd packages/backend && cp .env-example.test .env.test
- name: Run tests
run: cd packages/backend && yarn test

View File

@@ -1,5 +1,11 @@
name: Automatisch CI
on: [push]
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
jobs:
linter:
runs-on: ubuntu-latest

116
.github/workflows/playwright.yml vendored Normal file
View File

@@ -0,0 +1,116 @@
name: Automatisch UI Tests
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
env:
ENCRYPTION_KEY: sample_encryption_key
WEBHOOK_SECRET_KEY: sample_webhook_secret_key
APP_SECRET_KEY: sample_app_secret_key
POSTGRES_HOST: localhost
POSTGRES_DATABASE: automatisch
POSTGRES_PORT: 5432
POSTGRES_USERNAME: automatisch_user
POSTGRES_PASSWORD: automatisch_password
REDIS_HOST: localhost
APP_ENV: production
LICENSE_KEY: dummy_license_key
jobs:
test:
timeout-minutes: 60
runs-on:
- ubuntu-latest
services:
postgres:
image: postgres:14.5-alpine
env:
POSTGRES_DB: automatisch
POSTGRES_USER: automatisch_user
POSTGRES_PASSWORD: automatisch_password
options: >-
--health-cmd "pg_isready -U automatisch_user -d automatisch"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis:7.0.4-alpine
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: yarn && yarn lerna bootstrap
- name: Install Playwright Browsers
run: yarn playwright install --with-deps
- name: Build Automatisch
run: yarn lerna run --scope=@*/{web,backend,cli} build
env:
# Keep this until we clean up warnings in build processes
CI: false
- name: Migrate database
working-directory: ./packages/backend
run: yarn db:migrate --migrations-directory ./dist/src/db/migrations
- name: Seed user
working-directory: ./packages/backend
run: yarn db:seed:user &
- name: Install certutils
run: sudo apt install -y libnss3-tools
- name: Install mkcert
run: |
curl -JLO "https://dl.filippo.io/mkcert/latest?for=linux/amd64" \
&& chmod +x mkcert-v*-linux-amd64 \
&& sudo cp mkcert-v*-linux-amd64 /usr/local/bin/mkcert
- name: Install root certificate via mkcert
run: mkcert -install
- name: Create certificate
run: mkcert automatisch.io "*.automatisch.io" localhost 127.0.0.1 ::1
working-directory: ./packages/e2e-tests
- name: Set CAROOT environment variable
run: echo "NODE_EXTRA_CA_CERTS=$(mkcert -CAROOT)/rootCA.pem" >> "$GITHUB_ENV"
- name: Override license server with local server
run: sudo echo "127.0.0.1 license.automatisch.io" | sudo tee -a /etc/hosts
- name: Run local license server
working-directory: ./packages/e2e-tests
run: sudo yarn start-mock-license-server &
- name: Run Automatisch
run: yarn start &
working-directory: ./packages/backend
- name: Run Automatisch worker
run: node dist/src/worker.js &
working-directory: ./packages/backend
- name: Setup upterm session
if: false
uses: lhotari/action-upterm@v1
with:
limit-access-to-actor: true
limit-access-to-users: barinali
- name: Run Playwright tests
working-directory: ./packages/e2e-tests
env:
LOGIN_EMAIL: user@automatisch.io
LOGIN_PASSWORD: sample
BASE_URL: http://localhost:3000
GITHUB_CLIENT_ID: 1c0417daf898adfbd99a
GITHUB_CLIENT_SECRET: 3328fa814dd582ccd03dbe785cfd683fb8da92b3
run: yarn test
- uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: packages/e2e-tests/test-results
retention-days: 30

1
.node-version Normal file
View File

@@ -0,0 +1 @@
16.15.0

1
.nvmrc Normal file
View File

@@ -0,0 +1 @@
16.15.0

View File

@@ -1,4 +1,7 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}

View File

@@ -4,7 +4,7 @@ WORKDIR /automatisch
RUN \
apk --no-cache add --virtual build-dependencies python3 build-base && \
yarn global add @automatisch/cli@0.8.0 --network-timeout 1000000 && \
yarn global add @automatisch/cli@0.9.3 --network-timeout 1000000 && \
rm -rf /usr/local/share/.cache/ && \
apk del build-dependencies

View File

@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1
FROM automatischio/automatisch:0.8.0
FROM automatischio/automatisch:0.9.3
WORKDIR /automatisch
RUN apk add --no-cache openssl dos2unix

View File

@@ -2,7 +2,7 @@
"packages": [
"packages/*"
],
"version": "0.8.0",
"version": "0.9.3",
"npmClient": "yarn",
"useWorkspaces": true,
"command": {

View File

@@ -0,0 +1,15 @@
APP_ENV=test
HOST=localhost
PROTOCOL=http
PORT=3000
LOG_LEVEL=debug
ENCRYPTION_KEY=sample_encryption_key
WEBHOOK_SECRET_KEY=sample_webhook_secret_key
APP_SECRET_KEY=sample_app_secret_key
POSTGRES_HOST=localhost
POSTGRES_DATABASE=automatisch_test
POSTGRES_PORT=5432
POSTGRES_USERNAME=automatisch_test_user
POSTGRES_PASSWORD=automatisch_test_user_password
REDIS_HOST=localhost
AUTOMATISCH_CLOUD=true

View File

@@ -0,0 +1,7 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
setupFilesAfterEnv: ['./test/setup/global-hooks.ts'],
globalTeardown: './test/setup/global-teardown.ts',
};

View File

@@ -1,6 +1,7 @@
import { knexSnakeCaseMappers } from 'objection';
import appConfig from './src/config/app';
const fileExtension = appConfig.isDev ? 'ts' : 'js';
const fileExtension = appConfig.isDev || appConfig.isTest ? 'ts' : 'js';
const knexConfig = {
client: 'pg',
@@ -23,6 +24,7 @@ const knexConfig = {
seeds: {
directory: __dirname + '/src/db/seeds',
},
...(appConfig.isTest ? knexSnakeCaseMappers() : {}),
};
export default knexConfig;

View File

@@ -1,6 +1,6 @@
{
"name": "@automatisch/backend",
"version": "0.8.0",
"version": "0.9.3",
"license": "See LICENSE file",
"description": "The open source Zapier alternative. Build workflow automation without spending time and money.",
"scripts": {
@@ -9,7 +9,8 @@
"build": "tsc && yarn copy-statics",
"build:watch": "nodemon --watch 'src/**/*.ts' --watch 'bin/**/*.ts' --exec yarn build --ext ts",
"start": "node dist/src/server.js",
"test": "ava",
"pretest": "APP_ENV=test ts-node ./test/setup/prepare-test-env.ts",
"test": "APP_ENV=test jest --verbose",
"lint": "eslint . --ignore-path ../../.eslintignore",
"db:create": "ts-node ./bin/database/create.ts",
"db:seed:user": "ts-node ./bin/database/seed-user.ts",
@@ -22,7 +23,7 @@
"prebuild": "rm -rf ./dist"
},
"dependencies": {
"@automatisch/web": "^0.8.0",
"@automatisch/web": "^0.9.3",
"@bull-board/express": "^3.10.1",
"@casl/ability": "^6.5.0",
"@graphql-tools/graphql-file-loader": "^7.3.4",
@@ -31,9 +32,11 @@
"@rudderstack/rudder-sdk-node": "^1.1.2",
"@sentry/node": "^7.42.0",
"@sentry/tracing": "^7.42.0",
"@types/accounting": "^0.4.2",
"@types/luxon": "^2.3.1",
"@types/passport": "^1.0.12",
"@types/xmlrpc": "^1.3.7",
"accounting": "^0.4.1",
"ajv-formats": "^2.1.1",
"axios": "0.24.0",
"bcrypt": "^5.0.1",
@@ -57,6 +60,7 @@
"https-proxy-agent": "^7.0.1",
"jsonwebtoken": "^9.0.0",
"knex": "^2.4.0",
"libphonenumber-js": "^1.10.48",
"lodash.get": "^4.4.2",
"luxon": "2.5.2",
"memory-cache": "^0.2.0",
@@ -69,6 +73,8 @@
"passport": "^0.6.0",
"pg": "^8.7.1",
"php-serialize": "^4.0.2",
"pluralize": "^8.0.0",
"raw-body": "^2.5.2",
"showdown": "^2.1.0",
"stripe": "^11.13.0",
"winston": "^3.7.1",
@@ -110,13 +116,15 @@
"url": "https://github.com/automatisch/automatisch/issues"
},
"devDependencies": {
"@automatisch/types": "^0.8.0",
"@automatisch/types": "^0.9.3",
"@faker-js/faker": "^8.1.0",
"@types/bcrypt": "^5.0.0",
"@types/bull": "^3.15.8",
"@types/cors": "^2.8.12",
"@types/crypto-js": "^4.0.2",
"@types/express": "^4.17.15",
"@types/http-errors": "^1.8.1",
"@types/jest": "^29.5.5",
"@types/jsonwebtoken": "^8.5.8",
"@types/lodash.get": "^4.4.6",
"@types/memory-cache": "^0.2.2",
@@ -126,24 +134,17 @@
"@types/nodemailer": "^6.4.4",
"@types/pg": "^8.6.1",
"@types/pino": "^7.0.5",
"@types/pluralize": "^0.0.30",
"@types/showdown": "^2.0.1",
"ava": "^3.15.0",
"@types/supertest": "^2.0.14",
"jest": "^29.7.0",
"nodemon": "^2.0.13",
"sinon": "^11.1.2",
"supertest": "^6.3.3",
"ts-jest": "^29.1.1",
"ts-node": "^10.2.1",
"ts-node-dev": "^1.1.8"
},
"ava": {
"files": [
"test/**/*"
],
"extensions": [
"ts"
],
"require": [
"ts-node/register"
]
},
"publishConfig": {
"access": "public"
}

View File

@@ -33,6 +33,7 @@ injectBullBoardHandler(app, serverAdapter);
appAssetsHandler(app);
app.use(morgan);
app.use(
express.json({
limit: appConfig.requestBodySizeLimit,

View File

@@ -1,3 +1,4 @@
import Crypto from 'crypto';
import isEmpty from 'lodash/isEmpty';
import defineTrigger from '../../../../helpers/define-trigger';
import webhookFilters from '../../common/webhook-filters';
@@ -19,6 +20,17 @@ export default defineTrigger({
},
],
async run($) {
const dataItem = {
raw: $.request.body,
meta: {
internalId: Crypto.randomUUID(),
},
};
$.pushTriggerItem(dataItem);
},
async testRun($) {
const lastExecutionStep = await $.getLastExecutionStep();

View File

@@ -0,0 +1,49 @@
import defineAction from '../../../../helpers/define-action';
import formatDateTime from './transformers/format-date-time';
const transformers = {
formatDateTime,
};
export default defineAction({
name: 'Date / Time',
key: 'date-time',
description: 'Perform date and time related transformations on your data.',
arguments: [
{
label: 'Transform',
key: 'transform',
type: 'dropdown' as const,
required: true,
variables: true,
options: [{ label: 'Format Date / Time', value: 'formatDateTime' }],
additionalFields: {
type: 'query',
name: 'getDynamicFields',
arguments: [
{
name: 'key',
value: 'listTransformOptions',
},
{
name: 'parameters.transform',
value: '{parameters.transform}',
},
],
},
},
],
async run($) {
const transformerName = $.step.parameters
.transform as keyof typeof transformers;
const output = transformers[transformerName]($);
$.setActionItem({
raw: {
output,
},
});
},
});

View File

@@ -0,0 +1,23 @@
import { IGlobalVariable } from '@automatisch/types';
import { DateTime } from 'luxon';
const formatDateTime = ($: IGlobalVariable) => {
const input = $.step.parameters.input as string;
const fromFormat = $.step.parameters.fromFormat as string;
const fromTimezone = $.step.parameters.fromTimezone as string;
const inputDateTime = DateTime.fromFormat(input, fromFormat, {
zone: fromTimezone,
setZone: true,
});
const toFormat = $.step.parameters.toFormat as string;
const toTimezone = $.step.parameters.toTimezone as string;
const outputDateTime = inputDateTime.setZone(toTimezone).toFormat(toFormat);
return outputDateTime;
};
export default formatDateTime;

View File

@@ -1,3 +1,5 @@
import text from './text';
import numbers from './numbers';
import dateTime from './date-time';
export default [text];
export default [text, numbers, dateTime];

View File

@@ -0,0 +1,61 @@
import defineAction from '../../../../helpers/define-action';
import performMathOperation from './transformers/perform-math-operation';
import randomNumber from './transformers/random-number';
import formatNumber from './transformers/format-number';
import formatPhoneNumber from './transformers/format-phone-number';
const transformers = {
performMathOperation,
randomNumber,
formatNumber,
formatPhoneNumber,
};
export default defineAction({
name: 'Numbers',
key: 'numbers',
description:
'Transform numbers to perform math operations, generate random numbers, format numbers, and much more.',
arguments: [
{
label: 'Transform',
key: 'transform',
type: 'dropdown' as const,
required: true,
variables: true,
options: [
{ label: 'Perform Math Operation', value: 'performMathOperation' },
{ label: 'Random Number', value: 'randomNumber' },
{ label: 'Format Number', value: 'formatNumber' },
{ label: 'Format Phone Number', value: 'formatPhoneNumber' },
],
additionalFields: {
type: 'query',
name: 'getDynamicFields',
arguments: [
{
name: 'key',
value: 'listTransformOptions',
},
{
name: 'parameters.transform',
value: '{parameters.transform}',
},
],
},
},
],
async run($) {
const transformerName = $.step.parameters
.transform as keyof typeof transformers;
const output = transformers[transformerName]($);
$.setActionItem({
raw: {
output,
},
});
},
});

View File

@@ -0,0 +1,28 @@
import { IGlobalVariable } from '@automatisch/types';
import accounting from 'accounting';
const formatNumber = ($: IGlobalVariable) => {
const input = $.step.parameters.input as string;
const inputDecimalMark = $.step.parameters.inputDecimalMark as string;
const toFormat = $.step.parameters.toFormat as string;
const normalizedNumber = accounting.unformat(input, inputDecimalMark);
const decimalPart = normalizedNumber.toString().split('.')[1];
const precision = decimalPart ? decimalPart.length : 0;
if (toFormat === '0') {
// Comma for grouping & period for decimal
return accounting.formatNumber(normalizedNumber, precision, ',', '.');
} else if (toFormat === '1') {
// Period for grouping & comma for decimal
return accounting.formatNumber(normalizedNumber, precision, '.', ',');
} else if (toFormat === '2') {
// Space for grouping & period for decimal
return accounting.formatNumber(normalizedNumber, precision, ' ', '.');
} else if (toFormat === '3') {
// Space for grouping & comma for decimal
return accounting.formatNumber(normalizedNumber, precision, ' ', ',');
}
};
export default formatNumber;

View File

@@ -0,0 +1,24 @@
import { IGlobalVariable } from '@automatisch/types';
import parsePhoneNumber, { CountryCode } from 'libphonenumber-js';
const formatPhoneNumber = ($: IGlobalVariable) => {
const phoneNumber = $.step.parameters.phoneNumber as string;
const toFormat = $.step.parameters.toFormat as string;
const phoneNumberCountryCode = ($.step.parameters.phoneNumberCountryCode ||
'US') as CountryCode;
const parsedPhoneNumber = parsePhoneNumber(
phoneNumber,
phoneNumberCountryCode
);
if (toFormat === 'e164') {
return parsedPhoneNumber.format('E.164');
} else if (toFormat === 'international') {
return parsedPhoneNumber.formatInternational();
} else if (toFormat === 'national') {
return parsedPhoneNumber.formatNational();
}
};
export default formatPhoneNumber;

View File

@@ -0,0 +1,23 @@
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
import { add, divide, multiply, subtract } from 'lodash';
const mathOperation = ($: IGlobalVariable) => {
const mathOperation = $.step.parameters.mathOperation as string;
const values = ($.step.parameters.values as IJSONObject[]).map((value) =>
Number(value.input)
) as number[];
if (mathOperation === 'add') {
return values.reduce((acc, curr) => add(acc, curr), 0);
} else if (mathOperation === 'divide') {
return values.reduce((acc, curr) => divide(acc, curr));
} else if (mathOperation === 'makeNegative') {
return values.map((value) => -value);
} else if (mathOperation === 'multiply') {
return values.reduce((acc, curr) => multiply(acc, curr), 1);
} else if (mathOperation === 'subtract') {
return values.reduce((acc, curr) => subtract(acc, curr));
}
};
export default mathOperation;

View File

@@ -0,0 +1,15 @@
import { IGlobalVariable } from '@automatisch/types';
const randomNumber = ($: IGlobalVariable) => {
const lowerRange = Number($.step.parameters.lowerRange);
const upperRange = Number($.step.parameters.upperRange);
const decimalPoints = Number($.step.parameters.decimalPoints) || 0;
return Number(
(Math.random() * (upperRange - lowerRange) + lowerRange).toFixed(
decimalPoints
)
);
};
export default randomNumber;

View File

@@ -1,16 +1,27 @@
import defineAction from '../../../../helpers/define-action';
import capitalize from './transformers/capitalize';
import htmlToMarkdown from './transformers/html-to-markdown';
import markdownToHtml from './transformers/markdown-to-html';
import useDefaultValue from './transformers/use-default-value';
import extractEmailAddress from './transformers/extract-email-address';
import extractNumber from './transformers/extract-number';
import htmlToMarkdown from './transformers/html-to-markdown';
import lowercase from './transformers/lowercase';
import markdownToHtml from './transformers/markdown-to-html';
import pluralize from './transformers/pluralize';
import replace from './transformers/replace';
import trimWhitespace from './transformers/trim-whitespace';
import useDefaultValue from './transformers/use-default-value';
const transformers = {
capitalize,
htmlToMarkdown,
markdownToHtml,
useDefaultValue,
extractEmailAddress,
extractNumber,
htmlToMarkdown,
lowercase,
markdownToHtml,
pluralize,
replace,
trimWhitespace,
useDefaultValue,
};
export default defineAction({
@@ -24,14 +35,18 @@ export default defineAction({
key: 'transform',
type: 'dropdown' as const,
required: true,
description: 'Pick a channel to send the message to.',
variables: true,
options: [
{ label: 'Capitalize', value: 'capitalize' },
{ label: 'Convert HTML to Markdown', value: 'htmlToMarkdown' },
{ label: 'Convert Markdown to HTML', value: 'markdownToHtml' },
{ label: 'Use Default Value', value: 'useDefaultValue' },
{ label: 'Extract Email Address', value: 'extractEmailAddress' },
{ label: 'Extract Number', value: 'extractNumber' },
{ label: 'Lowercase', value: 'lowercase' },
{ label: 'Pluralize', value: 'pluralize' },
{ label: 'Replace', value: 'replace' },
{ label: 'Trim Whitespace', value: 'trimWhitespace' },
{ label: 'Use Default Value', value: 'useDefaultValue' },
],
additionalFields: {
type: 'query',

View File

@@ -0,0 +1,26 @@
import { IGlobalVariable } from '@automatisch/types';
const extractNumber = ($: IGlobalVariable) => {
const input = $.step.parameters.input as string;
// Example numbers that's supported:
// 123
// -123
// 123456
// -123456
// 121,234
// -121,234
// 121.234
// -121.234
// 1,234,567.89
// -1,234,567.89
// 1.234.567,89
// -1.234.567,89
const numberRegexp = /-?((\d{1,3})+\.?,?)+/g;
const numbers = input.match(numberRegexp);
return numbers ? numbers[0] : '';
};
export default extractNumber;

View File

@@ -0,0 +1,8 @@
import { IGlobalVariable } from '@automatisch/types';
const lowercase = ($: IGlobalVariable) => {
const input = $.step.parameters.input as string;
return input.toLowerCase();
};
export default lowercase;

View File

@@ -0,0 +1,9 @@
import { IGlobalVariable } from '@automatisch/types';
import pluralizeLibrary from 'pluralize';
const pluralize = ($: IGlobalVariable) => {
const input = $.step.parameters.input as string;
return pluralizeLibrary(input);
};
export default pluralize;

View File

@@ -0,0 +1,12 @@
import { IGlobalVariable } from '@automatisch/types';
const replace = ($: IGlobalVariable) => {
const input = $.step.parameters.input as string;
const find = $.step.parameters.find as string;
const replace = $.step.parameters.replace as string;
return input.replaceAll(find, replace);
};
export default replace;

View File

@@ -0,0 +1,8 @@
import { IGlobalVariable } from '@automatisch/types';
const trimWhitespace = ($: IGlobalVariable) => {
const input = $.step.parameters.input as string;
return input.trim();
};
export default trimWhitespace;

View File

@@ -0,0 +1,249 @@
const phoneNumberCountryCodes = [
{ label: 'Ascension Island', value: 'AC' },
{ label: 'Andorra', value: 'AD' },
{ label: 'United Arab Emirates', value: 'AE' },
{ label: 'Afghanistan', value: 'AF' },
{ label: 'Antigua & Barbuda', value: 'AG' },
{ label: 'Anguilla', value: 'AI' },
{ label: 'Albania', value: 'AL' },
{ label: 'Armenia', value: 'AM' },
{ label: 'Angola', value: 'AO' },
{ label: 'Argentina', value: 'AR' },
{ label: 'American Samoa', value: 'AS' },
{ label: 'Austria', value: 'AT' },
{ label: 'Australia', value: 'AU' },
{ label: 'Aruba', value: 'AW' },
{ label: 'Åland Islands', value: 'AX' },
{ label: 'Azerbaijan', value: 'AZ' },
{ label: 'Bosnia & Herzegovina', value: 'BA' },
{ label: 'Barbados', value: 'BB' },
{ label: 'Bangladesh', value: 'BD' },
{ label: 'Belgium', value: 'BE' },
{ label: 'Burkina Faso', value: 'BF' },
{ label: 'Bulgaria', value: 'BG' },
{ label: 'Bahrain', value: 'BH' },
{ label: 'Burundi', value: 'BI' },
{ label: 'Benin', value: 'BJ' },
{ label: 'St. Barthélemy', value: 'BL' },
{ label: 'Bermuda', value: 'BM' },
{ label: 'Brunei', value: 'BN' },
{ label: 'Bolivia', value: 'BO' },
{ label: 'Caribbean Netherlands', value: 'BQ' },
{ label: 'Brazil', value: 'BR' },
{ label: 'Bahamas', value: 'BS' },
{ label: 'Bhutan', value: 'BT' },
{ label: 'Botswana', value: 'BW' },
{ label: 'Belarus', value: 'BY' },
{ label: 'Belize', value: 'BZ' },
{ label: 'Canada', value: 'CA' },
{ label: 'Cocos (Keeling) Islands', value: 'CC' },
{ label: 'Congo - Kinshasa', value: 'CD' },
{ label: 'Central African Republic', value: 'CF' },
{ label: 'Congo - Brazzaville', value: 'CG' },
{ label: 'Switzerland', value: 'CH' },
{ label: 'Côte dIvoire', value: 'CI' },
{ label: 'Cook Islands', value: 'CK' },
{ label: 'Chile', value: 'CL' },
{ label: 'Cameroon', value: 'CM' },
{ label: 'China', value: 'CN' },
{ label: 'Colombia', value: 'CO' },
{ label: 'Costa Rica', value: 'CR' },
{ label: 'Cuba', value: 'CU' },
{ label: 'Cape Verde', value: 'CV' },
{ label: 'Curaçao', value: 'CW' },
{ label: 'Christmas Island', value: 'CX' },
{ label: 'Cyprus', value: 'CY' },
{ label: 'Czechia', value: 'CZ' },
{ label: 'Germany', value: 'DE' },
{ label: 'Djibouti', value: 'DJ' },
{ label: 'Denmark', value: 'DK' },
{ label: 'Dominica', value: 'DM' },
{ label: 'Dominican Republic', value: 'DO' },
{ label: 'Algeria', value: 'DZ' },
{ label: 'Ecuador', value: 'EC' },
{ label: 'Estonia', value: 'EE' },
{ label: 'Egypt', value: 'EG' },
{ label: 'Western Sahara', value: 'EH' },
{ label: 'Eritrea', value: 'ER' },
{ label: 'Spain', value: 'ES' },
{ label: 'Ethiopia', value: 'ET' },
{ label: 'Finland', value: 'FI' },
{ label: 'Fiji', value: 'FJ' },
{ label: 'Falkland Islands (Islas Malvinas)', value: 'FK' },
{ label: 'Micronesia', value: 'FM' },
{ label: 'Faroe Islands', value: 'FO' },
{ label: 'France', value: 'FR' },
{ label: 'Gabon', value: 'GA' },
{ label: 'United Kingdom', value: 'GB' },
{ label: 'Grenada', value: 'GD' },
{ label: 'Georgia', value: 'GE' },
{ label: 'French Guiana', value: 'GF' },
{ label: 'Guernsey', value: 'GG' },
{ label: 'Ghana', value: 'GH' },
{ label: 'Gibraltar', value: 'GI' },
{ label: 'Greenland', value: 'GL' },
{ label: 'Gambia', value: 'GM' },
{ label: 'Guinea', value: 'GN' },
{ label: 'Guadeloupe', value: 'GP' },
{ label: 'Equatorial Guinea', value: 'GQ' },
{ label: 'Greece', value: 'GR' },
{ label: 'Guatemala', value: 'GT' },
{ label: 'Guam', value: 'GU' },
{ label: 'Guinea-Bissau', value: 'GW' },
{ label: 'Guyana', value: 'GY' },
{ label: 'Hong Kong', value: 'HK' },
{ label: 'Honduras', value: 'HN' },
{ label: 'Croatia', value: 'HR' },
{ label: 'Haiti', value: 'HT' },
{ label: 'Hungary', value: 'HU' },
{ label: 'Indonesia', value: 'ID' },
{ label: 'Ireland', value: 'IE' },
{ label: 'Israel', value: 'IL' },
{ label: 'Isle of Man', value: 'IM' },
{ label: 'India', value: 'IN' },
{ label: 'British Indian Ocean Territory', value: 'IO' },
{ label: 'Iraq', value: 'IQ' },
{ label: 'Iran', value: 'IR' },
{ label: 'Iceland', value: 'IS' },
{ label: 'Italy', value: 'IT' },
{ label: 'Jersey', value: 'JE' },
{ label: 'Jamaica', value: 'JM' },
{ label: 'Jordan', value: 'JO' },
{ label: 'Japan', value: 'JP' },
{ label: 'Kenya', value: 'KE' },
{ label: 'Kyrgyzstan', value: 'KG' },
{ label: 'Cambodia', value: 'KH' },
{ label: 'Kiribati', value: 'KI' },
{ label: 'Comoros', value: 'KM' },
{ label: 'St. Kitts & Nevis', value: 'KN' },
{ label: 'North Korea', value: 'KP' },
{ label: 'South Korea', value: 'KR' },
{ label: 'Kuwait', value: 'KW' },
{ label: 'Cayman Islands', value: 'KY' },
{ label: 'Kazakhstan', value: 'KZ' },
{ label: 'Laos', value: 'LA' },
{ label: 'Lebanon', value: 'LB' },
{ label: 'St. Lucia', value: 'LC' },
{ label: 'Liechtenstein', value: 'LI' },
{ label: 'Sri Lanka', value: 'LK' },
{ label: 'Liberia', value: 'LR' },
{ label: 'Lesotho', value: 'LS' },
{ label: 'Lithuania', value: 'LT' },
{ label: 'Luxembourg', value: 'LU' },
{ label: 'Latvia', value: 'LV' },
{ label: 'Libya', value: 'LY' },
{ label: 'Morocco', value: 'MA' },
{ label: 'Monaco', value: 'MC' },
{ label: 'Moldova', value: 'MD' },
{ label: 'Montenegro', value: 'ME' },
{ label: 'St. Martin', value: 'MF' },
{ label: 'Madagascar', value: 'MG' },
{ label: 'Marshall Islands', value: 'MH' },
{ label: 'North Macedonia', value: 'MK' },
{ label: 'Mali', value: 'ML' },
{ label: 'Myanmar (Burma)', value: 'MM' },
{ label: 'Mongolia', value: 'MN' },
{ label: 'Macao', value: 'MO' },
{ label: 'Northern Mariana Islands', value: 'MP' },
{ label: 'Martinique', value: 'MQ' },
{ label: 'Mauritania', value: 'MR' },
{ label: 'Montserrat', value: 'MS' },
{ label: 'Malta', value: 'MT' },
{ label: 'Mauritius', value: 'MU' },
{ label: 'Maldives', value: 'MV' },
{ label: 'Malawi', value: 'MW' },
{ label: 'Mexico', value: 'MX' },
{ label: 'Malaysia', value: 'MY' },
{ label: 'Mozambique', value: 'MZ' },
{ label: 'Namibia', value: 'NA' },
{ label: 'New Caledonia', value: 'NC' },
{ label: 'Niger', value: 'NE' },
{ label: 'Norfolk Island', value: 'NF' },
{ label: 'Nigeria', value: 'NG' },
{ label: 'Nicaragua', value: 'NI' },
{ label: 'Netherlands', value: 'NL' },
{ label: 'Norway', value: 'NO' },
{ label: 'Nepal', value: 'NP' },
{ label: 'Nauru', value: 'NR' },
{ label: 'Niue', value: 'NU' },
{ label: 'New Zealand', value: 'NZ' },
{ label: 'Oman', value: 'OM' },
{ label: 'Panama', value: 'PA' },
{ label: 'Peru', value: 'PE' },
{ label: 'French Polynesia', value: 'PF' },
{ label: 'Papua New Guinea', value: 'PG' },
{ label: 'Philippines', value: 'PH' },
{ label: 'Pakistan', value: 'PK' },
{ label: 'Poland', value: 'PL' },
{ label: 'St. Pierre & Miquelon', value: 'PM' },
{ label: 'Puerto Rico', value: 'PR' },
{ label: 'Palestine', value: 'PS' },
{ label: 'Portugal', value: 'PT' },
{ label: 'Palau', value: 'PW' },
{ label: 'Paraguay', value: 'PY' },
{ label: 'Qatar', value: 'QA' },
{ label: 'Réunion', value: 'RE' },
{ label: 'Romania', value: 'RO' },
{ label: 'Serbia', value: 'RS' },
{ label: 'Russia', value: 'RU' },
{ label: 'Rwanda', value: 'RW' },
{ label: 'Saudi Arabia', value: 'SA' },
{ label: 'Solomon Islands', value: 'SB' },
{ label: 'Seychelles', value: 'SC' },
{ label: 'Sudan', value: 'SD' },
{ label: 'Sweden', value: 'SE' },
{ label: 'Singapore', value: 'SG' },
{ label: 'St. Helena', value: 'SH' },
{ label: 'Slovenia', value: 'SI' },
{ label: 'Svalbard & Jan Mayen', value: 'SJ' },
{ label: 'Slovakia', value: 'SK' },
{ label: 'Sierra Leone', value: 'SL' },
{ label: 'San Marino', value: 'SM' },
{ label: 'Senegal', value: 'SN' },
{ label: 'Somalia', value: 'SO' },
{ label: 'Suriname', value: 'SR' },
{ label: 'South Sudan', value: 'SS' },
{ label: 'São Tomé & Príncipe', value: 'ST' },
{ label: 'El Salvador', value: 'SV' },
{ label: 'Sint Maarten', value: 'SX' },
{ label: 'Syria', value: 'SY' },
{ label: 'Eswatini', value: 'SZ' },
{ label: 'Tristan da Cunha', value: 'TA' },
{ label: 'Turks & Caicos Islands', value: 'TC' },
{ label: 'Chad', value: 'TD' },
{ label: 'Togo', value: 'TG' },
{ label: 'Thailand', value: 'TH' },
{ label: 'Tajikistan', value: 'TJ' },
{ label: 'Tokelau', value: 'TK' },
{ label: 'Timor-Leste', value: 'TL' },
{ label: 'Turkmenistan', value: 'TM' },
{ label: 'Tunisia', value: 'TN' },
{ label: 'Tonga', value: 'TO' },
{ label: 'Türkiye', value: 'TR' },
{ label: 'Trinidad & Tobago', value: 'TT' },
{ label: 'Tuvalu', value: 'TV' },
{ label: 'Taiwan', value: 'TW' },
{ label: 'Tanzania', value: 'TZ' },
{ label: 'Ukraine', value: 'UA' },
{ label: 'Uganda', value: 'UG' },
{ label: 'United States', value: 'US' },
{ label: 'Uruguay', value: 'UY' },
{ label: 'Uzbekistan', value: 'UZ' },
{ label: 'Vatican City', value: 'VA' },
{ label: 'St. Vincent & Grenadines', value: 'VC' },
{ label: 'Venezuela', value: 'VE' },
{ label: 'British Virgin Islands', value: 'VG' },
{ label: 'U.S. Virgin Islands', value: 'VI' },
{ label: 'Vietnam', value: 'VN' },
{ label: 'Vanuatu', value: 'VU' },
{ label: 'Wallis & Futuna', value: 'WF' },
{ label: 'Samoa', value: 'WS' },
{ label: 'Kosovo', value: 'XK' },
{ label: 'Yemen', value: 'YE' },
{ label: 'Mayotte', value: 'YT' },
{ label: 'South Africa', value: 'ZA' },
{ label: 'Zambia', value: 'ZM' },
{ label: 'Zimbabwe', value: 'ZW' },
];
export default phoneNumberCountryCodes;

View File

@@ -0,0 +1,51 @@
import formatOptions from './options/format';
import timezoneOptions from './options/timezone';
const formatDateTime = [
{
label: 'Input',
key: 'input',
type: 'string' as const,
required: true,
description: 'The datetime you want to format.',
variables: true,
},
{
label: 'From Format',
key: 'fromFormat',
type: 'dropdown' as const,
required: true,
description: 'The format of the input.',
variables: true,
options: formatOptions,
},
{
label: 'From Timezone',
key: 'fromTimezone',
type: 'dropdown' as const,
required: true,
description: 'The timezone of the input.',
variables: true,
options: timezoneOptions,
},
{
label: 'To Format',
key: 'toFormat',
type: 'dropdown' as const,
required: true,
description: 'The format of the output.',
variables: true,
options: formatOptions,
},
{
label: 'To Timezone',
key: 'toTimezone',
type: 'dropdown' as const,
required: true,
description: 'The timezone of the output.',
variables: true,
options: timezoneOptions,
},
];
export default formatDateTime;

View File

@@ -0,0 +1,64 @@
const formatOptions = [
{
label: 'ccc MMM dd HH:mm:ssZZZ yyyy (Wed Aug 23 12:25:36-0000 2023)',
value: 'ccc MMM dd HH:mm:ssZZZ yyyy',
},
{
label: 'MMMM dd yyyy HH:mm:ss (August 23 2023 12:25:36)',
value: 'MMMM dd yyyy HH:mm:ss',
},
{
label: 'MMMM dd yyyy (August 23 2023)',
value: 'MMMM dd yyyy',
},
{
label: 'MMM dd yyyy (Aug 23 2023)',
value: 'MMM dd yyyy',
},
{
label: 'yyyy-MM-dd HH:mm:ss ZZZ (2023-08-23 12:25:36 -0000)',
value: 'yyyy-MM-dd HH:mm:ss ZZZ',
},
{
label: 'yyyy-MM-dd (2023-08-23)',
value: 'yyyy-MM-dd',
},
{
label: 'MM-dd-yyyy (08-23-2023)',
value: 'MM-dd-yyyy',
},
{
label: 'MM/dd/yyyy (08/23/2023)',
value: 'MM/dd/yyyy',
},
{
label: 'MM/dd/yy (08/23/23)',
value: 'MM/dd/yy',
},
{
label: 'dd-MM-yyyy (23-08-2023)',
value: 'dd-MM-yyyy',
},
{
label: 'dd/MM/yyyy (23/08/2023)',
value: 'dd/MM/yyyy',
},
{
label: 'dd/MM/yy (23/08/23)',
value: 'dd/MM/yy',
},
{
label: 'MM-yyyy (08-2023)',
value: 'MM-yyyy',
},
{
label: 'Unix timestamp in seconds (1694008283)',
value: 'X',
},
{
label: 'Unix timestamp in milliseconds (1694008306315)',
value: 'x',
},
];
export default formatOptions;

View File

@@ -0,0 +1,449 @@
// The list from Intl.supportedValuesOf('timeZone') which is used by Luxon.
const timezoneOptions = [
{ label: 'Africa/Abidjan', value: 'Africa/Abidjan' },
{ label: 'Africa/Accra', value: 'Africa/Accra' },
{ label: 'Africa/Addis_Ababa', value: 'Africa/Addis_Ababa' },
{ label: 'Africa/Algiers', value: 'Africa/Algiers' },
{ label: 'Africa/Asmera', value: 'Africa/Asmera' },
{ label: 'Africa/Bamako', value: 'Africa/Bamako' },
{ label: 'Africa/Bangui', value: 'Africa/Bangui' },
{ label: 'Africa/Banjul', value: 'Africa/Banjul' },
{ label: 'Africa/Bissau', value: 'Africa/Bissau' },
{ label: 'Africa/Blantyre', value: 'Africa/Blantyre' },
{ label: 'Africa/Brazzaville', value: 'Africa/Brazzaville' },
{ label: 'Africa/Bujumbura', value: 'Africa/Bujumbura' },
{ label: 'Africa/Cairo', value: 'Africa/Cairo' },
{ label: 'Africa/Casablanca', value: 'Africa/Casablanca' },
{ label: 'Africa/Ceuta', value: 'Africa/Ceuta' },
{ label: 'Africa/Conakry', value: 'Africa/Conakry' },
{ label: 'Africa/Dakar', value: 'Africa/Dakar' },
{ label: 'Africa/Dar_es_Salaam', value: 'Africa/Dar_es_Salaam' },
{ label: 'Africa/Djibouti', value: 'Africa/Djibouti' },
{ label: 'Africa/Douala', value: 'Africa/Douala' },
{ label: 'Africa/El_Aaiun', value: 'Africa/El_Aaiun' },
{ label: 'Africa/Freetown', value: 'Africa/Freetown' },
{ label: 'Africa/Gaborone', value: 'Africa/Gaborone' },
{ label: 'Africa/Harare', value: 'Africa/Harare' },
{ label: 'Africa/Johannesburg', value: 'Africa/Johannesburg' },
{ label: 'Africa/Juba', value: 'Africa/Juba' },
{ label: 'Africa/Kampala', value: 'Africa/Kampala' },
{ label: 'Africa/Khartoum', value: 'Africa/Khartoum' },
{ label: 'Africa/Kigali', value: 'Africa/Kigali' },
{ label: 'Africa/Kinshasa', value: 'Africa/Kinshasa' },
{ label: 'Africa/Lagos', value: 'Africa/Lagos' },
{ label: 'Africa/Libreville', value: 'Africa/Libreville' },
{ label: 'Africa/Lome', value: 'Africa/Lome' },
{ label: 'Africa/Luanda', value: 'Africa/Luanda' },
{ label: 'Africa/Lubumbashi', value: 'Africa/Lubumbashi' },
{ label: 'Africa/Lusaka', value: 'Africa/Lusaka' },
{ label: 'Africa/Malabo', value: 'Africa/Malabo' },
{ label: 'Africa/Maputo', value: 'Africa/Maputo' },
{ label: 'Africa/Maseru', value: 'Africa/Maseru' },
{ label: 'Africa/Mbabane', value: 'Africa/Mbabane' },
{ label: 'Africa/Mogadishu', value: 'Africa/Mogadishu' },
{ label: 'Africa/Monrovia', value: 'Africa/Monrovia' },
{ label: 'Africa/Nairobi', value: 'Africa/Nairobi' },
{ label: 'Africa/Ndjamena', value: 'Africa/Ndjamena' },
{ label: 'Africa/Niamey', value: 'Africa/Niamey' },
{ label: 'Africa/Nouakchott', value: 'Africa/Nouakchott' },
{ label: 'Africa/Ouagadougou', value: 'Africa/Ouagadougou' },
{ label: 'Africa/Porto-Novo', value: 'Africa/Porto-Novo' },
{ label: 'Africa/Sao_Tome', value: 'Africa/Sao_Tome' },
{ label: 'Africa/Tripoli', value: 'Africa/Tripoli' },
{ label: 'Africa/Tunis', value: 'Africa/Tunis' },
{ label: 'Africa/Windhoek', value: 'Africa/Windhoek' },
{ label: 'America/Adak', value: 'America/Adak' },
{ label: 'America/Anchorage', value: 'America/Anchorage' },
{ label: 'America/Anguilla', value: 'America/Anguilla' },
{ label: 'America/Antigua', value: 'America/Antigua' },
{ label: 'America/Araguaina', value: 'America/Araguaina' },
{ label: 'America/Argentina/La_Rioja', value: 'America/Argentina/La_Rioja' },
{
label: 'America/Argentina/Rio_Gallegos',
value: 'America/Argentina/Rio_Gallegos',
},
{ label: 'America/Argentina/Salta', value: 'America/Argentina/Salta' },
{ label: 'America/Argentina/San_Juan', value: 'America/Argentina/San_Juan' },
{ label: 'America/Argentina/San_Luis', value: 'America/Argentina/San_Luis' },
{ label: 'America/Argentina/Tucuman', value: 'America/Argentina/Tucuman' },
{ label: 'America/Argentina/Ushuaia', value: 'America/Argentina/Ushuaia' },
{ label: 'America/Aruba', value: 'America/Aruba' },
{ label: 'America/Asuncion', value: 'America/Asuncion' },
{ label: 'America/Bahia', value: 'America/Bahia' },
{ label: 'America/Bahia_Banderas', value: 'America/Bahia_Banderas' },
{ label: 'America/Barbados', value: 'America/Barbados' },
{ label: 'America/Belem', value: 'America/Belem' },
{ label: 'America/Belize', value: 'America/Belize' },
{ label: 'America/Blanc-Sablon', value: 'America/Blanc-Sablon' },
{ label: 'America/Boa_Vista', value: 'America/Boa_Vista' },
{ label: 'America/Bogota', value: 'America/Bogota' },
{ label: 'America/Boise', value: 'America/Boise' },
{ label: 'America/Buenos_Aires', value: 'America/Buenos_Aires' },
{ label: 'America/Cambridge_Bay', value: 'America/Cambridge_Bay' },
{ label: 'America/Campo_Grande', value: 'America/Campo_Grande' },
{ label: 'America/Cancun', value: 'America/Cancun' },
{ label: 'America/Caracas', value: 'America/Caracas' },
{ label: 'America/Catamarca', value: 'America/Catamarca' },
{ label: 'America/Cayenne', value: 'America/Cayenne' },
{ label: 'America/Cayman', value: 'America/Cayman' },
{ label: 'America/Chicago', value: 'America/Chicago' },
{ label: 'America/Chihuahua', value: 'America/Chihuahua' },
{ label: 'America/Ciudad_Juarez', value: 'America/Ciudad_Juarez' },
{ label: 'America/Coral_Harbour', value: 'America/Coral_Harbour' },
{ label: 'America/Cordoba', value: 'America/Cordoba' },
{ label: 'America/Costa_Rica', value: 'America/Costa_Rica' },
{ label: 'America/Creston', value: 'America/Creston' },
{ label: 'America/Cuiaba', value: 'America/Cuiaba' },
{ label: 'America/Curacao', value: 'America/Curacao' },
{ label: 'America/Danmarkshavn', value: 'America/Danmarkshavn' },
{ label: 'America/Dawson', value: 'America/Dawson' },
{ label: 'America/Dawson_Creek', value: 'America/Dawson_Creek' },
{ label: 'America/Denver', value: 'America/Denver' },
{ label: 'America/Detroit', value: 'America/Detroit' },
{ label: 'America/Dominica', value: 'America/Dominica' },
{ label: 'America/Edmonton', value: 'America/Edmonton' },
{ label: 'America/Eirunepe', value: 'America/Eirunepe' },
{ label: 'America/El_Salvador', value: 'America/El_Salvador' },
{ label: 'America/Fort_Nelson', value: 'America/Fort_Nelson' },
{ label: 'America/Fortaleza', value: 'America/Fortaleza' },
{ label: 'America/Glace_Bay', value: 'America/Glace_Bay' },
{ label: 'America/Godthab', value: 'America/Godthab' },
{ label: 'America/Goose_Bay', value: 'America/Goose_Bay' },
{ label: 'America/Grand_Turk', value: 'America/Grand_Turk' },
{ label: 'America/Grenada', value: 'America/Grenada' },
{ label: 'America/Guadeloupe', value: 'America/Guadeloupe' },
{ label: 'America/Guatemala', value: 'America/Guatemala' },
{ label: 'America/Guayaquil', value: 'America/Guayaquil' },
{ label: 'America/Guyana', value: 'America/Guyana' },
{ label: 'America/Halifax', value: 'America/Halifax' },
{ label: 'America/Havana', value: 'America/Havana' },
{ label: 'America/Hermosillo', value: 'America/Hermosillo' },
{ label: 'America/Indiana/Knox', value: 'America/Indiana/Knox' },
{ label: 'America/Indiana/Marengo', value: 'America/Indiana/Marengo' },
{ label: 'America/Indiana/Petersburg', value: 'America/Indiana/Petersburg' },
{ label: 'America/Indiana/Tell_City', value: 'America/Indiana/Tell_City' },
{ label: 'America/Indiana/Vevay', value: 'America/Indiana/Vevay' },
{ label: 'America/Indiana/Vincennes', value: 'America/Indiana/Vincennes' },
{ label: 'America/Indiana/Winamac', value: 'America/Indiana/Winamac' },
{ label: 'America/Indianapolis', value: 'America/Indianapolis' },
{ label: 'America/Inuvik', value: 'America/Inuvik' },
{ label: 'America/Iqaluit', value: 'America/Iqaluit' },
{ label: 'America/Jamaica', value: 'America/Jamaica' },
{ label: 'America/Jujuy', value: 'America/Jujuy' },
{ label: 'America/Juneau', value: 'America/Juneau' },
{
label: 'America/Kentucky/Monticello',
value: 'America/Kentucky/Monticello',
},
{ label: 'America/Kralendijk', value: 'America/Kralendijk' },
{ label: 'America/La_Paz', value: 'America/La_Paz' },
{ label: 'America/Lima', value: 'America/Lima' },
{ label: 'America/Los_Angeles', value: 'America/Los_Angeles' },
{ label: 'America/Louisville', value: 'America/Louisville' },
{ label: 'America/Lower_Princes', value: 'America/Lower_Princes' },
{ label: 'America/Maceio', value: 'America/Maceio' },
{ label: 'America/Managua', value: 'America/Managua' },
{ label: 'America/Manaus', value: 'America/Manaus' },
{ label: 'America/Marigot', value: 'America/Marigot' },
{ label: 'America/Martinique', value: 'America/Martinique' },
{ label: 'America/Matamoros', value: 'America/Matamoros' },
{ label: 'America/Mazatlan', value: 'America/Mazatlan' },
{ label: 'America/Mendoza', value: 'America/Mendoza' },
{ label: 'America/Menominee', value: 'America/Menominee' },
{ label: 'America/Merida', value: 'America/Merida' },
{ label: 'America/Metlakatla', value: 'America/Metlakatla' },
{ label: 'America/Mexico_City', value: 'America/Mexico_City' },
{ label: 'America/Miquelon', value: 'America/Miquelon' },
{ label: 'America/Moncton', value: 'America/Moncton' },
{ label: 'America/Monterrey', value: 'America/Monterrey' },
{ label: 'America/Montevideo', value: 'America/Montevideo' },
{ label: 'America/Montserrat', value: 'America/Montserrat' },
{ label: 'America/Nassau', value: 'America/Nassau' },
{ label: 'America/New_York', value: 'America/New_York' },
{ label: 'America/Nipigon', value: 'America/Nipigon' },
{ label: 'America/Nome', value: 'America/Nome' },
{ label: 'America/Noronha', value: 'America/Noronha' },
{
label: 'America/North_Dakota/Beulah',
value: 'America/North_Dakota/Beulah',
},
{
label: 'America/North_Dakota/Center',
value: 'America/North_Dakota/Center',
},
{
label: 'America/North_Dakota/New_Salem',
value: 'America/North_Dakota/New_Salem',
},
{ label: 'America/Ojinaga', value: 'America/Ojinaga' },
{ label: 'America/Panama', value: 'America/Panama' },
{ label: 'America/Pangnirtung', value: 'America/Pangnirtung' },
{ label: 'America/Paramaribo', value: 'America/Paramaribo' },
{ label: 'America/Phoenix', value: 'America/Phoenix' },
{ label: 'America/Port-au-Prince', value: 'America/Port-au-Prince' },
{ label: 'America/Port_of_Spain', value: 'America/Port_of_Spain' },
{ label: 'America/Porto_Velho', value: 'America/Porto_Velho' },
{ label: 'America/Puerto_Rico', value: 'America/Puerto_Rico' },
{ label: 'America/Punta_Arenas', value: 'America/Punta_Arenas' },
{ label: 'America/Rainy_River', value: 'America/Rainy_River' },
{ label: 'America/Rankin_Inlet', value: 'America/Rankin_Inlet' },
{ label: 'America/Recife', value: 'America/Recife' },
{ label: 'America/Regina', value: 'America/Regina' },
{ label: 'America/Resolute', value: 'America/Resolute' },
{ label: 'America/Rio_Branco', value: 'America/Rio_Branco' },
{ label: 'America/Santa_Isabel', value: 'America/Santa_Isabel' },
{ label: 'America/Santarem', value: 'America/Santarem' },
{ label: 'America/Santiago', value: 'America/Santiago' },
{ label: 'America/Santo_Domingo', value: 'America/Santo_Domingo' },
{ label: 'America/Sao_Paulo', value: 'America/Sao_Paulo' },
{ label: 'America/Scoresbysund', value: 'America/Scoresbysund' },
{ label: 'America/Sitka', value: 'America/Sitka' },
{ label: 'America/St_Barthelemy', value: 'America/St_Barthelemy' },
{ label: 'America/St_Johns', value: 'America/St_Johns' },
{ label: 'America/St_Kitts', value: 'America/St_Kitts' },
{ label: 'America/St_Lucia', value: 'America/St_Lucia' },
{ label: 'America/St_Thomas', value: 'America/St_Thomas' },
{ label: 'America/St_Vincent', value: 'America/St_Vincent' },
{ label: 'America/Swift_Current', value: 'America/Swift_Current' },
{ label: 'America/Tegucigalpa', value: 'America/Tegucigalpa' },
{ label: 'America/Thule', value: 'America/Thule' },
{ label: 'America/Thunder_Bay', value: 'America/Thunder_Bay' },
{ label: 'America/Tijuana', value: 'America/Tijuana' },
{ label: 'America/Toronto', value: 'America/Toronto' },
{ label: 'America/Tortola', value: 'America/Tortola' },
{ label: 'America/Vancouver', value: 'America/Vancouver' },
{ label: 'America/Whitehorse', value: 'America/Whitehorse' },
{ label: 'America/Winnipeg', value: 'America/Winnipeg' },
{ label: 'America/Yakutat', value: 'America/Yakutat' },
{ label: 'America/Yellowknife', value: 'America/Yellowknife' },
{ label: 'Antarctica/Casey', value: 'Antarctica/Casey' },
{ label: 'Antarctica/Davis', value: 'Antarctica/Davis' },
{ label: 'Antarctica/DumontDUrville', value: 'Antarctica/DumontDUrville' },
{ label: 'Antarctica/Macquarie', value: 'Antarctica/Macquarie' },
{ label: 'Antarctica/Mawson', value: 'Antarctica/Mawson' },
{ label: 'Antarctica/McMurdo', value: 'Antarctica/McMurdo' },
{ label: 'Antarctica/Palmer', value: 'Antarctica/Palmer' },
{ label: 'Antarctica/Rothera', value: 'Antarctica/Rothera' },
{ label: 'Antarctica/Syowa', value: 'Antarctica/Syowa' },
{ label: 'Antarctica/Troll', value: 'Antarctica/Troll' },
{ label: 'Antarctica/Vostok', value: 'Antarctica/Vostok' },
{ label: 'Arctic/Longyearbyen', value: 'Arctic/Longyearbyen' },
{ label: 'Asia/Aden', value: 'Asia/Aden' },
{ label: 'Asia/Almaty', value: 'Asia/Almaty' },
{ label: 'Asia/Amman', value: 'Asia/Amman' },
{ label: 'Asia/Anadyr', value: 'Asia/Anadyr' },
{ label: 'Asia/Aqtau', value: 'Asia/Aqtau' },
{ label: 'Asia/Aqtobe', value: 'Asia/Aqtobe' },
{ label: 'Asia/Ashgabat', value: 'Asia/Ashgabat' },
{ label: 'Asia/Atyrau', value: 'Asia/Atyrau' },
{ label: 'Asia/Baghdad', value: 'Asia/Baghdad' },
{ label: 'Asia/Bahrain', value: 'Asia/Bahrain' },
{ label: 'Asia/Baku', value: 'Asia/Baku' },
{ label: 'Asia/Bangkok', value: 'Asia/Bangkok' },
{ label: 'Asia/Barnaul', value: 'Asia/Barnaul' },
{ label: 'Asia/Beirut', value: 'Asia/Beirut' },
{ label: 'Asia/Bishkek', value: 'Asia/Bishkek' },
{ label: 'Asia/Brunei', value: 'Asia/Brunei' },
{ label: 'Asia/Calcutta', value: 'Asia/Calcutta' },
{ label: 'Asia/Chita', value: 'Asia/Chita' },
{ label: 'Asia/Choibalsan', value: 'Asia/Choibalsan' },
{ label: 'Asia/Colombo', value: 'Asia/Colombo' },
{ label: 'Asia/Damascus', value: 'Asia/Damascus' },
{ label: 'Asia/Dhaka', value: 'Asia/Dhaka' },
{ label: 'Asia/Dili', value: 'Asia/Dili' },
{ label: 'Asia/Dubai', value: 'Asia/Dubai' },
{ label: 'Asia/Dushanbe', value: 'Asia/Dushanbe' },
{ label: 'Asia/Famagusta', value: 'Asia/Famagusta' },
{ label: 'Asia/Gaza', value: 'Asia/Gaza' },
{ label: 'Asia/Hebron', value: 'Asia/Hebron' },
{ label: 'Asia/Hong_Kong', value: 'Asia/Hong_Kong' },
{ label: 'Asia/Hovd', value: 'Asia/Hovd' },
{ label: 'Asia/Irkutsk', value: 'Asia/Irkutsk' },
{ label: 'Asia/Jakarta', value: 'Asia/Jakarta' },
{ label: 'Asia/Jayapura', value: 'Asia/Jayapura' },
{ label: 'Asia/Jerusalem', value: 'Asia/Jerusalem' },
{ label: 'Asia/Kabul', value: 'Asia/Kabul' },
{ label: 'Asia/Kamchatka', value: 'Asia/Kamchatka' },
{ label: 'Asia/Karachi', value: 'Asia/Karachi' },
{ label: 'Asia/Katmandu', value: 'Asia/Katmandu' },
{ label: 'Asia/Khandyga', value: 'Asia/Khandyga' },
{ label: 'Asia/Krasnoyarsk', value: 'Asia/Krasnoyarsk' },
{ label: 'Asia/Kuala_Lumpur', value: 'Asia/Kuala_Lumpur' },
{ label: 'Asia/Kuching', value: 'Asia/Kuching' },
{ label: 'Asia/Kuwait', value: 'Asia/Kuwait' },
{ label: 'Asia/Macau', value: 'Asia/Macau' },
{ label: 'Asia/Magadan', value: 'Asia/Magadan' },
{ label: 'Asia/Makassar', value: 'Asia/Makassar' },
{ label: 'Asia/Manila', value: 'Asia/Manila' },
{ label: 'Asia/Muscat', value: 'Asia/Muscat' },
{ label: 'Asia/Nicosia', value: 'Asia/Nicosia' },
{ label: 'Asia/Novokuznetsk', value: 'Asia/Novokuznetsk' },
{ label: 'Asia/Novosibirsk', value: 'Asia/Novosibirsk' },
{ label: 'Asia/Omsk', value: 'Asia/Omsk' },
{ label: 'Asia/Oral', value: 'Asia/Oral' },
{ label: 'Asia/Phnom_Penh', value: 'Asia/Phnom_Penh' },
{ label: 'Asia/Pontianak', value: 'Asia/Pontianak' },
{ label: 'Asia/Pyongyang', value: 'Asia/Pyongyang' },
{ label: 'Asia/Qatar', value: 'Asia/Qatar' },
{ label: 'Asia/Qostanay', value: 'Asia/Qostanay' },
{ label: 'Asia/Qyzylorda', value: 'Asia/Qyzylorda' },
{ label: 'Asia/Rangoon', value: 'Asia/Rangoon' },
{ label: 'Asia/Riyadh', value: 'Asia/Riyadh' },
{ label: 'Asia/Saigon', value: 'Asia/Saigon' },
{ label: 'Asia/Sakhalin', value: 'Asia/Sakhalin' },
{ label: 'Asia/Samarkand', value: 'Asia/Samarkand' },
{ label: 'Asia/Seoul', value: 'Asia/Seoul' },
{ label: 'Asia/Shanghai', value: 'Asia/Shanghai' },
{ label: 'Asia/Singapore', value: 'Asia/Singapore' },
{ label: 'Asia/Srednekolymsk', value: 'Asia/Srednekolymsk' },
{ label: 'Asia/Taipei', value: 'Asia/Taipei' },
{ label: 'Asia/Tashkent', value: 'Asia/Tashkent' },
{ label: 'Asia/Tbilisi', value: 'Asia/Tbilisi' },
{ label: 'Asia/Tehran', value: 'Asia/Tehran' },
{ label: 'Asia/Thimphu', value: 'Asia/Thimphu' },
{ label: 'Asia/Tokyo', value: 'Asia/Tokyo' },
{ label: 'Asia/Tomsk', value: 'Asia/Tomsk' },
{ label: 'Asia/Ulaanbaatar', value: 'Asia/Ulaanbaatar' },
{ label: 'Asia/Urumqi', value: 'Asia/Urumqi' },
{ label: 'Asia/Ust-Nera', value: 'Asia/Ust-Nera' },
{ label: 'Asia/Vientiane', value: 'Asia/Vientiane' },
{ label: 'Asia/Vladivostok', value: 'Asia/Vladivostok' },
{ label: 'Asia/Yakutsk', value: 'Asia/Yakutsk' },
{ label: 'Asia/Yekaterinburg', value: 'Asia/Yekaterinburg' },
{ label: 'Asia/Yerevan', value: 'Asia/Yerevan' },
{ label: 'Atlantic/Azores', value: 'Atlantic/Azores' },
{ label: 'Atlantic/Bermuda', value: 'Atlantic/Bermuda' },
{ label: 'Atlantic/Canary', value: 'Atlantic/Canary' },
{ label: 'Atlantic/Cape_Verde', value: 'Atlantic/Cape_Verde' },
{ label: 'Atlantic/Faeroe', value: 'Atlantic/Faeroe' },
{ label: 'Atlantic/Madeira', value: 'Atlantic/Madeira' },
{ label: 'Atlantic/Reykjavik', value: 'Atlantic/Reykjavik' },
{ label: 'Atlantic/South_Georgia', value: 'Atlantic/South_Georgia' },
{ label: 'Atlantic/St_Helena', value: 'Atlantic/St_Helena' },
{ label: 'Atlantic/Stanley', value: 'Atlantic/Stanley' },
{ label: 'Australia/Adelaide', value: 'Australia/Adelaide' },
{ label: 'Australia/Brisbane', value: 'Australia/Brisbane' },
{ label: 'Australia/Broken_Hill', value: 'Australia/Broken_Hill' },
{ label: 'Australia/Currie', value: 'Australia/Currie' },
{ label: 'Australia/Darwin', value: 'Australia/Darwin' },
{ label: 'Australia/Eucla', value: 'Australia/Eucla' },
{ label: 'Australia/Hobart', value: 'Australia/Hobart' },
{ label: 'Australia/Lindeman', value: 'Australia/Lindeman' },
{ label: 'Australia/Lord_Howe', value: 'Australia/Lord_Howe' },
{ label: 'Australia/Melbourne', value: 'Australia/Melbourne' },
{ label: 'Australia/Perth', value: 'Australia/Perth' },
{ label: 'Australia/Sydney', value: 'Australia/Sydney' },
{ label: 'Europe/Amsterdam', value: 'Europe/Amsterdam' },
{ label: 'Europe/Andorra', value: 'Europe/Andorra' },
{ label: 'Europe/Astrakhan', value: 'Europe/Astrakhan' },
{ label: 'Europe/Athens', value: 'Europe/Athens' },
{ label: 'Europe/Belgrade', value: 'Europe/Belgrade' },
{ label: 'Europe/Berlin', value: 'Europe/Berlin' },
{ label: 'Europe/Bratislava', value: 'Europe/Bratislava' },
{ label: 'Europe/Brussels', value: 'Europe/Brussels' },
{ label: 'Europe/Bucharest', value: 'Europe/Bucharest' },
{ label: 'Europe/Budapest', value: 'Europe/Budapest' },
{ label: 'Europe/Busingen', value: 'Europe/Busingen' },
{ label: 'Europe/Chisinau', value: 'Europe/Chisinau' },
{ label: 'Europe/Copenhagen', value: 'Europe/Copenhagen' },
{ label: 'Europe/Dublin', value: 'Europe/Dublin' },
{ label: 'Europe/Gibraltar', value: 'Europe/Gibraltar' },
{ label: 'Europe/Guernsey', value: 'Europe/Guernsey' },
{ label: 'Europe/Helsinki', value: 'Europe/Helsinki' },
{ label: 'Europe/Isle_of_Man', value: 'Europe/Isle_of_Man' },
{ label: 'Europe/Istanbul', value: 'Europe/Istanbul' },
{ label: 'Europe/Jersey', value: 'Europe/Jersey' },
{ label: 'Europe/Kaliningrad', value: 'Europe/Kaliningrad' },
{ label: 'Europe/Kiev', value: 'Europe/Kiev' },
{ label: 'Europe/Kirov', value: 'Europe/Kirov' },
{ label: 'Europe/Lisbon', value: 'Europe/Lisbon' },
{ label: 'Europe/Ljubljana', value: 'Europe/Ljubljana' },
{ label: 'Europe/London', value: 'Europe/London' },
{ label: 'Europe/Luxembourg', value: 'Europe/Luxembourg' },
{ label: 'Europe/Madrid', value: 'Europe/Madrid' },
{ label: 'Europe/Malta', value: 'Europe/Malta' },
{ label: 'Europe/Mariehamn', value: 'Europe/Mariehamn' },
{ label: 'Europe/Minsk', value: 'Europe/Minsk' },
{ label: 'Europe/Monaco', value: 'Europe/Monaco' },
{ label: 'Europe/Moscow', value: 'Europe/Moscow' },
{ label: 'Europe/Oslo', value: 'Europe/Oslo' },
{ label: 'Europe/Paris', value: 'Europe/Paris' },
{ label: 'Europe/Podgorica', value: 'Europe/Podgorica' },
{ label: 'Europe/Prague', value: 'Europe/Prague' },
{ label: 'Europe/Riga', value: 'Europe/Riga' },
{ label: 'Europe/Rome', value: 'Europe/Rome' },
{ label: 'Europe/Samara', value: 'Europe/Samara' },
{ label: 'Europe/San_Marino', value: 'Europe/San_Marino' },
{ label: 'Europe/Sarajevo', value: 'Europe/Sarajevo' },
{ label: 'Europe/Saratov', value: 'Europe/Saratov' },
{ label: 'Europe/Simferopol', value: 'Europe/Simferopol' },
{ label: 'Europe/Skopje', value: 'Europe/Skopje' },
{ label: 'Europe/Sofia', value: 'Europe/Sofia' },
{ label: 'Europe/Stockholm', value: 'Europe/Stockholm' },
{ label: 'Europe/Tallinn', value: 'Europe/Tallinn' },
{ label: 'Europe/Tirane', value: 'Europe/Tirane' },
{ label: 'Europe/Ulyanovsk', value: 'Europe/Ulyanovsk' },
{ label: 'Europe/Uzhgorod', value: 'Europe/Uzhgorod' },
{ label: 'Europe/Vaduz', value: 'Europe/Vaduz' },
{ label: 'Europe/Vatican', value: 'Europe/Vatican' },
{ label: 'Europe/Vienna', value: 'Europe/Vienna' },
{ label: 'Europe/Vilnius', value: 'Europe/Vilnius' },
{ label: 'Europe/Volgograd', value: 'Europe/Volgograd' },
{ label: 'Europe/Warsaw', value: 'Europe/Warsaw' },
{ label: 'Europe/Zagreb', value: 'Europe/Zagreb' },
{ label: 'Europe/Zaporozhye', value: 'Europe/Zaporozhye' },
{ label: 'Europe/Zurich', value: 'Europe/Zurich' },
{ label: 'Indian/Antananarivo', value: 'Indian/Antananarivo' },
{ label: 'Indian/Chagos', value: 'Indian/Chagos' },
{ label: 'Indian/Christmas', value: 'Indian/Christmas' },
{ label: 'Indian/Cocos', value: 'Indian/Cocos' },
{ label: 'Indian/Comoro', value: 'Indian/Comoro' },
{ label: 'Indian/Kerguelen', value: 'Indian/Kerguelen' },
{ label: 'Indian/Mahe', value: 'Indian/Mahe' },
{ label: 'Indian/Maldives', value: 'Indian/Maldives' },
{ label: 'Indian/Mauritius', value: 'Indian/Mauritius' },
{ label: 'Indian/Mayotte', value: 'Indian/Mayotte' },
{ label: 'Indian/Reunion', value: 'Indian/Reunion' },
{ label: 'Pacific/Apia', value: 'Pacific/Apia' },
{ label: 'Pacific/Auckland', value: 'Pacific/Auckland' },
{ label: 'Pacific/Bougainville', value: 'Pacific/Bougainville' },
{ label: 'Pacific/Chatham', value: 'Pacific/Chatham' },
{ label: 'Pacific/Easter', value: 'Pacific/Easter' },
{ label: 'Pacific/Efate', value: 'Pacific/Efate' },
{ label: 'Pacific/Enderbury', value: 'Pacific/Enderbury' },
{ label: 'Pacific/Fakaofo', value: 'Pacific/Fakaofo' },
{ label: 'Pacific/Fiji', value: 'Pacific/Fiji' },
{ label: 'Pacific/Funafuti', value: 'Pacific/Funafuti' },
{ label: 'Pacific/Galapagos', value: 'Pacific/Galapagos' },
{ label: 'Pacific/Gambier', value: 'Pacific/Gambier' },
{ label: 'Pacific/Guadalcanal', value: 'Pacific/Guadalcanal' },
{ label: 'Pacific/Guam', value: 'Pacific/Guam' },
{ label: 'Pacific/Honolulu', value: 'Pacific/Honolulu' },
{ label: 'Pacific/Johnston', value: 'Pacific/Johnston' },
{ label: 'Pacific/Kiritimati', value: 'Pacific/Kiritimati' },
{ label: 'Pacific/Kosrae', value: 'Pacific/Kosrae' },
{ label: 'Pacific/Kwajalein', value: 'Pacific/Kwajalein' },
{ label: 'Pacific/Majuro', value: 'Pacific/Majuro' },
{ label: 'Pacific/Marquesas', value: 'Pacific/Marquesas' },
{ label: 'Pacific/Midway', value: 'Pacific/Midway' },
{ label: 'Pacific/Nauru', value: 'Pacific/Nauru' },
{ label: 'Pacific/Niue', value: 'Pacific/Niue' },
{ label: 'Pacific/Norfolk', value: 'Pacific/Norfolk' },
{ label: 'Pacific/Noumea', value: 'Pacific/Noumea' },
{ label: 'Pacific/Pago_Pago', value: 'Pacific/Pago_Pago' },
{ label: 'Pacific/Palau', value: 'Pacific/Palau' },
{ label: 'Pacific/Pitcairn', value: 'Pacific/Pitcairn' },
{ label: 'Pacific/Ponape', value: 'Pacific/Ponape' },
{ label: 'Pacific/Port_Moresby', value: 'Pacific/Port_Moresby' },
{ label: 'Pacific/Rarotonga', value: 'Pacific/Rarotonga' },
{ label: 'Pacific/Saipan', value: 'Pacific/Saipan' },
{ label: 'Pacific/Tahiti', value: 'Pacific/Tahiti' },
{ label: 'Pacific/Tarawa', value: 'Pacific/Tarawa' },
{ label: 'Pacific/Tongatapu', value: 'Pacific/Tongatapu' },
{ label: 'Pacific/Truk', value: 'Pacific/Truk' },
{ label: 'Pacific/Wake', value: 'Pacific/Wake' },
{ label: 'Pacific/Wallis', value: 'Pacific/Wallis' },
];
export default timezoneOptions;

View File

@@ -1,16 +1,36 @@
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
import capitalize from './options/capitalize';
import htmlToMarkdown from './options/html-to-markdown';
import markdownToHtml from './options/markdown-to-html';
import useDefaultValue from './options/use-default-value';
import extractEmailAddress from './options/extract-email-address';
import capitalize from './text/capitalize';
import extractEmailAddress from './text/extract-email-address';
import extractNumber from './text/extract-number';
import htmlToMarkdown from './text/html-to-markdown';
import lowercase from './text/lowercase';
import markdownToHtml from './text/markdown-to-html';
import pluralize from './text/pluralize';
import replace from './text/replace';
import trimWhitespace from './text/trim-whitespace';
import useDefaultValue from './text/use-default-value';
import performMathOperation from './numbers/perform-math-operation';
import randomNumber from './numbers/random-number';
import formatNumber from './numbers/format-number';
import formatPhoneNumber from './numbers/format-phone-number';
import formatDateTime from './date-time/format-date-time';
const options: IJSONObject = {
capitalize,
htmlToMarkdown,
markdownToHtml,
useDefaultValue,
extractEmailAddress,
extractNumber,
htmlToMarkdown,
lowercase,
markdownToHtml,
pluralize,
replace,
trimWhitespace,
useDefaultValue,
performMathOperation,
randomNumber,
formatNumber,
formatPhoneNumber,
formatDateTime,
};
export default {

View File

@@ -0,0 +1,38 @@
const formatNumber = [
{
label: 'Input',
key: 'input',
type: 'string' as const,
required: true,
description: 'The number you want to format.',
variables: true,
},
{
label: 'Input Decimal Mark',
key: 'inputDecimalMark',
type: 'dropdown' as const,
required: true,
description: 'The decimal mark of the input number.',
variables: true,
options: [
{ label: 'Comma', value: ',' },
{ label: 'Period', value: '.' },
],
},
{
label: 'To Format',
key: 'toFormat',
type: 'dropdown' as const,
required: true,
description: 'The format you want to convert the number to.',
variables: true,
options: [
{ label: 'Comma for grouping & period for decimal', value: '0' },
{ label: 'Period for grouping & comma for decimal', value: '1' },
{ label: 'Space for grouping & period for decimal', value: '2' },
{ label: 'Space for grouping & comma for decimal', value: '3' },
],
},
];
export default formatNumber;

View File

@@ -0,0 +1,36 @@
import phoneNumberCountryCodes from '../../../common/phone-number-country-codes';
const formatPhoneNumber = [
{
label: 'Phone Number',
key: 'phoneNumber',
type: 'string' as const,
required: true,
description: 'The phone number you want to format.',
variables: true,
},
{
label: 'To Format',
key: 'toFormat',
type: 'dropdown' as const,
required: true,
description: 'The format you want to convert the number to.',
variables: true,
options: [
{ label: '+491632223344 (E164)', value: 'e164' },
{ label: '+49 163 2223344 (International)', value: 'international' },
{ label: '0163 2223344 (National)', value: 'national' },
],
},
{
label: 'Phone Number Country Code',
key: 'phoneNumberCountryCode',
type: 'dropdown' as const,
required: true,
description: 'The country code of the phone number. The default is US.',
variables: true,
options: phoneNumberCountryCodes,
},
];
export default formatPhoneNumber;

View File

@@ -0,0 +1,36 @@
const performMathOperation = [
{
label: 'Math Operation',
key: 'mathOperation',
type: 'dropdown' as const,
required: true,
description: 'The math operation to perform.',
variables: true,
options: [
{ label: 'Add', value: 'add' },
{ label: 'Divide', value: 'divide' },
{ label: 'Make Negative', value: 'makeNegative' },
{ label: 'Multiply', value: 'multiply' },
{ label: 'Subtract', value: 'subtract' },
],
},
{
label: 'Values',
key: 'values',
type: 'dynamic' as const,
required: false,
description: 'Add or remove numbers as needed.',
fields: [
{
label: 'Input',
key: 'input',
type: 'string' as const,
required: true,
description: 'The number to perform the math operation on.',
variables: true,
},
],
},
];
export default performMathOperation;

View File

@@ -0,0 +1,29 @@
const randomNumber = [
{
label: 'Lower range',
key: 'lowerRange',
type: 'string' as const,
required: true,
description: 'The lowest number to generate.',
variables: true,
},
{
label: 'Upper range',
key: 'upperRange',
type: 'string' as const,
required: true,
description: 'The highest number to generate.',
variables: true,
},
{
label: 'Decimal points',
key: 'decimalPoints',
type: 'string' as const,
required: false,
description:
'The number of digits after the decimal point. It can be an integer between 0 and 15.',
variables: true,
},
];
export default randomNumber;

View File

@@ -0,0 +1,12 @@
const extractNumber = [
{
label: 'Input',
key: 'input',
type: 'string' as const,
required: true,
description: 'Text that will be searched for a number.',
variables: true,
},
];
export default extractNumber;

View File

@@ -0,0 +1,12 @@
const lowercase = [
{
label: 'Input',
key: 'input',
type: 'string' as const,
required: true,
description: 'Text that will be lowercased.',
variables: true,
},
];
export default lowercase;

View File

@@ -0,0 +1,12 @@
const pluralize = [
{
label: 'Input',
key: 'input',
type: 'string' as const,
required: true,
description: 'Text that will be pluralized.',
variables: true,
},
];
export default pluralize;

View File

@@ -0,0 +1,28 @@
const replace = [
{
label: 'Input',
key: 'input',
type: 'string' as const,
required: true,
description: 'Text that you want to search for and replace values.',
variables: true,
},
{
label: 'Find',
key: 'find',
type: 'string' as const,
required: true,
description: 'Text that will be searched for.',
variables: true,
},
{
label: 'Replace',
key: 'replace',
type: 'string' as const,
required: false,
description: 'Text that will replace the found text.',
variables: true,
},
];
export default replace;

View File

@@ -0,0 +1,12 @@
const trimWhitespace = [
{
label: 'Input',
key: 'input',
type: 'string' as const,
required: true,
description: 'Text you want to remove leading and trailing spaces.',
variables: true,
},
];
export default trimWhitespace;

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -19,6 +20,7 @@ export const triggerDescriptor: IRawTrigger = {
key: GITLAB_EVENT_TYPE.confidential_issues_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
run: ($) => getRunFn($),
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.confidential_issues_events),
unregisterHook,

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -19,6 +20,7 @@ export const triggerDescriptor: IRawTrigger = {
key: GITLAB_EVENT_TYPE.confidential_note_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
run: ($) => getRunFn($),
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.confidential_note_events),
unregisterHook,

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -18,6 +19,7 @@ export const triggerDescriptor: IRawTrigger = {
key: GITLAB_EVENT_TYPE.deployment_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
run: ($) => getRunFn($),
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.deployment_events),
unregisterHook,

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -18,6 +19,7 @@ export const triggerDescriptor: IRawTrigger = {
key: GITLAB_EVENT_TYPE.feature_flag_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
run: ($) => getRunFn($),
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.feature_flag_events),
unregisterHook,

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -18,6 +19,7 @@ export const triggerDescriptor: IRawTrigger = {
key: GITLAB_EVENT_TYPE.issues_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
run: ($) => getRunFn($),
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.issues_events),
unregisterHook,

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -17,6 +18,7 @@ export const triggerDescriptor: IRawTrigger = {
key: GITLAB_EVENT_TYPE.job_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
run: ($) => getRunFn($),
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.job_events),
unregisterHook,

View File

@@ -22,6 +22,17 @@ export const projectArgumentDescriptor = {
},
};
export const getRunFn = async ($: IGlobalVariable) => {
const dataItem = {
raw: $.request.body,
meta: {
internalId: Crypto.randomUUID(),
},
};
$.pushTriggerItem(dataItem);
};
export const getTestRunFn =
(eventData: IJSONObject) => ($: IGlobalVariable) => {
/*

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -18,6 +19,7 @@ export const triggerDescriptor: IRawTrigger = {
key: GITLAB_EVENT_TYPE.merge_requests_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
run: ($) => getRunFn($),
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.merge_requests_events),
unregisterHook,

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -18,6 +19,7 @@ export const triggerDescriptor: IRawTrigger = {
key: GITLAB_EVENT_TYPE.note_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
run: ($) => getRunFn($),
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.note_events),
unregisterHook,

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -18,6 +19,7 @@ export const triggerDescriptor: IRawTrigger = {
key: GITLAB_EVENT_TYPE.pipeline_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
run: ($) => getRunFn($),
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.pipeline_events),
unregisterHook,

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -54,6 +55,7 @@ export const triggerDescriptor: IRawTrigger = {
branchFilterStrategyArgumentDescriptor,
pushEventsBranchFilterArgumentDescriptor,
],
run: ($) => getRunFn($),
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.push_events),
unregisterHook,

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -17,6 +18,7 @@ export const triggerDescriptor: IRawTrigger = {
key: GITLAB_EVENT_TYPE.releases_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
run: ($) => getRunFn($),
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.releases_events),
unregisterHook,

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -18,6 +19,7 @@ export const triggerDescriptor: IRawTrigger = {
key: GITLAB_EVENT_TYPE.tag_push_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
run: ($) => getRunFn($),
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.tag_push_events),
unregisterHook,

View File

@@ -3,6 +3,7 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -18,6 +19,7 @@ export const triggerDescriptor: IRawTrigger = {
key: GITLAB_EVENT_TYPE.wiki_page_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
run: ($) => getRunFn($),
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.wiki_page_events),
unregisterHook,

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Livello_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 200 200" enable-background="new 0 0 200 200" xml:space="preserve">
<g>
<g transform="translate(3.75 3.75)">
<path fill="#FFFFFF" d="M148.882,43.618l-47.368-5.263l-57.895,5.263L38.355,96.25l5.263,52.632l52.632,6.579l52.632-6.579
l5.263-53.947L148.882,43.618z"/>
<path fill="#1A73E8" d="M65.211,125.276c-3.934-2.658-6.658-6.539-8.145-11.671l9.132-3.763c0.829,3.158,2.276,5.605,4.342,7.342
c2.053,1.737,4.553,2.592,7.474,2.592c2.987,0,5.553-0.908,7.697-2.724s3.224-4.132,3.224-6.934c0-2.868-1.132-5.211-3.395-7.026
s-5.105-2.724-8.5-2.724h-5.276v-9.039H76.5c2.921,0,5.382-0.789,7.382-2.368c2-1.579,3-3.737,3-6.487
c0-2.447-0.895-4.395-2.684-5.855s-4.053-2.197-6.803-2.197c-2.684,0-4.816,0.711-6.395,2.145s-2.724,3.197-3.447,5.276
l-9.039-3.763c1.197-3.395,3.395-6.395,6.618-8.987c3.224-2.592,7.342-3.895,12.342-3.895c3.697,0,7.026,0.711,9.974,2.145
c2.947,1.434,5.263,3.421,6.934,5.947c1.671,2.539,2.5,5.382,2.5,8.539c0,3.224-0.776,5.947-2.329,8.184
c-1.553,2.237-3.461,3.947-5.724,5.145v0.539c2.987,1.25,5.421,3.158,7.342,5.724c1.908,2.566,2.868,5.632,2.868,9.211
s-0.908,6.776-2.724,9.579c-1.816,2.803-4.329,5.013-7.513,6.618c-3.197,1.605-6.789,2.421-10.776,2.421
C73.408,129.263,69.145,127.934,65.211,125.276z"/>
<path fill="#1A73E8" d="M121.25,79.961l-9.974,7.25l-5.013-7.605l17.987-12.974h6.895v61.197h-9.895L121.25,79.961z"/>
<path fill="#EA4335" d="M148.882,196.25l47.368-47.368l-23.684-10.526l-23.684,10.526l-10.526,23.684L148.882,196.25z"/>
<path fill="#34A853" d="M33.092,172.566l10.526,23.684h105.263v-47.368H43.618L33.092,172.566z"/>
<path fill="#4285F4" d="M12.039-3.75C3.316-3.75-3.75,3.316-3.75,12.039v136.842l23.684,10.526l23.684-10.526V43.618h105.263
l10.526-23.684L148.882-3.75H12.039z"/>
<path fill="#188038" d="M-3.75,148.882v31.579c0,8.724,7.066,15.789,15.789,15.789h31.579v-47.368H-3.75z"/>
<path fill="#FBBC04" d="M148.882,43.618v105.263h47.368V43.618l-23.684-10.526L148.882,43.618z"/>
<path fill="#1967D2" d="M196.25,43.618V12.039c0-8.724-7.066-15.789-15.789-15.789h-31.579v47.368H196.25z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1,24 @@
import { IField, IGlobalVariable } from '@automatisch/types';
import { URLSearchParams } from 'url';
import authScope from '../common/auth-scope';
export default async function generateAuthUrl($: IGlobalVariable) {
const oauthRedirectUrlField = $.app.auth.fields.find(
(field: IField) => field.key == 'oAuthRedirectUrl'
);
const redirectUri = oauthRedirectUrlField.value as string;
const searchParams = new URLSearchParams({
client_id: $.auth.data.clientId as string,
redirect_uri: redirectUri,
prompt: 'select_account',
scope: authScope.join(' '),
response_type: 'code',
access_type: 'offline',
});
const url = `https://accounts.google.com/o/oauth2/v2/auth?${searchParams.toString()}`;
await $.auth.set({
url,
});
}

View File

@@ -0,0 +1,48 @@
import generateAuthUrl from './generate-auth-url';
import verifyCredentials from './verify-credentials';
import refreshToken from './refresh-token';
import isStillVerified from './is-still-verified';
export default {
fields: [
{
key: 'oAuthRedirectUrl',
label: 'OAuth Redirect URL',
type: 'string' as const,
required: true,
readOnly: true,
value: '{WEB_APP_URL}/app/google-calendar/connections/add',
placeholder: null,
description:
'When asked to input a redirect URL in Google Cloud, enter the URL above.',
clickToCopy: true,
},
{
key: 'clientId',
label: 'Client ID',
type: 'string' as const,
required: true,
readOnly: false,
value: null,
placeholder: null,
description: null,
clickToCopy: false,
},
{
key: 'clientSecret',
label: 'Client Secret',
type: 'string' as const,
required: true,
readOnly: false,
value: null,
placeholder: null,
description: null,
clickToCopy: false,
},
],
generateAuthUrl,
verifyCredentials,
isStillVerified,
refreshToken,
};

View File

@@ -0,0 +1,9 @@
import { IGlobalVariable } from '@automatisch/types';
import getCurrentUser from '../common/get-current-user';
const isStillVerified = async ($: IGlobalVariable) => {
const currentUser = await getCurrentUser($);
return !!currentUser.resourceName;
};
export default isStillVerified;

View File

@@ -0,0 +1,26 @@
import { URLSearchParams } from 'node:url';
import { IGlobalVariable } from '@automatisch/types';
import authScope from '../common/auth-scope';
const refreshToken = async ($: IGlobalVariable) => {
const params = new URLSearchParams({
client_id: $.auth.data.clientId as string,
client_secret: $.auth.data.clientSecret as string,
grant_type: 'refresh_token',
refresh_token: $.auth.data.refreshToken as string,
});
const { data } = await $.http.post(
'https://oauth2.googleapis.com/token',
params.toString()
);
await $.auth.set({
accessToken: data.access_token,
expiresIn: data.expires_in,
scope: authScope.join(' '),
tokenType: data.token_type,
});
};
export default refreshToken;

View File

@@ -0,0 +1,57 @@
import { IField, IGlobalVariable } from '@automatisch/types';
import getCurrentUser from '../common/get-current-user';
type TUser = {
displayName: string;
metadata: {
primary: boolean;
};
};
type TEmailAddress = {
value: string;
metadata: {
primary: boolean;
};
};
const verifyCredentials = async ($: IGlobalVariable) => {
const oauthRedirectUrlField = $.app.auth.fields.find(
(field: IField) => field.key == 'oAuthRedirectUrl'
);
const redirectUri = oauthRedirectUrlField.value as string;
const { data } = await $.http.post(`https://oauth2.googleapis.com/token`, {
client_id: $.auth.data.clientId,
client_secret: $.auth.data.clientSecret,
code: $.auth.data.code,
grant_type: 'authorization_code',
redirect_uri: redirectUri,
});
await $.auth.set({
accessToken: data.access_token,
tokenType: data.token_type,
});
const currentUser = await getCurrentUser($);
const { displayName } = currentUser.names.find(
(name: TUser) => name.metadata.primary
);
const { value: email } = currentUser.emailAddresses.find(
(emailAddress: TEmailAddress) => emailAddress.metadata.primary
);
await $.auth.set({
clientId: $.auth.data.clientId,
clientSecret: $.auth.data.clientSecret,
scope: $.auth.data.scope,
idToken: data.id_token,
expiresIn: data.expires_in,
refreshToken: data.refresh_token,
resourceName: currentUser.resourceName,
screenName: `${displayName} - ${email}`,
});
};
export default verifyCredentials;

View File

@@ -0,0 +1,11 @@
import { TBeforeRequest } from '@automatisch/types';
const addAuthHeader: TBeforeRequest = ($, requestConfig) => {
if ($.auth.data?.accessToken) {
requestConfig.headers.Authorization = `${$.auth.data.tokenType} ${$.auth.data.accessToken}`;
}
return requestConfig;
};
export default addAuthHeader;

View File

@@ -0,0 +1,7 @@
const authScope: string[] = [
'https://www.googleapis.com/auth/calendar',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile',
];
export default authScope;

View File

@@ -0,0 +1,10 @@
import { IGlobalVariable } from '@automatisch/types';
const getCurrentUser = async ($: IGlobalVariable) => {
const { data: currentUser } = await $.http.get(
'https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses'
);
return currentUser;
};
export default getCurrentUser;

View File

@@ -0,0 +1,3 @@
import listCalendars from './list-calendars';
export default [listCalendars];

View File

@@ -0,0 +1,36 @@
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
export default {
name: 'List calendars',
key: 'listCalendars',
async run($: IGlobalVariable) {
const drives: {
data: IJSONObject[];
} = {
data: [],
};
const params = {
pageToken: undefined as unknown as string,
};
do {
const { data } = await $.http.get(`/v3/users/me/calendarList`, {
params,
});
params.pageToken = data.nextPageToken;
if (data.items) {
for (const calendar of data.items) {
drives.data.push({
value: calendar.id,
name: calendar.summary,
});
}
}
} while (params.pageToken);
return drives;
},
};

View File

View File

@@ -0,0 +1,20 @@
import defineApp from '../../helpers/define-app';
import addAuthHeader from './common/add-auth-header';
import auth from './auth';
import triggers from './triggers';
import dynamicData from './dynamic-data';
export default defineApp({
name: 'Google Calendar',
key: 'google-calendar',
baseUrl: 'https://calendar.google.com',
apiBaseUrl: 'https://www.googleapis.com/calendar',
iconUrl: '{BASE_URL}/apps/google-calendar/assets/favicon.svg',
authDocUrl: 'https://automatisch.io/docs/apps/google-calendar/connection',
primaryColor: '448AFF',
supportsConnections: true,
beforeRequest: [addAuthHeader],
auth,
triggers,
dynamicData,
});

View File

@@ -0,0 +1,4 @@
import newCalendar from './new-calendar';
import newEvent from './new-event';
export default [newCalendar, newEvent];

View File

@@ -0,0 +1,34 @@
import defineTrigger from '../../../../helpers/define-trigger';
export default defineTrigger({
name: 'New calendar',
key: 'newCalendar',
pollInterval: 15,
description: 'Triggers when a new calendar is created.',
arguments: [],
async run($) {
const params: Record<string, unknown> = {
pageToken: undefined as unknown as string,
maxResults: 250,
};
do {
const { data } = await $.http.get('/v3/users/me/calendarList', {
params,
});
params.pageToken = data.nextPageToken;
if (data.items?.length) {
for (const calendar of data.items.reverse()) {
$.pushTriggerItem({
raw: calendar,
meta: {
internalId: calendar.etag,
},
});
}
}
} while (params.pageToken);
},
});

View File

@@ -0,0 +1,55 @@
import defineTrigger from '../../../../helpers/define-trigger';
export default defineTrigger({
name: 'New event',
key: 'newEvent',
pollInterval: 15,
description: 'Triggers when a new event is created.',
arguments: [
{
label: 'Calendar',
key: 'calendarId',
type: 'dropdown' as const,
required: true,
description: '',
variables: false,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listCalendars',
},
],
},
},
],
async run($) {
const calendarId = $.step.parameters.calendarId;
const params: Record<string, unknown> = {
pageToken: undefined as unknown as string,
orderBy: 'updated',
};
do {
const { data } = await $.http.get(`/v3/calendars/${calendarId}/events`, {
params,
});
params.pageToken = data.nextPageToken;
if (data.items?.length) {
for (const event of data.items.reverse()) {
$.pushTriggerItem({
raw: event,
meta: {
internalId: event.etag,
},
});
}
}
} while (params.pageToken);
},
});

View File

@@ -0,0 +1,83 @@
import defineAction from '../../../../helpers/define-action';
export default defineAction({
name: 'Create contact',
key: 'createContact',
description: `Create contact on user's account.`,
arguments: [
{
label: 'Company name',
key: 'company',
type: 'string' as const,
required: false,
variables: true,
},
{
label: 'Email',
key: 'email',
type: 'string' as const,
required: false,
variables: true,
},
{
label: 'First name',
key: 'firstName',
type: 'string' as const,
required: false,
variables: true,
},
{
label: 'Last name',
key: 'lastName',
type: 'string' as const,
required: false,
description: 'Last name',
variables: true,
},
{
label: 'Phone',
key: 'phone',
type: 'string' as const,
required: false,
variables: true,
},
{
label: 'Website URL',
key: 'website',
type: 'string' as const,
required: false,
variables: true,
},
{
label: 'Owner ID',
key: 'hubspotOwnerId',
type: 'string' as const,
required: false,
variables: true,
},
],
async run($) {
const company = $.step.parameters.company as string;
const email = $.step.parameters.email as string;
const firstName = $.step.parameters.firstName as string;
const lastName = $.step.parameters.lastName as string;
const phone = $.step.parameters.phone as string;
const website = $.step.parameters.website as string;
const hubspotOwnerId = $.step.parameters.hubspotOwnerId as string;
const response = await $.http.post(`crm/v3/objects/contacts`, {
properties: {
company,
email,
firstname: firstName,
lastname: lastName,
phone,
website,
hubspot_owner_id: hubspotOwnerId,
},
});
$.setActionItem({ raw: response.data });
},
});

View File

@@ -0,0 +1,3 @@
import createContact from './create-contact';
export default [ createContact ];

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="27px" height="28px" viewBox="0 0 27 28" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g fill="#f95c35">
<path d="M19.614233,20.1771162 C17.5228041,20.1771162 15.8274241,18.4993457 15.8274241,16.4299995 C15.8274241,14.3602937 17.5228041,12.6825232 19.614233,12.6825232 C21.7056619,12.6825232 23.4010418,14.3602937 23.4010418,16.4299995 C23.4010418,18.4993457 21.7056619,20.1771162 19.614233,20.1771162 M20.7478775,9.21551429 L20.7478775,5.88190722 C21.6271788,5.47091457 22.243053,4.59067833 22.243053,3.56912967 L22.243053,3.49218091 C22.243053,2.08229273 21.0774338,0.928780545 19.6527478,0.928780545 L19.5753548,0.928780545 C18.1506688,0.928780545 16.9850496,2.08229273 16.9850496,3.49218091 L16.9850496,3.56912967 C16.9850496,4.59067833 17.6009238,5.47127414 18.4802251,5.88226679 L18.4802251,9.21551429 C17.1710836,9.4157968 15.9749432,9.95012321 14.9884545,10.7365107 L5.73944086,3.61659339 C5.80048326,3.3846684 5.84335828,3.14591151 5.84372163,2.89492912 C5.84517502,1.29842223 4.53930368,0.00215931486 2.92531356,1.87311107e-06 C1.31205014,-0.00179599501 0.00181863138,1.29087118 1.8932965e-06,2.88773765 C-0.00181484479,4.48460412 1.30405649,5.78086703 2.91804661,5.7826649 C3.44381061,5.78338405 3.93069642,5.63559929 4.35726652,5.39540411 L13.4551275,12.3995387 C12.6815604,13.5552084 12.2281026,14.9395668 12.2281026,16.4299995 C12.2281026,17.9901894 12.7262522,19.433518 13.5677653,20.6204705 L10.8012365,23.3586237 C10.5825013,23.2935408 10.3557723,23.2482346 10.1152362,23.2482346 C8.78938076,23.2482346 7.71423516,24.3118533 7.71423516,25.6239375 C7.71423516,26.9363812 8.78938076,28 10.1152362,28 C11.441455,28 12.5162373,26.9363812 12.5162373,25.6239375 C12.5162373,25.3866189 12.4704555,25.1618854 12.4046896,24.9454221 L15.1414238,22.2371135 C16.3837093,23.1752411 17.9308435,23.7390526 19.614233,23.7390526 C23.6935367,23.7390526 27,20.466573 27,16.4299995 C27,12.7756527 24.2872467,9.7566726 20.7478775,9.21551429"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,20 @@
import { IField, IGlobalVariable } from '@automatisch/types';
import { URLSearchParams } from 'url';
import scopes from '../common/scopes';
export default async function generateAuthUrl($: IGlobalVariable) {
const oauthRedirectUrlField = $.app.auth.fields.find(
(field: IField) => field.key == 'oAuthRedirectUrl'
);
const callbackUrl = oauthRedirectUrlField.value as string;
const searchParams = new URLSearchParams({
client_id: $.auth.data.clientId as string,
redirect_uri: callbackUrl,
scope: scopes.join(' '),
});
const url = `https://app.hubspot.com/oauth/authorize?${searchParams.toString()}`;
await $.auth.set({ url });
}

View File

@@ -0,0 +1,48 @@
import generateAuthUrl from './generate-auth-url';
import verifyCredentials from './verify-credentials';
import isStillVerified from './is-still-verified';
import refreshToken from './refresh-token';
export default {
fields: [
{
key: 'oAuthRedirectUrl',
label: 'OAuth Redirect URL',
type: 'string' as const,
required: true,
readOnly: true,
value: '{WEB_APP_URL}/app/hubspot/connections/add',
placeholder: null,
description:
'When asked to input an OAuth callback or redirect URL in HubSpot OAuth, enter the URL above.',
clickToCopy: true,
},
{
key: 'clientId',
label: 'Client ID',
type: 'string' as const,
required: true,
readOnly: false,
value: null,
placeholder: null,
description: null,
clickToCopy: false,
},
{
key: 'clientSecret',
label: 'Client Secret',
type: 'string' as const,
required: true,
readOnly: false,
value: null,
placeholder: null,
description: null,
clickToCopy: false,
},
],
generateAuthUrl,
verifyCredentials,
isStillVerified,
refreshToken,
};

View File

@@ -0,0 +1,10 @@
import { IGlobalVariable } from '@automatisch/types';
import getAccessTokenInfo from '../common/get-access-token-info';
const isStillVerified = async ($: IGlobalVariable) => {
await getAccessTokenInfo($);
return true;
};
export default isStillVerified;

View File

@@ -0,0 +1,28 @@
import { IGlobalVariable, IField } from '@automatisch/types';
import { URLSearchParams } from 'url';
const refreshToken = async ($: IGlobalVariable) => {
const oauthRedirectUrlField = $.app.auth.fields.find(
(field: IField) => field.key == 'oAuthRedirectUrl'
);
const callbackUrl = oauthRedirectUrlField.value as string;
const params = new URLSearchParams({
grant_type: 'refresh_token',
client_id: $.auth.data.clientId as string,
client_secret: $.auth.data.clientSecret as string,
redirect_uri: callbackUrl,
refresh_token: $.auth.data.refreshToken as string,
});
const { data } = await $.http.post('/oauth/v1/token', params.toString());
await $.auth.set({
accessToken: data.access_token,
expiresIn: data.expires_in,
refreshToken: data.refresh_token,
});
};
export default refreshToken;

View File

@@ -0,0 +1,52 @@
import { IGlobalVariable, IField } from '@automatisch/types';
import { URLSearchParams } from 'url';
import getAccessTokenInfo from '../common/get-access-token-info';
const verifyCredentials = async ($: IGlobalVariable) => {
const oauthRedirectUrlField = $.app.auth.fields.find(
(field: IField) => field.key == 'oAuthRedirectUrl'
);
const callbackUrl = oauthRedirectUrlField.value as string;
const params = new URLSearchParams({
grant_type: 'authorization_code',
client_id: $.auth.data.clientId as string,
client_secret: $.auth.data.clientSecret as string,
redirect_uri: callbackUrl,
code: $.auth.data.code as string,
});
const { data: verifiedCredentials } = await $.http.post(
'/oauth/v1/token',
params.toString()
);
const {
access_token: accessToken,
refresh_token: refreshToken,
expires_in: expiresIn,
} = verifiedCredentials;
await $.auth.set({
accessToken,
refreshToken,
expiresIn,
});
const accessTokenInfo = await getAccessTokenInfo($);
await $.auth.set({
screenName: accessTokenInfo.user,
hubDomain: accessTokenInfo.hub_domain,
scopes: accessTokenInfo.scopes,
scopeToScopeGroupPks: accessTokenInfo.scope_to_scope_group_pks,
trialScopes: accessTokenInfo.trial_scopes,
trialScopeToScoreGroupPks: accessTokenInfo.trial_scope_to_scope_group_pks,
hubId: accessTokenInfo.hub_id,
appId: accessTokenInfo.app_id,
userId: accessTokenInfo.user_id,
expiresIn: accessTokenInfo.expires_in,
tokenType: accessTokenInfo.token_type,
});
};
export default verifyCredentials;

View File

@@ -0,0 +1,14 @@
import { TBeforeRequest } from '@automatisch/types';
const addAuthHeader: TBeforeRequest = ($, requestConfig) => {
if (requestConfig.additionalProperties?.skipAddingAuthHeader) return requestConfig;
if ($.auth.data?.accessToken) {
const authorizationHeader = `Bearer ${$.auth.data.accessToken}`;
requestConfig.headers.Authorization = authorizationHeader;
}
return requestConfig;
};
export default addAuthHeader;

View File

@@ -0,0 +1,11 @@
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
const getAccessTokenInfo = async ($: IGlobalVariable): Promise<IJSONObject> => {
const response = await $.http.get(
`/oauth/v1/access-tokens/${$.auth.data.accessToken}`
);
return response.data;
};
export default getAccessTokenInfo;

View File

@@ -0,0 +1,3 @@
const scopes = ['crm.objects.contacts.read', 'crm.objects.contacts.write'];
export default scopes;

View File

View File

@@ -0,0 +1,18 @@
import defineApp from '../../helpers/define-app';
import addAuthHeader from './common/add-auth-header';
import actions from './actions';
import auth from './auth';
export default defineApp({
name: 'HubSpot',
key: 'hubspot',
iconUrl: '{BASE_URL}/apps/hubspot/assets/favicon.svg',
authDocUrl: 'https://automatisch.io/docs/apps/hubspot/connection',
supportsConnections: true,
baseUrl: 'https://www.hubspot.com',
apiBaseUrl: 'https://api.hubapi.com',
primaryColor: 'F95C35',
beforeRequest: [addAuthHeader],
auth,
actions,
});

View File

@@ -0,0 +1,639 @@
export const fields = [
{
label: 'Client Name',
key: 'clientName',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Contact First Name',
key: 'contactFirstName',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Contact Last Name',
key: 'contactLastName',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Contact Email',
key: 'contactEmail',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Contact Phone',
key: 'contactPhone',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Language Code',
key: 'languageCode',
type: 'dropdown' as const,
required: false,
description: '',
variables: true,
options: [
{ value: 1, label: 'English - United States' },
{ value: 2, label: 'Italian' },
{ value: 3, label: 'German' },
{ value: 4, label: 'French' },
{ value: 5, label: 'Portuguese - Brazilian' },
{ value: 6, label: 'Dutch' },
{ value: 7, label: 'Spanish' },
{ value: 8, label: 'Norwegian' },
{ value: 9, label: 'Danish' },
{ value: 10, label: 'Japanese' },
{ value: 11, label: 'Swedish' },
{ value: 12, label: 'Spanish - Spain' },
{ value: 13, label: 'French - Canada' },
{ value: 14, label: 'Lithuanian' },
{ value: 15, label: 'Polish' },
{ value: 16, label: 'Czech' },
{ value: 17, label: 'Croatian' },
{ value: 18, label: 'Albanian' },
{ value: 19, label: 'Greek' },
{ value: 20, label: 'English - United Kingdom' },
{ value: 21, label: 'Portuguese - Portugal' },
{ value: 22, label: 'Slovenian' },
{ value: 23, label: 'Finnish' },
{ value: 24, label: 'Romanian' },
{ value: 25, label: 'Turkish - Turkey' },
{ value: 26, label: 'Thai' },
{ value: 27, label: 'Macedonian' },
{ value: 28, label: 'Chinese - Taiwan' },
{ value: 29, label: 'Russian (Russia)' },
{ value: 30, label: 'Arabic' },
{ value: 31, label: 'Persian' },
{ value: 32, label: 'Latvian' },
{ value: 33, label: 'Serbian' },
{ value: 34, label: 'Slovak' },
{ value: 35, label: 'Estonian' },
{ value: 36, label: 'Bulgarian' },
{ value: 37, label: 'Hebrew' },
{ value: 38, label: 'Khmer' },
{ value: 39, label: 'Hungarian' },
{ value: 40, label: 'French - Swiss' },
],
},
{
label: 'Currency Code',
key: 'currencyCode',
type: 'dropdown' as const,
required: false,
description: '',
variables: true,
options: [
{ value: 1, label: 'US Dollar' },
{ value: 2, label: 'British Pound' },
{ value: 3, label: 'Euro' },
{ value: 4, label: 'South African Rand' },
{ value: 5, label: 'Danish Krone' },
{ value: 6, label: 'Israeli Shekel' },
{ value: 7, label: 'Swedish Krona' },
{ value: 8, label: 'Kenyan Shilling' },
{ value: 9, label: 'Canadian Dollar' },
{ value: 10, label: 'Philippine Peso' },
{ value: 11, label: 'Indian Rupee' },
{ value: 12, label: 'Australian Dollar' },
{ value: 13, label: 'Singapore Dollar' },
{ value: 14, label: 'Norske Kroner' },
{ value: 15, label: 'New Zealand Dollar' },
{ value: 16, label: 'Vietnamese Dong' },
{ value: 17, label: 'Swiss Franc' },
{ value: 18, label: 'Guatemalan Quetzal' },
{ value: 19, label: 'Malaysian Ringgit' },
{ value: 20, label: 'Brazilian Real' },
{ value: 21, label: 'Thai Baht' },
{ value: 22, label: 'Nigerian Naira' },
{ value: 23, label: 'Argentine Peso' },
{ value: 24, label: 'Bangladeshi Taka' },
{ value: 25, label: 'United Arab Emirates Dirham' },
{ value: 26, label: 'Hong Kong Dollar' },
{ value: 27, label: 'Indonesian Rupiah' },
{ value: 28, label: 'Mexican Peso' },
{ value: 29, label: 'Egyptian Pound' },
{ value: 30, label: 'Colombian Peso' },
{ value: 31, label: 'West African Franc' },
{ value: 32, label: 'Chinese Renminbi' },
{ value: 33, label: 'Rwandan Franc' },
{ value: 34, label: 'Tanzanian Shilling' },
{ value: 35, label: 'Netherlands Antillean Guilder' },
{ value: 36, label: 'Trinidad and Tobago Dollar' },
{ value: 37, label: 'East Caribbean Dollar' },
{ value: 38, label: 'Ghanaian Cedi' },
{ value: 39, label: 'Bulgarian Lev' },
{ value: 40, label: 'Aruban Florin' },
{ value: 41, label: 'Turkish Lira' },
{ value: 42, label: 'Romanian New Leu' },
{ value: 43, label: 'Croatian Kuna' },
{ value: 44, label: 'Saudi Riyal' },
{ value: 45, label: 'Japanese Yen' },
{ value: 46, label: 'Maldivian Rufiyaa' },
{ value: 47, label: 'Costa Rican Colón' },
{ value: 48, label: 'Pakistani Rupee' },
{ value: 49, label: 'Polish Zloty' },
{ value: 50, label: 'Sri Lankan Rupee' },
{ value: 51, label: 'Czech Koruna' },
{ value: 52, label: 'Uruguayan Peso' },
{ value: 53, label: 'Namibian Dollar' },
{ value: 54, label: 'Tunisian Dinar' },
{ value: 55, label: 'Russian Ruble' },
{ value: 56, label: 'Mozambican Metical' },
{ value: 57, label: 'Omani Rial' },
{ value: 58, label: 'Ukrainian Hryvnia' },
{ value: 59, label: 'Macanese Pataca' },
{ value: 60, label: 'Taiwan New Dollar' },
{ value: 61, label: 'Dominican Peso' },
{ value: 62, label: 'Chilean Peso' },
{ value: 63, label: 'Icelandic Króna' },
{ value: 64, label: 'Papua New Guinean Kina' },
{ value: 65, label: 'Jordanian Dinar' },
{ value: 66, label: 'Myanmar Kyat' },
{ value: 67, label: 'Peruvian Sol' },
{ value: 68, label: 'Botswana Pula' },
{ value: 69, label: 'Hungarian Forint' },
{ value: 70, label: 'Ugandan Shilling' },
{ value: 71, label: 'Barbadian Dollar' },
{ value: 72, label: 'Brunei Dollar' },
{ value: 73, label: 'Georgian Lari' },
{ value: 74, label: 'Qatari Riyal' },
{ value: 75, label: 'Honduran Lempira' },
{ value: 76, label: 'Surinamese Dollar' },
{ value: 77, label: 'Bahraini Dinar' },
{ value: 78, label: 'Venezuelan Bolivars' },
{ value: 79, label: 'South Korean Won' },
{ value: 80, label: 'Moroccan Dirham' },
{ value: 81, label: 'Jamaican Dollar' },
{ value: 82, label: 'Angolan Kwanza' },
{ value: 83, label: 'Haitian Gourde' },
{ value: 84, label: 'Zambian Kwacha' },
{ value: 85, label: 'Nepalese Rupee' },
{ value: 86, label: 'CFP Franc' },
{ value: 87, label: 'Mauritian Rupee' },
{ value: 88, label: 'Cape Verdean Escudo' },
{ value: 89, label: 'Kuwaiti Dinar' },
{ value: 90, label: 'Algerian Dinar' },
{ value: 91, label: 'Macedonian Denar' },
{ value: 92, label: 'Fijian Dollar' },
{ value: 93, label: 'Bolivian Boliviano' },
{ value: 94, label: 'Albanian Lek' },
{ value: 95, label: 'Serbian Dinar' },
{ value: 96, label: 'Lebanese Pound' },
{ value: 97, label: 'Armenian Dram' },
{ value: 98, label: 'Azerbaijan Manat' },
{ value: 99, label: 'Bosnia and Herzegovina Convertible Mark' },
{ value: 100, label: 'Belarusian Ruble' },
{ value: 101, label: 'Gibraltar Pound' },
{ value: 102, label: 'Moldovan Leu' },
{ value: 103, label: 'Kazakhstani Tenge' },
{ value: 104, label: 'Ethiopian Birr' },
{ value: 105, label: 'Gambia Dalasi' },
{ value: 106, label: 'Paraguayan Guarani' },
{ value: 107, label: 'Malawi Kwacha' },
{ value: 108, label: 'Zimbabwean Dollar' },
{ value: 109, label: 'Cambodian Riel' },
{ value: 110, label: 'Vanuatu Vatu' },
{ value: 111, label: 'Cuban Peso' },
{ value: 112, label: 'Cayman Island Dollar' },
{ value: 113, label: 'Swazi lilangeni' },
{ value: 114, label: 'BZ Dollar' },
{ value: 115, label: 'Libyan Dinar' },
{ value: 116, label: 'Silver Troy Ounce' },
{ value: 117, label: 'Gold Troy Ounce' },
{ value: 118, label: 'Nicaraguan Córdoba' },
],
},
{
label: 'Id Number',
key: 'idNumber',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Vat Number',
key: 'vatNumber',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Street Address',
key: 'streetAddress',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Apt/Suite',
key: 'aptSuite',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'City',
key: 'city',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'State/Province',
key: 'stateProvince',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Postal Code',
key: 'postalCode',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Country Code',
key: 'countryCode',
type: 'dropdown' as const,
required: false,
description: '',
variables: true,
options: [
{ value: 4, label: 'Afghanistan' },
{ value: 8, label: 'Albania' },
{ value: 12, label: 'Algeria' },
{ value: 16, label: 'American Samoa' },
{ value: 20, label: 'Andorra' },
{ value: 24, label: 'Angola' },
{ value: 660, label: 'Anguilla' },
{ value: 10, label: 'Antarctica' },
{ value: 28, label: 'Antigua and Barbuda' },
{ value: 32, label: 'Argentina' },
{ value: 51, label: 'Armenia' },
{ value: 533, label: 'Aruba' },
{ value: 36, label: 'Australia' },
{ value: 40, label: 'Austria' },
{ value: 31, label: 'Azerbaijan' },
{ value: 44, label: 'Bahamas' },
{ value: 48, label: 'Bahrain' },
{ value: 50, label: 'Bangladesh' },
{ value: 52, label: 'Barbados' },
{ value: 112, label: 'Belarus' },
{ value: 56, label: 'Belgium' },
{ value: 84, label: 'Belize' },
{ value: 204, label: 'Benin' },
{ value: 60, label: 'Bermuda' },
{ value: 64, label: 'Bhutan' },
{ value: 68, label: 'Bolivia, Plurinational State of' },
{ value: 535, label: 'Bonaire, Sint Eustatius and Saba' },
{ value: 70, label: 'Bosnia and Herzegovina' },
{ value: 72, label: 'Botswana' },
{ value: 74, label: 'Bouvet Island' },
{ value: 76, label: 'Brazil' },
{ value: 86, label: 'British Indian Ocean Territory' },
{ value: 96, label: 'Brunei Darussalam' },
{ value: 100, label: 'Bulgaria' },
{ value: 854, label: 'Burkina Faso' },
{ value: 108, label: 'Burundi' },
{ value: 116, label: 'Cambodia' },
{ value: 120, label: 'Cameroon' },
{ value: 124, label: 'Canada' },
{ value: 132, label: 'Cape Verde' },
{ value: 136, label: 'Cayman Islands' },
{ value: 140, label: 'Central African Republic' },
{ value: 148, label: 'Chad' },
{ value: 152, label: 'Chile' },
{ value: 156, label: 'China' },
{ value: 162, label: 'Christmas Island' },
{ value: 166, label: 'Cocos (Keeling) Islands' },
{ value: 170, label: 'Colombia' },
{ value: 174, label: 'Comoros' },
{ value: 178, label: 'Congo' },
{ value: 180, label: 'Congo, the Democratic Republic of the' },
{ value: 184, label: 'Cook Islands' },
{ value: 188, label: 'Costa Rica' },
{ value: 191, label: 'Croatia' },
{ value: 192, label: 'Cuba' },
{ value: 531, label: 'Curaçao' },
{ value: 196, label: 'Cyprus' },
{ value: 203, label: 'Czech Republic' },
{ value: 384, label: "Côte d'Ivoire" },
{ value: 208, label: 'Denmark' },
{ value: 262, label: 'Djibouti' },
{ value: 212, label: 'Dominica' },
{ value: 214, label: 'Dominican Republic' },
{ value: 218, label: 'Ecuador' },
{ value: 818, label: 'Egypt' },
{ value: 222, label: 'El Salvador' },
{ value: 226, label: 'Equatorial Guinea' },
{ value: 232, label: 'Eritrea' },
{ value: 233, label: 'Estonia' },
{ value: 231, label: 'Ethiopia' },
{ value: 238, label: 'Falkland Islands (Malvinas)' },
{ value: 234, label: 'Faroe Islands' },
{ value: 242, label: 'Fiji' },
{ value: 246, label: 'Finland' },
{ value: 250, label: 'France' },
{ value: 254, label: 'French Guiana' },
{ value: 258, label: 'French Polynesia' },
{ value: 260, label: 'French Southern Territories' },
{ value: 266, label: 'Gabon' },
{ value: 270, label: 'Gambia' },
{ value: 268, label: 'Georgia' },
{ value: 276, label: 'Germany' },
{ value: 288, label: 'Ghana' },
{ value: 292, label: 'Gibraltar' },
{ value: 300, label: 'Greece' },
{ value: 304, label: 'Greenland' },
{ value: 308, label: 'Grenada' },
{ value: 312, label: 'Guadeloupe' },
{ value: 316, label: 'Guam' },
{ value: 320, label: 'Guatemala' },
{ value: 831, label: 'Guernsey' },
{ value: 324, label: 'Guinea' },
{ value: 624, label: 'Guinea-Bissau' },
{ value: 328, label: 'Guyana' },
{ value: 332, label: 'Haiti' },
{ value: 334, label: 'Heard Island and McDonald Islands' },
{ value: 336, label: 'Holy See (Vatican City State)' },
{ value: 340, label: 'Honduras' },
{ value: 344, label: 'Hong Kong' },
{ value: 348, label: 'Hungary' },
{ value: 352, label: 'Iceland' },
{ value: 356, label: 'India' },
{ value: 360, label: 'Indonesia' },
{ value: 364, label: 'Iran, Islamic Republic of' },
{ value: 368, label: 'Iraq' },
{ value: 372, label: 'Ireland' },
{ value: 833, label: 'Isle of Man' },
{ value: 376, label: 'Israel' },
{ value: 380, label: 'Italy' },
{ value: 388, label: 'Jamaica' },
{ value: 392, label: 'Japan' },
{ value: 832, label: 'Jersey' },
{ value: 400, label: 'Jordan' },
{ value: 398, label: 'Kazakhstan' },
{ value: 404, label: 'Kenya' },
{ value: 296, label: 'Kiribati' },
{ value: 408, label: "Korea, Democratic People's Republic of" },
{ value: 410, label: 'Korea, Republic of' },
{ value: 414, label: 'Kuwait' },
{ value: 417, label: 'Kyrgyzstan' },
{ value: 418, label: "Lao People's Democratic Republic" },
{ value: 428, label: 'Latvia' },
{ value: 422, label: 'Lebanon' },
{ value: 426, label: 'Lesotho' },
{ value: 430, label: 'Liberia' },
{ value: 434, label: 'Libya' },
{ value: 438, label: 'Liechtenstein' },
{ value: 440, label: 'Lithuania' },
{ value: 442, label: 'Luxembourg' },
{ value: 446, label: 'Macao' },
{ value: 807, label: 'Macedonia, the former Yugoslav Republic of' },
{ value: 450, label: 'Madagascar' },
{ value: 454, label: 'Malawi' },
{ value: 458, label: 'Malaysia' },
{ value: 462, label: 'Maldives' },
{ value: 466, label: 'Mali' },
{ value: 470, label: 'Malta' },
{ value: 584, label: 'Marshall Islands' },
{ value: 474, label: 'Martinique' },
{ value: 478, label: 'Mauritania' },
{ value: 480, label: 'Mauritius' },
{ value: 175, label: 'Mayotte' },
{ value: 484, label: 'Mexico' },
{ value: 583, label: 'Micronesia, Federated States of' },
{ value: 498, label: 'Moldova, Republic of' },
{ value: 492, label: 'Monaco' },
{ value: 496, label: 'Mongolia' },
{ value: 499, label: 'Montenegro' },
{ value: 500, label: 'Montserrat' },
{ value: 504, label: 'Morocco' },
{ value: 508, label: 'Mozambique' },
{ value: 104, label: 'Myanmar' },
{ value: 516, label: 'Namibia' },
{ value: 520, label: 'Nauru' },
{ value: 524, label: 'Nepal' },
{ value: 528, label: 'Netherlands' },
{ value: 540, label: 'New Caledonia' },
{ value: 554, label: 'New Zealand' },
{ value: 558, label: 'Nicaragua' },
{ value: 562, label: 'Niger' },
{ value: 566, label: 'Nigeria' },
{ value: 570, label: 'Niue' },
{ value: 574, label: 'Norfolk Island' },
{ value: 580, label: 'Northern Mariana Islands' },
{ value: 578, label: 'Norway' },
{ value: 512, label: 'Oman' },
{ value: 586, label: 'Pakistan' },
{ value: 585, label: 'Palau' },
{ value: 275, label: 'Palestine' },
{ value: 591, label: 'Panama' },
{ value: 598, label: 'Papua New Guinea' },
{ value: 600, label: 'Paraguay' },
{ value: 604, label: 'Peru' },
{ value: 608, label: 'Philippines' },
{ value: 612, label: 'Pitcairn' },
{ value: 616, label: 'Poland' },
{ value: 620, label: 'Portugal' },
{ value: 630, label: 'Puerto Rico' },
{ value: 634, label: 'Qatar' },
{ value: 642, label: 'Romania' },
{ value: 643, label: 'Russian Federation' },
{ value: 646, label: 'Rwanda' },
{ value: 638, label: 'Réunion' },
{ value: 652, label: 'Saint Barthélemy' },
{ value: 654, label: 'Saint Helena, Ascension and Tristan da Cunha' },
{ value: 659, label: 'Saint Kitts and Nevis' },
{ value: 662, label: 'Saint Lucia' },
{ value: 663, label: 'Saint Martin (French part)' },
{ value: 666, label: 'Saint Pierre and Miquelon' },
{ value: 670, label: 'Saint Vincent and the Grenadines' },
{ value: 882, label: 'Samoa' },
{ value: 674, label: 'San Marino' },
{ value: 678, label: 'Sao Tome and Principe' },
{ value: 682, label: 'Saudi Arabia' },
{ value: 686, label: 'Senegal' },
{ value: 688, label: 'Serbia' },
{ value: 690, label: 'Seychelles' },
{ value: 694, label: 'Sierra Leone' },
{ value: 702, label: 'Singapore' },
{ value: 534, label: 'Sint Maarten (Dutch part)' },
{ value: 703, label: 'Slovakia' },
{ value: 705, label: 'Slovenia' },
{ value: 90, label: 'Solomon Islands' },
{ value: 706, label: 'Somalia' },
{ value: 710, label: 'South Africa' },
{ value: 239, label: 'South Georgia and the South Sandwich Islands' },
{ value: 728, label: 'South Sudan' },
{ value: 724, label: 'Spain' },
{ value: 144, label: 'Sri Lanka' },
{ value: 729, label: 'Sudan' },
{ value: 740, label: 'Suriname' },
{ value: 744, label: 'Svalbard and Jan Mayen' },
{ value: 748, label: 'Swaziland' },
{ value: 752, label: 'Sweden' },
{ value: 756, label: 'Switzerland' },
{ value: 760, label: 'Syrian Arab Republic' },
{ value: 158, label: 'Taiwan, Province of China' },
{ value: 762, label: 'Tajikistan' },
{ value: 834, label: 'Tanzania, United Republic of' },
{ value: 764, label: 'Thailand' },
{ value: 626, label: 'Timor-Leste' },
{ value: 768, label: 'Togo' },
{ value: 772, label: 'Tokelau' },
{ value: 776, label: 'Tonga' },
{ value: 780, label: 'Trinidad and Tobago' },
{ value: 788, label: 'Tunisia' },
{ value: 792, label: 'Turkey' },
{ value: 795, label: 'Turkmenistan' },
{ value: 796, label: 'Turks and Caicos Islands' },
{ value: 798, label: 'Tuvalu' },
{ value: 800, label: 'Uganda' },
{ value: 804, label: 'Ukraine' },
{ value: 784, label: 'United Arab Emirates' },
{ value: 826, label: 'United Kingdom' },
{ value: 840, label: 'United States' },
{ value: 581, label: 'United States Minor Outlying Islands' },
{ value: 858, label: 'Uruguay' },
{ value: 860, label: 'Uzbekistan' },
{ value: 548, label: 'Vanuatu' },
{ value: 862, label: 'Venezuela, Bolivarian Republic of' },
{ value: 704, label: 'Viet Nam' },
{ value: 92, label: 'Virgin Islands, British' },
{ value: 850, label: 'Virgin Islands, U.S.' },
{ value: 876, label: 'Wallis and Futuna' },
{ value: 732, label: 'Western Sahara' },
{ value: 887, label: 'Yemen' },
{ value: 894, label: 'Zambia' },
{ value: 716, label: 'Zimbabwe' },
{ value: 248, label: 'Åland Islands' },
],
},
{
label: 'Shipping Street Address',
key: 'shippingStreetAddress',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Shipping Apt/Suite',
key: 'shippingAptSuite',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Shipping City',
key: 'shippingCity',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Shipping State/Province',
key: 'shippingStateProvince',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Shipping Postal Code',
key: 'shippingPostalCode',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Shipping Country Code',
key: 'shippingCountryCode',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Private Notes',
key: 'privateNotes',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Public Notes',
key: 'publicNotes',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Website',
key: 'website',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Value 1',
key: 'customValue1',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Value 2',
key: 'customValue2',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Value 3',
key: 'customValue3',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Value 4',
key: 'customValue4',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
];

View File

@@ -0,0 +1,84 @@
import defineAction from '../../../../helpers/define-action';
import { filterProvidedFields } from '../../common/filter-provided-fields';
import { fields } from './fields';
export default defineAction({
name: 'Create client',
key: 'createClient',
description: 'Creates a new client.',
arguments: fields,
async run($) {
const {
clientName,
contactFirstName,
contactLastName,
contactEmail,
contactPhone,
languageCode,
currencyCode,
idNumber,
vatNumber,
streetAddress,
aptSuite,
city,
stateProvince,
postalCode,
countryCode,
shippingStreetAddress,
shippingAptSuite,
shippingCity,
shippingStateProvince,
shippingPostalCode,
shippingCountryCode,
privateNotes,
publicNotes,
website,
customValue1,
customValue2,
customValue3,
customValue4,
} = $.step.parameters;
const bodyFields = {
name: clientName,
contacts: {
first_name: contactFirstName,
last_name: contactLastName,
email: contactEmail,
phone: contactPhone,
},
settings: {
language_id: languageCode,
currency_id: currencyCode,
},
id_number: idNumber,
vat_number: vatNumber,
address1: streetAddress,
address2: aptSuite,
city: city,
state: stateProvince,
postal_code: postalCode,
country_id: countryCode,
shipping_address1: shippingStreetAddress,
shipping_address2: shippingAptSuite,
shipping_city: shippingCity,
shipping_state: shippingStateProvince,
shipping_postal_code: shippingPostalCode,
shipping_country_id: shippingCountryCode,
private_notes: privateNotes,
public_notes: publicNotes,
website: website,
custom_value1: customValue1,
custom_value2: customValue2,
custom_value3: customValue3,
custom_value4: customValue4,
};
const body = filterProvidedFields(bodyFields);
const response = await $.http.post('/v1/clients', body);
$.setActionItem({ raw: response.data.data });
},
});

View File

@@ -0,0 +1,407 @@
export const fields = [
{
label: 'Client ID',
key: 'clientId',
type: 'dropdown' as const,
required: true,
description: 'The ID of the client, not the name or email address.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listClients',
},
],
},
},
{
label: 'Send Email',
key: 'sendEmail',
type: 'dropdown' as const,
required: false,
description: '',
variables: true,
options: [
{ label: 'False', value: 'false' },
{ label: 'True', value: 'true' },
],
},
{
label: 'Mark Sent',
key: 'markSent',
type: 'dropdown' as const,
required: false,
description: 'Setting this to true creates the invoice as sent.',
variables: true,
options: [
{ label: 'False', value: 'false' },
{ label: 'True', value: 'true' },
],
},
{
label: 'Paid',
key: 'paid',
type: 'dropdown' as const,
required: false,
description: 'Setting this to true creates the invoice as paid.',
variables: true,
options: [
{ label: 'False', value: 'false' },
{ label: 'True', value: 'true' },
],
},
{
label: 'Amount Paid',
key: 'amountPaid',
type: 'string' as const,
required: false,
description:
'If this value is greater than zero a payment will be created along with the invoice.',
variables: true,
},
{
label: 'Number',
key: 'number',
type: 'string' as const,
required: false,
description:
'The invoice number - is a unique alpha numeric number per invoice per company',
variables: true,
},
{
label: 'Discount',
key: 'discount',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'PO Number',
key: 'poNumber',
type: 'string' as const,
required: false,
description: 'The purchase order associated with this invoice',
variables: true,
},
{
label: 'Date',
key: 'date',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Due Date',
key: 'dueDate',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Tax Rate 1',
key: 'taxRate1',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Tax Name 1',
key: 'taxName1',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Tax Rate 2',
key: 'taxRate2',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Tax Name 2',
key: 'taxName2',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Tax Rate 3',
key: 'taxRate3',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Tax Name 3',
key: 'taxName3',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Field 1',
key: 'customField1',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Field 2',
key: 'customField2',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Field 3',
key: 'customField3',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Field 4',
key: 'customField4',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Surcharge 1',
key: 'customSurcharge1',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Surcharge 2',
key: 'customSurcharge2',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Surcharge 3',
key: 'customSurcharge3',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Surcharge 4',
key: 'customSurcharge4',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Is Amount Discount',
key: 'isAmountDiscount',
type: 'dropdown' as const,
required: false,
description:
'By default the discount is applied as a percentage, enabling this applies the discount as a fixed amount.',
variables: true,
options: [
{ label: 'False', value: 'false' },
{ label: 'True', value: 'true' },
],
},
{
label: 'Partial/Deposit',
key: 'partialDeposit',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Partial Due Date',
key: 'partialDueDate',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Cost',
key: 'lineItemCost',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Quatity',
key: 'lineItemQuantity',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Product',
key: 'lineItemProduct',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Discount',
key: 'lineItemDiscount',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Description',
key: 'lineItemDescription',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Tax Rate 1',
key: 'lineItemTaxRate1',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Tax Name 1',
key: 'lineItemTaxName1',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Tax Rate 2',
key: 'lineItemTaxRate2',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Tax Name 2',
key: 'lineItemTaxName2',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Tax Rate 3',
key: 'lineItemTaxRate3',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Tax Name 3',
key: 'lineItemTaxName3',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Custom Field 1',
key: 'lineItemCustomField1',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Custom Field 2',
key: 'lineItemCustomField2',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Custom Field 3',
key: 'lineItemCustomField3',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Custom Field 4',
key: 'lineItemCustomField4',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Line Item Product Cost',
key: 'lineItemProductCost',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Public Notes',
key: 'publicNotes',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Private Notes',
key: 'privateNotes',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Terms',
key: 'terms',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Footer',
key: 'footer',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
];

View File

@@ -0,0 +1,127 @@
import defineAction from '../../../../helpers/define-action';
import { filterProvidedFields } from '../../common/filter-provided-fields';
import { fields } from './fields';
export default defineAction({
name: 'Create invoice',
key: 'createInvoice',
description: 'Creates a new invoice.',
arguments: fields,
async run($) {
const {
clientId,
sendEmail,
markSent,
paid,
amountPaid,
number,
discount,
poNumber,
date,
dueDate,
taxRate1,
taxName1,
taxRate2,
taxName2,
taxRate3,
taxName3,
customField1,
customField2,
customField3,
customField4,
customSurcharge1,
customSurcharge2,
customSurcharge3,
customSurcharge4,
isAmountDiscount,
partialDeposit,
partialDueDate,
lineItemCost,
lineItemQuantity,
lineItemProduct,
lineItemDiscount,
lineItemDescription,
lineItemTaxRate1,
lineItemTaxName1,
lineItemTaxRate2,
lineItemTaxName2,
lineItemTaxRate3,
lineItemTaxName3,
lineItemCustomField1,
lineItemCustomField2,
lineItemCustomField3,
lineItemCustomField4,
lineItemProductCost,
publicNotes,
privateNotes,
terms,
footer,
} = $.step.parameters;
const paramFields = {
send_email: sendEmail,
mark_sent: markSent,
paid: paid,
amount_paid: amountPaid,
};
const params = filterProvidedFields(paramFields);
const bodyFields = {
client_id: clientId,
number: number,
discount: discount,
po_number: poNumber,
date: date,
due_date: dueDate,
tax_rate1: taxRate1,
tax_name1: taxName1,
tax_rate2: taxRate2,
tax_name2: taxName2,
tax_rate3: taxRate3,
tax_name3: taxName3,
custom_value1: customField1,
custom_value2: customField2,
custom_value3: customField3,
custom_value4: customField4,
custom_surcharge1: customSurcharge1,
custom_surcharge2: customSurcharge2,
custom_surcharge3: customSurcharge3,
custom_surcharge4: customSurcharge4,
is_amount_discount: Boolean(isAmountDiscount),
partial: partialDeposit,
partial_due_date: partialDueDate,
line_items: [
{
cost: lineItemCost,
quantity: lineItemQuantity,
product_key: lineItemProduct,
discount: lineItemDiscount,
notes: lineItemDescription,
tax_rate1: lineItemTaxRate1,
tax_name1: lineItemTaxName1,
tax_rate2: lineItemTaxRate2,
tax_name2: lineItemTaxName2,
tax_rate3: lineItemTaxRate3,
tax_name3: lineItemTaxName3,
custom_value1: lineItemCustomField1,
custom_value2: lineItemCustomField2,
custom_value3: lineItemCustomField3,
custom_value4: lineItemCustomField4,
product_cost: lineItemProductCost,
},
],
public_notes: publicNotes,
private_notes: privateNotes,
terms: terms,
footer: footer,
};
const body = filterProvidedFields(bodyFields);
const response = await $.http.post('/v1/invoices', body, { params });
$.setActionItem({ raw: response.data.data });
},
});

View File

@@ -0,0 +1,111 @@
export const fields = [
{
label: 'Client ID',
key: 'clientId',
type: 'dropdown' as const,
required: true,
description: 'The ID of the client, not the name or email address.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listClients',
},
],
},
},
{
label: 'Payment Date',
key: 'paymentDate',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Invoice',
key: 'invoiceId',
type: 'dropdown' as const,
required: false,
description: '',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listInvoices',
},
],
},
},
{
label: 'Invoice Amount',
key: 'invoiceAmount',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Payment Type',
key: 'paymentType',
type: 'dropdown' as const,
required: false,
description: '',
variables: true,
options: [
{ label: 'Bank Transfer', value: '1' },
{ label: 'Cash', value: '2' },
{ label: 'Debit', value: '3' },
{ label: 'ACH', value: '4' },
{ label: 'Visa Card', value: '5' },
{ label: 'MasterCard', value: '6' },
{ label: 'American Express', value: '7' },
{ label: 'Discover Card', value: '8' },
{ label: 'Diners Card', value: '9' },
{ label: 'EuroCard', value: '10' },
{ label: 'Nova', value: '11' },
{ label: 'Credit Card Other', value: '12' },
{ label: 'PayPal', value: '13' },
{ label: 'Google Wallet', value: '14' },
{ label: 'Check', value: '15' },
{ label: 'Carte Blanche', value: '16' },
{ label: 'UnionPay', value: '17' },
{ label: 'JCB', value: '18' },
{ label: 'Laser', value: '19' },
{ label: 'Maestro', value: '20' },
{ label: 'Solo', value: '21' },
{ label: 'Switch', value: '22' },
{ label: 'iZettle', value: '23' },
{ label: 'Swish', value: '24' },
{ label: 'Venmo', value: '25' },
{ label: 'Money Order', value: '26' },
{ label: 'Alipay', value: '27' },
{ label: 'Sofort', value: '28' },
{ label: 'SEPA', value: '29' },
{ label: 'GoCardless', value: '30' },
{ label: 'Bitcoin', value: '31' },
],
},
{
label: 'Transfer Reference',
key: 'transferReference',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Private Notes',
key: 'privateNotes',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
];

View File

@@ -0,0 +1,42 @@
import defineAction from '../../../../helpers/define-action';
import { filterProvidedFields } from '../../common/filter-provided-fields';
import { fields } from './fields';
export default defineAction({
name: 'Create payment',
key: 'createPayment',
description: 'Creates a new payment.',
arguments: fields,
async run($) {
const {
clientId,
paymentDate,
invoiceId,
invoiceAmount,
paymentType,
transferReference,
privateNotes,
} = $.step.parameters;
const bodyFields = {
client_id: clientId,
date: paymentDate,
invoices: [
{
invoice_id: invoiceId,
amount: invoiceAmount,
},
],
type_id: paymentType,
transaction_reference: transferReference,
private_notes: privateNotes,
};
const body = filterProvidedFields(bodyFields);
const response = await $.http.post('/v1/payments', body);
$.setActionItem({ raw: response.data.data });
},
});

View File

@@ -0,0 +1,114 @@
export const fields = [
{
label: 'Product Key',
key: 'productKey',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Notes',
key: 'notes',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Price',
key: 'price',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Quantity',
key: 'quantity',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Tax Rate 1',
key: 'taxRate1',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Tax Name 1',
key: 'taxName1',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Tax Rate 2',
key: 'taxRate2',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Tax Name 2',
key: 'taxName2',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Tax Rate 3',
key: 'taxRate3',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Tax Name 3',
key: 'taxName3',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Value 1',
key: 'customValue1',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Value 2',
key: 'customValue2',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Value 3',
key: 'customValue3',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Custom Value 4',
key: 'customValue4',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
];

View File

@@ -0,0 +1,52 @@
import defineAction from '../../../../helpers/define-action';
import { filterProvidedFields } from '../../common/filter-provided-fields';
import { fields } from './fields';
export default defineAction({
name: 'Create product',
key: 'createProduct',
description: 'Creates a new product.',
arguments: fields,
async run($) {
const {
productKey,
notes,
price,
quantity,
taxRate1,
taxName1,
taxRate2,
taxName2,
taxRate3,
taxName3,
customValue1,
customValue2,
customValue3,
customValue4,
} = $.step.parameters;
const bodyFields = {
product_key: productKey,
notes: notes,
price: price,
quantity: quantity,
tax_rate1: taxRate1,
tax_name1: taxName1,
tax_rate2: taxRate2,
tax_name2: taxName2,
tax_rate3: taxRate3,
tax_name3: taxName3,
custom_value1: customValue1,
custom_value2: customValue2,
custom_value3: customValue3,
custom_value4: customValue4,
};
const body = filterProvidedFields(bodyFields);
const response = await $.http.post('/v1/products', body);
$.setActionItem({ raw: response.data.data });
},
});

Some files were not shown because too many files have changed in this diff Show More