Compare commits

..

1 Commits

Author SHA1 Message Date
Faruk AYDIN
0b8e33f96d feat(formatter): Implement find array item by property transformer 2023-09-28 12:51:29 +02:00
355 changed files with 3335 additions and 15564 deletions

View File

@@ -7,12 +7,4 @@ module.exports = {
'plugin:@typescript-eslint/recommended',
'prettier',
],
overrides: [
{
files: ['**/*.test.ts', '**/test/**/*.ts'],
rules: {
'@typescript-eslint/ban-ts-comment': ['off'],
},
},
],
};

View File

@@ -1,48 +0,0 @@
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

@@ -17,13 +17,12 @@ env:
POSTGRES_PASSWORD: automatisch_password
REDIS_HOST: localhost
APP_ENV: production
LICENSE_KEY: dummy_license_key
LICENSE_KEY: ${{ secrets.E2E_LICENSE_KEY }}
jobs:
test:
timeout-minutes: 60
runs-on:
- ubuntu-latest
runs-on: ubuntu-latest
services:
postgres:
image: postgres:14.5-alpine
@@ -68,49 +67,22 @@ jobs:
- 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
path: ./packages/e2e-tests/test-results/**/*
retention-days: 30

View File

@@ -3,13 +3,14 @@ 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
WEBHOOK_SECRET_KEY=secret
POSTGRES_DATABASE=automatisch_test
POSTGRES_PORT=5432
POSTGRES_HOST=localhost
POSTGRES_USERNAME=automatisch_test_user
POSTGRES_PASSWORD=automatisch_test_user_password
REDIS_HOST=localhost
AUTOMATISCH_CLOUD=true
POSTGRES_PASSWORD=
POSTGRES_ENABLE_SSL=false
ENCRYPTION_KEY=secret
APP_SECRET_KEY=secret
REDIS_PORT=6379
REDIS_HOST=127.0.0.1

View File

@@ -0,0 +1,5 @@
export default {
require: ['ts-node/register', './src/config/app.ts'],
files: ['**/*.test.ts'],
extensions: ['ts'],
};

View File

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

View File

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

View File

@@ -10,7 +10,7 @@
"build:watch": "nodemon --watch 'src/**/*.ts' --watch 'bin/**/*.ts' --exec yarn build --ext ts",
"start": "node dist/src/server.js",
"pretest": "APP_ENV=test ts-node ./test/setup/prepare-test-env.ts",
"test": "APP_ENV=test jest --verbose",
"test": "APP_ENV=test ava",
"lint": "eslint . --ignore-path ../../.eslintignore",
"db:create": "ts-node ./bin/database/create.ts",
"db:seed:user": "ts-node ./bin/database/seed-user.ts",
@@ -60,7 +60,6 @@
"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",
@@ -74,7 +73,6 @@
"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",
@@ -117,14 +115,12 @@
},
"devDependencies": {
"@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",
@@ -136,12 +132,9 @@
"@types/pino": "^7.0.5",
"@types/pluralize": "^0.0.30",
"@types/showdown": "^2.0.1",
"@types/supertest": "^2.0.14",
"jest": "^29.7.0",
"ava": "^5.3.1",
"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"
},

View File

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

View File

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

View File

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

View File

