mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
mobx-6 migration -- part 1
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
1044c544ad
commit
a0fb8b5933
@ -51,8 +51,6 @@ export class ExamplePreferencesStore extends Store.ExtensionStore<ExamplePrefere
|
||||
toJSON(): ExamplePreferencesModel {
|
||||
return toJS({
|
||||
enabled: this.enabled
|
||||
}, {
|
||||
recurseEverything: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,6 +183,7 @@
|
||||
"@kubernetes/client-node": "^0.12.0",
|
||||
"abort-controller": "^3.0.0",
|
||||
"array-move": "^3.0.0",
|
||||
"autobind-decorator": "^2.4.0",
|
||||
"await-lock": "^2.1.0",
|
||||
"byline": "^5.0.0",
|
||||
"chalk": "^4.1.0",
|
||||
@ -207,9 +208,9 @@
|
||||
"mac-ca": "^1.0.4",
|
||||
"marked": "^2.0.3",
|
||||
"md5-file": "^5.0.0",
|
||||
"mobx": "^5.15.7",
|
||||
"mobx-observable-history": "^1.0.3",
|
||||
"mobx-react": "^6.2.2",
|
||||
"mobx": "^6.3.0",
|
||||
"mobx-observable-history": "^2.0.0",
|
||||
"mobx-react": "^7.1.0",
|
||||
"mock-fs": "^4.12.0",
|
||||
"moment": "^2.26.0",
|
||||
"moment-timezone": "^0.5.33",
|
||||
|
||||
@ -288,7 +288,7 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
||||
|
||||
@action
|
||||
protected fromStore({ activeCluster, clusters = [] }: ClusterStoreModel = {}) {
|
||||
const currentClusters = this.clusters.toJS();
|
||||
const currentClusters = toJS(this.clusters);
|
||||
const newClusters = new Map<ClusterId, Cluster>();
|
||||
const removedClusters = new Map<ClusterId, Cluster>();
|
||||
|
||||
@ -324,8 +324,6 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
||||
return toJS({
|
||||
activeCluster: this.activeCluster,
|
||||
clusters: this.clustersList.map(cluster => cluster.toJSON()),
|
||||
}, {
|
||||
recurseEverything: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
38
src/common/configure-packages.ts
Normal file
38
src/common/configure-packages.ts
Normal file
@ -0,0 +1,38 @@
|
||||
// Setup default configuration for external npm-packages.
|
||||
import * as Mobx from "mobx";
|
||||
import * as Immer from "immer";
|
||||
|
||||
const { isObservable, toJS, observable } = Mobx;
|
||||
|
||||
/**
|
||||
* Patch-fixing mobx@6.toJS() to support partially observable objects as data-input.
|
||||
* Otherwise it won't be recursively converted to corresponding non-observable plain JS-structure.
|
||||
* @example
|
||||
* data = {one: 1, two: observable.array([2])}; // "data" itself is non-observable
|
||||
*/
|
||||
Object.defineProperty(Mobx, "toJS", {
|
||||
value(data: any) {
|
||||
if (typeof data === "object" && !isObservable(data)) {
|
||||
return toJS(observable.box(data).get());
|
||||
}
|
||||
return toJS(data);
|
||||
}
|
||||
});
|
||||
|
||||
export default function configurePackages() {
|
||||
// Docs: https://mobx.js.org/configuration.html
|
||||
Mobx.configure({
|
||||
enforceActions: "never",
|
||||
isolateGlobalState: true,
|
||||
|
||||
// TODO: enable later (read more: https://mobx.js.org/migrating-from-4-or-5.html)
|
||||
// computedRequiresReaction: true,
|
||||
// reactionRequiresObservable: true,
|
||||
// observableRequiresReaction: true,
|
||||
});
|
||||
|
||||
// Docs: https://immerjs.github.io/immer/
|
||||
// Required for `storage-helper.ts`
|
||||
Immer.setAutoFreeze(false); // allow to merge mobx observables
|
||||
Immer.enableMapSet(); // allow to merge maps and sets
|
||||
}
|
||||
@ -219,8 +219,6 @@ export class HotbarStore extends BaseStore<HotbarStoreModel> {
|
||||
activeHotbarId: this.activeHotbarId
|
||||
};
|
||||
|
||||
return toJS(model, {
|
||||
recurseEverything: true,
|
||||
});
|
||||
return toJS(model);
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ export async function requestMain(channel: string, ...args: any[]) {
|
||||
}
|
||||
|
||||
function getSubFrames(): ClusterFrameInfo[] {
|
||||
return toJS(Array.from(clusterFrameMap.values()), { recurseEverything: true });
|
||||
return toJS(Array.from(clusterFrameMap.values()));
|
||||
}
|
||||
|
||||
export async function broadcastMessage(channel: string, ...args: any[]) {
|
||||
|
||||
@ -285,9 +285,7 @@ export class UserStore extends BaseStore<UserStoreModel> {
|
||||
},
|
||||
};
|
||||
|
||||
return toJS(model, {
|
||||
recurseEverything: true,
|
||||
});
|
||||
return toJS(model);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,45 +1,10 @@
|
||||
// Decorator for binding class methods
|
||||
// Can be applied to class or single method as @autobind()
|
||||
type Constructor<T = {}> = new (...args: any[]) => T;
|
||||
// Decorator for binding class methods to proper "this"-context.
|
||||
// API: https://github.com/andreypopp/autobind-decorator
|
||||
import bindMethodOrClass from "autobind-decorator"
|
||||
|
||||
export function autobind() {
|
||||
return function (target: Constructor | object, prop?: string, descriptor?: PropertyDescriptor) {
|
||||
if (target instanceof Function) return bindClass(target);
|
||||
else return bindMethod(target, prop, descriptor);
|
||||
// TODO: unwrap, replace usages of @autobind() to @autobind
|
||||
export function autobind<T extends object>() {
|
||||
return function (target: { new(...args: any[]): T } | object, prop?: string, descriptor?: PropertyDescriptor) {
|
||||
return bindMethodOrClass(target, prop, descriptor) as any;
|
||||
};
|
||||
}
|
||||
|
||||
function bindClass<T extends Constructor>(constructor: T) {
|
||||
const proto = constructor.prototype;
|
||||
const descriptors = Object.getOwnPropertyDescriptors(proto);
|
||||
const skipMethod = (methodName: string) => {
|
||||
return methodName === "constructor"
|
||||
|| typeof descriptors[methodName].value !== "function";
|
||||
};
|
||||
|
||||
Object.keys(descriptors).forEach(prop => {
|
||||
if (skipMethod(prop)) return;
|
||||
const boundDescriptor = bindMethod(proto, prop, descriptors[prop]);
|
||||
|
||||
Object.defineProperty(proto, prop, boundDescriptor);
|
||||
});
|
||||
}
|
||||
|
||||
function bindMethod(target: object, prop?: string, descriptor?: PropertyDescriptor) {
|
||||
if (!descriptor || typeof descriptor.value !== "function") {
|
||||
throw new Error(`@autobind() must be used on class or method only`);
|
||||
}
|
||||
const { value: func, enumerable, configurable } = descriptor;
|
||||
const boundFunc = new WeakMap<object, Function>();
|
||||
|
||||
return Object.defineProperty(target, prop, {
|
||||
enumerable,
|
||||
configurable,
|
||||
get() {
|
||||
if (this === target) return func; // direct access from prototype
|
||||
if (!boundFunc.has(this)) boundFunc.set(this, func.bind(this));
|
||||
|
||||
return boundFunc.get(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -444,8 +444,6 @@ export class ExtensionDiscovery extends Singleton {
|
||||
toJSON(): ExtensionDiscoveryChannelMessage {
|
||||
return toJS({
|
||||
isLoaded: this.isLoaded
|
||||
}, {
|
||||
recurseEverything: true
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { app, ipcRenderer, remote } from "electron";
|
||||
import { EventEmitter } from "events";
|
||||
import { isEqual } from "lodash";
|
||||
import { action, computed, observable, reaction, toJS, when } from "mobx";
|
||||
import { action, computed, observable, reaction, when } from "mobx";
|
||||
import path from "path";
|
||||
import { getHostedCluster } from "../common/cluster-store";
|
||||
import { broadcastMessage, handleRequest, requestMain, subscribeToBroadcast } from "../common/ipc";
|
||||
@ -40,7 +40,7 @@ export class ExtensionLoader extends Singleton {
|
||||
whenLoaded = when(() => this.isLoaded);
|
||||
|
||||
@computed get userExtensions(): Map<LensExtensionId, InstalledExtension> {
|
||||
const extensions = this.extensions.toJS();
|
||||
const extensions = this.toJSON();
|
||||
|
||||
extensions.forEach((ext, extId) => {
|
||||
if (ext.isBundled) {
|
||||
@ -54,7 +54,7 @@ export class ExtensionLoader extends Singleton {
|
||||
@computed get userExtensionsByName(): Map<string, LensExtension> {
|
||||
const extensions = new Map();
|
||||
|
||||
for (const [, val] of this.instances.toJS()) {
|
||||
for (const [, val] of this.instances.toJSON()) {
|
||||
if (val.isBundled) {
|
||||
continue;
|
||||
}
|
||||
@ -135,7 +135,7 @@ export class ExtensionLoader extends Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
protected async initMain() {
|
||||
protected async initMain() {
|
||||
this.isLoaded = true;
|
||||
this.loadOnMain();
|
||||
|
||||
@ -152,7 +152,7 @@ export class ExtensionLoader extends Singleton {
|
||||
});
|
||||
}
|
||||
|
||||
protected async initRenderer() {
|
||||
protected async initRenderer() {
|
||||
const extensionListHandler = (extensions: [LensExtensionId, InstalledExtension][]) => {
|
||||
this.isLoaded = true;
|
||||
this.syncExtensions(extensions);
|
||||
@ -311,10 +311,7 @@ export class ExtensionLoader extends Singleton {
|
||||
}
|
||||
|
||||
toJSON(): Map<LensExtensionId, InstalledExtension> {
|
||||
return toJS(this.extensions, {
|
||||
exportMapsAsObjects: false,
|
||||
recurseEverything: true,
|
||||
});
|
||||
return new Map(this.extensions.toJSON());
|
||||
}
|
||||
|
||||
broadcastExtensions(main = true) {
|
||||
|
||||
@ -47,9 +47,7 @@ export class ExtensionsStore extends BaseStore<LensExtensionsStoreModel> {
|
||||
|
||||
toJSON(): LensExtensionsStoreModel {
|
||||
return toJS({
|
||||
extensions: this.state.toJSON(),
|
||||
}, {
|
||||
recurseEverything: true
|
||||
extensions: Object.fromEntries(this.state.toJSON()),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ describe("getPageUrl", () => {
|
||||
});
|
||||
|
||||
it("gets page url with custom params", () => {
|
||||
const params: PageParams<string> = { test1: "one", test2: "2" };
|
||||
const params: PageParams = { test1: "one", test2: "2" };
|
||||
const searchParams = new URLSearchParams(params);
|
||||
const pageUrl = getExtensionPageUrl({ extensionId: ext.name, pageId: "page-with-params", params });
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { BaseRegistry } from "./base-registry";
|
||||
import { LensExtension, sanitizeExtensionName } from "../lens-extension";
|
||||
import { LensExtension, LensExtensionId, sanitizeExtensionName } from "../lens-extension";
|
||||
import { PageParam, PageParamInit } from "../../renderer/navigation/page-param";
|
||||
import { createPageParam } from "../../renderer/navigation/helpers";
|
||||
|
||||
@ -13,21 +13,18 @@ export interface PageRegistration {
|
||||
* When not provided, first registered page without "id" would be used for page-menus without target.pageId for same extension
|
||||
*/
|
||||
id?: string;
|
||||
params?: PageParams<string | ExtensionPageParamInit>;
|
||||
params?: PageParams<string | Omit<PageParamInit<any>, "name" | "prefix">>;
|
||||
components: PageComponents;
|
||||
}
|
||||
|
||||
// exclude "name" field since provided as key in page.params
|
||||
export type ExtensionPageParamInit = Omit<PageParamInit, "name" | "isSystem">;
|
||||
|
||||
export interface PageComponents {
|
||||
Page: React.ComponentType<any>;
|
||||
}
|
||||
|
||||
export interface PageTarget<P = PageParams> {
|
||||
export interface PageTarget {
|
||||
extensionId?: string;
|
||||
pageId?: string;
|
||||
params?: P;
|
||||
params?: PageParams;
|
||||
}
|
||||
|
||||
export interface PageParams<V = any> {
|
||||
@ -62,13 +59,11 @@ export function getExtensionPageUrl(target: PageTarget): string {
|
||||
|
||||
if (registeredPage?.params) {
|
||||
Object.entries(registeredPage.params).forEach(([name, param]) => {
|
||||
const paramValue = param.stringify(targetParams[name]);
|
||||
pageUrl.searchParams.delete(name); // first off, clear existing value(s)
|
||||
|
||||
if (param.init.skipEmpty && param.isEmpty(paramValue)) {
|
||||
pageUrl.searchParams.delete(name);
|
||||
} else {
|
||||
pageUrl.searchParams.set(name, paramValue);
|
||||
}
|
||||
param.stringify(targetParams[name]).forEach(value => {
|
||||
pageUrl.searchParams.append(name, value);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -79,7 +74,7 @@ export class PageRegistry extends BaseRegistry<PageRegistration, RegisteredPage>
|
||||
protected getRegisteredItem(page: PageRegistration, ext: LensExtension): RegisteredPage {
|
||||
const { id: pageId } = page;
|
||||
const extensionId = ext.name;
|
||||
const params = this.normalizeParams(page.params);
|
||||
const params = this.normalizeParams(extensionId, page.params);
|
||||
const components = this.normalizeComponents(page.components, params);
|
||||
const url = getExtensionPageUrl({ extensionId, pageId });
|
||||
|
||||
@ -92,25 +87,48 @@ export class PageRegistry extends BaseRegistry<PageRegistration, RegisteredPage>
|
||||
if (params) {
|
||||
const { Page } = components;
|
||||
|
||||
// inject extension's page component props.params
|
||||
components.Page = observer((props: object) => React.createElement(Page, { params, ...props }));
|
||||
}
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
protected normalizeParams(params?: PageParams<string | ExtensionPageParamInit>): PageParams<PageParam> {
|
||||
if (!params) {
|
||||
return;
|
||||
}
|
||||
Object.entries(params).forEach(([name, value]) => {
|
||||
const paramInit: PageParamInit = typeof value === "object"
|
||||
? { name, ...value }
|
||||
: { name, defaultValue: value };
|
||||
protected normalizeParams(extensionId: LensExtensionId, params?: PageParams<string | Partial<PageParamInit>>): PageParams<PageParam> {
|
||||
if (!params) return;
|
||||
const normalizedParams: PageParams<PageParam> = {};
|
||||
|
||||
params[paramInit.name] = createPageParam(paramInit);
|
||||
Object.entries(params).forEach(([paramName, paramValue]) => {
|
||||
const paramInit: PageParamInit = {
|
||||
name: paramName,
|
||||
prefix: `${extensionId}:`,
|
||||
defaultValue: paramValue,
|
||||
};
|
||||
|
||||
// handle non-string params
|
||||
if (typeof paramValue !== "string") {
|
||||
const { defaultValue: value, parse, stringify } = paramValue;
|
||||
|
||||
const notAStringValue = typeof value !== "string" || (
|
||||
Array.isArray(value) && !value.every(value => typeof value === "string")
|
||||
);
|
||||
|
||||
if (notAStringValue && !(parse || stringify)) {
|
||||
throw new Error(
|
||||
`PageRegistry: param's "${paramName}" initialization has failed:
|
||||
paramInit.parse() and paramInit.stringify() are required for non string | string[] "defaultValue"`
|
||||
)
|
||||
}
|
||||
|
||||
paramInit.defaultValue = value;
|
||||
paramInit.parse = parse;
|
||||
paramInit.stringify = stringify;
|
||||
}
|
||||
|
||||
normalizedParams[paramName] = createPageParam(paramInit);
|
||||
});
|
||||
|
||||
return params as PageParams<PageParam>;
|
||||
return normalizedParams;
|
||||
}
|
||||
|
||||
getByPageTarget(target: PageTarget): RegisteredPage | null {
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
import { PageParam, PageParamInit } from "../../renderer/navigation/page-param";
|
||||
import { navigation } from "../../renderer/navigation";
|
||||
import { navigation, PageParam, PageParamInit } from "../../renderer/navigation";
|
||||
|
||||
export type { PageParamInit, PageParam } from "../../renderer/navigation/page-param";
|
||||
export { PageParamInit, PageParam } from "../../renderer/navigation/page-param";
|
||||
export { navigate, isActiveRoute } from "../../renderer/navigation/helpers";
|
||||
export { hideDetails, showDetails, getDetailsUrl } from "../../renderer/components/kube-object/kube-object-details";
|
||||
export { IURLParams } from "../../common/utils/buildUrl";
|
||||
|
||||
// exporting to extensions-api version of helper without `isSystem` flag
|
||||
export function createPageParam<V = string>(init: PageParamInit<V>) {
|
||||
export function createPageParam<V>(init: PageParamInit<V>) {
|
||||
return new PageParam<V>(init, navigation);
|
||||
}
|
||||
|
||||
@ -1,4 +1,9 @@
|
||||
import configurePackages from "./common/configure-packages";
|
||||
import fetchMock from "jest-fetch-mock";
|
||||
|
||||
// setup default configuration for external npm-packages
|
||||
configurePackages();
|
||||
|
||||
// rewire global.fetch to call 'fetchMock'
|
||||
fetchMock.enableMocks();
|
||||
|
||||
|
||||
@ -14,14 +14,14 @@ export class CatalogPusher {
|
||||
init() {
|
||||
const disposers: Disposer[] = [];
|
||||
|
||||
disposers.push(reaction(() => toJS(this.catalog.items, { recurseEverything: true }), (items) => {
|
||||
disposers.push(reaction(() => toJS(this.catalog.items), (items) => {
|
||||
broadcastMessage("catalog:items", items);
|
||||
}, {
|
||||
fireImmediately: true,
|
||||
}));
|
||||
|
||||
const listener = subscribeToBroadcast("catalog:broadcast", () => {
|
||||
broadcastMessage("catalog:items", toJS(this.catalog.items, { recurseEverything: true }));
|
||||
broadcastMessage("catalog:items", toJS(this.catalog.items));
|
||||
});
|
||||
|
||||
disposers.push(() => unsubscribeFromBroadcast("catalog:broadcast", listener));
|
||||
|
||||
@ -47,7 +47,7 @@ export class KubeconfigSyncManager extends Singleton {
|
||||
this.startNewSync(filePath);
|
||||
}
|
||||
|
||||
this.syncListDisposer = UserStore.getInstance().syncKubeconfigEntries.observe(change => {
|
||||
this.syncListDisposer = UserStore.getInstance().syncKubeconfigEntries.observe_(change => {
|
||||
switch (change.type) {
|
||||
case "add":
|
||||
this.startNewSync(change.name);
|
||||
|
||||
@ -14,7 +14,7 @@ export class ClusterManager extends Singleton {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
reaction(() => toJS(ClusterStore.getInstance().clustersList, { recurseEverything: true }), () => {
|
||||
reaction(() => toJS(ClusterStore.getInstance().clustersList), () => {
|
||||
this.updateCatalog(ClusterStore.getInstance().clustersList);
|
||||
}, { fireImmediately: true });
|
||||
|
||||
|
||||
@ -206,9 +206,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
@computed get prometheusPreferences(): ClusterPrometheusPreferences {
|
||||
const { prometheus, prometheusProvider } = this.preferences;
|
||||
|
||||
return toJS({ prometheus, prometheusProvider }, {
|
||||
recurseEverything: true,
|
||||
});
|
||||
return toJS({ prometheus, prometheusProvider });
|
||||
}
|
||||
|
||||
/**
|
||||
@ -549,9 +547,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
accessibleNamespaces: this.accessibleNamespaces,
|
||||
};
|
||||
|
||||
return toJS(model, {
|
||||
recurseEverything: true
|
||||
});
|
||||
return toJS(model);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -571,9 +567,7 @@ export class Cluster implements ClusterModel, ClusterState {
|
||||
isGlobalWatchEnabled: this.isGlobalWatchEnabled,
|
||||
};
|
||||
|
||||
return toJS(state, {
|
||||
recurseEverything: true
|
||||
});
|
||||
return toJS(state);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -50,9 +50,7 @@ export class FilesystemProvisionerStore extends BaseStore<FSProvisionModel> {
|
||||
|
||||
toJSON(): FSProvisionModel {
|
||||
return toJS({
|
||||
extensions: this.registeredExtensions.toJSON(),
|
||||
}, {
|
||||
recurseEverything: true
|
||||
extensions: Object.fromEntries(this.registeredExtensions.toJSON()),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@ import { HotbarStore } from "../common/hotbar-store";
|
||||
import { HelmRepoManager } from "./helm/helm-repo-manager";
|
||||
import { KubeconfigSyncManager } from "./catalog-sources";
|
||||
import { handleWsUpgrade } from "./proxy/ws-upgrade";
|
||||
import configurePackages from "../common/configure-packages";
|
||||
|
||||
const workingDir = path.join(app.getPath("appData"), appName);
|
||||
|
||||
@ -55,6 +56,7 @@ if (process.env.LENS_DISABLE_GPU) {
|
||||
app.disableHardwareAcceleration();
|
||||
}
|
||||
|
||||
configurePackages();
|
||||
mangleProxyEnv();
|
||||
|
||||
if (app.commandLine.getSwitchValue("proxy-server") !== "") {
|
||||
|
||||
@ -22,6 +22,9 @@ import { ThemeStore } from "./theme.store";
|
||||
import { HelmRepoManager } from "../main/helm/helm-repo-manager";
|
||||
import { ExtensionInstallationStateStore } from "./components/+extensions/extension-install.store";
|
||||
import { DefaultProps } from "./mui-base-theme";
|
||||
import configurePackages from "../common/configure-packages";
|
||||
|
||||
configurePackages();
|
||||
|
||||
/**
|
||||
* If this is a development buid, wait a second to attach
|
||||
|
||||
@ -51,7 +51,7 @@ export class ReleaseDetails extends Component<Props> {
|
||||
);
|
||||
|
||||
@disposeOnUnmount
|
||||
secretWatcher = reaction(() => secretsStore.items.toJS(), () => {
|
||||
secretWatcher = reaction(() => secretsStore.items.toJSON(), () => {
|
||||
if (!this.props.release) return;
|
||||
const { getReleaseSecret } = releaseStore;
|
||||
const { release } = this.props;
|
||||
|
||||
@ -20,7 +20,7 @@ export class ReleaseStore extends ItemStore<HelmRelease> {
|
||||
}
|
||||
|
||||
watchAssociatedSecrets(): (() => void) {
|
||||
return reaction(() => secretsStore.items.toJS(), () => {
|
||||
return reaction(() => secretsStore.items.toJSON(), () => {
|
||||
if (this.isLoading) return;
|
||||
const newSecrets = this.getReleaseSecrets();
|
||||
const amountChanged = newSecrets.length !== this.releaseSecrets.size;
|
||||
|
||||
@ -39,7 +39,7 @@ export class ConfigMapDetails extends React.Component<Props> {
|
||||
|
||||
try {
|
||||
this.isSaving = true;
|
||||
await configMapsStore.update(configMap, { ...configMap, data: this.data.toJSON() });
|
||||
await configMapsStore.update(configMap, { ...configMap, data: Object.fromEntries(this.data.toJSON()) });
|
||||
Notifications.ok(
|
||||
<p>
|
||||
<>ConfigMap <b>{configMap.getName()}</b> successfully updated.</>
|
||||
@ -54,7 +54,7 @@ export class ConfigMapDetails extends React.Component<Props> {
|
||||
const { object: configMap } = this.props;
|
||||
|
||||
if (!configMap) return null;
|
||||
const data = Object.entries(this.data.toJSON());
|
||||
const data = this.data.toJSON();
|
||||
|
||||
return (
|
||||
<div className="ConfigMapDetails">
|
||||
|
||||
@ -14,8 +14,6 @@ import { Icon } from "../icon";
|
||||
|
||||
export const crdGroupsUrlParam = createPageParam<string[]>({
|
||||
name: "groups",
|
||||
multiValues: true,
|
||||
isSystem: true,
|
||||
defaultValue: [],
|
||||
});
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ export class CRDStore extends KubeObjectStore<CustomResourceDefinition> {
|
||||
super();
|
||||
|
||||
// auto-init stores for crd-s
|
||||
reaction(() => this.items.toJS(), items => items.forEach(initStore));
|
||||
reaction(() => this.items.toJSON(), items => items.forEach(initStore));
|
||||
}
|
||||
|
||||
protected sortItems(items: CustomResourceDefinition[]) {
|
||||
|
||||
@ -9,8 +9,6 @@ const selectedNamespaces = createStorage<string[] | undefined>("selected_namespa
|
||||
|
||||
export const namespaceUrlParam = createPageParam<string[]>({
|
||||
name: "namespaces",
|
||||
isSystem: true,
|
||||
multiValues: true,
|
||||
defaultValue: [],
|
||||
});
|
||||
|
||||
|
||||
@ -78,7 +78,7 @@ export class App extends React.Component {
|
||||
whatInput.ask(); // Start to monitor user input device
|
||||
|
||||
// Setup hosted cluster context
|
||||
KubeObjectStore.defaultContext = clusterContext;
|
||||
KubeObjectStore.defaultContext.set(clusterContext);
|
||||
kubeWatchApi.context = clusterContext;
|
||||
}
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ export class Dialog extends React.PureComponent<DialogProps, DialogState> {
|
||||
};
|
||||
|
||||
@disposeOnUnmount
|
||||
closeOnNavigate = reaction(() => navigation.getPath(), () => this.close());
|
||||
closeOnNavigate = reaction(() => navigation.toString(), () => this.close());
|
||||
|
||||
public state: DialogState = {
|
||||
isOpen: this.props.isOpen,
|
||||
|
||||
@ -54,7 +54,7 @@ export class DockTabStore<T> {
|
||||
}
|
||||
|
||||
protected getStorableData(): DockTabStorageState<T> {
|
||||
const allTabsData = toJS(this.data, { recurseEverything: true });
|
||||
const allTabsData = toJS(this.data);
|
||||
|
||||
return Object.fromEntries(
|
||||
Object.entries(allTabsData).map(([tabId, tabData]) => {
|
||||
|
||||
@ -21,7 +21,7 @@ export class ErrorBoundary extends React.Component<Props, State> {
|
||||
|
||||
@disposeOnUnmount
|
||||
resetOnNavigate = reaction(
|
||||
() => navigation.getPath(),
|
||||
() => navigation.toString(),
|
||||
() => this.setState({ error: null, errorInfo: null })
|
||||
);
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@ import { createPageParam } from "../../navigation";
|
||||
|
||||
export const searchUrlParam = createPageParam({
|
||||
name: "search",
|
||||
isSystem: true,
|
||||
defaultValue: "",
|
||||
});
|
||||
|
||||
|
||||
@ -18,7 +18,6 @@ import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"
|
||||
*/
|
||||
export const kubeDetailsUrlParam = createPageParam({
|
||||
name: "kube-details",
|
||||
isSystem: true,
|
||||
});
|
||||
|
||||
/**
|
||||
@ -30,7 +29,6 @@ export const kubeDetailsUrlParam = createPageParam({
|
||||
*/
|
||||
export const kubeSelectedUrlParam = createPageParam({
|
||||
name: "kube-selected",
|
||||
isSystem: true,
|
||||
get defaultValue() {
|
||||
return kubeDetailsUrlParam.get();
|
||||
}
|
||||
@ -49,12 +47,12 @@ export function hideDetails() {
|
||||
export function getDetailsUrl(selfLink: string, resetSelected = false, mergeGlobals = true) {
|
||||
const params = new URLSearchParams(mergeGlobals ? navigation.searchParams : "");
|
||||
|
||||
params.set(kubeDetailsUrlParam.urlName, selfLink);
|
||||
params.set(kubeDetailsUrlParam.name, selfLink);
|
||||
|
||||
if (resetSelected) {
|
||||
params.delete(kubeSelectedUrlParam.urlName);
|
||||
params.delete(kubeSelectedUrlParam.name);
|
||||
} else {
|
||||
params.set(kubeSelectedUrlParam.urlName, kubeSelectedUrlParam.get());
|
||||
params.set(kubeSelectedUrlParam.name, kubeSelectedUrlParam.get());
|
||||
}
|
||||
|
||||
return `?${params}`;
|
||||
|
||||
@ -46,12 +46,10 @@ export interface TableProps extends React.DOMAttributes<HTMLDivElement> {
|
||||
|
||||
export const sortByUrlParam = createPageParam({
|
||||
name: "sort",
|
||||
isSystem: true,
|
||||
});
|
||||
|
||||
export const orderByUrlParam = createPageParam({
|
||||
name: "order",
|
||||
isSystem: true,
|
||||
});
|
||||
|
||||
@observer
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { useState } from "react";
|
||||
import { createStorage } from "../utils";
|
||||
import { CreateObservableOptions } from "mobx/lib/api/observable";
|
||||
import { CreateObservableOptions } from "mobx";
|
||||
|
||||
export function useStorage<T>(key: string, initialValue: T, options?: CreateObservableOptions) {
|
||||
const storage = createStorage(key, initialValue, options);
|
||||
|
||||
@ -24,7 +24,7 @@ export abstract class ItemStore<T extends ItemObject = ItemObject> {
|
||||
}
|
||||
|
||||
public getItems(): T[] {
|
||||
return this.items.toJS();
|
||||
return this.items.toJSON();
|
||||
}
|
||||
|
||||
public getTotalCount(): number {
|
||||
|
||||
@ -18,7 +18,7 @@ export interface KubeObjectStoreLoadingParams {
|
||||
|
||||
@autobind()
|
||||
export abstract class KubeObjectStore<T extends KubeObject = any> extends ItemStore<T> {
|
||||
@observable static defaultContext: ClusterContext; // TODO: support multiple cluster contexts
|
||||
static defaultContext = observable.box<ClusterContext>(); // TODO: support multiple cluster contexts
|
||||
|
||||
abstract api: KubeApi<T>;
|
||||
public readonly limit?: number;
|
||||
@ -34,7 +34,7 @@ export abstract class KubeObjectStore<T extends KubeObject = any> extends ItemSt
|
||||
}
|
||||
|
||||
get context(): ClusterContext {
|
||||
return KubeObjectStore.defaultContext;
|
||||
return KubeObjectStore.defaultContext.get();
|
||||
}
|
||||
|
||||
@computed get contextItems(): T[] {
|
||||
@ -350,7 +350,7 @@ export abstract class KubeObjectStore<T extends KubeObject = any> extends ItemSt
|
||||
|
||||
@action
|
||||
protected updateFromEventsBuffer() {
|
||||
const items = this.items.toJS();
|
||||
const items = this.items.toJSON();
|
||||
|
||||
for (const { type, object } of this.eventsBuffer.clear()) {
|
||||
const index = items.findIndex(item => item.getId() === object.metadata?.uid);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { LocationDescriptor } from "history";
|
||||
import { matchPath, RouteProps } from "react-router";
|
||||
import { PageParam, PageSystemParamInit } from "./page-param";
|
||||
import { PageParam, PageParamInit } from "./page-param";
|
||||
import { clusterViewRoute, IClusterViewRouteParams } from "../components/cluster-manager/cluster-view.route";
|
||||
import { navigation } from "./history";
|
||||
|
||||
@ -14,7 +14,7 @@ export function navigate(location: LocationDescriptor) {
|
||||
}
|
||||
}
|
||||
|
||||
export function createPageParam<V = string>(init: PageSystemParamInit<V>) {
|
||||
export function createPageParam<V = string>(init: PageParamInit<V>) {
|
||||
return new PageParam<V>(init, navigation);
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,14 @@ import { createObservableHistory } from "mobx-observable-history";
|
||||
import logger from "../../main/logger";
|
||||
|
||||
export const history = ipcRenderer ? createBrowserHistory() : createMemoryHistory();
|
||||
export const navigation = createObservableHistory(history);
|
||||
|
||||
export const navigation = createObservableHistory(history, {
|
||||
searchParams: {
|
||||
skipEmpty: true, // skip empty params, e.g. "?x=&y2=" will be "?y=2"
|
||||
joinArrays: false, // join multiple params with same name, e.g. "?x=1&x=2" => "?x=1,2"
|
||||
joinArraysWith: ",", // param values splitter, applicable only with {joinArrays:true}
|
||||
}
|
||||
});
|
||||
|
||||
navigation.listen((location, action) => {
|
||||
const isClusterView = !process.isMainFrame;
|
||||
|
||||
@ -4,5 +4,6 @@ import { bindEvents } from "./events";
|
||||
|
||||
export * from "./history";
|
||||
export * from "./helpers";
|
||||
export * from "./page-param";
|
||||
|
||||
bindEvents();
|
||||
|
||||
@ -1,135 +1,113 @@
|
||||
// Manage observable URL-param from document.location.search
|
||||
import { IObservableHistory } from "mobx-observable-history";
|
||||
// Manage observable param from document's location.search
|
||||
import type { ObservableHistory } from "mobx-observable-history";
|
||||
import { action, computed } from "mobx";
|
||||
|
||||
export interface PageParamInit<V = any> {
|
||||
name: string;
|
||||
defaultValue?: V;
|
||||
defaultValueStringified?: string | string[]; // serialized version of "defaultValue"
|
||||
multiValues?: boolean; // false == by default
|
||||
multiValueSep?: string; // joining multiple values with separator, default: ","
|
||||
skipEmpty?: boolean; // skip empty value(s), e.g. "?param=", default: true
|
||||
parse?(value: string[]): V; // deserialize from URL
|
||||
stringify?(value: V): string | string[]; // serialize params to URL
|
||||
}
|
||||
|
||||
export interface PageSystemParamInit<V = any> extends PageParamInit<V> {
|
||||
isSystem?: boolean;
|
||||
prefix?: string; // name prefix, for extensions it's `${extension.id}:`
|
||||
parse?(value: string | string[]): V; // from URL
|
||||
stringify?(value: V): string | string[]; // to URL
|
||||
}
|
||||
|
||||
// TODO: write tests
|
||||
export class PageParam<V = any> {
|
||||
static SYSTEM_PREFIX = "lens-";
|
||||
|
||||
readonly name: string;
|
||||
readonly urlName: string;
|
||||
readonly isMulti: boolean;
|
||||
|
||||
constructor(readonly init: PageParamInit<V> | PageSystemParamInit<V>, protected history: IObservableHistory) {
|
||||
const { isSystem, name } = init as PageSystemParamInit;
|
||||
constructor(private init: PageParamInit<V>, private history: ObservableHistory) {
|
||||
const { prefix, name, defaultValue } = init;
|
||||
|
||||
this.name = name;
|
||||
this.init.skipEmpty ??= true;
|
||||
this.init.multiValueSep ??= ",";
|
||||
|
||||
// prefixing to avoid collisions with extensions
|
||||
this.urlName = `${isSystem ? PageParam.SYSTEM_PREFIX : ""}${name}`;
|
||||
this.name = `${prefix ?? ""}${name}`; // actual prefixed URL-name
|
||||
this.isMulti = Array.isArray(defaultValue); // multi-values param
|
||||
}
|
||||
|
||||
isEmpty(value: V | any) {
|
||||
return [value].flat().every(value => value == "" || value == null);
|
||||
// should be a getter since `init.defaultValue` could be a getter too
|
||||
get defaultValue(): V | undefined {
|
||||
return this.init.defaultValue;
|
||||
}
|
||||
|
||||
parse(values: string[]): V {
|
||||
const { parse, multiValues } = this.init;
|
||||
parse(values: string | string[]): V {
|
||||
const { parse } = this.init;
|
||||
|
||||
if (!multiValues) values.splice(1); // reduce values to single item
|
||||
const parsedValues = [parse ? parse(values) : values].flat();
|
||||
|
||||
return multiValues ? parsedValues : parsedValues[0] as any;
|
||||
}
|
||||
|
||||
stringify(value: V = this.get()): string {
|
||||
const { stringify, multiValues, multiValueSep, skipEmpty } = this.init;
|
||||
|
||||
if (skipEmpty && this.isEmpty(value)) {
|
||||
return "";
|
||||
if (parse) {
|
||||
return parse(values);
|
||||
}
|
||||
|
||||
if (multiValues) {
|
||||
const values = [value].flat();
|
||||
const stringValues = [stringify ? stringify(value) : values.map(String)].flat();
|
||||
// return as-is ("string"-value based params)
|
||||
return values as any as V;
|
||||
}
|
||||
|
||||
return stringValues.join(multiValueSep);
|
||||
stringify(value: V = this.get()): string[] {
|
||||
const { stringify } = this.init;
|
||||
|
||||
if (stringify) {
|
||||
return [stringify(value)].flat();
|
||||
}
|
||||
|
||||
return [stringify ? stringify(value) : String(value)].flat()[0];
|
||||
return [value].flat().map(String);
|
||||
}
|
||||
|
||||
get(): V {
|
||||
const value = this.parse(this.getRaw());
|
||||
|
||||
if (this.init.skipEmpty && this.isEmpty(value)) {
|
||||
return this.getDefaultValue();
|
||||
}
|
||||
|
||||
return value;
|
||||
return this.parse(this.getRaw()) ?? this.defaultValue;
|
||||
}
|
||||
|
||||
set(value: V, { mergeGlobals = true, replaceHistory = false } = {}) {
|
||||
const search = this.toSearchString({ mergeGlobals, value });
|
||||
@action
|
||||
set(value: V, { mergeGlobals = true, replaceHistory = false } = {}): void {
|
||||
const search = this.toString({ mergeGlobals, value });
|
||||
|
||||
this.history.merge({ search }, replaceHistory);
|
||||
}
|
||||
|
||||
setRaw(value: string | string[]) {
|
||||
const { history, urlName } = this;
|
||||
const { multiValues, multiValueSep, skipEmpty } = this.init;
|
||||
const paramValue = multiValues ? [value].flat().join(multiValueSep) : String(value);
|
||||
/**
|
||||
* Set stringified raw value(s) and update `document.location.search`
|
||||
* @param {string | string[]} value
|
||||
*/
|
||||
@action
|
||||
setRaw(value: string | string[]): void {
|
||||
const values: string[] = [value].flat();
|
||||
|
||||
if (skipEmpty && this.isEmpty(paramValue)) {
|
||||
history.searchParams.delete(urlName);
|
||||
} else {
|
||||
history.searchParams.set(urlName, paramValue);
|
||||
}
|
||||
}
|
||||
|
||||
getRaw(): string[] {
|
||||
const { history, urlName } = this;
|
||||
const { multiValueSep } = this.init;
|
||||
|
||||
return history.searchParams.getAsArray(urlName, multiValueSep);
|
||||
}
|
||||
|
||||
getDefaultValue() {
|
||||
const { defaultValue, defaultValueStringified } = this.init;
|
||||
|
||||
return defaultValueStringified ? this.parse([defaultValueStringified].flat()) : defaultValue;
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.history.searchParams.delete(this.urlName);
|
||||
}
|
||||
|
||||
toSearchString({ withPrefix = true, mergeGlobals = true, value = this.get() } = {}): string {
|
||||
const { history, urlName, init: { skipEmpty } } = this;
|
||||
const searchParams = new URLSearchParams(mergeGlobals ? history.location.search : "");
|
||||
|
||||
searchParams.set(urlName, this.stringify(value));
|
||||
|
||||
if (skipEmpty) {
|
||||
searchParams.forEach((value: any, paramName) => {
|
||||
if (this.isEmpty(value)) searchParams.delete(paramName);
|
||||
if (this.isMulti) {
|
||||
this.clear();
|
||||
values.forEach(value => {
|
||||
this.history.searchParams.append(this.name, value);
|
||||
});
|
||||
} else {
|
||||
this.history.searchParams.set(this.name, values[0]);
|
||||
}
|
||||
|
||||
if (Array.from(searchParams).length > 0) {
|
||||
return `${withPrefix ? "?" : ""}${searchParams}`;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
toObjectParam(value = this.get()): Record<string, V> {
|
||||
/**
|
||||
* Get stringified raw value(s) from `document.location.search`
|
||||
*/
|
||||
@computed getRaw(): string | string[] {
|
||||
const values: string[] = this.history.searchParams.getAll(this.name);
|
||||
|
||||
return this.isMulti ? values : values[0];
|
||||
}
|
||||
|
||||
@action
|
||||
clear() {
|
||||
this.history.searchParams.delete(this.name);
|
||||
}
|
||||
|
||||
toString({ withPrefix = true, mergeGlobals = true, value = this.get() } = {}): string {
|
||||
let searchParams = new URLSearchParams();
|
||||
|
||||
if (mergeGlobals) {
|
||||
searchParams = new URLSearchParams(this.history.searchParams);
|
||||
searchParams.delete(this.name);
|
||||
}
|
||||
|
||||
this.stringify(value).forEach(value => {
|
||||
searchParams.append(this.name, value);
|
||||
});
|
||||
return `${withPrefix ? "?" : ""}${searchParams}`;
|
||||
}
|
||||
|
||||
toObjectParam(): Record<string, V> {
|
||||
return {
|
||||
[this.urlName]: value,
|
||||
[this.name]: this.get(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,7 +175,7 @@ describe("renderer/utils/StorageHelper", () => {
|
||||
it("storage.get() is observable", () => {
|
||||
expect(storageHelper.get()).toEqual(defaultValue);
|
||||
|
||||
reaction(() => storageHelper.toJS(), change => {
|
||||
reaction(() => storageHelper.toJSON(), change => {
|
||||
observedChanges.push(change);
|
||||
});
|
||||
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
// Keeps window.localStorage state in external JSON-files.
|
||||
// Because app creates random port between restarts => storage session wiped out each time.
|
||||
import type { CreateObservableOptions } from "mobx/lib/api/observable";
|
||||
|
||||
import path from "path";
|
||||
import { app, remote } from "electron";
|
||||
import { observable, reaction, when } from "mobx";
|
||||
import { observable, reaction, when, CreateObservableOptions } from "mobx";
|
||||
import fse from "fs-extra";
|
||||
import { StorageHelper } from "./storageHelper";
|
||||
import { ClusterStore, getHostedClusterId } from "../../common/cluster-store";
|
||||
|
||||
@ -1,14 +1,10 @@
|
||||
// Helper for working with storages (e.g. window.localStorage, NodeJS/file-system, etc.)
|
||||
|
||||
import type { CreateObservableOptions } from "mobx/lib/api/observable";
|
||||
import { action, comparer, observable, toJS, when, IObservableValue } from "mobx";
|
||||
import produce, { Draft, enableMapSet, setAutoFreeze } from "immer";
|
||||
import { action, comparer, CreateObservableOptions, IObservableValue, observable, toJS, when } from "mobx";
|
||||
import produce, { Draft } from "immer";
|
||||
import { isEqual, isFunction, isPlainObject } from "lodash";
|
||||
import logger from "../../main/logger";
|
||||
|
||||
setAutoFreeze(false); // allow to merge observables
|
||||
enableMapSet(); // allow merging maps and sets
|
||||
|
||||
export interface StorageAdapter<T> {
|
||||
[metadata: string]: any;
|
||||
getItem(key: string): T | Promise<T>;
|
||||
@ -45,10 +41,8 @@ export class StorageHelper<T> {
|
||||
...StorageHelper.defaultOptions.observable,
|
||||
...(options.observable ?? {})
|
||||
});
|
||||
this.data.observe(change => {
|
||||
const { newValue, oldValue } = toJS(change, { recurseEverything: true });
|
||||
|
||||
this.onChange(newValue, oldValue);
|
||||
this.data.observe_(({ newValue, oldValue }) => {
|
||||
this.onChange(newValue as T, oldValue as T);
|
||||
});
|
||||
|
||||
this.storage = options.storage;
|
||||
@ -117,17 +111,18 @@ export class StorageHelper<T> {
|
||||
return this.data.get();
|
||||
}
|
||||
|
||||
@action
|
||||
set(value: T) {
|
||||
if (value == null) {
|
||||
// This cannot use recursion because defaultValue might be null or undefined
|
||||
this.data.set(this.defaultValue);
|
||||
this.reset();
|
||||
} else {
|
||||
this.data.set(value);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
reset() {
|
||||
this.set(this.defaultValue);
|
||||
this.data.set(this.defaultValue);
|
||||
}
|
||||
|
||||
merge(value: Partial<T> | ((draft: Draft<T>) => Partial<T> | void)) {
|
||||
@ -142,7 +137,7 @@ export class StorageHelper<T> {
|
||||
this.set(nextValue as T);
|
||||
}
|
||||
|
||||
toJS() {
|
||||
return toJS(this.get(), { recurseEverything: true });
|
||||
toJSON(): T {
|
||||
return toJS(this.get());
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"traceResolution": false,
|
||||
"resolveJsonModule": true,
|
||||
"useDefineForClassFields": false,
|
||||
"paths": {
|
||||
"*": [
|
||||
"node_modules/*",
|
||||
|
||||
165
yarn.lock
165
yarn.lock
@ -1269,11 +1269,16 @@
|
||||
"@types/shot" "*"
|
||||
joi "^17.3.0"
|
||||
|
||||
"@types/history@*", "@types/history@^4.7.3":
|
||||
"@types/history@*":
|
||||
version "4.7.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.6.tgz#ed8fc802c45b8e8f54419c2d054e55c9ea344356"
|
||||
integrity sha512-GRTZLeLJ8ia00ZH8mxMO8t0aC9M1N9bN461Z2eaRurJo6Fpa+utgCwLzI4jQHcrdzuzp5WPN9jRwpsCQ1VhJ5w==
|
||||
|
||||
"@types/history@^4.7.8":
|
||||
version "4.7.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.8.tgz#49348387983075705fe8f4e02fb67f7daaec4934"
|
||||
integrity sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==
|
||||
|
||||
"@types/hoist-non-react-statics@^3.3.0", "@types/hoist-non-react-statics@^3.3.1":
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
|
||||
@ -2703,6 +2708,11 @@ atob@^2.1.2:
|
||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
|
||||
|
||||
autobind-decorator@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/autobind-decorator/-/autobind-decorator-2.4.0.tgz#ea9e1c98708cf3b5b356f7cf9f10f265ff18239c"
|
||||
integrity sha512-OGYhWUO72V6DafbF8PM8rm3EPbfuyMZcJhtm5/n26IDwO18pohE4eNazLoCGhPiXOCD0gEGmrbU3849QvM8bbw==
|
||||
|
||||
await-lock@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/await-lock/-/await-lock-2.1.0.tgz#bc78c51d229a34d5d90965a1c94770e772c6145e"
|
||||
@ -4390,13 +4400,20 @@ debug@4.1.0:
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6:
|
||||
debug@^3.0.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^3.1.0:
|
||||
version "3.2.7"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
|
||||
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
|
||||
@ -4411,7 +4428,7 @@ debug@^4.3.2:
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
debuglog@^1.0.1:
|
||||
debuglog@*, debuglog@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
|
||||
integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=
|
||||
@ -5893,6 +5910,11 @@ fill-range@^7.0.1:
|
||||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
filter-obj@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b"
|
||||
integrity sha1-mzERErxsYSehbgFsbF1/GeCAXFs=
|
||||
|
||||
finalhandler@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
|
||||
@ -6530,12 +6552,12 @@ got@^9.6.0:
|
||||
to-readable-stream "^1.0.0"
|
||||
url-parse-lax "^3.0.0"
|
||||
|
||||
graceful-fs@^4.1.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.2.2, graceful-fs@^4.2.4:
|
||||
graceful-fs@^4.1.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.2.4:
|
||||
version "4.2.4"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
||||
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
|
||||
|
||||
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
|
||||
graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2:
|
||||
version "4.2.6"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
|
||||
integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
|
||||
@ -6739,11 +6761,16 @@ homedir-polyfill@^1.0.1:
|
||||
dependencies:
|
||||
parse-passwd "^1.0.0"
|
||||
|
||||
hosted-git-info@^2.1.4, hosted-git-info@^2.7.1, hosted-git-info@^2.8.8:
|
||||
hosted-git-info@^2.1.4:
|
||||
version "2.8.8"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
|
||||
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
|
||||
|
||||
hosted-git-info@^2.7.1, hosted-git-info@^2.8.9:
|
||||
version "2.8.9"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
|
||||
integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
|
||||
|
||||
hosted-git-info@^3.0.8:
|
||||
version "3.0.8"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d"
|
||||
@ -7063,7 +7090,7 @@ import-local@^3.0.2:
|
||||
pkg-dir "^4.2.0"
|
||||
resolve-cwd "^3.0.0"
|
||||
|
||||
imurmurhash@^0.1.4:
|
||||
imurmurhash@*, imurmurhash@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
|
||||
@ -7133,7 +7160,7 @@ ini@2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5"
|
||||
integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==
|
||||
|
||||
ini@^1.3.4, ini@^1.3.5, ini@~1.3.0:
|
||||
ini@^1.3.4, ini@^1.3.5, ini@^1.3.8, ini@~1.3.0:
|
||||
version "1.3.8"
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
|
||||
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
|
||||
@ -8884,6 +8911,11 @@ lodash-es@^4.17.20:
|
||||
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
|
||||
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
|
||||
|
||||
lodash._baseindexof@*:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c"
|
||||
integrity sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw=
|
||||
|
||||
lodash._baseuniq@~4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8"
|
||||
@ -8892,11 +8924,33 @@ lodash._baseuniq@~4.6.0:
|
||||
lodash._createset "~4.0.0"
|
||||
lodash._root "~3.0.0"
|
||||
|
||||
lodash._bindcallback@*:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e"
|
||||
integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4=
|
||||
|
||||
lodash._cacheindexof@*:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92"
|
||||
integrity sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI=
|
||||
|
||||
lodash._createcache@*:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093"
|
||||
integrity sha1-VtagZAF2JeeevKa4AY4XRAvc8JM=
|
||||
dependencies:
|
||||
lodash._getnative "^3.0.0"
|
||||
|
||||
lodash._createset@~4.0.0:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26"
|
||||
integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY=
|
||||
|
||||
lodash._getnative@*, lodash._getnative@^3.0.0:
|
||||
version "3.9.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
|
||||
integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=
|
||||
|
||||
lodash._root@~3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692"
|
||||
@ -8917,6 +8971,11 @@ lodash.memoize@4.x:
|
||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
||||
|
||||
lodash.restparam@*:
|
||||
version "3.6.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
|
||||
integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=
|
||||
|
||||
lodash.sortby@^4.7.0:
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
|
||||
@ -9151,9 +9210,9 @@ md5.js@^1.3.4:
|
||||
safe-buffer "^5.1.2"
|
||||
|
||||
meant@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/meant/-/meant-1.0.2.tgz#5d0c78310a3d8ae1408a16be0fe0bd42a969f560"
|
||||
integrity sha512-KN+1uowN/NK+sT/Lzx7WSGIj2u+3xe5n2LbwObfjOhPZiA+cCfCm6idVl0RkEfjThkw5XJ96CyRcanq6GmKtUg==
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/meant/-/meant-1.0.3.tgz#67769af9de1d158773e928ae82c456114903554c"
|
||||
integrity sha512-88ZRGcNxAq4EH38cQ4D85PM57pikCwS8Z99EWHODxN7KBY+UuPiqzRTtZzS8KTXO/ywSWbdjjJST2Hly/EQxLw==
|
||||
|
||||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
@ -9458,36 +9517,31 @@ mkdirp@1.x, mkdirp@^1.0.3:
|
||||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
mobx-observable-history@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/mobx-observable-history/-/mobx-observable-history-1.0.3.tgz#7e34be76024dc09c71b17c3996b422f50a347c98"
|
||||
integrity sha512-3JNF00AWbAXBSFJ8y/+xiPEpyySEDsNiWoT5q1G7V2w5BUQ+umqPSrmoJJlSzSs5d6Ey8HHGyPm0aGK444+hcA==
|
||||
mobx-observable-history@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/mobx-observable-history/-/mobx-observable-history-2.0.0.tgz#aec91929b8c0d363a19aac8dfd071a92c509caff"
|
||||
integrity sha512-xX8w4lM5mKAO0S3yJ2M8FQ2pQ7Ns7zOvq7+goEnhHizO8HeHfC7O5SCy+BL5LN3Ahr5p4AW08KAj3edLBK5h4Q==
|
||||
dependencies:
|
||||
"@types/history" "^4.7.3"
|
||||
"@types/history" "^4.7.8"
|
||||
history "^4.10.1"
|
||||
mobx "^5.15.4"
|
||||
mobx "^6.3.0"
|
||||
|
||||
mobx-react-lite@>=2.2.0:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-2.2.2.tgz#87c217dc72b4e47b22493daf155daf3759f868a6"
|
||||
integrity sha512-2SlXALHIkyUPDsV4VTKVR9DW7K3Ksh1aaIv3NrNJygTbhXe2A9GrcKHZ2ovIiOp/BXilOcTYemfHHZubP431dg==
|
||||
mobx-react-lite@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-3.2.0.tgz#331d7365a6b053378dfe9c087315b4e41c5df69f"
|
||||
integrity sha512-q5+UHIqYCOpBoFm/PElDuOhbcatvTllgRp3M1s+Hp5j0Z6XNgDbgqxawJ0ZAUEyKM8X1zs70PCuhAIzX1f4Q/g==
|
||||
|
||||
mobx-react@^6.2.2:
|
||||
version "6.3.0"
|
||||
resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-6.3.0.tgz#7d11799f988bbdadc49e725081993b18baa20329"
|
||||
integrity sha512-C14yya2nqEBRSEiJjPkhoWJLlV8pcCX3m2JRV7w1KivwANJqipoiPx9UMH4pm6QNMbqDdvJqoyl+LqNu9AhvEQ==
|
||||
mobx-react@^7.1.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-7.1.0.tgz#d947cada3cfad294b4b6f692e969c242b9c16eaf"
|
||||
integrity sha512-DxvA6VXmnZ+N9f/UTtolWtdRnAAQY2iHWTSPLktfpj8NKlXUe4dabBAjuXrBcZUM8GjLWnxD1ZEjssXq1M0RAw==
|
||||
dependencies:
|
||||
mobx-react-lite ">=2.2.0"
|
||||
mobx-react-lite "^3.2.0"
|
||||
|
||||
mobx@^5.15.4:
|
||||
version "5.15.4"
|
||||
resolved "https://registry.yarnpkg.com/mobx/-/mobx-5.15.4.tgz#9da1a84e97ba624622f4e55a0bf3300fb931c2ab"
|
||||
integrity sha512-xRFJxSU2Im3nrGCdjSuOTFmxVDGeqOHL+TyADCGbT0k4HHqGmx5u2yaHNryvoORpI4DfbzjJ5jPmuv+d7sioFw==
|
||||
|
||||
mobx@^5.15.7:
|
||||
version "5.15.7"
|
||||
resolved "https://registry.yarnpkg.com/mobx/-/mobx-5.15.7.tgz#b9a5f2b6251f5d96980d13c78e9b5d8d4ce22665"
|
||||
integrity sha512-wyM3FghTkhmC+hQjyPGGFdpehrcX1KOXsDuERhfK2YbJemkUhEB+6wzEN639T21onxlfYBmriA1PFnvxTUhcKw==
|
||||
mobx@^6.3.0:
|
||||
version "6.3.0"
|
||||
resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.3.0.tgz#a8fb693c3047bdfcb1eaff9aa48e36a7eb084f96"
|
||||
integrity sha512-Aa1+VXsg4WxqJMTQfWoYuJi5UD10VZhiobSmcs5kcmI3BIT0aVtn7DysvCeDADCzl7dnbX+0BTHUj/v7gLlZpQ==
|
||||
|
||||
mock-fs@^4.12.0:
|
||||
version "4.12.0"
|
||||
@ -9921,9 +9975,9 @@ npm-audit-report@^1.3.3:
|
||||
console-control-strings "^1.1.0"
|
||||
|
||||
npm-bundled@^1.0.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b"
|
||||
integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1"
|
||||
integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==
|
||||
dependencies:
|
||||
npm-normalize-package-bin "^1.0.1"
|
||||
|
||||
@ -10040,15 +10094,15 @@ npm-run-path@^4.0.0:
|
||||
dependencies:
|
||||
path-key "^3.0.0"
|
||||
|
||||
npm-user-validate@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.0.tgz#8ceca0f5cea04d4e93519ef72d0557a75122e951"
|
||||
integrity sha1-jOyg9c6gTU6TUZ73LQVXp1Ei6VE=
|
||||
npm-user-validate@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.1.tgz#31428fc5475fe8416023f178c0ab47935ad8c561"
|
||||
integrity sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw==
|
||||
|
||||
npm@^6.14.8:
|
||||
version "6.14.8"
|
||||
resolved "https://registry.yarnpkg.com/npm/-/npm-6.14.8.tgz#64ef754345639bc035982ec3f609353c8539033c"
|
||||
integrity sha512-HBZVBMYs5blsj94GTeQZel7s9odVuuSUHy1+AlZh7rPVux1os2ashvEGLy/STNK7vUjbrCg5Kq9/GXisJgdf6A==
|
||||
version "6.14.13"
|
||||
resolved "https://registry.yarnpkg.com/npm/-/npm-6.14.13.tgz#e88bcb6c48209869c40b5cedad8a1508e58e6f30"
|
||||
integrity sha512-SRl4jJi0EBHY2xKuu98FLRMo3VhYQSA6otyLnjSEiHoSG/9shXCFNJy9tivpUJvtkN9s6VDdItHa5Rn+fNBzag==
|
||||
dependencies:
|
||||
JSONStream "^1.3.5"
|
||||
abbrev "~1.1.1"
|
||||
@ -10080,12 +10134,12 @@ npm@^6.14.8:
|
||||
glob "^7.1.6"
|
||||
graceful-fs "^4.2.4"
|
||||
has-unicode "~2.0.1"
|
||||
hosted-git-info "^2.8.8"
|
||||
hosted-git-info "^2.8.9"
|
||||
iferr "^1.0.2"
|
||||
infer-owner "^1.0.4"
|
||||
inflight "~1.0.6"
|
||||
inherits "^2.0.4"
|
||||
ini "^1.3.5"
|
||||
ini "^1.3.8"
|
||||
init-package-json "^1.10.3"
|
||||
is-cidr "^3.0.0"
|
||||
json-parse-better-errors "^1.0.2"
|
||||
@ -10122,10 +10176,10 @@ npm@^6.14.8:
|
||||
npm-pick-manifest "^3.0.2"
|
||||
npm-profile "^4.0.4"
|
||||
npm-registry-fetch "^4.0.7"
|
||||
npm-user-validate "~1.0.0"
|
||||
npm-user-validate "^1.0.1"
|
||||
npmlog "~4.1.2"
|
||||
once "~1.4.0"
|
||||
opener "^1.5.1"
|
||||
opener "^1.5.2"
|
||||
osenv "^0.1.5"
|
||||
pacote "^9.5.12"
|
||||
path-is-inside "~1.0.2"
|
||||
@ -10149,7 +10203,7 @@ npm@^6.14.8:
|
||||
slide "~1.1.6"
|
||||
sorted-object "~2.0.1"
|
||||
sorted-union-stream "~2.1.3"
|
||||
ssri "^6.0.1"
|
||||
ssri "^6.0.2"
|
||||
stringify-package "^1.0.1"
|
||||
tar "^4.4.13"
|
||||
text-table "~0.2.0"
|
||||
@ -10377,7 +10431,7 @@ open@^7.3.1:
|
||||
is-docker "^2.0.0"
|
||||
is-wsl "^2.1.1"
|
||||
|
||||
opener@^1.5.1:
|
||||
opener@^1.5.2:
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598"
|
||||
integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==
|
||||
@ -11390,11 +11444,12 @@ query-string@^5.0.1:
|
||||
strict-uri-encode "^1.0.0"
|
||||
|
||||
query-string@^6.8.2:
|
||||
version "6.13.4"
|
||||
resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.13.4.tgz#b35a9a3bd4955bce55f94feb0e819b3d0be6f66f"
|
||||
integrity sha512-E2NPIeJoBEJGQNy3ib1k/Z/OkDBUKIo8IV2ZVwbKfoa65IS9unqWWUlLcbfU70Da0qNoxUZZA8CfKUjKLE641Q==
|
||||
version "6.14.1"
|
||||
resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a"
|
||||
integrity sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==
|
||||
dependencies:
|
||||
decode-uri-component "^0.2.0"
|
||||
filter-obj "^1.1.0"
|
||||
split-on-first "^1.0.0"
|
||||
strict-uri-encode "^2.0.0"
|
||||
|
||||
@ -12896,7 +12951,7 @@ sshpk@^1.7.0:
|
||||
safer-buffer "^2.0.2"
|
||||
tweetnacl "~0.14.0"
|
||||
|
||||
ssri@^6.0.0, ssri@^6.0.1:
|
||||
ssri@^6.0.0, ssri@^6.0.1, ssri@^6.0.2:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5"
|
||||
integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==
|
||||
|
||||
Loading…
Reference in New Issue
Block a user