Update zapier trigger payload (#8464)

- fixes zapier tests
This commit is contained in:
martmull
2024-11-12 17:58:36 +01:00
committed by GitHub
parent 31f03764d6
commit 269eaf4422
7 changed files with 65 additions and 49 deletions

View File

@@ -1,4 +1,4 @@
import { Injectable, UnauthorizedException } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { JwtService, JwtSignOptions, JwtVerifyOptions } from '@nestjs/jwt'; import { JwtService, JwtSignOptions, JwtVerifyOptions } from '@nestjs/jwt';
import { createHash } from 'crypto'; import { createHash } from 'crypto';
@@ -10,6 +10,7 @@ import {
AuthExceptionCode, AuthExceptionCode,
} from 'src/engine/core-modules/auth/auth.exception'; } from 'src/engine/core-modules/auth/auth.exception';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service'; import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { isDefined } from 'src/utils/is-defined';
export type WorkspaceTokenType = export type WorkspaceTokenType =
| 'ACCESS' | 'ACCESS'
@@ -53,9 +54,16 @@ export class JwtWrapperService {
json: true, json: true,
}); });
if (!isDefined(payload)) {
throw new AuthException('No payload', AuthExceptionCode.UNAUTHENTICATED);
}
// TODO: check if this is really needed // TODO: check if this is really needed
if (type !== 'FILE' && !payload.sub) { if (type !== 'FILE' && !payload.sub) {
throw new UnauthorizedException('No payload sub'); throw new AuthException(
'No payload sub',
AuthExceptionCode.UNAUTHENTICATED,
);
} }
try { try {

View File

@@ -64,15 +64,36 @@ const computeQueryParameters = (
} }
}; };
const getOperationFromDatabaseEventAction = (
z: ZObject,
databaseEventAction: DatabaseEventAction,
): 'create' | 'update' | 'delete' => {
switch (databaseEventAction) {
case DatabaseEventAction.CREATED:
return 'create';
case DatabaseEventAction.UPDATED:
return 'update';
case DatabaseEventAction.DELETED:
return 'delete';
default:
throw new z.errors.Error(
`Unknown databaseEventAction: ${databaseEventAction}`,
'Error',
404,
);
}
};
const perform = async (z: ZObject, bundle: Bundle) => { const perform = async (z: ZObject, bundle: Bundle) => {
const data = bundle.inputData; const data = bundle.inputData;
const operation = data.crudZapierOperation; const operation = data.crudZapierOperation;
const queryOperation = getOperationFromDatabaseEventAction(z, operation);
const nameSingular = data.nameSingular; const nameSingular = data.nameSingular;
delete data.nameSingular; delete data.nameSingular;
delete data.crudZapierOperation; delete data.crudZapierOperation;
const query = ` const query = `
mutation ${operation}${capitalize(nameSingular)} { mutation ${queryOperation}${capitalize(nameSingular)} {
${operation}${capitalize(nameSingular)}( ${queryOperation}${capitalize(nameSingular)}(
${computeQueryParameters(operation, data)} ${computeQueryParameters(operation, data)}
) )
{id} {id}

View File

@@ -15,6 +15,6 @@ describe('triggers.list_record_ids', () => {
); );
expect(result).toBeDefined(); expect(result).toBeDefined();
expect(result.length).toBeGreaterThan(1); expect(result.length).toBeGreaterThan(1);
expect(result[0].id).toBeDefined(); expect(result[0].record.id).toBeDefined();
}); });
}); });

View File

