sanitizeEnvVars function in Storybook codebase.



This content originally appeared on DEV Community and was authored by Ramu Narasinga

In this article, we review sanitizeEnvVars function in Storybook codebase. We will look at:

  1. sanitizeEnvVars function

I study patterns used in an open source project found on Github Trending. For this week, I reviewed some parts of Storybook codebase and wrote this article.

sanitizeEnvVars function

You will find the following definition in storybook/code/builders/builder-vite/src/envs.ts.

// Sanitize environment variables if needed
export async function sanitizeEnvVars(options: Options, config: ViteConfig) {
  const { presets } = options;
  const envsRaw = await presets.apply<Promise<Builder_EnvsRaw>>('env');
  let { define } = config;
  if (Object.keys(envsRaw).length) {
    // Stringify env variables after getting `envPrefix` from the  config
    const envs = stringifyProcessEnvs(envsRaw, config.envPrefix);
    define = {
      ...define,
      ...envs,
    };
  }
  return {
    ...config,
    define,
  } as ViteConfig;
}

stringifyProcessEnvs 

stringifyProcessEnvs is defined at L22 in the same file and is defined as following:

/**
 * Customized version of stringifyProcessEnvs from storybook/internal/core-common which uses
 * import.meta.env instead of process.env and checks for allowed variables.
 */
export function stringifyProcessEnvs(raw: Builder_EnvsRaw, envPrefix: ViteConfig['envPrefix']) {
  const updatedRaw: Builder_EnvsRaw = {};
  const envs = Object.entries(raw).reduce((acc: Builder_EnvsRaw, [key, value]) => {
    // Only add allowed values OR values from array OR string started with allowed prefixes
    if (
      allowedEnvVariables.includes(key) ||
      (Array.isArray(envPrefix) && !!envPrefix.find((prefix) => key.startsWith(prefix))) ||
      (typeof envPrefix === 'string' && key.startsWith(envPrefix))
    ) {
      acc[`import.meta.env.${key}`] = JSON.stringify(value);
      updatedRaw[key] = value;
    }
    return acc;
  }, {});
  // support destructuring like
  // const { foo } = import.meta.env;
  envs['import.meta.env'] = JSON.stringify(stringifyEnvs(updatedRaw));

  return envs;
}

Then this function is also calling another function named stringifyEnvs and it is defined in common/utils/envs.ts.

export const stringifyEnvs = (raw: Record<string, string>): Record<string, string> =>
  Object.entries(raw).reduce<Record<string, string>>((acc, [key, value]) => {
    acc[key] = JSON.stringify(value);
    return acc;
  }, {});

About me:

Hey, my name is Ramu Narasinga. I study codebase architecture in large open-source projects.

Email: ramu.narasinga@gmail.com

Study the patterns used in large OSS projects at Think Throo.

References:

  1. https://github.com/storybookjs/storybook/blob/next/code/builders/builder-vite/src/envs.ts#L44

  2. https://github.com/storybookjs/storybook/blob/next/code/builders/builder-vite/src/envs.ts#L22


This content originally appeared on DEV Community and was authored by Ramu Narasinga