From 57d58fde6179f46cf3f9fa20457166fe0c601063 Mon Sep 17 00:00:00 2001 From: Nick Bradley Date: Wed, 28 Jan 2026 12:09:33 +0000 Subject: [PATCH 1/3] chore: Update configuration and documentation for optional upload presets - Modified CONTRIBUTING.md and README.md to clarify that the upload preset is optional and can be omitted for signed uploads. - Updated code to handle cases where upload presets are not provided, ensuring that the application defaults to signed uploads. - Enhanced user interface elements to indicate that upload presets are optional, improving user experience and reducing confusion. --- CONTRIBUTING.md | 9 ++--- README.md | 18 ++++------ src/commands/switchEnvironment.ts | 4 +-- src/commands/uploadWidget.ts | 60 ++++++++++++++++--------------- src/commands/welcomeScreen.ts | 23 +++++------- src/config/configUtils.ts | 35 +++++++++--------- src/extension.ts | 4 +-- src/tree/treeDataProvider.ts | 8 +++-- 8 files changed, 78 insertions(+), 83 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ccad55c..682d8e8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,13 +44,14 @@ Before you begin, ensure you have the following installed: ```json { - "test-cloud": { - "apiKey": "your-test-api-key", - "apiSecret": "your-test-api-secret", - "uploadPreset": "your-test-upload-preset" + "your-cloud-name": { + "apiKey": "your-api-key", + "apiSecret": "your-api-secret" } } ``` + + > **Note:** The **cloud name is the key** (the property name). You can optionally add `"uploadPreset"` if you want a default preset. 4. **Build the extension** ```bash diff --git a/README.md b/README.md index dc3abb4..488a0cb 100644 --- a/README.md +++ b/README.md @@ -40,19 +40,15 @@ Auto-created with placeholder content on first use: ```json { - "your-cloud-name-1": { - "apiKey": "", - "apiSecret": "", - "uploadPreset": "" - }, - "your-cloud-name-2": { - "apiKey": "", - "apiSecret": "", - "uploadPreset": "" + "REPLACE_WITH_YOUR_CLOUD_NAME": { + "apiKey": "REPLACE_WITH_YOUR_API_KEY", + "apiSecret": "REPLACE_WITH_YOUR_API_SECRET" } } ``` +> **Note:** The **cloud name is the key** (the property name in the JSON object). You can optionally add `"uploadPreset": "your-preset-name"` if you want to use a default upload preset. + ### 2. **Workspace Config** (Optional override) You can also include a project-specific config: ``` @@ -87,13 +83,13 @@ Once a valid configuration has been added, the active environment will be shown - **File Browser** – Click "Browse Files" to select files from your system - **Remote URL** – Paste a URL to upload from a remote source - **Folder Selection** – Choose the destination folder from a dropdown -- **Upload Presets** – Select from your configured upload presets (view preset settings with the "Settings" toggle) +- **Upload Presets** – Optionally select from your configured upload presets (signed uploads work without a preset) - **Custom Public ID** – Specify a custom public ID for single file uploads - **Tags** – Add comma-separated tags to your uploads - **Progress Tracking** – See real-time upload progress for each file - **Uploaded Assets** – View thumbnails of uploaded assets, click to preview, copy URL or public ID -**Learn more**: See the [Cloudinary Upload Presets documentation](https://cloudinary.com/documentation/upload_presets) for details on creating and configuring upload presets. +**Learn more**: See the [Cloudinary Upload Presets documentation](https://cloudinary.com/documentation/upload_presets) for details on creating and configuring upload presets (optional). ![Uploading assets](https://res.cloudinary.com/demo/video/upload/w_1200/f_auto:animated/q_auto/e_accelerate:100/e_loop/docs/vscode-extension-vid3) diff --git a/src/commands/switchEnvironment.ts b/src/commands/switchEnvironment.ts index c27d331..a175621 100644 --- a/src/commands/switchEnvironment.ts +++ b/src/commands/switchEnvironment.ts @@ -8,7 +8,7 @@ import { generateUserAgent } from "../utils/userAgent"; interface CloudinaryEnvironment { apiKey: string; apiSecret: string; - uploadPreset: string; + uploadPreset?: string; // Optional: Default upload preset } /** @@ -44,7 +44,7 @@ function registerSwitchEnv( provider.cloudName = selected; provider.apiKey = env.apiKey; provider.apiSecret = env.apiSecret; - provider.uploadPreset = env.uploadPreset; + provider.uploadPreset = env.uploadPreset || null; const cacheKey = `cloudinary.dynamicFolders.${selected}`; const cachedFolderMode = context.globalState.get(cacheKey) as boolean | undefined; diff --git a/src/commands/uploadWidget.ts b/src/commands/uploadWidget.ts index 14de3e1..231ac08 100644 --- a/src/commands/uploadWidget.ts +++ b/src/commands/uploadWidget.ts @@ -44,14 +44,8 @@ function registerUpload( context.subscriptions.push( vscode.commands.registerCommand("cloudinary.openUploadWidget", async () => { try { + // Fetch presets but don't require them - signed uploads work without presets await provider.fetchUploadPresets(); - const uploadPreset = provider.getCurrentUploadPreset(); - - if (!uploadPreset) { - vscode.window.showErrorMessage("No upload presets available. Please create one in your Cloudinary account."); - return; - } - openOrRevealUploadPanel("", provider, context); } catch (err: any) { vscode.window.showErrorMessage(`Failed to open upload widget: ${err.message}`); @@ -65,14 +59,8 @@ function registerUpload( "cloudinary.uploadToFolder", async (folderItem: { label: string; data: { path?: string } }) => { try { + // Fetch presets but don't require them - signed uploads work without presets await provider.fetchUploadPresets(); - const uploadPreset = provider.getCurrentUploadPreset(); - - if (!uploadPreset) { - vscode.window.showErrorMessage("No upload presets available. Please create one in your Cloudinary account."); - return; - } - const folderPath = folderItem.data.path || ""; openOrRevealUploadPanel(folderPath, provider, context); } catch (err: any) { @@ -234,12 +222,17 @@ function createUploadPanel( } // Get upload options based on current preset, folder, and optional overrides - const getUploadOptions = (presetName: string, folder: string, publicId?: string, tags?: string, fileName?: string) => { + // Upload preset is optional - signed uploads work without one + const getUploadOptions = (presetName: string | null | undefined, folder: string, publicId?: string, tags?: string, fileName?: string) => { const options: Record = { - upload_preset: presetName, resource_type: "auto", }; + // Only add upload_preset if one is selected (not null, undefined, or empty string) + if (presetName && presetName.trim()) { + options.upload_preset = presetName; + } + // Add folder configuration if (folder) { if (provider.dynamicFolders) { @@ -276,7 +269,8 @@ function createUploadPanel( }; if (message.command === "uploadFile" && message.dataUri && message.fileId) { - const presetName = message.preset || currentPreset; + // Use nullish coalescing - empty string "" means "no preset" (signed upload) + const presetName = message.preset !== undefined ? message.preset : currentPreset; const folder = message.folderPath !== undefined ? message.folderPath : currentFolderPath; const options = getUploadOptions(presetName, folder, message.publicId, message.tags, message.fileName); @@ -315,7 +309,8 @@ function createUploadPanel( } if (message.command === "uploadUrl" && message.url) { - const presetName = message.preset || currentPreset; + // Use nullish coalescing - empty string "" means "no preset" (signed upload) + const presetName = message.preset !== undefined ? message.preset : currentPreset; const folder = message.folderPath !== undefined ? message.folderPath : currentFolderPath; // Try to extract filename from URL for display_name let urlFileName: string | undefined; @@ -1009,10 +1004,11 @@ function getWebviewContent(
-
Upload Preset
- +
Upload Preset (optional)
+ ${provider.uploadPresets.length > 0 ? '' : ''}