Compare commits
	
		
			1 Commits
		
	
	
		
			dependabot
			...
			AUT-1005
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					e6540b5b7e | 
							
								
								
									
										3
									
								
								.github/workflows/playwright.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/workflows/playwright.yml
									
									
									
									
										vendored
									
									
								
							@@ -71,6 +71,9 @@ jobs:
 | 
				
			|||||||
      - name: Migrate database
 | 
					      - name: Migrate database
 | 
				
			||||||
        working-directory: ./packages/backend
 | 
					        working-directory: ./packages/backend
 | 
				
			||||||
        run: yarn db:migrate
 | 
					        run: yarn db:migrate
 | 
				
			||||||
 | 
					      - name: Seed user
 | 
				
			||||||
 | 
					        working-directory: ./packages/backend
 | 
				
			||||||
 | 
					        run: yarn db:seed:user &
 | 
				
			||||||
      - name: Install certutils
 | 
					      - name: Install certutils
 | 
				
			||||||
        run: sudo apt install -y libnss3-tools
 | 
					        run: sudo apt install -y libnss3-tools
 | 
				
			||||||
      - name: Install mkcert
 | 
					      - name: Install mkcert
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,10 @@
 | 
				
			|||||||
# syntax=docker/dockerfile:1
 | 
					# syntax=docker/dockerfile:1
 | 
				
			||||||
FROM node:18-alpine
 | 
					FROM node:18-alpine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENV PORT=3000
 | 
					ENV PORT 3000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN \
 | 
					RUN \
 | 
				
			||||||
  apk --no-cache add --virtual build-dependencies python3 build-base git make g++
 | 
					  apk --no-cache add --virtual build-dependencies python3 build-base git
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WORKDIR /automatisch
 | 
					WORKDIR /automatisch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@ import process from 'process';
 | 
				
			|||||||
