diff --git a/packages/core/package.nls.json b/packages/core/package.nls.json index fdf4e5d303d..98cbeb6e956 100644 --- a/packages/core/package.nls.json +++ b/packages/core/package.nls.json @@ -26,7 +26,9 @@ "AWS.stepFunctions.asl.maxItemsComputed.desc": "The maximum number of outline symbols and folding regions computed (limited for performance reasons).", "AWS.stepFunctions.workflowStudio.actions.progressMessage": "Opening asl file in Workflow Studio", "AWS.stepFunctions.workflowStudio.actions.saveSuccessMessage": "{0} has been saved", - "AWS.stepFunctions.workflowStudio.actions.invalidJson": "The Workflow Studio editor was not opened because the JSON in the file is invalid. To access Workflow Studio, please fix the JSON and manually reopen the integration.", + "AWS.stepFunctions.workflowStudio.actions.InvalidJSONContent": "The Workflow Studio editor was not opened because the JSON in the file is invalid. To access Workflow Studio, please fix the JSON and manually reopen the integration.", + "AWS.stepFunctions.workflowStudio.actions.InvalidYAMLContent": "The Workflow Studio editor was not opened because the YAML in the file is invalid. To access Workflow Studio, please fix the YAML and manually reopen the integration.", + "AWS.stepFunctions.workflowStudio.actions.webviewFetchFailed": "Failed to load Workflow Studio editor. Please check your network connection and try again.", "AWS.configuration.description.awssam.debug.api": "API Gateway configuration", "AWS.configuration.description.awssam.debug.api.clientCertId": "The API Gateway client certificate ID", "AWS.configuration.description.awssam.debug.api.headers": "Additional HTTP headers", diff --git a/packages/core/src/stepFunctions/utils.ts b/packages/core/src/stepFunctions/utils.ts index cfb89f5f162..238a08989dd 100644 --- a/packages/core/src/stepFunctions/utils.ts +++ b/packages/core/src/stepFunctions/utils.ts @@ -6,6 +6,7 @@ import * as nls from 'vscode-nls' const localize = nls.loadMessageBundle() import { IAM, StepFunctions } from 'aws-sdk' +import * as yaml from 'js-yaml' import * as vscode from 'vscode' import { StepFunctionsClient } from '../shared/clients/stepFunctionsClient' import { fileExists } from '../shared/filesystemUtilities' @@ -232,7 +233,7 @@ export async function isDocumentValid(text: string, textDocument?: vscode.TextDo } /** - * Checks if the JSON content in a text document is invalid. + * Checks if the JSON content in an ASL text document is invalid. * Returns `true` for invalid JSON; `false` for valid JSON, empty content, or non-JSON files. * * @param textDocument - The text document to check. @@ -241,9 +242,25 @@ export async function isDocumentValid(text: string, textDocument?: vscode.TextDo export const isInvalidJsonFile = (textDocument: vscode.TextDocument): boolean => { const documentContent = textDocument.getText().trim() // An empty file or whitespace-only text is considered valid JSON for our use case - return textDocument.fileName.toLowerCase().endsWith('.json') && documentContent - ? isInvalidJson(documentContent) - : false + return textDocument.languageId === 'asl' && documentContent ? isInvalidJson(documentContent) : false +} + +/** + * Checks if the YAML content in an ASL text document is invalid. + * Returns `true` for invalid YAML; `false` for valid YAML, empty content, or non-YAML files. + * + * @param textDocument - The text document to check. + * @returns `true` if invalid; `false` otherwise. + */ +export const isInvalidYamlFile = (textDocument: vscode.TextDocument): boolean => { + try { + if (textDocument.languageId === 'asl-yaml') { + yaml.load(textDocument.getText()) + } + return false + } catch { + return true + } } const isInvalidJson = (content: string): boolean => { diff --git a/packages/core/src/stepFunctions/workflowStudio/workflowStudioEditorProvider.ts b/packages/core/src/stepFunctions/workflowStudio/workflowStudioEditorProvider.ts index 54d641df1dd..22887856c03 100644 --- a/packages/core/src/stepFunctions/workflowStudio/workflowStudioEditorProvider.ts +++ b/packages/core/src/stepFunctions/workflowStudio/workflowStudioEditorProvider.ts @@ -12,9 +12,10 @@ import { telemetry } from '../../shared/telemetry/telemetry' import globals from '../../shared/extensionGlobals' import { getRandomString, getStringHash } from '../../shared/utilities/textUtilities' import { ToolkitError } from '../../shared/errors' +import { getTabSizeSetting } from '../../shared/utilities/editorUtilities' import { WorkflowStudioEditor } from './workflowStudioEditor' import { i18n } from '../../shared/i18n-helper' -import { isInvalidJsonFile } from '../utils' +import { isInvalidJsonFile, isInvalidYamlFile } from '../utils' const isLocalDev = false const localhost = 'http://127.0.0.1:3002' @@ -72,9 +73,6 @@ export class WorkflowStudioEditorProvider implements vscode.CustomTextEditorProv * @private */ private getWebviewContent = async () => { - if (!this.webviewHtml) { - await this.fetchWebviewHtml() - } let htmlFileSplit = this.webviewHtml.split('
') // Set asset source to CDN @@ -86,13 +84,15 @@ export class WorkflowStudioEditorProvider implements vscode.CustomTextEditorProv const localeTag = `` const theme = vscode.window.activeColorTheme.kind const isDarkMode = theme === vscode.ColorThemeKind.Dark || theme === vscode.ColorThemeKind.HighContrast + const tabSizeTag = `` const darkModeTag = `` - let html = `${htmlFileSplit[0]} ${baseTag} ${localeTag} ${darkModeTag} ${htmlFileSplit[1]}` + let html = `${htmlFileSplit[0]} ${baseTag} ${localeTag} ${darkModeTag} ${tabSizeTag} ${htmlFileSplit[1]}` const nonce = getRandomString() + const localDevURL = isLocalDev ? localhost : '' htmlFileSplit = html.split("script-src 'self'") - html = `${htmlFileSplit[0]} script-src 'self' 'nonce-${nonce}' ${isLocalDev && localhost} ${htmlFileSplit[1]}` + html = `${htmlFileSplit[0]} script-src 'self' 'nonce-${nonce}' ${localDevURL} ${htmlFileSplit[1]}` htmlFileSplit = html.split('') const script = await fs.readFileText( @@ -115,35 +115,56 @@ export class WorkflowStudioEditorProvider implements vscode.CustomTextEditorProv _token: vscode.CancellationToken ): Promise