UNPKG

dotenv-types-generator

Version:
171 lines (150 loc) 4.83 kB
#!/usr/bin/env node 'use strict'; var yargs = require('yargs'); var process$1 = require('process'); var fs = require('fs'); /** * Merges mapped types with already defined types from the given file * @param {Array} mappedTypes Mapped type definitions * @param {String} path The env.d.ts file to merge */ var mergeTypes = function mergeTypes(mappedTypes, path) { var mergedArray; var file; try { file = fs.readFileSync(path); } catch (_unused) { return mappedTypes; } var fileContent = file.toString(); var isValidFile = /(?<=ProcessEnv[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*\{)([\s\S]+?)(?=\})/g.test(fileContent); if (isValidFile) { var typeDefinitions = fileContent.match(/(?<=\s*)\w+\??: string/gim); var diff = mappedTypes.filter(function (item) { // we split the item and strip ? character to check if it exists in the file var val = item.split(':')[0].replace('?', ''); return typeDefinitions.findIndex(function (el) { return el.includes(val); }) === -1; }); mergedArray = typeDefinitions.concat(diff); } else mergedArray = mappedTypes; return mergedArray; }; var placeholderText = 'types-placeholder'; var template = [{ indentation: 0, value: 'declare global {\n' }, { indentation: 1, value: 'namespace NodeJS {\n' }, { indentation: 2, value: 'interface ProcessEnv {\n' }, { indentation: 3, value: placeholderText }, { indentation: 2, value: '}\n' }, { indentation: 1, value: '}\n' }, { indentation: 0, value: '}\n' }, { indentation: 0, value: '\n' }, { indentation: 0, value: 'export {};\n' }]; /** * Creates a type definition file template depending on the given indentation size. * @param {Number} indentationSize Defines how the template should be indented * @param {Array} mappedTypes Mapped type definitions */ var printTypes = function printTypes(indentationSize, mappedTypes) { var output = ''; var indentationText = ' '.repeat(indentationSize); template.forEach(function (element) { var indentation = indentationText.repeat(element.indentation); if (element.value === placeholderText) { mappedTypes.forEach(function (mappedType) { output += "".concat(indentation).concat(mappedType, ";\n"); }); } else output += "".concat(indentation).concat(element.value); }); return output; }; var generate = function generate(cwd, path) { var shouldOutputOptionalTypes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var indentationSize = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 2; var shouldMerge = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; var defaults = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : []; var file; try { file = fs.readFileSync("".concat(cwd, "/").concat(path)); } catch (_unused) { console.error('invalid path to .env file'); process.exit(1); } var variables = file.toString().match(/(?<=\s*)\w+(?==)/gm); try { if (!variables) throw new Error(); } catch (_unused2) { console.error('Empty .env file'); process.exit(1); } // merge defaults variables = variables.concat(defaults); variables = variables.filter(function (item, pos) { return variables.indexOf(item) === pos; }); var outPath = path.match(/[.\w\-/]*\/(?=\.env)/); outPath = outPath ? "".concat(outPath, "/") : ''; var mappedTypes = variables.map(function (v) { return "".concat(v).concat(shouldOutputOptionalTypes ? '?' : '', ": string"); }); if (shouldMerge) { mappedTypes = mergeTypes(mappedTypes, "".concat(cwd, "/").concat(outPath, "env.d.ts")); } var typeDeclaration = printTypes(indentationSize, mappedTypes); fs.writeFileSync("".concat(cwd, "/").concat(outPath, "env.d.ts"), typeDeclaration); return Buffer.from(typeDeclaration); }; var _options$help$alias = yargs.options({ file: { type: 'string', "default": '.env', alias: 'f' }, version: { alias: 'v' }, optionalTypes: { type: 'boolean', "default": false, alias: 'o', description: 'Makes all types optional (nullable)' }, indentationSize: { type: 'number', "default": 2, alias: 'i', description: 'Defines how the template should be indented' }, mergeTypes: { type: 'boolean', "default": false, alias: 'm', description: 'Merges existing types from env.d.ts file with the types from .env file' }, defaults: { type: 'array', alias: 'd', description: 'Adds default process.env properties to template' } }).help().alias('help', 'h'), argv = _options$help$alias.argv; generate(process$1.cwd(), argv.file, argv.optionalTypes, argv.indentationSize, argv.mergeTypes, argv.defaults);