async function fetchAdminRole() {
 | 
					async function fetchAdminRole() {
 | 
				
			||||||
  const role = await Role.query()
 | 
					  const role = await Role.query()
 | 
				
			||||||
    .where({
 | 
					    .where({
 | 
				
			||||||
      name: 'Admin',
 | 
					      key: 'admin',
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    .limit(1)
 | 
					    .limit(1)
 | 
				
			||||||
    .first();
 | 
					    .first();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
import { knexSnakeCaseMappers } from 'objection';
 | 
					import { knexSnakeCaseMappers } from 'objection';
 | 
				
			||||||
import appConfig from './src/config/app.js';
 | 
					import appConfig from './src/config/app.js';
 | 
				
			||||||
import path, { join } from 'path';
 | 
					import path from 'path';
 | 
				
			||||||
import { fileURLToPath } from 'url';
 | 
					import { fileURLToPath } from 'url';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const fileExtension = 'js';
 | 
					const fileExtension = 'js';
 | 
				
			||||||
@@ -20,12 +20,12 @@ const knexConfig = {
 | 
				
			|||||||
  searchPath: [appConfig.postgresSchema],
 | 
					  searchPath: [appConfig.postgresSchema],
 | 
				
			||||||
  pool: { min: 0, max: 20 },
 | 
					  pool: { min: 0, max: 20 },
 | 
				
			||||||
  migrations: {
 | 
					  migrations: {
 | 
				
			||||||
    directory: join(__dirname, '/src/db/migrations'),
 | 
					    directory: __dirname + '/src/db/migrations',
 | 
				
			||||||
    extension: fileExtension,
 | 
					    extension: fileExtension,
 | 
				
			||||||
    loadExtensions: [`.${fileExtension}`],
 | 
					    loadExtensions: [`.${fileExtension}`],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  seeds: {
 | 
					  seeds: {
 | 
				
			||||||
    directory: join(__dirname, '/src/db/seeds'),
 | 
					    directory: __dirname + '/src/db/seeds',
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  ...(appConfig.isTest ? knexSnakeCaseMappers() : {}),
 | 
					  ...(appConfig.isTest ? knexSnakeCaseMappers() : {}),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,13 +5,12 @@
 | 
				
			|||||||
  "description": "The open source Zapier alternative. Build workflow automation without spending time and money.",
 | 
					  "description": "The open source Zapier alternative. Build workflow automation without spending time and money.",
 | 
				
			||||||
  "type": "module",
 | 
					  "type": "module",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
    "dev": "nodemon --exec node src/server.js",
 | 
					    "dev": "nodemon --watch 'src/**/*.js' --exec 'node' src/server.js",
 | 
				
			||||||
    "worker": "nodemon --exec node src/worker.js",
 | 
					    "worker": "nodemon --watch 'src/**/*.js' --exec 'node' src/worker.js",
 | 
				
			||||||
    "start": "node src/server.js",
 | 
					    "start": "node src/server.js",
 | 
				
			||||||
    "start:worker": "node src/worker.js",
 | 
					    "start:worker": "node src/worker.js",
 | 
				
			||||||
    "pretest": "APP_ENV=test node ./test/setup/prepare-test-env.js",
 | 
					    "pretest": "APP_ENV=test node ./test/setup/prepare-test-env.js",
 | 
				
			||||||
    "test": "APP_ENV=test vitest run",
 | 
					    "test": "APP_ENV=test vitest run",
 | 
				
			||||||
    "test:watch": "APP_ENV=test vitest watch",
 | 
					 | 
				
			||||||
    "lint": "eslint .",
 | 
					    "lint": "eslint .",
 | 
				
			||||||
    "db:create": "node ./bin/database/create.js",
 | 
					    "db:create": "node ./bin/database/create.js",
 | 
				
			||||||
    "db:seed:user": "node ./bin/database/seed-user.js",
 | 
					    "db:seed:user": "node ./bin/database/seed-user.js",
 | 
				
			||||||
@@ -23,6 +22,8 @@
 | 
				
			|||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@bull-board/express": "^3.10.1",
 | 
					    "@bull-board/express": "^3.10.1",
 | 
				
			||||||
    "@casl/ability": "^6.5.0",
 | 
					    "@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",
 | 
					    "@node-saml/passport-saml": "^4.0.4",
 | 
				
			||||||
    "@rudderstack/rudder-sdk-node": "^1.1.2",
 | 
					    "@rudderstack/rudder-sdk-node": "^1.1.2",
 | 
				
			||||||
    "@sentry/node": "^7.42.0",
 | 
					    "@sentry/node": "^7.42.0",
 | 
				
			||||||
@@ -36,15 +37,18 @@
 | 
				
			|||||||
    "crypto-js": "^4.1.1",
 | 
					    "crypto-js": "^4.1.1",
 | 
				
			||||||
    "debug": "~2.6.9",
 | 
					    "debug": "~2.6.9",
 | 
				
			||||||
    "dotenv": "^10.0.0",
 | 
					    "dotenv": "^10.0.0",
 | 
				
			||||||
    "express": "~4.20.0",
 | 
					    "express": "~4.18.2",
 | 
				
			||||||
    "express-async-errors": "^3.1.1",
 | 
					    "express-async-handler": "^1.2.0",
 | 
				
			||||||
    "express-basic-auth": "^1.2.1",
 | 
					    "express-basic-auth": "^1.2.1",
 | 
				
			||||||
 | 
					    "express-graphql": "^0.12.0",
 | 
				
			||||||
    "fast-xml-parser": "^4.0.11",
 | 
					    "fast-xml-parser": "^4.0.11",
 | 
				
			||||||
 | 
					    "graphql-middleware": "^6.1.15",
 | 
				
			||||||
 | 
					    "graphql-shield": "^7.5.0",
 | 
				
			||||||
 | 
					    "graphql-tools": "^8.2.0",
 | 
				
			||||||
    "handlebars": "^4.7.7",
 | 
					    "handlebars": "^4.7.7",
 | 
				
			||||||
    "http-errors": "~1.6.3",
 | 
					    "http-errors": "~1.6.3",
 | 
				
			||||||
    "http-proxy-agent": "^7.0.0",
 | 
					    "http-proxy-agent": "^7.0.0",
 | 
				
			||||||
    "https-proxy-agent": "^7.0.1",
 | 
					    "https-proxy-agent": "^7.0.1",
 | 
				
			||||||
    "isolated-vm": "^5.0.1",
 | 
					 | 
				
			||||||
    "jsonwebtoken": "^9.0.0",
 | 
					    "jsonwebtoken": "^9.0.0",
 | 
				
			||||||
    "knex": "^2.4.0",
 | 
					    "knex": "^2.4.0",
 | 
				
			||||||
    "libphonenumber-js": "^1.10.48",
 | 
					    "libphonenumber-js": "^1.10.48",
 | 
				
			||||||
@@ -99,11 +103,5 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  "publishConfig": {
 | 
					  "publishConfig": {
 | 
				
			||||||
    "access": "public"
 | 
					    "access": "public"
 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  "nodemonConfig": {
 | 
					 | 
				
			||||||
    "watch": [
 | 
					 | 
				
			||||||
      "src/"
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    "ext": "js"
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,5 @@
 | 
				
			|||||||
import createError from 'http-errors';
 | 
					import createError from 'http-errors';
 | 
				
			||||||
import express from 'express';
 | 
					import express from 'express';
 | 
				
			||||||
import 'express-async-errors';
 | 
					 | 
				
			||||||
import cors from 'cors';
 | 
					import cors from 'cors';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import appConfig from './config/app.js';
 | 
					import appConfig from './config/app.js';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ export default defineAction({
 | 
				
			|||||||
    'Creates an attachment of a specified object by given parent ID.',
 | 
					    'Creates an attachment of a specified object by given parent ID.',
 | 
				
			||||||
  arguments: [
 | 
					  arguments: [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      label: 'Template Data',
 | 
					      label: 'Templete Data',
 | 
				
			||||||
      key: 'templateData',
 | 
					      key: 'templateData',
 | 
				
			||||||
      type: 'string',
 | 
					      type: 'string',
 | 
				
			||||||
      required: true,
 | 
					      required: true,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,72 +0,0 @@
 | 
				
			|||||||
import defineAction from '../../../../helpers/define-action.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineAction({
 | 
					 | 
				
			||||||
  name: 'Create folder',
 | 
					 | 
				
			||||||
  key: 'createFolder',
 | 
					 | 
				
			||||||
  description: 'Creates a new folder.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Workspace',
 | 
					 | 
				
			||||||
      key: 'workspaceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listWorkspaces',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Space',
 | 
					 | 
				
			||||||
      key: 'spaceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.workspaceId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listSpaces',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.workspaceId',
 | 
					 | 
				
			||||||
            value: '{parameters.workspaceId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Folder Name',
 | 
					 | 
				
			||||||
      key: 'folderName',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const { spaceId, folderName } = $.step.parameters;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const body = {
 | 
					 | 
				
			||||||
      name: folderName,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.post(`/v2/space/${spaceId}/folder`, body);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.setActionItem({
 | 
					 | 
				
			||||||
      raw: data,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,135 +0,0 @@
 | 
				
			|||||||
import defineAction from '../../../../helpers/define-action.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineAction({
 | 
					 | 
				
			||||||
  name: 'Create list',
 | 
					 | 
				
			||||||
  key: 'createList',
 | 
					 | 
				
			||||||
  description: 'Creates a new list.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Workspace',
 | 
					 | 
				
			||||||
      key: 'workspaceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listWorkspaces',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Space',
 | 
					 | 
				
			||||||
      key: 'spaceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.workspaceId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listSpaces',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.workspaceId',
 | 
					 | 
				
			||||||
            value: '{parameters.workspaceId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Folder',
 | 
					 | 
				
			||||||
      key: 'folderId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.spaceId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listFolders',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.spaceId',
 | 
					 | 
				
			||||||
            value: '{parameters.spaceId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'List Name',
 | 
					 | 
				
			||||||
      key: 'listName',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'List Info',
 | 
					 | 
				
			||||||
      key: 'listInfo',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Priority',
 | 
					 | 
				
			||||||
      key: 'priority',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      options: [
 | 
					 | 
				
			||||||
        { label: 'Urgent', value: 1 },
 | 
					 | 
				
			||||||
        { label: 'High', value: 2 },
 | 
					 | 
				
			||||||
        { label: 'Normal', value: 3 },
 | 
					 | 
				
			||||||
        { label: 'Low', value: 4 },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Due Date',
 | 
					 | 
				
			||||||
      key: 'dueDate',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description: 'format: integer <int64>',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const { folderId, listName, listInfo, priority, dueDate } =
 | 
					 | 
				
			||||||
      $.step.parameters;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const body = {
 | 
					 | 
				
			||||||
      name: listName,
 | 
					 | 
				
			||||||
      content: listInfo,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (priority) {
 | 
					 | 
				
			||||||
      body.priority = priority;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (dueDate) {
 | 
					 | 
				
			||||||
      body.due_date = dueDate;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.post(`/v2/folder/${folderId}/list`, body);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.setActionItem({
 | 
					 | 
				
			||||||
      raw: data,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,294 +0,0 @@
 | 
				
			|||||||
import defineAction from '../../../../helpers/define-action.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineAction({
 | 
					 | 
				
			||||||
  name: 'Create task',
 | 
					 | 
				
			||||||
  key: 'createTask',
 | 
					 | 
				
			||||||
  description: 'Creates a new task.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Workspace',
 | 
					 | 
				
			||||||
      key: 'workspaceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listWorkspaces',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Space',
 | 
					 | 
				
			||||||
      key: 'spaceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.workspaceId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listSpaces',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.workspaceId',
 | 
					 | 
				
			||||||
            value: '{parameters.workspaceId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Folder',
 | 
					 | 
				
			||||||
      key: 'folderId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.spaceId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listFolders',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.spaceId',
 | 
					 | 
				
			||||||
            value: '{parameters.spaceId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'List',
 | 
					 | 
				
			||||||
      key: 'listId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.folderId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listLists',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.folderId',
 | 
					 | 
				
			||||||
            value: '{parameters.folderId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Task Name',
 | 
					 | 
				
			||||||
      key: 'taskName',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Task Description',
 | 
					 | 
				
			||||||
      key: 'taskDescription',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Markdown Content',
 | 
					 | 
				
			||||||
      key: 'markdownContent',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      options: [
 | 
					 | 
				
			||||||
        { label: 'False', value: 'false' },
 | 
					 | 
				
			||||||
        { label: 'True', value: 'true' },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Assignees',
 | 
					 | 
				
			||||||
      key: 'assigneeIds',
 | 
					 | 
				
			||||||
      type: 'dynamic',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      fields: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          label: 'Assignee',
 | 
					 | 
				
			||||||
          key: 'assigneeId',
 | 
					 | 
				
			||||||
          type: 'dropdown',
 | 
					 | 
				
			||||||
          required: false,
 | 
					 | 
				
			||||||
          dependsOn: ['parameters.listId'],
 | 
					 | 
				
			||||||
          variables: true,
 | 
					 | 
				
			||||||
          source: {
 | 
					 | 
				
			||||||
            type: 'query',
 | 
					 | 
				
			||||||
            name: 'getDynamicData',
 | 
					 | 
				
			||||||
            arguments: [
 | 
					 | 
				
			||||||
              {
 | 
					 | 
				
			||||||
                name: 'key',
 | 
					 | 
				
			||||||
                value: 'listAssignees',
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
              {
 | 
					 | 
				
			||||||
                name: 'parameters.listId',
 | 
					 | 
				
			||||||
                value: '{parameters.listId}',
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Task Status',
 | 
					 | 
				
			||||||
      key: 'taskStatus',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.listId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listStatuses',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.listId',
 | 
					 | 
				
			||||||
            value: '{parameters.listId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Tags',
 | 
					 | 
				
			||||||
      key: 'tagIds',
 | 
					 | 
				
			||||||
      type: 'dynamic',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      fields: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          label: 'tag',
 | 
					 | 
				
			||||||
          key: 'tagId',
 | 
					 | 
				
			||||||
          type: 'dropdown',
 | 
					 | 
				
			||||||
          required: false,
 | 
					 | 
				
			||||||
          variables: true,
 | 
					 | 
				
			||||||
          source: {
 | 
					 | 
				
			||||||
            type: 'query',
 | 
					 | 
				
			||||||
            name: 'getDynamicData',
 | 
					 | 
				
			||||||
            arguments: [
 | 
					 | 
				
			||||||
              {
 | 
					 | 
				
			||||||
                name: 'key',
 | 
					 | 
				
			||||||
                value: 'listTags',
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Priority',
 | 
					 | 
				
			||||||
      key: 'priority',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      options: [
 | 
					 | 
				
			||||||
        { label: 'Urgent', value: 1 },
 | 
					 | 
				
			||||||
        { label: 'High', value: 2 },
 | 
					 | 
				
			||||||
        { label: 'Normal', value: 3 },
 | 
					 | 
				
			||||||
        { label: 'Low', value: 4 },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Due Date',
 | 
					 | 
				
			||||||
      key: 'dueDate',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description: 'format: integer <int64>',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Start Date',
 | 
					 | 
				
			||||||
      key: 'startDate',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description: 'format: integer <int64>',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const {
 | 
					 | 
				
			||||||
      listId,
 | 
					 | 
				
			||||||
      taskName,
 | 
					 | 
				
			||||||
      taskDescription,
 | 
					 | 
				
			||||||
      markdownContent,
 | 
					 | 
				
			||||||
      assigneeIds,
 | 
					 | 
				
			||||||
      taskStatus,
 | 
					 | 
				
			||||||
      tagIds,
 | 
					 | 
				
			||||||
      priority,
 | 
					 | 
				
			||||||
      dueDate,
 | 
					 | 
				
			||||||
      startDate,
 | 
					 | 
				
			||||||
    } = $.step.parameters;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const tags = tagIds.map((tag) => tag.tagId);
 | 
					 | 
				
			||||||
    const assignees = assigneeIds.map((assignee) =>
 | 
					 | 
				
			||||||
      Number(assignee.assigneeId)
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const body = {
 | 
					 | 
				
			||||||
      name: taskName,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (assignees.length) {
 | 
					 | 
				
			||||||
      body.assignees = assignees;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (taskStatus) {
 | 
					 | 
				
			||||||
      body.status = taskStatus;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (tags.length) {
 | 
					 | 
				
			||||||
      body.tags = tags;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (priority) {
 | 
					 | 
				
			||||||
      body.priority = priority;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (dueDate) {
 | 
					 | 
				
			||||||
      body.due_date = dueDate;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (startDate) {
 | 
					 | 
				
			||||||
      body.start_date = startDate;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (markdownContent) {
 | 
					 | 
				
			||||||
      body.markdown_description = taskDescription;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      body.description = taskDescription;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.post(`/v2/list/${listId}/task`, body);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.setActionItem({
 | 
					 | 
				
			||||||
      raw: data,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,82 +0,0 @@
 | 
				
			|||||||
import defineAction from '../../../../helpers/define-action.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineAction({
 | 
					 | 
				
			||||||
  name: 'Find task by id',
 | 
					 | 
				
			||||||
  key: 'findTaskById',
 | 
					 | 
				
			||||||
  description: 'Finds a task using id.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Task ID',
 | 
					 | 
				
			||||||
      key: 'taskId',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Use Custom ID',
 | 
					 | 
				
			||||||
      key: 'useCustomId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      options: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          label: 'True',
 | 
					 | 
				
			||||||
          value: true,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          label: 'False',
 | 
					 | 
				
			||||||
          value: false,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      additionalFields: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicFields',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listFieldsWhenUsingCustomId',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.useCustomId',
 | 
					 | 
				
			||||||
            value: '{parameters.useCustomId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Include Subtasks?',
 | 
					 | 
				
			||||||
      key: 'includeSubtasks',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      options: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          label: 'True',
 | 
					 | 
				
			||||||
          value: true,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          label: 'False',
 | 
					 | 
				
			||||||
          value: false,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const { taskId, useCustomId, includeSubtasks } = $.step.parameters;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const params = {
 | 
					 | 
				
			||||||
      custom_task_ids: useCustomId || false,
 | 
					 | 
				
			||||||
      include_subtasks: includeSubtasks,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.get(`/v2/task/${taskId}`, { params });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.setActionItem({
 | 
					 | 
				
			||||||
      raw: data,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,6 +0,0 @@
 | 
				
			|||||||
import createFolder from './create-folder/index.js';
 | 
					 | 
				
			||||||
import createList from './create-list/index.js';
 | 
					 | 
				
			||||||
import createTask from './create-task/index.js';
 | 
					 | 
				
			||||||
import findTaskById from './find-task-by-id/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default [createFolder, createList, createTask, findTaskById];
 | 
					 | 
				
			||||||
@@ -1,27 +0,0 @@
 | 
				
			|||||||
<svg width="185" height="185" viewBox="0 0 185 185" fill="none" xmlns="http://www.w3.org/2000/svg">
 | 
					 | 
				
			||||||
<g filter="url(#filter0_d)">
 | 
					 | 
				
			||||||
<rect x="30" y="20" width="125" height="125" rx="62.5" fill="white"/>
 | 
					 | 
				
			||||||
<rect x="30" y="20" width="125" height="125" rx="62.5" fill="white"/>
 | 
					 | 
				
			||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M55.8789 105.714L69.3974 95.3593C76.5762 104.732 84.1998 109.051 92.6948 109.051C101.143 109.051 108.557 104.781 115.414 95.4832L129.119 105.59C119.232 118.996 106.932 126.079 92.6948 126.079C78.5049 126.079 66.0907 119.046 55.8789 105.714Z" fill="url(#paint0_linear)"/>
 | 
					 | 
				
			||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M92.6491 60.7078L68.5883 81.4406L57.4727 68.5407L92.6969 38.1885L127.647 68.5644L116.477 81.417L92.6491 60.7078Z" fill="url(#paint1_linear)"/>
 | 
					 | 
				
			||||||
</g>
 | 
					 | 
				
			||||||
<defs>
 | 
					 | 
				
			||||||
<filter id="filter0_d" x="0" y="0" width="185" height="185" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
 | 
					 | 
				
			||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
 | 
					 | 
				
			||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
 | 
					 | 
				
			||||||
<feOffset dy="10"/>
 | 
					 | 
				
			||||||
<feGaussianBlur stdDeviation="15"/>
 | 
					 | 
				
			||||||
<feColorMatrix type="matrix" values="0 0 0 0 0.0627451 0 0 0 0 0.117647 0 0 0 0 0.211765 0 0 0 0.1 0"/>
 | 
					 | 
				
			||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
 | 
					 | 
				
			||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
 | 
					 | 
				
			||||||
</filter>
 | 
					 | 
				
			||||||
<linearGradient id="paint0_linear" x1="55.8789" y1="116.251" x2="129.119" y2="116.251" gradientUnits="userSpaceOnUse">
 | 
					 | 
				
			||||||
<stop stop-color="#8930FD"/>
 | 
					 | 
				
			||||||
<stop offset="1" stop-color="#49CCF9"/>
 | 
					 | 
				
			||||||
</linearGradient>
 | 
					 | 
				
			||||||
<linearGradient id="paint1_linear" x1="57.4727" y1="67.6025" x2="127.647" y2="67.6025" gradientUnits="userSpaceOnUse">
 | 
					 | 
				
			||||||
<stop stop-color="#FF02F0"/>
 | 
					 | 
				
			||||||
<stop offset="1" stop-color="#FFC800"/>
 | 
					 | 
				
			||||||
</linearGradient>
 | 
					 | 
				
			||||||
</defs>
 | 
					 | 
				
			||||||
</svg>
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 1.8 KiB  | 
@@ -1,21 +0,0 @@
 | 
				
			|||||||
import { URLSearchParams } from 'url';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default async function generateAuthUrl($) {
 | 
					 | 
				
			||||||
  const oauthRedirectUrlField = $.app.auth.fields.find(
 | 
					 | 
				
			||||||
    (field) => field.key == 'oAuthRedirectUrl'
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
  const redirectUri = oauthRedirectUrlField.value;
 | 
					 | 
				
			||||||
  const state = Math.random().toString();
 | 
					 | 
				
			||||||
  const searchParams = new URLSearchParams({
 | 
					 | 
				
			||||||
    client_id: $.auth.data.clientId,
 | 
					 | 
				
			||||||
    redirect_uri: redirectUri,
 | 
					 | 
				
			||||||
    state,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const url = `https://app.clickup.com/api?${searchParams.toString()}`;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  await $.auth.set({
 | 
					 | 
				
			||||||
    url,
 | 
					 | 
				
			||||||
    originalState: state,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,46 +0,0 @@
 | 
				
			|||||||
import generateAuthUrl from './generate-auth-url.js';
 | 
					 | 
				
			||||||
import verifyCredentials from './verify-credentials.js';
 | 
					 | 
				
			||||||
import isStillVerified from './is-still-verified.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default {
 | 
					 | 
				
			||||||
  fields: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      key: 'oAuthRedirectUrl',
 | 
					 | 
				
			||||||
      label: 'OAuth Redirect URL',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      readOnly: true,
 | 
					 | 
				
			||||||
      value: '{WEB_APP_URL}/app/clickup/connections/add',
 | 
					 | 
				
			||||||
      placeholder: null,
 | 
					 | 
				
			||||||
      description:
 | 
					 | 
				
			||||||
        'When asked to input a redirect URL in ClickUp, enter the URL above.',
 | 
					 | 
				
			||||||
      clickToCopy: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      key: 'clientId',
 | 
					 | 
				
			||||||
      label: 'Client ID',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      readOnly: false,
 | 
					 | 
				
			||||||
      value: null,
 | 
					 | 
				
			||||||
      placeholder: null,
 | 
					 | 
				
			||||||
      description: null,
 | 
					 | 
				
			||||||
      clickToCopy: false,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      key: 'clientSecret',
 | 
					 | 
				
			||||||
      label: 'Client Secret',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      readOnly: false,
 | 
					 | 
				
			||||||
      value: null,
 | 
					 | 
				
			||||||
      placeholder: null,
 | 
					 | 
				
			||||||
      description: null,
 | 
					 | 
				
			||||||
      clickToCopy: false,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  generateAuthUrl,
 | 
					 | 
				
			||||||
  verifyCredentials,
 | 
					 | 
				
			||||||
  isStillVerified,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,8 +0,0 @@
 | 
				
			|||||||
import getCurrentUser from '../common/get-current-user.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const isStillVerified = async ($) => {
 | 
					 | 
				
			||||||
  const currentUser = await getCurrentUser($);
 | 
					 | 
				
			||||||
  return !!currentUser.id;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default isStillVerified;
 | 
					 | 
				
			||||||
@@ -1,31 +0,0 @@
 | 
				
			|||||||
import getCurrentUser from '../common/get-current-user.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const verifyCredentials = async ($) => {
 | 
					 | 
				
			||||||
  if ($.auth.data.originalState !== $.auth.data.state) {
 | 
					 | 
				
			||||||
    throw new Error(`The 'state' parameter does not match.`);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const { data } = await $.http.post('/v2/oauth/token', {
 | 
					 | 
				
			||||||
    client_id: $.auth.data.clientId,
 | 
					 | 
				
			||||||
    client_secret: $.auth.data.clientSecret,
 | 
					 | 
				
			||||||
    code: $.auth.data.code,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  await $.auth.set({
 | 
					 | 
				
			||||||
    accessToken: data.access_token,
 | 
					 | 
				
			||||||
    tokenType: data.token_type,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const currentUser = await getCurrentUser($);
 | 
					 | 
				
			||||||
  const screenName = [currentUser.username, currentUser.email]
 | 
					 | 
				
			||||||
    .filter(Boolean)
 | 
					 | 
				
			||||||
    .join(' @ ');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  await $.auth.set({
 | 
					 | 
				
			||||||
    clientId: $.auth.data.clientId,
 | 
					 | 
				
			||||||
    clientSecret: $.auth.data.clientSecret,
 | 
					 | 
				
			||||||
    screenName,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default verifyCredentials;
 | 
					 | 
				
			||||||
@@ -1,9 +0,0 @@
 | 
				
			|||||||
const addAuthHeader = ($, requestConfig) => {
 | 
					 | 
				
			||||||
  if ($.auth.data?.accessToken) {
 | 
					 | 
				
			||||||
    requestConfig.headers.Authorization = `${$.auth.data.tokenType} ${$.auth.data.accessToken}`;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return requestConfig;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default addAuthHeader;
 | 
					 | 
				
			||||||
@@ -1,6 +0,0 @@
 | 
				
			|||||||
const getCurrentUser = async ($) => {
 | 
					 | 
				
			||||||
  const { data } = await $.http.get('/v2/user');
 | 
					 | 
				
			||||||
  return data.user;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default getCurrentUser;
 | 
					 | 
				
			||||||
@@ -1,19 +0,0 @@
 | 
				
			|||||||
import listAssignees from './list-assignees/index.js';
 | 
					 | 
				
			||||||
import listFolders from './list-folders/index.js';
 | 
					 | 
				
			||||||
import listLists from './list-lists/index.js';
 | 
					 | 
				
			||||||
import listSpaces from './list-spaces/index.js';
 | 
					 | 
				
			||||||
import listStatuses from './list-statuses/index.js';
 | 
					 | 
				
			||||||
import listTags from './list-tags/index.js';
 | 
					 | 
				
			||||||
import listTasks from './list-tasks/index.js';
 | 
					 | 
				
			||||||
import listWorkspaces from './list-workspaces/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default [
 | 
					 | 
				
			||||||
  listAssignees,
 | 
					 | 
				
			||||||
  listFolders,
 | 
					 | 
				
			||||||
  listLists,
 | 
					 | 
				
			||||||
  listSpaces,
 | 
					 | 
				
			||||||
  listStatuses,
 | 
					 | 
				
			||||||
  listTags,
 | 
					 | 
				
			||||||
  listTasks,
 | 
					 | 
				
			||||||
  listWorkspaces,
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List assignees',
 | 
					 | 
				
			||||||
  key: 'listAssignees',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const assignees = {
 | 
					 | 
				
			||||||
      data: [],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    const listId = $.step.parameters.listId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!listId) {
 | 
					 | 
				
			||||||
      return assignees;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.get(`/v2/list/${listId}/member`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (data.members) {
 | 
					 | 
				
			||||||
      for (const member of data.members) {
 | 
					 | 
				
			||||||
        assignees.data.push({
 | 
					 | 
				
			||||||
          value: member.id,
 | 
					 | 
				
			||||||
          name: member.username,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return assignees;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List folders',
 | 
					 | 
				
			||||||
  key: 'listFolders',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const folders = {
 | 
					 | 
				
			||||||
      data: [],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    const spaceId = $.step.parameters.spaceId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!spaceId) {
 | 
					 | 
				
			||||||
      return folders;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.get(`/v2/space/${spaceId}/folder`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (data.folders) {
 | 
					 | 
				
			||||||
      for (const folder of data.folders) {
 | 
					 | 
				
			||||||
        folders.data.push({
 | 
					 | 
				
			||||||
          value: folder.id,
 | 
					 | 
				
			||||||
          name: folder.name,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return folders;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List lists',
 | 
					 | 
				
			||||||
  key: 'listLists',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const lists = {
 | 
					 | 
				
			||||||
      data: [],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    const folderId = $.step.parameters.folderId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!folderId) {
 | 
					 | 
				
			||||||
      return lists;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.get(`/v2/folder/${folderId}/list`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (data.lists) {
 | 
					 | 
				
			||||||
      for (const list of data.lists) {
 | 
					 | 
				
			||||||
        lists.data.push({
 | 
					 | 
				
			||||||
          value: list.id,
 | 
					 | 
				
			||||||
          name: list.name,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return lists;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List spaces',
 | 
					 | 
				
			||||||
  key: 'listSpaces',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const spaces = {
 | 
					 | 
				
			||||||
      data: [],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    const workspaceId = $.step.parameters.workspaceId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!workspaceId) {
 | 
					 | 
				
			||||||
      return spaces;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.get(`/v2/team/${workspaceId}/space`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (data.spaces) {
 | 
					 | 
				
			||||||
      for (const space of data.spaces) {
 | 
					 | 
				
			||||||
        spaces.data.push({
 | 
					 | 
				
			||||||
          value: space.id,
 | 
					 | 
				
			||||||
          name: space.name,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return spaces;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List statuses',
 | 
					 | 
				
			||||||
  key: 'listStatuses',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const statuses = {
 | 
					 | 
				
			||||||
      data: [],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    const listId = $.step.parameters.listId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!listId) {
 | 
					 | 
				
			||||||
      return statuses;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.get(`/v2/list/${listId}`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (data.statuses) {
 | 
					 | 
				
			||||||
      for (const status of data.statuses) {
 | 
					 | 
				
			||||||
        statuses.data.push({
 | 
					 | 
				
			||||||
          value: status.status,
 | 
					 | 
				
			||||||
          name: status.status,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return statuses;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List tags',
 | 
					 | 
				
			||||||
  key: 'listTags',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const tags = {
 | 
					 | 
				
			||||||
      data: [],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    const spaceId = $.step.parameters.spaceId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!spaceId) {
 | 
					 | 
				
			||||||
      return spaceId;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.get(`v2/space/${spaceId}/tag`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (data.tags) {
 | 
					 | 
				
			||||||
      for (const tag of data.tags) {
 | 
					 | 
				
			||||||
        tags.data.push({
 | 
					 | 
				
			||||||
          value: tag.name,
 | 
					 | 
				
			||||||
          name: tag.name,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return tags;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,41 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List tasks',
 | 
					 | 
				
			||||||
  key: 'listTasks',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const tasks = {
 | 
					 | 
				
			||||||
      data: [],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    const listId = $.step.parameters.listId;
 | 
					 | 
				
			||||||
    let next = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!listId) {
 | 
					 | 
				
			||||||
      return tasks;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const params = {
 | 
					 | 
				
			||||||
      order_by: 'created',
 | 
					 | 
				
			||||||
      reverse: true,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    do {
 | 
					 | 
				
			||||||
      const { data } = await $.http.get(`/v2/list/${listId}/task`, { params });
 | 
					 | 
				
			||||||
      if (data.last_page) {
 | 
					 | 
				
			||||||
        next = false;
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        next = true;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (data.tasks) {
 | 
					 | 
				
			||||||
        for (const task of data.tasks) {
 | 
					 | 
				
			||||||
          tasks.data.push({
 | 
					 | 
				
			||||||
            value: task.id,
 | 
					 | 
				
			||||||
            name: task.name,
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } while (next);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return tasks;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,23 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List workspaces',
 | 
					 | 
				
			||||||
  key: 'listWorkspaces',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const workspaces = {
 | 
					 | 
				
			||||||
      data: [],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.get('/v2/team');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (data.teams) {
 | 
					 | 
				
			||||||
      for (const workspace of data.teams) {
 | 
					 | 
				
			||||||
        workspaces.data.push({
 | 
					 | 
				
			||||||
          value: workspace.id,
 | 
					 | 
				
			||||||
          name: workspace.name,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return workspaces;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,3 +0,0 @@
 | 
				
			|||||||
import useCustomId from './use-custom-id/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default [useCustomId];
 | 
					 | 
				
			||||||
@@ -1,29 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List workspaces when using custom id',
 | 
					 | 
				
			||||||
  key: 'listFieldsWhenUsingCustomId',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    if ($.step.parameters.useCustomId) {
 | 
					 | 
				
			||||||
      return [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          label: 'Workspace',
 | 
					 | 
				
			||||||
          key: 'workspaceId',
 | 
					 | 
				
			||||||
          type: 'dropdown',
 | 
					 | 
				
			||||||
          required: true,
 | 
					 | 
				
			||||||
          description: '',
 | 
					 | 
				
			||||||
          variables: true,
 | 
					 | 
				
			||||||
          source: {
 | 
					 | 
				
			||||||
            type: 'query',
 | 
					 | 
				
			||||||
            name: 'getDynamicData',
 | 
					 | 
				
			||||||
            arguments: [
 | 
					 | 
				
			||||||
              {
 | 
					 | 
				
			||||||
                name: 'key',
 | 
					 | 
				
			||||||
                value: 'listWorkspaces',
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,24 +0,0 @@
 | 
				
			|||||||
import defineApp from '../../helpers/define-app.js';
 | 
					 | 
				
			||||||
import addAuthHeader from './common/add-auth-header.js';
 | 
					 | 
				
			||||||
import auth from './auth/index.js';
 | 
					 | 
				
			||||||
import triggers from './triggers/index.js';
 | 
					 | 
				
			||||||
import dynamicData from './dynamic-data/index.js';
 | 
					 | 
				
			||||||
import actions from './actions/index.js';
 | 
					 | 
				
			||||||
import dynamicFields from './dynamic-fields/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineApp({
 | 
					 | 
				
			||||||
  name: 'ClickUp',
 | 
					 | 
				
			||||||
  key: 'clickup',
 | 
					 | 
				
			||||||
  baseUrl: 'https://clickup.com',
 | 
					 | 
				
			||||||
  apiBaseUrl: 'https://api.clickup.com/api',
 | 
					 | 
				
			||||||
  iconUrl: '{BASE_URL}/apps/clickup/assets/favicon.svg',
 | 
					 | 
				
			||||||
  authDocUrl: 'https://automatisch.io/docs/apps/clickup/connection',
 | 
					 | 
				
			||||||
  primaryColor: 'FD71AF',
 | 
					 | 
				
			||||||
  supportsConnections: true,
 | 
					 | 
				
			||||||
  beforeRequest: [addAuthHeader],
 | 
					 | 
				
			||||||
  auth,
 | 
					 | 
				
			||||||
  triggers,
 | 
					 | 
				
			||||||
  dynamicData,
 | 
					 | 
				
			||||||
  actions,
 | 
					 | 
				
			||||||
  dynamicFields,
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,6 +0,0 @@
 | 
				
			|||||||
import newFolders from './new-folders/index.js';
 | 
					 | 
				
			||||||
import newLists from './new-lists/index.js';
 | 
					 | 
				
			||||||
import newTasks from './new-tasks/index.js';
 | 
					 | 
				
			||||||
import updatedTask from './updated-task/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default [newFolders, newLists, newTasks, updatedTask];
 | 
					 | 
				
			||||||
@@ -1,105 +0,0 @@
 | 
				
			|||||||
import Crypto from 'crypto';
 | 
					 | 
				
			||||||
import defineTrigger from '../../../../helpers/define-trigger.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineTrigger({
 | 
					 | 
				
			||||||
  name: 'New folders',
 | 
					 | 
				
			||||||
  key: 'newFolder',
 | 
					 | 
				
			||||||
  type: 'webhook',
 | 
					 | 
				
			||||||
  description: 'Triggers when a new folder is created.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Workspace',
 | 
					 | 
				
			||||||
      key: 'workspaceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listWorkspaces',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Space',
 | 
					 | 
				
			||||||
      key: 'spaceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.workspaceId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listSpaces',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.workspaceId',
 | 
					 | 
				
			||||||
            value: '{parameters.workspaceId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const dataItem = {
 | 
					 | 
				
			||||||
      raw: $.request.body,
 | 
					 | 
				
			||||||
      meta: {
 | 
					 | 
				
			||||||
        internalId: $.request.body.folder_id,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.pushTriggerItem(dataItem);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async testRun($) {
 | 
					 | 
				
			||||||
    const sampleEventData = {
 | 
					 | 
				
			||||||
      event: 'folderCreated',
 | 
					 | 
				
			||||||
      folder_id: '90180382912',
 | 
					 | 
				
			||||||
      webhook_id: Crypto.randomUUID(),
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const dataItem = {
 | 
					 | 
				
			||||||
      raw: sampleEventData,
 | 
					 | 
				
			||||||
      meta: {
 | 
					 | 
				
			||||||
        internalId: '',
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.pushTriggerItem(dataItem);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async registerHook($) {
 | 
					 | 
				
			||||||
    const { workspaceId, spaceId } = $.step.parameters;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const payload = {
 | 
					 | 
				
			||||||
      name: $.flow.id,
 | 
					 | 
				
			||||||
      endpoint: $.webhookUrl,
 | 
					 | 
				
			||||||
      events: ['folderCreated'],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (spaceId) {
 | 
					 | 
				
			||||||
      payload.space_id = spaceId;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.post(
 | 
					 | 
				
			||||||
      `/v2/team/${workspaceId}/webhook`,
 | 
					 | 
				
			||||||
      payload
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    await $.flow.setRemoteWebhookId(data.id);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async unregisterHook($) {
 | 
					 | 
				
			||||||
    await $.http.delete(`/v2/webhook/${$.flow.remoteWebhookId}`);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,129 +0,0 @@
 | 
				
			|||||||
import Crypto from 'crypto';
 | 
					 | 
				
			||||||
import defineTrigger from '../../../../helpers/define-trigger.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineTrigger({
 | 
					 | 
				
			||||||
  name: 'New lists',
 | 
					 | 
				
			||||||
  key: 'newLists',
 | 
					 | 
				
			||||||
  type: 'webhook',
 | 
					 | 
				
			||||||
  description: 'Triggers when a new list is created.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Workspace',
 | 
					 | 
				
			||||||
      key: 'workspaceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listWorkspaces',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Space',
 | 
					 | 
				
			||||||
      key: 'spaceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.workspaceId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listSpaces',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.workspaceId',
 | 
					 | 
				
			||||||
            value: '{parameters.workspaceId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Folder',
 | 
					 | 
				
			||||||
      key: 'folderId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.spaceId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listFolders',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.spaceId',
 | 
					 | 
				
			||||||
            value: '{parameters.spaceId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const dataItem = {
 | 
					 | 
				
			||||||
      raw: $.request.body,
 | 
					 | 
				
			||||||
      meta: {
 | 
					 | 
				
			||||||
        internalId: $.request.body.list_id,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.pushTriggerItem(dataItem);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async testRun($) {
 | 
					 | 
				
			||||||
    const sampleEventData = {
 | 
					 | 
				
			||||||
      event: 'listCreated',
 | 
					 | 
				
			||||||
      list_id: '901800588812',
 | 
					 | 
				
			||||||
      webhook_id: Crypto.randomUUID(),
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const dataItem = {
 | 
					 | 
				
			||||||
      raw: sampleEventData,
 | 
					 | 
				
			||||||
      meta: {
 | 
					 | 
				
			||||||
        internalId: sampleEventData.webhook_id,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.pushTriggerItem(dataItem);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async registerHook($) {
 | 
					 | 
				
			||||||
    const { workspaceId, spaceId, folderId } = $.step.parameters;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const payload = {
 | 
					 | 
				
			||||||
      name: $.flow.id,
 | 
					 | 
				
			||||||
      endpoint: $.webhookUrl,
 | 
					 | 
				
			||||||
      events: ['listCreated'],
 | 
					 | 
				
			||||||
      space_id: spaceId,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (folderId) {
 | 
					 | 
				
			||||||
      payload.folder_id = folderId;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.post(
 | 
					 | 
				
			||||||
      `/v2/team/${workspaceId}/webhook`,
 | 
					 | 
				
			||||||
      payload
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    await $.flow.setRemoteWebhookId(data.id);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async unregisterHook($) {
 | 
					 | 
				
			||||||
    await $.http.delete(`/v2/webhook/${$.flow.remoteWebhookId}`);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,186 +0,0 @@
 | 
				
			|||||||
import Crypto from 'crypto';
 | 
					 | 
				
			||||||
import defineTrigger from '../../../../helpers/define-trigger.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineTrigger({
 | 
					 | 
				
			||||||
  name: 'New tasks',
 | 
					 | 
				
			||||||
  key: 'newTasks',
 | 
					 | 
				
			||||||
  type: 'webhook',
 | 
					 | 
				
			||||||
  description: 'Triggers when a new task is created.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Workspace',
 | 
					 | 
				
			||||||
      key: 'workspaceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listWorkspaces',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Space',
 | 
					 | 
				
			||||||
      key: 'spaceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.workspaceId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listSpaces',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.workspaceId',
 | 
					 | 
				
			||||||
            value: '{parameters.workspaceId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Folder',
 | 
					 | 
				
			||||||
      key: 'folderId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.spaceId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listFolders',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.spaceId',
 | 
					 | 
				
			||||||
            value: '{parameters.spaceId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'List',
 | 
					 | 
				
			||||||
      key: 'listId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.folderId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listLists',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.folderId',
 | 
					 | 
				
			||||||
            value: '{parameters.folderId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Task',
 | 
					 | 
				
			||||||
      key: 'taskId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.listId'],
 | 
					 | 
				
			||||||
      description:
 | 
					 | 
				
			||||||
        'Choose an optional task to determine when this flow should be activated. In this scenario, only subtasks will initiate this flow.',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listTasks',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.listId',
 | 
					 | 
				
			||||||
            value: '{parameters.listId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const dataItem = {
 | 
					 | 
				
			||||||
      raw: $.request.body,
 | 
					 | 
				
			||||||
      meta: {
 | 
					 | 
				
			||||||
        internalId: $.request.body.task_id,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.pushTriggerItem(dataItem);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async testRun($) {
 | 
					 | 
				
			||||||
    const sampleEventData = {
 | 
					 | 
				
			||||||
      event: 'taskCreated',
 | 
					 | 
				
			||||||
      task_id: '86enn7pg7',
 | 
					 | 
				
			||||||
      webhook_id: Crypto.randomUUID(),
 | 
					 | 
				
			||||||
      history_items: [],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const dataItem = {
 | 
					 | 
				
			||||||
      raw: sampleEventData,
 | 
					 | 
				
			||||||
      meta: {
 | 
					 | 
				
			||||||
        internalId: sampleEventData.webhook_id,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.pushTriggerItem(dataItem);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async registerHook($) {
 | 
					 | 
				
			||||||
    const { workspaceId, spaceId, folderId, listId, taskId } =
 | 
					 | 
				
			||||||
      $.step.parameters;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const payload = {
 | 
					 | 
				
			||||||
      name: $.flow.id,
 | 
					 | 
				
			||||||
      endpoint: $.webhookUrl,
 | 
					 | 
				
			||||||
      events: ['taskCreated'],
 | 
					 | 
				
			||||||
      space_id: spaceId,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (folderId) {
 | 
					 | 
				
			||||||
      payload.folder_id = folderId;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (listId) {
 | 
					 | 
				
			||||||
      payload.list_id = listId;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (taskId) {
 | 
					 | 
				
			||||||
      payload.task_id = taskId;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.post(
 | 
					 | 
				
			||||||
      `/v2/team/${workspaceId}/webhook`,
 | 
					 | 
				
			||||||
      payload
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    await $.flow.setRemoteWebhookId(data.id);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async unregisterHook($) {
 | 
					 | 
				
			||||||
    await $.http.delete(`/v2/webhook/${$.flow.remoteWebhookId}`);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,172 +0,0 @@
 | 
				
			|||||||
import Crypto from 'crypto';
 | 
					 | 
				
			||||||
import defineTrigger from '../../../../helpers/define-trigger.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineTrigger({
 | 
					 | 
				
			||||||
  name: 'Updated task',
 | 
					 | 
				
			||||||
  key: 'updatedTask',
 | 
					 | 
				
			||||||
  type: 'webhook',
 | 
					 | 
				
			||||||
  description: 'Triggers when a task is updated.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Workspace',
 | 
					 | 
				
			||||||
      key: 'workspaceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listWorkspaces',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Space',
 | 
					 | 
				
			||||||
      key: 'spaceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.workspaceId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listSpaces',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.workspaceId',
 | 
					 | 
				
			||||||
            value: '{parameters.workspaceId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Folder',
 | 
					 | 
				
			||||||
      key: 'folderId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.spaceId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listFolders',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.spaceId',
 | 
					 | 
				
			||||||
            value: '{parameters.spaceId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'List',
 | 
					 | 
				
			||||||
      key: 'listId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.folderId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listLists',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.folderId',
 | 
					 | 
				
			||||||
            value: '{parameters.folderId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'What Changed?',
 | 
					 | 
				
			||||||
      key: 'whatChanged',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      options: [
 | 
					 | 
				
			||||||
        { label: 'Status', value: 'taskStatusUpdated' },
 | 
					 | 
				
			||||||
        { label: 'Assignee Added', value: 'taskAssigneeUpdated' },
 | 
					 | 
				
			||||||
        { label: 'Priority', value: 'taskPriorityUpdated' },
 | 
					 | 
				
			||||||
        { label: 'Tag Added', value: 'taskTagUpdated' },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const dataItem = {
 | 
					 | 
				
			||||||
      raw: $.request.body,
 | 
					 | 
				
			||||||
      meta: {
 | 
					 | 
				
			||||||
        internalId: Crypto.randomUUID(),
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.pushTriggerItem(dataItem);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async testRun($) {
 | 
					 | 
				
			||||||
    const sampleEventData = {
 | 
					 | 
				
			||||||
      event: 'taskUpdated',
 | 
					 | 
				
			||||||
      task_id: '86enn7pg7',
 | 
					 | 
				
			||||||
      webhook_id: Crypto.randomUUID(),
 | 
					 | 
				
			||||||
      history_items: [],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const dataItem = {
 | 
					 | 
				
			||||||
      raw: sampleEventData,
 | 
					 | 
				
			||||||
      meta: {
 | 
					 | 
				
			||||||
        internalId: sampleEventData.webhook_id,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.pushTriggerItem(dataItem);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async registerHook($) {
 | 
					 | 
				
			||||||
    const { workspaceId, spaceId, folderId, listId, whatChanged } =
 | 
					 | 
				
			||||||
      $.step.parameters;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const payload = {
 | 
					 | 
				
			||||||
      name: $.flow.id,
 | 
					 | 
				
			||||||
      endpoint: $.webhookUrl,
 | 
					 | 
				
			||||||
      space_id: spaceId,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    payload.events = [whatChanged || 'taskUpdated'];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (folderId) {
 | 
					 | 
				
			||||||
      payload.folder_id = folderId;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (listId) {
 | 
					 | 
				
			||||||
      payload.list_id = listId;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.post(
 | 
					 | 
				
			||||||
      `/v2/team/${workspaceId}/webhook`,
 | 
					 | 
				
			||||||
      payload
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    await $.flow.setRemoteWebhookId(data.id);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async unregisterHook($) {
 | 
					 | 
				
			||||||
    await $.http.delete(`/v2/webhook/${$.flow.remoteWebhookId}`);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,3 +0,0 @@
 | 
				
			|||||||
import runJavascript from './run-javascript/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default [runJavascript];
 | 
					 | 
				
			||||||
@@ -1,84 +0,0 @@
 | 
				
			|||||||
import defineAction from '../../../../helpers/define-action.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineAction({
 | 
					 | 
				
			||||||
  name: 'Run Javascript',
 | 
					 | 
				
			||||||
  key: 'runJavascript',
 | 
					 | 
				
			||||||
  description:
 | 
					 | 
				
			||||||
    'Run browser Javascript code. You can not use NodeJS specific features and npm packages.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Inputs',
 | 
					 | 
				
			||||||
      key: 'inputs',
 | 
					 | 
				
			||||||
      type: 'dynamic',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description:
 | 
					 | 
				
			||||||
        'To be able to use data from previous steps, you need to expose them as input entries. You can access these input values in your code by using the `inputs` argument.',
 | 
					 | 
				
			||||||
      value: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          key: '',
 | 
					 | 
				
			||||||
          value: '',
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      fields: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          label: 'Key',
 | 
					 | 
				
			||||||
          key: 'key',
 | 
					 | 
				
			||||||
          type: 'string',
 | 
					 | 
				
			||||||
          required: true,
 | 
					 | 
				
			||||||
          variables: true,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          label: 'Value',
 | 
					 | 
				
			||||||
          key: 'value',
 | 
					 | 
				
			||||||
          type: 'string',
 | 
					 | 
				
			||||||
          required: true,
 | 
					 | 
				
			||||||
          variables: true,
 | 
					 | 
				
			||||||
          valueType: 'parse',
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Code Snippet',
 | 
					 | 
				
			||||||
      key: 'codeSnippet',
 | 
					 | 
				
			||||||
      type: 'code',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      variables: false,
 | 
					 | 
				
			||||||
      value:
 | 
					 | 
				
			||||||
        'const code = async (inputs) => { \n  // E.g. if you have an input called username,\n  // you can access its value by calling inputs.username\n  // Return value will be used as output of this step.\n\n  return true;\n};',
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const { inputs = [], codeSnippet } = $.step.parameters;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const objectifiedInput = {};
 | 
					 | 
				
			||||||
    for (const input of inputs) {
 | 
					 | 
				
			||||||
      if (input.key) {
 | 
					 | 
				
			||||||
        objectifiedInput[input.key] = input.value;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const ivm = (await import('isolated-vm')).default;
 | 
					 | 
				
			||||||
    const isolate = new ivm.Isolate({ memoryLimit: 128 });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    try {
 | 
					 | 
				
			||||||
      const context = await isolate.createContext();
 | 
					 | 
				
			||||||
      await context.global.set(
 | 
					 | 
				
			||||||
        'inputs',
 | 
					 | 
				
			||||||
        new ivm.ExternalCopy(objectifiedInput).copyInto()
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      const compiledCodeSnippet = await isolate.compileScript(
 | 
					 | 
				
			||||||
        `${codeSnippet}; code(inputs);`
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
      const codeFunction = await compiledCodeSnippet.run(context, {
 | 
					 | 
				
			||||||
        reference: true,
 | 
					 | 
				
			||||||
        promise: true,
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      $.setActionItem({ raw: { output: await codeFunction.copy() } });
 | 
					 | 
				
			||||||
    } finally {
 | 
					 | 
				
			||||||
      isolate.dispose();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,5 +0,0 @@
 | 
				
			|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="800px" height="800px" viewBox="0 0 512 512">
 | 
					 | 
				
			||||||
  <polyline points="160 368 32 256 160 144" style="fill:none;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/>
 | 
					 | 
				
			||||||
  <polyline points="352 368 480 256 352 144" style="fill:none;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/>
 | 
					 | 
				
			||||||
  <line x1="304" y1="96" x2="208" y2="416" style="fill:none;stroke:#000000;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/>
 | 
					 | 
				
			||||||
</svg>
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 519 B  | 
@@ -1,14 +0,0 @@
 | 
				
			|||||||
import defineApp from '../../helpers/define-app.js';
 | 
					 | 
				
			||||||
import actions from './actions/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineApp({
 | 
					 | 
				
			||||||
  name: 'Code',
 | 
					 | 
				
			||||||
  key: 'code',
 | 
					 | 
				
			||||||
  baseUrl: '',
 | 
					 | 
				
			||||||
  apiBaseUrl: '',
 | 
					 | 
				
			||||||
  iconUrl: '{BASE_URL}/apps/code/assets/favicon.svg',
 | 
					 | 
				
			||||||
  authDocUrl: '{DOCS_URL}/apps/code/connection',
 | 
					 | 
				
			||||||
  primaryColor: '000000',
 | 
					 | 
				
			||||||
  supportsConnections: false,
 | 
					 | 
				
			||||||
  actions,
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,64 +0,0 @@
 | 
				
			|||||||
import { createHmac } from 'node:crypto';
 | 
					 | 
				
			||||||
import defineAction from '../../../../helpers/define-action.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineAction({
 | 
					 | 
				
			||||||
  name: 'Create HMAC',
 | 
					 | 
				
			||||||
  key: 'createHmac',
 | 
					 | 
				
			||||||
  description: 'Create a Hash-based Message Authentication Code (HMAC) using the specified algorithm, secret key, and message.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Algorithm',
 | 
					 | 
				
			||||||
      key: 'algorithm',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      value: 'sha256',
 | 
					 | 
				
			||||||
      description: 'Specifies the cryptographic hash function to use for HMAC generation.',
 | 
					 | 
				
			||||||
      options: [
 | 
					 | 
				
			||||||
        { label: 'SHA-256', value: 'sha256' },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Message',
 | 
					 | 
				
			||||||
      key: 'message',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: 'The input message to be hashed. This is the value that will be processed to generate the HMAC.',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Secret Key',
 | 
					 | 
				
			||||||
      key: 'secretKey',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: 'The secret key used to create the HMAC.',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Output Encoding',
 | 
					 | 
				
			||||||
      key: 'outputEncoding',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      value: 'hex',
 | 
					 | 
				
			||||||
      description: 'Specifies the encoding format for the HMAC digest output.',
 | 
					 | 
				
			||||||
      options: [
 | 
					 | 
				
			||||||
        { label: 'base64', value: 'base64' },
 | 
					 | 
				
			||||||
        { label: 'base64url', value: 'base64url' },
 | 
					 | 
				
			||||||
        { label: 'hex', value: 'hex' },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const hash = createHmac($.step.parameters.algorithm, $.step.parameters.secretKey)
 | 
					 | 
				
			||||||
      .update($.step.parameters.message)
 | 
					 | 
				
			||||||
      .digest($.step.parameters.outputEncoding);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.setActionItem({
 | 
					 | 
				
			||||||
      raw: {
 | 
					 | 
				
			||||||
        hash
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,65 +0,0 @@
 | 
				
			|||||||
import crypto from 'node:crypto';
 | 
					 | 
				
			||||||
import defineAction from '../../../../helpers/define-action.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineAction({
 | 
					 | 
				
			||||||
  name: 'Create Signature',
 | 
					 | 
				
			||||||
  key: 'createSignature',
 | 
					 | 
				
			||||||
  description: 'Create a digital signature using the specified algorithm, secret key, and message.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Algorithm',
 | 
					 | 
				
			||||||
      key: 'algorithm',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      value: 'RSA-SHA256',
 | 
					 | 
				
			||||||
      description: 'Specifies the cryptographic hash function to use for HMAC generation.',
 | 
					 | 
				
			||||||
      options: [
 | 
					 | 
				
			||||||
        { label: 'RSA-SHA256', value: 'RSA-SHA256' },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Message',
 | 
					 | 
				
			||||||
      key: 'message',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: 'The input message to be signed.',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Private Key',
 | 
					 | 
				
			||||||
      key: 'privateKey',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: 'The RSA private key in PEM format used for signing.',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Output Encoding',
 | 
					 | 
				
			||||||
      key: 'outputEncoding',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      value: 'hex',
 | 
					 | 
				
			||||||
      description: 'Specifies the encoding format for the digital signature output. This determines how the generated signature will be represented as a string.',
 | 
					 | 
				
			||||||
      options: [
 | 
					 | 
				
			||||||
        { label: 'base64', value: 'base64' },
 | 
					 | 
				
			||||||
        { label: 'base64url', value: 'base64url' },
 | 
					 | 
				
			||||||
        { label: 'hex', value: 'hex' },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const signer = crypto.createSign($.step.parameters.algorithm);
 | 
					 | 
				
			||||||
    signer.update($.step.parameters.message);
 | 
					 | 
				
			||||||
    signer.end();
 | 
					 | 
				
			||||||
    const signature = signer.sign($.step.parameters.privateKey, $.step.parameters.outputEncoding);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.setActionItem({
 | 
					 | 
				
			||||||
      raw: {
 | 
					 | 
				
			||||||
        signature
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,4 +0,0 @@
 | 
				
			|||||||
import createHmac from './create-hmac/index.js';
 | 
					 | 
				
			||||||
import createRsaSha256Signature from './create-rsa-sha256-signature/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default [createHmac, createRsaSha256Signature];
 | 
					 | 
				
			||||||
@@ -1,3 +0,0 @@
 | 
				
			|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="100pt" height="100pt" version="1.1" viewBox="0 0 100 100">
 | 
					 | 
				
			||||||
 <path d="m66.012 33h-3.0117v-11c0-7.1719-5.8281-13-13-13s-13 5.8281-13 13v11h-3.0117c-2.75 0-4.9883 2.2383-4.9883 4.9883v28.012c0 2.75 2.2383 4.9883 4.9883 4.9883h32.012c2.75 0 4.9883-2.2383 4.9883-4.9883v-28.012c0.011719-2.75-2.2266-4.9883-4.9766-4.9883zm-27.012-11c0-6.0703 4.9297-11 11-11s11 4.9297 11 11v11h-22zm30 44.012c0 1.6484-1.3398 2.9883-2.9883 2.9883h-32.023c-1.6484 0-2.9883-1.3398-2.9883-2.9883v-28.023c0-1.6484 1.3398-2.9883 2.9883-2.9883h32.023c1.6484 0 2.9883 1.3398 2.9883 2.9883zm-18 9.9883v14c0 0.55078-0.44922 1-1 1s-1-0.44922-1-1v-14c0-0.55078 0.44922-1 1-1s1 0.44922 1 1zm20 8c0 0.55078-0.44922 1-1 1h-8c-0.55078 0-1-0.44922-1-1v-8c0-0.55078 0.44922-1 1-1s1 0.44922 1 1v7h7c0.55078 0 1 0.44922 1 1zm-32-8v8c0 0.55078-0.44922 1-1 1h-8c-0.55078 0-1-0.44922-1-1s0.44922-1 1-1h7v-7c0-0.55078 0.44922-1 1-1s1 0.44922 1 1zm-14-26c0 0.55078-0.44922 1-1 1h-14c-0.55078 0-1-0.44922-1-1s0.44922-1 1-1h14c0.55078 0 1 0.44922 1 1zm0-12c0 0.55078-0.44922 1-1 1h-8c-0.55078 0-1-0.44922-1-1v-8c0-0.55078 0.44922-1 1-1s1 0.44922 1 1v7h7c0.55078 0 1 0.44922 1 1zm0 24c0 0.55078-0.44922 1-1 1h-7v7c0 0.55078-0.44922 1-1 1s-1-0.44922-1-1v-8c0-0.55078 0.44922-1 1-1h8c0.55078 0 1 0.44922 1 1zm66-12c0 0.55078-0.44922 1-1 1h-14c-0.55078 0-1-0.44922-1-1s0.44922-1 1-1h14c0.55078 0 1 0.44922 1 1zm-16-12c0-0.55078 0.44922-1 1-1h7v-7c0-0.55078 0.44922-1 1-1s1 0.44922 1 1v8c0 0.55078-0.44922 1-1 1h-8c-0.55078 0-1-0.44922-1-1zm10 24v8c0 0.55078-0.44922 1-1 1s-1-0.44922-1-1v-7h-7c-0.55078 0-1-0.44922-1-1s0.44922-1 1-1h8c0.55078 0 1 0.44922 1 1zm-35-17c-2.7617 0-5 2.2383-5 5 0 2.4102 1.7188 4.4297 4 4.8984v5.1016c0 0.55078 0.44922 1 1 1s1-0.44922 1-1v-5.1016c2.2812-0.46094 4-2.4805 4-4.8984 0-2.7617-2.2383-5-5-5zm0 8c-1.6484 0-3-1.3516-3-3s1.3516-3 3-3 3 1.3516 3 3-1.3516 3-3 3z"/>
 | 
					 | 
				
			||||||
</svg>
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 1.9 KiB  | 
@@ -1,14 +0,0 @@
 | 
				
			|||||||
import defineApp from '../../helpers/define-app.js';
 | 
					 | 
				
			||||||
import actions from './actions/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineApp({
 | 
					 | 
				
			||||||
  name: 'Cryptography',
 | 
					 | 
				
			||||||
  key: 'cryptography',
 | 
					 | 
				
			||||||
  iconUrl: '{BASE_URL}/apps/cryptography/assets/favicon.svg',
 | 
					 | 
				
			||||||
  authDocUrl: '{DOCS_URL}/apps/cryptography/connection',
 | 
					 | 
				
			||||||
  supportsConnections: false,
 | 
					 | 
				
			||||||
  baseUrl: '',
 | 
					 | 
				
			||||||
  apiBaseUrl: '',
 | 
					 | 
				
			||||||
  primaryColor: '001F52',
 | 
					 | 
				
			||||||
  actions,
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,10 +1,8 @@
 | 
				
			|||||||
import defineAction from '../../../../helpers/define-action.js';
 | 
					import defineAction from '../../../../helpers/define-action.js';
 | 
				
			||||||
import formatDateTime from './transformers/format-date-time.js';
 | 
					import formatDateTime from './transformers/format-date-time.js';
 | 
				
			||||||
import getCurrentTimestamp from './transformers/get-current-timestamp.js';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const transformers = {
 | 
					const transformers = {
 | 
				
			||||||
  formatDateTime,
 | 
					  formatDateTime,
 | 
				
			||||||
  getCurrentTimestamp,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default defineAction({
 | 
					export default defineAction({
 | 
				
			||||||
@@ -18,16 +16,7 @@ export default defineAction({
 | 
				
			|||||||
      type: 'dropdown',
 | 
					      type: 'dropdown',
 | 
				
			||||||
      required: true,
 | 
					      required: true,
 | 
				
			||||||
      variables: true,
 | 
					      variables: true,
 | 
				
			||||||
      options: [
 | 
					      options: [{ label: 'Format Date / Time', value: 'formatDateTime' }],
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          label: 'Get current timestamp',
 | 
					 | 
				
			||||||
          value: 'getCurrentTimestamp',
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          label: 'Format Date / Time',
 | 
					 | 
				
			||||||
          value: 'formatDateTime',
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      additionalFields: {
 | 
					      additionalFields: {
 | 
				
			||||||
        type: 'query',
 | 
					        type: 'query',
 | 
				
			||||||
        name: 'getDynamicFields',
 | 
					        name: 'getDynamicFields',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +0,0 @@
 | 
				
			|||||||
const getCurrentTimestamp = () => {
 | 
					 | 
				
			||||||
  return Date.now();
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default getCurrentTimestamp;
 | 
					 | 
				
			||||||
@@ -14,8 +14,6 @@ import stringToBase64 from './transformers/string-to-base64.js';
 | 
				
			|||||||
import encodeUri from './transformers/encode-uri.js';
 | 
					import encodeUri from './transformers/encode-uri.js';
 | 
				
			||||||
import trimWhitespace from './transformers/trim-whitespace.js';
 | 
					import trimWhitespace from './transformers/trim-whitespace.js';
 | 
				
			||||||
import useDefaultValue from './transformers/use-default-value.js';
 | 
					import useDefaultValue from './transformers/use-default-value.js';
 | 
				
			||||||
import parseStringifiedJson from './transformers/parse-stringified-json.js';
 | 
					 | 
				
			||||||
import createUuid from './transformers/create-uuid.js';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const transformers = {
 | 
					const transformers = {
 | 
				
			||||||
  base64ToString,
 | 
					  base64ToString,
 | 
				
			||||||
@@ -32,8 +30,6 @@ const transformers = {
 | 
				
			|||||||
  encodeUri,
 | 
					  encodeUri,
 | 
				
			||||||
  trimWhitespace,
 | 
					  trimWhitespace,
 | 
				
			||||||
  useDefaultValue,
 | 
					  useDefaultValue,
 | 
				
			||||||
  parseStringifiedJson,
 | 
					 | 
				
			||||||
  createUuid,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default defineAction({
 | 
					export default defineAction({
 | 
				
			||||||
@@ -51,21 +47,19 @@ export default defineAction({
 | 
				
			|||||||
      options: [
 | 
					      options: [
 | 
				
			||||||
        { label: 'Base64 to String', value: 'base64ToString' },
 | 
					        { label: 'Base64 to String', value: 'base64ToString' },
 | 
				
			||||||
        { label: 'Capitalize', value: 'capitalize' },
 | 
					        { label: 'Capitalize', value: 'capitalize' },
 | 
				
			||||||
        { label: 'Convert HTML to Markdown', value: 'htmlToMarkdown' },
 | 
					 | 
				
			||||||
        { label: 'Convert Markdown to HTML', value: 'markdownToHtml' },
 | 
					 | 
				
			||||||
        { label: 'Create UUID', value: 'createUuid' },
 | 
					 | 
				
			||||||
        { label: 'Encode URI', value: 'encodeUri' },
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          label: 'Encode URI Component',
 | 
					          label: 'Encode URI Component',
 | 
				
			||||||
          value: 'encodeUriComponent',
 | 
					          value: 'encodeUriComponent',
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        { label: 'Convert HTML to Markdown', value: 'htmlToMarkdown' },
 | 
				
			||||||
 | 
					        { label: 'Convert Markdown to HTML', value: 'markdownToHtml' },
 | 
				
			||||||
        { label: 'Extract Email Address', value: 'extractEmailAddress' },
 | 
					        { label: 'Extract Email Address', value: 'extractEmailAddress' },
 | 
				
			||||||
        { label: 'Extract Number', value: 'extractNumber' },
 | 
					        { label: 'Extract Number', value: 'extractNumber' },
 | 
				
			||||||
        { label: 'Lowercase', value: 'lowercase' },
 | 
					        { label: 'Lowercase', value: 'lowercase' },
 | 
				
			||||||
        { label: 'Parse stringified JSON', value: 'parseStringifiedJson' },
 | 
					 | 
				
			||||||
        { label: 'Pluralize', value: 'pluralize' },
 | 
					        { label: 'Pluralize', value: 'pluralize' },
 | 
				
			||||||
        { label: 'Replace', value: 'replace' },
 | 
					        { label: 'Replace', value: 'replace' },
 | 
				
			||||||
        { label: 'String to Base64', value: 'stringToBase64' },
 | 
					        { label: 'String to Base64', value: 'stringToBase64' },
 | 
				
			||||||
 | 
					        { label: 'Encode URI', value: 'encodeUri' },
 | 
				
			||||||
        { label: 'Trim Whitespace', value: 'trimWhitespace' },
 | 
					        { label: 'Trim Whitespace', value: 'trimWhitespace' },
 | 
				
			||||||
        { label: 'Use Default Value', value: 'useDefaultValue' },
 | 
					        { label: 'Use Default Value', value: 'useDefaultValue' },
 | 
				
			||||||
      ],
 | 
					      ],
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +0,0 @@
 | 
				
			|||||||
import { v4 as uuidv4 } from 'uuid';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const createUuidV4 = () => {
 | 
					 | 
				
			||||||
  return uuidv4();
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default createUuidV4;
 | 
					 | 
				
			||||||
@@ -1,7 +0,0 @@
 | 
				
			|||||||
const parseStringifiedJson = ($) => {
 | 
					 | 
				
			||||||
  const input = $.step.parameters.input;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return JSON.parse(input);
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default parseStringifiedJson;
 | 
					 | 
				
			||||||
@@ -1,26 +1,8 @@
 | 
				
			|||||||
const replace = ($) => {
 | 
					const replace = ($) => {
 | 
				
			||||||
  const input = $.step.parameters.input;
 | 
					  const input = $.step.parameters.input;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const find = $.step.parameters.find;
 | 
					  const find = $.step.parameters.find;
 | 
				
			||||||
  const replace = $.step.parameters.replace;
 | 
					  const replace = $.step.parameters.replace;
 | 
				
			||||||
  const useRegex = $.step.parameters.useRegex;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (useRegex) {
 | 
					 | 
				
			||||||
    const ignoreCase = $.step.parameters.ignoreCase;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const flags = [ignoreCase && 'i', 'g'].filter(Boolean).join('');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const timeoutId = setTimeout(() => {
 | 
					 | 
				
			||||||
      $.execution.exit();
 | 
					 | 
				
			||||||
    }, 100);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const regex = new RegExp(find, flags);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const replacedValue = input.replaceAll(regex, replace);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    clearTimeout(timeoutId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return replacedValue;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return input.replaceAll(find, replace);
 | 
					  return input.replaceAll(find, replace);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,3 @@
 | 
				
			|||||||
import listTransformOptions from './list-transform-options/index.js';
 | 
					import listTransformOptions from './list-transform-options/index.js';
 | 
				
			||||||
import listReplaceRegexOptions from './list-replace-regex-options/index.js';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default [listTransformOptions, listReplaceRegexOptions];
 | 
					export default [listTransformOptions];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,23 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List replace regex options',
 | 
					 | 
				
			||||||
  key: 'listReplaceRegexOptions',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    if (!$.step.parameters.useRegex) return [];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        label: 'Ignore case',
 | 
					 | 
				
			||||||
        key: 'ignoreCase',
 | 
					 | 
				
			||||||
        type: 'dropdown',
 | 
					 | 
				
			||||||
        required: true,
 | 
					 | 
				
			||||||
        description: 'Ignore case sensitivity.',
 | 
					 | 
				
			||||||
        variables: true,
 | 
					 | 
				
			||||||
        options: [
 | 
					 | 
				
			||||||
          { label: 'Yes', value: true },
 | 
					 | 
				
			||||||
          { label: 'No', value: false },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    ];
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -12,7 +12,6 @@ import stringToBase64 from './text/string-to-base64.js';
 | 
				
			|||||||
import encodeUri from './text/encode-uri.js';
 | 
					import encodeUri from './text/encode-uri.js';
 | 
				
			||||||
import trimWhitespace from './text/trim-whitespace.js';
 | 
					import trimWhitespace from './text/trim-whitespace.js';
 | 
				
			||||||
import useDefaultValue from './text/use-default-value.js';
 | 
					import useDefaultValue from './text/use-default-value.js';
 | 
				
			||||||
import parseStringifiedJson from './text/parse-stringified-json.js';
 | 
					 | 
				
			||||||
import performMathOperation from './numbers/perform-math-operation.js';
 | 
					import performMathOperation from './numbers/perform-math-operation.js';
 | 
				
			||||||
import randomNumber from './numbers/random-number.js';
 | 
					import randomNumber from './numbers/random-number.js';
 | 
				
			||||||
import formatNumber from './numbers/format-number.js';
 | 
					import formatNumber from './numbers/format-number.js';
 | 
				
			||||||
@@ -39,7 +38,6 @@ const options = {
 | 
				
			|||||||
  formatNumber,
 | 
					  formatNumber,
 | 
				
			||||||
  formatPhoneNumber,
 | 
					  formatPhoneNumber,
 | 
				
			||||||
  formatDateTime,
 | 
					  formatDateTime,
 | 
				
			||||||
  parseStringifiedJson,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +0,0 @@
 | 
				
			|||||||
const useDefaultValue = [
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    label: 'Input',
 | 
					 | 
				
			||||||
    key: 'input',
 | 
					 | 
				
			||||||
    type: 'string',
 | 
					 | 
				
			||||||
    required: true,
 | 
					 | 
				
			||||||
    description: 'Stringified JSON you want to parse.',
 | 
					 | 
				
			||||||
    variables: true,
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default useDefaultValue;
 | 
					 | 
				
			||||||
@@ -23,33 +23,6 @@ const replace = [
 | 
				
			|||||||
    description: 'Text that will replace the found text.',
 | 
					    description: 'Text that will replace the found text.',
 | 
				
			||||||
    variables: true,
 | 
					    variables: true,
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    label: 'Use Regular Expression',
 | 
					 | 
				
			||||||
    key: 'useRegex',
 | 
					 | 
				
			||||||
    type: 'dropdown',
 | 
					 | 
				
			||||||
    required: true,
 | 
					 | 
				
			||||||
    description: 'Use regex to search values.',
 | 
					 | 
				
			||||||
    variables: true,
 | 
					 | 
				
			||||||
    value: false,
 | 
					 | 
				
			||||||
    options: [
 | 
					 | 
				
			||||||
      { label: 'Yes', value: true },
 | 
					 | 
				
			||||||
      { label: 'No', value: false },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    additionalFields: {
 | 
					 | 
				
			||||||
      type: 'query',
 | 
					 | 
				
			||||||
      name: 'getDynamicFields',
 | 
					 | 
				
			||||||
      arguments: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          name: 'key',
 | 
					 | 
				
			||||||
          value: 'listReplaceRegexOptions',
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          name: 'parameters.useRegex',
 | 
					 | 
				
			||||||
          value: '{parameters.useRegex}',
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default replace;
 | 
					export default replace;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@ export default defineAction({
 | 
				
			|||||||
      label: 'Repo',
 | 
					      label: 'Repo',
 | 
				
			||||||
      key: 'repo',
 | 
					      key: 'repo',
 | 
				
			||||||
      type: 'dropdown',
 | 
					      type: 'dropdown',
 | 
				
			||||||
      required: true,
 | 
					      required: false,
 | 
				
			||||||
      variables: true,
 | 
					      variables: true,
 | 
				
			||||||
      source: {
 | 
					      source: {
 | 
				
			||||||
        type: 'query',
 | 
					        type: 'query',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,175 +0,0 @@
 | 
				
			|||||||
import defineAction from '../../../../helpers/define-action.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineAction({
 | 
					 | 
				
			||||||
  name: 'Find worksheet',
 | 
					 | 
				
			||||||
  key: 'findWorksheet',
 | 
					 | 
				
			||||||
  description:
 | 
					 | 
				
			||||||
    'Finds a worksheet by title. Optionally, create a worksheet if none are found.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Drive',
 | 
					 | 
				
			||||||
      key: 'driveId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description:
 | 
					 | 
				
			||||||
        'The Google Drive where your spreadsheet resides. If nothing is selected, then your personal Google Drive will be used.',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listDrives',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Spreadsheet',
 | 
					 | 
				
			||||||
      key: 'spreadsheetId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.driveId'],
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listSpreadsheets',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.driveId',
 | 
					 | 
				
			||||||
            value: '{parameters.driveId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Title',
 | 
					 | 
				
			||||||
      key: 'title',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description:
 | 
					 | 
				
			||||||
        'The worksheet title needs to match exactly, and the search is case-sensitive.',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Create worksheet if none are found.',
 | 
					 | 
				
			||||||
      key: 'createWorksheet',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      options: [
 | 
					 | 
				
			||||||
        { label: 'Yes', value: true },
 | 
					 | 
				
			||||||
        { label: 'No', value: false },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      additionalFields: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicFields',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listCreateWorksheetFields',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.createWorksheet',
 | 
					 | 
				
			||||||
            value: '{parameters.createWorksheet}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const createWorksheet = $.step.parameters.createWorksheet;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    async function findWorksheet() {
 | 
					 | 
				
			||||||
      const {
 | 
					 | 
				
			||||||
        data: { sheets },
 | 
					 | 
				
			||||||
      } = await $.http.get(`/v4/spreadsheets/${$.step.parameters.spreadsheetId}`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      const selectedSheet = sheets.find(
 | 
					 | 
				
			||||||
        (sheet) => sheet.properties.title === $.step.parameters.title
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      return selectedSheet;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const selectedSheet = await findWorksheet();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (selectedSheet) {
 | 
					 | 
				
			||||||
      $.setActionItem({
 | 
					 | 
				
			||||||
        raw: selectedSheet,
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (createWorksheet) {
 | 
					 | 
				
			||||||
      const headers = $.step.parameters.headers;
 | 
					 | 
				
			||||||
      const headerValues = headers.map((entry) => entry.header);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      const body = {
 | 
					 | 
				
			||||||
        requests: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            addSheet: {
 | 
					 | 
				
			||||||
              properties: {
 | 
					 | 
				
			||||||
                title: $.step.parameters.title,
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      const { data } = await $.http.post(
 | 
					 | 
				
			||||||
        `/v4/spreadsheets/${$.step.parameters.spreadsheetId}:batchUpdate`,
 | 
					 | 
				
			||||||
        body
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (headerValues.length) {
 | 
					 | 
				
			||||||
        const body = {
 | 
					 | 
				
			||||||
          requests: [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              updateCells: {
 | 
					 | 
				
			||||||
                rows: [
 | 
					 | 
				
			||||||
                  {
 | 
					 | 
				
			||||||
                    values: headerValues.map((header) => ({
 | 
					 | 
				
			||||||
                      userEnteredValue: { stringValue: header },
 | 
					 | 
				
			||||||
                    })),
 | 
					 | 
				
			||||||
                  },
 | 
					 | 
				
			||||||
                ],
 | 
					 | 
				
			||||||
                fields: '*',
 | 
					 | 
				
			||||||
                start: {
 | 
					 | 
				
			||||||
                  sheetId:
 | 
					 | 
				
			||||||
                    data.replies[data.replies.length - 1].addSheet.properties
 | 
					 | 
				
			||||||
                      .sheetId,
 | 
					 | 
				
			||||||
                  rowIndex: 0,
 | 
					 | 
				
			||||||
                  columnIndex: 0,
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          ],
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        await $.http.post(
 | 
					 | 
				
			||||||
          `/v4/spreadsheets/${$.step.parameters.spreadsheetId}:batchUpdate`,
 | 
					 | 
				
			||||||
          body
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const createdSheet = await findWorksheet();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $.setActionItem({
 | 
					 | 
				
			||||||
          raw: createdSheet,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.setActionItem({
 | 
					 | 
				
			||||||
      raw: null,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,11 +1,5 @@
 | 
				
			|||||||
import createSpreadsheet from './create-spreadsheet/index.js';
 | 
					import createSpreadsheet from './create-spreadsheet/index.js';
 | 
				
			||||||
import createSpreadsheetRow from './create-spreadsheet-row/index.js';
 | 
					import createSpreadsheetRow from './create-spreadsheet-row/index.js';
 | 
				
			||||||
import createWorksheet from './create-worksheet/index.js';
 | 
					import createWorksheet from './create-worksheet/index.js';
 | 
				
			||||||
import findWorksheet from './find-worksheet/index.js';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default [
 | 
					export default [createSpreadsheet, createSpreadsheetRow, createWorksheet];
 | 
				
			||||||
  createSpreadsheet,
 | 
					 | 
				
			||||||
  createSpreadsheetRow,
 | 
					 | 
				
			||||||
  createWorksheet,
 | 
					 | 
				
			||||||
  findWorksheet,
 | 
					 | 
				
			||||||
];
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,3 @@
 | 
				
			|||||||
import listSheetHeaders from './list-sheet-headers/index.js';
 | 
					import listSheetHeaders from './list-sheet-headers/index.js';
 | 
				
			||||||
import listCreateWorksheetFields from './list-create-worksheet-fields/index.js';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default [listSheetHeaders, listCreateWorksheetFields];
 | 
					export default [listSheetHeaders];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,26 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List create worksheet fields',
 | 
					 | 
				
			||||||
  key: 'listCreateWorksheetFields',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    if ($.step.parameters.createWorksheet) {
 | 
					 | 
				
			||||||
      return [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          label: 'Headers',
 | 
					 | 
				
			||||||
          key: 'headers',
 | 
					 | 
				
			||||||
          type: 'dynamic',
 | 
					 | 
				
			||||||
          required: false,
 | 
					 | 
				
			||||||
          fields: [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              label: 'Header',
 | 
					 | 
				
			||||||
              key: 'header',
 | 
					 | 
				
			||||||
              type: 'string',
 | 
					 | 
				
			||||||
              required: true,
 | 
					 | 
				
			||||||
              variables: true,
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          ],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -145,13 +145,6 @@ export default defineAction({
 | 
				
			|||||||
      responseData = Buffer.from(responseData).toString('base64');
 | 
					      responseData = Buffer.from(responseData).toString('base64');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $.setActionItem({
 | 
					    $.setActionItem({ raw: { data: responseData } });
 | 
				
			||||||
      raw: {
 | 
					 | 
				
			||||||
        data: responseData,
 | 
					 | 
				
			||||||
        headers: response.headers,
 | 
					 | 
				
			||||||
        status: response.status,
 | 
					 | 
				
			||||||
        statusText: response.statusText
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +0,0 @@
 | 
				
			|||||||
<svg xmlns:xlink="http://www.w3.org/1999/xlink" class="jff-logo-img" width="53" height="59" viewBox="0 0 53 59" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M14.4509 55.1332C15.5462 56.1951 14.7721 58.0143 13.2168 58.0143H3.4831C1.56265 58.0143 0 56.4995 0 54.6377V45.2017C0 43.6939 1.87664 42.9436 2.97195 44.0054L14.4509 55.1332Z" fill="#0A1551"></path><path d="M29.6655 55.8676C26.7843 53.0052 26.7843 48.3642 29.6655 45.5018L40.0638 35.1713C42.945 32.3089 47.6164 32.3089 50.4976 35.1713C53.3788 38.0338 53.3788 42.6747 50.4976 45.5371L40.0993 55.8676C37.2181 58.73 32.5468 58.73 29.6655 55.8676Z" fill="#FFB629"></path><path d="M2.1968 29.9101C-0.684414 27.0476 -0.684413 22.4067 2.1968 19.5443L19.696 2.14685C22.5772 -0.71559 27.2486 -0.715594 30.1298 2.14685C33.011 5.00929 33.011 9.65022 30.1298 12.5127L12.6306 29.9101C9.74937 32.7725 5.078 32.7725 2.1968 29.9101Z" fill="#0099FF"></path><path d="M16.5015 42.3095C13.6203 39.4471 13.6203 34.8062 16.5015 31.9437L40.1461 8.45322C43.0273 5.59079 47.6986 5.59079 50.5798 8.45322C53.4611 11.3157 53.4611 15.9566 50.5798 18.819L26.9353 42.3095C24.0541 45.1719 19.3827 45.1719 16.5015 42.3095Z" fill="#FF6100"></path></svg>
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 1.2 KiB  | 
@@ -1,30 +0,0 @@
 | 
				
			|||||||
import verifyCredentials from './verify-credentials.js';
 | 
					 | 
				
			||||||
import isStillVerified from './is-still-verified.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default {
 | 
					 | 
				
			||||||
  fields: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      key: 'apiUrl',
 | 
					 | 
				
			||||||
      label: 'API URL',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      readOnly: false,
 | 
					 | 
				
			||||||
      value: 'https://api.jotform.com',
 | 
					 | 
				
			||||||
      placeholder: 'https://${subdomain}.jotform.com/api',
 | 
					 | 
				
			||||||
      clickToCopy: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      key: 'apiKey',
 | 
					 | 
				
			||||||
      label: 'API Key',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      readOnly: false,
 | 
					 | 
				
			||||||
      value: null,
 | 
					 | 
				
			||||||
      placeholder: null,
 | 
					 | 
				
			||||||
      clickToCopy: false,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  verifyCredentials,
 | 
					 | 
				
			||||||
  isStillVerified,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,8 +0,0 @@
 | 
				
			|||||||
import getCurrentUser from '../common/get-current-user.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const isStillVerified = async ($) => {
 | 
					 | 
				
			||||||
  const user = await getCurrentUser($);
 | 
					 | 
				
			||||||
  return !!user.username;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default isStillVerified;
 | 
					 | 
				
			||||||
@@ -1,12 +0,0 @@
 | 
				
			|||||||
import getCurrentUser from '../common/get-current-user.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const verifyCredentials = async ($) => {
 | 
					 | 
				
			||||||
  const user = await getCurrentUser($);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  await $.auth.set({
 | 
					 | 
				
			||||||
    screenName: user.name,
 | 
					 | 
				
			||||||
    apiKey: $.auth.data.apiKey,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default verifyCredentials;
 | 
					 | 
				
			||||||
@@ -1,9 +0,0 @@
 | 
				
			|||||||
const addAuthHeader = ($, requestConfig) => {
 | 
					 | 
				
			||||||
  if ($.auth.data?.apiKey) {
 | 
					 | 
				
			||||||
    requestConfig.headers['APIKEY'] = `${$.auth.data.apiKey}`;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return requestConfig;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default addAuthHeader;
 | 
					 | 
				
			||||||
@@ -1,7 +0,0 @@
 | 
				
			|||||||
const getCurrentUser = async ($) => {
 | 
					 | 
				
			||||||
  const response = await $.http.get('/user');
 | 
					 | 
				
			||||||
  const currentUser = response.data.content;
 | 
					 | 
				
			||||||
  return currentUser;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default getCurrentUser;
 | 
					 | 
				
			||||||
@@ -1,11 +0,0 @@
 | 
				
			|||||||
const setBaseUrl = ($, requestConfig) => {
 | 
					 | 
				
			||||||
  if ($.auth.data.apiUrl) {
 | 
					 | 
				
			||||||
    requestConfig.baseURL = $.auth.data.apiUrl;
 | 
					 | 
				
			||||||
  } else if ($.app.apiBaseUrl) {
 | 
					 | 
				
			||||||
    requestConfig.baseURL = $.app.apiBaseUrl;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return requestConfig;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default setBaseUrl;
 | 
					 | 
				
			||||||
@@ -1,3 +0,0 @@
 | 
				
			|||||||
import listForms from './list-forms/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default [listForms];
 | 
					 | 
				
			||||||
@@ -1,41 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List forms',
 | 
					 | 
				
			||||||
  key: 'listForms',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const forms = {
 | 
					 | 
				
			||||||
      data: [],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    let hasMore = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const params = {
 | 
					 | 
				
			||||||
      limit: 1000,
 | 
					 | 
				
			||||||
      offset: 0,
 | 
					 | 
				
			||||||
      orderby: 'created_at',
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    do {
 | 
					 | 
				
			||||||
      const { data } = await $.http.get('/user/forms', { params });
 | 
					 | 
				
			||||||
      params.offset = params.offset + params.limit;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (data.content?.length) {
 | 
					 | 
				
			||||||
        for (const form of data.content) {
 | 
					 | 
				
			||||||
          if (form.status === 'ENABLED') {
 | 
					 | 
				
			||||||
            forms.data.push({
 | 
					 | 
				
			||||||
              value: form.id,
 | 
					 | 
				
			||||||
              name: form.title,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (data.resultSet.count >= data.resultSet.limit) {
 | 
					 | 
				
			||||||
        hasMore = true;
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        hasMore = false;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } while (hasMore);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return forms;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,21 +0,0 @@
 | 
				
			|||||||
import defineApp from '../../helpers/define-app.js';
 | 
					 | 
				
			||||||
import addAuthHeader from './common/add-auth-header.js';
 | 
					 | 
				
			||||||
import auth from './auth/index.js';
 | 
					 | 
				
			||||||
import setBaseUrl from './common/set-base-url.js';
 | 
					 | 
				
			||||||
import triggers from './triggers/index.js';
 | 
					 | 
				
			||||||
import dynamicData from './dynamic-data/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineApp({
 | 
					 | 
				
			||||||
  name: 'Jotform',
 | 
					 | 
				
			||||||
  key: 'jotform',
 | 
					 | 
				
			||||||
  iconUrl: '{BASE_URL}/apps/jotform/assets/favicon.svg',
 | 
					 | 
				
			||||||
  authDocUrl: 'https://automatisch.io/docs/apps/jotform/connection',
 | 
					 | 
				
			||||||
  supportsConnections: true,
 | 
					 | 
				
			||||||
  baseUrl: 'https://www.jotform.com',
 | 
					 | 
				
			||||||
  apiBaseUrl: 'https://api.jotform.com',
 | 
					 | 
				
			||||||
  primaryColor: 'FF6100',
 | 
					 | 
				
			||||||
  beforeRequest: [setBaseUrl, addAuthHeader],
 | 
					 | 
				
			||||||
  auth,
 | 
					 | 
				
			||||||
  triggers,
 | 
					 | 
				
			||||||
  dynamicData,
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,3 +0,0 @@
 | 
				
			|||||||
import newSubmissions from './new-submissions/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default [newSubmissions];
 | 
					 | 
				
			||||||
@@ -1,109 +0,0 @@
 | 
				
			|||||||
import Crypto from 'crypto';
 | 
					 | 
				
			||||||
import { URLSearchParams } from 'url';
 | 
					 | 
				
			||||||
import defineTrigger from '../../../../helpers/define-trigger.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineTrigger({
 | 
					 | 
				
			||||||
  name: 'New submissions',
 | 
					 | 
				
			||||||
  key: 'newSubmissions',
 | 
					 | 
				
			||||||
  type: 'webhook',
 | 
					 | 
				
			||||||
  description:
 | 
					 | 
				
			||||||
    'Triggers when a new submission has been added to a specific form.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Form',
 | 
					 | 
				
			||||||
      key: 'formId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listForms',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const dataItem = {
 | 
					 | 
				
			||||||
      raw: $.request.body,
 | 
					 | 
				
			||||||
      meta: {
 | 
					 | 
				
			||||||
        internalId: Crypto.randomUUID(),
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.pushTriggerItem(dataItem);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async testRun($) {
 | 
					 | 
				
			||||||
    const sampleEventData = {
 | 
					 | 
				
			||||||
      ip: '127.0.0.1',
 | 
					 | 
				
			||||||
      type: 'WEB',
 | 
					 | 
				
			||||||
      appID: '',
 | 
					 | 
				
			||||||
      event: '',
 | 
					 | 
				
			||||||
      action: '',
 | 
					 | 
				
			||||||
      formID: Crypto.randomUUID(),
 | 
					 | 
				
			||||||
      parent: '',
 | 
					 | 
				
			||||||
      pretty: 'Name:test, E-mail:user@automatisch.io',
 | 
					 | 
				
			||||||
      teamID: '',
 | 
					 | 
				
			||||||
      unread: '',
 | 
					 | 
				
			||||||
      product: '',
 | 
					 | 
				
			||||||
      subject: '',
 | 
					 | 
				
			||||||
      isSilent: '',
 | 
					 | 
				
			||||||
      username: 'username',
 | 
					 | 
				
			||||||
      deviceIDs: 'Array',
 | 
					 | 
				
			||||||
      formTitle: 'Opt-In Form-Get Free Email Updates!',
 | 
					 | 
				
			||||||
      fromTable: '',
 | 
					 | 
				
			||||||
      customBody: '',
 | 
					 | 
				
			||||||
      documentID: '',
 | 
					 | 
				
			||||||
      rawRequest: '',
 | 
					 | 
				
			||||||
      webhookURL: '',
 | 
					 | 
				
			||||||
      customTitle: '',
 | 
					 | 
				
			||||||
      trackAction: 'Array',
 | 
					 | 
				
			||||||
      customParams: '',
 | 
					 | 
				
			||||||
      submissionID: Crypto.randomUUID(),
 | 
					 | 
				
			||||||
      customBodyParams: 'Array',
 | 
					 | 
				
			||||||
      customTitleParams: 'Array',
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const dataItem = {
 | 
					 | 
				
			||||||
      raw: sampleEventData,
 | 
					 | 
				
			||||||
      meta: {
 | 
					 | 
				
			||||||
        internalId: sampleEventData.submissionID,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.pushTriggerItem(dataItem);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async registerHook($) {
 | 
					 | 
				
			||||||
    const formId = $.step.parameters.formId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const params = new URLSearchParams({
 | 
					 | 
				
			||||||
      webhookURL: $.webhookUrl,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.post(
 | 
					 | 
				
			||||||
      `/form/${formId}/webhooks`,
 | 
					 | 
				
			||||||
      params.toString()
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    await $.flow.setRemoteWebhookId(data.content[0]);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async unregisterHook($) {
 | 
					 | 
				
			||||||
    const formId = $.step.parameters.formId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.get(`/form/${formId}/webhooks`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const webhookURLs = Object.values(data.content);
 | 
					 | 
				
			||||||
    const webhookId = webhookURLs.findIndex((url) => url === $.webhookUrl);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    await $.http.delete(`/form/${formId}/webhooks/${webhookId}`);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
							
								
								
									
										28
									
								
								packages/backend/src/apps/libretranslate/assets/favicon.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								packages/backend/src/apps/libretranslate/assets/favicon.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="187.04305" height="188.81523" viewBox="0 0 49.488472 49.957363" version="1.1" id="svg8">
 | 
				
			||||||
 | 
					  <defs id="defs2">
 | 
				
			||||||
 | 
					    <rect x="25.162016" y="84.327377" width="71.115189" height="52.835255" id="rect835"/>
 | 
				
			||||||
 | 
					    <rect x="25.162016" y="84.327377" width="71.115189" height="52.835255" id="rect835-7"/>
 | 
				
			||||||
 | 
					    <rect x="25.162016" y="84.327377" width="71.115189" height="52.835255" id="rect874"/>
 | 
				
			||||||
 | 
					    <rect x="25.162016" y="84.327377" width="71.115189" height="52.835255" id="rect923"/>
 | 
				
			||||||
 | 
					  </defs>
 | 
				
			||||||
 | 
					  <metadata id="metadata5">
 | 
				
			||||||
 | 
					    <rdf:RDF>
 | 
				
			||||||
 | 
					      <cc:Work rdf:about="">
 | 
				
			||||||
 | 
					        <dc:format>image/svg+xml</dc:format>
 | 
				
			||||||
 | 
					        <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
 | 
				
			||||||
 | 
					        <dc:title/>
 | 
				
			||||||
 | 
					      </cc:Work>
 | 
				
			||||||
 | 
					    </rdf:RDF>
 | 
				
			||||||
 | 
					  </metadata>
 | 
				
			||||||
 | 
					  <g id="layer1" transform="translate(-23.040803,-26.932047)">
 | 
				
			||||||
 | 
					    <g id="g861" transform="translate(-42.114518,-17.993737)" style="fill:#000000">
 | 
				
			||||||
 | 
					      <g aria-label="众" transform="matrix(4.3205134,0,0,4.3205134,-37.271798,-327.6536)" id="text833" style="font-style:normal;font-weight:normal;font-size:10.5833px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect835);fill:#000000;fill-opacity:1;stroke:none">
 | 
				
			||||||
 | 
					        <path d="m 34.996103,90.121035 -0.614947,0.759641 q -2.754346,-1.41593 -3.948067,-2.950715 -1.167884,1.617467 -3.7672,2.888703 L 26.0096,90.084861 q 3.457142,-1.601964 4.283963,-3.849882 l 0.878496,0.273884 q -0.175699,0.516763 -0.232543,0.604613 1.116207,1.596797 4.056587,3.007559 z m 0.165364,4.91958 -0.676959,0.645954 q -1.514115,-1.157549 -2.346102,-2.826692 -0.547769,1.550288 -2.268589,2.806021 l -0.676959,-0.625283 q 1.19889,-0.795814 1.798334,-1.875848 0.599445,-1.080034 0.682127,-3.079906 l 0.909502,0.07751 q 0,0.268716 -0.04134,0.671791 l -0.03617,0.361734 q 0,0.273884 0.30489,1.033525 0.310058,0.754474 0.899167,1.467606 0.594277,0.707965 1.452103,1.343583 z m -4.800725,-1.374588 -0.702797,0.63045 q -0.594277,-0.780312 -1.162716,-1.276404 -0.651121,1.421098 -2.020542,2.676831 l -0.687295,-0.614948 q 1.229895,-1.095537 1.767329,-2.201409 0.5426,-1.105872 0.697629,-2.795686 l 0.919838,0.09819 q -0.103353,0.940508 -0.366902,1.91719 1.00252,0.862993 1.555456,1.565791 z" style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'Adobe Garamond Pro';-inkscape-font-specification:'Adobe Garamond Pro Bold';fill:#00000" id="path961"/>
 | 
				
			||||||
 | 
					      </g>
 | 
				
			||||||
 | 
					      <g aria-label="L" id="text841" style="font-style:normal;font-weight:normal;font-size:43.3964px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.08492">
 | 
				
			||||||
 | 
					        <path d="M 84.81389,94.883148 V 91.324643 H 69.191186 V 63.247172 h -4.035865 v 31.635976 z" style="fill:#000000;stroke-width:1.08492" id="path964"/>
 | 
				
			||||||
 | 
					      </g>
 | 
				
			||||||
 | 
					    </g>
 | 
				
			||||||
 | 
					    <g id="g921" transform="translate(29.198135,-14.725175)"/>
 | 
				
			||||||
 | 
					  </g>
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 3.1 KiB  | 
@@ -16,14 +16,25 @@ export default {
 | 
				
			|||||||
      clickToCopy: false,
 | 
					      clickToCopy: false,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      key: 'apiKey',
 | 
					      key: 'instanceUrl',
 | 
				
			||||||
      label: 'API Key',
 | 
					      label: 'Instance URL',
 | 
				
			||||||
      type: 'string',
 | 
					      type: 'string',
 | 
				
			||||||
      required: true,
 | 
					      required: false,
 | 
				
			||||||
      readOnly: false,
 | 
					      readOnly: false,
 | 
				
			||||||
      value: null,
 | 
					      value: null,
 | 
				
			||||||
      placeholder: null,
 | 
					      placeholder: null,
 | 
				
			||||||
      description: 'MailerLite API key of your account.',
 | 
					      description: 'For the self hosted version.',
 | 
				
			||||||
 | 
					      clickToCopy: false,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      key: 'apiKey',
 | 
				
			||||||
 | 
					      label: 'API Key',
 | 
				
			||||||
 | 
					      type: 'string',
 | 
				
			||||||
 | 
					      required: false,
 | 
				
			||||||
 | 
					      readOnly: false,
 | 
				
			||||||
 | 
					      value: null,
 | 
				
			||||||
 | 
					      placeholder: null,
 | 
				
			||||||
 | 
					      description: 'LibreTranslate API key of your account.',
 | 
				
			||||||
      clickToCopy: false,
 | 
					      clickToCopy: false,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
@@ -1,5 +1,9 @@
 | 
				
			|||||||
const verifyCredentials = async ($) => {
 | 
					const verifyCredentials = async ($) => {
 | 
				
			||||||
  await $.http.get('/campaigns');
 | 
					  const body = {
 | 
				
			||||||
 | 
					    q: 'Hi!',
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  await $.http.post('/detect', body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  await $.auth.set({
 | 
					  await $.auth.set({
 | 
				
			||||||
    screenName: $.auth.data.screenName,
 | 
					    screenName: $.auth.data.screenName,
 | 
				
			||||||
@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					const addApiKey = ($, requestConfig) => {
 | 
				
			||||||
 | 
					  const apiKey = $.auth.data.apiKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  requestConfig.data = { api_key: apiKey, ...(requestConfig.data || {}) };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return requestConfig;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default addApiKey;
 | 
				
			||||||
@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					const setBaseUrl = ($, requestConfig) => {
 | 
				
			||||||
 | 
					  const instanceUrl = $.auth.data.instanceUrl;
 | 
				
			||||||
 | 
					  const apiKey = $.auth.data.apiKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (instanceUrl) {
 | 
				
			||||||
 | 
					    requestConfig.baseURL = instanceUrl;
 | 
				
			||||||
 | 
					  } else if ($.app.apiBaseUrl) {
 | 
				
			||||||
 | 
					    requestConfig.baseURL = $.app.apiBaseUrl;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  requestConfig.data = { api_key: apiKey, ...(requestConfig.data || {}) };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return requestConfig;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default setBaseUrl;
 | 
				
			||||||
							
								
								
									
										17
									
								
								packages/backend/src/apps/libretranslate/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								packages/backend/src/apps/libretranslate/index.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					import defineApp from '../../helpers/define-app.js';
 | 
				
			||||||
 | 
					import auth from './auth/index.js';
 | 
				
			||||||
 | 
					import addApiKey from './common/add-api-key.js';
 | 
				
			||||||
 | 
					import setBaseUrl from './common/set-base-url.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default defineApp({
 | 
				
			||||||
 | 
					  name: 'LibreTranslate',
 | 
				
			||||||
 | 
					  key: 'libretranslate',
 | 
				
			||||||
 | 
					  iconUrl: '{BASE_URL}/apps/libretranslate/assets/favicon.svg',
 | 
				
			||||||
 | 
					  authDocUrl: '{DOCS_URL}/apps/libretranslate/connection',
 | 
				
			||||||
 | 
					  supportsConnections: true,
 | 
				
			||||||
 | 
					  baseUrl: 'https://libretranslate.com',
 | 
				
			||||||
 | 
					  apiBaseUrl: 'https://libretranslate.com',
 | 
				
			||||||
 | 
					  primaryColor: 'ffffff',
 | 
				
			||||||
 | 
					  beforeRequest: [setBaseUrl, addApiKey],
 | 
				
			||||||
 | 
					  auth,
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@@ -1,180 +0,0 @@
 | 
				
			|||||||
import defineAction from '../../../../helpers/define-action.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineAction({
 | 
					 | 
				
			||||||
  name: 'Create campaign',
 | 
					 | 
				
			||||||
  key: 'createCampaign',
 | 
					 | 
				
			||||||
  description: 'Creates a new campaign draft.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Campaign Name',
 | 
					 | 
				
			||||||
      key: 'campaignName',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Audience',
 | 
					 | 
				
			||||||
      key: 'audienceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listAudiences',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Segment or Tag',
 | 
					 | 
				
			||||||
      key: 'segmentOrTagId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.audienceId'],
 | 
					 | 
				
			||||||
      description:
 | 
					 | 
				
			||||||
        'Choose the specific segment or tag to which you"d like to direct the campaign. If no segment or tag is chosen, the campaign will be distributed to the entire audience previously selected.',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listSegmentsOrTags',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.audienceId',
 | 
					 | 
				
			||||||
            value: '{parameters.audienceId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Email Subject',
 | 
					 | 
				
			||||||
      key: 'emailSubject',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Preview Text',
 | 
					 | 
				
			||||||
      key: 'previewText',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description:
 | 
					 | 
				
			||||||
        'The snippet will be visible in the inbox following the subject line.',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'From Name',
 | 
					 | 
				
			||||||
      key: 'fromName',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: 'The "from" name on the campaign (not an email address).',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'From Email Address',
 | 
					 | 
				
			||||||
      key: 'fromEmailAddress',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: 'The reply-to email address for the campaign.',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'To Name',
 | 
					 | 
				
			||||||
      key: 'toName',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description:
 | 
					 | 
				
			||||||
        'Supports *|MERGETAGS|* for recipient name, such as *|FNAME|*, *|LNAME|*, *|FNAME|* *|LNAME|*, etc.',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Template',
 | 
					 | 
				
			||||||
      key: 'templateId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description:
 | 
					 | 
				
			||||||
        'Select either a template or provide HTML email content, you cannot provide both. If both fields are left blank, the campaign draft will have no content.',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listTemplates',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Email Content (HTML)',
 | 
					 | 
				
			||||||
      key: 'emailContent',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: false,
 | 
					 | 
				
			||||||
      description:
 | 
					 | 
				
			||||||
        'Select either a template or provide HTML email content, you cannot provide both. If both fields are left blank, the campaign draft will have no content.',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const {
 | 
					 | 
				
			||||||
      campaignName,
 | 
					 | 
				
			||||||
      audienceId,
 | 
					 | 
				
			||||||
      segmentOrTagId,
 | 
					 | 
				
			||||||
      emailSubject,
 | 
					 | 
				
			||||||
      previewText,
 | 
					 | 
				
			||||||
      fromName,
 | 
					 | 
				
			||||||
      fromEmailAddress,
 | 
					 | 
				
			||||||
      toName,
 | 
					 | 
				
			||||||
      templateId,
 | 
					 | 
				
			||||||
      emailContent,
 | 
					 | 
				
			||||||
    } = $.step.parameters;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const body = {
 | 
					 | 
				
			||||||
      type: 'regular',
 | 
					 | 
				
			||||||
      recipients: {
 | 
					 | 
				
			||||||
        list_id: audienceId,
 | 
					 | 
				
			||||||
        segment_opts: {
 | 
					 | 
				
			||||||
          saved_segment_id: Number(segmentOrTagId),
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      settings: {
 | 
					 | 
				
			||||||
        subject_line: emailSubject,
 | 
					 | 
				
			||||||
        reply_to: fromEmailAddress,
 | 
					 | 
				
			||||||
        title: campaignName,
 | 
					 | 
				
			||||||
        preview_text: previewText,
 | 
					 | 
				
			||||||
        from_name: fromName,
 | 
					 | 
				
			||||||
        to_name: toName,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data: campaign } = await $.http.post('/3.0/campaigns', body);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const campaignBody = {
 | 
					 | 
				
			||||||
      template: {
 | 
					 | 
				
			||||||
        id: Number(templateId),
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      html: emailContent,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.put(
 | 
					 | 
				
			||||||
      `/3.0/campaigns/${campaign.id}/content`,
 | 
					 | 
				
			||||||
      campaignBody
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.setActionItem({
 | 
					 | 
				
			||||||
      raw: data,
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,4 +0,0 @@
 | 
				
			|||||||
import createCampaign from './create-campaign/index.js';
 | 
					 | 
				
			||||||
import sendCampaign from './send-campaign/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default [createCampaign, sendCampaign];
 | 
					 | 
				
			||||||
@@ -1,39 +0,0 @@
 | 
				
			|||||||
import defineAction from '../../../../helpers/define-action.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineAction({
 | 
					 | 
				
			||||||
  name: 'Send campaign',
 | 
					 | 
				
			||||||
  key: 'sendCampaign',
 | 
					 | 
				
			||||||
  description: 'Sends a campaign draft.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Campaign',
 | 
					 | 
				
			||||||
      key: 'campaignId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listCampaigns',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const campaignId = $.step.parameters.campaignId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    await $.http.post(`/3.0/campaigns/${campaignId}/actions/send`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.setActionItem({
 | 
					 | 
				
			||||||
      raw: {
 | 
					 | 
				
			||||||
        output: 'sent',
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
		 Before Width: | Height: | Size: 5.0 KiB  | 
@@ -1,19 +0,0 @@
 | 
				
			|||||||
import { URLSearchParams } from 'url';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default async function generateAuthUrl($) {
 | 
					 | 
				
			||||||
  const oauthRedirectUrlField = $.app.auth.fields.find(
 | 
					 | 
				
			||||||
    (field) => field.key == 'oAuthRedirectUrl'
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
  const redirectUri = oauthRedirectUrlField.value;
 | 
					 | 
				
			||||||
  const searchParams = new URLSearchParams({
 | 
					 | 
				
			||||||
    response_type: 'code',
 | 
					 | 
				
			||||||
    client_id: $.auth.data.clientId,
 | 
					 | 
				
			||||||
    redirect_uri: redirectUri,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const url = `https://login.mailchimp.com/oauth2/authorize?${searchParams.toString()}`;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  await $.auth.set({
 | 
					 | 
				
			||||||
    url,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,46 +0,0 @@
 | 
				
			|||||||
import generateAuthUrl from './generate-auth-url.js';
 | 
					 | 
				
			||||||
import verifyCredentials from './verify-credentials.js';
 | 
					 | 
				
			||||||
import isStillVerified from './is-still-verified.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default {
 | 
					 | 
				
			||||||
  fields: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      key: 'oAuthRedirectUrl',
 | 
					 | 
				
			||||||
      label: 'OAuth Redirect URL',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      readOnly: true,
 | 
					 | 
				
			||||||
      value: '{WEB_APP_URL}/app/mailchimp/connections/add',
 | 
					 | 
				
			||||||
      placeholder: null,
 | 
					 | 
				
			||||||
      description:
 | 
					 | 
				
			||||||
        'When asked to input a redirect URL in Mailchimp, enter the URL above.',
 | 
					 | 
				
			||||||
      clickToCopy: true,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      key: 'clientId',
 | 
					 | 
				
			||||||
      label: 'Client ID',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      readOnly: false,
 | 
					 | 
				
			||||||
      value: null,
 | 
					 | 
				
			||||||
      placeholder: null,
 | 
					 | 
				
			||||||
      description: null,
 | 
					 | 
				
			||||||
      clickToCopy: false,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      key: 'clientSecret',
 | 
					 | 
				
			||||||
      label: 'Client Secret',
 | 
					 | 
				
			||||||
      type: 'string',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      readOnly: false,
 | 
					 | 
				
			||||||
      value: null,
 | 
					 | 
				
			||||||
      placeholder: null,
 | 
					 | 
				
			||||||
      description: null,
 | 
					 | 
				
			||||||
      clickToCopy: false,
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  generateAuthUrl,
 | 
					 | 
				
			||||||
  verifyCredentials,
 | 
					 | 
				
			||||||
  isStillVerified,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,8 +0,0 @@
 | 
				
			|||||||
import getCurrentUser from '../common/get-current-user.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const isStillVerified = async ($) => {
 | 
					 | 
				
			||||||
  const currentUser = await getCurrentUser($);
 | 
					 | 
				
			||||||
  return !!currentUser.user_id;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default isStillVerified;
 | 
					 | 
				
			||||||
@@ -1,40 +0,0 @@
 | 
				
			|||||||
import getCurrentUser from '../common/get-current-user.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const verifyCredentials = async ($) => {
 | 
					 | 
				
			||||||
  const oauthRedirectUrlField = $.app.auth.fields.find(
 | 
					 | 
				
			||||||
    (field) => field.key == 'oAuthRedirectUrl'
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
  const redirectUri = oauthRedirectUrlField.value;
 | 
					 | 
				
			||||||
  const params = new URLSearchParams({
 | 
					 | 
				
			||||||
    grant_type: 'authorization_code',
 | 
					 | 
				
			||||||
    client_id: $.auth.data.clientId,
 | 
					 | 
				
			||||||
    client_secret: $.auth.data.clientSecret,
 | 
					 | 
				
			||||||
    redirect_uri: redirectUri,
 | 
					 | 
				
			||||||
    code: $.auth.data.code,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const { data } = await $.http.post(
 | 
					 | 
				
			||||||
    'https://login.mailchimp.com/oauth2/token',
 | 
					 | 
				
			||||||
    params.toString()
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  await $.auth.set({
 | 
					 | 
				
			||||||
    accessToken: data.access_token,
 | 
					 | 
				
			||||||
    tokenType: data.token_type,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const currentUser = await getCurrentUser($);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  await $.auth.set({
 | 
					 | 
				
			||||||
    clientId: $.auth.data.clientId,
 | 
					 | 
				
			||||||
    clientSecret: $.auth.data.clientSecret,
 | 
					 | 
				
			||||||
    scope: $.auth.data.scope,
 | 
					 | 
				
			||||||
    idToken: data.id_token,
 | 
					 | 
				
			||||||
    expiresIn: data.expires_in,
 | 
					 | 
				
			||||||
    refreshToken: data.refresh_token,
 | 
					 | 
				
			||||||
    serverPrefix: currentUser.dc,
 | 
					 | 
				
			||||||
    screenName: currentUser.login.login_name,
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default verifyCredentials;
 | 
					 | 
				
			||||||
@@ -1,12 +0,0 @@
 | 
				
			|||||||
const addAuthHeader = ($, requestConfig) => {
 | 
					 | 
				
			||||||
  if (
 | 
					 | 
				
			||||||
    !requestConfig.additionalProperties?.skipAddingAuthHeader &&
 | 
					 | 
				
			||||||
    $.auth.data?.accessToken
 | 
					 | 
				
			||||||
  ) {
 | 
					 | 
				
			||||||
    requestConfig.headers.Authorization = `Bearer ${$.auth.data.accessToken}`;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return requestConfig;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default addAuthHeader;
 | 
					 | 
				
			||||||
@@ -1,18 +0,0 @@
 | 
				
			|||||||
const getCurrentUser = async ($) => {
 | 
					 | 
				
			||||||
  const { data: currentUser } = await $.http.get(
 | 
					 | 
				
			||||||
    'https://login.mailchimp.com/oauth2/metadata',
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      headers: {
 | 
					 | 
				
			||||||
        Authorization: `OAuth ${$.auth.data.accessToken}`,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      additionalProperties: {
 | 
					 | 
				
			||||||
        skipAddingAuthHeader: true,
 | 
					 | 
				
			||||||
        skipAddingBaseUrl: true,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return currentUser;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default getCurrentUser;
 | 
					 | 
				
			||||||
@@ -1,10 +0,0 @@
 | 
				
			|||||||
const setBaseUrl = ($, requestConfig) => {
 | 
					 | 
				
			||||||
  const serverPrefix = $.auth.data.serverPrefix;
 | 
					 | 
				
			||||||
  if (!requestConfig.additionalProperties?.skipAddingBaseUrl && serverPrefix) {
 | 
					 | 
				
			||||||
    requestConfig.baseURL = `https://${serverPrefix}.api.mailchimp.com`;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return requestConfig;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default setBaseUrl;
 | 
					 | 
				
			||||||
@@ -1,6 +0,0 @@
 | 
				
			|||||||
import listAudiences from './list-audiences/index.js';
 | 
					 | 
				
			||||||
import listCampaigns from './list-campaigns/index.js';
 | 
					 | 
				
			||||||
import listTags from './list-segments-or-tags/index.js';
 | 
					 | 
				
			||||||
import listTemplates from './list-templates/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default [listAudiences, listCampaigns, listTags, listTemplates];
 | 
					 | 
				
			||||||
@@ -1,40 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List audiences',
 | 
					 | 
				
			||||||
  key: 'listAudiences',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const audiences = {
 | 
					 | 
				
			||||||
      data: [],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    let hasMore = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const params = {
 | 
					 | 
				
			||||||
      sort_field: 'date_created',
 | 
					 | 
				
			||||||
      sort_dir: 'DESC',
 | 
					 | 
				
			||||||
      count: 1000,
 | 
					 | 
				
			||||||
      offset: 0,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    do {
 | 
					 | 
				
			||||||
      const { data } = await $.http.get('/3.0/lists', { params });
 | 
					 | 
				
			||||||
      params.offset = params.offset + params.count;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (data?.lists) {
 | 
					 | 
				
			||||||
        for (const audience of data.lists) {
 | 
					 | 
				
			||||||
          audiences.data.push({
 | 
					 | 
				
			||||||
            value: audience.id,
 | 
					 | 
				
			||||||
            name: audience.name,
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (data.total_items > params.offset) {
 | 
					 | 
				
			||||||
        hasMore = true;
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        hasMore = false;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } while (hasMore);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return audiences;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,42 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List campaigns',
 | 
					 | 
				
			||||||
  key: 'listCampaigns',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const campaigns = {
 | 
					 | 
				
			||||||
      data: [],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    let hasMore = false;
 | 
					 | 
				
			||||||
    const audienceId = $.step.parameters.audienceId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const params = {
 | 
					 | 
				
			||||||
      list_id: audienceId,
 | 
					 | 
				
			||||||
      sort_field: 'create_time',
 | 
					 | 
				
			||||||
      sort_dir: 'DESC',
 | 
					 | 
				
			||||||
      count: 1000,
 | 
					 | 
				
			||||||
      offset: 0,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    do {
 | 
					 | 
				
			||||||
      const { data } = await $.http.get('/3.0/campaigns', { params });
 | 
					 | 
				
			||||||
      params.offset = params.offset + params.count;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (data?.campaigns) {
 | 
					 | 
				
			||||||
        for (const campaign of data.campaigns) {
 | 
					 | 
				
			||||||
          campaigns.data.push({
 | 
					 | 
				
			||||||
            value: campaign.id,
 | 
					 | 
				
			||||||
            name: campaign.settings.title || campaign.settings.subject_line || 'Unnamed campaign',
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (data.total_items > params.offset) {
 | 
					 | 
				
			||||||
        hasMore = true;
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        hasMore = false;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } while (hasMore);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return campaigns;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,44 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List segments or tags',
 | 
					 | 
				
			||||||
  key: 'listSegmentsOrTags',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const segmentsOrTags = {
 | 
					 | 
				
			||||||
      data: [],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    const audienceId = $.step.parameters.audienceId;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!audienceId) {
 | 
					 | 
				
			||||||
      return segmentsOrTags;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const {
 | 
					 | 
				
			||||||
      data: { tags: allTags },
 | 
					 | 
				
			||||||
    } = await $.http.get(`/3.0/lists/${audienceId}/tag-search`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const {
 | 
					 | 
				
			||||||
      data: { segments },
 | 
					 | 
				
			||||||
    } = await $.http.get(`/3.0/lists/${audienceId}/segments`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const mergedArray = [...allTags, ...segments].reduce(
 | 
					 | 
				
			||||||
      (accumulator, current) => {
 | 
					 | 
				
			||||||
        if (!accumulator.some((item) => item.id === current.id)) {
 | 
					 | 
				
			||||||
          accumulator.push(current);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return accumulator;
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      []
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (mergedArray?.length) {
 | 
					 | 
				
			||||||
      for (const tagOrSegment of mergedArray) {
 | 
					 | 
				
			||||||
        segmentsOrTags.data.push({
 | 
					 | 
				
			||||||
          value: tagOrSegment.id,
 | 
					 | 
				
			||||||
          name: tagOrSegment.name,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return segmentsOrTags;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,30 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
  name: 'List templates',
 | 
					 | 
				
			||||||
  key: 'listTemplates',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const templates = {
 | 
					 | 
				
			||||||
      data: [],
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const params = {
 | 
					 | 
				
			||||||
      sort_field: 'date_created',
 | 
					 | 
				
			||||||
      sort_dir: 'DESC',
 | 
					 | 
				
			||||||
      count: 1000,
 | 
					 | 
				
			||||||
      offset: 0,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const { data } = await $.http.get('/3.0/templates', { params });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (data?.templates) {
 | 
					 | 
				
			||||||
      for (const template of data.templates) {
 | 
					 | 
				
			||||||
        templates.data.push({
 | 
					 | 
				
			||||||
          value: template.id,
 | 
					 | 
				
			||||||
          name: template.name,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return templates;
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -1,23 +0,0 @@
 | 
				
			|||||||
import defineApp from '../../helpers/define-app.js';
 | 
					 | 
				
			||||||
import addAuthHeader from './common/add-auth-header.js';
 | 
					 | 
				
			||||||
import setBaseUrl from './common/set-base-url.js';
 | 
					 | 
				
			||||||
import auth from './auth/index.js';
 | 
					 | 
				
			||||||
import triggers from './triggers/index.js';
 | 
					 | 
				
			||||||
import dynamicData from './dynamic-data/index.js';
 | 
					 | 
				
			||||||
import actions from './actions/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineApp({
 | 
					 | 
				
			||||||
  name: 'Mailchimp',
 | 
					 | 
				
			||||||
  key: 'mailchimp',
 | 
					 | 
				
			||||||
  baseUrl: 'https://mailchimp.com',
 | 
					 | 
				
			||||||
  apiBaseUrl: '',
 | 
					 | 
				
			||||||
  iconUrl: '{BASE_URL}/apps/mailchimp/assets/favicon.svg',
 | 
					 | 
				
			||||||
  authDocUrl: 'https://automatisch.io/docs/apps/mailchimp/connection',
 | 
					 | 
				
			||||||
  primaryColor: '000000',
 | 
					 | 
				
			||||||
  supportsConnections: true,
 | 
					 | 
				
			||||||
  beforeRequest: [setBaseUrl, addAuthHeader],
 | 
					 | 
				
			||||||
  auth,
 | 
					 | 
				
			||||||
  triggers,
 | 
					 | 
				
			||||||
  dynamicData,
 | 
					 | 
				
			||||||
  actions,
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,101 +0,0 @@
 | 
				
			|||||||
import defineTrigger from '../../../../helpers/define-trigger.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default defineTrigger({
 | 
					 | 
				
			||||||
  name: 'Email opened',
 | 
					 | 
				
			||||||
  key: 'emailOpened',
 | 
					 | 
				
			||||||
  pollInterval: 15,
 | 
					 | 
				
			||||||
  description:
 | 
					 | 
				
			||||||
    'Triggers when a recipient opens an email as part of a particular campaign.',
 | 
					 | 
				
			||||||
  arguments: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Audience',
 | 
					 | 
				
			||||||
      key: 'audienceId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listAudiences',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Campaign Type',
 | 
					 | 
				
			||||||
      key: 'campaignType',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      options: [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          label: 'Campaign',
 | 
					 | 
				
			||||||
          value: 'campaign',
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      label: 'Campaign',
 | 
					 | 
				
			||||||
      key: 'campaignId',
 | 
					 | 
				
			||||||
      type: 'dropdown',
 | 
					 | 
				
			||||||
      required: true,
 | 
					 | 
				
			||||||
      dependsOn: ['parameters.audienceId'],
 | 
					 | 
				
			||||||
      description: '',
 | 
					 | 
				
			||||||
      variables: true,
 | 
					 | 
				
			||||||
      source: {
 | 
					 | 
				
			||||||
        type: 'query',
 | 
					 | 
				
			||||||
        name: 'getDynamicData',
 | 
					 | 
				
			||||||
        arguments: [
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'key',
 | 
					 | 
				
			||||||
            value: 'listCampaigns',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            name: 'parameters.audienceId',
 | 
					 | 
				
			||||||
            value: '{parameters.audienceId}',
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  async run($) {
 | 
					 | 
				
			||||||
    const campaignId = $.step.parameters.campaignId;
 | 
					 | 
				
			||||||
    let hasMore = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const params = {
 | 
					 | 
				
			||||||
      count: 1000,
 | 
					 | 
				
			||||||
      offset: 0,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    do {
 | 
					 | 
				
			||||||
      const { data } = await $.http.get(
 | 
					 | 
				
			||||||
        `/3.0/reports/${campaignId}/open-details`,
 | 
					 | 
				
			||||||
        { params }
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
      params.offset = params.offset + params.count;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (data.members?.length) {
 | 
					 | 
				
			||||||
        for (const member of data.members) {
 | 
					 | 
				
			||||||
          $.pushTriggerItem({
 | 
					 | 
				
			||||||
            raw: member,
 | 
					 | 
				
			||||||
            meta: {
 | 
					 | 
				
			||||||
              internalId: member.email_id,
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (data.total_items > params.offset) {
 | 
					 | 
				
			||||||
        hasMore = true;
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        hasMore = false;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } while (hasMore);
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1,5 +0,0 @@
 | 
				
			|||||||
import emailOpened from './email-opened/index.js';
 | 
					 | 
				
			||||||
import newSubscribers from './new-subscribers/index.js';
 | 
					 | 
				
			||||||
import newUnsubscribers from './new-unsubscribers/index.js';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default [emailOpened, newSubscribers, newUnsubscribers];
 | 
					 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user