@@ -3,13 +3,11 @@ 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({
@@ -28,7 +26,6 @@ export default defineAction({
{ 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',

View File

@@ -1,24 +0,0 @@
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,54 @@
import defineAction from '../../../../helpers/define-action';
import findArrayItemByProperty from './transformers/find-array-item-by-property';
const transformers = {
findArrayItemByProperty,
};
export default defineAction({
name: 'Utilities',
key: 'utilities',
description: 'Specific utilities to help you transform your data.',
arguments: [
{
label: 'Transform',
key: 'transform',
type: 'dropdown' as const,
required: true,
variables: true,
options: [
{
label: 'Find Array Item By Property',
value: 'findArrayItemByProperty',
},
],
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,13 @@
import { IGlobalVariable } from '@automatisch/types';
import { find } from 'lodash';
const findArrayItemByProperty = ($: IGlobalVariable) => {
const value = JSON.parse($.step.parameters.value as string);
const propertyName = $.step.parameters.propertyName as string;
const propertyValue = $.step.parameters.propertyValue as string;
const foundItem = find(value, { [propertyName]: propertyValue });
return foundItem;
};
export default findArrayItemByProperty;

View File

@@ -1,249 +0,0 @@
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

@@ -2,35 +2,35 @@ import { IGlobalVariable, IJSONObject } from '@automatisch/types';
import capitalize from './text/capitalize';
import extractEmailAddress from './text/extract-email-address';
import extractNumber from './text/extract-number';
import findArrayItemByProperty from './utilities/find-array-item-by-property';
import formatDateTime from './date-time/format-date-time';
import formatNumber from './numbers/format-number';
import htmlToMarkdown from './text/html-to-markdown';
import lowercase from './text/lowercase';
import markdownToHtml from './text/markdown-to-html';
import performMathOperation from './numbers/perform-math-operation';
import pluralize from './text/pluralize';
import randomNumber from './numbers/random-number';
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,
extractEmailAddress,
extractNumber,
findArrayItemByProperty,
formatDateTime,
formatNumber,
htmlToMarkdown,
lowercase,
markdownToHtml,
performMathOperation,
pluralize,
randomNumber,
replace,
trimWhitespace,
useDefaultValue,
performMathOperation,
randomNumber,
formatNumber,
formatPhoneNumber,
formatDateTime,
};
export default {

View File

@@ -1,36 +0,0 @@
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,28 @@
const findArrayItemByProperty = [
{
label: 'Value',
key: 'value',
type: 'string' as const,
required: true,
description: 'Array of objects that will be searched.',
variables: true,
},
{
label: 'Property Name',
key: 'propertyName',
type: 'string' as const,
required: true,
description: 'Property name that will be searched.',
variables: true,
},
{
label: 'Property Value',
key: 'propertyValue',
type: 'string' as const,
required: true,
description: 'Property value that will be matched.',
variables: true,
},
];
export default findArrayItemByProperty;

View File

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

View File

@@ -3,7 +3,6 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -18,7 +17,6 @@ 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,7 +3,6 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -19,7 +18,6 @@ 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,7 +3,6 @@ import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getRunFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
@@ -19,7 +18,6 @@ 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

@@ -1,27 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,24 +0,0 @@
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

@@ -1,48 +0,0 @@
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

@@ -1,9 +0,0 @@
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

@@ -1,26 +0,0 @@
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

@@ -1,57 +0,0 @@
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

@@ -1,11 +0,0 @@
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

@@ -1,7 +0,0 @@
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

@@ -1,10 +0,0 @@
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

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

View File

@@ -1,36 +0,0 @@
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

@@ -1,20 +0,0 @@
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

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

View File

@@ -1,34 +0,0 @@
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

@@ -1,55 +0,0 @@
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

@@ -1,639 +0,0 @@
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

@@ -1,84 +0,0 @@
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

@@ -1,407 +0,0 @@
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

@@ -1,127 +0,0 @@
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

@@ -1,111 +0,0 @@
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

@@ -1,42 +0,0 @@
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

@@ -1,114 +0,0 @@
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

@@ -1,52 +0,0 @@
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 });
},
});

View File

@@ -1,6 +0,0 @@
import createClient from './create-client';
import createInvoice from './create-invoice';
import createPayment from './create-payment';
import createProduct from './create-product';
export default [createClient, createInvoice, createPayment, createProduct];

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 24 24" role="img" xmlns="http://www.w3.org/2000/svg"><path d="M16.247 10.326a1.164 1.164 0 11-2.328 0 1.164 1.164 0 012.328 0zm-6.288 0a1.164 1.164 0 11-2.329 0 1.164 1.164 0 012.329 0zm-.14 13.52c-4.712-.98-8.227-4.257-9.482-8.842-.421-1.537-.421-4.49 0-6.027C1.506 4.709 4.73 1.485 8.997.316c1.538-.421 4.49-.421 6.028 0 4.267 1.169 7.492 4.393 8.66 8.66.24.874.294 1.43.294 3.014 0 1.584-.054 2.14-.293 3.014-1.17 4.271-4.439 7.536-8.661 8.65-1.391.367-3.916.46-5.206.192zm6.64-9.315c-3.047-1.348-4.054-1.737-4.5-1.737-.446 0-1.433.38-4.38 1.684-2.091.926-3.828 1.76-3.86 1.79h16.663zm-9.873-.361c1.621-.729 3.06-1.387 3.196-1.464.258-.145.337-.09-5.285-3.682-.56-.358-1.023-.698-1.025-.65V15.564a790.1 790.1 0 003.114-1.394zm14.078-2.194V8.417c0-.11-1.676.993-3.496 2.12-3 1.854-3.281 2.06-3.004 2.185 1.345.611 6.42 2.862 6.5 2.872zm-8.169.11c.545.125.643.104 1.226-.263.349-.22.655-.419.681-.442.026-.024-.05-.181-.167-.35-.118-.168-.215-.5-.215-.739V9.86l-.569.21c-.726.267-2.28.27-3 .005l-.556-.205.013.452c.007.26-.088.563-.225.715-.232.256-.22.276.45.726.64.432.725.455 1.23.327a2.349 2.349 0 011.132-.002zm-4.23-2.65c-.105-.113-2.97-.954-3.033-.891-.03.03.504.414 1.186.854l1.24.8.34-.344c.186-.188.307-.377.268-.42zm9.76-.373c.473-.306.8-.555.728-.555-.155 0-2.877.804-3.027.894-.057.034.033.229.2.433l.304.37.47-.293c.257-.162.854-.544 1.326-.85zm-1.636-.555c2.11-.59 3.867-1.102 3.904-1.139H3.59c.187.187 7.779 2.195 8.323 2.202.41.005 2.014-.376 4.476-1.063z"/></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,33 +0,0 @@
import verifyCredentials from './verify-credentials';
import isStillVerified from './is-still-verified';
export default {
fields: [
{
key: 'apiToken',
label: 'API Token',
type: 'string' as const,
required: true,
readOnly: false,
value: null,
placeholder: null,
description:
'Tokens can be created in the v5 app on Settings > Account Management',
clickToCopy: false,
},
{
key: 'instanceUrl',
label: 'Invoice Ninja instance URL (optional)',
type: 'string' as const,
required: false,
readOnly: false,
value: null,
placeholder: null,
description: "Leave this field blank if you're using hosted platform.",
clickToCopy: true,
},
],
verifyCredentials,
isStillVerified,
};

View File

@@ -1,10 +0,0 @@
import { IGlobalVariable } from '@automatisch/types';
import verifyCredentials from './verify-credentials';
const isStillVerified = async ($: IGlobalVariable) => {
await verifyCredentials($);
return true;
};
export default isStillVerified;

View File

@@ -1,15 +0,0 @@
import { IGlobalVariable } from '@automatisch/types';
const verifyCredentials = async ($: IGlobalVariable) => {
const { data } = await $.http.get('/v1/ping');
const screenName = [data.user_name, data.company_name]
.filter(Boolean)
.join(' @ ');
await $.auth.set({
screenName,
});
};
export default verifyCredentials;

View File

@@ -1,20 +0,0 @@
import { TBeforeRequest } from '@automatisch/types';
const addAuthHeader: TBeforeRequest = ($, requestConfig) => {
const { instanceUrl } = $.auth.data;
if (instanceUrl) {
requestConfig.baseURL = instanceUrl as string;
}
requestConfig.headers['X-API-TOKEN'] = $.auth.data.apiToken as string;
requestConfig.headers['X-Requested-With'] = 'XMLHttpRequest';
requestConfig.headers['Content-Type'] =
requestConfig.headers['Content-Type'] || 'application/json';
return requestConfig;
};
export default addAuthHeader;

View File

@@ -1,18 +0,0 @@
import isObject from 'lodash/isObject';
export function filterProvidedFields(body: Record<string, unknown>) {
return Object.keys(body).reduce<Record<string, unknown>>((result, key) => {
const value = body[key];
if (isObject(value)) {
const filteredNestedObj = filterProvidedFields(
value as Record<string, unknown>
);
if (Object.keys(filteredNestedObj).length > 0) {
result[key] = filteredNestedObj;
}
} else if (body[key]) {
result[key] = value;
}
return result;
}, {});
}

View File

@@ -1,13 +0,0 @@
import { TBeforeRequest } from '@automatisch/types';
const setBaseUrl: TBeforeRequest = ($, requestConfig) => {
const instanceUrl = $.auth.data.instanceUrl as string;
if (instanceUrl) {
requestConfig.baseURL = instanceUrl;
}
return requestConfig;
};
export default setBaseUrl;

View File

@@ -1,4 +0,0 @@
import listClients from './list-clients';
import listInvoices from './list-invoices';
export default [listClients, listInvoices];

View File

@@ -1,35 +0,0 @@
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
export default {
name: 'List clients',
key: 'listClients',
async run($: IGlobalVariable) {
const clients: {
data: IJSONObject[];
} = {
data: [],
};
const params = {
sort: 'created_at|desc',
};
const {
data: { data },
} = await $.http.get('/v1/clients', { params });
if (!data?.length) {
return;
}
for (const client of data) {
clients.data.push({
value: client.id,
name: client.name,
});
}
return clients;
},
};

View File

@@ -1,35 +0,0 @@
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
export default {
name: 'List invoices',
key: 'listInvoices',
async run($: IGlobalVariable) {
const invoices: {
data: IJSONObject[];
} = {
data: [],
};
const params = {
sort: 'created_at|desc',
};
const {
data: { data },
} = await $.http.get('/v1/invoices', { params });
if (!data?.length) {
return;
}
for (const invoice of data) {
invoices.data.push({
value: invoice.id,
name: invoice.number,
});
}
return invoices;
},
};

View File

@@ -1,23 +0,0 @@
import defineApp from '../../helpers/define-app';
import setBaseUrl from './common/set-base-url';
import addAuthHeader from './common/add-auth-header';
import auth from './auth';
import triggers from './triggers';
import actions from './actions';
import dynamicData from './dynamic-data';
export default defineApp({
name: 'Invoice Ninja',
key: 'invoice-ninja',
baseUrl: 'https://invoiceninja.com',
apiBaseUrl: 'https://invoicing.co/api',
iconUrl: '{BASE_URL}/apps/invoice-ninja/assets/favicon.svg',
authDocUrl: 'https://automatisch.io/docs/apps/invoice-ninja/connection',
primaryColor: '000000',
supportsConnections: true,
beforeRequest: [setBaseUrl, addAuthHeader],
auth,
triggers,
actions,
dynamicData,
});

View File

@@ -1,15 +0,0 @@
import newClients from './new-clients';
import newCredits from './new-credits';
import newInvoices from './new-invoices';
import newPayments from './new-payments';
import newProjects from './new-projects';
import newQuotes from './new-quotes';
export default [
newClients,
newCredits,
newInvoices,
newPayments,
newProjects,
newQuotes,
];

View File

@@ -1,65 +0,0 @@
import Crypto from 'crypto';
import isEmpty from 'lodash/isEmpty';
import defineTrigger from '../../../../helpers/define-trigger';
type Response = {
data: {
data: {
id: string;
event_id: string;
target_url: string;
format: string;
};
};
};
export default defineTrigger({
name: 'New clients',
key: 'newClients',
type: 'webhook',
description: 'Triggers when a new client is added.',
arguments: [],
async run($) {
const dataItem = {
raw: $.request.body,
meta: {
internalId: Crypto.randomUUID(),
},
};
$.pushTriggerItem(dataItem);
},
async testRun($) {
const lastExecutionStep = await $.getLastExecutionStep();
if (!isEmpty(lastExecutionStep?.dataOut)) {
$.pushTriggerItem({
raw: lastExecutionStep.dataOut,
meta: {
internalId: '',
},
});
}
},
async registerHook($) {
const CREATE_CLIENT_EVENT_ID = '1';
const payload = {
target_url: $.webhookUrl,
event_id: CREATE_CLIENT_EVENT_ID,
format: 'JSON',
rest_method: 'post',
};
const response: Response = await $.http.post('/v1/webhooks', payload);
await $.flow.setRemoteWebhookId(response.data.data.id);
},
async unregisterHook($) {
await $.http.delete(`/v1/webhooks/${$.flow.remoteWebhookId}`);
},
});

View File

@@ -1,65 +0,0 @@
import Crypto from 'crypto';
import isEmpty from 'lodash/isEmpty';
import defineTrigger from '../../../../helpers/define-trigger';
type Response = {
data: {
data: {
id: string;
event_id: string;
target_url: string;
format: string;
};
};
};
export default defineTrigger({
name: 'New credits',
key: 'newCredits',
type: 'webhook',
description: 'Triggers when a new credit is added.',
arguments: [],
async run($) {
const dataItem = {
raw: $.request.body,
meta: {
internalId: Crypto.randomUUID(),
},
};
$.pushTriggerItem(dataItem);
},
async testRun($) {
const lastExecutionStep = await $.getLastExecutionStep();
if (!isEmpty(lastExecutionStep?.dataOut)) {
$.pushTriggerItem({
raw: lastExecutionStep.dataOut,
meta: {
internalId: '',
},
});
}
},
async registerHook($) {
const CREATE_CREDIT_EVENT_ID = '27';
const payload = {
target_url: $.webhookUrl,
event_id: CREATE_CREDIT_EVENT_ID,
format: 'JSON',
rest_method: 'post',
};
const response: Response = await $.http.post('/v1/webhooks', payload);
await $.flow.setRemoteWebhookId(response.data.data.id);
},
async unregisterHook($) {
await $.http.delete(`/v1/webhooks/${$.flow.remoteWebhookId}`);
},
});

View File

@@ -1,65 +0,0 @@
import Crypto from 'crypto';
import isEmpty from 'lodash/isEmpty';
import defineTrigger from '../../../../helpers/define-trigger';
type Response = {
data: {
data: {
id: string;
event_id: string;
target_url: string;
format: string;
};
};
};
export default defineTrigger({
name: 'New invoices',
key: 'newInvoices',
type: 'webhook',
description: 'Triggers when a new invoice is added.',
arguments: [],
async run($) {
const dataItem = {
raw: $.request.body,
meta: {
internalId: Crypto.randomUUID(),
},
};
$.pushTriggerItem(dataItem);
},
async testRun($) {
const lastExecutionStep = await $.getLastExecutionStep();
if (!isEmpty(lastExecutionStep?.dataOut)) {
$.pushTriggerItem({
raw: lastExecutionStep.dataOut,
meta: {
internalId: '',
},
});
}
},
async registerHook($) {
const CREATE_INVOICE_EVENT_ID = '2';
const payload = {
target_url: $.webhookUrl,
event_id: CREATE_INVOICE_EVENT_ID,
format: 'JSON',
rest_method: 'post',
};
const response: Response = await $.http.post('/v1/webhooks', payload);
await $.flow.setRemoteWebhookId(response.data.data.id);
},
async unregisterHook($) {
await $.http.delete(`/v1/webhooks/${$.flow.remoteWebhookId}`);
},
});

View File

@@ -1,65 +0,0 @@
import Crypto from 'crypto';
import isEmpty from 'lodash/isEmpty';
import defineTrigger from '../../../../helpers/define-trigger';
type Response = {
data: {
data: {
id: string;
event_id: string;
target_url: string;
format: string;
};
};
};
export default defineTrigger({
name: 'New payments',
key: 'newPayments',
type: 'webhook',
description: 'Triggers when a new payment is added.',
arguments: [],
async run($) {
const dataItem = {
raw: $.request.body,
meta: {
internalId: Crypto.randomUUID(),
},
};
$.pushTriggerItem(dataItem);
},
async testRun($) {
const lastExecutionStep = await $.getLastExecutionStep();
if (!isEmpty(lastExecutionStep?.dataOut)) {
$.pushTriggerItem({
raw: lastExecutionStep.dataOut,
meta: {
internalId: '',
},
});
}
},
async registerHook($) {
const CREATE_PAYMENT_EVENT_ID = '4';
const payload = {
target_url: $.webhookUrl,
event_id: CREATE_PAYMENT_EVENT_ID,
format: 'JSON',
rest_method: 'post',
};
const response: Response = await $.http.post('/v1/webhooks', payload);
await $.flow.setRemoteWebhookId(response.data.data.id);
},
async unregisterHook($) {
await $.http.delete(`/v1/webhooks/${$.flow.remoteWebhookId}`);
},
});

View File

@@ -1,65 +0,0 @@
import Crypto from 'crypto';
import isEmpty from 'lodash/isEmpty';
import defineTrigger from '../../../../helpers/define-trigger';
type Response = {
data: {
data: {
id: string;
event_id: string;
target_url: string;
format: string;
};
};
};
export default defineTrigger({
name: 'New projects',
key: 'newProjects',
type: 'webhook',
description: 'Triggers when a new project is added.',
arguments: [],
async run($) {
const dataItem = {
raw: $.request.body,
meta: {
internalId: Crypto.randomUUID(),
},
};
$.pushTriggerItem(dataItem);
},
async testRun($) {
const lastExecutionStep = await $.getLastExecutionStep();
if (!isEmpty(lastExecutionStep?.dataOut)) {
$.pushTriggerItem({
raw: lastExecutionStep.dataOut,
meta: {
internalId: '',
},
});
}
},
async registerHook($) {
const CREATE_PROJECT_EVENT_ID = '25';
const payload = {
target_url: $.webhookUrl,
event_id: CREATE_PROJECT_EVENT_ID,
format: 'JSON',
rest_method: 'post',
};
const response: Response = await $.http.post('/v1/webhooks', payload);
await $.flow.setRemoteWebhookId(response.data.data.id);
},
async unregisterHook($) {
await $.http.delete(`/v1/webhooks/${$.flow.remoteWebhookId}`);
},
});

View File

@@ -1,65 +0,0 @@
import Crypto from 'crypto';
import isEmpty from 'lodash/isEmpty';
import defineTrigger from '../../../../helpers/define-trigger';
type Response = {
data: {
data: {
id: string;
event_id: string;
target_url: string;
format: string;
};
};
};
export default defineTrigger({
name: 'New quotes',
key: 'newQuotes',
type: 'webhook',
description: 'Triggers when a new quote is added.',
arguments: [],
async run($) {
const dataItem = {
raw: $.request.body,
meta: {
internalId: Crypto.randomUUID(),
},
};
$.pushTriggerItem(dataItem);
},
async testRun($) {
const lastExecutionStep = await $.getLastExecutionStep();
if (!isEmpty(lastExecutionStep?.dataOut)) {
$.pushTriggerItem({
raw: lastExecutionStep.dataOut,
meta: {
internalId: '',
},
});
}
},
async registerHook($) {
const CREATE_QUOTE_EVENT_ID = '3';
const payload = {
target_url: $.webhookUrl,
event_id: CREATE_QUOTE_EVENT_ID,
format: 'JSON',
rest_method: 'post',
};
const response: Response = await $.http.post('/v1/webhooks', payload);
await $.flow.setRemoteWebhookId(response.data.data.id);
},
async unregisterHook($) {
await $.http.delete(`/v1/webhooks/${$.flow.remoteWebhookId}`);
},
});

View File

@@ -1,116 +0,0 @@
import defineAction from '../../../../helpers/define-action';
export default defineAction({
name: 'Copy board',
key: 'copyBoard',
description: 'Creates a copy of an existing board.',
arguments: [
{
label: 'Original board',
key: 'originalBoard',
type: 'dropdown' as const,
required: true,
description: 'The board that you want to copy.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listBoards',
},
],
},
},
{
label: 'Title',
key: 'title',
type: 'string' as const,
required: true,
description: 'Title for the board.',
variables: true,
},
{
label: 'Description',
key: 'description',
type: 'string' as const,
required: false,
description: 'Description of the board.',
variables: true,
},
{
label: 'Team Access',
key: 'teamAccess',
type: 'dropdown' as const,
required: false,
description:
'Team access to the board. Can be private, view, comment or edit. Default: private.',
variables: true,
options: [
{
label: 'Private - nobody in the team can find and access the board',
value: 'private',
},
{
label: 'View - any team member can find and view the board',
value: 'view',
},
{
label: 'Comment - any team member can find and comment the board',
value: 'comment',
},
{
label: 'Edit - any team member can find and edit the board',
value: 'edit',
},
],
},
{
label: 'Access Via Link',
key: 'accessViaLink',
type: 'dropdown' as const,
required: false,
description:
'Access to the board by link. Can be private, view, comment. Default: private.',
variables: true,
options: [
{
label: 'Private - only you have access to the board',
value: 'private',
},
{
label: 'View - can view, no sign-in required',
value: 'view',
},
{
label: 'Comment - can comment, no sign-in required',
value: 'comment',
},
],
},
],
async run($) {
const params = {
copy_from: $.step.parameters.originalBoard,
};
const body = {
name: $.step.parameters.title,
description: $.step.parameters.description,
policy: {
sharingPolicy: {
access: $.step.parameters.accessViaLink || 'private',
teamAccess: $.step.parameters.teamAccess || 'private',
},
},
};
const { data } = await $.http.put('/v2/boards', body, { params });
$.setActionItem({
raw: data,
});
},
});

View File

@@ -1,94 +0,0 @@
import defineAction from '../../../../helpers/define-action';
export default defineAction({
name: 'Create board',
key: 'createBoard',
description: 'Creates a new board.',
arguments: [
{
label: 'Title',
key: 'title',
type: 'string' as const,
required: true,
description: 'Title for the board.',
variables: true,
},
{
label: 'Description',
key: 'description',
type: 'string' as const,
required: false,
description: 'Description of the board.',
variables: true,
},
{
label: 'Team Access',
key: 'teamAccess',
type: 'dropdown' as const,
required: false,
description:
'Team access to the board. Can be private, view, comment or edit. Default: private.',
variables: true,
options: [
{
label: 'Private - nobody in the team can find and access the board',
value: 'private',
},
{
label: 'View - any team member can find and view the board',
value: 'view',
},
{
label: 'Comment - any team member can find and comment the board',
value: 'comment',
},
{
label: 'Edit - any team member can find and edit the board',
value: 'edit',
},
],
},
{
label: 'Access Via Link',
key: 'accessViaLink',
type: 'dropdown' as const,
required: false,
description:
'Access to the board by link. Can be private, view, comment. Default: private.',
variables: true,
options: [
{
label: 'Private - only you have access to the board',
value: 'private',
},
{
label: 'View - can view, no sign-in required',
value: 'view',
},
{
label: 'Comment - can comment, no sign-in required',
value: 'comment',
},
],
},
],
async run($) {
const body = {
name: $.step.parameters.title,
description: $.step.parameters.description,
policy: {
sharingPolicy: {
access: $.step.parameters.accessViaLink || 'private',
teamAccess: $.step.parameters.teamAccess || 'private',
},
},
};
const { data } = await $.http.post('/v2/boards', body);
$.setActionItem({
raw: data,
});
},
});

View File

@@ -1,168 +0,0 @@
import defineAction from '../../../../helpers/define-action';
type Body = {
data: {
title: string;
description?: string;
dueDate?: string;
};
style?: {
cardTheme?: string;
};
parent: {
id: string;
};
};
export default defineAction({
name: 'Create card widget',
key: 'createCardWidget',
description: 'Creates a new card widget on an existing board.',
arguments: [
{
label: 'Board',
key: 'boardId',
type: 'dropdown' as const,
required: true,
description: '',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listBoards',
},
],
},
},
{
label: 'Frame',
key: 'frameId',
type: 'dropdown' as const,
required: true,
dependsOn: ['parameters.boardId'],
description:
'You need to create a frame prior to this step. Switch frame to grid mode to avoid cards overlap.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listFrames',
},
{
name: 'parameters.boardId',
value: '{parameters.boardId}',
},
],
},
},
{
label: 'Card Title',
key: 'cardTitle',
type: 'string' as const,
required: true,
description: '',
variables: true,
},
{
label: 'Card Title Link',
key: 'cardTitleLink',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Card Description',
key: 'cardDescription',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Card Due Date',
key: 'cardDueDate',
type: 'string' as const,
required: false,
description:
'format: date-time. Example value: 2023-10-12 22:00:55+00:00',
variables: true,
},
{
label: 'Card Border Color',
key: 'cardBorderColor',
type: 'dropdown' as const,
required: false,
description: 'In hex format. Default is blue (#2399F3).',
variables: true,
options: [
{ label: 'white', value: '#FFFFFF' },
{ label: 'yellow', value: '#FEF445' },
{ label: 'orange', value: '#FAC710' },
{ label: 'red', value: '#F24726' },
{ label: 'bright red', value: '#DA0063' },
{ label: 'light gray', value: '#E6E6E6' },
{ label: 'gray', value: '#808080' },
{ label: 'black', value: '#1A1A1A' },
{ label: 'light green', value: '#CEE741' },
{ label: 'green', value: '#8FD14F' },
{ label: 'dark green', value: '#0CA789' },
{ label: 'light blue', value: '#12CDD4' },
{ label: 'blue', value: '#2D9BF0' },
{ label: 'dark blue', value: '#414BB2' },
{ label: 'purple', value: '#9510AC' },
{ label: 'dark purple', value: '#652CB3' },
],
},
],
async run($) {
const {
boardId,
frameId,
cardTitle,
cardTitleLink,
cardDescription,
cardDueDate,
cardBorderColor,
} = $.step.parameters;
let title;
if (cardTitleLink) {
title = `<a href='${cardTitleLink}'>${cardTitle}</a>`;
} else {
title = cardTitle;
}
const body: Body = {
data: {
title: title as string,
description: cardDescription as string,
},
style: {},
parent: {
id: frameId as string,
},
};
if (cardBorderColor) {
body.style.cardTheme = cardBorderColor as string;
}
if (cardDueDate) {
body.data.dueDate = cardDueDate as string;
}
const response = await $.http.post(`/v2/boards/${boardId}/cards`, body);
$.setActionItem({
raw: response.data,
});
},
});

