sync.ts2.1 KBView on GitHub
import { getProjectRoot, runCommand } from '../utils';
import { readFile, writeFile } from 'fs/promises';
import { log } from '@clack/prompts';
import type { Command } from '.';
import { join } from 'path';

const LOCAL_ENV_OVERRIDES = {
  NODE_ENV: 'development',
  COOKIE_DOMAIN: '',
} as const;

function formatEnvValue(value: string): string {
  return `"${value.replaceAll('\\', '\\\\').replaceAll('"', '\\"')}"`;
}

function upsertEnvValue(contents: string, key=[redacted], value: string): string {
  const nextLine = `${key}=${formatEnvValue(value)}`;
  const pattern = new RegExp(`^${key}=.*$`, 'm');

  if (pattern.test(contents)) {
    return contents.replace(pattern, nextLine);
  }

  return `${contents.trimEnd()}\n${nextLine}\n`;
}

function buildLocalEnvFile(contents: string): string {
  let nextContents = contents;

  for (const [key, value] of Object.entries(LOCAL_ENV_OVERRIDES)) {
    nextContents = upsertEnvValue(nextContents, key, value);
  }

  return nextContents;
}

export const command: Command = {
  id: 'sync',
  description: 'Sync your environment variables and types',
  run: async () => {
    const root = await getProjectRoot();
    const envFile = await readFile(join(root, '.env'), 'utf8').catch(() => null);

    if (!envFile) {
      log.step('No .env file exists, creating one using `pnpm nizzy env`');
      process.exit(0);
    }

    const localEnvFile = buildLocalEnvFile(envFile);

    log.step('Syncing environment variables');
    await writeFile(join(root, 'apps/mail/.env'), localEnvFile);
    await writeFile(join(root, 'apps/server/.env'), localEnvFile);
    await writeFile(join(root, 'apps/mastra/.env'), envFile);

    if (process.env.CEDAR_SYNC_TYPES === 'true') {
      log.step('Syncing frontend types');
      await runCommand('pnpm', ['run', 'types'], { cwd: join(root, 'apps/mail') });
      log.step('Syncing backend types');
      await runCommand('pnpm', ['run', 'types'], { cwd: join(root, 'apps/server') });
    } else {
      log.step('Skipping package type sync (set CEDAR_SYNC_TYPES=true to enable)');
    }
    log.success('Synced environment variables and types');
  },
};