diff --git a/config/env-replace/env-replace.docs.mdx b/config/env-replace/env-replace.docs.mdx index 355abcb..21dcb98 100644 --- a/config/env-replace/env-replace.docs.mdx +++ b/config/env-replace/env-replace.docs.mdx @@ -16,3 +16,23 @@ import { envReplace } from '@pnpm/config.env-replace' envReplace('${foo}', process.env) ``` + +## `stripEnvFallback` + +```ts +function stripEnvFallback(settingValue: string): string; +``` + +Strips fallback values from environment variable placeholders, leaving only the variable name. + +Usage: + +```ts +import { stripEnvFallback } from '@pnpm/config.env-replace' + +stripEnvFallback('${HOME-/default}/config') +// Returns: '${HOME}/config' + +stripEnvFallback('${FOO:-fallback}') +// Returns: '${FOO}' +``` diff --git a/config/env-replace/env-replace.spec.ts b/config/env-replace/env-replace.spec.ts index ec1b09d..9e8c9f1 100644 --- a/config/env-replace/env-replace.spec.ts +++ b/config/env-replace/env-replace.spec.ts @@ -1,4 +1,4 @@ -import { envReplace } from './env-replace'; +import { envReplace, stripEnvFallback } from './env-replace'; const ENV = { foo: 'foo_value', @@ -25,3 +25,15 @@ test('fail when the env variable is not found', () => { expect(() => envReplace('${foo:-}', ENV)).toThrow(`Failed to replace env in config: \${foo:-}`); }) +test.each([ + ['-${foo}-${bar}', '-${foo}-${bar}'], + ['-${foo-fallback-value}-${bar:-fallback-value}', '-${foo}-${bar}'], + ['-${qar-fallback-value}-${zoo:-fallback-for-empty-value}', '-${qar}-${zoo}'], + ['\\${foo}', '${foo}'], + ['\\\\${foo}', '\\${foo}'], + ['${foo}', '${foo}'], +])('stripEnvFallback %s => %s', (settingValue, expected) => { + const actual = stripEnvFallback(settingValue); + expect(actual).toEqual(expected); +}) + diff --git a/config/env-replace/env-replace.ts b/config/env-replace/env-replace.ts index d4074cc..874e94f 100644 --- a/config/env-replace/env-replace.ts +++ b/config/env-replace/env-replace.ts @@ -26,3 +26,22 @@ function getEnvValue (env: NodeJS.ProcessEnv, name: string): string | undefined } return fallback } + +export function stripEnvFallback (settingValue: string): string { + return settingValue.replace(ENV_EXPR, replaceEnvMatchForStrip) +} + +function replaceEnvMatchForStrip (orig: string, escape: string, name: string): string { + if (escape.length % 2) { + return orig.slice((escape.length + 1) / 2) + } + const strippedName = getStrippedEnvName(name) + return `${escape.slice(escape.length / 2)}\${${strippedName}}` +} + +function getStrippedEnvName (name: string): string { + const matched = name.match(ENV_VALUE) + if (!matched) return name + const [, variableName] = matched + return variableName +} diff --git a/config/env-replace/index.ts b/config/env-replace/index.ts index f3a18b5..4c6dbb3 100644 --- a/config/env-replace/index.ts +++ b/config/env-replace/index.ts @@ -1 +1 @@ -export { envReplace } from './env-replace'; +export { envReplace, stripEnvFallback } from './env-replace';