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/8b92376b.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,31 @@ describe(`Features`, () => {
}),
);

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

const {stdout} = await run(`config`, `get`, `npmScopes`, `--json`);
expect(JSON.parse(stdout).scoped.npmMinimalAgeGate).toBeNull();

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

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

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

const scopedPackageGateSettings = {
npmMinimalAgeGate: {
description: `Minimum age of a package version according to the publish date on the npm registry to be considered for installation`,
type: SettingsType.DURATION,
unit: DurationUnit.MINUTES,
isNullable: true,
default: null,
},
} 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 +117,7 @@ declare module '@yarnpkg/core' {
npmPublishRegistry: string | null;
npmRegistryServer: string;

npmMinimalAgeGate: number;
npmMinimalAgeGate: number | null;
}>>;
npmRegistries: Map<string, miscUtils.ToMapValue<{
npmAlwaysAuth: boolean;
Expand All @@ -133,7 +143,7 @@ const plugin: Plugin = {
properties: {
...authSettings,
...registrySettings,
...scopablePackageGateSettings,
...scopedPackageGateSettings,
},
},
},
Expand Down
8 changes: 7 additions & 1 deletion packages/yarnpkg-core/sources/Configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export enum DurationUnit {
WEEKS = `w`,
}
export type DurationSettingsDefinition = BaseSettingsDefinition<SettingsType.DURATION> & {
default: string;
default: string | null;
unit: DurationUnit;
isNullable?: boolean;
};
Expand Down Expand Up @@ -810,6 +810,9 @@ function parseSingleValue(configuration: Configuration, path: string, valueBase:
if (value === null && !definition.isNullable && definition.default !== null)
throw new Error(`Non-nullable configuration settings "${path}" cannot be set to null`);

if (value === null)
return null;

if (`values` in definition && definition.values?.includes(value))
return value;

Expand Down Expand Up @@ -953,6 +956,9 @@ function getDefaultValue(configuration: Configuration, definition: SettingsDefin
}
}
case SettingsType.DURATION: {
if (definition.default === null)
return null;

return miscUtils.parseDuration(definition.default, definition.unit);
}
default: {
Expand Down
Loading