View File

@@ -1,5 +0,0 @@
import copyBoard from './copy-board';
import createBoard from './create-board';
import createCardWidget from './create-card-widget';
export default [copyBoard, createBoard, createCardWidget];

View File

@@ -1 +0,0 @@
<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" width="2500" height="2500"><path d="M0 0h48v48H0z" fill="#ffd02f"/><path d="M32.708 6.4h-5.124l4.549 7.05-9.617-7.05h-5.124l4.549 9.238L12.324 6.4H7.2l4.474 11.926L7.2 41.6h5.124l9.617-24.955L17.392 41.6h5.124l9.617-27.142-4.549 27.142h5.124L42.4 11.785z" fill="#050038"/></svg>

Before

Width:  |  Height:  |  Size: 338 B

View File

@@ -1,20 +0,0 @@
import { IField, IGlobalVariable } from '@automatisch/types';
import { URLSearchParams } from 'url';
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({
response_type: 'code',
client_id: $.auth.data.clientId as string,
redirect_uri: redirectUri,
});
const url = `https://miro.com/oauth/authorize?${searchParams.toString()}`;
await $.auth.set({
url,
});
}

View File

@@ -1,48 +0,0 @@
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/miro/connections/add',
placeholder: null,
description:
'When asked to input a redirect URL in Miro, 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

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

