Skip to content

Commit

Permalink
Project update. [p][robotic]
Browse files Browse the repository at this point in the history
  • Loading branch information
jaswrks committed Oct 4, 2023
1 parent afe7929 commit 19bc4cc
Show file tree
Hide file tree
Showing 33 changed files with 657 additions and 721 deletions.
2 changes: 1 addition & 1 deletion .browserslistrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# Generated data.
# <generated:start>

# Last generated Sat, Sep 30, 2023, 2:53:40 PM EDT.
# Last generated Wed, Oct 4, 2023, 6:54:13 PM EDT.

[production]
last 1 chrome versions
Expand Down
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# Generated data.
# <generated:start>

# Last generated Sat, Sep 30, 2023, 2:53:39 PM EDT.
# Last generated Wed, Oct 4, 2023, 6:54:13 PM EDT.

# Locals

Expand Down
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# Generated data.
# <generated:start>

# Last generated Sat, Sep 30, 2023, 2:53:39 PM EDT.
# Last generated Wed, Oct 4, 2023, 6:54:13 PM EDT.

# Default

Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# Generated data.
# <generated:start>

# Last generated Sat, Sep 30, 2023, 2:53:39 PM EDT.
# Last generated Wed, Oct 4, 2023, 6:54:13 PM EDT.

# Locals

Expand Down
2 changes: 1 addition & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
# Generated data.
# <generated:start>

# Last generated Sat, Sep 30, 2023, 2:53:39 PM EDT.
# Last generated Wed, Oct 4, 2023, 6:54:13 PM EDT.

# Locals

Expand Down
2 changes: 1 addition & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# Generated data.
# <generated:start>

# Last generated Sat, Sep 30, 2023, 2:53:39 PM EDT.
# Last generated Wed, Oct 4, 2023, 6:54:13 PM EDT.

