updates
This commit is contained in:
parent
3e769771f9
commit
80da640084
|
@ -1,3 +1,4 @@
|
|||
node_modules/
|
||||
yarn.lock
|
||||
package.json.lock
|
||||
.env
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# ngrok-to-dotenv
|
||||
|
||||
This is a ngrok start-up wrapper that uses a dotenv file (at '../.env' relative to this project's folder) to get the authtoken and save the https address; it's a node cli tool that you can use with projects that need ngrok. You clone it into your project's folder, and add to the project's package.json a run script to call "cd ngrok-to-dotenv && node ngrok". Be sure to add the folder to your .gitignore and install the one package which is ngrok and command-line-args, using 'npm i' or 'yarn'. The 'node ngrok' script supports two arguments --proto or -P (string, the protocol), --port or -p (number, the port number).
|
||||
This is a ngrok start-up wrapper that uses a dotenv file (at './.env') to get the authtoken and save the https address; it's a node cli tool that you can use with projects that need ngrok. You clone it into your project's folder, and add to the project's package.json a run script to call "cd ngrok-to-dotenv && node ngrok". Be sure to add the folder to your .gitignore and install the one package which is ngrok and command-line-args, using 'npm i' or 'yarn'. The 'node ngrok' script supports two arguments --proto or -P (string, the protocol), --port or -p (number, the port number).
|
||||
|
||||
By default 'node ngrok' (no arguments) is equivalent to 'node ngrok -P http -p 3000' and 'node ngrok --proto http --port 3000'.
|
|
@ -0,0 +1,164 @@
|
|||
#!/usr/bin/env node
|
||||
const ngrok = require("ngrok");
|
||||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
const { parse } = require("yaml");
|
||||
|
||||
// Parse the command line options
|
||||
const commandLineArgs = require("command-line-args");
|
||||
const optionDefinitions = [
|
||||
{ name: "proto", alias: "P", type: String },
|
||||
{ name: "port", alias: "p", type: Number },
|
||||
{ name: "env", alias: "e", type: String },
|
||||
];
|
||||
const options = commandLineArgs(optionDefinitions);
|
||||
const dotenvFile = options?.env ?? "./.env";
|
||||
|
||||
// vars
|
||||
let authToken = null; // string || null
|
||||
|
||||
// Main (an async) function
|
||||
(async function () {
|
||||
// Get the ngrok config file path
|
||||
let ngrokConfig = getNgrokConfig();
|
||||
|
||||
// Check if the ngrok config file exists
|
||||
if (!fs.existsSync(ngrokConfig)) {
|
||||
throw new Error("No ngrok config file found");
|
||||
}
|
||||
|
||||
// Read the ngrok config file
|
||||
try {
|
||||
const { authToken } = readNgrokConfig(ngrokConfig);
|
||||
global.authToken = authToken;
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Start ngrok
|
||||
const proto = options?.proto ?? "http";
|
||||
const addr = options?.port ? options.port : 3000;
|
||||
try {
|
||||
const url = await ngrok.connect({
|
||||
authtoken: authToken,
|
||||
proto,
|
||||
addr,
|
||||
onLogEvent: (data) => {
|
||||
// combine the key-value pairs into a single object
|
||||
const dataObj = parseLogLine(data);
|
||||
// console.log(`[${dataObj.lvl}] ${dataObj.msg}`);
|
||||
// console.log(dataObj);
|
||||
},
|
||||
});
|
||||
writeDotEnv(url); // Sync the .env file
|
||||
console.log(`Started ngrok: protocol '${proto}', addr '${addr}'`);
|
||||
console.log(`Your current ngrok url is ${url}.`);
|
||||
console.log(`Your .env file has been updated.`);
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
})(); // end main async function
|
||||
|
||||
function getNgrokConfig() {
|
||||
// Newer versions of ngrok
|
||||
let ngrokConfig = os.homedir() + "/.ngrok2/ngrok.yml";
|
||||
if (fs.existsSync(ngrokConfig)) {
|
||||
return ngrokConfig;
|
||||
}
|
||||
|
||||
// Alternative location for linux
|
||||
ngrokConfig = os.homedir() + "/.config/ngrok/ngrok.yml";
|
||||
if (fs.existsSync(ngrokConfig)) {
|
||||
return ngrokConfig;
|
||||
}
|
||||
|
||||
// MacOS
|
||||
ngrokConfig = os.homedir() + "/Library/Application Support/ngrok/ngrok.yml";
|
||||
if (fs.existsSync(ngrokConfig)) {
|
||||
return ngrokConfig;
|
||||
}
|
||||
|
||||
// Windows
|
||||
ngrokConfig = os.homedir() + "/AppData/Local/ngrok/ngrok.yml";
|
||||
if (fs.existsSync(ngrokConfig)) {
|
||||
return ngrokConfig;
|
||||
}
|
||||
|
||||
throw new Error("ngrok config file not found");
|
||||
}
|
||||
|
||||
function readNgrokConfig(ngrokConfig) {
|
||||
const data = fs.readFileSync(ngrokConfig, "utf8");
|
||||
|
||||
let authToken;
|
||||
|
||||
// Convert string to string array, split at newlines
|
||||
let lines = data.split("\n"); // string[]
|
||||
|
||||
// find the auth token (format: authtoken: token_goes_here)
|
||||
lines.forEach((element) => {
|
||||
const [name, value] = element.split(": ");
|
||||
if (name === "authtoken") authToken = value;
|
||||
});
|
||||
|
||||
// No token found
|
||||
if (!authToken) {
|
||||
// https://dashboard.ngrok.com/get-started/your-authtoken
|
||||
throw new Error("Setup NGROK_AUTHTOKEN in your .env file");
|
||||
}
|
||||
|
||||
return { authToken };
|
||||
}
|
||||
|
||||
function readDotEnv() {
|
||||
const data = fs.readFileSync(dotenvFile, "utf8");
|
||||
|
||||
// Convert string to string array, split at newlines
|
||||
let lines = data.split("\n"); // string[]
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
function writeDotEnv(url) {
|
||||
// Read the .env file
|
||||
let lines = readDotEnv(dotenvFile);
|
||||
|
||||
// Rebuild lines with the new url
|
||||
let found = false;
|
||||
lines = lines.map((element) => {
|
||||
const [name] = element.split("=");
|
||||
if (name === "NGROK_SERVERHOST") {
|
||||
found = true;
|
||||
return `${name}=${url}`;
|
||||
}
|
||||
return element;
|
||||
});
|
||||
|
||||
// Is this variable already in the .env, if not add it.
|
||||
if (!found) {
|
||||
lines.unshift(`NGROK_SERVERHOST=${url}`);
|
||||
}
|
||||
|
||||
// convert back to string format
|
||||
let writeData = "";
|
||||
lines.forEach((element) => {
|
||||
writeData += element + "\n";
|
||||
});
|
||||
writeData = writeData.slice(0, writeData.length - 1);
|
||||
|
||||
// Write the new .env file
|
||||
fs.writeFileSync(dotenvFile, writeData);
|
||||
}
|
||||
|
||||
function parseLogLine(line) {
|
||||
const regex = /(\S+)=("[^"]+"|\S+)/g;
|
||||
const logEntry = {};
|
||||
let match;
|
||||
while ((match = regex.exec(line)) !== null) {
|
||||
logEntry[match[1]] = match[2].replace(/"/g, "");
|
||||
}
|
||||
logEntry.t = new Date(logEntry.t);
|
||||
return logEntry;
|
||||
}
|
88
ngrok.js
88
ngrok.js
|
@ -1,88 +0,0 @@
|
|||
const ngrok = require("ngrok");
|
||||
const fs = require("fs");
|
||||
const { exec } = require("child_process");
|
||||
|
||||
const dotenvFile = "../.env";
|
||||
|
||||
const optionDefinitions = [
|
||||
{ name: "proto", alias: 'P', type: String },
|
||||
{ name: "port", alias: 'p', type: Number },
|
||||
];
|
||||
|
||||
const commandLineArgs = require("command-line-args");
|
||||
const options = commandLineArgs(optionDefinitions);
|
||||
|
||||
console.log(options);
|
||||
|
||||
// Read the .env file
|
||||
fs.readFile(dotenvFile, "utf8", (err, data) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert string to string array, split at newlines
|
||||
let lines = data.split("\n"); // string[]
|
||||
let authtoken = null; // string || null
|
||||
|
||||
// find the auth token
|
||||
lines.forEach((element) => {
|
||||
const [name, value] = element.split("=");
|
||||
if (name === "NGROK_AUTHTOKEN") authtoken = value;
|
||||
});
|
||||
|
||||
// No token found
|
||||
if (!authtoken) {
|
||||
console.error("Setup NGROK_AUTHTOKEN in your .env file");
|
||||
return;
|
||||
}
|
||||
|
||||
// Start ngrok
|
||||
(async function () {
|
||||
const proto = options?.proto ?? "http";
|
||||
const addr = options?.addr ? options.addr : 3000;
|
||||
|
||||
// Start ngrok
|
||||
try {
|
||||
const url = await ngrok.connect({ authtoken, proto, addr });
|
||||
|
||||
// Rebuild lines with the new url
|
||||
let found = false;
|
||||
lines = lines.map((element) => {
|
||||
const [name] = element.split("=");
|
||||
if (name === "NGROK_SERVERHOST") {
|
||||
found = true;
|
||||
return `${name}=${url}`;
|
||||
}
|
||||
return element;
|
||||
});
|
||||
|
||||
// Is this variable already in the .env, if not add it.
|
||||
if (!found) {
|
||||
lines.unshift(`NGROK_SERVERHOST=${url}`)
|
||||
}
|
||||
|
||||
// convert back to string format
|
||||
let writeData = "";
|
||||
lines.forEach((element) => {
|
||||
writeData += element + "\n";
|
||||
});
|
||||
writeData = writeData.slice(0, writeData.length - 1);
|
||||
|
||||
// Write the new .env file
|
||||
fs.writeFile(dotenvFile, writeData, (err) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
console.clear();
|
||||
console.log(`Started ngrok: protocol '${proto}', addr '${addr}'`);
|
||||
console.log(`Your current ngrok url is ${url}.`);
|
||||
console.log(`Your .env file has been updated.`);
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
});
|
18
package.json
18
package.json
|
@ -1,16 +1,22 @@
|
|||
{
|
||||
"name": "ngrok-to-dotenv",
|
||||
"version": "1.0.0",
|
||||
"description": "ngrok start-up wrapper that uses a dotenv file to get the authtoken and save the https address",
|
||||
"main": "ngrok.js",
|
||||
"name": "ngenv",
|
||||
"version": "1.1.1",
|
||||
"description": "Writes ngrok tunnel url to .env file",
|
||||
"main": "ngenv",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"ngenv": "./ngenv"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"debug": "node --inspect ngrok.js",
|
||||
"start": "node ngrok"
|
||||
"debug": "node --inspect ngenv",
|
||||
"start": "node ngenv"
|
||||
},
|
||||
"dependencies": {
|
||||
"command-line-args": "^5.2.0",
|
||||
"ngrok": "^4.2.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"yaml": "*"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue