Compare commits
1 Commits
formatter-
...
new-or-upd
Author | SHA1 | Date | |
---|---|---|---|
![]() |
03b357393e |
@@ -29,6 +29,7 @@ rm -rf .env
|
||||
echo "
|
||||
PORT=$WEB_PORT
|
||||
REACT_APP_GRAPHQL_URL=http://localhost:$BACKEND_PORT/graphql
|
||||
REACT_APP_NOTIFICATIONS_URL=https://notifications.automatisch.io
|
||||
" >> .env
|
||||
cd $CURRENT_DIR
|
||||
|
||||
|
@@ -33,32 +33,7 @@ services:
|
||||
- '6379:6379'
|
||||
expose:
|
||||
- 6379
|
||||
keycloak:
|
||||
image: quay.io/keycloak/keycloak:21.1
|
||||
restart: always
|
||||
container_name: keycloak
|
||||
environment:
|
||||
- KEYCLOAK_ADMIN=admin
|
||||
- KEYCLOAK_ADMIN_PASSWORD=admin
|
||||
- KC_DB=postgres
|
||||
- KC_DB_URL_HOST=postgres
|
||||
- KC_DB_URL_DATABASE=keycloak
|
||||
- KC_DB_USERNAME=automatisch_user
|
||||
- KC_DB_PASSWORD=automatisch_password
|
||||
- KC_HEALTH_ENABLED=true
|
||||
ports:
|
||||
- "8080:8080"
|
||||
command: start-dev
|
||||
depends_on:
|
||||
- postgres
|
||||
healthcheck:
|
||||
test: "curl -f http://localhost:8080/health/ready || exit 1"
|
||||
volumes:
|
||||
- keycloak:/opt/keycloak/data/
|
||||
expose:
|
||||
- 8080
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
redis_data:
|
||||
keycloak:
|
||||
|
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@@ -1,11 +1,5 @@
|
||||
name: Automatisch CI
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
on: [push]
|
||||
jobs:
|
||||
linter:
|
||||
runs-on: ubuntu-latest
|
||||
|
88
.github/workflows/playwright.yml
vendored
88
.github/workflows/playwright.yml
vendored
@@ -1,88 +0,0 @@
|
||||
name: Automatisch UI Tests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
ENCRYPTION_KEY: sample_encryption_key
|
||||
WEBHOOK_SECRET_KEY: sample_webhook_secret_key
|
||||
APP_SECRET_KEY: sample_app_secret_key
|
||||
POSTGRES_HOST: localhost
|
||||
POSTGRES_DATABASE: automatisch
|
||||
POSTGRES_PORT: 5432
|
||||
POSTGRES_USERNAME: automatisch_user
|
||||
POSTGRES_PASSWORD: automatisch_password
|
||||
REDIS_HOST: localhost
|
||||
APP_ENV: production
|
||||
LICENSE_KEY: ${{ secrets.E2E_LICENSE_KEY }}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
timeout-minutes: 60
|
||||
runs-on: ubuntu-latest
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:14.5-alpine
|
||||
env:
|
||||
POSTGRES_DB: automatisch
|
||||
POSTGRES_USER: automatisch_user
|
||||
POSTGRES_PASSWORD: automatisch_password
|
||||
options: >-
|
||||
--health-cmd "pg_isready -U automatisch_user -d automatisch"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
redis:
|
||||
image: redis:7.0.4-alpine
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
- name: Install dependencies
|
||||
run: yarn && yarn lerna bootstrap
|
||||
- name: Install Playwright Browsers
|
||||
run: yarn playwright install --with-deps
|
||||
- name: Build Automatisch
|
||||
run: yarn lerna run --scope=@*/{web,backend,cli} build
|
||||
env:
|
||||
# Keep this until we clean up warnings in build processes
|
||||
CI: false
|
||||
- name: Migrate database
|
||||
working-directory: ./packages/backend
|
||||
run: yarn db:migrate --migrations-directory ./dist/src/db/migrations
|
||||
- name: Seed user
|
||||
working-directory: ./packages/backend
|
||||
run: yarn db:seed:user &
|
||||
- name: Run Automatisch
|
||||
run: yarn start &
|
||||
working-directory: ./packages/backend
|
||||
- name: Run Automatisch worker
|
||||
run: node dist/src/worker.js &
|
||||
working-directory: ./packages/backend
|
||||
- name: Run Playwright tests
|
||||
working-directory: ./packages/e2e-tests
|
||||
env:
|
||||
LOGIN_EMAIL: user@automatisch.io
|
||||
LOGIN_PASSWORD: sample
|
||||
BASE_URL: http://localhost:3000
|
||||
run: yarn test
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: playwright-report
|
||||
path: ./packages/e2e-tests/test-results/**/*
|
||||
retention-days: 30
|
@@ -1 +0,0 @@
|
||||
16.15.0
|
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -1,7 +1,4 @@
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
}
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@ WORKDIR /automatisch
|
||||
|
||||
RUN \
|
||||
apk --no-cache add --virtual build-dependencies python3 build-base && \
|
||||
yarn global add @automatisch/cli@0.9.3 --network-timeout 1000000 && \
|
||||
yarn global add @automatisch/cli@0.7.1 --network-timeout 1000000 && \
|
||||
rm -rf /usr/local/share/.cache/ && \
|
||||
apk del build-dependencies
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM automatischio/automatisch:0.9.3
|
||||
FROM automatischio/automatisch:0.7.1
|
||||
WORKDIR /automatisch
|
||||
|
||||
RUN apk add --no-cache openssl dos2unix
|
||||
|
@@ -2,7 +2,7 @@
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"version": "0.9.3",
|
||||
"version": "0.7.1",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"command": {
|
||||
|
@@ -1,16 +0,0 @@
|
||||
APP_ENV=test
|
||||
HOST=localhost
|
||||
PROTOCOL=http
|
||||
PORT=3000
|
||||
LOG_LEVEL=debug
|
||||
WEBHOOK_SECRET_KEY=secret
|
||||
POSTGRES_DATABASE=automatisch_test
|
||||
POSTGRES_PORT=5432
|
||||
POSTGRES_HOST=localhost
|
||||
POSTGRES_USERNAME=automatisch_test_user
|
||||
POSTGRES_PASSWORD=
|
||||
POSTGRES_ENABLE_SSL=false
|
||||
ENCRYPTION_KEY=secret
|
||||
APP_SECRET_KEY=secret
|
||||
REDIS_PORT=6379
|
||||
REDIS_HOST=127.0.0.1
|
@@ -1,5 +0,0 @@
|
||||
export default {
|
||||
require: ['ts-node/register', './src/config/app.ts'],
|
||||
files: ['**/*.test.ts'],
|
||||
extensions: ['ts'],
|
||||
};
|
@@ -2,33 +2,18 @@ import appConfig from '../../src/config/app';
|
||||
import logger from '../../src/helpers/logger';
|
||||
import client from './client';
|
||||
import User from '../../src/models/user';
|
||||
import Role from '../../src/models/role';
|
||||
import '../../src/config/orm';
|
||||
|
||||
async function fetchAdminRole() {
|
||||
const role = await Role
|
||||
.query()
|
||||
.where({
|
||||
key: 'admin'
|
||||
})
|
||||
.limit(1)
|
||||
.first();
|
||||
|
||||
return role;
|
||||
}
|
||||
|
||||
export async function createUser(
|
||||
email = 'user@automatisch.io',
|
||||
password = 'sample'
|
||||
) {
|
||||
const UNIQUE_VIOLATION_CODE = '23505';
|
||||
|
||||
const role = await fetchAdminRole();
|
||||
const userParams = {
|
||||
email,
|
||||
password,
|
||||
fullName: 'Initial admin',
|
||||
roleId: role.id,
|
||||
role: 'admin',
|
||||
};
|
||||
|
||||
try {
|
||||
|
@@ -12,7 +12,6 @@ const knexConfig = {
|
||||
database: appConfig.postgresDatabase,
|
||||
ssl: appConfig.postgresEnableSsl,
|
||||
},
|
||||
asyncStackTraces: appConfig.isDev,
|
||||
searchPath: [appConfig.postgresSchema],
|
||||
pool: { min: 0, max: 20 },
|
||||
migrations: {
|
||||
|
@@ -1,16 +1,15 @@
|
||||
{
|
||||
"name": "@automatisch/backend",
|
||||
"version": "0.9.3",
|
||||
"version": "0.7.1",
|
||||
"license": "See LICENSE file",
|
||||
"description": "The open source Zapier alternative. Build workflow automation without spending time and money.",
|
||||
"scripts": {
|
||||
"dev": "ts-node-dev --watch 'src/graphql/schema.graphql' --exit-child src/server.ts",
|
||||
"dev": "ts-node-dev --exit-child src/server.ts",
|
||||
"worker": "nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/worker.ts",
|
||||
"build": "tsc && yarn copy-statics",
|
||||
"build:watch": "nodemon --watch 'src/**/*.ts' --watch 'bin/**/*.ts' --exec yarn build --ext ts",
|
||||
"start": "node dist/src/server.js",
|
||||
"pretest": "APP_ENV=test ts-node ./test/setup/prepare-test-env.ts",
|
||||
"test": "APP_ENV=test ava",
|
||||
"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",
|
||||
@@ -23,20 +22,14 @@
|
||||
"prebuild": "rm -rf ./dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@automatisch/web": "^0.9.3",
|
||||
"@automatisch/web": "^0.7.1",
|
||||
"@bull-board/express": "^3.10.1",
|
||||
"@casl/ability": "^6.5.0",
|
||||
"@graphql-tools/graphql-file-loader": "^7.3.4",
|
||||
"@graphql-tools/load": "^7.5.2",
|
||||
"@node-saml/passport-saml": "^4.0.4",
|
||||
"@rudderstack/rudder-sdk-node": "^1.1.2",
|
||||
"@sentry/node": "^7.42.0",
|
||||
"@sentry/tracing": "^7.42.0",
|
||||
"@types/accounting": "^0.4.2",
|
||||
"@types/luxon": "^2.3.1",
|
||||
"@types/passport": "^1.0.12",
|
||||
"@types/xmlrpc": "^1.3.7",
|
||||
"accounting": "^0.4.1",
|
||||
"ajv-formats": "^2.1.1",
|
||||
"axios": "0.24.0",
|
||||
"bcrypt": "^5.0.1",
|
||||
@@ -56,8 +49,6 @@
|
||||
"graphql-type-json": "^0.3.2",
|
||||
"handlebars": "^4.7.7",
|
||||
"http-errors": "~1.6.3",
|
||||
"http-proxy-agent": "^7.0.0",
|
||||
"https-proxy-agent": "^7.0.1",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"knex": "^2.4.0",
|
||||
"lodash.get": "^4.4.2",
|
||||
@@ -65,18 +56,13 @@
|
||||
"memory-cache": "^0.2.0",
|
||||
"morgan": "^1.10.0",
|
||||
"multer": "1.4.5-lts.1",
|
||||
"node-html-markdown": "^1.3.0",
|
||||
"nodemailer": "6.7.0",
|
||||
"oauth-1.0a": "^2.2.6",
|
||||
"objection": "^3.0.0",
|
||||
"passport": "^0.6.0",
|
||||
"pg": "^8.7.1",
|
||||
"php-serialize": "^4.0.2",
|
||||
"pluralize": "^8.0.0",
|
||||
"showdown": "^2.1.0",
|
||||
"stripe": "^11.13.0",
|
||||
"winston": "^3.7.1",
|
||||
"xmlrpc": "^1.3.2"
|
||||
"winston": "^3.7.1"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
@@ -114,7 +100,7 @@
|
||||
"url": "https://github.com/automatisch/automatisch/issues"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@automatisch/types": "^0.9.3",
|
||||
"@automatisch/types": "^0.7.1",
|
||||
"@types/bcrypt": "^5.0.0",
|
||||
"@types/bull": "^3.15.8",
|
||||
"@types/cors": "^2.8.12",
|
||||
@@ -130,14 +116,23 @@
|
||||
"@types/nodemailer": "^6.4.4",
|
||||
"@types/pg": "^8.6.1",
|
||||
"@types/pino": "^7.0.5",
|
||||
"@types/pluralize": "^0.0.30",
|
||||
"@types/showdown": "^2.0.1",
|
||||
"ava": "^5.3.1",
|
||||
"ava": "^3.15.0",
|
||||
"nodemon": "^2.0.13",
|
||||
"sinon": "^11.1.2",
|
||||
"ts-node": "^10.2.1",
|
||||
"ts-node-dev": "^1.1.8"
|
||||
},
|
||||
"ava": {
|
||||
"files": [
|
||||
"test/**/*"
|
||||
],
|
||||
"extensions": [
|
||||
"ts"
|
||||
],
|
||||
"require": [
|
||||
"ts-node/register"
|
||||
]
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
|
@@ -17,7 +17,6 @@ import {
|
||||
} from './helpers/create-bull-board-handler';
|
||||
import injectBullBoardHandler from './helpers/inject-bull-board-handler';
|
||||
import router from './routes';
|
||||
import configurePassport from './helpers/passport';
|
||||
|
||||
createBullBoardHandler(serverAdapter);
|
||||
|
||||
@@ -51,9 +50,6 @@ app.use(
|
||||
})
|
||||
);
|
||||
app.use(cors(corsOptions));
|
||||
|
||||
configurePassport(app);
|
||||
|
||||
app.use('/', router);
|
||||
|
||||
webUIHandler(app);
|
||||
|
@@ -20,7 +20,7 @@ export default defineAction({
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
description: 'Language to translate the text to.',
|
||||
variables: true,
|
||||
variables: false,
|
||||
value: '',
|
||||
options: [
|
||||
{ label: 'Bulgarian', value: 'BG' },
|
||||
|
@@ -13,7 +13,7 @@ export default defineAction({
|
||||
required: true,
|
||||
value: null,
|
||||
description: 'Delay for unit, e.g. minutes, hours, days, weeks.',
|
||||
variables: true,
|
||||
variables: false,
|
||||
options: [
|
||||
{
|
||||
label: 'Minutes',
|
||||
|
@@ -11,7 +11,7 @@ export default defineAction({
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
description: 'Pick a channel to send the message to.',
|
||||
variables: true,
|
||||
variables: false,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
|
@@ -19,8 +19,8 @@ export default {
|
||||
|
||||
channels.data = response.data
|
||||
.filter((channel: IJSONObject) => {
|
||||
// filter in text channels and announcement channels only
|
||||
return channel.type === 0 || channel.type === 5;
|
||||
// filter in text channels only
|
||||
return channel.type === 0;
|
||||
})
|
||||
.map((channel: IJSONObject) => {
|
||||
return {
|
||||
|
@@ -1,49 +0,0 @@
|
||||
import defineAction from '../../../../helpers/define-action';
|
||||
|
||||
import formatDateTime from './transformers/format-date-time';
|
||||
|
||||
const transformers = {
|
||||
formatDateTime,
|
||||
};
|
||||
|
||||
export default defineAction({
|
||||
name: 'Date / Time',
|
||||
key: 'date-time',
|
||||
description: 'Perform date and time related transformations on your data.',
|
||||
arguments: [
|
||||
{
|
||||
label: 'Transform',
|
||||
key: 'transform',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
variables: true,
|
||||
options: [{ label: 'Format Date / Time', value: 'formatDateTime' }],
|
||||
additionalFields: {
|
||||
type: 'query',
|
||||
name: 'getDynamicFields',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listTransformOptions',
|
||||
},
|
||||
{
|
||||
name: 'parameters.transform',
|
||||
value: '{parameters.transform}',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
async run($) {
|
||||
const transformerName = $.step.parameters
|
||||
.transform as keyof typeof transformers;
|
||||
const output = transformers[transformerName]($);
|
||||
|
||||
$.setActionItem({
|
||||
raw: {
|
||||
output,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
@@ -1,23 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
const formatDateTime = ($: IGlobalVariable) => {
|
||||
const input = $.step.parameters.input as string;
|
||||
|
||||
const fromFormat = $.step.parameters.fromFormat as string;
|
||||
const fromTimezone = $.step.parameters.fromTimezone as string;
|
||||
|
||||
const inputDateTime = DateTime.fromFormat(input, fromFormat, {
|
||||
zone: fromTimezone,
|
||||
setZone: true,
|
||||
});
|
||||
|
||||
const toFormat = $.step.parameters.toFormat as string;
|
||||
const toTimezone = $.step.parameters.toTimezone as string;
|
||||
|
||||
const outputDateTime = inputDateTime.setZone(toTimezone).toFormat(toFormat);
|
||||
|
||||
return outputDateTime;
|
||||
};
|
||||
|
||||
export default formatDateTime;
|
@@ -1,6 +0,0 @@
|
||||
import text from './text';
|
||||
import numbers from './numbers';
|
||||
import dateTime from './date-time';
|
||||
import utilities from './utilities';
|
||||
|
||||
export default [text, numbers, dateTime, utilities];
|
@@ -1,58 +0,0 @@
|
||||
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';
|
||||
|
||||
const transformers = {
|
||||
performMathOperation,
|
||||
randomNumber,
|
||||
formatNumber,
|
||||
};
|
||||
|
||||
export default defineAction({
|
||||
name: 'Numbers',
|
||||
key: 'numbers',
|
||||
description:
|
||||
'Transform numbers to perform math operations, generate random numbers, format numbers, and much more.',
|
||||
arguments: [
|
||||
{
|
||||
label: 'Transform',
|
||||
key: 'transform',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
variables: true,
|
||||
options: [
|
||||
{ label: 'Perform Math Operation', value: 'performMathOperation' },
|
||||
{ label: 'Random Number', value: 'randomNumber' },
|
||||
{ label: 'Format Number', value: 'formatNumber' },
|
||||
],
|
||||
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,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
@@ -1,28 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import accounting from 'accounting';
|
||||
|
||||
const formatNumber = ($: IGlobalVariable) => {
|
||||
const input = $.step.parameters.input as string;
|
||||
const inputDecimalMark = $.step.parameters.inputDecimalMark as string;
|
||||
const toFormat = $.step.parameters.toFormat as string;
|
||||
|
||||
const normalizedNumber = accounting.unformat(input, inputDecimalMark);
|
||||
const decimalPart = normalizedNumber.toString().split('.')[1];
|
||||
const precision = decimalPart ? decimalPart.length : 0;
|
||||
|
||||
if (toFormat === '0') {
|
||||
// Comma for grouping & period for decimal
|
||||
return accounting.formatNumber(normalizedNumber, precision, ',', '.');
|
||||
} else if (toFormat === '1') {
|
||||
// Period for grouping & comma for decimal
|
||||
return accounting.formatNumber(normalizedNumber, precision, '.', ',');
|
||||
} else if (toFormat === '2') {
|
||||
// Space for grouping & period for decimal
|
||||
return accounting.formatNumber(normalizedNumber, precision, ' ', '.');
|
||||
} else if (toFormat === '3') {
|
||||
// Space for grouping & comma for decimal
|
||||
return accounting.formatNumber(normalizedNumber, precision, ' ', ',');
|
||||
}
|
||||
};
|
||||
|
||||
export default formatNumber;
|
@@ -1,23 +0,0 @@
|
||||
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
|
||||
import { add, divide, multiply, subtract } from 'lodash';
|
||||
|
||||
const mathOperation = ($: IGlobalVariable) => {
|
||||
const mathOperation = $.step.parameters.mathOperation as string;
|
||||
const values = ($.step.parameters.values as IJSONObject[]).map((value) =>
|
||||
Number(value.input)
|
||||
) as number[];
|
||||
|
||||
if (mathOperation === 'add') {
|
||||
return values.reduce((acc, curr) => add(acc, curr), 0);
|
||||
} else if (mathOperation === 'divide') {
|
||||
return values.reduce((acc, curr) => divide(acc, curr));
|
||||
} else if (mathOperation === 'makeNegative') {
|
||||
return values.map((value) => -value);
|
||||
} else if (mathOperation === 'multiply') {
|
||||
return values.reduce((acc, curr) => multiply(acc, curr), 1);
|
||||
} else if (mathOperation === 'subtract') {
|
||||
return values.reduce((acc, curr) => subtract(acc, curr));
|
||||
}
|
||||
};
|
||||
|
||||
export default mathOperation;
|
@@ -1,15 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
|
||||
const randomNumber = ($: IGlobalVariable) => {
|
||||
const lowerRange = Number($.step.parameters.lowerRange);
|
||||
const upperRange = Number($.step.parameters.upperRange);
|
||||
const decimalPoints = Number($.step.parameters.decimalPoints) || 0;
|
||||
|
||||
return Number(
|
||||
(Math.random() * (upperRange - lowerRange) + lowerRange).toFixed(
|
||||
decimalPoints
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
export default randomNumber;
|
@@ -1,79 +0,0 @@
|
||||
import defineAction from '../../../../helpers/define-action';
|
||||
|
||||
import capitalize from './transformers/capitalize';
|
||||
import extractEmailAddress from './transformers/extract-email-address';
|
||||
import extractNumber from './transformers/extract-number';
|
||||
import htmlToMarkdown from './transformers/html-to-markdown';
|
||||
import lowercase from './transformers/lowercase';
|
||||
import markdownToHtml from './transformers/markdown-to-html';
|
||||
import pluralize from './transformers/pluralize';
|
||||
import replace from './transformers/replace';
|
||||
import trimWhitespace from './transformers/trim-whitespace';
|
||||
import useDefaultValue from './transformers/use-default-value';
|
||||
|
||||
const transformers = {
|
||||
capitalize,
|
||||
extractEmailAddress,
|
||||
extractNumber,
|
||||
htmlToMarkdown,
|
||||
lowercase,
|
||||
markdownToHtml,
|
||||
pluralize,
|
||||
replace,
|
||||
trimWhitespace,
|
||||
useDefaultValue,
|
||||
};
|
||||
|
||||
export default defineAction({
|
||||
name: 'Text',
|
||||
key: 'text',
|
||||
description:
|
||||
'Transform text data to capitalize, extract emails, apply default value, and much more.',
|
||||
arguments: [
|
||||
{
|
||||
label: 'Transform',
|
||||
key: 'transform',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
variables: true,
|
||||
options: [
|
||||
{ label: 'Capitalize', value: 'capitalize' },
|
||||
{ label: 'Convert HTML to Markdown', value: 'htmlToMarkdown' },
|
||||
{ label: 'Convert Markdown to HTML', value: 'markdownToHtml' },
|
||||
{ label: 'Extract Email Address', value: 'extractEmailAddress' },
|
||||
{ label: 'Extract Number', value: 'extractNumber' },
|
||||
{ label: 'Lowercase', value: 'lowercase' },
|
||||
{ label: 'Pluralize', value: 'pluralize' },
|
||||
{ label: 'Replace', value: 'replace' },
|
||||
{ label: 'Trim Whitespace', value: 'trimWhitespace' },
|
||||
{ label: 'Use Default Value', value: 'useDefaultValue' },
|
||||
],
|
||||
additionalFields: {
|
||||
type: 'query',
|
||||
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,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
@@ -1,11 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import { capitalize as lodashCapitalize } from 'lodash';
|
||||
|
||||
const capitalize = ($: IGlobalVariable) => {
|
||||
const input = $.step.parameters.input as string;
|
||||
const capitalizedInput = input.replace(/\w+/g, lodashCapitalize);
|
||||
|
||||
return capitalizedInput;
|
||||
};
|
||||
|
||||
export default capitalize;
|
@@ -1,12 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
|
||||
const extractEmailAddress = ($: IGlobalVariable) => {
|
||||
const input = $.step.parameters.input as string;
|
||||
const emailRegexp =
|
||||
/[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
|
||||
|
||||
const email = input.match(emailRegexp);
|
||||
return email ? email[0] : '';
|
||||
};
|
||||
|
||||
export default extractEmailAddress;
|
@@ -1,26 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
|
||||
const extractNumber = ($: IGlobalVariable) => {
|
||||
const input = $.step.parameters.input as string;
|
||||
|
||||
// Example numbers that's supported:
|
||||
// 123
|
||||
// -123
|
||||
// 123456
|
||||
// -123456
|
||||
// 121,234
|
||||
// -121,234
|
||||
// 121.234
|
||||
// -121.234
|
||||
// 1,234,567.89
|
||||
// -1,234,567.89
|
||||
// 1.234.567,89
|
||||
// -1.234.567,89
|
||||
|
||||
const numberRegexp = /-?((\d{1,3})+\.?,?)+/g;
|
||||
|
||||
const numbers = input.match(numberRegexp);
|
||||
return numbers ? numbers[0] : '';
|
||||
};
|
||||
|
||||
export default extractNumber;
|
@@ -1,11 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import { NodeHtmlMarkdown } from 'node-html-markdown';
|
||||
|
||||
const htmlToMarkdown = ($: IGlobalVariable) => {
|
||||
const input = $.step.parameters.input as string;
|
||||
|
||||
const markdown = NodeHtmlMarkdown.translate(input);
|
||||
return markdown;
|
||||
};
|
||||
|
||||
export default htmlToMarkdown;
|
@@ -1,8 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
|
||||
const lowercase = ($: IGlobalVariable) => {
|
||||
const input = $.step.parameters.input as string;
|
||||
return input.toLowerCase();
|
||||
};
|
||||
|
||||
export default lowercase;
|
@@ -1,13 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import showdown from 'showdown';
|
||||
|
||||
const converter = new showdown.Converter();
|
||||
|
||||
const markdownToHtml = ($: IGlobalVariable) => {
|
||||
const input = $.step.parameters.input as string;
|
||||
|
||||
const html = converter.makeHtml(input);
|
||||
return html;
|
||||
};
|
||||
|
||||
export default markdownToHtml;
|
@@ -1,9 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import pluralizeLibrary from 'pluralize';
|
||||
|
||||
const pluralize = ($: IGlobalVariable) => {
|
||||
const input = $.step.parameters.input as string;
|
||||
return pluralizeLibrary(input);
|
||||
};
|
||||
|
||||
export default pluralize;
|
@@ -1,12 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
|
||||
const replace = ($: IGlobalVariable) => {
|
||||
const input = $.step.parameters.input as string;
|
||||
|
||||
const find = $.step.parameters.find as string;
|
||||
const replace = $.step.parameters.replace as string;
|
||||
|
||||
return input.replaceAll(find, replace);
|
||||
};
|
||||
|
||||
export default replace;
|
@@ -1,8 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
|
||||
const trimWhitespace = ($: IGlobalVariable) => {
|
||||
const input = $.step.parameters.input as string;
|
||||
return input.trim();
|
||||
};
|
||||
|
||||
export default trimWhitespace;
|
@@ -1,13 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
|
||||
const useDefaultValue = ($: IGlobalVariable) => {
|
||||
const input = $.step.parameters.input as string;
|
||||
|
||||
if (input && input.trim().length > 0) {
|
||||
return input;
|
||||
}
|
||||
|
||||
return $.step.parameters.defaultValue as string;
|
||||
};
|
||||
|
||||
export default useDefaultValue;
|
@@ -1,54 +0,0 @@
|
||||
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,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
@@ -1,13 +0,0 @@
|
||||
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;
|
@@ -1,3 +0,0 @@
|
||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 4H20M4 12H20M4 20H20M4 8H14M4 16H14" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 243 B |
@@ -1,3 +0,0 @@
|
||||
import listTransformOptions from './list-transform-options';
|
||||
|
||||
export default [listTransformOptions];
|
@@ -1,51 +0,0 @@
|
||||
import formatOptions from './options/format';
|
||||
import timezoneOptions from './options/timezone';
|
||||
|
||||
const formatDateTime = [
|
||||
{
|
||||
label: 'Input',
|
||||
key: 'input',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'The datetime you want to format.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'From Format',
|
||||
key: 'fromFormat',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
description: 'The format of the input.',
|
||||
variables: true,
|
||||
options: formatOptions,
|
||||
},
|
||||
{
|
||||
label: 'From Timezone',
|
||||
key: 'fromTimezone',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
description: 'The timezone of the input.',
|
||||
variables: true,
|
||||
options: timezoneOptions,
|
||||
},
|
||||
{
|
||||
label: 'To Format',
|
||||
key: 'toFormat',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
description: 'The format of the output.',
|
||||
variables: true,
|
||||
options: formatOptions,
|
||||
},
|
||||
{
|
||||
label: 'To Timezone',
|
||||
key: 'toTimezone',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
description: 'The timezone of the output.',
|
||||
variables: true,
|
||||
options: timezoneOptions,
|
||||
},
|
||||
];
|
||||
|
||||
export default formatDateTime;
|
@@ -1,64 +0,0 @@
|
||||
const formatOptions = [
|
||||
{
|
||||
label: 'ccc MMM dd HH:mm:ssZZZ yyyy (Wed Aug 23 12:25:36-0000 2023)',
|
||||
value: 'ccc MMM dd HH:mm:ssZZZ yyyy',
|
||||
},
|
||||
{
|
||||
label: 'MMMM dd yyyy HH:mm:ss (August 23 2023 12:25:36)',
|
||||
value: 'MMMM dd yyyy HH:mm:ss',
|
||||
},
|
||||
{
|
||||
label: 'MMMM dd yyyy (August 23 2023)',
|
||||
value: 'MMMM dd yyyy',
|
||||
},
|
||||
{
|
||||
label: 'MMM dd yyyy (Aug 23 2023)',
|
||||
value: 'MMM dd yyyy',
|
||||
},
|
||||
{
|
||||
label: 'yyyy-MM-dd HH:mm:ss ZZZ (2023-08-23 12:25:36 -0000)',
|
||||
value: 'yyyy-MM-dd HH:mm:ss ZZZ',
|
||||
},
|
||||
{
|
||||
label: 'yyyy-MM-dd (2023-08-23)',
|
||||
value: 'yyyy-MM-dd',
|
||||
},
|
||||
{
|
||||
label: 'MM-dd-yyyy (08-23-2023)',
|
||||
value: 'MM-dd-yyyy',
|
||||
},
|
||||
{
|
||||
label: 'MM/dd/yyyy (08/23/2023)',
|
||||
value: 'MM/dd/yyyy',
|
||||
},
|
||||
{
|
||||
label: 'MM/dd/yy (08/23/23)',
|
||||
value: 'MM/dd/yy',
|
||||
},
|
||||
{
|
||||
label: 'dd-MM-yyyy (23-08-2023)',
|
||||
value: 'dd-MM-yyyy',
|
||||
},
|
||||
{
|
||||
label: 'dd/MM/yyyy (23/08/2023)',
|
||||
value: 'dd/MM/yyyy',
|
||||
},
|
||||
{
|
||||
label: 'dd/MM/yy (23/08/23)',
|
||||
value: 'dd/MM/yy',
|
||||
},
|
||||
{
|
||||
label: 'MM-yyyy (08-2023)',
|
||||
value: 'MM-yyyy',
|
||||
},
|
||||
{
|
||||
label: 'Unix timestamp in seconds (1694008283)',
|
||||
value: 'X',
|
||||
},
|
||||
{
|
||||
label: 'Unix timestamp in milliseconds (1694008306315)',
|
||||
value: 'x',
|
||||
},
|
||||
];
|
||||
|
||||
export default formatOptions;
|
@@ -1,449 +0,0 @@
|
||||
// The list from Intl.supportedValuesOf('timeZone') which is used by Luxon.
|
||||
|
||||
const timezoneOptions = [
|
||||
{ label: 'Africa/Abidjan', value: 'Africa/Abidjan' },
|
||||
{ label: 'Africa/Accra', value: 'Africa/Accra' },
|
||||
{ label: 'Africa/Addis_Ababa', value: 'Africa/Addis_Ababa' },
|
||||
{ label: 'Africa/Algiers', value: 'Africa/Algiers' },
|
||||
{ label: 'Africa/Asmera', value: 'Africa/Asmera' },
|
||||
{ label: 'Africa/Bamako', value: 'Africa/Bamako' },
|
||||
{ label: 'Africa/Bangui', value: 'Africa/Bangui' },
|
||||
{ label: 'Africa/Banjul', value: 'Africa/Banjul' },
|
||||
{ label: 'Africa/Bissau', value: 'Africa/Bissau' },
|
||||
{ label: 'Africa/Blantyre', value: 'Africa/Blantyre' },
|
||||
{ label: 'Africa/Brazzaville', value: 'Africa/Brazzaville' },
|
||||
{ label: 'Africa/Bujumbura', value: 'Africa/Bujumbura' },
|
||||
{ label: 'Africa/Cairo', value: 'Africa/Cairo' },
|
||||
{ label: 'Africa/Casablanca', value: 'Africa/Casablanca' },
|
||||
{ label: 'Africa/Ceuta', value: 'Africa/Ceuta' },
|
||||
{ label: 'Africa/Conakry', value: 'Africa/Conakry' },
|
||||
{ label: 'Africa/Dakar', value: 'Africa/Dakar' },
|
||||
{ label: 'Africa/Dar_es_Salaam', value: 'Africa/Dar_es_Salaam' },
|
||||
{ label: 'Africa/Djibouti', value: 'Africa/Djibouti' },
|
||||
{ label: 'Africa/Douala', value: 'Africa/Douala' },
|
||||
{ label: 'Africa/El_Aaiun', value: 'Africa/El_Aaiun' },
|
||||
{ label: 'Africa/Freetown', value: 'Africa/Freetown' },
|
||||
{ label: 'Africa/Gaborone', value: 'Africa/Gaborone' },
|
||||
{ label: 'Africa/Harare', value: 'Africa/Harare' },
|
||||
{ label: 'Africa/Johannesburg', value: 'Africa/Johannesburg' },
|
||||
{ label: 'Africa/Juba', value: 'Africa/Juba' },
|
||||
{ label: 'Africa/Kampala', value: 'Africa/Kampala' },
|
||||
{ label: 'Africa/Khartoum', value: 'Africa/Khartoum' },
|
||||
{ label: 'Africa/Kigali', value: 'Africa/Kigali' },
|
||||
{ label: 'Africa/Kinshasa', value: 'Africa/Kinshasa' },
|
||||
{ label: 'Africa/Lagos', value: 'Africa/Lagos' },
|
||||
{ label: 'Africa/Libreville', value: 'Africa/Libreville' },
|
||||
{ label: 'Africa/Lome', value: 'Africa/Lome' },
|
||||
{ label: 'Africa/Luanda', value: 'Africa/Luanda' },
|
||||
{ label: 'Africa/Lubumbashi', value: 'Africa/Lubumbashi' },
|
||||
{ label: 'Africa/Lusaka', value: 'Africa/Lusaka' },
|
||||
{ label: 'Africa/Malabo', value: 'Africa/Malabo' },
|
||||
{ label: 'Africa/Maputo', value: 'Africa/Maputo' },
|
||||
{ label: 'Africa/Maseru', value: 'Africa/Maseru' },
|
||||
{ label: 'Africa/Mbabane', value: 'Africa/Mbabane' },
|
||||
{ label: 'Africa/Mogadishu', value: 'Africa/Mogadishu' },
|
||||
{ label: 'Africa/Monrovia', value: 'Africa/Monrovia' },
|
||||
{ label: 'Africa/Nairobi', value: 'Africa/Nairobi' },
|
||||
{ label: 'Africa/Ndjamena', value: 'Africa/Ndjamena' },
|
||||
{ label: 'Africa/Niamey', value: 'Africa/Niamey' },
|
||||
{ label: 'Africa/Nouakchott', value: 'Africa/Nouakchott' },
|
||||
{ label: 'Africa/Ouagadougou', value: 'Africa/Ouagadougou' },
|
||||
{ label: 'Africa/Porto-Novo', value: 'Africa/Porto-Novo' },
|
||||
{ label: 'Africa/Sao_Tome', value: 'Africa/Sao_Tome' },
|
||||
{ label: 'Africa/Tripoli', value: 'Africa/Tripoli' },
|
||||
{ label: 'Africa/Tunis', value: 'Africa/Tunis' },
|
||||
{ label: 'Africa/Windhoek', value: 'Africa/Windhoek' },
|
||||
{ label: 'America/Adak', value: 'America/Adak' },
|
||||
{ label: 'America/Anchorage', value: 'America/Anchorage' },
|
||||
{ label: 'America/Anguilla', value: 'America/Anguilla' },
|
||||
{ label: 'America/Antigua', value: 'America/Antigua' },
|
||||
{ label: 'America/Araguaina', value: 'America/Araguaina' },
|
||||
{ label: 'America/Argentina/La_Rioja', value: 'America/Argentina/La_Rioja' },
|
||||
{
|
||||
label: 'America/Argentina/Rio_Gallegos',
|
||||
value: 'America/Argentina/Rio_Gallegos',
|
||||
},
|
||||
{ label: 'America/Argentina/Salta', value: 'America/Argentina/Salta' },
|
||||
{ label: 'America/Argentina/San_Juan', value: 'America/Argentina/San_Juan' },
|
||||
{ label: 'America/Argentina/San_Luis', value: 'America/Argentina/San_Luis' },
|
||||
{ label: 'America/Argentina/Tucuman', value: 'America/Argentina/Tucuman' },
|
||||
{ label: 'America/Argentina/Ushuaia', value: 'America/Argentina/Ushuaia' },
|
||||
{ label: 'America/Aruba', value: 'America/Aruba' },
|
||||
{ label: 'America/Asuncion', value: 'America/Asuncion' },
|
||||
{ label: 'America/Bahia', value: 'America/Bahia' },
|
||||
{ label: 'America/Bahia_Banderas', value: 'America/Bahia_Banderas' },
|
||||
{ label: 'America/Barbados', value: 'America/Barbados' },
|
||||
{ label: 'America/Belem', value: 'America/Belem' },
|
||||
{ label: 'America/Belize', value: 'America/Belize' },
|
||||
{ label: 'America/Blanc-Sablon', value: 'America/Blanc-Sablon' },
|
||||
{ label: 'America/Boa_Vista', value: 'America/Boa_Vista' },
|
||||
{ label: 'America/Bogota', value: 'America/Bogota' },
|
||||
{ label: 'America/Boise', value: 'America/Boise' },
|
||||
{ label: 'America/Buenos_Aires', value: 'America/Buenos_Aires' },
|
||||
{ label: 'America/Cambridge_Bay', value: 'America/Cambridge_Bay' },
|
||||
{ label: 'America/Campo_Grande', value: 'America/Campo_Grande' },
|
||||
{ label: 'America/Cancun', value: 'America/Cancun' },
|
||||
{ label: 'America/Caracas', value: 'America/Caracas' },
|
||||
{ label: 'America/Catamarca', value: 'America/Catamarca' },
|
||||
{ label: 'America/Cayenne', value: 'America/Cayenne' },
|
||||
{ label: 'America/Cayman', value: 'America/Cayman' },
|
||||
{ label: 'America/Chicago', value: 'America/Chicago' },
|
||||
{ label: 'America/Chihuahua', value: 'America/Chihuahua' },
|
||||
{ label: 'America/Ciudad_Juarez', value: 'America/Ciudad_Juarez' },
|
||||
{ label: 'America/Coral_Harbour', value: 'America/Coral_Harbour' },
|
||||
{ label: 'America/Cordoba', value: 'America/Cordoba' },
|
||||
{ label: 'America/Costa_Rica', value: 'America/Costa_Rica' },
|
||||
{ label: 'America/Creston', value: 'America/Creston' },
|
||||
{ label: 'America/Cuiaba', value: 'America/Cuiaba' },
|
||||
{ label: 'America/Curacao', value: 'America/Curacao' },
|
||||
{ label: 'America/Danmarkshavn', value: 'America/Danmarkshavn' },
|
||||
{ label: 'America/Dawson', value: 'America/Dawson' },
|
||||
{ label: 'America/Dawson_Creek', value: 'America/Dawson_Creek' },
|
||||
{ label: 'America/Denver', value: 'America/Denver' },
|
||||
{ label: 'America/Detroit', value: 'America/Detroit' },
|
||||
{ label: 'America/Dominica', value: 'America/Dominica' },
|
||||
{ label: 'America/Edmonton', value: 'America/Edmonton' },
|
||||
{ label: 'America/Eirunepe', value: 'America/Eirunepe' },
|
||||
{ label: 'America/El_Salvador', value: 'America/El_Salvador' },
|
||||
{ label: 'America/Fort_Nelson', value: 'America/Fort_Nelson' },
|
||||
{ label: 'America/Fortaleza', value: 'America/Fortaleza' },
|
||||
{ label: 'America/Glace_Bay', value: 'America/Glace_Bay' },
|
||||
{ label: 'America/Godthab', value: 'America/Godthab' },
|
||||
{ label: 'America/Goose_Bay', value: 'America/Goose_Bay' },
|
||||
{ label: 'America/Grand_Turk', value: 'America/Grand_Turk' },
|
||||
{ label: 'America/Grenada', value: 'America/Grenada' },
|
||||
{ label: 'America/Guadeloupe', value: 'America/Guadeloupe' },
|
||||
{ label: 'America/Guatemala', value: 'America/Guatemala' },
|
||||
{ label: 'America/Guayaquil', value: 'America/Guayaquil' },
|
||||
{ label: 'America/Guyana', value: 'America/Guyana' },
|
||||
{ label: 'America/Halifax', value: 'America/Halifax' },
|
||||
{ label: 'America/Havana', value: 'America/Havana' },
|
||||
{ label: 'America/Hermosillo', value: 'America/Hermosillo' },
|
||||
{ label: 'America/Indiana/Knox', value: 'America/Indiana/Knox' },
|
||||
{ label: 'America/Indiana/Marengo', value: 'America/Indiana/Marengo' },
|
||||
{ label: 'America/Indiana/Petersburg', value: 'America/Indiana/Petersburg' },
|
||||
{ label: 'America/Indiana/Tell_City', value: 'America/Indiana/Tell_City' },
|
||||
{ label: 'America/Indiana/Vevay', value: 'America/Indiana/Vevay' },
|
||||
{ label: 'America/Indiana/Vincennes', value: 'America/Indiana/Vincennes' },
|
||||
{ label: 'America/Indiana/Winamac', value: 'America/Indiana/Winamac' },
|
||||
{ label: 'America/Indianapolis', value: 'America/Indianapolis' },
|
||||
{ label: 'America/Inuvik', value: 'America/Inuvik' },
|
||||
{ label: 'America/Iqaluit', value: 'America/Iqaluit' },
|
||||
{ label: 'America/Jamaica', value: 'America/Jamaica' },
|
||||
{ label: 'America/Jujuy', value: 'America/Jujuy' },
|
||||
{ label: 'America/Juneau', value: 'America/Juneau' },
|
||||
{
|
||||
label: 'America/Kentucky/Monticello',
|
||||
value: 'America/Kentucky/Monticello',
|
||||
},
|
||||
{ label: 'America/Kralendijk', value: 'America/Kralendijk' },
|
||||
{ label: 'America/La_Paz', value: 'America/La_Paz' },
|
||||
{ label: 'America/Lima', value: 'America/Lima' },
|
||||
{ label: 'America/Los_Angeles', value: 'America/Los_Angeles' },
|
||||
{ label: 'America/Louisville', value: 'America/Louisville' },
|
||||
{ label: 'America/Lower_Princes', value: 'America/Lower_Princes' },
|
||||
{ label: 'America/Maceio', value: 'America/Maceio' },
|
||||
{ label: 'America/Managua', value: 'America/Managua' },
|
||||
{ label: 'America/Manaus', value: 'America/Manaus' },
|
||||
{ label: 'America/Marigot', value: 'America/Marigot' },
|
||||
{ label: 'America/Martinique', value: 'America/Martinique' },
|
||||
{ label: 'America/Matamoros', value: 'America/Matamoros' },
|
||||
{ label: 'America/Mazatlan', value: 'America/Mazatlan' },
|
||||
{ label: 'America/Mendoza', value: 'America/Mendoza' },
|
||||
{ label: 'America/Menominee', value: 'America/Menominee' },
|
||||
{ label: 'America/Merida', value: 'America/Merida' },
|
||||
{ label: 'America/Metlakatla', value: 'America/Metlakatla' },
|
||||
{ label: 'America/Mexico_City', value: 'America/Mexico_City' },
|
||||
{ label: 'America/Miquelon', value: 'America/Miquelon' },
|
||||
{ label: 'America/Moncton', value: 'America/Moncton' },
|
||||
{ label: 'America/Monterrey', value: 'America/Monterrey' },
|
||||
{ label: 'America/Montevideo', value: 'America/Montevideo' },
|
||||
{ label: 'America/Montserrat', value: 'America/Montserrat' },
|
||||
{ label: 'America/Nassau', value: 'America/Nassau' },
|
||||
{ label: 'America/New_York', value: 'America/New_York' },
|
||||
{ label: 'America/Nipigon', value: 'America/Nipigon' },
|
||||
{ label: 'America/Nome', value: 'America/Nome' },
|
||||
{ label: 'America/Noronha', value: 'America/Noronha' },
|
||||
{
|
||||
label: 'America/North_Dakota/Beulah',
|
||||
value: 'America/North_Dakota/Beulah',
|
||||
},
|
||||
{
|
||||
label: 'America/North_Dakota/Center',
|
||||
value: 'America/North_Dakota/Center',
|
||||
},
|
||||
{
|
||||
label: 'America/North_Dakota/New_Salem',
|
||||
value: 'America/North_Dakota/New_Salem',
|
||||
},
|
||||
{ label: 'America/Ojinaga', value: 'America/Ojinaga' },
|
||||
{ label: 'America/Panama', value: 'America/Panama' },
|
||||
{ label: 'America/Pangnirtung', value: 'America/Pangnirtung' },
|
||||
{ label: 'America/Paramaribo', value: 'America/Paramaribo' },
|
||||
{ label: 'America/Phoenix', value: 'America/Phoenix' },
|
||||
{ label: 'America/Port-au-Prince', value: 'America/Port-au-Prince' },
|
||||
{ label: 'America/Port_of_Spain', value: 'America/Port_of_Spain' },
|
||||
{ label: 'America/Porto_Velho', value: 'America/Porto_Velho' },
|
||||
{ label: 'America/Puerto_Rico', value: 'America/Puerto_Rico' },
|
||||
{ label: 'America/Punta_Arenas', value: 'America/Punta_Arenas' },
|
||||
{ label: 'America/Rainy_River', value: 'America/Rainy_River' },
|
||||
{ label: 'America/Rankin_Inlet', value: 'America/Rankin_Inlet' },
|
||||
{ label: 'America/Recife', value: 'America/Recife' },
|
||||
{ label: 'America/Regina', value: 'America/Regina' },
|
||||
{ label: 'America/Resolute', value: 'America/Resolute' },
|
||||
{ label: 'America/Rio_Branco', value: 'America/Rio_Branco' },
|
||||
{ label: 'America/Santa_Isabel', value: 'America/Santa_Isabel' },
|
||||
{ label: 'America/Santarem', value: 'America/Santarem' },
|
||||
{ label: 'America/Santiago', value: 'America/Santiago' },
|
||||
{ label: 'America/Santo_Domingo', value: 'America/Santo_Domingo' },
|
||||
{ label: 'America/Sao_Paulo', value: 'America/Sao_Paulo' },
|
||||
{ label: 'America/Scoresbysund', value: 'America/Scoresbysund' },
|
||||
{ label: 'America/Sitka', value: 'America/Sitka' },
|
||||
{ label: 'America/St_Barthelemy', value: 'America/St_Barthelemy' },
|
||||
{ label: 'America/St_Johns', value: 'America/St_Johns' },
|
||||
{ label: 'America/St_Kitts', value: 'America/St_Kitts' },
|
||||
{ label: 'America/St_Lucia', value: 'America/St_Lucia' },
|
||||
{ label: 'America/St_Thomas', value: 'America/St_Thomas' },
|
||||
{ label: 'America/St_Vincent', value: 'America/St_Vincent' },
|
||||
{ label: 'America/Swift_Current', value: 'America/Swift_Current' },
|
||||
{ label: 'America/Tegucigalpa', value: 'America/Tegucigalpa' },
|
||||
{ label: 'America/Thule', value: 'America/Thule' },
|
||||
{ label: 'America/Thunder_Bay', value: 'America/Thunder_Bay' },
|
||||
{ label: 'America/Tijuana', value: 'America/Tijuana' },
|
||||
{ label: 'America/Toronto', value: 'America/Toronto' },
|
||||
{ label: 'America/Tortola', value: 'America/Tortola' },
|
||||
{ label: 'America/Vancouver', value: 'America/Vancouver' },
|
||||
{ label: 'America/Whitehorse', value: 'America/Whitehorse' },
|
||||
{ label: 'America/Winnipeg', value: 'America/Winnipeg' },
|
||||
{ label: 'America/Yakutat', value: 'America/Yakutat' },
|
||||
{ label: 'America/Yellowknife', value: 'America/Yellowknife' },
|
||||
{ label: 'Antarctica/Casey', value: 'Antarctica/Casey' },
|
||||
{ label: 'Antarctica/Davis', value: 'Antarctica/Davis' },
|
||||
{ label: 'Antarctica/DumontDUrville', value: 'Antarctica/DumontDUrville' },
|
||||
{ label: 'Antarctica/Macquarie', value: 'Antarctica/Macquarie' },
|
||||
{ label: 'Antarctica/Mawson', value: 'Antarctica/Mawson' },
|
||||
{ label: 'Antarctica/McMurdo', value: 'Antarctica/McMurdo' },
|
||||
{ label: 'Antarctica/Palmer', value: 'Antarctica/Palmer' },
|
||||
{ label: 'Antarctica/Rothera', value: 'Antarctica/Rothera' },
|
||||
{ label: 'Antarctica/Syowa', value: 'Antarctica/Syowa' },
|
||||
{ label: 'Antarctica/Troll', value: 'Antarctica/Troll' },
|
||||
{ label: 'Antarctica/Vostok', value: 'Antarctica/Vostok' },
|
||||
{ label: 'Arctic/Longyearbyen', value: 'Arctic/Longyearbyen' },
|
||||
{ label: 'Asia/Aden', value: 'Asia/Aden' },
|
||||
{ label: 'Asia/Almaty', value: 'Asia/Almaty' },
|
||||
{ label: 'Asia/Amman', value: 'Asia/Amman' },
|
||||
{ label: 'Asia/Anadyr', value: 'Asia/Anadyr' },
|
||||
{ label: 'Asia/Aqtau', value: 'Asia/Aqtau' },
|
||||
{ label: 'Asia/Aqtobe', value: 'Asia/Aqtobe' },
|
||||
{ label: 'Asia/Ashgabat', value: 'Asia/Ashgabat' },
|
||||
{ label: 'Asia/Atyrau', value: 'Asia/Atyrau' },
|
||||
{ label: 'Asia/Baghdad', value: 'Asia/Baghdad' },
|
||||
{ label: 'Asia/Bahrain', value: 'Asia/Bahrain' },
|
||||
{ label: 'Asia/Baku', value: 'Asia/Baku' },
|
||||
{ label: 'Asia/Bangkok', value: 'Asia/Bangkok' },
|
||||
{ label: 'Asia/Barnaul', value: 'Asia/Barnaul' },
|
||||
{ label: 'Asia/Beirut', value: 'Asia/Beirut' },
|
||||
{ label: 'Asia/Bishkek', value: 'Asia/Bishkek' },
|
||||
{ label: 'Asia/Brunei', value: 'Asia/Brunei' },
|
||||
{ label: 'Asia/Calcutta', value: 'Asia/Calcutta' },
|
||||
{ label: 'Asia/Chita', value: 'Asia/Chita' },
|
||||
{ label: 'Asia/Choibalsan', value: 'Asia/Choibalsan' },
|
||||
{ label: 'Asia/Colombo', value: 'Asia/Colombo' },
|
||||
{ label: 'Asia/Damascus', value: 'Asia/Damascus' },
|
||||
{ label: 'Asia/Dhaka', value: 'Asia/Dhaka' },
|
||||
{ label: 'Asia/Dili', value: 'Asia/Dili' },
|
||||
{ label: 'Asia/Dubai', value: 'Asia/Dubai' },
|
||||
{ label: 'Asia/Dushanbe', value: 'Asia/Dushanbe' },
|
||||
{ label: 'Asia/Famagusta', value: 'Asia/Famagusta' },
|
||||
{ label: 'Asia/Gaza', value: 'Asia/Gaza' },
|
||||
{ label: 'Asia/Hebron', value: 'Asia/Hebron' },
|
||||
{ label: 'Asia/Hong_Kong', value: 'Asia/Hong_Kong' },
|
||||
{ label: 'Asia/Hovd', value: 'Asia/Hovd' },
|
||||
{ label: 'Asia/Irkutsk', value: 'Asia/Irkutsk' },
|
||||
{ label: 'Asia/Jakarta', value: 'Asia/Jakarta' },
|
||||
{ label: 'Asia/Jayapura', value: 'Asia/Jayapura' },
|
||||
{ label: 'Asia/Jerusalem', value: 'Asia/Jerusalem' },
|
||||
{ label: 'Asia/Kabul', value: 'Asia/Kabul' },
|
||||
{ label: 'Asia/Kamchatka', value: 'Asia/Kamchatka' },
|
||||
{ label: 'Asia/Karachi', value: 'Asia/Karachi' },
|
||||
{ label: 'Asia/Katmandu', value: 'Asia/Katmandu' },
|
||||
{ label: 'Asia/Khandyga', value: 'Asia/Khandyga' },
|
||||
{ label: 'Asia/Krasnoyarsk', value: 'Asia/Krasnoyarsk' },
|
||||
{ label: 'Asia/Kuala_Lumpur', value: 'Asia/Kuala_Lumpur' },
|
||||
{ label: 'Asia/Kuching', value: 'Asia/Kuching' },
|
||||
{ label: 'Asia/Kuwait', value: 'Asia/Kuwait' },
|
||||
{ label: 'Asia/Macau', value: 'Asia/Macau' },
|
||||
{ label: 'Asia/Magadan', value: 'Asia/Magadan' },
|
||||
{ label: 'Asia/Makassar', value: 'Asia/Makassar' },
|
||||
{ label: 'Asia/Manila', value: 'Asia/Manila' },
|
||||
{ label: 'Asia/Muscat', value: 'Asia/Muscat' },
|
||||
{ label: 'Asia/Nicosia', value: 'Asia/Nicosia' },
|
||||
{ label: 'Asia/Novokuznetsk', value: 'Asia/Novokuznetsk' },
|
||||
{ label: 'Asia/Novosibirsk', value: 'Asia/Novosibirsk' },
|
||||
{ label: 'Asia/Omsk', value: 'Asia/Omsk' },
|
||||
{ label: 'Asia/Oral', value: 'Asia/Oral' },
|
||||
{ label: 'Asia/Phnom_Penh', value: 'Asia/Phnom_Penh' },
|
||||
{ label: 'Asia/Pontianak', value: 'Asia/Pontianak' },
|
||||
{ label: 'Asia/Pyongyang', value: 'Asia/Pyongyang' },
|
||||
{ label: 'Asia/Qatar', value: 'Asia/Qatar' },
|
||||
{ label: 'Asia/Qostanay', value: 'Asia/Qostanay' },
|
||||
{ label: 'Asia/Qyzylorda', value: 'Asia/Qyzylorda' },
|
||||
{ label: 'Asia/Rangoon', value: 'Asia/Rangoon' },
|
||||
{ label: 'Asia/Riyadh', value: 'Asia/Riyadh' },
|
||||
{ label: 'Asia/Saigon', value: 'Asia/Saigon' },
|
||||
{ label: 'Asia/Sakhalin', value: 'Asia/Sakhalin' },
|
||||
{ label: 'Asia/Samarkand', value: 'Asia/Samarkand' },
|
||||
{ label: 'Asia/Seoul', value: 'Asia/Seoul' },
|
||||
{ label: 'Asia/Shanghai', value: 'Asia/Shanghai' },
|
||||
{ label: 'Asia/Singapore', value: 'Asia/Singapore' },
|
||||
{ label: 'Asia/Srednekolymsk', value: 'Asia/Srednekolymsk' },
|
||||
{ label: 'Asia/Taipei', value: 'Asia/Taipei' },
|
||||
{ label: 'Asia/Tashkent', value: 'Asia/Tashkent' },
|
||||
{ label: 'Asia/Tbilisi', value: 'Asia/Tbilisi' },
|
||||
{ label: 'Asia/Tehran', value: 'Asia/Tehran' },
|
||||
{ label: 'Asia/Thimphu', value: 'Asia/Thimphu' },
|
||||
{ label: 'Asia/Tokyo', value: 'Asia/Tokyo' },
|
||||
{ label: 'Asia/Tomsk', value: 'Asia/Tomsk' },
|
||||
{ label: 'Asia/Ulaanbaatar', value: 'Asia/Ulaanbaatar' },
|
||||
{ label: 'Asia/Urumqi', value: 'Asia/Urumqi' },
|
||||
{ label: 'Asia/Ust-Nera', value: 'Asia/Ust-Nera' },
|
||||
{ label: 'Asia/Vientiane', value: 'Asia/Vientiane' },
|
||||
{ label: 'Asia/Vladivostok', value: 'Asia/Vladivostok' },
|
||||
{ label: 'Asia/Yakutsk', value: 'Asia/Yakutsk' },
|
||||
{ label: 'Asia/Yekaterinburg', value: 'Asia/Yekaterinburg' },
|
||||
{ label: 'Asia/Yerevan', value: 'Asia/Yerevan' },
|
||||
{ label: 'Atlantic/Azores', value: 'Atlantic/Azores' },
|
||||
{ label: 'Atlantic/Bermuda', value: 'Atlantic/Bermuda' },
|
||||
{ label: 'Atlantic/Canary', value: 'Atlantic/Canary' },
|
||||
{ label: 'Atlantic/Cape_Verde', value: 'Atlantic/Cape_Verde' },
|
||||
{ label: 'Atlantic/Faeroe', value: 'Atlantic/Faeroe' },
|
||||
{ label: 'Atlantic/Madeira', value: 'Atlantic/Madeira' },
|
||||
{ label: 'Atlantic/Reykjavik', value: 'Atlantic/Reykjavik' },
|
||||
{ label: 'Atlantic/South_Georgia', value: 'Atlantic/South_Georgia' },
|
||||
{ label: 'Atlantic/St_Helena', value: 'Atlantic/St_Helena' },
|
||||
{ label: 'Atlantic/Stanley', value: 'Atlantic/Stanley' },
|
||||
{ label: 'Australia/Adelaide', value: 'Australia/Adelaide' },
|
||||
{ label: 'Australia/Brisbane', value: 'Australia/Brisbane' },
|
||||
{ label: 'Australia/Broken_Hill', value: 'Australia/Broken_Hill' },
|
||||
{ label: 'Australia/Currie', value: 'Australia/Currie' },
|
||||
{ label: 'Australia/Darwin', value: 'Australia/Darwin' },
|
||||
{ label: 'Australia/Eucla', value: 'Australia/Eucla' },
|
||||
{ label: 'Australia/Hobart', value: 'Australia/Hobart' },
|
||||
{ label: 'Australia/Lindeman', value: 'Australia/Lindeman' },
|
||||
{ label: 'Australia/Lord_Howe', value: 'Australia/Lord_Howe' },
|
||||
{ label: 'Australia/Melbourne', value: 'Australia/Melbourne' },
|
||||
{ label: 'Australia/Perth', value: 'Australia/Perth' },
|
||||
{ label: 'Australia/Sydney', value: 'Australia/Sydney' },
|
||||
{ label: 'Europe/Amsterdam', value: 'Europe/Amsterdam' },
|
||||
{ label: 'Europe/Andorra', value: 'Europe/Andorra' },
|
||||
{ label: 'Europe/Astrakhan', value: 'Europe/Astrakhan' },
|
||||
{ label: 'Europe/Athens', value: 'Europe/Athens' },
|
||||
{ label: 'Europe/Belgrade', value: 'Europe/Belgrade' },
|
||||
{ label: 'Europe/Berlin', value: 'Europe/Berlin' },
|
||||
{ label: 'Europe/Bratislava', value: 'Europe/Bratislava' },
|
||||
{ label: 'Europe/Brussels', value: 'Europe/Brussels' },
|
||||
{ label: 'Europe/Bucharest', value: 'Europe/Bucharest' },
|
||||
{ label: 'Europe/Budapest', value: 'Europe/Budapest' },
|
||||
{ label: 'Europe/Busingen', value: 'Europe/Busingen' },
|
||||
{ label: 'Europe/Chisinau', value: 'Europe/Chisinau' },
|
||||
{ label: 'Europe/Copenhagen', value: 'Europe/Copenhagen' },
|
||||
{ label: 'Europe/Dublin', value: 'Europe/Dublin' },
|
||||
{ label: 'Europe/Gibraltar', value: 'Europe/Gibraltar' },
|
||||
{ label: 'Europe/Guernsey', value: 'Europe/Guernsey' },
|
||||
{ label: 'Europe/Helsinki', value: 'Europe/Helsinki' },
|
||||
{ label: 'Europe/Isle_of_Man', value: 'Europe/Isle_of_Man' },
|
||||
{ label: 'Europe/Istanbul', value: 'Europe/Istanbul' },
|
||||
{ label: 'Europe/Jersey', value: 'Europe/Jersey' },
|
||||
{ label: 'Europe/Kaliningrad', value: 'Europe/Kaliningrad' },
|
||||
{ label: 'Europe/Kiev', value: 'Europe/Kiev' },
|
||||
{ label: 'Europe/Kirov', value: 'Europe/Kirov' },
|
||||
{ label: 'Europe/Lisbon', value: 'Europe/Lisbon' },
|
||||
{ label: 'Europe/Ljubljana', value: 'Europe/Ljubljana' },
|
||||
{ label: 'Europe/London', value: 'Europe/London' },
|
||||
{ label: 'Europe/Luxembourg', value: 'Europe/Luxembourg' },
|
||||
{ label: 'Europe/Madrid', value: 'Europe/Madrid' },
|
||||
{ label: 'Europe/Malta', value: 'Europe/Malta' },
|
||||
{ label: 'Europe/Mariehamn', value: 'Europe/Mariehamn' },
|
||||
{ label: 'Europe/Minsk', value: 'Europe/Minsk' },
|
||||
{ label: 'Europe/Monaco', value: 'Europe/Monaco' },
|
||||
{ label: 'Europe/Moscow', value: 'Europe/Moscow' },
|
||||
{ label: 'Europe/Oslo', value: 'Europe/Oslo' },
|
||||
{ label: 'Europe/Paris', value: 'Europe/Paris' },
|
||||
{ label: 'Europe/Podgorica', value: 'Europe/Podgorica' },
|
||||
{ label: 'Europe/Prague', value: 'Europe/Prague' },
|
||||
{ label: 'Europe/Riga', value: 'Europe/Riga' },
|
||||
{ label: 'Europe/Rome', value: 'Europe/Rome' },
|
||||
{ label: 'Europe/Samara', value: 'Europe/Samara' },
|
||||
{ label: 'Europe/San_Marino', value: 'Europe/San_Marino' },
|
||||
{ label: 'Europe/Sarajevo', value: 'Europe/Sarajevo' },
|
||||
{ label: 'Europe/Saratov', value: 'Europe/Saratov' },
|
||||
{ label: 'Europe/Simferopol', value: 'Europe/Simferopol' },
|
||||
{ label: 'Europe/Skopje', value: 'Europe/Skopje' },
|
||||
{ label: 'Europe/Sofia', value: 'Europe/Sofia' },
|
||||
{ label: 'Europe/Stockholm', value: 'Europe/Stockholm' },
|
||||
{ label: 'Europe/Tallinn', value: 'Europe/Tallinn' },
|
||||
{ label: 'Europe/Tirane', value: 'Europe/Tirane' },
|
||||
{ label: 'Europe/Ulyanovsk', value: 'Europe/Ulyanovsk' },
|
||||
{ label: 'Europe/Uzhgorod', value: 'Europe/Uzhgorod' },
|
||||
{ label: 'Europe/Vaduz', value: 'Europe/Vaduz' },
|
||||
{ label: 'Europe/Vatican', value: 'Europe/Vatican' },
|
||||
{ label: 'Europe/Vienna', value: 'Europe/Vienna' },
|
||||
{ label: 'Europe/Vilnius', value: 'Europe/Vilnius' },
|
||||
{ label: 'Europe/Volgograd', value: 'Europe/Volgograd' },
|
||||
{ label: 'Europe/Warsaw', value: 'Europe/Warsaw' },
|
||||
{ label: 'Europe/Zagreb', value: 'Europe/Zagreb' },
|
||||
{ label: 'Europe/Zaporozhye', value: 'Europe/Zaporozhye' },
|
||||
{ label: 'Europe/Zurich', value: 'Europe/Zurich' },
|
||||
{ label: 'Indian/Antananarivo', value: 'Indian/Antananarivo' },
|
||||
{ label: 'Indian/Chagos', value: 'Indian/Chagos' },
|
||||
{ label: 'Indian/Christmas', value: 'Indian/Christmas' },
|
||||
{ label: 'Indian/Cocos', value: 'Indian/Cocos' },
|
||||
{ label: 'Indian/Comoro', value: 'Indian/Comoro' },
|
||||
{ label: 'Indian/Kerguelen', value: 'Indian/Kerguelen' },
|
||||
{ label: 'Indian/Mahe', value: 'Indian/Mahe' },
|
||||
{ label: 'Indian/Maldives', value: 'Indian/Maldives' },
|
||||
{ label: 'Indian/Mauritius', value: 'Indian/Mauritius' },
|
||||
{ label: 'Indian/Mayotte', value: 'Indian/Mayotte' },
|
||||
{ label: 'Indian/Reunion', value: 'Indian/Reunion' },
|
||||
{ label: 'Pacific/Apia', value: 'Pacific/Apia' },
|
||||
{ label: 'Pacific/Auckland', value: 'Pacific/Auckland' },
|
||||
{ label: 'Pacific/Bougainville', value: 'Pacific/Bougainville' },
|
||||
{ label: 'Pacific/Chatham', value: 'Pacific/Chatham' },
|
||||
{ label: 'Pacific/Easter', value: 'Pacific/Easter' },
|
||||
{ label: 'Pacific/Efate', value: 'Pacific/Efate' },
|
||||
{ label: 'Pacific/Enderbury', value: 'Pacific/Enderbury' },
|
||||
{ label: 'Pacific/Fakaofo', value: 'Pacific/Fakaofo' },
|
||||
{ label: 'Pacific/Fiji', value: 'Pacific/Fiji' },
|
||||
{ label: 'Pacific/Funafuti', value: 'Pacific/Funafuti' },
|
||||
{ label: 'Pacific/Galapagos', value: 'Pacific/Galapagos' },
|
||||
{ label: 'Pacific/Gambier', value: 'Pacific/Gambier' },
|
||||
{ label: 'Pacific/Guadalcanal', value: 'Pacific/Guadalcanal' },
|
||||
{ label: 'Pacific/Guam', value: 'Pacific/Guam' },
|
||||
{ label: 'Pacific/Honolulu', value: 'Pacific/Honolulu' },
|
||||
{ label: 'Pacific/Johnston', value: 'Pacific/Johnston' },
|
||||
{ label: 'Pacific/Kiritimati', value: 'Pacific/Kiritimati' },
|
||||
{ label: 'Pacific/Kosrae', value: 'Pacific/Kosrae' },
|
||||
{ label: 'Pacific/Kwajalein', value: 'Pacific/Kwajalein' },
|
||||
{ label: 'Pacific/Majuro', value: 'Pacific/Majuro' },
|
||||
{ label: 'Pacific/Marquesas', value: 'Pacific/Marquesas' },
|
||||
{ label: 'Pacific/Midway', value: 'Pacific/Midway' },
|
||||
{ label: 'Pacific/Nauru', value: 'Pacific/Nauru' },
|
||||
{ label: 'Pacific/Niue', value: 'Pacific/Niue' },
|
||||
{ label: 'Pacific/Norfolk', value: 'Pacific/Norfolk' },
|
||||
{ label: 'Pacific/Noumea', value: 'Pacific/Noumea' },
|
||||
{ label: 'Pacific/Pago_Pago', value: 'Pacific/Pago_Pago' },
|
||||
{ label: 'Pacific/Palau', value: 'Pacific/Palau' },
|
||||
{ label: 'Pacific/Pitcairn', value: 'Pacific/Pitcairn' },
|
||||
{ label: 'Pacific/Ponape', value: 'Pacific/Ponape' },
|
||||
{ label: 'Pacific/Port_Moresby', value: 'Pacific/Port_Moresby' },
|
||||
{ label: 'Pacific/Rarotonga', value: 'Pacific/Rarotonga' },
|
||||
{ label: 'Pacific/Saipan', value: 'Pacific/Saipan' },
|
||||
{ label: 'Pacific/Tahiti', value: 'Pacific/Tahiti' },
|
||||
{ label: 'Pacific/Tarawa', value: 'Pacific/Tarawa' },
|
||||
{ label: 'Pacific/Tongatapu', value: 'Pacific/Tongatapu' },
|
||||
{ label: 'Pacific/Truk', value: 'Pacific/Truk' },
|
||||
{ label: 'Pacific/Wake', value: 'Pacific/Wake' },
|
||||
{ label: 'Pacific/Wallis', value: 'Pacific/Wallis' },
|
||||
];
|
||||
|
||||
export default timezoneOptions;
|
@@ -1,43 +0,0 @@
|
||||
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';
|
||||
|
||||
const options: IJSONObject = {
|
||||
capitalize,
|
||||
extractEmailAddress,
|
||||
extractNumber,
|
||||
findArrayItemByProperty,
|
||||
formatDateTime,
|
||||
formatNumber,
|
||||
htmlToMarkdown,
|
||||
lowercase,
|
||||
markdownToHtml,
|
||||
performMathOperation,
|
||||
pluralize,
|
||||
randomNumber,
|
||||
replace,
|
||||
trimWhitespace,
|
||||
useDefaultValue,
|
||||
};
|
||||
|
||||
export default {
|
||||
name: 'List fields after transform',
|
||||
key: 'listTransformOptions',
|
||||
|
||||
async run($: IGlobalVariable) {
|
||||
return options[$.step.parameters.transform as string];
|
||||
},
|
||||
};
|
@@ -1,38 +0,0 @@
|
||||
const formatNumber = [
|
||||
{
|
||||
label: 'Input',
|
||||
key: 'input',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'The number you want to format.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Input Decimal Mark',
|
||||
key: 'inputDecimalMark',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
description: 'The decimal mark of the input number.',
|
||||
variables: true,
|
||||
options: [
|
||||
{ label: 'Comma', value: ',' },
|
||||
{ label: 'Period', value: '.' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'To Format',
|
||||
key: 'toFormat',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
description: 'The format you want to convert the number to.',
|
||||
variables: true,
|
||||
options: [
|
||||
{ label: 'Comma for grouping & period for decimal', value: '0' },
|
||||
{ label: 'Period for grouping & comma for decimal', value: '1' },
|
||||
{ label: 'Space for grouping & period for decimal', value: '2' },
|
||||
{ label: 'Space for grouping & comma for decimal', value: '3' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default formatNumber;
|
@@ -1,36 +0,0 @@
|
||||
const performMathOperation = [
|
||||
{
|
||||
label: 'Math Operation',
|
||||
key: 'mathOperation',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
description: 'The math operation to perform.',
|
||||
variables: true,
|
||||
options: [
|
||||
{ label: 'Add', value: 'add' },
|
||||
{ label: 'Divide', value: 'divide' },
|
||||
{ label: 'Make Negative', value: 'makeNegative' },
|
||||
{ label: 'Multiply', value: 'multiply' },
|
||||
{ label: 'Subtract', value: 'subtract' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Values',
|
||||
key: 'values',
|
||||
type: 'dynamic' as const,
|
||||
required: false,
|
||||
description: 'Add or remove numbers as needed.',
|
||||
fields: [
|
||||
{
|
||||
label: 'Input',
|
||||
key: 'input',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'The number to perform the math operation on.',
|
||||
variables: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default performMathOperation;
|
@@ -1,29 +0,0 @@
|
||||
const randomNumber = [
|
||||
{
|
||||
label: 'Lower range',
|
||||
key: 'lowerRange',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'The lowest number to generate.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Upper range',
|
||||
key: 'upperRange',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'The highest number to generate.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Decimal points',
|
||||
key: 'decimalPoints',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
description:
|
||||
'The number of digits after the decimal point. It can be an integer between 0 and 15.',
|
||||
variables: true,
|
||||
},
|
||||
];
|
||||
|
||||
export default randomNumber;
|
@@ -1,12 +0,0 @@
|
||||
const capitalize = [
|
||||
{
|
||||
label: 'Input',
|
||||
key: 'input',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'Text that will be capitalized.',
|
||||
variables: true,
|
||||
},
|
||||
];
|
||||
|
||||
export default capitalize;
|
@@ -1,12 +0,0 @@
|
||||
const extractEmailAddress = [
|
||||
{
|
||||
label: 'Input',
|
||||
key: 'input',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'Text that will be searched for an email address.',
|
||||
variables: true,
|
||||
},
|
||||
];
|
||||
|
||||
export default extractEmailAddress;
|
@@ -1,12 +0,0 @@
|
||||
const extractNumber = [
|
||||
{
|
||||
label: 'Input',
|
||||
key: 'input',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'Text that will be searched for a number.',
|
||||
variables: true,
|
||||
},
|
||||
];
|
||||
|
||||
export default extractNumber;
|
@@ -1,12 +0,0 @@
|
||||
const htmlToMarkdown = [
|
||||
{
|
||||
label: 'Input',
|
||||
key: 'input',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'HTML that will be converted to Markdown.',
|
||||
variables: true,
|
||||
},
|
||||
];
|
||||
|
||||
export default htmlToMarkdown;
|
@@ -1,12 +0,0 @@
|
||||
const lowercase = [
|
||||
{
|
||||
label: 'Input',
|
||||
key: 'input',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'Text that will be lowercased.',
|
||||
variables: true,
|
||||
},
|
||||
];
|
||||
|
||||
export default lowercase;
|
@@ -1,12 +0,0 @@
|
||||
const markdownToHtml = [
|
||||
{
|
||||
label: 'Input',
|
||||
key: 'input',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'Markdown text that will be converted to HTML.',
|
||||
variables: true,
|
||||
},
|
||||
];
|
||||
|
||||
export default markdownToHtml;
|
@@ -1,12 +0,0 @@
|
||||
const pluralize = [
|
||||
{
|
||||
label: 'Input',
|
||||
key: 'input',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'Text that will be pluralized.',
|
||||
variables: true,
|
||||
},
|
||||
];
|
||||
|
||||
export default pluralize;
|
@@ -1,28 +0,0 @@
|
||||
const replace = [
|
||||
{
|
||||
label: 'Input',
|
||||
key: 'input',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'Text that you want to search for and replace values.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Find',
|
||||
key: 'find',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'Text that will be searched for.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Replace',
|
||||
key: 'replace',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
description: 'Text that will replace the found text.',
|
||||
variables: true,
|
||||
},
|
||||
];
|
||||
|
||||
export default replace;
|
@@ -1,12 +0,0 @@
|
||||
const trimWhitespace = [
|
||||
{
|
||||
label: 'Input',
|
||||
key: 'input',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'Text you want to remove leading and trailing spaces.',
|
||||
variables: true,
|
||||
},
|
||||
];
|
||||
|
||||
export default trimWhitespace;
|
@@ -1,21 +0,0 @@
|
||||
const useDefaultValue = [
|
||||
{
|
||||
label: 'Input',
|
||||
key: 'input',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'Text you want to check whether it is empty or not.',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Default Value',
|
||||
key: 'defaultValue',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description:
|
||||
'Text that will be used as a default value if the input is empty.',
|
||||
variables: true,
|
||||
},
|
||||
];
|
||||
|
||||
export default useDefaultValue;
|
@@ -1,28 +0,0 @@
|
||||
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;
|
@@ -1,16 +0,0 @@
|
||||
import defineApp from '../../helpers/define-app';
|
||||
import actions from './actions';
|
||||
import dynamicFields from './dynamic-fields';
|
||||
|
||||
export default defineApp({
|
||||
name: 'Formatter',
|
||||
key: 'formatter',
|
||||
iconUrl: '{BASE_URL}/apps/formatter/assets/favicon.svg',
|
||||
authDocUrl: 'https://automatisch.io/docs/apps/formatter/connection',
|
||||
supportsConnections: false,
|
||||
baseUrl: '',
|
||||
apiBaseUrl: '',
|
||||
primaryColor: '001F52',
|
||||
actions,
|
||||
dynamicFields,
|
||||
});
|
@@ -11,7 +11,7 @@ export default defineAction({
|
||||
key: 'repo',
|
||||
type: 'dropdown' as const,
|
||||
required: false,
|
||||
variables: true,
|
||||
variables: false,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
|
@@ -6,7 +6,7 @@ import actions from './actions';
|
||||
import dynamicData from './dynamic-data';
|
||||
|
||||
export default defineApp({
|
||||
name: 'GitHub',
|
||||
name: 'Github',
|
||||
key: 'github',
|
||||
baseUrl: 'https://github.com',
|
||||
apiBaseUrl: 'https://api.github.com',
|
||||
|
@@ -25,12 +25,6 @@ const verifyCredentials = async ($: IGlobalVariable) => {
|
||||
$.auth.data.accessToken = data.access_token;
|
||||
|
||||
const currentUser = await getCurrentUser($);
|
||||
const screenName = [
|
||||
currentUser.username,
|
||||
$.auth.data.instanceUrl,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' @ ');
|
||||
|
||||
await $.auth.set({
|
||||
clientId: $.auth.data.clientId,
|
||||
@@ -40,7 +34,7 @@ const verifyCredentials = async ($: IGlobalVariable) => {
|
||||
scope: data.scope,
|
||||
tokenType: data.token_type,
|
||||
userId: currentUser.id,
|
||||
screenName,
|
||||
screenName: `${currentUser.username} @ ${$.auth.data.instanceUrl}`,
|
||||
});
|
||||
};
|
||||
|
||||
|
@@ -9,11 +9,11 @@ export default {
|
||||
// ref:
|
||||
// - https://docs.gitlab.com/ee/api/projects.html#list-all-projects
|
||||
// - https://docs.gitlab.com/ee/api/rest/index.html#keyset-based-pagination
|
||||
|
||||
const firstPageRequest = $.http.get('/api/v4/projects', {
|
||||
params: {
|
||||
simple: true,
|
||||
pagination: 'keyset',
|
||||
membership: true,
|
||||
order_by: 'id',
|
||||
sort: 'asc',
|
||||
},
|
||||
|
@@ -6,7 +6,7 @@ import triggers from './triggers';
|
||||
import dynamicData from './dynamic-data';
|
||||
|
||||
export default defineApp({
|
||||
name: 'GitLab',
|
||||
name: 'Gitlab',
|
||||
key: 'gitlab',
|
||||
baseUrl: 'https://gitlab.com',
|
||||
apiBaseUrl: 'https://gitlab.com',
|
||||
|
@@ -21,7 +21,7 @@ export default defineAction({
|
||||
required: false,
|
||||
description:
|
||||
'The Google Drive where your spreadsheet resides. If nothing is selected, then your personal Google Drive will be used.',
|
||||
variables: true,
|
||||
variables: false,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
@@ -40,7 +40,7 @@ export default defineAction({
|
||||
required: true,
|
||||
dependsOn: ['parameters.driveId'],
|
||||
description: 'The spreadsheets in your Google Drive.',
|
||||
variables: true,
|
||||
variables: false,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
@@ -63,7 +63,7 @@ export default defineAction({
|
||||
required: true,
|
||||
dependsOn: ['parameters.spreadsheetId'],
|
||||
description: 'The worksheets in your selected spreadsheet.',
|
||||
variables: true,
|
||||
variables: false,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
|
@@ -1,105 +0,0 @@
|
||||
import defineAction from '../../../../helpers/define-action';
|
||||
|
||||
type THeaders = {
|
||||
__id: string;
|
||||
header: string;
|
||||
}[];
|
||||
|
||||
export default defineAction({
|
||||
name: 'Create spreadsheet',
|
||||
key: 'createSpreadsheet',
|
||||
description:
|
||||
'Create a blank spreadsheet or duplicate an existing spreadsheet. Optionally, provide headers.',
|
||||
arguments: [
|
||||
{
|
||||
label: 'Title',
|
||||
key: 'title',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: '',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Spreadsheet to copy',
|
||||
key: 'spreadsheetId',
|
||||
type: 'dropdown' as const,
|
||||
required: false,
|
||||
description: 'Choose a spreadsheet to copy its data.',
|
||||
variables: true,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listSpreadsheets',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Headers',
|
||||
key: 'headers',
|
||||
type: 'dynamic' as const,
|
||||
required: false,
|
||||
description:
|
||||
'These headers are ignored if "Spreadsheet to Copy" is selected.',
|
||||
fields: [
|
||||
{
|
||||
label: 'Header',
|
||||
key: 'header',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
variables: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
async run($) {
|
||||
if ($.step.parameters.spreadsheetId) {
|
||||
const body = { name: $.step.parameters.title };
|
||||
|
||||
const { data } = await $.http.post(
|
||||
`https://www.googleapis.com/drive/v3/files/${$.step.parameters.spreadsheetId}/copy`,
|
||||
body
|
||||
);
|
||||
|
||||
$.setActionItem({
|
||||
raw: data,
|
||||
});
|
||||
} else {
|
||||
const headers = $.step.parameters.headers as THeaders;
|
||||
const values = headers.map((entry) => entry.header);
|
||||
|
||||
const spreadsheetBody = {
|
||||
properties: {
|
||||
title: $.step.parameters.title,
|
||||
},
|
||||
sheets: [
|
||||
{
|
||||
data: [
|
||||
{
|
||||
startRow: 0,
|
||||
startColumn: 0,
|
||||
rowData: [
|
||||
{
|
||||
values: values.map((header) => ({
|
||||
userEnteredValue: { stringValue: header },
|
||||
})),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const { data } = await $.http.post('/v4/spreadsheets', spreadsheetBody);
|
||||
|
||||
$.setActionItem({
|
||||
raw: data,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
@@ -1,191 +0,0 @@
|
||||
import { IJSONObject } from '@automatisch/types';
|
||||
import defineAction from '../../../../helpers/define-action';
|
||||
|
||||
type THeaders = {
|
||||
__id: string;
|
||||
header: string;
|
||||
}[];
|
||||
|
||||
type TSheetsResponse = {
|
||||
sheets: {
|
||||
properties: {
|
||||
sheetId: string;
|
||||
title: string;
|
||||
};
|
||||
}[];
|
||||
};
|
||||
|
||||
type TBody = {
|
||||
requests: IJSONObject[];
|
||||
};
|
||||
|
||||
export default defineAction({
|
||||
name: 'Create worksheet',
|
||||
key: 'createWorksheet',
|
||||
description:
|
||||
'Create a blank worksheet with a title. Optionally, provide headers.',
|
||||
arguments: [
|
||||
{
|
||||
label: 'Drive',
|
||||
key: 'driveId',
|
||||
type: 'dropdown' as const,
|
||||
required: false,
|
||||
description:
|
||||
'The Google Drive where your spreadsheet resides. If nothing is selected, then your personal Google Drive will be used.',
|
||||
variables: true,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listDrives',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Spreadsheet',
|
||||
key: 'spreadsheetId',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
dependsOn: ['parameters.driveId'],
|
||||
variables: true,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listSpreadsheets',
|
||||
},
|
||||
{
|
||||
name: 'parameters.driveId',
|
||||
value: '{parameters.driveId}',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Title',
|
||||
key: 'title',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: '',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Headers',
|
||||
key: 'headers',
|
||||
type: 'dynamic' as const,
|
||||
required: false,
|
||||
fields: [
|
||||
{
|
||||
label: 'Header',
|
||||
key: 'header',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
variables: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Overwrite',
|
||||
key: 'overwrite',
|
||||
type: 'dropdown' as const,
|
||||
required: false,
|
||||
value: false,
|
||||
description:
|
||||
'If a worksheet with the specified title exists, its content would be lost. Please, use with caution.',
|
||||
variables: true,
|
||||
options: [
|
||||
{
|
||||
label: 'Yes',
|
||||
value: 'true',
|
||||
},
|
||||
{
|
||||
label: 'No',
|
||||
value: 'false',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
async run($) {
|
||||
const {
|
||||
data: { sheets },
|
||||
} = await $.http.get<TSheetsResponse>(
|
||||
`/v4/spreadsheets/${$.step.parameters.spreadsheetId}`
|
||||
);
|
||||
const selectedSheet = sheets.find(
|
||||
(sheet) => sheet.properties.title === $.step.parameters.title
|
||||
);
|
||||
const headers = $.step.parameters.headers as THeaders;
|
||||
const values = headers.map((entry) => entry.header);
|
||||
|
||||
const body: TBody = {
|
||||
requests: [
|
||||
{
|
||||
addSheet: {
|
||||
properties: {
|
||||
title: $.step.parameters.title,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
if ($.step.parameters.overwrite === 'true' && selectedSheet) {
|
||||
body.requests.unshift({
|
||||
deleteSheet: {
|
||||
sheetId: selectedSheet.properties.sheetId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const { data } = await $.http.post(
|
||||
`https://sheets.googleapis.com/v4/spreadsheets/${$.step.parameters.spreadsheetId}:batchUpdate`,
|
||||
body
|
||||
);
|
||||
|
||||
if (values.length) {
|
||||
const body = {
|
||||
requests: [
|
||||
{
|
||||
updateCells: {
|
||||
rows: [
|
||||
{
|
||||
values: values.map((header) => ({
|
||||
userEnteredValue: { stringValue: header },
|
||||
})),
|
||||
},
|
||||
],
|
||||
fields: '*',
|
||||
start: {
|
||||
sheetId:
|
||||
data.replies[data.replies.length - 1].addSheet.properties
|
||||
.sheetId,
|
||||
rowIndex: 0,
|
||||
columnIndex: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const { data: response } = await $.http.post(
|
||||
`https://sheets.googleapis.com/v4/spreadsheets/${$.step.parameters.spreadsheetId}:batchUpdate`,
|
||||
body
|
||||
);
|
||||
|
||||
$.setActionItem({
|
||||
raw: response,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
$.setActionItem({
|
||||
raw: data,
|
||||
});
|
||||
},
|
||||
});
|
@@ -1,5 +1,3 @@
|
||||
import createSpreadsheet from './create-spreadsheet';
|
||||
import createSpreadsheetRow from './create-spreadsheet-row';
|
||||
import createWorksheet from './create-worksheet';
|
||||
|
||||
export default [createSpreadsheet, createSpreadsheetRow, createWorksheet];
|
||||
export default [createSpreadsheetRow];
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import listDrives from './list-drives';
|
||||
import listSpreadsheets from './list-spreadsheets';
|
||||
import listWorksheets from './list-worksheets';
|
||||
import listColumns from './list-columns';
|
||||
|
||||
export default [listDrives, listSpreadsheets, listWorksheets];
|
||||
export default [listDrives, listSpreadsheets, listWorksheets, listColumns];
|
||||
|
@@ -0,0 +1,70 @@
|
||||
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
|
||||
|
||||
type TSheetsResponse = {
|
||||
sheets: {
|
||||
properties: {
|
||||
sheetId: string;
|
||||
title: string;
|
||||
};
|
||||
}[];
|
||||
};
|
||||
|
||||
function getColumnNameByNumber(columnNumber: number) {
|
||||
let columnName = '';
|
||||
while (columnNumber > 0) {
|
||||
const modulo = (columnNumber - 1) % 26;
|
||||
columnName = String.fromCharCode(65 + modulo) + columnName;
|
||||
columnNumber = Math.floor((columnNumber - modulo) / 26);
|
||||
}
|
||||
return columnName;
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'List columns',
|
||||
key: 'listColumns',
|
||||
|
||||
async run($: IGlobalVariable) {
|
||||
const spreadsheetId = $.step.parameters.spreadsheetId as string;
|
||||
|
||||
const headers: {
|
||||
data: IJSONObject[];
|
||||
} = {
|
||||
data: [],
|
||||
};
|
||||
|
||||
if (!spreadsheetId) {
|
||||
return headers;
|
||||
}
|
||||
|
||||
const {
|
||||
data: { sheets },
|
||||
} = await $.http.get<TSheetsResponse>(
|
||||
`/v4/spreadsheets/${$.step.parameters.spreadsheetId}`
|
||||
);
|
||||
|
||||
const selectedSheet = sheets.find(
|
||||
(sheet) => sheet.properties.sheetId === $.step.parameters.worksheetId
|
||||
);
|
||||
|
||||
if (!selectedSheet) return;
|
||||
|
||||
const sheetName = selectedSheet.properties.title;
|
||||
|
||||
const range = `${sheetName}!1:1`;
|
||||
|
||||
const { data } = await $.http.get(
|
||||
`v4/spreadsheets/${$.step.parameters.spreadsheetId}/values/${range}`
|
||||
);
|
||||
|
||||
if (data.values?.length) {
|
||||
for (let number = 0; number < data.values[0].length; number++) {
|
||||
headers.data.push({
|
||||
value: getColumnNameByNumber(number + 1),
|
||||
name: data.values[0][number],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return headers;
|
||||
},
|
||||
};
|
@@ -1,5 +1,11 @@
|
||||
import newSpreadsheets from './new-spreadsheets';
|
||||
import newWorksheets from './new-worksheets';
|
||||
import newSpreadsheetRows from './new-spreadsheet-rows';
|
||||
import newOrUpdatedSpreadsheetRows from './new-or-updated-spreadsheet-rows';
|
||||
|
||||
export default [newSpreadsheets, newWorksheets, newSpreadsheetRows];
|
||||
export default [
|
||||
newSpreadsheets,
|
||||
newWorksheets,
|
||||
newSpreadsheetRows,
|
||||
newOrUpdatedSpreadsheetRows,
|
||||
];
|
||||
|
@@ -0,0 +1,109 @@
|
||||
import defineTrigger from '../../../../helpers/define-trigger';
|
||||
import newOrUpdatedSpreadsheetRows from './new-or-updated-spreadsheet-rows';
|
||||
|
||||
export default defineTrigger({
|
||||
name: 'New or updated spreadsheet rows',
|
||||
key: 'newOrUpdatedSpreadsheetRows',
|
||||
pollInterval: 15,
|
||||
description: 'Triggers when a new row is added or modified in a spreadsheet.',
|
||||
arguments: [
|
||||
{
|
||||
label: 'Drive',
|
||||
key: 'driveId',
|
||||
type: 'dropdown' as const,
|
||||
required: false,
|
||||
description:
|
||||
'The Google Drive where your spreadsheet resides. If nothing is selected, then your personal Google Drive will be used.',
|
||||
variables: false,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listDrives',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Spreadsheet',
|
||||
key: 'spreadsheetId',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
dependsOn: ['parameters.driveId'],
|
||||
description: 'The spreadsheets in your Google Drive.',
|
||||
variables: false,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listSpreadsheets',
|
||||
},
|
||||
{
|
||||
name: 'parameters.driveId',
|
||||
value: '{parameters.driveId}',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Worksheet',
|
||||
key: 'worksheetId',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
dependsOn: ['parameters.spreadsheetId'],
|
||||
description:
|
||||
'The worksheets in your selected spreadsheet. You must have column headers.',
|
||||
variables: false,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listWorksheets',
|
||||
},
|
||||
{
|
||||
name: 'parameters.spreadsheetId',
|
||||
value: '{parameters.spreadsheetId}',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Trigger Column',
|
||||
key: 'triggerColumnIndex',
|
||||
type: 'dropdown' as const,
|
||||
required: false,
|
||||
dependsOn: ['parameters.worksheetId'],
|
||||
description:
|
||||
'Triggers on changes to cells in this column only. Leave this field blank if you want the flow to trigger on changes to any cell within the row. Please note: All new rows will trigger the flow even if the Trigger column is empty.',
|
||||
variables: false,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listColumns',
|
||||
},
|
||||
{
|
||||
name: 'parameters.spreadsheetId',
|
||||
value: '{parameters.spreadsheetId}',
|
||||
},
|
||||
{
|
||||
name: 'parameters.worksheetId',
|
||||
value: '{parameters.worksheetId}',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
async run($) {
|
||||
await newOrUpdatedSpreadsheetRows($);
|
||||
},
|
||||
});
|
@@ -0,0 +1,50 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
|
||||
type TSheetsResponse = {
|
||||
sheets: {
|
||||
properties: {
|
||||
sheetId: string;
|
||||
title: string;
|
||||
};
|
||||
}[];
|
||||
};
|
||||
|
||||
const newOrUpdatedSpreadsheetRows = async ($: IGlobalVariable) => {
|
||||
const {
|
||||
data: { sheets },
|
||||
} = await $.http.get<TSheetsResponse>(
|
||||
`/v4/spreadsheets/${$.step.parameters.spreadsheetId}`
|
||||
);
|
||||
|
||||
const selectedSheet = sheets.find(
|
||||
(sheet) => sheet.properties.sheetId === $.step.parameters.worksheetId
|
||||
);
|
||||
|
||||
if (!selectedSheet) return;
|
||||
|
||||
const sheetName = selectedSheet.properties.title;
|
||||
|
||||
let range = sheetName;
|
||||
|
||||
if ($.step.parameters.triggerColumnIndex) {
|
||||
range = `${sheetName}!${$.step.parameters.triggerColumnIndex}:${$.step.parameters.triggerColumnIndex}`;
|
||||
}
|
||||
|
||||
const { data } = await $.http.get(
|
||||
`v4/spreadsheets/${$.step.parameters.spreadsheetId}/values/${range}`
|
||||
);
|
||||
|
||||
if (data.values?.length) {
|
||||
for (let index = data.values.length - 1; index > 0; index--) {
|
||||
const value = data.values[index];
|
||||
$.pushTriggerItem({
|
||||
raw: { row: value },
|
||||
meta: {
|
||||
internalId: `${value}-${index.toString()}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default newOrUpdatedSpreadsheetRows;
|
@@ -84,7 +84,7 @@ export default defineAction({
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'Header key',
|
||||
variables: true,
|
||||
variables: false,
|
||||
},
|
||||
{
|
||||
label: 'Value',
|
||||
@@ -132,7 +132,7 @@ export default defineAction({
|
||||
|
||||
throwIfFileSizeExceedsLimit(metadataResponse.headers['content-length']);
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch { }
|
||||
} catch {}
|
||||
|
||||
const requestData: AxiosRequestConfig = {
|
||||
url,
|
||||
|
@@ -1,83 +0,0 @@
|
||||
import defineAction from '../../../../helpers/define-action';
|
||||
|
||||
export default defineAction({
|
||||
name: 'Create contact',
|
||||
key: 'createContact',
|
||||
description: `Create contact on user's account.`,
|
||||
arguments: [
|
||||
{
|
||||
label: 'Company name',
|
||||
key: 'company',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Email',
|
||||
key: 'email',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'First name',
|
||||
key: 'firstName',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Last name',
|
||||
key: 'lastName',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
description: 'Last name',
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Phone',
|
||||
key: 'phone',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Website URL',
|
||||
key: 'website',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
variables: true,
|
||||
},
|
||||
{
|
||||
label: 'Owner ID',
|
||||
key: 'hubspotOwnerId',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
variables: true,
|
||||
},
|
||||
],
|
||||
|
||||
async run($) {
|
||||
const company = $.step.parameters.company as string;
|
||||
const email = $.step.parameters.email as string;
|
||||
const firstName = $.step.parameters.firstName as string;
|
||||
const lastName = $.step.parameters.lastName as string;
|
||||
const phone = $.step.parameters.phone as string;
|
||||
const website = $.step.parameters.website as string;
|
||||
const hubspotOwnerId = $.step.parameters.hubspotOwnerId as string;
|
||||
|
||||
const response = await $.http.post(`crm/v3/objects/contacts`, {
|
||||
properties: {
|
||||
company,
|
||||
email,
|
||||
firstname: firstName,
|
||||
lastname: lastName,
|
||||
phone,
|
||||
website,
|
||||
hubspot_owner_id: hubspotOwnerId,
|
||||
},
|
||||
});
|
||||
|
||||
$.setActionItem({ raw: response.data });
|
||||
},
|
||||
});
|
@@ -1,3 +0,0 @@
|
||||
import createContact from './create-contact';
|
||||
|
||||
export default [ createContact ];
|
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="27px" height="28px" viewBox="0 0 27 28" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g fill="#f95c35">
|
||||
<path d="M19.614233,20.1771162 C17.5228041,20.1771162 15.8274241,18.4993457 15.8274241,16.4299995 C15.8274241,14.3602937 17.5228041,12.6825232 19.614233,12.6825232 C21.7056619,12.6825232 23.4010418,14.3602937 23.4010418,16.4299995 C23.4010418,18.4993457 21.7056619,20.1771162 19.614233,20.1771162 M20.7478775,9.21551429 L20.7478775,5.88190722 C21.6271788,5.47091457 22.243053,4.59067833 22.243053,3.56912967 L22.243053,3.49218091 C22.243053,2.08229273 21.0774338,0.928780545 19.6527478,0.928780545 L19.5753548,0.928780545 C18.1506688,0.928780545 16.9850496,2.08229273 16.9850496,3.49218091 L16.9850496,3.56912967 C16.9850496,4.59067833 17.6009238,5.47127414 18.4802251,5.88226679 L18.4802251,9.21551429 C17.1710836,9.4157968 15.9749432,9.95012321 14.9884545,10.7365107 L5.73944086,3.61659339 C5.80048326,3.3846684 5.84335828,3.14591151 5.84372163,2.89492912 C5.84517502,1.29842223 4.53930368,0.00215931486 2.92531356,1.87311107e-06 C1.31205014,-0.00179599501 0.00181863138,1.29087118 1.8932965e-06,2.88773765 C-0.00181484479,4.48460412 1.30405649,5.78086703 2.91804661,5.7826649 C3.44381061,5.78338405 3.93069642,5.63559929 4.35726652,5.39540411 L13.4551275,12.3995387 C12.6815604,13.5552084 12.2281026,14.9395668 12.2281026,16.4299995 C12.2281026,17.9901894 12.7262522,19.433518 13.5677653,20.6204705 L10.8012365,23.3586237 C10.5825013,23.2935408 10.3557723,23.2482346 10.1152362,23.2482346 C8.78938076,23.2482346 7.71423516,24.3118533 7.71423516,25.6239375 C7.71423516,26.9363812 8.78938076,28 10.1152362,28 C11.441455,28 12.5162373,26.9363812 12.5162373,25.6239375 C12.5162373,25.3866189 12.4704555,25.1618854 12.4046896,24.9454221 L15.1414238,22.2371135 C16.3837093,23.1752411 17.9308435,23.7390526 19.614233,23.7390526 C23.6935367,23.7390526 27,20.466573 27,16.4299995 C27,12.7756527 24.2872467,9.7566726 20.7478775,9.21551429"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -1,20 +0,0 @@
|
||||
import { IField, IGlobalVariable } from '@automatisch/types';
|
||||
import { URLSearchParams } from 'url';
|
||||
import scopes from '../common/scopes';
|
||||
|
||||
export default async function generateAuthUrl($: IGlobalVariable) {
|
||||
const oauthRedirectUrlField = $.app.auth.fields.find(
|
||||
(field: IField) => field.key == 'oAuthRedirectUrl'
|
||||
);
|
||||
const callbackUrl = oauthRedirectUrlField.value as string;
|
||||
|
||||
const searchParams = new URLSearchParams({
|
||||
client_id: $.auth.data.clientId as string,
|
||||
redirect_uri: callbackUrl,
|
||||
scope: scopes.join(' '),
|
||||
});
|
||||
|
||||
const url = `https://app.hubspot.com/oauth/authorize?${searchParams.toString()}`;
|
||||
|
||||
await $.auth.set({ url });
|
||||
}
|
@@ -1,48 +0,0 @@
|
||||
import generateAuthUrl from './generate-auth-url';
|
||||
import verifyCredentials from './verify-credentials';
|
||||
import isStillVerified from './is-still-verified';
|
||||
import refreshToken from './refresh-token';
|
||||
|
||||
export default {
|
||||
fields: [
|
||||
{
|
||||
key: 'oAuthRedirectUrl',
|
||||
label: 'OAuth Redirect URL',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: true,
|
||||
value: '{WEB_APP_URL}/app/hubspot/connections/add',
|
||||
placeholder: null,
|
||||
description:
|
||||
'When asked to input an OAuth callback or redirect URL in HubSpot OAuth, enter the URL above.',
|
||||
clickToCopy: true,
|
||||
},
|
||||
{
|
||||
key: 'clientId',
|
||||
label: 'Client ID',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: false,
|
||||
value: null,
|
||||
placeholder: null,
|
||||
description: null,
|
||||
clickToCopy: false,
|
||||
},
|
||||
{
|
||||
key: 'clientSecret',
|
||||
label: 'Client Secret',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
readOnly: false,
|
||||
value: null,
|
||||
placeholder: null,
|
||||
description: null,
|
||||
clickToCopy: false,
|
||||
},
|
||||
],
|
||||
|
||||
generateAuthUrl,
|
||||
verifyCredentials,
|
||||
isStillVerified,
|
||||
refreshToken,
|
||||
};
|
@@ -1,10 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import getAccessTokenInfo from '../common/get-access-token-info';
|
||||
|
||||
const isStillVerified = async ($: IGlobalVariable) => {
|
||||
await getAccessTokenInfo($);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
export default isStillVerified;
|
@@ -1,28 +0,0 @@
|
||||
import { IGlobalVariable, IField } from '@automatisch/types';
|
||||
import { URLSearchParams } from 'url';
|
||||
|
||||
const refreshToken = async ($: IGlobalVariable) => {
|
||||
const oauthRedirectUrlField = $.app.auth.fields.find(
|
||||
(field: IField) => field.key == 'oAuthRedirectUrl'
|
||||
);
|
||||
|
||||
const callbackUrl = oauthRedirectUrlField.value as string;
|
||||
|
||||
const params = new URLSearchParams({
|
||||
grant_type: 'refresh_token',
|
||||
client_id: $.auth.data.clientId as string,
|
||||
client_secret: $.auth.data.clientSecret as string,
|
||||
redirect_uri: callbackUrl,
|
||||
refresh_token: $.auth.data.refreshToken as string,
|
||||
});
|
||||
|
||||
const { data } = await $.http.post('/oauth/v1/token', params.toString());
|
||||
|
||||
await $.auth.set({
|
||||
accessToken: data.access_token,
|
||||
expiresIn: data.expires_in,
|
||||
refreshToken: data.refresh_token,
|
||||
});
|
||||
};
|
||||
|
||||
export default refreshToken;
|
@@ -1,52 +0,0 @@
|
||||
import { IGlobalVariable, IField } from '@automatisch/types';
|
||||
import { URLSearchParams } from 'url';
|
||||
import getAccessTokenInfo from '../common/get-access-token-info';
|
||||
|
||||
const verifyCredentials = async ($: IGlobalVariable) => {
|
||||
const oauthRedirectUrlField = $.app.auth.fields.find(
|
||||
(field: IField) => field.key == 'oAuthRedirectUrl'
|
||||
);
|
||||
const callbackUrl = oauthRedirectUrlField.value as string;
|
||||
const params = new URLSearchParams({
|
||||
grant_type: 'authorization_code',
|
||||
client_id: $.auth.data.clientId as string,
|
||||
client_secret: $.auth.data.clientSecret as string,
|
||||
redirect_uri: callbackUrl,
|
||||
code: $.auth.data.code as string,
|
||||
});
|
||||
|
||||
const { data: verifiedCredentials } = await $.http.post(
|
||||
'/oauth/v1/token',
|
||||
params.toString()
|
||||
);
|
||||
|
||||
const {
|
||||
access_token: accessToken,
|
||||
refresh_token: refreshToken,
|
||||
expires_in: expiresIn,
|
||||
} = verifiedCredentials;
|
||||
|
||||
await $.auth.set({
|
||||
accessToken,
|
||||
refreshToken,
|
||||
expiresIn,
|
||||
});
|
||||
|
||||
const accessTokenInfo = await getAccessTokenInfo($);
|
||||
|
||||
await $.auth.set({
|
||||
screenName: accessTokenInfo.user,
|
||||
hubDomain: accessTokenInfo.hub_domain,
|
||||
scopes: accessTokenInfo.scopes,
|
||||
scopeToScopeGroupPks: accessTokenInfo.scope_to_scope_group_pks,
|
||||
trialScopes: accessTokenInfo.trial_scopes,
|
||||
trialScopeToScoreGroupPks: accessTokenInfo.trial_scope_to_scope_group_pks,
|
||||
hubId: accessTokenInfo.hub_id,
|
||||
appId: accessTokenInfo.app_id,
|
||||
userId: accessTokenInfo.user_id,
|
||||
expiresIn: accessTokenInfo.expires_in,
|
||||
tokenType: accessTokenInfo.token_type,
|
||||
});
|
||||
};
|
||||
|
||||
export default verifyCredentials;
|
@@ -1,14 +0,0 @@
|
||||
import { TBeforeRequest } from '@automatisch/types';
|
||||
|
||||
const addAuthHeader: TBeforeRequest = ($, requestConfig) => {
|
||||
if (requestConfig.additionalProperties?.skipAddingAuthHeader) return requestConfig;
|
||||
|
||||
if ($.auth.data?.accessToken) {
|
||||
const authorizationHeader = `Bearer ${$.auth.data.accessToken}`;
|
||||
requestConfig.headers.Authorization = authorizationHeader;
|
||||
}
|
||||
|
||||
return requestConfig;
|
||||
};
|
||||
|
||||
export default addAuthHeader;
|
@@ -1,11 +0,0 @@
|
||||
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
|
||||
|
||||
const getAccessTokenInfo = async ($: IGlobalVariable): Promise<IJSONObject> => {
|
||||
const response = await $.http.get(
|
||||
`/oauth/v1/access-tokens/${$.auth.data.accessToken}`
|
||||
);
|
||||
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export default getAccessTokenInfo;
|
@@ -1,3 +0,0 @@
|
||||
const scopes = ['crm.objects.contacts.read', 'crm.objects.contacts.write'];
|
||||
|
||||
export default scopes;
|
@@ -1,18 +0,0 @@
|
||||
import defineApp from '../../helpers/define-app';
|
||||
import addAuthHeader from './common/add-auth-header';
|
||||
import actions from './actions';
|
||||
import auth from './auth';
|
||||
|
||||
export default defineApp({
|
||||
name: 'HubSpot',
|
||||
key: 'hubspot',
|
||||
iconUrl: '{BASE_URL}/apps/hubspot/assets/favicon.svg',
|
||||
authDocUrl: 'https://automatisch.io/docs/apps/hubspot/connection',
|
||||
supportsConnections: true,
|
||||
baseUrl: 'https://www.hubspot.com',
|
||||
apiBaseUrl: 'https://api.hubapi.com',
|
||||
primaryColor: 'F95C35',
|
||||
beforeRequest: [addAuthHeader],
|
||||
auth,
|
||||
actions,
|
||||
});
|
@@ -1,3 +0,0 @@
|
||||
import sendMessageToChannel from './send-a-message-to-channel';
|
||||
|
||||
export default [sendMessageToChannel];
|
@@ -1,42 +0,0 @@
|
||||
import defineAction from '../../../../helpers/define-action';
|
||||
import postMessage from './post-message';
|
||||
|
||||
export default defineAction({
|
||||
name: 'Send a message to channel',
|
||||
key: 'sendMessageToChannel',
|
||||
description: 'Sends a message to a channel you specify.',
|
||||
arguments: [
|
||||
{
|
||||
label: 'Channel',
|
||||
key: 'channel',
|
||||
type: 'dropdown' as const,
|
||||
required: true,
|
||||
description: 'Pick a channel to send the message to.',
|
||||
variables: true,
|
||||
source: {
|
||||
type: 'query',
|
||||
name: 'getDynamicData',
|
||||
arguments: [
|
||||
{
|
||||
name: 'key',
|
||||
value: 'listChannels',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Message text',
|
||||
key: 'message',
|
||||
type: 'string' as const,
|
||||
required: true,
|
||||
description: 'The content of your new message.',
|
||||
variables: true,
|
||||
},
|
||||
],
|
||||
|
||||
async run($) {
|
||||
const message = await postMessage($);
|
||||
|
||||
return message;
|
||||
},
|
||||
});
|
@@ -1,27 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
|
||||
type TData = {
|
||||
channel_id: string;
|
||||
message: string;
|
||||
};
|
||||
|
||||
const postMessage = async ($: IGlobalVariable) => {
|
||||
const { parameters } = $.step;
|
||||
const channel_id = parameters.channel as string;
|
||||
const message = parameters.message as string;
|
||||
|
||||
const data: TData = {
|
||||
channel_id,
|
||||
message,
|
||||
};
|
||||
|
||||
const response = await $.http.post('/api/v4/posts', data);
|
||||
|
||||
const actionData = {
|
||||
raw: response?.data,
|
||||
};
|
||||
|
||||
$.setActionItem(actionData);
|
||||
};
|
||||
|
||||
export default postMessage;
|
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="256px" height="256px" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
|
||||
<g>
|
||||
<path d="M6.79123171,86.9648684 C25.2351716,32.4823178 76.783459,-1.43234143 131.421839,0.0464773399 L131.421839,0.0464773399 L113.909757,20.739032 C81.4957329,26.5997669 53.5072568,48.7337413 42.5072761,81.2287969 C26.140539,129.576353 53.572705,182.545803 103.779303,199.543648 C153.985902,216.538377 207.952658,191.12264 224.319395,142.7782 C235.283535,110.390667 226.589826,75.9306053 204.563374,51.5978814 L204.563374,51.5978814 L203.21701,24.4290666 C247.371203,56.4768925 267.622761,114.633895 249.208429,169.029181 C226.546194,235.970273 153.909545,271.865521 86.9684532,249.204844 C20.0273609,226.542609 -15.8694453,153.905961 6.79123171,86.9648684 Z M165.185344,11.9237762 C165.839826,11.6401671 166.594039,11.5793938 167.321762,11.8256038 C168.035459,12.0671391 168.585536,12.5580009 168.936152,13.1595015 L168.936152,13.1595015 L169.007833,13.2763734 L169.071723,13.4103864 C169.240019,13.7313945 169.383381,14.0991514 169.450388,14.5510559 C169.582343,15.4417519 169.641535,17.5358595 169.665634,19.6808502 L169.671365,20.2662434 C169.677102,20.9486534 169.679633,21.6256073 169.680171,22.2599793 L169.680173,22.7924325 C169.678741,24.5267431 169.663874,25.8268542 169.663874,25.8268542 L169.663874,25.8268542 L170.167202,44.7600977 L170.910507,66.6151379 L171.837691,104.59538 C171.837691,104.59538 171.83785,104.602367 171.838064,104.616156 L171.838772,104.677745 C171.838883,104.691349 171.838983,104.706608 171.839058,104.723498 L171.839105,104.844231 C171.832023,107.013302 171.387173,122.892918 160.122454,133.928662 C148.009853,145.795053 133.131285,144.708923 123.451177,141.433394 C113.771069,138.154749 101.293828,129.979951 98.8800345,113.195592 C96.8283098,98.9302108 104.41287,86.9390787 106.734401,83.6627102 L106.889339,83.4459953 C107.205256,83.0081712 107.389865,82.7777388 107.389865,82.7777388 L107.389865,82.7777388 L131.197445,53.1717559 L145.064682,36.2627333 L156.965355,21.5275276 C156.965355,21.5275276 158.715313,19.1834331 160.51647,16.874806 L160.876881,16.4142586 C161.477025,15.6498178 162.070275,14.9069442 162.593713,14.2737698 L162.898895,13.907734 C163.342593,13.3805415 163.71955,12.9564826 163.983901,12.6998055 C164.292443,12.4006135 164.608776,12.205827 164.918876,12.0546727 L164.918876,12.0546727 L165.146386,11.9393591 Z" fill="#0058CC"></path>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.5 KiB |
@@ -1,18 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import { URL, URLSearchParams } from 'url';
|
||||
import getBaseUrl from '../common/get-base-url';
|
||||
|
||||
export default async function generateAuthUrl($: IGlobalVariable) {
|
||||
const searchParams = new URLSearchParams({
|
||||
client_id: $.auth.data.clientId as string,
|
||||
redirect_uri: $.auth.data.oAuthRedirectUrl as string,
|
||||
response_type: 'code',
|
||||
});
|
||||
|
||||
const baseUrl = getBaseUrl($);
|
||||
const path = `/oauth/authorize?${searchParams.toString()}`;
|
||||
|
||||
await $.auth.set({
|
||||
url: new URL(path, baseUrl).toString(),
|
||||
});
|
||||
}
|
@@ -1,57 +0,0 @@
|
||||
import generateAuthUrl from './generate-auth-url';
|
||||
import verifyCredentials from './verify-credentials';
|
||||
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/mattermost/connections/add',
|
||||
placeholder: null,
|
||||
description:
|
||||
'When asked to input an OAuth callback or redirect URL in Mattermost OAuth, enter the URL above.',
|
||||
clickToCopy: true,
|
||||
},
|
||||
{
|
||||
key: 'instanceUrl',
|
||||
label: 'Mattermost instance URL',
|
||||
type: 'string' as const,
|
||||
required: false,
|
||||
readOnly: false,
|
||||
value: null,
|
||||
placeholder: null,
|
||||
description: 'Your Mattermost instance URL',
|
||||
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,
|
||||
};
|
@@ -1,9 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import getCurrentUser from '../common/get-current-user';
|
||||
|
||||
const isStillVerified = async ($: IGlobalVariable) => {
|
||||
const user = await getCurrentUser($);
|
||||
return !!user.id;
|
||||
};
|
||||
|
||||
export default isStillVerified;
|
@@ -1,44 +0,0 @@
|
||||
import { IGlobalVariable } from '@automatisch/types';
|
||||
import getCurrentUser from '../common/get-current-user';
|
||||
|
||||
const verifyCredentials = async ($: IGlobalVariable) => {
|
||||
const oauthRedirectUrlField = $.app.auth.fields.find(
|
||||
(field) => field.key == 'oAuthRedirectUrl'
|
||||
);
|
||||
const redirectUri = oauthRedirectUrlField.value as string;
|
||||
const params = {
|
||||
client_id: $.auth.data.clientId,
|
||||
client_secret: $.auth.data.clientSecret,
|
||||
code: $.auth.data.code,
|
||||
grant_type: 'authorization_code',
|
||||
redirect_uri: redirectUri,
|
||||
};
|
||||
const headers = {
|
||||
'Content-Type': 'application/x-www-form-urlencoded', // This is not documented yet required
|
||||
};
|
||||
const response = await $.http.post('/oauth/access_token', null, {
|
||||
params,
|
||||
headers,
|
||||
});
|
||||
|
||||
const {
|
||||
data: { access_token, refresh_token, scope, token_type },
|
||||
} = response;
|
||||
|
||||
$.auth.data.accessToken = response.data.access_token;
|
||||
|
||||
const currentUser = await getCurrentUser($);
|
||||
|
||||
await $.auth.set({
|
||||
clientId: $.auth.data.clientId,
|
||||
clientSecret: $.auth.data.clientSecret,
|
||||
accessToken: access_token,
|
||||
refreshToken: refresh_token,
|
||||
scope: scope,
|
||||
tokenType: token_type,
|
||||
userId: currentUser.id,
|
||||
screenName: currentUser.username,
|
||||
});
|
||||
};
|
||||
|
||||
export default verifyCredentials;
|
@@ -1,12 +0,0 @@
|
||||
import { TBeforeRequest } from '@automatisch/types';
|
||||
|
||||
const addAuthHeader: TBeforeRequest = ($, requestConfig) => {
|
||||
if ($.auth.data?.accessToken) {
|
||||
requestConfig.headers = requestConfig.headers || {};
|
||||
requestConfig.headers.Authorization = `Bearer ${$.auth.data.accessToken}`;
|
||||
}
|
||||
|
||||
return requestConfig;
|
||||
};
|
||||
|
||||
export default addAuthHeader;
|
@@ -1,11 +0,0 @@
|
||||
import { TBeforeRequest } from '@automatisch/types';
|
||||
|
||||
const addXRequestedWithHeader: TBeforeRequest = ($, requestConfig) => {
|
||||
// This is not documented yet required
|
||||
// ref. https://forum.mattermost.com/t/solved-invalid-or-expired-session-please-login-again/6772
|
||||
requestConfig.headers = requestConfig.headers || {};
|
||||
requestConfig.headers['X-Requested-With'] = `XMLHttpRequest`;
|
||||
return requestConfig;
|
||||
};
|
||||
|
||||
export default addXRequestedWithHeader;
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user