# Packages

Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @note This entire file will be updated automatically.
* @note Instead of editing here, please review `./settings.mjs`.
*
* Last generated using `./settings.mjs` Sat, Sep 30, 2023, 2:53:39 PM EDT.
* Last generated using `./settings.mjs` Wed, Oct 4, 2023, 6:54:12 PM EDT.
*/
{
"editor.formatOnType": false,
Expand Down
2 changes: 1 addition & 1 deletion .vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# Generated data.
# <generated:start>

# Last generated Sat, Sep 30, 2023, 2:53:39 PM EDT.
# Last generated Wed, Oct 4, 2023, 6:54:13 PM EDT.

# Locals

Expand Down
89 changes: 5 additions & 84 deletions dev/.files/bin/envs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class Install {
* Deletes old files so a new install can begin.
*/

u.log($chalk.gray('Deleting any existing `.env.me`, `.env.vault` files.'));
u.log($chalk.gray('Deleting any existing `./.env.me`, `./.env.vault` files.'));
if (!this.args.dryRun) {
await fsp.rm(path.resolve(projDir, './.env.me'), { force: true });
await fsp.rm(path.resolve(projDir, './.env.vault'), { force: true });
Expand Down Expand Up @@ -251,60 +251,6 @@ class Pull {
}
}

/**
* Compile command.
*/
class Compile {
/**
* Constructor.
*/
constructor(args) {
this.args = args;
}

/**
* Runs CMD.
*/
async run() {
await this.compile();

if (this.args.dryRun) {
u.log($chalk.cyanBright('Dry run. This was all a simulation.'));
}
}

/**
* Runs compile.
*/
async compile() {
/**
* Displays preamble.
*/

u.log($chalk.green('Compiling all Dotenv Vault envs.'));

/**
* Checks if project has a Dotenv Vault.
*/

if (!(await u.isEnvsVault())) {
throw new Error('There are no Dotenv Vault envs to compile.');
}

/**
* Compiles all Dotenv Vault envs.
*/

await u.envsCompile({ dryRun: this.args.dryRun });

/**
* Signals completion with success.
*/

u.log(await u.finaleBox('Success', 'Dotenv Vault compilation complete.'));
}
}

/**
* Keys command.
*/
Expand Down Expand Up @@ -489,15 +435,15 @@ await (async () => {
requiresArg: false,
demandOption: false,
default: false,
description: 'Perform a new (fresh) install?',
description: 'Perform a new install?',
},
open: {
type: 'boolean',
requiresArg: false,
demandOption: false,
default: false,
description: // prettier-ignore
'When not `--new`, open the Dotenv Vault in a browser tab upon logging in?' +
'When not `--new`, open Dotenv Vault in a browser tab upon logging in?' +
' If not set explicitly, only opens Dotenv Vault for login, not for editing.' +
' Note: This option has no effect when `--new` is given.',
},
Expand Down Expand Up @@ -580,31 +526,6 @@ await (async () => {
await new Pull(args).run();
},
})
.command({
command: 'compile',
describe: 'Compiles all envs into `./dev/.envs/comp/.env.[env].json` JSON files.',
builder: (yargs) => {
return yargs
.options({
dryRun: {
type: 'boolean',
requiresArg: false,
demandOption: false,
default: false,
description: 'Dry run?',
},
})
.check(async (/* args */) => {
if (!(await u.isInteractive())) {
throw new Error('This *must* be performed interactively.');
}
return true;
});
},
handler: async (args) => {
await new Compile(args).run();
},
})
.command({
command: 'keys',
describe: 'Retrieves Dotenv Vault decryption keys for all envs.',
Expand Down Expand Up @@ -632,7 +553,7 @@ await (async () => {
})
.command({
command: 'encrypt',
describe: 'Encrypts all envs into `.env.vault`; powered by Dotenv Vault.',
describe: 'Encrypts all envs into `./.env.vault`, powered by Dotenv Vault.',
builder: (yargs) => {
return yargs
.options({
Expand All @@ -657,7 +578,7 @@ await (async () => {
})
.command({
command: 'decrypt',
describe: 'Decrypts `.env.vault` env(s) for the given key(s); powered by Dotenv Vault.',
describe: 'Decrypts `./.env.vault` envs for the given key(s), powered by Dotenv Vault.',
builder: (yargs) => {
return yargs
.options({
Expand Down
91 changes: 35 additions & 56 deletions dev/.files/bin/includes/utilities.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -114,31 +114,20 @@ export default class u {
* Pkg utilities.
*/

static async pkg() {
if (!fs.existsSync(pkgFile)) {
throw new Error('u.pkg: Missing `./package.json`.');
static async pkg(file = pkgFile) {
if (!fs.existsSync(file)) {
throw new Error('u.pkg: Missing `' + file + '`.');
}
const pkg = $json.parse(fs.readFileSync(pkgFile).toString());
const pkg = $json.parse(fs.readFileSync(file).toString());

if (!$is.plainObject(pkg)) {
throw new Error('u.pkg: Unable to parse `./package.json`.');
throw new Error('u.pkg: Unable to parse `' + file + '`.');
}
return pkg; // JSON object data.
}

static async depPkg(dependency) {
// This is a dependency-specific package file.
const pkgFile = path.resolve(projDir, './node_modules', dependency, './package.json');

if (!fs.existsSync(pkgFile)) {
return undefined; // Not possible.
}
const pkg = $json.parse(fs.readFileSync(pkgFile).toString());

if (!$is.plainObject(pkg)) {
throw new Error('u.pkg: Unable to parse `' + pkgFile + '`.');
}
return pkg; // JSON object data.
return u.pkg(path.resolve(projDir, './node_modules', dependency, './package.json'));
}

static async isPkgRepo(ownerRepo) {
Expand Down Expand Up @@ -958,8 +947,6 @@ export default class u {
await u.spawn('npx', ['dotenv-vault', 'push', envName, envFile, '--yes']);
}
}
await u.envsCompile({ dryRun: opts.dryRun });

u.log($chalk.gray('Encrypting all envs using latest Dotenv Vault data.'));
if (!opts.dryRun) {
await u.spawn('npx', ['dotenv-vault', 'build', '--yes']);
Expand All @@ -977,32 +964,9 @@ export default class u {
if (!opts.dryRun) {
await fsp.mkdir(path.dirname(envFile), { recursive: true });
await u.spawn('npx', ['dotenv-vault', 'pull', envName, envFile, '--yes']);
}
// log($chalk.gray('Deleting previous file for `' + envName + '` env.'));
if (!opts.dryRun) {
await fsp.rm(envFile + '.previous', { force: true });
}
}
await u.envsCompile({ dryRun: opts.dryRun });
}

static async envsCompile(opts = { dryRun: false }) {
const envFiles = await u.envFiles();
const mainEnv = $dotenv.parse(envFiles.main);

u.log($chalk.gray('Compiling all Dotenv Vault envs; i.e., generating JSON files.'));
if (!opts.dryRun) {
for (const [envName, envFile] of Object.entries($obj.omit(envFiles, ['main']))) {
const thisEnv = $dotenv.parse(envFile);
const env = $obj.mergeDeep({}, mainEnv, thisEnv);

const compDir = path.resolve(path.dirname(envFile), './.~comp');
const envJSONFile = path.resolve(compDir, path.basename(envFile) + '.json');

await fsp.mkdir(compDir, { recursive: true });
await fsp.writeFile(envJSONFile, await u._envToJSON(envName, env));
}
}
}

static async envsKeys(opts = { dryRun: false }) {
Expand Down Expand Up @@ -1031,15 +995,15 @@ export default class u {
}
u.log($chalk.gray('Decrypting `' + envName + '` env using Dotenv Vault key.'));
if (!opts.dryRun) {
const origDotenvKey = process.env.DOTENV_KEY || '';
process.env.DOTENV_KEY = key; // For `dotEnvVaultCore`.

// Note: `path` leads to `.env.vault`. See: <https://o5p.me/MqXJaf>.
const { parsed: env } = $dotenv.vault.config({ path: path.resolve(projDir, './.env' /* .vault */) });

// Note: this doesn’t leak our environment variables, but it does leak all of the
// variables in `./.env.vault`, because of the way it is processed internally by dotenv.
// Issue opened at dotenv regarding the problem; {@see https://o5p.me/DBbi7j}.
const env = $dotenv.$._parseVault({
DOTENV_KEY: key, // Pass explicitly.
path: path.resolve(projDir, './.env.vault'),
});
await fsp.mkdir(path.dirname(envFile), { recursive: true });
await fsp.writeFile(envFile, await u._envToText(envName, env));
process.env.DOTENV_KEY = origDotenvKey;
await fsp.writeFile(envFile, await u._envToProps(envName, env));
}
}
}
Expand Down Expand Up @@ -1083,6 +1047,15 @@ export default class u {
}
}

static async loadEnv({ mode }) {
const envFiles = await u.envFiles();

if (!mode || 'main' === mode || !envFiles[mode]) {
throw new Error('u.loadEnv: Invalid mode: `' + mode + '`.');
}
return $dotenv.parseExpand([envFiles.main, envFiles[mode]]);
}

static async _envsExtractKeys() {
const keys = {}; // Initialize.
const envFiles = await u.envFiles();
Expand All @@ -1091,9 +1064,9 @@ export default class u {
const output = await u.spawn('npx', ['dotenv-vault', 'keys', '--yes'], { quiet: true });

let _m = null; // Initialize.
const regexp = /\bdotenv:\/\/:key_.+?\?environment=([^\s]+)/giu;
const regExp = /\bdotenv:\/\/:key_.+?\?environment=([^\s]+)/giu;

while ((_m = regexp.exec(output)) !== null) {
while ((_m = regExp.exec(output)) !== null) {
keys[_m[1]] = _m[0];
}
if (Object.keys(keys).length !== Object.keys(envFiles).length) {
Expand All @@ -1111,16 +1084,22 @@ export default class u {
return $json.stringify(json, { pretty: true });
}

static async _envToText(envName, env) {
let text = '# ' + envName + '\n';
static async _envToProps(envName, env) {
let props = '# ' + envName + '\n';

for (let [name, value] of Object.entries(env)) {
value = String(value);
value = value.replace(/\r\n?/gu, '\n');
value = value.replace(/\n/gu, '\\n');
text += name + '="' + value.replace(/"/gu, '\\"') + '"\n';

if (value.includes('\\n')) {
// Dotenv evaulates newlines only if using double quotes.
props += name + '=' + $str.quote(value, { type: 'double' }) + '\n';
} else {
props += name + '=' + $str.quote(value) + '\n'; // Single quotes.
}
}
return text;
return props;
}

/*
Expand Down
Loading

0 comments on commit 19bc4cc

Please sign in to comment.