Skip to content

Commit 577018b

Browse files
committed
Enhance PostgreSQL plugin with password generation and configuration
1 parent 466f83f commit 577018b

File tree

17 files changed

+926
-198
lines changed

17 files changed

+926
-198
lines changed

package-lock.json

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@
4444
"ink": "^4.4.1",
4545
"ink-big-text": "^2.0.0",
4646
"ink-gradient": "^3.0.0",
47+
"ink-select-input": "^5.0.0",
4748
"ink-spinner": "^5.0.0",
4849
"ink-text-input": "^5.0.1",
49-
"ink-select-input": "^5.0.0",
5050
"liquidjs": "^10.10.1",
5151
"node-fetch": "^3.3.2",
5252
"ora": "^8.0.1",
@@ -56,6 +56,7 @@
5656
"devDependencies": {
5757
"@commitlint/cli": "^18.4.3",
5858
"@commitlint/config-conventional": "^18.4.3",
59+
"@types/dotenv": "^6.1.1",
5960
"@types/fs-extra": "^11.0.4",
6061
"@types/ink-big-text": "^1.2.4",
6162
"@types/ink-gradient": "^2.0.4",
@@ -64,23 +65,24 @@
6465
"@typescript-eslint/eslint-plugin": "^6.15.0",
6566
"@typescript-eslint/parser": "^6.15.0",
6667
"@vitest/coverage-v8": "^1.1.0",
68+
"@vitest/ui": "^1.1.0",
69+
"dotenv": "^16.4.7",
6770
"eslint": "^8.56.0",
6871
"eslint-config-prettier": "^9.1.0",
6972
"eslint-plugin-prettier": "^5.1.0",
7073
"eslint-plugin-react": "^7.33.2",
7174
"eslint-plugin-react-hooks": "^4.6.0",
7275
"husky": "^8.0.3",
76+
"ink-testing-library": "^3.0.0",
7377
"lint-staged": "^15.2.0",
7478
"prettier": "^3.1.1",
7579
"rimraf": "^5.0.5",
7680
"semantic-release": "^22.0.12",
81+
"strip-ansi": "^7.1.0",
7782
"tsup": "^8.0.1",
83+
"tsx": "^4.7.0",
7884
"typescript": "^5.3.3",
79-
"vitest": "^1.1.0",
80-
"@vitest/ui": "^1.1.0",
81-
"ink-testing-library": "^3.0.0",
82-
"strip-ansi": "^7.1.0",
83-
"tsx": "^4.7.0"
85+
"vitest": "^1.1.0"
8486
},
8587
"peerDependencies": {
8688
"react": "^18.2.0"

src/plugins/core/plugin-manager.ts

Lines changed: 52 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,124 +1,76 @@
1-
import fs from 'fs';
2-
import path from 'path';
3-
import { Plugin } from './types';
4-
import { DatabasePlugin } from '../databases/types';
1+
import { BaseDatabasePlugin } from '../databases/core/base-plugin';
2+
import { DatabaseAnswers, Question } from '../databases/core/types';
3+
import { PostgreSQLPlugin } from '../databases/postgresql';
4+
import { MySQLPlugin } from '../databases/mysql';
5+
import { MariaDBPlugin } from '../databases/mariadb';
6+
import { SQLitePlugin } from '../databases/sqlite';
57

68
export class PluginManager {
7-
private plugins: Map<string, Plugin>;
8-
private pluginsPath: string;
9+
private plugins: Map<string, BaseDatabasePlugin>;
910

10-
constructor(pluginsPath: string) {
11+
constructor() {
1112
this.plugins = new Map();
12-
this.pluginsPath = pluginsPath;
13+
this.loadBuiltinPlugins();
1314
}
1415

15-
// Load all plugins from the plugins directory
16-
async loadPlugins(): Promise<void> {
17-
try {
18-
// Get all database plugin directories
19-
const databasesPath = path.join(this.pluginsPath, 'databases');
20-
const entries = fs.readdirSync(databasesPath, { withFileTypes: true });
21-
22-
for (const entry of entries) {
23-
if (entry.isDirectory()) {
24-
const pluginPath = path.join(databasesPath, entry.name);
25-
await this.loadPlugin(pluginPath);
26-
}
27-
}
28-
} catch (error) {
29-
console.error('Error loading plugins:', error);
30-
}
31-
}
16+
private loadBuiltinPlugins(): void {
17+
// Load built-in plugins
18+
const builtinPlugins = [
19+
new PostgreSQLPlugin(),
20+
new MySQLPlugin(),
21+
new MariaDBPlugin(),
22+
new SQLitePlugin()
23+
] as BaseDatabasePlugin[];
3224

33-
// Load a specific plugin from a directory
34-
private async loadPlugin(pluginPath: string): Promise<void> {
35-
try {
36-
const indexPath = path.join(pluginPath, 'index.ts');
37-
if (fs.existsSync(indexPath)) {
38-
const plugin = await import(indexPath);
39-
const pluginInstance = this.instantiatePlugin(plugin);
40-
if (pluginInstance) {
41-
this.plugins.set(pluginInstance.name, pluginInstance);
42-
}
43-
}
44-
} catch (error) {
45-
console.error(`Error loading plugin from ${pluginPath}:`, error);
25+
for (const plugin of builtinPlugins) {
26+
this.plugins.set(plugin.constructor.name.toLowerCase().replace('plugin', ''), plugin);
4627
}
4728
}
4829

49-
// Create an instance of the plugin
50-
private instantiatePlugin(plugin: any): Plugin | null {
51-
const PluginClass = Object.values(plugin)[0];
52-
if (typeof PluginClass === 'function') {
53-
try {
54-
return new PluginClass();
55-
} catch (error) {
56-
console.error('Error instantiating plugin:', error);
57-
}
58-
}
59-
return null;
30+
/**
31+
* Get a list of available database types
32+
*/
33+
getDatabaseTypes(): string[] {
34+
return Array.from(this.plugins.keys());
6035
}
6136

62-
// Get a specific database plugin
63-
getDatabasePlugin(name: string): DatabasePlugin | undefined {
64-
const plugin = this.plugins.get(name);
65-
if (plugin?.type === 'database') {
66-
return plugin as DatabasePlugin;
67-
}
68-
return undefined;
37+
/**
38+
* Get a plugin by database type
39+
*/
40+
getPlugin(type: string): BaseDatabasePlugin | undefined {
41+
return this.plugins.get(type.toLowerCase());
6942
}
7043

71-
// Get all available database plugins
72-
getAllDatabasePlugins(): DatabasePlugin[] {
73-
return Array.from(this.plugins.values())
74-
.filter(plugin => plugin.type === 'database') as DatabasePlugin[];
75-
}
76-
77-
// Load templates for a specific plugin
78-
async loadTemplates(pluginName: string): Promise<Record<string, string>> {
79-
const templates: Record<string, string> = {};
80-
const plugin = this.plugins.get(pluginName);
81-
44+
/**
45+
* Get questions for a specific database type
46+
*/
47+
async getQuestions(type: string): Promise<Question[]> {
48+
const plugin = this.getPlugin(type);
8249
if (!plugin) {
83-
return templates;
84-
}
85-
86-
const templatesPath = path.join(this.pluginsPath, plugin.type + 's', pluginName, 'templates');
87-
if (!fs.existsSync(templatesPath)) {
88-
return templates;
50+
throw new Error(`Unknown database type: ${type}`);
8951
}
52+
return plugin.getQuestions();
53+
}
9054

91-
const files = fs.readdirSync(templatesPath);
92-
for (const file of files) {
93-
if (file.endsWith('.liquid')) {
94-
const templateName = path.basename(file, '.liquid');
95-
const templateContent = fs.readFileSync(path.join(templatesPath, file), 'utf-8');
96-
templates[templateName] = templateContent;
97-
}
55+
/**
56+
* Process answers for a specific database type
57+
*/
58+
processAnswers(type: string, answers: Record<string, any>): DatabaseAnswers {
59+
const plugin = this.getPlugin(type);
60+
if (!plugin) {
61+
throw new Error(`Unknown database type: ${type}`);
9862
}
99-
100-
return templates;
63+
return plugin.processAnswers(answers);
10164
}
10265

103-
// Generate Docker configuration based on selected database
104-
async generateDockerConfig(databaseType: string, answers: Record<string, any>): Promise<{
105-
templates: Record<string, string>;
106-
variables: Record<string, any>;
107-
}> {
108-
const plugin = this.getDatabasePlugin(databaseType);
66+
/**
67+
* Get template variables for a specific database type
68+
*/
69+
getTemplateVariables(type: string, answers: DatabaseAnswers): Record<string, any> {
70+
const plugin = this.getPlugin(type);
10971
if (!plugin) {
110-
throw new Error(`Database plugin ${databaseType} not found`);
72+
throw new Error(`Unknown database type: ${type}`);
11173
}
112-
113-
// Load templates
114-
const templates = await this.loadTemplates(databaseType);
115-
116-
// Get template variables from plugin
117-
const templateData = plugin.getTemplates(answers)[0]; // Get first template for now
118-
119-
return {
120-
templates,
121-
variables: templateData.variables
122-
};
74+
return plugin.getTemplateVariables(answers);
12375
}
12476
}

0 commit comments

Comments
 (0)