Using nodejs ssh2 within a web worker - node.js

I'm trying to use from a nx project (using #nrwl/node), within a nodeJS API, the ssh2 plugin.
Here's my module:
export const datasetTranferModule = ({ username, password }) => {
var connSettings = {
host: "192.168.1.14",
port: 22,
username,
password
// You can use a key file too, read the ssh2 documentation
};
var SSHClient = require("ssh2").Client;
// do something with SSHClient
return;
};
By changing the default webpack behavior, I didn't manage to get it working:
module.exports = (config, context) => {
const WorkerPlugin = require('worker-plugin')
return {
...config,
node: {
process: true,
global: true
},
plugins: [
new WorkerPlugin({
plugins: [
// A string here will copy the named plugin from your configuration:
'ssh2',
// Or you can specify a plugin directly, only applied to Worker code:
]
})
]
};
};
Is it fine to do it within a worker? If so how to import ssh from the worker?

Related

Unable to read values from .env.local file in latest Cypress version

I am using latest Cypress version 10.11.0 and I am trying to read username, password from .env.local file in my system using process.env. But some how it not getting the values from the .env.local file ? Could someone please advise ?
Note : As a normal way, I am able to get values if I provide values in cypress.config.js (see below). Since username, password can't expose in config, i need to read it from .env.local file.
env:{
MYBOOKS_USERNAME:"testuser1#test.com",
MYBOOKS_PASSWORD:"Some_password"
},
// cypress.config.js file
const { defineConfig } = require("cypress");
module.exports = defineConfig({
chromeWebSecurity: false,
viewportWidth :1920,
viewportHeight:1080,
responseTimeout: 60000,
fixturesFolder: 'cypress/fixtures',
screenshotsFolder: 'cypress/screenshots',
videosFolder: 'cypress/videos',
numTestsKeptInMemory: 10,
video:false,
e2e: {
setupNodeEvents(on, config) {
require("cypress-grep/src/plugin")(config),
// implement node event listeners here
on('before:browser:launch', (browser, launchOptions ) => {
console.log("Print browser name: "+browser.name);
if (browser.name === 'chrome' || browser.name === 'chrome' && browser.isHeadless) {
launchOptions.args.push('--disable-features=SameSiteByDefaultCookies')
return launchOptions
}
});
on('task', {
logAtConsole (message) {
console.log('Printing the data using task::', message);
return null
}
});
},
baseUrl: "https://somebookssite-test.com",
specPattern: "cypress/e2e/booksSite/**/*.spec.{js,jsx,ts,tsx}",
},
});
// .env.local file
CYPRESS_MYBOOKS_USERNAME=testuser1#test.com,
CYPRESS_MYBOOKS_PASSWORD=Some_password
// commands.js file
const userName = process.env.MYBOOKS_USERNAME;
const userPassword = process.env.MYBOOKS_PASSWORD;
Cypress.Commands.add('loginRequest', (url) => {
helperFunctions.dynamicEnvironmentSelection();
const apiEndpoint = helperFunctions.getItemFromLocalStorage('apiUrl');
cy.request({
method: 'POST',
url: apiEndpoint + url,
contentType: 'application/json',
body: {
username: userName,
password: userPassword,
}
}).then((resp) => {
helperFunctions.setLoginCookies(resp);
});
});
You could use dotenv to read the .env.local file.
Using the convention for this tool, use key=value format in .env.local.
MYBOOKS_USERNAME="testuser1#test.com"
MYBOOKS_PASSWORD="Some_password"
const { defineConfig } = require('cypress')
const path = require('path')
const dotenv = require('dotenv')
const envLocal = dotenv.config({path: path.resolve(process.cwd(), '.env.local')})
module.exports = defineConfig({
env: {
// non-sensitive env vars hard-coded here
login_url: '/login',
products_url: '/products'
// sensitive env vars read in above from external file
...envLocal
},
Without dotenv
If you change the external file to .env.local.json, then it's possible to read it directly.
{
"MYBOOKS_USERNAME": "testuser1#test.com",
"MYBOOKS_PASSWORD": "Some_password"
}
const { defineConfig } = require('cypress')
const envLocal = require('./.env.local.json')
module.exports = defineConfig({
env: {
// non-sensitive env vars hard-coded here
login_url: '/login',
products_url: '/products'
// sensitive env vars read in above from external file
...envLocal
},

VSCode Extension with LSP in C#, how to terminate the LSP dll?

I have a very simple extension that loads a DLL that will contain my LSP project.
namespace SimpleLsp
{
class Program
{
static async Task Main(string[] args)
{
var server = await OmniSharp.Extensions.LanguageServer.Server.LanguageServer
.From(
options => options
.WithInput(Console.OpenStandardInput())
.WithOutput(Console.OpenStandardOutput())
).ConfigureAwait(false);
await server.WaitForExit;
}
}
}
and the TypeScript extension
import * as vscode from 'vscode';
import path = require('path');
import { workspace } from 'vscode';
import {
LanguageClient,
LanguageClientOptions,
ServerOptions,
TransportKind,
} from "vscode-languageclient/node";
let client: LanguageClient;
export function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "simplelspextension" is now active!');
const extensionPath = vscode.extensions.getExtension("PauloAboimPinto.simplelspextension")?.extensionPath as string;
const libsFolder = path.join(extensionPath, "libs");
const dllPath = path.join(libsFolder, "simpleLsp.dll");
let serverOptions: ServerOptions = {
run: {
command: "dotnet",
args: [dllPath],
transport: TransportKind.pipe
},
debug: {
command: "dotnet",
args: [dllPath],
transport: TransportKind.pipe,
runtime: ""
}
};
let clientOptions: LanguageClientOptions = {
documentSelector: [
{
pattern: "**/*.xaml",
},
{
pattern: "**/*.axaml",
},
{
pattern: "**/*.csproj",
},
],
synchronize: {
// Notify the server about file changes to '.clientrc files contained in the workspace
fileEvents: workspace.createFileSystemWatcher('**/.axaml')
}
};
client = new LanguageClient(
"simpleLsp",
"Simple Language Server Protocol",
serverOptions,
clientOptions
);
let disposableLsp = client.start();
context.subscriptions.push(disposableLsp);
}
// this method is called when your extension is deactivated
export function deactivate() {
if (!client) {
return undefined;
}
return client.stop();
}
During deactivation I'm sending the stop command to the client, expecting the execution DLL to be terminated, but it's not.
When I close the VSCode I would expect the simpleLsp.dll to be terminated but it's not and I have to terminate it manually.
What I'm missing or doing wrong here?
How I can terminate the execution of the DLL that contains the LSP?
thanks in advance

How to set env.development and env.production in Preact app

On react app, you can create .env.production and .env.development and enter different key and values like this.
REACT_APP_API_URL= "xyz"
to pick environment variables automatically based on commands used --> npm start or npm run build.
What is the equivalent process in preact?
It is my solution
env.js in the root of project:
import fs from 'fs';
import dotenv from 'dotenv';
function getAppEnvironment() {
const prefix = "PREACT";
return Object.keys(process.env)
.filter((key) => new RegExp(`^${prefix}_`, 'i').test(key))
.reduce((env, key) => {
env[key] = process.env[key];
return env;
}, {});
}
function resolveFile(file) {
const path = fs.realpathSync(process.cwd());
return `${path}/${file}`;
}
function getEnvFiles(production) {
const key = production ? 'production' : 'development';
return [
resolveFile(".env"),
resolveFile(".env.local"),
resolveFile(`.env.${key}`),
resolveFile(`.env.${key}.local`),
].filter(Boolean);
}
export function getEnvironment(production) {
const dotenvFiles = getEnvFiles(production);
dotenvFiles.forEach((dotenvFile) => {
if (fs.existsSync(dotenvFile)) {
dotenv.config({
path: dotenvFile,
override: true
})
}
});
return getAppEnvironment();
}
export default getEnvironment;
then create or modify your preact.config.js:
import getEnvironment from './env';
export default {
plugins: [],
webpack(config, env, helpers) {
config.plugins.push(
new helpers.webpack.DefinePlugin({
'process.env': JSON.stringify(getEnvironment(env.production))
}),
);
},
};

How to assign serviceAccount using gcloud compute nodejs client?

I'm trying to create a new virtual machine using gcloud compute nodejs client:
const Compute = require('#google-cloud/compute');
const compute = new Compute();
async function createVM() {
try {
const zone = await compute.zone('us-central1-a');
const config = {
os: 'ubuntu',
http: true,
https: true,
metadata: {
items: [
{
key: 'startup-script-url',
value: 'gs://<path_to_startup_script>/startup_script.sh'
},
],
},
};
const data = await zone.createVM('vm-9', config);
const operation = data[1];
await operation.promise();
return console.log(' VM Created');
} catch (err) {
console.error(err);
return Promise.reject(err);
}
}
I have a serviceAccount with the needed roles for this VM to call other resources but I can't figure how to where to assign the serviceAccount when creating the new VM. Any pointers are greatly appreciated, I haven't been able to find any documentation and I'm stuck.
You can specify the service account to use in the new VM by adding a serviceAccounts field within the options for config passed into createVM. Here is an example snippet:
zone.createVM('name', {
serviceAccounts: [
{
email: '...',
scopes: [
'...'
]
}
]
})
Reference:
Service Account and Access Scopes or Method: instances.insert
createVM - The config object can take all the parameters of the instance resource.

Sequelize with Singleton

I'm working with Sequelize in node.js and the idea is to use the Singleton pattern.
Reading about how node works with the modules caching and some singleton examples
My file in this moment is:
const DBManager = (function () {
// Instance stores a reference to the Singleton
let instance: any;
let db: string = null;
let user: string;
let password: string;
let host: string;
let sequelize: Sequelize.Sequelize;
function init(bdName: string) {
db = bdName;
user = process.env.MYSQL_DB_USERNAME || 'root';
password = process.env.MYSQL_DB_PASSWORD || 'root';
host = process.env.MYSQL_DB_HOST || 'localhost';
return {
open: () => {
sequelize = new Sequelize(db, user, password, {
host: host,
dialect: 'mysql',
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
operatorsAliases: false,
logging: !process.env.HIDE_LOGS
});
},
testConnection: () => {
return sequelize.authenticate();
},
getManagerObject: () => {
return sequelize;
},
close: () => {
sequelize.close();
}
};
}
return {
// Get the Singleton instance if one exists
// or create one if it doesn't
getInstance: (bd?: string) => {
if (!instance) {
instance = init(bd);
}
return instance;
}
};
})();
export default DBManager;
So, as expected when i require this file anywhere in my project the references are the same and works as expected.
I'm not sure if this is the right way to implement the Singleton pattern, or if there is a defined and documented one, because the oficial documentation does not say anything about this.
There's usually no need for explicit singleton implementation. JS modules (CommonJS and ES modules in particular) are evaluated only once under normal circumstances, exported class instance is efficiently a singleton.
There's no need for IIFE as well because modules have their own scopes. Since init function isn't reused, there's possibly no need for it either. It can be simplified to:
export default {
open: ...
testConnection: ...
...
};
This abstraction isn't practical. There's already sequelize instance, creating wrapper methods for its own methods doesn't serve a good purpose.
Since a connection is usable after it's established, it makes sense to just export a promise of a connection, similarly to the one that is shown in this answer.
If the configuration (database name) is available in database manager module, it's preferable to just use it in-place:
// db.js
const dbName = someConfig.db;
const sequelize = new Sequelize(dbName, ...);
export default sequelize.authenticate().then(() => sequelize);
Which is used like:
import dbConnection from './db';
dbConnection.then(sequelize => { /* all code that depends on the connection */ });
If there may be several connections, or the configuration isn't available on import, factory function is exported instead:
// db.js
export default dbName => {
const sequelize = new Sequelize(dbName, ...);
sequelize.authenticate().then(() => sequelize);
}
Singleton instances are naturally handled with modules:
// foo-db.js
import getDbConnection from './db';
export default getFooDbName().then(dbName => getDbConnection(dbName));
And used like:
import dbConnection from './foo-db';
dbConnection.then(sequelize => { /* all code that depends on the connection */ });

Resources