Ctrl K
ComunidadGuías…

scripts/local-secrets.mjs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { spawnSync } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import { resolve } from 'node:path';
import { writeFileAtomic } from './setup-config.mjs';
import { encodeEnvValue } from './env-file.mjs';

export function renderLocalEnvironment(fields) {
  const settings = fields.filter(field => field.section?.id === 'local_environment');
  if (!settings.length) throw new Error('The vault item has no Local application fields.');
  const seen = new Set();
  const lines = settings.map(field => {
    const key = field.label;
    if (!/^[A-Z][A-Z0-9_]*$/.test(key) || seen.has(key))
      throw new Error('The vault item contains an invalid or duplicate environment field.');
    seen.add(key);
    const value = field.value ?? '';
    if (typeof value !== 'string') throw new Error('Environment values must be text.');
    return `${key}=${encodeEnvValue(value)}`;
  });
  return `${lines.join('\n')}\n`;
}

function pullLocalSecrets() {
  const env = { ...process.env };
  if (!env.OP_SERVICE_ACCOUNT_TOKEN) {
    if (process.platform !== 'darwin')
      throw new Error('Set OP_SERVICE_ACCOUNT_TOKEN to access the Development vault.');
    const key = spawnSync('security', [
      'find-generic-password', '-a', 'service-account', '-s', 'development-1password', '-w',
    ], { encoding: 'utf8' });
    if (key.status !== 0 || !key.stdout.trim())
      throw new Error('Could not read the development service-account token from Keychain.');
    env.OP_SERVICE_ACCOUNT_TOKEN = key.stdout.trim();
  }
  const result = spawnSync('op', [
    'item', 'get', 'devpush (local)', '--vault', 'Development', '--format', 'json',
  ], { env, encoding: 'utf8', maxBuffer: 4 * 1024 * 1024 });
  if (result.status !== 0)
    throw new Error('Could not read devpush (local). Check that op is installed and the service account has vault access.');
  let item;
  try { item = JSON.parse(result.stdout); }
  catch { throw new Error('1Password returned an invalid item.'); }
  if (!Array.isArray(item.fields)) throw new Error('1Password returned no item fields.');
  const content = renderLocalEnvironment(item.fields);
  writeFileAtomic(fileURLToPath(new URL('../app/.env', import.meta.url)), content, 0o600);
  console.log('Restored app/.env from Development / devpush (local), with owner-only permissions.');
}

if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
  try { pullLocalSecrets(); }
  catch (error) {
    console.error(error.message);
    process.exitCode = 1;
  }
}