diff --git a/lib/modules/datasource/api.ts b/lib/modules/datasource/api.ts
index 082c3a7d7b6..1893ea6d19f 100644
--- a/lib/modules/datasource/api.ts
+++ b/lib/modules/datasource/api.ts
@@ -61,6 +61,7 @@ import { PuppetForgeDatasource } from './puppet-forge';
import { PypiDatasource } from './pypi';
import { PythonVersionDatasource } from './python-version';
import { RepologyDatasource } from './repology';
+import { RpmDatasource } from './rpm';
import { RubyVersionDatasource } from './ruby-version';
import { RubygemsDatasource } from './rubygems';
import { SbtPackageDatasource } from './sbt-package';
@@ -139,6 +140,7 @@ api.set(PuppetForgeDatasource.id, new PuppetForgeDatasource());
api.set(PypiDatasource.id, new PypiDatasource());
api.set(PythonVersionDatasource.id, new PythonVersionDatasource());
api.set(RepologyDatasource.id, new RepologyDatasource());
+api.set(RpmDatasource.id, new RpmDatasource());
api.set(RubyVersionDatasource.id, new RubyVersionDatasource());
api.set(RubygemsDatasource.id, new RubygemsDatasource());
api.set(SbtPackageDatasource.id, new SbtPackageDatasource());
diff --git a/lib/modules/datasource/rpm/index.spec.ts b/lib/modules/datasource/rpm/index.spec.ts
new file mode 100644
index 00000000000..7b171b621fa
--- /dev/null
+++ b/lib/modules/datasource/rpm/index.spec.ts
@@ -0,0 +1,451 @@
+import { gzipSync } from 'node:zlib';
+import { RpmDatasource } from '.';
+import * as httpMock from '~test/http-mock';
+
+describe('modules/datasource/rpm/index', () => {
+ describe('getPrimaryGzipUrl', () => {
+ const registryUrl = 'https://example.com/repo/repodata/';
+ const rpmDatasource = new RpmDatasource();
+
+ it('returns the correct primary.xml URL', async () => {
+ const repomdXml = `
+
+
+
+
+`;
+
+ httpMock
+ .scope(registryUrl)
+ .get('/repomd.xml')
+ .reply(200, repomdXml, { 'Content-Type': 'application/gzip' });
+
+ const primaryXmlUrl = await rpmDatasource.getPrimaryGzipUrl(registryUrl);
+
+ expect(primaryXmlUrl).toBe(
+ 'https://example.com/repo/repodata/somesha256-primary.xml.gz',
+ );
+ });
+
+ it('throws an error if repomd.xml is missing', async () => {
+ httpMock.scope(registryUrl).get('/repomd.xml').reply(404, 'Not Found');
+
+ await expect(
+ rpmDatasource.getPrimaryGzipUrl(registryUrl),
+ ).rejects.toThrow(`Response code 404 (Not Found)`);
+ });
+
+ it('throws an error if http.getText fails', async () => {
+ httpMock
+ .scope(registryUrl)
+ .get('/repomd.xml')
+ .replyWithError('Network error');
+
+ await expect(
+ rpmDatasource.getPrimaryGzipUrl(registryUrl),
+ ).rejects.toThrow('Network error');
+ });
+
+ it('throws an error if repomdXml is not in XML format', async () => {
+ const repomdXml = `
+
+
+
+
+`;
+ httpMock
+ .scope(registryUrl)
+ .get('/repomd.xml')
+ .reply(200, repomdXml, { 'Content-Type': 'application/xml' });
+ await expect(
+ rpmDatasource.getPrimaryGzipUrl(registryUrl),
+ ).rejects.toThrow(`is not in XML format.`);
+ });
+
+ it('throws an error if no primary data is found', async () => {
+ const repomdXml = `
+
+
+
+
+`;
+
+ httpMock
+ .scope(registryUrl)
+ .get('/repomd.xml')
+ .reply(200, repomdXml, { 'Content-Type': 'application/xml' });
+
+ await expect(
+ rpmDatasource.getPrimaryGzipUrl(registryUrl),
+ ).rejects.toThrow(
+ 'No primary data found in https://example.com/repo/repodata/repomd.xml',
+ );
+ });
+
+ it('throws an error if no location element is found', async () => {
+ const repomdXml = `
+
+
+
+
+`;
+
+ httpMock
+ .scope(registryUrl)
+ .get('/repomd.xml')
+ .reply(200, repomdXml, { 'Content-Type': 'application/xml' });
+
+ await expect(
+ rpmDatasource.getPrimaryGzipUrl(registryUrl),
+ ).rejects.toThrow(
+ 'No location element found in https://example.com/repo/repodata/repomd.xml',
+ );
+ });
+
+ it('throws an error if location href is missing', async () => {
+ const repomdXml = `
+
+
+
+
+`;
+
+ httpMock
+ .scope(registryUrl)
+ .get('/repomd.xml')
+ .reply(200, repomdXml, { 'Content-Type': 'application/xml' });
+
+ await expect(
+ rpmDatasource.getPrimaryGzipUrl(registryUrl),
+ ).rejects.toThrow(
+ `No href found in https://example.com/repo/repodata/repomd.xml`,
+ );
+ });
+ });
+
+ describe('getReleasesByPackageName', () => {
+ const packageName = 'example-package';
+ const rpmDatasource = new RpmDatasource();
+ const primaryXmlUrl =
+ 'https://example.com/repo/repodata/somesha256-primary.xml.gz';
+
+ it('returns the correct releases', async () => {
+ const primaryXml = `
+
+
+ example-package
+ x86_64
+
+
+
+ example-package
+ x86_64
+
+
+
+ example-package
+ x86_64
+
+
+
+ example-package
+ x86_64
+
+
+
+`;
+ // gzip the primaryXml content
+ const gzippedPrimaryXml = gzipSync(primaryXml);
+ httpMock
+ .scope(primaryXmlUrl.replace(/\/[^/]+$/, ''))
+ .get('/somesha256-primary.xml.gz')
+ .reply(200, gzippedPrimaryXml, {
+ 'Content-Type': 'application/gzip',
+ });
+ const releases = await rpmDatasource.getReleasesByPackageName(
+ primaryXmlUrl,
+ packageName,
+ );
+ expect(releases).toEqual({
+ releases: [
+ {
+ version: '1.0-2.azl3',
+ },
+ {
+ version: '1.1-1.azl3',
+ },
+ {
+ version: '1.1-2.azl3',
+ },
+ {
+ version: '1.2',
+ },
+ ],
+ });
+ });
+
+ it('throws an error if somesha256-primary.xml.gz is not found', async () => {
+ httpMock
+ .scope(primaryXmlUrl.replace(/\/[^/]+$/, ''))
+ .get('/somesha256-primary.xml.gz')
+ .reply(404, 'Not Found');
+
+ await expect(
+ rpmDatasource.getReleasesByPackageName(primaryXmlUrl, packageName),
+ ).rejects.toThrow(`Response code 404 (Not Found)`);
+ });
+
+ it('throws an error if response.body is empty', async () => {
+ httpMock
+ .scope(primaryXmlUrl.replace(/\/[^/]+$/, ''))
+ .get('/somesha256-primary.xml.gz')
+ .reply(200, '', { 'Content-Type': 'application/gzip' });
+
+ await expect(
+ rpmDatasource.getReleasesByPackageName(primaryXmlUrl, packageName),
+ ).rejects.toThrowError(
+ 'Empty response body from getting ' + primaryXmlUrl + '.',
+ );
+ });
+
+ it('returns null if no element package is found in primary.xml', async () => {
+ const primaryXml = `
+
+
+ example-package
+ x86_64
+
+
+
+`;
+ // gzip the primaryXml content
+ const gzippedprimaryXml = gzipSync(primaryXml);
+ httpMock
+ .scope(primaryXmlUrl.replace(/\/[^/]+$/, ''))
+ .get('/somesha256-primary.xml.gz')
+ .reply(200, gzippedprimaryXml, {
+ 'Content-Type': 'application/gzip',
+ });
+ const result = await rpmDatasource.getReleasesByPackageName(
+ primaryXmlUrl,
+ packageName,
+ );
+ expect(result).toBeNull();
+ });
+
+ it('returns null if the specific packageName is not found in primary.xml', async () => {
+ const primaryXml = `
+
+
+ wrong-package
+ x86_64
+
+
+
+`;
+ // gzip the primaryXml content
+ const gzippedprimaryXml = gzipSync(primaryXml);
+ httpMock
+ .scope(primaryXmlUrl.replace(/\/[^/]+$/, ''))
+ .get('/somesha256-primary.xml.gz')
+ .reply(200, gzippedprimaryXml, {
+ 'Content-Type': 'application/gzip',
+ });
+ expect(
+ await rpmDatasource.getReleasesByPackageName(
+ primaryXmlUrl,
+ packageName,
+ ),
+ ).toBeNull();
+ });
+
+ it('returns an empty array if version is not found in a version element', async () => {
+ const primaryXml = `
+
+
+ example-package
+ x86_64
+
+
+
+`;
+ // gzip the primaryXml content
+ const gzippedprimaryXml = gzipSync(primaryXml);
+ httpMock
+ .scope(primaryXmlUrl.replace(/\/[^/]+$/, ''))
+ .get('/somesha256-primary.xml.gz')
+ .reply(200, gzippedprimaryXml, {
+ 'Content-Type': 'application/gzip',
+ });
+ const releases = await rpmDatasource.getReleasesByPackageName(
+ primaryXmlUrl,
+ packageName,
+ );
+ expect(releases).toBeNull();
+ });
+
+ // this is most likely a bug in the RPM XML file, but we can still handle it gracefully
+ it('returns an array of releases without duplicate versionWithRel', async () => {
+ const primaryXmlUrl =
+ 'https://example.com/repo/repodata/somesha256-primary.xml.gz';
+ const primaryXml = `
+
+
+ example-package
+ x86_64
+
+
+
+ example-package
+ x86_64
+
+
+
+`;
+ // gzip the primaryXml content
+ const gzippedprimaryXml = gzipSync(primaryXml);
+ httpMock
+ .scope(primaryXmlUrl.replace(/\/[^/]+$/, ''))
+ .get('/somesha256-primary.xml.gz')
+ .reply(200, gzippedprimaryXml, {
+ 'Content-Type': 'application/gzip',
+ });
+ const releases = await rpmDatasource.getReleasesByPackageName(
+ primaryXmlUrl,
+ packageName,
+ );
+ expect(releases).toEqual({
+ releases: [
+ {
+ version: '1.0-dulp.azl3',
+ },
+ ],
+ });
+ });
+
+ it('handles parser error event in getReleasesByPackageName', async () => {
+ const primaryXmlMalformed = `
+<%$#metadata xmlns="http://linux.duke.edu/metadata/common">
+
+ example-package
+ x86_64
+
+
+`;
+ // gzip the primaryXml content
+ const gzippedprimaryXml = gzipSync(primaryXmlMalformed);
+ httpMock
+ .scope(primaryXmlUrl.replace(/\/[^/]+$/, ''))
+ .get('/somesha256-primary.xml.gz')
+ .reply(200, gzippedprimaryXml, {
+ 'Content-Type': 'application/gzip',
+ });
+ await expect(
+ rpmDatasource.getReleasesByPackageName(primaryXmlUrl, packageName),
+ ).rejects.toThrowError('Unencoded <');
+ });
+ });
+
+ describe('getReleases', () => {
+ const registryUrl = 'https://example.com/repo/repodata/';
+ const rpmDatasource = new RpmDatasource();
+
+ it('returns null if registryUrl is not provided', async () => {
+ const releases = await rpmDatasource.getReleases({
+ registryUrl: undefined,
+ packageName: 'example-package',
+ });
+ expect(releases).toBeNull();
+ });
+
+ it('returns null if primaryXmlUrl is empty', async () => {
+ vi.spyOn(rpmDatasource, 'getPrimaryGzipUrl').mockResolvedValue(null);
+ const releases = await rpmDatasource.getReleases({
+ registryUrl: 'someurl',
+ packageName: 'example-package',
+ });
+ expect(releases).toBeNull();
+ });
+
+ it('returns null if packageName is not provided', async () => {
+ const releases = await rpmDatasource.getReleases({
+ registryUrl,
+ packageName: '',
+ });
+ expect(releases).toBeNull();
+ });
+
+ it('returns the correct releases', async () => {
+ //mock the getPrimaryGzipUrl method to return the primaryXmlUrl
+ vi.spyOn(rpmDatasource, 'getPrimaryGzipUrl').mockResolvedValue(
+ 'https://example.com/repo/repodata/',
+ );
+ vi.spyOn(rpmDatasource, 'getReleasesByPackageName').mockResolvedValue({
+ releases: [
+ {
+ version: '1.0-2.azl3',
+ },
+ {
+ version: '1.1-1.azl3',
+ },
+ {
+ version: '1.1-2.azl3',
+ },
+ {
+ version: '1.2',
+ },
+ ],
+ });
+
+ const releases = await rpmDatasource.getReleases({
+ registryUrl,
+ packageName: 'example-package',
+ });
+ expect(releases).toEqual({
+ releases: [
+ {
+ version: '1.0-2.azl3',
+ },
+ {
+ version: '1.1-1.azl3',
+ },
+ {
+ version: '1.1-2.azl3',
+ },
+ {
+ version: '1.2',
+ },
+ ],
+ });
+ });
+
+ it('throws an error if getPrimaryGzipUrl fails', async () => {
+ vi.spyOn(rpmDatasource, 'getPrimaryGzipUrl').mockRejectedValue(
+ new Error('Something wrong'),
+ );
+
+ await expect(
+ rpmDatasource.getReleases({
+ registryUrl,
+ packageName: 'example-package',
+ }),
+ ).rejects.toThrow('Something wrong');
+ });
+
+ it('throws an error if getReleasesByPackageName fails', async () => {
+ vi.spyOn(rpmDatasource, 'getPrimaryGzipUrl').mockResolvedValue(
+ 'https://example.com/repo/repodata/',
+ );
+ vi.spyOn(rpmDatasource, 'getReleasesByPackageName').mockRejectedValue(
+ new Error('Something wrong'),
+ );
+
+ await expect(
+ rpmDatasource.getReleases({
+ registryUrl,
+ packageName: 'example-package',
+ }),
+ ).rejects.toThrow('Something wrong');
+ });
+ });
+});
diff --git a/lib/modules/datasource/rpm/index.ts b/lib/modules/datasource/rpm/index.ts
new file mode 100644
index 00000000000..0ba1758f51b
--- /dev/null
+++ b/lib/modules/datasource/rpm/index.ts
@@ -0,0 +1,220 @@
+import { Readable } from 'node:stream';
+import { gunzip } from 'node:zlib';
+import { promisify } from 'util';
+import sax from 'sax';
+import { XmlDocument } from 'xmldoc';
+import { logger } from '../../../logger';
+import { cache } from '../../../util/cache/package/decorator';
+import type { HttpResponse } from '../../../util/http';
+import { joinUrlParts } from '../../../util/url';
+import { Datasource } from '../datasource';
+import type { GetReleasesConfig, Release, ReleaseResult } from '../types';
+
+const gunzipAsync = promisify(gunzip);
+
+export class RpmDatasource extends Datasource {
+ static readonly id = 'rpm';
+
+ // repomd.xml is a standard file name in RPM repositories which contains metadata about the repository
+ static readonly repomdXmlFileName = 'repomd.xml';
+
+ constructor() {
+ super(RpmDatasource.id);
+ }
+
+ /**
+ * Users are able to specify custom RPM repositories as long as they follow the format.
+ * There is a URI http://linux.duke.edu/metadata/common in the -primary.xml.
+ * But according to this post, it's not something we can really look into or reference.
+ * @see{https://lists.rpm.org/pipermail/rpm-ecosystem/2015-October/000283.html}
+ */
+ override readonly customRegistrySupport = true;
+
+ /**
+ * Fetches the release information for a given package from the registry URL.
+ *
+ * @param registryUrl - the registryUrl should be the folder which contains repodata.xml and its corresponding file list -primary.xml.gz, e.g.: https://packages.microsoft.com/azurelinux/3.0/prod/cloud-native/x86_64/repodata/
+ * @param packageName - the name of the package to fetch releases for.
+ * @returns The release result if the package is found, otherwise null.
+ */
+ @cache({
+ namespace: `datasource-${RpmDatasource.id}`,
+ key: ({ registryUrl, packageName }: GetReleasesConfig) =>
+ `${registryUrl}:${packageName}`,
+ ttlMinutes: 1440,
+ })
+ async getReleases({
+ registryUrl,
+ packageName,
+ }: GetReleasesConfig): Promise {
+ if (!registryUrl || !packageName) {
+ return null;
+ }
+ try {
+ const primaryGzipUrl = await this.getPrimaryGzipUrl(registryUrl);
+ if (!primaryGzipUrl) {
+ return null;
+ }
+ return await this.getReleasesByPackageName(primaryGzipUrl, packageName);
+ } catch (err) {
+ this.handleGenericErrors(err);
+ }
+ }
+
+ // Fetches the primary.xml.gz URL from the repomd.xml file.
+ @cache({
+ namespace: `datasource-${RpmDatasource.id}`,
+ key: (registryUrl: string) => registryUrl,
+ ttlMinutes: 1440,
+ })
+ async getPrimaryGzipUrl(registryUrl: string): Promise {
+ const repomdUrl = joinUrlParts(
+ registryUrl,
+ RpmDatasource.repomdXmlFileName,
+ );
+ const response = await this.http.getText(repomdUrl.toString());
+
+ // check if repomd.xml is in XML format
+ if (!response.body.startsWith(' {
+ let response: HttpResponse;
+ let decompressedBuffer: Buffer;
+ try {
+ // primaryGzipUrl is a .gz file, need to extract it before parsing
+ response = await this.http.getBuffer(primaryGzipUrl);
+ if (response.body.length === 0) {
+ logger.debug(`Empty response body from getting ${primaryGzipUrl}.`);
+ throw new Error(`Empty response body from getting ${primaryGzipUrl}.`);
+ }
+ // decompress the gzipped file
+ decompressedBuffer = await gunzipAsync(response.body);
+ } catch (err) {
+ logger.debug(
+ `Failed to fetch or decompress ${primaryGzipUrl}: ${
+ err instanceof Error ? err.message : err
+ }`,
+ );
+ throw err;
+ }
+
+ // Use sax streaming parser to handle large XML files efficiently
+ // This allows us to parse the XML file without loading the entire file into memory.
+ const releases: Record = {};
+ let insidePackage = false;
+ let isTargetPackage = false;
+ let insideName = false;
+
+ // Create a SAX parser in strict mode
+ const saxParser = sax.createStream(true, {
+ lowercase: true, // normalize tag names to lowercase
+ trim: true,
+ });
+
+ saxParser.on('opentag', (node: sax.Tag) => {
+ if (node.name === 'package' && node.attributes.type === 'rpm') {
+ insidePackage = true;
+ isTargetPackage = false;
+ }
+ if (insidePackage && node.name === 'name') {
+ insideName = true;
+ }
+ if (insidePackage && isTargetPackage && node.name === 'version') {
+ // rel is optional
+ if (node.attributes.rel === undefined) {
+ const version = `${node.attributes.ver}`;
+ releases[version] = { version };
+ } else {
+ const version = `${node.attributes.ver}-${node.attributes.rel}`;
+ releases[version] = { version };
+ }
+ }
+ });
+ saxParser.on('text', (text: string) => {
+ if (insidePackage && insideName) {
+ if (text.trim() === packageName) {
+ isTargetPackage = true;
+ }
+ }
+ });
+ saxParser.on('closetag', (tag: string) => {
+ if (tag === 'name' && insidePackage) {
+ insideName = false;
+ }
+ if (tag === 'package') {
+ insidePackage = false;
+ isTargetPackage = false;
+ }
+ });
+
+ await new Promise((resolve, reject) => {
+ let settled = false;
+ saxParser.on('error', (err: Error) => {
+ if (settled) {
+ return;
+ }
+ settled = true;
+ logger.debug(`SAX parsing error in ${primaryGzipUrl}: ${err.message}`);
+ setImmediate(() => saxParser.removeAllListeners());
+ reject(err);
+ });
+ saxParser.on('end', () => {
+ settled = true;
+ setImmediate(() => saxParser.removeAllListeners());
+ resolve();
+ });
+ Readable.from(decompressedBuffer).pipe(saxParser);
+ });
+
+ if (Object.keys(releases).length === 0) {
+ logger.trace(
+ `No releases found for package ${packageName} in ${primaryGzipUrl}`,
+ );
+ return null;
+ }
+ return {
+ releases: Object.values(releases).map((release) => ({
+ version: release.version,
+ })),
+ };
+ }
+}
diff --git a/lib/modules/datasource/rpm/readme.md b/lib/modules/datasource/rpm/readme.md
new file mode 100644
index 00000000000..3ec04b43049
--- /dev/null
+++ b/lib/modules/datasource/rpm/readme.md
@@ -0,0 +1,94 @@
+This datasource `rpm` returns releases of the RPM packages.
+It assumes the RPM repository is following the RPM standard and by default it has a repomd.xml in the directory provided by user in the `registryUrl`.
+According to this Pulp project doc, ,
+
+> repomd.xml is the metadata file that clients use to discover what repository metadata files exist in the repository.
+> It should always be located at repodata/repomd.xml relative to the root of the repository.
+
+## Set URL when using an RPM repository
+
+To use an RPM repository with the datasource, you must set a `registryUrl` with the directory that contains the `repomd.xml` and corresponding `primary.xml`.
+
+**Example**:
+
+If we have
+
+- `http://example.com/repo/repodata/repomd.xml`
+- `http://example.com/repo/repodata/-primary.xml` where `` is a dynamically generated SHA256 pattern.
+
+Then the `registryUrl` should set as `http://example.com/repo/repodata/` or `http://example.com/repo/repodata`.
+
+## Usage Example
+
+Say you're defining dnf/tdnf/yum packages in a `manifest.json` and you want Renovate to update them.
+
+Assuming your `manifest.json` looks like this.
+
+```manifest.json
+{
+ "package1": "1.0.0-1",
+ "package2": "1.1.0"
+}
+```
+
+where the versioning format could be `-`, or just ``
+
+```renovate.json
+{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
+ "customManagers": [
+ {
+ "customType": "regex",
+ "fileMatch": [
+ "path_to_manifest_json"
+ ],
+ "registryUrlTemplate": "http://example.com/repo/repodata/",
+ "datasourceTemplate": "rpm"
+ }
+ ]
+}
+```
+
+In an RPM repository, the `-primary.xml` looks like this:
+
+```
+`
+
+
+ example-package
+ x86_64
+
+
+
+ example-package
+ x86_64
+
+
+
+ example-package
+ x86_64
+
+
+
+ example-package
+ x86_64
+
+
+...
+...
+
+```
+
+You can see that `ver` and `rel` (release/revision) is stored separately.
+But the RPM datasource implementation will combine these together as `ver-rel`.
+That's why in the `manifest.json` above, the version is defined as `1.0.0-1`, if `rel` is available.
+Or just `1.1.0` if `rel` is not available.
+
+## Limitation and Consideration
+
+In real-world scenarios, the decompressed `primary.xml` file from an RPM repository can be extremely large.
+To handle this efficiently, this implementation uses streaming XML parsing, which processes the file incrementally and avoids loading the entire XML into memory.
+
+Streaming XML parsing is a practical solution for large files in Node.js, but for extremely large or complex cases (e.g., files exceeding ~512MB), you may still encounter memory or performance issues.
+For such scenarios, consider using more robust approaches such as native modules, optimized SAX parsers, or external tools.
+Contributions and suggestions for further improving large file handling are welcome.
diff --git a/lib/util/cache/package/types.ts b/lib/util/cache/package/types.ts
index f67588ed1b3..52524adec2d 100644
--- a/lib/util/cache/package/types.ts
+++ b/lib/util/cache/package/types.ts
@@ -96,6 +96,7 @@ export type PackageCacheNamespace =
| 'datasource-python-version'
| 'datasource-releases'
| 'datasource-repology'
+ | 'datasource-rpm'
| 'datasource-ruby-version'
| 'datasource-rubygems'
| 'datasource-sbt-package'
diff --git a/package.json b/package.json
index f0a0b529734..e30f8c9fb80 100644
--- a/package.json
+++ b/package.json
@@ -245,6 +245,7 @@
"remark": "13.0.0",
"remark-github": "10.1.0",
"safe-stable-stringify": "2.5.0",
+ "sax": "1.4.1",
"semver": "7.7.2",
"semver-stable": "3.0.0",
"semver-utils": "1.1.4",
@@ -304,6 +305,7 @@
"@types/node": "22.15.30",
"@types/parse-link-header": "2.0.3",
"@types/punycode": "2.1.4",
+ "@types/sax": "1.2.7",
"@types/semver": "7.7.0",
"@types/semver-stable": "3.0.2",
"@types/semver-utils": "1.1.3",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 17933abb5c8..695125a4bad 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -308,6 +308,9 @@ importers:
safe-stable-stringify:
specifier: 2.5.0
version: 2.5.0
+ sax:
+ specifier: 1.4.1
+ version: 1.4.1
semver:
specifier: 7.7.2
version: 7.7.2
@@ -465,6 +468,9 @@ importers:
'@types/punycode':
specifier: 2.1.4
version: 2.1.4
+ '@types/sax':
+ specifier: 1.2.7
+ version: 1.2.7
'@types/semver':
specifier: 7.7.0
version: 7.7.0
@@ -1077,18 +1083,22 @@ packages:
resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
- '@eslint/config-array@0.20.0':
- resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==}
+ '@eslint/config-array@0.20.1':
+ resolution: {integrity: sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/config-helpers@0.2.2':
- resolution: {integrity: sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==}
+ '@eslint/config-helpers@0.2.3':
+ resolution: {integrity: sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@eslint/core@0.14.0':
resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ '@eslint/core@0.15.0':
+ resolution: {integrity: sha512-b7ePw78tEWWkpgZCDYkbqDOP8dmM6qe+AOC6iuJqlq1R/0ahMAeH3qynpnqKFGkMltrp44ohV4ubGyvLX28tzw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
'@eslint/eslintrc@3.3.1':
resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -1101,8 +1111,8 @@ packages:
resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@eslint/plugin-kit@0.3.1':
- resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==}
+ '@eslint/plugin-kit@0.3.2':
+ resolution: {integrity: sha512-4SaFZCNfJqvk/kenHpI8xvN42DMaoycy4PzKc5otHxRswww1kAt82OlBuwRVLofCACCTZEcla2Ydxv8scMXaTg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@gwhitney/detect-indent@7.0.1':
@@ -2150,6 +2160,9 @@ packages:
'@types/responselike@1.0.3':
resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==}
+ '@types/sax@1.2.7':
+ resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==}
+
'@types/semver-stable@3.0.2':
resolution: {integrity: sha512-uNLK57+EY0r8VprVwHytHhlTb1tUVZiWgXkMBKoeu1/3LaFq+ZiaG29xAC3APAWG7xdedwGqeUY8N1y9YG1vjw==}
@@ -2285,88 +2298,98 @@ packages:
resolution: {integrity: sha512-qHV7pW7E85A0x6qyrFn+O+q1k1p3tQCsqIZ1KZ5ESLXY57aTvUd3/a4rdPTeXisvhXn2VQG0VSKUqs8KHF2zcA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@unrs/resolver-binding-darwin-arm64@1.7.13':
- resolution: {integrity: sha512-LIKeCzNSkTWwGHjtiUIfvS96+7kpuyrKq2pzw/0XT2S8ykczj40Hh27oLTbXguCX8tGrCoaD2yXxzwqMMhAzhA==}
+ '@unrs/resolver-binding-android-arm-eabi@1.9.0':
+ resolution: {integrity: sha512-h1T2c2Di49ekF2TE8ZCoJkb+jwETKUIPDJ/nO3tJBKlLFPu+fyd93f0rGP/BvArKx2k2HlRM4kqkNarj3dvZlg==}
+ cpu: [arm]
+ os: [android]
+
+ '@unrs/resolver-binding-android-arm64@1.9.0':
+ resolution: {integrity: sha512-sG1NHtgXtX8owEkJ11yn34vt0Xqzi3k9TJ8zppDmyG8GZV4kVWw44FHwKwHeEFl07uKPeC4ZoyuQaGh5ruJYPA==}
+ cpu: [arm64]
+ os: [android]
+
+ '@unrs/resolver-binding-darwin-arm64@1.9.0':
+ resolution: {integrity: sha512-nJ9z47kfFnCxN1z/oYZS7HSNsFh43y2asePzTEZpEvK7kGyuShSl3RRXnm/1QaqFL+iP+BjMwuB+DYUymOkA5A==}
cpu: [arm64]
os: [darwin]
- '@unrs/resolver-binding-darwin-x64@1.7.13':
- resolution: {integrity: sha512-GB5G3qUNrdo2l6xaZehpz1ln4wCQ75tr51HZ8OQEcX6XkBIFVL9E4ikCZvCmRmUgKGR+zP5ogyFib7ZbIMWKWA==}
+ '@unrs/resolver-binding-darwin-x64@1.9.0':
+ resolution: {integrity: sha512-TK+UA1TTa0qS53rjWn7cVlEKVGz2B6JYe0C++TdQjvWYIyx83ruwh0wd4LRxYBM5HeuAzXcylA9BH2trARXJTw==}
cpu: [x64]
os: [darwin]
- '@unrs/resolver-binding-freebsd-x64@1.7.13':
- resolution: {integrity: sha512-rb8gzoBgqVhDkQiKaq+MrFPhNK3x8XkSFhgU55LfgOa5skv7KIdM3dELKzQVNZNlY49DuZmm0FsEfHK5xPKKiA==}
+ '@unrs/resolver-binding-freebsd-x64@1.9.0':
+ resolution: {integrity: sha512-6uZwzMRFcD7CcCd0vz3Hp+9qIL2jseE/bx3ZjaLwn8t714nYGwiE84WpaMCYjU+IQET8Vu/+BNAGtYD7BG/0yA==}
cpu: [x64]
os: [freebsd]
- '@unrs/resolver-binding-linux-arm-gnueabihf@1.7.13':
- resolution: {integrity: sha512-bqdzngbTGzhsqhTV3SWECyZUAyvtewKtrCW4E8QPcK6yHSaN0k1h9gKwNOBxFwIqkQRsAibpm18XDum8M5AiCw==}
+ '@unrs/resolver-binding-linux-arm-gnueabihf@1.9.0':
+ resolution: {integrity: sha512-bPUBksQfrgcfv2+mm+AZinaKq8LCFvt5PThYqRotqSuuZK1TVKkhbVMS/jvSRfYl7jr3AoZLYbDkItxgqMKRkg==}
cpu: [arm]
os: [linux]
- '@unrs/resolver-binding-linux-arm-musleabihf@1.7.13':
- resolution: {integrity: sha512-vkoL3DSS5tsUNLhNtBJWaqDJNNEQsMCr0o2N02sLCSpe5S8TQHz+klQT42Qgj4PqATMwnG3OF0QQ5BH0oAKIPg==}
+ '@unrs/resolver-binding-linux-arm-musleabihf@1.9.0':
+ resolution: {integrity: sha512-uT6E7UBIrTdCsFQ+y0tQd3g5oudmrS/hds5pbU3h4s2t/1vsGWbbSKhBSCD9mcqaqkBwoqlECpUrRJCmldl8PA==}
cpu: [arm]
os: [linux]
- '@unrs/resolver-binding-linux-arm64-gnu@1.7.13':
- resolution: {integrity: sha512-uNpLKxlDF+NF6aUztbAVhhFSF65zf/6QEfk5NifUgYFbpBObzvMnl2ydEsXV96spwPcmeNTpG9byvq+Twwd3HQ==}
+ '@unrs/resolver-binding-linux-arm64-gnu@1.9.0':
+ resolution: {integrity: sha512-vdqBh911wc5awE2bX2zx3eflbyv8U9xbE/jVKAm425eRoOVv/VseGZsqi3A3SykckSpF4wSROkbQPvbQFn8EsA==}
cpu: [arm64]
os: [linux]
- '@unrs/resolver-binding-linux-arm64-musl@1.7.13':
- resolution: {integrity: sha512-mEFL6q7vtxA6YJ9sLbxCnKOBynOvClVOcqwUErmaCxA94hgP11rlstouySxJCGeFAb8KfUX9mui82waYrqoBlQ==}
+ '@unrs/resolver-binding-linux-arm64-musl@1.9.0':
+ resolution: {integrity: sha512-/8JFZ/SnuDr1lLEVsxsuVwrsGquTvT51RZGvyDB/dOK3oYK2UqeXzgeyq6Otp8FZXQcEYqJwxb9v+gtdXn03eQ==}
cpu: [arm64]
os: [linux]
- '@unrs/resolver-binding-linux-ppc64-gnu@1.7.13':
- resolution: {integrity: sha512-MjJaNk8HK3rCOIPS6AQPJXlrDfG1LaePum+CZddHZygPqDNZyVrVdWTadT+U51vIx5QOdEE0oXcgTY+7VYsU1g==}
+ '@unrs/resolver-binding-linux-ppc64-gnu@1.9.0':
+ resolution: {integrity: sha512-FkJjybtrl+rajTw4loI3L6YqSOpeZfDls4SstL/5lsP2bka9TiHUjgMBjygeZEis1oC8LfJTS8FSgpKPaQx2tQ==}
cpu: [ppc64]
os: [linux]
- '@unrs/resolver-binding-linux-riscv64-gnu@1.7.13':
- resolution: {integrity: sha512-9gAuT1+ed2eIuOXHSu4SdJOe7SUEzPTpOTEuTjGePvMEoWHywY5pvlcY7xMn3d8rhKHpwMzEhl8F8Oy+rkudzA==}
+ '@unrs/resolver-binding-linux-riscv64-gnu@1.9.0':
+ resolution: {integrity: sha512-w/NZfHNeDusbqSZ8r/hp8iL4S39h4+vQMc9/vvzuIKMWKppyUGKm3IST0Qv0aOZ1rzIbl9SrDeIqK86ZpUK37w==}
cpu: [riscv64]
os: [linux]
- '@unrs/resolver-binding-linux-riscv64-musl@1.7.13':
- resolution: {integrity: sha512-CNrJythJN9jC8SIJGoawebYylzGNJuWAWTKxxxx5Fr3DGEXbex/We4U7N4u6/dQAK3cLVOuAE/9a4D2JH35JIA==}
+ '@unrs/resolver-binding-linux-riscv64-musl@1.9.0':
+ resolution: {integrity: sha512-bEPBosut8/8KQbUixPry8zg/fOzVOWyvwzOfz0C0Rw6dp+wIBseyiHKjkcSyZKv/98edrbMknBaMNJfA/UEdqw==}
cpu: [riscv64]
os: [linux]
- '@unrs/resolver-binding-linux-s390x-gnu@1.7.13':
- resolution: {integrity: sha512-J0MVXXPvM2Bv+f+gzOZHLHEmXUJNKwJqkfMDTwE763w/tD+OA7UlTMLQihrcYRXwW5jZ8nbM2cEWTeFsTiH2JQ==}
+ '@unrs/resolver-binding-linux-s390x-gnu@1.9.0':
+ resolution: {integrity: sha512-LDtMT7moE3gK753gG4pc31AAqGUC86j3AplaFusc717EUGF9ZFJ356sdQzzZzkBk1XzMdxFyZ4f/i35NKM/lFA==}
cpu: [s390x]
os: [linux]
- '@unrs/resolver-binding-linux-x64-gnu@1.7.13':
- resolution: {integrity: sha512-Ii2WhtIpeWUe6XG/YhPUX3JNL3PiyXe56PJzqAYDUyB0gctkk/nngpuPnNKlLMcN9FID0T39mIJPhA6YpRcGDQ==}
+ '@unrs/resolver-binding-linux-x64-gnu@1.9.0':
+ resolution: {integrity: sha512-WmFd5KINHIXj8o1mPaT8QRjA9HgSXhN1gl9Da4IZihARihEnOylu4co7i/yeaIpcfsI6sYs33cNZKyHYDh0lrA==}
cpu: [x64]
os: [linux]
- '@unrs/resolver-binding-linux-x64-musl@1.7.13':
- resolution: {integrity: sha512-8F5E9EhtGYkfEM1OhyVgq76+SnMF5NfZS4v5Rq9JlfuqPnqXWgUjg903hxnG54PQr4I3jmG5bEeT77pGAA3Vvg==}
+ '@unrs/resolver-binding-linux-x64-musl@1.9.0':
+ resolution: {integrity: sha512-CYuXbANW+WgzVRIl8/QvZmDaZxrqvOldOwlbUjIM4pQ46FJ0W5cinJ/Ghwa/Ng1ZPMJMk1VFdsD/XwmCGIXBWg==}
cpu: [x64]
os: [linux]
- '@unrs/resolver-binding-wasm32-wasi@1.7.13':
- resolution: {integrity: sha512-7RXGTyDtyR/5o1FlBcjEaQQmQ2rKvu5Jq0Uhvce3PsbreZ61M4LQ5Mey2OMomIq4opphAkfDdm/lkHhWJNKNrw==}
+ '@unrs/resolver-binding-wasm32-wasi@1.9.0':
+ resolution: {integrity: sha512-6Rp2WH0OoitMYR57Z6VE8Y6corX8C6QEMWLgOV6qXiJIeZ1F9WGXY/yQ8yDC4iTraotyLOeJ2Asea0urWj2fKQ==}
engines: {node: '>=14.0.0'}
cpu: [wasm32]
- '@unrs/resolver-binding-win32-arm64-msvc@1.7.13':
- resolution: {integrity: sha512-MomJVcaVZe3j+CvkcfIVEcQyOOzauKpJYGY8d6PoKXn1FalMVGHX9/c0kXCI0WCK+CRGMExAiQhD8jkhyUVKxg==}
+ '@unrs/resolver-binding-win32-arm64-msvc@1.9.0':
+ resolution: {integrity: sha512-rknkrTRuvujprrbPmGeHi8wYWxmNVlBoNW8+4XF2hXUnASOjmuC9FNF1tGbDiRQWn264q9U/oGtixyO3BT8adQ==}
cpu: [arm64]
os: [win32]
- '@unrs/resolver-binding-win32-ia32-msvc@1.7.13':
- resolution: {integrity: sha512-pnHfzbFj6e4gUARI1Yvz0TUhmFZae248O7JOMCSmSBN3R35RJiKyHmsMuIiPrUYWDzm5jUMPTxSs+b3Ipawusw==}
+ '@unrs/resolver-binding-win32-ia32-msvc@1.9.0':
+ resolution: {integrity: sha512-Ceymm+iBl+bgAICtgiHyMLz6hjxmLJKqBim8tDzpX61wpZOx2bPK6Gjuor7I2RiUynVjvvkoRIkrPyMwzBzF3A==}
cpu: [ia32]
os: [win32]
- '@unrs/resolver-binding-win32-x64-msvc@1.7.13':
- resolution: {integrity: sha512-tI0+FTntE3BD0UxhTP12F/iTtkeMK+qh72/2aSxPZnTlOcMR9CTJid8CdppbSjj9wenq7PNcqScLtpPENH3Lvg==}
+ '@unrs/resolver-binding-win32-x64-msvc@1.9.0':
+ resolution: {integrity: sha512-k59o9ZyeyS0hAlcaKFezYSH2agQeRFEB7KoQLXl3Nb3rgkqT1NY9Vwy+SqODiLmYnEjxWJVRE/yq2jFVqdIxZw==}
cpu: [x64]
os: [win32]
@@ -2725,8 +2748,8 @@ packages:
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
engines: {node: '>=6'}
- caniuse-lite@1.0.30001722:
- resolution: {integrity: sha512-DCQHBBZtiK6JVkAGw7drvAMK0Q0POD/xZvEmDp6baiMMP6QXXk9HpD6mNYBZWhOPG6LvIDb82ITqtWjhDckHCA==}
+ caniuse-lite@1.0.30001723:
+ resolution: {integrity: sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==}
chai@5.2.0:
resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==}
@@ -3123,8 +3146,8 @@ packages:
engines: {node: '>=18'}
hasBin: true
- electron-to-chromium@1.5.166:
- resolution: {integrity: sha512-QPWqHL0BglzPYyJJ1zSSmwFFL6MFXhbACOCcsCdUMCkzPdS9/OIBVxg516X/Ado2qwAq8k0nJJ7phQPCqiaFAw==}
+ electron-to-chromium@1.5.167:
+ resolution: {integrity: sha512-LxcRvnYO5ez2bMOFpbuuVuAI5QNeY1ncVytE/KXaL6ZNfzX1yPlAO0nSOyIHx2fVAuUprMqPs/TdVhUFZy7SIQ==}
email-addresses@5.0.0:
resolution: {integrity: sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==}
@@ -3891,8 +3914,8 @@ packages:
resolution: {integrity: sha512-YVt14UZCgsX1vZQ3gKjkWVdBdHQ6eu3MPU1TBgL1H5orXe2+jWD006WCPPtOuwlQm10NuzOW5WawiF1Q9veW8g==}
engines: {node: '>=18.20'}
- import-in-the-middle@1.14.0:
- resolution: {integrity: sha512-g5zLT0HaztRJWysayWYiUq/7E5H825QIiecMD2pI5QO7Wzr847l6GDvPvmZaDIdrDtS2w7qRczywxiK6SL5vRw==}
+ import-in-the-middle@1.14.2:
+ resolution: {integrity: sha512-5tCuY9BV8ujfOpwtAGgsTx9CGUapcFMEEyByLv1B+v2+6DhAcw+Zr0nhQT7uwaZ7DiourxFEscghOR8e1aPLQw==}
import-meta-resolve@4.1.0:
resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==}
@@ -5248,8 +5271,8 @@ packages:
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
engines: {node: '>= 0.4'}
- postcss@8.5.4:
- resolution: {integrity: sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==}
+ postcss@8.5.5:
+ resolution: {integrity: sha512-d/jtm+rdNT8tpXuHY5MMtcbJFBkhXE6593XVR9UoGCH8jSFGci7jGvMGH5RYd5PBJW+00NZQt6gf7CbagJCrhg==}
engines: {node: ^10 || ^12 || >=14}
prebuild-install@7.1.3:
@@ -5958,8 +5981,8 @@ packages:
peerDependencies:
typescript: '>=4.8.4'
- ts-essentials@10.1.0:
- resolution: {integrity: sha512-LirrVzbhIpFQ9BdGfqLnM9r7aP9rnyfeoxbP5ZEkdr531IaY21+KdebRSsbvqu28VDJtcDDn+AlGn95t0c52zQ==}
+ ts-essentials@10.1.1:
+ resolution: {integrity: sha512-4aTB7KLHKmUvkjNj8V+EdnmuVTiECzn3K+zIbRthumvHu+j44x3w63xpfs0JL3NGIzGXqoQ7AV591xHO+XrOTw==}
peerDependencies:
typescript: '>=4.5.0'
peerDependenciesMeta:
@@ -6145,8 +6168,8 @@ packages:
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
engines: {node: '>= 10.0.0'}
- unrs-resolver@1.7.13:
- resolution: {integrity: sha512-QUjCYKAgrdJpf3wA73zWjOrO7ra19lfnwQ8HRkNOLah5AVDqOS38UunnyhzsSL8AE+2/AGnAHxlr8cGshCP35A==}
+ unrs-resolver@1.9.0:
+ resolution: {integrity: sha512-wqaRu4UnzBD2ABTC1kLfBjAqIDZ5YUTr/MLGa7By47JV1bJDSW7jq/ZSLigB7enLe7ubNaJhtnBXgrc/50cEhg==}
upath@2.0.1:
resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==}
@@ -7470,7 +7493,7 @@ snapshots:
'@eslint-community/regexpp@4.12.1': {}
- '@eslint/config-array@0.20.0':
+ '@eslint/config-array@0.20.1':
dependencies:
'@eslint/object-schema': 2.1.6
debug: 4.4.1
@@ -7478,12 +7501,16 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@eslint/config-helpers@0.2.2': {}
+ '@eslint/config-helpers@0.2.3': {}
'@eslint/core@0.14.0':
dependencies:
'@types/json-schema': 7.0.15
+ '@eslint/core@0.15.0':
+ dependencies:
+ '@types/json-schema': 7.0.15
+
'@eslint/eslintrc@3.3.1':
dependencies:
ajv: 6.12.6
@@ -7502,9 +7529,9 @@ snapshots:
'@eslint/object-schema@2.1.6': {}
- '@eslint/plugin-kit@0.3.1':
+ '@eslint/plugin-kit@0.3.2':
dependencies:
- '@eslint/core': 0.14.0
+ '@eslint/core': 0.15.0
levn: 0.4.1
'@gwhitney/detect-indent@7.0.1': {}
@@ -7762,7 +7789,7 @@ snapshots:
dependencies:
'@opentelemetry/api': 1.9.0
'@opentelemetry/api-logs': 0.202.0
- import-in-the-middle: 1.14.0
+ import-in-the-middle: 1.14.2
require-in-the-middle: 7.5.2
transitivePeerDependencies:
- supports-color
@@ -8722,6 +8749,10 @@ snapshots:
dependencies:
'@types/node': 22.15.30
+ '@types/sax@1.2.7':
+ dependencies:
+ '@types/node': 22.15.30
+
'@types/semver-stable@3.0.2': {}
'@types/semver-utils@1.1.3': {}
@@ -8787,8 +8818,8 @@ snapshots:
'@typescript-eslint/project-service@8.33.1(typescript@5.8.3)':
dependencies:
- '@typescript-eslint/tsconfig-utils': 8.34.0(typescript@5.8.3)
- '@typescript-eslint/types': 8.34.0
+ '@typescript-eslint/tsconfig-utils': 8.33.1(typescript@5.8.3)
+ '@typescript-eslint/types': 8.33.1
debug: 4.4.1
typescript: 5.8.3
transitivePeerDependencies:
@@ -8900,57 +8931,63 @@ snapshots:
'@typescript-eslint/types': 8.34.0
eslint-visitor-keys: 4.2.1
- '@unrs/resolver-binding-darwin-arm64@1.7.13':
+ '@unrs/resolver-binding-android-arm-eabi@1.9.0':
+ optional: true
+
+ '@unrs/resolver-binding-android-arm64@1.9.0':
+ optional: true
+
+ '@unrs/resolver-binding-darwin-arm64@1.9.0':
optional: true
- '@unrs/resolver-binding-darwin-x64@1.7.13':
+ '@unrs/resolver-binding-darwin-x64@1.9.0':
optional: true
- '@unrs/resolver-binding-freebsd-x64@1.7.13':
+ '@unrs/resolver-binding-freebsd-x64@1.9.0':
optional: true
- '@unrs/resolver-binding-linux-arm-gnueabihf@1.7.13':
+ '@unrs/resolver-binding-linux-arm-gnueabihf@1.9.0':
optional: true
- '@unrs/resolver-binding-linux-arm-musleabihf@1.7.13':
+ '@unrs/resolver-binding-linux-arm-musleabihf@1.9.0':
optional: true
- '@unrs/resolver-binding-linux-arm64-gnu@1.7.13':
+ '@unrs/resolver-binding-linux-arm64-gnu@1.9.0':
optional: true
- '@unrs/resolver-binding-linux-arm64-musl@1.7.13':
+ '@unrs/resolver-binding-linux-arm64-musl@1.9.0':
optional: true
- '@unrs/resolver-binding-linux-ppc64-gnu@1.7.13':
+ '@unrs/resolver-binding-linux-ppc64-gnu@1.9.0':
optional: true
- '@unrs/resolver-binding-linux-riscv64-gnu@1.7.13':
+ '@unrs/resolver-binding-linux-riscv64-gnu@1.9.0':
optional: true
- '@unrs/resolver-binding-linux-riscv64-musl@1.7.13':
+ '@unrs/resolver-binding-linux-riscv64-musl@1.9.0':
optional: true
- '@unrs/resolver-binding-linux-s390x-gnu@1.7.13':
+ '@unrs/resolver-binding-linux-s390x-gnu@1.9.0':
optional: true
- '@unrs/resolver-binding-linux-x64-gnu@1.7.13':
+ '@unrs/resolver-binding-linux-x64-gnu@1.9.0':
optional: true
- '@unrs/resolver-binding-linux-x64-musl@1.7.13':
+ '@unrs/resolver-binding-linux-x64-musl@1.9.0':
optional: true
- '@unrs/resolver-binding-wasm32-wasi@1.7.13':
+ '@unrs/resolver-binding-wasm32-wasi@1.9.0':
dependencies:
'@napi-rs/wasm-runtime': 0.2.11
optional: true
- '@unrs/resolver-binding-win32-arm64-msvc@1.7.13':
+ '@unrs/resolver-binding-win32-arm64-msvc@1.9.0':
optional: true
- '@unrs/resolver-binding-win32-ia32-msvc@1.7.13':
+ '@unrs/resolver-binding-win32-ia32-msvc@1.9.0':
optional: true
- '@unrs/resolver-binding-win32-x64-msvc@1.7.13':
+ '@unrs/resolver-binding-win32-x64-msvc@1.9.0':
optional: true
'@vitest/coverage-v8@3.2.2(vitest@3.2.2(@types/debug@4.1.12)(@types/node@22.15.30)(tsx@4.19.4)(yaml@2.8.0))':
@@ -9302,8 +9339,8 @@ snapshots:
browserslist@4.25.0:
dependencies:
- caniuse-lite: 1.0.30001722
- electron-to-chromium: 1.5.166
+ caniuse-lite: 1.0.30001723
+ electron-to-chromium: 1.5.167
node-releases: 2.0.19
update-browserslist-db: 1.1.3(browserslist@4.25.0)
@@ -9392,7 +9429,7 @@ snapshots:
camelcase@5.3.1: {}
- caniuse-lite@1.0.30001722: {}
+ caniuse-lite@1.0.30001723: {}
chai@5.2.0:
dependencies:
@@ -9761,7 +9798,7 @@ snapshots:
minimatch: 10.0.1
semver: 7.7.2
- electron-to-chromium@1.5.166: {}
+ electron-to-chromium@1.5.167: {}
email-addresses@5.0.0: {}
@@ -9947,12 +9984,12 @@ snapshots:
strip-ansi: 6.0.1
text-table: 0.2.0
- eslint-import-context@0.1.8(unrs-resolver@1.7.13):
+ eslint-import-context@0.1.8(unrs-resolver@1.9.0):
dependencies:
get-tsconfig: 4.10.1
stable-hash-x: 0.1.1
optionalDependencies:
- unrs-resolver: 1.7.13
+ unrs-resolver: 1.9.0
eslint-import-resolver-node@0.3.9:
dependencies:
@@ -9966,12 +10003,12 @@ snapshots:
dependencies:
debug: 4.4.1
eslint: 9.28.0
- eslint-import-context: 0.1.8(unrs-resolver@1.7.13)
+ eslint-import-context: 0.1.8(unrs-resolver@1.9.0)
get-tsconfig: 4.10.1
is-bun-module: 2.0.0
stable-hash-x: 0.1.1
tinyglobby: 0.2.14
- unrs-resolver: 1.7.13
+ unrs-resolver: 1.9.0
optionalDependencies:
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.33.1(eslint@9.28.0)(typescript@5.8.3))(eslint-import-resolver-typescript@4.4.3)(eslint@9.28.0)
eslint-plugin-import-x: 4.15.1(@typescript-eslint/utils@8.34.0(eslint@9.28.0)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint@9.28.0)
@@ -9995,12 +10032,12 @@ snapshots:
comment-parser: 1.4.1
debug: 4.4.1
eslint: 9.28.0
- eslint-import-context: 0.1.8(unrs-resolver@1.7.13)
+ eslint-import-context: 0.1.8(unrs-resolver@1.9.0)
is-glob: 4.0.3
minimatch: 10.0.1
semver: 7.7.2
stable-hash-x: 0.1.1
- unrs-resolver: 1.7.13
+ unrs-resolver: 1.9.0
optionalDependencies:
'@typescript-eslint/utils': 8.34.0(eslint@9.28.0)(typescript@5.8.3)
eslint-import-resolver-node: 0.3.9
@@ -10054,12 +10091,12 @@ snapshots:
dependencies:
'@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0)
'@eslint-community/regexpp': 4.12.1
- '@eslint/config-array': 0.20.0
- '@eslint/config-helpers': 0.2.2
+ '@eslint/config-array': 0.20.1
+ '@eslint/config-helpers': 0.2.3
'@eslint/core': 0.14.0
'@eslint/eslintrc': 3.3.1
'@eslint/js': 9.28.0
- '@eslint/plugin-kit': 0.3.1
+ '@eslint/plugin-kit': 0.3.2
'@humanfs/node': 0.16.6
'@humanwhocodes/module-importer': 1.0.1
'@humanwhocodes/retry': 0.4.3
@@ -10694,7 +10731,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- import-in-the-middle@1.14.0:
+ import-in-the-middle@1.14.2:
dependencies:
acorn: 8.15.0
acorn-import-attributes: 1.9.5(acorn@8.15.0)
@@ -12140,7 +12177,7 @@ snapshots:
possible-typed-array-names@1.1.0: {}
- postcss@8.5.4:
+ postcss@8.5.5:
dependencies:
nanoid: 3.3.11
picocolors: 1.1.1
@@ -13006,7 +13043,7 @@ snapshots:
dependencies:
typescript: 5.8.3
- ts-essentials@10.1.0(typescript@5.8.3):
+ ts-essentials@10.1.1(typescript@5.8.3):
optionalDependencies:
typescript: 5.8.3
@@ -13188,27 +13225,29 @@ snapshots:
universalify@2.0.1: {}
- unrs-resolver@1.7.13:
+ unrs-resolver@1.9.0:
dependencies:
napi-postinstall: 0.2.4
optionalDependencies:
- '@unrs/resolver-binding-darwin-arm64': 1.7.13
- '@unrs/resolver-binding-darwin-x64': 1.7.13
- '@unrs/resolver-binding-freebsd-x64': 1.7.13
- '@unrs/resolver-binding-linux-arm-gnueabihf': 1.7.13
- '@unrs/resolver-binding-linux-arm-musleabihf': 1.7.13
- '@unrs/resolver-binding-linux-arm64-gnu': 1.7.13
- '@unrs/resolver-binding-linux-arm64-musl': 1.7.13
- '@unrs/resolver-binding-linux-ppc64-gnu': 1.7.13
- '@unrs/resolver-binding-linux-riscv64-gnu': 1.7.13
- '@unrs/resolver-binding-linux-riscv64-musl': 1.7.13
- '@unrs/resolver-binding-linux-s390x-gnu': 1.7.13
- '@unrs/resolver-binding-linux-x64-gnu': 1.7.13
- '@unrs/resolver-binding-linux-x64-musl': 1.7.13
- '@unrs/resolver-binding-wasm32-wasi': 1.7.13
- '@unrs/resolver-binding-win32-arm64-msvc': 1.7.13
- '@unrs/resolver-binding-win32-ia32-msvc': 1.7.13
- '@unrs/resolver-binding-win32-x64-msvc': 1.7.13
+ '@unrs/resolver-binding-android-arm-eabi': 1.9.0
+ '@unrs/resolver-binding-android-arm64': 1.9.0
+ '@unrs/resolver-binding-darwin-arm64': 1.9.0
+ '@unrs/resolver-binding-darwin-x64': 1.9.0
+ '@unrs/resolver-binding-freebsd-x64': 1.9.0
+ '@unrs/resolver-binding-linux-arm-gnueabihf': 1.9.0
+ '@unrs/resolver-binding-linux-arm-musleabihf': 1.9.0
+ '@unrs/resolver-binding-linux-arm64-gnu': 1.9.0
+ '@unrs/resolver-binding-linux-arm64-musl': 1.9.0
+ '@unrs/resolver-binding-linux-ppc64-gnu': 1.9.0
+ '@unrs/resolver-binding-linux-riscv64-gnu': 1.9.0
+ '@unrs/resolver-binding-linux-riscv64-musl': 1.9.0
+ '@unrs/resolver-binding-linux-s390x-gnu': 1.9.0
+ '@unrs/resolver-binding-linux-x64-gnu': 1.9.0
+ '@unrs/resolver-binding-linux-x64-musl': 1.9.0
+ '@unrs/resolver-binding-wasm32-wasi': 1.9.0
+ '@unrs/resolver-binding-win32-arm64-msvc': 1.9.0
+ '@unrs/resolver-binding-win32-ia32-msvc': 1.9.0
+ '@unrs/resolver-binding-win32-x64-msvc': 1.9.0
upath@2.0.1: {}
@@ -13298,7 +13337,7 @@ snapshots:
esbuild: 0.25.5
fdir: 6.4.6(picomatch@4.0.2)
picomatch: 4.0.2
- postcss: 8.5.4
+ postcss: 8.5.5
rollup: 4.43.0
tinyglobby: 0.2.14
optionalDependencies:
@@ -13309,7 +13348,7 @@ snapshots:
vitest-mock-extended@3.1.0(typescript@5.8.3)(vitest@3.2.2(@types/debug@4.1.12)(@types/node@22.15.30)(tsx@4.19.4)(yaml@2.8.0)):
dependencies:
- ts-essentials: 10.1.0(typescript@5.8.3)
+ ts-essentials: 10.1.1(typescript@5.8.3)
typescript: 5.8.3
vitest: 3.2.2(@types/debug@4.1.12)(@types/node@22.15.30)(tsx@4.19.4)(yaml@2.8.0)