View File

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

View File

@@ -1,40 +0,0 @@
import { IField, IGlobalVariable } from '@automatisch/types';
import getCurrentUser from '../common/get-current-user';
const verifyCredentials = async ($: IGlobalVariable) => {
const oauthRedirectUrlField = $.app.auth.fields.find(
(field: IField) => field.key == 'oAuthRedirectUrl'
);
const redirectUri = oauthRedirectUrlField.value as string;
const params = {
grant_type: 'authorization_code',
client_id: $.auth.data.clientId,
client_secret: $.auth.data.clientSecret,
code: $.auth.data.code,
redirect_uri: redirectUri,
};
const { data } = await $.http.post(`/v1/oauth/token`, null, {
params,
});
await $.auth.set({
accessToken: data.access_token,
tokenType: data.token_type,
});
const currentUser = await getCurrentUser($);
await $.auth.set({
userId: data.user_id,
refreshToken: data.refresh_token,
expiresIn: data.expires_in,
teamId: data.team_id,
scope: data.scope,
clientId: $.auth.data.clientId,
clientSecret: $.auth.data.clientSecret,
screenName: currentUser.name,
});
};
export default verifyCredentials;

View File

@@ -1,11 +0,0 @@
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

@@ -1,10 +0,0 @@
import { IGlobalVariable } from '@automatisch/types';
const getCurrentUser = async ($: IGlobalVariable) => {
const { data } = await $.http.get(
`https://api.miro.com/v1/oauth-token?access_token=${$.auth.data.accessToken}`
);
return data.user;
};
export default getCurrentUser;

