From c483b2822d899cd037704c248220b5558b6cb1f5 Mon Sep 17 00:00:00 2001 From: Mohammad AbuAboud Date: Mon, 12 Aug 2024 19:03:03 +0000 Subject: [PATCH 01/12] fix: audit events schema --- package-lock.json | 9 ++-- package.json | 2 +- .../ee/shared/src/lib/audit-events/index.ts | 1 + .../1723489038729-MigrateAuditEventSchema.ts | 42 +++++++++++++++++++ .../src/app/database/postgres-connection.ts | 2 + .../app/ee/audit-logs/audit-event-entity.ts | 5 +++ .../app/ee/audit-logs/audit-event-service.ts | 19 +++++---- .../db-piece-metadata-service.ts | 4 +- .../file-piece-metadata-service.ts | 4 +- .../src/app/workers/redis/redis-consumer.ts | 7 +--- packages/server/shared/package.json | 2 +- .../src/lib/engine/flow-enginer-util.ts | 4 +- packages/shared/src/lib/flow-run/flow-run.ts | 2 +- .../src/lib/pieces/dto/piece-requests.ts | 14 ++++--- 14 files changed, 83 insertions(+), 34 deletions(-) create mode 100644 packages/server/api/src/app/database/migration/postgres/1723489038729-MigrateAuditEventSchema.ts diff --git a/package-lock.json b/package-lock.json index fb0b686af7..9ed15b437c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -58,7 +58,7 @@ "@segment/analytics-node": "2.1.0", "@sendgrid/mail": "8.0.0", "@sentry/node": "7.64.0", - "@sinclair/typebox": "0.31.28", + "@sinclair/typebox": "0.32.35", "@slack/web-api": "7.0.4", "@socket.io/redis-adapter": "8.2.1", "@supabase/supabase-js": "2.33.1", @@ -12455,10 +12455,9 @@ } }, "node_modules/@sinclair/typebox": { - "version": "0.31.28", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.31.28.tgz", - "integrity": "sha512-/s55Jujywdw/Jpan+vsy6JZs1z2ZTGxTmbZTPiuSL2wz9mfzA2gN1zzaqmvfi4pq+uOt7Du85fkiwv5ymW84aQ==", - "license": "MIT" + "version": "0.32.35", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.32.35.tgz", + "integrity": "sha512-Ul3YyOTU++to8cgNkttakC0dWvpERr6RYoHO2W47DLbFvrwBDJUY31B1sImH6JZSYc4Kt4PyHtoPNu+vL2r2dA==" }, "node_modules/@sindresorhus/is": { "version": "4.6.0", diff --git a/package.json b/package.json index ca1bd992a0..0ab9b81bfb 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "@segment/analytics-node": "2.1.0", "@sendgrid/mail": "8.0.0", "@sentry/node": "7.64.0", - "@sinclair/typebox": "0.31.28", + "@sinclair/typebox": "0.32.35", "@slack/web-api": "7.0.4", "@socket.io/redis-adapter": "8.2.1", "@supabase/supabase-js": "2.33.1", diff --git a/packages/ee/shared/src/lib/audit-events/index.ts b/packages/ee/shared/src/lib/audit-events/index.ts index 77cae7eb94..3c6a67f064 100644 --- a/packages/ee/shared/src/lib/audit-events/index.ts +++ b/packages/ee/shared/src/lib/audit-events/index.ts @@ -32,6 +32,7 @@ const BaseAuditEventProps = { ...BaseModelSchema, platformId: Type.String(), projectId: Type.Optional(Type.String()), + projectDisplayName: Type.Optional(Type.String()), userId: Type.Optional(Type.String()), userEmail: Type.Optional(Type.String()), ip: Type.Optional(Type.String()), diff --git a/packages/server/api/src/app/database/migration/postgres/1723489038729-MigrateAuditEventSchema.ts b/packages/server/api/src/app/database/migration/postgres/1723489038729-MigrateAuditEventSchema.ts new file mode 100644 index 0000000000..78e3fe0cb1 --- /dev/null +++ b/packages/server/api/src/app/database/migration/postgres/1723489038729-MigrateAuditEventSchema.ts @@ -0,0 +1,42 @@ +import { MigrationInterface, QueryRunner } from 'typeorm' + +export class MigrateAuditEventSchema1723489038729 implements MigrationInterface { + name = 'MigrateAuditEventSchema1723489038729' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DROP INDEX "public"."audit_event_platform_id_project_id_user_id_idx" + `) + await queryRunner.query(` + ALTER TABLE "audit_event" + ALTER COLUMN "userEmail" DROP NOT NULL + `) + await queryRunner.query(` + ALTER TABLE "audit_event" + ALTER COLUMN "userId" DROP NOT NULL + `) + await queryRunner.query(` + CREATE INDEX "audit_event_platform_id_project_id_user_id_idx" ON "audit_event" ("platformId", "projectId", "userId") + `) + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DROP INDEX "public"."audit_event_platform_id_project_id_user_id_idx" + `) + await queryRunner.query(` + ALTER TABLE "audit_event" + ALTER COLUMN "userId" + SET NOT NULL + `) + await queryRunner.query(` + ALTER TABLE "audit_event" + ALTER COLUMN "userEmail" + SET NOT NULL + `) + await queryRunner.query(` + CREATE INDEX "audit_event_platform_id_project_id_user_id_idx" ON "audit_event" ("platformId", "projectId", "userId") + `) + } + +} diff --git a/packages/server/api/src/app/database/postgres-connection.ts b/packages/server/api/src/app/database/postgres-connection.ts index 85b2fb9e4b..b9eb87c3ea 100644 --- a/packages/server/api/src/app/database/postgres-connection.ts +++ b/packages/server/api/src/app/database/postgres-connection.ts @@ -139,6 +139,7 @@ import { AddPremiumPiecesColumnPostgres1717370717678 } from './migration/postgre import { AddUserInvitation1717960689650 } from './migration/postgres/1717960689650-AddUserInvitation' import { ModifyProjectMembers1717961669938 } from './migration/postgres/1717961669938-ModifyProjectMembers' import { AddWorkerMachine1720101280025 } from './migration/postgres/1720101280025-AddWorkerMachine' +import { MigrateAuditEventSchema1723489038729 } from './migration/postgres/1723489038729-MigrateAuditEventSchema' const getSslConfig = (): boolean | TlsOptions => { const useSsl = system.get(AppSystemProp.POSTGRES_USE_SSL) @@ -301,6 +302,7 @@ const getMigrations = (): (new () => MigrationInterface)[] => { // New Migration After Unifying ModifyProjectMembers1717961669938, + MigrateAuditEventSchema1723489038729, ) break case ApEdition.COMMUNITY: diff --git a/packages/server/api/src/app/ee/audit-logs/audit-event-entity.ts b/packages/server/api/src/app/ee/audit-logs/audit-event-entity.ts index 99e9149497..1189e39c3a 100644 --- a/packages/server/api/src/app/ee/audit-logs/audit-event-entity.ts +++ b/packages/server/api/src/app/ee/audit-logs/audit-event-entity.ts @@ -23,6 +23,11 @@ export const AuditEventEntity = new EntitySchema({ }, userEmail: { type: String, + nullable: true, + }, + projectDisplayName: { + type: String, + nullable: true, }, data: { type: JSONB_COLUMN_TYPE, diff --git a/packages/server/api/src/app/ee/audit-logs/audit-event-service.ts b/packages/server/api/src/app/ee/audit-logs/audit-event-service.ts index 8e2e8b0d94..f9c542366a 100644 --- a/packages/server/api/src/app/ee/audit-logs/audit-event-service.ts +++ b/packages/server/api/src/app/ee/audit-logs/audit-event-service.ts @@ -4,12 +4,11 @@ import { import { logger, networkUtls, rejectedPromiseHandler } from '@activepieces/server-shared' import { apId, - assertEqual, Cursor, PrincipalType, SeekPage, } from '@activepieces/shared' -import Ajv from 'ajv' +import { Value } from '@sinclair/typebox/value' import { FastifyRequest } from 'fastify' import { repoFactory } from '../../core/db/repo-factory' import { AuditEventParam } from '../../helper/application-events' @@ -19,11 +18,8 @@ import { platformService } from '../../platform/platform.service' import { projectService } from '../../project/project-service' import { userService } from '../../user/user-service' import { AuditEventEntity } from './audit-event-entity' - const auditLogRepo = repoFactory(AuditEventEntity) -const ajv = new Ajv({ removeAdditional: 'all' }) -const eventSchema = ajv.compile(ApplicationEvent) export const auditLogService = { sendUserEvent(request: FastifyRequest, params: AuditEventParam): void { @@ -84,7 +80,9 @@ async function saveEvent(info: MetaInformation, rawEvent: AuditEventParam): Prom created: new Date().toISOString(), updated: new Date().toISOString(), userId: info.userId, + userEmail: user?.email, projectId: info.projectId, + projectDisplayName: project?.displayName, platformId: info.platformId, ip: info.ip, data: { @@ -94,12 +92,15 @@ async function saveEvent(info: MetaInformation, rawEvent: AuditEventParam): Prom }, action: rawEvent.action, } - const valid = eventSchema(eventToSave) - assertEqual(valid, true, 'Event validation', 'true') - const appEvent = await auditLogRepo().save(eventToSave as ApplicationEvent) + + // The event may contain Date objects, so we serialize it to convert dates back to strings as per the schema. + const clonedAndSerializedDates = JSON.parse(JSON.stringify(eventToSave)) + const cleanedEvent = Value.Clean(ApplicationEvent, clonedAndSerializedDates) as ApplicationEvent + + const savedEvent = await auditLogRepo().save(cleanedEvent) logger.info({ message: '[AuditEventService#saveEvent] Audit event saved', - appEvent, + appEvent: savedEvent, }) } diff --git a/packages/server/api/src/app/pieces/piece-metadata-service/db-piece-metadata-service.ts b/packages/server/api/src/app/pieces/piece-metadata-service/db-piece-metadata-service.ts index f64b9bca28..c5f212618f 100644 --- a/packages/server/api/src/app/pieces/piece-metadata-service/db-piece-metadata-service.ts +++ b/packages/server/api/src/app/pieces/piece-metadata-service/db-piece-metadata-service.ts @@ -1,6 +1,6 @@ import { PieceMetadataModel, PieceMetadataModelSummary } from '@activepieces/pieces-framework' -import { ActivepiecesError, apId, assertNotNullOrUndefined, ErrorCode, EXACT_VERSION_PATTERN, isNil, ListVersionsResponse, PieceType } from '@activepieces/shared' +import { ActivepiecesError, apId, assertNotNullOrUndefined, ErrorCode, EXACT_VERSION_REGEX, isNil, ListVersionsResponse, PieceType } from '@activepieces/shared' import dayjs from 'dayjs' import semVer from 'semver' import { IsNull } from 'typeorm' @@ -112,7 +112,7 @@ export const FastDbPieceMetadataService = (): PieceMetadataService => { }) }, async getExactPieceVersion({ name, version, projectId }): Promise { - const isExactVersion = EXACT_VERSION_PATTERN.test(version) + const isExactVersion = EXACT_VERSION_REGEX.test(version) if (isExactVersion) { return version diff --git a/packages/server/api/src/app/pieces/piece-metadata-service/file-piece-metadata-service.ts b/packages/server/api/src/app/pieces/piece-metadata-service/file-piece-metadata-service.ts index 656f781577..b33f92b433 100644 --- a/packages/server/api/src/app/pieces/piece-metadata-service/file-piece-metadata-service.ts +++ b/packages/server/api/src/app/pieces/piece-metadata-service/file-piece-metadata-service.ts @@ -7,7 +7,7 @@ import { ActivepiecesError, ApEdition, ErrorCode, - EXACT_VERSION_PATTERN, + EXACT_VERSION_REGEX, extractPieceFromModule, isNil, ListVersionsResponse, @@ -170,7 +170,7 @@ export const FilePieceMetadataService = (): PieceMetadataService => { }, async getExactPieceVersion({ projectId, name, version }): Promise { - const isExactVersion = EXACT_VERSION_PATTERN.test(version) + const isExactVersion = EXACT_VERSION_REGEX.test(version) if (isExactVersion) { return version diff --git a/packages/server/api/src/app/workers/redis/redis-consumer.ts b/packages/server/api/src/app/workers/redis/redis-consumer.ts index d0fd8ba9ca..0cfe7f1dc0 100644 --- a/packages/server/api/src/app/workers/redis/redis-consumer.ts +++ b/packages/server/api/src/app/workers/redis/redis-consumer.ts @@ -60,12 +60,7 @@ export const redisConsumer: ConsumerManager = { await Promise.all(sharedConsumers) }, async close(): Promise { - const promises = Object.values(consumer).map((consumerGroup) => { - return Promise.all(Object.values(consumerGroup).map(async (consumer) => { - await consumer.drain() - await consumer.close() - })) - }) + const promises = Object.values(consumer).map(consumer => consumer.close()) await Promise.all(promises) }, } diff --git a/packages/server/shared/package.json b/packages/server/shared/package.json index e2cdedebce..d80412074f 100644 --- a/packages/server/shared/package.json +++ b/packages/server/shared/package.json @@ -9,7 +9,7 @@ "@activepieces/shared": "*", "fastify": "4.12.0", "async-mutex": "0.4.0", - "@sinclair/typebox": "0.31.28" + "@sinclair/typebox": "0.32.35" }, "type": "commonjs", "main": "./src/index.js", diff --git a/packages/server/worker/src/lib/engine/flow-enginer-util.ts b/packages/server/worker/src/lib/engine/flow-enginer-util.ts index e22d4f26ff..9c34c1baa7 100644 --- a/packages/server/worker/src/lib/engine/flow-enginer-util.ts +++ b/packages/server/worker/src/lib/engine/flow-enginer-util.ts @@ -1,4 +1,4 @@ -import { Action, ActionType, assertEqual, CodeAction, EXACT_VERSION_PATTERN, flowHelper, FlowVersion, PackageType, PieceActionSettings, PiecePackage, PieceTriggerSettings, PieceType, Trigger, TriggerType } from '@activepieces/shared' +import { Action, ActionType, assertEqual, CodeAction, EXACT_VERSION_REGEX, flowHelper, FlowVersion, PackageType, PieceActionSettings, PiecePackage, PieceTriggerSettings, PieceType, Trigger, TriggerType } from '@activepieces/shared' import { engineApiService } from '../api/server-api.service' import { CodeArtifact } from './engine-runner' @@ -62,7 +62,7 @@ export const pieceEngineUtil = { } } case PackageType.REGISTRY: { - const exactVersion = EXACT_VERSION_PATTERN.test(pieceVersion) + const exactVersion = EXACT_VERSION_REGEX.test(pieceVersion) const version = exactVersion ? pieceVersion : (await engineApiService(engineToken).getPiece(pieceName, { version: pieceVersion, })).version diff --git a/packages/shared/src/lib/flow-run/flow-run.ts b/packages/shared/src/lib/flow-run/flow-run.ts index 7fbd9eff79..6fc63ac934 100755 --- a/packages/shared/src/lib/flow-run/flow-run.ts +++ b/packages/shared/src/lib/flow-run/flow-run.ts @@ -34,7 +34,7 @@ export const FlowRun = Type.Object({ status: Type.Enum(FlowRunStatus), duration: Type.Optional(Type.Number()), startTime: Type.String(), - finishTime: Type.String(), + finishTime: Type.Optional(Type.String()), environment: Type.Enum(RunEnvironment), pauseMetadata: Type.Optional(PauseMetadata), steps: Type.Record(Type.String(), Type.Unknown()), diff --git a/packages/shared/src/lib/pieces/dto/piece-requests.ts b/packages/shared/src/lib/pieces/dto/piece-requests.ts index d336a5d9a5..6332a09106 100644 --- a/packages/shared/src/lib/pieces/dto/piece-requests.ts +++ b/packages/shared/src/lib/pieces/dto/piece-requests.ts @@ -2,12 +2,16 @@ import { Static, Type } from '@sinclair/typebox' import { ApEdition } from '../../flag/flag' import { PackageType, PieceCategory, PieceType } from '../piece' -export const EXACT_VERSION_PATTERN = /^[0-9]+\.[0-9]+\.[0-9]+$/ -export const VERSION_PATTERN = /^([~^])?[0-9]+\.[0-9]+\.[0-9]+$/ - -export const ExactVersionType = Type.RegExp(EXACT_VERSION_PATTERN) -export const VersionType = Type.RegExp(VERSION_PATTERN) +export const EXACT_VERSION_PATTERN = '^[0-9]+\\.[0-9]+\\.[0-9]+$' +export const EXACT_VERSION_REGEX = new RegExp(EXACT_VERSION_PATTERN) +const VERSION_PATTERN = '^([~^])?[0-9]+\\.[0-9]+\\.[0-9]+$' +export const ExactVersionType = Type.String({ + pattern: EXACT_VERSION_PATTERN, +}) +export const VersionType = Type.String({ + pattern: VERSION_PATTERN, +}) export enum SuggestionType { ACTION = 'ACTION', TRIGGER = 'TRIGGER', From 77a8ad6f60fdfd581a39545aa382d42ccfabaf0c Mon Sep 17 00:00:00 2001 From: Mohammad AbuAboud Date: Mon, 12 Aug 2024 23:12:39 +0200 Subject: [PATCH 02/12] fix: event routing --- .../app-event-routing.module.ts | 144 +++++++++--------- 1 file changed, 69 insertions(+), 75 deletions(-) diff --git a/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts b/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts index b55b14de4b..9c092c46e7 100644 --- a/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts +++ b/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts @@ -7,11 +7,11 @@ import { JobType, LATEST_JOB_DATA_SCHEMA_VERSION, logger, rejectedPromiseHandler import { ActivepiecesError, ALL_PRINCIPAL_TYPES, apId, + assertNotNullOrUndefined, ErrorCode, isNil, } from '@activepieces/shared' -import { FastifyPluginAsyncTypebox } from '@fastify/type-provider-typebox' -import { FastifyRequest } from 'fastify' +import { FastifyPluginAsyncTypebox, Type } from '@fastify/type-provider-typebox' import { flowQueue } from '../workers/queue' import { DEFAULT_PRIORITY } from '../workers/queue/queue-manager' import { appEventRoutingService } from './app-event-routing.service' @@ -22,7 +22,6 @@ const appWebhooks: Record = { 'facebook-leads': facebookLeads, intercom, } - const pieceNames: Record = { slack: '@activepieces/piece-slack', square: '@activepieces/piece-square', @@ -37,79 +36,74 @@ export const appEventRoutingModule: FastifyPluginAsyncTypebox = async (app) => { export const appEventRoutingController: FastifyPluginAsyncTypebox = async ( fastify, ) => { - fastify.all( - '/:pieceUrl', - { - config: { - rawBody: true, - allowedPrincipals: ALL_PRINCIPAL_TYPES, - }, - logLevel: 'silent', - }, - async ( - request: FastifyRequest<{ - Body: unknown - Params: { - pieceUrl: string - } - }>, - requestReply, - ) => { - const pieceUrl = request.params.pieceUrl - const eventPayload = { - headers: request.headers as Record, - body: request.body, - rawBody: request.rawBody, - method: request.method, - queryParams: request.query as Record, - } - const piece = appWebhooks[pieceUrl] - if (isNil(piece)) { - throw new ActivepiecesError({ - code: ErrorCode.PIECE_NOT_FOUND, - params: { - pieceName: pieceUrl, - pieceVersion: 'latest', - message: 'Pieces is not found in app event routing', - }, - }) - } - const pieceName = pieceNames[pieceUrl] - const { reply, event, identifierValue } = piece.events!.parseAndReply({ - payload: eventPayload, + fastify.all('/:pieceUrl', EventRoutingParam, async (request, requestReply) => { + const pieceUrl = request.params.pieceUrl + const payload = { + headers: request.headers as Record, + body: request.body, + rawBody: request.rawBody, + method: request.method, + queryParams: request.query as Record, + } + const piece = appWebhooks[pieceUrl] + if (isNil(piece)) { + throw new ActivepiecesError({ + code: ErrorCode.PIECE_NOT_FOUND, + params: { + pieceName: pieceUrl, + pieceVersion: 'latest', + message: 'Pieces is not found in app event routing', + }, }) - - logger.debug( - `Received event ${event} with identifier ${identifierValue} in app ${pieceName}`, - ) - if (event && identifierValue) { - const listeners = await appEventRoutingService.listListeners({ - appName: pieceName, - event, - identifierValue, + } + const pieceName = pieceNames[pieceUrl] + assertNotNullOrUndefined(piece.events, 'Event is not defined') + const { reply, event, identifierValue } = piece.events.parseAndReply({ payload }) + logger.info({ + event, + identifierValue, + }, '[AppEventRoutingController#event] event') + if (event && identifierValue) { + const listeners = await appEventRoutingService.listListeners({ + appName: pieceName, + event, + identifierValue, + }) + rejectedPromiseHandler(Promise.all(listeners.map(async (listener) => { + const requestId = apId() + await flowQueue.add({ + id: requestId, + type: JobType.WEBHOOK, + data: { + projectId: listener.projectId, + schemaVersion: LATEST_JOB_DATA_SCHEMA_VERSION, + requestId, + synchronousHandlerId: null, + payload, + flowId: listener.flowId, + simulate: false, + }, + priority: DEFAULT_PRIORITY, }) - rejectedPromiseHandler(Promise.all(listeners.map(async (listener) => { - const requestId = apId() - await flowQueue.add({ - id: requestId, - type: JobType.WEBHOOK, - data: { - projectId: listener.projectId, - schemaVersion: LATEST_JOB_DATA_SCHEMA_VERSION, - requestId, - synchronousHandlerId: null, - payload: eventPayload, - flowId: listener.flowId, - simulate: false, - }, - priority: DEFAULT_PRIORITY, - }) - }))) - } - return requestReply - .status(200) - .headers(reply?.headers ?? {}) - .send(reply?.body ?? {}) - }, + }))) + } + return requestReply + .status(200) + .headers(reply?.headers ?? {}) + .send(reply?.body ?? {}) + }, ) } + +const EventRoutingParam = { + config: { + rawBody: true, + allowedPrincipals: ALL_PRINCIPAL_TYPES, + }, + schema: { + params: Type.Object({ + pieceUrl: Type.String(), + }), + body: Type.Unknown(), + }, +} \ No newline at end of file From 7615f6ef05af4721ec3251cf002e7d2cc60fb3d1 Mon Sep 17 00:00:00 2001 From: Mohammad AbuAboud Date: Mon, 12 Aug 2024 23:18:42 +0200 Subject: [PATCH 03/12] fix: log errors in app routing --- .../app-event-routing.module.ts | 69 ++++++++++--------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts b/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts index 9c092c46e7..1993541f52 100644 --- a/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts +++ b/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts @@ -12,7 +12,7 @@ import { isNil, } from '@activepieces/shared' import { FastifyPluginAsyncTypebox, Type } from '@fastify/type-provider-typebox' -import { flowQueue } from '../workers/queue' +import { StatusCodes } from 'http-status-codes' import { DEFAULT_PRIORITY } from '../workers/queue/queue-manager' import { appEventRoutingService } from './app-event-routing.service' @@ -56,43 +56,48 @@ export const appEventRoutingController: FastifyPluginAsyncTypebox = async ( }, }) } - const pieceName = pieceNames[pieceUrl] - assertNotNullOrUndefined(piece.events, 'Event is not defined') + const appName = pieceNames[pieceUrl] + assertNotNullOrUndefined(piece.events, 'Event is possible in this piece') const { reply, event, identifierValue } = piece.events.parseAndReply({ payload }) + if (!isNil(reply)) { + logger.info({ + reply, + piece: pieceUrl, + }, '[AppEventRoutingController#event] reply') + return requestReply.status(StatusCodes.OK).headers(reply?.headers ?? {}).send(reply?.body ?? {}) + } logger.info({ event, identifierValue, }, '[AppEventRoutingController#event] event') - if (event && identifierValue) { - const listeners = await appEventRoutingService.listListeners({ - appName: pieceName, - event, - identifierValue, - }) - rejectedPromiseHandler(Promise.all(listeners.map(async (listener) => { - const requestId = apId() - await flowQueue.add({ - id: requestId, - type: JobType.WEBHOOK, - data: { - projectId: listener.projectId, - schemaVersion: LATEST_JOB_DATA_SCHEMA_VERSION, - requestId, - synchronousHandlerId: null, - payload, - flowId: listener.flowId, - simulate: false, - }, - priority: DEFAULT_PRIORITY, - }) - }))) + if (isNil(event) || isNil(identifierValue)) { + return requestReply.status(StatusCodes.BAD_REQUEST).send({}) } - return requestReply - .status(200) - .headers(reply?.headers ?? {}) - .send(reply?.body ?? {}) - }, - ) + const listeners = await appEventRoutingService.listListeners({ + appName, + event, + identifierValue, + }) + const eventsQueue = listeners.map(async (listener) => { + const requestId = apId() + return { + id: requestId, + type: JobType.WEBHOOK, + data: { + projectId: listener.projectId, + schemaVersion: LATEST_JOB_DATA_SCHEMA_VERSION, + requestId, + synchronousHandlerId: null, + payload, + flowId: listener.flowId, + simulate: false, + }, + priority: DEFAULT_PRIORITY, + } + }) + rejectedPromiseHandler(Promise.all(eventsQueue)) + return requestReply.status(StatusCodes.OK).send({}) + }) } const EventRoutingParam = { From 96e78361770446a3f54c34574c781d6e9ab8748f Mon Sep 17 00:00:00 2001 From: Mohammad AbuAboud Date: Tue, 13 Aug 2024 00:41:54 +0200 Subject: [PATCH 04/12] fix: improve and disable open ai on angular --- .../api/src/app/copilot/copilot.service.ts | 288 ++++++++++-------- packages/shared/src/lib/copilot/index.ts | 6 +- ...artifact-control-fullscreen.component.html | 21 -- .../code-step-input-form.component.html | 14 +- 4 files changed, 160 insertions(+), 169 deletions(-) diff --git a/packages/server/api/src/app/copilot/copilot.service.ts b/packages/server/api/src/app/copilot/copilot.service.ts index fafdc44d77..cf8d39942a 100644 --- a/packages/server/api/src/app/copilot/copilot.service.ts +++ b/packages/server/api/src/app/copilot/copilot.service.ts @@ -1,5 +1,5 @@ import { AppSystemProp, CopilotInstanceTypes, logger, system } from '@activepieces/server-shared' -import { assertNotNullOrUndefined } from '@activepieces/shared' +import { assertNotNullOrUndefined, GenerateCodeResponse } from '@activepieces/shared' import OpenAI from 'openai' import { ChatCompletionMessageParam, @@ -11,12 +11,141 @@ type GenerateCodeParams = { previousContext: ChatCompletionMessageParam[] } +const CODE_TOOLS: ChatCompletionTool[] = [ + { + type: 'function', + function: { + name: 'generate_code', + description: 'Write TypeScript code snippet based on user prompt.', + parameters: { + type: 'object', + properties: { + code: { + type: 'string', + description: 'The code snippet to write.', + }, + inputs: { + type: 'array', + description: 'The inputs used in the code snippet.', + items: { + type: 'object', + properties: { + key: { + type: 'string', + description: 'The name of the input property.', + }, + value: { + type: 'string', + description: 'The value to fill the property with.', + }, + }, + }, + }, + packages: { + type: 'array', + description: 'The packages imported in the code snippet', + items: { + type: 'string', + description: + 'The name of the package, e.g axios, lodash, etc.', + }, + }, + }, + required: ['code'], + }, + }, + }, +] + + +const CODE_PROMPT: ChatCompletionMessageParam[] = [ + { + role: 'user', + content: ` +# INTRODUCTION +You are a TypeScript coding bot that helps users turn natural language into usable code, for an open-source automation platform called Activepieces. + +# RESPONSE FORMAT +You will not respond to any messages that require a conversational answer. +You will not elaborate. +You MUST respond ONLY with a function call. +You must import syntax since you are using typescript, prefer fetch over axios. + `, + }, + { + role: 'user', + content: 'I want code that will combine 2 arrays and only return the unique elements', + }, + { + role: 'assistant', + content: null, + function_call: { + name: 'generate_code', + arguments: JSON.stringify({ + code: ` +export const code = async (inputs) => { + const combinedArray = [...inputs.array1, ...inputs.array2]; + const uniqueArray = Array.from(new Set(combinedArray)); + return uniqueArray; +};`, + inputs: [ + { key: 'array1', value: '[1,2,3]' }, + { key: 'array2', value: '[4,5,6]' }, + ], + packages: [], + }), + }, + }, + { + role: 'user', + content: 'Write me a piece of code that splits the user\'s first name from his last name in a full name string received in inputs.', + }, + { + role: 'assistant', + content: null, + function_call: { + name: 'generate_code', + arguments: JSON.stringify({ + code: ` +export const code = async (inputs) => { + const nameParts = inputs.fullName.split(' '); + const firstName = nameParts[0]; + const lastName = nameParts.slice(1).join(''); + return { firstName, lastName }; +};`, + inputs: [{ key: 'fullName', value: 'John Doe' }], + packages: [], + }), + }, + }, + { + role: 'user', + content: 'from an array of objects, take the created_at property for each object and print it as an ISO string', + }, + { + role: 'assistant', + content: null, + function_call: { + name: 'generate_code', + arguments: JSON.stringify({ + code: ` +export const code = async (inputs) => { + const isoStrings = inputs.array.map(obj => new Date(obj.created_at).toISOString()); + return isoStrings; +};`, + inputs: [ + { key: 'array', value: '[{ "created_at": "2022-01-14T12:34:56Z" }, { "created_at": "2022-01-15T09:45:30Z" }]' }, + ], + packages: [], + }), + }, + }, +] function getOpenAI(): OpenAI { let openai const apiKey = system.getOrThrow(AppSystemProp.OPENAI_API_KEY) const openaiInstanceType = system.getOrThrow(AppSystemProp.COPILOT_INSTANCE_TYPE) - switch (openaiInstanceType) { case CopilotInstanceTypes.AZURE_OPENAI: { const apiVersion = system.getOrThrow(AppSystemProp.AZURE_OPENAI_API_VERSION) @@ -39,20 +168,25 @@ function getOpenAI(): OpenAI { return openai } +type OpenAIResponse = { + inputs: { key: string, value: string }[] + packages: string[] + code: string +} export const copilotService = { - async generateCode({ prompt, previousContext }: GenerateCodeParams): Promise { + async generateCode({ prompt, previousContext }: GenerateCodeParams): Promise { logger.debug({ prompt }, '[CopilotService#generateCode] Prompting...') const result = await getOpenAI().chat.completions.create({ - model: 'gpt-3.5-turbo', + model: 'gpt-4o', messages: [ - ...this.createCodeMessageContext(), + ...CODE_PROMPT, ...previousContext, { role: 'user', content: prompt, }, ], - tools: this.createCodeTools(), + tools: CODE_TOOLS, tool_choice: { type: 'function', function: { @@ -65,133 +199,19 @@ export const copilotService = { result.choices[0].message.tool_calls, 'OpenAICodeResponse', ) - logger.debug( - { response: result.choices[0].message.tool_calls[0] }, - '[CopilotService#generateCode] Response received...', - ) - return result.choices[0].message.tool_calls[0].function.arguments - }, - - createCodeTools(): ChatCompletionTool[] { - const tools = [ - { - type: 'function', - function: { - name: 'generate_code', - description: 'Write TypeScript code snippet based on user prompt.', - parameters: { - type: 'object', - properties: { - code: { - type: 'string', - description: 'The code snippet to write.', - }, - inputs: { - type: 'array', - description: 'The inputs used in the code snippet.', - items: { - type: 'object', - properties: { - key: { - type: 'string', - description: 'The name of the input property.', - }, - value: { - type: 'string', - description: 'The value to fill the property with.', - }, - }, - }, - }, - packages: { - type: 'array', - description: 'The packages imported in the code snippet', - items: { - type: 'string', - description: - 'The name of the package, e.g axios, lodash, etc.', - }, - }, - }, - required: ['code'], - }, - }, - }, - ] - - return tools as ChatCompletionTool[] - }, - - createCodeMessageContext(): ChatCompletionMessageParam[] { - return [ - { - role: 'user', - content: ` -# INTRODUCTION -You are a TypeScript coding bot that helps users turn natural language into useable code, for an open-source automation platform called Activepieces. - -# RESPONSE FORMAT -You will not respond to any messages that require a conversational answer. -You will not elaborate. -You MUST respond ONLY with a function call. -You will use import to import any libraries you need. You will be penalized for using require. You will be punished for using libraries that are not imported. - `, + const response = JSON.parse(result.choices[0].message.tool_calls[0].function.arguments) as OpenAIResponse + return { + code: response.code, + inputs: response.inputs.reduce((acc, curr) => { + acc[curr.key] = curr.value + return acc + }, {} as Record), + packageJson: { + depdedencies: response.packages.reduce((acc, curr) => { + acc[curr] = curr + return acc + }, {} as Record), }, - { - role: 'user', - content: - 'I want code that will combine 2 arrays and only return the unique elements', - }, - { - role: 'assistant', - content: null, - function_call: { - name: 'generate_code', - arguments: - '{ "code": "export const code = async (inputs) => { const combinedArray = [...inputs.array1, ...inputs.array2] const uniqueArray = Array.from(new Set(combinedArray)) return uniqueArray};", "inputs": [ { "key": "array1", "value": "[1,2,3]" }, { "key": "array2", "value": "[4,5,6]" } ], "packages": [] }', - }, - }, - { - role: 'user', - content: - 'Write me a piece of code that splits the user\'s first name from his last name in a full name string received in inputs.', - }, - { - role: 'assistant', - content: null, - function_call: { - name: 'generate_code', - arguments: - '{ "code": "export const code = async (inputs) => { const nameParts = inputs.fullName.split(\' \') const firstName = nameParts[0] const lastName = nameParts.slice(1).join(\'\') return { firstName, lastName }};", "inputs": [ { "key": "fullName","value": "John Doe" } ], "packages": [] }', - }, - }, - { - role: 'user', - content: - 'from an array of objects, take the created_at property for each object and print it as an ISO string', - }, - { - role: 'assistant', - content: null, - function_call: { - name: 'generate_code', - arguments: - '{ "code": "export const code = async (inputs) => { const isoStrings = inputs.array.map(obj => new Date(obj.created_at).toISOString()) return isoStrings;};", "inputs": [ { "key": "array","value": "[{ "created_at": "2022-01-14T12:34:56Z" }, { "created_at": "2022-01-15T09:45:30Z" } ]" } ], "packages": [] }', - }, - }, - { - role: 'user', - content: 'Hi', - }, - { - role: 'assistant', - content: null, - function_call: { - name: 'generate_code', - arguments: - '{ "code": "export const code = async (inputs) => { return \'Hi\'};", "inputs": [], "packages": [] }', - }, - }, - ] + } }, -} \ No newline at end of file +} diff --git a/packages/shared/src/lib/copilot/index.ts b/packages/shared/src/lib/copilot/index.ts index 4a5eb78f5d..1debaa0f33 100644 --- a/packages/shared/src/lib/copilot/index.ts +++ b/packages/shared/src/lib/copilot/index.ts @@ -12,7 +12,11 @@ export const GenerateCodeRequest = Type.Object({ export type GenerateCodeRequest = Static export const GenerateCodeResponse = Type.Object({ - result: Type.String(), + code: Type.String(), + packageJson: Type.Object({ + depdedencies: Type.Record(Type.String(), Type.String()) + }), + inputs: Type.Record(Type.String(), Type.String()), }) export type GenerateCodeResponse = Static diff --git a/packages/ui/feature-builder-form-controls/src/lib/components/code-artifact-form-control/code-artifact-control-fullscreen/code-artifact-control-fullscreen.component.html b/packages/ui/feature-builder-form-controls/src/lib/components/code-artifact-form-control/code-artifact-control-fullscreen/code-artifact-control-fullscreen.component.html index 06ca473001..fb7bda51f3 100755 --- a/packages/ui/feature-builder-form-controls/src/lib/components/code-artifact-form-control/code-artifact-control-fullscreen/code-artifact-control-fullscreen.component.html +++ b/packages/ui/feature-builder-form-controls/src/lib/components/code-artifact-form-control/code-artifact-control-fullscreen/code-artifact-control-fullscreen.component.html @@ -4,27 +4,6 @@ > Code Editor - -
- - Ask AI -
-
@if(!readOnly && (allowNpmPackages$ | async)) { diff --git a/packages/ui/feature-builder-right-sidebar/src/lib/input-forms/code-step-input-form/code-step-input-form.component.html b/packages/ui/feature-builder-right-sidebar/src/lib/input-forms/code-step-input-form/code-step-input-form.component.html index a309474d11..daf0b22b8d 100755 --- a/packages/ui/feature-builder-right-sidebar/src/lib/input-forms/code-step-input-form/code-step-input-form.component.html +++ b/packages/ui/feature-builder-right-sidebar/src/lib/input-forms/code-step-input-form/code-step-input-form.component.html @@ -10,19 +10,7 @@
- - - -
- - Ask AI -
-
-
+
Date: Tue, 13 Aug 2024 00:43:51 +0200 Subject: [PATCH 05/12] feat: 0.30.0-rc.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0ab9b81bfb..a6229d6570 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "activepieces", "version": "0.29.1", - "rcVersion": "0.30.0-rc.4", + "rcVersion": "0.30.0-rc.5", "scripts": { "prepare": "husky install", "serve:frontend": "nx serve ui-core", From 9630a341648288bce66b6298767ef97111d1a432 Mon Sep 17 00:00:00 2001 From: Mohammad AbuAboud Date: Tue, 13 Aug 2024 00:45:15 +0200 Subject: [PATCH 06/12] revert: "feat: 0.30.0-rc.5" This reverts commit e4f79b236fe65718b7897c93b666a03e4a7ed562. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a6229d6570..0ab9b81bfb 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "activepieces", "version": "0.29.1", - "rcVersion": "0.30.0-rc.5", + "rcVersion": "0.30.0-rc.4", "scripts": { "prepare": "husky install", "serve:frontend": "nx serve ui-core", From 50928d16306d72803aff681ada82e8c3fb366624 Mon Sep 17 00:00:00 2001 From: Mohammad AbuAboud Date: Tue, 13 Aug 2024 00:46:08 +0200 Subject: [PATCH 07/12] feat: 0.30.0-rc.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0ab9b81bfb..a6229d6570 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "activepieces", "version": "0.29.1", - "rcVersion": "0.30.0-rc.4", + "rcVersion": "0.30.0-rc.5", "scripts": { "prepare": "husky install", "serve:frontend": "nx serve ui-core", From 0d1f01e87076ca26fbf27dcc7e5ac0d66bcac517 Mon Sep 17 00:00:00 2001 From: Mohammad AbuAboud Date: Tue, 13 Aug 2024 01:00:30 +0200 Subject: [PATCH 08/12] fix: revert schema in app event controller --- .../app-event-routing.module.ts | 148 +++++++++--------- 1 file changed, 76 insertions(+), 72 deletions(-) diff --git a/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts b/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts index 1993541f52..e511ad9c0f 100644 --- a/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts +++ b/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts @@ -15,6 +15,7 @@ import { FastifyPluginAsyncTypebox, Type } from '@fastify/type-provider-typebox' import { StatusCodes } from 'http-status-codes' import { DEFAULT_PRIORITY } from '../workers/queue/queue-manager' import { appEventRoutingService } from './app-event-routing.service' +import { FastifyRequest } from 'fastify' const appWebhooks: Record = { slack, @@ -36,79 +37,82 @@ export const appEventRoutingModule: FastifyPluginAsyncTypebox = async (app) => { export const appEventRoutingController: FastifyPluginAsyncTypebox = async ( fastify, ) => { - fastify.all('/:pieceUrl', EventRoutingParam, async (request, requestReply) => { - const pieceUrl = request.params.pieceUrl - const payload = { - headers: request.headers as Record, - body: request.body, - rawBody: request.rawBody, - method: request.method, - queryParams: request.query as Record, - } - const piece = appWebhooks[pieceUrl] - if (isNil(piece)) { - throw new ActivepiecesError({ - code: ErrorCode.PIECE_NOT_FOUND, - params: { - pieceName: pieceUrl, - pieceVersion: 'latest', - message: 'Pieces is not found in app event routing', - }, - }) - } - const appName = pieceNames[pieceUrl] - assertNotNullOrUndefined(piece.events, 'Event is possible in this piece') - const { reply, event, identifierValue } = piece.events.parseAndReply({ payload }) - if (!isNil(reply)) { + fastify.all( + '/:pieceUrl', + { + config: { + rawBody: true, + allowedPrincipals: ALL_PRINCIPAL_TYPES, + }, + }, + async ( + request: FastifyRequest<{ + Body: unknown + Params: { + pieceUrl: string + } + }>, + requestReply, + ) => { + const pieceUrl = request.params.pieceUrl + const payload = { + headers: request.headers as Record, + body: request.body, + rawBody: request.rawBody, + method: request.method, + queryParams: request.query as Record, + } + const piece = appWebhooks[pieceUrl] + if (isNil(piece)) { + throw new ActivepiecesError({ + code: ErrorCode.PIECE_NOT_FOUND, + params: { + pieceName: pieceUrl, + pieceVersion: 'latest', + message: 'Pieces is not found in app event routing', + }, + }) + } + const appName = pieceNames[pieceUrl] + assertNotNullOrUndefined(piece.events, 'Event is possible in this piece') + const { reply, event, identifierValue } = piece.events.parseAndReply({ payload }) + if (!isNil(reply)) { + logger.info({ + reply, + piece: pieceUrl, + }, '[AppEventRoutingController#event] reply') + return requestReply.status(StatusCodes.OK).headers(reply?.headers ?? {}).send(reply?.body ?? {}) + } logger.info({ - reply, - piece: pieceUrl, - }, '[AppEventRoutingController#event] reply') - return requestReply.status(StatusCodes.OK).headers(reply?.headers ?? {}).send(reply?.body ?? {}) - } - logger.info({ - event, - identifierValue, - }, '[AppEventRoutingController#event] event') - if (isNil(event) || isNil(identifierValue)) { - return requestReply.status(StatusCodes.BAD_REQUEST).send({}) - } - const listeners = await appEventRoutingService.listListeners({ - appName, - event, - identifierValue, - }) - const eventsQueue = listeners.map(async (listener) => { - const requestId = apId() - return { - id: requestId, - type: JobType.WEBHOOK, - data: { - projectId: listener.projectId, - schemaVersion: LATEST_JOB_DATA_SCHEMA_VERSION, - requestId, - synchronousHandlerId: null, - payload, - flowId: listener.flowId, - simulate: false, - }, - priority: DEFAULT_PRIORITY, + event, + identifierValue, + }, '[AppEventRoutingController#event] event') + if (isNil(event) || isNil(identifierValue)) { + return requestReply.status(StatusCodes.BAD_REQUEST).send({}) } + const listeners = await appEventRoutingService.listListeners({ + appName, + event, + identifierValue, + }) + const eventsQueue = listeners.map(async (listener) => { + const requestId = apId() + return { + id: requestId, + type: JobType.WEBHOOK, + data: { + projectId: listener.projectId, + schemaVersion: LATEST_JOB_DATA_SCHEMA_VERSION, + requestId, + synchronousHandlerId: null, + payload, + flowId: listener.flowId, + simulate: false, + }, + priority: DEFAULT_PRIORITY, + } + }) + rejectedPromiseHandler(Promise.all(eventsQueue)) + return requestReply.status(StatusCodes.OK).send({}) }) - rejectedPromiseHandler(Promise.all(eventsQueue)) - return requestReply.status(StatusCodes.OK).send({}) - }) } - -const EventRoutingParam = { - config: { - rawBody: true, - allowedPrincipals: ALL_PRINCIPAL_TYPES, - }, - schema: { - params: Type.Object({ - pieceUrl: Type.String(), - }), - body: Type.Unknown(), - }, -} \ No newline at end of file From 587cf6a9c00ca7cb4123a4a4daddba12f3890539 Mon Sep 17 00:00:00 2001 From: Mohammad AbuAboud Date: Tue, 13 Aug 2024 01:01:31 +0200 Subject: [PATCH 09/12] fix: lint in shared --- packages/shared/src/lib/copilot/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared/src/lib/copilot/index.ts b/packages/shared/src/lib/copilot/index.ts index 1debaa0f33..fcd7b4e86c 100644 --- a/packages/shared/src/lib/copilot/index.ts +++ b/packages/shared/src/lib/copilot/index.ts @@ -14,7 +14,7 @@ export type GenerateCodeRequest = Static export const GenerateCodeResponse = Type.Object({ code: Type.String(), packageJson: Type.Object({ - depdedencies: Type.Record(Type.String(), Type.String()) + depdedencies: Type.Record(Type.String(), Type.String()), }), inputs: Type.Record(Type.String(), Type.String()), }) From d35bdb48ad5b87e46ed241973f059149542b8c2a Mon Sep 17 00:00:00 2001 From: Mohammad AbuAboud Date: Tue, 13 Aug 2024 01:08:02 +0200 Subject: [PATCH 10/12] fix: app event routing --- .../src/app/app-event-routing/app-event-routing.module.ts | 4 ++-- packages/server/api/src/app/copilot/copilot.module.ts | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts b/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts index e511ad9c0f..1a8f1f5bb1 100644 --- a/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts +++ b/packages/server/api/src/app/app-event-routing/app-event-routing.module.ts @@ -11,11 +11,11 @@ import { ErrorCode, isNil, } from '@activepieces/shared' -import { FastifyPluginAsyncTypebox, Type } from '@fastify/type-provider-typebox' +import { FastifyPluginAsyncTypebox } from '@fastify/type-provider-typebox' +import { FastifyRequest } from 'fastify' import { StatusCodes } from 'http-status-codes' import { DEFAULT_PRIORITY } from '../workers/queue/queue-manager' import { appEventRoutingService } from './app-event-routing.service' -import { FastifyRequest } from 'fastify' const appWebhooks: Record = { slack, diff --git a/packages/server/api/src/app/copilot/copilot.module.ts b/packages/server/api/src/app/copilot/copilot.module.ts index 12d6eb7877..87d1ee6326 100644 --- a/packages/server/api/src/app/copilot/copilot.module.ts +++ b/packages/server/api/src/app/copilot/copilot.module.ts @@ -7,10 +7,7 @@ export const copilotModule: FastifyPluginAsyncTypebox = async () => { websocketService.addListener(WebsocketServerEvent.GENERATE_CODE, (socket) => { return async (data: GenerateCodeRequest) => { const { prompt, previousContext } = data - const result = await copilotService.generateCode({ prompt, previousContext }) - const response: GenerateCodeResponse = { - result, - } + const response: GenerateCodeResponse = await copilotService.generateCode({ prompt, previousContext }) socket.emit(WebsocketClientEvent.GENERATE_CODE_FINISHED, response) } }) From b5c7b54a4238041eb20f3abc7bb78033331e5069 Mon Sep 17 00:00:00 2001 From: Mohammad AbuAboud Date: Tue, 13 Aug 2024 01:26:56 +0200 Subject: [PATCH 11/12] fix: angular build issue --- .../code-writer-dialog.component.ts | 43 ++----------------- 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/packages/ui/feature-builder-right-sidebar/src/lib/input-forms/code-step-input-form/code-writer-dialog/code-writer-dialog.component.ts b/packages/ui/feature-builder-right-sidebar/src/lib/input-forms/code-step-input-form/code-writer-dialog/code-writer-dialog.component.ts index a52716166f..943c7a19c1 100755 --- a/packages/ui/feature-builder-right-sidebar/src/lib/input-forms/code-step-input-form/code-writer-dialog/code-writer-dialog.component.ts +++ b/packages/ui/feature-builder-right-sidebar/src/lib/input-forms/code-step-input-form/code-writer-dialog/code-writer-dialog.component.ts @@ -1,5 +1,5 @@ import { ApEdition } from '@activepieces/shared'; -import { FlagService, HighlightService } from '@activepieces/ui/common'; +import { FlagService } from '@activepieces/ui/common'; import { CodeService } from '@activepieces/ui/feature-builder-store'; import { ChangeDetectionStrategy, @@ -50,7 +50,6 @@ export class CodeWriterDialogComponent { private dialogRef: MatDialogRef, private codeWriterService: CodeWriterService, private flagService: FlagService, - private highlightService: HighlightService, @Inject(MAT_DIALOG_DATA) public data: CodeWriterDialogData, private codeService: CodeService @@ -84,39 +83,7 @@ export class CodeWriterDialogComponent { }) .pipe( tap((response) => { - this.promptForm.enable(); - this.promptForm.controls.prompt.removeValidators( - Validators.required - ); - this.promptForm.controls.prompt.setValue(''); - try { - const result: { - code: string; - inputs: { - key: string; - value: unknown; - }[]; - packages: string[]; - } = JSON.parse(response.result); - this.receivedCode$.next( - result.code.replace(/\*\*\*NEW_LINE\*\*\*/g, '\n') - ); - this.receivedInputs = result.inputs; - this.receivedPackages = result.packages; - this.receivedPackages.forEach((pkg) => { - this.lookForNpmPackage(pkg); - }); - if (this.stepper.selected) { - this.stepper.selected.completed = true; - this.stepper.next(); - } - this.prisimFix = !this.prisimFix; - this.highlightPrism(); - } catch (e) { - console.error('Copilot response not valid JSON.'); - console.error((e as Error).message); - } - this.loading$.next(false); + }), map(() => void 0) ); @@ -149,9 +116,5 @@ export class CodeWriterDialogComponent { }); this.reset(); } - private highlightPrism() { - setTimeout(() => { - this.highlightService.highlightAll(); - }, 10); - } + } From 99c1e188298fee81fdc5f0c9b5e96f7c43c6b2c1 Mon Sep 17 00:00:00 2001 From: Mohammad AbuAboud Date: Tue, 13 Aug 2024 01:54:46 +0200 Subject: [PATCH 12/12] fix: typo in deps --- packages/server/api/src/app/copilot/copilot.service.ts | 2 +- packages/shared/src/lib/copilot/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server/api/src/app/copilot/copilot.service.ts b/packages/server/api/src/app/copilot/copilot.service.ts index cf8d39942a..d47179f2d0 100644 --- a/packages/server/api/src/app/copilot/copilot.service.ts +++ b/packages/server/api/src/app/copilot/copilot.service.ts @@ -207,7 +207,7 @@ export const copilotService = { return acc }, {} as Record), packageJson: { - depdedencies: response.packages.reduce((acc, curr) => { + dependencies: response.packages.reduce((acc, curr) => { acc[curr] = curr return acc }, {} as Record), diff --git a/packages/shared/src/lib/copilot/index.ts b/packages/shared/src/lib/copilot/index.ts index fcd7b4e86c..a699d28522 100644 --- a/packages/shared/src/lib/copilot/index.ts +++ b/packages/shared/src/lib/copilot/index.ts @@ -14,7 +14,7 @@ export type GenerateCodeRequest = Static export const GenerateCodeResponse = Type.Object({ code: Type.String(), packageJson: Type.Object({ - depdedencies: Type.Record(Type.String(), Type.String()), + dependencies: Type.Record(Type.String(), Type.String()), }), inputs: Type.Record(Type.String(), Type.String()), })