diff --git a/README.md b/README.md index 08e9b29..76f201a 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,15 @@ visitors. (Technically the # and @ in the URL fragment should probably be escaped, but in practice for legibility we bend the rules and include it verbatim) +### Optional parameters + +https://matrix.to/#/#matrix:matrix.org?web-instance[element.io]=chat.mozilla.org + +- `client`, e.g. `client=im.fluffychat`, `client=element.io` +- `web-instance[]`, e.g. `web-instance[element.io]=chat.mozilla.org`. + - For [matrix.to](https://matrix.to/), we have this list of [trusted web instances](https://github.com/matrix-org/matrix.to/blob/260d2b61cdb6b0e4318bc1bd59b4e2deef86d2a5/src/open/clients/Element.js#L20-L25) configured. +- `via`, e.g. `via=mozilla.org` + You can discuss matrix.to in [`#matrix.to:matrix.org`](https://matrix.to/#/#matrix.to:matrix.org) diff --git a/images/client-icons/org.kde.neochat.svg b/images/client-icons/org.kde.neochat.svg new file mode 100644 index 0000000..64d5fc9 --- /dev/null +++ b/images/client-icons/org.kde.neochat.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/package.json b/package.json index a680dac..6892eda 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix.to", - "version": "1.2.12", + "version": "1.2.16", "type": "module", "license": "Apache-2.0", "engines": { diff --git a/scripts/build.js b/scripts/build.js index 5bd584a..1fdb7a2 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -146,7 +146,7 @@ function buildAppleAssociatedAppsFile(clients) { async function buildCss(entryPath, targetDir, assets) { entryPath = path.join(projectDir, entryPath); const assetUrlMapper = ({absolutePath}) => { - const relPath = absolutePath.substr(projectDir.length); + const relPath = absolutePath.slice(projectDir.length); return assets.resolve(path.join(targetDir, relPath)); }; @@ -211,7 +211,7 @@ class AssetMap { if (!resourcePath.startsWith(this._targetDir)) { throw new Error(`absolute path ${resourcePath} that is not within target dir ${this._targetDir}`); } - relPath = resourcePath.substr(this._targetDir.length + 1); // + 1 for the / + relPath = resourcePath.slice(this._targetDir.length + 1); // + 1 for the / } return relPath; } @@ -267,7 +267,7 @@ class AssetMap { if (!assetMap.directory.startsWith(this.directory)) { throw new Error(`map directory doesn't start with this directory: ${assetMap.directory} ${this.directory}`); } - const relSubRoot = assetMap.directory.substr(this.directory.length + 1); + const relSubRoot = assetMap.directory.slice(this.directory.length + 1); for (const [key, value] of assetMap._assets.entries()) { this._assets.set(path.join(relSubRoot, key), path.join(relSubRoot, value)); } diff --git a/src/Link.js b/src/Link.js index 119e6de..623e269 100644 --- a/src/Link.js +++ b/src/Link.js @@ -46,8 +46,8 @@ function getWebInstanceMap(queryParams) { const postfix = "]"; const webInstanceParams = queryParams.filter(([key]) => key.startsWith(prefix) && key.endsWith(postfix)); const webInstances = webInstanceParams.map(([key, value]) => { - const noPrefix = key.substr(prefix.length); - const clientId = noPrefix.substr(0, noPrefix.length - postfix.length); + const noPrefix = key.slice(prefix.length); + const clientId = noPrefix.slice(0, -postfix.length); return [clientId, value]; }); return webInstances.reduce((map, [clientId, host]) => { diff --git a/src/RootViewModel.js b/src/RootViewModel.js index 05a8cd8..32257ce 100644 --- a/src/RootViewModel.js +++ b/src/RootViewModel.js @@ -66,7 +66,7 @@ export class RootViewModel extends ViewModel { this.createLinkViewModel = null; let newLink; if (hash.startsWith("#/policy/")) { - const server = hash.substr(9); + const server = hash.slice(9); this._updateChildVMs(null, oldLink); this.loadServerPolicyViewModel = new LoadServerPolicyViewModel(this.childOptions({server})); this.loadServerPolicyViewModel.load(); diff --git a/src/open/ClientViewModel.js b/src/open/ClientViewModel.js index 3987315..2cd7244 100644 --- a/src/open/ClientViewModel.js +++ b/src/open/ClientViewModel.js @@ -139,7 +139,7 @@ export class ClientViewModel extends ViewModel { let label = preferredWebInstance; const subDomainIdx = preferredWebInstance.lastIndexOf(".", preferredWebInstance.lastIndexOf(".")); if (subDomainIdx !== -1) { - label = preferredWebInstance.substr(preferredWebInstance.length - subDomainIdx + 1); + label = preferredWebInstance.slice(preferredWebInstance.length - subDomainIdx + 1); } return `Hosted by ${label}`; } diff --git a/src/open/clients/Element.js b/src/open/clients/Element.js index 0d54946..d0d5e24 100644 --- a/src/open/clients/Element.js +++ b/src/open/clients/Element.js @@ -52,18 +52,23 @@ export class Element { let fragmentPath; switch (link.kind) { case LinkKind.User: - fragmentPath = `user/${link.identifier}`; + fragmentPath = `user/${encodeURIComponent(link.identifier)}`; break; case LinkKind.Room: - fragmentPath = `room/${link.identifier}`; + fragmentPath = `room/${encodeURIComponent(link.identifier)}`; break; case LinkKind.Group: - fragmentPath = `group/${link.identifier}`; + fragmentPath = `group/${encodeURIComponent(link.identifier)}`; break; case LinkKind.Event: - fragmentPath = `room/${link.identifier}/${link.eventId}`; + fragmentPath = `room/${encodeURIComponent(link.identifier)}/${encodeURIComponent(link.eventId)}`; break; } + + if ((link.kind === LinkKind.Event || link.kind === LinkKind.Room) && link.servers.length > 0) { + fragmentPath += '?' + link.servers.map(server => `via=${encodeURIComponent(server)}`).join('&'); + } + const isWebPlatform = platform === Platform.DesktopWeb || platform === Platform.MobileWeb; if (isWebPlatform || platform === Platform.iOS) { let instanceHost = trustedWebInstances[0]; diff --git a/src/open/clients/Fluffychat.js b/src/open/clients/Fluffychat.js index 9955c6a..baa0cdc 100644 --- a/src/open/clients/Fluffychat.js +++ b/src/open/clients/Fluffychat.js @@ -11,7 +11,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Maturity, Platform, LinkKind, FlathubLink, AppleStoreLink, PlayStoreLink, WebsiteLink } from "../types.js"; +import { Maturity, Platform, LinkKind, FlathubLink, AppleStoreLink, PlayStoreLink, FDroidLink, WebsiteLink } from "../types.js"; /** * Information on how to deep link to a given matrix client. @@ -44,8 +44,14 @@ export class Fluffychat { getInstallLinks(platform) { switch (platform) { case Platform.iOS: return [new AppleStoreLink("fluffychat", "id1551469600")]; - case Platform.Android: return [new PlayStoreLink("chat.fluffy.fluffychat")]; - case Platform.Linux: return [new FlathubLink("im.fluffychat.Fluffychat")]; + case Platform.Android: return [ + new PlayStoreLink("chat.fluffy.fluffychat"), + new FDroidLink('chat.fluffy.fluffychat'), + ]; + case Platform.Linux: return [ + new FlathubLink("im.fluffychat.Fluffychat"), + new WebsiteLink("https://fluffychat.im"), + ]; default: return [new WebsiteLink("https://fluffychat.im")]; } } @@ -73,7 +79,13 @@ export class Fluffychat { } } - getDeepLink(platform, link) { } + getDeepLink(platform, link) { + switch (platform) { + case Platform.Android: return `im.fluffychat://chat/${link.identifier}`; + case Platform.iOS: return `im.fluffychat://chat/${link.identifier}`; + default: break; + } + } canInterceptMatrixToLinks(platform) { return platform === Platform.Android; } diff --git a/src/open/clients/NeoChat.js b/src/open/clients/NeoChat.js new file mode 100644 index 0000000..2e43a11 --- /dev/null +++ b/src/open/clients/NeoChat.js @@ -0,0 +1,79 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. +Copyright 2021 Carl Schwan + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import {Maturity, Platform, LinkKind, FlathubLink, style} from "../types.js"; + +export class NeoChat { + get id() { return "neochat"; } + get name() { return "NeoChat"; } + get icon() { return "images/client-icons/org.kde.neochat.svg"; } + get author() { return "Tobias Fella and Carl Schwan"; } + get homepage() { return "https://apps.kde.org/neochat/"; } + get platforms() { return [Platform.Linux]; } + get description() { return 'NeoChat is a convergent, cross-platform Matrix client.'; } + getMaturity(platform) { return Maturity.Beta; } + getDeepLink(platform, link) { + if (platform === Platform.Linux || platform === Platform.Windows) { + let identifier = encodeURIComponent(link.identifier.substring(1)); + let isRoomid = link.identifier.substring(0, 1) === '!'; + let fragmentPath; + switch (link.kind) { + case LinkKind.User: + fragmentPath = `u/${identifier}?action=chat`; + break; + case LinkKind.Room: + case LinkKind.Event: + if (isRoomid) + fragmentPath = `roomid/${identifier}`; + else + fragmentPath = `r/${identifier}`; + + if (link.kind === LinkKind.Event) + fragmentPath += `/e/${encodeURIComponent(link.eventId.substring(1))}`; + fragmentPath += '?action=join'; + fragmentPath += link.servers.map(server => `&via=${encodeURIComponent(server)}`).join(''); + break; + case LinkKind.Group: + return; + } + return `matrix:${fragmentPath}`; + } + } + canInterceptMatrixToLinks(platform) { return false; } + + getLinkInstructions(platform, link) { + switch (link.kind) { + case LinkKind.User: return [`Type `, style.code(`/invite ${link.identifier}`)]; + case LinkKind.Room: return [`Type `, style.code(`/join ${link.identifier}`)]; + } + } + + getCopyString(platform, link) { + switch (link.kind) { + case LinkKind.User: return `/invite ${link.identifier}`; + case LinkKind.Room: return `/join ${link.identifier}`; + } + } + + getInstallLinks(platform) { + if (platform === Platform.Linux) { + return [new FlathubLink("org.kde.neochat")]; + } + } + + getPreferredWebInstance(link) {} +} diff --git a/src/open/clients/Nheko.js b/src/open/clients/Nheko.js index c2e3ab0..e861526 100644 --- a/src/open/clients/Nheko.js +++ b/src/open/clients/Nheko.js @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {Maturity, Platform, LinkKind, FlathubLink, style} from "../types.js"; +import {Maturity, Platform, LinkKind, FlathubLink, WebsiteLink, style} from "../types.js"; /** * Information on how to deep link to a given matrix client. @@ -72,8 +72,12 @@ export class Nheko { } getInstallLinks(platform) { - if (platform === Platform.Linux) { - return [new FlathubLink("io.github.NhekoReborn.Nheko")]; + switch (platform) { + case Platform.Linux: return [ + new FlathubLink("io.github.NhekoReborn.Nheko"), + new WebsiteLink("https://github.com/Nheko-Reborn/nheko/releases/latest"), + ]; + default: return [new WebsiteLink("https://github.com/Nheko-Reborn/nheko/releases/latest")]; } } diff --git a/src/open/clients/Quaternion.js b/src/open/clients/Quaternion.js index 0240821..f04a98a 100644 --- a/src/open/clients/Quaternion.js +++ b/src/open/clients/Quaternion.js @@ -14,14 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {Maturity, Platform, LinkKind, FlathubLink, style} from "../types.js"; +import {Maturity, Platform, LinkKind, FlathubLink, WebsiteLink, style} from "../types.js"; export class Quaternion { get id() { return "quaternion"; } get name() { return "Quaternion"; } get icon() { return "images/client-icons/quaternion.svg"; } - get author() { return "Felix Rohrbach"; } - get homepage() { return "https://github.com/Fxrh/Quaternion"; } + get author() { return "The Quotient project"; } + get homepage() { return "https://github.com/quotient-im/Quaternion"; } get platforms() { return [Platform.Windows, Platform.macOS, Platform.Linux]; } get description() { return 'Qt5 and C++ cross-platform desktop Matrix client.'; } getMaturity(platform) { return Maturity.Beta; } @@ -43,8 +43,12 @@ export class Quaternion { } getInstallLinks(platform) { - if (platform === Platform.Linux) { - return [new FlathubLink("com.github.quaternion")]; + switch (platform) { + case Platform.Linux: return [ + new FlathubLink("com.github.quaternion"), + new WebsiteLink("https://github.com/quotient-im/Quaternion/releases/latest"), + ]; + default: return [new WebsiteLink("https://github.com/quotient-im/Quaternion/releases/latest")]; } } diff --git a/src/open/clients/index.js b/src/open/clients/index.js index 44acee2..364bbc6 100644 --- a/src/open/clients/index.js +++ b/src/open/clients/index.js @@ -21,6 +21,7 @@ import {Fractal} from "./Fractal.js"; import {Quaternion} from "./Quaternion.js"; import {Tensor} from "./Tensor.js"; import {Fluffychat} from "./Fluffychat.js"; +import {NeoChat} from "./NeoChat.js"; export function createClients() { return [ @@ -31,5 +32,6 @@ export function createClients() { new Quaternion(), new Tensor(), new Fluffychat(), + new NeoChat(), ]; } diff --git a/src/preview/HomeServer.js b/src/preview/HomeServer.js index 964e1e7..a9a9a67 100644 --- a/src/preview/HomeServer.js +++ b/src/preview/HomeServer.js @@ -15,7 +15,7 @@ limitations under the License. */ function noTrailingSlash(url) { - return url.endsWith("/") ? url.substr(0, url.length - 1) : url; + return url.endsWith("/") ? url.slice(0, -1) : url; } export async function resolveServer(request, baseURL) { @@ -123,7 +123,7 @@ export class HomeServer { function parseMxcUrl(url) { const prefix = "mxc://"; if (url.startsWith(prefix)) { - return url.substr(prefix.length).split("/", 2); + return url.slice(prefix.length).split("/", 2); } else { return null; } diff --git a/src/utils/TemplateView.js b/src/utils/TemplateView.js index 349907c..547dd25 100644 --- a/src/utils/TemplateView.js +++ b/src/utils/TemplateView.js @@ -210,7 +210,7 @@ class TemplateBuilder { setAttribute(node, key, classNames(value)); } } else if (key.startsWith("on") && key.length > 2 && isFn) { - const eventName = key.substr(2, 1).toLowerCase() + key.substr(3); + const eventName = key.slice(2, 3).toLowerCase() + key.slice(3); const handler = value; this._templateView._addEventListener(node, eventName, handler); } else if (isFn) { diff --git a/yarn.lock b/yarn.lock index 9151b4d..649231e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -815,6 +815,46 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@jridgewell/gen-mapping@^0.3.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" + integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.14" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@rollup/plugin-babel@^5.1.0": version "5.2.2" resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.2.2.tgz#e5623a01dd8e37e004ba87f2de218c611727d9b2" @@ -900,6 +940,11 @@ dependencies: "@types/node" "*" +acorn@^8.5.0: + version "8.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" + integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -956,9 +1001,9 @@ browserslist@^4.14.5, browserslist@^4.15.0: node-releases "^1.1.71" buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== builtin-modules@^3.1.0: version "3.1.0" @@ -1852,10 +1897,10 @@ source-map-js@^0.6.2: resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== -source-map-support@~0.5.19: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -1870,11 +1915,6 @@ source-map@^0.6.0, source-map@^0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@~0.7.2: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== - sourcemap-codec@^1.4.4: version "1.4.8" resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" @@ -1914,13 +1954,14 @@ supports-color@^7.0.0: has-flag "^4.0.0" terser@^5.0.0: - version "5.5.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.5.1.tgz#540caa25139d6f496fdea056e414284886fb2289" - integrity sha512-6VGWZNVP2KTUcltUQJ25TtNjx/XgdDsBDKGt8nN0MpydU36LmbPPcMBd2kmtZNNGVVDLg44k7GKeHHj+4zPIBQ== + version "5.14.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" + integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" commander "^2.20.0" - source-map "~0.7.2" - source-map-support "~0.5.19" + source-map-support "~0.5.20" to-fast-properties@^2.0.0: version "2.0.0"