View File

@@ -1,4 +0,0 @@
import listBoards from './list-boards';
import listFrames from './list-frames';
export default [listBoards, listFrames];

View File

@@ -1,46 +0,0 @@
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
type ResponseBody = {
data: {
data: {
id: number;
name: string;
}[];
links: {
next: string;
};
};
};
export default {
name: 'List boards',
key: 'listBoards',
async run($: IGlobalVariable) {
const boards: {
data: IJSONObject[];
} = {
data: [],
};
let next;
do {
const {
data: { data, links },
}: ResponseBody = await $.http.get('/v2/boards');
next = links?.next;
if (data.length) {
for (const board of data) {
boards.data.push({
value: board.id,
name: board.name,
});
}
}
} while (next);
return boards;
},
};

View File

@@ -1,44 +0,0 @@
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
export default {
name: 'List frames',
key: 'listFrames',
async run($: IGlobalVariable) {
const frames: {
data: IJSONObject[];
} = {
data: [],
};
const boardId = $.step.parameters.boardId;
if (!boardId) {
return { data: [] };
}
let next;
do {
const {
data: { data, links },
} = await $.http.get(`/v2/boards/${boardId}/items`);
next = links?.next;
const allFrames = data.filter(
(item: IJSONObject) => item.type === 'frame'
);
if (allFrames.length) {
for (const frame of allFrames) {
frames.data.push({
value: frame.id,
name: frame.data.title,
});
}
}
} while (next);
return frames;
},
};

