Stop using .env variables to authenticate with cli (#15461)
- as title, solves our user facing authentication issues using the twenty-cli - update twenty-cli version (breaking change from previous PR)
This commit is contained in:
@@ -1,4 +0,0 @@
|
||||
TWENTY_API_URL=http://localhost:3000
|
||||
# APPLE_JANE_ADMIN_ACCESS_TOKEN
|
||||
TWENTY_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC1lNmI1LTQ2ODAtOGEzMi1iODIwOTczNzE1NmIiLCJ1c2VySWQiOiIyMDIwMjAyMC1lNmI1LTQ2ODAtOGEzMi1iODIwOTczNzE1NmIiLCJ3b3Jrc3BhY2VJZCI6IjIwMjAyMDIwLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtNDYzZi00MzViLTgyOGMtMTA3ZTAwN2EyNzExIiwidXNlcldvcmtzcGFjZUlkIjoiMjAyMDIwMjAtMWU3Yy00M2Q5LWE1ZGItNjg1YjUwNjlkODE2IiwidHlwZSI6IkFDQ0VTUyIsImF1dGhQcm92aWRlciI6InBhc3N3b3JkIiwiaWF0IjoxNzUxMjgxNzA0LCJleHAiOjIwNjY4NTc3MDR9.HMGqCsVlOAPVUBhKSGlD1X86VoHKt4LIUtET3CGIdik
|
||||
TWENTY_DEFAULT_APP=e2e-default-app
|
||||
@@ -14,6 +14,7 @@ const jestConfig: JestConfigWithTsJest = {
|
||||
testRegex: '\\.e2e-spec\\.ts$',
|
||||
modulePathIgnorePatterns: ['<rootDir>/dist'],
|
||||
globalTeardown: '<rootDir>/src/__tests__/e2e/teardown.ts',
|
||||
setupFilesAfterEnv: ['<rootDir>/src/__tests__/e2e/setupTest.ts'],
|
||||
testTimeout: 30000, // 30 seconds timeout for e2e tests
|
||||
maxWorkers: 1,
|
||||
transform: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-cli",
|
||||
"version": "0.1.3",
|
||||
"version": "0.2.0",
|
||||
"description": "Command-line interface for Twenty application development",
|
||||
"main": "dist/cli.js",
|
||||
"bin": {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import { TwentyConfig } from '../../../types/config.types';
|
||||
|
||||
export const testConfig: TwentyConfig = {
|
||||
apiUrl: 'http://localhost:3000',
|
||||
apiKey:
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMDIwMjAyMC1lNmI1LTQ2ODAtOGEzMi1iODIwOTczNzE1NmIiLCJ1c2VySWQiOiIyMDIwMjAyMC1lNmI1LTQ2ODAtOGEzMi1iODIwOTczNzE1NmIiLCJ3b3Jrc3BhY2VJZCI6IjIwMjAyMDIwLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIndvcmtzcGFjZU1lbWJlcklkIjoiMjAyMDIwMjAtNDYzZi00MzViLTgyOGMtMTA3ZTAwN2EyNzExIiwidXNlcldvcmtzcGFjZUlkIjoiMjAyMDIwMjAtMWU3Yy00M2Q5LWE1ZGItNjg1YjUwNjlkODE2IiwidHlwZSI6IkFDQ0VTUyIsImF1dGhQcm92aWRlciI6InBhc3N3b3JkIiwiaWF0IjoxNzUxMjgxNzA0LCJleHAiOjIwNjY4NTc3MDR9.HMGqCsVlOAPVUBhKSGlD1X86VoHKt4LIUtET3CGIdik',
|
||||
defaultApp: 'e2e-default-app',
|
||||
};
|
||||
@@ -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();
|
||||
});
|
||||
@@ -1,40 +1,19 @@
|
||||
import { config as loadDotenv } from 'dotenv';
|
||||
import * as fs from 'fs-extra';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import { TwentyConfig } from '../types/config.types';
|
||||
|
||||
export class ConfigService {
|
||||
private configPath: string;
|
||||
private readonly configPath: string;
|
||||
|
||||
constructor() {
|
||||
this.configPath = path.join(os.homedir(), '.twenty', 'config.json');
|
||||
this.loadEnvironmentVariables();
|
||||
}
|
||||
|
||||
private loadEnvironmentVariables(): void {
|
||||
// Load local .env file if it exists in current working directory
|
||||
const localEnvPath = path.join(
|
||||
process.cwd(),
|
||||
process.env.NODE_ENV === 'test' ? '.env.e2e' : '.env',
|
||||
);
|
||||
if (fs.existsSync(localEnvPath)) {
|
||||
loadDotenv({ path: localEnvPath });
|
||||
}
|
||||
|
||||
// Also try to load from user's home .twenty directory
|
||||
const userEnvPath = path.join(os.homedir(), '.twenty', '.env');
|
||||
if (fs.existsSync(userEnvPath)) {
|
||||
loadDotenv({ path: userEnvPath });
|
||||
}
|
||||
}
|
||||
|
||||
async getConfig(): Promise<TwentyConfig> {
|
||||
try {
|
||||
// Start with default config
|
||||
const defaultConfig = this.getDefaultConfig();
|
||||
|
||||
// Load config file if it exists
|
||||
let fileConfig = {};
|
||||
await fs.ensureFile(this.configPath);
|
||||
const configExists = await fs.pathExists(this.configPath);
|
||||
@@ -45,14 +24,9 @@ export class ConfigService {
|
||||
fileConfig = JSON.parse(configContent || '{}');
|
||||
}
|
||||
|
||||
// Environment variables override everything
|
||||
const envConfig = this.getEnvironmentConfig();
|
||||
|
||||
// Merge configs with proper precedence: defaults < file < environment
|
||||
return {
|
||||
...defaultConfig,
|
||||
...fileConfig,
|
||||
...envConfig,
|
||||
};
|
||||
} catch {
|
||||
return this.getDefaultConfig();
|
||||
@@ -79,22 +53,4 @@ export class ConfigService {
|
||||
apiUrl: 'http://localhost:3000',
|
||||
};
|
||||
}
|
||||
|
||||
private getEnvironmentConfig(): Partial<TwentyConfig> {
|
||||
const envConfig: Partial<TwentyConfig> = {};
|
||||
|
||||
if (process.env.TWENTY_API_URL) {
|
||||
envConfig.apiUrl = process.env.TWENTY_API_URL;
|
||||
}
|
||||
|
||||
if (process.env.TWENTY_API_KEY) {
|
||||
envConfig.apiKey = process.env.TWENTY_API_KEY;
|
||||
}
|
||||
|
||||
if (process.env.TWENTY_DEFAULT_APP) {
|
||||
envConfig.defaultApp = process.env.TWENTY_DEFAULT_APP;
|
||||
}
|
||||
|
||||
return envConfig;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user