Home > OS >  How can I dynamically edit a .env file from an npm script?
How can I dynamically edit a .env file from an npm script?

Time:12-11

I've got a .env file for a project that I'm working on, I won't reveal the whole file because it contains sensitive data, but, in that file I have an item called 'STATUS'.

NOTE: This is for a Discord bot,

The 'STATUS' variable looks like this: STATUS=DEVELOPMENT

In my code I have a handler that deploys commands to all servers or just my specific server relative to the value of 'STATUS'.
example: if STATUS was equal to DEVELOPMENT than it would deploy the commands to the development server and if it was equal to PRODUCTION then it would deploy the commands to all of the servers the bot is in.

That code looks something like this:

if (STATUS == "DEVELOPMENT") {
  Routes.applicationGuildCommands(CLIENT_ID, process.env.DEVELOPMENT_GUILD_ID),
    { body: slashCommands },
    console.log(
      chalk.yellow(`Slash Commands • Registered Locally to 
  the development server`)
    );
} else if (STATUS == "PRODUCTION") {
  await rest.put(
    Routes.applicationCommands(CLIENT_ID),
    { body: slashCommands },
    console.log(chalk.yellow("Slash Commands • Registered Globally"))
  );
}

In my package.json file I would like to have two scripts that control if the commands get pushed to production or development.
example:

"scripts": {
      "prod": "changes the 'STATUS' to 'PRODUCTION' and runs the file",
      "dev": "changes the 'STATUS' to 'DEVELOPMENT' and runs the file"
  },

CodePudding user response:

You can just create a simple utility JS script to do the work:

// status.js
const fs = require("fs")
const path = require("path")

// get the first argument passed to this file:
const status = process.argv[3] // the first and second element will always be `node` and `filename.js`, respectively

if(!status) {
  throw new Error("You must supply a status to change to")
}

const envPath = path.join(process.cwd(), ".env") // resolve to the directory calling this script
// parse the environment variable file
let env = fs.readFileSync(envPath)
env = env.split(/\r?\n/g) // optional linefeed character

let prevExists = false
for(let lineNumber in env) {
  if(env[lineNumber].startsWith("STATUS=")) {
    prevExists = true
    env[lineNumber] = `STATUS=${status}`
    break
  }
}
if(!prevExists) env.push(`STATUS=${status}`)

const newEnv = env.join("\n")
fs.writeFileSync(envPath, newEnv)

console.log(`Successfully changed the status to "${status}"`)

Then in your package.json, you can put the following:

"scripts": {
  "prod": "node status.js PRODUCTION && command to deploy server",
  "dev": "node status.js DEVELOPMENT && command to deploy server"
}
  • Related