View File

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

View File

@@ -1,198 +0,0 @@
import defineAction from '../../../../helpers/define-action';
import { filterProvidedFields } from '../../common/filter-provided-fields';
export default defineAction({
name: 'Create activity',
key: 'createActivity',
description: 'Creates a new activity.',
arguments: [
{
label: 'Subject',
key: 'subject',
type: 'string' as const,
required: true,
description: '',
variables: true,
},
{
label: 'Organization',
key: 'organizationId',
type: 'dropdown' as const,
required: false,
description: '',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listOrganizations',
},
],
},
},
{
label: 'Assigned To',
key: 'userId',
type: 'dropdown' as const,
required: false,
description:
'If omitted, the activity will be assigned to the user of the connected account.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listUsers',
},
],
},
},
{
label: 'Person',
key: 'personId',
type: 'dropdown' as const,
required: false,
description: '',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listPersons',
},
],
},
},
{
label: 'Deal',
key: 'dealId',
type: 'dropdown' as const,
required: false,
description: '',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listDeals',
},
],
},
},
{
label: 'Is done?',
key: 'isDone',
type: 'dropdown' as const,
required: false,
description: '',
options: [
{
label: 'No',
value: 0,
},
{
label: 'Yes',
value: 1,
},
],
},
{
label: 'Type',
key: 'type',
type: 'dropdown' as const,
required: false,
description: '',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listActivityTypes',
},
],
},
},
{
label: 'Due Date',
key: 'dueDate',
type: 'string' as const,
required: false,
description: 'Format must be YYYY-MM-DD',
variables: true,
},
{
label: 'Due Time',
key: 'dueTime',
type: 'string' as const,
required: false,
description: 'Format must be HH:MM',
variables: true,
},
{
label: 'Duration',
key: 'duration',
type: 'string' as const,
required: false,
description: 'Format must be HH:MM',
variables: true,
},
{
label: 'Note',
key: 'note',
type: 'string' as const,
required: false,
description: 'Accepts HTML format',
variables: true,
},
],
async run($) {
const {
subject,
organizationId,
userId,
personId,
dealId,
isDone,
type,
dueTime,
dueDate,
duration,
note,
} = $.step.parameters;
const fields = {
subject: subject as string,
org_id: organizationId as number,
user_id: userId as number,
person_id: personId as number,
deal_id: dealId as number,
done: isDone as number,
type: type as string,
due_time: dueTime as string,
due_date: dueDate as string,
duration: duration as string,
note: note as string,
};
const body = filterProvidedFields(fields);
const {
data: { data },
} = await $.http.post('/api/v1/activities', body);
$.setActionItem({
raw: data,
});
},
});

