Compare commits

..

6 Commits

Author SHA1 Message Date
Faruk AYDIN
caffea49ce docs: Add postgres schema to the environment variables 2023-04-17 14:52:19 +02:00
Faruk AYDIN
272bd9dc62 feat: Use postgres schema instead of database schema 2023-04-17 14:52:19 +02:00
Faruk AYDIN
a4e7824109 chore: No need to specify schema in .env-example file 2023-04-17 14:52:19 +02:00
Shehab Ghazy
5ed7fc8b7c Update .env-example 2023-04-17 14:52:19 +02:00
Shehab Ghazy
c4d4b2a2a8 Update knexfile.ts 2023-04-17 14:52:19 +02:00
Shehab Ghazy
47212c37c2 honor schema from env 2023-04-17 14:52:19 +02:00
674 changed files with 2460 additions and 20945 deletions

View File

@@ -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

View File

@@ -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:

View File

@@ -1,8 +0,0 @@
**/node_modules/
**/dist/
**/logs/
**/.devcontainer
**/.github
**/.vscode
packages/docs
packages/e2e-test

View File

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

View File

@@ -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

3
.gitignore vendored
View File

@@ -125,6 +125,3 @@ dist
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
# MacOS finder preferences
.DS_store

View File

@@ -1 +0,0 @@
16.15.0

1
.nvmrc
View File

@@ -1 +0,0 @@
16.15.0

View File

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

View File

@@ -1,5 +1,5 @@
The Automatisch Enterprise license (the “Enterprise License”)
Copyright (c) 2023-present AB Software GmbH.
Copyright (c) 2023 Ömer Faruk Aydın, Ali Barın.
With regard to the Automatisch Software:

View File

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

View File

@@ -1,19 +0,0 @@
# syntax=docker/dockerfile:1
FROM node:16-alpine
WORKDIR /automatisch
ENV PORT 3000
RUN ls -lna
# copy the app, note .dockerignore
COPY . ./
RUN yarn
RUN yarn lerna bootstrap
RUN yarn lerna run --scope=@*/{web,backend,cli} build
COPY ./docker/entrypoint-cloud.sh /entrypoint-cloud.sh
EXPOSE 3000
ENTRYPOINT ["sh", "/entrypoint-cloud.sh"]

View File

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

View File

@@ -1,9 +0,0 @@
#!/bin/sh
set -e
if [ -n "$WORKER" ]; then
yarn automatisch start-worker
else
yarn automatisch start
fi

View File

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

View File

@@ -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

View File

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

View File

@@ -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 {

View File

@@ -12,7 +12,6 @@ const knexConfig = {
database: appConfig.postgresDatabase,
ssl: appConfig.postgresEnableSsl,
},
asyncStackTraces: appConfig.isDev,
searchPath: [appConfig.postgresSchema],
pool: { min: 0, max: 20 },
migrations: {

View File

@@ -1,16 +1,15 @@
{
"name": "@automatisch/backend",
"version": "0.9.3",
"version": "0.5.0",
"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",
@@ -18,25 +17,19 @@
"db:migration:create": "knex migrate:make",
"db:rollback": "knex migrate:rollback",
"db:migrate": "knex migrate:latest",
"copy-statics": "copyfiles src/**/*.{graphql,json,svg,hbs} dist",
"copy-statics": "copyfiles src/**/*.{graphql,json,svg} dist",
"prepack": "yarn build",
"prebuild": "rm -rf ./dist"
},
"dependencies": {
"@automatisch/web": "^0.9.3",
"@automatisch/web": "^0.5.0",
"@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.5.0",
"@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"
}

View File

@@ -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);

View File

@@ -2,7 +2,7 @@ import qs from 'qs';
import defineAction from '../../../../helpers/define-action';
export default defineAction({
name: 'Translate text',
name: 'Translate Text',
key: 'translateText',
description: 'Translates text from one language to another.',
arguments: [
@@ -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' },

View File

@@ -1,7 +1,7 @@
import defineAction from '../../../../helpers/define-action';
export default defineAction({
name: 'Delay for',
name: 'Delay For',
key: 'delayFor',
description:
'Delays the execution of the next action by a specified amount of time.',
@@ -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',

View File

@@ -1,7 +1,7 @@
import defineAction from '../../../../helpers/define-action';
export default defineAction({
name: 'Delay until',
name: 'Delay Until',
key: 'delayUntil',
description:
'Delays the execution of the next action until a specified date.',

View File

@@ -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',

View File

@@ -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 {

View File

@@ -10,7 +10,7 @@ type TGroupItem = {
type TGroup = Record<'and', TGroupItem[]>;
const isEqual = (a: string, b: string) => a === b;
const isNotEqual = (a: string, b: string) => !isEqual(a, b);
const isNotEqual = (a: string, b: string) => !isEqual(a, b)
const isGreaterThan = (a: string, b: string) => Number(a) > Number(b);
const isLessThan = (a: string, b: string) => Number(a) < Number(b);
const isGreaterThanOrEqual = (a: string, b: string) => Number(a) >= Number(b);
@@ -18,36 +18,6 @@ const isLessThanOrEqual = (a: string, b: string) => Number(a) <= Number(b);
const contains = (a: string, b: string) => a.includes(b);
const doesNotContain = (a: string, b: string) => !contains(a, b);
const shouldContinue = (orGroups: TGroup[]) => {
let atLeastOneGroupMatches = false;
for (const group of orGroups) {
let groupMatches = true;
for (const condition of group.and) {
const conditionMatches = operate(
condition.operator,
condition.key,
condition.value
);
if (!conditionMatches) {
groupMatches = false;
break;
}
}
if (groupMatches) {
atLeastOneGroupMatches = true;
break;
}
}
return atLeastOneGroupMatches;
}
type TOperatorFunc = (a: string, b: string) => boolean;
type TOperators = {
@@ -96,7 +66,7 @@ export default defineAction({
return groups;
}, []);
if (!shouldContinue(orGroups)) {
if (matchingGroups.length === 0) {
$.execution.exit();
}

View File

@@ -20,14 +20,12 @@ export default defineTrigger({
],
async testRun($) {
const lastExecutionStep = await $.getLastExecutionStep();
if (!isEmpty(lastExecutionStep?.dataOut)) {
if (!isEmpty($.lastExecutionStep?.dataOut)) {
$.pushTriggerItem({
raw: lastExecutionStep.dataOut,
raw: $.lastExecutionStep.dataOut,
meta: {
internalId: '',
},
}
});
}
},
@@ -37,15 +35,20 @@ export default defineTrigger({
name: $.flow.id,
type: 'POST',
url: $.webhookUrl,
filters: [$.step.parameters.filters],
filters: [$.step.parameters.filters]
};
const { data } = await $.http.post(`/v2/public/api/webhooks`, payload);
const { data } = await $.http.post(
`/v2/public/api/webhooks`,
payload
);
await $.flow.setRemoteWebhookId(data.id);
},
async unregisterHook($) {
await $.http.delete(`/v2/public/api/webhooks/${$.flow.remoteWebhookId}`);
await $.http.delete(
`/v2/public/api/webhooks/${$.flow.remoteWebhookId}`
);
},
});

View File

@@ -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,
},
});
},
});

View File

@@ -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;

View File

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

View File

@@ -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,
},
});
},
});

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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,
},
});
},
});

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -1,3 +0,0 @@
import listTransformOptions from './list-transform-options';
export default [listTransformOptions];

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -1,41 +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 htmlToMarkdown from './text/html-to-markdown';
import lowercase from './text/lowercase';
import markdownToHtml from './text/markdown-to-html';
import pluralize from './text/pluralize';
import replace from './text/replace';
import trimWhitespace from './text/trim-whitespace';
import useDefaultValue from './text/use-default-value';
import performMathOperation from './numbers/perform-math-operation';
import randomNumber from './numbers/random-number';
import formatNumber from './numbers/format-number';
import formatDateTime from './date-time/format-date-time';
const options: IJSONObject = {
capitalize,
extractEmailAddress,
extractNumber,
htmlToMarkdown,
lowercase,
markdownToHtml,
pluralize,
replace,
trimWhitespace,
useDefaultValue,
performMathOperation,
randomNumber,
formatNumber,
formatDateTime,
};
export default {
name: 'List fields after transform',
key: 'listTransformOptions',
async run($: IGlobalVariable) {
return options[$.step.parameters.transform as string];
},
};

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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,
});

