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" />
This commit is contained in:
+48
@@ -0,0 +1,48 @@
|
||||
import { existsSync } from 'fs';
|
||||
import { AppSyncCommand } from '../../commands/app-sync.command';
|
||||
import { AppUninstallCommand } from '../../commands/app-uninstall.command';
|
||||
import { COVERED_APPLICATION_FOLDERS } from './constants/covered-applications-folder.constant';
|
||||
import { getTestedApplicationPath } from './utils/get-tested-application-path.util';
|
||||
|
||||
describe.each(COVERED_APPLICATION_FOLDERS)(
|
||||
'Application: "%s" install delete and reinstall test suite',
|
||||
(applicationName) => {
|
||||
const syncCommand = new AppSyncCommand();
|
||||
const deleteCommand = new AppUninstallCommand();
|
||||
const appPath = getTestedApplicationPath(applicationName);
|
||||
|
||||
beforeAll(async () => {
|
||||
expect(existsSync(appPath)).toBe(true);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
const result = await deleteCommand.execute({
|
||||
appPath,
|
||||
askForConfirmation: false,
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
it(`should successfully install ${applicationName} application`, async () => {
|
||||
const result = await syncCommand.execute(appPath);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
it(`should successfully delete ${applicationName} application`, async () => {
|
||||
const result = await deleteCommand.execute({
|
||||
appPath,
|
||||
askForConfirmation: false,
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
it(`should successfully re-install ${applicationName} application`, async () => {
|
||||
const result = await syncCommand.execute(appPath);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
},
|
||||
);
|
||||
+1
@@ -0,0 +1 @@
|
||||
export const COVERED_APPLICATION_FOLDERS = ['hello-world'] as const;
|
||||
@@ -0,0 +1 @@
|
||||
export const SERVER_URL = 'http://localhost:3000';
|
||||
@@ -0,0 +1,7 @@
|
||||
import { type TwentyConfig } from '../../../types/config.types';
|
||||
|
||||
export const testConfig: TwentyConfig = {
|
||||
apiUrl: 'http://localhost:3000',
|
||||
apiKey:
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC1lNmI1LTQ2ODAtOGEzMi1iODIwOTczNzE1NmIiLCJ1c2VySWQiOiIyMDIwMjAyMC1lNmI1LTQ2ODAtOGEzMi1iODIwOTczNzE1NmIiLCJ3b3Jrc3BhY2VJZCI6IjIwMjAyMDIwLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtNDYzZi00MzViLTgyOGMtMTA3ZTAwN2EyNzExIiwidXNlcldvcmtzcGFjZUlkIjoiMjAyMDIwMjAtMWU3Yy00M2Q5LWE1ZGItNjg1YjUwNjlkODE2IiwidHlwZSI6IkFDQ0VTUyIsImF1dGhQcm92aWRlciI6InBhc3N3b3JkIiwiaWF0IjoxNzUxMjgxNzA0LCJleHAiOjIwNjY4NTc3MDR9.HMGqCsVlOAPVUBhKSGlD1X86VoHKt4LIUtET3CGIdik',
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
import axios from 'axios';
|
||||
import { SERVER_URL } from './constants/server-url.constant';
|
||||
|
||||
describe('Twenty Server Health Check (E2E)', () => {
|
||||
const HEALTH_ENDPOINT = `${SERVER_URL}/healthz`;
|
||||
|
||||
it('should return 200 for health', async () => {
|
||||
const response = await axios.get(HEALTH_ENDPOINT);
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.data).toBeDefined();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
import { ConfigService } from '../../services/config.service';
|
||||
import { testConfig } from './constants/testConfig';
|
||||
|
||||
beforeAll(() => {
|
||||
jest
|
||||
.spyOn(ConfigService.prototype, 'getConfig')
|
||||
.mockResolvedValue(testConfig);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
import { exec } from 'child_process';
|
||||
|
||||
export default async () =>
|
||||
new Promise<void>((resolve) => {
|
||||
exec('pkill -f "nest start" || true', (error: unknown) => {
|
||||
if (error) {
|
||||
console.log('No server processes to kill');
|
||||
} else {
|
||||
console.log('✅ Server processes cleaned up');
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
import path from 'path';
|
||||
|
||||
export const getTestedApplicationPath = (relativePath: string): string => {
|
||||
const twentyAppsPath = path.resolve(
|
||||
__dirname,
|
||||
'../../../../../../twenty-apps',
|
||||
);
|
||||
|
||||
return path.join(twentyAppsPath, relativePath);
|
||||
};
|
||||
Reference in New Issue
Block a user