@fluidframework/synthesize 0.54.2 → 0.56.0-49831

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,33 +2,32 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ import { IFluidDependencySynthesizer, } from "./IFluidDependencySynthesizer";
5
6
  /**
6
7
  * DependencyContainer is similar to a IoC Container. It takes providers and will
7
8
  * synthesize an object based on them when requested.
8
9
  */
9
10
  export class DependencyContainer {
10
- constructor(parent = undefined) {
11
- this.parent = parent;
11
+ constructor(...parents) {
12
12
  this.providers = new Map();
13
+ this.parents = parents.filter((v) => v !== undefined);
13
14
  }
14
15
  get IFluidDependencySynthesizer() { return this; }
15
16
  /**
16
- * {@inheritDoc (IFluidDependencySynthesizer:interface).registeredTypes}
17
- */
18
- get registeredTypes() {
19
- return this.providers.keys();
20
- }
21
- /**
22
- * {@inheritDoc (IFluidDependencySynthesizer:interface).register}
17
+ * Add a new provider
18
+ * @param type - Name of the Type T being provided
19
+ * @param provider - A provider that will resolve the T correctly when asked
20
+ * @throws - If passing a type that's already registered
23
21
  */
24
22
  register(type, provider) {
25
- if (this.has(type)) {
23
+ if (this.providers.has(type)) {
26
24
  throw new Error(`Attempting to register a provider of type ${type} that already exists`);
27
25
  }
28
26
  this.providers.set(type, provider);
29
27
  }
30
28
  /**
31
- * {@inheritDoc (IFluidDependencySynthesizer:interface).unregister}
29
+ * Remove a provider
30
+ * @param type - Name of the provider to remove
32
31
  */
33
32
  unregister(type) {
34
33
  if (this.providers.has(type)) {
@@ -39,77 +38,76 @@ export class DependencyContainer {
39
38
  * {@inheritDoc (IFluidDependencySynthesizer:interface).synthesize}
40
39
  */
41
40
  synthesize(optionalTypes, requiredTypes) {
42
- const optionalValues = Object.values(optionalTypes);
43
- const requiredValues = Object.values(requiredTypes);
44
- // There was nothing passed in so we can return
45
- if (optionalValues === [] && requiredValues === []) {
46
- return {};
47
- }
48
- const required = this.generateRequired(requiredTypes);
49
- const optional = this.generateOptional(optionalTypes);
50
- return Object.assign(Object.assign({}, required), optional);
41
+ const base = {};
42
+ this.generateRequired(base, requiredTypes);
43
+ this.generateOptional(base, optionalTypes);
44
+ Object.defineProperty(base, IFluidDependencySynthesizer, { get: () => this });
45
+ return base;
51
46
  }
52
47
  /**
53
48
  * {@inheritDoc (IFluidDependencySynthesizer:interface).has}
49
+ * @param excludeParents - If true, exclude checking parent registries
54
50
  */
55
- has(...types) {
56
- return types.every((type) => {
57
- return this.providers.has(type);
58
- });
59
- }
60
- /**
61
- * {@inheritDoc (IFluidDependencySynthesizer:interface).getProvider}
62
- */
63
- getProvider(type) {
64
- // If we have the provider return it
65
- const provider = this.providers.get(type);
66
- if (provider) {
67
- return provider;
51
+ has(type, excludeParents) {
52
+ if (this.providers.has(type)) {
53
+ return true;
68
54
  }
69
- if (this.parent) {
70
- return this.parent.getProvider(type);
55
+ if (excludeParents !== true) {
56
+ return this.parents.some((p) => p.has(type));
71
57
  }
72
- return undefined;
58
+ return false;
73
59
  }
74
- generateRequired(types) {
75
- const values = Object.values(types);
76
- return Object.assign({}, ...Array.from(values, (t) => {
77
- const provider = this.getProvider(t);
78
- if (!provider) {
79
- throw new Error(`Object attempted to be created without registered required provider ${t}`);
60
+ generateRequired(base, types) {
61
+ if (types === undefined)
62
+ return;
63
+ for (const key of Object.keys(types)) {
64
+ const provider = this.resolveProvider(key);
65
+ if (provider === undefined) {
66
+ throw new Error(`Object attempted to be created without registered required provider ${key}`);
80
67
  }
81
- return this.resolveProvider(provider, t);
82
- }));
68
+ Object.defineProperty(base, key, provider);
69
+ }
83
70
  }
84
- generateOptional(types) {
85
- const values = Object.values(types);
86
- return Object.assign({}, ...Array.from(values, (t) => {
87
- const provider = this.getProvider(t);
88
- if (!provider) {
89
- return { get [t]() { return Promise.resolve(undefined); } };
90
- }
91
- return this.resolveProvider(provider, t);
92
- }));
71
+ generateOptional(base, types) {
72
+ var _a;
73
+ if (types === undefined)
74
+ return;
75
+ for (const key of Object.keys(types)) {
76
+ // back-compat: in 0.56 we allow undefined in the types, but we didn't before
77
+ // this will keep runtime back compat, eventually we should support undefined properties
78
+ // rather than properties that return promises that resolve to undefined
79
+ const provider = (_a = this.resolveProvider(key)) !== null && _a !== void 0 ? _a : { get: () => Promise.resolve(undefined) };
80
+ Object.defineProperty(base, key, provider);
81
+ }
93
82
  }
94
- resolveProvider(provider, t) {
83
+ resolveProvider(t) {
84
+ // If we have the provider return it
85
+ const provider = this.providers.get(t);
86
+ if (provider === undefined) {
87
+ for (const parent of this.parents) {
88
+ const sp = { [t]: t };
89
+ const syn = parent.synthesize(sp, {});
90
+ const descriptor = Object.getOwnPropertyDescriptor(syn, t);
91
+ if (descriptor !== undefined) {
92
+ return descriptor;
93
+ }
94
+ }
95
+ return undefined;
96
+ }
95
97
  // The double nested gets are required for lazy loading the provider resolution
96
98
  if (typeof provider === "function") {
97
- // eslint-disable-next-line @typescript-eslint/no-this-alias
98
- const self = this;
99
99
  return {
100
- get [t]() {
100
+ get() {
101
101
  if (provider && typeof provider === "function") {
102
- return Promise.resolve(provider(self)).then((p) => {
103
- if (p) {
104
- return p[t];
105
- }
106
- });
102
+ return Promise.resolve(this[IFluidDependencySynthesizer])
103
+ .then(async (fds) => provider(fds))
104
+ .then((p) => p === null || p === void 0 ? void 0 : p[t]);
107
105
  }
108
106
  },
109
107
  };
110
108
  }
111
109
  return {
112
- get [t]() {
110
+ get() {
113
111
  if (provider) {
114
112
  return Promise.resolve(provider).then((p) => {
115
113
  if (p) {
@@ -1 +1 @@
1
- {"version":3,"file":"dependencyContainer.js","sourceRoot":"","sources":["../src/dependencyContainer.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IFluidObject } from \"@fluidframework/core-interfaces\";\n\nimport {\n AsyncFluidObjectProvider,\n FluidObjectSymbolProvider,\n FluidObjectProvider,\n FluidObjectKey,\n} from \"./types\";\nimport {\n IFluidDependencySynthesizer,\n} from \"./IFluidDependencySynthesizer\";\n\n/**\n * DependencyContainer is similar to a IoC Container. It takes providers and will\n * synthesize an object based on them when requested.\n */\nexport class DependencyContainer implements IFluidDependencySynthesizer {\n private readonly providers = new Map<keyof IFluidObject, FluidObjectProvider<any>>();\n\n public get IFluidDependencySynthesizer() { return this; }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).registeredTypes}\n */\n public get registeredTypes(): Iterable<(keyof IFluidObject)> {\n return this.providers.keys();\n }\n\n public constructor(public parent: IFluidDependencySynthesizer | undefined = undefined) { }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).register}\n */\n public register<T extends keyof IFluidObject>(type: T, provider: FluidObjectProvider<T>): void {\n if (this.has(type)) {\n throw new Error(`Attempting to register a provider of type ${type} that already exists`);\n }\n\n this.providers.set(type, provider);\n }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).unregister}\n */\n public unregister<T extends keyof IFluidObject>(type: T): void {\n if (this.providers.has(type)) {\n this.providers.delete(type);\n }\n }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).synthesize}\n */\n public synthesize<\n O extends IFluidObject,\n // eslint-disable-next-line @typescript-eslint/ban-types\n R extends IFluidObject = {}>(\n optionalTypes: FluidObjectSymbolProvider<O>,\n requiredTypes: FluidObjectSymbolProvider<R>,\n ): AsyncFluidObjectProvider<FluidObjectKey<O>, FluidObjectKey<R>> {\n const optionalValues = Object.values(optionalTypes);\n const requiredValues = Object.values(requiredTypes);\n\n // There was nothing passed in so we can return\n if (optionalValues === [] && requiredValues === []) {\n return {} as any;\n }\n\n const required = this.generateRequired<R>(requiredTypes);\n const optional = this.generateOptional<O>(optionalTypes);\n return { ...required, ...optional };\n }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).has}\n */\n public has(...types: (keyof IFluidObject)[]): boolean {\n return types.every((type) => {\n return this.providers.has(type);\n });\n }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).getProvider}\n */\n public getProvider<T extends keyof IFluidObject>(type: T): FluidObjectProvider<T> | undefined {\n // If we have the provider return it\n const provider = this.providers.get(type);\n if (provider) {\n return provider;\n }\n\n if (this.parent) {\n return this.parent.getProvider(type);\n }\n\n return undefined;\n }\n\n private generateRequired<T extends IFluidObject>(\n types: FluidObjectSymbolProvider<T>,\n ) {\n const values: (keyof IFluidObject)[] = Object.values(types);\n return Object.assign({}, ...Array.from(values, (t) => {\n const provider = this.getProvider(t);\n if (!provider) {\n throw new Error(`Object attempted to be created without registered required provider ${t}`);\n }\n\n return this.resolveProvider(provider, t);\n }));\n }\n\n private generateOptional<T extends IFluidObject>(\n types: FluidObjectSymbolProvider<T>,\n ) {\n const values: (keyof IFluidObject)[] = Object.values(types);\n return Object.assign({}, ...Array.from(values, (t) => {\n const provider = this.getProvider(t);\n if (!provider) {\n return { get [t]() { return Promise.resolve(undefined); } };\n }\n\n return this.resolveProvider(provider, t);\n }));\n }\n\n private resolveProvider<T extends keyof IFluidObject>(provider: FluidObjectProvider<T>, t: keyof IFluidObject) {\n // The double nested gets are required for lazy loading the provider resolution\n if (typeof provider === \"function\") {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const self = this;\n return {\n get [t]() {\n if (provider && typeof provider === \"function\") {\n return Promise.resolve(provider(self)).then((p) => {\n if (p) {\n return p[t];\n }\n });\n }\n },\n };\n }\n\n return {\n get [t]() {\n if (provider) {\n return Promise.resolve(provider).then((p) => {\n if (p) {\n return p[t];\n }\n });\n }\n },\n };\n }\n}\n"]}
1
+ {"version":3,"file":"dependencyContainer.js","sourceRoot":"","sources":["../src/dependencyContainer.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n AsyncFluidObjectProvider,\n FluidObjectSymbolProvider,\n FluidObjectProvider,\n AsyncOptionalFluidObjectProvider,\n AsyncRequiredFluidObjectProvider,\n} from \"./types\";\nimport {\n IFluidDependencySynthesizer,\n} from \"./IFluidDependencySynthesizer\";\n\n/**\n * DependencyContainer is similar to a IoC Container. It takes providers and will\n * synthesize an object based on them when requested.\n */\nexport class DependencyContainer<TMap> implements IFluidDependencySynthesizer {\n private readonly providers = new Map<keyof TMap, FluidObjectProvider<any>>();\n private readonly parents: IFluidDependencySynthesizer[];\n public get IFluidDependencySynthesizer() { return this; }\n\n public constructor(... parents: (IFluidDependencySynthesizer | undefined)[]) {\n this.parents = parents.filter((v): v is IFluidDependencySynthesizer => v !== undefined);\n }\n\n /**\n * Add a new provider\n * @param type - Name of the Type T being provided\n * @param provider - A provider that will resolve the T correctly when asked\n * @throws - If passing a type that's already registered\n */\n public register<T extends keyof TMap = keyof TMap>(type: T, provider: FluidObjectProvider<Pick<TMap, T>>): void {\n if (this.providers.has(type)) {\n throw new Error(`Attempting to register a provider of type ${type} that already exists`);\n }\n\n this.providers.set(type, provider);\n }\n\n /**\n * Remove a provider\n * @param type - Name of the provider to remove\n */\n public unregister(type: keyof TMap): void {\n if (this.providers.has(type)) {\n this.providers.delete(type);\n }\n }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).synthesize}\n */\n public synthesize<O, R = undefined | Record<string, never>>(\n optionalTypes: FluidObjectSymbolProvider<O>,\n requiredTypes: Required<FluidObjectSymbolProvider<R>>,\n ): AsyncFluidObjectProvider<O, R> {\n const base: AsyncFluidObjectProvider<O, R> = {} as any;\n this.generateRequired<R>(base, requiredTypes);\n this.generateOptional<O>(base, optionalTypes);\n Object.defineProperty(base, IFluidDependencySynthesizer, { get: () => this });\n return base;\n }\n\n /**\n * {@inheritDoc (IFluidDependencySynthesizer:interface).has}\n * @param excludeParents - If true, exclude checking parent registries\n */\n public has(type: string, excludeParents?: boolean): boolean {\n if (this.providers.has(type as keyof TMap)) {\n return true;\n }\n if (excludeParents !== true) {\n return this.parents.some((p: IFluidDependencySynthesizer) => p.has(type));\n }\n return false;\n }\n\n private generateRequired<T>(\n base: AsyncRequiredFluidObjectProvider<T>,\n types: Required<FluidObjectSymbolProvider<T>>,\n ) {\n if(types === undefined) return;\n for(const key of Object.keys(types) as unknown as (keyof TMap)[]) {\n const provider = this.resolveProvider(key);\n if(provider === undefined) {\n throw new Error(`Object attempted to be created without registered required provider ${key}`);\n }\n Object.defineProperty(\n base,\n key,\n provider,\n );\n }\n }\n\n private generateOptional<T>(\n base: AsyncOptionalFluidObjectProvider<T>,\n types: FluidObjectSymbolProvider<T>,\n ) {\n if(types === undefined) return;\n for(const key of Object.keys(types) as unknown as (keyof TMap)[]) {\n // back-compat: in 0.56 we allow undefined in the types, but we didn't before\n // this will keep runtime back compat, eventually we should support undefined properties\n // rather than properties that return promises that resolve to undefined\n const provider = this.resolveProvider(key) ?? {get:()=>Promise.resolve(undefined)};\n Object.defineProperty(\n base,\n key,\n provider,\n );\n }\n }\n\n private resolveProvider<T extends keyof TMap>(t: T): PropertyDescriptor | undefined {\n // If we have the provider return it\n const provider = this.providers.get(t);\n if (provider === undefined) {\n for(const parent of this.parents) {\n const sp = { [t]: t } as FluidObjectSymbolProvider<Pick<TMap, T>>;\n const syn = parent.synthesize<Pick<TMap, T>,{}>(\n sp,\n {});\n const descriptor = Object.getOwnPropertyDescriptor(syn, t);\n if (descriptor !== undefined) {\n return descriptor;\n }\n }\n return undefined;\n }\n\n // The double nested gets are required for lazy loading the provider resolution\n if (typeof provider === \"function\") {\n return {\n get() {\n if (provider && typeof provider === \"function\") {\n return Promise.resolve(this[IFluidDependencySynthesizer])\n .then(async (fds): Promise<any> => provider(fds))\n .then((p) => p?.[t]);\n }\n },\n };\n }\n return {\n get() {\n if (provider) {\n return Promise.resolve(provider).then((p) => {\n if (p) {\n return p[t];\n }\n });\n }\n },\n };\n }\n}\n"]}
package/lib/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport { IFluidObject } from \"@fluidframework/core-interfaces\";\nimport { DependencyContainer } from \"./dependencyContainer\";\n\nexport type FluidObjectKey<T extends IFluidObject> = keyof T & keyof IFluidObject;\n\n/**\n * This is a condensed version of Record that requires the object has all\n * the IFluidObject properties as its type mapped to a string representation\n * of that property.\n *\n * @example - \\{ IFoo: \"IFoo\" \\}\n */\nexport type FluidObjectSymbolProvider<T extends IFluidObject> = {\n [P in FluidObjectKey<T>]: FluidObjectKey<T> & P;\n};\n\n/**\n * This is a condensed version of Record that requires the object has all\n * the IFluidObject properties as its type mapped to an object that implements\n * the property.\n */\nexport type AsyncRequiredFluidObjectProvider<T extends keyof IFluidObject> = {\n [P in T]: Promise<NonNullable<IFluidObject[P]>>\n};\n\n/**\n * This is a condensed version of Record that requires the object has all\n * the IFluidObject properties as its type, mapped to an object that implements\n * the property or undefined.\n */\nexport type AsyncOptionalFluidObjectProvider<T extends keyof IFluidObject> = {\n [P in T]: Promise<IFluidObject[P] | undefined>;\n};\n\n/**\n * Combined type for Optional and Required Async Fluid object Providers\n */\nexport type AsyncFluidObjectProvider<O extends keyof IFluidObject, R extends keyof IFluidObject>\n = AsyncOptionalFluidObjectProvider<O> & AsyncRequiredFluidObjectProvider<R>;\n\n/**\n * Provided a keyof IFluidObject will ensure the type is an instance of that type\n */\nexport type NonNullableFluidObject<T extends keyof IFluidObject> = NonNullable<IFluidObject[T]>;\n\n/**\n * Multiple ways to provide a Fluid object.\n */\nexport type FluidObjectProvider<T extends keyof IFluidObject> =\n NonNullableFluidObject<T>\n | Promise<NonNullableFluidObject<T>>\n | ((dependencyContainer: DependencyContainer) => NonNullableFluidObject<T>)\n | ((dependencyContainer: DependencyContainer) => Promise<NonNullableFluidObject<T>>);\n\n/**\n * ProviderEntry is a mapping of the type to the Provider\n */\nexport interface ProviderEntry<T extends keyof IFluidObject> {\n type: T;\n provider: FluidObjectProvider<T>\n}\n\n/**\n * A mapping of ProviderEntries\n */\nexport type DependencyContainerRegistry = Iterable<ProviderEntry<any>>;\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport { IFluidDependencySynthesizer } from \".\";\n/**\n * This is a condensed version of Record that requires the object has all\n * the IFluidObject properties as its type mapped to a string representation\n * of that property.\n *\n * @example - \\{ IFoo: \"IFoo\" \\}\n */\nexport type FluidObjectSymbolProvider<T> = {\n [P in keyof T]?: P;\n};\n\n/**\n * This is a condensed version of Record that requires the object has all\n * the IFluidObject properties as its type mapped to an object that implements\n * the property.\n */\nexport type AsyncRequiredFluidObjectProvider<T> = T extends undefined ? Record<string, never> : {\n [P in keyof T]: Promise<NonNullable<Exclude<T[P], undefined | null>>>\n};\n\n/**\n * This is a condensed version of Record that requires the object has all\n * the IFluidObject properties as its type, mapped to an object that implements\n * the property or undefined.\n */\nexport type AsyncOptionalFluidObjectProvider<T> = T extends undefined\n ? Record<string, never>\n : {\n [P in keyof T]?: Promise<T[P] | undefined>;\n };\n\n/**\n * Combined type for Optional and Required Async Fluid object Providers\n */\nexport type AsyncFluidObjectProvider<O, R = undefined>\n = AsyncOptionalFluidObjectProvider<O> & AsyncRequiredFluidObjectProvider<R>;\n\n/**\n * Multiple ways to provide a Fluid object.\n */\nexport type FluidObjectProvider<T> =\n NonNullable<T>\n | Promise<NonNullable<T>>\n | ((dependencyContainer: IFluidDependencySynthesizer) => NonNullable<T>)\n | ((dependencyContainer: IFluidDependencySynthesizer) => Promise<NonNullable<T>>);"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/synthesize",
3
- "version": "0.54.2",
3
+ "version": "0.56.0-49831",
4
4
  "description": "A library for synthesizing scope objects.",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": "https://github.com/microsoft/FluidFramework",
@@ -26,7 +26,7 @@
26
26
  "ci:build:docs": "api-extractor run --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/* ../../../_api-extractor-temp/",
27
27
  "clean": "rimraf dist lib *.tsbuildinfo *.build.log",
28
28
  "eslint": "eslint --format stylish src",
29
- "eslint:fix": "eslint --format stylish src --fix",
29
+ "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
30
30
  "lint": "npm run eslint",
31
31
  "lint:fix": "npm run eslint:fix",
32
32
  "test": "npm run test:mocha",
@@ -57,29 +57,28 @@
57
57
  ],
58
58
  "temp-directory": "nyc/.nyc_output"
59
59
  },
60
- "dependencies": {
61
- "@fluidframework/core-interfaces": "^0.41.0"
62
- },
63
60
  "devDependencies": {
64
61
  "@fluidframework/build-common": "^0.23.0",
65
- "@fluidframework/datastore": "^0.54.2",
66
- "@fluidframework/eslint-config-fluid": "^0.24.0",
67
- "@fluidframework/mocha-test-setup": "^0.54.2",
62
+ "@fluidframework/core-interfaces": "^0.42.0-0",
63
+ "@fluidframework/datastore": "0.56.0-49831",
64
+ "@fluidframework/eslint-config-fluid": "^0.25.0",
65
+ "@fluidframework/mocha-test-setup": "0.56.0-49831",
68
66
  "@microsoft/api-extractor": "^7.16.1",
67
+ "@rushstack/eslint-config": "^2.5.1",
69
68
  "@types/mocha": "^8.2.2",
70
69
  "@types/node": "^14.18.0",
71
- "@typescript-eslint/eslint-plugin": "~4.14.0",
72
- "@typescript-eslint/parser": "~4.14.0",
70
+ "@typescript-eslint/eslint-plugin": "~5.9.0",
71
+ "@typescript-eslint/parser": "~5.9.0",
73
72
  "concurrently": "^6.2.0",
74
73
  "copyfiles": "^2.1.0",
75
74
  "cross-env": "^7.0.2",
76
- "eslint": "~7.18.0",
75
+ "eslint": "~8.6.0",
76
+ "eslint-plugin-editorconfig": "~3.2.0",
77
77
  "eslint-plugin-eslint-comments": "~3.2.0",
78
- "eslint-plugin-import": "~2.22.1",
78
+ "eslint-plugin-import": "~2.25.4",
79
79
  "eslint-plugin-no-null": "~1.0.2",
80
- "eslint-plugin-prefer-arrow": "~1.2.2",
81
- "eslint-plugin-react": "~7.22.0",
82
- "eslint-plugin-unicorn": "~26.0.1",
80
+ "eslint-plugin-react": "~7.28.0",
81
+ "eslint-plugin-unicorn": "~40.0.0",
83
82
  "mocha": "^8.4.0",
84
83
  "nyc": "^15.0.0",
85
84
  "rimraf": "^2.6.2",