View File

@@ -11,7 +11,7 @@ export default defineAction({
key: 'repo',
type: 'dropdown' as const,
required: false,
variables: true,
variables: false,
source: {
type: 'query',
name: 'getDynamicData',

View File

@@ -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',

View File

@@ -1,2 +0,0 @@
<!-- https://about.gitlab.com/images/press/logo/svg/gitlab-logo-500.svg -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 380 380"><defs><style>.cls-1{fill:#e24329;}.cls-2{fill:#fc6d26;}.cls-3{fill:#fca326;}</style></defs><g id="LOGO"><path class="cls-1" d="M282.83,170.73l-.27-.69-26.14-68.22a6.81,6.81,0,0,0-2.69-3.24,7,7,0,0,0-8,.43,7,7,0,0,0-2.32,3.52l-17.65,54H154.29l-17.65-54A6.86,6.86,0,0,0,134.32,99a7,7,0,0,0-8-.43,6.87,6.87,0,0,0-2.69,3.24L97.44,170l-.26.69a48.54,48.54,0,0,0,16.1,56.1l.09.07.24.17,39.82,29.82,19.7,14.91,12,9.06a8.07,8.07,0,0,0,9.76,0l12-9.06,19.7-14.91,40.06-30,.1-.08A48.56,48.56,0,0,0,282.83,170.73Z"/><path class="cls-2" d="M282.83,170.73l-.27-.69a88.3,88.3,0,0,0-35.15,15.8L190,229.25c19.55,14.79,36.57,27.64,36.57,27.64l40.06-30,.1-.08A48.56,48.56,0,0,0,282.83,170.73Z"/><path class="cls-3" d="M153.43,256.89l19.7,14.91,12,9.06a8.07,8.07,0,0,0,9.76,0l12-9.06,19.7-14.91S209.55,244,190,229.25C170.45,244,153.43,256.89,153.43,256.89Z"/><path class="cls-2" d="M132.58,185.84A88.19,88.19,0,0,0,97.44,170l-.26.69a48.54,48.54,0,0,0,16.1,56.1l.09.07.24.17,39.82,29.82s17-12.85,36.57-27.64Z"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,24 +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) {
// ref: https://docs.gitlab.com/ee/api/oauth2.html#authorization-code-flow
const scopes = ['api', 'read_user'];
const searchParams = new URLSearchParams({
client_id: $.auth.data.clientId as string,
redirect_uri: $.auth.data.oAuthRedirectUrl as string,
scope: scopes.join(' '),
response_type: 'code',
state: Date.now().toString(),
});
const baseUrl = getBaseUrl($);
const path = `/oauth/authorize?${searchParams.toString()}`;
await $.auth.set({
url: new URL(path, baseUrl).toString(),
});
}

View File

@@ -1,63 +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/gitlab/connections/add',
placeholder: null,
description:
'When asked to input an OAuth callback or redirect URL in Gitlab OAuth, enter the URL above.',
docUrl: 'https://automatisch.io/docs/gitlab#oauth-redirect-url',
clickToCopy: true,
},
{
key: 'instanceUrl',
label: 'Gitlab instance URL',
type: 'string' as const,
required: false,
readOnly: false,
value: 'https://gitlab.com',
placeholder: 'https://gitlab.com',
description: 'Your Gitlab instance URL. Default is https://gitlab.com.',
docUrl: 'https://automatisch.io/docs/gitlab#oauth-redirect-url',
clickToCopy: true,
},
{
key: 'clientId',
label: 'Client ID',
type: 'string' as const,
required: true,
readOnly: false,
value: null,
placeholder: null,
description: null,
docUrl: 'https://automatisch.io/docs/gitlab#client-id',
clickToCopy: false,
},
{
key: 'clientSecret',
label: 'Client Secret',
type: 'string' as const,
required: true,
readOnly: false,
value: null,
placeholder: null,
description: null,
docUrl: 'https://automatisch.io/docs/gitlab#client-secret',
clickToCopy: false,
},
],
generateAuthUrl,
refreshToken,
verifyCredentials,
isStillVerified,
};

