diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 3b08960a3a20ab4..09daa06b0b9b163 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/containerbase/devcontainer:13.5.10 +FROM ghcr.io/containerbase/devcontainer:13.7.0 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fa4e3a42949ee63..90789efa1937696 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -304,7 +304,7 @@ jobs: os: ${{ runner.os }} - name: Lint markdown - uses: DavidAnson/markdownlint-cli2-action@a23dae216ce3fee4db69da41fed90d2a4af801cf # v19.0.0 + uses: DavidAnson/markdownlint-cli2-action@05f32210e84442804257b2a6f20b273450ec8265 # v19.1.0 - name: Lint fenced code blocks run: pnpm doc-fence-check @@ -438,7 +438,7 @@ jobs: merge-multiple: true - name: Codecov - uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2 + uses: codecov/codecov-action@0da7aa657d958d32c117fc47e1f977e7524753c7 # v5.3.0 with: token: ${{ secrets.CODECOV_TOKEN }} directory: coverage/lcov @@ -684,7 +684,7 @@ jobs: show-progress: false - name: docker-config - uses: containerbase/internal-tools@c8f78cbc830d1883e695d06e3028136656e70f5b # v3.5.17 + uses: containerbase/internal-tools@4453842226e67bc5d507c41b21184cc9220f4974 # v3.5.19 with: command: docker-config diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 28e256da7b5452c..7e6c52f60621b20 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -41,7 +41,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1 + uses: github/codeql-action/init@ee117c905ab18f32fa0f66c2fe40ecc8013f3e04 # v3.28.4 with: languages: javascript @@ -51,7 +51,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1 + uses: github/codeql-action/autobuild@ee117c905ab18f32fa0f66c2fe40ecc8013f3e04 # v3.28.4 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -65,4 +65,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1 + uses: github/codeql-action/analyze@ee117c905ab18f32fa0f66c2fe40ecc8013f3e04 # v3.28.4 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index a21f09f36381343..4010ca21f77ec1f 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -51,6 +51,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1 + uses: github/codeql-action/upload-sarif@ee117c905ab18f32fa0f66c2fe40ecc8013f3e04 # v3.28.4 with: sarif_file: results.sarif diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index 9b99d5869217c05..c81c2f2c68f53ae 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -31,7 +31,7 @@ jobs: format: 'sarif' output: 'trivy-results.sarif' - - uses: github/codeql-action/upload-sarif@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1 + - uses: github/codeql-action/upload-sarif@ee117c905ab18f32fa0f66c2fe40ecc8013f3e04 # v3.28.4 with: sarif_file: trivy-results.sarif category: 'docker-image-${{ matrix.tag }}' diff --git a/.nvmrc b/.nvmrc index 6fa8dec4cd6789d..d5b283a3acacfde 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22.13.0 +22.13.1 diff --git a/docs/usage/docker.md b/docs/usage/docker.md index 188c30f0a941de2..7a3361e99045a69 100644 --- a/docs/usage/docker.md +++ b/docs/usage/docker.md @@ -307,7 +307,7 @@ Renovate will get the credentials with the [`google-auth-library`](https://www.n service_account: ${{ env.SERVICE_ACCOUNT }} - name: renovate - uses: renovatebot/github-action@v41.0.9 + uses: renovatebot/github-action@v41.0.10 env: RENOVATE_HOST_RULES: | [ @@ -478,7 +478,7 @@ Make sure to install the Google Cloud SDK into the custom image, as you need the For example: ```Dockerfile -FROM renovate/renovate:39.104.1 +FROM renovate/renovate:39.117.2 # Include the "Docker tip" which you can find here https://cloud.google.com/sdk/docs/install # under "Installation" for "Debian/Ubuntu" RUN ... diff --git a/docs/usage/examples/opentelemetry.md b/docs/usage/examples/opentelemetry.md index 504a7e0ef92e90f..6225f08569db351 100644 --- a/docs/usage/examples/opentelemetry.md +++ b/docs/usage/examples/opentelemetry.md @@ -36,7 +36,7 @@ services: otel-collector: # Using the Contrib version to access the spanmetrics connector. # If you don't need the spanmetrics connector, you can use the standard version - image: otel/opentelemetry-collector-contrib:0.117.0 + image: otel/opentelemetry-collector-contrib:0.118.0 volumes: - ./otel-collector-config.yml:/etc/otelcol-contrib/config.yaml ports: diff --git a/docs/usage/examples/self-hosting.md b/docs/usage/examples/self-hosting.md index 9388b091bca91ae..f8a6ab005917df4 100644 --- a/docs/usage/examples/self-hosting.md +++ b/docs/usage/examples/self-hosting.md @@ -25,8 +25,8 @@ It builds `latest` based on the `main` branch and all SemVer tags are published ```sh title="Example of valid tags" docker run --rm renovate/renovate docker run --rm renovate/renovate:39 -docker run --rm renovate/renovate:39.104 -docker run --rm renovate/renovate:39.104.1 +docker run --rm renovate/renovate:39.117 +docker run --rm renovate/renovate:39.117.2 ``` @@ -62,7 +62,7 @@ spec: - name: renovate # Update this to the latest available and then enable Renovate on # the manifest - image: renovate/renovate:39.104.1 + image: renovate/renovate:39.117.2 args: - user/repo # Environment Variables @@ -121,7 +121,7 @@ spec: template: spec: containers: - - image: renovate/renovate:39.104.1 + - image: renovate/renovate:39.117.2 name: renovate-bot env: # For illustration purposes, please use secrets. - name: RENOVATE_PLATFORM @@ -367,7 +367,7 @@ spec: containers: - name: renovate # Update this to the latest available and then enable Renovate on the manifest - image: renovate/renovate:39.104.1 + image: renovate/renovate:39.117.2 volumeMounts: - name: ssh-key-volume readOnly: true diff --git a/docs/usage/mend-hosted/hosted-apps-config.md b/docs/usage/mend-hosted/hosted-apps-config.md index 787ec273bf84f16..202d4eea4cbae0b 100644 --- a/docs/usage/mend-hosted/hosted-apps-config.md +++ b/docs/usage/mend-hosted/hosted-apps-config.md @@ -1,7 +1,5 @@ # Mend-hosted Apps Configuration -The Mend-hosted apps ([Renovate App on GitHub](https://github.com/apps/renovate) and [Mend App on Bitbucket](https://marketplace.atlassian.com/apps/1232072/mend)) are popular ways to use Renovate on the cloud. - This page: - covers all non-default Renovate behavior of these Mend-hosted apps @@ -74,12 +72,12 @@ This change causes Renovate to create an Onboarding PR, even if Renovate does no ## Fork Processing -If an Organization installs Renovate with the "All repositories" option, then `forkProcessing` will remain set to its default value `false`. +If an Organization installs Renovate with the "All repositories" option, then `forkProcessing` will remain set to its default value `disabled`. This means forked repositories are _not_ onboarded, Renovate ignores them. -To change this behavior, push a `renovate.json` file to the repository with `"forkProcessing": true`. +To change this behavior, push a `renovate.json` file to the repository with `"forkProcessing": "enabled"`. If an Organization installs Renovate with "Selected repositories", we assume the organization wants to onboard _all_ of the selected repositories, even forked repositories. -Therefore we set `forkProcessing` to `true`. +Therefore we set `forkProcessing` to "enabled". ## Inherited config diff --git a/docs/usage/nuget.md b/docs/usage/nuget.md index ef827088a822729..e0db20ba96758e8 100644 --- a/docs/usage/nuget.md +++ b/docs/usage/nuget.md @@ -47,13 +47,16 @@ You can set alternative feeds: ```json { - "nuget": { - "registryUrls": [ - "https://api.nuget.org/v3/index.json", - "https://example1.com/nuget/", - "https://example2.com/nuget/v3/index.json" - ] - } + "packageRules": [ + { + "matchDatasources": ["nuget"], + "registryUrls": [ + "https://api.nuget.org/v3/index.json", + "https://example1.com/nuget/", + "https://example2.com/nuget/v3/index.json" + ] + } + ] } ``` @@ -93,9 +96,12 @@ If a `v3` feed URL does not end with `index.json`, you must specify the version ```json { - "nuget": { - "registryUrls": ["http://myV3feed#protocolVersion=3"] - } + "packageRules": [ + { + "matchDatasources": ["nuget"], + "registryUrls": ["https://example1.com/nuget/#protocolVersion=3"] + } + ] } ``` diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index ad6970f4492bc07..92c196249329749 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -344,6 +344,92 @@ For example, to override the default TTL of 60 minutes for the `docker` datasour } ``` +Valid codes for namespaces are as follows: + +- `changelog-bitbucket-notes@v2` +- `changelog-bitbucket-release` +- `changelog-gitea-notes@v2` +- `changelog-gitea-release` +- `changelog-github-notes@v2` +- `changelog-github-release` +- `changelog-gitlab-notes@v2` +- `changelog-gitlab-release` +- `datasource-artifactory` +- `datasource-aws-machine-image` +- `datasource-aws-rds` +- `datasource-azure-bicep-resource` +- `datasource-azure-pipelines-tasks` +- `datasource-bazel` +- `datasource-bitbucket-tags` +- `datasource-bitrise` +- `datasource-cdnjs` +- `datasource-conan` +- `datasource-conda` +- `datasource-cpan` +- `datasource-crate-metadata` +- `datasource-crate` +- `datasource-deb` +- `datasource-deno` +- `datasource-docker-architecture` +- `datasource-docker-hub-cache` +- `datasource-docker-digest` +- `datasource-docker-hub-tags` +- `datasource-docker-imageconfig` +- `datasource-docker-labels` +- `datasource-docker-releases-v2` +- `datasource-docker-tags` +- `datasource-dotnet-version` +- `datasource-endoflife-date` +- `datasource-galaxy-collection` +- `datasource-galaxy` +- `datasource-git-refs` +- `datasource-git-tags` +- `datasource-git` +- `datasource-gitea-releases` +- `datasource-gitea-tags` +- `datasource-github-release-attachments` +- `datasource-gitlab-packages` +- `datasource-gitlab-releases` +- `datasource-gitlab-tags` +- `datasource-glasskube-packages` +- `datasource-go-direct` +- `datasource-go-proxy` +- `datasource-go` +- `datasource-golang-version` +- `datasource-gradle-version` +- `datasource-helm` +- `datasource-hermit` +- `datasource-hex` +- `datasource-hexpm-bob` +- `datasource-java-version` +- `datasource-jenkins-plugins` +- `datasource-maven` +- `datasource-maven:head-requests-timeout` +- `datasource-maven:head-requests` +- `datasource-maven:metadata-xml` +- `datasource-node-version` +- `datasource-npm:data` +- `datasource-nuget-v3` +- `datasource-orb` +- `datasource-packagist` +- `datasource-pod` +- `datasource-python-version` +- `datasource-releases` +- `datasource-repology` +- `datasource-ruby-version` +- `datasource-rubygems` +- `datasource-sbt-package` +- `datasource-terraform-module` +- `datasource-terraform-provider` +- `datasource-terraform` +- `datasource-unity3d` +- `github-releases-datasource-v2` +- `github-tags-datasource-v2` +- `merge-confidence` +- `preset` +- `terraform-provider-hash` +- `url-sha256` + ## checkedBranches This array will allow you to set the names of the branches you want to rebase/create, as if you selected their checkboxes in the Dependency Dashboard issue. diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index ea5da7747594a5d..1468e9c99393e42 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -516,7 +516,7 @@ const options: RenovateOptions[] = [ description: 'Change this value to override the default Renovate sidecar image.', type: 'string', - default: 'ghcr.io/containerbase/sidecar:13.5.10', + default: 'ghcr.io/containerbase/sidecar:13.7.0', globalOnly: true, }, { diff --git a/lib/config/presets/internal/custom-managers.ts b/lib/config/presets/internal/custom-managers.ts index 5a3fc8b244d53c5..63ceefda7117a20 100644 --- a/lib/config/presets/internal/custom-managers.ts +++ b/lib/config/presets/internal/custom-managers.ts @@ -24,7 +24,7 @@ export const presets: Record = { customType: 'regex', fileMatch: ['(^|/)bitbucket-pipelines\\.ya?ml$'], matchStrings: [ - '# renovate: datasource=(?[a-z-.]+?) depName=(?[^\\s]+?)(?: (lookupName|packageName)=(?[^\\s]+?))?(?: versioning=(?[^\\s]+?))?(?: extractVersion=(?[^\\s]+?))?(?: registryUrl=(?[^\\s]+?))?\\s+.*\\s+[A-Za-z0-9_]+?_VERSION[ =:]\\s?["\']?(?.+?)["\']?\\s', + '# renovate: datasource=(?[a-zA-Z0-9-._]+?) depName=(?[^\\s]+?)(?: (lookupName|packageName)=(?[^\\s]+?))?(?: versioning=(?[^\\s]+?))?(?: extractVersion=(?[^\\s]+?))?(?: registryUrl=(?[^\\s]+?))?\\s+.*\\s+[A-Za-z0-9_]+?_VERSION[ =:]\\s?["\']?(?.+?)["\']?\\s', ], }, ], @@ -39,7 +39,7 @@ export const presets: Record = { '(^|/)([Dd]ocker|[Cc]ontainer)file[^/]*$', ], matchStrings: [ - '# renovate: datasource=(?[a-z-.]+?) depName=(?[^\\s]+?)(?: (lookupName|packageName)=(?[^\\s]+?))?(?: versioning=(?[^\\s]+?))?(?: extractVersion=(?[^\\s]+?))?(?: registryUrl=(?[^\\s]+?))?\\s(?:ENV|ARG)\\s+[A-Za-z0-9_]+?_VERSION[ =]["\']?(?.+?)["\']?\\s', + '# renovate: datasource=(?[a-zA-Z0-9-._]+?) depName=(?[^\\s]+?)(?: (lookupName|packageName)=(?[^\\s]+?))?(?: versioning=(?[^\\s]+?))?(?: extractVersion=(?[^\\s]+?))?(?: registryUrl=(?[^\\s]+?))?\\s(?:ENV|ARG)\\s+[A-Za-z0-9_]+?_VERSION[ =]["\']?(?.+?)["\']?\\s', ], }, ], @@ -54,7 +54,7 @@ export const presets: Record = { '(^|/)action\\.ya?ml$', ], matchStrings: [ - '# renovate: datasource=(?[a-z-.]+?) depName=(?[^\\s]+?)(?: (?:lookupName|packageName)=(?[^\\s]+?))?(?: versioning=(?[^\\s]+?))?(?: extractVersion=(?[^\\s]+?))?\\s+[A-Za-z0-9_]+?_VERSION\\s*:\\s*["\']?(?.+?)["\']?\\s', + '# renovate: datasource=(?[a-zA-Z0-9-._]+?) depName=(?[^\\s]+?)(?: (?:lookupName|packageName)=(?[^\\s]+?))?(?: versioning=(?[^\\s]+?))?(?: extractVersion=(?[^\\s]+?))?\\s+[A-Za-z0-9_]+?_VERSION\\s*:\\s*["\']?(?.+?)["\']?\\s', ], }, ], @@ -67,7 +67,7 @@ export const presets: Record = { customType: 'regex', fileMatch: ['\\.gitlab-ci\\.ya?ml$'], matchStrings: [ - '# renovate: datasource=(?[a-z-.]+?) depName=(?[^\\s]+?)(?: (?:packageName)=(?[^\\s]+?))?(?: versioning=(?[^\\s]+?))?(?: extractVersion=(?[^\\s]+?))?(?: registryUrl=(?[^\\s]+?))?\\s+[A-Za-z0-9_]+?_VERSION\\s*:\\s*["\']?(?.+?)["\']?\\s', + '# renovate: datasource=(?[a-zA-Z0-9-._]+?) depName=(?[^\\s]+?)(?: (?:packageName)=(?[^\\s]+?))?(?: versioning=(?[^\\s]+?))?(?: extractVersion=(?[^\\s]+?))?(?: registryUrl=(?[^\\s]+?))?\\s+[A-Za-z0-9_]+?_VERSION\\s*:\\s*["\']?(?.+?)["\']?\\s', ], }, ], @@ -98,7 +98,7 @@ export const presets: Record = { '\\.mk$', ], matchStrings: [ - '# renovate: datasource=(?[a-z-.]+?) depName=(?[^\\s]+?)(?: (?:packageName)=(?[^\\s]+?))?(?: versioning=(?[^\\s]+?))?(?: extractVersion=(?[^\\s]+?))?(?: registryUrl=(?[^\\s]+?))?\\s+[A-Za-z0-9_]+?_VERSION\\s*:*\\??=\\s*["\']?(?.+?)["\']?\\s', + '# renovate: datasource=(?[a-zA-Z0-9-._]+?) depName=(?[^\\s]+?)(?: (?:packageName)=(?[^\\s]+?))?(?: versioning=(?[^\\s]+?))?(?: extractVersion=(?[^\\s]+?))?(?: registryUrl=(?[^\\s]+?))?\\s+[A-Za-z0-9_]+?_VERSION\\s*:*\\??=\\s*["\']?(?.+?)["\']?\\s', ], }, ], @@ -112,7 +112,7 @@ export const presets: Record = { '{{#if datasource}}{{{datasource}}}{{else}}maven{{/if}}', fileMatch: ['(^|/)pom\\.xml$'], matchStrings: [ - '\\s+<.+\\.version>(?.+)<\\/.+\\.version>', + '\\s+<.+\\.version>(?.+)<\\/.+\\.version>', ], versioningTemplate: '{{#if versioning}}{{{versioning}}}{{/if}}', }, diff --git a/lib/config/types.ts b/lib/config/types.ts index 7bf0bcaf0237f26..583069f0ec5c021 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -6,6 +6,7 @@ import type { HostRule, SkipReason } from '../types'; import type { StageName } from '../types/skip-reason'; import type { GitNoVerifyOption } from '../util/git/types'; import type { MergeConfidence } from '../util/merge-confidence/types'; +import type { Timestamp } from '../util/timestamp'; export type RenovateConfigStage = | 'global' @@ -271,6 +272,7 @@ export interface RenovateConfig packageFile?: string; packageRules?: PackageRule[]; postUpdateOptions?: string[]; + branchConcurrentLimit?: number | null; prConcurrentLimit?: number; prHourlyLimit?: number; forkModeDisallowMaintainerEdits?: boolean; @@ -551,7 +553,7 @@ export interface PackageRuleInputConfig extends Record { manager?: string; datasource?: string; packageRules?: (PackageRule & PackageRuleInputConfig)[]; - releaseTimestamp?: string | null; + releaseTimestamp?: Timestamp | null; repository?: string; currentVersionAgeInDays?: number; currentVersionTimestamp?: string; diff --git a/lib/data/monorepo.json b/lib/data/monorepo.json index 1d0437dbc8db72a..2a85ecfd6c59d31 100644 --- a/lib/data/monorepo.json +++ b/lib/data/monorepo.json @@ -26,6 +26,7 @@ "arcus.observability": "https://github.com/arcus-azure/arcus.observability", "arcus.security": "https://github.com/arcus-azure/arcus.security", "arcus.webapi": "https://github.com/arcus-azure/arcus.webapi", + "arrow-kt": "https://github.com/arrow-kt/arrow", "aspire": "https://github.com/dotnet/aspire", "aspnet aspnetwebstack": "https://github.com/aspnet/AspNetWebStack", "aspnet extensions": "https://github.com/aspnet/Extensions", @@ -325,6 +326,7 @@ "happy-dom": "https://github.com/capricorn86/happy-dom", "Hangfire": "https://github.com/HangfireIO/Hangfire", "hickory-dns": "https://github.com/hickory-dns/hickory-dns", + "html-eslint": "https://github.com/yeonjuan/html-eslint", "infrastructure-ui": "https://github.com/instructure/instructure-ui", "ionic-native": "https://github.com/ionic-team/ionic-native", "istanbuljs": "https://github.com/istanbuljs/istanbuljs", @@ -392,6 +394,7 @@ "mstest": "https://github.com/microsoft/testfx", "mutation-testing-elements": "https://github.com/stryker-mutator/mutation-testing-elements", "nest": [ + "https://github.com/nestjs/config", "https://github.com/nestjs/nest", "https://github.com/nestjs/nest-cli", "https://github.com/nestjs/passport", @@ -459,6 +462,7 @@ "prisma": "https://github.com/prisma/prisma", "prometheus-net": "https://github.com/prometheus-net/prometheus-net", "promster": "https://github.com/tdeekens/promster", + "protobuf": "https://github.com/protocolbuffers/protobuf", "quartznet": "https://github.com/quartznet/quartznet", "radix-ui-primitives": "https://github.com/radix-ui/primitives", "reach-ui": "https://github.com/reach/reach-ui", diff --git a/lib/modules/datasource/aws-machine-image/index.ts b/lib/modules/datasource/aws-machine-image/index.ts index f069ef5a52777eb..1c3dce2d9851078 100644 --- a/lib/modules/datasource/aws-machine-image/index.ts +++ b/lib/modules/datasource/aws-machine-image/index.ts @@ -2,6 +2,7 @@ import type { Filter, Image } from '@aws-sdk/client-ec2'; import { DescribeImagesCommand, EC2Client } from '@aws-sdk/client-ec2'; import { fromNodeProviderChain } from '@aws-sdk/credential-providers'; import { cache } from '../../../util/cache/package/decorator'; +import { asTimestamp } from '../../../util/timestamp'; import * as amazonMachineImageVersioning from '../../versioning/aws-machine-image'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, ReleaseResult } from '../types'; @@ -147,7 +148,7 @@ export class AwsMachineImageDatasource extends Datasource { releases: [ { version: latestImage.ImageId, - releaseTimestamp: latestImage.CreationDate, + releaseTimestamp: asTimestamp(latestImage.CreationDate), isDeprecated: Date.parse(latestImage.DeprecationTime ?? this.now.toString()) < this.now, diff --git a/lib/modules/datasource/bitbucket-tags/index.ts b/lib/modules/datasource/bitbucket-tags/index.ts index 1ca5ddf16895131..66c39743d1727b7 100644 --- a/lib/modules/datasource/bitbucket-tags/index.ts +++ b/lib/modules/datasource/bitbucket-tags/index.ts @@ -1,6 +1,7 @@ import { cache } from '../../../util/cache/package/decorator'; import type { PackageCacheNamespace } from '../../../util/cache/package/types'; import { BitbucketHttp } from '../../../util/http/bitbucket'; +import { asTimestamp } from '../../../util/timestamp'; import { ensureTrailingSlash } from '../../../util/url'; import { RepoInfo } from '../../platform/bitbucket/schema'; import type { PagedResult } from '../../platform/bitbucket/types'; @@ -79,7 +80,7 @@ export class BitbucketTagsDatasource extends Datasource { releases: bitbucketTags.map(({ name, target }) => ({ version: name, gitRef: name, - releaseTimestamp: target?.date, + releaseTimestamp: asTimestamp(target?.date), })), }; diff --git a/lib/modules/datasource/bitrise/schema.ts b/lib/modules/datasource/bitrise/schema.ts index 064151a45de2cd8..ac29bec00e694b3 100644 --- a/lib/modules/datasource/bitrise/schema.ts +++ b/lib/modules/datasource/bitrise/schema.ts @@ -1,9 +1,10 @@ import { z } from 'zod'; import { Yaml } from '../../../util/schema-utils'; +import { MaybeTimestamp } from '../../../util/timestamp'; export const BitriseStepFile = Yaml.pipe( z.object({ - published_at: z.string(), + published_at: MaybeTimestamp, source_code_url: z.string().optional(), }), ); diff --git a/lib/modules/datasource/cpan/schema.ts b/lib/modules/datasource/cpan/schema.ts index 8e997143ba3849c..e44ce810626f508 100644 --- a/lib/modules/datasource/cpan/schema.ts +++ b/lib/modules/datasource/cpan/schema.ts @@ -1,5 +1,6 @@ import { z } from 'zod'; import { LooseArray } from '../../../util/schema-utils'; +import { MaybeTimestamp } from '../../../util/timestamp'; import type { CpanRelease } from './types'; /** @@ -14,7 +15,7 @@ const MetaCpanApiFileSchema = z }), ), distribution: z.string(), - date: z.string(), + date: MaybeTimestamp, deprecated: z.boolean(), maturity: z.string(), status: z.union([ diff --git a/lib/modules/datasource/crate/index.spec.ts b/lib/modules/datasource/crate/index.spec.ts index 765bba4d61ecdb1..f5138c14b37169a 100644 --- a/lib/modules/datasource/crate/index.spec.ts +++ b/lib/modules/datasource/crate/index.spec.ts @@ -427,7 +427,7 @@ describe('modules/datasource/crate/index', () => { expect(res).toEqual({ version: '4.5.17', - releaseTimestamp: '2024-09-04T19:16:41.355243+00:00', + releaseTimestamp: '2024-09-04T19:16:41.355Z', }); }); }); diff --git a/lib/modules/datasource/crate/schema.ts b/lib/modules/datasource/crate/schema.ts index 9d799be31b42cc4..af908f22a932624 100644 --- a/lib/modules/datasource/crate/schema.ts +++ b/lib/modules/datasource/crate/schema.ts @@ -1,9 +1,10 @@ import { z } from 'zod'; +import { MaybeTimestamp } from '../../../util/timestamp'; export const ReleaseTimestampSchema = z .object({ version: z.object({ - created_at: z.string(), + created_at: MaybeTimestamp, }), }) .transform(({ version: { created_at } }) => created_at) diff --git a/lib/modules/datasource/custom/schema.ts b/lib/modules/datasource/custom/schema.ts index 50c19b7ed948b15..c45628064f4a94d 100644 --- a/lib/modules/datasource/custom/schema.ts +++ b/lib/modules/datasource/custom/schema.ts @@ -1,4 +1,5 @@ import { z } from 'zod'; +import { MaybeTimestamp } from '../../../util/timestamp'; export const ReleaseResultZodSchema = z.object({ releases: z.array( @@ -6,7 +7,7 @@ export const ReleaseResultZodSchema = z.object({ .object({ version: z.string(), isDeprecated: z.boolean().optional(), - releaseTimestamp: z.string().optional(), + releaseTimestamp: MaybeTimestamp, sourceUrl: z.string().optional(), sourceDirectory: z.string().optional(), changelogUrl: z.string().optional(), diff --git a/lib/modules/datasource/dart/index.ts b/lib/modules/datasource/dart/index.ts index 80ea1cf8e3a2b44..5cae12d29a50df6 100644 --- a/lib/modules/datasource/dart/index.ts +++ b/lib/modules/datasource/dart/index.ts @@ -1,4 +1,5 @@ import type { HttpResponse } from '../../../util/http/types'; +import { asTimestamp } from '../../../util/timestamp'; import { ensureTrailingSlash } from '../../../util/url'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, ReleaseResult } from '../types'; @@ -49,7 +50,7 @@ export class DartDatasource extends Datasource { ?.filter(({ retracted }) => !retracted) ?.map(({ version, published }) => ({ version, - releaseTimestamp: published, + releaseTimestamp: asTimestamp(published), })); if (releases && latest) { result = { releases }; diff --git a/lib/modules/datasource/deno/schema.ts b/lib/modules/datasource/deno/schema.ts index 2587874425d9d8f..a72b7d29669d712 100644 --- a/lib/modules/datasource/deno/schema.ts +++ b/lib/modules/datasource/deno/schema.ts @@ -1,6 +1,7 @@ import { z } from 'zod'; import { getSourceUrl as getGithubSourceUrl } from '../../../util/github/url'; import { LooseArray } from '../../../util/schema-utils'; +import { MaybeTimestamp } from '../../../util/timestamp'; import type { Release } from '../types'; export const DenoApiTag = z.object({ @@ -31,7 +32,7 @@ export const DenoAPIUploadOptions = z.object({ export const DenoAPIModuleVersionResponse = z .object({ upload_options: DenoAPIUploadOptions, - uploaded_at: z.string(), + uploaded_at: MaybeTimestamp, version: z.string(), }) .transform( @@ -41,6 +42,11 @@ export const DenoAPIModuleVersionResponse = z if (type === 'github') { sourceUrl = getGithubSourceUrl(repository); } - return { version, gitRef, releaseTimestamp, sourceUrl }; + return { + version, + gitRef, + releaseTimestamp, + sourceUrl, + }; }, ); diff --git a/lib/modules/datasource/devbox/schema.ts b/lib/modules/datasource/devbox/schema.ts index bc31efae879850c..d4c3fac44b6208b 100644 --- a/lib/modules/datasource/devbox/schema.ts +++ b/lib/modules/datasource/devbox/schema.ts @@ -1,8 +1,9 @@ import { z } from 'zod'; +import { MaybeTimestamp } from '../../../util/timestamp'; export const DevboxRelease = z.object({ version: z.string(), - last_updated: z.string(), + last_updated: MaybeTimestamp, }); export const DevboxResponse = z diff --git a/lib/modules/datasource/docker/index.ts b/lib/modules/datasource/docker/index.ts index dec17989b8ff5b4..87c59c23441777e 100644 --- a/lib/modules/datasource/docker/index.ts +++ b/lib/modules/datasource/docker/index.ts @@ -10,6 +10,7 @@ import { hasKey } from '../../../util/object'; import { regEx } from '../../../util/regex'; import { type AsyncResult, Result } from '../../../util/result'; import { isDockerDigest } from '../../../util/string-match'; +import { asTimestamp } from '../../../util/timestamp'; import { ensurePathPrefix, joinUrlParts, @@ -1001,13 +1002,10 @@ export class DockerDatasource extends Datasource { const items = cache.getItems(); return items.map( - ({ - name: version, - tag_last_pushed: releaseTimestamp, - digest: newDigest, - }) => { + ({ name: version, tag_last_pushed, digest: newDigest }) => { const release: Release = { version }; + const releaseTimestamp = asTimestamp(tag_last_pushed); if (releaseTimestamp) { release.releaseTimestamp = releaseTimestamp; } diff --git a/lib/modules/datasource/dotnet-version/schema.ts b/lib/modules/datasource/dotnet-version/schema.ts index ce940ac245319a7..8660a322b5f0679 100644 --- a/lib/modules/datasource/dotnet-version/schema.ts +++ b/lib/modules/datasource/dotnet-version/schema.ts @@ -1,5 +1,6 @@ import { z } from 'zod'; import { LooseArray } from '../../../util/schema-utils'; +import { MaybeTimestamp } from '../../../util/timestamp'; import type { Release } from '../types'; export const ReleasesIndex = z @@ -15,7 +16,7 @@ export const ReleasesIndex = z .transform(({ 'releases-index': releasesIndex }) => releasesIndex); const ReleaseBase = z.object({ - 'release-date': z.string(), + 'release-date': MaybeTimestamp, 'release-notes': z.string(), }); const ReleaseDetails = z.object({ diff --git a/lib/modules/datasource/endoflife-date/schema.ts b/lib/modules/datasource/endoflife-date/schema.ts index 4f184a86fc9d724..aa4e83cd0040358 100644 --- a/lib/modules/datasource/endoflife-date/schema.ts +++ b/lib/modules/datasource/endoflife-date/schema.ts @@ -1,6 +1,7 @@ import { DateTime } from 'luxon'; import { z } from 'zod'; import { UtcDate } from '../../../util/schema-utils'; +import { MaybeTimestamp } from '../../../util/timestamp'; import type { Release } from '../types'; const ExpireableField = z.union([ @@ -15,7 +16,7 @@ export const EndoflifeDateVersions = z .object({ cycle: z.string(), latest: z.optional(z.string()), - releaseDate: z.optional(z.string()), + releaseDate: MaybeTimestamp, eol: z.optional(ExpireableField), discontinued: z.optional(ExpireableField), }) diff --git a/lib/modules/datasource/flutter-version/index.ts b/lib/modules/datasource/flutter-version/index.ts index 5069f9779ecc853..8fd364877c8d22f 100644 --- a/lib/modules/datasource/flutter-version/index.ts +++ b/lib/modules/datasource/flutter-version/index.ts @@ -1,4 +1,5 @@ import { regEx } from '../../../util/regex'; +import { asTimestamp } from '../../../util/timestamp'; import { id as semverId } from '../../versioning/semver'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, ReleaseResult } from '../types'; @@ -58,7 +59,7 @@ export class FlutterVersionDatasource extends Datasource { }) .map(({ version, release_date, channel }) => ({ version, - releaseTimestamp: release_date, + releaseTimestamp: asTimestamp(release_date), isStable: channel === 'stable', })); return result.releases.length ? result : null; diff --git a/lib/modules/datasource/galaxy-collection/schema.ts b/lib/modules/datasource/galaxy-collection/schema.ts index 06be4898c52e998..0842fc9ccbec597 100644 --- a/lib/modules/datasource/galaxy-collection/schema.ts +++ b/lib/modules/datasource/galaxy-collection/schema.ts @@ -1,4 +1,5 @@ import { z } from 'zod'; +import { MaybeTimestamp } from '../../../util/timestamp'; export type GalaxyV3 = z.infer; export const GalaxyV3 = z.object({ @@ -14,7 +15,7 @@ export const GalaxyV3Versions = z data: z.array( z.object({ version: z.string(), - created_at: z.string().datetime(), + created_at: MaybeTimestamp, }), ), }) diff --git a/lib/modules/datasource/galaxy/index.ts b/lib/modules/datasource/galaxy/index.ts index cae51402213a80f..075653dddf5bebc 100644 --- a/lib/modules/datasource/galaxy/index.ts +++ b/lib/modules/datasource/galaxy/index.ts @@ -82,18 +82,13 @@ export class GalaxyDatasource extends Datasource { result.sourceUrl = `https://github.com/${user}/${repo}`; } - result.releases = versions.map( - (version: { name: string; created?: string }) => { - const release: Release = { - version: version.name, - }; - - if (is.nonEmptyString(version.created)) { - release.releaseTimestamp = version.created; - } - return release; - }, - ); + result.releases = versions.map(({ version, releaseTimestamp }) => { + const release: Release = { version }; + if (releaseTimestamp) { + release.releaseTimestamp = releaseTimestamp; + } + return release; + }); return result; } diff --git a/lib/modules/datasource/galaxy/schema.ts b/lib/modules/datasource/galaxy/schema.ts index 7fb519004908e35..2366ffa67b1c95e 100644 --- a/lib/modules/datasource/galaxy/schema.ts +++ b/lib/modules/datasource/galaxy/schema.ts @@ -1,4 +1,5 @@ import { z } from 'zod'; +import { MaybeTimestamp } from '../../../util/timestamp'; export type GalaxyV1 = z.infer; export const GalaxyV1 = z.object({ @@ -6,10 +7,15 @@ export const GalaxyV1 = z.object({ z.object({ summary_fields: z.object({ versions: z.array( - z.object({ - name: z.string(), - created: z.string().optional(), - }), + z + .object({ + name: z.string(), + created: MaybeTimestamp, + }) + .transform(({ name, created }) => ({ + version: name, + releaseTimestamp: created, + })), ), }), github_user: z.string().optional(), diff --git a/lib/modules/datasource/gitea-releases/schema.ts b/lib/modules/datasource/gitea-releases/schema.ts index fe57281c672d579..b1482c99701e636 100644 --- a/lib/modules/datasource/gitea-releases/schema.ts +++ b/lib/modules/datasource/gitea-releases/schema.ts @@ -1,11 +1,12 @@ import { z } from 'zod'; +import { MaybeTimestamp } from '../../../util/timestamp'; export const ReleaseSchema = z.object({ name: z.string(), tag_name: z.string(), body: z.string(), prerelease: z.boolean(), - published_at: z.string().datetime({ offset: true }), + published_at: MaybeTimestamp, }); export const ReleasesSchema = z.array(ReleaseSchema); diff --git a/lib/modules/datasource/gitea-tags/schema.ts b/lib/modules/datasource/gitea-tags/schema.ts index 603730de8f1dbfa..3ba004a0bb1062a 100644 --- a/lib/modules/datasource/gitea-tags/schema.ts +++ b/lib/modules/datasource/gitea-tags/schema.ts @@ -1,4 +1,5 @@ import { z } from 'zod'; +import { MaybeTimestamp } from '../../../util/timestamp'; export const CommitSchema = z.object({ sha: z.string(), @@ -8,7 +9,7 @@ export const CommitsSchema = z.array(CommitSchema); const TagCommitSchema = z.object({ sha: z.string(), - created: z.string().datetime({ offset: true }), + created: MaybeTimestamp, }); export const TagSchema = z.object({ diff --git a/lib/modules/datasource/github-release-attachments/index.spec.ts b/lib/modules/datasource/github-release-attachments/index.spec.ts index f1c17ad42c91026..02872612d4d86df 100644 --- a/lib/modules/datasource/github-release-attachments/index.spec.ts +++ b/lib/modules/datasource/github-release-attachments/index.spec.ts @@ -3,6 +3,7 @@ import { getDigest, getPkgReleases } from '..'; import { mocked } from '../../../../test/util'; import * as githubGraphql from '../../../util/github/graphql'; import * as _hostRules from '../../../util/host-rules'; +import type { Timestamp } from '../../../util/timestamp'; import { GitHubReleaseAttachmentMocker } from './test'; import { GithubReleaseAttachmentsDatasource } from '.'; @@ -28,7 +29,7 @@ describe('modules/datasource/github-release-attachments/index', () => { name: 'some/dep2', description: 'some description', version: 'a', - releaseTimestamp: '2020-03-09T13:00:00Z', + releaseTimestamp: '2020-03-09T13:00:00Z' as Timestamp, }, { id: 2, @@ -36,7 +37,7 @@ describe('modules/datasource/github-release-attachments/index', () => { name: 'some/dep2', description: 'some description', version: 'v', - releaseTimestamp: '2020-03-09T12:00:00Z', + releaseTimestamp: '2020-03-09T12:00:00Z' as Timestamp, }, { id: 3, @@ -44,7 +45,7 @@ describe('modules/datasource/github-release-attachments/index', () => { name: 'some/dep2', description: 'some description', version: '1.0.0', - releaseTimestamp: '2020-03-09T11:00:00Z', + releaseTimestamp: '2020-03-09T11:00:00Z' as Timestamp, }, { id: 4, @@ -52,7 +53,7 @@ describe('modules/datasource/github-release-attachments/index', () => { name: 'some/dep2', description: 'some description', version: 'v1.1.0', - releaseTimestamp: '2020-03-09T10:00:00Z', + releaseTimestamp: '2020-03-09T10:00:00Z' as Timestamp, }, { id: 5, @@ -60,7 +61,7 @@ describe('modules/datasource/github-release-attachments/index', () => { name: 'some/dep2', description: 'some description', version: '2.0.0', - releaseTimestamp: '2020-04-09T10:00:00Z', + releaseTimestamp: '2020-04-09T10:00:00Z' as Timestamp, isStable: false, }, ]); diff --git a/lib/modules/datasource/github-releases/index.spec.ts b/lib/modules/datasource/github-releases/index.spec.ts index e6f93f07803bcdc..fbd1f962a94958b 100644 --- a/lib/modules/datasource/github-releases/index.spec.ts +++ b/lib/modules/datasource/github-releases/index.spec.ts @@ -3,6 +3,7 @@ import { getDigest, getPkgReleases } from '..'; import { mocked } from '../../../../test/util'; import * as githubGraphql from '../../../util/github/graphql'; import * as _hostRules from '../../../util/host-rules'; +import type { Timestamp } from '../../../util/timestamp'; import { GithubReleasesDatasource } from '.'; jest.mock('../../../util/host-rules', () => mockDeep()); @@ -25,7 +26,7 @@ describe('modules/datasource/github-releases/index', () => { name: 'some/dep2', description: 'some description', version: 'a', - releaseTimestamp: '2020-03-09T13:00:00Z', + releaseTimestamp: '2020-03-09T13:00:00Z' as Timestamp, }, { id: 2, @@ -33,7 +34,7 @@ describe('modules/datasource/github-releases/index', () => { name: 'some/dep2', description: 'some description', version: 'v', - releaseTimestamp: '2020-03-09T12:00:00Z', + releaseTimestamp: '2020-03-09T12:00:00Z' as Timestamp, }, { id: 3, @@ -41,7 +42,7 @@ describe('modules/datasource/github-releases/index', () => { name: 'some/dep2', description: 'some description', version: '1.0.0', - releaseTimestamp: '2020-03-09T11:00:00Z', + releaseTimestamp: '2020-03-09T11:00:00Z' as Timestamp, }, { id: 4, @@ -49,7 +50,7 @@ describe('modules/datasource/github-releases/index', () => { name: 'some/dep2', description: 'some description', version: 'v1.1.0', - releaseTimestamp: '2020-03-09T10:00:00Z', + releaseTimestamp: '2020-03-09T10:00:00Z' as Timestamp, }, { id: 5, @@ -57,7 +58,7 @@ describe('modules/datasource/github-releases/index', () => { name: 'some/dep2', description: 'some description', version: '2.0.0', - releaseTimestamp: '2020-04-09T10:00:00Z', + releaseTimestamp: '2020-04-09T10:00:00Z' as Timestamp, isStable: false, }, ]); @@ -70,11 +71,17 @@ describe('modules/datasource/github-releases/index', () => { expect(res).toMatchObject({ registryUrl: 'https://github.com', releases: [ - { releaseTimestamp: '2020-03-09T11:00:00.000Z', version: '1.0.0' }, - { version: 'v1.1.0', releaseTimestamp: '2020-03-09T10:00:00.000Z' }, + { + releaseTimestamp: '2020-03-09T11:00:00.000Z' as Timestamp, + version: '1.0.0', + }, + { + version: 'v1.1.0', + releaseTimestamp: '2020-03-09T10:00:00.000Z' as Timestamp, + }, { version: '2.0.0', - releaseTimestamp: '2020-04-09T10:00:00.000Z', + releaseTimestamp: '2020-04-09T10:00:00.000Z' as Timestamp, isStable: false, }, ], @@ -95,13 +102,13 @@ describe('modules/datasource/github-releases/index', () => { { version: 'v1.0.0', gitRef: 'v1.0.0', - releaseTimestamp: '2021-01-01', + releaseTimestamp: '2021-01-01' as Timestamp, hash: 'sha-of-v1', }, { version: 'v15.0.0', gitRef: 'v15.0.0', - releaseTimestamp: '2022-10-01', + releaseTimestamp: '2022-10-01' as Timestamp, hash: 'sha-of-v15', }, ]); diff --git a/lib/modules/datasource/github-tags/index.spec.ts b/lib/modules/datasource/github-tags/index.spec.ts index 8bde1f8d3fec43f..02b2d0b9dcda442 100644 --- a/lib/modules/datasource/github-tags/index.spec.ts +++ b/lib/modules/datasource/github-tags/index.spec.ts @@ -4,6 +4,7 @@ import { partial } from '../../../../test/util'; import * as githubGraphql from '../../../util/github/graphql'; import type { GithubTagItem } from '../../../util/github/graphql/types'; import * as hostRules from '../../../util/host-rules'; +import type { Timestamp } from '../../../util/timestamp'; import { GithubTagsDatasource } from '.'; const githubApiHost = 'https://api.github.com'; @@ -55,13 +56,13 @@ describe('modules/datasource/github-tags/index', () => { { version: 'v1.0.0', gitRef: 'v1.0.0', - releaseTimestamp: '2021-01-01', + releaseTimestamp: '2021-01-01' as Timestamp, hash: '123', }, { version: 'v2.0.0', gitRef: 'v2.0.0', - releaseTimestamp: '2022-01-01', + releaseTimestamp: '2022-01-01' as Timestamp, hash: 'abc', }, ]); @@ -74,13 +75,13 @@ describe('modules/datasource/github-tags/index', () => { { version: 'v1.0.0', gitRef: 'v1.0.0', - releaseTimestamp: '2021-01-01', + releaseTimestamp: '2021-01-01' as Timestamp, hash: '123', }, partial({ version: 'v2.0.0', gitRef: 'v2.0.0', - releaseTimestamp: '2022-01-01', + releaseTimestamp: '2022-01-01' as Timestamp, }), ]); const res = await github.getDigest({ packageName }, 'v2.0.0'); @@ -92,13 +93,13 @@ describe('modules/datasource/github-tags/index', () => { { version: 'v1.0.0', gitRef: 'v1.0.0', - releaseTimestamp: '2021-01-01', + releaseTimestamp: '2021-01-01' as Timestamp, hash: '123', }, { version: 'v2.0.0', gitRef: 'v2.0.0', - releaseTimestamp: '2022-01-01', + releaseTimestamp: '2022-01-01' as Timestamp, hash: 'abc', }, ]); @@ -121,13 +122,13 @@ describe('modules/datasource/github-tags/index', () => { { version: 'v1.0.0', gitRef: 'v1.0.0', - releaseTimestamp: '2021-01-01', + releaseTimestamp: '2021-01-01' as Timestamp, hash: '123', }, { version: 'v2.0.0', gitRef: 'v2.0.0', - releaseTimestamp: '2022-01-01', + releaseTimestamp: '2022-01-01' as Timestamp, hash: 'abc', }, ]); @@ -135,7 +136,7 @@ describe('modules/datasource/github-tags/index', () => { { id: 1, version: 'v1.0.0', - releaseTimestamp: '2021-01-01', + releaseTimestamp: '2021-01-01' as Timestamp, isStable: true, url: 'https://example.com', name: 'some/dep2', @@ -144,7 +145,7 @@ describe('modules/datasource/github-tags/index', () => { { id: 2, version: 'v2.0.0', - releaseTimestamp: '2022-01-01', + releaseTimestamp: '2022-01-01' as Timestamp, isStable: false, url: 'https://example.com', name: 'some/dep2', diff --git a/lib/modules/datasource/gitlab-packages/index.ts b/lib/modules/datasource/gitlab-packages/index.ts index 651fb6d0141f167..fa2bfa27fdcee1c 100644 --- a/lib/modules/datasource/gitlab-packages/index.ts +++ b/lib/modules/datasource/gitlab-packages/index.ts @@ -1,5 +1,6 @@ import { cache } from '../../../util/cache/package/decorator'; import { GitlabHttp } from '../../../util/http/gitlab'; +import { asTimestamp } from '../../../util/timestamp'; import { joinUrlParts } from '../../../util/url'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, ReleaseResult } from '../types'; @@ -85,7 +86,7 @@ export class GitlabPackagesDatasource extends Datasource { .filter((r) => r.name === packagePart) .map(({ version, created_at }) => ({ version, - releaseTimestamp: created_at, + releaseTimestamp: asTimestamp(created_at), })); } catch (err) { this.handleGenericErrors(err); diff --git a/lib/modules/datasource/gitlab-releases/index.ts b/lib/modules/datasource/gitlab-releases/index.ts index f82a5eb68bb50f7..547cd5e5b7b599d 100644 --- a/lib/modules/datasource/gitlab-releases/index.ts +++ b/lib/modules/datasource/gitlab-releases/index.ts @@ -1,5 +1,6 @@ import { cache } from '../../../util/cache/package/decorator'; import { GitlabHttp } from '../../../util/http/gitlab'; +import { asTimestamp } from '../../../util/timestamp'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, Release, ReleaseResult } from '../types'; import type { GitlabRelease } from './types'; @@ -53,7 +54,7 @@ export class GitlabReleasesDatasource extends Datasource { registryUrl, gitRef: tag_name, version: tag_name, - releaseTimestamp: released_at, + releaseTimestamp: asTimestamp(released_at), }; return release; }), diff --git a/lib/modules/datasource/gitlab-tags/index.ts b/lib/modules/datasource/gitlab-tags/index.ts index 77690fcce599420..a4a23fadec508b0 100644 --- a/lib/modules/datasource/gitlab-tags/index.ts +++ b/lib/modules/datasource/gitlab-tags/index.ts @@ -1,6 +1,7 @@ import { logger } from '../../../logger'; import { cache } from '../../../util/cache/package/decorator'; import { GitlabHttp } from '../../../util/http/gitlab'; +import { asTimestamp } from '../../../util/timestamp'; import { joinUrlParts } from '../../../util/url'; import { Datasource } from '../datasource'; import type { DigestConfig, GetReleasesConfig, ReleaseResult } from '../types'; @@ -60,7 +61,7 @@ export class GitlabTagsDatasource extends Datasource { dependency.releases = gitlabTags.map(({ name, commit }) => ({ version: name, gitRef: name, - releaseTimestamp: commit?.created_at, + releaseTimestamp: asTimestamp(commit?.created_at), })); return dependency; diff --git a/lib/modules/datasource/go/__snapshots__/releases-direct.spec.ts.snap b/lib/modules/datasource/go/__snapshots__/releases-direct.spec.ts.snap index 4e65ba27707cd45..d70e507a08ad467 100644 --- a/lib/modules/datasource/go/__snapshots__/releases-direct.spec.ts.snap +++ b/lib/modules/datasource/go/__snapshots__/releases-direct.spec.ts.snap @@ -6,12 +6,12 @@ exports[`modules/datasource/go/releases-direct getReleases support bitbucket tag "releases": [ { "gitRef": "v1.0.0", - "releaseTimestamp": undefined, + "releaseTimestamp": null, "version": "v1.0.0", }, { "gitRef": "v2.0.0", - "releaseTimestamp": undefined, + "releaseTimestamp": null, "version": "v2.0.0", }, ], @@ -40,12 +40,12 @@ exports[`modules/datasource/go/releases-direct getReleases support gitlab 1`] = "releases": [ { "gitRef": "v1.0.0", - "releaseTimestamp": undefined, + "releaseTimestamp": null, "version": "v1.0.0", }, { "gitRef": "v2.0.0", - "releaseTimestamp": undefined, + "releaseTimestamp": null, "version": "v2.0.0", }, ], @@ -58,12 +58,12 @@ exports[`modules/datasource/go/releases-direct getReleases support gitlab subgro "releases": [ { "gitRef": "v1.0.0", - "releaseTimestamp": undefined, + "releaseTimestamp": null, "version": "v1.0.0", }, { "gitRef": "v2.0.0", - "releaseTimestamp": undefined, + "releaseTimestamp": null, "version": "v2.0.0", }, ], @@ -76,12 +76,12 @@ exports[`modules/datasource/go/releases-direct getReleases support self hosted g "releases": [ { "gitRef": "v1.0.0", - "releaseTimestamp": undefined, + "releaseTimestamp": null, "version": "v1.0.0", }, { "gitRef": "v2.0.0", - "releaseTimestamp": undefined, + "releaseTimestamp": null, "version": "v2.0.0", }, ], diff --git a/lib/modules/datasource/go/releases-direct.spec.ts b/lib/modules/datasource/go/releases-direct.spec.ts index 19da04761d3c4a3..c63003fa541a2bc 100644 --- a/lib/modules/datasource/go/releases-direct.spec.ts +++ b/lib/modules/datasource/go/releases-direct.spec.ts @@ -129,19 +129,19 @@ describe('modules/datasource/go/releases-direct', () => { { gitRef: 'v0.1.0', newDigest: 'd73d815ec22c421e7192a414594ac798c73c89e5', - releaseTimestamp: '2022-05-15T16:29:42Z', + releaseTimestamp: '2022-05-15T16:29:42.000Z', version: 'v0.1.0', }, { gitRef: 'v0.2.0', newDigest: '3976707232cb68751ff2ddf42547ff95c6878a97', - releaseTimestamp: '2022-05-15T17:23:28Z', + releaseTimestamp: '2022-05-15T17:23:28.000Z', version: 'v0.2.0', }, { gitRef: 'v0.2.1', newDigest: '2963b104773ead7ed28c00181c03318885d909dc', - releaseTimestamp: '2024-09-06T23:44:34Z', + releaseTimestamp: '2024-09-06T23:44:34.000Z', version: 'v0.2.1', }, ], diff --git a/lib/modules/datasource/go/releases-goproxy.spec.ts b/lib/modules/datasource/go/releases-goproxy.spec.ts index 2d6950d057f79e3..70c5287f7b6f60b 100644 --- a/lib/modules/datasource/go/releases-goproxy.spec.ts +++ b/lib/modules/datasource/go/releases-goproxy.spec.ts @@ -64,7 +64,7 @@ describe('modules/datasource/go/releases-goproxy', () => { expect(release).toEqual({ version: 'v0.5.0', - releaseTimestamp: '2017-06-08T17:28:36Z', + releaseTimestamp: '2017-06-08T17:28:36.000Z', }); }); }); @@ -155,15 +155,15 @@ describe('modules/datasource/go/releases-goproxy', () => { releases: [ { version: 'v1.0.0', - releaseTimestamp: '2018-08-13T15:31:12Z', + releaseTimestamp: '2018-08-13T15:31:12.000Z', }, { version: 'v1.0.1', - releaseTimestamp: '2019-10-16T16:15:28Z', + releaseTimestamp: '2019-10-16T16:15:28.000Z', }, { version: 'v1.28.1-20230721020619-4464c06fa399.4', - releaseTimestamp: '2023-07-21T02:06:19Z', + releaseTimestamp: '2023-07-21T02:06:19.000Z', newDigest: '4464c06fa399', }, ], @@ -245,8 +245,8 @@ describe('modules/datasource/go/releases-goproxy', () => { expect(res).toEqual({ releases: [ - { releaseTimestamp: '2018-08-13T15:31:12Z', version: 'v1.0.0' }, - { releaseTimestamp: '2019-10-16T16:15:28Z', version: 'v1.0.1' }, + { releaseTimestamp: '2018-08-13T15:31:12.000Z', version: 'v1.0.0' }, + { releaseTimestamp: '2019-10-16T16:15:28.000Z', version: 'v1.0.1' }, ], sourceUrl: 'https://github.com/google/btree', tags: { latest: 'v1.0.1' }, @@ -296,8 +296,8 @@ describe('modules/datasource/go/releases-goproxy', () => { expect(res).toEqual({ releases: [ - { releaseTimestamp: '2018-08-13T15:31:12Z', version: 'v1.0.0' }, - { releaseTimestamp: '2019-10-16T16:15:28Z', version: 'v1.0.1' }, + { releaseTimestamp: '2018-08-13T15:31:12.000Z', version: 'v1.0.0' }, + { releaseTimestamp: '2019-10-16T16:15:28.000Z', version: 'v1.0.1' }, ], sourceUrl: 'https://github.com/google/btree', tags: { latest: 'v1.0.1' }, @@ -399,7 +399,7 @@ describe('modules/datasource/go/releases-goproxy', () => { httpMock .scope(`${baseUrl}/custom.com/lib/btree`) .get('/@v/list') - .reply(200, ['v1.0.0 2018-08-13T15:31:12Z', 'v1.0.1'].join('\n')) + .reply(200, ['v1.0.0 2018-08-13T15:31:12.000Z', 'v1.0.1'].join('\n')) .get('/@v/v1.0.1.info') .reply(200, { Version: 'v1.0.1', Time: '2019-10-16T16:15:28Z' }) .get('/@latest') @@ -417,8 +417,8 @@ describe('modules/datasource/go/releases-goproxy', () => { expect(res).toEqual({ releases: [ - { releaseTimestamp: '2018-08-13T15:31:12Z', version: 'v1.0.0' }, - { releaseTimestamp: '2019-10-16T16:15:28Z', version: 'v1.0.1' }, + { releaseTimestamp: '2018-08-13T15:31:12.000Z', version: 'v1.0.0' }, + { releaseTimestamp: '2019-10-16T16:15:28.000Z', version: 'v1.0.1' }, ], tags: { latest: 'v1.0.1' }, }); @@ -470,9 +470,9 @@ describe('modules/datasource/go/releases-goproxy', () => { expect(res).toEqual({ releases: [ - { releaseTimestamp: '2018-08-13T15:31:12Z', version: 'v1.0.0' }, - { releaseTimestamp: '2019-10-16T16:15:28Z', version: 'v1.0.1' }, - { releaseTimestamp: '2020-10-16T16:15:28Z', version: 'v2.0.0' }, + { releaseTimestamp: '2018-08-13T15:31:12.000Z', version: 'v1.0.0' }, + { releaseTimestamp: '2019-10-16T16:15:28.000Z', version: 'v1.0.1' }, + { releaseTimestamp: '2020-10-16T16:15:28.000Z', version: 'v2.0.0' }, ], sourceUrl: 'https://github.com/google/btree', tags: { latest: 'v2.0.0' }, @@ -513,10 +513,10 @@ describe('modules/datasource/go/releases-goproxy', () => { expect(res).toEqual({ releases: [ - { releaseTimestamp: '2020-05-06T23:08:38Z', version: 'v2.3.0' }, - { releaseTimestamp: '2020-11-17T15:46:20Z', version: 'v2.4.0' }, - { releaseTimestamp: '2022-05-21T10:33:21Z', version: 'v3.0.0' }, - { releaseTimestamp: '2022-05-27T08:35:30Z', version: 'v3.0.1' }, + { releaseTimestamp: '2020-05-06T23:08:38.000Z', version: 'v2.3.0' }, + { releaseTimestamp: '2020-11-17T15:46:20.000Z', version: 'v2.4.0' }, + { releaseTimestamp: '2022-05-21T10:33:21.000Z', version: 'v3.0.0' }, + { releaseTimestamp: '2022-05-27T08:35:30.000Z', version: 'v3.0.1' }, ], sourceUrl: 'https://github.com/go-yaml/yaml', tags: { latest: 'v3.0.1' }, @@ -551,9 +551,9 @@ describe('modules/datasource/go/releases-goproxy', () => { expect(res).toEqual({ releases: [ - { releaseTimestamp: '2017-01-01T00:00:00Z', version: 'v0.1.0' }, - { releaseTimestamp: '2017-02-01T00:00:00Z', version: 'v0.2.0' }, - { releaseTimestamp: '2018-01-01T00:00:00Z', version: 'v1.0.0' }, + { releaseTimestamp: '2017-01-01T00:00:00.000Z', version: 'v0.1.0' }, + { releaseTimestamp: '2017-02-01T00:00:00.000Z', version: 'v0.2.0' }, + { releaseTimestamp: '2018-01-01T00:00:00.000Z', version: 'v1.0.0' }, ], sourceUrl: 'https://github.com/go-foo/foo', tags: { latest: 'v1.0.0' }, @@ -588,9 +588,9 @@ describe('modules/datasource/go/releases-goproxy', () => { expect(res).toEqual({ releases: [ - { releaseTimestamp: '2017-01-01T00:00:00Z', version: 'v0.1.0' }, - { releaseTimestamp: '2017-02-01T00:00:00Z', version: 'v0.2.0' }, - { releaseTimestamp: '2018-01-01T00:00:00Z', version: 'v1.0.0' }, + { releaseTimestamp: '2017-01-01T00:00:00.000Z', version: 'v0.1.0' }, + { releaseTimestamp: '2017-02-01T00:00:00.000Z', version: 'v0.2.0' }, + { releaseTimestamp: '2018-01-01T00:00:00.000Z', version: 'v1.0.0' }, ], sourceUrl: 'https://github.com/go-foo/foo', tags: { latest: 'v1.0.0' }, @@ -632,7 +632,7 @@ describe('modules/datasource/go/releases-goproxy', () => { releases: [ { newDigest: '921286631fa9', - releaseTimestamp: '2023-09-05T20:02:55Z', + releaseTimestamp: '2023-09-05T20:02:55.000Z', version: 'v0.0.0-20230905200255-921286631fa9', }, ], diff --git a/lib/modules/datasource/go/releases-goproxy.ts b/lib/modules/datasource/go/releases-goproxy.ts index 4464a2e33b6a579..e3f87682a3478f2 100644 --- a/lib/modules/datasource/go/releases-goproxy.ts +++ b/lib/modules/datasource/go/releases-goproxy.ts @@ -1,5 +1,4 @@ import is from '@sindresorhus/is'; -import { DateTime } from 'luxon'; import { logger } from '../../../logger'; import { ExternalHostError } from '../../../types/errors/external-host-error'; import { cache } from '../../../util/cache/package/decorator'; @@ -7,6 +6,7 @@ import { filterMap } from '../../../util/filter-map'; import { HttpError } from '../../../util/http'; import * as p from '../../../util/promises'; import { newlineRegex, regEx } from '../../../util/regex'; +import { asTimestamp } from '../../../util/timestamp'; import { joinUrlParts } from '../../../util/url'; import goVersioning from '../../versioning/go-mod-directive'; import { Datasource } from '../datasource'; @@ -33,9 +33,7 @@ export function pseudoVersionToRelease(pseudoVersion: string): Release | null { } const { digest: newDigest, timestamp } = match; - const releaseTimestamp = DateTime.fromFormat(timestamp, 'yyyyMMddHHmmss', { - zone: 'UTC', - }).toISO({ suppressMilliseconds: true }); + const releaseTimestamp = asTimestamp(timestamp); return { version: pseudoVersion, @@ -142,9 +140,10 @@ export class GoProxyDatasource extends Datasource { return null; } - const [version, releaseTimestamp] = str.trim().split(regEx(/\s+/)); + const [version, timestamp] = str.trim().split(regEx(/\s+/)); const release: Release = pseudoVersionToRelease(version) ?? { version }; + const releaseTimestamp = asTimestamp(timestamp); if (releaseTimestamp) { release.releaseTimestamp = releaseTimestamp; } @@ -170,8 +169,9 @@ export class GoProxyDatasource extends Datasource { version: res.body.Version, }; - if (res.body.Time) { - result.releaseTimestamp = res.body.Time; + const releaseTimestamp = asTimestamp(res.body.Time); + if (releaseTimestamp) { + result.releaseTimestamp = releaseTimestamp; } return result; diff --git a/lib/modules/datasource/golang-version/index.ts b/lib/modules/datasource/golang-version/index.ts index 65e7d9b87b37c3e..6d355a60aeb4bc9 100644 --- a/lib/modules/datasource/golang-version/index.ts +++ b/lib/modules/datasource/golang-version/index.ts @@ -1,6 +1,7 @@ import { ExternalHostError } from '../../../types/errors/external-host-error'; import { cache } from '../../../util/cache/package/decorator'; import { regEx } from '../../../util/regex'; +import { asTimestamp } from '../../../util/timestamp'; import { joinUrlParts } from '../../../util/url'; import { isVersion, id as semverVersioningId } from '../../versioning/semver'; import { Datasource } from '../datasource'; @@ -111,7 +112,9 @@ export class GolangVersionDatasource extends Datasource { const year = releaseDateMatch.groups.year.padStart(4, '0'); const month = releaseDateMatch.groups.month.padStart(2, '0'); const day = releaseDateMatch.groups.day.padStart(2, '0'); - release.releaseTimestamp = `${year}-${month}-${day}T00:00:00.000Z`; + release.releaseTimestamp = asTimestamp( + `${year}-${month}-${day}T00:00:00.000Z`, + ); } const releaseVersionMatch = releaseVersionRegex.exec(line); if (releaseVersionMatch?.groups) { diff --git a/lib/modules/datasource/gradle-version/index.ts b/lib/modules/datasource/gradle-version/index.ts index 4667b6891955ca3..d733216953e9cca 100644 --- a/lib/modules/datasource/gradle-version/index.ts +++ b/lib/modules/datasource/gradle-version/index.ts @@ -1,5 +1,5 @@ import { cache } from '../../../util/cache/package/decorator'; -import { regEx } from '../../../util/regex'; +import { asTimestamp } from '../../../util/timestamp'; import * as gradleVersioning from '../../versioning/gradle'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, Release, ReleaseResult } from '../types'; @@ -27,10 +27,6 @@ export class GradleVersionDatasource extends Datasource { override readonly sourceUrlNote = 'We use the URL: https://github.com/gradle/gradle.'; - private static readonly buildTimeRegex = regEx( - '^(\\d\\d\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d)(\\+\\d\\d\\d\\d)$', - ); - @cache({ namespace: `datasource-${GradleVersionDatasource.id}`, // TODO: types (#22198) @@ -55,8 +51,7 @@ export class GradleVersionDatasource extends Datasource { const gitRef = GradleVersionDatasource.getGitRef(release.version); - const releaseTimestamp = - GradleVersionDatasource.formatBuildTime(buildTime); + const releaseTimestamp = asTimestamp(buildTime); const result: Release = { version, gitRef, releaseTimestamp }; @@ -81,19 +76,6 @@ export class GradleVersionDatasource extends Datasource { return null; } - private static formatBuildTime(timeStr: string): string | null { - if (!timeStr) { - return null; - } - if (GradleVersionDatasource.buildTimeRegex.test(timeStr)) { - return timeStr.replace( - GradleVersionDatasource.buildTimeRegex, - '$1-$2-$3T$4:$5:$6$7', - ); - } - return null; - } - /** * Calculate `gitTag` based on `version`: * - `8.1.2` -> `v8.1.2` diff --git a/lib/modules/datasource/hackage/index.spec.ts b/lib/modules/datasource/hackage/index.spec.ts index 676e082583da489..1235b179a91cde0 100644 --- a/lib/modules/datasource/hackage/index.spec.ts +++ b/lib/modules/datasource/hackage/index.spec.ts @@ -8,7 +8,7 @@ describe('modules/datasource/hackage/index', () => { describe('versionToRelease', () => { it('should make release with given version', () => { expect( - versionToRelease('3.1.0', 'base', 'http://localhost').version, + versionToRelease('3.1.0', 'base', 'http://localhost', false).version, ).toBe('3.1.0'); }); }); @@ -33,11 +33,11 @@ describe('modules/datasource/hackage/index', () => { ).toBeNull(); }); - it('returns release for 200', async () => { + it('returns releases for 200', async () => { httpMock .scope(baseUrl) .get('/package/base.json') - .reply(200, { '4.20.0.1': 'normal' }); + .reply(200, { '4.19.0.1': 'deprecated', '4.20.0.1': 'normal' }); expect( await getPkgReleases({ datasource: HackageDatasource.id, @@ -46,9 +46,15 @@ describe('modules/datasource/hackage/index', () => { ).toEqual({ registryUrl: baseUrl, releases: [ + { + changelogUrl: baseUrl + 'package/base-4.19.0.1/changelog', + version: '4.19.0.1', + isDeprecated: true, + }, { changelogUrl: baseUrl + 'package/base-4.20.0.1/changelog', version: '4.20.0.1', + isDeprecated: false, }, ], }); diff --git a/lib/modules/datasource/hackage/index.ts b/lib/modules/datasource/hackage/index.ts index 4a75568d485468a..481d92b56d42684 100644 --- a/lib/modules/datasource/hackage/index.ts +++ b/lib/modules/datasource/hackage/index.ts @@ -28,12 +28,14 @@ export class HackageDatasource extends Datasource { `${massagedPackageName}.json`, ); const res = await this.http.getJson(url, HackagePackageMetadata); - const keys = Object.keys(res.body); - return { - releases: keys.map((version) => - versionToRelease(version, packageName, registryUrl), - ), - }; + const releases = []; + for (const [version, versionStatus] of Object.entries(res.body)) { + const isDeprecated = versionStatus === 'deprecated'; + releases.push( + versionToRelease(version, packageName, registryUrl, isDeprecated), + ); + } + return { releases }; } } @@ -41,6 +43,7 @@ export function versionToRelease( version: string, packageName: string, registryUrl: string, + isDeprecated: boolean, ): Release { return { version, @@ -50,5 +53,6 @@ export function versionToRelease( `${packageName}-${version}`, 'changelog', ), + isDeprecated, }; } diff --git a/lib/modules/datasource/hackage/schema.ts b/lib/modules/datasource/hackage/schema.ts index dcee186743c6020..4081d153f3b92aa 100644 --- a/lib/modules/datasource/hackage/schema.ts +++ b/lib/modules/datasource/hackage/schema.ts @@ -1,3 +1,8 @@ import { z } from 'zod'; -export const HackagePackageMetadata = z.record(z.string()); +// See https://github.com/haskell/hackage-server +// revision e885d36c +// src/Distribution/Server/Features/PackageInfoJSON/State.hs line 160 +const VersionStatus = z.enum(['normal', 'deprecated', 'unpreferred']); + +export const HackagePackageMetadata = z.record(VersionStatus); diff --git a/lib/modules/datasource/helm/schema.ts b/lib/modules/datasource/helm/schema.ts index d10d90120b86ab4..64465295c67d86d 100644 --- a/lib/modules/datasource/helm/schema.ts +++ b/lib/modules/datasource/helm/schema.ts @@ -3,11 +3,12 @@ import { detectPlatform } from '../../../util/common'; import { parseGitUrl } from '../../../util/git/url'; import { regEx } from '../../../util/regex'; import { LooseRecord } from '../../../util/schema-utils'; +import { MaybeTimestamp } from '../../../util/timestamp'; import type { Release } from '../types'; const HelmReleaseSchema = z.object({ version: z.string(), - created: z.string().nullable().catch(null), + created: MaybeTimestamp, digest: z.string().optional().catch(undefined), home: z.string().optional().catch(undefined), sources: z.array(z.string()).catch([]), diff --git a/lib/modules/datasource/hex/schema.ts b/lib/modules/datasource/hex/schema.ts index a04aa81a49f3998..be37b11f93c575e 100644 --- a/lib/modules/datasource/hex/schema.ts +++ b/lib/modules/datasource/hex/schema.ts @@ -1,6 +1,7 @@ import is from '@sindresorhus/is'; import { z } from 'zod'; import { LooseArray } from '../../../util/schema-utils'; +import { MaybeTimestamp } from '../../../util/timestamp'; import type { Release, ReleaseResult } from '../types'; export const HexRelease = z @@ -29,7 +30,7 @@ export const HexRelease = z releases: LooseArray( z.object({ version: z.string(), - inserted_at: z.string().optional(), + inserted_at: MaybeTimestamp, }), ).refine((releases) => releases.length > 0, 'No releases found'), retirements: z diff --git a/lib/modules/datasource/hexpm-bob/index.ts b/lib/modules/datasource/hexpm-bob/index.ts index c841f26e9a38d46..817df0a53aebcbe 100644 --- a/lib/modules/datasource/hexpm-bob/index.ts +++ b/lib/modules/datasource/hexpm-bob/index.ts @@ -3,6 +3,7 @@ import { logger } from '../../../logger'; import { ExternalHostError } from '../../../types/errors/external-host-error'; import { cache } from '../../../util/cache/package/decorator'; import { HttpError } from '../../../util/http'; +import { asTimestamp } from '../../../util/timestamp'; import { id as semverId } from '../../versioning/semver'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, ReleaseResult } from '../types'; @@ -69,7 +70,7 @@ export class HexpmBobDatasource extends Datasource { return { gitRef, isStable: HexpmBobDatasource.isStable(version, packageType), - releaseTimestamp: buildDate, + releaseTimestamp: asTimestamp(buildDate), version: HexpmBobDatasource.cleanVersion(version, packageType), }; }); diff --git a/lib/modules/datasource/jenkins-plugins/index.spec.ts b/lib/modules/datasource/jenkins-plugins/index.spec.ts index 65cb05070d7e944..d8bee66fb89b6b6 100644 --- a/lib/modules/datasource/jenkins-plugins/index.spec.ts +++ b/lib/modules/datasource/jenkins-plugins/index.spec.ts @@ -1,5 +1,6 @@ import { getPkgReleases } from '..'; import * as httpMock from '../../../../test/http-mock'; +import type { Timestamp } from '../../../util/timestamp'; import * as versioning from '../../versioning/docker'; import type { JenkinsPluginsInfoResponse, @@ -31,7 +32,7 @@ const jenkinsPluginsVersions: JenkinsPluginsVersionsResponse = { '3.0.0': { version: '3.0.0', url: 'https://download.example.com', - releaseTimestamp: '2020-05-13T00:11:40.00Z', + releaseTimestamp: '2020-05-13T00:11:40.00Z' as Timestamp, requiredCore: '2.164.3', }, }, @@ -87,12 +88,12 @@ describe('modules/datasource/jenkins-plugins/index', () => { }, { downloadUrl: 'https://download.example.com', - releaseTimestamp: '2020-01-02T00:00:00.000Z', + releaseTimestamp: '2020-01-02T00:00:00.000Z' as Timestamp, version: '2.0.0', }, { downloadUrl: 'https://download.example.com', - releaseTimestamp: '2020-05-13T00:11:40.000Z', + releaseTimestamp: '2020-05-13T00:11:40.000Z' as Timestamp, version: '3.0.0', }, ], @@ -155,12 +156,12 @@ describe('modules/datasource/jenkins-plugins/index', () => { }, { downloadUrl: 'https://download.example.com', - releaseTimestamp: '2020-01-02T00:00:00.000Z', + releaseTimestamp: '2020-01-02T00:00:00.000Z' as Timestamp, version: '2.0.0', }, { downloadUrl: 'https://download.example.com', - releaseTimestamp: '2020-05-13T00:11:40.000Z', + releaseTimestamp: '2020-05-13T00:11:40.000Z' as Timestamp, version: '3.0.0', }, ], diff --git a/lib/modules/datasource/jenkins-plugins/index.ts b/lib/modules/datasource/jenkins-plugins/index.ts index 1f846c1c240e022..02fa74fdf602544 100644 --- a/lib/modules/datasource/jenkins-plugins/index.ts +++ b/lib/modules/datasource/jenkins-plugins/index.ts @@ -1,6 +1,7 @@ import { logger } from '../../../logger'; import { cache } from '../../../util/cache/package/decorator'; import { clone } from '../../../util/clone'; +import { asTimestamp } from '../../../util/timestamp'; import { ensureTrailingSlash } from '../../../util/url'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, Release, ReleaseResult } from '../types'; @@ -96,8 +97,7 @@ export class JenkinsPluginsDatasource extends Datasource { const downloadUrl = plugins[name][version]?.url; const buildDate = plugins[name][version]?.buildDate; const releaseTimestamp = - plugins[name][version]?.releaseTimestamp ?? - (buildDate ? new Date(`${buildDate} UTC`).toISOString() : null); + plugins[name][version]?.releaseTimestamp ?? asTimestamp(buildDate); const jenkins = plugins[name][version]?.requiredCore; const constraints = jenkins ? { jenkins: [`>=${jenkins}`] } : undefined; return { diff --git a/lib/modules/datasource/jenkins-plugins/types.ts b/lib/modules/datasource/jenkins-plugins/types.ts index 5224ff1072240dc..b8e350bebc59272 100644 --- a/lib/modules/datasource/jenkins-plugins/types.ts +++ b/lib/modules/datasource/jenkins-plugins/types.ts @@ -1,3 +1,5 @@ +import type { Timestamp } from '../../../util/timestamp'; + export interface JenkinsPluginInfo { name: string; scm?: string; @@ -9,7 +11,7 @@ export interface JenkinsPluginVersion { url?: string; requiredCore?: string; - releaseTimestamp?: string; + releaseTimestamp?: Timestamp; } export interface JenkinsPluginsInfoResponse { diff --git a/lib/modules/datasource/maven/index.ts b/lib/modules/datasource/maven/index.ts index b35bc6996a59bb6..32ac272918fe578 100644 --- a/lib/modules/datasource/maven/index.ts +++ b/lib/modules/datasource/maven/index.ts @@ -4,6 +4,7 @@ import { GlobalConfig } from '../../../config/global'; import { logger } from '../../../logger'; import * as packageCache from '../../../util/cache/package'; import { cache } from '../../../util/cache/package/decorator'; +import { asTimestamp } from '../../../util/timestamp'; import { ensureTrailingSlash } from '../../../util/url'; import mavenVersion from '../../versioning/maven'; import * as mavenVersioning from '../../versioning/maven'; @@ -198,7 +199,7 @@ export class MavenDatasource extends Datasource { } if (is.date(res)) { - release.releaseTimestamp = res.toISOString(); + release.releaseTimestamp = asTimestamp(res.toISOString()); } return release; diff --git a/lib/modules/datasource/metadata.spec.ts b/lib/modules/datasource/metadata.spec.ts index 645d270f98ae1bf..87a73eb8c65adab 100644 --- a/lib/modules/datasource/metadata.spec.ts +++ b/lib/modules/datasource/metadata.spec.ts @@ -1,4 +1,5 @@ import { partial } from '../../../test/util'; +import type { Timestamp } from '../../util/timestamp'; import { HelmDatasource } from './helm'; import { MavenDatasource } from './maven'; import { @@ -15,13 +16,22 @@ describe('modules/datasource/metadata', () => { it('Should handle manualChangelogUrls', () => { const dep: ReleaseResult = { releases: [ - { version: '2.0.0', releaseTimestamp: '2018-07-13T10:14:17.000Z' }, + { + version: '2.0.0', + releaseTimestamp: '2018-07-13T10:14:17.000Z' as Timestamp, + }, { version: '2.0.0.dev1', - releaseTimestamp: '2017-10-24T10:09:16.000Z', + releaseTimestamp: '2017-10-24T10:09:16.000Z' as Timestamp, + }, + { + version: '2.1.0', + releaseTimestamp: '2019-01-20T19:59:28.000Z' as Timestamp, + }, + { + version: '2.2.0', + releaseTimestamp: '2019-07-16T18:29:00.000Z' as Timestamp, }, - { version: '2.1.0', releaseTimestamp: '2019-01-20T19:59:28.000Z' }, - { version: '2.2.0', releaseTimestamp: '2019-07-16T18:29:00.000Z' }, ], }; @@ -38,13 +48,22 @@ describe('modules/datasource/metadata', () => { it('Should handle manualSourceUrls', () => { const dep: ReleaseResult = { releases: [ - { version: '2.0.0', releaseTimestamp: '2018-07-13T10:14:17.000Z' }, + { + version: '2.0.0', + releaseTimestamp: '2018-07-13T10:14:17.000Z' as Timestamp, + }, { version: '2.0.0.dev1', - releaseTimestamp: '2017-10-24T10:09:16.000Z', + releaseTimestamp: '2017-10-24T10:09:16.000Z' as Timestamp, + }, + { + version: '2.1.0', + releaseTimestamp: '2019-01-20T19:59:28.000Z' as Timestamp, + }, + { + version: '2.2.0', + releaseTimestamp: '2019-07-16T18:29:00.000Z' as Timestamp, }, - { version: '2.1.0', releaseTimestamp: '2019-01-20T19:59:28.000Z' }, - { version: '2.2.0', releaseTimestamp: '2019-07-16T18:29:00.000Z' }, ], }; @@ -61,13 +80,22 @@ describe('modules/datasource/metadata', () => { const dep: ReleaseResult = { sourceUrl: 'https://github.com/carltongibson/django-filter/tree/master', releases: [ - { version: '2.0.0', releaseTimestamp: '2018-07-13T10:14:17.000Z' }, + { + version: '2.0.0', + releaseTimestamp: '2018-07-13T10:14:17.000Z' as Timestamp, + }, { version: '2.0.0.dev1', - releaseTimestamp: '2017-10-24T10:09:16.000Z', + releaseTimestamp: '2017-10-24T10:09:16.000Z' as Timestamp, + }, + { + version: '2.1.0', + releaseTimestamp: '2019-01-20T19:59:28.000Z' as Timestamp, + }, + { + version: '2.2.0', + releaseTimestamp: '2019-07-16T18:29:00.000Z' as Timestamp, }, - { version: '2.1.0', releaseTimestamp: '2019-01-20T19:59:28.000Z' }, - { version: '2.2.0', releaseTimestamp: '2019-07-16T18:29:00.000Z' }, ], }; const datasource = PypiDatasource.id; @@ -142,13 +170,22 @@ describe('modules/datasource/metadata', () => { const dep: ReleaseResult = { sourceUrl: 'https://some.github.com/repo', releases: [ - { version: '2.0.0', releaseTimestamp: '2018-07-13T10:14:17.000Z' }, + { + version: '2.0.0', + releaseTimestamp: '2018-07-13T10:14:17.000Z' as Timestamp, + }, { version: '2.0.0.dev1', - releaseTimestamp: '2017-10-24T10:09:16.000Z', + releaseTimestamp: '2017-10-24T10:09:16.000Z' as Timestamp, + }, + { + version: '2.1.0', + releaseTimestamp: '2019-01-20T19:59:28.000Z' as Timestamp, + }, + { + version: '2.2.0', + releaseTimestamp: '2019-07-16T18:29:00.000Z' as Timestamp, }, - { version: '2.1.0', releaseTimestamp: '2019-01-20T19:59:28.000Z' }, - { version: '2.2.0', releaseTimestamp: '2019-07-16T18:29:00.000Z' }, ], }; const datasource = PypiDatasource.id; @@ -164,10 +201,13 @@ describe('modules/datasource/metadata', () => { const dep: ReleaseResult = { sourceUrl: 'https://gitlab.com/meno/dropzone/tree/master', releases: [ - { version: '5.7.0', releaseTimestamp: '2020-02-14T13:12:00.000Z' }, + { + version: '5.7.0', + releaseTimestamp: '2020-02-14T13:12:00.000Z' as Timestamp, + }, { version: '5.6.1', - releaseTimestamp: '2020-02-14T10:04:00.000Z', + releaseTimestamp: '2020-02-14T10:04:00.000Z' as Timestamp, }, ], }; @@ -184,10 +224,13 @@ describe('modules/datasource/metadata', () => { const dep = { sourceUrl: 'https://gitlab-nope', releases: [ - { version: '5.7.0', releaseTimestamp: '2020-02-14T13:12:00.000Z' }, + { + version: '5.7.0', + releaseTimestamp: '2020-02-14T13:12:00.000Z' as Timestamp, + }, { version: '5.6.1', - releaseTimestamp: '2020-02-14T10:04:00.000Z', + releaseTimestamp: '2020-02-14T10:04:00.000Z' as Timestamp, }, ], }; @@ -204,10 +247,13 @@ describe('modules/datasource/metadata', () => { const dep = { sourceUrl: 'https://nope-nope-nope', releases: [ - { version: '5.7.0', releaseTimestamp: '2020-02-14T13:12:00.000Z' }, + { + version: '5.7.0', + releaseTimestamp: '2020-02-14T13:12:00.000Z' as Timestamp, + }, { version: '5.6.1', - releaseTimestamp: '2020-02-14T10:04:00.000Z', + releaseTimestamp: '2020-02-14T10:04:00.000Z' as Timestamp, }, ], }; @@ -224,10 +270,13 @@ describe('modules/datasource/metadata', () => { const dep = { sourceUrl: 'not-a-url', releases: [ - { version: '5.7.0', releaseTimestamp: '2020-02-14T13:12:00.000Z' }, + { + version: '5.7.0', + releaseTimestamp: '2020-02-14T13:12:00.000Z' as Timestamp, + }, { version: '5.6.1', - releaseTimestamp: '2020-02-14T10:04:00.000Z', + releaseTimestamp: '2020-02-14T10:04:00.000Z' as Timestamp, }, ], }; @@ -280,10 +329,19 @@ describe('modules/datasource/metadata', () => { it('Should normalize releaseTimestamp', () => { const dep = { releases: [ - { version: '1.0.1', releaseTimestamp: '2000-01-01T12:34:56' }, - { version: '1.0.2', releaseTimestamp: '2000-01-02T12:34:56.000Z' }, - { version: '1.0.3', releaseTimestamp: '2000-01-03T14:34:56.000+02:00' }, - { version: '1.0.4', releaseTimestamp: '20000103150210' }, + { + version: '1.0.1', + releaseTimestamp: '2000-01-01T12:34:56' as Timestamp, + }, + { + version: '1.0.2', + releaseTimestamp: '2000-01-02T12:34:56.000Z' as Timestamp, + }, + { + version: '1.0.3', + releaseTimestamp: '2000-01-03T14:34:56.000+02:00' as Timestamp, + }, + { version: '1.0.4', releaseTimestamp: '20000103150210' as Timestamp }, ], }; addMetaData(dep, MavenDatasource.id, 'foobar'); @@ -374,9 +432,18 @@ describe('modules/datasource/metadata', () => { homepage: 'https://github.com/foo/bar', sourceUrl: 'https://github.com/foo/bar', releases: [ - { version: '1.0.1', releaseTimestamp: '2000-01-01T12:34:56' }, - { version: '1.0.2', releaseTimestamp: '2000-01-02T12:34:56.000Z' }, - { version: '1.0.3', releaseTimestamp: '2000-01-03T14:34:56.000+02:00' }, + { + version: '1.0.1', + releaseTimestamp: '2000-01-01T12:34:56' as Timestamp, + }, + { + version: '1.0.2', + releaseTimestamp: '2000-01-02T12:34:56.000Z' as Timestamp, + }, + { + version: '1.0.3', + releaseTimestamp: '2000-01-03T14:34:56.000+02:00' as Timestamp, + }, ], }; addMetaData(dep, MavenDatasource.id, 'foobar'); @@ -404,9 +471,18 @@ describe('modules/datasource/metadata', () => { sourceUrl: 'https://gitlab.com/meno/repo', homepage: 'https://gitlab.com/meno/repo', releases: [ - { version: '1.0.1', releaseTimestamp: '2000-01-01T12:34:56' }, - { version: '1.0.2', releaseTimestamp: '2000-01-02T12:34:56.000Z' }, - { version: '1.0.3', releaseTimestamp: '2000-01-03T14:34:56.000+02:00' }, + { + version: '1.0.1', + releaseTimestamp: '2000-01-01T12:34:56' as Timestamp, + }, + { + version: '1.0.2', + releaseTimestamp: '2000-01-02T12:34:56.000Z' as Timestamp, + }, + { + version: '1.0.3', + releaseTimestamp: '2000-01-03T14:34:56.000+02:00' as Timestamp, + }, ], }; addMetaData(dep, MavenDatasource.id, 'foobar'); @@ -433,9 +509,18 @@ describe('modules/datasource/metadata', () => { const dep = { sourceUrl: 'https://gitlab.com/meno/repo', releases: [ - { version: '1.0.1', releaseTimestamp: '2000-01-01T12:34:56' }, - { version: '1.0.2', releaseTimestamp: '2000-01-02T12:34:56.000Z' }, - { version: '1.0.3', releaseTimestamp: '2000-01-03T14:34:56.000+02:00' }, + { + version: '1.0.1', + releaseTimestamp: '2000-01-01T12:34:56' as Timestamp, + }, + { + version: '1.0.2', + releaseTimestamp: '2000-01-02T12:34:56.000Z' as Timestamp, + }, + { + version: '1.0.3', + releaseTimestamp: '2000-01-03T14:34:56.000+02:00' as Timestamp, + }, ], }; addMetaData(dep, MavenDatasource.id, 'foobar'); @@ -462,9 +547,18 @@ describe('modules/datasource/metadata', () => { const dep = { homepage: 'https://somesource.com/', releases: [ - { version: '1.0.1', releaseTimestamp: '2000-01-01T12:34:56' }, - { version: '1.0.2', releaseTimestamp: '2000-01-02T12:34:56.000Z' }, - { version: '1.0.3', releaseTimestamp: '2000-01-03T14:34:56.000+02:00' }, + { + version: '1.0.1', + releaseTimestamp: '2000-01-01T12:34:56' as Timestamp, + }, + { + version: '1.0.2', + releaseTimestamp: '2000-01-02T12:34:56.000Z' as Timestamp, + }, + { + version: '1.0.3', + releaseTimestamp: '2000-01-03T14:34:56.000+02:00' as Timestamp, + }, ], }; addMetaData(dep, MavenDatasource.id, 'foobar'); diff --git a/lib/modules/datasource/node-version/index.ts b/lib/modules/datasource/node-version/index.ts index aba6bd7da83e63b..c5caf6d8ed4898d 100644 --- a/lib/modules/datasource/node-version/index.ts +++ b/lib/modules/datasource/node-version/index.ts @@ -1,4 +1,5 @@ import { cache } from '../../../util/cache/package/decorator'; +import { asTimestamp } from '../../../util/timestamp'; import { joinUrlParts } from '../../../util/url'; import { id as versioning } from '../../versioning/node'; import { Datasource } from '../datasource'; @@ -53,7 +54,7 @@ export class NodeVersionDatasource extends Datasource { result.releases.push( ...resp.map(({ version, date, lts }) => ({ version, - releaseTimestamp: date, + releaseTimestamp: asTimestamp(date), isStable: lts !== false, })), ); diff --git a/lib/modules/datasource/npm/get.ts b/lib/modules/datasource/npm/get.ts index ec6cc4e5576055e..4bee6946abd0dcb 100644 --- a/lib/modules/datasource/npm/get.ts +++ b/lib/modules/datasource/npm/get.ts @@ -12,6 +12,7 @@ import type { Http } from '../../../util/http'; import type { HttpOptions } from '../../../util/http/types'; import { regEx } from '../../../util/regex'; import { HttpCacheStats } from '../../../util/stats'; +import { asTimestamp } from '../../../util/timestamp'; import { joinUrlParts } from '../../../util/url'; import type { Release, ReleaseResult } from '../types'; import type { CachedReleaseResult, NpmResponse } from './types'; @@ -199,8 +200,9 @@ export async function getDependency( dependencies: res.versions?.[version].dependencies, devDependencies: res.versions?.[version].devDependencies, }; - if (res.time?.[version]) { - release.releaseTimestamp = res.time[version]; + const releaseTimestamp = asTimestamp(res.time?.[version]); + if (releaseTimestamp) { + release.releaseTimestamp = releaseTimestamp; } if (res.versions?.[version].deprecated) { release.isDeprecated = true; diff --git a/lib/modules/datasource/nuget/v2.ts b/lib/modules/datasource/nuget/v2.ts index 48c89d34b4a6fd3..b542298eadcb935 100644 --- a/lib/modules/datasource/nuget/v2.ts +++ b/lib/modules/datasource/nuget/v2.ts @@ -3,6 +3,7 @@ import { XmlDocument } from 'xmldoc'; import { logger } from '../../../logger'; import type { Http } from '../../../util/http'; import { regEx } from '../../../util/regex'; +import { asTimestamp } from '../../../util/timestamp'; import type { ReleaseResult } from '../types'; import { massageUrl, removeBuildMeta } from './common'; @@ -32,7 +33,9 @@ export class NugetV2Api { for (const pkgInfo of pkgInfoList) { const version = this.getPkgProp(pkgInfo, 'Version'); - const releaseTimestamp = this.getPkgProp(pkgInfo, 'Published'); + const releaseTimestamp = asTimestamp( + this.getPkgProp(pkgInfo, 'Published'), + ); dep.releases.push({ // TODO: types (#22198) version: removeBuildMeta(`${version}`), diff --git a/lib/modules/datasource/nuget/v3.ts b/lib/modules/datasource/nuget/v3.ts index b773b5865f76606..2492c02d70a674d 100644 --- a/lib/modules/datasource/nuget/v3.ts +++ b/lib/modules/datasource/nuget/v3.ts @@ -13,6 +13,7 @@ import type { Http } from '../../../util/http'; import { HttpError } from '../../../util/http'; import * as p from '../../../util/promises'; import { regEx } from '../../../util/regex'; +import { asTimestamp } from '../../../util/timestamp'; import { ensureTrailingSlash } from '../../../util/url'; import { api as versioning } from '../../versioning/nuget'; import type { Release, ReleaseResult } from '../types'; @@ -161,14 +162,9 @@ export class NugetV3Api { let latestStable: string | null = null; let nupkgUrl: string | null = null; const releases = catalogEntries.map( - ({ - version, - published: releaseTimestamp, - projectUrl, - listed, - packageContent, - }) => { + ({ version, published, projectUrl, listed, packageContent }) => { const release: Release = { version: removeBuildMeta(version) }; + const releaseTimestamp = asTimestamp(published); if (releaseTimestamp) { release.releaseTimestamp = releaseTimestamp; } diff --git a/lib/modules/datasource/orb/index.ts b/lib/modules/datasource/orb/index.ts index 80fa61e4e932043..0de66700aee4fc9 100644 --- a/lib/modules/datasource/orb/index.ts +++ b/lib/modules/datasource/orb/index.ts @@ -1,5 +1,6 @@ import { logger } from '../../../logger'; import { cache } from '../../../util/cache/package/decorator'; +import { asTimestamp } from '../../../util/timestamp'; import { joinUrlParts } from '../../../util/url'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, ReleaseResult } from '../types'; @@ -71,7 +72,7 @@ export class OrbDatasource extends Datasource { : `https://circleci.com/developer/orbs/orb/${packageName}`; const releases = orb.versions.map(({ version, createdAt }) => ({ version, - releaseTimestamp: createdAt ?? null, + releaseTimestamp: asTimestamp(createdAt), })); const dep = { homepage, isPrivate: !!orb.isPrivate, releases }; diff --git a/lib/modules/datasource/packagist/schema.spec.ts b/lib/modules/datasource/packagist/schema.spec.ts index a83918d124f34e6..6f8b759ded16708 100644 --- a/lib/modules/datasource/packagist/schema.spec.ts +++ b/lib/modules/datasource/packagist/schema.spec.ts @@ -1,3 +1,4 @@ +import type { Timestamp } from '../../../util/timestamp'; import type { ReleaseResult } from '../types'; import { ComposerRelease, @@ -144,10 +145,13 @@ describe('modules/datasource/packagist/schema', () => { }); expect( - ComposerRelease.parse({ version: '1.2.3', time: '12345' }), + ComposerRelease.parse({ + version: '1.2.3', + time: '2025-01-16T12:00:00.000Z', + }), ).toEqual({ version: '1.2.3', - time: '12345', + time: '2025-01-16T12:00:00.000Z', homepage: null, source: null, require: null, @@ -312,7 +316,7 @@ describe('modules/datasource/packagist/schema', () => { 'foo/bar': [ { version: 'v1.1.1', - time: '111', + time: '2025-01-16T12:00:00+00:00' as Timestamp, homepage: 'https://example.com/1', source: { url: 'git@example.com:foo/bar-1' }, require: { php: '^8.0' }, @@ -321,7 +325,7 @@ describe('modules/datasource/packagist/schema', () => { 'baz/qux': [ { version: 'v2.2.2', - time: '222', + time: '2025-01-16T12:00:00+00:00' as Timestamp, homepage: 'https://example.com/2', source: { url: 'git@example.com:baz/qux-2' }, require: null, @@ -334,7 +338,7 @@ describe('modules/datasource/packagist/schema', () => { 'foo/bar': [ { version: 'v3.3.3', - time: '333', + time: '2025-01-16T12:00:00+00:00' as Timestamp, homepage: 'https://example.com/3', source: { url: 'git@example.com:foo/bar-3' }, require: { php: '^7.0' }, @@ -343,7 +347,7 @@ describe('modules/datasource/packagist/schema', () => { 'baz/qux': [ { version: 'v4.4.4', - time: '444', + time: '2025-01-16T12:00:00+00:00' as Timestamp, homepage: 'https://example.com/4', source: { url: 'git@example.com:baz/qux-3' }, require: null, @@ -359,13 +363,13 @@ describe('modules/datasource/packagist/schema', () => { { version: '1.1.1', gitRef: 'v1.1.1', - releaseTimestamp: '111', + releaseTimestamp: '2025-01-16T12:00:00.000Z' as Timestamp, constraints: { php: ['^8.0'] }, }, { version: '3.3.3', gitRef: 'v3.3.3', - releaseTimestamp: '333', + releaseTimestamp: '2025-01-16T12:00:00.000Z' as Timestamp, constraints: { php: ['^7.0'] }, }, ], diff --git a/lib/modules/datasource/packagist/schema.ts b/lib/modules/datasource/packagist/schema.ts index 2d95b2ad95d6115..29af76574d5b3c8 100644 --- a/lib/modules/datasource/packagist/schema.ts +++ b/lib/modules/datasource/packagist/schema.ts @@ -2,6 +2,7 @@ import is from '@sindresorhus/is'; import { z } from 'zod'; import { logger } from '../../../logger'; import { LooseArray, LooseRecord } from '../../../util/schema-utils'; +import { MaybeTimestamp } from '../../../util/timestamp'; import type { Release, ReleaseResult } from '../types'; export const MinifiedArray = z.array(z.record(z.unknown())).transform((xs) => { @@ -44,7 +45,7 @@ export const ComposerRelease = z.object({ version: z.string(), homepage: z.string().nullable().catch(null), source: z.object({ url: z.string() }).nullable().catch(null), - time: z.string().nullable().catch(null), + time: MaybeTimestamp, require: z.object({ php: z.string() }).nullable().catch(null), }); export type ComposerRelease = z.infer; diff --git a/lib/modules/datasource/postprocess-release.spec.ts b/lib/modules/datasource/postprocess-release.spec.ts index 3ec6de9abd8e997..9efbbbc3a8ebcf5 100644 --- a/lib/modules/datasource/postprocess-release.spec.ts +++ b/lib/modules/datasource/postprocess-release.spec.ts @@ -1,4 +1,5 @@ import { mocked } from '../../../test/util'; +import type { Timestamp } from '../../util/timestamp'; import * as _datasourceCommon from './common'; import { Datasource } from './datasource'; import { postprocessRelease } from './postprocess-release'; @@ -86,7 +87,7 @@ describe('modules/datasource/postprocess-release', () => { _config: PostprocessReleaseConfig, release: Release, ): Promise { - release.releaseTimestamp = '2024-09-05'; + release.releaseTimestamp = '2024-09-05' as Timestamp; return Promise.resolve(release); } } diff --git a/lib/modules/datasource/puppet-forge/index.ts b/lib/modules/datasource/puppet-forge/index.ts index 9bed72a5444d844..41b45a6a5b998cc 100644 --- a/lib/modules/datasource/puppet-forge/index.ts +++ b/lib/modules/datasource/puppet-forge/index.ts @@ -1,3 +1,4 @@ +import { asTimestamp } from '../../../util/timestamp'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, Release, ReleaseResult } from '../types'; import { PUPPET_FORGE } from './common'; @@ -37,7 +38,7 @@ export class PuppetForgeDatasource extends Datasource { const releases: Release[] = module?.releases?.map((release) => ({ version: release.version, downloadUrl: release.file_uri, - releaseTimestamp: release.created_at, + releaseTimestamp: asTimestamp(release.created_at), registryUrl, })); diff --git a/lib/modules/datasource/pypi/index.ts b/lib/modules/datasource/pypi/index.ts index 16bcb1bcc9fc77a..48fda7604991f10 100644 --- a/lib/modules/datasource/pypi/index.ts +++ b/lib/modules/datasource/pypi/index.ts @@ -6,6 +6,7 @@ import { coerceArray } from '../../../util/array'; import { parse } from '../../../util/html'; import type { OutgoingHttpHeaders } from '../../../util/http/types'; import { regEx } from '../../../util/regex'; +import { asTimestamp } from '../../../util/timestamp'; import { ensureTrailingSlash, parseUrl } from '../../../util/url'; import * as pep440 from '../../versioning/pep440'; import { Datasource } from '../datasource'; @@ -173,7 +174,7 @@ export class PypiDatasource extends Datasource { const isDeprecated = releases.some(({ yanked }) => yanked); const result: Release = { version, - releaseTimestamp, + releaseTimestamp: asTimestamp(releaseTimestamp), }; if (isDeprecated) { result.isDeprecated = isDeprecated; diff --git a/lib/modules/datasource/python-version/index.spec.ts b/lib/modules/datasource/python-version/index.spec.ts index 4333bfe0cec3447..dea8e2d35106015 100644 --- a/lib/modules/datasource/python-version/index.spec.ts +++ b/lib/modules/datasource/python-version/index.spec.ts @@ -4,6 +4,7 @@ import { Fixtures } from '../../../../test/fixtures'; import * as httpMock from '../../../../test/http-mock'; import { EXTERNAL_HOST_ERROR } from '../../../constants/error-messages'; import * as githubGraphql from '../../../util/github/graphql'; +import type { Timestamp } from '../../../util/timestamp'; import { registryUrl as eolRegistryUrl } from '../endoflife-date/common'; import { datasource, defaultRegistryUrl } from './common'; import { PythonVersionDatasource } from '.'; @@ -38,7 +39,7 @@ describe('modules/datasource/python-version/index', () => { name: 'containerbase/python-prebuild', description: 'some description', version: '3.12.1', - releaseTimestamp: '2020-03-09T13:00:00Z', + releaseTimestamp: '2020-03-09T13:00:00Z' as Timestamp, }, { id: 2, @@ -46,7 +47,7 @@ describe('modules/datasource/python-version/index', () => { name: 'containerbase/python-prebuild', description: 'some description', version: '3.12.0', - releaseTimestamp: '2020-03-09T13:00:00Z', + releaseTimestamp: '2020-03-09T13:00:00Z' as Timestamp, }, { id: 3, @@ -54,7 +55,7 @@ describe('modules/datasource/python-version/index', () => { name: 'containerbase/python-prebuild', description: 'some description', version: '3.7.8', - releaseTimestamp: '2020-03-09T13:00:00Z', + releaseTimestamp: '2020-03-09T13:00:00Z' as Timestamp, }, ]); }); @@ -105,7 +106,7 @@ describe('modules/datasource/python-version/index', () => { expect(res?.releases[0]).toEqual({ isDeprecated: true, isStable: true, - releaseTimestamp: '2020-06-27T12:55:01.000Z', + releaseTimestamp: '2020-06-27T12:55:01.000Z' as Timestamp, version: '3.7.8', }); }); diff --git a/lib/modules/datasource/python-version/schema.ts b/lib/modules/datasource/python-version/schema.ts index 2f804ef8a42f4dd..4aa2f7f61b697bb 100644 --- a/lib/modules/datasource/python-version/schema.ts +++ b/lib/modules/datasource/python-version/schema.ts @@ -1,4 +1,5 @@ import { z } from 'zod'; +import { MaybeTimestamp } from '../../../util/timestamp'; import type { Release } from '../types'; export const PythonRelease = z @@ -12,7 +13,7 @@ export const PythonRelease = z /** is latest major version, true for Python 2.7.18 and latest Python 3 */ is_latest: z.boolean(), is_published: z.boolean(), - release_date: z.string(), + release_date: MaybeTimestamp, pre_release: z.boolean(), release_page: z.string().nullable(), show_on_download_page: z.boolean(), diff --git a/lib/modules/datasource/ruby-version/index.ts b/lib/modules/datasource/ruby-version/index.ts index 7f2a2613c1d6f8a..edf3f52c46d6d47 100644 --- a/lib/modules/datasource/ruby-version/index.ts +++ b/lib/modules/datasource/ruby-version/index.ts @@ -3,6 +3,7 @@ import { ExternalHostError } from '../../../types/errors/external-host-error'; import { cache } from '../../../util/cache/package/decorator'; import { parse } from '../../../util/html'; import type { HttpError } from '../../../util/http'; +import { asTimestamp } from '../../../util/timestamp'; import { isVersion, id as rubyVersioningId } from '../../versioning/ruby'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, ReleaseResult } from '../types'; @@ -51,7 +52,7 @@ export class RubyVersionDatasource extends Datasource { if (columns.length) { const version = columns[0].replace('Ruby ', ''); if (isVersion(version)) { - const releaseTimestamp = columns[1]; + const releaseTimestamp = asTimestamp(columns[1]); const changelogUrl = columns[2] .replace('more...', ''); diff --git a/lib/modules/datasource/rubygems/metadata-cache.spec.ts b/lib/modules/datasource/rubygems/metadata-cache.spec.ts index d1d611ac3c58827..2ebafc33dc489f9 100644 --- a/lib/modules/datasource/rubygems/metadata-cache.spec.ts +++ b/lib/modules/datasource/rubygems/metadata-cache.spec.ts @@ -78,19 +78,19 @@ describe('modules/datasource/rubygems/metadata-cache', () => { releases: [ { version: '1.0.0', - releaseTimestamp: '2021-01-01', + releaseTimestamp: '2021-01-01T00:00:00.000Z', changelogUrl: 'https://v1.example.com/changelog', sourceUrl: 'https://v1.example.com/source', }, { version: '2.0.0', - releaseTimestamp: '2022-01-01', + releaseTimestamp: '2022-01-01T00:00:00.000Z', changelogUrl: 'https://v2.example.com/changelog', sourceUrl: 'https://v2.example.com/source', }, { version: '3.0.0', - releaseTimestamp: '2023-01-01', + releaseTimestamp: '2023-01-01T00:00:00.000Z', changelogUrl: 'https://v3.example.com/changelog', sourceUrl: 'https://v3.example.com/source', }, diff --git a/lib/modules/datasource/rubygems/schema.spec.ts b/lib/modules/datasource/rubygems/schema.spec.ts index 5ece346c68d547b..ebe3fb212af071d 100644 --- a/lib/modules/datasource/rubygems/schema.spec.ts +++ b/lib/modules/datasource/rubygems/schema.spec.ts @@ -97,7 +97,7 @@ describe('modules/datasource/rubygems/schema', () => { releases: [ { version: '1.0.0', - releaseTimestamp: '2021-01-01', + releaseTimestamp: '2021-01-01T00:00:00.000Z', changelogUrl: 'https://example.com', sourceUrl: 'https://example.com', constraints: { @@ -108,7 +108,7 @@ describe('modules/datasource/rubygems/schema', () => { }, { version: '2.0.0', - releaseTimestamp: '2022-01-01', + releaseTimestamp: '2022-01-01T00:00:00.000Z', changelogUrl: 'https://example.com', sourceUrl: 'https://example.com', constraints: { @@ -119,7 +119,7 @@ describe('modules/datasource/rubygems/schema', () => { }, { version: '3.0.0', - releaseTimestamp: '2023-01-01', + releaseTimestamp: '2023-01-01T00:00:00.000Z', changelogUrl: 'https://example.com', sourceUrl: 'https://example.com', constraints: { diff --git a/lib/modules/datasource/rubygems/schema.ts b/lib/modules/datasource/rubygems/schema.ts index 86c856cfebd3769..63e289f93e4cb18 100644 --- a/lib/modules/datasource/rubygems/schema.ts +++ b/lib/modules/datasource/rubygems/schema.ts @@ -3,6 +3,7 @@ import { z } from 'zod'; import { filterMap } from '../../../util/filter-map'; import { newlineRegex } from '../../../util/regex'; import { LooseArray } from '../../../util/schema-utils'; +import { MaybeTimestamp } from '../../../util/timestamp'; import type { Release } from '../types'; export const MarshalledVersionInfo = LooseArray( @@ -36,7 +37,7 @@ export const GemVersions = LooseArray( z .object({ number: z.string(), - created_at: z.string(), + created_at: MaybeTimestamp, platform: z.string().optional().catch(undefined), ruby_version: z.string().optional().catch(undefined), rubygems_version: z.string().optional().catch(undefined), diff --git a/lib/modules/datasource/sbt-package/index.ts b/lib/modules/datasource/sbt-package/index.ts index c956922097486c1..43697efde462452 100644 --- a/lib/modules/datasource/sbt-package/index.ts +++ b/lib/modules/datasource/sbt-package/index.ts @@ -5,6 +5,8 @@ import * as packageCache from '../../../util/cache/package'; import { cache } from '../../../util/cache/package/decorator'; import { Http } from '../../../util/http'; import { regEx } from '../../../util/regex'; +import type { Timestamp } from '../../../util/timestamp'; +import { asTimestamp } from '../../../util/timestamp'; import { ensureTrailingSlash, trimTrailingSlash } from '../../../util/url'; import * as ivyVersioning from '../../versioning/ivy'; import { compare } from '../../versioning/maven/compare'; @@ -30,7 +32,7 @@ interface ScalaDepCoordinate { interface PomInfo { homepage?: string; sourceUrl?: string; - releaseTimestamp?: string; + releaseTimestamp?: Timestamp; } export class SbtPackageDatasource extends MavenDatasource { @@ -285,7 +287,7 @@ export class SbtPackageDatasource extends MavenDatasource { const result: PomInfo = {}; - const releaseTimestamp = val.lastModified; + const releaseTimestamp = asTimestamp(val.lastModified); if (releaseTimestamp) { result.releaseTimestamp = releaseTimestamp; } diff --git a/lib/modules/datasource/terraform-module/index.ts b/lib/modules/datasource/terraform-module/index.ts index 05ff6d5e972141a..c035536d5167303 100644 --- a/lib/modules/datasource/terraform-module/index.ts +++ b/lib/modules/datasource/terraform-module/index.ts @@ -2,6 +2,7 @@ import { logger } from '../../../logger'; import { cache } from '../../../util/cache/package/decorator'; import { regEx } from '../../../util/regex'; import { coerceString } from '../../../util/string'; +import { asTimestamp } from '../../../util/timestamp'; import { isHttpUrl } from '../../../util/url'; import * as hashicorpVersioning from '../../versioning/hashicorp'; import type { GetReleasesConfig, ReleaseResult } from '../types'; @@ -128,7 +129,7 @@ export class TerraformModuleDatasource extends TerraformDatasource { (release) => res.version === release.version, ); if (latestVersion) { - latestVersion.releaseTimestamp = res.published_at; + latestVersion.releaseTimestamp = asTimestamp(res.published_at); } return dep; } diff --git a/lib/modules/datasource/terraform-provider/index.ts b/lib/modules/datasource/terraform-provider/index.ts index 81f7de33cf51a23..0f3e72dcacab757 100644 --- a/lib/modules/datasource/terraform-provider/index.ts +++ b/lib/modules/datasource/terraform-provider/index.ts @@ -5,6 +5,7 @@ import { ExternalHostError } from '../../../types/errors/external-host-error'; import { cache } from '../../../util/cache/package/decorator'; import * as p from '../../../util/promises'; import { regEx } from '../../../util/regex'; +import { asTimestamp } from '../../../util/timestamp'; import { joinUrlParts } from '../../../util/url'; import * as hashicorpVersioning from '../../versioning/hashicorp'; import { TerraformDatasource } from '../terraform-module/base'; @@ -130,7 +131,7 @@ export class TerraformProviderDatasource extends TerraformDatasource { ); // istanbul ignore else if (latestVersion) { - latestVersion.releaseTimestamp = res.published_at; + latestVersion.releaseTimestamp = asTimestamp(res.published_at); } dep.homepage = `${registryUrl}/providers/${repository}`; return dep; diff --git a/lib/modules/datasource/types.ts b/lib/modules/datasource/types.ts index aea32290d9fbce9..9e8e8300819467f 100644 --- a/lib/modules/datasource/types.ts +++ b/lib/modules/datasource/types.ts @@ -3,6 +3,7 @@ import type { CustomDatasourceConfig, } from '../../config/types'; import type { ModuleApi } from '../../types'; +import type { Timestamp } from '../../util/timestamp'; export interface GetDigestInputConfig { datasource: string; @@ -59,7 +60,7 @@ export interface Release { gitRef?: string; isDeprecated?: boolean; isStable?: boolean; - releaseTimestamp?: string | null; + releaseTimestamp?: Timestamp | null; version: string; /** The original value to which `extractVersion` was applied */ versionOrig?: string; diff --git a/lib/modules/datasource/unity3d/index.ts b/lib/modules/datasource/unity3d/index.ts index a54bbb03e61085a..e134d9aba3a667c 100644 --- a/lib/modules/datasource/unity3d/index.ts +++ b/lib/modules/datasource/unity3d/index.ts @@ -2,6 +2,7 @@ import type { XmlElement } from 'xmldoc'; import { XmlDocument } from 'xmldoc'; import { logger } from '../../../logger'; import { cache } from '../../../util/cache/package/decorator'; +import { asTimestamp } from '../../../util/timestamp'; import * as Unity3dVersioning from '../../versioning/unity3d'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, Release, ReleaseResult } from '../types'; @@ -64,7 +65,7 @@ export class Unity3dDatasource extends Datasource { const versionWithoutHash = itemNode.childNamed('title')?.val; const release: Release = { version: withHash ? versionWithHash : versionWithoutHash!, - releaseTimestamp: itemNode.childNamed('pubDate')?.val, + releaseTimestamp: asTimestamp(itemNode.childNamed('pubDate')?.val), changelogUrl: itemNode.childNamed('link')?.val, isStable: registryUrl !== Unity3dDatasource.streams.beta, registryUrl, diff --git a/lib/modules/manager/azure-pipelines/readme.md b/lib/modules/manager/azure-pipelines/readme.md index ddf32fdbce8e32e..9be81b70e8a7f64 100644 --- a/lib/modules/manager/azure-pipelines/readme.md +++ b/lib/modules/manager/azure-pipelines/readme.md @@ -44,7 +44,7 @@ resources: - container: linux image: ubuntu:24.04 - container: python - image: python:3.13@sha256:d57ec66c94b9497b9f3c66f6cdddc1e4e0bad4c584397e0b57a721baef0e6fdc + image: python:3.13@sha256:6ee79759eb6c6843f7aec973df1d3ae60f7199822669deaf77fba16a7b27d1db stages: - stage: StageOne diff --git a/lib/modules/manager/bundler/artifacts.spec.ts b/lib/modules/manager/bundler/artifacts.spec.ts index ad0ee829c84efb7..857afb0b6617116 100644 --- a/lib/modules/manager/bundler/artifacts.spec.ts +++ b/lib/modules/manager/bundler/artifacts.spec.ts @@ -679,71 +679,6 @@ describe('modules/manager/bundler/artifacts', () => { ]); }); - it('handles failure of strict updating for version solving', async () => { - const execError = new ExecError('Exec error', { - cmd: '', - stdout: '', - stderr: 'version solving has failed', - options: { encoding: 'utf8' }, - }); - fs.readLocalFile.mockResolvedValue('Current Gemfile.lock'); - const execSnapshots = mockExecSequence([ - execError, - { stdout: '', stderr: '' }, - ]); - git.getRepoStatus.mockResolvedValueOnce( - partial({ - modified: ['Gemfile.lock'], - }), - ); - - const res = await updateArtifacts({ - packageFileName: 'Gemfile', - updatedDeps: [{ depName: 'foo', updateType: 'minor' }], - newPackageFileContent: '{}', - config, - }); - - expect(res).toMatchObject([{ file: { path: 'Gemfile.lock' } }]); - expect(execSnapshots).toMatchObject([ - { cmd: 'bundler lock --minor --strict --update foo' }, - { cmd: 'bundler lock --minor --conservative --update foo' }, - ]); - }); - - it('handles failure of strict updating for missing gem', async () => { - // See https://github.com/rubygems/rubygems/issues/7369 - const execError = new ExecError('Exec error', { - cmd: '', - stdout: '', - stderr: "Could not find gems matching 'foo ", - options: { encoding: 'utf8' }, - }); - fs.readLocalFile.mockResolvedValue('Current Gemfile.lock'); - const execSnapshots = mockExecSequence([ - execError, - { stdout: '', stderr: '' }, - ]); - git.getRepoStatus.mockResolvedValueOnce( - partial({ - modified: ['Gemfile.lock'], - }), - ); - - const res = await updateArtifacts({ - packageFileName: 'Gemfile', - updatedDeps: [{ depName: 'foo', updateType: 'minor' }], - newPackageFileContent: '{}', - config, - }); - - expect(res).toMatchObject([{ file: { path: 'Gemfile.lock' } }]); - expect(execSnapshots).toMatchObject([ - { cmd: 'bundler lock --minor --strict --update foo' }, - { cmd: 'bundler lock --minor --conservative --update foo' }, - ]); - }); - it('updates the Gemfile.lock when upgrading ruby', async () => { // See https://github.com/renovatebot/renovate/issues/15114 fs.readLocalFile.mockResolvedValue('Current Gemfile.lock'); diff --git a/lib/modules/manager/bundler/artifacts.ts b/lib/modules/manager/bundler/artifacts.ts index 071bd1a652c2ce7..6dd081147cbba98 100644 --- a/lib/modules/manager/bundler/artifacts.ts +++ b/lib/modules/manager/bundler/artifacts.ts @@ -105,8 +105,8 @@ export async function updateArtifacts( } const updateTypes = { - patch: '--patch --strict ', - minor: '--minor --strict ', + patch: '--patch ', + minor: '--minor ', major: '', }; for (const [updateType, updateArg] of Object.entries(updateTypes)) { @@ -120,12 +120,9 @@ export async function updateArtifacts( additionalArgs = '--conservative '; } if (deps.length) { - let cmd = `bundler lock ${updateArg}${additionalArgs}--update ${deps + const cmd = `bundler lock ${updateArg}${additionalArgs}--update ${deps .map(quote) .join(' ')}`; - if (cmd.includes(' --conservative ')) { - cmd = cmd.replace(' --strict', ''); - } commands.push(cmd); } } @@ -226,29 +223,6 @@ export async function updateArtifacts( memCache.set('bundlerArtifactsError', BUNDLER_INVALID_CREDENTIALS); throw new Error(BUNDLER_INVALID_CREDENTIALS); } - if ( - recursionLimit > 0 && - (output.includes('version solving has failed') || - output.includes('Could not find gem')) - ) { - logger.debug('Failed to lock strictly, retrying non-strict'); - const newConfig = { - ...config, - postUpdateOptions: [ - ...(config.postUpdateOptions ?? []), - 'bundlerConservative', - ], - }; - return updateArtifacts( - { - packageFileName, - updatedDeps, - newPackageFileContent, - config: newConfig, - }, - recursionLimit - 1, - ); - } const resolveMatches: string[] = getResolvedPackages(output).filter( (depName) => !updatedDepNames.includes(depName), ); diff --git a/lib/modules/manager/haskell-cabal/extract.spec.ts b/lib/modules/manager/haskell-cabal/extract.spec.ts index 7625c210396a08f..d4f680e75f74c0b 100644 --- a/lib/modules/manager/haskell-cabal/extract.spec.ts +++ b/lib/modules/manager/haskell-cabal/extract.spec.ts @@ -2,10 +2,19 @@ import { countPackageNameLength, countPrecedingIndentation, extractNamesAndRanges, + findDepends, findExtents, splitSingleDependency, } from './extract'; +const commentCabalFile = `build-depends: + -- leading + base, +-- middle + other, + -- trailing + other2`; + describe('modules/manager/haskell-cabal/extract', () => { describe('countPackageNameLength', () => { it.each` @@ -91,4 +100,14 @@ describe('modules/manager/haskell-cabal/extract', () => { ]); }); }); + + describe('findDepends()', () => { + it('strips comments', () => { + const res = findDepends(commentCabalFile + '\na: b'); + expect(res).toEqual({ + buildDependsContent: '\n base,\n other,\n other2', + lengthProcessed: commentCabalFile.length, + }); + }); + }); }); diff --git a/lib/modules/manager/haskell-cabal/extract.ts b/lib/modules/manager/haskell-cabal/extract.ts index 80231c3e5c7a932..7abeee0c78e6dbb 100644 --- a/lib/modules/manager/haskell-cabal/extract.ts +++ b/lib/modules/manager/haskell-cabal/extract.ts @@ -3,6 +3,7 @@ import { regEx } from '../../../util/regex'; const buildDependsRegex = regEx( /(?build-depends[ \t]*:)/i, ); +const commentRegex = regEx(/^[ \t]*--/); function isNonASCII(str: string): boolean { for (let i = 0; i < str.length; i++) { if (str.charCodeAt(i) > 127) { @@ -86,6 +87,11 @@ export function findExtents(indent: number, content: string): number { break; } if (thisIndent < indent) { + if (content.slice(blockIdx - 1, blockIdx + 1) === '--') { + // not enough indention, but the line is a comment, so include it + mode = 'finding-newline'; + continue; + } // go back to before the newline for (;;) { if (content[blockIdx--] === '\n') { @@ -125,7 +131,8 @@ export function countPrecedingIndentation( * * @returns {{buildDependsContent: string, lengthProcessed: number}} * buildDependsContent: - * the contents of the field, excluding the field name and the colon. + * the contents of the field, excluding the field name and the colon, + * and any comments within * * lengthProcessed: * points to after the end of the field. Note that the field does _not_ @@ -143,10 +150,19 @@ export function findDepends( const indent = countPrecedingIndentation(content, matchObj.index); const ourIdx: number = matchObj.index + matchObj.groups['buildDependsFieldName'].length; - const extent: number = findExtents(indent + 1, content.slice(ourIdx)); + const extentLength: number = findExtents(indent + 1, content.slice(ourIdx)); + const extent = content.slice(ourIdx, ourIdx + extentLength); + const lines = []; + // Windows-style line breaks are fine because + // carriage returns are before the line feed. + for (const maybeCommentLine of extent.split('\n')) { + if (!commentRegex.test(maybeCommentLine)) { + lines.push(maybeCommentLine); + } + } return { - buildDependsContent: content.slice(ourIdx, ourIdx + extent), - lengthProcessed: ourIdx + extent, + buildDependsContent: lines.join('\n'), + lengthProcessed: ourIdx + extentLength, }; } diff --git a/lib/modules/manager/npm/extract/pnpm.spec.ts b/lib/modules/manager/npm/extract/pnpm.spec.ts index 5a18700e4a1f6a3..73ad5be0f513308 100644 --- a/lib/modules/manager/npm/extract/pnpm.spec.ts +++ b/lib/modules/manager/npm/extract/pnpm.spec.ts @@ -1,7 +1,6 @@ import { Fixtures } from '../../../../../test/fixtures'; -import { getFixturePath, logger, partial } from '../../../../../test/util'; +import { fs, getFixturePath, logger, partial } from '../../../../../test/util'; import { GlobalConfig } from '../../../../config/global'; -import * as fs from '../../../../util/fs'; import * as yaml from '../../../../util/yaml'; import type { PackageFile } from '../../types'; import type { NpmManagerData } from '../types'; @@ -12,6 +11,8 @@ import { getPnpmLock, } from './pnpm'; +jest.mock('../../../../util/fs'); + describe('modules/manager/npm/extract/pnpm', () => { beforeAll(() => { GlobalConfig.set({ localDir: getFixturePath('pnpm-monorepo/', '..') }); @@ -23,9 +24,7 @@ describe('modules/manager/npm/extract/pnpm', () => { describe('.extractPnpmFilters()', () => { it('detects errors in pnpm-workspace.yml file structure', async () => { - jest - .spyOn(fs, 'readLocalFile') - .mockResolvedValueOnce('p!!!ckages:\n - "packages/*"'); + fs.readLocalFile.mockResolvedValueOnce('p!!!ckages:\n - "packages/*"'); const workSpaceFilePath = getFixturePath( 'pnpm-monorepo/pnpm-workspace.yml', @@ -60,7 +59,7 @@ describe('modules/manager/npm/extract/pnpm', () => { describe('.findPnpmWorkspace()', () => { it('detects missing pnpm-workspace.yaml', async () => { - jest.spyOn(fs, 'findLocalSiblingOrParent').mockResolvedValueOnce(null); + fs.findLocalSiblingOrParent.mockResolvedValueOnce(null); const packageFile = 'package.json'; const res = await findPnpmWorkspace(packageFile); @@ -72,10 +71,8 @@ describe('modules/manager/npm/extract/pnpm', () => { }); it('detects missing pnpm-lock.yaml when pnpm-workspace.yaml was already found', async () => { - jest - .spyOn(fs, 'findLocalSiblingOrParent') - .mockResolvedValueOnce('pnpm-workspace.yaml'); - jest.spyOn(fs, 'localPathExists').mockResolvedValueOnce(false); + fs.findLocalSiblingOrParent.mockResolvedValueOnce('pnpm-workspace.yaml'); + fs.localPathExists.mockResolvedValueOnce(false); const packageFile = 'package.json'; const res = await findPnpmWorkspace(packageFile); @@ -91,7 +88,23 @@ describe('modules/manager/npm/extract/pnpm', () => { }); describe('.detectPnpmWorkspaces()', () => { + beforeEach(() => { + const realFs = jest.requireActual('../../../../util/fs'); + + // The real implementations of these functions are used for this block; + // they do static path manipulation. + fs.findLocalSiblingOrParent.mockImplementation( + realFs.findLocalSiblingOrParent, + ); + fs.getSiblingFileName.mockImplementation(realFs.getSiblingFileName); + + // Falls through to reading from the fixture path defined in GlobalConfig + // at the top of this file + fs.readLocalFile.mockImplementation(realFs.readLocalFile); + }); + it('uses pnpm workspaces', async () => { + fs.localPathExists.mockResolvedValue(true); const packageFiles = partial>([ { packageFile: 'package.json', @@ -197,6 +210,7 @@ describe('modules/manager/npm/extract/pnpm', () => { }); it('filters none matching packages', async () => { + fs.localPathExists.mockResolvedValue(true); const packageFiles = [ { packageFile: 'package.json', @@ -242,14 +256,14 @@ describe('modules/manager/npm/extract/pnpm', () => { describe('.getPnpmLock()', () => { it('returns empty if failed to parse', async () => { - jest.spyOn(fs, 'readLocalFile').mockResolvedValueOnce(undefined as never); + fs.readLocalFile.mockResolvedValueOnce(undefined as never); const res = await getPnpmLock('package.json'); expect(res.lockedVersionsWithPath).toBeUndefined(); }); it('extracts version from monorepo', async () => { const plocktest1Lock = Fixtures.get('pnpm-monorepo/pnpm-lock.yaml', '..'); - jest.spyOn(fs, 'readLocalFile').mockResolvedValueOnce(plocktest1Lock); + fs.readLocalFile.mockResolvedValueOnce(plocktest1Lock); const res = await getPnpmLock('package.json'); expect(Object.keys(res.lockedVersionsWithPath!)).toHaveLength(11); }); @@ -259,13 +273,13 @@ describe('modules/manager/npm/extract/pnpm', () => { 'lockfile-parsing/pnpm-lock.yaml', '..', ); - jest.spyOn(fs, 'readLocalFile').mockResolvedValueOnce(plocktest1Lock); + fs.readLocalFile.mockResolvedValueOnce(plocktest1Lock); const res = await getPnpmLock('package.json'); expect(Object.keys(res.lockedVersionsWithPath!)).toHaveLength(1); }); it('returns empty if no deps', async () => { - jest.spyOn(fs, 'readLocalFile').mockResolvedValueOnce('{}'); + fs.readLocalFile.mockResolvedValueOnce('{}'); const res = await getPnpmLock('package.json'); expect(res.lockedVersionsWithPath).toBeUndefined(); }); diff --git a/lib/modules/manager/nuget/artifacts.spec.ts b/lib/modules/manager/nuget/artifacts.spec.ts index 4dfbbc4a04de05f..33a7465d63028b4 100644 --- a/lib/modules/manager/nuget/artifacts.spec.ts +++ b/lib/modules/manager/nuget/artifacts.spec.ts @@ -15,7 +15,7 @@ jest.mock('../../../util/host-rules', () => mockDeep()); jest.mock('../../../util/git'); jest.mock('./util'); -const { getDefaultRegistries } = mocked(util); +const { getDefaultRegistries, findGlobalJson } = mocked(util); process.env.CONTAINERBASE = 'true'; @@ -230,12 +230,14 @@ describe('modules/manager/nuget/artifacts', () => { fs.getLocalFiles.mockResolvedValueOnce({ 'packages.lock.json': 'New packages.lock.json', }); + + findGlobalJson.mockResolvedValueOnce({ sdk: { version: '7.0.100' } }); expect( await nuget.updateArtifacts({ packageFileName: 'project.csproj', updatedDeps: [{ depName: 'dep' }], newPackageFileContent: '{}', - config: { ...config, constraints: { dotnet: '7.0.100' } }, + config, }), ).toEqual([ { diff --git a/lib/modules/manager/nuget/artifacts.ts b/lib/modules/manager/nuget/artifacts.ts index c60e04262e63637..88dcdd92e89471c 100644 --- a/lib/modules/manager/nuget/artifacts.ts +++ b/lib/modules/manager/nuget/artifacts.ts @@ -25,7 +25,11 @@ import { NUGET_CENTRAL_FILE, getDependentPackageFiles, } from './package-tree'; -import { getConfiguredRegistries, getDefaultRegistries } from './util'; +import { + findGlobalJson, + getConfiguredRegistries, + getDefaultRegistries, +} from './util'; async function createCachedNuGetConfigFile( nugetCacheDir: string, @@ -55,6 +59,9 @@ async function runDotnetRestore( packageFileName, ); + const dotnetVersion = + config.constraints?.dotnet ?? + (await findGlobalJson(packageFileName))?.sdk?.version; const execOptions: ExecOptions = { docker: {}, userConfiguredEnv: config.env, @@ -62,9 +69,7 @@ async function runDotnetRestore( NUGET_PACKAGES: join(nugetCacheDir, 'packages'), MSBUILDDISABLENODEREUSE: '1', }, - toolConstraints: [ - { toolName: 'dotnet', constraint: config.constraints?.dotnet }, - ], + toolConstraints: [{ toolName: 'dotnet', constraint: dotnetVersion }], }; const cmds = [ diff --git a/lib/modules/manager/nuget/extract/global-manifest.ts b/lib/modules/manager/nuget/extract/global-manifest.ts index ae9c6e9f99c0427..d7e36b7f66c8ead 100644 --- a/lib/modules/manager/nuget/extract/global-manifest.ts +++ b/lib/modules/manager/nuget/extract/global-manifest.ts @@ -2,11 +2,8 @@ import { logger } from '../../../../logger'; import { DotnetVersionDatasource } from '../../../datasource/dotnet-version'; import { NugetDatasource } from '../../../datasource/nuget'; import type { PackageDependency, PackageFileContent } from '../../types'; -import type { - MsbuildGlobalManifest, - NugetPackageDependency, - Registry, -} from '../types'; +import { GlobalJson } from '../schema'; +import type { NugetPackageDependency, Registry } from '../types'; import { applyRegistries } from '../util'; export function extractMsbuildGlobalManifest( @@ -15,10 +12,10 @@ export function extractMsbuildGlobalManifest( registries: Registry[] | undefined, ): PackageFileContent | null { const deps: PackageDependency[] = []; - let manifest: MsbuildGlobalManifest; + let manifest: GlobalJson; let extractedConstraints: Record | undefined; try { - manifest = JSON.parse(content); + manifest = GlobalJson.parse(content); } catch { logger.debug({ packageFile }, `Invalid JSON`); return null; diff --git a/lib/modules/manager/nuget/schema.ts b/lib/modules/manager/nuget/schema.ts new file mode 100644 index 000000000000000..c71dabc94a1fc17 --- /dev/null +++ b/lib/modules/manager/nuget/schema.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; +import { Jsonc } from '../../../util/schema-utils'; + +/** + * The roll-forward policy to use when selecting an SDK version, either as a fallback when a specific SDK version is missing or as a directive to use a later version. A version must be specified with a rollForward value, unless you're setting it to latestMajor. The default roll forward behavior is determined by the matching rules. + * + * https://learn.microsoft.com/de-de/dotnet/core/tools/global-json#rollforward + */ +const RollForwardSchema = z.enum([ + 'patch', + 'feature', + 'minor', + 'major', + 'latestPatch', + 'latestFeature', + 'latestMinor', + 'latestMajor', + 'disable', +]); +export type RollForward = z.infer; + +/** + * global.json schema + * + * https://learn.microsoft.com/en-us/dotnet/core/tools/global-json#allowprerelease + */ +export const GlobalJsonSchema = z.object({ + /** + * Specifies information about the .NET SDK to select. + */ + sdk: z + .object({ + /** + * The version of the .NET SDK to use. + * + * https://learn.microsoft.com/de-de/dotnet/core/tools/global-json#version + */ + version: z.string().optional(), + /** + * The roll-forward policy to use when selecting an SDK version, either as a fallback when a specific SDK version is missing or as a directive to use a later version. A version must be specified with a rollForward value, unless you're setting it to latestMajor. The default roll forward behavior is determined by the matching rules. + * + * https://learn.microsoft.com/de-de/dotnet/core/tools/global-json#rollforward + */ + rollForward: RollForwardSchema.optional(), + /** + * Indicates whether the SDK resolver should consider prerelease versions when selecting the SDK version to use. + * + * https://learn.microsoft.com/de-de/dotnet/core/tools/global-json#allowprerelease + */ + allowPrerelease: z.boolean().optional(), + }) + .optional(), + + /** + * Lets you control the project SDK version in one place rather than in each individual project. For more information, see How project SDKs are resolved. + * + * https://learn.microsoft.com/de-de/dotnet/core/tools/global-json#msbuild-sdks + */ + 'msbuild-sdks': z.record(z.string()).optional(), +}); + +export const GlobalJson = Jsonc.pipe(GlobalJsonSchema); +export type GlobalJson = z.infer; diff --git a/lib/modules/manager/nuget/types.ts b/lib/modules/manager/nuget/types.ts index 0eef41beaf9885b..9d34b776f14fb81 100644 --- a/lib/modules/manager/nuget/types.ts +++ b/lib/modules/manager/nuget/types.ts @@ -17,17 +17,6 @@ export interface Registry { readonly name?: string; sourceMappedPackagePatterns?: string[]; } - -export interface MsbuildGlobalManifest { - readonly sdk?: MsbuildSdk; - readonly 'msbuild-sdks'?: Record; -} - -export interface MsbuildSdk { - readonly version: string; - readonly rollForward: string; -} - export interface ProjectFile { readonly isLeaf: boolean; readonly name: string; diff --git a/lib/modules/manager/nuget/util.spec.ts b/lib/modules/manager/nuget/util.spec.ts index 0956e2014c03830..a1a01dec1040d1e 100644 --- a/lib/modules/manager/nuget/util.spec.ts +++ b/lib/modules/manager/nuget/util.spec.ts @@ -3,7 +3,12 @@ import { XmlDocument } from 'xmldoc'; import { fs } from '../../../../test/util'; import type { Registry } from './types'; import { bumpPackageVersion } from './update'; -import { applyRegistries, findVersion, getConfiguredRegistries } from './util'; +import { + applyRegistries, + findGlobalJson, + findVersion, + getConfiguredRegistries, +} from './util'; jest.mock('../../../util/fs'); @@ -340,4 +345,34 @@ describe('modules/manager/nuget/util', () => { }); }); }); + + describe('findGlobalJson', () => { + it('not found', async () => { + fs.findLocalSiblingOrParent.mockResolvedValueOnce(null); + const globalJson = await findGlobalJson('project.csproj'); + expect(globalJson).toBeNull(); + }); + + it('no content', async () => { + fs.findLocalSiblingOrParent.mockResolvedValueOnce('global.json'); + const globalJson = await findGlobalJson('project.csproj'); + expect(globalJson).toBeNull(); + }); + + it('fails to parse', async () => { + fs.findLocalSiblingOrParent.mockResolvedValueOnce('global.json'); + fs.readLocalFile.mockResolvedValueOnce('{'); + const globalJson = await findGlobalJson('project.csproj'); + expect(globalJson).toBeNull(); + }); + + it('parses', async () => { + fs.findLocalSiblingOrParent.mockResolvedValueOnce('global.json'); + fs.readLocalFile.mockResolvedValueOnce( + '{ /* This is comment */ "sdk": { "version": "5.0.100" }, "some": true }', + ); + const globalJson = await findGlobalJson('project.csproj'); + expect(globalJson).toEqual({ sdk: { version: '5.0.100' } }); + }); + }); }); diff --git a/lib/modules/manager/nuget/util.ts b/lib/modules/manager/nuget/util.ts index dd210357d3a863b..3f04f4318e758bc 100644 --- a/lib/modules/manager/nuget/util.ts +++ b/lib/modules/manager/nuget/util.ts @@ -2,10 +2,15 @@ import upath from 'upath'; import type { XmlElement } from 'xmldoc'; import { XmlDocument } from 'xmldoc'; import { logger } from '../../../logger'; -import { findUpLocal, readLocalFile } from '../../../util/fs'; +import { + findLocalSiblingOrParent, + findUpLocal, + readLocalFile, +} from '../../../util/fs'; import { minimatch } from '../../../util/minimatch'; import { regEx } from '../../../util/regex'; import { nugetOrg } from '../../datasource/nuget'; +import { GlobalJson } from './schema'; import type { NugetPackageDependency, Registry } from './types'; export async function readFileAsXmlDocument( @@ -207,3 +212,31 @@ function sortPatterns( return a[0].localeCompare(b[0]) * -1; } + +export async function findGlobalJson( + packageFile: string, +): Promise { + const globalJsonPath = await findLocalSiblingOrParent( + packageFile, + 'global.json', + ); + if (!globalJsonPath) { + return null; + } + + const content = await readLocalFile(globalJsonPath, 'utf8'); + if (!content) { + logger.debug({ packageFile, globalJsonPath }, 'Failed to read global.json'); + return null; + } + + const result = await GlobalJson.safeParseAsync(content); + if (!result.success) { + logger.debug( + { packageFile, globalJsonPath, err: result.error }, + 'Failed to parse global.json', + ); + return null; + } + return result.data; +} diff --git a/lib/modules/manager/types.ts b/lib/modules/manager/types.ts index 6c93b44a19556af..0937191789a0b64 100644 --- a/lib/modules/manager/types.ts +++ b/lib/modules/manager/types.ts @@ -14,6 +14,7 @@ import type { } from '../../types'; import type { FileChange } from '../../util/git/types'; import type { MergeConfidence } from '../../util/merge-confidence/types'; +import type { Timestamp } from '../../util/timestamp'; import type { CustomExtractConfig } from './custom/types'; export type MaybePromise = T | Promise; @@ -103,7 +104,7 @@ export interface LookupUpdate { userStrings?: Record; checksumUrl?: string; downloadUrl?: string; - releaseTimestamp?: any; + releaseTimestamp?: Timestamp; newVersionAgeInDays?: number; registryUrl?: string; libYears?: number; diff --git a/lib/modules/versioning/cargo/index.spec.ts b/lib/modules/versioning/cargo/index.spec.ts index 8198b12f4055929..0c5e6a5ae52a5f7 100644 --- a/lib/modules/versioning/cargo/index.spec.ts +++ b/lib/modules/versioning/cargo/index.spec.ts @@ -132,6 +132,7 @@ describe('modules/versioning/cargo/index', () => { ${'5.0'} | ${'bump'} | ${'5.0.0'} | ${'6.1.7'} | ${'6.1.7'} ${'0.5'} | ${'bump'} | ${'0.5.0'} | ${'0.5.1'} | ${'0.5.1'} ${'0.5'} | ${'bump'} | ${'0.5.0'} | ${'0.6.1'} | ${'0.6.1'} + ${'1.2'} | ${'replace'} | ${'1.2.3'} | ${'1.3.0'} | ${'1.2'} ${'5.0'} | ${'replace'} | ${'5.0.0'} | ${'5.1.7'} | ${'5.0'} ${'5.0'} | ${'replace'} | ${'5.0.0'} | ${'6.1.7'} | ${'6.0'} ${'0.5'} | ${'replace'} | ${'0.5.0'} | ${'0.6.1'} | ${'0.6'} diff --git a/lib/modules/versioning/cargo/index.ts b/lib/modules/versioning/cargo/index.ts index c78fc095cecfcbb..e8309f06a6826c2 100644 --- a/lib/modules/versioning/cargo/index.ts +++ b/lib/modules/versioning/cargo/index.ts @@ -106,6 +106,9 @@ function getNewValue({ res += newVersion; return res; } + if (rangeStrategy === 'replace' && matches(newVersion, currentValue)) { + return currentValue; + } const newSemver = npm.getNewValue({ currentValue: cargo2npm(currentValue), rangeStrategy, @@ -142,6 +145,7 @@ function getNewValue({ const components = currentValue.split('.').length; newCargo = withoutCaret.split('.').slice(0, components).join('.'); } + return newCargo; } diff --git a/lib/util/github/graphql/cache-strategies/memory-cache-strategy.spec.ts b/lib/util/github/graphql/cache-strategies/memory-cache-strategy.spec.ts index ac1abbb09b38fa1..8fb5f1849ae9ac3 100644 --- a/lib/util/github/graphql/cache-strategies/memory-cache-strategy.spec.ts +++ b/lib/util/github/graphql/cache-strategies/memory-cache-strategy.spec.ts @@ -1,6 +1,7 @@ import { DateTime, Settings } from 'luxon'; import * as memCache from '../../../cache/memory'; import { clone } from '../../../clone'; +import type { Timestamp } from '../../../timestamp'; import type { GithubDatasourceItem, GithubGraphqlCacheRecord } from '../types'; import { GithubGraphqlMemoryCacheStrategy } from './memory-cache-strategy'; @@ -21,7 +22,7 @@ const isoTs = (t: string) => { } else { throw new Error('Unrecognized date-time string. ' + t); } - return iso; + return iso as Timestamp; }; const mockTime = (input: string): void => { diff --git a/lib/util/github/graphql/cache-strategies/package-cache-strategy.spec.ts b/lib/util/github/graphql/cache-strategies/package-cache-strategy.spec.ts index eb386ca9e6f21da..4208ff1bb5ac1f5 100644 --- a/lib/util/github/graphql/cache-strategies/package-cache-strategy.spec.ts +++ b/lib/util/github/graphql/cache-strategies/package-cache-strategy.spec.ts @@ -1,10 +1,11 @@ import { DateTime, Settings } from 'luxon'; +import type { Timestamp } from '../../../../util/timestamp'; import * as packageCache from '../../../cache/package'; import { clone } from '../../../clone'; import type { GithubDatasourceItem, GithubGraphqlCacheRecord } from '../types'; import { GithubGraphqlPackageCacheStrategy } from './package-cache-strategy'; -const isoTs = (t: string) => t.replace(' ', 'T') + ':00.000Z'; +const isoTs = (t: string) => (t.replace(' ', 'T') + ':00.000Z') as Timestamp; const mockTime = (input: string): void => { const now = DateTime.fromISO(isoTs(input)).valueOf(); diff --git a/lib/util/github/graphql/datasource-fetcher.spec.ts b/lib/util/github/graphql/datasource-fetcher.spec.ts index ba139bf80a4c330..7046905135fbef2 100644 --- a/lib/util/github/graphql/datasource-fetcher.spec.ts +++ b/lib/util/github/graphql/datasource-fetcher.spec.ts @@ -2,6 +2,7 @@ import AggregateError from 'aggregate-error'; import * as httpMock from '../../../../test/http-mock'; import { mocked, partial } from '../../../../test/util'; import * as _packageCache from '../../../util/cache/package'; +import type { Timestamp } from '../../../util/timestamp'; import type { GithubGraphqlResponse } from '../../http/github'; import { GithubHttp } from '../../http/github'; import { range } from '../../range'; @@ -54,7 +55,7 @@ const adapter: GithubGraphqlDatasourceAdapter< version && releaseTimestamp && foo ? { version, - releaseTimestamp, + releaseTimestamp: releaseTimestamp as Timestamp, bar: foo, } : null, diff --git a/lib/util/github/graphql/index.spec.ts b/lib/util/github/graphql/index.spec.ts index a234bac6dd19c06..0a01cfebd03c4cd 100644 --- a/lib/util/github/graphql/index.spec.ts +++ b/lib/util/github/graphql/index.spec.ts @@ -72,7 +72,7 @@ describe('util/github/graphql/index', () => { expect(res).toEqual([ { version: '1.2.3', - releaseTimestamp: '2024-09-24', + releaseTimestamp: '2024-09-24T00:00:00.000Z', url: 'https://example.com', id: 123, name: 'name', diff --git a/lib/util/github/graphql/query-adapters/releases-query-adapter.spec.ts b/lib/util/github/graphql/query-adapters/releases-query-adapter.spec.ts index 7e874c311eff300..bd1620fe2cc5e5f 100644 --- a/lib/util/github/graphql/query-adapters/releases-query-adapter.spec.ts +++ b/lib/util/github/graphql/query-adapters/releases-query-adapter.spec.ts @@ -1,9 +1,10 @@ +import type { Timestamp } from '../../../../util/timestamp'; import { adapter } from './releases-query-adapter'; import type { GithubGraphqlRelease } from './releases-query-adapter'; const item: GithubGraphqlRelease = { version: '1.2.3', - releaseTimestamp: '2024-09-24', + releaseTimestamp: '2024-09-24' as Timestamp, isDraft: false, isPrerelease: false, url: 'https://example.com', @@ -18,7 +19,7 @@ describe('util/github/graphql/query-adapters/releases-query-adapter', () => { description: 'description', id: 123, name: 'name', - releaseTimestamp: '2024-09-24', + releaseTimestamp: '2024-09-24T00:00:00.000Z' as Timestamp, url: 'https://example.com', version: '1.2.3', }); diff --git a/lib/util/github/graphql/query-adapters/releases-query-adapter.ts b/lib/util/github/graphql/query-adapters/releases-query-adapter.ts index 65cf0cfb10a2d56..7fe39e8bf908e1e 100644 --- a/lib/util/github/graphql/query-adapters/releases-query-adapter.ts +++ b/lib/util/github/graphql/query-adapters/releases-query-adapter.ts @@ -1,4 +1,5 @@ import { z } from 'zod'; +import { Timestamp } from '../../../timestamp'; import type { GithubGraphqlDatasourceAdapter, GithubReleaseItem, @@ -32,7 +33,7 @@ const query = prepareQuery(` const GithubGraphqlRelease = z.object({ version: z.string(), - releaseTimestamp: z.string(), + releaseTimestamp: Timestamp, isDraft: z.boolean(), isPrerelease: z.boolean(), url: z.string(), diff --git a/lib/util/github/graphql/query-adapters/tags-query-adapter.spec.ts b/lib/util/github/graphql/query-adapters/tags-query-adapter.spec.ts index 07a83d1536feb3b..ac6f68968f32538 100644 --- a/lib/util/github/graphql/query-adapters/tags-query-adapter.spec.ts +++ b/lib/util/github/graphql/query-adapters/tags-query-adapter.spec.ts @@ -1,3 +1,4 @@ +import type { Timestamp } from '../../../../util/timestamp'; import { adapter } from './tags-query-adapter'; describe('util/github/graphql/query-adapters/tags-query-adapter', () => { @@ -8,14 +9,14 @@ describe('util/github/graphql/query-adapters/tags-query-adapter', () => { target: { type: 'Commit', oid: 'abc123', - releaseTimestamp: '2022-09-24', + releaseTimestamp: '2022-09-24' as Timestamp, }, }), ).toEqual({ version: '1.2.3', gitRef: '1.2.3', hash: 'abc123', - releaseTimestamp: '2022-09-24', + releaseTimestamp: '2022-09-24' as Timestamp, }); }); @@ -26,14 +27,14 @@ describe('util/github/graphql/query-adapters/tags-query-adapter', () => { target: { type: 'Tag', target: { oid: 'abc123' }, - tagger: { releaseTimestamp: '2022-09-24' }, + tagger: { releaseTimestamp: '2022-09-24' as Timestamp }, }, }), ).toEqual({ version: '1.2.3', gitRef: '1.2.3', hash: 'abc123', - releaseTimestamp: '2022-09-24', + releaseTimestamp: '2022-09-24' as Timestamp, }); }); diff --git a/lib/util/github/graphql/query-adapters/tags-query-adapter.ts b/lib/util/github/graphql/query-adapters/tags-query-adapter.ts index 0fbb2cf7728ccc0..bdc847b55d92c60 100644 --- a/lib/util/github/graphql/query-adapters/tags-query-adapter.ts +++ b/lib/util/github/graphql/query-adapters/tags-query-adapter.ts @@ -1,4 +1,5 @@ import { z } from 'zod'; +import { Timestamp } from '../../../timestamp'; import type { GithubGraphqlDatasourceAdapter, GithubTagItem } from '../types'; import { prepareQuery } from '../util'; @@ -10,7 +11,7 @@ const GithubGraphqlTag = z.object({ z.object({ type: z.literal('Commit'), oid: z.string(), - releaseTimestamp: z.string(), + releaseTimestamp: Timestamp, }), z.object({ type: z.literal('Tag'), @@ -18,7 +19,7 @@ const GithubGraphqlTag = z.object({ oid: z.string(), }), tagger: z.object({ - releaseTimestamp: z.string(), + releaseTimestamp: Timestamp, }), }), ]), diff --git a/lib/util/github/graphql/types.ts b/lib/util/github/graphql/types.ts index 61c8f864300786e..ed0f8bd51fd36eb 100644 --- a/lib/util/github/graphql/types.ts +++ b/lib/util/github/graphql/types.ts @@ -1,8 +1,9 @@ import type { PackageCacheNamespace } from '../../cache/package/types'; +import type { Timestamp } from '../../timestamp'; export interface GithubDatasourceItem { version: string; - releaseTimestamp: string; + releaseTimestamp: Timestamp; } /** diff --git a/lib/util/github/tags.spec.ts b/lib/util/github/tags.spec.ts index 5eb4a304404ed10..ff811d09eaea7f2 100644 --- a/lib/util/github/tags.spec.ts +++ b/lib/util/github/tags.spec.ts @@ -1,3 +1,4 @@ +import type { Timestamp } from '../../util/timestamp'; import { GithubHttp } from '../http/github'; import * as githubGraphql from './graphql'; import { findCommitOfTag } from './tags'; @@ -12,13 +13,13 @@ describe('util/github/tags', () => { { version: 'v1.0.0', gitRef: 'v1.0.0', - releaseTimestamp: '2021-01-01', + releaseTimestamp: '2021-01-01' as Timestamp, hash: '123', }, { version: 'v2.0.0', gitRef: 'v2.0.0', - releaseTimestamp: '2022-01-01', + releaseTimestamp: '2022-01-01' as Timestamp, hash: 'abc', }, ]); diff --git a/lib/util/http/cache/abstract-http-cache-provider.ts b/lib/util/http/cache/abstract-http-cache-provider.ts index 938e60b836dca61..3204cd24bf0d284 100644 --- a/lib/util/http/cache/abstract-http-cache-provider.ts +++ b/lib/util/http/cache/abstract-http-cache-provider.ts @@ -2,8 +2,8 @@ import { logger } from '../../../logger'; import { HttpCacheStats } from '../../stats'; import type { GotOptions, HttpResponse } from '../types'; import { copyResponse } from '../util'; -import { HttpCacheSchema } from './schema'; -import type { HttpCache, HttpCacheProvider } from './types'; +import { type HttpCache, HttpCacheSchema } from './schema'; +import type { HttpCacheProvider } from './types'; export abstract class AbstractHttpCacheProvider implements HttpCacheProvider { protected abstract load(url: string): Promise; diff --git a/lib/util/http/cache/repository-http-cache-provider.spec.ts b/lib/util/http/cache/repository-http-cache-provider.spec.ts index da8c1806d03cd25..5b070114cee82dc 100644 --- a/lib/util/http/cache/repository-http-cache-provider.spec.ts +++ b/lib/util/http/cache/repository-http-cache-provider.spec.ts @@ -1,7 +1,7 @@ import { Http } from '..'; import * as httpMock from '../../../../test/http-mock'; import { logger } from '../../../../test/util'; -import { getCache, resetCache } from '../../cache/repository'; +import { resetCache } from '../../cache/repository'; import { repoCacheProvider } from './repository-http-cache-provider'; describe('util/http/cache/repository-http-cache-provider', () => { @@ -59,27 +59,6 @@ describe('util/http/cache/repository-http-cache-provider', () => { }); }); - it('uses older cache format', async () => { - const repoCache = getCache(); - repoCache.httpCache = { - 'https://example.com/foo/bar': { - etag: '123', - lastModified: 'Mon, 01 Jan 2000 00:00:00 GMT', - httpResponse: { statusCode: 200, body: { msg: 'Hello, world!' } }, - timeStamp: new Date().toISOString(), - }, - }; - httpMock.scope('https://example.com').get('/foo/bar').reply(304); - - const res = await http.getJsonUnchecked('https://example.com/foo/bar'); - - expect(res).toMatchObject({ - statusCode: 200, - body: { msg: 'Hello, world!' }, - authorization: false, - }); - }); - it('reports if cache could not be persisted', async () => { httpMock .scope('https://example.com') diff --git a/lib/util/http/cache/repository-http-cache-provider.ts b/lib/util/http/cache/repository-http-cache-provider.ts index 9cf9c8cfa3b0c13..8ec1909d19497ad 100644 --- a/lib/util/http/cache/repository-http-cache-provider.ts +++ b/lib/util/http/cache/repository-http-cache-provider.ts @@ -1,6 +1,6 @@ import { getCache } from '../../cache/repository'; import { AbstractHttpCacheProvider } from './abstract-http-cache-provider'; -import type { HttpCache } from './types'; +import type { HttpCache } from './schema'; export class RepositoryHttpCacheProvider extends AbstractHttpCacheProvider { override load(url: string): Promise { diff --git a/lib/util/http/cache/schema.ts b/lib/util/http/cache/schema.ts index d1d71fda9bc61aa..c9b9db1e291d92e 100644 --- a/lib/util/http/cache/schema.ts +++ b/lib/util/http/cache/schema.ts @@ -1,34 +1,16 @@ import { z } from 'zod'; -const invalidFieldsMsg = - 'Cache object should have `etag` or `lastModified` fields'; - export const HttpCacheSchema = z .object({ - // TODO: remove this migration part during the Christmas eve 2024 - timeStamp: z.string().optional(), - timestamp: z.string().optional(), - }) - .passthrough() - .transform((data) => { - if (data.timeStamp) { - data.timestamp = data.timeStamp; - delete data.timeStamp; - } - return data; + etag: z.string().optional(), + lastModified: z.string().optional(), + httpResponse: z.unknown(), + timestamp: z.string(), }) - .pipe( - z - .object({ - etag: z.string().optional(), - lastModified: z.string().optional(), - httpResponse: z.unknown(), - timestamp: z.string(), - }) - .refine( - ({ etag, lastModified }) => etag ?? lastModified, - invalidFieldsMsg, - ), + .refine( + ({ etag, lastModified }) => etag ?? lastModified, + 'Cache object should have `etag` or `lastModified` fields', ) .nullable() .catch(null); +export type HttpCache = z.infer; diff --git a/lib/util/http/cache/types.ts b/lib/util/http/cache/types.ts index 1159f58028762f8..d6ab8831129ac16 100644 --- a/lib/util/http/cache/types.ts +++ b/lib/util/http/cache/types.ts @@ -1,12 +1,5 @@ import type { GotOptions, HttpResponse } from '../types'; -export interface HttpCache { - etag?: string; - lastModified?: string; - httpResponse: unknown; - timestamp: string; -} - export interface HttpCacheProvider { setCacheHeaders>( url: string, diff --git a/lib/util/timestamp.spec.ts b/lib/util/timestamp.spec.ts index 1926ea478aed719..9b7efe3732c2a81 100644 --- a/lib/util/timestamp.spec.ts +++ b/lib/util/timestamp.spec.ts @@ -1,4 +1,4 @@ -import { TimestampSchema, asTimestamp } from './timestamp'; +import { MaybeTimestamp, asTimestamp } from './timestamp'; describe('util/timestamp', () => { describe('asTimestamp', () => { @@ -33,9 +33,7 @@ describe('util/timestamp', () => { ${'202x0101000000'} | ${null} `('$input -> $expected', ({ input, expected }) => { expect(asTimestamp(input)).toBe(expected); - expect(TimestampSchema.nullable().catch(null).parse(input)).toBe( - expected, - ); + expect(MaybeTimestamp.parse(input)).toBe(expected); }); }); }); diff --git a/lib/util/timestamp.ts b/lib/util/timestamp.ts index 5c0e3d32b9c9c15..adf44b1c346ca26 100644 --- a/lib/util/timestamp.ts +++ b/lib/util/timestamp.ts @@ -87,7 +87,7 @@ export function asTimestamp(input: unknown): Timestamp | null { return null; } -export const TimestampSchema = z.unknown().transform((input, ctx) => { +export const Timestamp = z.unknown().transform((input, ctx) => { const timestamp = asTimestamp(input); if (!timestamp) { ctx.addIssue({ @@ -99,3 +99,4 @@ export const TimestampSchema = z.unknown().transform((input, ctx) => { return timestamp; }); +export const MaybeTimestamp = Timestamp.nullable().catch(null); diff --git a/lib/workers/global/limits.spec.ts b/lib/workers/global/limits.spec.ts index 84dc44687e5c408..2a3b43997faca03 100644 --- a/lib/workers/global/limits.spec.ts +++ b/lib/workers/global/limits.spec.ts @@ -1,7 +1,13 @@ +import { partial } from '../../../test/util'; +import type { BranchConfig, BranchUpgradeConfig } from '../types'; import { + calcLimit, + hasMultipleLimits, + incCountValue, incLimitedValue, isLimitReached, resetAllLimits, + setCount, setMaxLimit, } from './limits'; @@ -60,4 +66,242 @@ describe('workers/global/limits', () => { setMaxLimit('Commits', -1000); expect(isLimitReached('Commits')).toBeTrue(); }); + + describe('calcLimit', () => { + it('handles single upgrade', () => { + const upgrades = partial([ + { + prHourlyLimit: 10, + branchConcurrentLimit: 11, + prConcurrentLimit: 12, + }, + ]); + + expect(calcLimit(upgrades, 'prHourlyLimit')).toBe(10); + expect(calcLimit(upgrades, 'branchConcurrentLimit')).toBe(11); + expect(calcLimit(upgrades, 'prConcurrentLimit')).toBe(12); + }); + + it('inherits prConcurrentLimit if branchConcurrentLimit is null', () => { + const upgrades = partial([ + { + prHourlyLimit: 10, + branchConcurrentLimit: null, + prConcurrentLimit: 12, + }, + ]); + + expect(calcLimit(upgrades, 'prHourlyLimit')).toBe(10); + expect(calcLimit(upgrades, 'branchConcurrentLimit')).toBe(12); + expect(calcLimit(upgrades, 'prConcurrentLimit')).toBe(12); + }); + + it('returns 0 if atleast one upgrade has no limit in the branch', () => { + const upgrades = partial([ + { + prHourlyLimit: 10, + branchConcurrentLimit: 11, + prConcurrentLimit: 12, + }, + { + prHourlyLimit: 0, + branchConcurrentLimit: 0, + prConcurrentLimit: 0, + }, + { + prHourlyLimit: 1, + branchConcurrentLimit: 1, + prConcurrentLimit: 1, + }, + ]); + + expect(calcLimit(upgrades, 'prHourlyLimit')).toBe(0); + expect(calcLimit(upgrades, 'branchConcurrentLimit')).toBe(0); + expect(calcLimit(upgrades, 'prConcurrentLimit')).toBe(0); + }); + + it('computes the lowest limit if multiple limits are present', () => { + const upgrades = partial([ + { + prHourlyLimit: 10, + branchConcurrentLimit: 11, + prConcurrentLimit: 12, + }, + { + prHourlyLimit: 10, + branchConcurrentLimit: 11, + prConcurrentLimit: 12, + }, + { + prHourlyLimit: 1, + branchConcurrentLimit: 1, + prConcurrentLimit: 1, + }, + { + prHourlyLimit: 5, + branchConcurrentLimit: 6, + prConcurrentLimit: 3, + }, + { + prHourlyLimit: 5, + branchConcurrentLimit: null, + prConcurrentLimit: undefined, + }, + { + prHourlyLimit: 5, + branchConcurrentLimit: 6, + prConcurrentLimit: 2, + }, + ]); + + expect(calcLimit(upgrades, 'prHourlyLimit')).toBe(1); + expect(calcLimit(upgrades, 'branchConcurrentLimit')).toBe(1); + expect(calcLimit(upgrades, 'prConcurrentLimit')).toBe(1); + }); + }); + + describe('hasMultipleLimits', () => { + it('handles single limit', () => { + const upgrades = partial([ + { + prHourlyLimit: 10, + branchConcurrentLimit: 11, + prConcurrentLimit: 12, + }, + ]); + expect(hasMultipleLimits(upgrades, 'prHourlyLimit')).toBe(false); + expect(hasMultipleLimits(upgrades, 'branchConcurrentLimit')).toBe(false); + expect(hasMultipleLimits(upgrades, 'prConcurrentLimit')).toBe(false); + }); + + it('returns false if there are multiple limits with value', () => { + const upgrades = partial([ + { + prHourlyLimit: 10, + branchConcurrentLimit: 11, + prConcurrentLimit: 12, + }, + { + prHourlyLimit: 10, + branchConcurrentLimit: 11, + prConcurrentLimit: 12, + }, + ]); + expect(hasMultipleLimits(upgrades, 'prHourlyLimit')).toBe(false); + expect(hasMultipleLimits(upgrades, 'branchConcurrentLimit')).toBe(false); + expect(hasMultipleLimits(upgrades, 'prConcurrentLimit')).toBe(false); + }); + + it('handles multiple limits', () => { + const upgrades = partial([ + { + prHourlyLimit: 10, + branchConcurrentLimit: 11, + prConcurrentLimit: 12, + }, + { + prHourlyLimit: 11, + branchConcurrentLimit: 12, + prConcurrentLimit: 13, + }, + { + prHourlyLimit: 0, + branchConcurrentLimit: null, + prConcurrentLimit: 3, + }, + ]); + expect(hasMultipleLimits(upgrades, 'prHourlyLimit')).toBe(true); + expect(hasMultipleLimits(upgrades, 'branchConcurrentLimit')).toBe(true); + expect(hasMultipleLimits(upgrades, 'prConcurrentLimit')).toBe(true); + }); + }); + + describe('isLimitReached', () => { + it('returns false based on concurrent limits', () => { + setCount('ConcurrentPRs', 1); + setCount('HourlyPRs', 1); + incCountValue('Branches'); // using incCountValue so it gets test coverage + const upgrades = partial([ + { + prHourlyLimit: 10, + branchConcurrentLimit: 11, + prConcurrentLimit: 12, + }, + { + prHourlyLimit: 11, + branchConcurrentLimit: 12, + prConcurrentLimit: 13, + }, + { + prHourlyLimit: 0, + branchConcurrentLimit: null, + prConcurrentLimit: 3, + }, + ]); + expect( + isLimitReached('Branches', partial({ upgrades })), + ).toBe(false); + expect( + isLimitReached('ConcurrentPRs', partial({ upgrades })), + ).toBe(false); + }); + + it('returns true when hourly limit is reached', () => { + setCount('Branches', 2); + setCount('ConcurrentPRs', 2); + setCount('HourlyPRs', 2); + const upgrades = partial([ + { + prHourlyLimit: 10, + branchConcurrentLimit: 11, + prConcurrentLimit: 12, + }, + { + prHourlyLimit: 11, + branchConcurrentLimit: 12, + prConcurrentLimit: 13, + }, + { + prHourlyLimit: 2, + branchConcurrentLimit: null, + prConcurrentLimit: 3, + }, + ]); + expect( + isLimitReached('Branches', partial({ upgrades })), + ).toBe(true); + expect( + isLimitReached('ConcurrentPRs', partial({ upgrades })), + ).toBe(true); + }); + + it('returns true when concurrent limit is reached', () => { + setCount('Branches', 3); + setCount('ConcurrentPRs', 3); + setCount('HourlyPRs', 4); + const upgrades = partial([ + { + prHourlyLimit: 10, + branchConcurrentLimit: 11, + prConcurrentLimit: 12, + }, + { + prHourlyLimit: 11, + branchConcurrentLimit: 12, + prConcurrentLimit: 13, + }, + { + prHourlyLimit: 5, + branchConcurrentLimit: null, + prConcurrentLimit: 3, + }, + ]); + expect( + isLimitReached('Branches', partial({ upgrades })), + ).toBe(true); + expect( + isLimitReached('ConcurrentPRs', partial({ upgrades })), + ).toBe(true); + }); + }); }); diff --git a/lib/workers/global/limits.ts b/lib/workers/global/limits.ts index aa030b059506471..7a68b3f260559a2 100644 --- a/lib/workers/global/limits.ts +++ b/lib/workers/global/limits.ts @@ -1,7 +1,8 @@ +import is from '@sindresorhus/is'; import { logger } from '../../logger'; +import type { BranchConfig, BranchUpgradeConfig } from '../types'; -export type Limit = 'Commits' | 'PullRequests' | 'Branches'; - +export type Limit = 'Commits'; interface LimitValue { max: number | null; current: number; @@ -27,8 +28,8 @@ export function incLimitedValue(key: Limit, incBy = 1): void { }); } -export function isLimitReached(key: Limit): boolean { - const limit = limits.get(key); +function handleCommitsLimit(): boolean { + const limit = limits.get('Commits'); // TODO: fix me? // eslint-disable-next-line @typescript-eslint/prefer-optional-chain if (!limit || limit.max === null) { @@ -37,3 +38,162 @@ export function isLimitReached(key: Limit): boolean { const { max, current } = limit; return max - current <= 0; } + +export type CountName = 'ConcurrentPRs' | 'HourlyPRs' | 'Branches'; + +type BranchLimitName = + | 'branchConcurrentLimit' + | 'prConcurrentLimit' + | 'prHourlyLimit'; + +export const counts = new Map(); + +export function getCount(key: CountName): number { + const count = counts.get(key); + // istanbul ignore if: should not happen + if (!is.integer(count)) { + logger.debug(`Could not compute the count of ${key}, returning zero.`); + return 0; + } + return count; +} + +export function setCount(key: CountName, val: number): void { + counts.set(key, val); + logger.debug(`${key} count = ${val}`); +} + +export function incCountValue(key: CountName, incBy = 1): void { + const count = getCount(key); + counts.set(key, count + incBy); +} + +function handleConcurrentLimits( + key: Exclude, + config: BranchConfig, +): boolean { + const limitKey = + key === 'Branches' ? 'branchConcurrentLimit' : 'prConcurrentLimit'; + + // calculate the limits for this branch + const hourlyLimit = calcLimit(config.upgrades, 'prHourlyLimit'); + const hourlyPrCount = getCount('HourlyPRs'); + + // if a limit is defined ( >0 ) and limit reached return true ie. limit has been reached + if (hourlyLimit && hourlyPrCount >= hourlyLimit) { + return true; + } + + const limitValue = calcLimit(config.upgrades, limitKey); + const currentCount = getCount(key); + + if (limitValue && currentCount >= limitValue) { + return true; + } + + return false; +} + +export function calcLimit( + upgrades: BranchUpgradeConfig[], + limitName: BranchLimitName, +): number { + logger.debug( + { + limits: upgrades.map((upg) => { + return { depName: upg.depName, [limitName]: upg[limitName] }; + }), + }, + `${limitName} of the upgrades present in this branch`, + ); + + if (hasMultipleLimits(upgrades, limitName)) { + logger.once.debug( + `Branch has multiple ${limitName} limits. The lowest among these will be selected.`, + ); + } + + let lowestLimit = Number.MAX_SAFE_INTEGER; + for (const upgrade of upgrades) { + let limit = upgrade[limitName]; + + // inherit prConcurrentLimit value incase branchConcurrentLimit is null + if (!is.number(limit) && limitName === 'branchConcurrentLimit') { + limit = upgrade.prConcurrentLimit; + } + + // istanbul ignore if: should never happen as all limits get a default value + if (is.undefined(limit)) { + limit = Number.MAX_SAFE_INTEGER; + } + + // no limit + if (limit === 0 || limit === null) { + logger.debug( + `${limitName} of this branch is unlimited, because atleast one of the upgrade has it's ${limitName} set to "No limit" ie. 0 or null`, + ); + return 0; + } + + // limit is set + lowestLimit = limit < lowestLimit ? limit : lowestLimit; + } + + logger.debug( + `Calculated lowest ${limitName} among the upgrades present in this branch is ${lowestLimit}.`, + ); + return lowestLimit; +} + +export function hasMultipleLimits( + upgrades: BranchUpgradeConfig[], + limitName: BranchLimitName, +): boolean { + if (upgrades.length === 1) { + return false; + } + + const distinctLimits = new Set(); + for (const upgrade of upgrades) { + let limitValue = upgrade[limitName]; + + // inherit prConcurrentLimit value incase branchConcurrentLimit is null + if (limitName === 'branchConcurrentLimit' && !is.number(limitValue)) { + limitValue = upgrade.prConcurrentLimit; + } + + // istanbul ignore if: should not happen as the limits are of type number + if (limitValue === null) { + limitValue = 0; + } + + if (!is.undefined(limitValue) && !distinctLimits.has(limitValue)) { + distinctLimits.add(limitValue); + } + } + + return distinctLimits.size > 1; +} + +export function isLimitReached(limit: 'Commits'): boolean; +export function isLimitReached( + limit: 'Branches' | 'ConcurrentPRs', + config: BranchConfig, +): boolean; +export function isLimitReached( + limit: 'Commits' | 'Branches' | 'ConcurrentPRs', + config?: BranchConfig, +): boolean { + if (limit === 'Commits') { + return handleCommitsLimit(); + } + + if (config) { + return handleConcurrentLimits(limit, config); + } + + // istanbul ignore next: should not happen + throw new Error( + 'Config is required for computing limits for Branches and PullRequests', + ); +} diff --git a/lib/workers/repository/process/libyear.spec.ts b/lib/workers/repository/process/libyear.spec.ts index e4a1f1fe24ff43b..c8e32d80bb8e111 100644 --- a/lib/workers/repository/process/libyear.spec.ts +++ b/lib/workers/repository/process/libyear.spec.ts @@ -1,5 +1,6 @@ import { logger } from '../../../../test/util'; import type { PackageFile } from '../../../modules/manager/types'; +import type { Timestamp } from '../../../util/timestamp'; import { calculateLibYears } from './libyear'; describe('workers/repository/process/libyear', () => { @@ -30,15 +31,15 @@ describe('workers/repository/process/libyear', () => { { depName: 'dep1', currentVersion: '0.1.0', - currentVersionTimestamp: '2019-07-01T00:00:00Z', + currentVersionTimestamp: '2019-07-01T00:00:00Z' as Timestamp, updates: [ { newVersion: '1.0.0', - releaseTimestamp: '2020-01-01T00:00:00Z', + releaseTimestamp: '2020-01-01T00:00:00Z' as Timestamp, }, { newVersion: '2.0.0', - releaseTimestamp: '2020-07-01T00:00:00Z', + releaseTimestamp: '2020-07-01T00:00:00Z' as Timestamp, }, { newVersion: '3.0.0', @@ -55,11 +56,11 @@ describe('workers/repository/process/libyear', () => { { depName: 'dep2', currentVersion: '1.0.0', - currentVersionTimestamp: '2019-07-01T00:00:00Z', + currentVersionTimestamp: '2019-07-01T00:00:00Z' as Timestamp, updates: [ { newVersion: '2.0.0', - releaseTimestamp: '2020-01-01T00:00:00Z', + releaseTimestamp: '2020-01-01T00:00:00Z' as Timestamp, }, ], }, @@ -69,7 +70,7 @@ describe('workers/repository/process/libyear', () => { updates: [ { newVersion: '2.0.0', - releaseTimestamp: '2020-01-01T00:00:00Z', + releaseTimestamp: '2020-01-01T00:00:00Z' as Timestamp, }, ], }, diff --git a/lib/workers/repository/process/limits.spec.ts b/lib/workers/repository/process/limits.spec.ts index 93e381066448738..7e9e7030d7abfae 100644 --- a/lib/workers/repository/process/limits.spec.ts +++ b/lib/workers/repository/process/limits.spec.ts @@ -18,8 +18,8 @@ beforeEach(() => { }); describe('workers/repository/process/limits', () => { - describe('getPrHourlyRemaining()', () => { - it('calculates hourly limit remaining', async () => { + describe('getPrHourlyCount()', () => { + it('calculates hourly pr count', async () => { const time = DateTime.local(); const createdAt = time.toISO(); platform.getPrList.mockResolvedValueOnce([ @@ -33,30 +33,19 @@ describe('workers/repository/process/limits', () => { { createdAt, sourceBranch: 'bar/configure' }, { createdAt, sourceBranch: 'baz/test' }, ] as never); - const res = await limits.getPrHourlyRemaining({ - ...config, - prHourlyLimit: 10, - }); - expect(res).toBe(7); + const res = await limits.getPrHourlyCount(config); + expect(res).toBe(3); }); - it('returns prHourlyLimit if errored', async () => { - config.prHourlyLimit = 5; + it('returns zero if errored', async () => { platform.getPrList.mockRejectedValue('Unknown error'); - const res = await limits.getPrHourlyRemaining(config); - expect(res).toBe(5); - }); - - it('returns MAX_SAFE_INTEGER if no hourly limit', async () => { - config.prHourlyLimit = 0; - const res = await limits.getPrHourlyRemaining(config); - expect(res).toBe(Number.MAX_SAFE_INTEGER); + const res = await limits.getPrHourlyCount(config); + expect(res).toBe(0); }); }); - describe('getConcurrentPrsRemaining()', () => { - it('calculates concurrent limit remaining', async () => { - config.prConcurrentLimit = 20; + describe('getConcurrentPrsCount()', () => { + it('calculates concurrent prs present', async () => { platform.getBranchPr.mockImplementation((branchName) => branchName ? Promise.resolve( @@ -71,100 +60,21 @@ describe('workers/repository/process/limits', () => { { branchName: 'test' }, { branchName: null }, ] as never; - const res = await limits.getConcurrentPrsRemaining(config, branches); - expect(res).toBe(19); - }); - - it('returns MAX_SAFE_INTEGER if no concurrent limit', async () => { - config.prConcurrentLimit = 0; - const res = await limits.getConcurrentPrsRemaining(config, []); - expect(res).toBe(Number.MAX_SAFE_INTEGER); - }); - }); - - describe('getPrsRemaining()', () => { - it('returns hourly limit', async () => { - config.prHourlyLimit = 1; - platform.getPrList.mockResolvedValueOnce([]); - const res = await limits.getPrsRemaining(config, []); - expect(res).toBe(1); - }); - - it('returns concurrent limit', async () => { - config.prConcurrentLimit = 1; - const res = await limits.getPrsRemaining(config, []); + const res = await limits.getConcurrentPrsCount(config, branches); expect(res).toBe(1); }); }); - describe('getConcurrentBranchesRemaining()', () => { - it('calculates concurrent limit remaining', async () => { - config.branchConcurrentLimit = 20; - scm.branchExists.mockResolvedValueOnce(true); - const res = await limits.getConcurrentBranchesRemaining(config, [ - { branchName: 'foo' }, - ] as never); - expect(res).toBe(19); - }); - - it('defaults to prConcurrentLimit', async () => { - config.branchConcurrentLimit = null; - config.prConcurrentLimit = 20; - scm.branchExists.mockResolvedValueOnce(true); - const res = await limits.getConcurrentBranchesRemaining(config, [ + describe('getConcurrentBranchesCount()', () => { + it('calculates concurrent branches present', async () => { + scm.branchExists.mockImplementation((branchName) => + branchName ? Promise.resolve(true) : Promise.resolve(false), + ); + const res = await limits.getConcurrentBranchesCount([ { branchName: 'foo' }, + { branchName: null }, ] as never); - expect(res).toBe(19); - }); - - it('does not use prConcurrentLimit for explicit branchConcurrentLimit=0', async () => { - config.branchConcurrentLimit = 0; - config.prConcurrentLimit = 20; - const res = await limits.getConcurrentBranchesRemaining(config, []); - expect(res).toBe(Number.MAX_SAFE_INTEGER); - }); - - it('returns 10 if no limits are set', async () => { - const res = await limits.getConcurrentBranchesRemaining(config, []); - expect(res).toBe(10); - }); - - it('returns prConcurrentLimit if errored', async () => { - config.branchConcurrentLimit = 2; - // TODO: #22198 - const res = await limits.getConcurrentBranchesRemaining( - config, - null as never, - ); - expect(res).toBe(2); - }); - }); - - describe('getBranchesRemaining()', () => { - it('returns minimal of both limits', async () => { - platform.getPrList.mockResolvedValue([]); - - await expect( - limits.getBranchesRemaining( - { - ...config, - prHourlyLimit: 3, - branchConcurrentLimit: 5, - }, - [], - ), - ).resolves.toBe(3); - - await expect( - limits.getBranchesRemaining( - { - ...config, - prHourlyLimit: 11, - branchConcurrentLimit: 7, - }, - [], - ), - ).resolves.toBe(7); + expect(res).toBe(1); }); }); }); diff --git a/lib/workers/repository/process/limits.ts b/lib/workers/repository/process/limits.ts index 55aae025e095c89..fb320f221f73213 100644 --- a/lib/workers/repository/process/limits.ts +++ b/lib/workers/repository/process/limits.ts @@ -1,141 +1,79 @@ import { DateTime } from 'luxon'; import type { RenovateConfig } from '../../../config/types'; import { logger } from '../../../logger'; -import type { Pr } from '../../../modules/platform'; import { platform } from '../../../modules/platform'; import { scm } from '../../../modules/platform/scm'; import { ExternalHostError } from '../../../types/errors/external-host-error'; import type { BranchConfig } from '../../types'; -export async function getPrHourlyRemaining( +export async function getPrHourlyCount( config: RenovateConfig, ): Promise { - if (config.prHourlyLimit) { - try { - logger.debug('Calculating hourly PRs remaining'); - const prList = await platform.getPrList(); - const currentHourStart = DateTime.local().startOf('hour'); - logger.debug(`currentHourStart=${String(currentHourStart)}`); - const soFarThisHour = prList.filter( - (pr) => - pr.sourceBranch !== config.onboardingBranch && - pr.sourceBranch.startsWith(config.branchPrefix!) && - DateTime.fromISO(pr.createdAt!) > currentHourStart, - ); - const prsRemaining = Math.max( - 0, - config.prHourlyLimit - soFarThisHour.length, - ); - logger.debug(`PR hourly limit remaining: ${prsRemaining}`); - return prsRemaining; - } catch (err) { - // istanbul ignore if - if (err instanceof ExternalHostError) { - throw err; - } - logger.error({ err }, 'Error checking PRs created per hour'); - return config.prHourlyLimit; + try { + const prList = await platform.getPrList(); + const currentHourStart = DateTime.local().setZone('utc').startOf('hour'); + logger.debug( + `Calculating PRs created so far in this hour currentHourStart=${String(currentHourStart)}`, + ); + const soFarThisHour = prList.filter( + (pr) => + pr.sourceBranch !== config.onboardingBranch && + pr.sourceBranch.startsWith(config.branchPrefix!) && + DateTime.fromISO(pr.createdAt!) > currentHourStart, + ); + logger.debug( + `${soFarThisHour.length} PRs have been created so far in this hour.`, + ); + return soFarThisHour.length; + } catch (err) { + // istanbul ignore if + if (err instanceof ExternalHostError) { + throw err; } + logger.error({ err }, 'Error checking PRs created per hour'); + return 0; } - return Number.MAX_SAFE_INTEGER; } -export async function getConcurrentPrsRemaining( +export async function getConcurrentPrsCount( config: RenovateConfig, branches: BranchConfig[], ): Promise { - if (config.prConcurrentLimit) { - logger.debug(`Calculating prConcurrentLimit (${config.prConcurrentLimit})`); + let openPrCount = 0; + for (const { branchName } of branches) { try { - const openPrs: Pr[] = []; - for (const { branchName } of branches) { - try { - const pr = await platform.getBranchPr(branchName, config.baseBranch); - if ( - pr && - pr.sourceBranch !== config.onboardingBranch && - pr.state === 'open' - ) { - openPrs.push(pr); - } - } catch (err) { - // istanbul ignore if - if (err instanceof ExternalHostError) { - throw err; - } else { - // no-op - } - } + const pr = await platform.getBranchPr(branchName, config.baseBranch); + if ( + pr && + pr.sourceBranch !== config.onboardingBranch && + pr.state === 'open' + ) { + openPrCount++; + } + } catch (err) { + // istanbul ignore if + if (err instanceof ExternalHostError) { + throw err; + } else { + // no-op } - logger.debug(`${openPrs.length} PRs are currently open`); - const concurrentRemaining = Math.max( - 0, - config.prConcurrentLimit - openPrs.length, - ); - logger.debug(`PR concurrent limit remaining: ${concurrentRemaining}`); - return concurrentRemaining; - } catch (err) /* istanbul ignore next */ { - logger.error({ err }, 'Error checking concurrent PRs'); - return config.prConcurrentLimit; } } - return Number.MAX_SAFE_INTEGER; -} -export async function getPrsRemaining( - config: RenovateConfig, - branches: BranchConfig[], -): Promise { - const hourlyRemaining = await getPrHourlyRemaining(config); - const concurrentRemaining = await getConcurrentPrsRemaining(config, branches); - return Math.min(hourlyRemaining, concurrentRemaining); + logger.debug(`${openPrCount} PRs are currently open`); + return openPrCount; } -export async function getConcurrentBranchesRemaining( - config: RenovateConfig, +export async function getConcurrentBranchesCount( branches: BranchConfig[], ): Promise { - const { branchConcurrentLimit, prConcurrentLimit } = config; - const limit = - typeof branchConcurrentLimit === 'number' - ? branchConcurrentLimit - : prConcurrentLimit; - if (typeof limit === 'number' && limit) { - logger.debug(`Calculating branchConcurrentLimit (${limit})`); - try { - const existingBranches: string[] = []; - for (const branch of branches) { - if (await scm.branchExists(branch.branchName)) { - existingBranches.push(branch.branchName); - } - } - - const existingCount = existingBranches.length; - logger.debug( - `${existingCount} already existing branches found: ${existingBranches.join()}`, - ); - - const concurrentRemaining = Math.max(0, limit - existingCount); - logger.debug(`Branch concurrent limit remaining: ${concurrentRemaining}`); - - return concurrentRemaining; - } catch (err) { - // TODO: #22198 should never throw - logger.error({ err }, 'Error checking concurrent branches'); - return limit; + let existingBranchCount = 0; + for (const branch of branches) { + if (await scm.branchExists(branch.branchName)) { + existingBranchCount++; } } - return Number.MAX_SAFE_INTEGER; -} -export async function getBranchesRemaining( - config: RenovateConfig, - branches: BranchConfig[], -): Promise { - const hourlyRemaining = await getPrHourlyRemaining(config); - const concurrentRemaining = await getConcurrentBranchesRemaining( - config, - branches, - ); - return Math.min(hourlyRemaining, concurrentRemaining); + logger.debug(`${existingBranchCount} already existing branches found.`); + return existingBranchCount; } diff --git a/lib/workers/repository/process/lookup/filter-checks.spec.ts b/lib/workers/repository/process/lookup/filter-checks.spec.ts index aa1f3d63fed6b68..37c0a56d6646502 100644 --- a/lib/workers/repository/process/lookup/filter-checks.spec.ts +++ b/lib/workers/repository/process/lookup/filter-checks.spec.ts @@ -13,6 +13,7 @@ import { clone } from '../../../../util/clone'; import * as _dateUtil from '../../../../util/date'; import * as _mergeConfidence from '../../../../util/merge-confidence'; import { toMs } from '../../../../util/pretty-time'; +import type { Timestamp } from '../../../../util/timestamp'; import { filterInternalChecks } from './filter-checks'; import type { LookupUpdateConfig, UpdateResult } from './types'; @@ -42,19 +43,19 @@ const versioning = allVersioning.get('semver'); const releases: Release[] = [ { version: '1.0.1', - releaseTimestamp: '2021-01-01T00:00:01.000Z', + releaseTimestamp: '2021-01-01T00:00:01.000Z' as Timestamp, }, { version: '1.0.2', - releaseTimestamp: '2021-01-03T00:00:00.000Z', + releaseTimestamp: '2021-01-03T00:00:00.000Z' as Timestamp, }, { version: '1.0.3', - releaseTimestamp: '2021-01-05T00:00:00.000Z', + releaseTimestamp: '2021-01-05T00:00:00.000Z' as Timestamp, }, { version: '1.0.4', - releaseTimestamp: '2021-01-07T00:00:00.000Z', + releaseTimestamp: '2021-01-07T00:00:00.000Z' as Timestamp, }, ]; diff --git a/lib/workers/repository/process/lookup/filter.spec.ts b/lib/workers/repository/process/lookup/filter.spec.ts index e445a9b0fdffdb3..5cdf6f78b895e9d 100644 --- a/lib/workers/repository/process/lookup/filter.spec.ts +++ b/lib/workers/repository/process/lookup/filter.spec.ts @@ -1,6 +1,7 @@ import { partial } from '../../../../../test/util'; import type { Release } from '../../../../modules/datasource/types'; import * as allVersioning from '../../../../modules/versioning'; +import type { Timestamp } from '../../../../util/timestamp'; import { filterVersions } from './filter'; import type { FilterConfig } from './types'; @@ -12,24 +13,24 @@ describe('workers/repository/process/lookup/filter', () => { const releases = [ { version: '1.0.1', - releaseTimestamp: '2021-01-01T00:00:01.000Z', + releaseTimestamp: '2021-01-01T00:00:01.000Z' as Timestamp, }, { version: '1.2.0', - releaseTimestamp: '2021-01-03T00:00:00.000Z', + releaseTimestamp: '2021-01-03T00:00:00.000Z' as Timestamp, }, { version: '2.0.0', - releaseTimestamp: '2021-01-05T00:00:00.000Z', + releaseTimestamp: '2021-01-05T00:00:00.000Z' as Timestamp, }, { version: '2.1.0', - releaseTimestamp: '2021-01-07T00:00:00.000Z', + releaseTimestamp: '2021-01-07T00:00:00.000Z' as Timestamp, }, // for coverage { version: 'invalid.version', - releaseTimestamp: '2021-01-07T00:00:00.000Z', + releaseTimestamp: '2021-01-07T00:00:00.000Z' as Timestamp, }, ] satisfies Release[]; diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts index 26e13ba8e456734..31fe79439242b7c 100644 --- a/lib/workers/repository/process/lookup/index.spec.ts +++ b/lib/workers/repository/process/lookup/index.spec.ts @@ -31,6 +31,7 @@ import * as memCache from '../../../../util/cache/memory'; import { initConfig, resetConfig } from '../../../../util/merge-confidence'; import * as McApi from '../../../../util/merge-confidence'; import { Result } from '../../../../util/result'; +import type { Timestamp } from '../../../../util/timestamp'; import type { LookupUpdateConfig } from './types'; import * as lookup from '.'; @@ -162,7 +163,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '1.4.1', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -219,7 +220,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '^0.9.0', newVersion: '0.9.7', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2013-09-04T17:07:22.948Z', + releaseTimestamp: '2013-09-04T17:07:22.948Z' as Timestamp, updateType: 'minor', }, { @@ -231,7 +232,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '^1.0.0', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -261,7 +262,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '^0.4.0', newVersion: '0.4.4', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2011-06-10T17:20:04.719Z', + releaseTimestamp: '2011-06-10T17:20:04.719Z' as Timestamp, updateType: 'patch', }, { @@ -273,7 +274,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '^0.9.0', newVersion: '0.9.7', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2013-09-04T17:07:22.948Z', + releaseTimestamp: '2013-09-04T17:07:22.948Z' as Timestamp, updateType: 'minor', }, { @@ -285,7 +286,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '^1.0.0', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -436,7 +437,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '^0.9.0', newVersion: '0.9.7', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2013-09-04T17:07:22.948Z', + releaseTimestamp: '2013-09-04T17:07:22.948Z' as Timestamp, updateType: 'minor', }, { @@ -448,7 +449,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '^1.0.0', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -500,7 +501,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '0.9.7', newVersion: '0.9.7', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2013-09-04T17:07:22.948Z', + releaseTimestamp: '2013-09-04T17:07:22.948Z' as Timestamp, updateType: 'minor', }, ]); @@ -526,7 +527,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '0.9.7', newVersion: '0.9.7', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2013-09-04T17:07:22.948Z', + releaseTimestamp: '2013-09-04T17:07:22.948Z' as Timestamp, updateType: 'minor', }, ]); @@ -553,7 +554,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '0.9.7', newVersion: '0.9.7', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2013-09-04T17:07:22.948Z', + releaseTimestamp: '2013-09-04T17:07:22.948Z' as Timestamp, updateType: 'minor', }, ]); @@ -580,7 +581,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '0.9.4', newVersion: '0.9.4', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2013-05-22T20:26:50.888Z', + releaseTimestamp: '2013-05-22T20:26:50.888Z' as Timestamp, updateType: 'minor', }, ]); @@ -699,7 +700,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '0.9.7', newVersion: '0.9.7', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2013-09-04T17:07:22.948Z', + releaseTimestamp: '2013-09-04T17:07:22.948Z' as Timestamp, updateType: 'patch', }, { @@ -710,7 +711,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '1.4.1', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -794,7 +795,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '^1.0.0', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -821,7 +822,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '1.4.1', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -1059,7 +1060,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~0.9.0', newVersion: '0.9.7', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2013-09-04T17:07:22.948Z', + releaseTimestamp: '2013-09-04T17:07:22.948Z' as Timestamp, updateType: 'minor', }, { @@ -1071,7 +1072,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~1.4.0', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -1216,7 +1217,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~1.4.0', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -1250,7 +1251,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~1.4.0', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -1391,7 +1392,7 @@ describe('workers/repository/process/lookup/index', () => { newPatch: 0, newValue: undefined, newVersion: '1.3.0', - releaseTimestamp: '2015-04-26T16:42:11.311Z', + releaseTimestamp: '2015-04-26T16:42:11.311Z' as Timestamp, updateType: 'minor', }, ]); @@ -1420,7 +1421,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~1.3.0 || ~1.4.0', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -1447,7 +1448,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~1.4.0', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -1477,7 +1478,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '^2.0.0 || ^3.0.0', newVersion: '3.8.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2017-10-17T15:22:36.646Z', + releaseTimestamp: '2017-10-17T15:22:36.646Z' as Timestamp, updateType: 'major', }, ]); @@ -1507,7 +1508,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '^3.0.0', newVersion: '3.8.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2017-10-17T15:22:36.646Z', + releaseTimestamp: '2017-10-17T15:22:36.646Z' as Timestamp, updateType: 'major', }, ]); @@ -1615,7 +1616,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~1.4.0', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -1649,7 +1650,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '1.4.x', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -1676,7 +1677,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~1.4.0', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -1703,7 +1704,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '1.x', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -1730,7 +1731,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '1.4.x', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -1757,7 +1758,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '1.2.x - 1.4.x', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -1784,7 +1785,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '1', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -1811,7 +1812,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '1.4', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -1838,7 +1839,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~0.9.0', newVersion: '0.9.7', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2013-09-04T17:07:22.948Z', + releaseTimestamp: '2013-09-04T17:07:22.948Z' as Timestamp, updateType: 'minor', }, { @@ -1850,7 +1851,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~1.4.0', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -1877,7 +1878,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '^0.9.0', newVersion: '0.9.7', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2013-09-04T17:07:22.948Z', + releaseTimestamp: '2013-09-04T17:07:22.948Z' as Timestamp, updateType: 'minor', }, { @@ -1889,7 +1890,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '^1.0.0', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -1958,7 +1959,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '^1.0.0 || ^2.0.0 || ^3.0.0', newVersion: '3.8.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2017-10-17T15:22:36.646Z', + releaseTimestamp: '2017-10-17T15:22:36.646Z' as Timestamp, updateType: 'major', }, ]); @@ -1988,7 +1989,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '1.x - 3.x', newVersion: '3.8.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2017-10-17T15:22:36.646Z', + releaseTimestamp: '2017-10-17T15:22:36.646Z' as Timestamp, updateType: 'major', }, ]); @@ -2018,7 +2019,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '1.x || 2.x || 3.x', newVersion: '3.8.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2017-10-17T15:22:36.646Z', + releaseTimestamp: '2017-10-17T15:22:36.646Z' as Timestamp, updateType: 'major', }, ]); @@ -2048,7 +2049,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '1 || 2 || 3', newVersion: '3.8.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2017-10-17T15:22:36.646Z', + releaseTimestamp: '2017-10-17T15:22:36.646Z' as Timestamp, updateType: 'major', }, ]); @@ -2075,7 +2076,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~1.2.0 || ~1.3.0 || ~1.4.0', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -2116,7 +2117,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '<= 0.9.7', newVersion: '0.9.7', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2013-09-04T17:07:22.948Z', + releaseTimestamp: '2013-09-04T17:07:22.948Z' as Timestamp, updateType: 'minor', }, { @@ -2128,7 +2129,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '<= 1.4.1', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -2155,7 +2156,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '< 0.9.8', newVersion: '0.9.7', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2013-09-04T17:07:22.948Z', + releaseTimestamp: '2013-09-04T17:07:22.948Z' as Timestamp, updateType: 'minor', }, { @@ -2167,7 +2168,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '< 1.4.2', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -2194,7 +2195,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '< 2', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -2221,7 +2222,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '<= 1.4', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -2248,7 +2249,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '=1.4.1', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -2276,7 +2277,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '<= 2', newVersion: '2.0.3', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-01-31T08:11:47.852Z', + releaseTimestamp: '2015-01-31T08:11:47.852Z' as Timestamp, updateType: 'major', }, ]); @@ -2475,7 +2476,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '2.0.3', newVersion: '2.0.3', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-01-31T08:11:47.852Z', + releaseTimestamp: '2015-01-31T08:11:47.852Z' as Timestamp, updateType: 'major', }, ]); @@ -2571,11 +2572,11 @@ describe('workers/repository/process/lookup/index', () => { { version: '1.4.4' }, { version: '1.4.5', - releaseTimestamp: lastWeek.toISOString(), + releaseTimestamp: lastWeek.toISOString() as Timestamp, }, { version: '1.4.6', - releaseTimestamp: yesterday.toISOString(), + releaseTimestamp: yesterday.toISOString() as Timestamp, }, ], }); @@ -2615,11 +2616,11 @@ describe('workers/repository/process/lookup/index', () => { { version: '1.4.4' }, { version: '1.4.5', - releaseTimestamp: lastWeek.toISOString(), + releaseTimestamp: lastWeek.toISOString() as Timestamp, }, { version: '1.4.6', - releaseTimestamp: yesterday.toISOString(), + releaseTimestamp: yesterday.toISOString() as Timestamp, }, ], }); @@ -2916,7 +2917,7 @@ describe('workers/repository/process/lookup/index', () => { { version: 'v2.0.0', gitRef: 'v2.0.0', - releaseTimestamp: '2022-01-01', + releaseTimestamp: '2022-01-01' as Timestamp, }, ], }); @@ -2951,7 +2952,7 @@ describe('workers/repository/process/lookup/index', () => { { version: 'v2.0.0', gitRef: 'v2.0.0', - releaseTimestamp: '2022-01-01', + releaseTimestamp: '2022-01-01' as Timestamp, }, ], }); @@ -2984,7 +2985,7 @@ describe('workers/repository/process/lookup/index', () => { { version: 'v1.0.0', gitRef: 'v1.0.0', - releaseTimestamp: '2022-01-01', + releaseTimestamp: '2022-01-01' as Timestamp, }, ], }); @@ -3051,7 +3052,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '^0.0.35', newVersion: '0.0.35', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2017-04-27T16:59:06.479Z', + releaseTimestamp: '2017-04-27T16:59:06.479Z' as Timestamp, updateType: 'patch', }, ]); @@ -3227,7 +3228,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '^1.4.1', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -3256,7 +3257,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~1.0.1', newVersion: '1.0.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2014-03-11T18:47:17.560Z', + releaseTimestamp: '2014-03-11T18:47:17.560Z' as Timestamp, updateType: 'patch', }, { @@ -3268,7 +3269,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~1.4.1', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -3297,7 +3298,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~1.0.1', newVersion: '1.0.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2014-03-11T18:47:17.560Z', + releaseTimestamp: '2014-03-11T18:47:17.560Z' as Timestamp, updateType: 'patch', }, { @@ -3309,7 +3310,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~1.4.1', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -3337,7 +3338,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '>=1.4.1', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -3366,7 +3367,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '>=1.4.1', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -3435,7 +3436,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '1.4.1', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'minor', }, ]); @@ -3537,7 +3538,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '~=1.4', newVersion: '1.4.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2015-05-17T04:25:07.299Z', + releaseTimestamp: '2015-05-17T04:25:07.299Z' as Timestamp, updateType: 'major', }, ]); @@ -3555,7 +3556,7 @@ describe('workers/repository/process/lookup/index', () => { expect(res).toMatchObject({ currentVersion: '1.3.0', - currentVersionTimestamp: '2015-04-26T16:42:11.311Z', + currentVersionTimestamp: '2015-04-26T16:42:11.311Z' as Timestamp, fixedVersion: '1.3.0', isSingleVersion: true, registryUrl: 'https://registry.npmjs.org', @@ -3598,7 +3599,7 @@ describe('workers/repository/process/lookup/index', () => { ).unwrapOrThrow(); expect(res).toMatchObject({ currentVersion: '1.3.0', - currentVersionTimestamp: '2015-04-26T16:42:11.311Z', + currentVersionTimestamp: '2015-04-26T16:42:11.311Z' as Timestamp, fixedVersion: '1.3.0', isSingleVersion: true, registryUrl: 'https://registry.npmjs.org', @@ -3655,7 +3656,7 @@ describe('workers/repository/process/lookup/index', () => { expect(res).toMatchObject({ currentVersion: '1.3.0', - currentVersionTimestamp: '2015-04-26T16:42:11.311Z', + currentVersionTimestamp: '2015-04-26T16:42:11.311Z' as Timestamp, deprecationMessage: codeBlock` On registry \`https://registry.npmjs.org\`, the "latest" version of dependency \`q3\` has the following deprecation notice: @@ -4424,7 +4425,7 @@ describe('workers/repository/process/lookup/index', () => { // a day old release releaseTimestamp: new Date( Date.now() - 25 * 60 * 60 * 1000, - ).toISOString(), + ).toISOString() as Timestamp, }, { version: '18.0.0', @@ -4466,7 +4467,7 @@ describe('workers/repository/process/lookup/index', () => { ]; const releaseTimestamp = new Date( Date.now() - 25 * 60 * 60 * 1000, - ).toISOString(); + ).toISOString() as Timestamp; getDockerReleases.mockResolvedValueOnce({ releases: [ { @@ -4683,10 +4684,8 @@ describe('workers/repository/process/lookup/index', () => { config.packageName = 'openjdk'; config.currentDigest = 'sha256:fedcba0987654321'; config.currentValue = '17.0.0'; - //config.pinDigests = true; config.datasource = DockerDatasource.id; config.versioning = dockerVersioningId; - // This config is normally set when packageRules are applied config.replacementName = 'eclipse-temurin'; config.replacementVersion = '19.0.0'; getDockerReleases.mockResolvedValueOnce({ @@ -4785,7 +4784,6 @@ describe('workers/repository/process/lookup/index', () => { it('handles replacements - name and version', async () => { config.currentValue = '1.4.1'; config.packageName = 'q'; - // This config is normally set when packageRules are applied config.replacementName = 'r'; config.replacementVersion = '2.0.0'; config.datasource = NpmDatasource.id; @@ -5056,7 +5054,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '3.8.1', newVersion: '3.8.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2017-10-17T15:22:36.646Z', + releaseTimestamp: '2017-10-17T15:22:36.646Z' as Timestamp, updateType: 'minor', }, ]); @@ -5085,7 +5083,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: '3.8.1', newVersion: '3.8.1', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2017-10-17T15:22:36.646Z', + releaseTimestamp: '2017-10-17T15:22:36.646Z' as Timestamp, updateType: 'minor', }, ]); @@ -5145,7 +5143,7 @@ describe('workers/repository/process/lookup/index', () => { newValue: 'v0.0.0-20240509183442-62759503f434', newVersion: 'v0.0.0-20240509183442-62759503f434', newVersionAgeInDays: expect.any(Number), - releaseTimestamp: '2024-05-09T18:34:42.000Z', + releaseTimestamp: '2024-05-09T18:34:42.000Z' as Timestamp, updateType: 'digest', }, ]); diff --git a/lib/workers/repository/process/write.spec.ts b/lib/workers/repository/process/write.spec.ts index f3a7405fabba465..70a8165ffc5ff91 100644 --- a/lib/workers/repository/process/write.spec.ts +++ b/lib/workers/repository/process/write.spec.ts @@ -12,7 +12,7 @@ import type { } from '../../../util/cache/repository/types'; import { fingerprint } from '../../../util/fingerprint'; import type { LongCommitSha } from '../../../util/git/types'; -import { isLimitReached } from '../../global/limits'; +import { counts } from '../../global/limits'; import type { BranchConfig, BranchUpgradeConfig } from '../../types'; import * as _branchWorker from '../update/branch'; import * as _limits from './limits'; @@ -32,8 +32,9 @@ const repoCache = mocked(_repoCache); branchWorker.processBranch = jest.fn(); -limits.getPrsRemaining = jest.fn().mockResolvedValue(99); -limits.getBranchesRemaining = jest.fn().mockResolvedValue(99); +limits.getConcurrentPrsCount = jest.fn().mockResolvedValue(0); +limits.getConcurrentBranchesCount = jest.fn().mockResolvedValue(0); +limits.getPrHourlyCount = jest.fn().mockResolvedValue(0); let config: RenovateConfig; @@ -104,22 +105,35 @@ describe('workers/repository/process/write', () => { it('increments branch counter', async () => { const branchName = 'branchName'; - const branches: BranchConfig[] = [ - { baseBranch: 'main', branchName, upgrades: [], manager: 'npm' }, - { baseBranch: 'dev', branchName, upgrades: [], manager: 'npm' }, - ]; + const branches = partial([ + { + baseBranch: 'main', + branchName, + upgrades: partial([{ prConcurrentLimit: 10 }]), + manager: 'npm', + }, + { + baseBranch: 'dev', + branchName, + upgrades: partial([{ prConcurrentLimit: 10 }]), + manager: 'npm', + }, + ]); repoCache.getCache.mockReturnValueOnce({}); branchWorker.processBranch.mockResolvedValueOnce({ branchExists: true, result: 'pr-created', }); - scm.branchExists.mockResolvedValueOnce(false).mockResolvedValueOnce(true); - limits.getBranchesRemaining.mockResolvedValueOnce(1); - expect(isLimitReached('Branches')).toBeFalse(); + + limits.getConcurrentPrsCount.mockResolvedValue(0); + limits.getConcurrentBranchesCount.mockResolvedValue(0); + limits.getPrHourlyCount.mockResolvedValue(0); + + scm.branchExists.mockResolvedValueOnce(false).mockResolvedValue(true); GlobalConfig.set({ dryRun: 'full' }); config.baseBranches = ['main', 'dev']; await writeUpdates(config, branches); - expect(isLimitReached('Branches')).toBeTrue(); + expect(counts.get('Branches')).toBe(1); expect(addMeta).toHaveBeenCalledWith({ baseBranch: 'main', branch: branchName, diff --git a/lib/workers/repository/process/write.ts b/lib/workers/repository/process/write.ts index 4cc9f74c5d3adb8..6f7309b86b2f660 100644 --- a/lib/workers/repository/process/write.ts +++ b/lib/workers/repository/process/write.ts @@ -7,11 +7,15 @@ import { getCache } from '../../../util/cache/repository'; import type { BranchCache } from '../../../util/cache/repository/types'; import { fingerprint } from '../../../util/fingerprint'; import { setBranchNewCommit } from '../../../util/git/set-branch-commit'; -import { incLimitedValue, setMaxLimit } from '../../global/limits'; +import { incCountValue, setCount } from '../../global/limits'; import type { BranchConfig, UpgradeFingerprintConfig } from '../../types'; import { processBranch } from '../update/branch'; import { upgradeFingerprintFields } from './fingerprint-fields'; -import { getBranchesRemaining, getPrsRemaining } from './limits'; +import { + getConcurrentBranchesCount, + getConcurrentPrsCount, + getPrHourlyCount, +} from './limits'; export type WriteUpdateResult = 'done' | 'automerged'; @@ -127,15 +131,15 @@ export async function writeUpdates( .sort() .join(', ')}`, ); - const prsRemaining = await getPrsRemaining(config, branches); - logger.debug(`Calculated maximum PRs remaining this run: ${prsRemaining}`); - setMaxLimit('PullRequests', prsRemaining); - const branchesRemaining = await getBranchesRemaining(config, branches); - logger.debug( - `Calculated maximum branches remaining this run: ${branchesRemaining}`, - ); - setMaxLimit('Branches', branchesRemaining); + const concurrentPrsCount = await getConcurrentPrsCount(config, branches); + setCount('ConcurrentPRs', concurrentPrsCount); + + const concurrentBranchesCount = await getConcurrentBranchesCount(branches); + setCount('Branches', concurrentBranchesCount); + + const prsThisHourCount = await getPrHourlyCount(config); + setCount('HourlyPRs', prsThisHourCount); for (const branch of branches) { const { baseBranch, branchName } = branch; @@ -182,7 +186,7 @@ export async function writeUpdates( return 'automerged'; } if (!branchExisted && (await scm.branchExists(branch.branchName))) { - incLimitedValue('Branches'); + incCountValue('Branches'); } } removeMeta(['branch', 'baseBranch']); diff --git a/lib/workers/repository/update/branch/index.spec.ts b/lib/workers/repository/update/branch/index.spec.ts index ba8aba7d85a76f7..174679d01823e92 100644 --- a/lib/workers/repository/update/branch/index.spec.ts +++ b/lib/workers/repository/update/branch/index.spec.ts @@ -36,6 +36,7 @@ import type { } from '../../../../util/git/types'; import * as _mergeConfidence from '../../../../util/merge-confidence'; import * as _sanitize from '../../../../util/sanitize'; +import type { Timestamp } from '../../../../util/timestamp'; import * as _limits from '../../../global/limits'; import type { BranchConfig, BranchUpgradeConfig } from '../../../types'; import type { ResultWithPr } from '../pr'; @@ -183,11 +184,13 @@ describe('workers/repository/update/branch/index', () => { config.prCreation = 'not-pending'; (config.upgrades as Partial[]) = [ { - releaseTimestamp: new Date('2019-01-01').getTime().toString(), + releaseTimestamp: new Date('2019-01-01') + .getTime() + .toString() as Timestamp, minimumReleaseAge: '1 day', }, { - releaseTimestamp: new Date().toString(), + releaseTimestamp: new Date().toString() as Timestamp, minimumReleaseAge: '1 day', }, ]; @@ -206,7 +209,7 @@ describe('workers/repository/update/branch/index', () => { config.prCreation = 'not-pending'; config.upgrades = partial([ { - releaseTimestamp: '2099-12-31', + releaseTimestamp: '2099-12-31' as Timestamp, minimumReleaseAge: '1 day', }, ]); @@ -1092,7 +1095,7 @@ describe('workers/repository/update/branch/index', () => { pr: partial(), }); prAutomerge.checkAutoMerge.mockResolvedValueOnce({ automerged: true }); - config.releaseTimestamp = '2018-04-26T05:15:51.877Z'; + config.releaseTimestamp = '2018-04-26T05:15:51.877Z' as Timestamp; commit.commitFilesToBranch.mockResolvedValueOnce(null); await branchWorker.processBranch(config); expect(platform.ensureComment).toHaveBeenCalledTimes(1); @@ -1117,7 +1120,7 @@ describe('workers/repository/update/branch/index', () => { pr: partial(), }); prAutomerge.checkAutoMerge.mockResolvedValueOnce({ automerged: true }); - config.releaseTimestamp = new Date().toISOString(); + config.releaseTimestamp = new Date().toISOString() as Timestamp; commit.commitFilesToBranch.mockResolvedValueOnce(null); await branchWorker.processBranch(config); expect(platform.ensureComment).toHaveBeenCalledTimes(1); @@ -1142,7 +1145,7 @@ describe('workers/repository/update/branch/index', () => { pr: partial(), }); prAutomerge.checkAutoMerge.mockResolvedValueOnce({ automerged: true }); - config.releaseTimestamp = new Date().toISOString(); + config.releaseTimestamp = new Date().toISOString() as Timestamp; await expect(branchWorker.processBranch(config)).rejects.toThrow( Error(MANAGER_LOCKFILE_ERROR), ); diff --git a/lib/workers/repository/update/branch/index.ts b/lib/workers/repository/update/branch/index.ts index e76b4c2dce533d5..b6038b5ba943995 100644 --- a/lib/workers/repository/update/branch/index.ts +++ b/lib/workers/repository/update/branch/index.ts @@ -34,7 +34,7 @@ import { import { coerceNumber } from '../../../../util/number'; import { toMs } from '../../../../util/pretty-time'; import * as template from '../../../../util/template'; -import { isLimitReached } from '../../../global/limits'; +import { getCount, isLimitReached } from '../../../global/limits'; import type { BranchConfig, BranchResult, PrBlockedBy } from '../../../types'; import { embedChangelogs } from '../../changelog'; import { ensurePr, getPlatformPrOptions } from '../pr'; @@ -212,9 +212,14 @@ export async function processBranch( }; } } + + logger.debug( + `Open PR Count: ${getCount('ConcurrentPRs')}, Existing Branch Count: ${getCount('Branches')}, Hourly PR Count: ${getCount('HourlyPRs')}`, + ); + if ( !branchExists && - isLimitReached('Branches') && + isLimitReached('Branches', branchConfig) && !dependencyDashboardCheck && !config.isVulnerabilityAlert ) { diff --git a/lib/workers/repository/update/pr/changelog/gitea/index.spec.ts b/lib/workers/repository/update/pr/changelog/gitea/index.spec.ts index 8bf9593052931de..b00012eccfe0e13 100644 --- a/lib/workers/repository/update/pr/changelog/gitea/index.spec.ts +++ b/lib/workers/repository/update/pr/changelog/gitea/index.spec.ts @@ -4,6 +4,7 @@ import { partial } from '../../../../../../../test/util'; import * as semverVersioning from '../../../../../../modules/versioning/semver'; import * as hostRules from '../../../../../../util/host-rules'; import { toBase64 } from '../../../../../../util/string'; +import type { Timestamp } from '../../../../../../util/timestamp'; import type { BranchUpgradeConfig } from '../../../../../types'; import { GiteaChangeLogSource } from '../gitea/source'; import { getReleaseNotesMd } from '.'; @@ -22,10 +23,13 @@ const upgrade = partial({ { version: '5.2.0' }, { version: '5.4.0', - releaseTimestamp: '2018-08-24T14:23:00.000Z', + releaseTimestamp: '2018-08-24T14:23:00.000Z' as Timestamp, }, { version: '5.5.0', gitRef: 'eba303e91c930292198b2fc57040145682162a1b' }, - { version: '5.6.0', releaseTimestamp: '2020-02-13T15:37:00.000Z' }, + { + version: '5.6.0', + releaseTimestamp: '2020-02-13T15:37:00.000Z' as Timestamp, + }, { version: '5.6.1' }, ], }); diff --git a/lib/workers/repository/update/pr/changelog/github/index.spec.ts b/lib/workers/repository/update/pr/changelog/github/index.spec.ts index 4e85b2a379b4afb..b5a3523ca1098e8 100644 --- a/lib/workers/repository/update/pr/changelog/github/index.spec.ts +++ b/lib/workers/repository/update/pr/changelog/github/index.spec.ts @@ -6,6 +6,7 @@ import * as semverVersioning from '../../../../../../modules/versioning/semver'; import * as githubGraphql from '../../../../../../util/github/graphql'; import type { GithubTagItem } from '../../../../../../util/github/graphql/types'; import * as hostRules from '../../../../../../util/host-rules'; +import type { Timestamp } from '../../../../../../util/timestamp'; import type { BranchUpgradeConfig } from '../../../../../types'; jest.mock('../../../../../../modules/datasource/npm'); @@ -25,10 +26,13 @@ const upgrade = partial({ { version: '2.3.0', gitRef: 'npm_2.3.0', - releaseTimestamp: '2017-10-24T03:20:46.238Z', + releaseTimestamp: '2017-10-24T03:20:46.238Z' as Timestamp, }, { version: '2.2.2', gitRef: 'npm_2.2.2' }, - { version: '2.4.2', releaseTimestamp: '2017-12-24T03:20:46.238Z' }, + { + version: '2.4.2', + releaseTimestamp: '2017-12-24T03:20:46.238Z' as Timestamp, + }, { version: '2.5.2' }, ], }); diff --git a/lib/workers/repository/update/pr/changelog/gitlab/index.spec.ts b/lib/workers/repository/update/pr/changelog/gitlab/index.spec.ts index f55e0e197cfc39d..8986b7dbbb081be 100644 --- a/lib/workers/repository/update/pr/changelog/gitlab/index.spec.ts +++ b/lib/workers/repository/update/pr/changelog/gitlab/index.spec.ts @@ -3,6 +3,7 @@ import * as httpMock from '../../../../../../../test/http-mock'; import { partial } from '../../../../../../../test/util'; import * as semverVersioning from '../../../../../../modules/versioning/semver'; import * as hostRules from '../../../../../../util/host-rules'; +import type { Timestamp } from '../../../../../../util/timestamp'; import type { BranchUpgradeConfig } from '../../../../../types'; import { GitLabChangeLogSource } from './source'; @@ -20,10 +21,13 @@ const upgrade = partial({ { version: '5.2.0' }, { version: '5.4.0', - releaseTimestamp: '2018-08-24T14:23:00.000Z', + releaseTimestamp: '2018-08-24T14:23:00.000Z' as Timestamp, }, { version: '5.5.0', gitRef: 'eba303e91c930292198b2fc57040145682162a1b' }, - { version: '5.6.0', releaseTimestamp: '2020-02-13T15:37:00.000Z' }, + { + version: '5.6.0', + releaseTimestamp: '2020-02-13T15:37:00.000Z' as Timestamp, + }, { version: '5.6.1' }, ], }); diff --git a/lib/workers/repository/update/pr/changelog/index.spec.ts b/lib/workers/repository/update/pr/changelog/index.spec.ts index 5dcfa186fcc60c1..f74d1cbc1a9f0a9 100644 --- a/lib/workers/repository/update/pr/changelog/index.spec.ts +++ b/lib/workers/repository/update/pr/changelog/index.spec.ts @@ -4,6 +4,7 @@ import { GlobalConfig } from '../../../../../config/global'; import * as semverVersioning from '../../../../../modules/versioning/semver'; import * as githubGraphql from '../../../../../util/github/graphql'; import * as hostRules from '../../../../../util/host-rules'; +import type { Timestamp } from '../../../../../util/timestamp'; import type { BranchConfig } from '../../../../types'; import * as releases from './releases'; import { getChangeLogJSON } from '.'; @@ -29,10 +30,13 @@ const upgrade = partial({ { version: '2.3.0', gitRef: 'npm_2.3.0', - releaseTimestamp: '2017-10-24T03:20:46.238Z', + releaseTimestamp: '2017-10-24T03:20:46.238Z' as Timestamp, }, { version: '2.2.2', gitRef: 'npm_2.2.2' }, - { version: '2.4.2', releaseTimestamp: '2017-12-24T03:20:46.238Z' }, + { + version: '2.4.2', + releaseTimestamp: '2017-12-24T03:20:46.238Z' as Timestamp, + }, { version: '2.5.2' }, ], }); diff --git a/lib/workers/repository/update/pr/changelog/release-notes.spec.ts b/lib/workers/repository/update/pr/changelog/release-notes.spec.ts index 7bb3bd2ebb0c777..42534bb5bc1e082 100644 --- a/lib/workers/repository/update/pr/changelog/release-notes.spec.ts +++ b/lib/workers/repository/update/pr/changelog/release-notes.spec.ts @@ -8,6 +8,7 @@ import * as githubGraphql from '../../../../../util/github/graphql'; import type { GithubReleaseItem } from '../../../../../util/github/graphql/types'; import * as _hostRules from '../../../../../util/host-rules'; import { toBase64 } from '../../../../../util/string'; +import type { Timestamp } from '../../../../../util/timestamp'; import type { BranchUpgradeConfig } from '../../../../types'; import { addReleaseNotes, @@ -251,7 +252,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { githubReleasesMock.mockResolvedValueOnce([ { version: `v1.0.0`, - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 1, url: 'https://example.com', name: 'some/dep', @@ -259,7 +260,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }, { version: `v1.0.1`, - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 1, url: 'https://example.com', name: 'some/dep', @@ -370,7 +371,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { githubReleasesMock.mockResolvedValueOnce([ { version: '1.0.0', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 1, url: 'https://github.com/some/other-repository/releases/1.0.0', name: '', @@ -378,7 +379,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }, { version: '1.0.1', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 2, url: 'https://github.com/some/other-repository/releases/1.0.1', name: '', @@ -404,7 +405,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { githubReleasesMock.mockResolvedValueOnce([ { version: '1.0.0', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 1, url: 'https://github.com/some/other-repository/releases/1.0.0', name: 'some/dep', @@ -412,7 +413,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }, { version: '1.0.1', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 2, url: 'https://github.com/some/other-repository/releases/1.0.1', name: 'some/dep', @@ -447,7 +448,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { githubReleasesMock.mockResolvedValueOnce([ { version: '1.0.0', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 1, url: 'https://github.com/some/other-repository/releases/1.0.0', name: 'some/dep', @@ -455,7 +456,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }, { version: '1.0.1', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 2, url: 'https://github.com/some/other-repository/releases/1.0.1', name: 'some release name', @@ -489,7 +490,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { githubReleasesMock.mockResolvedValueOnce([ { version: '1.0.0', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 1, url: 'https://github.com/some/other-repository/releases/1.0.0', name: 'Release v1.0.0', @@ -497,7 +498,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }, { version: '1.0.1', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 2, url: 'https://github.com/some/other-repository/releases/1.0.1', name: '1.0.1', @@ -531,7 +532,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { githubReleasesMock.mockResolvedValueOnce([ { version: '1.0.0', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 1, url: 'https://github.com/some/other-repository/releases/1.0.1', name: 'some/dep', @@ -539,7 +540,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }, { version: '1.0.1', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 2, url: 'https://github.com/some/other-repository/releases/1.0.1', name: 'v1.0.1 some release', @@ -573,7 +574,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { githubReleasesMock.mockResolvedValueOnce([ { version: '1.0.0', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 1, url: 'correct/url/tag.com', name: 'some/dep', @@ -581,7 +582,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }, { version: '1.0.1', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 2, url: 'correct/url/tag.com', name: '1.0.1', @@ -607,7 +608,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { githubReleasesMock.mockResolvedValueOnce([ { version: 'v1.0.0', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 1, url: 'https://github.com/some/other-repository/releases/v1.0.0', name: 'some/dep', @@ -615,7 +616,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }, { version: 'v1.0.1', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 2, url: 'https://github.com/some/other-repository/releases/v1.0.1', name: 'some/dep', @@ -650,7 +651,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { githubReleasesMock.mockResolvedValueOnce([ { version: 'other-1.0.0', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 1, url: 'https://github.com/some/other-repository/releases/other-1.0.0', name: 'some/dep', @@ -658,7 +659,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }, { version: 'other-1.0.1', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 2, url: 'https://github.com/some/other-repository/releases/other-1.0.1', name: 'some/dep', @@ -694,7 +695,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { githubReleasesMock.mockResolvedValueOnce([ { version: 'other-1.0.0', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 1, url: 'https://github.com/some/other-repository/releases/other-1.0.0', name: 'some/dep', @@ -702,7 +703,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }, { version: 'other-1.0.1', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 2, url: 'https://github.com/some/other-repository/releases/other-1.0.1', name: 'some/dep', @@ -739,7 +740,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { githubReleasesMock.mockResolvedValueOnce([ { version: 'other_v1.0.0', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 1, url: 'https://github.com/some/other-repository/releases/other_v1.0.0', name: 'some/dep', @@ -747,7 +748,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { }, { version: 'other_v1.0.1', - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, id: 2, url: 'https://github.com/some/other-repository/releases/other_v1.0.1', name: 'some/dep', @@ -784,7 +785,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { { version: 'other@1.0.0', id: 1, - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, url: 'https://github.com/some/other-repository/releases/other@1.0.0', name: 'some/dep', description: 'some body', @@ -794,7 +795,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { description: 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)', id: 2, - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, url: 'https://github.com/some/other-repository/releases/other@1.0.1', name: 'some/dep', }, @@ -956,7 +957,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { { id: 1, version: `${packageName}@1.0.0`, - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, url: 'correct/url/tag.com', name: 'some/dep', description: 'some body', @@ -964,7 +965,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { { id: 2, version: `someOtherRelease1/exampleDep_1.0.0`, - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, url: 'correct/url/tag.com', name: 'some/dep', description: 'some body', @@ -972,7 +973,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { { id: 3, version: `someOtherRelease2/exampleDep-1.0.0`, - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, url: 'correct/url/tag.com', name: 'some/dep', description: 'some body', @@ -1006,7 +1007,7 @@ describe('workers/repository/update/pr/changelog/release-notes', () => { { id: 123, version: `app-1.0.0`, - releaseTimestamp: '2020-01-01', + releaseTimestamp: '2020-01-01' as Timestamp, url: 'correct/url/tag.com', description: 'some body', name: 'some/dep', diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index 2583501774f4b4a..20de0385e341a8f 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -89,8 +89,9 @@ describe('workers/repository/update/pr/index', () => { const res = await ensurePr(config); expect(res).toEqual({ type: 'with-pr', pr }); - expect(limits.incLimitedValue).toHaveBeenCalledOnce(); - expect(limits.incLimitedValue).toHaveBeenCalledWith('PullRequests'); + expect(limits.incCountValue).toHaveBeenCalledTimes(2); + expect(limits.incCountValue).toHaveBeenCalledWith('ConcurrentPRs'); + expect(limits.incCountValue).toHaveBeenCalledWith('HourlyPRs'); expect(logger.logger.info).toHaveBeenCalledWith( { pr: pr.number, prTitle }, 'PR created', diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index aa6817daf31a351..6b1a05a75e0af9a 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -27,7 +27,7 @@ import { stripEmojis } from '../../../../util/emoji'; import { fingerprint } from '../../../../util/fingerprint'; import { getBranchLastCommitTime } from '../../../../util/git'; import { memoize } from '../../../../util/memoize'; -import { incLimitedValue, isLimitReached } from '../../../global/limits'; +import { incCountValue, isLimitReached } from '../../../global/limits'; import type { BranchConfig, BranchUpgradeConfig, @@ -482,7 +482,7 @@ export async function ensurePr( try { if ( !dependencyDashboardCheck && - isLimitReached('PullRequests') && + isLimitReached('ConcurrentPRs', prConfig) && !config.isVulnerabilityAlert ) { logger.debug('Skipping PR - limit reached'); @@ -499,7 +499,8 @@ export async function ensurePr( milestone: config.milestone, }); - incLimitedValue('PullRequests'); + incCountValue('ConcurrentPRs'); + incCountValue('HourlyPRs'); logger.info({ pr: pr?.number, prTitle }, 'PR created'); } catch (err) { logger.debug({ err }, 'Pull request creation error'); diff --git a/lib/workers/repository/updates/flatten.spec.ts b/lib/workers/repository/updates/flatten.spec.ts index 42cd3a7b3b6fe7e..8561d1a0a1afb00 100644 --- a/lib/workers/repository/updates/flatten.spec.ts +++ b/lib/workers/repository/updates/flatten.spec.ts @@ -1,7 +1,7 @@ import is from '@sindresorhus/is'; import type { RenovateConfig } from '../../../../test/util'; import { getConfig } from '../../../config/defaults'; -import { flattenUpdates } from './flatten'; +import { flattenUpdates, sanitizeDepName } from './flatten'; jest.mock('../../../util/git/semantic'); @@ -14,6 +14,14 @@ beforeEach(() => { }); describe('workers/repository/updates/flatten', () => { + describe('sanitizeDepName()', () => { + it('sanitizes urls', () => { + expect(sanitizeDepName('https://some.host.name/a/path/to.git')).toBe( + 'https-some.host.name-a-path-to.git', + ); + }); + }); + describe('flattenUpdates()', () => { it('flattens', async () => { // TODO #22198 diff --git a/lib/workers/repository/updates/flatten.ts b/lib/workers/repository/updates/flatten.ts index 93b1d51c8556c48..989ff00553864cd 100644 --- a/lib/workers/repository/updates/flatten.ts +++ b/lib/workers/repository/updates/flatten.ts @@ -17,12 +17,13 @@ import { generateBranchName } from './branch-name'; const upper = (str: string): string => str.charAt(0).toUpperCase() + str.substring(1); -function sanitizeDepName(depName: string): string { +export function sanitizeDepName(depName: string): string { return depName .replace('@types/', '') .replace('@', '') .replace(regEx(/\//g), '-') .replace(regEx(/\s+/g), '-') + .replace(regEx(/:/g), '-') .replace(regEx(/-+/), '-') .toLowerCase(); } diff --git a/lib/workers/repository/updates/generate.spec.ts b/lib/workers/repository/updates/generate.spec.ts index 6769da86bb68035..ad7bfe4f8628012 100644 --- a/lib/workers/repository/updates/generate.spec.ts +++ b/lib/workers/repository/updates/generate.spec.ts @@ -2,6 +2,7 @@ import { codeBlock } from 'common-tags'; import { getConfig } from '../../../config/defaults'; import type { UpdateType } from '../../../config/types'; import { NpmDatasource } from '../../../modules/datasource/npm'; +import type { Timestamp } from '../../../util/timestamp'; import type { BranchUpgradeConfig } from '../../types'; import { generateBranchConfig } from './generate'; @@ -34,7 +35,7 @@ describe('workers/repository/updates/generate', () => { depName: 'some-dep', groupName: 'some-group', prTitle: 'some-title', - releaseTimestamp: '2017-02-07T20:01:41+00:00', + releaseTimestamp: '2017-02-07T20:01:41+00:00' as Timestamp, foo: 1, group: { foo: 2, @@ -161,7 +162,7 @@ describe('workers/repository/updates/generate', () => { group: { foo: 2, }, - releaseTimestamp: '2017-02-07T20:01:41+00:00', + releaseTimestamp: '2017-02-07T20:01:41+00:00' as Timestamp, automerge: true, constraints: { foo: '1.0.0', @@ -181,7 +182,7 @@ describe('workers/repository/updates/generate', () => { group: { foo: 2, }, - releaseTimestamp: '2017-02-06T20:01:41+00:00', + releaseTimestamp: '2017-02-06T20:01:41+00:00' as Timestamp, automerge: false, constraints: { foo: '1.0.0', @@ -202,7 +203,7 @@ describe('workers/repository/updates/generate', () => { group: { foo: 2, }, - releaseTimestamp: '2017-02-06T20:01:41+00:00', + releaseTimestamp: '2017-02-06T20:01:41+00:00' as Timestamp, automerge: false, }, ]; @@ -400,7 +401,7 @@ describe('workers/repository/updates/generate', () => { group: { foo: 2, }, - releaseTimestamp: '2017-02-07T20:01:41+00:00', + releaseTimestamp: '2017-02-07T20:01:41+00:00' as Timestamp, updateType: 'minor', separateMinorPatch: true, prTitleStrict: true, @@ -420,7 +421,7 @@ describe('workers/repository/updates/generate', () => { group: { foo: 2, }, - releaseTimestamp: '2017-02-08T20:01:41+00:00', + releaseTimestamp: '2017-02-08T20:01:41+00:00' as Timestamp, updateType: 'minor', separateMinorPatch: true, prTitleStrict: true, @@ -455,7 +456,7 @@ describe('workers/repository/updates/generate', () => { group: { foo: 2, }, - releaseTimestamp: '2017-02-07T20:01:41+00:00', + releaseTimestamp: '2017-02-07T20:01:41+00:00' as Timestamp, updateType: 'minor', separateMinorPatch: true, }, @@ -474,7 +475,7 @@ describe('workers/repository/updates/generate', () => { group: { foo: 2, }, - releaseTimestamp: '2017-02-08T20:01:41+00:00', + releaseTimestamp: '2017-02-08T20:01:41+00:00' as Timestamp, updateType: 'minor', separateMinorPatch: true, }, @@ -507,7 +508,7 @@ describe('workers/repository/updates/generate', () => { group: { foo: 2, }, - releaseTimestamp: '2017-02-07T20:01:41+00:00', + releaseTimestamp: '2017-02-07T20:01:41+00:00' as Timestamp, }, { manager: 'some-manager', @@ -523,7 +524,7 @@ describe('workers/repository/updates/generate', () => { group: { foo: 2, }, - releaseTimestamp: '2017-02-08T20:01:41+00:00', + releaseTimestamp: '2017-02-08T20:01:41+00:00' as Timestamp, }, ] satisfies BranchUpgradeConfig[]; const res = generateBranchConfig(branch); @@ -550,7 +551,7 @@ describe('workers/repository/updates/generate', () => { group: { foo: 2, }, - releaseTimestamp: '2017-02-07T20:01:41+00:00', + releaseTimestamp: '2017-02-07T20:01:41+00:00' as Timestamp, }, { manager: 'some-manager', @@ -566,7 +567,7 @@ describe('workers/repository/updates/generate', () => { group: { foo: 2, }, - releaseTimestamp: '2017-02-08T20:01:41+00:00', + releaseTimestamp: '2017-02-08T20:01:41+00:00' as Timestamp, }, ] satisfies BranchUpgradeConfig[]; const res = generateBranchConfig(branch); @@ -651,7 +652,7 @@ describe('workers/repository/updates/generate', () => { group: { foo: 2, }, - releaseTimestamp: '2017-02-07T20:01:41+00:00', + releaseTimestamp: '2017-02-07T20:01:41+00:00' as Timestamp, }, { manager: 'some-manager', @@ -667,7 +668,7 @@ describe('workers/repository/updates/generate', () => { group: { foo: 2, }, - releaseTimestamp: '2017-02-08T20:01:41+00:00', + releaseTimestamp: '2017-02-08T20:01:41+00:00' as Timestamp, }, ] satisfies BranchUpgradeConfig[]; const res = generateBranchConfig(branch); diff --git a/lib/workers/repository/updates/generate.ts b/lib/workers/repository/updates/generate.ts index f2637f2fb95a665..c2db51f46b56561 100644 --- a/lib/workers/repository/updates/generate.ts +++ b/lib/workers/repository/updates/generate.ts @@ -9,6 +9,7 @@ import { newlineRegex, regEx } from '../../../util/regex'; import { sanitize } from '../../../util/sanitize'; import { safeStringify } from '../../../util/stringify'; import * as template from '../../../util/template'; +import type { Timestamp } from '../../../util/timestamp'; import { uniq } from '../../../util/uniq'; import type { BranchConfig, BranchUpgradeConfig } from '../../types'; import { CommitMessage } from '../model/commit-message'; @@ -245,7 +246,7 @@ export function generateBranchConfig( logger.trace(`groupEligible: ${groupEligible}`); const useGroupSettings = hasGroupName && groupEligible; logger.trace(`useGroupSettings: ${useGroupSettings}`); - let releaseTimestamp: string; + let releaseTimestamp: Timestamp; if (depTypes.size) { config.depTypes = Array.from(depTypes).sort(); diff --git a/lib/workers/types.ts b/lib/workers/types.ts index e4c6477b45f6627..3b5727320bbe08f 100644 --- a/lib/workers/types.ts +++ b/lib/workers/types.ts @@ -19,6 +19,7 @@ import type { import type { PlatformPrOptions } from '../modules/platform/types'; import type { FileChange } from '../util/git/types'; import type { MergeConfidence } from '../util/merge-confidence/types'; +import type { Timestamp } from '../util/timestamp'; import type { ChangeLogRelease, ChangeLogResult, @@ -65,7 +66,7 @@ export interface BranchUpgradeConfig prettyNewMajor?: string; prettyNewVersion?: string; releases?: ReleaseWithNotes[]; - releaseTimestamp?: string; + releaseTimestamp?: Timestamp; repoName?: string; minimumConfidence?: MergeConfidence | undefined; sourceDirectory?: string; @@ -122,7 +123,7 @@ export interface BranchConfig errors?: ValidationMessage[]; hasTypes?: boolean; dependencyDashboardChecks?: Record; - releaseTimestamp?: string; + releaseTimestamp?: Timestamp; forceCommit?: boolean; rebaseRequested?: boolean; result?: BranchResult; diff --git a/package.json b/package.json index e849a97a597b754..4f764221c5b21b4 100644 --- a/package.json +++ b/package.json @@ -139,8 +139,8 @@ "pnpm": "^9.0.0" }, "volta": { - "node": "22.13.0", - "pnpm": "9.15.3" + "node": "22.13.1", + "pnpm": "9.15.4" }, "dependencies": { "@aws-sdk/client-codecommit": "3.726.1", @@ -152,19 +152,19 @@ "@breejs/later": "4.2.0", "@cdktf/hcl2json": "0.20.11", "@opentelemetry/api": "1.9.0", - "@opentelemetry/context-async-hooks": "1.30.0", - "@opentelemetry/exporter-trace-otlp-http": "0.57.0", - "@opentelemetry/instrumentation": "0.57.0", + "@opentelemetry/context-async-hooks": "1.30.1", + "@opentelemetry/exporter-trace-otlp-http": "0.57.1", + "@opentelemetry/instrumentation": "0.57.1", "@opentelemetry/instrumentation-bunyan": "0.45.0", - "@opentelemetry/instrumentation-http": "0.57.0", - "@opentelemetry/resources": "1.30.0", - "@opentelemetry/sdk-trace-base": "1.30.0", - "@opentelemetry/sdk-trace-node": "1.30.0", + "@opentelemetry/instrumentation-http": "0.57.1", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/sdk-trace-base": "1.30.1", + "@opentelemetry/sdk-trace-node": "1.30.1", "@opentelemetry/semantic-conventions": "1.28.0", "@qnighy/marshal": "0.1.3", "@renovatebot/detect-tools": "1.1.0", "@renovatebot/kbpgp": "4.0.1", - "@renovatebot/osv-offline": "1.5.11", + "@renovatebot/osv-offline": "1.5.12", "@renovatebot/pep440": "4.0.1", "@renovatebot/ruby-semver": "4.0.0", "@sindresorhus/is": "4.6.0", @@ -184,7 +184,7 @@ "commander": "12.1.0", "conventional-commits-detector": "1.0.3", "croner": "9.0.0", - "cronstrue": "2.52.0", + "cronstrue": "2.53.0", "deepmerge": "4.3.1", "dequal": "2.0.3", "detect-indent": "6.1.0", @@ -197,7 +197,7 @@ "extract-zip": "2.0.1", "find-packages": "10.0.4", "find-up": "5.0.0", - "fs-extra": "11.2.0", + "fs-extra": "11.3.0", "git-url-parse": "16.0.0", "github-url-from-git": "1.5.0", "glob": "11.0.1", @@ -207,7 +207,7 @@ "got": "11.8.6", "graph-data-structure": "4.3.0", "handlebars": "4.7.8", - "ignore": "7.0.0", + "ignore": "7.0.3", "ini": "5.0.0", "json-dup-key-validator": "1.0.3", "json-stringify-pretty-compact": "3.0.0", @@ -254,7 +254,7 @@ "zod": "3.24.1" }, "optionalDependencies": { - "better-sqlite3": "11.7.2", + "better-sqlite3": "11.8.0", "openpgp": "6.0.1", "re2": "1.21.4" }, @@ -299,7 +299,7 @@ "@types/mdast": "3.0.15", "@types/moo": "0.5.10", "@types/ms": "0.7.34", - "@types/node": "22.10.5", + "@types/node": "22.10.7", "@types/parse-link-header": "2.0.3", "@types/punycode": "2.1.4", "@types/semver": "7.5.8", @@ -311,8 +311,8 @@ "@types/url-join": "4.0.3", "@types/validate-npm-package-name": "4.0.2", "@types/xmldoc": "1.1.9", - "@typescript-eslint/eslint-plugin": "8.19.1", - "@typescript-eslint/parser": "8.19.1", + "@typescript-eslint/eslint-plugin": "8.20.0", + "@typescript-eslint/parser": "8.20.0", "aws-sdk-client-mock": "4.1.0", "callsite": "1.0.0", "common-tags": "1.8.2", @@ -322,7 +322,7 @@ "eslint-formatter-gha": "1.5.2", "eslint-import-resolver-typescript": "3.7.0", "eslint-plugin-import": "2.31.0", - "eslint-plugin-jest": "28.10.0", + "eslint-plugin-jest": "28.11.0", "eslint-plugin-jest-formatting": "3.1.0", "eslint-plugin-promise": "7.2.1", "eslint-plugin-typescript-enum": "2.1.0", @@ -351,7 +351,7 @@ "typescript": "5.7.3", "unified": "9.2.2" }, - "packageManager": "pnpm@9.15.3", + "packageManager": "pnpm@9.15.4", "files": [ "dist", "renovate-schema.json" diff --git a/pdm.lock b/pdm.lock index 2a60e46c387dca4..2300b1e1502c678 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default"] strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:389d88fe2eea354363ad2bc3a292f9398c1ab70d41dec7307928a6d5fe1a11c5" +content_hash = "sha256:a03cc9a3cd0c5c98c36b8ea5b28cad01f8fc69178d24ab168005edb15697d803" [[metadata.targets]] requires_python = ">=3.11" @@ -297,7 +297,7 @@ files = [ [[package]] name = "mkdocs-material" -version = "9.5.49" +version = "9.5.50" requires_python = ">=3.8" summary = "Documentation that simply works" groups = ["default"] @@ -315,8 +315,8 @@ dependencies = [ "requests~=2.26", ] files = [ - {file = "mkdocs_material-9.5.49-py3-none-any.whl", hash = "sha256:c3c2d8176b18198435d3a3e119011922f3e11424074645c24019c2dcf08a360e"}, - {file = "mkdocs_material-9.5.49.tar.gz", hash = "sha256:3671bb282b4f53a1c72e08adbe04d2481a98f85fed392530051f80ff94a9621d"}, + {file = "mkdocs_material-9.5.50-py3-none-any.whl", hash = "sha256:f24100f234741f4d423a9d672a909d859668a4f404796be3cf035f10d6050385"}, + {file = "mkdocs_material-9.5.50.tar.gz", hash = "sha256:ae5fe16f3d7c9ccd05bb6916a7da7420cf99a9ce5e33debd9d40403a090d5825"}, ] [[package]] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 42951809e0fdaa9..9a57daca0acaf24 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,29 +39,29 @@ importers: specifier: 1.9.0 version: 1.9.0 '@opentelemetry/context-async-hooks': - specifier: 1.30.0 - version: 1.30.0(@opentelemetry/api@1.9.0) + specifier: 1.30.1 + version: 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/exporter-trace-otlp-http': - specifier: 0.57.0 - version: 0.57.0(@opentelemetry/api@1.9.0) + specifier: 0.57.1 + version: 0.57.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation': - specifier: 0.57.0 - version: 0.57.0(@opentelemetry/api@1.9.0) + specifier: 0.57.1 + version: 0.57.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-bunyan': specifier: 0.45.0 version: 0.45.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-http': - specifier: 0.57.0 - version: 0.57.0(@opentelemetry/api@1.9.0) + specifier: 0.57.1 + version: 0.57.1(@opentelemetry/api@1.9.0) '@opentelemetry/resources': - specifier: 1.30.0 - version: 1.30.0(@opentelemetry/api@1.9.0) + specifier: 1.30.1 + version: 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': - specifier: 1.30.0 - version: 1.30.0(@opentelemetry/api@1.9.0) + specifier: 1.30.1 + version: 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-node': - specifier: 1.30.0 - version: 1.30.0(@opentelemetry/api@1.9.0) + specifier: 1.30.1 + version: 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': specifier: 1.28.0 version: 1.28.0 @@ -75,8 +75,8 @@ importers: specifier: 4.0.1 version: 4.0.1 '@renovatebot/osv-offline': - specifier: 1.5.11 - version: 1.5.11(encoding@0.1.13) + specifier: 1.5.12 + version: 1.5.12(encoding@0.1.13) '@renovatebot/pep440': specifier: 4.0.1 version: 4.0.1 @@ -135,8 +135,8 @@ importers: specifier: 9.0.0 version: 9.0.0 cronstrue: - specifier: 2.52.0 - version: 2.52.0 + specifier: 2.53.0 + version: 2.53.0 deepmerge: specifier: 4.3.1 version: 4.3.1 @@ -174,8 +174,8 @@ importers: specifier: 5.0.0 version: 5.0.0 fs-extra: - specifier: 11.2.0 - version: 11.2.0 + specifier: 11.3.0 + version: 11.3.0 git-url-parse: specifier: 16.0.0 version: 16.0.0 @@ -204,8 +204,8 @@ importers: specifier: 4.7.8 version: 4.7.8 ignore: - specifier: 7.0.0 - version: 7.0.0 + specifier: 7.0.3 + version: 7.0.3 ini: specifier: 5.0.0 version: 5.0.0 @@ -340,8 +340,8 @@ importers: version: 3.24.1 optionalDependencies: better-sqlite3: - specifier: 11.7.2 - version: 11.7.2 + specifier: 11.8.0 + version: 11.8.0 openpgp: specifier: 6.0.1 version: 6.0.1 @@ -470,8 +470,8 @@ importers: specifier: 0.7.34 version: 0.7.34 '@types/node': - specifier: 22.10.5 - version: 22.10.5 + specifier: 22.10.7 + version: 22.10.7 '@types/parse-link-header': specifier: 2.0.3 version: 2.0.3 @@ -506,11 +506,11 @@ importers: specifier: 1.1.9 version: 1.1.9 '@typescript-eslint/eslint-plugin': - specifier: 8.19.1 - version: 8.19.1(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3) + specifier: 8.20.0 + version: 8.20.0(@typescript-eslint/parser@8.20.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3) '@typescript-eslint/parser': - specifier: 8.19.1 - version: 8.19.1(eslint@8.57.1)(typescript@5.7.3) + specifier: 8.20.0 + version: 8.20.0(eslint@8.57.1)(typescript@5.7.3) aws-sdk-client-mock: specifier: 4.1.0 version: 4.1.0 @@ -537,10 +537,10 @@ importers: version: 3.7.0(eslint-plugin-import@2.31.0)(eslint@8.57.1) eslint-plugin-import: specifier: 2.31.0 - version: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) + version: 2.31.0(@typescript-eslint/parser@8.20.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) eslint-plugin-jest: - specifier: 28.10.0 - version: 28.10.0(@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(jest@29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)))(typescript@5.7.3) + specifier: 28.11.0 + version: 28.11.0(@typescript-eslint/eslint-plugin@8.20.0(@typescript-eslint/parser@8.20.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(jest@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)))(typescript@5.7.3) eslint-plugin-jest-formatting: specifier: 3.1.0 version: 3.1.0(eslint@8.57.1) @@ -564,16 +564,16 @@ importers: version: 9.1.7 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)) + version: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)) jest-extended: specifier: 4.0.2 - version: 4.0.2(jest@29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3))) + version: 4.0.2(jest@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3))) jest-mock: specifier: 29.7.0 version: 29.7.0 jest-mock-extended: specifier: 3.0.7 - version: 3.0.7(jest@29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)))(typescript@5.7.3) + version: 3.0.7(jest@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)))(typescript@5.7.3) jest-snapshot: specifier: 29.7.0 version: 29.7.0 @@ -609,10 +609,10 @@ importers: version: 3.0.3 ts-jest: specifier: 29.2.5 - version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)))(typescript@5.7.3) + version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)))(typescript@5.7.3) ts-node: specifier: 10.9.2 - version: 10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3) + version: 10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3) type-fest: specifier: 4.32.0 version: 4.32.0 @@ -1302,8 +1302,8 @@ packages: resolution: {integrity: sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==} engines: {node: '>= 18'} - '@octokit/request@9.1.4': - resolution: {integrity: sha512-tMbOwGm6wDII6vygP3wUVqFTw3Aoo0FnVQyhihh8vVq12uO3P+vQZeo2CKMpWtPSogpACD0yyZAlVlQnjW71DA==} + '@octokit/request@9.2.0': + resolution: {integrity: sha512-kXLfcxhC4ozCnAXy2ff+cSxpcF0A1UqxjvYMqNuPIeOAzJbVWQ+dy5G2fTylofB/gTbObT8O6JORab+5XtA1Kw==} engines: {node: '>= 18'} '@octokit/rest@20.1.1': @@ -1325,28 +1325,28 @@ packages: typescript: optional: true - '@opentelemetry/api-logs@0.57.0': - resolution: {integrity: sha512-l1aJ30CXeauVYaI+btiynHpw341LthkMTv3omi1VJDX14werY2Wmv9n1yudMsq9HuY0m8PvXEVX4d8zxEb+WRg==} + '@opentelemetry/api-logs@0.57.1': + resolution: {integrity: sha512-I4PHczeujhQAQv6ZBzqHYEUiggZL4IdSMixtVD3EYqbdrjujE7kRfI5QohjlPoJm8BvenoW5YaTMWRrbpot6tg==} engines: {node: '>=14'} '@opentelemetry/api@1.9.0': resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} - '@opentelemetry/context-async-hooks@1.30.0': - resolution: {integrity: sha512-roCetrG/cz0r/gugQm/jFo75UxblVvHaNSRoR0kSSRSzXFAiIBqFCZuH458BHBNRtRe+0yJdIJ21L9t94bw7+g==} + '@opentelemetry/context-async-hooks@1.30.1': + resolution: {integrity: sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/core@1.30.0': - resolution: {integrity: sha512-Q/3u/K73KUjTCnFUP97ZY+pBjQ1kPEgjOfXj/bJl8zW7GbXdkw6cwuyZk6ZTXkVgCBsYRYUzx4fvYK1jxdb9MA==} + '@opentelemetry/core@1.30.1': + resolution: {integrity: sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/exporter-trace-otlp-http@0.57.0': - resolution: {integrity: sha512-BJl35PSkwoMlGEOrzjCG1ih6zqZoAZJIR4xyqSKC2BqPtwuRjID0vWBaEdP9xrxxJTEIEQw+gEY/0pUgicX0ew==} + '@opentelemetry/exporter-trace-otlp-http@0.57.1': + resolution: {integrity: sha512-43dLEjlf6JGxpVt9RaRlJAvjHG1wGsbAuNd67RIDy/95zfKk2aNovtiGUgFdS/kcvgvS90upIUbgn0xUd9JjMg==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 @@ -1357,68 +1357,68 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-http@0.57.0': - resolution: {integrity: sha512-GJD6e/YSSZUI/xZokK9L+ghMAyFrtGV+8HHXCnV8tDYCo66biLpmC9BUTg6fBnv26QsosYvFTYbdo6Sfn6TxCw==} + '@opentelemetry/instrumentation-http@0.57.1': + resolution: {integrity: sha512-ThLmzAQDs7b/tdKI3BV2+yawuF09jF111OFsovqT1Qj3D8vjwKBwhi/rDE5xethwn4tSXtZcJ9hBsVAlWFQZ7g==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation@0.57.0': - resolution: {integrity: sha512-qIKp+tSCLqofneUWRc5XHtr9jHIq0N0BJfaJamM9gjEFO8sthV4SDXDGNOSAx16PxkbrQJ5/AxMPAGCXl8W/Hg==} + '@opentelemetry/instrumentation@0.57.1': + resolution: {integrity: sha512-SgHEKXoVxOjc20ZYusPG3Fh+RLIZTSa4x8QtD3NfgAUDyqdFFS9W1F2ZVbZkqDCdyMcQG02Ok4duUGLHJXHgbA==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/otlp-exporter-base@0.57.0': - resolution: {integrity: sha512-QQl4Ngm3D6H8SDO0EM642ncTxjRsf/HDq7+IWIA0eaEK/NTsJeQ3iYJiZj3F4jkALnvyeM1kkwd+DHtqxTBx9Q==} + '@opentelemetry/otlp-exporter-base@0.57.1': + resolution: {integrity: sha512-GNBJAEYfeiYJQ3O2dvXgiNZ/qjWrBxSb1L1s7iV/jKBRGMN3Nv+miTk2SLeEobF5E5ZK4rVcHKlBZ71bPVIv/g==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/otlp-transformer@0.57.0': - resolution: {integrity: sha512-yHX7sdwkdAmSa6Jbi3caSLDWy0PCHS1pKQeKz8AIWSyQqL7IojHKgdk9A+7eRd98Z1n9YTdwWSWLnObvIqhEhQ==} + '@opentelemetry/otlp-transformer@0.57.1': + resolution: {integrity: sha512-EX67y+ukNNfFrOLyjYGw8AMy0JPIlEX1dW60SGUNZWW2hSQyyolX7EqFuHP5LtXLjJHNfzx5SMBVQ3owaQCNDw==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/propagator-b3@1.30.0': - resolution: {integrity: sha512-lcobQQmd+hLdtxJJKu/i51lNXmF1PJJ7Y9B97ciHRVQuMI260vSZG7Uf4Zg0fqR8PB+fT/7rnlDwS0M7QldZQQ==} + '@opentelemetry/propagator-b3@1.30.1': + resolution: {integrity: sha512-oATwWWDIJzybAZ4pO76ATN5N6FFbOA1otibAVlS8v90B4S1wClnhRUk7K+2CHAwN1JKYuj4jh/lpCEG5BAqFuQ==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/propagator-jaeger@1.30.0': - resolution: {integrity: sha512-0hdP495V6HPRkVpowt54+Swn5NdesMIRof+rlp0mbnuIUOM986uF+eNxnPo9q5MmJegVBRTxgMHXXwvnXRnKRg==} + '@opentelemetry/propagator-jaeger@1.30.1': + resolution: {integrity: sha512-Pj/BfnYEKIOImirH76M4hDaBSx6HyZ2CXUqk+Kj02m6BB80c/yo4BdWkn/1gDFfU+YPY+bPR2U0DKBfdxCKwmg==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/resources@1.30.0': - resolution: {integrity: sha512-5mGMjL0Uld/99t7/pcd7CuVtJbkARckLVuiOX84nO8RtLtIz0/J6EOHM2TGvPZ6F4K+XjUq13gMx14w80SVCQg==} + '@opentelemetry/resources@1.30.1': + resolution: {integrity: sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/sdk-logs@0.57.0': - resolution: {integrity: sha512-6Kbxdu/QE9LWH7+WSLmYo3DjAq+c55TiCLXiXu6b/2m2muy5SyOG2m0MrGqetyRpfYSSbIqHmJoqNVTN3+2a9g==} + '@opentelemetry/sdk-logs@0.57.1': + resolution: {integrity: sha512-jGdObb/BGWu6Peo3cL3skx/Rl1Ak/wDDO3vpPrrThGbqE7isvkCsX6uE+OAt8Ayjm9YC8UGkohWbLR09JmM0FA==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': '>=1.4.0 <1.10.0' - '@opentelemetry/sdk-metrics@1.30.0': - resolution: {integrity: sha512-5kcj6APyRMvv6dEIP5plz2qfJAD4OMipBRT11u/pa1a68rHKI2Ln+iXVkAGKgx8o7CXbD7FdPypTUY88ZQgP4Q==} + '@opentelemetry/sdk-metrics@1.30.1': + resolution: {integrity: sha512-q9zcZ0Okl8jRgmy7eNW3Ku1XSgg3sDLa5evHZpCwjspw7E8Is4K/haRPDJrBcX3YSn/Y7gUvFnByNYEKQNbNog==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/sdk-trace-base@1.30.0': - resolution: {integrity: sha512-RKQDaDIkV7PwizmHw+rE/FgfB2a6MBx+AEVVlAHXRG1YYxLiBpPX2KhmoB99R5vA4b72iJrjle68NDWnbrE9Dg==} + '@opentelemetry/sdk-trace-base@1.30.1': + resolution: {integrity: sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/sdk-trace-node@1.30.0': - resolution: {integrity: sha512-MeXkXEdBs9xq1JSGTr/3P1lHBSUBaVmo1+UpoQhUpviPMzDXy0MNsdTC7KKI6/YcG74lTX6eqeNjlC1jV4Rstw==} + '@opentelemetry/sdk-trace-node@1.30.1': + resolution: {integrity: sha512-cBjYOINt1JxXdpw1e5MlHmFRc5fgj4GW/86vsKFxJCJ8AL4PdVtYH41gWwl4qd4uQjqEL1oJVrXkSy5cnduAnQ==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' @@ -1550,8 +1550,8 @@ packages: '@renovatebot/osv-offline-db@1.7.0': resolution: {integrity: sha512-E24t9YfqJWkR2VbkUiatTEeUdWcTgVly/9JMAEYrLEjJPNZDQQEophsH19faOwFPnIoHhIpsNeTWf2iPhn4OEg==} - '@renovatebot/osv-offline@1.5.11': - resolution: {integrity: sha512-y4lTOL90P1JpsAQ+gadSCXmeRP+tvRrFPCmKtsRUwq/00vO2HoTi9GgKRTEWS6QxtDVnKlHrQS0xbBCmdXySTA==} + '@renovatebot/osv-offline@1.5.12': + resolution: {integrity: sha512-gmPsOjHoCsaIsahv+T373WDc28GZ5WTzcA6Usxd1lDGvEF/t7JdBe3lx1ZBLurbundnGmKJ3zYBsqmr54lBR7A==} '@renovatebot/pep440@4.0.1': resolution: {integrity: sha512-jKodfnFIIGjK9PcoB7+2JkDQ+prjv3LHFMUS21F3+IEaiGomrvpiH27+gjyQRRwtSkkRnrxkqjEPdkj2IxC2qA==} @@ -1660,8 +1660,8 @@ packages: resolution: {integrity: sha512-Igfg8lKu3dRVkTSEm98QpZUvKEOa71jDX4vKRcvJVyRc3UgN3j7vFMf0s7xLQhYmKa8kyJGQgUJDOV5V3neVlQ==} engines: {node: '>=18.0.0'} - '@smithy/core@3.1.0': - resolution: {integrity: sha512-swFv0wQiK7TGHeuAp6lfF5Kw1dHWsTrCuc+yh4Kh05gEShjsE2RUxHucEerR9ih9JITNtaHcSpUThn5Y/vDw0A==} + '@smithy/core@3.1.1': + resolution: {integrity: sha512-hhUZlBWYuh9t6ycAcN90XOyG76C1AzwxZZgaCVPMYpWqqk9uMFo7HGG5Zu2cEhCJn7DdOi5krBmlibWWWPgdsw==} engines: {node: '>=18.0.0'} '@smithy/credential-provider-imds@4.0.1': @@ -1724,12 +1724,12 @@ packages: resolution: {integrity: sha512-OGXo7w5EkB5pPiac7KNzVtfCW2vKBTZNuCctn++TTSOMpe6RZO/n6WEC1AxJINn3+vWLKW49uad3lo/u0WJ9oQ==} engines: {node: '>=18.0.0'} - '@smithy/middleware-endpoint@4.0.1': - resolution: {integrity: sha512-hCCOPu9+sRI7Wj0rZKKnGylKXBEd9cQJetzjQqe8cT4PWvtQAbvNVa6cgAONiZg9m8LaXtP9/waxm3C3eO4hiw==} + '@smithy/middleware-endpoint@4.0.2': + resolution: {integrity: sha512-Z9m67CXizGpj8CF/AW/7uHqYNh1VXXOn9Ap54fenWsCa0HnT4cJuE61zqG3cBkTZJDCy0wHJphilI41co/PE5g==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.0.1': - resolution: {integrity: sha512-n3g2zZFgOWaz2ZYCy8+4wxSmq+HSTD8QKkRhFDv+nkxY1o7gzyp4PDz/+tOdcNPMPZ/A6Mt4aVECYNjQNiaHJw==} + '@smithy/middleware-retry@4.0.3': + resolution: {integrity: sha512-TiKwwQTwUDeDtwWW8UWURTqu7s6F3wN2pmziLU215u7bqpVT9Mk2oEvURjpRLA+5XeQhM68R5BpAGzVtomsqgA==} engines: {node: '>=18.0.0'} '@smithy/middleware-serde@4.0.1': @@ -1744,8 +1744,8 @@ packages: resolution: {integrity: sha512-8mRTjvCtVET8+rxvmzRNRR0hH2JjV0DFOmwXPrISmTIJEfnCBugpYYGAsCj8t41qd+RB5gbheSQ/6aKZCQvFLQ==} engines: {node: '>=18.0.0'} - '@smithy/node-http-handler@4.0.1': - resolution: {integrity: sha512-ddQc7tvXiVLC5c3QKraGWde761KSk+mboCheZoWtuqnXh5l0WKyFy3NfDIM/dsKrI9HlLVH/21pi9wWK2gUFFA==} + '@smithy/node-http-handler@4.0.2': + resolution: {integrity: sha512-X66H9aah9hisLLSnGuzRYba6vckuFtGE+a5DcHLliI/YlqKrGoxhisD5XbX44KyoeRzoNlGr94eTsMVHFAzPOw==} engines: {node: '>=18.0.0'} '@smithy/property-provider@4.0.1': @@ -1776,8 +1776,8 @@ packages: resolution: {integrity: sha512-nCe6fQ+ppm1bQuw5iKoeJ0MJfz2os7Ic3GBjOkLOPtavbD1ONoyE3ygjBfz2ythFWm4YnRm6OxW+8p/m9uCoIA==} engines: {node: '>=18.0.0'} - '@smithy/smithy-client@4.1.0': - resolution: {integrity: sha512-NiboZnrsrZY+Cy5hQNbYi+nVNssXVi2I+yL4CIKNIanOhH8kpC5PKQ2jx/MQpwVr21a3XcVoQBArlpRF36OeEQ==} + '@smithy/smithy-client@4.1.2': + resolution: {integrity: sha512-0yApeHWBqocelHGK22UivZyShNxFbDNrgREBllGh5Ws0D0rg/yId/CJfeoKKpjbfY2ju8j6WgDUGZHYQmINZ5w==} engines: {node: '>=18.0.0'} '@smithy/types@4.1.0': @@ -1812,12 +1812,12 @@ packages: resolution: {integrity: sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.0.1': - resolution: {integrity: sha512-nkQifWzWUHw/D0aLPgyKut+QnJ5X+5E8wBvGfvrYLLZ86xPfVO6MoqfQo/9s4bF3Xscefua1M6KLZtobHMWrBg==} + '@smithy/util-defaults-mode-browser@4.0.3': + resolution: {integrity: sha512-7c5SF1fVK0EOs+2EOf72/qF199zwJflU1d02AevwKbAUPUZyE9RUZiyJxeUmhVxfKDWdUKaaVojNiaDQgnHL9g==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.0.1': - resolution: {integrity: sha512-LeAx2faB83litC9vaOdwFaldtto2gczUHxfFf8yoRwDU3cwL4/pDm7i0hxsuBCRk5mzHsrVGw+3EVCj32UZMdw==} + '@smithy/util-defaults-mode-node@4.0.3': + resolution: {integrity: sha512-CVnD42qYD3JKgDlImZ9+On+MqJHzq9uJgPbMdeBE8c2x8VJ2kf2R3XO/yVFx+30ts5lD/GlL0eFIShY3x9ROgQ==} engines: {node: '>=18.0.0'} '@smithy/util-endpoints@3.0.1': @@ -1836,8 +1836,8 @@ packages: resolution: {integrity: sha512-WmRHqNVwn3kI3rKk1LsKcVgPBG6iLTBGC1iYOV3GQegwJ3E8yjzHytPt26VNzOWr1qu0xE03nK0Ug8S7T7oufw==} engines: {node: '>=18.0.0'} - '@smithy/util-stream@4.0.1': - resolution: {integrity: sha512-Js16gOgU6Qht6qTPfuJgb+1YD4AEO+5Y1UPGWKSp3BNo8ONl/qhXSYDhFKJtwybRJynlCqvP5IeiaBsUmkSPTQ==} + '@smithy/util-stream@4.0.2': + resolution: {integrity: sha512-0eZ4G5fRzIoewtHtwaYyl8g2C+osYOT4KClXgfdNEDAgkbe2TYPqcnw4GAWabqkZCax2ihRGPe9LZnsPdIUIHA==} engines: {node: '>=18.0.0'} '@smithy/util-uri-escape@4.0.0': @@ -2130,8 +2130,8 @@ packages: '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} - '@types/node@22.10.5': - resolution: {integrity: sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==} + '@types/node@22.10.7': + resolution: {integrity: sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -2202,8 +2202,8 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.19.1': - resolution: {integrity: sha512-tJzcVyvvb9h/PB96g30MpxACd9IrunT7GF9wfA9/0TJ1LxGOJx1TdPzSbBBnNED7K9Ka8ybJsnEpiXPktolTLg==} + '@typescript-eslint/eslint-plugin@8.20.0': + resolution: {integrity: sha512-naduuphVw5StFfqp4Gq4WhIBE2gN1GEmMUExpJYknZJdRnc+2gDzB8Z3+5+/Kv33hPQRDGzQO/0opHE72lZZ6A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 @@ -2216,8 +2216,8 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - '@typescript-eslint/parser@8.19.1': - resolution: {integrity: sha512-67gbfv8rAwawjYx3fYArwldTQKoYfezNUT4D5ioWetr/xCrxXxvleo3uuiFuKfejipvq+og7mjz3b0G2bVyUCw==} + '@typescript-eslint/parser@8.20.0': + resolution: {integrity: sha512-gKXG7A5HMyjDIedBi6bUrDcun8GIjnI8qOwVLiY3rx6T/sHP/19XLJOnIq/FgQvWLHja5JN/LSE7eklNBr612g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2227,12 +2227,12 @@ packages: resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@typescript-eslint/scope-manager@8.19.1': - resolution: {integrity: sha512-60L9KIuN/xgmsINzonOcMDSB8p82h95hoBfSBtXuO4jlR1R9L1xSkmVZKgCPVfavDlXihh4ARNjXhh1gGnLC7Q==} + '@typescript-eslint/scope-manager@8.20.0': + resolution: {integrity: sha512-J7+VkpeGzhOt3FeG1+SzhiMj9NzGD/M6KoGn9f4dbz3YzK9hvbhVTmLj/HiTp9DazIzJ8B4XcM80LrR9Dm1rJw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@8.19.1': - resolution: {integrity: sha512-Rp7k9lhDKBMRJB/nM9Ksp1zs4796wVNyihG9/TU9R6KCJDNkQbc2EOKjrBtLYh3396ZdpXLtr/MkaSEmNMtykw==} + '@typescript-eslint/type-utils@8.20.0': + resolution: {integrity: sha512-bPC+j71GGvA7rVNAHAtOjbVXbLN5PkwqMvy1cwGeaxUoRQXVuKCebRoLzm+IPW/NtFFpstn1ummSIasD5t60GA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2242,8 +2242,8 @@ packages: resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@typescript-eslint/types@8.19.1': - resolution: {integrity: sha512-JBVHMLj7B1K1v1051ZaMMgLW4Q/jre5qGK0Ew6UgXz1Rqh+/xPzV1aW581OM00X6iOfyr1be+QyW8LOUf19BbA==} + '@typescript-eslint/types@8.20.0': + resolution: {integrity: sha512-cqaMiY72CkP+2xZRrFt3ExRBu0WmVitN/rYPZErA80mHjHx/Svgp8yfbzkJmDoQ/whcytOPO9/IZXnOc+wigRA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@5.62.0': @@ -2255,8 +2255,8 @@ packages: typescript: optional: true - '@typescript-eslint/typescript-estree@8.19.1': - resolution: {integrity: sha512-jk/TZwSMJlxlNnqhy0Eod1PNEvCkpY6MXOXE/WLlblZ6ibb32i2We4uByoKPv1d0OD2xebDv4hbs3fm11SMw8Q==} + '@typescript-eslint/typescript-estree@8.20.0': + resolution: {integrity: sha512-Y7ncuy78bJqHI35NwzWol8E0X7XkRVS4K4P4TCyzWkOJih5NDvtoRDW4Ba9YJJoB2igm9yXDdYI/+fkiiAxPzA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.8.0' @@ -2267,8 +2267,8 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - '@typescript-eslint/utils@8.19.1': - resolution: {integrity: sha512-IxG5gLO0Ne+KaUc8iW1A+XuKLd63o4wlbI1Zp692n1xojCl/THvgIKXJXBZixTh5dd5+yTJ/VXH7GJaaw21qXA==} + '@typescript-eslint/utils@8.20.0': + resolution: {integrity: sha512-dq70RUw6UK9ei7vxc4KQtBRk7qkHZv447OUZ6RPQMQl71I3NZxQJX/f32Smr+iqWrB02pHKn2yAdHBb0KNrRMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2278,8 +2278,8 @@ packages: resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@typescript-eslint/visitor-keys@8.19.1': - resolution: {integrity: sha512-fzmjU8CHK853V/avYZAvuVut3ZTfwN5YtMaoi+X9Y9MA9keaWNHC3zEQ9zvyX/7Hj+5JkNyK1l7TOR2hevHB6Q==} + '@typescript-eslint/visitor-keys@8.20.0': + resolution: {integrity: sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.2.1': @@ -2513,8 +2513,8 @@ packages: before-after-hook@3.0.2: resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==} - better-sqlite3@11.7.2: - resolution: {integrity: sha512-10a57cHVDmfNQS4jrZ9AH2t+2ekzYh5Rhbcnb4ytpmYweoLdogDmyTt5D+hLiY9b44Mx9foowb/4iXBTO2yP3Q==} + better-sqlite3@11.8.0: + resolution: {integrity: sha512-aKv9s2dir7bsEX5RIjL9HHWB9uQ+f6Vch5B4qmeAOop4Y9OYHX+PNKLr+mpv6+d8L/ZYh4l7H8zPuVMbWkVMLw==} bignumber.js@9.1.2: resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} @@ -2634,8 +2634,8 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001692: - resolution: {integrity: sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A==} + caniuse-lite@1.0.30001695: + resolution: {integrity: sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw==} chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -2854,8 +2854,8 @@ packages: resolution: {integrity: sha512-onMB0OkDjkXunhdW9htFjEhqrD54+M94i6ackoUkjHKbRnXdyEyKRelp4nJ1kAz32+s27jP1FsebpJCVl0BsvA==} engines: {node: '>=18.0'} - cronstrue@2.52.0: - resolution: {integrity: sha512-NKgHbWkSZXJUcaBHSsyzC8eegD6bBd4O0oCI6XMIJ+y4Bq3v4w7sY3wfWoKPuVlq9pQHRB6od0lmKpIqi8TlKA==} + cronstrue@2.53.0: + resolution: {integrity: sha512-CkAcaI94xL8h6N7cGxgXfR5D7oV2yVtDzB9vMZP8tIgPyEv/oc/7nq9rlk7LMxvc3N+q6LKZmNLCVxJRpyEg8A==} hasBin: true cross-spawn@7.0.6: @@ -3056,8 +3056,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.80: - resolution: {integrity: sha512-LTrKpW0AqIuHwmlVNV+cjFYTnXtM9K37OGhpe0ZI10ScPSxqVSryZHIY3WnCS5NSYbBODRTZyhRMS2h5FAEqAw==} + electron-to-chromium@1.5.83: + resolution: {integrity: sha512-LcUDPqSt+V0QmI47XLzZrz5OqILSMGsPFkDYus22rIbgorSvBYEFqq854ltTmUdHkY92FSdAAvsh4jWEULMdfQ==} email-addresses@5.0.0: resolution: {integrity: sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==} @@ -3134,8 +3134,8 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-object-atoms@1.0.0: - resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} es-set-tostringtag@2.1.0: @@ -3236,8 +3236,8 @@ packages: peerDependencies: eslint: '>=0.8.0' - eslint-plugin-jest@28.10.0: - resolution: {integrity: sha512-hyMWUxkBH99HpXT3p8hc7REbEZK3D+nk8vHXGgpB+XXsi0gO4PxMSP+pjfUzb67GnV9yawV9a53eUmcde1CCZA==} + eslint-plugin-jest@28.11.0: + resolution: {integrity: sha512-QAfipLcNCWLVocVbZW8GimKn5p5iiMcgGbRzz8z/P5q7xw+cNEpYqyzFMtIF/ZgF2HLOyy+dYBut+DoYolvqig==} engines: {node: ^16.10.0 || ^18.12.0 || >=20.0.0} peerDependencies: '@typescript-eslint/eslint-plugin': ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3466,6 +3466,10 @@ packages: resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} engines: {node: '>=14.14'} + fs-extra@11.3.0: + resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} + engines: {node: '>=14.14'} + fs-minipass@2.1.0: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} @@ -3797,8 +3801,8 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - ignore@7.0.0: - resolution: {integrity: sha512-lcX8PNQygAa22u/0BysEY8VhaFRzlOkvdlKczDPnJvrkJD1EuqzEky5VYYKM2iySIuaVIDv9N190DfSreSLw2A==} + ignore@7.0.3: + resolution: {integrity: sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==} engines: {node: '>= 4'} immediate@3.0.6: @@ -4354,8 +4358,8 @@ packages: jws@4.0.0: resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==} - katex@0.16.19: - resolution: {integrity: sha512-3IA6DYVhxhBabjSLTNO9S4+OliA3Qvb8pBQXMfC4WxXJgLwZgnfDl0BmB4z6nBMdznBsZ+CGM8DrGZ5hcguDZg==} + katex@0.16.21: + resolution: {integrity: sha512-XvqR7FgOHtWupfMiigNzmh+MgUVmDGU2kXZm899ZkPfcuoPuFxyHmXsgATDpFZDAXCI8tvinaVcDo8PIIJSo4A==} hasBin: true keybase-ecurve@1.0.1: @@ -4830,8 +4834,8 @@ packages: resolution: {integrity: sha512-o2zOYiCpzRqSzPj0Zt/dQ/DqZeYoaQ7TUonc/xUPjCGl9WeHpNbxgVvOquXYAaJzI0M9BXV3HTzG0p8IUAbBTQ==} engines: {node: '>= 10.13'} - node-abi@3.71.0: - resolution: {integrity: sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==} + node-abi@3.73.0: + resolution: {integrity: sha512-z8iYzQGBu35ZkTQ9mtR8RqugJZ9RCLn8fv3d7LsgDBzOijGQP3RdKTX4LA7LXw03ZhU5z0l4xfhIMgSES31+cg==} engines: {node: '>=10'} node-emoji@2.2.0: @@ -5349,8 +5353,8 @@ packages: resolution: {integrity: sha512-L/e3qq/3m/TrYtINo2aBB98oz6w8VHGyFy+arSKwPMZDUNNw2OaQxYnZO6UIZZw2OnRl2qkxGmuSOEfsuHXJdA==} engines: {node: '>=0.10.0'} - qs@6.13.1: - resolution: {integrity: sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==} + qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} queue-microtask@1.2.3: @@ -5718,8 +5722,8 @@ packages: spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - spdx-license-ids@3.0.20: - resolution: {integrity: sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==} + spdx-license-ids@3.0.21: + resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} split2@1.0.0: resolution: {integrity: sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==} @@ -5855,8 +5859,8 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - tar-fs@2.1.1: - resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + tar-fs@2.1.2: + resolution: {integrity: sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==} tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} @@ -6489,26 +6493,26 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.723.0 '@aws-sdk/util-user-agent-node': 3.726.0 '@smithy/config-resolver': 4.0.1 - '@smithy/core': 3.1.0 + '@smithy/core': 3.1.1 '@smithy/fetch-http-handler': 5.0.1 '@smithy/hash-node': 4.0.1 '@smithy/invalid-dependency': 4.0.1 '@smithy/middleware-content-length': 4.0.1 - '@smithy/middleware-endpoint': 4.0.1 - '@smithy/middleware-retry': 4.0.1 + '@smithy/middleware-endpoint': 4.0.2 + '@smithy/middleware-retry': 4.0.3 '@smithy/middleware-serde': 4.0.1 '@smithy/middleware-stack': 4.0.1 '@smithy/node-config-provider': 4.0.1 - '@smithy/node-http-handler': 4.0.1 + '@smithy/node-http-handler': 4.0.2 '@smithy/protocol-http': 5.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 '@smithy/url-parser': 4.0.1 '@smithy/util-base64': 4.0.0 '@smithy/util-body-length-browser': 4.0.0 '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.1 - '@smithy/util-defaults-mode-node': 4.0.1 + '@smithy/util-defaults-mode-browser': 4.0.3 + '@smithy/util-defaults-mode-node': 4.0.3 '@smithy/util-endpoints': 3.0.1 '@smithy/util-middleware': 4.0.1 '@smithy/util-retry': 4.0.1 @@ -6537,26 +6541,26 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.723.0 '@aws-sdk/util-user-agent-node': 3.726.0 '@smithy/config-resolver': 4.0.1 - '@smithy/core': 3.1.0 + '@smithy/core': 3.1.1 '@smithy/fetch-http-handler': 5.0.1 '@smithy/hash-node': 4.0.1 '@smithy/invalid-dependency': 4.0.1 '@smithy/middleware-content-length': 4.0.1 - '@smithy/middleware-endpoint': 4.0.1 - '@smithy/middleware-retry': 4.0.1 + '@smithy/middleware-endpoint': 4.0.2 + '@smithy/middleware-retry': 4.0.3 '@smithy/middleware-serde': 4.0.1 '@smithy/middleware-stack': 4.0.1 '@smithy/node-config-provider': 4.0.1 - '@smithy/node-http-handler': 4.0.1 + '@smithy/node-http-handler': 4.0.2 '@smithy/protocol-http': 5.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 '@smithy/url-parser': 4.0.1 '@smithy/util-base64': 4.0.0 '@smithy/util-body-length-browser': 4.0.0 '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.1 - '@smithy/util-defaults-mode-node': 4.0.1 + '@smithy/util-defaults-mode-browser': 4.0.3 + '@smithy/util-defaults-mode-node': 4.0.3 '@smithy/util-endpoints': 3.0.1 '@smithy/util-middleware': 4.0.1 '@smithy/util-retry': 4.0.1 @@ -6584,26 +6588,26 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.723.0 '@aws-sdk/util-user-agent-node': 3.726.0 '@smithy/config-resolver': 4.0.1 - '@smithy/core': 3.1.0 + '@smithy/core': 3.1.1 '@smithy/fetch-http-handler': 5.0.1 '@smithy/hash-node': 4.0.1 '@smithy/invalid-dependency': 4.0.1 '@smithy/middleware-content-length': 4.0.1 - '@smithy/middleware-endpoint': 4.0.1 - '@smithy/middleware-retry': 4.0.1 + '@smithy/middleware-endpoint': 4.0.2 + '@smithy/middleware-retry': 4.0.3 '@smithy/middleware-serde': 4.0.1 '@smithy/middleware-stack': 4.0.1 '@smithy/node-config-provider': 4.0.1 - '@smithy/node-http-handler': 4.0.1 + '@smithy/node-http-handler': 4.0.2 '@smithy/protocol-http': 5.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 '@smithy/url-parser': 4.0.1 '@smithy/util-base64': 4.0.0 '@smithy/util-body-length-browser': 4.0.0 '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.1 - '@smithy/util-defaults-mode-node': 4.0.1 + '@smithy/util-defaults-mode-browser': 4.0.3 + '@smithy/util-defaults-mode-node': 4.0.3 '@smithy/util-endpoints': 3.0.1 '@smithy/util-middleware': 4.0.1 '@smithy/util-retry': 4.0.1 @@ -6633,26 +6637,26 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.723.0 '@aws-sdk/util-user-agent-node': 3.726.0 '@smithy/config-resolver': 4.0.1 - '@smithy/core': 3.1.0 + '@smithy/core': 3.1.1 '@smithy/fetch-http-handler': 5.0.1 '@smithy/hash-node': 4.0.1 '@smithy/invalid-dependency': 4.0.1 '@smithy/middleware-content-length': 4.0.1 - '@smithy/middleware-endpoint': 4.0.1 - '@smithy/middleware-retry': 4.0.1 + '@smithy/middleware-endpoint': 4.0.2 + '@smithy/middleware-retry': 4.0.3 '@smithy/middleware-serde': 4.0.1 '@smithy/middleware-stack': 4.0.1 '@smithy/node-config-provider': 4.0.1 - '@smithy/node-http-handler': 4.0.1 + '@smithy/node-http-handler': 4.0.2 '@smithy/protocol-http': 5.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 '@smithy/url-parser': 4.0.1 '@smithy/util-base64': 4.0.0 '@smithy/util-body-length-browser': 4.0.0 '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.1 - '@smithy/util-defaults-mode-node': 4.0.1 + '@smithy/util-defaults-mode-browser': 4.0.3 + '@smithy/util-defaults-mode-node': 4.0.3 '@smithy/util-endpoints': 3.0.1 '@smithy/util-middleware': 4.0.1 '@smithy/util-retry': 4.0.1 @@ -6681,26 +6685,26 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.723.0 '@aws-sdk/util-user-agent-node': 3.726.0 '@smithy/config-resolver': 4.0.1 - '@smithy/core': 3.1.0 + '@smithy/core': 3.1.1 '@smithy/fetch-http-handler': 5.0.1 '@smithy/hash-node': 4.0.1 '@smithy/invalid-dependency': 4.0.1 '@smithy/middleware-content-length': 4.0.1 - '@smithy/middleware-endpoint': 4.0.1 - '@smithy/middleware-retry': 4.0.1 + '@smithy/middleware-endpoint': 4.0.2 + '@smithy/middleware-retry': 4.0.3 '@smithy/middleware-serde': 4.0.1 '@smithy/middleware-stack': 4.0.1 '@smithy/node-config-provider': 4.0.1 - '@smithy/node-http-handler': 4.0.1 + '@smithy/node-http-handler': 4.0.2 '@smithy/protocol-http': 5.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 '@smithy/url-parser': 4.0.1 '@smithy/util-base64': 4.0.0 '@smithy/util-body-length-browser': 4.0.0 '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.1 - '@smithy/util-defaults-mode-node': 4.0.1 + '@smithy/util-defaults-mode-browser': 4.0.3 + '@smithy/util-defaults-mode-node': 4.0.3 '@smithy/util-endpoints': 3.0.1 '@smithy/util-middleware': 4.0.1 '@smithy/util-retry': 4.0.1 @@ -6737,7 +6741,7 @@ snapshots: '@aws-sdk/util-user-agent-node': 3.726.0 '@aws-sdk/xml-builder': 3.723.0 '@smithy/config-resolver': 4.0.1 - '@smithy/core': 3.1.0 + '@smithy/core': 3.1.1 '@smithy/eventstream-serde-browser': 4.0.1 '@smithy/eventstream-serde-config-resolver': 4.0.1 '@smithy/eventstream-serde-node': 4.0.1 @@ -6748,25 +6752,25 @@ snapshots: '@smithy/invalid-dependency': 4.0.1 '@smithy/md5-js': 4.0.1 '@smithy/middleware-content-length': 4.0.1 - '@smithy/middleware-endpoint': 4.0.1 - '@smithy/middleware-retry': 4.0.1 + '@smithy/middleware-endpoint': 4.0.2 + '@smithy/middleware-retry': 4.0.3 '@smithy/middleware-serde': 4.0.1 '@smithy/middleware-stack': 4.0.1 '@smithy/node-config-provider': 4.0.1 - '@smithy/node-http-handler': 4.0.1 + '@smithy/node-http-handler': 4.0.2 '@smithy/protocol-http': 5.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 '@smithy/url-parser': 4.0.1 '@smithy/util-base64': 4.0.0 '@smithy/util-body-length-browser': 4.0.0 '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.1 - '@smithy/util-defaults-mode-node': 4.0.1 + '@smithy/util-defaults-mode-browser': 4.0.3 + '@smithy/util-defaults-mode-node': 4.0.3 '@smithy/util-endpoints': 3.0.1 '@smithy/util-middleware': 4.0.1 '@smithy/util-retry': 4.0.1 - '@smithy/util-stream': 4.0.1 + '@smithy/util-stream': 4.0.2 '@smithy/util-utf8': 4.0.0 '@smithy/util-waiter': 4.0.2 tslib: 2.8.1 @@ -6790,26 +6794,26 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.723.0 '@aws-sdk/util-user-agent-node': 3.726.0 '@smithy/config-resolver': 4.0.1 - '@smithy/core': 3.1.0 + '@smithy/core': 3.1.1 '@smithy/fetch-http-handler': 5.0.1 '@smithy/hash-node': 4.0.1 '@smithy/invalid-dependency': 4.0.1 '@smithy/middleware-content-length': 4.0.1 - '@smithy/middleware-endpoint': 4.0.1 - '@smithy/middleware-retry': 4.0.1 + '@smithy/middleware-endpoint': 4.0.2 + '@smithy/middleware-retry': 4.0.3 '@smithy/middleware-serde': 4.0.1 '@smithy/middleware-stack': 4.0.1 '@smithy/node-config-provider': 4.0.1 - '@smithy/node-http-handler': 4.0.1 + '@smithy/node-http-handler': 4.0.2 '@smithy/protocol-http': 5.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 '@smithy/url-parser': 4.0.1 '@smithy/util-base64': 4.0.0 '@smithy/util-body-length-browser': 4.0.0 '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.1 - '@smithy/util-defaults-mode-node': 4.0.1 + '@smithy/util-defaults-mode-browser': 4.0.3 + '@smithy/util-defaults-mode-node': 4.0.3 '@smithy/util-endpoints': 3.0.1 '@smithy/util-middleware': 4.0.1 '@smithy/util-retry': 4.0.1 @@ -6833,26 +6837,26 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.723.0 '@aws-sdk/util-user-agent-node': 3.726.0 '@smithy/config-resolver': 4.0.1 - '@smithy/core': 3.1.0 + '@smithy/core': 3.1.1 '@smithy/fetch-http-handler': 5.0.1 '@smithy/hash-node': 4.0.1 '@smithy/invalid-dependency': 4.0.1 '@smithy/middleware-content-length': 4.0.1 - '@smithy/middleware-endpoint': 4.0.1 - '@smithy/middleware-retry': 4.0.1 + '@smithy/middleware-endpoint': 4.0.2 + '@smithy/middleware-retry': 4.0.3 '@smithy/middleware-serde': 4.0.1 '@smithy/middleware-stack': 4.0.1 '@smithy/node-config-provider': 4.0.1 - '@smithy/node-http-handler': 4.0.1 + '@smithy/node-http-handler': 4.0.2 '@smithy/protocol-http': 5.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 '@smithy/url-parser': 4.0.1 '@smithy/util-base64': 4.0.0 '@smithy/util-body-length-browser': 4.0.0 '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.1 - '@smithy/util-defaults-mode-node': 4.0.1 + '@smithy/util-defaults-mode-browser': 4.0.3 + '@smithy/util-defaults-mode-node': 4.0.3 '@smithy/util-endpoints': 3.0.1 '@smithy/util-middleware': 4.0.1 '@smithy/util-retry': 4.0.1 @@ -6878,26 +6882,26 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.723.0 '@aws-sdk/util-user-agent-node': 3.726.0 '@smithy/config-resolver': 4.0.1 - '@smithy/core': 3.1.0 + '@smithy/core': 3.1.1 '@smithy/fetch-http-handler': 5.0.1 '@smithy/hash-node': 4.0.1 '@smithy/invalid-dependency': 4.0.1 '@smithy/middleware-content-length': 4.0.1 - '@smithy/middleware-endpoint': 4.0.1 - '@smithy/middleware-retry': 4.0.1 + '@smithy/middleware-endpoint': 4.0.2 + '@smithy/middleware-retry': 4.0.3 '@smithy/middleware-serde': 4.0.1 '@smithy/middleware-stack': 4.0.1 '@smithy/node-config-provider': 4.0.1 - '@smithy/node-http-handler': 4.0.1 + '@smithy/node-http-handler': 4.0.2 '@smithy/protocol-http': 5.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 '@smithy/url-parser': 4.0.1 '@smithy/util-base64': 4.0.0 '@smithy/util-body-length-browser': 4.0.0 '@smithy/util-body-length-node': 4.0.0 - '@smithy/util-defaults-mode-browser': 4.0.1 - '@smithy/util-defaults-mode-node': 4.0.1 + '@smithy/util-defaults-mode-browser': 4.0.3 + '@smithy/util-defaults-mode-node': 4.0.3 '@smithy/util-endpoints': 3.0.1 '@smithy/util-middleware': 4.0.1 '@smithy/util-retry': 4.0.1 @@ -6909,12 +6913,12 @@ snapshots: '@aws-sdk/core@3.723.0': dependencies: '@aws-sdk/types': 3.723.0 - '@smithy/core': 3.1.0 + '@smithy/core': 3.1.1 '@smithy/node-config-provider': 4.0.1 '@smithy/property-provider': 4.0.1 '@smithy/protocol-http': 5.0.1 '@smithy/signature-v4': 5.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 '@smithy/util-middleware': 4.0.1 fast-xml-parser: 4.4.1 @@ -6943,12 +6947,12 @@ snapshots: '@aws-sdk/core': 3.723.0 '@aws-sdk/types': 3.723.0 '@smithy/fetch-http-handler': 5.0.1 - '@smithy/node-http-handler': 4.0.1 + '@smithy/node-http-handler': 4.0.2 '@smithy/property-provider': 4.0.1 '@smithy/protocol-http': 5.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 - '@smithy/util-stream': 4.0.1 + '@smithy/util-stream': 4.0.2 tslib: 2.8.1 '@aws-sdk/credential-provider-ini@3.726.0(@aws-sdk/client-sso-oidc@3.726.0(@aws-sdk/client-sts@3.726.1))(@aws-sdk/client-sts@3.726.1)': @@ -7073,7 +7077,7 @@ snapshots: '@smithy/protocol-http': 5.0.1 '@smithy/types': 4.1.0 '@smithy/util-middleware': 4.0.1 - '@smithy/util-stream': 4.0.1 + '@smithy/util-stream': 4.0.2 '@smithy/util-utf8': 4.0.0 tslib: 2.8.1 @@ -7107,10 +7111,10 @@ snapshots: dependencies: '@aws-sdk/types': 3.723.0 '@aws-sdk/util-format-url': 3.723.0 - '@smithy/middleware-endpoint': 4.0.1 + '@smithy/middleware-endpoint': 4.0.2 '@smithy/protocol-http': 5.0.1 '@smithy/signature-v4': 5.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 tslib: 2.8.1 @@ -7118,7 +7122,7 @@ snapshots: dependencies: '@aws-sdk/types': 3.723.0 '@aws-sdk/util-format-url': 3.723.0 - '@smithy/middleware-endpoint': 4.0.1 + '@smithy/middleware-endpoint': 4.0.2 '@smithy/protocol-http': 5.0.1 '@smithy/signature-v4': 5.0.1 '@smithy/types': 4.1.0 @@ -7129,15 +7133,15 @@ snapshots: '@aws-sdk/core': 3.723.0 '@aws-sdk/types': 3.723.0 '@aws-sdk/util-arn-parser': 3.723.0 - '@smithy/core': 3.1.0 + '@smithy/core': 3.1.1 '@smithy/node-config-provider': 4.0.1 '@smithy/protocol-http': 5.0.1 '@smithy/signature-v4': 5.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 '@smithy/util-config-provider': 4.0.0 '@smithy/util-middleware': 4.0.1 - '@smithy/util-stream': 4.0.1 + '@smithy/util-stream': 4.0.2 '@smithy/util-utf8': 4.0.0 tslib: 2.8.1 @@ -7152,7 +7156,7 @@ snapshots: '@aws-sdk/core': 3.723.0 '@aws-sdk/types': 3.723.0 '@aws-sdk/util-endpoints': 3.726.0 - '@smithy/core': 3.1.0 + '@smithy/core': 3.1.1 '@smithy/protocol-http': 5.0.1 '@smithy/types': 4.1.0 tslib: 2.8.1 @@ -7501,27 +7505,27 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 22.10.7 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3))': + '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 22.10.7 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)) + jest-config: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -7546,7 +7550,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 22.10.7 jest-mock: 29.7.0 '@jest/expect-utils@29.4.1': @@ -7568,7 +7572,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 22.10.5 + '@types/node': 22.10.7 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -7590,7 +7594,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 22.10.5 + '@types/node': 22.10.7 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -7660,7 +7664,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.10.5 + '@types/node': 22.10.7 '@types/yargs': 17.0.33 chalk: 4.1.2 @@ -7764,7 +7768,7 @@ snapshots: dependencies: '@octokit/auth-token': 5.1.1 '@octokit/graphql': 8.1.2 - '@octokit/request': 9.1.4 + '@octokit/request': 9.2.0 '@octokit/request-error': 6.1.6 '@octokit/types': 13.7.0 before-after-hook: 3.0.2 @@ -7788,7 +7792,7 @@ snapshots: '@octokit/graphql@8.1.2': dependencies: - '@octokit/request': 9.1.4 + '@octokit/request': 9.2.0 '@octokit/types': 13.7.0 universal-user-agent: 7.0.2 @@ -7843,7 +7847,7 @@ snapshots: '@octokit/types': 13.7.0 universal-user-agent: 6.0.1 - '@octokit/request@9.1.4': + '@octokit/request@9.2.0': dependencies: '@octokit/endpoint': 10.1.2 '@octokit/request-error': 6.1.6 @@ -7868,54 +7872,54 @@ snapshots: optionalDependencies: typescript: 5.7.3 - '@opentelemetry/api-logs@0.57.0': + '@opentelemetry/api-logs@0.57.1': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/api@1.9.0': {} - '@opentelemetry/context-async-hooks@1.30.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core@1.30.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/semantic-conventions': 1.28.0 - '@opentelemetry/exporter-trace-otlp-http@0.57.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-trace-otlp-http@0.57.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.57.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.57.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.30.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.57.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.57.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-bunyan@0.45.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.57.0 - '@opentelemetry/instrumentation': 0.57.0(@opentelemetry/api@1.9.0) + '@opentelemetry/api-logs': 0.57.1 + '@opentelemetry/instrumentation': 0.57.1(@opentelemetry/api@1.9.0) '@types/bunyan': 1.8.9 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-http@0.57.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-http@0.57.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.57.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.57.1(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.28.0 forwarded-parse: 2.1.2 semver: 7.6.3 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation@0.57.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation@0.57.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.57.0 + '@opentelemetry/api-logs': 0.57.1 '@types/shimmer': 1.2.0 import-in-the-middle: 1.12.0 require-in-the-middle: 7.4.0 @@ -7924,67 +7928,67 @@ snapshots: transitivePeerDependencies: - supports-color - '@opentelemetry/otlp-exporter-base@0.57.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/otlp-exporter-base@0.57.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.57.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.57.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer@0.57.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/otlp-transformer@0.57.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.57.0 - '@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.57.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 1.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.30.0(@opentelemetry/api@1.9.0) + '@opentelemetry/api-logs': 0.57.1 + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.57.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0) protobufjs: 7.4.0 - '@opentelemetry/propagator-b3@1.30.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/propagator-b3@1.30.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/propagator-jaeger@1.30.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/propagator-jaeger@1.30.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources@1.30.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/resources@1.30.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.28.0 - '@opentelemetry/sdk-logs@0.57.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-logs@0.57.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.57.0 - '@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.30.0(@opentelemetry/api@1.9.0) + '@opentelemetry/api-logs': 0.57.1 + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics@1.30.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-metrics@1.30.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.30.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base@1.30.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 1.30.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.30.1(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': 1.28.0 - '@opentelemetry/sdk-trace-node@1.30.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-trace-node@1.30.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 1.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 1.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/propagator-b3': 1.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/propagator-jaeger': 1.30.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 1.30.0(@opentelemetry/api@1.9.0) + '@opentelemetry/context-async-hooks': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-b3': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-jaeger': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.30.1(@opentelemetry/api@1.9.0) semver: 7.6.3 '@opentelemetry/semantic-conventions@1.28.0': {} @@ -8101,7 +8105,7 @@ snapshots: '@renovatebot/detect-tools@1.1.0': dependencies: - fs-extra: 11.2.0 + fs-extra: 11.3.0 toml-eslint-parser: 0.10.0 upath: 2.0.1 zod: 3.24.1 @@ -8127,12 +8131,12 @@ snapshots: dependencies: '@seald-io/nedb': 4.0.4 - '@renovatebot/osv-offline@1.5.11(encoding@0.1.13)': + '@renovatebot/osv-offline@1.5.12(encoding@0.1.13)': dependencies: '@octokit/rest': 20.1.1 '@renovatebot/osv-offline-db': 1.7.0 adm-zip: 0.5.16 - fs-extra: 11.2.0 + fs-extra: 11.3.0 got: 11.8.6 luxon: 3.5.0 node-fetch: 2.7.0(encoding@0.1.13) @@ -8212,7 +8216,7 @@ snapshots: '@semantic-release/error': 4.0.0 aggregate-error: 5.0.0 execa: 9.5.2 - fs-extra: 11.2.0 + fs-extra: 11.3.0 lodash-es: 4.17.21 nerf-dart: 1.0.0 normalize-url: 8.0.1 @@ -8294,14 +8298,14 @@ snapshots: '@smithy/util-middleware': 4.0.1 tslib: 2.8.1 - '@smithy/core@3.1.0': + '@smithy/core@3.1.1': dependencies: '@smithy/middleware-serde': 4.0.1 '@smithy/protocol-http': 5.0.1 '@smithy/types': 4.1.0 '@smithy/util-body-length-browser': 4.0.0 '@smithy/util-middleware': 4.0.1 - '@smithy/util-stream': 4.0.1 + '@smithy/util-stream': 4.0.2 '@smithy/util-utf8': 4.0.0 tslib: 2.8.1 @@ -8396,9 +8400,9 @@ snapshots: '@smithy/types': 4.1.0 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.0.1': + '@smithy/middleware-endpoint@4.0.2': dependencies: - '@smithy/core': 3.1.0 + '@smithy/core': 3.1.1 '@smithy/middleware-serde': 4.0.1 '@smithy/node-config-provider': 4.0.1 '@smithy/shared-ini-file-loader': 4.0.1 @@ -8407,12 +8411,12 @@ snapshots: '@smithy/util-middleware': 4.0.1 tslib: 2.8.1 - '@smithy/middleware-retry@4.0.1': + '@smithy/middleware-retry@4.0.3': dependencies: '@smithy/node-config-provider': 4.0.1 '@smithy/protocol-http': 5.0.1 '@smithy/service-error-classification': 4.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 '@smithy/util-middleware': 4.0.1 '@smithy/util-retry': 4.0.1 @@ -8436,7 +8440,7 @@ snapshots: '@smithy/types': 4.1.0 tslib: 2.8.1 - '@smithy/node-http-handler@4.0.1': + '@smithy/node-http-handler@4.0.2': dependencies: '@smithy/abort-controller': 4.0.1 '@smithy/protocol-http': 5.0.1 @@ -8485,14 +8489,14 @@ snapshots: '@smithy/util-utf8': 4.0.0 tslib: 2.8.1 - '@smithy/smithy-client@4.1.0': + '@smithy/smithy-client@4.1.2': dependencies: - '@smithy/core': 3.1.0 - '@smithy/middleware-endpoint': 4.0.1 + '@smithy/core': 3.1.1 + '@smithy/middleware-endpoint': 4.0.2 '@smithy/middleware-stack': 4.0.1 '@smithy/protocol-http': 5.0.1 '@smithy/types': 4.1.0 - '@smithy/util-stream': 4.0.1 + '@smithy/util-stream': 4.0.2 tslib: 2.8.1 '@smithy/types@4.1.0': @@ -8533,21 +8537,21 @@ snapshots: dependencies: tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.0.1': + '@smithy/util-defaults-mode-browser@4.0.3': dependencies: '@smithy/property-provider': 4.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 bowser: 2.11.0 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.0.1': + '@smithy/util-defaults-mode-node@4.0.3': dependencies: '@smithy/config-resolver': 4.0.1 '@smithy/credential-provider-imds': 4.0.1 '@smithy/node-config-provider': 4.0.1 '@smithy/property-provider': 4.0.1 - '@smithy/smithy-client': 4.1.0 + '@smithy/smithy-client': 4.1.2 '@smithy/types': 4.1.0 tslib: 2.8.1 @@ -8572,10 +8576,10 @@ snapshots: '@smithy/types': 4.1.0 tslib: 2.8.1 - '@smithy/util-stream@4.0.1': + '@smithy/util-stream@4.0.2': dependencies: '@smithy/fetch-http-handler': 5.0.1 - '@smithy/node-http-handler': 4.0.1 + '@smithy/node-http-handler': 4.0.2 '@smithy/types': 4.1.0 '@smithy/util-base64': 4.0.0 '@smithy/util-buffer-from': 4.0.0 @@ -8708,7 +8712,7 @@ snapshots: '@types/aws4@1.11.6': dependencies: - '@types/node': 22.10.5 + '@types/node': 22.10.7 '@types/babel__core@7.20.5': dependencies: @@ -8733,27 +8737,27 @@ snapshots: '@types/better-sqlite3@7.6.12': dependencies: - '@types/node': 22.10.5 + '@types/node': 22.10.7 '@types/breejs__later@4.1.5': {} '@types/bunyan@1.8.11': dependencies: - '@types/node': 22.10.5 + '@types/node': 22.10.7 '@types/bunyan@1.8.9': dependencies: - '@types/node': 22.10.5 + '@types/node': 22.10.7 '@types/cacache@17.0.2': dependencies: - '@types/node': 22.10.5 + '@types/node': 22.10.7 '@types/cacheable-request@6.0.3': dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 22.10.5 + '@types/node': 22.10.7 '@types/responselike': 1.0.3 '@types/callsite@1.0.34': {} @@ -8784,7 +8788,7 @@ snapshots: '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 22.10.5 + '@types/node': 22.10.7 '@types/git-url-parse@9.0.3': {} @@ -8794,7 +8798,7 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 22.10.5 + '@types/node': 22.10.7 '@types/http-cache-semantics@4.0.4': {} @@ -8820,13 +8824,13 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 22.10.5 + '@types/node': 22.10.7 '@types/katex@0.16.7': {} '@types/keyv@3.1.4': dependencies: - '@types/node': 22.10.5 + '@types/node': 22.10.7 '@types/linkify-it@5.0.0': {} @@ -8845,7 +8849,7 @@ snapshots: '@types/marshal@0.5.3': dependencies: - '@types/node': 22.10.5 + '@types/node': 22.10.7 '@types/mdast@3.0.15': dependencies: @@ -8861,7 +8865,7 @@ snapshots: '@types/ms@0.7.34': {} - '@types/node@22.10.5': + '@types/node@22.10.7': dependencies: undici-types: 6.20.0 @@ -8875,7 +8879,7 @@ snapshots: '@types/responselike@1.0.3': dependencies: - '@types/node': 22.10.5 + '@types/node': 22.10.7 '@types/semver-stable@3.0.2': {} @@ -8895,7 +8899,7 @@ snapshots: '@types/tar@6.1.13': dependencies: - '@types/node': 22.10.5 + '@types/node': 22.10.7 minipass: 4.2.8 '@types/tmp@0.2.6': {} @@ -8920,17 +8924,17 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.10.5 + '@types/node': 22.10.7 optional: true - '@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3)': + '@typescript-eslint/eslint-plugin@8.20.0(@typescript-eslint/parser@8.20.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.19.1(eslint@8.57.1)(typescript@5.7.3) - '@typescript-eslint/scope-manager': 8.19.1 - '@typescript-eslint/type-utils': 8.19.1(eslint@8.57.1)(typescript@5.7.3) - '@typescript-eslint/utils': 8.19.1(eslint@8.57.1)(typescript@5.7.3) - '@typescript-eslint/visitor-keys': 8.19.1 + '@typescript-eslint/parser': 8.20.0(eslint@8.57.1)(typescript@5.7.3) + '@typescript-eslint/scope-manager': 8.20.0 + '@typescript-eslint/type-utils': 8.20.0(eslint@8.57.1)(typescript@5.7.3) + '@typescript-eslint/utils': 8.20.0(eslint@8.57.1)(typescript@5.7.3) + '@typescript-eslint/visitor-keys': 8.20.0 eslint: 8.57.1 graphemer: 1.4.0 ignore: 5.3.2 @@ -8948,12 +8952,12 @@ snapshots: - supports-color - typescript - '@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3)': + '@typescript-eslint/parser@8.20.0(eslint@8.57.1)(typescript@5.7.3)': dependencies: - '@typescript-eslint/scope-manager': 8.19.1 - '@typescript-eslint/types': 8.19.1 - '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.3) - '@typescript-eslint/visitor-keys': 8.19.1 + '@typescript-eslint/scope-manager': 8.20.0 + '@typescript-eslint/types': 8.20.0 + '@typescript-eslint/typescript-estree': 8.20.0(typescript@5.7.3) + '@typescript-eslint/visitor-keys': 8.20.0 debug: 4.4.0 eslint: 8.57.1 typescript: 5.7.3 @@ -8965,15 +8969,15 @@ snapshots: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - '@typescript-eslint/scope-manager@8.19.1': + '@typescript-eslint/scope-manager@8.20.0': dependencies: - '@typescript-eslint/types': 8.19.1 - '@typescript-eslint/visitor-keys': 8.19.1 + '@typescript-eslint/types': 8.20.0 + '@typescript-eslint/visitor-keys': 8.20.0 - '@typescript-eslint/type-utils@8.19.1(eslint@8.57.1)(typescript@5.7.3)': + '@typescript-eslint/type-utils@8.20.0(eslint@8.57.1)(typescript@5.7.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.3) - '@typescript-eslint/utils': 8.19.1(eslint@8.57.1)(typescript@5.7.3) + '@typescript-eslint/typescript-estree': 8.20.0(typescript@5.7.3) + '@typescript-eslint/utils': 8.20.0(eslint@8.57.1)(typescript@5.7.3) debug: 4.4.0 eslint: 8.57.1 ts-api-utils: 2.0.0(typescript@5.7.3) @@ -8983,7 +8987,7 @@ snapshots: '@typescript-eslint/types@5.62.0': {} - '@typescript-eslint/types@8.19.1': {} + '@typescript-eslint/types@8.20.0': {} '@typescript-eslint/typescript-estree@5.62.0(typescript@5.7.3)': dependencies: @@ -8999,10 +9003,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.19.1(typescript@5.7.3)': + '@typescript-eslint/typescript-estree@8.20.0(typescript@5.7.3)': dependencies: - '@typescript-eslint/types': 8.19.1 - '@typescript-eslint/visitor-keys': 8.19.1 + '@typescript-eslint/types': 8.20.0 + '@typescript-eslint/visitor-keys': 8.20.0 debug: 4.4.0 fast-glob: 3.3.3 is-glob: 4.0.3 @@ -9028,12 +9032,12 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@8.19.1(eslint@8.57.1)(typescript@5.7.3)': + '@typescript-eslint/utils@8.20.0(eslint@8.57.1)(typescript@5.7.3)': dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.19.1 - '@typescript-eslint/types': 8.19.1 - '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.3) + '@typescript-eslint/scope-manager': 8.20.0 + '@typescript-eslint/types': 8.20.0 + '@typescript-eslint/typescript-estree': 8.20.0(typescript@5.7.3) eslint: 8.57.1 typescript: 5.7.3 transitivePeerDependencies: @@ -9044,9 +9048,9 @@ snapshots: '@typescript-eslint/types': 5.62.0 eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@8.19.1': + '@typescript-eslint/visitor-keys@8.20.0': dependencies: - '@typescript-eslint/types': 8.19.1 + '@typescript-eslint/types': 8.20.0 eslint-visitor-keys: 4.2.0 '@ungap/structured-clone@1.2.1': {} @@ -9211,7 +9215,7 @@ snapshots: call-bind: 1.0.8 define-properties: 1.2.1 es-abstract: 1.23.9 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 get-intrinsic: 1.2.7 is-string: 1.1.1 @@ -9223,7 +9227,7 @@ snapshots: define-properties: 1.2.1 es-abstract: 1.23.9 es-errors: 1.3.0 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 es-shim-unscopables: 1.0.2 array.prototype.flat@1.3.3: @@ -9344,7 +9348,7 @@ snapshots: before-after-hook@3.0.2: {} - better-sqlite3@11.7.2: + better-sqlite3@11.8.0: dependencies: bindings: 1.5.0 prebuild-install: 7.1.2 @@ -9389,8 +9393,8 @@ snapshots: browserslist@4.24.4: dependencies: - caniuse-lite: 1.0.30001692 - electron-to-chromium: 1.5.80 + caniuse-lite: 1.0.30001695 + electron-to-chromium: 1.5.83 node-releases: 2.0.19 update-browserslist-db: 1.1.2(browserslist@4.24.4) @@ -9499,7 +9503,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001692: {} + caniuse-lite@1.0.30001695: {} chalk@2.4.2: dependencies: @@ -9685,13 +9689,13 @@ snapshots: optionalDependencies: typescript: 5.7.3 - create-jest@29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)): + create-jest@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)) + jest-config: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -9704,7 +9708,7 @@ snapshots: croner@9.0.0: {} - cronstrue@2.52.0: {} + cronstrue@2.53.0: {} cross-spawn@7.0.6: dependencies: @@ -9888,7 +9892,7 @@ snapshots: dependencies: jake: 10.9.2 - electron-to-chromium@1.5.80: {} + electron-to-chromium@1.5.83: {} email-addresses@5.0.0: {} @@ -9954,7 +9958,7 @@ snapshots: data-view-byte-offset: 1.0.1 es-define-property: 1.0.1 es-errors: 1.3.0 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 es-set-tostringtag: 2.1.0 es-to-primitive: 1.3.0 function.prototype.name: 1.1.8 @@ -10000,7 +10004,7 @@ snapshots: es-errors@1.3.0: {} - es-object-atoms@1.0.0: + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -10066,22 +10070,22 @@ snapshots: is-glob: 4.0.3 stable-hash: 0.0.4 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.20.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.20.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.19.1(eslint@8.57.1)(typescript@5.7.3) + '@typescript-eslint/parser': 8.20.0(eslint@8.57.1)(typescript@5.7.3) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.20.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -10092,7 +10096,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.20.0(eslint@8.57.1)(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -10104,7 +10108,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.19.1(eslint@8.57.1)(typescript@5.7.3) + '@typescript-eslint/parser': 8.20.0(eslint@8.57.1)(typescript@5.7.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -10114,13 +10118,13 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-plugin-jest@28.10.0(@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(jest@29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)))(typescript@5.7.3): + eslint-plugin-jest@28.11.0(@typescript-eslint/eslint-plugin@8.20.0(@typescript-eslint/parser@8.20.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(jest@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)))(typescript@5.7.3): dependencies: - '@typescript-eslint/utils': 8.19.1(eslint@8.57.1)(typescript@5.7.3) + '@typescript-eslint/utils': 8.20.0(eslint@8.57.1)(typescript@5.7.3) eslint: 8.57.1 optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.19.1(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3) - jest: 29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)) + '@typescript-eslint/eslint-plugin': 8.20.0(@typescript-eslint/parser@8.20.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3) + jest: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)) transitivePeerDependencies: - supports-color - typescript @@ -10424,6 +10428,12 @@ snapshots: jsonfile: 6.1.0 universalify: 2.0.1 + fs-extra@11.3.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + fs-minipass@2.1.0: dependencies: minipass: 3.3.6 @@ -10482,7 +10492,7 @@ snapshots: call-bind-apply-helpers: 1.0.1 es-define-property: 1.0.1 es-errors: 1.3.0 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 function-bind: 1.1.2 get-proto: 1.0.1 gopd: 1.2.0 @@ -10495,7 +10505,7 @@ snapshots: get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 get-stream@5.2.0: dependencies: @@ -10802,7 +10812,7 @@ snapshots: ignore@5.3.2: {} - ignore@7.0.0: {} + ignore@7.0.3: {} immediate@3.0.6: {} @@ -11144,7 +11154,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 22.10.7 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3 @@ -11164,16 +11174,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)): + jest-cli@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)) + create-jest: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)) + jest-config: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -11183,7 +11193,7 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)): + jest-config@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)): dependencies: '@babel/core': 7.26.0 '@jest/test-sequencer': 29.7.0 @@ -11208,8 +11218,8 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 22.10.5 - ts-node: 10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3) + '@types/node': 22.10.7 + ts-node: 10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -11238,16 +11248,16 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 22.10.7 jest-mock: 29.7.0 jest-util: 29.7.0 - jest-extended@4.0.2(jest@29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3))): + jest-extended@4.0.2(jest@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3))): dependencies: jest-diff: 29.7.0 jest-get-type: 29.6.3 optionalDependencies: - jest: 29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)) + jest: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)) jest-get-type@29.6.3: {} @@ -11255,7 +11265,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 22.10.5 + '@types/node': 22.10.7 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -11298,16 +11308,16 @@ snapshots: slash: 3.0.0 stack-utils: 2.0.6 - jest-mock-extended@3.0.7(jest@29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)))(typescript@5.7.3): + jest-mock-extended@3.0.7(jest@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)))(typescript@5.7.3): dependencies: - jest: 29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)) + jest: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)) ts-essentials: 10.0.4(typescript@5.7.3) typescript: 5.7.3 jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 22.10.7 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -11342,7 +11352,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 22.10.7 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -11370,7 +11380,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 22.10.7 chalk: 4.1.2 cjs-module-lexer: 1.4.1 collect-v8-coverage: 1.0.2 @@ -11416,7 +11426,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 22.10.7 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -11435,7 +11445,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 22.10.7 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -11444,17 +11454,17 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 22.10.5 + '@types/node': 22.10.7 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)): + jest@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)) + jest-cli: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -11532,7 +11542,7 @@ snapshots: jwa: 2.0.0 safe-buffer: 5.2.1 - katex@0.16.19: + katex@0.16.21: dependencies: commander: 8.3.0 @@ -11869,7 +11879,7 @@ snapshots: dependencies: '@types/katex': 0.16.7 devlop: 1.1.0 - katex: 0.16.19 + katex: 0.16.21 micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 micromark-util-symbol: 2.0.1 @@ -12140,7 +12150,7 @@ snapshots: transitivePeerDependencies: - supports-color - node-abi@3.71.0: + node-abi@3.73.0: dependencies: semver: 7.6.3 optional: true @@ -12293,7 +12303,7 @@ snapshots: call-bind: 1.0.8 call-bound: 1.0.3 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 has-symbols: 1.1.0 object-keys: 1.1.1 @@ -12302,7 +12312,7 @@ snapshots: call-bind: 1.0.8 define-properties: 1.2.1 es-abstract: 1.23.9 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 object.groupby@1.0.3: dependencies: @@ -12315,7 +12325,7 @@ snapshots: call-bind: 1.0.8 call-bound: 1.0.3 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 once@1.4.0: dependencies: @@ -12557,11 +12567,11 @@ snapshots: minimist: 1.2.8 mkdirp-classic: 0.5.3 napi-build-utils: 1.0.2 - node-abi: 3.71.0 + node-abi: 3.73.0 pump: 3.0.2 rc: 1.2.8 simple-get: 4.0.1 - tar-fs: 2.1.1 + tar-fs: 2.1.2 tunnel-agent: 0.6.0 optional: true @@ -12617,7 +12627,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 22.10.5 + '@types/node': 22.10.7 long: 5.2.4 protocols@2.0.1: {} @@ -12635,7 +12645,7 @@ snapshots: purepack@1.0.6: {} - qs@6.13.1: + qs@6.14.0: dependencies: side-channel: 1.1.0 @@ -12736,7 +12746,7 @@ snapshots: define-properties: 1.2.1 es-abstract: 1.23.9 es-errors: 1.3.0 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 get-intrinsic: 1.2.7 get-proto: 1.0.1 which-builtin-type: 1.2.1 @@ -12964,7 +12974,7 @@ snapshots: dependencies: dunder-proto: 1.0.1 es-errors: 1.3.0 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 shebang-command@2.0.0: dependencies: @@ -13103,16 +13113,16 @@ snapshots: spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.20 + spdx-license-ids: 3.0.21 spdx-exceptions@2.5.0: {} spdx-expression-parse@3.0.1: dependencies: spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.20 + spdx-license-ids: 3.0.21 - spdx-license-ids@3.0.20: {} + spdx-license-ids@3.0.21: {} split2@1.0.0: dependencies: @@ -13170,7 +13180,7 @@ snapshots: define-data-property: 1.1.4 define-properties: 1.2.1 es-abstract: 1.23.9 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 has-property-descriptors: 1.0.2 string.prototype.trimend@1.0.9: @@ -13178,13 +13188,13 @@ snapshots: call-bind: 1.0.8 call-bound: 1.0.3 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 string.prototype.trimstart@1.0.8: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 string_decoder@1.1.1: dependencies: @@ -13250,7 +13260,7 @@ snapshots: tapable@2.2.1: {} - tar-fs@2.1.1: + tar-fs@2.1.2: dependencies: chownr: 1.1.4 mkdirp-classic: 0.5.3 @@ -13380,12 +13390,12 @@ snapshots: optionalDependencies: typescript: 5.7.3 - ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)))(typescript@5.7.3): + ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)))(typescript@5.7.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@22.10.5)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3)) + jest: 29.7.0(@types/node@22.10.7)(ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3)) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -13399,14 +13409,14 @@ snapshots: '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.26.0) - ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.5)(typescript@5.7.3): + ts-node@10.9.2(@swc/core@1.10.7)(@types/node@22.10.7)(typescript@5.7.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 22.10.5 + '@types/node': 22.10.7 acorn: 8.14.0 acorn-walk: 8.3.4 arg: 4.1.3 @@ -13511,7 +13521,7 @@ snapshots: dependencies: des.js: 1.1.0 js-md4: 0.3.2 - qs: 6.13.1 + qs: 6.14.0 tunnel: 0.0.6 underscore: 1.13.7 diff --git a/pyproject.toml b/pyproject.toml index 505881c624b7135..6f45156ddfa0692 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] dependencies = [ - "mkdocs-material==9.5.49", + "mkdocs-material==9.5.50", "mkdocs-awesome-pages-plugin==2.10.1", ] requires-python = ">=3.11" diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 9a695353f488f3a..8f8b3c05664dc99 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -1,27 +1,27 @@ -# syntax=docker/dockerfile:1.12.1@sha256:93bfd3b68c109427185cd78b4779fc82b484b0b7618e36d0f104d4d801e66d25 +# syntax=docker/dockerfile:1.13.0@sha256:426b85b823c113372f766a963f68cfd9cd4878e1bcc0fda58779127ee98a28eb ARG BASE_IMAGE_TYPE=slim # -------------------------------------- # slim image # -------------------------------------- -FROM ghcr.io/renovatebot/base-image:9.33.2@sha256:8b958697ed82f189abb46c92591cbd96600977696014e971c825d776891aac5a AS slim-base +FROM ghcr.io/renovatebot/base-image:9.34.1@sha256:29f6bf5ef45fdb516cb6c09987d2f3349aaa6edc60af4ac7b43f5a4f8a9c15e8 AS slim-base # -------------------------------------- # full image # -------------------------------------- -FROM ghcr.io/renovatebot/base-image:9.33.2-full@sha256:a0f2a13b6857c9cfba1c810fed13f4ef2c25020645a006bbe80b6f87cfb535e3 AS full-base +FROM ghcr.io/renovatebot/base-image:9.34.0-full@sha256:9a4d5f592b9f4c6d0ae9a5e46987c2120660f7ccaa0ab38f9a773a8ba1bfd495 AS full-base ENV RENOVATE_BINARY_SOURCE=global # -------------------------------------- # build image # -------------------------------------- -FROM --platform=$BUILDPLATFORM ghcr.io/renovatebot/base-image:9.33.2@sha256:8b958697ed82f189abb46c92591cbd96600977696014e971c825d776891aac5a AS build +FROM --platform=$BUILDPLATFORM ghcr.io/renovatebot/base-image:9.34.1@sha256:29f6bf5ef45fdb516cb6c09987d2f3349aaa6edc60af4ac7b43f5a4f8a9c15e8 AS build # We want a specific node version here # renovate: datasource=node-version -RUN install-tool node 22.13.0 +RUN install-tool node 22.13.1 WORKDIR /usr/local/renovate diff --git a/tools/mkdocs/mkdocs.yml b/tools/mkdocs/mkdocs.yml index 5b8eef98dd29623..cf68267748d9c96 100644 --- a/tools/mkdocs/mkdocs.yml +++ b/tools/mkdocs/mkdocs.yml @@ -59,7 +59,7 @@ theme: # The custom_dir points to the overrides folder, this folder has the code for our announcement bar. # The easiest way to disable the announcement bar is to comment out the custom_dir: overrides entry in this mkdocs.yml file. # https://squidfunk.github.io/mkdocs-material/customization/#setup-and-theme-structure - # custom_dir: overrides + custom_dir: overrides logo: 'assets/images/logo.png' favicon: 'assets/images/logo.png' diff --git a/tools/mkdocs/overrides/main.html b/tools/mkdocs/overrides/main.html index 7c2c95214149ebe..6f60b52c63b8ece 100644 --- a/tools/mkdocs/overrides/main.html +++ b/tools/mkdocs/overrides/main.html @@ -6,6 +6,6 @@ {% block announce %}

- We released Renovate v39. Read the Release notes for major versions of Renovate to learn what's changed. + If you use a Mend-hosted Renovate App and you have encrypted secrets in your Renovate config, then you must migrate the secrets to the Developer Portal UI. If you do not migrate the secrets, eventually Renovate will stop running on repositories that use the Mend-hosted Renovate App. Please read the announcement about the disabling of Encrypted Secrets in Mend-hosted Renovate apps to learn more.

{% endblock %}