@@ -24,18 +24,18 @@ describe('triggers.trigger_record.created', () => {
requestDb( requestDb(
z, z,
bundle, bundle,
`query webhook {webhooks(filter: {id: {eq: "${result.id}"}}){edges {node {id operation}}}}`, `query webhook {webhooks(filter: {id: {eq: "${result.id}"}}){edges {node {id operations}}}}`,
), ),
bundle, bundle,
); );
expect(checkDbResult.data.webhooks.edges[0].node.operation).toEqual( expect(checkDbResult.data.webhooks.edges[0].node.operations[0]).toEqual(
'create.company', 'company.created',
); );
}); });
test('should succeed to unsubscribe', async () => { test('should succeed to unsubscribe', async () => {
const bundle = getBundle({}); const bundle = getBundle({});
bundle.inputData.nameSingular = 'company'; bundle.inputData.nameSingular = 'company';
bundle.inputData.operation = 'create'; bundle.inputData.operation = DatabaseEventAction.CREATED;
bundle.targetUrl = 'https://test.com'; bundle.targetUrl = 'https://test.com';
const result = await appTester( const result = await appTester(
App.triggers[triggerRecordKey].operation.performSubscribe, App.triggers[triggerRecordKey].operation.performSubscribe,
@@ -54,7 +54,7 @@ describe('triggers.trigger_record.created', () => {
requestDb( requestDb(
z, z,
bundle, bundle,
`query webhook {webhooks(filter: {id: {eq: "${result.id}"}}){edges {node {id operation}}}}`, `query webhook {webhooks(filter: {id: {eq: "${result.id}"}}){edges {node {id operations}}}}`,
), ),
bundle, bundle,
); );
@@ -83,19 +83,19 @@ describe('triggers.trigger_record.created', () => {
); );
expect(results.length).toEqual(1); expect(results.length).toEqual(1);
const company = results[0]; const company = results[0];
expect(company.id).toEqual('d6ccb1d1-a90b-4822-a992-a0dd946592c9'); expect(company.record.id).toEqual('d6ccb1d1-a90b-4822-a992-a0dd946592c9');
}); });
it('should load companies from list', async () => { it('should load companies from list', async () => {
const bundle = getBundle({}); const bundle = getBundle({});
bundle.inputData.nameSingular = 'company'; bundle.inputData.nameSingular = 'company';
bundle.inputData.operation = 'create'; bundle.inputData.operation = DatabaseEventAction.CREATED;
const results = await appTester( const results = await appTester(
App.triggers[triggerRecordKey].operation.performList, App.triggers[triggerRecordKey].operation.performList,
bundle, bundle,
); );
expect(results.length).toBeGreaterThan(1); expect(results.length).toBeGreaterThan(1);
const firstCompany = results[0]; const firstCompany = results[0];
expect(firstCompany).toBeDefined(); expect(firstCompany.record).toBeDefined();
}); });
}); });
@@ -103,7 +103,7 @@ describe('triggers.trigger_record.update', () => {
test('should succeed to subscribe', async () => { test('should succeed to subscribe', async () => {
const bundle = getBundle({}); const bundle = getBundle({});
bundle.inputData.nameSingular = 'company'; bundle.inputData.nameSingular = 'company';
bundle.inputData.operation = 'update'; bundle.inputData.operation = DatabaseEventAction.UPDATED;
bundle.targetUrl = 'https://test.com'; bundle.targetUrl = 'https://test.com';
const result = await appTester( const result = await appTester(
App.triggers[triggerRecordKey].operation.performSubscribe, App.triggers[triggerRecordKey].operation.performSubscribe,
@@ -116,18 +116,18 @@ describe('triggers.trigger_record.update', () => {
requestDb( requestDb(
z, z,
bundle, bundle,
`query webhook {webhooks(filter: {id: {eq: "${result.id}"}}){edges {node {id operation}}}}`, `query webhook {webhooks(filter: {id: {eq: "${result.id}"}}){edges {node {id operations}}}}`,
), ),
bundle, bundle,
); );
expect(checkDbResult.data.webhooks.edges[0].node.operation).toEqual( expect(checkDbResult.data.webhooks.edges[0].node.operations[0]).toEqual(
'update.company', 'company.updated',
); );
}); });
test('should succeed to unsubscribe', async () => { test('should succeed to unsubscribe', async () => {
const bundle = getBundle({}); const bundle = getBundle({});
bundle.inputData.nameSingular = 'company'; bundle.inputData.nameSingular = 'company';
bundle.inputData.operation = 'update'; bundle.inputData.operation = DatabaseEventAction.UPDATED;
bundle.targetUrl = 'https://test.com'; bundle.targetUrl = 'https://test.com';
const result = await appTester( const result = await appTester(
App.triggers[triggerRecordKey].operation.performSubscribe, App.triggers[triggerRecordKey].operation.performSubscribe,
@@ -146,7 +146,7 @@ describe('triggers.trigger_record.update', () => {
requestDb( requestDb(
z, z,
bundle, bundle,
`query webhook {webhooks(filter: {id: {eq: "${result.id}"}}){edges {node {id operation}}}}`, `query webhook {webhooks(filter: {id: {eq: "${result.id}"}}){edges {node {id operations}}}}`,
), ),
bundle, bundle,
); );
@@ -155,14 +155,15 @@ describe('triggers.trigger_record.update', () => {
it('should load companies from list', async () => { it('should load companies from list', async () => {
const bundle = getBundle({}); const bundle = getBundle({});
bundle.inputData.nameSingular = 'company'; bundle.inputData.nameSingular = 'company';
bundle.inputData.operation = 'update'; bundle.inputData.operation = DatabaseEventAction.UPDATED;
const results = await appTester( const results = await appTester(
App.triggers[triggerRecordKey].operation.performList, App.triggers[triggerRecordKey].operation.performList,
bundle, bundle,
); );
expect(results.length).toBeGreaterThan(1); expect(results.length).toBeGreaterThan(1);
const firstCompany = results[0]; const firstCompany = results[0];
expect(firstCompany).toBeDefined(); expect(firstCompany.record).toBeDefined();
expect(firstCompany.updatedFields).toBeDefined();
}); });
}); });
@@ -170,7 +171,7 @@ describe('triggers.trigger_record.delete', () => {
test('should succeed to subscribe', async () => { test('should succeed to subscribe', async () => {
const bundle = getBundle({}); const bundle = getBundle({});
bundle.inputData.nameSingular = 'company'; bundle.inputData.nameSingular = 'company';
bundle.inputData.operation = 'delete'; bundle.inputData.operation = DatabaseEventAction.DELETED;
bundle.targetUrl = 'https://test.com'; bundle.targetUrl = 'https://test.com';
const result = await appTester( const result = await appTester(
App.triggers[triggerRecordKey].operation.performSubscribe, App.triggers[triggerRecordKey].operation.performSubscribe,
@@ -183,18 +184,18 @@ describe('triggers.trigger_record.delete', () => {
requestDb( requestDb(
z, z,
bundle, bundle,
`query webhook {webhooks(filter: {id: {eq: "${result.id}"}}){edges {node {id operation}}}}`, `query webhook {webhooks(filter: {id: {eq: "${result.id}"}}){edges {node {id operations}}}}`,
), ),
bundle, bundle,
); );
expect(checkDbResult.data.webhooks.edges[0].node.operation).toEqual( expect(checkDbResult.data.webhooks.edges[0].node.operations[0]).toEqual(
'delete.company', 'company.deleted',
); );
}); });
test('should succeed to unsubscribe', async () => { test('should succeed to unsubscribe', async () => {
const bundle = getBundle({}); const bundle = getBundle({});
bundle.inputData.nameSingular = 'company'; bundle.inputData.nameSingular = 'company';
bundle.inputData.operation = 'delete'; bundle.inputData.operation = DatabaseEventAction.DELETED;
bundle.targetUrl = 'https://test.com'; bundle.targetUrl = 'https://test.com';
const result = await appTester( const result = await appTester(
App.triggers[triggerRecordKey].operation.performSubscribe, App.triggers[triggerRecordKey].operation.performSubscribe,
@@ -213,7 +214,7 @@ describe('triggers.trigger_record.delete', () => {
requestDb( requestDb(
z, z,
bundle, bundle,
`query webhook {webhooks(filter: {id: {eq: "${result.id}"}}){edges {node {id operation}}}}`, `query webhook {webhooks(filter: {id: {eq: "${result.id}"}}){edges {node {id operations}}}}`,
), ),
bundle, bundle,
); );
@@ -222,7 +223,7 @@ describe('triggers.trigger_record.delete', () => {
it('should load companies from list', async () => { it('should load companies from list', async () => {
const bundle = getBundle({}); const bundle = getBundle({});
bundle.inputData.nameSingular = 'company'; bundle.inputData.nameSingular = 'company';
bundle.inputData.operation = 'delete'; bundle.inputData.operation = DatabaseEventAction.DELETED;
const results = await appTester( const results = await appTester(
App.triggers[triggerRecordKey].operation.performList, App.triggers[triggerRecordKey].operation.performList,
bundle, bundle,
@@ -230,7 +231,7 @@ describe('triggers.trigger_record.delete', () => {
expect(results.length).toBeGreaterThan(1); expect(results.length).toBeGreaterThan(1);
const firstCompany = results[0]; const firstCompany = results[0];
expect(firstCompany).toBeDefined(); expect(firstCompany).toBeDefined();
expect(firstCompany.id).toBeDefined(); expect(firstCompany.record.id).toBeDefined();
expect(Object.keys(firstCompany).length).toEqual(1); expect(Object.keys(firstCompany).length).toEqual(1);
}); });
}); });

View File

@@ -1,14 +1,4 @@
import { Bundle, ZObject } from 'zapier-platform-core'; import { performList } from '../utils/triggers/triggers.utils';
import { ObjectData } from '../utils/data.types';
import { listSample } from '../utils/triggers/triggers.utils';
const listRecordIdsRequest = async (
z: ZObject,
bundle: Bundle,
): Promise<ObjectData[]> => {
return listSample(z, bundle, true);
};
export const listRecordIdsKey = 'list_record_ids'; export const listRecordIdsKey = 'list_record_ids';
@@ -21,6 +11,6 @@ export default {
key: listRecordIdsKey, key: listRecordIdsKey,
noun: 'Object', noun: 'Object',
operation: { operation: {
perform: listRecordIdsRequest, perform: performList,
}, },
}; };

View File

@@ -1,7 +1,5 @@
export type InputData = { [x: string]: any }; export type InputData = { [x: string]: any };
export type ObjectData = { id: string } | { [x: string]: any };
export type NodeField = { export type NodeField = {
type: FieldMetadataType; type: FieldMetadataType;
name: string; name: string;

View File

@@ -1,6 +1,5 @@
import { Bundle, ZObject } from 'zapier-platform-core'; import { Bundle, ZObject } from 'zapier-platform-core';
import { ObjectData } from '../../utils/data.types';
import handleQueryParams from '../../utils/handleQueryParams'; import handleQueryParams from '../../utils/handleQueryParams';
import requestDb, { import requestDb, {
requestDbViaRestApi, requestDbViaRestApi,
@@ -11,7 +10,6 @@ export enum DatabaseEventAction {
CREATED = 'created', CREATED = 'created',
UPDATED = 'updated', UPDATED = 'updated',
DELETED = 'deleted', DELETED = 'deleted',
DESTROYED = 'destroyed',
} }
export const performSubscribe = async (z: ZObject, bundle: Bundle) => { export const performSubscribe = async (z: ZObject, bundle: Bundle) => {
@@ -81,7 +79,7 @@ const getNamePluralFromNameSingular = async (
export const performList = async ( export const performList = async (
z: ZObject, z: ZObject,
bundle: Bundle, bundle: Bundle,
): Promise<ObjectData[]> => { ): Promise<{ record: Record<string, any>; updatedFields?: string[] }[]> => {
const nameSingular = bundle.inputData.nameSingular; const nameSingular = bundle.inputData.nameSingular;
const namePlural = await getNamePluralFromNameSingular( const namePlural = await getNamePluralFromNameSingular(
z, z,
@@ -92,9 +90,9 @@ export const performList = async (
return results.map((result) => ({ return results.map((result) => ({
record: result, record: result,
...(bundle.inputData.operation === DatabaseEventAction.UPDATED && { ...(bundle.inputData.operation === DatabaseEventAction.UPDATED && {
updatedFields: Object.keys(result).filter((key) => key !== 'id')?.[0] || [ updatedFields: [
'updatedField', Object.keys(result).filter((key) => key !== 'id')?.[0],
], ] || ['updatedField'],
}), }),
})); }));
}; };