View File

@@ -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;

View File

@@ -1,24 +0,0 @@
import { IGlobalVariable } from '@automatisch/types';
import { URLSearchParams } from 'url';
const refreshToken = async ($: IGlobalVariable) => {
// ref: https://docs.gitlab.com/ee/api/oauth2.html#authorization-code-flow
const params = new URLSearchParams({
grant_type: 'refresh_token',
client_id: $.auth.data.clientId as string,
client_secret: $.auth.data.clientSecret as string,
refresh_token: $.auth.data.refreshToken as string,
});
const { data } = await $.http.post('/oauth/token', params.toString());
await $.auth.set({
accessToken: data.access_token,
expiresIn: data.expires_in,
tokenType: data.token_type,
refreshToken: data.refresh_token,
});
};
export default refreshToken;

View File

@@ -1,47 +0,0 @@
import { IGlobalVariable } from '@automatisch/types';
import getCurrentUser from '../common/get-current-user';
const verifyCredentials = async ($: IGlobalVariable) => {
// ref: https://docs.gitlab.com/ee/api/oauth2.html#authorization-code-flow
const response = await $.http.post(
'/oauth/token',
{
client_id: $.auth.data.clientId,
client_secret: $.auth.data.clientSecret,
code: $.auth.data.code,
grant_type: 'authorization_code',
redirect_uri: $.auth.data.oAuthRedirectUrl,
},
{
headers: {
Accept: 'application/json',
},
}
);
const data = response.data;
$.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,
clientSecret: $.auth.data.clientSecret,
accessToken: data.access_token,
refreshToken: data.refresh_token,
scope: data.scope,
tokenType: data.token_type,
userId: currentUser.id,
screenName,
});
};
export default verifyCredentials;

View File

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

View File

@@ -1,15 +0,0 @@
import { IGlobalVariable } from '@automatisch/types';
const getBaseUrl = ($: IGlobalVariable): string => {
if ($.auth.data.instanceUrl) {
return $.auth.data.instanceUrl as string;
}
if ($.app.apiBaseUrl) {
return $.app.apiBaseUrl;
}
return $.app.baseUrl;
};
export default getBaseUrl;

View File

@@ -1,11 +0,0 @@
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
const getCurrentUser = async ($: IGlobalVariable): Promise<IJSONObject> => {
// ref: https://docs.gitlab.com/ee/api/users.html#list-current-user
const response = await $.http.get('/api/v4/user');
const currentUser = response.data;
return currentUser;
};
export default getCurrentUser;

View File

@@ -1,33 +0,0 @@
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
import type { AxiosResponse } from 'axios';
import parseLinkHeader from '../../../helpers/parse-header-link';
type TResponse = {
data: IJSONObject[];
error?: IJSONObject;
};
export default async function paginateAll(
$: IGlobalVariable,
request: Promise<AxiosResponse>
) {
const response = await request;
const aggregatedResponse: TResponse = {
data: [...response.data],
};
let links = parseLinkHeader(response.headers.link);
while (links.next) {
const nextPageResponse = await $.http.request({
...response.config,
url: links.next.uri,
});
aggregatedResponse.data.push(...nextPageResponse.data);
links = parseLinkHeader(nextPageResponse.headers.link);
}
return aggregatedResponse;
}

View File

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

View File

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

View File

@@ -1,33 +0,0 @@
import { IGlobalVariable } from '@automatisch/types';
import paginateAll from '../../common/paginate-all';
export default {
name: 'List projects',
key: 'listProjects',
async run($: IGlobalVariable) {
// 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',
},
});
const response = await paginateAll($, firstPageRequest);
response.data = response.data.map((repo: { name: string; id: number }) => {
return {
value: repo.id,
name: repo.name,
};
});
return response;
},
};

View File

@@ -1 +0,0 @@

View File

