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.
This commit is contained in:
@@ -2,12 +2,30 @@ import { vi } from 'vitest';
|
||||
|
||||
const mockApiService = {
|
||||
validateAuth: vi.fn().mockResolvedValue({ authValid: true, serverUp: true }),
|
||||
checkApplicationExist: vi
|
||||
.fn()
|
||||
.mockResolvedValue({ success: true, data: false }),
|
||||
findOneApplication: vi.fn().mockResolvedValue({ success: true, data: null }),
|
||||
createApplication: vi
|
||||
.fn()
|
||||
.mockResolvedValue({ success: true, data: { id: 'mock-id' } }),
|
||||
generateApplicationToken: vi.fn().mockResolvedValue({
|
||||
success: true,
|
||||
data: {
|
||||
applicationAccessToken: { token: 'mock-access-token', expiresAt: '' },
|
||||
applicationRefreshToken: { token: 'mock-refresh-token', expiresAt: '' },
|
||||
},
|
||||
}),
|
||||
renewApplicationToken: vi.fn().mockResolvedValue({
|
||||
success: true,
|
||||
data: {
|
||||
applicationAccessToken: {
|
||||
token: 'mock-renewed-access-token',
|
||||
expiresAt: '',
|
||||
},
|
||||
applicationRefreshToken: {
|
||||
token: 'mock-renewed-refresh-token',
|
||||
expiresAt: '',
|
||||
},
|
||||
},
|
||||
}),
|
||||
syncApplication: vi.fn().mockResolvedValue({ success: true, data: true }),
|
||||
uploadFile: vi.fn().mockResolvedValue({ success: true, data: true }),
|
||||
};
|
||||
@@ -15,8 +33,10 @@ const mockApiService = {
|
||||
vi.mock('@/cli/utilities/api/api-service', () => ({
|
||||
ApiService: class {
|
||||
validateAuth = mockApiService.validateAuth;
|
||||
checkApplicationExist = mockApiService.checkApplicationExist;
|
||||
findOneApplication = mockApiService.findOneApplication;
|
||||
createApplication = mockApiService.createApplication;
|
||||
generateApplicationToken = mockApiService.generateApplicationToken;
|
||||
renewApplicationToken = mockApiService.renewApplicationToken;
|
||||
syncApplication = mockApiService.syncApplication;
|
||||
uploadFile = mockApiService.uploadFile;
|
||||
},
|
||||
@@ -28,6 +48,6 @@ vi.mock('@/cli/utilities/file/file-uploader', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('@/cli/utilities/dev/dev-ui', () => ({
|
||||
vi.mock('@/cli/utilities/dev/ui/components/dev-ui', () => ({
|
||||
renderDevUI: vi.fn().mockResolvedValue({ unmount: vi.fn() }),
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user