Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .yarn/versions/56c1f837.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
releases:
"@yarnpkg/core": patch
"@yarnpkg/plugin-npm": patch

declined:
- "@yarnpkg/plugin-catalog"
- "@yarnpkg/plugin-compat"
- "@yarnpkg/plugin-constraints"
- "@yarnpkg/plugin-dlx"
- "@yarnpkg/plugin-essentials"
- "@yarnpkg/plugin-exec"
- "@yarnpkg/plugin-file"
- "@yarnpkg/plugin-git"
- "@yarnpkg/plugin-github"
- "@yarnpkg/plugin-http"
- "@yarnpkg/plugin-init"
- "@yarnpkg/plugin-interactive-tools"
- "@yarnpkg/plugin-jsr"
- "@yarnpkg/plugin-link"
- "@yarnpkg/plugin-nm"
- "@yarnpkg/plugin-npm-cli"
- "@yarnpkg/plugin-pack"
- "@yarnpkg/plugin-patch"
- "@yarnpkg/plugin-pnp"
- "@yarnpkg/plugin-pnpm"
- "@yarnpkg/plugin-stage"
- "@yarnpkg/plugin-typescript"
- "@yarnpkg/plugin-version"
- "@yarnpkg/plugin-workspace-tools"
- "@yarnpkg/builder"
- "@yarnpkg/cli"
- "@yarnpkg/doctor"
- "@yarnpkg/extensions"
- "@yarnpkg/nm"
- "@yarnpkg/pnpify"
- "@yarnpkg/sdks"
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,28 @@ describe(`Features`, () => {
}),
);

test(
`unset scope gate inherits from the disabled global gate`,
makeTemporaryEnv({}, async ({path, run, source}) => {
const registryUrl = await startPackageServer();
await xfs.writeJsonPromise(`${path}/.yarnrc.yml` as PortablePath, {
npmMinimalAgeGate: 0,
npmScopes: {
scoped: {
npmRegistryServer: registryUrl,
},
},
});

await run(`add`, `@scoped/release-date@1.1.1`);

await expect(source(`require('@scoped/release-date/package.json')`)).resolves.toMatchObject({
name: `@scoped/release-date`,
version: `1.1.1`,
});
}),
);

