From bd4f0fe49b292ace50db3cf4389137bb4bec5fd3 Mon Sep 17 00:00:00 2001 From: Ivan Paramonau Date: Tue, 21 Jul 2026 10:59:29 -0400 Subject: [PATCH 01/11] Add an option to group LD object entities --- config.local.js.SAMPLE | 15 +++++++ lib/utils.js | 92 ++++++++++++++++++++++++++++-------------- 2 files changed, 77 insertions(+), 30 deletions(-) diff --git a/config.local.js.SAMPLE b/config.local.js.SAMPLE index 29bbc0532..4b673480d 100644 --- a/config.local.js.SAMPLE +++ b/config.local.js.SAMPLE @@ -290,6 +290,21 @@ export default { */ }, + // optionally group JSON+LD into buckets so it is easier to operate + /* + LD_TYPE_GROUPS: { + article: [ + 'Article', + 'NewsArticle', + 'ReportageNewsArticle', + 'AnalysisNewsArticle', + 'AskPublicNewsArticle', + 'BackgroundNewsArticle', + 'OpinionNewsArticle' + ] + } + */ + // WHITELIST_WILDCARD, if present, will be added to whitelist as record for top level domain: "*" // with it, you can define what parsers do when they run accross unknown publisher. // If absent or empty, all generic media parsers will be disabled except for known domains diff --git a/lib/utils.js b/lib/utils.js index 77c117541..8bdba4425 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -494,7 +494,7 @@ export function parseJSONSource(text, decode) { return JSON.parse(s); }; -export function parseLDSource(ld, decode, uri) { +export function parseLDSource(ld, decode, uri) { if (typeof ld === 'string') { try { @@ -505,7 +505,7 @@ export function parseLDSource(ld, decode, uri) { } } - if (!ld) return; + if (!ld) return; if (!(ld instanceof Array)) { if (!ld['@type'] && ld['@graph'] && Array.isArray(ld['@graph'])) { @@ -515,58 +515,90 @@ export function parseLDSource(ld, decode, uri) { } } - var ldParsed; + const ldParsed = {}; + const entities = {}; - const addObject = function(obj) { + const getName = function(type) { + if (!type) return '-'; - const pushObj = function(id, obj) { - if (id) { + let name = String(type).toLowerCase().replace(/[^a-z0-9]/g, ''); + if (CONFIG.LD_TYPE_GROUPS) { + const group = Object.keys(CONFIG.LD_TYPE_GROUPS).find(group => { + return CONFIG.LD_TYPE_GROUPS[group].some( + type => name === type.toLowerCase() || name.endsWith(type.toLowerCase()) + ); + }) + if (group) { + name = group; + } + } + return name; + } - if (!ldParsed) { - ldParsed = {}; - } + const pushObj = function(name, obj) { + if (name) { - if (!ldParsed[id]) { - ldParsed[id] = obj; - } else { - if (!Array.isArray(ldParsed[id])) { - ldParsed[id] = [ldParsed[id]]; - } - ldParsed[id].push(obj); + if (!ldParsed) { + ldParsed = {}; + } + + if (!ldParsed[name]) { + ldParsed[name] = obj; + + } else { + if (!Array.isArray(ldParsed[name])) { + ldParsed[name] = [ldParsed[name]]; } - } + ldParsed[name].push(obj); + } + } + }; + + const addObject = function(obj) { + + if (!obj || !obj['@type']) { + return; } - if (Array.isArray(obj['@type'])) { - for (var i = 0; i < obj['@type'].length; i++) { - var type = obj['@type'][i]; - pushObj(type && type.toLowerCase && type.toLowerCase(), obj); - } - } else { - var type = obj && obj['@type']; - pushObj(type && type.toLowerCase && type.toLowerCase(), obj); + const type = Array.isArray(obj['@type']) ? obj['@type'][0] : obj['@type']; + const name = getName(type); + + pushObj(name, obj); + + // reverse map + if (!entities[type]) { + entities[type] = name; } }; - for (var i = 0; i < ld.length; i++) { + for (let i = 0; i < ld.length; i++) { try { - var str = ld[i]; - var obj = typeof str === 'string' ? parseJSONSource(str, decode) : str; + const str = ld[i]; + const obj = typeof str === 'string' ? parseJSONSource(str, decode) : str; if (Array.isArray(obj)) { - for(var j = 0; j < obj.length; j++) { + for(let j = 0; j < obj.length; j++) { addObject(obj[j]); } } else { addObject(obj); } - + } catch (ex) { log(' -- Error parsing ld-json', uri, ex.message); } } if (ldParsed) { + if (Object.keys(entities).length > 0) { + ldParsed['@entities'] = []; + Object.keys(entities).forEach(type => { + ldParsed['@entities'].push({ + '@type': type, + see: entities[type] + }) + }) + } return ldParsed; } }; From 95eb59b32e17aadd1f7f5db2049715825631ddd3 Mon Sep 17 00:00:00 2001 From: Ivan Paramonau Date: Tue, 21 Jul 2026 14:49:54 -0400 Subject: [PATCH 02/11] review the use of ld objects --- config.js | 1 + .../facebook.com/facebook.thumbnail.js | 5 +-- plugins/meta/ld-article-keywords.js | 4 +-- plugins/meta/ld-article.js | 31 ++++++++++++------- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/config.js b/config.js index 0e42e379a..903dceaab 100644 --- a/config.js +++ b/config.js @@ -136,6 +136,7 @@ og: "og", twitter: "twitter", oembed: "oembed", + ld: "ld", icon: "icon", logo: "logo", diff --git a/plugins/domains/facebook.com/facebook.thumbnail.js b/plugins/domains/facebook.com/facebook.thumbnail.js index a8e18318a..dd32d7e1b 100644 --- a/plugins/domains/facebook.com/facebook.thumbnail.js +++ b/plugins/domains/facebook.com/facebook.thumbnail.js @@ -15,10 +15,7 @@ export default { getLink: function(url, __allowFBThumbnail, options, meta) { var thumbnail = meta.twitter?.image - || meta.og?.image - || meta.ld?.socialmediaposting?.image?.contenturl - || meta.ld?.socialmediaposting?.image && Array.isArray(meta.ld.socialmediaposting.image) // This one is for photos - && meta.ld.socialmediaposting.image.length === 1 && meta.ld.socialmediaposting.image[0].contenturl; + || meta.og?.image; if (thumbnail?.url || thumbnail?.src) { thumbnail = thumbnail.url || thumbnail.src; diff --git a/plugins/meta/ld-article-keywords.js b/plugins/meta/ld-article-keywords.js index d77b6c4a0..4e469478c 100644 --- a/plugins/meta/ld-article-keywords.js +++ b/plugins/meta/ld-article-keywords.js @@ -2,9 +2,9 @@ export default { getMeta: function(ld) { - if (ld.newsarticle && ld.newsarticle.keywords && ld.newsarticle.keywords instanceof Array) { + if (ld.article?.keywords && ld.article.keywords instanceof Array) { return { - keywords: ld.newsarticle.keywords.join(', ') + keywords: ld.article.keywords.join(', ') } } } diff --git a/plugins/meta/ld-article.js b/plugins/meta/ld-article.js index 418169b29..69807587c 100644 --- a/plugins/meta/ld-article.js +++ b/plugins/meta/ld-article.js @@ -14,27 +14,34 @@ export default { } } - if (ld.newsarticle) { + if (ld.article) { return { - title: clean(ld.newsarticle.headline), - category: clean(ld.newsarticle.articlesection), - description: clean(ld.newsarticle.description) + title: clean(ld.article.headline), + category: clean(ld.article.articlesection), + description: clean(ld.article.description) } } }, getLink: function(ld) { - if (ld.newsarticle && ld.newsarticle.thumbnailurl) { - return { - href: ld.newsarticle.thumbnailurl, - type: CONFIG.T.image, - rel: CONFIG.R.thumbnail - } + if (ld.article?.image) { + const images = Array.isArray(ld.article.image) ? ld.article.image : [ld.article.image] + const links = []; + + images.forEach(image => { + links.push({ + href: image.contenturl || image.url, + type: CONFIG.T.image, + rel: [CONFIG.R.thumbnail, CONFIG.R.ld], + alt: image.caption || image.name + }) + }); + + return links; } } // ex: - // http://www.app.com/story/entertainment/music/2017/03/17/springsteen-legacy-apmff-upstage-film-explores-1970-asbury-park/99313864/ - // https://www.nhl.com/video/oshie-buries-ppg-with-a-backhand/c-51625603?tcid=tw_video_content_id + // https://www.sabah.com.tr/yasam/2019/09/20/son-dakika-tuzladaki-yanginla-ilgili-flas-aciklama }; From 5a71f7bae1914d27118f28af54d40c82226a38b5 Mon Sep 17 00:00:00 2001 From: Ivan Paramonau Date: Wed, 22 Jul 2026 09:41:28 -0400 Subject: [PATCH 03/11] fix typos --- lib/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/utils.js b/lib/utils.js index 8bdba4425..73e6d88a2 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -515,7 +515,7 @@ export function parseLDSource(ld, decode, uri) { } } - const ldParsed = {}; + let ldParsed; const entities = {}; const getName = function(type) { From 2897226e70c554ee70c34b9a013e5bc5a4452191 Mon Sep 17 00:00:00 2001 From: Ivan Paramonau Date: Wed, 22 Jul 2026 21:11:14 -0400 Subject: [PATCH 04/11] review and simplify --- config.js | 18 +++++++++++++++++- lib/utils.js | 28 +++++++--------------------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/config.js b/config.js index 903dceaab..fe598438f 100644 --- a/config.js +++ b/config.js @@ -374,7 +374,23 @@ 'getSignals': 'signals', 'getPolicy': 'policy', 'getContent': 'content', - } + }, + + // Used to (re-)group LD+JSON into buckets + LD_TYPE_ALIASES: { + article: [ + 'Article', + //'BlogPosting', + 'LiveBlogPosting', + 'SocialMediaPosting', + 'Report' + ], + + image: [ + 'ImageObject', + 'Photograph' + ] + } }; // Providers config loader. diff --git a/lib/utils.js b/lib/utils.js index 73e6d88a2..fe8f93133 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -494,7 +494,7 @@ export function parseJSONSource(text, decode) { return JSON.parse(s); }; -export function parseLDSource(ld, decode, uri) { +export function parseLDSource(ld, decode, uri, type_aliases) { if (typeof ld === 'string') { try { @@ -516,20 +516,20 @@ export function parseLDSource(ld, decode, uri) { } let ldParsed; - const entities = {}; const getName = function(type) { if (!type) return '-'; let name = String(type).toLowerCase().replace(/[^a-z0-9]/g, ''); - if (CONFIG.LD_TYPE_GROUPS) { - const group = Object.keys(CONFIG.LD_TYPE_GROUPS).find(group => { - return CONFIG.LD_TYPE_GROUPS[group].some( + const TYPE_ALIASES = type_aliases || CONFIG.LD_TYPE_ALIASES; + if (TYPE_ALIASES) { + const alias = Object.keys(TYPE_ALIASES).find(alias => { + return TYPE_ALIASES[alias].some( type => name === type.toLowerCase() || name.endsWith(type.toLowerCase()) ); }) - if (group) { - name = group; + if (alias) { + name = alias; } } return name; @@ -564,11 +564,6 @@ export function parseLDSource(ld, decode, uri) { const name = getName(type); pushObj(name, obj); - - // reverse map - if (!entities[type]) { - entities[type] = name; - } }; for (let i = 0; i < ld.length; i++) { @@ -590,15 +585,6 @@ export function parseLDSource(ld, decode, uri) { } if (ldParsed) { - if (Object.keys(entities).length > 0) { - ldParsed['@entities'] = []; - Object.keys(entities).forEach(type => { - ldParsed['@entities'].push({ - '@type': type, - see: entities[type] - }) - }) - } return ldParsed; } }; From bbc0ce90295ed6c43a300b4c6e575c0a3c50679b Mon Sep 17 00:00:00 2001 From: Ivan Paramonau Date: Wed, 22 Jul 2026 21:21:56 -0400 Subject: [PATCH 05/11] cleanup --- config.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/config.js b/config.js index fe598438f..16cd00dca 100644 --- a/config.js +++ b/config.js @@ -380,17 +380,16 @@ LD_TYPE_ALIASES: { article: [ 'Article', - //'BlogPosting', + 'BlogPosting', 'LiveBlogPosting', 'SocialMediaPosting', - 'Report' ], image: [ 'ImageObject', 'Photograph' ] - } + } }; // Providers config loader. From 6e11ad4ae6a82ee089072a6d4d330754764679ba Mon Sep 17 00:00:00 2001 From: Ivan Paramonau Date: Wed, 22 Jul 2026 21:51:37 -0400 Subject: [PATCH 06/11] more cleanup --- config.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/config.js b/config.js index 16cd00dca..034fcceec 100644 --- a/config.js +++ b/config.js @@ -379,10 +379,7 @@ // Used to (re-)group LD+JSON into buckets LD_TYPE_ALIASES: { article: [ - 'Article', - 'BlogPosting', - 'LiveBlogPosting', - 'SocialMediaPosting', + 'Article' ], image: [ From cf146e873ee3909bf53fbf6bcdd7a77f8e67496a Mon Sep 17 00:00:00 2001 From: Ivan Paramonau Date: Wed, 22 Jul 2026 22:23:19 -0400 Subject: [PATCH 07/11] clean up example config --- config.local.js.SAMPLE | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/config.local.js.SAMPLE b/config.local.js.SAMPLE index 4b673480d..29bbc0532 100644 --- a/config.local.js.SAMPLE +++ b/config.local.js.SAMPLE @@ -290,21 +290,6 @@ export default { */ }, - // optionally group JSON+LD into buckets so it is easier to operate - /* - LD_TYPE_GROUPS: { - article: [ - 'Article', - 'NewsArticle', - 'ReportageNewsArticle', - 'AnalysisNewsArticle', - 'AskPublicNewsArticle', - 'BackgroundNewsArticle', - 'OpinionNewsArticle' - ] - } - */ - // WHITELIST_WILDCARD, if present, will be added to whitelist as record for top level domain: "*" // with it, you can define what parsers do when they run accross unknown publisher. // If absent or empty, all generic media parsers will be disabled except for known domains From 1c1a1a7f888ad0a7e566ab4d34c39538192c76fc Mon Sep 17 00:00:00 2001 From: Nazar Leush Date: Thu, 23 Jul 2026 15:47:20 +0300 Subject: [PATCH 08/11] fix audit --- audit.log | 49 +++++++++++++++- pnpm-lock.yaml | 134 ++++++++++++++++++++++++++++++++++---------- pnpm-workspace.yaml | 3 + 3 files changed, 156 insertions(+), 30 deletions(-) diff --git a/audit.log b/audit.log index 5c418afc9..364713bdb 100644 --- a/audit.log +++ b/audit.log @@ -1 +1,48 @@ -No known vulnerabilities found +┌─────────────────────┬────────────────────────────────────────────────────────┐ +│ moderate │ js-yaml: YAML merge-key chains can force quadratic CPU │ +│ │ consumption in js-yaml │ +├─────────────────────┼────────────────────────────────────────────────────────┤ +│ Package │ js-yaml │ +├─────────────────────┼────────────────────────────────────────────────────────┤ +│ Vulnerable versions │ >=5.0.0 <=5.1.0 │ +├─────────────────────┼────────────────────────────────────────────────────────┤ +│ Patched versions │ >=5.1.1 │ +├─────────────────────┼────────────────────────────────────────────────────────┤ +│ Paths │ .>node-yaml-config>js-yaml │ +│ │ │ +│ │ .>mocha>js-yaml │ +├─────────────────────┼────────────────────────────────────────────────────────┤ +│ More info │ https://github.com/advisories/GHSA-g796-fgmg-93mv │ +└─────────────────────┴────────────────────────────────────────────────────────┘ +┌─────────────────────┬────────────────────────────────────────────────────────┐ +│ moderate │ js-yaml: Quadratic-complexity (O(n^2)) DoS via !!omap │ +│ │ tag in YAML11_SCHEMA │ +├─────────────────────┼────────────────────────────────────────────────────────┤ +│ Package │ js-yaml │ +├─────────────────────┼────────────────────────────────────────────────────────┤ +│ Vulnerable versions │ >=5.0.0 <=5.2.0 │ +├─────────────────────┼────────────────────────────────────────────────────────┤ +│ Patched versions │ >=5.2.1 │ +├─────────────────────┼────────────────────────────────────────────────────────┤ +│ Paths │ .>node-yaml-config>js-yaml │ +│ │ │ +│ │ .>mocha>js-yaml │ +├─────────────────────┼────────────────────────────────────────────────────────┤ +│ More info │ https://github.com/advisories/GHSA-724g-mxrg-4qvm │ +└─────────────────────┴────────────────────────────────────────────────────────┘ +┌─────────────────────┬────────────────────────────────────────────────────────┐ +│ low │ body-parser vulnerable to denial of service when │ +│ │ invalid limit value silently disables size enforcement │ +├─────────────────────┼────────────────────────────────────────────────────────┤ +│ Package │ body-parser │ +├─────────────────────┼────────────────────────────────────────────────────────┤ +│ Vulnerable versions │ >=2.0.0 <2.3.0 │ +├─────────────────────┼────────────────────────────────────────────────────────┤ +│ Patched versions │ >=2.3.0 │ +├─────────────────────┼────────────────────────────────────────────────────────┤ +│ Paths │ .>mock-http-server>body-parser │ +├─────────────────────┼────────────────────────────────────────────────────────┤ +│ More info │ https://github.com/advisories/GHSA-v422-hmwv-36x6 │ +└─────────────────────┴────────────────────────────────────────────────────────┘ +3 vulnerabilities found +Severity: 1 low | 2 moderate diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0bb481c37..09ed79445 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,11 +19,12 @@ overrides: underscore@<=1.13.7: '>=1.13.8' form-data@>=4.0.0 <4.0.6: '>=4.0.6' js-yaml@<=4.1.1: '>=4.2.0' + brace-expansion@<1.1.16: ^1.1.16 + brace-expansion@>=2.0.0 <2.1.2: ^2.1.2 + brace-expansion@>=3.0.0 <5.0.7: ^5.0.7 patchedDependencies: - readabilitySAX@1.6.1: - hash: 13d40f78c0537e2538fd3a338f5ead833d968e2a80882e92f1eb3580b599c757 - path: patches/readabilitySAX@1.6.1.patch + readabilitySAX@1.6.1: 13d40f78c0537e2538fd3a338f5ead833d968e2a80882e92f1eb3580b599c757 importers: @@ -31,7 +32,7 @@ importers: dependencies: '@adobe/fetch': specifier: ^4.1.11 - version: 4.1.11 + version: 4.1.11(supports-color@8.1.1) async: specifier: ^3.2.4 version: 3.2.4 @@ -55,7 +56,7 @@ importers: version: 1.1.2 express: specifier: ^5.1.0 - version: 5.1.0 + version: 5.1.0(supports-color@8.1.1) got: specifier: ^14.4.4 version: 14.4.5 @@ -131,7 +132,7 @@ importers: version: 8.24.0 supertest: specifier: ^7.1.4 - version: 7.1.4 + version: 7.1.4(supports-color@8.1.1) packages: @@ -242,17 +243,21 @@ packages: resolution: {integrity: sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==} engines: {node: '>=18'} + body-parser@2.3.0: + resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} + engines: {node: '>=18'} + boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - brace-expansion@1.1.14: - resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} + brace-expansion@1.1.16: + resolution: {integrity: sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==} - brace-expansion@2.1.0: - resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==} + brace-expansion@2.1.2: + resolution: {integrity: sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==} - brace-expansion@5.0.6: - resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + brace-expansion@5.0.7: + resolution: {integrity: sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==} engines: {node: 18 || 20 || >=22} browser-stdout@1.3.1: @@ -348,6 +353,10 @@ packages: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} + content-type@2.0.0: + resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==} + engines: {node: '>=18'} + cookie-signature@1.2.2: resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} engines: {node: '>=6.6.0'} @@ -641,6 +650,7 @@ packages: glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} @@ -700,6 +710,10 @@ packages: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + http2-wrapper@2.2.1: resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} engines: {node: '>=10.19.0'} @@ -716,8 +730,13 @@ packages: resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} engines: {node: '>=0.10.0'} + iconv-lite@0.7.3: + resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} + engines: {node: '>=0.10.0'} + inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -803,6 +822,7 @@ packages: lodash.get@4.4.2: resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. lodash.has@4.5.2: resolution: {integrity: sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g==} @@ -1031,6 +1051,7 @@ packages: osenv@0.1.5: resolution: {integrity: sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==} + deprecated: This package is no longer supported. p-cancelable@4.0.1: resolution: {integrity: sha512-wBowNApzd45EIKdO1LaU+LrMBwAcjfPaYtVzV3lmfM3gf8Z4CHZsiIqlM8TZZ8okYvh5A1cP6gTfCRQtwUpaUg==} @@ -1115,6 +1136,10 @@ packages: resolution: {integrity: sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==} engines: {node: '>= 0.10'} + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + readabilitySAX@1.6.1: resolution: {integrity: sha512-Lwu2VN5mM/rvzqxanFID8P7XnoYFn0H37fnQnBeBANRVNJ1TiNJClbambqo2fBMtda/bj//0Shb5MSxTLCtkeQ==} hasBin: true @@ -1216,6 +1241,10 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + stream-parser@0.3.1: resolution: {integrity: sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==} @@ -1269,6 +1298,10 @@ packages: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} + type-is@2.1.0: + resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} + engines: {node: '>= 18'} + uid-safe@2.1.5: resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==} engines: {node: '>= 0.8'} @@ -1347,7 +1380,7 @@ packages: snapshots: - '@adobe/fetch@4.1.11': + '@adobe/fetch@4.1.11(supports-color@8.1.1)': dependencies: debug: 4.4.0(supports-color@8.1.1) http-cache-semantics: 4.1.1 @@ -1450,18 +1483,32 @@ snapshots: transitivePeerDependencies: - supports-color + body-parser@2.3.0: + dependencies: + bytes: 3.1.2 + content-type: 2.0.0 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + on-finished: 2.4.1 + qs: 6.15.2 + raw-body: 3.0.2 + type-is: 2.1.0 + transitivePeerDependencies: + - supports-color + boolbase@1.0.0: {} - brace-expansion@1.1.14: + brace-expansion@1.1.16: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.1.0: + brace-expansion@2.1.2: dependencies: balanced-match: 1.0.2 - brace-expansion@5.0.6: + brace-expansion@5.0.7: dependencies: balanced-match: 4.0.4 @@ -1570,6 +1617,8 @@ snapshots: content-type@1.0.5: {} + content-type@2.0.0: {} + cookie-signature@1.2.2: {} cookie@0.7.2: {} @@ -1739,10 +1788,10 @@ snapshots: exit@0.1.2: {} - express@5.1.0: + express@5.1.0(supports-color@8.1.1): dependencies: accepts: 2.0.0 - body-parser: 2.2.1 + body-parser: 2.3.0 content-disposition: 1.0.0 content-type: 1.0.5 cookie: 0.7.2 @@ -1751,7 +1800,7 @@ snapshots: encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 2.1.0 + finalhandler: 2.1.0(supports-color@8.1.1) fresh: 2.0.0 http-errors: 2.0.0 merge-descriptors: 2.0.0 @@ -1762,7 +1811,7 @@ snapshots: proxy-addr: 2.0.7 qs: 6.15.2 range-parser: 1.2.1 - router: 2.2.0 + router: 2.2.0(supports-color@8.1.1) send: 1.2.0 serve-static: 2.2.0 statuses: 2.0.1 @@ -1801,7 +1850,7 @@ snapshots: transitivePeerDependencies: - supports-color - finalhandler@2.1.0: + finalhandler@2.1.0(supports-color@8.1.1): dependencies: debug: 4.4.0(supports-color@8.1.1) encodeurl: 2.0.0 @@ -1963,6 +2012,14 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + http2-wrapper@2.2.1: dependencies: quick-lru: 5.1.1 @@ -1980,6 +2037,10 @@ snapshots: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.7.3: + dependencies: + safer-buffer: 2.1.2 + inflight@1.0.6: dependencies: once: 1.4.0 @@ -2103,19 +2164,19 @@ snapshots: minimatch@10.2.4: dependencies: - brace-expansion: 5.0.6 + brace-expansion: 5.0.7 minimatch@3.1.5: dependencies: - brace-expansion: 1.1.14 + brace-expansion: 1.1.16 minimatch@5.1.9: dependencies: - brace-expansion: 2.1.0 + brace-expansion: 2.1.2 minimatch@9.0.9: dependencies: - brace-expansion: 2.1.0 + brace-expansion: 2.1.2 minipass@7.1.2: {} @@ -2340,6 +2401,13 @@ snapshots: iconv-lite: 0.7.0 unpipe: 1.0.0 + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.0 + unpipe: 1.0.0 + readabilitySAX@1.6.1(patch_hash=13d40f78c0537e2538fd3a338f5ead833d968e2a80882e92f1eb3580b599c757): dependencies: entities: 0.5.0 @@ -2401,7 +2469,7 @@ snapshots: retry@0.6.0: {} - router@2.2.0: + router@2.2.0(supports-color@8.1.1): dependencies: debug: 4.4.0(supports-color@8.1.1) depd: 2.0.0 @@ -2488,6 +2556,8 @@ snapshots: statuses@2.0.1: {} + statuses@2.0.2: {} + stream-parser@0.3.1: dependencies: debug: 2.6.9 @@ -2512,7 +2582,7 @@ snapshots: strip-json-comments@3.1.1: {} - superagent@10.2.3: + superagent@10.2.3(supports-color@8.1.1): dependencies: component-emitter: 1.3.1 cookiejar: 2.1.4 @@ -2526,10 +2596,10 @@ snapshots: transitivePeerDependencies: - supports-color - supertest@7.1.4: + supertest@7.1.4(supports-color@8.1.1): dependencies: methods: 1.1.2 - superagent: 10.2.3 + superagent: 10.2.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -2555,6 +2625,12 @@ snapshots: media-typer: 1.1.0 mime-types: 3.0.1 + type-is@2.1.0: + dependencies: + content-type: 2.0.0 + media-typer: 1.1.0 + mime-types: 3.0.1 + uid-safe@2.1.5: dependencies: random-bytes: 1.0.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index b7444a981..085c25970 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -13,5 +13,8 @@ overrides: underscore@<=1.13.7: '>=1.13.8' form-data@>=4.0.0 <4.0.6: ">=4.0.6" js-yaml@<=4.1.1: ">=4.2.0" + brace-expansion@<1.1.16: ^1.1.16 + brace-expansion@>=2.0.0 <2.1.2: ^2.1.2 + brace-expansion@>=3.0.0 <5.0.7: ^5.0.7 patchedDependencies: readabilitySAX@1.6.1: patches/readabilitySAX@1.6.1.patch From 9660d9ff0498e37c9c1f354985ecdced06cc5cbf Mon Sep 17 00:00:00 2001 From: Nazar Leush Date: Thu, 23 Jul 2026 16:27:40 +0300 Subject: [PATCH 09/11] package.json: `patchedDependencies` moved to workspace --- package.json | 5 ----- 1 file changed, 5 deletions(-) diff --git a/package.json b/package.json index c3e5ac970..ccdbaa5fe 100644 --- a/package.json +++ b/package.json @@ -67,10 +67,5 @@ }, "engines": { "node": ">=20.19.3" - }, - "pnpm": { - "patchedDependencies": { - "readabilitySAX@1.6.1": "patches/readabilitySAX@1.6.1.patch" - } } } From 27909704541ab74c33f4c04ffb6f23c1db33b898 Mon Sep 17 00:00:00 2001 From: Nazar Leush Date: Thu, 23 Jul 2026 16:32:05 +0300 Subject: [PATCH 10/11] test: update pnpm and node versions to fix test --- .github/workflows/tests.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c404cd17b..dd6d42617 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: - node-version: ['20.x'] + node-version: ['22.x'] steps: - uses: actions/checkout@v4 @@ -17,7 +17,6 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v4 with: - version: 10 run_install: false - name: Use Node.js ${{ matrix.node-version }} From 4c31f6bfa0d80552db73c60f551d058944fd0b8c Mon Sep 17 00:00:00 2001 From: Nazar Leush Date: Thu, 23 Jul 2026 16:35:01 +0300 Subject: [PATCH 11/11] test: update pnpm versions to fix test --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index dd6d42617..8da8c2632 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -17,6 +17,7 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v4 with: + version: 11 run_install: false - name: Use Node.js ${{ matrix.node-version }}