diff --git a/package-lock.json b/package-lock.json index 645172d..7bdcfcb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "@salesforce-ux/design-system": "^2.23.2", - "@vscode/codicons": "^0.0.35", + "@vscode/codicons": "^0.0.36", "winston": "^3.13.0" }, "devDependencies": { @@ -1825,9 +1825,9 @@ "dev": true }, "node_modules/@vscode/codicons": { - "version": "0.0.35", - "resolved": "https://registry.npmjs.org/@vscode/codicons/-/codicons-0.0.35.tgz", - "integrity": "sha512-7iiKdA5wHVYSbO7/Mm0hiHD3i4h+9hKUe1O4hISAe/nHhagMwb2ZbFC8jU6d7Cw+JNT2dWXN2j+WHbkhT5/l2w==" + "version": "0.0.36", + "resolved": "https://registry.npmjs.org/@vscode/codicons/-/codicons-0.0.36.tgz", + "integrity": "sha512-wsNOvNMMJ2BY8rC2N2MNBG7yOowV3ov8KlvUE/AiVUlHKTfWsw3OgAOQduX7h0Un6GssKD3aoTVH+TF3DSQwKQ==" }, "node_modules/@vscode/test-electron": { "version": "2.3.10", diff --git a/package.json b/package.json index 6a3e7e2..1966cbe 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ }, { "command": "sfmc-devtools-vscext.devtoolsCMCopyToBU", - "when": "sfmc-devtools-vscode.isDevToolsProject && editorIsOpen && resourcePath =~ /retrieve/" + "when": "sfmc-devtools-vscode.isDevToolsProject && editorIsOpen && resourcePath =~ /\\\\retrieve\\\\.*\\\\.*/" } ], "explorer/context": [ @@ -85,7 +85,7 @@ "group": "devtools" }, { - "when": "sfmc-devtools-vscode.isDevToolsProject && resourcePath =~ /retrieve/ && resourceFilename != 'retrieve' && resourceFilename != 'deploy'", + "when": "sfmc-devtools-vscode.isDevToolsProject && resourcePath =~ /\\\\retrieve\\\\.*\\\\.*/", "command": "sfmc-devtools-vscext.devtoolsCMCopyToBU", "group": "devtools" } @@ -102,7 +102,7 @@ "group": "devtools" }, { - "when": "sfmc-devtools-vscode.isDevToolsProject && resourcePath =~ /retrieve/ && resourceFilename != 'retrieve' && resourceFilename != 'deploy'", + "when": "sfmc-devtools-vscode.isDevToolsProject && resourcePath =~ /\\\\retrieve\\\\.*\\\\.*/", "command": "sfmc-devtools-vscext.devtoolsCMCopyToBU", "group": "devtools" } @@ -119,7 +119,7 @@ "group": "devtools" }, { - "when": "sfmc-devtools-vscode.isDevToolsProject && resourcePath =~ /retrieve/ && resourceFilename != 'retrieve' && resourceFilename != 'deploy'", + "when": "sfmc-devtools-vscode.isDevToolsProject && resourcePath =~ /\\\\retrieve\\\\.*\\\\.*/", "command": "sfmc-devtools-vscext.devtoolsCMCopyToBU", "group": "devtools" } @@ -165,7 +165,7 @@ }, "dependencies": { "@salesforce-ux/design-system": "^2.23.2", - "@vscode/codicons": "^0.0.35", + "@vscode/codicons": "^0.0.36", "winston": "^3.13.0" } } diff --git a/src/devtools/commands/DevToolsAdminCommands.ts b/src/devtools/commands/DevToolsAdminCommands.ts index 58f2854..1d2c98d 100644 --- a/src/devtools/commands/DevToolsAdminCommands.ts +++ b/src/devtools/commands/DevToolsAdminCommands.ts @@ -59,11 +59,7 @@ class DevToolsAdminCommands extends DevToolsCommands { } log("debug", `Init payload: ${JSON.stringify(initArgs)}`); - const commandConfigured: string | undefined = await this.configureCommandWithParameters( - config, - initArgs, - [] - ); + const commandConfigured: string | undefined = await this.configureCommandWithParameters(config, initArgs); // Checks if the command is still missing so required parameter if (this.hasPlaceholders(commandConfigured)) { log("debug", `Required Parameters missing from Init command: ${commandConfigured}`); @@ -89,11 +85,7 @@ class DevToolsAdminCommands extends DevToolsCommands { try { log("info", `Running DevTools Admin Command: Explain Types...`); if ("command" in config && config.command) { - const commandConfigured: string | undefined = await this.configureCommandWithParameters( - config, - args, - [] - ); + const commandConfigured: string | undefined = await this.configureCommandWithParameters(config, args); log("debug", `Explain types final command: ${commandConfigured}`); const commandResult: string | number = await this.executeCommand( commandConfigured, diff --git a/src/devtools/commands/DevToolsCommands.ts b/src/devtools/commands/DevToolsCommands.ts index 39824f7..65a1221 100644 --- a/src/devtools/commands/DevToolsCommands.ts +++ b/src/devtools/commands/DevToolsCommands.ts @@ -3,7 +3,6 @@ import * as commandsConfig from "./commands.config.json"; import DevToolsCommandSetting from "../../shared/interfaces/devToolsCommandSetting"; import DevToolsCommandRunner from "../../shared/interfaces/devToolsCommandRunner"; import SupportedMetadataTypes from "../../shared/interfaces/supportedMetadataTypes"; -import InputOptionsSettings from "../../shared/interfaces/inputOptionsSettings"; import { editorInput } from "../../editor/input"; import { log } from "../../editor/output"; import { lib } from "../../shared/utils/lib"; @@ -13,10 +12,9 @@ import { metadatatypes } from "../../config/metadatatypes.config"; abstract class DevToolsCommands { static readonly commandPrefix: string = "mcdev"; static commandMap: { [key: string]: DevToolsCommands }; + static metadataTypes: SupportedMetadataTypes[]; abstract run(commandRunner: DevToolsCommandRunner): void; - abstract setMetadataTypes(mdTypes: SupportedMetadataTypes[]): void; - abstract getMetadataTypes(): SupportedMetadataTypes[] | void; abstract isSupportedMetadataType(action: string, metadataType: string): boolean | void; executeCommand(command: string, path: string, showOnTerminal: boolean): Promise { @@ -44,8 +42,7 @@ abstract class DevToolsCommands { async configureCommandWithParameters( config: DevToolsCommandSetting, - args: { [key: string]: string | string[] | boolean }, - mdTypes: SupportedMetadataTypes[] + args: { [key: string]: string | string[] | boolean } ): Promise { log("debug", `ConfigureCommandWithParameters: ${JSON.stringify(config)}`); let { command } = config; @@ -54,14 +51,6 @@ abstract class DevToolsCommands { for (const param of config.requiredParams) { if (param in args && args[param]) { command = command.replace(`{{${param}}}`, args[param] as string); - } else { - // Requests user - if (param.toLowerCase() === "mdtypes" && mdTypes.length) { - const userSelecteMDTypes: string | undefined = await this.handleMetadataTypeRequest(mdTypes); - if (userSelecteMDTypes) { - command = command.replace(`{{${param}}}`, `"${userSelecteMDTypes}"`); - } - } } } } @@ -78,26 +67,6 @@ abstract class DevToolsCommands { return command; } - async handleMetadataTypeRequest(mdTypes: SupportedMetadataTypes[]): Promise { - const mdTypeInputOptions: InputOptionsSettings[] = mdTypes.map((mdType: SupportedMetadataTypes) => ({ - id: mdType.apiName, - label: mdType.name, - detail: "" - })); - const userResponse: InputOptionsSettings | InputOptionsSettings[] | undefined = - await editorInput.handleQuickPickSelection( - mdTypeInputOptions, - "Please select one or multiple metadata types...", - true - ); - if (userResponse && Array.isArray(userResponse)) { - const mdTypes: string = `${userResponse.map((response: InputOptionsSettings) => response.id)}`; - log("debug", `User selected metadata types: "${mdTypes}"`); - return mdTypes; - } - return; - } - hasPlaceholders(command: string): boolean { const pattern: RegExp = /{{.*?}}/g; return pattern.test(command); @@ -130,14 +99,11 @@ abstract class DevToolsCommands { }, {}); } - // Sends the supported mtdata types to each DevTools Command - Object.keys(this.commandMap).forEach((key: string) => { - const devToolCommand: DevToolsCommands = this.commandMap[key]; - const sortedSuppMdtByName: SupportedMetadataTypes[] = metadatatypes.sort((a, b) => - a.name.localeCompare(b.name) - ); - devToolCommand.setMetadataTypes(sortedSuppMdtByName); - }); + // Sets the metadata types sorted by name + const sortedSuppMdtByName: SupportedMetadataTypes[] = metadatatypes.sort((a, b) => + a.name.localeCompare(b.name) + ); + this.setMetadataTypes(sortedSuppMdtByName); } static async runCommand( @@ -219,6 +185,14 @@ abstract class DevToolsCommands { return false; } + static setMetadataTypes(mdTypes: SupportedMetadataTypes[]): void { + this.metadataTypes = mdTypes; + } + + static getMetadataTypes(): SupportedMetadataTypes[] { + return this.metadataTypes; + } + static isSupportedMetadataType(action: string, metadataType: string) { if ("standard" in this.commandMap) { const devToolsCommand: DevToolsCommands = this.commandMap["standard"]; diff --git a/src/devtools/commands/DevToolsStandardCommands.ts b/src/devtools/commands/DevToolsStandardCommands.ts index 7df04cc..6d40682 100644 --- a/src/devtools/commands/DevToolsStandardCommands.ts +++ b/src/devtools/commands/DevToolsStandardCommands.ts @@ -13,7 +13,6 @@ class DevToolsStandardCommands extends DevToolsCommands { commandHandlers: { [key: string]: (args?: any) => void } ) => void; } = {}; - private metadataTypes: SupportedMetadataTypes[] = []; constructor() { super(); log("debug", "DevToolsStandardCommands Class created"); @@ -35,20 +34,14 @@ class DevToolsStandardCommands extends DevToolsCommands { } } - setMetadataTypes(mdTypes: SupportedMetadataTypes[]): void { - this.metadataTypes = mdTypes; - } - - getMetadataTypes(): SupportedMetadataTypes[] { - return this.metadataTypes; - } - getSupportedMetadataTypeByAction(action: string) { const supportedActions: { [key: string]: () => SupportedMetadataTypes[] } = { retrieve: () => - this.getMetadataTypes().filter((mdType: SupportedMetadataTypes) => mdType.supports.retrieve), + DevToolsCommands.getMetadataTypes().filter( + (mdType: SupportedMetadataTypes) => mdType.supports.retrieve + ), deploy: () => - this.getMetadataTypes().filter( + DevToolsCommands.getMetadataTypes().filter( (mdType: SupportedMetadataTypes) => mdType.supports.create || mdType.supports.update ) }; @@ -70,15 +63,8 @@ class DevToolsStandardCommands extends DevToolsCommands { ) { log("info", `Running DevTools Standard Command: Retrieve...`); if ("command" in config && config.command) { - // Gets that metadata types that are supported for retrieve - const supportedMdTypes: SupportedMetadataTypes[] = this.getSupportedMetadataTypeByAction("retrieve"); - // Configures the command to replace all the parameters with the values - const commandConfigured: string | undefined = await this.configureCommandWithParameters( - config, - args, - supportedMdTypes - ); + const commandConfigured: string | undefined = await this.configureCommandWithParameters(config, args); // Checks if the command is still missing so required parameter if (this.hasPlaceholders(commandConfigured)) { @@ -89,6 +75,7 @@ class DevToolsStandardCommands extends DevToolsCommands { log("debug", `Retrieve Command configured: ${commandConfigured}`); loadingNotification(); + const commandResult: string | number = await this.executeCommand(commandConfigured, path, true); if (typeof commandResult === "number") { handleCommandResult({ success: commandResult === 0, cancelled: false }); @@ -106,15 +93,8 @@ class DevToolsStandardCommands extends DevToolsCommands { ) { log("info", `Running DevTools Standard Command: Deploy...`); if ("command" in config && config.command) { - // Gets that metadata types that are supported for deploy - const supportedMdTypes: SupportedMetadataTypes[] = this.getSupportedMetadataTypeByAction("deploy"); - // Configures the command to replace all the parameters with the values - const commandConfigured: string | undefined = await this.configureCommandWithParameters( - config, - args, - supportedMdTypes - ); + const commandConfigured: string | undefined = await this.configureCommandWithParameters(config, args); // Checks if the command is still missing so required parameter if (this.hasPlaceholders(commandConfigured)) { @@ -125,6 +105,7 @@ class DevToolsStandardCommands extends DevToolsCommands { log("debug", `Deploy Command configured: ${commandConfigured}`); loadingNotification(); + const commandResult: string | number = await this.executeCommand(commandConfigured, path, true); if (typeof commandResult === "number") { handleCommandResult({ success: commandResult === 0, cancelled: false }); diff --git a/src/devtools/commands/commands.config.json b/src/devtools/commands/commands.config.json index 39abc9b..041fcee 100644 --- a/src/devtools/commands/commands.config.json +++ b/src/devtools/commands/commands.config.json @@ -41,8 +41,8 @@ "id":"retrieve", "title": "Retrieve", "command": "mcdev retrieve {{bu}} {{mdtypes}} {{key}} --skipInteraction", - "requiredParams": ["bu", "mdtypes"], - "optionalParams": ["key"], + "requiredParams": ["bu"], + "optionalParams": ["key", "mdtypes"], "description": "Retrieves metadata of a business unit.", "isAvailable": true }, @@ -50,8 +50,8 @@ "id":"deploy", "title": "Deploy", "command": "mcdev deploy {{bu}} {{mdtypes}} {{key}} {{fromRetrieve}} --skipInteraction", - "requiredParams": ["bu", "mdtypes"], - "optionalParams": ["key", "fromRetrieve"], + "requiredParams": ["bu"], + "optionalParams": ["key", "mdtypes", "fromRetrieve"], "description": "Deploys local metadata to a business unit.", "isAvailable": true }, diff --git a/src/devtools/main.ts b/src/devtools/main.ts index 7097bab..51e1dca 100644 --- a/src/devtools/main.ts +++ b/src/devtools/main.ts @@ -15,6 +15,7 @@ import DevToolsPathComponents from "../shared/interfaces/devToolsPathComponents" import { lib } from "../shared/utils/lib"; import { file } from "../shared/utils/file"; import { editorCommands } from "../editor/commands"; +import SupportedMetadataTypes from "../shared/interfaces/supportedMetadataTypes"; async function initDevToolsExtension(): Promise { try { @@ -60,8 +61,6 @@ async function handleDevToolsRequirements(/*isDevToolsProject: boolean*/): Promi } log("info", "SFMC DevTools is installed."); - // Deactivates Compact folders for command right execution - editorDependencies.deactivateCompactFolders(); // init DevTools Commands DevToolsCommands.init(); return; @@ -624,7 +623,23 @@ async function handleCopyToBuCMCommand(selectedPaths: string[]) { const { supportedMetadataTypes, unsupportedMetadataTypes }: SupportedMetadataTypeConfiguration = configuredSelectedPaths.reduce( (accObj: SupportedMetadataTypeConfiguration, configPath: DevToolsPathConfiguration) => { - if (DevToolsCommands.isSupportedMetadataType("deploy", configPath.metadataType)) { + if (!configPath.metadataType) { + // Gets all the metadata types that are supported for deployment + const allDeployMetadataTypes: SupportedMetadataTypes[] = + DevToolsCommands.getMetadataTypes().filter((mdType: SupportedMetadataTypes) => + DevToolsCommands.isSupportedMetadataType("deploy", mdType.apiName) + ); + // Configures and adds all the metadata types that exist in the BU folder + accObj.supportedMetadataTypes = allDeployMetadataTypes + .map((mdType: SupportedMetadataTypes) => ({ + ...configPath, + absolutePath: `${configPath.absolutePath}/${mdType.apiName}`, + metadataType: mdType.apiName + })) + .filter((pathConfig: DevToolsPathConfiguration) => + file.isPathADirectory(pathConfig.absolutePath) + ); + } else if (DevToolsCommands.isSupportedMetadataType("deploy", configPath.metadataType)) { accObj.supportedMetadataTypes.push(configPath); } else { accObj.unsupportedMetadataTypes = lib.removeDuplicates([ @@ -687,21 +702,23 @@ async function handleCopyToBuCMCommand(selectedPaths: string[]) { const buSelected: string[] = buOptions.map((bu: InputOptionsSettings) => bu.id); const filePathsConfigured: FileCopyConfig[] = supportedMetadataTypes - .map((configPath: DevToolsPathConfiguration) => { - const { absolutePath, businessUnit } = configPath; - + .map(({ absolutePath, businessUnit, metadataType, keys }: DevToolsPathConfiguration) => { if (businessUnit) { let paths: string[] = []; - - if (file.isPathADirectory(absolutePath)) { - paths = [...paths, absolutePath]; + // When the selected file to copy is inside a folder in asset type + // the whole folder and all files inside should be copied + if (metadataType === "asset" && keys.length > 2) { + const [_, assetKey]: string[] = keys; + paths.push(absolutePath.split(assetKey).shift() + assetKey); + } else if (file.isPathADirectory(absolutePath)) { + paths.push(absolutePath); } else { const [currentFileExt]: string[] = mainConfig.fileExtensions.filter( (fileExt: string) => absolutePath.endsWith(fileExt) ); if (currentFileExt) { - paths = [ - ...paths, + // Copies the same file for multiple extensions, eg sql & json + paths.push( ...file.fileExists( mainConfig.fileExtensions .filter( @@ -712,12 +729,11 @@ async function handleCopyToBuCMCommand(selectedPaths: string[]) { absolutePath.replace(currentFileExt, fileExtension) ) ) - ]; + ); } } return buSelected - .filter((buSelected: string) => buSelected !== businessUnit) .map((buSelected: string) => paths.map((keyFilePath: string) => ({ sourceFilePath: keyFilePath, diff --git a/src/editor/dependencies.ts b/src/editor/dependencies.ts index e2ad812..89c3332 100644 --- a/src/editor/dependencies.ts +++ b/src/editor/dependencies.ts @@ -39,18 +39,8 @@ async function activateExtensionDependencies(dependencies: string | string[]) { } } -function deactivateCompactFolders() { - const workspaceConfiguration = editorWorkspace.handleWorkspaceConfiguration("explorer", "Workspace"); - const isCompactFoldersEnabled: boolean = Boolean(workspaceConfiguration.get("compactFolders", true)); - if (isCompactFoldersEnabled) { - // Disable Compact Folders - workspaceConfiguration.set("compactFolders", false); - } -} - const editorDependencies = { - activateExtensionDependencies, - deactivateCompactFolders + activateExtensionDependencies }; export { editorDependencies }; diff --git a/src/shared/utils/file.ts b/src/shared/utils/file.ts index ae2a5e0..0ea1bcb 100644 --- a/src/shared/utils/file.ts +++ b/src/shared/utils/file.ts @@ -18,11 +18,7 @@ function fileExists(path: string | string[]): string[] { } function isPathADirectory(path: string): boolean { - try { - return fs.lstatSync(path.replace(/^\/[a-zA-Z]:/g, "")).isDirectory(); - } catch (error) { - throw error; - } + return fileExists(path).length > 0 && fs.lstatSync(path.replace(/^\/[a-zA-Z]:/g, "")).isDirectory(); } function createFilePath(pathArray: string[]): string {