diff --git a/.changeset/breezy-clouds-kick.md b/.changeset/breezy-clouds-kick.md new file mode 100644 index 0000000000..8b4dde1d16 --- /dev/null +++ b/.changeset/breezy-clouds-kick.md @@ -0,0 +1,6 @@ +--- +"@pnpm/plugin-commands-config": patch +"pnpm": patch +--- + +`pnpm config set` should convert the settings to their correct type before adding them to `pnpm-workspace.yaml` [#9355](https://github.com/pnpm/pnpm/issues/9355). diff --git a/config/plugin-commands-config/src/configSet.ts b/config/plugin-commands-config/src/configSet.ts index b5d38fe47b..102f07c3a0 100644 --- a/config/plugin-commands-config/src/configSet.ts +++ b/config/plugin-commands-config/src/configSet.ts @@ -1,6 +1,7 @@ import fs from 'fs' import path from 'path' import util from 'util' +import { types } from '@pnpm/config' import { runNpm } from '@pnpm/run-npm' import { updateWorkspaceManifest } from '@pnpm/workspace.manifest-writer' import camelCase from 'camelcase' @@ -34,10 +35,43 @@ export async function configSet (opts: ConfigCommandOptions, key: string, value: } key = camelCase(key) await updateWorkspaceManifest(opts.workspaceDir ?? opts.dir, { - [key]: value, + [key]: castField(value, kebabCase(key)), }) } +function castField (value: unknown, key: string) { + if (typeof value !== 'string') { + return value + } + + const type = types[key as keyof typeof types] as (string | number | boolean | null | NumberConstructor) + const typeList = Array.isArray(type) ? type : [type] + const isNumber = typeList.includes(Number) + + value = value.trim() + + switch (value) { + case 'true': { + return true + } + case 'false': { + return false + } + case 'null': { + return null + } + case 'undefined': { + return undefined + } + } + + if (isNumber && !isNaN(value as number)) { + value = Number(value) + } + + return value +} + export function settingShouldFallBackToNpm (key: string): boolean { return ( ['registry', '_auth', '_authToken', 'username', '_password'].includes(key) || diff --git a/config/plugin-commands-config/test/configSet.test.ts b/config/plugin-commands-config/test/configSet.test.ts index cbbcd15905..5a27068db7 100644 --- a/config/plugin-commands-config/test/configSet.test.ts +++ b/config/plugin-commands-config/test/configSet.test.ts @@ -112,6 +112,24 @@ test('config set using the location=project option', async () => { }) }) +test('config set saves the setting in the right format to pnpm-workspace.yaml', async () => { + const tmp = tempDir() + const configDir = path.join(tmp, 'global-config') + fs.mkdirSync(configDir, { recursive: true }) + + await config.handler({ + dir: process.cwd(), + cliOptions: {}, + configDir, + location: 'project', + rawConfig: {}, + }, ['set', 'fetch-timeout', '1000']) + + expect(readYamlFile(path.join(tmp, 'pnpm-workspace.yaml'))).toEqual({ + fetchTimeout: 1000, + }) +}) + test('config set in project .npmrc file', async () => { const tmp = tempDir() const configDir = path.join(tmp, 'global-config')