forked from asyncapi/cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathenableAutoComplete.js
More file actions
160 lines (144 loc) · 4.92 KB
/
Copy pathenableAutoComplete.js
File metadata and controls
160 lines (144 loc) · 4.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/* eslint-disable @typescript-eslint/no-var-requires */
const { spawnSync } = require('child_process');
const os = require('os');
const fs = require('fs');
const path = require('path');
const allowedShells = ['zsh', 'bash'];
// Helper function to find the first existing file among a list of paths
function findExistingFile(possibleFiles) {
for (const file of possibleFiles) {
const fullPath = path.join(os.homedir(), file);
if (fs.existsSync(fullPath)) {
return fullPath;
}
}
return null;
}
const shellConfigs = {
zsh: {
rcFile: path.join(os.homedir(), '.zshrc'),
detectFile: path.join(os.homedir(), '.zshrc'),
postMessage: 'Run: source ~/.zshrc',
action: (output, rcFile) => {
const configContent = fs.existsSync(rcFile) ? fs.readFileSync(rcFile, 'utf-8') : '';
if (configContent.includes(output.trim())) {
console.log(`✅ Autocomplete is already configured in ${rcFile}. Skipping addition.`);
} else {
fs.appendFileSync(rcFile, `\n# AsyncAPI CLI Autocomplete\n${output}\n`);
console.log(`✅ Autocomplete configuration added to ${rcFile}.`);
}
},
},
bash: {
rcFile: findExistingFile(['.bashrc', '.bash_profile', '.profile']) || path.join(os.homedir(), '.bashrc'),
detectFile: findExistingFile(['.bashrc', '.bash_profile', '.profile']),
postMessage: '', // This will be set dynamically later
action: (output, rcFile) => {
const configContent = fs.existsSync(rcFile) ? fs.readFileSync(rcFile, 'utf-8') : '';
if (configContent.includes(output.trim())) {
console.log(`✅ Autocomplete is already configured in ${rcFile}. Skipping addition.`);
} else {
fs.appendFileSync(rcFile, `\n# AsyncAPI CLI Autocomplete\n${output}\n`);
console.log(`✅ Autocomplete configuration added to ${rcFile}.`);
}
},
},
};
// Set correct postMessage dynamically
if (shellConfigs.bash.detectFile) {
shellConfigs.bash.postMessage = `Run: source ${shellConfigs.bash.detectFile}`;
} else {
shellConfigs.bash.postMessage = 'Run: source ~/.bashrc';
}
function getShellConfig(shell) {
if (!allowedShells.includes(shell)) {
throw new Error(`Unsupported shell: ${shell}. Autocomplete only supports zsh and bash.`);
}
return shellConfigs[shell];
}
function detectShell() {
const detectedShells = [];
for (const [shell, config] of Object.entries(shellConfigs)) {
if (config.detectFile && fs.existsSync(config.detectFile)) {
detectedShells.push(shell);
}
}
return detectedShells;
}
function checkPotentialPath(potentialPath) {
if (potentialPath.includes(path.sep)) {
if (fs.existsSync(potentialPath)) {
return potentialPath;
}
} else {
const result = spawnSync('/bin/sh', ['-c', `command -v ${potentialPath}`], {
encoding: 'utf-8',
stdio: 'pipe',
});
if (result.status === 0 && result.stdout) {
return result.stdout.trim().split('\n')[0];
}
}
return null;
}
function findCliExecutable() {
const possiblePaths = [
path.resolve('./bin/run'),
path.resolve('../bin/run'),
path.resolve('./node_modules/.bin/asyncapi'),
'asyncapi',
];
for (const potentialPath of possiblePaths) {
try {
const foundPath = checkPotentialPath(potentialPath);
if (foundPath) {
console.log(`Found CLI executable at: ${foundPath}`);
return foundPath;
}
} catch (error) {
console.warn(`⚠️ Ignored error while checking path ${potentialPath}: ${error.message}`);
}
}
throw new Error('CLI executable not found. Ensure AsyncAPI CLI is installed.');
}
function generateAutocompleteScript(shell) {
const executablePath = findCliExecutable();
const result = spawnSync(executablePath, ['autocomplete', 'script', shell], {
encoding: 'utf-8',
stdio: 'pipe',
});
if (result.status !== 0 || result.error) {
throw new Error(
`Autocomplete setup for ${shell} failed: ${result.stderr || result.error?.message || 'Unknown error'}`
);
}
const output = result.stdout;
if (!output || output.trim() === '') {
throw new Error(`No autocomplete script generated for ${shell}.`);
}
return output;
}
function setupAutocomplete(shell) {
if (!allowedShells.includes(shell)) {
console.error(`❌ Autocomplete only supports zsh and bash. Skipping setup for ${shell}.`);
return;
}
try {
const config = getShellConfig(shell);
console.log(`🔧 Generating autocomplete script for ${shell}...`);
const output = generateAutocompleteScript(shell);
config.action(output, config.rcFile);
console.log(`✅ Autocomplete configured for ${shell}. ${config.postMessage}`);
} catch (error) {
console.error(`❌ Failed to setup autocomplete for ${shell}: ${error.message}`);
}
}
// Start
const shells = detectShell();
if (shells.length) {
for (const shell of shells) {
setupAutocomplete(shell);
}
} else {
console.log('⚠️ Shell not detected or unsupported. Autocomplete setup skipped.');
}