diff --git a/configurator.js b/configurator.js index 96c4fd3..efa1e9c 100644 --- a/configurator.js +++ b/configurator.js @@ -4,39 +4,49 @@ import rls from "readline-sync"; const configFilePath = `${os.homedir()}/.infisical-env.config.json`; const configTemplate = { - projects: [], - storeTokens: false, - infisicalInstance: "https://app.infisical.com" + projects: [ + { + name: "proj1", + environments: [ + { + slug: "prod", + envar: "INFISICAL_PROJ1_PROD_READ_TOKEN", + paths: ["/", "/database"], + }, + ], + }, + ], + storeTokens: false, + infisicalInstance: "https://app.infisical.com", +}; + +export function loadConfig() { + return JSON.parse(fs.readFileSync(configFilePath)); } -export function loadConfig(){ - return JSON.parse(fs.readFileSync(configFilePath)); +export function upsertConfig() { + if (fs.existsSync(configFilePath)) return; + generateConfig(); } -export function upsertConfig(){ - if(fs.existsSync(configFilePath)) return; - generateConfig(); +export function writeConfig(overrides) { + const config = { ...configTemplate, ...overrides }; + fs.writeFileSync(configFilePath, JSON.stringify(config)); } -export function writeConfig(overrides){ - const config = {...configTemplate, ...overrides}; - fs.writeFileSync(configFilePath, JSON.stringify(config)); -} - -export function generateConfig(){ - const url = rls.question("Infisical Instance: "); - const store = rls.keyInYNStrict("Store Tokens? (Will Be Unencrypted)"); - const projectOptions = ["Add Project", "Exit"]; - const envOptions = ["Add Environment", "Exit"]; - const pathOptions = ["Add Path", "Exit"]; - var opt; - projLoop: while(1){ - opt = rls.keyInSelect(projectOptions, "Select"); - if(opt !== 1) break projLoop; - envLoop: while(1){ +export function generateConfig() { + const url = rls.question("Infisical Instance: "); + const store = rls.keyInYNStrict("Store Tokens? (Will Be Unencrypted)"); + const projectOptions = ["Add Project", "Exit"]; + const envOptions = ["Add Environment", "Exit"]; + const pathOptions = ["Add Path", "Exit"]; + var opt; + projLoop: while (1) { opt = rls.keyInSelect(projectOptions, "Select"); - } - } - console.log({infisicalInstance: url, storeTokens: store}); - + if (opt !== 1) break projLoop; + envLoop: while (1) { + opt = rls.keyInSelect(projectOptions, "Select"); + } + } + console.log({ infisicalInstance: url, storeTokens: store }); } diff --git a/index.js b/index.js index 18f7558..06425dd 100644 --- a/index.js +++ b/index.js @@ -2,7 +2,7 @@ import fs from "node:fs"; import os from "node:os"; import InfisicalClient from "infisical-node"; import rls from "readline-sync"; -import {loadConfig, upsertConfig} from "./configurator.js"; +import { loadConfig, upsertConfig } from "./configurator.js"; const envpath = `${os.homedir()}/.env`; //upsertConfig(); //TODO Build Configuration Generator const config = loadConfig(); @@ -12,29 +12,66 @@ const siteURL = config.infisicalInstance; const projects = config.projects; const pendingSecrets = []; -async function getProjectSecrets(project, environment, token, path="/", includeImports=true){ - const client = new InfisicalClient({token, siteURL}); - const secrets = await client.getAllSecrets({environment, path, includeImports, attachToProcessEnv: false}); - return secrets.map((s)=>({...s, project, path})) +async function getProjectSecrets( + project, + environment, + token, + path = "/", + includeImports = true, +) { + const client = new InfisicalClient({ token, siteURL }); + const secrets = await client.getAllSecrets({ + environment, + path, + includeImports, + attachToProcessEnv: false, + }); + return secrets.map((s) => ({ ...s, project, path })); } -function mapToFile(secrets, filename){ - const envSecrets = secrets.map((s)=>`export ${s.secretName}=${s.secretValue}`).join("\n"); - fs.writeFileSync(`${envpath}/${filename}`, envSecrets); +function mapToFile(proj, secrets) { + const filename = `infisical-autoenv-${proj}`; + const date = new Date(); + const dateString = + date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate(); + const paths = Object.keys(secrets); + const lines = paths.map( + (p) => + `# ---${p}--- ${dateString}\n` + + secrets[p] + .map((s) => `export ${s.secretName}=${s.secretValue}`) + .join("\n"), + ); + const fileData = lines.join("\n"); + fs.writeFileSync(`${envpath}/${filename}`, fileData); } -for(var p of projects){ - for(var e of p.environments){ - if(!process.env[e.envar]) throw Error(`${e.envar} could not be found!`); - for(var path of e.paths){ - pendingSecrets.push(getProjectSecrets(p.name, e.slug, process.env[e.envar], path)); - } - } +for (var p of projects) { + for (var e of p.environments) { + if (!process.env[e.envar]) throw Error(`${e.envar} could not be found!`); + for (var path of e.paths) { + pendingSecrets.push( + getProjectSecrets(p.name, e.slug, process.env[e.envar], path), + ); + } + } } -const loadedSecrets = await Promise.all(pendingSecrets) -const filteredSecrets = loadedSecrets.flat(2).filter((s)=>!s.isFallback); -console.log(filteredSecrets); - +const loadedSecrets = await Promise.all(pendingSecrets); +const filteredSecrets = loadedSecrets.flat(2).filter((s) => !s.isFallback); +const proj = projects.map((p) => ({ + name: p.name, + paths: p.environments.map((envs) => envs.paths).flat(2), +})); +const projectSecrets = {}; +for (var p of proj) { + projectSecrets[p.name] = {}; + for (var path of p.paths) { + projectSecrets[p.name][path] = filteredSecrets.filter( + (s) => s.project === p.name && s.path === path, + ); + } + mapToFile(p.name, projectSecrets[p.name]); +}