diff --git a/lib/modules/datasource/cdnjs/__snapshots__/index.spec.ts.snap b/lib/modules/datasource/cdnjs/__snapshots__/index.spec.ts.snap index c779cc09bbdd79..e1aead3be8d6fd 100644 --- a/lib/modules/datasource/cdnjs/__snapshots__/index.spec.ts.snap +++ b/lib/modules/datasource/cdnjs/__snapshots__/index.spec.ts.snap @@ -6,6 +6,7 @@ exports[`modules/datasource/cdnjs/index getReleases filters releases by asset pr "registryUrl": "https://api.cdnjs.com/", "releases": [ { + "newDigest": undefined, "version": "0.7.5", }, ], diff --git a/lib/modules/datasource/galaxy-collection/__snapshots__/index.spec.ts.snap b/lib/modules/datasource/galaxy-collection/__snapshots__/index.spec.ts.snap index 738884ca312d6f..a02c616cd39f22 100644 --- a/lib/modules/datasource/galaxy-collection/__snapshots__/index.spec.ts.snap +++ b/lib/modules/datasource/galaxy-collection/__snapshots__/index.spec.ts.snap @@ -58,5 +58,6 @@ exports[`modules/datasource/galaxy-collection/index getReleases returns only val "version": "1.2.0", }, ], + "tags": undefined, } `; diff --git a/lib/modules/datasource/index.ts b/lib/modules/datasource/index.ts index a9998eb83fd8e3..f175c8347b9ffb 100644 --- a/lib/modules/datasource/index.ts +++ b/lib/modules/datasource/index.ts @@ -353,7 +353,7 @@ export async function getPkgReleases( logger.error({ config }, 'Datasource getReleases without packageName'); return null; } - let res: ReleaseResult; + let res: ReleaseResult | null = null; try { res = clone( await getRawReleases({ diff --git a/lib/modules/datasource/npm/__snapshots__/index.spec.ts.snap b/lib/modules/datasource/npm/__snapshots__/index.spec.ts.snap index a174e16de440dd..02cf5b7c7e009e 100644 --- a/lib/modules/datasource/npm/__snapshots__/index.spec.ts.snap +++ b/lib/modules/datasource/npm/__snapshots__/index.spec.ts.snap @@ -6,10 +6,16 @@ exports[`modules/datasource/npm/index should fetch package info from custom regi "registryUrl": "https://npm.mycustomregistry.com", "releases": [ { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-06T05:21:53.000Z", "version": "0.0.1", }, { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-07T05:21:53.000Z", "version": "0.0.2", }, @@ -28,10 +34,16 @@ exports[`modules/datasource/npm/index should fetch package info from npm 1`] = ` "registryUrl": "https://registry.npmjs.org", "releases": [ { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-06T05:21:53.000Z", "version": "0.0.1", }, { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-07T05:21:53.000Z", "version": "0.0.2", }, @@ -50,10 +62,16 @@ exports[`modules/datasource/npm/index should handle foobar 1`] = ` "registryUrl": "https://registry.npmjs.org", "releases": [ { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-06T05:21:53.000Z", "version": "0.0.1", }, { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-07T05:21:53.000Z", "version": "0.0.2", }, @@ -72,10 +90,16 @@ exports[`modules/datasource/npm/index should handle no time 1`] = ` "registryUrl": "https://registry.npmjs.org", "releases": [ { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-06T05:21:53.000Z", "version": "0.0.1", }, { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "version": "0.0.2", }, ], @@ -93,10 +117,16 @@ exports[`modules/datasource/npm/index should not send an authorization header if "registryUrl": "https://registry.npmjs.org", "releases": [ { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-06T05:21:53.000Z", "version": "0.0.1", }, { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-07T05:21:53.000Z", "version": "0.0.2", }, @@ -115,6 +145,9 @@ exports[`modules/datasource/npm/index should parse repo url (string) 1`] = ` "registryUrl": "https://registry.npmjs.org", "releases": [ { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-06T05:21:53.000Z", "version": "0.0.1", }, @@ -132,6 +165,9 @@ exports[`modules/datasource/npm/index should parse repo url 1`] = ` "registryUrl": "https://registry.npmjs.org", "releases": [ { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-06T05:21:53.000Z", "version": "0.0.1", }, @@ -149,10 +185,16 @@ exports[`modules/datasource/npm/index should replace any environment variable in "registryUrl": "https://registry.from-env.com", "releases": [ { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-06T05:21:53.000Z", "version": "0.0.1", }, { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-07T05:21:53.000Z", "version": "0.0.2", }, @@ -176,10 +218,16 @@ Marking the latest version of an npm package as deprecated results in the entire "registryUrl": "https://registry.npmjs.org", "releases": [ { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-06T05:21:53.000Z", "version": "0.0.1", }, { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "isDeprecated": true, "releaseTimestamp": "2018-05-07T05:21:53.000Z", "version": "0.0.2", @@ -206,10 +254,16 @@ exports[`modules/datasource/npm/index should send an authorization header if pro "registryUrl": "https://registry.npmjs.org", "releases": [ { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-06T05:21:53.000Z", "version": "0.0.1", }, { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-07T05:21:53.000Z", "version": "0.0.2", }, @@ -228,10 +282,16 @@ exports[`modules/datasource/npm/index should use default registry if missing fro "registryUrl": "https://registry.npmjs.org", "releases": [ { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-06T05:21:53.000Z", "version": "0.0.1", }, { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-07T05:21:53.000Z", "version": "0.0.2", }, @@ -250,10 +310,16 @@ exports[`modules/datasource/npm/index should use host rules by baseUrl if provid "registryUrl": "https://npm.mycustomregistry.com/_packaging/mycustomregistry/npm/registry", "releases": [ { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-06T05:21:53.000Z", "version": "0.0.1", }, { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-07T05:21:53.000Z", "version": "0.0.2", }, @@ -272,10 +338,16 @@ exports[`modules/datasource/npm/index should use host rules by hostName if provi "registryUrl": "https://npm.mycustomregistry.com", "releases": [ { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-06T05:21:53.000Z", "version": "0.0.1", }, { + "dependencies": undefined, + "devDependencies": undefined, + "gitRef": undefined, "releaseTimestamp": "2018-05-07T05:21:53.000Z", "version": "0.0.2", }, diff --git a/lib/util/clone.spec.ts b/lib/util/clone.spec.ts index 6e7ade68f105f2..dc03323d6690cc 100644 --- a/lib/util/clone.spec.ts +++ b/lib/util/clone.spec.ts @@ -1,19 +1,20 @@ import { clone } from './clone'; describe('util/clone', () => { - const obj: any = { - name: 'object', - type: 'object', - isObject: true, - }; - it('returns null', () => { const res = clone(null); expect(res).toBeNull(); }); it('maintains same order', () => { + const obj: any = { + name: 'object', + type: 'object', + isObject: true, + }; + const res = clone(obj); + expect(res).toMatchSnapshot(`{ name: 'object', type: 'object', @@ -22,8 +23,18 @@ describe('util/clone', () => { }); it('assigns "[Circular]" to circular references', () => { + const obj: any = { + name: 'object', + type: 'object', + isObject: true, + }; obj.circular = obj; - const res = clone(obj); - expect(res.circular).toBe('[Circular]'); + + expect(clone(obj)).toMatchObject({ + circular: '[Circular]', + isObject: true, + name: 'object', + type: 'object', + }); }); }); diff --git a/lib/util/clone.ts b/lib/util/clone.ts index 422add0b37d904..93a81cdcb1b075 100644 --- a/lib/util/clone.ts +++ b/lib/util/clone.ts @@ -1,3 +1,5 @@ +import { klona } from 'klona/json'; +import { logger } from '../logger'; import { quickStringify } from './stringify'; /** @@ -5,7 +7,17 @@ import { quickStringify } from './stringify'; * @deprecated Use {@link structuredClone} instead. * @param input The object to clone. */ -export function clone(input: T | null = null): T { - const stringifiedInput = quickStringify(input); - return stringifiedInput ? JSON.parse(stringifiedInput) : null; +export function clone(input: T): T { + try { + return klona(input); + } catch (err) { + logger.warn({ err }, 'error cloning object'); + const str = quickStringify(input); + if (str) { + return JSON.parse(str); + } + + // istanbul ignore next: not easily testable + throw err; + } } diff --git a/package.json b/package.json index e5f5a0348f11fb..5b2d54eeb6dac3 100644 --- a/package.json +++ b/package.json @@ -209,6 +209,7 @@ "json-dup-key-validator": "1.0.3", "json-stringify-pretty-compact": "3.0.0", "json5": "2.2.3", + "klona": "2.0.6", "luxon": "3.3.0", "markdown-it": "13.0.1", "markdown-table": "2.0.0",