Fix app:dev CLI by removing deleted createOneApplication mutation (#18460)
## Summary - The `createOneApplication` GraphQL mutation was removed from the server during the application architecture refactor (#18432), but the SDK CLI (`app:dev`, `app:build --sync`) still called it, causing failures. - Simplified the SDK to use `syncApplication` (which now internally creates the `ApplicationEntity` via `ensureApplicationExists`) instead of a separate create step. - On first run (clean install), the orchestrator now runs an initial sync before initializing the file uploader, so file uploads can proceed (they require the `ApplicationEntity` to exist). ## Test plan - [x] Typecheck passes for both `twenty-sdk` and `twenty-server` - [x] `app:dev` tested locally with existing app (finds app, uploads, syncs) - [x] `app:dev` tested locally after `app:uninstall` (creates app via sync, uploads, syncs) - [x] SDK unit tests pass (23/26 files, 3 pre-existing failures unrelated) Made with [Cursor](https://cursor.com)
This commit is contained in:
+5
-5
@@ -1,7 +1,7 @@
|
||||
import { resolve } from 'path';
|
||||
import { vi } from 'vitest';
|
||||
|
||||
import { appBuild } from '@/cli/public-operations/app-build';
|
||||
import { appGenerateClient } from '@/cli/public-operations/app-generate-client';
|
||||
import { appUninstall } from '@/cli/public-operations/app-uninstall';
|
||||
import { functionExecute } from '@/cli/public-operations/function-execute';
|
||||
import { ADD_NUMBERS_UNIVERSAL_IDENTIFIER } from '../src/logic-functions/add-numbers.function';
|
||||
@@ -10,15 +10,15 @@ const APP_PATH = resolve(__dirname, '../');
|
||||
|
||||
describe('functionExecute E2E', () => {
|
||||
beforeAll(async () => {
|
||||
const buildResult = await appBuild({ appPath: APP_PATH });
|
||||
const generateResult = await appGenerateClient({ appPath: APP_PATH });
|
||||
|
||||
if (!buildResult.success) {
|
||||
if (!generateResult.success) {
|
||||
throw new Error(
|
||||
`appBuild failed: ${buildResult.error.code} – ${buildResult.error.message}`,
|
||||
`appGenerateClient failed: ${generateResult.error.code} – ${generateResult.error.message}`,
|
||||
);
|
||||
}
|
||||
|
||||
// Although appBuild uploads files before syncing the manifest, the server
|
||||
// Although appGenerateClient uploads files before syncing the manifest, the server
|
||||
// may need a moment to make them readable by the execution engine.
|
||||
// Retry a dummy execution until the handler file becomes available.
|
||||
await vi.waitFor(
|
||||
|
||||
+5
-2
@@ -7,10 +7,13 @@ export const defineEntitiesTests = (appPath: string): void => {
|
||||
describe('logicFunctions', () => {
|
||||
it('should have built logicFunctions preserving source path structure', async () => {
|
||||
const files = await readdir(outputDir, { recursive: true });
|
||||
const sortedFiles = files.map((f) => f.toString()).sort();
|
||||
// api-client is generated post-sync and depends on server schema availability
|
||||
const sortedFiles = files
|
||||
.map((f) => f.toString())
|
||||
.filter((f) => !f.startsWith('api-client'))
|
||||
.sort();
|
||||
|
||||
expect(sortedFiles).toEqual([
|
||||
'api-client',
|
||||
'manifest.json',
|
||||
'package.json',
|
||||
'public',
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ export const runAppDevInProcess = async (options: {
|
||||
|
||||
const command = new AppDevCommand();
|
||||
|
||||
await command.execute({ appPath });
|
||||
await command.execute({ appPath, headless: true });
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
|
||||
@@ -2,10 +2,6 @@ import { vi } from 'vitest';
|
||||
|
||||
const mockApiService = {
|
||||
validateAuth: vi.fn().mockResolvedValue({ authValid: true, serverUp: true }),
|
||||
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: {
|
||||
@@ -39,6 +35,10 @@ const mockApiService = {
|
||||
clientSecret: 'mock-client-secret',
|
||||
},
|
||||
}),
|
||||
createDevelopmentApplication: vi.fn().mockResolvedValue({
|
||||
success: true,
|
||||
data: { id: 'mock-app-id', universalIdentifier: 'mock-uid' },
|
||||
}),
|
||||
syncApplication: vi.fn().mockResolvedValue({ success: true, data: true }),
|
||||
uploadFile: vi.fn().mockResolvedValue({ success: true, data: true }),
|
||||
};
|
||||
@@ -46,14 +46,13 @@ const mockApiService = {
|
||||
vi.mock('@/cli/utilities/api/api-service', () => ({
|
||||
ApiService: class {
|
||||
validateAuth = mockApiService.validateAuth;
|
||||
findOneApplication = mockApiService.findOneApplication;
|
||||
createApplication = mockApiService.createApplication;
|
||||
generateApplicationToken = mockApiService.generateApplicationToken;
|
||||
renewApplicationToken = mockApiService.renewApplicationToken;
|
||||
findApplicationRegistrationByUniversalIdentifier =
|
||||
mockApiService.findApplicationRegistrationByUniversalIdentifier;
|
||||
createApplicationRegistration =
|
||||
mockApiService.createApplicationRegistration;
|
||||
createDevelopmentApplication = mockApiService.createDevelopmentApplication;
|
||||
syncApplication = mockApiService.syncApplication;
|
||||
uploadFile = mockApiService.uploadFile;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user