Commit Graph
15 Commits
Author SHA1 Message Date
martmullandGitHub 1cbbd04761 Function trigger updates 2 (#16608)
- Improves route trigger job performances
- expose function params types

## Before

<img width="938" height="271" alt="image"
src="https://github.com/user-attachments/assets/5752ba64-f31d-44ed-974d-536e63458f2c"
/>


## After

<img width="1000" height="559" alt="image"
src="https://github.com/user-attachments/assets/b1f4927a-5f43-49f0-a606-244c72356772"
/>
2025-12-16 18:20:26 +01:00
martmullandGitHub 9b00084fb0 Vendor twenty-shared into twenty-sdk (#16592)
twenty-shared is not bundled properly when deploying twenty-sdk to npm.
This aims to fix that issue
2025-12-16 16:48:38 +01:00
martmullandGitHub 7f1e69740a 1895 extensibility v1 application tokens (#16365)
First PR to implement application tokens
- add new application role in twenty-server
- move duplicated constants and types to twenty-shared
- will  add role configuration utils into twenty-sdk in another PR
2025-12-08 10:42:46 +01:00
martmullandGitHub 5e8fbc7c5c 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

<img width="1303" height="827" alt="image"
src="https://github.com/user-attachments/assets/2ce70558-91bc-4cfc-aced-42ac9e0226bf"
/>

- 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

<img width="1109" height="182" alt="image"
src="https://github.com/user-attachments/assets/2e874060-e99d-4978-ab9c-c91e52cb7478"
/>


<img width="1061" height="176" alt="image"
src="https://github.com/user-attachments/assets/1f533e32-7435-4d7b-89c6-d1154816a8ab"
/>

- add new version for create-twenty-app and twenty-sdk `0.1.3`
2025-12-04 16:40:58 +01:00
martmullandGitHub 267bfcadf8 Twenty sdk follow up (#16290)
as title
2025-12-03 15:50:16 +00:00
martmullandGitHub ea79425fc0 Fix twenty sdk and create twenty app (#16282)
As title
2025-12-03 15:12:34 +01:00
martmullandGitHub e498367e2f Merge twenty-cli into twenty-sdk (#16150)
- Moves twenty-cli content into twenty-sdk
- add a new twenty-sdk:0.1.0 version
- this new twenty-sdk exports a cli command called 'twenty' (like
twenty-cli before)
- deprecates twenty-cli
- simplify app init command base-project
- use `twenty-sdk:0.1.0` in base project
- move the "twenty-sdk/application" barrel to "twenty-sdk"
- add `create-twenty-app` package

<img width="1512" height="919" alt="image"
src="https://github.com/user-attachments/assets/007bef45-4e71-419a-9213-cebed376adbf"
/>

<img width="1506" height="929" alt="image"
src="https://github.com/user-attachments/assets/3de2fec6-1624-4923-ae13-f4e1cf165eb5"
/>
2025-12-01 11:44:35 +01:00
martmullandGitHub 1fa9c45879 Fix twenty sdk (#15991)
As title
2025-11-21 14:28:15 +00:00
Abdullah.andGitHub 222feb90b4 fix: update glob version to 11.1.0 (#15884)
Some Glob CLI related alerts were generated last night. I believe
they're safe to dismiss since I do not expect us to use the Glob CLI in
production environment, and those alerts do not impact the API, but
still updating the dependency version just in case.

Not sure if this would resolve all/any of the alerts since glob is a
dependency for many other dependencies, so a good number of dependency
variants are pulled in.

The alert that confirms it's just a CLI related vulnerability:
[Dependabot Alert
307](https://github.com/twentyhq/twenty/security/dependabot/307)
2025-11-18 17:12:53 +01:00
2a44bde848 Dynamic grql api wrapper on application sync (#15791)
# Introduction

Important note: for the moment testing this locally will require some
hack due to latest twenty-sdk not being published.
You will need to build twenty-cli and `cd packages/twenty-cli && yarn
link`
To finally sync the app in your app folder as `cd app-folder && twenty
app sync`

close https://github.com/twentyhq/core-team-issues/issues/1863

In this PR is introduced the generate sdk programmatic call to
[genql](https://genql.dev/) exposed in a `client` barrel of `twenty-sdk`
located in this package as there's high chances that will add a codegen
layer above it at some point ?

The cli calls this method after a sync application and writes a client
in a generated folder. It will make a graql introspection query on the
whole workspace. We should later improve that and only filter by current
applicationId and its dependencies ( when twenty-standard application is
introduced )

Fully typesafe ( input, output, filters etc ) auto-completed client

## Hello-world app serverless refactor

<img width="2480" height="1326" alt="image"
src="https://github.com/user-attachments/assets/b18ea372-b21d-4560-8fbc-1dc348427a95"
/>

---------

Co-authored-by: martmull <martmull@hotmail.fr>
2025-11-17 14:46:59 +01:00
martmullandGitHub 9880f192a5 Move composite types to twenty-shared (#15741) 2025-11-10 22:11:52 +01:00
martmullandGitHub aa48a68a34 Increase packages versions (#15694)
As title
2025-11-07 10:46:43 +01:00
martmullandGitHub a6cc80eedd 1751 extensibility twenty sdk v2 use twenty sdk to define a serverless function trigger (#15347)
This PR adds 2 columns handlerPath and handlerName in serverlessFunction
to locate the entrypoint of a serverless in a codebase

It adds the following decorators in twenty-sdk:
- ServerlessFunction
- DatabaseEventTrigger
- RouteTrigger
- CronTrigger
- ApplicationVariable

It still supports deprecated entity.manifest.jsonc 

Overall code needs to be cleaned a little bit, but it should work
properly so you can try to test if the DEVX fits your needs

See updates in hello-world application

```typescript
import axios from 'axios';
import {
  DatabaseEventTrigger,
  ServerlessFunction,
  RouteTrigger,
  CronTrigger,
  ApplicationVariable,
} from 'twenty-sdk';

@ApplicationVariable({
  universalIdentifier: 'dedc53eb-9c12-4fe2-ba86-4a2add19d305',
  key: 'TWENTY_API_KEY',
  description: 'Twenty API Key',
  isSecret: true,
})
@DatabaseEventTrigger({
  universalIdentifier: '203f1df3-4a82-4d06-a001-b8cf22a31156',
  eventName: 'person.created',
})
@RouteTrigger({
  universalIdentifier: 'c9f84c8d-b26d-40d1-95dd-4f834ae5a2c6',
  path: '/post-card/create',
  httpMethod: 'GET',
  isAuthRequired: false,
})
@CronTrigger({
  universalIdentifier: 'dd802808-0695-49e1-98c9-d5c9e2704ce2',
  pattern: '0 0 1 1 *', // Every year 1st of January
})
@ServerlessFunction({
  universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
})
class CreateNewPostCard {
  main = async (params: { recipient: string }): Promise<string> => {
    const { recipient } = params;

    const options = {
      method: 'POST',
      url: 'http://localhost:3000/rest/postCards',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${process.env.TWENTY_API_KEY}`,
      },
      data: { name: recipient ?? 'Unknown' },
    };

    try {
      const { data } = await axios.request(options);

      console.log(`New post card to "${recipient}" created`);

      return data;
    } catch (error) {
      console.error(error);
      throw error;
    }
  };
}

export const createNewPostCardHandler = new CreateNewPostCard().main;

```


### [edit] V2 

After the v1 proposal, I see that using a class method to define the
serverless function handler is pretty confusing. Lets leave
serverlessFunction configuration decorators on the class, but move the
handler like before. Here is the v2 hello-world serverless function:

```typescript
import axios from 'axios';
import {
  DatabaseEventTrigger,
  ServerlessFunction,
  RouteTrigger,
  CronTrigger,
  ApplicationVariable,
} from 'twenty-sdk';

@ApplicationVariable({
  universalIdentifier: 'dedc53eb-9c12-4fe2-ba86-4a2add19d305',
  key: 'TWENTY_API_KEY',
  description: 'Twenty API Key',
  isSecret: true,
})
@DatabaseEventTrigger({
  universalIdentifier: '203f1df3-4a82-4d06-a001-b8cf22a31156',
  eventName: 'person.created',
})
@RouteTrigger({
  universalIdentifier: 'c9f84c8d-b26d-40d1-95dd-4f834ae5a2c6',
  path: '/post-card/create',
  httpMethod: 'GET',
  isAuthRequired: false,
})
@CronTrigger({
  universalIdentifier: 'dd802808-0695-49e1-98c9-d5c9e2704ce2',
  pattern: '0 0 1 1 *', // Every year 1st of January
})
@ServerlessFunction({
  universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
})
export class ServerlessFunctionDefinition {}

export const main = async (params: { recipient: string }): Promise<string> => {
  const { recipient } = params;

  const options = {
    method: 'POST',
    url: 'http://localhost:3000/rest/postCards',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${process.env.TWENTY_API_KEY}`,
    },
    data: { name: recipient ?? 'Unknown' },
  };

  try {
    const { data } = await axios.request(options);

    console.log(`New post card to "${recipient}" created`);

    return data;
  } catch (error) {
    console.error(error);
    throw error;
  }
};

```


### [edit] V3

After the v2 proposal, we don't really like decorators on empty classes.
We decided to go with a Vercel approach with a config constant

```typescript
import axios from 'axios';
import { ServerlessFunctionConfig } from 'twenty-sdk';

export const main = async (params: { recipient: string }): Promise<string> => {
  const { recipient } = params;

  const options = {
    method: 'POST',
    url: 'http://localhost:3000/rest/postCards',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${process.env.TWENTY_API_KEY}`,
    },
    data: { name: recipient ?? 'Unknown' },
  };

  try {
    const { data } = await axios.request(options);

    console.log(`New post card to "${recipient}" created`);

    return data;
  } catch (error) {
    console.error(error);
    throw error;
  }
};

export const config: ServerlessFunctionConfig = {
  universalIdentifier: 'e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf',
  routeTriggers: [
  {
    universalIdentifier: 'c9f84c8d-b26d-40d1-95dd-4f834ae5a2c6',
    path: '/post-card/create',
    httpMethod: 'GET',
    isAuthRequired: false,
  }
  ],
  cronTriggers: [
    {
      universalIdentifier: 'dd802808-0695-49e1-98c9-d5c9e2704ce2',
      pattern: '0 0 1 1 *', // Every year 1st of January
    }
  ],
  databaseEventTriggers: [
  {
    universalIdentifier: '203f1df3-4a82-4d06-a001-b8cf22a31156',
    eventName: 'person.created',
   }
  ]
}

```
2025-10-29 16:51:43 +00:00
martmullandGitHub 033c28a3d5 1750 extensibility twenty sdk v2 use twenty sdk to define an object (#15230)
We maintain jsonc object definition but will deprecate them pretty soon

## Before
<img width="1512" height="575" alt="image"
src="https://github.com/user-attachments/assets/d2fa6ca4-c456-4aa9-a1e3-845b61839718"
/>

## After
<img width="1260" height="555" alt="image"
src="https://github.com/user-attachments/assets/ba72f4cf-d443-4967-913c-029bc71f3f48"
/>
2025-10-22 13:18:23 +00:00
WeikoandGitHub 76c2dc020e Add twenty-sdk (#15208) 2025-10-20 15:54:08 +02:00