@@ -1,21 +0,0 @@
import defineApp from '../../helpers/define-app';
import addAuthHeader from './common/add-auth-header';
import setBaseUrl from './common/set-base-url';
import auth from './auth';
import triggers from './triggers';
import dynamicData from './dynamic-data';
export default defineApp({
name: 'GitLab',
key: 'gitlab',
baseUrl: 'https://gitlab.com',
apiBaseUrl: 'https://gitlab.com',
iconUrl: '{BASE_URL}/apps/gitlab/assets/favicon.svg',
authDocUrl: 'https://automatisch.io/docs/apps/gitlab/connection',
primaryColor: 'FC6D26',
supportsConnections: true,
beforeRequest: [setBaseUrl, addAuthHeader],
auth,
triggers,
dynamicData,
});

View File

@@ -1,27 +0,0 @@
import { IRawTrigger } from '@automatisch/types';
import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
} from '../lib';
// confidential_issues_events has the same event data as issues_events
import data from './issue_event';
export const triggerDescriptor: IRawTrigger = {
name: 'Confidential issue event',
description:
'Confidential issue event (triggered when a new confidential issue is created or an existing issue is updated, closed, or reopened)',
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#issue-events',
key: GITLAB_EVENT_TYPE.confidential_issues_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.confidential_issues_events),
unregisterHook,
};
export default defineTrigger(triggerDescriptor);

View File

@@ -1,159 +0,0 @@
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#issue-events
export default {
object_kind: 'issue',
event_type: 'issue',
user: {
id: 1,
name: 'Administrator',
username: 'root',
avatar_url:
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
email: 'admin@example.com',
},
project: {
id: 1,
name: 'Gitlab Test',
description: 'Aut reprehenderit ut est.',
web_url: 'http://example.com/gitlabhq/gitlab-test',
avatar_url: null,
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
namespace: 'GitlabHQ',
visibility_level: 20,
path_with_namespace: 'gitlabhq/gitlab-test',
default_branch: 'master',
ci_config_path: null,
homepage: 'http://example.com/gitlabhq/gitlab-test',
url: 'http://example.com/gitlabhq/gitlab-test.git',
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
},
object_attributes: {
id: 301,
title: 'New API: create/update/delete file',
assignee_ids: [51],
assignee_id: 51,
author_id: 51,
project_id: 14,
created_at: '2013-12-03T17:15:43Z',
updated_at: '2013-12-03T17:15:43Z',
updated_by_id: 1,
last_edited_at: null,
last_edited_by_id: null,
relative_position: 0,
description: 'Create new API for manipulations with repository',
milestone_id: null,
state_id: 1,
confidential: false,
discussion_locked: true,
due_date: null,
moved_to_id: null,
duplicated_to_id: null,
time_estimate: 0,
total_time_spent: 0,
time_change: 0,
human_total_time_spent: null,
human_time_estimate: null,
human_time_change: null,
weight: null,
iid: 23,
url: 'http://example.com/diaspora/issues/23',
state: 'opened',
action: 'open',
severity: 'high',
escalation_status: 'triggered',
escalation_policy: {
id: 18,
name: 'Engineering On-call',
},
labels: [
{
id: 206,
title: 'API',
color: '#ffffff',
project_id: 14,
created_at: '2013-12-03T17:15:43Z',
updated_at: '2013-12-03T17:15:43Z',
template: false,
description: 'API related issues',
type: 'ProjectLabel',
group_id: 41,
},
],
},
repository: {
name: 'Gitlab Test',
url: 'http://example.com/gitlabhq/gitlab-test.git',
description: 'Aut reprehenderit ut est.',
homepage: 'http://example.com/gitlabhq/gitlab-test',
},
assignees: [
{
name: 'User1',
username: 'user1',
avatar_url:
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
},
],
assignee: {
name: 'User1',
username: 'user1',
avatar_url:
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
},
labels: [
{
id: 206,
title: 'API',
color: '#ffffff',
project_id: 14,
created_at: '2013-12-03T17:15:43Z',
updated_at: '2013-12-03T17:15:43Z',
template: false,
description: 'API related issues',
type: 'ProjectLabel',
group_id: 41,
},
],
changes: {
updated_by_id: {
previous: null,
current: 1,
},
updated_at: {
previous: '2017-09-15 16:50:55 UTC',
current: '2017-09-15 16:52:00 UTC',
},
labels: {
previous: [
{
id: 206,
title: 'API',
color: '#ffffff',
project_id: 14,
created_at: '2013-12-03T17:15:43Z',
updated_at: '2013-12-03T17:15:43Z',
template: false,
description: 'API related issues',
type: 'ProjectLabel',
group_id: 41,
},
],
current: [
{
id: 205,
title: 'Platform',
color: '#123123',
project_id: 14,
created_at: '2013-12-03T17:15:43Z',
updated_at: '2013-12-03T17:15:43Z',
template: false,
description: 'Platform related issues',
type: 'ProjectLabel',
group_id: 41,
},
],
},
},
};

View File

@@ -1,27 +0,0 @@
import { IRawTrigger } from '@automatisch/types';
import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
} from '../lib';
// confidential_note_events has the same event data as note_events
import data from './note_event';
export const triggerDescriptor: IRawTrigger = {
name: 'Confidential comment event',
description:
'Confidential comment event (triggered when a new confidential comment is made on commits, merge requests, issues, and code snippets)',
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#comment-events',
key: GITLAB_EVENT_TYPE.confidential_note_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.confidential_note_events),
unregisterHook,
};
export default defineTrigger(triggerDescriptor);

View File

