From 5e8fbc7c5cfbd19a4874cb91f50d1a5aad145171 Mon Sep 17 00:00:00 2001 From: martmull Date: Thu, 4 Dec 2025 16:40:58 +0100 Subject: [PATCH] 1825 extensibility v1 see serverless logs using subscriptions in twnty cli or settings serverkess section (#16321) - Adds a log section to settings serverless functions test tab image - Adds a new subscription endpoint to graphql api `serverlessFunctionLogs` that that emit function logs - Adds a new command `twenty app logs` to `twenty-sdk` to watch logs in terminal image image - add new version for create-twenty-app and twenty-sdk `0.1.3` --- packages/create-twenty-app/README.md | 6 ++ packages/create-twenty-app/package.json | 2 +- .../src/constants/base-application/README.md | 12 +--- .../src/utils/app-template.ts | 4 +- .../src/generated-metadata/graphql.ts | 20 ++++++ .../twenty-front/src/generated/graphql.ts | 20 ++++++ .../ServerlessFunctionExecutionResult.tsx | 7 ++- .../SettingsServerlessFunctionTestTab.tsx | 20 +++++- packages/twenty-sdk/package.json | 6 +- .../src/cli/commands/app-logs.command.ts | 62 +++++++++++++++++++ .../src/cli/commands/app.command.ts | 28 +++++++++ .../src/cli/services/api.service.ts | 50 +++++++++++++++ .../serverless-function-logs-trigger.ts | 1 + .../dtos/serverless-function-logs.dto.ts | 22 +++++++ .../dtos/serverless-function-logs.input.ts | 21 +++++++ .../serverless-function.module.ts | 2 + .../serverless-function.resolver.ts | 49 ++++++++++++++- .../serverless-function.service.ts | 19 +++++- .../constants/on-db-event-trigger.ts | 1 + .../subscriptions/subscriptions.resolver.ts | 3 +- .../subscriptions/subscriptions.service.ts | 3 +- yarn.lock | 1 + 22 files changed, 339 insertions(+), 20 deletions(-) create mode 100644 packages/twenty-sdk/src/cli/commands/app-logs.command.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/serverless-function/constants/serverless-function-logs-trigger.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/serverless-function-logs.dto.ts create mode 100644 packages/twenty-server/src/engine/metadata-modules/serverless-function/dtos/serverless-function-logs.input.ts create mode 100644 packages/twenty-server/src/engine/subscriptions/constants/on-db-event-trigger.ts diff --git a/packages/create-twenty-app/README.md b/packages/create-twenty-app/README.md index ce7cd052f5..96b3c2c44a 100644 --- a/packages/create-twenty-app/README.md +++ b/packages/create-twenty-app/README.md @@ -42,8 +42,14 @@ yarn dev # Or run a one‑time sync yarn sync +# Watch your application's functions logs +yarn logs + # Uninstall the application from the current workspace yarn uninstall + +# Display commands' help +yarn help ``` ## What gets scaffolded diff --git a/packages/create-twenty-app/package.json b/packages/create-twenty-app/package.json index d387a360cb..b520bbcb71 100644 --- a/packages/create-twenty-app/package.json +++ b/packages/create-twenty-app/package.json @@ -1,6 +1,6 @@ { "name": "create-twenty-app", - "version": "0.1.0", + "version": "0.1.3", "description": "Command-line interface to create Twenty application", "main": "dist/cli.cjs", "bin": "dist/cli.cjs", diff --git a/packages/create-twenty-app/src/constants/base-application/README.md b/packages/create-twenty-app/src/constants/base-application/README.md index 58bc619f4e..6f50cba69c 100644 --- a/packages/create-twenty-app/src/constants/base-application/README.md +++ b/packages/create-twenty-app/src/constants/base-application/README.md @@ -8,22 +8,14 @@ First, authenticate to your workspace: yarn auth ``` -Then, run the development server: +Then, install this app to your workspace: ```bash -yarn dev +yarn sync ``` Open your Twenty instance and go to `/settings/applications` section to see the result. -You can start adding twenty entities by running - -```bash -yarn create-entity -``` - -The application auto-updates as you edit the file. - ## Learn More To learn more about Twenty applications, take a look at the following resources: diff --git a/packages/create-twenty-app/src/utils/app-template.ts b/packages/create-twenty-app/src/utils/app-template.ts index 4310c9836f..1ce01a3190 100644 --- a/packages/create-twenty-app/src/utils/app-template.ts +++ b/packages/create-twenty-app/src/utils/app-template.ts @@ -121,11 +121,13 @@ const createPackageJson = async ({ dev: 'twenty app dev', generate: 'twenty app generate', sync: 'twenty app sync', + logs: 'twenty app logs', uninstall: 'twenty app uninstall', + help: 'twenty help', auth: 'twenty auth login', }, dependencies: { - 'twenty-sdk': '0.1.2', + 'twenty-sdk': '0.1.3', }, devDependencies: { '@types/node': '^24.7.2', diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 25d12b57fa..dcc9d7bb4a 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -3946,6 +3946,20 @@ export type ServerlessFunctionLayer = { updatedAt: Scalars['DateTime']; }; +export type ServerlessFunctionLogs = { + __typename?: 'ServerlessFunctionLogs'; + /** Execution Logs */ + logs: Scalars['String']; +}; + +export type ServerlessFunctionLogsInput = { + applicationId?: InputMaybe; + applicationUniversalIdentifier?: InputMaybe; + id?: InputMaybe; + name?: InputMaybe; + universalIdentifier?: InputMaybe; +}; + export type SetupOidcSsoInput = { clientID: Scalars['String']; clientSecret: Scalars['String']; @@ -4008,6 +4022,7 @@ export type SubmitFormStepInput = { export type Subscription = { __typename?: 'Subscription'; onDbEvent: OnDbEvent; + serverlessFunctionLogs: ServerlessFunctionLogs; }; @@ -4015,6 +4030,11 @@ export type SubscriptionOnDbEventArgs = { input: OnDbEventInput; }; + +export type SubscriptionServerlessFunctionLogsArgs = { + input: ServerlessFunctionLogsInput; +}; + export enum SubscriptionInterval { Month = 'Month', Year = 'Year' diff --git a/packages/twenty-front/src/generated/graphql.ts b/packages/twenty-front/src/generated/graphql.ts index 32d76a6937..10b89c09f8 100644 --- a/packages/twenty-front/src/generated/graphql.ts +++ b/packages/twenty-front/src/generated/graphql.ts @@ -3783,6 +3783,20 @@ export type ServerlessFunctionLayer = { updatedAt: Scalars['DateTime']; }; +export type ServerlessFunctionLogs = { + __typename?: 'ServerlessFunctionLogs'; + /** Execution Logs */ + logs: Scalars['String']; +}; + +export type ServerlessFunctionLogsInput = { + applicationId?: InputMaybe; + applicationUniversalIdentifier?: InputMaybe; + id?: InputMaybe; + name?: InputMaybe; + universalIdentifier?: InputMaybe; +}; + export type SetupOidcSsoInput = { clientID: Scalars['String']; clientSecret: Scalars['String']; @@ -3845,6 +3859,7 @@ export type SubmitFormStepInput = { export type Subscription = { __typename?: 'Subscription'; onDbEvent: OnDbEvent; + serverlessFunctionLogs: ServerlessFunctionLogs; }; @@ -3852,6 +3867,11 @@ export type SubscriptionOnDbEventArgs = { input: OnDbEventInput; }; + +export type SubscriptionServerlessFunctionLogsArgs = { + input: ServerlessFunctionLogsInput; +}; + export enum SubscriptionInterval { Month = 'Month', Year = 'Year' diff --git a/packages/twenty-front/src/modules/serverless-functions/components/ServerlessFunctionExecutionResult.tsx b/packages/twenty-front/src/modules/serverless-functions/components/ServerlessFunctionExecutionResult.tsx index 65182f635d..8e4c2205e6 100644 --- a/packages/twenty-front/src/modules/serverless-functions/components/ServerlessFunctionExecutionResult.tsx +++ b/packages/twenty-front/src/modules/serverless-functions/components/ServerlessFunctionExecutionResult.tsx @@ -7,9 +7,11 @@ import { ServerlessFunctionExecutionStatus } from '~/generated-metadata/graphql' export const ServerlessFunctionExecutionResult = ({ serverlessFunctionTestData, + maxHeight, isTesting = false, }: { serverlessFunctionTestData: ServerlessFunctionTestData; + maxHeight?: number; isTesting?: boolean; }) => { const result = @@ -40,7 +42,10 @@ export const ServerlessFunctionExecutionResult = ({ 0 ? 200 : undefined + } isTesting={isTesting} /> + {serverlessFunctionTestData.output.logs.length > 0 && ( + + Logs +