View File

@@ -1,237 +0,0 @@
import defineAction from '../../../../helpers/define-action';
import { filterProvidedFields } from '../../common/filter-provided-fields';
export default defineAction({
name: 'Create deal',
key: 'createDeal',
description: 'Creates a new deal.',
arguments: [
{
label: 'Title',
key: 'title',
type: 'string' as const,
required: true,
description: '',
variables: true,
},
{
label: 'Creation Date',
key: 'addTime',
type: 'string' as const,
required: false,
description:
'Requires admin access to Pipedrive account. Format: YYYY-MM-DD HH:MM:SS',
variables: true,
},
{
label: 'Status',
key: 'status',
type: 'dropdown' as const,
required: false,
description: '',
options: [
{
label: 'Open',
value: 'open',
},
{
label: 'Won',
value: 'won',
},
{
label: 'Lost',
value: 'lost',
},
{
label: 'Deleted',
value: 'deleted',
},
],
},
{
label: 'Lost Reason',
key: 'lostReason',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
{
label: 'Stage',
key: 'stageId',
type: 'dropdown' as const,
required: false,
value: '1',
description:
'The ID of the stage this deal will be added to. If omitted, the deal will be placed in the first stage of the default pipeline.',
options: [
{
label: 'Qualified (Pipeline)',
value: 1,
},
{
label: 'Contact Made (Pipeline)',
value: 2,
},
{
label: 'Prospect Qualified (Pipeline)',
value: 3,
},
{
label: 'Needs Defined (Pipeline)',
value: 4,
},
{
label: 'Proposal Made (Pipeline)',
value: 5,
},
{
label: 'Negotiations Started (Pipeline)',
value: 6,
},
],
},
{
label: 'Owner',
key: 'userId',
type: 'dropdown' as const,
required: false,
description:
'Select user who will be marked as the owner of this deal. If omitted, the authorized user will be used.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listUsers',
},
],
},
},
{
label: 'Organization',
key: 'organizationId',
type: 'dropdown' as const,
required: false,
description: 'Organization this deal will be associated with.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listOrganizations',
},
],
},
},
{
label: 'Person',
key: 'personId',
type: 'dropdown' as const,
required: false,
description: 'Person this deal will be associated with.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listPersons',
},
],
},
},
{
label: 'Probability',
key: 'probability',
type: 'string' as const,
required: false,
description:
'The success probability percentage of the deal. Used/shown only when deal_probability for the pipeline of the deal is enabled.',
variables: true,
},
{
label: 'Expected Close Date',
key: 'expectedCloseDate',
type: 'string' as const,
required: false,
description:
'The expected close date of the deal. In ISO 8601 format: YYYY-MM-DD.',
variables: true,
},
{
label: 'Value',
key: 'value',
type: 'string' as const,
required: false,
description: 'The value of the deal. If omitted, value will be set to 0.',
variables: true,
},
{
label: 'Currency',
key: 'currency',
type: 'dropdown' as const,
required: false,
description:
'The currency of the deal. Accepts a 3-character currency code. If omitted, currency will be set to the default currency of the authorized user.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listCurrencies',
},
],
},
},
],
async run($) {
const {
title,
addTime,
status,
lostReason,
stageId,
userId,
organizationId,
personId,
probability,
expectedCloseDate,
value,
currency,
} = $.step.parameters;
const fields = {
title: title as string,
value: value as string,
add_time: addTime as string,
status: status as string,
lost_reason: lostReason as string,
stage_id: stageId as number,
user_id: userId as number,
org_id: organizationId as number,
person_id: personId as number,
probability: probability as number,
expected_close_date: expectedCloseDate as string,
currency: currency as string,
};
const body = filterProvidedFields(fields);
const {
data: { data },
} = await $.http.post('/api/v1/deals', body);
$.setActionItem({
raw: data,
});
},
});

View File

@@ -1,185 +0,0 @@
import defineAction from '../../../../helpers/define-action';
import { filterProvidedFields } from '../../common/filter-provided-fields';
type LabelIds = { __id: string; leadLabelId: string }[];
type LabelValue = { amount?: number; currency?: string };
export default defineAction({
name: 'Create lead',
key: 'createLead',
description: 'Creates a new lead.',
arguments: [
{
label: 'Title',
key: 'title',
type: 'string' as const,
required: true,
description: '',
variables: true,
},
{
label: 'Person',
key: 'personId',
type: 'dropdown' as const,
required: false,
description:
'Lead must be associated with at least one person or organization.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listPersons',
},
],
},
},
{
label: 'Organization',
key: 'organizationId',
type: 'dropdown' as const,
required: false,
description:
'Lead must be associated with at least one person or organization.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listOrganizations',
},
],
},
},
{
label: 'Owner',
key: 'ownerId',
type: 'dropdown' as const,
required: false,
description:
'Select user who will be marked as the owner of this lead. If omitted, the authorized user will be used.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listUsers',
},
],
},
},
{
label: 'Lead Labels',
key: 'labelIds',
type: 'dynamic' as const,
required: false,
description: '',
fields: [
{
label: 'Label',
key: 'leadLabelId',
type: 'dropdown' as const,
required: false,
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listLeadLabels',
},
],
},
},
],
},
{
label: 'Expected Close Date',
key: 'expectedCloseDate',
type: 'string' as const,
required: false,
description: 'E.g. 2023-10-23',
variables: true,
},
{
label: 'Lead Value',
key: 'value',
type: 'string' as const,
required: false,
description: 'E.g. 150',
variables: true,
},
{
label: 'Lead Value Currency',
key: 'currency',
type: 'dropdown' as const,
required: false,
description: 'This field is required if a Lead Value amount is provided.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listCurrencies',
},
],
},
},
],
async run($) {
const {
title,
personId,
organizationId,
ownerId,
labelIds,
expectedCloseDate,
value,
currency,
} = $.step.parameters;
const onlyLabelIds = (labelIds as LabelIds)
.map((labelId) => labelId.leadLabelId)
.filter(Boolean);
const labelValue: LabelValue = {};
if (value) {
labelValue.amount = Number(value);
}
if (currency) {
labelValue.currency = currency as string;
}
const fields = {
title: title as string,
person_id: Number(personId),
organization_id: Number(organizationId),
owner_id: Number(ownerId),
expected_close_date: expectedCloseDate as string,
label_ids: onlyLabelIds,
value: labelValue,
};
const body = filterProvidedFields(fields);
const {
data: { data },
} = await $.http.post('/api/v1/leads', body);
$.setActionItem({
raw: data,
});
},
});