@@ -1,74 +0,0 @@
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#comment-events
export default {
object_kind: 'note',
event_type: 'note',
user: {
id: 1,
name: 'Administrator',
username: 'root',
avatar_url:
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
email: 'admin@example.com',
},
project_id: 5,
project: {
id: 5,
name: 'Gitlab Test',
description: 'Aut reprehenderit ut est.',
web_url: 'http://example.com/gitlabhq/gitlab-test',
avatar_url: null,
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
namespace: 'GitlabHQ',
visibility_level: 20,
path_with_namespace: 'gitlabhq/gitlab-test',
default_branch: 'master',
homepage: 'http://example.com/gitlabhq/gitlab-test',
url: 'http://example.com/gitlabhq/gitlab-test.git',
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
},
repository: {
name: 'Gitlab Test',
url: 'http://example.com/gitlab-org/gitlab-test.git',
description: 'Aut reprehenderit ut est.',
homepage: 'http://example.com/gitlab-org/gitlab-test',
},
object_attributes: {
id: 1243,
note: 'This is a commit comment. How does this work?',
noteable_type: 'Commit',
author_id: 1,
created_at: '2015-05-17 18:08:09 UTC',
updated_at: '2015-05-17 18:08:09 UTC',
project_id: 5,
attachment: null,
line_code: 'bec9703f7a456cd2b4ab5fb3220ae016e3e394e3_0_1',
commit_id: 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660',
noteable_id: null,
system: false,
st_diff: {
diff: '--- /dev/null\n+++ b/six\n@@ -0,0 +1 @@\n+Subproject commit 409f37c4f05865e4fb208c771485f211a22c4c2d\n',
new_path: 'six',
old_path: 'six',
a_mode: '0',
b_mode: '160000',
new_file: true,
renamed_file: false,
deleted_file: false,
},
url: 'http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660#note_1243',
},
commit: {
id: 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660',
message:
'Add submodule\n\nSigned-off-by: Example User \u003cuser@example.com.com\u003e\n',
timestamp: '2014-02-27T10:06:20+02:00',
url: 'http://example.com/gitlab-org/gitlab-test/commit/cfe32cf61b73a0d5e9f13e774abde7ff789b1660',
author: {
name: 'Example User',
email: 'user@example.com',
},
},
};

View File

@@ -1,45 +0,0 @@
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#deployment-events
export default {
object_kind: 'deployment',
status: 'success',
status_changed_at: '2021-04-28 21:50:00 +0200',
deployment_id: 15,
deployable_id: 796,
deployable_url:
'http://10.126.0.2:3000/root/test-deployment-webhooks/-/jobs/796',
environment: 'staging',
environment_slug: 'staging',
environment_external_url: 'https://staging.example.com',
project: {
id: 30,
name: 'test-deployment-webhooks',
description: '',
web_url: 'http://10.126.0.2:3000/root/test-deployment-webhooks',
avatar_url: null,
git_ssh_url: 'ssh://vlad@10.126.0.2:2222/root/test-deployment-webhooks.git',
git_http_url: 'http://10.126.0.2:3000/root/test-deployment-webhooks.git',
namespace: 'Administrator',
visibility_level: 0,
path_with_namespace: 'root/test-deployment-webhooks',
default_branch: 'master',
ci_config_path: '',
homepage: 'http://10.126.0.2:3000/root/test-deployment-webhooks',
url: 'ssh://vlad@10.126.0.2:2222/root/test-deployment-webhooks.git',
ssh_url: 'ssh://vlad@10.126.0.2:2222/root/test-deployment-webhooks.git',
http_url: 'http://10.126.0.2:3000/root/test-deployment-webhooks.git',
},
short_sha: '279484c0',
user: {
id: 1,
name: 'Administrator',
username: 'root',
avatar_url:
'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
email: 'admin@example.com',
},
user_url: 'http://10.126.0.2:3000/root',
commit_url:
'http://10.126.0.2:3000/root/test-deployment-webhooks/-/commit/279484c09fbe69ededfced8c1bb6e6d24616b468',
commit_title: 'Add new file',
};

View File

@@ -1,26 +0,0 @@
import { IRawTrigger } from '@automatisch/types';
import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
} from '../lib';
import data from './deployment_event';
export const triggerDescriptor: IRawTrigger = {
name: 'Deployment event',
description:
'Deployment event (triggered when a deployment starts, succeeds, fails or is canceled)',
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#deployment-events',
key: GITLAB_EVENT_TYPE.deployment_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.deployment_events),
unregisterHook,
};
export default defineTrigger(triggerDescriptor);

View File

@@ -1,38 +0,0 @@
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#feature-flag-events
export default {
object_kind: 'feature_flag',
project: {
id: 1,
name: 'Gitlab Test',
description: 'Aut reprehenderit ut est.',
web_url: 'http://example.com/gitlabhq/gitlab-test',
avatar_url: null,
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
namespace: 'GitlabHQ',
visibility_level: 20,
path_with_namespace: 'gitlabhq/gitlab-test',
default_branch: 'master',
ci_config_path: null,
homepage: 'http://example.com/gitlabhq/gitlab-test',
url: 'http://example.com/gitlabhq/gitlab-test.git',
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
},
user: {
id: 1,
name: 'Administrator',
username: 'root',
avatar_url:
'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
email: 'admin@example.com',
},
user_url: 'http://example.com/root',
object_attributes: {
id: 6,
name: 'test-feature-flag',
description: 'test-feature-flag-description',
active: true,
},
};

View File

@@ -1,26 +0,0 @@
import { IRawTrigger } from '@automatisch/types';
import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
} from '../lib';
import data from './feature_flag_event';
export const triggerDescriptor: IRawTrigger = {
name: 'Feature flag event',
description:
'Feature flag event (triggered when a feature flag is turned on or off)',
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#feature-flag-events',
key: GITLAB_EVENT_TYPE.feature_flag_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.feature_flag_events),
unregisterHook,
};
export default defineTrigger(triggerDescriptor);

