This is an automated email from the ASF dual-hosted git repository. msciabarra pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/openserverless-vscode-extension.git
commit 2b77cb577e928de44048e60dd37ddf3f0a86f392 Author: mattia-tatone <[email protected]> AuthorDate: Thu Mar 7 14:20:01 2024 +0100 Re-organize imports and watch fix --- esbuild.js | 76 ++++++----- src/constants.ts | 11 +- src/enumerators.ts | 17 +++ src/extension.ts | 96 +++++++------- src/{constants.ts => interfaces.ts} | 11 +- src/{panels/Login.ts => login/LoginPanel.ts} | 18 +-- src/login/login.ts | 85 ++++++++++++ src/{webview/main.ts => utilities/validate.ts} | 174 ++++++------------------- 8 files changed, 244 insertions(+), 244 deletions(-) diff --git a/esbuild.js b/esbuild.js index 2b76e99..7a78f4b 100644 --- a/esbuild.js +++ b/esbuild.js @@ -27,37 +27,51 @@ const extensionConfig = { } })(); -const webviewConfig = { - ...baseConfig, - target: "es2020", - format: "esm", - entryPoints: ["./src/webview/main.ts"], - outfile: "./out/webview.js", - }; - - (async () => { - const args = process.argv.slice(2); - try { - if (args.includes("--watch")) { - // Build and watch extension and webview code - console.log("[watch] build started"); - await build({ - ...extensionConfig, - ...watchConfig, - }); - await build({ - ...webviewConfig, - ...watchConfig, - }); - console.log("[watch] build finished"); +const loginConfig = { + ...baseConfig, + target: "es2020", + format: "esm", + entryPoints: ["./src/login/login.ts"], + outfile: "./out/login.js", +}; + +const watchConfig = { + watch: { + onRebuild(error, result) { + console.log("[watch] build started"); + if (error) { + error.errors.forEach(error => + console.error(`> ${error.location.file}:${error.location.line}:${error.location.column}: error: ${error.text}`) + ); } else { - // Build extension and webview code - await build(extensionConfig); - await build(webviewConfig); - console.log("build complete"); + console.log("[watch] build finished"); } - } catch (err) { - process.stderr.write(err.stderr); - process.exit(1); + }, + }, +}; + + +(async () => { + const args = process.argv.slice(2); + try { + if (args.includes("--watch")) { + console.log("[watch] build started"); + await build({ + ...extensionConfig, + ...watchConfig, + }); + await build({ + ...loginConfig, + ...watchConfig, + }); + console.log("[watch] build finished"); + } else { + await build(extensionConfig); + await build(loginConfig); + console.log("build complete"); } - })(); \ No newline at end of file + } catch (err) { + process.stderr.write(err.stderr); + process.exit(1); + } +})(); \ No newline at end of file diff --git a/src/constants.ts b/src/constants.ts index e21666f..01562f2 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,10 +1 @@ -export enum COMMANDS { - DEPLOY = "nuv ide deploy", - DEVEL = "nuv ide devel" -} - -export interface NuvolarisLoginParams { - nuvUser: string | undefined, - nuvApiHost: string | undefined, - nuvPassword: string | undefined -} \ No newline at end of file +export const NuvolarisTerminalName = "Nuvolaris"; \ No newline at end of file diff --git a/src/enumerators.ts b/src/enumerators.ts new file mode 100644 index 0000000..799b43c --- /dev/null +++ b/src/enumerators.ts @@ -0,0 +1,17 @@ +export enum Commands { + Deploy = "nuv ide deploy", + Devel = "nuv ide devel" +} + +export enum LoginPageIDs { + Username = "username-input", + Password = "password-input", + ApiHost = "api-host-input", + LoginButton = "login-button" +} + +export enum LoginEnvironmentVariables { + NuvUser = "NUV_USER", + NuvPassword = "NUV_PASSWORD", + NuvApihost = "NUV_APIHOST" +} \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index 347ec52..3a4f45e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,39 +1,44 @@ import * as vscode from 'vscode'; -import { COMMANDS, NuvolarisLoginParams } from './constants'; -import { LoginPanel } from "./panels/Login"; - +import { NuvolarisTerminalName } from './constants'; +import { NuvolarisLoginParams } from './interfaces'; +import { LoginPanel } from './login/LoginPanel'; +import { Commands, LoginEnvironmentVariables } from './enumerators'; let nuvLoginParams: NuvolarisLoginParams = { nuvUser: '', nuvApiHost: '', nuvPassword: '' } -let context: vscode.ExtensionContext | null = null; +let context: vscode.ExtensionContext; + export async function activate(ctx: vscode.ExtensionContext) { try { context = ctx; - let envUser = context.environmentVariableCollection.get('NUV_USER')?.value - let envPassword = context.environmentVariableCollection.get('NUV_PASSWORD')?.value - let envApiHost = context.environmentVariableCollection.get('NUV_APIHOST')?.value + let envUser = context.environmentVariableCollection.get(LoginEnvironmentVariables.NuvUser)?.value; + let envPassword = context.environmentVariableCollection.get(LoginEnvironmentVariables.NuvPassword)?.value; + let envApiHost = context.environmentVariableCollection.get(LoginEnvironmentVariables.NuvApihost)?.value; + + if (envUser && envPassword && envApiHost) { + updateNuvolarisLoginParams(envUser, envPassword, envApiHost); + } - updateNuvolarisLoginParams(envUser, envPassword, envApiHost) - Object.entries(COMMANDS).forEach(([name, command]) => - context!.subscriptions.push(vscode.commands.registerCommand(`nuvolaris.${name.toLowerCase()}`, () => { - if (loginIfNotAlreadyLoggedIn()) launchTerminal(command) + Object.entries(Commands).forEach(([name, command]) => + context.subscriptions.push(vscode.commands.registerCommand(`nuvolaris.${name.toLowerCase()}`, () => { + if (loginIfNotAlreadyLoggedIn()) launchTerminal(command); } ))); - context!.subscriptions.push(vscode.commands.registerCommand('nuvolaris.changeuser', () => { - vscode.window.showInformationMessage("Are you sure you want to change user?", "Yes", "No") + context.subscriptions.push(vscode.commands.registerCommand('nuvolaris.changeuser', () => { + let yes = "Yes"; + let no = "No"; + vscode.window.showInformationMessage("Are you sure you want to change user?", yes, no) .then(answer => { - if (answer === "Yes") { + if (answer === yes) { clearEnvironmentVariables(); loginIfNotAlreadyLoggedIn(); } }) })); - - } catch (error: any) { printError(error); throw error; @@ -44,7 +49,7 @@ function loginIfNotAlreadyLoggedIn() { try { let validCredentials = validateNuvolarisCredentials(); if (validCredentials) launchLoginTerminal(); - else LoginPanel.render(handleLogin, context!.extensionUri); + else LoginPanel.render(handleLogin, context.extensionUri); return validCredentials; } catch (error) { printError(error); @@ -55,7 +60,8 @@ function loginIfNotAlreadyLoggedIn() { function handleLogin(username: string, password: string, apiHost: string) { try { - storeNuvolarisCredentials(username, apiHost, password); + updateNuvolarisLoginParams(username, password, apiHost); + launchLoginTerminal(); } catch (error) { printError(error); throw error; @@ -64,45 +70,44 @@ function handleLogin(username: string, password: string, apiHost: string) { function validateNuvolarisCredentials() { try { - return nuvLoginParams.nuvUser && nuvLoginParams.nuvApiHost && nuvLoginParams.nuvPassword + let { nuvUser, nuvApiHost, nuvPassword } = nuvLoginParams; + return nuvUser && nuvApiHost && nuvPassword; } catch (error) { printError(error); throw error; } } -function storeNuvolarisCredentials(nuvUser: string | undefined, nuvApiHost: string | undefined, nuvPassword: string | undefined) { +function updateNuvolarisLoginParams(nuvUser: string, nuvPassword: string, nuvApiHost: string) { try { - updateNuvolarisLoginParams(nuvUser, nuvApiHost, nuvPassword); - launchLoginTerminal(); + nuvLoginParams = { + nuvUser: nuvUser, + nuvApiHost: nuvApiHost, + nuvPassword: nuvPassword + } + context.environmentVariableCollection.append(LoginEnvironmentVariables.NuvUser, nuvUser); + context.environmentVariableCollection.append(LoginEnvironmentVariables.NuvPassword, nuvPassword); + context.environmentVariableCollection.append(LoginEnvironmentVariables.NuvApihost, nuvApiHost); } catch (error) { printError(error); throw error; } } -function updateNuvolarisLoginParams(nuvUser: string | undefined, nuvApiHost: string | undefined, nuvPassword: string | undefined) { - nuvLoginParams = { - nuvUser: nuvUser, - nuvApiHost: nuvApiHost, - nuvPassword: nuvPassword - } - context!.environmentVariableCollection.append('NUV_USER', nuvUser + '') - context!.environmentVariableCollection.append('NUV_PASSWORD', nuvPassword + '') - context!.environmentVariableCollection.append('NUV_APIHOST', nuvApiHost + '') - -} - function clearEnvironmentVariables() { - nuvLoginParams = { - nuvUser: '', - nuvApiHost: '', - nuvPassword: '' + try { + nuvLoginParams = { + nuvUser: '', + nuvApiHost: '', + nuvPassword: '' + } + context.environmentVariableCollection.delete(LoginEnvironmentVariables.NuvUser); + context.environmentVariableCollection.delete(LoginEnvironmentVariables.NuvPassword); + context.environmentVariableCollection.delete(LoginEnvironmentVariables.NuvApihost); + } catch (error) { + printError(error); + throw error; } - context!.environmentVariableCollection.delete('NUV_USER') - context!.environmentVariableCollection.delete('NUV_PASSWORD') - context!.environmentVariableCollection.delete('NUV_APIHOST') - } function launchLoginTerminal() { @@ -118,7 +123,7 @@ function launchLoginTerminal() { function launchTerminal(command: string) { try { // If a terminal named "Nuvolaris" already exists, launch the command inside that one. - const terminal = vscode.window.terminals.find(t => t.name === "Nuvolaris") || vscode.window.createTerminal("Nuvolaris"); + const terminal = vscode.window.terminals.find(t => t.name === NuvolarisTerminalName) || vscode.window.createTerminal(NuvolarisTerminalName); terminal.show(); terminal.sendText(command, true); } catch (error) { @@ -129,6 +134,5 @@ function launchTerminal(command: string) { function printError(error: any) { - return vscode.window.showErrorMessage("Si è verificato un errore", error.toString()); -} - + return vscode.window.showErrorMessage("Error occurred", error.toString()); +} \ No newline at end of file diff --git a/src/constants.ts b/src/interfaces.ts similarity index 57% copy from src/constants.ts copy to src/interfaces.ts index e21666f..6511ea0 100644 --- a/src/constants.ts +++ b/src/interfaces.ts @@ -1,10 +1,11 @@ -export enum COMMANDS { - DEPLOY = "nuv ide deploy", - DEVEL = "nuv ide devel" -} - export interface NuvolarisLoginParams { nuvUser: string | undefined, nuvApiHost: string | undefined, nuvPassword: string | undefined +} + +export interface ValidatorAssertion { + isValid: boolean, + message: string, + htmlElement: HTMLElement } \ No newline at end of file diff --git a/src/panels/Login.ts b/src/login/LoginPanel.ts similarity index 98% rename from src/panels/Login.ts rename to src/login/LoginPanel.ts index 4f1a17a..d7e2684 100644 --- a/src/panels/Login.ts +++ b/src/login/LoginPanel.ts @@ -10,17 +10,12 @@ export class LoginPanel { private constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) { this._panel = panel; - this._panel.onDidDispose(() => this.dispose(), null, this._disposables); this._panel.webview.html = this._getWebviewContent(this._panel.webview, extensionUri); - this._setWebviewMessageListener(this._panel.webview); // this._panel.webview.onDidReceiveMessage(message => { - // switch (message.command) { - // case 'login': - // // Handle login form submission // const { username, password, apiHost } = message; // console.log('Submitted login details:', username, password, apiHost); @@ -39,7 +34,7 @@ export class LoginPanel { const command = message.command; switch (command) { - case "login": + case "login": // Handle login form submission const { username, password, apiHost } = message; // Pass the login details back to the extension @@ -53,9 +48,7 @@ export class LoginPanel { this._disposables ); } - private _getWebviewContent(webview: vscode.Webview, extensionUri: vscode.Uri) { - const webviewUri = getUri(webview, extensionUri, ["out", "webview.js"]); const nonce = getNonce(); return /*html*/ ` @@ -102,19 +95,15 @@ export class LoginPanel { cursor: pointer; font-weight: bolder; } - .logo-img { background-color: #1da1ce; } - .input-error { border: 2px solid red !important; } - .input-success { border: 2px solid green !important; } - .error-message { color: #ffa944; font-size: 0.8em; @@ -127,11 +116,9 @@ export class LoginPanel { <img src="https://assets-global.website-files.com/64b64691257b91236b0e7482/64bfcab6bd343008e30e5d06_Nuvolaris%20logo%20white.png" class="logo-img"></img> <h2>Login</h2> <form class="login-form" id="login-form"> - <input type="text" id="username-input" placeholder="Username"> <input type="password" id="password-input" placeholder="Password"> <input type="text" id="api-host-input" placeholder="API Host URL"> - <vscode-button id="login-button" type="submit" value="https://nuvolaris.dev/"> L O G I N </vscode-button> </form> </div> @@ -139,11 +126,8 @@ export class LoginPanel { </body> </html> `; - } - private _onLoginCallback: ((username: string, password: string, apiHost: string) => void) | undefined; - public static render(onLogin: (username: string, password: string, apiHost: string) => void, extensionUri: vscode.Uri) { if (LoginPanel.currentPanel) { LoginPanel.currentPanel._panel.reveal(vscode.ViewColumn.One); diff --git a/src/login/login.ts b/src/login/login.ts new file mode 100644 index 0000000..748c50f --- /dev/null +++ b/src/login/login.ts @@ -0,0 +1,85 @@ +import { provideVSCodeDesignSystem, vsCodeButton } from "@vscode/webview-ui-toolkit"; +import { LoginPageIDs } from "../enumerators"; +import { validateApiHost, validatePassword, validateUsername } from "../utilities/validate"; +provideVSCodeDesignSystem().register(vsCodeButton()); +const vscode = acquireVsCodeApi(); +window.addEventListener("load", main); + +const LoginPage = { + getUsername: (): HTMLInputElement => { return document.getElementById(LoginPageIDs.Username) as HTMLInputElement }, + getPassword: (): HTMLInputElement => { return document.getElementById(LoginPageIDs.Password) as HTMLInputElement }, + getApiHost: (): HTMLInputElement => { return document.getElementById(LoginPageIDs.ApiHost) as HTMLInputElement }, + getLoginButton: (): HTMLButtonElement => { return document.getElementById(LoginPageIDs.LoginButton) as HTMLButtonElement } +} + +function main() { + try { + LoginPage.getLoginButton() + .addEventListener("click", handleLoginSubmit); + + LoginPage.getUsername() + .addEventListener("change", validateLogin); + + LoginPage.getPassword() + .addEventListener("change", validateLogin); + + LoginPage.getApiHost() + .addEventListener("change", validateLogin); + + } catch (error: any) { + sendError(error); + throw error; + } +} + +function handleLoginSubmit() { + try { + const username = LoginPage.getUsername(); + const password = LoginPage.getPassword(); + const apiHost = LoginPage.getApiHost(); + + validateLogin(); + if (validateLogin()) { + vscode.postMessage({ + command: "login", + username: `${username.value}`, + password: `${password.value}`, + apiHost: `${apiHost.value}`, + text: `${username.value} ${password.value} ${apiHost.value} PASS`, + }); + } + else { + vscode.postMessage({ + command: "login", + text: `${username.value} ${password.value} ${apiHost.value} NOT PASS`, + }); + } + } catch (error: any) { + sendError(error); + throw error; + } +} + + +function validateLogin() { + try { + const loginSubmitButton = LoginPage.getLoginButton(); + let isUsernameValid = validateUsername(LoginPage.getUsername()); + let isPasswordValid = validatePassword(LoginPage.getPassword()); + let isApiHostValid = validateApiHost(LoginPage.getApiHost()); + let isValid = isUsernameValid && isPasswordValid && isApiHostValid; + loginSubmitButton.disabled = !isValid; + return isValid; + } catch (error: any) { + sendError(error); + throw error; + } + +} + +function sendError(error: any) { + return vscode.postMessage({ + type: "error", + text: `Error occurred: ${error.toString()}`, + }); +} \ No newline at end of file diff --git a/src/webview/main.ts b/src/utilities/validate.ts similarity index 54% rename from src/webview/main.ts rename to src/utilities/validate.ts index af17af9..3855527 100644 --- a/src/webview/main.ts +++ b/src/utilities/validate.ts @@ -1,80 +1,6 @@ -import { provideVSCodeDesignSystem, vsCodeButton } from "@vscode/webview-ui-toolkit"; +import { ValidatorAssertion } from "../interfaces"; -provideVSCodeDesignSystem().register(vsCodeButton()); -const vscode = acquireVsCodeApi(); - -interface ValidatorAssertion { - isValid: boolean, - message: string, - htmlElement: HTMLElement -} - -enum LoginPageIDs { - username = "username-input", - password = "password-input", - apiHost = "api-host-input", - loginButton = "login-button" -} - -const LoginPage = { - getUsername: (): HTMLInputElement => { return document.getElementById(LoginPageIDs.username) as HTMLInputElement }, - getPassword: (): HTMLInputElement => { return document.getElementById(LoginPageIDs.password) as HTMLInputElement }, - getApiHost: (): HTMLInputElement => { return document.getElementById(LoginPageIDs.apiHost) as HTMLInputElement }, - getLoginButton: (): HTMLButtonElement => { return document.getElementById(LoginPageIDs.loginButton) as HTMLButtonElement } -} - - -window.addEventListener("load", main); - -function main() { - try { - const submitButton = LoginPage.getLoginButton(); - - submitButton?.addEventListener("click", handleLoginSubmit) - LoginPage.getUsername().addEventListener("change", validateLogin); - LoginPage.getPassword().addEventListener("change", validateLogin); - LoginPage.getApiHost().addEventListener("change", validateLogin); - - } catch (error: any) { - console.error(error); - sendError(error); - throw error; - } - - -} - -function handleLoginSubmit() { - try { - const username = LoginPage.getUsername(); - const password = LoginPage.getPassword(); - const apiHost = LoginPage.getApiHost(); - - validateLogin(); - if (validateLogin()) { - vscode.postMessage({ - command: "login", - username: `${username.value}`, - password: `${password.value}`, - apiHost: `${apiHost.value}`, - text: `${username.value} ${password.value} ${apiHost.value} PASS`, - }); - } - /*else { - vscode.postMessage({ - command: "login", - text: `${username.value} ${password.value} ${apiHost.value} NOT PASS`, - }); - }*/ - } catch (error: any) { - console.error(error); - sendError(error); - throw error; - } -} - - -const Validators = { +export const Validators = { minChars: (htmlElement: HTMLInputElement, min: number, fieldName: string | null = null): ValidatorAssertion => { let message = `Field '${fieldName || htmlElement.id}' should contain minimum ${min} chars.` let isValid = true; @@ -97,46 +23,23 @@ const Validators = { '(\\#[-a-z\\d_]*)?$', 'i'); // anchor (optional) let isValid = pattern.test(htmlElement.value); return { isValid, message, htmlElement }; + }, + isNotNullOrUndefined: (htmlElement: HTMLInputElement, fieldName: string | null = null): ValidatorAssertion => { + let message = `Field '${fieldName || htmlElement.id}' should not be null or undefined.`; + let isValid = htmlElement.value !== null && htmlElement.value !== undefined; + return { isValid, message, htmlElement } + }, + isNot: (htmlElement: HTMLInputElement, value: any, fieldName: string | null = null): ValidatorAssertion => { + let message = `Field '${fieldName || htmlElement.id}' should not be ${value}.`; + let isValid = htmlElement.value !== value; + return { isValid, message, htmlElement } } } - -function createErrorMessages(assertions: ValidatorAssertion[]) { - try { - assertions.forEach((assertion: ValidatorAssertion, i: number) => { - let { htmlElement } = assertion; - htmlElement.classList.remove("input-error"); - htmlElement.classList.add("input-success"); - - let oldErrorMessageElements = Array.from(document.getElementsByClassName("error-message")); - oldErrorMessageElements.forEach((errorMessageElement) => { - if (errorMessageElement.id === `${htmlElement.id}-error-${i + 1}`) errorMessageElement.remove(); - }) - }); - - assertions.filter(a => !a.isValid).forEach((assertion: ValidatorAssertion, i: number) => { - let { htmlElement, message } = assertion; - htmlElement.classList.add("input-error"); - htmlElement.classList.remove("input-success"); - - let errorMessageElement = document.createElement("small"); - errorMessageElement.id = `${htmlElement.id}-error-${i + 1}`; - errorMessageElement.classList.add("error-message"); - - errorMessageElement.textContent = message; - htmlElement.parentNode?.insertBefore(errorMessageElement, htmlElement); - }) - } catch (error: any) { - sendError(error); - throw error; - } -} - -function validateUsername() { +export function validateUsername(input: HTMLInputElement) { try { let fieldName = "Username"; - let input = LoginPage.getUsername(); let assertions = []; let isNotEmpty = Validators.minChars(input, 1, fieldName); // let shouldBeMax12 = Validators.maxChars(input, 12, fieldName); @@ -145,16 +48,14 @@ function validateUsername() { createErrorMessages(assertions); return assertions.filter(a => !a.isValid).length === 0; } catch (error: any) { - sendError(error); throw error; } } -function validatePassword() { +export function validatePassword(input: HTMLInputElement) { try { let fieldName = "Password"; - let input = LoginPage.getPassword(); let assertions = []; let isNotEmpty = Validators.minChars(input, 1, fieldName); // let shouldBeMax30 = Validators.maxChars(input, 30, fieldName); @@ -163,15 +64,13 @@ function validatePassword() { createErrorMessages(assertions); return assertions.filter(a => !a.isValid).length === 0; } catch (error: any) { - sendError(error); throw error; } } -function validateApiHost() { +export function validateApiHost(input: HTMLInputElement) { try { let fieldName = "Api Host"; - let input = LoginPage.getApiHost(); let assertions = []; let isNotEmpty = Validators.minChars(input, 1, fieldName); /*if(shouldBeUrl.isValid && !/^https?:\/\//i.test(input.value)){ @@ -181,32 +80,37 @@ function validateApiHost() { createErrorMessages(assertions); return assertions.filter(a => !a.isValid).length === 0; } catch (error: any) { - sendError(error); throw error; } - } -function validateLogin() { + +export function createErrorMessages(assertions: ValidatorAssertion[]) { try { - const loginSubmitButton = LoginPage.getLoginButton(); - let isUsernameValid = validateUsername(); - let isPasswordValid = validatePassword(); - let isApiHostValid = validateApiHost(); + assertions.forEach((assertion: ValidatorAssertion, i: number) => { + let { htmlElement } = assertion; + htmlElement.classList.remove("input-error"); + htmlElement.classList.add("input-success"); - let isValid = isUsernameValid && isPasswordValid && isApiHostValid; - loginSubmitButton.disabled = !isValid; - return isValid; + let oldErrorMessageElements = Array.from(document.getElementsByClassName("error-message")); + oldErrorMessageElements.forEach((errorMessageElement) => { + if (errorMessageElement.id === `${htmlElement.id}-error-${i + 1}`) errorMessageElement.remove(); + }) + }); + + assertions.filter(a => !a.isValid).forEach((assertion: ValidatorAssertion, i: number) => { + let { htmlElement, message } = assertion; + htmlElement.classList.add("input-error"); + htmlElement.classList.remove("input-success"); + + let errorMessageElement = document.createElement("small"); + errorMessageElement.id = `${htmlElement.id}-error-${i + 1}`; + errorMessageElement.classList.add("error-message"); + + errorMessageElement.textContent = message; + htmlElement.parentNode?.insertBefore(errorMessageElement, htmlElement); + }) } catch (error: any) { - sendError(error); throw error; } - -} - -function sendError(error: any) { - return vscode.postMessage({ - type: "error", - text: `Si è verificato un errore: ${error.toString()}`, - }); } \ No newline at end of file
