mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Remove last usages of request in our code (#6911)
* Improve the injectability of cluster metadata detection - Remove unnecessary and complex base class Signed-off-by: Sebastian Malton <sebastian@malton.name> * Remove dead code Signed-off-by: Sebastian Malton <sebastian@malton.name> * Remove dead code Signed-off-by: Sebastian Malton <sebastian@malton.name> * Remove last usages of request in our code Signed-off-by: Sebastian Malton <sebastian@malton.name> * Remove more deps Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix tests Signed-off-by: Sebastian Malton <sebastian@malton.name> * Fix lensFetch Signed-off-by: Sebastian Malton <sebastian@malton.name> Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
8e65a0acd6
commit
305c4a5573
@ -287,8 +287,6 @@
|
|||||||
"react-router": "^5.3.4",
|
"react-router": "^5.3.4",
|
||||||
"react-virtualized-auto-sizer": "^1.0.7",
|
"react-virtualized-auto-sizer": "^1.0.7",
|
||||||
"readable-stream": "^3.6.0",
|
"readable-stream": "^3.6.0",
|
||||||
"request": "^2.88.2",
|
|
||||||
"request-promise-native": "^1.0.9",
|
|
||||||
"rfc6902": "^5.0.1",
|
"rfc6902": "^5.0.1",
|
||||||
"selfsigned": "^2.1.1",
|
"selfsigned": "^2.1.1",
|
||||||
"semver": "^7.3.8",
|
"semver": "^7.3.8",
|
||||||
@ -355,8 +353,6 @@
|
|||||||
"@types/react-virtualized-auto-sizer": "^1.0.1",
|
"@types/react-virtualized-auto-sizer": "^1.0.1",
|
||||||
"@types/react-window": "^1.8.5",
|
"@types/react-window": "^1.8.5",
|
||||||
"@types/readable-stream": "^2.3.13",
|
"@types/readable-stream": "^2.3.13",
|
||||||
"@types/request": "^2.48.7",
|
|
||||||
"@types/request-promise-native": "^1.0.18",
|
|
||||||
"@types/semver": "^7.3.13",
|
"@types/semver": "^7.3.13",
|
||||||
"@types/sharp": "^0.31.1",
|
"@types/sharp": "^0.31.1",
|
||||||
"@types/tar": "^6.1.3",
|
"@types/tar": "^6.1.3",
|
||||||
@ -461,7 +457,6 @@
|
|||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"@types/react-virtualized-auto-sizer": "^1.0.1",
|
"@types/react-virtualized-auto-sizer": "^1.0.1",
|
||||||
"@types/react-window": "^1.8.5",
|
"@types/react-window": "^1.8.5",
|
||||||
"@types/request-promise-native": "^1.0.18",
|
|
||||||
"@types/tar": "^6.1.3",
|
"@types/tar": "^6.1.3",
|
||||||
"@types/tcp-port-used": "^1.0.1",
|
"@types/tcp-port-used": "^1.0.1",
|
||||||
"@types/url-parse": "^1.4.8",
|
"@types/url-parse": "^1.4.8",
|
||||||
|
|||||||
@ -15,7 +15,6 @@ import plimit from "p-limit";
|
|||||||
import type { ClusterState, ClusterMetricsResourceType, ClusterId, ClusterMetadata, ClusterModel, ClusterPreferences, ClusterPrometheusPreferences, UpdateClusterModel, KubeAuthUpdate, ClusterConfigData } from "../cluster-types";
|
import type { ClusterState, ClusterMetricsResourceType, ClusterId, ClusterMetadata, ClusterModel, ClusterPreferences, ClusterPrometheusPreferences, UpdateClusterModel, KubeAuthUpdate, ClusterConfigData } from "../cluster-types";
|
||||||
import { ClusterMetadataKey, initialNodeShellImage, ClusterStatus, clusterModelIdChecker, updateClusterModelChecker } from "../cluster-types";
|
import { ClusterMetadataKey, initialNodeShellImage, ClusterStatus, clusterModelIdChecker, updateClusterModelChecker } from "../cluster-types";
|
||||||
import { disposer, isDefined, isRequestError, toJS } from "../utils";
|
import { disposer, isDefined, isRequestError, toJS } from "../utils";
|
||||||
import type { Response } from "request";
|
|
||||||
import { clusterListNamespaceForbiddenChannel } from "../ipc/cluster";
|
import { clusterListNamespaceForbiddenChannel } from "../ipc/cluster";
|
||||||
import type { CanI } from "./authorization-review.injectable";
|
import type { CanI } from "./authorization-review.injectable";
|
||||||
import type { ListNamespaces } from "./list-namespaces.injectable";
|
import type { ListNamespaces } from "./list-namespaces.injectable";
|
||||||
@ -658,7 +657,7 @@ export class Cluster implements ClusterModel {
|
|||||||
const namespaceList = [ctx?.namespace].filter(isDefined);
|
const namespaceList = [ctx?.namespace].filter(isDefined);
|
||||||
|
|
||||||
if (namespaceList.length === 0 && error instanceof HttpError && error.statusCode === 403) {
|
if (namespaceList.length === 0 && error instanceof HttpError && error.statusCode === 403) {
|
||||||
const { response } = error as HttpError & { response: Response };
|
const { response } = error as HttpError & { response: { body: unknown }};
|
||||||
|
|
||||||
this.dependencies.logger.info("[CLUSTER]: listing namespaces is forbidden, broadcasting", { clusterId: this.id, error: response.body });
|
this.dependencies.logger.info("[CLUSTER]: listing namespaces is forbidden, broadcasting", { clusterId: this.id, error: response.body });
|
||||||
this.dependencies.broadcastMessage(clusterListNamespaceForbiddenChannel, this.id);
|
this.dependencies.broadcastMessage(clusterListNamespaceForbiddenChannel, this.id);
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { getGlobalOverrideForFunction } from "../test-utils/get-global-override-for-function";
|
||||||
|
import lensFetchInjectable from "./lens-fetch.injectable";
|
||||||
|
|
||||||
|
export default getGlobalOverrideForFunction(lensFetchInjectable);
|
||||||
37
src/common/fetch/lens-fetch.injectable.ts
Normal file
37
src/common/fetch/lens-fetch.injectable.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { Agent } from "https";
|
||||||
|
import type { RequestInit, Response } from "node-fetch";
|
||||||
|
import lensProxyPortInjectable from "../../main/lens-proxy/lens-proxy-port.injectable";
|
||||||
|
import lensProxyCertificateInjectable from "../certificate/lens-proxy-certificate.injectable";
|
||||||
|
import nodeFetchModuleInjectable from "./fetch-module.injectable";
|
||||||
|
|
||||||
|
export type LensRequestInit = Omit<RequestInit, "agent">;
|
||||||
|
|
||||||
|
export type LensFetch = (pathnameAndQuery: string, init?: LensRequestInit) => Promise<Response>;
|
||||||
|
|
||||||
|
const lensFetchInjectable = getInjectable({
|
||||||
|
id: "lens-fetch",
|
||||||
|
instantiate: (di): LensFetch => {
|
||||||
|
const { default: fetch } = di.inject(nodeFetchModuleInjectable);
|
||||||
|
const lensProxyPort = di.inject(lensProxyPortInjectable);
|
||||||
|
const lensProxyCertificate = di.inject(lensProxyCertificateInjectable);
|
||||||
|
|
||||||
|
return async (pathnameAndQuery, init = {}) => {
|
||||||
|
const agent = new Agent({
|
||||||
|
ca: lensProxyCertificate.get().cert,
|
||||||
|
});
|
||||||
|
|
||||||
|
return fetch(`https://127.0.0.1:${lensProxyPort.get()}${pathnameAndQuery}`, {
|
||||||
|
...init,
|
||||||
|
agent,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
},
|
||||||
|
causesSideEffects: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default lensFetchInjectable;
|
||||||
@ -4,16 +4,19 @@
|
|||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import type { Cluster } from "../common/cluster/cluster";
|
import type { Cluster } from "../common/cluster/cluster";
|
||||||
|
import nodeFetchModuleInjectable from "../common/fetch/fetch-module.injectable";
|
||||||
import type { RequestMetricsParams } from "../common/k8s-api/endpoints/metrics.api/request-metrics.injectable";
|
import type { RequestMetricsParams } from "../common/k8s-api/endpoints/metrics.api/request-metrics.injectable";
|
||||||
|
import { object } from "../common/utils";
|
||||||
import k8sRequestInjectable from "./k8s-request.injectable";
|
import k8sRequestInjectable from "./k8s-request.injectable";
|
||||||
|
|
||||||
export type GetMetrics = (cluster: Cluster, prometheusPath: string, queryParams: RequestMetricsParams & { query: string }) => Promise<any>;
|
export type GetMetrics = (cluster: Cluster, prometheusPath: string, queryParams: RequestMetricsParams & { query: string }) => Promise<unknown>;
|
||||||
|
|
||||||
const getMetricsInjectable = getInjectable({
|
const getMetricsInjectable = getInjectable({
|
||||||
id: "get-metrics",
|
id: "get-metrics",
|
||||||
|
|
||||||
instantiate: (di): GetMetrics => {
|
instantiate: (di): GetMetrics => {
|
||||||
const k8sRequest = di.inject(k8sRequestInjectable);
|
const k8sRequest = di.inject(k8sRequestInjectable);
|
||||||
|
const { FormData } = di.inject(nodeFetchModuleInjectable);
|
||||||
|
|
||||||
return async (
|
return async (
|
||||||
cluster,
|
cluster,
|
||||||
@ -22,13 +25,16 @@ const getMetricsInjectable = getInjectable({
|
|||||||
) => {
|
) => {
|
||||||
const prometheusPrefix = cluster.preferences.prometheus?.prefix || "";
|
const prometheusPrefix = cluster.preferences.prometheus?.prefix || "";
|
||||||
const metricsPath = `/api/v1/namespaces/${prometheusPath}/proxy${prometheusPrefix}/api/v1/query_range`;
|
const metricsPath = `/api/v1/namespaces/${prometheusPath}/proxy${prometheusPrefix}/api/v1/query_range`;
|
||||||
|
const body = new FormData();
|
||||||
|
|
||||||
|
for (const [key, value] of object.entries(queryParams)) {
|
||||||
|
body.set(key, value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
return k8sRequest(cluster, metricsPath, {
|
return k8sRequest(cluster, metricsPath, {
|
||||||
timeout: 0,
|
timeout: 0,
|
||||||
resolveWithFullResponse: false,
|
|
||||||
json: true,
|
|
||||||
method: "POST",
|
method: "POST",
|
||||||
form: queryParams,
|
body,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -2,35 +2,49 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import type { RequestPromiseOptions } from "request-promise-native";
|
|
||||||
import request from "request-promise-native";
|
|
||||||
import type { Cluster } from "../common/cluster/cluster";
|
import type { Cluster } from "../common/cluster/cluster";
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import lensProxyPortInjectable from "./lens-proxy/lens-proxy-port.injectable";
|
import type { LensRequestInit } from "../common/fetch/lens-fetch.injectable";
|
||||||
import lensProxyCertificateInjectable from "../common/certificate/lens-proxy-certificate.injectable";
|
import lensFetchInjectable from "../common/fetch/lens-fetch.injectable";
|
||||||
|
import { withTimeout } from "../common/fetch/timeout-controller";
|
||||||
|
|
||||||
export type K8sRequest = (cluster: Cluster, path: string, options?: RequestPromiseOptions) => Promise<any>;
|
export interface K8sRequestInit extends LensRequestInit {
|
||||||
|
timeout?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type K8sRequest = (cluster: Cluster, pathnameAndQuery: string, init?: K8sRequestInit) => Promise<unknown>;
|
||||||
|
|
||||||
const k8sRequestInjectable = getInjectable({
|
const k8sRequestInjectable = getInjectable({
|
||||||
id: "k8s-request",
|
id: "k8s-request",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di): K8sRequest => {
|
||||||
const lensProxyPort = di.inject(lensProxyPortInjectable);
|
const lensFetch = di.inject(lensFetchInjectable);
|
||||||
const lensProxyCertificate = di.inject(lensProxyCertificateInjectable);
|
|
||||||
|
|
||||||
return async (
|
return async (
|
||||||
cluster: Cluster,
|
cluster,
|
||||||
path: string,
|
pathnameAndQuery,
|
||||||
options: RequestPromiseOptions = {},
|
{
|
||||||
|
timeout = 30_000,
|
||||||
|
signal,
|
||||||
|
...init
|
||||||
|
} = {},
|
||||||
) => {
|
) => {
|
||||||
const kubeProxyUrl = `https://127.0.0.1:${lensProxyPort.get()}/${cluster.id}`;
|
const controller = timeout ? withTimeout(timeout) : undefined;
|
||||||
|
|
||||||
options.ca = lensProxyCertificate.get().cert;
|
if (controller) {
|
||||||
options.headers ??= {};
|
signal?.addEventListener("abort", () => controller.abort());
|
||||||
options.json ??= true;
|
}
|
||||||
options.timeout ??= 30000;
|
|
||||||
|
|
||||||
return request(kubeProxyUrl + path, options);
|
const response = await lensFetch(`/${cluster.id}${pathnameAndQuery}`, {
|
||||||
|
...init,
|
||||||
|
signal: controller?.signal ?? signal,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.status < 200 || response.status >= 300) {
|
||||||
|
throw new Error(`Failed to ${init.method ?? "get"} ${pathnameAndQuery} for clusterId=${cluster.id}: ${response.statusText}`, { cause: response });
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
48
yarn.lock
48
yarn.lock
@ -2619,14 +2619,7 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/relateurl/-/relateurl-0.2.29.tgz#68ccecec3d4ffdafb9c577fe764f912afc050fe6"
|
resolved "https://registry.yarnpkg.com/@types/relateurl/-/relateurl-0.2.29.tgz#68ccecec3d4ffdafb9c577fe764f912afc050fe6"
|
||||||
integrity sha512-QSvevZ+IRww2ldtfv1QskYsqVVVwCKQf1XbwtcyyoRvLIQzfyPhj/C+3+PKzSDRdiyejaiLgnq//XTkleorpLg==
|
integrity sha512-QSvevZ+IRww2ldtfv1QskYsqVVVwCKQf1XbwtcyyoRvLIQzfyPhj/C+3+PKzSDRdiyejaiLgnq//XTkleorpLg==
|
||||||
|
|
||||||
"@types/request-promise-native@^1.0.18":
|
"@types/request@^2.47.1":
|
||||||
version "1.0.18"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/request-promise-native/-/request-promise-native-1.0.18.tgz#437ee2d0b772e01c9691a983b558084b4b3efc2c"
|
|
||||||
integrity sha512-tPnODeISFc/c1LjWyLuZUY+Z0uLB3+IMfNoQyDEi395+j6kTFTTRAqjENjoPJUid4vHRGEozoTrcTrfZM+AcbA==
|
|
||||||
dependencies:
|
|
||||||
"@types/request" "*"
|
|
||||||
|
|
||||||
"@types/request@*", "@types/request@^2.47.1", "@types/request@^2.48.7":
|
|
||||||
version "2.48.8"
|
version "2.48.8"
|
||||||
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.8.tgz#0b90fde3b655ab50976cb8c5ac00faca22f5a82c"
|
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.8.tgz#0b90fde3b655ab50976cb8c5ac00faca22f5a82c"
|
||||||
integrity sha512-whjk1EDJPcAR2kYHRbFl/lKeeKYTi05A15K9bnLInCVroNDCtXce57xKdI0/rQaA3K+6q0eFyUBPmqfSndUZdQ==
|
integrity sha512-whjk1EDJPcAR2kYHRbFl/lKeeKYTi05A15K9bnLInCVroNDCtXce57xKdI0/rQaA3K+6q0eFyUBPmqfSndUZdQ==
|
||||||
@ -11471,23 +11464,7 @@ repeat-string@^1.5.2, repeat-string@^1.6.1:
|
|||||||
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
|
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
|
||||||
integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==
|
integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==
|
||||||
|
|
||||||
request-promise-core@1.1.4:
|
request@^2.88.0:
|
||||||
version "1.1.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f"
|
|
||||||
integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==
|
|
||||||
dependencies:
|
|
||||||
lodash "^4.17.19"
|
|
||||||
|
|
||||||
request-promise-native@^1.0.9:
|
|
||||||
version "1.0.9"
|
|
||||||
resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28"
|
|
||||||
integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==
|
|
||||||
dependencies:
|
|
||||||
request-promise-core "1.1.4"
|
|
||||||
stealthy-require "^1.1.1"
|
|
||||||
tough-cookie "^2.3.3"
|
|
||||||
|
|
||||||
request@^2.88.0, request@^2.88.2:
|
|
||||||
version "2.88.2"
|
version "2.88.2"
|
||||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
||||||
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
|
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
|
||||||
@ -12346,11 +12323,6 @@ statuses@2.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
||||||
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
|
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
|
||||||
|
|
||||||
stealthy-require@^1.1.1:
|
|
||||||
version "1.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
|
|
||||||
integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=
|
|
||||||
|
|
||||||
stream-buffers@^3.0.2:
|
stream-buffers@^3.0.2:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-3.0.2.tgz#5249005a8d5c2d00b3a32e6e0a6ea209dc4f3521"
|
resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-3.0.2.tgz#5249005a8d5c2d00b3a32e6e0a6ea209dc4f3521"
|
||||||
@ -12906,14 +12878,6 @@ touch@^3.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
nopt "~1.0.10"
|
nopt "~1.0.10"
|
||||||
|
|
||||||
tough-cookie@^2.3.3, tough-cookie@~2.5.0:
|
|
||||||
version "2.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
|
|
||||||
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
|
|
||||||
dependencies:
|
|
||||||
psl "^1.1.28"
|
|
||||||
punycode "^2.1.1"
|
|
||||||
|
|
||||||
tough-cookie@^4.0.0:
|
tough-cookie@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4"
|
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4"
|
||||||
@ -12923,6 +12887,14 @@ tough-cookie@^4.0.0:
|
|||||||
punycode "^2.1.1"
|
punycode "^2.1.1"
|
||||||
universalify "^0.1.2"
|
universalify "^0.1.2"
|
||||||
|
|
||||||
|
tough-cookie@~2.5.0:
|
||||||
|
version "2.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
|
||||||
|
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
|
||||||
|
dependencies:
|
||||||
|
psl "^1.1.28"
|
||||||
|
punycode "^2.1.1"
|
||||||
|
|
||||||
tr46@^2.1.0:
|
tr46@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240"
|
resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user