mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-25 03:44:29 +03:00
Added URL transform for image cards in Lexical documents (#15890)
refs https://github.com/TryGhost/Team/issues/2225 - updated the `formatOnWrite` transform map for posts to include the new `nodes` and `transformMap` options used by `urlUtils` for transforming node payload data - added `nodes` to the `lexicalLib` module that pulls in our default nodes to be passed in to the URL transform utilities - added `urlTransformMap` to the `lexicalLib` module that maps transform type and data type to URL transform utility functions that accept a single URL argument
This commit is contained in:
parent
86abab4f1d
commit
457c672c6a
@ -1,4 +1,8 @@
|
||||
const urlUtils = require('../../shared/url-utils');
|
||||
|
||||
let nodes;
|
||||
let lexicalHtmlRenderer;
|
||||
let urlTransformMap;
|
||||
|
||||
module.exports = {
|
||||
get lexicalHtmlRenderer() {
|
||||
@ -8,5 +12,38 @@ module.exports = {
|
||||
}
|
||||
|
||||
return lexicalHtmlRenderer;
|
||||
},
|
||||
|
||||
get nodes() {
|
||||
if (!nodes) {
|
||||
const {DEFAULT_NODES} = require('@tryghost/kg-default-nodes');
|
||||
nodes = DEFAULT_NODES;
|
||||
}
|
||||
|
||||
return nodes;
|
||||
},
|
||||
|
||||
get urlTransformMap() {
|
||||
if (!urlTransformMap) {
|
||||
urlTransformMap = {
|
||||
absoluteToRelative: {
|
||||
url: urlUtils.absoluteToRelative.bind(urlUtils),
|
||||
html: urlUtils.htmlAbsoluteToRelative.bind(urlUtils),
|
||||
markdown: urlUtils.markdownAbsoluteToRelative.bind(urlUtils)
|
||||
},
|
||||
relativeToAbsolute: {
|
||||
url: urlUtils.relativeToAbsolute.bind(urlUtils),
|
||||
html: urlUtils.htmlRelativeToAbsolute.bind(urlUtils),
|
||||
markdown: urlUtils.markdownRelativeToAbsolute.bind(urlUtils)
|
||||
},
|
||||
toTransformReady: {
|
||||
url: urlUtils.toTransformReady.bind(urlUtils),
|
||||
html: urlUtils.htmlToTransformReady.bind(urlUtils),
|
||||
markdown: urlUtils.markdownToTransformReady.bind(urlUtils)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return urlTransformMap;
|
||||
}
|
||||
};
|
||||
|
@ -180,7 +180,13 @@ Post = ghostBookshelf.Model.extend({
|
||||
cardTransformers: mobiledocLib.cards
|
||||
}
|
||||
},
|
||||
lexical: 'lexicalToTransformReady',
|
||||
lexical: {
|
||||
method: 'lexicalToTransformReady',
|
||||
options: {
|
||||
nodes: lexicalLib.nodes,
|
||||
transformMap: lexicalLib.urlTransformMap
|
||||
}
|
||||
},
|
||||
html: 'htmlToTransformReady',
|
||||
plaintext: 'plaintextToTransformReady',
|
||||
custom_excerpt: 'htmlToTransformReady',
|
||||
|
@ -86,6 +86,7 @@
|
||||
"@tryghost/kg-card-factory": "3.1.7",
|
||||
"@tryghost/kg-default-atoms": "3.1.4",
|
||||
"@tryghost/kg-default-cards": "5.18.5",
|
||||
"@tryghost/kg-default-nodes": "0.0.1",
|
||||
"@tryghost/kg-lexical-html-renderer": "0.0.11",
|
||||
"@tryghost/kg-mobiledoc-html-renderer": "5.3.9",
|
||||
"@tryghost/limit-service": "1.2.3",
|
||||
@ -128,7 +129,7 @@
|
||||
"@tryghost/tiers": "0.0.0",
|
||||
"@tryghost/tpl": "0.1.19",
|
||||
"@tryghost/update-check-service": "0.0.0",
|
||||
"@tryghost/url-utils": "4.2.0",
|
||||
"@tryghost/url-utils": "4.3.0",
|
||||
"@tryghost/validator": "0.1.29",
|
||||
"@tryghost/verification-trigger": "0.0.0",
|
||||
"@tryghost/version": "0.1.16",
|
||||
|
@ -1190,15 +1190,15 @@ describe('Post Model', function () {
|
||||
it('stores lexical as transform-ready and reads as absolute', async function () {
|
||||
const post = {
|
||||
title: 'Absolute->Transform-ready Lexical URL Transform Test',
|
||||
lexical: `{"root":{"children":[{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"local link","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"url":"http://127.0.0.1:2369/local"}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"external link","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"url":"https://example.com/external"}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}`
|
||||
lexical: `{"root":{"children":[{"type":"image","src":"http://127.0.0.1:2369/content/images/card.jpg"},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"local link","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"url":"http://127.0.0.1:2369/local"}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"external link","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"url":"https://example.com/external"}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}`
|
||||
};
|
||||
|
||||
const createdPost = await models.Post.add(post, context);
|
||||
createdPost.get('lexical').should.equal(`{"root":{"children":[{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"local link","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"url":"http://127.0.0.1:2369/local"}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"external link","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"url":"https://example.com/external"}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}`, 'Post.add result');
|
||||
createdPost.get('lexical').should.equal(`{"root":{"children":[{"type":"image","src":"http://127.0.0.1:2369/content/images/card.jpg"},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"local link","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"url":"http://127.0.0.1:2369/local"}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"external link","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"url":"https://example.com/external"}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}`, 'Post.add result');
|
||||
|
||||
const knexResult = await db.knex('posts').where({id: createdPost.id});
|
||||
const [knexPost] = knexResult;
|
||||
knexPost.lexical.should.equal('{"root":{"children":[{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"local link","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"url":"__GHOST_URL__/local"}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"external link","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"url":"https://example.com/external"}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}', 'knex result');
|
||||
knexPost.lexical.should.equal('{"root":{"children":[{"type":"image","src":"__GHOST_URL__/content/images/card.jpg"},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"local link","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"url":"__GHOST_URL__/local"}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1},{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"external link","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"link","version":1,"rel":null,"target":null,"url":"https://example.com/external"}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}', 'knex result');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -9,5 +9,37 @@ describe('lib/lexical', function () {
|
||||
lexicalLib.lexicalHtmlRenderer.render(lexical)
|
||||
.should.eql('<p>Lexical is <strong><em>rendering.</em></strong></p>');
|
||||
});
|
||||
|
||||
it('renders all default cards', function () {
|
||||
const lexicalState = JSON.stringify({
|
||||
root: {
|
||||
children: [
|
||||
{
|
||||
type: 'image',
|
||||
cardWidth: 'wide',
|
||||
src: '/content/images/2018/04/NatGeo06.jpg',
|
||||
width: 4000,
|
||||
height: 2000,
|
||||
caption: 'Birdies'
|
||||
}
|
||||
],
|
||||
direction: null,
|
||||
format: '',
|
||||
indent: 0,
|
||||
type: 'root',
|
||||
version: 1
|
||||
}
|
||||
});
|
||||
|
||||
lexicalLib.lexicalHtmlRenderer.render(lexicalState)
|
||||
.should.eql(`
|
||||
<figure class="kg-card kg-image-card kg-width-wide">
|
||||
<img src="/content/images/2018/04/NatGeo06.jpg" alt="" />
|
||||
<figcaption>
|
||||
Birdies
|
||||
</figcaption>
|
||||
</figure>
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
93
yarn.lock
93
yarn.lock
@ -4429,6 +4429,14 @@
|
||||
lodash "^4.17.21"
|
||||
luxon "^2.1.1"
|
||||
|
||||
"@tryghost/kg-default-nodes@0.0.1":
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/kg-default-nodes/-/kg-default-nodes-0.0.1.tgz#1d0d3b05aaaf99d016d1560c5d6b49538c604bf0"
|
||||
integrity sha512-u+UJ/wxEMhiNlvRXZBp92nHj5PTgqrcja73HoA1S5WDOu97+8dZvAmGxhRHHHEY5VNGHEA0cXxi8S7owL9FUMg==
|
||||
dependencies:
|
||||
jsdom "^20.0.3"
|
||||
lexical "^0.6.0"
|
||||
|
||||
"@tryghost/kg-lexical-html-renderer@0.0.11":
|
||||
version "0.0.11"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/kg-lexical-html-renderer/-/kg-lexical-html-renderer-0.0.11.tgz#0f4636660be9866cf5f030cc6a435ad958e8804b"
|
||||
@ -4444,11 +4452,11 @@
|
||||
lexical "^0.5.0"
|
||||
|
||||
"@tryghost/kg-markdown-html-renderer@^5.1.9":
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/kg-markdown-html-renderer/-/kg-markdown-html-renderer-5.1.9.tgz#cb043705fb3cb140aef8577f87237cc82277ee15"
|
||||
integrity sha512-HPziXC+qdqzpXi8K00GGZg0U3suJAm1Z4mmiWDFDc5BkDO0Dlrl+whOXbmmev+XIsZgr6sOje/uMO9fbAefZuA==
|
||||
version "5.1.11"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/kg-markdown-html-renderer/-/kg-markdown-html-renderer-5.1.11.tgz#c0aa728bc2ec518cefa69353211bdb866f70090d"
|
||||
integrity sha512-mMQmQbO5/l5vVfiKiqlq0Y81wPX83AdSXPEq5GcAklq8E9q1ITpVtIZKC0KGrnQNiuledGOTP6wf2t5tyjgTLg==
|
||||
dependencies:
|
||||
"@tryghost/kg-utils" "^1.0.6"
|
||||
"@tryghost/kg-utils" "^1.0.8"
|
||||
markdown-it "^12.2.0"
|
||||
markdown-it-footnote "^3.0.3"
|
||||
markdown-it-image-lazy-loading "^1.1.0"
|
||||
@ -4479,6 +4487,13 @@
|
||||
dependencies:
|
||||
semver "^7.3.5"
|
||||
|
||||
"@tryghost/kg-utils@^1.0.8":
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/kg-utils/-/kg-utils-1.0.8.tgz#305897a7199cc32062e5db1ef54f8ad33ba45755"
|
||||
integrity sha512-uO8WDFG8Q2VQ6LCAa2oAryavxFLcewMeXAoQ2PCj+oJZ/MiUjmUeTPEHnQV9TjlHyoriWyhz51PBFvlegjSxRw==
|
||||
dependencies:
|
||||
semver "^7.3.5"
|
||||
|
||||
"@tryghost/limit-service@1.2.3":
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/limit-service/-/limit-service-1.2.3.tgz#161acc62f180a47b2a326562a657f0b6c6dd96c0"
|
||||
@ -4665,7 +4680,19 @@
|
||||
dependencies:
|
||||
lodash.template "^4.5.0"
|
||||
|
||||
"@tryghost/url-utils@4.2.0", "@tryghost/url-utils@^4.0.0":
|
||||
"@tryghost/url-utils@4.3.0":
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/url-utils/-/url-utils-4.3.0.tgz#f276ea0963f34547dca8f8f8a6c7bd4e6d4bb6e3"
|
||||
integrity sha512-DtsCVFytzkB6pE3azrO8PVP4wzwLR6Mjljy0ckwgvC7hj7bKM1QeGpCIasPNIKF+mTo/U9dXYadSVs1oGod1rA==
|
||||
dependencies:
|
||||
cheerio "^0.22.0"
|
||||
moment "^2.27.0"
|
||||
moment-timezone "^0.5.31"
|
||||
remark "^11.0.2"
|
||||
remark-footnotes "^1.0.0"
|
||||
unist-util-visit "^2.0.0"
|
||||
|
||||
"@tryghost/url-utils@^4.0.0":
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/url-utils/-/url-utils-4.2.0.tgz#342c73c840dda4f2ba2316fc581167404e219554"
|
||||
integrity sha512-ipeGBj6CJau/17J+M1t2vUJvdptoTnCPVgph2mbKGclOEdAMv9h3/S15cNMnxIqoSNURAvwMKD+QxkOboM/7zg==
|
||||
@ -5741,6 +5768,11 @@ acorn@^8.1.0, acorn@^8.2.4, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0:
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8"
|
||||
integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==
|
||||
|
||||
acorn@^8.8.1:
|
||||
version "8.8.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73"
|
||||
integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==
|
||||
|
||||
address@^1.0.1, address@^1.1.2:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/address/-/address-1.2.1.tgz#25bb61095b7522d65b357baa11bc05492d4c8acd"
|
||||
@ -10301,7 +10333,7 @@ decamelize@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837"
|
||||
integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==
|
||||
|
||||
decimal.js@^10.2.1, decimal.js@^10.4.1:
|
||||
decimal.js@^10.2.1, decimal.js@^10.4.1, decimal.js@^10.4.2:
|
||||
version "10.4.2"
|
||||
resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.2.tgz#0341651d1d997d86065a2ce3a441fbd0d8e8b98e"
|
||||
integrity sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==
|
||||
@ -17231,6 +17263,38 @@ jsdom@^20.0.0, jsdom@~20.0.0:
|
||||
ws "^8.9.0"
|
||||
xml-name-validator "^4.0.0"
|
||||
|
||||
jsdom@^20.0.3:
|
||||
version "20.0.3"
|
||||
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-20.0.3.tgz#886a41ba1d4726f67a8858028c99489fed6ad4db"
|
||||
integrity sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==
|
||||
dependencies:
|
||||
abab "^2.0.6"
|
||||
acorn "^8.8.1"
|
||||
acorn-globals "^7.0.0"
|
||||
cssom "^0.5.0"
|
||||
cssstyle "^2.3.0"
|
||||
data-urls "^3.0.2"
|
||||
decimal.js "^10.4.2"
|
||||
domexception "^4.0.0"
|
||||
escodegen "^2.0.0"
|
||||
form-data "^4.0.0"
|
||||
html-encoding-sniffer "^3.0.0"
|
||||
http-proxy-agent "^5.0.0"
|
||||
https-proxy-agent "^5.0.1"
|
||||
is-potential-custom-element-name "^1.0.1"
|
||||
nwsapi "^2.2.2"
|
||||
parse5 "^7.1.1"
|
||||
saxes "^6.0.0"
|
||||
symbol-tree "^3.2.4"
|
||||
tough-cookie "^4.1.2"
|
||||
w3c-xmlserializer "^4.0.0"
|
||||
webidl-conversions "^7.0.0"
|
||||
whatwg-encoding "^2.0.0"
|
||||
whatwg-mimetype "^3.0.0"
|
||||
whatwg-url "^11.0.0"
|
||||
ws "^8.11.0"
|
||||
xml-name-validator "^4.0.0"
|
||||
|
||||
jsesc@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
|
||||
@ -17654,6 +17718,11 @@ lexical@^0.5.0:
|
||||
resolved "https://registry.yarnpkg.com/lexical/-/lexical-0.5.0.tgz#03a8abc816f6d922384ecd01bd14ed36a1ea4d63"
|
||||
integrity sha512-J0cFuNPQQY5P9W5XW2/xgqp5W0eEQ2rxShLf8eevLvxFWsPSY3zjg3RCzTHyheSiGBBjKDIaM4gxtO8eNeJr2A==
|
||||
|
||||
lexical@^0.6.0:
|
||||
version "0.6.4"
|
||||
resolved "https://registry.yarnpkg.com/lexical/-/lexical-0.6.4.tgz#00f5070a967fd1410aaa7d4c928f6e61af73c604"
|
||||
integrity sha512-QBJEowv2FRkanu9V4HxCiR/V0rECt98zUeHsaYcgUCphrxbZseQgk8AO5UbHJMgAD4iQ0CCKZWbiqbv7Z8tYnw==
|
||||
|
||||
liftoff@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3"
|
||||
@ -26121,6 +26190,13 @@ w3c-xmlserializer@^3.0.0:
|
||||
dependencies:
|
||||
xml-name-validator "^4.0.0"
|
||||
|
||||
w3c-xmlserializer@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz#aebdc84920d806222936e3cdce408e32488a3073"
|
||||
integrity sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==
|
||||
dependencies:
|
||||
xml-name-validator "^4.0.0"
|
||||
|
||||
walk-sync@3.0.0, walk-sync@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/walk-sync/-/walk-sync-3.0.0.tgz#67f882925021e20569a1edd560b8da31da8d171c"
|
||||
@ -26823,6 +26899,11 @@ ws@^7.4.6:
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591"
|
||||
integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==
|
||||
|
||||
ws@^8.11.0:
|
||||
version "8.11.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143"
|
||||
integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==
|
||||
|
||||
ws@^8.4.2, ws@^8.9.0:
|
||||
version "8.9.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.9.0.tgz#2a994bb67144be1b53fe2d23c53c028adeb7f45e"
|
||||
|
Loading…
Reference in New Issue
Block a user