Files
twenty/packages/twenty-sdk/project.json
T
Charles BochetandGitHub c0cc0689d6 Add Client Api generation (#17961)
## Add API client generation to SDK dev mode and refactor orchestrator
into step-based pipeline

### Why

The SDK dev mode lacked typed API client generation, forcing developers
to work without auto-generated GraphQL types when building applications.
Additionally, the orchestrator was a monolithic class that mixed watcher
management, token handling, and sync logic — making it difficult to
extend with new steps like client generation.

### How

- **Refactored the orchestrator** into a step-based pipeline with
dedicated classes: `CheckServer`, `EnsureValidTokens`,
`ResolveApplication`, `BuildManifest`, `UploadFiles`,
`GenerateApiClient`, `SyncApplication`, and `StartWatchers`. Each step
has typed input/output/status, managed by a new `OrchestratorState`
class.
- **Added `GenerateApiClientOrchestratorStep`** that detects
object/field schema changes and regenerates a typed GraphQL client (via
`@genql/cli`) into `node_modules/twenty-sdk/generated` for seamless
imports.
- **Replaced `checkApplicationExist`** with `findOneApplication` on both
server resolver and SDK API service, returning the entity data instead
of a boolean.
- **Added application token pair mutations**
(`generateApplicationToken`, `renewApplicationToken`) to the API
service, with the server now returning `ApplicationTokenPairDTO`
containing both access and refresh tokens.
- **Restructured the dev UI** into `dev/ui/components/` with dedicated
panel, section, and event log components.
- **Simplified `AppDevCommand`** from ~180 lines of watcher management
down to ~40 lines that delegate entirely to the orchestrator.
2026-02-17 18:45:52 +01:00

231 lines
6.4 KiB
JSON

{
"name": "twenty-sdk",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/twenty-sdk/src",
"projectType": "library",
"tags": [
"scope:sdk",
"scope:shared"
],
"targets": {
"build": {
"executor": "nx:run-commands",
"cache": true,
"inputs": [
"production",
"^production"
],
"dependsOn": [
"^build"
],
"outputs": [
"{projectRoot}/dist"
],
"options": {
"cwd": "{projectRoot}",
"commands": [
"npx rimraf dist && npx vite build -c vite.config.node.ts && npx vite build -c vite.config.browser.ts && npx vite build -c vite.config.sdk.ts",
"tsgo -p tsconfig.lib.json --declaration --emitDeclarationOnly --noEmit false --outDir dist --rootDir src && npx tsc-alias -p tsconfig.lib.json --outDir dist"
],
"parallel": false
}
},
"dev": {
"executor": "nx:run-commands",
"dependsOn": [
"^build"
],
"options": {
"cwd": "packages/twenty-sdk",
"command": "npx rimraf dist && npx vite build -c vite.config.node.ts && npx vite build -c vite.config.browser.ts && npx vite build -c vite.config.sdk.ts && tsgo -p tsconfig.lib.json --declaration --emitDeclarationOnly --noEmit false --outDir dist --rootDir src && npx tsc-alias -p tsconfig.lib.json --outDir dist && npx vite build -c vite.config.node.ts --watch & npx vite build -c vite.config.browser.ts --watch & npx vite build -c vite.config.sdk.ts --watch"
}
},
"start": {
"executor": "nx:run-commands",
"dependsOn": [
"build"
],
"options": {
"cwd": "packages/twenty-sdk",
"command": "node dist/cli.cjs"
}
},
"typecheck": {},
"lint": {
"options": {
"lintFilePatterns": [
"{projectRoot}/src/**/*.{ts,json}"
],
"maxWarnings": 0
},
"configurations": {
"ci": {
"lintFilePatterns": [
"{projectRoot}/src/**/*.{ts,json}"
],
"maxWarnings": 0
},
"fix": {}
}
},
"test": {
"executor": "@nx/vitest:test",
"outputs": [
"{workspaceRoot}/coverage/{projectRoot}"
],
"options": {
"config": "{projectRoot}/vitest.config.ts"
},
"configurations": {
"ci": {
"coverage": true,
"watch": false
}
}
},
"test:unit": {
"executor": "nx:run-commands",
"options": {
"cwd": "packages/twenty-sdk",
"command": "npx vitest run --config vitest.unit.config.ts"
}
},
"test:integration": {
"executor": "nx:run-commands",
"options": {
"cwd": "packages/twenty-sdk",
"command": "npx vitest run --config vitest.integration.config.ts"
}
},
"test:e2e": {
"executor": "nx:run-commands",
"options": {
"cwd": "packages/twenty-sdk",
"command": "npx wait-on http://localhost:3000/healthz --timeout 600000 --interval 1000 --log && NODE_ENV=test npx vitest run --config ./vitest.e2e.config.ts"
},
"parallel": false,
"dependsOn": [
"build",
{
"target": "database:reset",
"projects": "twenty-server"
},
{
"target": "start:ci-if-needed",
"projects": "twenty-server"
}
]
},
"build:sdk": {
"executor": "nx:run-commands",
"cache": true,
"dependsOn": [
"^build"
],
"inputs": [
"{projectRoot}/src/sdk/**/*"
],
"outputs": [
"{projectRoot}/dist/sdk"
],
"options": {
"cwd": "{projectRoot}",
"command": "npx vite build -c vite.config.sdk.ts"
}
},
"generate-remote-dom-elements": {
"executor": "nx:run-commands",
"cache": true,
"dependsOn": [
"^build"
],
"inputs": [
"{projectRoot}/scripts/remote-dom/**/*",
"{projectRoot}/src/sdk/front-component-api/**/*",
"{workspaceRoot}/packages/twenty-ui/src/**/index.ts",
"{workspaceRoot}/packages/twenty-ui/src/**/*.tsx"
],
"outputs": [
"{projectRoot}/src/front-component-renderer/host/generated/*",
"{projectRoot}/src/front-component-renderer/remote/generated/*"
],
"options": {
"cwd": "packages/twenty-sdk",
"command": "tsx -r tsconfig-paths/register scripts/remote-dom/generate-remote-dom-elements.ts"
},
"configurations": {
"verbose": {
"command": "tsx -r tsconfig-paths/register scripts/remote-dom/generate-remote-dom-elements.ts --verbose"
}
}
},
"storybook:prebuild": {
"executor": "nx:run-commands",
"cache": true,
"dependsOn": [
"generate-remote-dom-elements",
"build:sdk",
{
"target": "build:individual",
"projects": "twenty-ui"
},
{
"target": "build:individual",
"projects": "twenty-shared"
}
],
"inputs": [
"{projectRoot}/scripts/front-component-stories/**/*",
"{projectRoot}/src/front-component-renderer/__stories__/example-sources/*",
"{projectRoot}/src/cli/utilities/build/**/*"
],
"outputs": [
"{projectRoot}/src/front-component-renderer/__stories__/example-sources-built/*"
],
"options": {
"command": "tsx {projectRoot}/scripts/front-component-stories/build-source-examples.ts"
}
},
"storybook:build": {
"dependsOn": [
"storybook:prebuild"
],
"configurations": {
"test": {}
}
},
"storybook:serve:dev": {
"executor": "nx:run-commands",
"options": {
"port": 6008
}
},
"storybook:serve:static": {
"options": {
"buildTarget": "twenty-sdk:storybook:build",
"port": 6008
},
"configurations": {
"test": {}
}
},
"storybook:test": {
"dependsOn": [
"storybook:prebuild"
],
"options": {
"command": "vitest run --coverage --config vitest.storybook.config.ts --shard={args.shard}"
}
},
"storybook:test:no-coverage": {
"dependsOn": [
"storybook:prebuild"
],
"options": {
"command": "vitest run --config vitest.storybook.config.ts --shard={args.shard}"
}
},
"storybook:coverage": {}
}
}