test(
`--no-time-gate bypasses scope override`,
makeTemporaryEnv({}, async ({path, run, source}) => {
Expand Down
12 changes: 10 additions & 2 deletions packages/plugin-npm/sources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ const scopablePackageGateSettings = {
},
} satisfies Record<string, SettingsDefinition>;

const scopedPackageGateSettings = {
npmMinimalAgeGate: {
...scopablePackageGateSettings.npmMinimalAgeGate,
fallback: `npmMinimalAgeGate`,
default: undefined,
},
} satisfies Record<string, SettingsDefinition>;

const globalOnlyPackageGateSettings = {
npmPreapprovedPackages: {
description: `Array of package descriptors or package name glob patterns to exclude from the minimum release age check`,
Expand Down Expand Up @@ -107,7 +115,7 @@ declare module '@yarnpkg/core' {
npmPublishRegistry: string | null;
npmRegistryServer: string;

npmMinimalAgeGate: number;
npmMinimalAgeGate: number | undefined;
}>>;
npmRegistries: Map<string, miscUtils.ToMapValue<{
npmAlwaysAuth: boolean;
Expand All @@ -133,7 +141,7 @@ const plugin: Plugin = {
properties: {
...authSettings,
...registrySettings,
...scopablePackageGateSettings,
...scopedPackageGateSettings,
},
},
},
Expand Down
19 changes: 13 additions & 6 deletions packages/yarnpkg-core/sources/Configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ export const FormatType = formatUtils.Type;
export type BaseSettingsDefinition<T extends SettingsType = SettingsType> = {
description: string;
type: T;
fallback?: string;
} & ({isArray?: false} | {isArray: true, concatenateValues?: boolean});

export enum DurationUnit {
Expand All @@ -168,7 +169,7 @@ export enum DurationUnit {
WEEKS = `w`,
}
export type DurationSettingsDefinition = BaseSettingsDefinition<SettingsType.DURATION> & {
default: string;
default: string | undefined;
unit: DurationUnit;
isNullable?: boolean;
};
Expand Down Expand Up @@ -953,6 +954,9 @@ function getDefaultValue(configuration: Configuration, definition: SettingsDefin
}
}
case SettingsType.DURATION: {
if (typeof definition.default === `undefined`)
return undefined;

return miscUtils.parseDuration(definition.default, definition.unit);
}
default: {
Expand All @@ -966,7 +970,10 @@ type SettingTransforms = {
getNativePaths: boolean;
};

function transformConfiguration(rawValue: unknown, definition: SettingsDefinitionNoDefault, transforms: SettingTransforms) {
function transformConfiguration(configuration: Configuration, rawValue: unknown, definition: SettingsDefinitionNoDefault, transforms: SettingTransforms) {
if (typeof rawValue === `undefined` && typeof definition.fallback !== `undefined`)
return configuration.get(definition.fallback);

if (definition.type === SettingsType.SECRET && typeof rawValue === `string` && transforms.hideSecrets)
return SECRET;
if (definition.type === SettingsType.ABSOLUTE_PATH && typeof rawValue === `string` && transforms.getNativePaths)
Expand All @@ -976,7 +983,7 @@ function transformConfiguration(rawValue: unknown, definition: SettingsDefinitio
const newValue: Array<unknown> = [];

for (const value of rawValue)
newValue.push(transformConfiguration(value, definition, transforms));
newValue.push(transformConfiguration(configuration, value, definition, transforms));

return newValue;
}
Expand All @@ -988,7 +995,7 @@ function transformConfiguration(rawValue: unknown, definition: SettingsDefinitio
const newValue: Map<string, unknown> = new Map();

for (const [key, value] of rawValue.entries()) {
const transformedValue = transformConfiguration(value, definition.valueDefinition, transforms);
const transformedValue = transformConfiguration(configuration, value, definition.valueDefinition, transforms);
if (typeof transformedValue !== `undefined`) {
newValue.set(key, transformedValue);
}
Expand All @@ -1006,7 +1013,7 @@ function transformConfiguration(rawValue: unknown, definition: SettingsDefinitio
for (const [key, value] of rawValue.entries()) {
const propertyDefinition = definition.properties[key];

const transformedValue = transformConfiguration(value, propertyDefinition, transforms);
const transformedValue = transformConfiguration(configuration, value, propertyDefinition, transforms);
if (typeof transformedValue !== `undefined`) {
newValue.set(key, transformedValue);
}
Expand Down Expand Up @@ -1733,7 +1740,7 @@ export class Configuration {
if (typeof definition === `undefined`)
throw new UsageError(`Couldn't find a configuration settings named "${key}"`);

return transformConfiguration(rawValue, definition, {
return transformConfiguration(this, rawValue, definition, {
hideSecrets,
getNativePaths,
}) as T;
Expand Down
18 changes: 18 additions & 0 deletions packages/yarnpkg-core/tests/Configuration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,24 @@ describe(`Configuration`, () => {
});

describe(`Configuration merging`, () => {
it(`should resolve scoped npmMinimalAgeGate from the global value when unset`, async () => {
await initializeConfiguration({
npmMinimalAgeGate: 0,
npmScopes: {
scopeName: {
npmRegistryServer: `https://example.com/npm/registry`,
},
},
}, async dir => {
const configuration = await Configuration.find(dir, {
modules: new Map([[`@yarnpkg/plugin-npm`, NpmPlugin]]),
plugins: new Set([`@yarnpkg/plugin-npm`]),
});

expect(configuration.getSpecial(`npmScopes`, {hideSecrets: false}).get(`scopeName`).get(`npmMinimalAgeGate`)).toBe(0);
});
});

it(`should merge map properties`, async () => {
await initializeConfiguration({
npmRegistryServer: `https://foo.server`,
Expand Down
Loading