mirror of
https://github.com/stoatchat/javascript-client-sdk.git
synced 2026-07-16 07:04:24 -04:00
feat: esm + unreads util
This commit is contained in:
@@ -2,11 +2,13 @@
|
||||
|
||||
 
|
||||
|
||||
**revolt.js** is a direct implementation of the entire Revolt API and provides a way to authenticate and start communicating with Revolt servers.
|
||||
**revolt.js** is a direct implementation of the entire Revolt API and provides a way to authenticate and start communicating with Revolt servers. **This is an ESM library!**
|
||||
|
||||
## Example Usage
|
||||
|
||||
```typescript
|
||||
import { Client } from "revolt.js";
|
||||
|
||||
let client = new Client();
|
||||
|
||||
client.on("ready", async () =>
|
||||
|
||||
+6
-2
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"type": "module",
|
||||
"name": "revolt.js",
|
||||
"version": "5.1.0-alpha.15",
|
||||
"version": "5.2.0",
|
||||
"main": "dist/index.js",
|
||||
"repository": "https://github.com/revoltchat/revolt.js",
|
||||
"author": "Paul Makles <insrt.uk>",
|
||||
@@ -11,6 +12,7 @@
|
||||
"exponential-backoff": "^3.1.0",
|
||||
"isomorphic-ws": "^4.0.1",
|
||||
"lodash.defaultsdeep": "^4.6.1",
|
||||
"lodash.flatten": "^4.4.0",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"mobx": "^6.3.2",
|
||||
"revolt-api": "^0.5.3-alpha.9",
|
||||
@@ -21,6 +23,7 @@
|
||||
"@types/events": "^3.0.0",
|
||||
"@types/lodash": "^4.14.168",
|
||||
"@types/lodash.defaultsdeep": "^4.6.6",
|
||||
"@types/lodash.flatten": "^4.4.6",
|
||||
"@types/lodash.isequal": "^4.5.5",
|
||||
"@types/node": "^14.14.31",
|
||||
"@types/ws": "^7.2.1",
|
||||
@@ -28,6 +31,7 @@
|
||||
"@typescript-eslint/parser": "^5.3.1",
|
||||
"dotenv": "^8.2.0",
|
||||
"eslint": "^8.2.0",
|
||||
"esm": "^3.2.25",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-typedoc": "^3.0.1",
|
||||
"in-publish": "^2.0.1",
|
||||
@@ -68,7 +72,7 @@
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "tsc-watch --onSuccess \"node dist/tester\"",
|
||||
"dev": "tsc-watch --onSuccess \"node --experimental-specifier-resolution=node dist/tester\"",
|
||||
"prepublish": "in-publish && tsc || echo Skipping build.",
|
||||
"build": "rimraf dist && tsc",
|
||||
"build:watch": "tsc-watch",
|
||||
|
||||
+24
-6
@@ -1,7 +1,7 @@
|
||||
import Axios, { AxiosInstance, AxiosRequestConfig } from "axios";
|
||||
import { EventEmitter } from "eventemitter3";
|
||||
import EventEmitter from "eventemitter3";
|
||||
import defaultsDeep from "lodash.defaultsdeep";
|
||||
import { action, makeObservable, observable } from "mobx";
|
||||
import { action, makeObservable, observable, runInAction } from "mobx";
|
||||
import type { Session } from "revolt-api/types/Auth";
|
||||
import type { SizeOptions } from "revolt-api/types/Autumn";
|
||||
import type { RevoltConfiguration } from "revolt-api/types/Core";
|
||||
@@ -21,6 +21,7 @@ import { ClientboundNotification } from "./websocket/notifications";
|
||||
|
||||
import { defaultConfig } from "./config";
|
||||
import { Nullable } from "./util/null";
|
||||
import Unreads from "./util/Unreads";
|
||||
|
||||
/**
|
||||
* Client options object
|
||||
@@ -28,7 +29,9 @@ import { Nullable } from "./util/null";
|
||||
export interface ClientOptions {
|
||||
apiURL: string;
|
||||
debug: boolean;
|
||||
|
||||
cache: boolean;
|
||||
unreads: boolean;
|
||||
|
||||
heartbeat: number;
|
||||
autoReconnect: boolean;
|
||||
@@ -108,6 +111,8 @@ export class Client extends EventEmitter {
|
||||
messages: Messages;
|
||||
bots: Bots;
|
||||
|
||||
unreads?: Unreads;
|
||||
|
||||
constructor(options: Partial<ClientOptions> = {}) {
|
||||
super();
|
||||
|
||||
@@ -137,6 +142,10 @@ export class Client extends EventEmitter {
|
||||
this.options = defaultsDeep(options, defaultConfig);
|
||||
if (this.options.cache) throw "Cache is not supported yet.";
|
||||
|
||||
if (this.options.unreads) {
|
||||
this.unreads = new Unreads(this);
|
||||
}
|
||||
|
||||
this.Axios = Axios.create({ baseURL: this.apiURL });
|
||||
this.websocket = new WebSocketClient(this);
|
||||
this.heartbeat = this.options.heartbeat;
|
||||
@@ -161,14 +170,23 @@ export class Client extends EventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
this.on("ready", () => {
|
||||
if (this.options.unreads) {
|
||||
this.unreads!.sync();
|
||||
}
|
||||
});
|
||||
|
||||
this.on("message", async (message) => {
|
||||
const channel = message.channel;
|
||||
if (!channel) return;
|
||||
if (channel.channel_type === "DirectMessage") {
|
||||
channel.active = true;
|
||||
}
|
||||
|
||||
channel.last_message_id = message._id;
|
||||
runInAction(() => {
|
||||
if (channel.channel_type === "DirectMessage") {
|
||||
channel.active = true;
|
||||
}
|
||||
|
||||
channel.last_message_id = message._id;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ export const defaultConfig = {
|
||||
autoReconnect: true,
|
||||
heartbeat: 30,
|
||||
debug: false,
|
||||
|
||||
cache: false,
|
||||
unreads: false,
|
||||
|
||||
ackRateLimiter: true,
|
||||
};
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
U32_MAX,
|
||||
UserPermission,
|
||||
} from "../api/permissions";
|
||||
import { INotificationChecker } from "../util/Unreads";
|
||||
|
||||
export class Channel {
|
||||
client: Client;
|
||||
@@ -146,6 +147,13 @@ export class Channel {
|
||||
return this.client.messages.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last message ID if it is present or the origin timestamp.
|
||||
*/
|
||||
get last_message_id_or_past() {
|
||||
return this.last_message_id ?? "0";
|
||||
}
|
||||
|
||||
/**
|
||||
* Group recipients.
|
||||
* @requires `Group`
|
||||
@@ -170,6 +178,40 @@ export class Channel {
|
||||
return decodeTime(this._id);
|
||||
}
|
||||
|
||||
@computed isUnread(permit: INotificationChecker) {
|
||||
if (permit.isMuted(this)) return false;
|
||||
return this.unread;
|
||||
}
|
||||
|
||||
@computed getMentions(permit: INotificationChecker) {
|
||||
if (permit.isMuted(this)) return [];
|
||||
return this.mentions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether this channel is unread.
|
||||
*/
|
||||
get unread() {
|
||||
if (!this.last_message_id
|
||||
|| this.channel_type === 'SavedMessages'
|
||||
|| this.channel_type === 'VoiceChannel') return false;
|
||||
|
||||
return (
|
||||
(
|
||||
this.client.unreads?.getUnread(this._id)?.last_id ?? "0"
|
||||
).localeCompare(this.last_message_id) === -1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mentions in this channel for user.
|
||||
*/
|
||||
get mentions() {
|
||||
if (this.channel_type === 'SavedMessages'
|
||||
|| this.channel_type === 'VoiceChannel') return [];
|
||||
return this.client.unreads?.getUnread(this._id)?.mentions ?? [];
|
||||
}
|
||||
|
||||
constructor(client: Client, data: ChannelI) {
|
||||
this.client = client;
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import Collection from "./Collection";
|
||||
import { User } from "./Users";
|
||||
import { Client, FileArgs } from "..";
|
||||
import { decodeTime } from "ulid";
|
||||
import { INotificationChecker } from "../util/Unreads";
|
||||
|
||||
export class Server {
|
||||
client: Client;
|
||||
@@ -50,6 +51,21 @@ export class Server {
|
||||
return decodeTime(this._id);
|
||||
}
|
||||
|
||||
@computed isUnread(permit?: INotificationChecker) {
|
||||
if (permit?.isMuted(this)) return false;
|
||||
return this.channels.find((channel) =>
|
||||
!permit?.isMuted(channel) && channel?.unread);
|
||||
}
|
||||
|
||||
@computed getMentions(permit?: INotificationChecker) {
|
||||
if (permit?.isMuted(this)) return [];
|
||||
const arr = this.channels
|
||||
.filter(channel => !permit?.isMuted(channel))
|
||||
.map((channel) => channel?.mentions) as string[][];
|
||||
|
||||
return arr[0].concat(...arr.slice(1));
|
||||
}
|
||||
|
||||
constructor(client: Client, data: ServerI) {
|
||||
this.client = client;
|
||||
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
import { Client } from "../Client";
|
||||
import {
|
||||
action,
|
||||
computed,
|
||||
makeAutoObservable,
|
||||
ObservableMap,
|
||||
runInAction,
|
||||
} from "mobx";
|
||||
import type { ChannelUnread } from "revolt-api/types/Sync";
|
||||
import { ulid } from "ulid";
|
||||
import { Channel } from "../maps/Channels";
|
||||
import { Server } from "../maps/Servers";
|
||||
|
||||
export interface INotificationChecker {
|
||||
isMuted(target?: Channel | Server): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles channel unreads.
|
||||
*/
|
||||
export default class Unreads {
|
||||
private client: Client;
|
||||
private channels: ObservableMap<string, Omit<ChannelUnread, "_id">>;
|
||||
|
||||
/**
|
||||
* Construct new Unreads store.
|
||||
*/
|
||||
constructor(client: Client) {
|
||||
this.channels = new ObservableMap();
|
||||
makeAutoObservable(this);
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync unread data from the server.
|
||||
*/
|
||||
async sync() {
|
||||
const unreads = await this.client.syncFetchUnreads();
|
||||
runInAction(() => {
|
||||
for (const unread of unreads) {
|
||||
const { _id, ...data } = unread;
|
||||
this.channels.set(_id.channel, data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get channel unread object for a given channel.
|
||||
* @param channel_id Target channel ID
|
||||
* @returns Partial channel unread object
|
||||
*/
|
||||
@computed getUnread(channel_id: string) {
|
||||
return this.channels.get(channel_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a channel as unread by setting a custom last_id.
|
||||
* @param channel_id Target channel ID
|
||||
* @param last_id New last ID
|
||||
*/
|
||||
@action markUnread(channel_id: string, last_id: string) {
|
||||
this.channels.set(channel_id, {
|
||||
...this.getUnread(channel_id),
|
||||
last_id,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a mention to a channel unread.
|
||||
* @param channel_id Target channel ID
|
||||
* @param message_id Target message ID
|
||||
*/
|
||||
@action markMention(channel_id: string, message_id: string) {
|
||||
const unread = this.getUnread(channel_id);
|
||||
this.channels.set(channel_id, {
|
||||
last_id: "0",
|
||||
...unread,
|
||||
mentions: [...(unread?.mentions ?? []), message_id],
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a channel as read.
|
||||
* @param channel_id Target channel ID
|
||||
* @param message_id Target message ID (last sent in channel)
|
||||
* @param emit Whether to emit to server
|
||||
* @param skipRateLimiter Whether to skip the rate limiter
|
||||
*/
|
||||
@action markRead(
|
||||
channel_id: string,
|
||||
message_id?: string,
|
||||
emit = false,
|
||||
skipRateLimiter = false,
|
||||
) {
|
||||
const last_id = message_id ?? ulid();
|
||||
this.channels.set(channel_id, { last_id });
|
||||
|
||||
if (emit) {
|
||||
this.client.channels.get(channel_id)?.ack(last_id, skipRateLimiter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark multiple channels as read.
|
||||
* @param channel_ids Target channel IDs
|
||||
*/
|
||||
@action markMultipleRead(channel_ids: string[]) {
|
||||
const last_id = ulid();
|
||||
for (const channel_id of channel_ids) {
|
||||
this.channels.set(channel_id, { last_id });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -445,8 +445,13 @@ export class WebSocketClient {
|
||||
break;
|
||||
}
|
||||
|
||||
case "ChannelAck":
|
||||
case "ChannelAck": {
|
||||
this.client.unreads?.markRead(
|
||||
packet.id,
|
||||
packet.message_id,
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case "Pong": {
|
||||
this.ping = +new Date() - packet.data;
|
||||
|
||||
+55
-57
@@ -1,63 +1,61 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Basic Options */
|
||||
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
|
||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
||||
// "lib": [], /* Specify library files to be included in the compilation. */
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
"declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
"outDir": "./dist", /* Redirect output structure to the directory. */
|
||||
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
// "noEmit": true, /* Do not emit outputs. */
|
||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||
"compilerOptions": {
|
||||
/* Basic Options */
|
||||
"target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
|
||||
"module": "ES6" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
|
||||
// "lib": [], /* Specify library files to be included in the compilation. */
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
"declaration": true /* Generates corresponding '.d.ts' file. */,
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
"outDir": "./dist" /* Redirect output structure to the directory. */,
|
||||
"rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
// "noEmit": true, /* Do not emit outputs. */
|
||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
||||
"strictPropertyInitialization": false, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": true /* Enable all strict type-checking options. */,
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
||||
"strictPropertyInitialization": false /* Enable strict checking of property initialization in classes. */,
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
|
||||
/* Module Resolution Options */
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
/* Module Resolution Options */
|
||||
"moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
|
||||
/* Source Map Options */
|
||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
/* Source Map Options */
|
||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
|
||||
/* Experimental Options */
|
||||
"experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
},
|
||||
"include": [
|
||||
"src/*"
|
||||
]
|
||||
}
|
||||
/* Experimental Options */
|
||||
"experimentalDecorators": true /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
},
|
||||
"include": ["src/*"]
|
||||
}
|
||||
|
||||
@@ -69,6 +69,13 @@
|
||||
dependencies:
|
||||
"@types/lodash" "*"
|
||||
|
||||
"@types/lodash.flatten@^4.4.6":
|
||||
version "4.4.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash.flatten/-/lodash.flatten-4.4.6.tgz#b74c3267c87e44e603137d4621e8a9396b6551f5"
|
||||
integrity sha512-omCBl4M8EJSmf2DZqh4/zwjgXQpzC7YO/PXTcG8rI9r7xun8CohrHeNx8HZRkqWc61uJfIaZop9MwJEXPVssHw==
|
||||
dependencies:
|
||||
"@types/lodash" "*"
|
||||
|
||||
"@types/lodash.isequal@^4.5.5":
|
||||
version "4.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash.isequal/-/lodash.isequal-4.5.5.tgz#4fed1b1b00bef79e305de0352d797e9bb816c8ff"
|
||||
@@ -912,6 +919,11 @@ eslint@^8.2.0:
|
||||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
esm@^3.2.25:
|
||||
version "3.2.25"
|
||||
resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10"
|
||||
integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==
|
||||
|
||||
espree@^9.0.0:
|
||||
version "9.0.0"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-9.0.0.tgz#e90a2965698228502e771c7a58489b1a9d107090"
|
||||
@@ -1920,6 +1932,11 @@ lodash.defaultsdeep@^4.6.1:
|
||||
resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6"
|
||||
integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==
|
||||
|
||||
lodash.flatten@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
|
||||
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
|
||||
|
||||
lodash.isequal@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||
|
||||
Reference in New Issue
Block a user