View File

@@ -1,29 +0,0 @@
import confidentialIssueEvent from './confidential-issue-event';
import confidentialNoteEvent from './confidential-note-event';
import deploymentEvent from './deployment-event';
import featureFlagEvent from './feature-flag-event';
import issueEvent from './issue-event';
import jobEvent from './job-event';
import mergeRequestEvent from './merge-request-event';
import noteEvent from './note-event';
import pipelineEvent from './pipeline-event';
import pushEvent from './push-event';
import releaseEvent from './release-event';
import tagPushEvent from './tag-push-event';
import wikiPageEvent from './wiki-page-event';
export default [
confidentialIssueEvent,
confidentialNoteEvent,
deploymentEvent,
featureFlagEvent,
issueEvent,
jobEvent,
mergeRequestEvent,
noteEvent,
pipelineEvent,
pushEvent,
releaseEvent,
tagPushEvent,
wikiPageEvent,
];

View File

@@ -1,26 +0,0 @@
import { IRawTrigger } from '@automatisch/types';
import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
} from '../lib';
import data from './issue_event';
export const triggerDescriptor: IRawTrigger = {
name: 'Issue event',
description:
'Issue event (triggered when a new issue is created or an existing issue is updated, closed, or reopened)',
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#issue-events',
key: GITLAB_EVENT_TYPE.issues_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.issues_events),
unregisterHook,
};
export default defineTrigger(triggerDescriptor);

View File

@@ -1,159 +0,0 @@
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#issue-events
export default {
object_kind: 'issue',
event_type: 'issue',
user: {
id: 1,
name: 'Administrator',
username: 'root',
avatar_url:
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
email: 'admin@example.com',
},
project: {
id: 1,
name: 'Gitlab Test',
description: 'Aut reprehenderit ut est.',
web_url: 'http://example.com/gitlabhq/gitlab-test',
avatar_url: null,
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
namespace: 'GitlabHQ',
visibility_level: 20,
path_with_namespace: 'gitlabhq/gitlab-test',
default_branch: 'master',
ci_config_path: null,
homepage: 'http://example.com/gitlabhq/gitlab-test',
url: 'http://example.com/gitlabhq/gitlab-test.git',
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
},
object_attributes: {
id: 301,
title: 'New API: create/update/delete file',
assignee_ids: [51],
assignee_id: 51,
author_id: 51,
project_id: 14,
created_at: '2013-12-03T17:15:43Z',
updated_at: '2013-12-03T17:15:43Z',
updated_by_id: 1,
last_edited_at: null,
last_edited_by_id: null,
relative_position: 0,
description: 'Create new API for manipulations with repository',
milestone_id: null,
state_id: 1,
confidential: false,
discussion_locked: true,
due_date: null,
moved_to_id: null,
duplicated_to_id: null,
time_estimate: 0,
total_time_spent: 0,
time_change: 0,
human_total_time_spent: null,
human_time_estimate: null,
human_time_change: null,
weight: null,
iid: 23,
url: 'http://example.com/diaspora/issues/23',
state: 'opened',
action: 'open',
severity: 'high',
escalation_status: 'triggered',
escalation_policy: {
id: 18,
name: 'Engineering On-call',
},
labels: [
{
id: 206,
title: 'API',
color: '#ffffff',
project_id: 14,
created_at: '2013-12-03T17:15:43Z',
updated_at: '2013-12-03T17:15:43Z',
template: false,
description: 'API related issues',
type: 'ProjectLabel',
group_id: 41,
},
],
},
repository: {
name: 'Gitlab Test',
url: 'http://example.com/gitlabhq/gitlab-test.git',
description: 'Aut reprehenderit ut est.',
homepage: 'http://example.com/gitlabhq/gitlab-test',
},
assignees: [
{
name: 'User1',
username: 'user1',
avatar_url:
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
},
],
assignee: {
name: 'User1',
username: 'user1',
avatar_url:
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
},
labels: [
{
id: 206,
title: 'API',
color: '#ffffff',
project_id: 14,
created_at: '2013-12-03T17:15:43Z',
updated_at: '2013-12-03T17:15:43Z',
template: false,
description: 'API related issues',
type: 'ProjectLabel',
group_id: 41,
},
],
changes: {
updated_by_id: {
previous: null,
current: 1,
},
updated_at: {
previous: '2017-09-15 16:50:55 UTC',
current: '2017-09-15 16:52:00 UTC',
},
labels: {
previous: [
{
id: 206,
title: 'API',
color: '#ffffff',
project_id: 14,
created_at: '2013-12-03T17:15:43Z',
updated_at: '2013-12-03T17:15:43Z',
template: false,
description: 'API related issues',
type: 'ProjectLabel',
group_id: 41,
},
],
current: [
{
id: 205,
title: 'Platform',
color: '#123123',
project_id: 14,
created_at: '2013-12-03T17:15:43Z',
updated_at: '2013-12-03T17:15:43Z',
template: false,
description: 'Platform related issues',
type: 'ProjectLabel',
group_id: 41,
},
],
},
},
};

View File

@@ -1,25 +0,0 @@
import { IRawTrigger } from '@automatisch/types';
import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
} from '../lib';
import data from './job_event';
export const triggerDescriptor: IRawTrigger = {
name: 'Job event',
description: 'Job event (triggered when the status of a job changes)',
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#job-events',
key: GITLAB_EVENT_TYPE.job_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.job_events),
unregisterHook,
};
export default defineTrigger(triggerDescriptor);

View File

