UNPKG

windows-environment

Version:

A powerful library to manage Environment Variables on Windows using Node.JS

263 lines (248 loc) 10.4 kB
const { spawnSync } = require('child_process'); /** * A scope enumeration of Target Constants * * @public * @const * @returns {string} Returns `Environment Variable Target (USER or MACHINE)`. */ const Target = { USER: "USER", MACHINE: "MACHINE" }; /** * A enumeration to decide whether to receive values in long form or not * If this is set to no, all the values will be displayed as is. * If set to yes then, the values enclosed inside % symbol will take its long form * for e.g. %userprofile% will be C:\Users\UserName * for e.g. %systemroot% will be C:\Windows * * @public * @const * @returns {string} Returns `Expanded Form Value (FULL or SHORT)`. */ const ExpandedForm = { YES: "FULL", NO: "SHORT" }; /** * A enumeration to decide whether to create a new Environment Variable or update an existing one with new value appended to it. * * @public * @const * @returns {string} Returns `Set Operation Type (NEW or APPEND)`. */ const SetOperationType = { NEW: "NEW", APPEND: "APPEND" }; /** * A enumeration to decide what kind of operation to be performed on Environment Variable Value. * * @public * @const * @returns {string} Returns string if OPTIMIZED option is selected and returns array if BROKEN or DUPLICATES option is selected. */ const ExtOperationType = { BROKEN: "BROKEN", DUPLICATES: "DUPLICATES", OPTIMIZE: "OPTIMIZE" }; function checkForTargetValidity(options) { if ('target' in options) { switch (options.target) { case Target.USER: return Target.USER; case Target.MACHINE: return Target.MACHINE; default: return Target.USER; } } else { return Target.USER; } } function checkForExpandedFormValidity(options) { if ('expandedForm' in options) { switch (options.expandedForm) { case ExpandedForm.YES: return ExpandedForm.YES; case ExpandedForm.NO: return ExpandedForm.NO; default: return ExpandedForm.NO; } } else { return ExpandedForm.NO; } } function checkForSetOperationTypeValidity(options) { if ('setOperationType' in options) { switch (options.setOperationType) { case SetOperationType.NEW: return SetOperationType.NEW; case SetOperationType.APPEND: return SetOperationType.APPEND; default: return SetOperationType.APPEND; } } else { return SetOperationType.APPEND; } } function checkForExtOperationTypeValidity(options) { if ('extOperationType' in options) { switch (options.extOperationType) { case ExtOperationType.BROKEN: return ExtOperationType.BROKEN; case ExtOperationType.DUPLICATES: return ExtOperationType.DUPLICATES; case ExtOperationType.OPTIMIZE: return ExtOperationType.OPTIMIZE; default: return ExtOperationType.OPTIMIZE; } } else { return ExtOperationType.OPTIMIZE; } } /** * The main class which acts as the core of module * containing 4 static functions for managing Windows Environment Variable * * @public * @class */ class Env { /** * This function either reads the Environment Variable value by its name * and if name is not specified it reads all the Environment Variables * under the specified target (User or System). * * @public * @static * @function * @param {Object} [options={}] The Options object * @param {Object} [options.target=Target.USER] Specifies the target to look into (User or System). * @param {Object} [options.expandedForm=ExpandedForm.NO] If set to yes then the values enclosed inside % symbol will take its long form for e.g. %userprofile% will be C:\Users\UserName * @param {Object} [options.name] It can be any name like JDK, PATH, GH_TOKEN, TEMP, TMP, etc. * @return It returns string if name is specified or array if name is not specified * @return {Array} [array] returns array of JS Objects containing keys like: * name: Name of the environment variable inside specified target. * value: Value of the environment variable of that name. */ static get(options) { if (!options) options={}; let target = checkForTargetValidity(options); let expandedForm = checkForExpandedFormValidity(options); let command = ('name' in options) ? `${__dirname}\\libs\\get-env.exe ${target} ${expandedForm} "${options.name}"` : `${__dirname}\\libs\\get-env.exe ${target} ${expandedForm}`; let child = spawnSync("cmd.exe", ["/c", command], { shell: true }); if ('name' in options) { return child.stdout.toString().replace(/\r\n/g,''); } else { let retValue = child.stdout.toString().replace(/\r/g,''); let array = retValue.split('\n'); array.pop(); let newArray = []; for (let arr of array) { let temp = arr.split("="); newArray.push({ name: temp[0], value: temp[1] }); } return newArray; } } /** * Requires Admin Privileges (set-env.exe is the program it tries to run) * This function creates a new Environment Variable or it updates the existing with the passed value. * * @public * @static * @function * @param {Object} [options={}] The Options object * @param {Object} [options.target=Target.USER] Specifies the target to look into (User or System). * @param {Object} [options.setOperationType=SetOperationType.APPEND] If set to SetOperationType.Append it just adds a new value to the existing value and if set to SetOperationType.NEW, a new Environment Variable is created overwriting the existing one if it exists. * @param {Object} [options.name] It can be any name like JDK, PATH, GH_TOKEN, TEMP, TMP, etc. * @param {Object} [options.value] The value to be appended or set for the Environment Variable. * @return {number} the exit code of method execution is returned either 0 (success) or 1 (failure) */ static set(options) { if (!options) options={}; let target = checkForTargetValidity(options); let setOperationType = checkForSetOperationTypeValidity(options); let name = options.name; let value = options.value; if(!name || !value) throw new Error("Name and value field are mandatory!"); value = value.replace(/%/g, '^%'); if (!value.endsWith(";")) value = value+";"; let child = spawnSync("cmd.exe", ["/c", `${__dirname}\\libs\\set-env.exe ${target} ${setOperationType} "${name}" "${value}"`], { shell:true }); return child.status; } /** * Requires Admin Privileges (del-env.exe is the program it tries to run) * This function deletes an existing Environment Variable or it deletes a particular value from it. * * @public * @static * @function * @param {Object} [options={}] The Options object * @param {Object} [options.target=Target.USER] Specifies the target to look into (User or System). * @param {Object} [options.name] It can be any name like JDK, PATH, GH_TOKEN, TEMP, TMP, etc. * @param {Object} [options.value] If the value is specified it deletes only this value from the existing value and if not specified then the entire Environment Variable is deleted * @return {number} the exit code of method execution is returned either 0 (success) or 1 (failure) */ static del(options) { if (!options) options={}; let target = checkForTargetValidity(options); let name = options.name; if(!name) throw new Error("Name field is mandatory!"); let command = `${__dirname}\\libs\\del-env.exe ${target} "${name}"`; if ('value' in options) { command = `${__dirname}\\libs\\del-env.exe ${target} "${name}" "${options.value.replace(/%/g, '^%')}"` } let child = spawnSync("cmd.exe", ["/c", command], { shell: true }); return child.status; } /** * This function operates on a single Environment Variable at a time. * It can be used to find: * broken paths: (the path which no longer exits on your File System) * duplicate values: duplicate paths are returned * optimized value: value which removes any redundancies (duplicate values) and broken paths. * * @public * @static * @function * @param {Object} [options={}] The Options object * @param {Object} [options.target=Target.USER] Specifies the target to look into (User or System). * @param {Object} [options.extOperationType=ExtOperationType.OPTIMIZE] the type of operation you want to perform. * @param {Object} [options.name] It can be any name like JDK, PATH, GH_TOKEN, TEMP, TMP, etc. * @return It returns string if optimize option is specified. * @return {Array} [array] broken paths or duplicate paths are returned. */ static ext(options) { if (!options) options={}; let target = checkForTargetValidity(options); let exOperationType = checkForExtOperationTypeValidity(options); let name = options.name; if(!name) throw new Error("Name field is mandatory!"); let child = spawnSync("cmd.exe", ["/c", `${__dirname}\\libs\\ext-env.exe ${target} "${name}" ${exOperationType}`], { shell: true }); if (exOperationType === ExtOperationType.BROKEN || exOperationType === ExtOperationType.DUPLICATES) { let retValue = child.stdout.toString().replace(/\r/g,''); let array = retValue.split('\n'); array.pop(); return array; } else { return child.stdout.toString(); } } } module.exports = { Env, Target, ExpandedForm, SetOperationType, ExtOperationType };