Files
pnpm/config/reader/test/projectConfig.test.ts
Zoltan Kochan 4a36b9a110 refactor: rename internal packages to @pnpm/<domain>.<leaf> convention (#10997)
## Summary

Rename all internal packages so their npm names follow the `@pnpm/<domain>.<leaf>` convention, matching their directory structure. Also rename directories to remove redundancy and improve clarity.

### Bulk rename (94 packages)

All `@pnpm/` packages now derive their name from their directory path using dot-separated segments. Exceptions: `packages/`, `__utils__/`, and `pnpm/artifacts/` keep leaf names only.

### Directory renames (removing redundant prefixes)

- `cli/cli-meta` → `cli/meta`, `cli/cli-utils` → `cli/utils`
- `config/config` → `config/reader`, `config/config-writer` → `config/writer`
- `fetching/fetching-types` → `fetching/types`
- `lockfile/lockfile-to-pnp` → `lockfile/to-pnp`
- `store/store-connection-manager` → `store/connection-manager`
- `store/store-controller-types` → `store/controller-types`
- `store/store-path` → `store/path`

### Targeted renames (clarity improvements)

- `deps/dependency-path` → `deps/path` (`@pnpm/deps.path`)
- `deps/calc-dep-state` → `deps/graph-hasher` (`@pnpm/deps.graph-hasher`)
- `deps/inspection/dependencies-hierarchy` → `deps/inspection/tree-builder` (`@pnpm/deps.inspection.tree-builder`)
- `bins/link-bins` → `bins/linker`, `bins/remove-bins` → `bins/remover`, `bins/package-bins` → `bins/resolver`
- `installing/get-context` → `installing/context`
- `store/package-store` → `store/controller`
- `pkg-manifest/manifest-utils` → `pkg-manifest/utils`

### Manifest reader/writer renames

- `workspace/read-project-manifest` → `workspace/project-manifest-reader` (`@pnpm/workspace.project-manifest-reader`)
- `workspace/write-project-manifest` → `workspace/project-manifest-writer` (`@pnpm/workspace.project-manifest-writer`)
- `workspace/read-manifest` → `workspace/workspace-manifest-reader` (`@pnpm/workspace.workspace-manifest-reader`)
- `workspace/manifest-writer` → `workspace/workspace-manifest-writer` (`@pnpm/workspace.workspace-manifest-writer`)

### Workspace package renames

- `workspace/find-packages` → `workspace/projects-reader`
- `workspace/find-workspace-dir` → `workspace/root-finder`
- `workspace/resolve-workspace-range` → `workspace/range-resolver`
- `workspace/filter-packages-from-dir` merged into `workspace/filter-workspace-packages` → `workspace/projects-filter`

### Domain moves

- `pkg-manifest/read-project-manifest` → `workspace/project-manifest-reader`
- `pkg-manifest/write-project-manifest` → `workspace/project-manifest-writer`
- `pkg-manifest/exportable-manifest` → `releasing/exportable-manifest`

### Scope

- 1206 files changed
- Updated: package.json names/deps, TypeScript imports, tsconfig references, changeset files, renovate.json, test fixtures, import ordering
2026-03-17 21:50:40 +01:00

550 lines
16 KiB
TypeScript

import { omit } from 'ramda'
import type {
Config,
ProjectConfig,
ProjectConfigMultiMatch,
ProjectConfigRecord,
ProjectConfigSet,
} from '../src/Config.js'
import { createProjectConfigRecord } from '../src/projectConfig.js'
it('returns undefined for undefined', () => {
expect(createProjectConfigRecord({})).toBeUndefined()
expect(createProjectConfigRecord({ packageConfigs: undefined })).toBeUndefined()
expect(createProjectConfigRecord({ packageConfigs: null as unknown as undefined })).toBeUndefined()
})
it('errors on invalid packageConfigs', () => {
expect(() => createProjectConfigRecord({
packageConfigs: 0 as unknown as ProjectConfigSet,
})).toThrow(expect.objectContaining({
configSet: 0,
code: 'ERR_PNPM_PROJECT_CONFIGS_IS_NEITHER_OBJECT_NOR_ARRAY',
}))
expect(() => createProjectConfigRecord({
packageConfigs: 'some string' as unknown as ProjectConfigSet,
})).toThrow(expect.objectContaining({
configSet: 'some string',
code: 'ERR_PNPM_PROJECT_CONFIGS_IS_NEITHER_OBJECT_NOR_ARRAY',
}))
expect(() => createProjectConfigRecord({
packageConfigs: true as unknown as ProjectConfigSet,
})).toThrow(expect.objectContaining({
configSet: true,
code: 'ERR_PNPM_PROJECT_CONFIGS_IS_NEITHER_OBJECT_NOR_ARRAY',
}))
})
describe('record', () => {
it('returns an empty record for an empty record', () => {
expect(createProjectConfigRecord({ packageConfigs: {} })).toStrictEqual({})
})
it('returns a valid record for a valid record', () => {
const packageConfigs: ProjectConfigRecord = {
'project-1': {
modulesDir: 'foo',
},
'project-2': {
saveExact: true,
},
'project-3': {
savePrefix: '~',
},
}
expect(createProjectConfigRecord({ packageConfigs })).toStrictEqual(packageConfigs)
})
it('explicitly sets hoistPattern to undefined when hoist is false', () => {
expect(createProjectConfigRecord({
packageConfigs: {
'project-1': { hoist: false },
},
})).toStrictEqual({
'project-1': {
hoist: false,
hoistPattern: undefined,
},
} as ProjectConfigRecord)
})
it('errors on invalid project config', () => {
expect(() => createProjectConfigRecord({
packageConfigs: {
'project-1': 0 as unknown as ProjectConfig,
},
})).toThrow(expect.objectContaining({
actualRawConfig: 0,
code: 'ERR_PNPM_PROJECT_CONFIG_NOT_AN_OBJECT',
}))
expect(() => createProjectConfigRecord({
packageConfigs: {
'project-1': 'some string' as unknown as ProjectConfig,
},
})).toThrow(expect.objectContaining({
actualRawConfig: 'some string',
code: 'ERR_PNPM_PROJECT_CONFIG_NOT_AN_OBJECT',
}))
expect(() => createProjectConfigRecord({
packageConfigs: {
'project-1': true as unknown as ProjectConfig,
},
})).toThrow(expect.objectContaining({
actualRawConfig: true,
code: 'ERR_PNPM_PROJECT_CONFIG_NOT_AN_OBJECT',
}))
expect(() => createProjectConfigRecord({
packageConfigs: {
'project-1': null as unknown as ProjectConfig,
},
})).toThrow(expect.objectContaining({
actualRawConfig: null,
code: 'ERR_PNPM_PROJECT_CONFIG_NOT_AN_OBJECT',
}))
expect(() => createProjectConfigRecord({
packageConfigs: {
'project-1': [0, 1, 2] as unknown as ProjectConfig,
},
})).toThrow(expect.objectContaining({
actualRawConfig: [0, 1, 2],
code: 'ERR_PNPM_PROJECT_CONFIG_NOT_AN_OBJECT',
}))
})
it('errors on invalid hoist', () => {
expect(() => createProjectConfigRecord({
packageConfigs: {
'project-1': { hoist: 'invalid' as unknown as boolean },
},
})).toThrow(expect.objectContaining({
expectedType: 'boolean',
actualValue: 'invalid',
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
expect(() => createProjectConfigRecord({
packageConfigs: {
'project-1': { hoist: 0 as unknown as boolean },
},
})).toThrow(expect.objectContaining({
expectedType: 'boolean',
actualValue: 0,
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
})
it('errors on invalid modulesDir', () => {
expect(() => createProjectConfigRecord({
packageConfigs: {
'project-1': { modulesDir: 0 as unknown as string },
},
})).toThrow(expect.objectContaining({
expectedType: 'string',
actualValue: 0,
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
expect(() => createProjectConfigRecord({
packageConfigs: {
'project-1': { modulesDir: true as unknown as string },
},
})).toThrow(expect.objectContaining({
expectedType: 'string',
actualValue: true,
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
})
it('errors on invalid saveExact', () => {
expect(() => createProjectConfigRecord({
packageConfigs: {
'project-1': { saveExact: 'invalid' as unknown as boolean },
},
})).toThrow(expect.objectContaining({
expectedType: 'boolean',
actualValue: 'invalid',
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
expect(() => createProjectConfigRecord({
packageConfigs: {
'project-1': { saveExact: 0 as unknown as boolean },
},
})).toThrow(expect.objectContaining({
expectedType: 'boolean',
actualValue: 0,
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
})
it('errors on invalid savePrefix', () => {
expect(() => createProjectConfigRecord({
packageConfigs: {
'project-1': { savePrefix: 0 as unknown as string },
},
})).toThrow(expect.objectContaining({
expectedType: 'string',
actualValue: 0,
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
expect(() => createProjectConfigRecord({
packageConfigs: {
'project-1': { savePrefix: false as unknown as string },
},
})).toThrow(expect.objectContaining({
expectedType: 'string',
actualValue: false,
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
})
it('errors on unsupported fields', () => {
expect(() => createProjectConfigRecord({
packageConfigs: {
'project-1': {
ignoreScripts: true,
} as Partial<Config>,
},
})).toThrow(expect.objectContaining({
field: 'ignoreScripts',
code: 'ERR_PNPM_PROJECT_CONFIG_UNSUPPORTED_FIELD',
}))
expect(() => createProjectConfigRecord({
packageConfigs: {
'project-1': {
hoistPattern: ['*'],
} as Partial<Config>,
},
})).toThrow(expect.objectContaining({
field: 'hoistPattern',
code: 'ERR_PNPM_PROJECT_CONFIG_UNSUPPORTED_FIELD',
}))
})
it('does not error on unsupported but undefined fields', () => {
expect(createProjectConfigRecord({
packageConfigs: {
'project-1': {
ignoreScripts: undefined,
hoistPattern: undefined,
} as Partial<Config>,
},
})).toStrictEqual({
'project-1': {
ignoreScripts: undefined,
hoistPattern: undefined,
} as Partial<Config>,
})
})
})
describe('array', () => {
type ProjectConfigWithExtraFields = Pick<ProjectConfigMultiMatch, 'match'> & Partial<Config>
it('returns an empty record for an empty array', () => {
expect(createProjectConfigRecord({ packageConfigs: [] })).toStrictEqual({})
})
it('returns a map of project-specific settings for a non-empty array', () => {
const withoutMatch: (withMatch: ProjectConfigMultiMatch) => ProjectConfig = omit(['match'])
const packageConfigs = [
{
match: ['project-1'],
modulesDir: 'foo',
},
{
match: ['project-2', 'project-3'],
saveExact: true,
},
{
match: ['project-4', 'project-5', 'project-6'],
savePrefix: '~',
},
] as const satisfies ProjectConfigMultiMatch[]
const record: ProjectConfigRecord | undefined = createProjectConfigRecord({ packageConfigs })
expect(record).toStrictEqual({
'project-1': withoutMatch(packageConfigs[0]),
'project-2': withoutMatch(packageConfigs[1]),
'project-3': withoutMatch(packageConfigs[1]),
'project-4': withoutMatch(packageConfigs[2]),
'project-5': withoutMatch(packageConfigs[2]),
'project-6': withoutMatch(packageConfigs[2]),
} as ProjectConfigRecord)
expect(createProjectConfigRecord({ packageConfigs: record })).toStrictEqual(record)
})
it('explicitly sets hoistPattern to undefined when hoist is false', () => {
expect(createProjectConfigRecord({
packageConfigs: [{
match: ['project-1'],
hoist: false,
}],
})).toStrictEqual({
'project-1': {
hoist: false,
hoistPattern: undefined,
},
} as ProjectConfigRecord)
})
it('errors on invalid array items', () => {
expect(() => createProjectConfigRecord({
packageConfigs: [0 as unknown as ProjectConfigMultiMatch],
})).toThrow(expect.objectContaining({
item: 0,
code: 'ERR_PNPM_PROJECT_CONFIGS_ARRAY_ITEM_IS_NOT_AN_OBJECT',
}))
expect(() => createProjectConfigRecord({
packageConfigs: ['some string' as unknown as ProjectConfigMultiMatch],
})).toThrow(expect.objectContaining({
item: 'some string',
code: 'ERR_PNPM_PROJECT_CONFIGS_ARRAY_ITEM_IS_NOT_AN_OBJECT',
}))
expect(() => createProjectConfigRecord({
packageConfigs: [true as unknown as ProjectConfigMultiMatch],
})).toThrow(expect.objectContaining({
item: true,
code: 'ERR_PNPM_PROJECT_CONFIGS_ARRAY_ITEM_IS_NOT_AN_OBJECT',
}))
expect(() => createProjectConfigRecord({
packageConfigs: [null as unknown as ProjectConfigMultiMatch],
})).toThrow(expect.objectContaining({
item: null,
code: 'ERR_PNPM_PROJECT_CONFIGS_ARRAY_ITEM_IS_NOT_AN_OBJECT',
}))
})
it('errors on undefined match', () => {
expect(() => createProjectConfigRecord({
packageConfigs: [{} as ProjectConfigMultiMatch],
})).toThrow(expect.objectContaining({
code: 'ERR_PNPM_PROJECT_CONFIGS_ARRAY_ITEM_MATCH_IS_NOT_DEFINED',
}))
})
it('errors on non-array match', () => {
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: 0 as unknown as string[],
}],
})).toThrow(expect.objectContaining({
match: 0,
code: 'ERR_PNPM_PROJECT_CONFIGS_ARRAY_ITEM_MATCH_IS_NOT_AN_ARRAY',
}))
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: 'some string' as unknown as string[],
}],
})).toThrow(expect.objectContaining({
match: 'some string',
code: 'ERR_PNPM_PROJECT_CONFIGS_ARRAY_ITEM_MATCH_IS_NOT_AN_ARRAY',
}))
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: true as unknown as string[],
}],
})).toThrow(expect.objectContaining({
match: true,
code: 'ERR_PNPM_PROJECT_CONFIGS_ARRAY_ITEM_MATCH_IS_NOT_AN_ARRAY',
}))
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: undefined as unknown as string[],
}],
})).toThrow(expect.objectContaining({
match: undefined,
code: 'ERR_PNPM_PROJECT_CONFIGS_ARRAY_ITEM_MATCH_IS_NOT_AN_ARRAY',
}))
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: null as unknown as string[],
}],
})).toThrow(expect.objectContaining({
match: null,
code: 'ERR_PNPM_PROJECT_CONFIGS_ARRAY_ITEM_MATCH_IS_NOT_AN_ARRAY',
}))
})
it('errors on non-string match item', () => {
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: [0 as unknown as string],
}],
})).toThrow(expect.objectContaining({
matchItem: 0,
code: 'ERR_PNPM_PROJECT_CONFIGS_MATCH_ITEM_IS_NOT_A_STRING',
}))
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: [null as unknown as string],
}],
})).toThrow(expect.objectContaining({
matchItem: null,
code: 'ERR_PNPM_PROJECT_CONFIGS_MATCH_ITEM_IS_NOT_A_STRING',
}))
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: [{} as unknown as string],
}],
})).toThrow(expect.objectContaining({
matchItem: {},
code: 'ERR_PNPM_PROJECT_CONFIGS_MATCH_ITEM_IS_NOT_A_STRING',
}))
})
it('errors on invalid hoist', () => {
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: ['project-1'],
hoist: 'invalid' as unknown as boolean,
}],
})).toThrow(expect.objectContaining({
expectedType: 'boolean',
actualValue: 'invalid',
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: ['project-1'],
hoist: 0 as unknown as boolean,
}],
})).toThrow(expect.objectContaining({
expectedType: 'boolean',
actualValue: 0,
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
})
it('errors on invalid modulesDir', () => {
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: ['project-1'],
modulesDir: 0 as unknown as string,
}],
})).toThrow(expect.objectContaining({
expectedType: 'string',
actualValue: 0,
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: ['project-1'],
modulesDir: true as unknown as string,
}],
})).toThrow(expect.objectContaining({
expectedType: 'string',
actualValue: true,
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
})
it('errors on invalid saveExact', () => {
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: ['project-1'],
saveExact: 'invalid' as unknown as boolean,
}],
})).toThrow(expect.objectContaining({
expectedType: 'boolean',
actualValue: 'invalid',
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: ['project-1'],
saveExact: 0 as unknown as boolean,
}],
})).toThrow(expect.objectContaining({
expectedType: 'boolean',
actualValue: 0,
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
})
it('errors on invalid savePrefix', () => {
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: ['project-1'],
savePrefix: 0 as unknown as string,
}],
})).toThrow(expect.objectContaining({
expectedType: 'string',
actualValue: 0,
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: ['project-1'],
savePrefix: false as unknown as string,
}],
})).toThrow(expect.objectContaining({
expectedType: 'string',
actualValue: false,
code: 'ERR_PNPM_PROJECT_CONFIG_INVALID_VALUE_TYPE',
}))
})
it('errors on unsupported fields', () => {
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: ['project-1'],
ignoreScripts: true,
} as ProjectConfigWithExtraFields],
})).toThrow(expect.objectContaining({
field: 'ignoreScripts',
code: 'ERR_PNPM_PROJECT_CONFIG_UNSUPPORTED_FIELD',
}))
expect(() => createProjectConfigRecord({
packageConfigs: [{
match: ['project-1'],
hoistPattern: ['*'],
}],
})).toThrow(expect.objectContaining({
field: 'hoistPattern',
code: 'ERR_PNPM_PROJECT_CONFIG_UNSUPPORTED_FIELD',
}))
})
it('does not error on unsupported but undefined fields', () => {
expect(createProjectConfigRecord({
packageConfigs: [{
match: ['project-1'],
ignoreScripts: undefined,
hoistPattern: undefined,
} as ProjectConfigWithExtraFields],
})).toStrictEqual({
'project-1': {
ignoreScripts: undefined,
hoistPattern: undefined,
} as Partial<Config>,
})
})
})