@@ -1,60 +0,0 @@
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#job-events
export default {
object_kind: 'build',
ref: 'gitlab-script-trigger',
tag: false,
before_sha: '2293ada6b400935a1378653304eaf6221e0fdb8f',
sha: '2293ada6b400935a1378653304eaf6221e0fdb8f',
build_id: 1977,
build_name: 'test',
build_stage: 'test',
build_status: 'created',
build_created_at: '2021-02-23T02:41:37.886Z',
build_started_at: null,
build_finished_at: null,
build_duration: null,
build_queued_duration: 1095.588715, // duration in seconds
build_allow_failure: false,
build_failure_reason: 'script_failure',
retries_count: 2, // the second retry of this job
pipeline_id: 2366,
project_id: 380,
project_name: 'gitlab-org/gitlab-test',
user: {
id: 3,
name: 'User',
email: 'user@gitlab.com',
avatar_url:
'http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon',
},
commit: {
id: 2366,
name: 'Build pipeline',
sha: '2293ada6b400935a1378653304eaf6221e0fdb8f',
message: 'test\n',
author_name: 'User',
author_email: 'user@gitlab.com',
status: 'created',
duration: null,
started_at: null,
finished_at: null,
},
repository: {
name: 'gitlab_test',
description: 'Atque in sunt eos similique dolores voluptatem.',
homepage: 'http://192.168.64.1:3005/gitlab-org/gitlab-test',
git_ssh_url: 'git@192.168.64.1:gitlab-org/gitlab-test.git',
git_http_url: 'http://192.168.64.1:3005/gitlab-org/gitlab-test.git',
visibility_level: 20,
},
runner: {
active: true,
runner_type: 'project_type',
is_shared: false,
id: 380987,
description: 'shared-runners-manager-6.gitlab.com',
tags: ['linux', 'docker'],
},
environment: null,
};

View File

@@ -1,89 +0,0 @@
import { IGlobalVariable, IJSONObject } from '@automatisch/types';
import Crypto from 'crypto';
import { GITLAB_EVENT_TYPE } from './types';
import appConfig from '../../../config/app';
export const projectArgumentDescriptor = {
label: 'Project',
key: 'projectId',
type: 'dropdown' as const,
required: true,
description: 'Pick a project to receive events from',
variables: false,
source: {
type: 'query',
name: 'getDynamicData',
arguments: [
{
name: 'key',
value: 'listProjects',
},
],
},
};
export const getTestRunFn =
(eventData: IJSONObject) => ($: IGlobalVariable) => {
/*
Not fetching actual events from gitlab and using static event data from documentation
as there is no way to filter out events of one category using gitlab event types,
filtering is very limited and uses different grouping than what is applicable when creating a webhook.
ref:
- https://docs.gitlab.com/ee/api/events.html#target-types
- https://docs.gitlab.com/ee/api/projects.html#add-project-hook
*/
if (!eventData) {
return;
}
const dataItem = {
raw: eventData,
meta: {
// there is no distinct id on gitlab event object thus creating it
internalId: Crypto.randomUUID(),
},
};
$.pushTriggerItem(dataItem);
return Promise.resolve();
};
export const getRegisterHookFn =
(eventType: GITLAB_EVENT_TYPE) => async ($: IGlobalVariable) => {
// ref: https://docs.gitlab.com/ee/api/projects.html#add-project-hook
const subscriptionPayload = {
url: $.webhookUrl,
token: appConfig.webhookSecretKey,
enable_ssl_verification: true,
[eventType]: true,
};
if (
['wildcard', 'regex'].includes(
$.step.parameters.branch_filter_strategy as string
)
) {
subscriptionPayload.branch_filter_strategy = $.step.parameters
.branch_filter_strategy as string;
subscriptionPayload.push_events_branch_filter = $.step.parameters
.push_events_branch_filter as string;
}
const { data } = await $.http.post(
`/api/v4/projects/${$.step.parameters.projectId}/hooks`,
subscriptionPayload
);
await $.flow.setRemoteWebhookId(data.id.toString());
};
export const unregisterHook = async ($: IGlobalVariable) => {
// ref: https://docs.gitlab.com/ee/api/projects.html#delete-project-hook
await $.http.delete(
`/api/v4/projects/${$.step.parameters.projectId}/hooks/${$.flow.remoteWebhookId}`
);
};

View File

@@ -1,26 +0,0 @@
import { IRawTrigger } from '@automatisch/types';
import defineTrigger from '../../../../helpers/define-trigger';
import { GITLAB_EVENT_TYPE } from '../types';
import {
getRegisterHookFn,
getTestRunFn,
projectArgumentDescriptor,
unregisterHook,
} from '../lib';
import data from './merge_request_event';
export const triggerDescriptor: IRawTrigger = {
name: 'Merge request event',
description:
'Merge request event (triggered when merge request is created, updated, or closed)',
// info: 'https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#merge-request-events',
key: GITLAB_EVENT_TYPE.merge_requests_events,
type: 'webhook',
arguments: [projectArgumentDescriptor],
testRun: getTestRunFn(data),
registerHook: getRegisterHookFn(GITLAB_EVENT_TYPE.merge_requests_events),
unregisterHook,
};
export default defineTrigger(triggerDescriptor);

View File

