-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathextension.ts
More file actions
195 lines (163 loc) · 6.37 KB
/
extension.ts
File metadata and controls
195 lines (163 loc) · 6.37 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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
import * as vscode from "vscode";
import * as path from "path";
import {
getGlobalConfigPath,
loadEnvironments,
CloudinaryEnvironment,
isPlaceholderConfig,
} from "./config/configUtils";
import detectFolderMode from "./config/detectFolderMode";
import { registerAllCommands } from "./commands/registerCommands";
import { CloudinaryTreeDataProvider } from "./tree/treeDataProvider";
import { v2 as cloudinary } from "cloudinary";
import { generateUserAgent } from "./utils/userAgent";
let statusBar: vscode.StatusBarItem;
/**
* Called by VS Code on extension activation. Sets up provider, status bar, and commands.
* @param context - Extension context provided by VS Code.
*/
export async function activate(context: vscode.ExtensionContext) {
const cloudinaryProvider = new CloudinaryTreeDataProvider();
// Check if this is the first run of the extension
const isFirstRun = context.globalState.get('cloudinary.firstRun', true);
if (isFirstRun) {
// Mark as no longer first run
context.globalState.update('cloudinary.firstRun', false);
// Show welcome screen automatically on first install
vscode.commands.executeCommand("cloudinary.openWelcomeScreen");
}
const environments = await loadEnvironments();
const firstCloudName = Object.keys(environments)[0];
const selectedEnv: CloudinaryEnvironment = environments[firstCloudName];
if (!selectedEnv) {
vscode.window.showErrorMessage(
"❌ No Cloudinary environment found in config."
);
return;
}
// Check if credentials are placeholder values
if (isPlaceholderConfig(firstCloudName, selectedEnv.apiKey, selectedEnv.apiSecret)) {
// Initialize status bar with placeholder indicator (no popup message to avoid scaring new users)
statusBar = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Right,
500
);
statusBar.text = `$(warning) Cloudinary: Not Configured`;
statusBar.tooltip = "Click to configure Cloudinary credentials";
statusBar.command = "cloudinary.openGlobalConfig";
statusBar.show();
context.subscriptions.push(statusBar);
// Still register the tree view but don't make API calls
vscode.window.registerTreeDataProvider(
"cloudinaryMediaLibrary",
cloudinaryProvider
);
registerAllCommands(context, cloudinaryProvider, statusBar);
return;
}
cloudinaryProvider.cloudName = firstCloudName;
cloudinaryProvider.apiKey = selectedEnv.apiKey;
cloudinaryProvider.apiSecret = selectedEnv.apiSecret;
cloudinaryProvider.uploadPreset = selectedEnv.uploadPreset;
// Set user platform for analytics
(cloudinary.utils as any).userPlatform = generateUserAgent();
cloudinary.config({
cloud_name: firstCloudName,
api_key: selectedEnv.apiKey,
api_secret: selectedEnv.apiSecret,
});
statusBar = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Right,
500
);
statusBar.text = `$(cloud) ${cloudinaryProvider.cloudName}`;
statusBar.tooltip = "Click to switch Cloudinary environment";
statusBar.command = "cloudinary.switchEnvironment";
statusBar.show();
context.subscriptions.push(statusBar);
// Reload config if file changes
const globalConfigPath = getGlobalConfigPath();
const watcher = vscode.workspace.createFileSystemWatcher(
new vscode.RelativePattern(
path.dirname(globalConfigPath),
path.basename(globalConfigPath)
)
);
watcher.onDidChange(async () => {
const updatedEnvs = await loadEnvironments();
const cloudNames = Object.keys(updatedEnvs);
if (cloudNames.length === 0) {
vscode.window.showErrorMessage("❌ No Cloudinary environments found in updated config.");
return;
}
// Try to keep the previously active cloud name
const preferredCloud = cloudinaryProvider.cloudName;
const newCloudName = cloudNames.includes(preferredCloud || '')
? preferredCloud
: cloudNames[0];
const env = updatedEnvs[newCloudName!];
// Check if updated credentials are still placeholders
if (isPlaceholderConfig(newCloudName!, env.apiKey, env.apiSecret)) {
statusBar.text = `$(warning) Cloudinary: Not Configured`;
statusBar.tooltip = "Click to configure Cloudinary credentials";
statusBar.command = "cloudinary.openGlobalConfig";
// Don't show message - just update status bar silently
return;
}
cloudinaryProvider.cloudName = newCloudName;
cloudinaryProvider.apiKey = env.apiKey;
cloudinaryProvider.apiSecret = env.apiSecret;
cloudinaryProvider.uploadPreset = env.uploadPreset;
statusBar.text = `$(cloud) ${newCloudName}`;
statusBar.tooltip = "Click to switch Cloudinary environment";
statusBar.command = "cloudinary.switchEnvironment";
// Update user platform for analytics
(cloudinary.utils as any).userPlatform = generateUserAgent();
cloudinary.config({
cloud_name: newCloudName!,
api_key: env.apiKey,
api_secret: env.apiSecret,
});
const cacheKey = `cloudinary.dynamicFolders.${newCloudName}`;
const cachedFolderMode = context.globalState.get(cacheKey) as boolean | undefined;
if (typeof cachedFolderMode === "boolean") {
cloudinaryProvider.dynamicFolders = cachedFolderMode;
} else {
cloudinaryProvider.dynamicFolders = await detectFolderMode(
newCloudName!,
env.apiKey,
env.apiSecret
);
context.globalState.update(cacheKey, cloudinaryProvider.dynamicFolders);
}
cloudinaryProvider.refresh({
folderPath: '',
nextCursor: null,
searchQuery: null,
resourceTypeFilter: 'all'
});
});
context.subscriptions.push(watcher);
// Detect and cache folder mode
const cacheKey = `cloudinary.dynamicFolders.${cloudinaryProvider.cloudName}`;
const cachedFolderMode = context.globalState.get(cacheKey) as boolean | undefined;
if (typeof cachedFolderMode === "boolean") {
cloudinaryProvider.dynamicFolders = cachedFolderMode;
} else {
cloudinaryProvider.dynamicFolders = await detectFolderMode(
cloudinaryProvider.cloudName,
cloudinaryProvider.apiKey,
cloudinaryProvider.apiSecret
);
context.globalState.update(cacheKey, cloudinaryProvider.dynamicFolders);
}
vscode.window.registerTreeDataProvider(
"cloudinaryMediaLibrary",
cloudinaryProvider
);
registerAllCommands(context, cloudinaryProvider, statusBar);
}
/**
* Optional cleanup on extension deactivation.
*/
export function deactivate() { }