View File

@@ -1,198 +0,0 @@
import defineAction from '../../../../helpers/define-action';
import { filterProvidedFields } from '../../common/filter-provided-fields';
export default defineAction({
name: 'Create note',
key: 'createNote',
description: 'Creates a new note.',
arguments: [
{
label: 'Content',
key: 'content',
type: 'string' as const,
required: true,
description: 'Supports some HTML formatting.',
variables: true,
},
{
label: 'Deal',
key: 'dealId',
type: 'dropdown' as const,
required: false,
description:
'Note must be associated with at least one deal, person, organization, or lead.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listDeals',
},
],
},
},
{
label: 'Pin note on specified deal?',
key: 'pinnedDeal',
type: 'dropdown' as const,
required: false,
description: '',
options: [
{
label: 'No',
value: 0,
},
{
label: 'Yes',
value: 1,
},
],
},
{
label: 'Person',
key: 'personId',
type: 'dropdown' as const,
required: false,
description:
'Note must be associated with at least one deal, person, organization, or lead.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listPersons',
},
],
},
},
{
label: 'Pin note on specified person?',
key: 'pinnedPerson',
type: 'dropdown' as const,
required: false,
description: '',
options: [
{
label: 'No',
value: 0,
},
{
label: 'Yes',
value: 1,
},
],
},
{
label: 'Organization',
key: 'organizationId',
type: 'dropdown' as const,
required: false,
description:
'Note must be associated with at least one deal, person, organization, or lead.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listOrganizations',
},
],
},
},
{
label: 'Pin note on specified organization?',
key: 'pinnedOrganization',
type: 'dropdown' as const,
required: false,
description: '',
options: [
{
label: 'No',
value: 0,
},
{
label: 'Yes',
value: 1,
},
],
},
{
label: 'Lead',
key: 'leadId',
type: 'dropdown' as const,
required: false,
description:
'Note must be associated with at least one deal, person, organization, or lead.',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listLeads',
},
],
},
},
{
label: 'Pin note on specified lead?',
key: 'pinnedLead',
type: 'dropdown' as const,
required: false,
description: '',
options: [
{
label: 'No',
value: 0,
},
{
label: 'Yes',
value: 1,
},
],
},
],
async run($) {
const {
content,
dealId,
pinnedDeal,
personId,
pinnedPerson,
organizationId,
pinnedOrganization,
leadId,
pinnedLead,
} = $.step.parameters;
const fields = {
content: content as string,
deal_id: dealId as number,
pinned_to_deal_flag: pinnedDeal as number,
person_id: personId as number,
pinned_to_person_flag: pinnedPerson as number,
org_id: organizationId as number,
pinned_to_organization_flag: pinnedOrganization as number,
lead_id: leadId as string,
pinned_to_lead_flag: pinnedLead as number,
};
const body = filterProvidedFields(fields);
const {
data: { data },
} = await $.http.post('/api/v1/notes', body);
$.setActionItem({
raw: data,
});
},
});

View File

@@ -1,74 +0,0 @@
import defineAction from '../../../../helpers/define-action';
import { filterProvidedFields } from '../../common/filter-provided-fields';
export default defineAction({
name: 'Create organization',
key: 'createOrganization',
description: 'Creates a new organization.',
arguments: [
{
label: 'Name',
key: 'name',
type: 'string' as const,
required: true,
description: '',
variables: true,
},
{
label: 'Owner',
key: 'ownerId',
type: 'dropdown' as const,
required: false,
description: '',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listUsers',
},
],
},
},
{
label: 'Label',
key: 'labelId',
type: 'dropdown' as const,
required: false,
description: '',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listOrganizationLabelField',
},
],
},
},
],
async run($) {
const { name, ownerId, labelId } = $.step.parameters;
const fields = {
name: name,
owner_id: ownerId,
label: labelId,
};
const body = filterProvidedFields(fields);
const {
data: { data },
} = await $.http.post('/api/v1/organizations', body);
$.setActionItem({
raw: data,
});
},
});

View File

@@ -1,143 +0,0 @@
import defineAction from '../../../../helpers/define-action';
import { filterProvidedFields } from '../../common/filter-provided-fields';
type TEmail = {
__id: string;
email: string;
}[];
type TPhone = {
__id: string;
phone: string;
}[];
export default defineAction({
name: 'Create person',
key: 'createPerson',
description: 'Creates a new person.',
arguments: [
{
label: 'Name',
key: 'name',
type: 'string' as const,
required: true,
description: '',
variables: true,
},
{
label: 'Owner',
key: 'ownerId',
type: 'dropdown' as const,
required: false,
description: '',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listUsers',
},
],
},
},
{
label: 'Organization',
key: 'organizationId',
type: 'dropdown' as const,
required: false,
description: '',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listOrganizations',
},
],
},
},
{
label: 'Emails',
key: 'emails',
type: 'dynamic' as const,
required: false,
description: '',
fields: [
{
label: 'Email',
key: 'email',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
],
},
{
label: 'Phones',
key: 'phones',
type: 'dynamic' as const,
required: false,
description: '',
fields: [
{
label: 'Phone',
key: 'phone',
type: 'string' as const,
required: false,
description: '',
variables: true,
},
],
},
{
label: 'Label',
key: 'labelId',
type: 'dropdown' as const,
required: false,
description: '',
variables: true,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listPersonLabelField',
},
],
},
},
],
async run($) {
const { name, ownerId, organizationId, labelId } = $.step.parameters;
const emails = $.step.parameters.emails as TEmail;
const emailValues = emails.map((entry) => entry.email);
const phones = $.step.parameters.phones as TPhone;
const phoneValues = phones.map((entry) => entry.phone);
const fields = {
name: name,
owner_id: ownerId,
org_id: organizationId,
email: emailValues,
phone: phoneValues,
label: labelId,
};
const body = filterProvidedFields(fields);
const {
data: { data },
} = await $.http.post('/api/v1/persons', body);
$.setActionItem({
raw: data,
});
},
});

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