@@ -1,208 +0,0 @@
// https://docs.gitlab.com/ee/user/project/integrations/webhook_events.html#merge-request-events
export default {
object_kind: 'merge_request',
event_type: 'merge_request',
user: {
id: 1,
name: 'Administrator',
username: 'root',
avatar_url:
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
email: 'admin@example.com',
},
project: {
id: 1,
name: 'Gitlab Test',
description: 'Aut reprehenderit ut est.',
web_url: 'http://example.com/gitlabhq/gitlab-test',
avatar_url: null,
git_ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
git_http_url: 'http://example.com/gitlabhq/gitlab-test.git',
namespace: 'GitlabHQ',
visibility_level: 20,
path_with_namespace: 'gitlabhq/gitlab-test',
default_branch: 'master',
ci_config_path: '',
homepage: 'http://example.com/gitlabhq/gitlab-test',
url: 'http://example.com/gitlabhq/gitlab-test.git',
ssh_url: 'git@example.com:gitlabhq/gitlab-test.git',
http_url: 'http://example.com/gitlabhq/gitlab-test.git',
},
repository: {
name: 'Gitlab Test',
url: 'http://example.com/gitlabhq/gitlab-test.git',
description: 'Aut reprehenderit ut est.',
homepage: 'http://example.com/gitlabhq/gitlab-test',
},
object_attributes: {
id: 99,
iid: 1,
target_branch: 'master',
source_branch: 'ms-viewport',
source_project_id: 14,
author_id: 51,
assignee_ids: [6],
assignee_id: 6,
reviewer_ids: [6],
title: 'MS-Viewport',
created_at: '2013-12-03T17:23:34Z',
updated_at: '2013-12-03T17:23:34Z',
last_edited_at: '2013-12-03T17:23:34Z',
last_edited_by_id: 1,
milestone_id: null,
state_id: 1,
state: 'opened',
blocking_discussions_resolved: true,
work_in_progress: false,
first_contribution: true,
merge_status: 'unchecked',
target_project_id: 14,
description: '',
total_time_spent: 1800,
time_change: 30,
human_total_time_spent: '30m',
human_time_change: '30s',
human_time_estimate: '30m',
url: 'http://example.com/diaspora/merge_requests/1',
source: {
name: 'Awesome Project',
description: 'Aut reprehenderit ut est.',
web_url: 'http://example.com/awesome_space/awesome_project',
avatar_url: null,
git_ssh_url: 'git@example.com:awesome_space/awesome_project.git',
git_http_url: 'http://example.com/awesome_space/awesome_project.git',
namespace: 'Awesome Space',
visibility_level: 20,
path_with_namespace: 'awesome_space/awesome_project',
default_branch: 'master',
homepage: 'http://example.com/awesome_space/awesome_project',
url: 'http://example.com/awesome_space/awesome_project.git',
ssh_url: 'git@example.com:awesome_space/awesome_project.git',
http_url: 'http://example.com/awesome_space/awesome_project.git',
},
target: {
name: 'Awesome Project',
description: 'Aut reprehenderit ut est.',
web_url: 'http://example.com/awesome_space/awesome_project',
avatar_url: null,
git_ssh_url: 'git@example.com:awesome_space/awesome_project.git',
git_http_url: 'http://example.com/awesome_space/awesome_project.git',
namespace: 'Awesome Space',
visibility_level: 20,
path_with_namespace: 'awesome_space/awesome_project',
default_branch: 'master',
homepage: 'http://example.com/awesome_space/awesome_project',
url: 'http://example.com/awesome_space/awesome_project.git',
ssh_url: 'git@example.com:awesome_space/awesome_project.git',
http_url: 'http://example.com/awesome_space/awesome_project.git',
},
last_commit: {
id: 'da1560886d4f094c3e6c9ef40349f7d38b5d27d7',
message: 'fixed readme',
title: 'Update file README.md',
timestamp: '2012-01-03T23:36:29+02:00',
url: 'http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7',
author: {
name: 'GitLab dev user',
email: 'gitlabdev@dv6700.(none)',
},
},
labels: [
{
id: 206,
title: 'API',
color: '#ffffff',
project_id: 14,
created_at: '2013-12-03T17:15:43Z',
updated_at: '2013-12-03T17:15:43Z',
template: false,
description: 'API related issues',
type: 'ProjectLabel',
group_id: 41,
},
],
action: 'open',
detailed_merge_status: 'mergeable',
},
labels: [
{
id: 206,
title: 'API',
color: '#ffffff',
project_id: 14,
created_at: '2013-12-03T17:15:43Z',
updated_at: '2013-12-03T17:15:43Z',
template: false,
description: 'API related issues',
type: 'ProjectLabel',
group_id: 41,
},
],
changes: {
updated_by_id: {
previous: null,
current: 1,
},
updated_at: {
previous: '2017-09-15 16:50:55 UTC',
current: '2017-09-15 16:52:00 UTC',
},
labels: {
previous: [
{
id: 206,
title: 'API',
color: '#ffffff',
project_id: 14,
created_at: '2013-12-03T17:15:43Z',
updated_at: '2013-12-03T17:15:43Z',
template: false,
description: 'API related issues',
type: 'ProjectLabel',
group_id: 41,
},
],
current: [
{
id: 205,
title: 'Platform',
color: '#123123',
project_id: 14,
created_at: '2013-12-03T17:15:43Z',
updated_at: '2013-12-03T17:15:43Z',
template: false,
description: 'Platform related issues',
type: 'ProjectLabel',
group_id: 41,
},
],
},
last_edited_at: {
previous: null,
current: '2023-03-15 00:00:10 UTC',
},
last_edited_by_id: {
previous: null,
current: 3278533,
},
},
assignees: [
{
id: 6,
name: 'User1',
username: 'user1',
avatar_url:
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
},
],
reviewers: [
{
id: 6,
name: 'User1',
username: 'user1',
avatar_url:
'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon',
},
],
};

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