Typescript

This commit is contained in:
Max Hoffmann 2023-09-20 18:47:25 -07:00
parent cffd3ef2f9
commit b3e34bc5df
No known key found for this signature in database
GPG Key ID: 3015B3271A63BCAE
94 changed files with 2253 additions and 1370 deletions

View File

@ -1,12 +0,0 @@
{
"env": {
"test": {
"plugins": [
"transform-class-properties",
"transform-object-rest-spread",
"transform-es2015-modules-commonjs",
"transform-es2015-classes"
]
}
}
}

View File

@ -1,15 +1,27 @@
const path = require('path');
module.exports = {
extends: ['plugin:@shopify/esnext', 'plugin:@shopify/jest', 'plugin:@shopify/prettier'],
extends: [
'plugin:@shopify/typescript',
'plugin:@shopify/jest',
'plugin:@shopify/prettier',
],
parser: '@typescript-eslint/parser',
env: {
browser: true,
node: true,
},
rules: {
'import/no-unresolved': 'off',
'import/no-extraneous-dependencies': 'off',
'class-methods-use-this': 'off',
'line-comment-position': 0,
'lines-around-comment': 'off',
'jest/valid-title': 'off',
},
settings: {
'import/resolver': {
node: {
paths: [
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'test'),
],
},
},
},
};

View File

@ -25,5 +25,11 @@ jobs:
- name: Lint
run: yarn lint
- name: Library typecheck
run: yarn type-check
- name: Scripts typecheck
run: yarn type-check:scripts
- name: Test
run: yarn test

View File

@ -1,7 +1 @@
{
"trailingComma": "all",
"printWidth": 120,
"singleQuote": true,
"bracketSpacing": false,
"arrowParens": "always"
}
"@shopify/prettier-config"

11
.vscode/launch.json vendored
View File

@ -1,21 +1,16 @@
{
"version": "0.2.0",
"version": "1.0.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Jest Tests",
"program": "${workspaceRoot}/node_modules/jest/bin/jest.js",
"program": "${workspaceRoot}/node_modules/.bin/jest",
"console": "integratedTerminal",
"args": [
"--config",
"config.json",
"-i",
"--watchAll"
],
"internalConsoleOptions": "openOnSessionStart",
"outFiles": [
"${workspaceRoot}/dist/**/*"
],
}
]
}

View File

@ -9,6 +9,9 @@
"**/node_modules": true,
"lib": true
},
"[typescript]": {
"editor.formatOnSave": false,
},
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true

View File

@ -14,21 +14,21 @@ orientation.
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
- The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities

View File

@ -7,10 +7,10 @@ appreciated and encouraged.
1. [Code of Conduct](#code-of-conduct)
2. [How to contribute](#how-to-contribute)
1. [Creating issues](#creating-issues)
2. [Opening pull requests](#opening-pull-requests)
3. [JS Docblocks](#js-docblocks)
4. [How to run locally](#how-to-run-locally)
1. [Creating issues](#creating-issues)
2. [Opening pull requests](#opening-pull-requests)
3. [JS Docblocks](#js-docblocks)
3. [How to run locally](#how-to-run-locally)
## Code of Conduct

View File

@ -1,17 +0,0 @@
{
"testEnvironment": "jsdom",
"testMatch": ["<rootDir>/src/**/*.test.js"],
"setupFiles": ["<rootDir>/scripts/test/environment.js"],
"setupFilesAfterEnv": ["<rootDir>/scripts/test/setup.js"],
"transform": {".*": "<rootDir>/node_modules/babel-jest"},
"moduleFileExtensions": ["js"],
"collectCoverageFrom": [
"src/**/*.js",
"!src/**/*/index.js",
"!src/index.js",
"!src/index.legacy.js"
],
"coverageDirectory": "./coverage/",
"collectCoverage": true,
"moduleDirectories": ["node_modules", "src", "scripts/test"]
}

1121
index.d.ts vendored

File diff suppressed because it is too large Load Diff

31
jest.config.js Normal file
View File

@ -0,0 +1,31 @@
module.exports = {
testEnvironment: 'jsdom',
testMatch: ['<rootDir>/src/**/*.test.(js|ts)'],
setupFiles: ['<rootDir>/test/environment.ts'],
setupFilesAfterEnv: ['<rootDir>/test/setup.ts'],
transform: {
'\\.(ts|js)': [
'babel-jest',
{
babelrc: false,
presets: [
['@shopify/babel-preset', {typescript: true, isWebpack5: true}],
],
sourceMaps: 'inline',
},
],
},
moduleFileExtensions: ['js', 'ts'],
collectCoverageFrom: [
'src/**/*.js',
'!src/**/*/index.js',
'!src/index.js',
'!src/index.legacy.js',
],
moduleNameMapper: {
'shared/(.*)': '<rootDir>/src/shared/$1',
},
coverageDirectory: './coverage/',
collectCoverage: true,
moduleDirectories: ['node_modules', 'src', 'test'],
};

View File

@ -1,5 +0,0 @@
{
"compilerOptions": {
"baseUrl": "./src/"
}
}

View File

@ -27,15 +27,18 @@
"scripts": {
"start": "concurrently \"yarn watch\" \"cd examples && yarn && yarn start\"",
"build": "yarn build:production",
"watch": "node scripts/watch.js",
"watch": "ts-node --project='./scripts/tsconfig.json' ./scripts/watch.ts",
"prepare": "yarn build:development",
"prepublishOnly": "yarn build:production",
"lint": "eslint ./src ./scripts --max-warnings 0",
"lint": "eslint ./src ./scripts ./test --max-warnings 0",
"type-check": "tsc --noEmit",
"type-check:scripts": "tsc --noEmit --project scripts",
"esdoc": "esdoc -c esdoc.json",
"test": "jest --config config.json",
"test-ci": "jest --config config.json --coverage && codecov",
"build:development": "node scripts/build.js",
"build:production": "node scripts/build.js --production"
"test": "jest",
"test-ci": "jest --coverage && codecov",
"build:development": "ts-node --project='./scripts/tsconfig.json' ./scripts/build.ts",
"build:production": "ts-node --project='./scripts/tsconfig.json' ./scripts/build.ts --production",
"verify": "yarn lint && yarn type-check && yarn type-check:scripts && yarn build && yarn test"
},
"files": [
"lib/**/*.js",
@ -43,14 +46,17 @@
],
"devDependencies": {
"@babel/core": "^7.22.20",
"@microsoft/tsdoc": "^0.14.2",
"@shopify/babel-preset": "^25.0.0",
"@shopify/eslint-plugin": "^43.0.0",
"@shopify/prettier-config": "^1.1.2",
"@shopify/typescript-configs": "^5.1.0",
"@types/jest": "^29.5.5",
"@types/node": "^20.6.3",
"@types/webpack": "^5.28.2",
"@types/webpack-bundle-analyzer": "^4.6.0",
"babel-jest": "^29.7.0",
"babel-loader": "^9.1.3",
"babel-plugin-transform-class-properties": "^7.0.0-beta.3",
"babel-plugin-transform-es2015-classes": "^7.0.0-beta.3",
"babel-plugin-transform-es2015-modules-commonjs": "^7.0.0-beta.3",
"babel-plugin-transform-object-rest-spread": "^7.0.0-beta.3",
"babel-preset-shopify": "^21.0.0",
"codecov": "^3.0.2",
"concurrently": "^3.5.1",
@ -59,10 +65,15 @@
"esdoc-ecmascript-proposal-plugin": "^1.0.0",
"esdoc-standard-plugin": "^1.0.0",
"eslint": "^8.49.0",
"eslint-plugin-tsdoc": "^0.2.17",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"prettier": "^3.0.3",
"timers": "^0.1.1",
"ts-jest": "^29.1.1",
"ts-loader": "^9.4.4",
"ts-node": "^10.9.1",
"typescript": "^5.2.2",
"webpack": "^5.88.2",
"webpack-bundle-analyzer": "^4.9.1",
"webpack-cli": "^5.1.4"

View File

@ -1,16 +0,0 @@
const webpack = require('webpack');
const {isProd, useAnalyser} = require('./build/config');
const {createConfig: createDevelopmentConfig} = require('./build/development');
const {createConfig: createProductionConfig} = require('./build/production');
const {runner} = require('./build/utils');
let compiler;
if (isProd) {
compiler = webpack(createProductionConfig({analyser: useAnalyser}));
} else {
compiler = webpack(createDevelopmentConfig({analyser: useAnalyser}));
}
compiler.run(runner);

16
scripts/build.ts Normal file
View File

@ -0,0 +1,16 @@
import webpack from 'webpack';
import {isProd, useAnalyser} from './build/config';
import {createConfig as createDevelopmentConfig} from './build/development';
import {createConfig as createProductionConfig} from './build/production';
import {runner} from './build/runner';
let compiler;
if (isProd) {
compiler = webpack(createProductionConfig({analyser: useAnalyser}));
} else {
compiler = webpack(createDevelopmentConfig({analyser: useAnalyser}));
}
compiler.run(runner);

View File

@ -1,4 +1,11 @@
const bundles = [
export interface Bundle {
name: string;
filename: string;
source: string;
path?: string;
}
export const bundles: Bundle[] = [
{
name: 'Draggable',
filename: 'draggable.bundle',
@ -76,5 +83,3 @@ const bundles = [
path: 'plugins/',
},
];
module.exports = {bundles};

View File

@ -1,15 +0,0 @@
const args = process.argv.filter((value, index) => index >= 2);
const useAnalyser = args.find((value) => value === '--analyser');
const isProd = args.find((value) => value === '--production');
const rootPath = `${__dirname}/../../`;
const targetPath = isProd ? `${rootPath}lib/` : `${rootPath}examples/packages/@shopify/draggable`;
const resolveModules = ['node_modules', 'src/'];
module.exports = {
isProd,
rootPath,
targetPath,
resolveModules,
useAnalyser,
};

9
scripts/build/config.ts Normal file
View File

@ -0,0 +1,9 @@
const args = process.argv.filter((_, index) => index >= 2);
export const useAnalyser = args.some((value) => value === '--analyser');
export const isProd = args.find((value) => value === '--production');
export const rootPath = `${__dirname}/../../`;
export const targetPath = isProd
? `${rootPath}lib/`
: `${rootPath}examples/packages/@shopify/draggable`;
export const resolveModules = ['node_modules', 'src/'];

View File

@ -1,49 +0,0 @@
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const {targetPath, resolveModules} = require('./config');
function createConfig({analyser}) {
const plugins = [];
const minimize = Boolean(analyser);
if (analyser) {
plugins.push(new BundleAnalyzerPlugin({analyzerMode: 'static', openAnalyzer: false}));
}
return {
mode: 'development',
entry: `./src/index.js`,
output: {
path: targetPath,
filename: `index.js`,
library: 'Draggable',
libraryTarget: 'umd',
umdNamedDefine: true,
},
optimization: {
minimize,
},
resolve: {
modules: resolveModules,
},
plugins,
module: {
rules: [
{
test: /(\.js)$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: {
plugins: [
'transform-class-properties',
'transform-object-rest-spread',
'transform-es2015-modules-commonjs',
],
},
},
],
},
};
}
module.exports = {createConfig};

View File

@ -0,0 +1,56 @@
import type {Configuration} from 'webpack';
import {BundleAnalyzerPlugin} from 'webpack-bundle-analyzer';
import {targetPath, resolveModules} from './config';
interface Options {
analyser?: boolean;
}
export function createConfig({analyser}: Options): Configuration {
const plugins: Configuration['plugins'] = [];
const minimize = Boolean(analyser);
if (analyser) {
plugins.push(
new BundleAnalyzerPlugin({analyzerMode: 'static', openAnalyzer: false}),
);
}
return {
mode: 'development',
entry: `./src/index.js`,
output: {
path: targetPath,
filename: `index.js`,
library: 'Draggable',
libraryTarget: 'umd',
umdNamedDefine: true,
},
optimization: {
minimize,
},
resolve: {
extensions: ['.js', '.ts'],
modules: resolveModules,
},
plugins,
module: {
rules: [
{
test: /(\.js)$/,
loader: 'babel-loader',
exclude: /node_modules/,
},
{
test: /(\.ts)$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
transpileOnly: true,
},
},
],
},
};
}

View File

@ -1,13 +1,19 @@
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
import type {Configuration} from 'webpack';
import {BundleAnalyzerPlugin} from 'webpack-bundle-analyzer';
const {targetPath, resolveModules} = require('./config');
const {bundles} = require('./bundles');
import {targetPath, resolveModules} from './config';
import {bundles} from './bundles';
import type {Bundle} from './bundles';
function createBundleConfig(bundle, {analyser}) {
interface Options {
analyser?: boolean;
}
function createBundleConfig(bundle: Bundle, {analyser}: Options) {
const outputPath = bundle.path || '';
const minimize = Boolean(analyser);
const plugins = [];
const es5Plugins = [];
const plugins: Configuration['plugins'] = [];
const es5Plugins: Configuration['plugins'] = [];
if (analyser) {
plugins.push(
@ -19,7 +25,7 @@ function createBundleConfig(bundle, {analyser}) {
);
}
const config = {
const config: Configuration = {
mode: 'production',
entry: `./src/${bundle.source}.js`,
output: {
@ -33,6 +39,7 @@ function createBundleConfig(bundle, {analyser}) {
minimize,
},
resolve: {
extensions: ['.js', '.ts'],
modules: resolveModules,
},
plugins,
@ -42,12 +49,13 @@ function createBundleConfig(bundle, {analyser}) {
test: /(\.js)$/,
loader: 'babel-loader',
exclude: /node_modules/,
},
{
test: /(\.ts)$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
plugins: [
'transform-class-properties',
'transform-object-rest-spread',
'transform-es2015-modules-commonjs',
],
transpileOnly: true,
},
},
],
@ -81,6 +89,14 @@ function createBundleConfig(bundle, {analyser}) {
presets: [['@shopify/babel-preset']],
},
},
{
test: /(\.ts)$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: {
transpileOnly: true,
},
},
],
},
};
@ -88,8 +104,9 @@ function createBundleConfig(bundle, {analyser}) {
return [config, es5Config];
}
function createConfig(options) {
return bundles.reduce((configs, bundle) => [...configs, ...createBundleConfig(bundle, options)], []);
export function createConfig(options: Options): Configuration[] {
return bundles.reduce<Configuration[]>(
(configs, bundle) => [...configs, ...createBundleConfig(bundle, options)],
[],
);
}
module.exports = {createConfig};

View File

@ -1,10 +1,16 @@
function runner(error, stats) {
import type {Stats, MultiStats} from 'webpack';
export function runner(error?: Error | null, stats?: Stats | MultiStats) {
/* eslint-disable no-console */
if (error) {
console.error(error);
return;
}
if (!stats) {
return;
}
console.log(
stats.toString({
chunks: false,
@ -13,5 +19,3 @@ function runner(error, stats) {
);
/* eslint-enable no-console */
}
module.exports = {runner};

View File

@ -1,23 +0,0 @@
import AbstractPlugin from 'shared/AbstractPlugin';
export class TestPlugin extends AbstractPlugin {
constructor(draggable) {
super(draggable);
jest.spyOn(this, 'attachFunction').mockImplementation();
jest.spyOn(this, 'detachFunction').mockImplementation();
}
attach() {
this.attachFunction();
}
detach() {
this.detachFunction();
}
/* eslint-disable no-empty-function */
attachFunction() {}
detachFunction() {}
/* eslint-enable no-empty-function */
}

12
scripts/tsconfig.json Normal file
View File

@ -0,0 +1,12 @@
{
"extends": "@shopify/typescript-configs/base.json",
"compilerOptions": {
"baseUrl": ".",
"rootDir": "../",
"module": "commonjs",
"target": "es2022",
"esModuleInterop": true,
"useUnknownInCatchVariables": false
},
"include": ["../config/**/*", "./**/*"]
}

View File

@ -1,14 +0,0 @@
const webpack = require('webpack');
const {createConfig: createDevelopmentConfig} = require('./build/development');
const {runner} = require('./build/utils');
const compiler = webpack(createDevelopmentConfig({analyser: false}));
compiler.watch(
{
aggregateTimeout: 300,
poll: 1000,
},
runner,
);

14
scripts/watch.ts Normal file
View File

@ -0,0 +1,14 @@
import webpack from 'webpack';
import {createConfig as createDevelopmentConfig} from './build/development';
import {runner} from './build/runner';
const compiler = webpack(createDevelopmentConfig({analyser: false}));
compiler.watch(
{
aggregateTimeout: 300,
poll: 1000,
},
runner,
);

View File

@ -1,14 +1,37 @@
import AbstractEvent from 'shared/AbstractEvent';
/**
* DragEventData
* @interface DragEventData
*/
interface DragEventData {
source: HTMLElement;
originalSource: HTMLElement;
mirror: HTMLElement;
sourceContainer: HTMLElement;
sensorEvent: any;
}
/**
* Base drag event
* @class DragEvent
* @module DragEvent
* @extends AbstractEvent
*/
export class DragEvent extends AbstractEvent {
export class DragEvent<
T extends DragEventData,
> extends AbstractEvent<DragEventData> {
static type = 'drag';
/**
* DragEvent constructor.
* @constructs DragEvent
* @param {DragEventData} data - Event data
*/
constructor(public data: T) {
super(data);
}
/**
* Draggables source element
* @property source
@ -80,7 +103,7 @@ export class DragEvent extends AbstractEvent {
* @module DragStartEvent
* @extends DragEvent
*/
export class DragStartEvent extends DragEvent {
export class DragStartEvent extends DragEvent<DragEventData> {
static type = 'drag:start';
static cancelable = true;
}
@ -91,17 +114,26 @@ export class DragStartEvent extends DragEvent {
* @module DragMoveEvent
* @extends DragEvent
*/
export class DragMoveEvent extends DragEvent {
export class DragMoveEvent extends DragEvent<DragEventData> {
static type = 'drag:move';
}
/**
* DragOverEventData
* @interface DragOverEventData
*/
interface DragOverEventData extends DragEventData {
overContainer: HTMLElement;
over: HTMLElement;
}
/**
* Drag over event
* @class DragOverEvent
* @module DragOverEvent
* @extends DragEvent
*/
export class DragOverEvent extends DragEvent {
export class DragOverEvent extends DragEvent<DragOverEventData> {
static type = 'drag:over';
static cancelable = true;
@ -126,13 +158,22 @@ export class DragOverEvent extends DragEvent {
}
}
/**
* DragOutEventData
* @interface DragOutEventData
*/
interface DragOutEventData extends DragEventData {
overContainer: HTMLElement;
over: HTMLElement;
}
/**
* Drag out event
* @class DragOutEvent
* @module DragOutEvent
* @extends DragEvent
*/
export class DragOutEvent extends DragEvent {
export class DragOutEvent extends DragEvent<DragOutEventData> {
static type = 'drag:out';
/**
@ -156,13 +197,22 @@ export class DragOutEvent extends DragEvent {
}
}
/**
* DragOverContainerEventData
* @interface DragOverContainerEventData
*/
interface DragOverContainerEventData extends DragEventData {
overContainer: HTMLElement;
over: HTMLElement;
}
/**
* Drag over container event
* @class DragOverContainerEvent
* @module DragOverContainerEvent
* @extends DragEvent
*/
export class DragOverContainerEvent extends DragEvent {
export class DragOverContainerEvent extends DragEvent<DragOverContainerEventData> {
static type = 'drag:over:container';
/**
@ -176,13 +226,21 @@ export class DragOverContainerEvent extends DragEvent {
}
}
/**
* DragOutContainerEventData
* @interface DragOutContainerEventData
*/
interface DragOutContainerEventData extends DragEventData {
overContainer: HTMLElement;
}
/**
* Drag out container event
* @class DragOutContainerEvent
* @module DragOutContainerEvent
* @extends DragEvent
*/
export class DragOutContainerEvent extends DragEvent {
export class DragOutContainerEvent extends DragEvent<DragOutContainerEventData> {
static type = 'drag:out:container';
/**
@ -196,13 +254,21 @@ export class DragOutContainerEvent extends DragEvent {
}
}
/**
* DragPressureEventData
* @interface DragPressureEventData
*/
interface DragPressureEventData extends DragEventData {
pressure: number;
}
/**
* Drag pressure event
* @class DragPressureEvent
* @module DragPressureEvent
* @extends DragEvent
*/
export class DragPressureEvent extends DragEvent {
export class DragPressureEvent extends DragEvent<DragPressureEventData> {
static type = 'drag:pressure';
/**
@ -222,7 +288,7 @@ export class DragPressureEvent extends DragEvent {
* @module DragStopEvent
* @extends DragEvent
*/
export class DragStopEvent extends DragEvent {
export class DragStopEvent extends DragEvent<DragEventData> {
static type = 'drag:stop';
static cancelable = true;
}
@ -235,6 +301,6 @@ export class DragStopEvent extends DragEvent {
* @module DragStoppedEvent
* @extends DragEvent
*/
export class DragStoppedEvent extends DragEvent {
export class DragStoppedEvent extends DragEvent<DragEventData> {
static type = 'drag:stopped';
}

View File

@ -3,7 +3,10 @@ import {closest} from 'shared/utils';
import {Announcement, Focusable, Mirror, Scrollable} from './Plugins';
import Emitter from './Emitter';
import {MouseSensor, TouchSensor} from './Sensors';
import {DraggableInitializedEvent, DraggableDestroyEvent} from './DraggableEvent';
import {
DraggableInitializedEvent,
DraggableDestroyEvent,
} from './DraggableEvent';
import {
DragStartEvent,
DragMoveEvent,
@ -28,8 +31,14 @@ const dragStop = Symbol('dragStop');
* @const {Function} defaultAnnouncements['drag:stop']
*/
const defaultAnnouncements = {
'drag:start': (event) => `Picked up ${event.source.textContent.trim() || event.source.id || 'draggable element'}`,
'drag:stop': (event) => `Released ${event.source.textContent.trim() || event.source.id || 'draggable element'}`,
'drag:start': (event) =>
`Picked up ${
event.source.textContent.trim() || event.source.id || 'draggable element'
}`,
'drag:stop': (event) =>
`Released ${
event.source.textContent.trim() || event.source.id || 'draggable element'
}`,
};
const defaultClasses = {
@ -103,7 +112,9 @@ export default class Draggable {
} else if (containers instanceof HTMLElement) {
this.containers = [containers];
} else {
throw new Error('Draggable containers are expected to be of type `NodeList`, `HTMLElement[]` or `HTMLElement`');
throw new Error(
'Draggable containers are expected to be of type `NodeList`, `HTMLElement[]` or `HTMLElement`',
);
}
this.options = {
@ -225,10 +236,14 @@ export default class Draggable {
* @example draggable.removePlugin(MirrorPlugin, CustomMirrorPlugin)
*/
removePlugin(...plugins) {
const removedPlugins = this.plugins.filter((plugin) => plugins.includes(plugin.constructor));
const removedPlugins = this.plugins.filter((plugin) =>
plugins.includes(plugin.constructor),
);
removedPlugins.forEach((plugin) => plugin.detach());
this.plugins = this.plugins.filter((plugin) => !plugins.includes(plugin.constructor));
this.plugins = this.plugins.filter(
(plugin) => !plugins.includes(plugin.constructor),
);
return this;
}
@ -240,7 +255,9 @@ export default class Draggable {
* @example draggable.addSensor(ForceTouchSensor, CustomSensor)
*/
addSensor(...sensors) {
const activeSensors = sensors.map((Sensor) => new Sensor(this.containers, this.options));
const activeSensors = sensors.map(
(Sensor) => new Sensor(this.containers, this.options),
);
activeSensors.forEach((sensor) => sensor.attach());
this.sensors = [...this.sensors, ...activeSensors];
@ -256,10 +273,14 @@ export default class Draggable {
* @example draggable.removeSensor(TouchSensor, DragSensor)
*/
removeSensor(...sensors) {
const removedSensors = this.sensors.filter((sensor) => sensors.includes(sensor.constructor));
const removedSensors = this.sensors.filter((sensor) =>
sensors.includes(sensor.constructor),
);
removedSensors.forEach((sensor) => sensor.detach());
this.sensors = this.sensors.filter((sensor) => !sensors.includes(sensor.constructor));
this.sensors = this.sensors.filter(
(sensor) => !sensors.includes(sensor.constructor),
);
return this;
}
@ -283,7 +304,9 @@ export default class Draggable {
* @example draggable.removeContainer(document.body)
*/
removeContainer(...containers) {
this.containers = this.containers.filter((container) => !containers.includes(container));
this.containers = this.containers.filter(
(container) => !containers.includes(container),
);
this.sensors.forEach((sensor) => sensor.removeContainer(...containers));
return this;
}
@ -373,10 +396,14 @@ export default class Draggable {
* @return {HTMLElement[]}
*/
getDraggableElementsForContainer(container) {
const allDraggableElements = container.querySelectorAll(this.options.draggable);
const allDraggableElements = container.querySelectorAll(
this.options.draggable,
);
return [...allDraggableElements].filter((childElement) => {
return childElement !== this.originalSource && childElement !== this.mirror;
return (
childElement !== this.originalSource && childElement !== this.mirror
);
});
}
@ -400,7 +427,11 @@ export default class Draggable {
return;
}
if (this.options.handle && target && !closest(target, this.options.handle)) {
if (
this.options.handle &&
target &&
!closest(target, this.options.handle)
) {
sensorEvent.cancel();
return;
}
@ -410,12 +441,19 @@ export default class Draggable {
if (this.lastPlacedSource && this.lastPlacedContainer) {
clearTimeout(this.placedTimeoutID);
this.lastPlacedSource.classList.remove(...this.getClassNamesFor('source:placed'));
this.lastPlacedContainer.classList.remove(...this.getClassNamesFor('container:placed'));
this.lastPlacedSource.classList.remove(
...this.getClassNamesFor('source:placed'),
);
this.lastPlacedContainer.classList.remove(
...this.getClassNamesFor('container:placed'),
);
}
this.source = this.originalSource.cloneNode(true);
this.originalSource.parentNode.insertBefore(this.source, this.originalSource);
this.originalSource.parentNode.insertBefore(
this.source,
this.originalSource,
);
this.originalSource.style.display = 'none';
const dragStartEvent = new DragStartEvent({
@ -435,9 +473,13 @@ export default class Draggable {
return;
}
this.originalSource.classList.add(...this.getClassNamesFor('source:original'));
this.originalSource.classList.add(
...this.getClassNamesFor('source:original'),
);
this.source.classList.add(...this.getClassNamesFor('source:dragging'));
this.sourceContainer.classList.add(...this.getClassNamesFor('container:dragging'));
this.sourceContainer.classList.add(
...this.getClassNamesFor('container:dragging'),
);
document.body.classList.add(...this.getClassNamesFor('body:dragging'));
applyUserSelect(document.body, 'none');
@ -482,10 +524,13 @@ export default class Draggable {
target = closest(target, this.options.draggable);
const withinCorrectContainer = closest(sensorEvent.target, this.containers);
const overContainer = sensorEvent.overContainer || withinCorrectContainer;
const isLeavingContainer = this.currentOverContainer && overContainer !== this.currentOverContainer;
const isLeavingContainer =
this.currentOverContainer && overContainer !== this.currentOverContainer;
const isLeavingDraggable = this.currentOver && target !== this.currentOver;
const isOverContainer = overContainer && this.currentOverContainer !== overContainer;
const isOverDraggable = withinCorrectContainer && target && this.currentOver !== target;
const isOverContainer =
overContainer && this.currentOverContainer !== overContainer;
const isOverDraggable =
withinCorrectContainer && target && this.currentOver !== target;
if (isLeavingDraggable) {
const dragOutEvent = new DragOutEvent({
@ -497,7 +542,9 @@ export default class Draggable {
overContainer: this.currentOverContainer,
});
this.currentOver.classList.remove(...this.getClassNamesFor('draggable:over'));
this.currentOver.classList.remove(
...this.getClassNamesFor('draggable:over'),
);
this.currentOver = null;
this.trigger(dragOutEvent);
@ -512,7 +559,9 @@ export default class Draggable {
overContainer: this.currentOverContainer,
});
this.currentOverContainer.classList.remove(...this.getClassNamesFor('container:over'));
this.currentOverContainer.classList.remove(
...this.getClassNamesFor('container:over'),
);
this.currentOverContainer = null;
this.trigger(dragOutContainerEvent);
@ -573,24 +622,37 @@ export default class Draggable {
this.trigger(dragStopEvent);
if (!dragStopEvent.canceled()) this.source.parentNode.insertBefore(this.originalSource, this.source);
if (!dragStopEvent.canceled())
this.source.parentNode.insertBefore(this.originalSource, this.source);
this.source.remove();
this.originalSource.style.display = '';
this.source.classList.remove(...this.getClassNamesFor('source:dragging'));
this.originalSource.classList.remove(...this.getClassNamesFor('source:original'));
this.originalSource.classList.add(...this.getClassNamesFor('source:placed'));
this.sourceContainer.classList.add(...this.getClassNamesFor('container:placed'));
this.sourceContainer.classList.remove(...this.getClassNamesFor('container:dragging'));
this.originalSource.classList.remove(
...this.getClassNamesFor('source:original'),
);
this.originalSource.classList.add(
...this.getClassNamesFor('source:placed'),
);
this.sourceContainer.classList.add(
...this.getClassNamesFor('container:placed'),
);
this.sourceContainer.classList.remove(
...this.getClassNamesFor('container:dragging'),
);
document.body.classList.remove(...this.getClassNamesFor('body:dragging'));
applyUserSelect(document.body, '');
if (this.currentOver) {
this.currentOver.classList.remove(...this.getClassNamesFor('draggable:over'));
this.currentOver.classList.remove(
...this.getClassNamesFor('draggable:over'),
);
}
if (this.currentOverContainer) {
this.currentOverContainer.classList.remove(...this.getClassNamesFor('container:over'));
this.currentOverContainer.classList.remove(
...this.getClassNamesFor('container:over'),
);
}
this.lastPlacedSource = this.originalSource;
@ -598,11 +660,15 @@ export default class Draggable {
this.placedTimeoutID = setTimeout(() => {
if (this.lastPlacedSource) {
this.lastPlacedSource.classList.remove(...this.getClassNamesFor('source:placed'));
this.lastPlacedSource.classList.remove(
...this.getClassNamesFor('source:placed'),
);
}
if (this.lastPlacedContainer) {
this.lastPlacedContainer.classList.remove(...this.getClassNamesFor('container:placed'));
this.lastPlacedContainer.classList.remove(
...this.getClassNamesFor('container:placed'),
);
}
this.lastPlacedSource = null;
@ -643,7 +709,9 @@ export default class Draggable {
}
const sensorEvent = getSensorEvent(event);
const source = this.source || closest(sensorEvent.originalEvent.target, this.options.draggable);
const source =
this.source ||
closest(sensorEvent.originalEvent.target, this.options.draggable);
const dragPressureEvent = new DragPressureEvent({
sensorEvent,

View File

@ -68,7 +68,10 @@ export default class Emitter {
if (caughtErrors.length) {
/* eslint-disable no-console */
console.error(`Draggable caught errors while triggering '${event.type}'`, caughtErrors);
console.error(
`Draggable caught errors while triggering '${event.type}'`,
caughtErrors,
);
/* eslint-enable no-console */
}

View File

@ -78,7 +78,10 @@ describe('Emitter', () => {
emitter.trigger(testEvent);
expect(consoleErrorSpy).toHaveBeenCalled();
expect(consoleErrorSpy).toHaveBeenCalledWith("Draggable caught errors while triggering 'event'", [error]);
expect(consoleErrorSpy).toHaveBeenCalledWith(
"Draggable caught errors while triggering 'event'",
[error],
);
expect(callbacks[0]).toHaveBeenCalled();
expect(callbacks[2]).toHaveBeenCalled();

View File

@ -43,14 +43,18 @@ export default class Focusable extends AbstractPlugin {
* Attaches listeners to draggable
*/
attach() {
this.draggable.on('draggable:initialize', this[onInitialize]).on('draggable:destroy', this[onDestroy]);
this.draggable
.on('draggable:initialize', this[onInitialize])
.on('draggable:destroy', this[onDestroy]);
}
/**
* Detaches listeners from draggable
*/
detach() {
this.draggable.off('draggable:initialize', this[onInitialize]).off('draggable:destroy', this[onDestroy]);
this.draggable
.off('draggable:initialize', this[onInitialize])
.off('draggable:destroy', this[onDestroy]);
// Remove modified elements when detach
this[onDestroy]();
@ -69,7 +73,10 @@ export default class Focusable extends AbstractPlugin {
* @return {HTMLElement[]}
*/
getElements() {
return [...this.draggable.containers, ...this.draggable.getDraggableElements()];
return [
...this.draggable.containers,
...this.draggable.getDraggableElements(),
];
}
/**
@ -109,7 +116,9 @@ const elementsWithMissingTabIndex = [];
* @private
*/
function decorateElement(element) {
const hasMissingTabIndex = Boolean(!element.getAttribute('tabindex') && element.tabIndex === -1);
const hasMissingTabIndex = Boolean(
!element.getAttribute('tabindex') && element.tabIndex === -1,
);
if (hasMissingTabIndex) {
elementsWithMissingTabIndex.push(element);

View File

@ -36,7 +36,9 @@ describe('Focusable', () => {
draggable: 'li',
});
const focusablePlugin = draggable.plugins.find((plugin) => plugin.constructor === Focusable);
const focusablePlugin = draggable.plugins.find(
(plugin) => plugin.constructor === Focusable,
);
expect(focusablePlugin).toBeInstanceOf(Focusable);
});
@ -46,7 +48,10 @@ describe('Focusable', () => {
draggable: 'li',
});
const elements = [...draggable.containers, ...draggable.getDraggableElements()];
const elements = [
...draggable.containers,
...draggable.getDraggableElements(),
];
waitForRequestAnimationFrame();
@ -60,7 +65,10 @@ describe('Focusable', () => {
draggable: 'li',
});
const elements = [...draggable.containers, ...draggable.getDraggableElements()];
const elements = [
...draggable.containers,
...draggable.getDraggableElements(),
];
waitForRequestAnimationFrame();
@ -103,6 +111,8 @@ describe('Focusable', () => {
waitForRequestAnimationFrame();
expect(elementWithTabIndexAttribute.tabIndex).toStrictEqual(originalTabIndex);
expect(elementWithTabIndexAttribute.tabIndex).toStrictEqual(
originalTabIndex,
);
});
});

View File

@ -163,7 +163,8 @@ export default class Mirror extends AbstractPlugin {
return;
}
const appendableContainer = this[getAppendableContainer](source) || sourceContainer;
const appendableContainer =
this[getAppendableContainer](source) || sourceContainer;
this.mirror = source.cloneNode(true);
const mirrorCreatedEvent = new MirrorCreatedEvent({
@ -415,8 +416,14 @@ function computeMirrorDimensions({source, ...args}) {
*/
function calculateMirrorOffset({sensorEvent, sourceRect, options, ...args}) {
return withPromise((resolve) => {
const top = options.cursorOffsetY === null ? sensorEvent.clientY - sourceRect.top : options.cursorOffsetY;
const left = options.cursorOffsetX === null ? sensorEvent.clientX - sourceRect.left : options.cursorOffsetX;
const top =
options.cursorOffsetY === null
? sensorEvent.clientY - sourceRect.top
: options.cursorOffsetY;
const left =
options.cursorOffsetX === null
? sensorEvent.clientX - sourceRect.left
: options.cursorOffsetX;
const mirrorOffset = {top, left};
@ -529,12 +536,16 @@ function positionMirror({withFrame = false, initial = false} = {}) {
if (mirrorOffset) {
const x = passedThreshX
? Math.round((sensorEvent.clientX - mirrorOffset.left - scrollOffset.x) / (options.thresholdX || 1)) *
(options.thresholdX || 1)
? Math.round(
(sensorEvent.clientX - mirrorOffset.left - scrollOffset.x) /
(options.thresholdX || 1),
) * (options.thresholdX || 1)
: Math.round(lastMovedX);
const y = passedThreshY
? Math.round((sensorEvent.clientY - mirrorOffset.top - scrollOffset.y) / (options.thresholdY || 1)) *
(options.thresholdY || 1)
? Math.round(
(sensorEvent.clientY - mirrorOffset.top - scrollOffset.y) /
(options.thresholdY || 1),
) * (options.thresholdY || 1)
: Math.round(lastMovedY);
if ((options.xAxis && options.yAxis) || initial) {

View File

@ -69,7 +69,10 @@ describe('Mirror', () => {
let dragEvent;
draggable.on('mirror:create', mirrorCreateHandler);
draggable.on('drag:start', (dragStartEvent) => (dragEvent = dragStartEvent));
draggable.on(
'drag:start',
(dragStartEvent) => (dragEvent = dragStartEvent),
);
clickMouse(draggableElement);
waitForDragDelay();
@ -128,7 +131,10 @@ describe('Mirror', () => {
let dragEvent;
draggable.on('mirror:created', mirrorCreatedHandler);
draggable.on('drag:start', (dragStartEvent) => (dragEvent = dragStartEvent));
draggable.on(
'drag:start',
(dragStartEvent) => (dragEvent = dragStartEvent),
);
clickMouse(draggableElement);
waitForDragDelay();
@ -158,7 +164,10 @@ describe('Mirror', () => {
let dragEvent;
draggable.on('mirror:attached', mirrorAttachedHandler);
draggable.on('drag:start', (dragStartEvent) => (dragEvent = dragStartEvent));
draggable.on(
'drag:start',
(dragStartEvent) => (dragEvent = dragStartEvent),
);
clickMouse(draggableElement);
waitForDragDelay();
@ -167,7 +176,9 @@ describe('Mirror', () => {
const mirrorElement = document.querySelector('.draggable-mirror');
expect(mirrorAttachedHandler).toHaveBeenCalledWithEvent(MirrorAttachedEvent);
expect(mirrorAttachedHandler).toHaveBeenCalledWithEvent(
MirrorAttachedEvent,
);
expect(mirrorAttachedHandler).toHaveBeenCalledWithEventProperties({
dragEvent,
mirror: mirrorElement,

View File

@ -119,7 +119,10 @@ export default class Scrollable extends AbstractPlugin {
*/
getScrollableElement(target) {
if (this.hasDefinedScrollableElements()) {
return closest(target, this.options.scrollableElements) || document.documentElement;
return (
closest(target, this.options.scrollableElements) ||
document.documentElement
);
} else {
return closestScrollableElement(target);
}
@ -152,7 +155,9 @@ export default class Scrollable extends AbstractPlugin {
*/
[onDragMove](dragEvent) {
this.findScrollableElementFrame = requestAnimationFrame(() => {
this.scrollableElement = this.getScrollableElement(dragEvent.sensorEvent.target);
this.scrollableElement = this.getScrollableElement(
dragEvent.sensorEvent.target,
);
});
if (!this.scrollableElement) {
@ -163,8 +168,16 @@ export default class Scrollable extends AbstractPlugin {
const scrollOffset = {x: 0, y: 0};
if ('ontouchstart' in window) {
scrollOffset.y = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
scrollOffset.x = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0;
scrollOffset.y =
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop ||
0;
scrollOffset.x =
window.pageXOffset ||
document.documentElement.scrollLeft ||
document.body.scrollLeft ||
0;
}
this.currentMousePosition = {
@ -212,7 +225,11 @@ export default class Scrollable extends AbstractPlugin {
const clientX = this.currentMousePosition.clientX;
const clientY = this.currentMousePosition.clientY;
if (scrollableElement !== document.body && scrollableElement !== document.documentElement && !cutOff) {
if (
scrollableElement !== document.body &&
scrollableElement !== document.documentElement &&
!cutOff
) {
const {offsetHeight, offsetWidth} = scrollableElement;
if (rect.top + offsetHeight - clientY < sensitivity) {

View File

@ -1,4 +1,13 @@
export {default as Announcement, defaultOptions as defaultAnnouncementOptions} from './Announcement';
export {
default as Announcement,
defaultOptions as defaultAnnouncementOptions,
} from './Announcement';
export {default as Focusable} from './Focusable';
export {default as Mirror, defaultOptions as defaultMirrorOptions} from './Mirror';
export {default as Scrollable, defaultOptions as defaultScrollableOptions} from './Scrollable';
export {
default as Mirror,
defaultOptions as defaultMirrorOptions,
} from './Mirror';
export {
default as Scrollable,
defaultOptions as defaultScrollableOptions,
} from './Scrollable';

View File

@ -1,7 +1,11 @@
import {closest} from 'shared/utils';
import Sensor from '../Sensor';
import {DragStartSensorEvent, DragMoveSensorEvent, DragStopSensorEvent} from '../SensorEvent';
import {
DragStartSensorEvent,
DragMoveSensorEvent,
DragStopSensorEvent,
} from '../SensorEvent';
const onMouseDown = Symbol('onMouseDown');
const onMouseUp = Symbol('onMouseUp');
@ -195,7 +199,11 @@ export default class DragSensor extends Sensor {
return;
}
if (this.options.handle && target && !closest(target, this.options.handle)) {
if (
this.options.handle &&
target &&
!closest(target, this.options.handle)
) {
return;
}
@ -205,7 +213,10 @@ export default class DragSensor extends Sensor {
return;
}
const nativeDraggableElement = closest(event.target, (element) => element.draggable);
const nativeDraggableElement = closest(
event.target,
(element) => element.draggable,
);
if (nativeDraggableElement) {
nativeDraggableElement.draggable = false;

View File

@ -47,7 +47,9 @@ describe('DragSensor', () => {
}
describe('common', () => {
beforeEach(setup);
beforeEach(() => {
setup();
});
afterEach(teardown);

View File

@ -1,7 +1,12 @@
import {closest} from 'shared/utils';
import Sensor from '../Sensor';
import {DragStartSensorEvent, DragMoveSensorEvent, DragStopSensorEvent, DragPressureSensorEvent} from '../SensorEvent';
import {
DragStartSensorEvent,
DragMoveSensorEvent,
DragStopSensorEvent,
DragPressureSensorEvent,
} from '../SensorEvent';
const onMouseForceWillBegin = Symbol('onMouseForceWillBegin');
const onMouseForceDown = Symbol('onMouseForceDown');
@ -47,10 +52,22 @@ export default class ForceTouchSensor extends Sensor {
*/
attach() {
for (const container of this.containers) {
container.addEventListener('webkitmouseforcewillbegin', this[onMouseForceWillBegin], false);
container.addEventListener('webkitmouseforcedown', this[onMouseForceDown], false);
container.addEventListener(
'webkitmouseforcewillbegin',
this[onMouseForceWillBegin],
false,
);
container.addEventListener(
'webkitmouseforcedown',
this[onMouseForceDown],
false,
);
container.addEventListener('mousedown', this[onMouseDown], true);
container.addEventListener('webkitmouseforcechanged', this[onMouseForceChange], false);
container.addEventListener(
'webkitmouseforcechanged',
this[onMouseForceChange],
false,
);
}
document.addEventListener('mousemove', this[onMouseMove]);
@ -62,10 +79,22 @@ export default class ForceTouchSensor extends Sensor {
*/
detach() {
for (const container of this.containers) {
container.removeEventListener('webkitmouseforcewillbegin', this[onMouseForceWillBegin], false);
container.removeEventListener('webkitmouseforcedown', this[onMouseForceDown], false);
container.removeEventListener(
'webkitmouseforcewillbegin',
this[onMouseForceWillBegin],
false,
);
container.removeEventListener(
'webkitmouseforcedown',
this[onMouseForceDown],
false,
);
container.removeEventListener('mousedown', this[onMouseDown], true);
container.removeEventListener('webkitmouseforcechanged', this[onMouseForceChange], false);
container.removeEventListener(
'webkitmouseforcechanged',
this[onMouseForceChange],
false,
);
}
document.removeEventListener('mousemove', this[onMouseMove]);
@ -95,7 +124,11 @@ export default class ForceTouchSensor extends Sensor {
const target = document.elementFromPoint(event.clientX, event.clientY);
const container = event.currentTarget;
if (this.options.handle && target && !closest(target, this.options.handle)) {
if (
this.options.handle &&
target &&
!closest(target, this.options.handle)
) {
return;
}

View File

@ -1,7 +1,11 @@
import {closest, distance as euclideanDistance} from 'shared/utils';
import Sensor from '../Sensor';
import {DragStartSensorEvent, DragMoveSensorEvent, DragStopSensorEvent} from '../SensorEvent';
import {
DragStartSensorEvent,
DragMoveSensorEvent,
DragStopSensorEvent,
} from '../SensorEvent';
const onContextMenuWhileDragging = Symbol('onContextMenuWhileDragging');
const onMouseDown = Symbol('onMouseDown');
@ -47,7 +51,8 @@ export default class MouseSensor extends Sensor {
*/
this.pageY = null;
this[onContextMenuWhileDragging] = this[onContextMenuWhileDragging].bind(this);
this[onContextMenuWhileDragging] =
this[onContextMenuWhileDragging].bind(this);
this[onMouseDown] = this[onMouseDown].bind(this);
this[onMouseMove] = this[onMouseMove].bind(this);
this[onMouseUp] = this[onMouseUp].bind(this);
@ -84,7 +89,11 @@ export default class MouseSensor extends Sensor {
return;
}
if (this.options.handle && event.target && !closest(event.target, this.options.handle)) {
if (
this.options.handle &&
event.target &&
!closest(event.target, this.options.handle)
) {
return;
}
@ -135,7 +144,11 @@ export default class MouseSensor extends Sensor {
this.dragging = !dragStartEvent.canceled();
if (this.dragging) {
document.addEventListener('contextmenu', this[onContextMenuWhileDragging], true);
document.addEventListener(
'contextmenu',
this[onContextMenuWhileDragging],
true,
);
document.addEventListener('mousemove', this[onMouseMove]);
}
}
@ -158,7 +171,8 @@ export default class MouseSensor extends Sensor {
}
const timeElapsed = Date.now() - this.onMouseDownAt;
const distanceTravelled = euclideanDistance(startEvent.pageX, startEvent.pageY, pageX, pageY) || 0;
const distanceTravelled =
euclideanDistance(startEvent.pageX, startEvent.pageY, pageX, pageY) || 0;
clearTimeout(this.mouseDownTimeout);
@ -226,7 +240,11 @@ export default class MouseSensor extends Sensor {
this.trigger(this.currentContainer, dragStopEvent);
document.removeEventListener('contextmenu', this[onContextMenuWhileDragging], true);
document.removeEventListener(
'contextmenu',
this[onContextMenuWhileDragging],
true,
);
document.removeEventListener('mousemove', this[onMouseMove]);
this.currentContainer = null;

View File

@ -1,4 +1,12 @@
import {createSandbox, triggerEvent, waitForDragDelay, DRAG_DELAY, clickMouse, moveMouse, releaseMouse} from 'helper';
import {
createSandbox,
triggerEvent,
waitForDragDelay,
DRAG_DELAY,
clickMouse,
moveMouse,
releaseMouse,
} from 'helper';
import MouseSensor from '..';
@ -47,7 +55,9 @@ describe('MouseSensor', () => {
}
describe('common', () => {
beforeEach(setup);
beforeEach(() => {
setup();
});
afterEach(teardown);
@ -138,7 +148,11 @@ describe('MouseSensor', () => {
releaseMouse(document.body);
}
[dragFlowWithRightClick, dragFlowWithCtrlKey, dragFlowWithMetaKey].forEach((dragFlow) => {
[
dragFlowWithRightClick,
dragFlowWithCtrlKey,
dragFlowWithMetaKey,
].forEach((dragFlow) => {
expect(dragFlow).not.toHaveTriggeredSensorEvent('drag:start');
});
});
@ -165,7 +179,9 @@ describe('MouseSensor', () => {
beforeEach(() => {
setup({handle: '.handle'});
handleInDraggableElement = sandbox.querySelector('.draggable .handle');
handleInNonDraggableElement = sandbox.querySelector('.non-draggable .handle');
handleInNonDraggableElement = sandbox.querySelector(
'.non-draggable .handle',
);
});
afterEach(teardown);
@ -173,7 +189,10 @@ describe('MouseSensor', () => {
it('does not prevent `dragstart` event when attempting to drag handle in non draggable element', () => {
clickMouse(handleInNonDraggableElement);
moveMouse(document, {pageX: 1, pageY: 1});
const nativeDragEvent = triggerEvent(handleInNonDraggableElement, 'dragstart');
const nativeDragEvent = triggerEvent(
handleInNonDraggableElement,
'dragstart',
);
expect(nativeDragEvent).not.toHaveDefaultPrevented();
@ -183,7 +202,10 @@ describe('MouseSensor', () => {
it('prevent `dragstart` event when attempting to drag handle in draggable element', () => {
clickMouse(handleInDraggableElement);
moveMouse(document, {pageX: 1, pageY: 1});
const nativeDragEvent = triggerEvent(handleInDraggableElement, 'dragstart');
const nativeDragEvent = triggerEvent(
handleInDraggableElement,
'dragstart',
);
expect(nativeDragEvent).toHaveDefaultPrevented();

View File

@ -98,7 +98,9 @@ export default class Sensor {
* @example draggable.removeContainer(document.body)
*/
removeContainer(...containers) {
this.containers = this.containers.filter((container) => !containers.includes(container));
this.containers = this.containers.filter(
(container) => !containers.includes(container),
);
}
/**

View File

@ -1,7 +1,15 @@
import {closest, distance as euclideanDistance, touchCoords} from 'shared/utils';
import {
closest,
distance as euclideanDistance,
touchCoords,
} from 'shared/utils';
import Sensor from '../Sensor';
import {DragStartSensorEvent, DragMoveSensorEvent, DragStopSensorEvent} from '../SensorEvent';
import {
DragStartSensorEvent,
DragMoveSensorEvent,
DragStopSensorEvent,
} from '../SensorEvent';
const onTouchStart = Symbol('onTouchStart');
const onTouchEnd = Symbol('onTouchEnd');
@ -113,7 +121,11 @@ export default class TouchSensor extends Sensor {
return;
}
if (this.options.handle && event.target && !closest(event.target, this.options.handle)) {
if (
this.options.handle &&
event.target &&
!closest(event.target, this.options.handle)
) {
return;
}
@ -143,7 +155,9 @@ export default class TouchSensor extends Sensor {
}
this.tapTimeout = window.setTimeout(() => {
this[onDistanceChange]({touches: [{pageX: this.pageX, pageY: this.pageY}]});
this[onDistanceChange]({
touches: [{pageX: this.pageX, pageY: this.pageY}],
});
}, delay.touch);
}
@ -187,7 +201,12 @@ export default class TouchSensor extends Sensor {
const start = touchCoords(startEvent);
const current = touchCoords(event);
const timeElapsed = Date.now() - this.onTouchStartAt;
const distanceTravelled = euclideanDistance(start.pageX, start.pageY, current.pageX, current.pageY);
const distanceTravelled = euclideanDistance(
start.pageX,
start.pageY,
current.pageX,
current.pageY,
);
Object.assign(this, current);
@ -212,7 +231,10 @@ export default class TouchSensor extends Sensor {
return;
}
const {pageX, pageY} = touchCoords(event);
const target = document.elementFromPoint(pageX - window.scrollX, pageY - window.scrollY);
const target = document.elementFromPoint(
pageX - window.scrollX,
pageY - window.scrollY,
);
const dragMoveEvent = new DragMoveSensorEvent({
clientX: pageX,
@ -249,7 +271,10 @@ export default class TouchSensor extends Sensor {
document.removeEventListener('touchmove', this[onTouchMove]);
const {pageX, pageY} = touchCoords(event);
const target = document.elementFromPoint(pageX - window.scrollX, pageY - window.scrollY);
const target = document.elementFromPoint(
pageX - window.scrollX,
pageY - window.scrollY,
);
event.preventDefault();

View File

@ -1,4 +1,12 @@
import {createSandbox, triggerEvent, waitForDragDelay, DRAG_DELAY, touchStart, touchMove, touchRelease} from 'helper';
import {
createSandbox,
triggerEvent,
waitForDragDelay,
DRAG_DELAY,
touchStart,
touchMove,
touchRelease,
} from 'helper';
import TouchSensor from '..';
@ -38,7 +46,9 @@ describe('TouchSensor', () => {
}
describe('common', () => {
beforeEach(setup);
beforeEach(() => {
setup();
});
afterEach(teardown);

View File

@ -10,8 +10,16 @@ import {
} from 'helper';
import Draggable, {defaultOptions} from '../Draggable';
import {DragStartEvent, DragMoveEvent, DragStopEvent, DragStoppedEvent} from '../DragEvent';
import {DraggableInitializedEvent, DraggableDestroyEvent} from '../DraggableEvent';
import {
DragStartEvent,
DragMoveEvent,
DragStopEvent,
DragStoppedEvent,
} from '../DragEvent';
import {
DraggableInitializedEvent,
DraggableDestroyEvent,
} from '../DraggableEvent';
import {Focusable, Mirror, Scrollable, Announcement} from '../Plugins';
import {MouseSensor, TouchSensor} from '../Sensors';
@ -72,7 +80,9 @@ describe('Draggable', () => {
it.skip('should set containers', () => {
const newInstance = new Draggable(containers);
expect(newInstance.containers).toMatchObject(Array.prototype.slice.call(containers));
expect(newInstance.containers).toMatchObject(
Array.prototype.slice.call(containers),
);
});
it.skip('should set single container if a list is not passed', () => {
@ -85,11 +95,15 @@ describe('Draggable', () => {
it('should throw error if `containers` argument is wrong type', () => {
expect(() => {
return new Draggable({});
}).toThrow('Draggable containers are expected to be of type `NodeList`, `HTMLElement[]` or `HTMLElement`');
}).toThrow(
'Draggable containers are expected to be of type `NodeList`, `HTMLElement[]` or `HTMLElement`',
);
expect(() => {
return new Draggable('.li');
}).toThrow('Draggable containers are expected to be of type `NodeList`, `HTMLElement[]` or `HTMLElement`');
}).toThrow(
'Draggable containers are expected to be of type `NodeList`, `HTMLElement[]` or `HTMLElement`',
);
});
it('should attach default plugins', () => {
@ -131,9 +145,9 @@ describe('Draggable', () => {
expect(customPlugin.draggable).toBe(newInstance);
expect(customPlugin.attachFunction).toHaveBeenCalled();
expect(customPlugin.attach).toHaveBeenCalled();
expect(customPlugin.detachFunction).not.toHaveBeenCalled();
expect(customPlugin.detach).not.toHaveBeenCalled();
});
it('should attach sensors', () => {
@ -204,17 +218,17 @@ describe('Draggable', () => {
newInstance.destroy();
expect(expectedPlugins[4].detachFunction).toHaveBeenCalled();
expect(expectedPlugins[4].detach).toHaveBeenCalled();
expect(expectedPlugins[4].detachFunction).toHaveBeenCalledTimes(1);
expect(expectedPlugins[4].detach).toHaveBeenCalledTimes(1);
expect(expectedPlugins[5].detachFunction).toHaveBeenCalled();
expect(expectedPlugins[5].detach).toHaveBeenCalled();
expect(expectedPlugins[5].detachFunction).toHaveBeenCalledTimes(1);
expect(expectedPlugins[5].detach).toHaveBeenCalledTimes(1);
expect(expectedPlugins[6].detachFunction).toHaveBeenCalled();
expect(expectedPlugins[6].detach).toHaveBeenCalled();
expect(expectedPlugins[6].detachFunction).toHaveBeenCalledTimes(1);
expect(expectedPlugins[6].detach).toHaveBeenCalledTimes(1);
});
it('should remove all sensor event listeners', () => {
@ -248,7 +262,9 @@ describe('Draggable', () => {
expect('my:event' in newInstance.emitter.callbacks).toBe(true);
expect(newInstance.emitter.callbacks['my:event']).toMatchObject([stubHandler]);
expect(newInstance.emitter.callbacks['my:event']).toMatchObject([
stubHandler,
]);
});
it('should return draggable instance', () => {
@ -329,7 +345,9 @@ describe('Draggable', () => {
// Wait for delay
waitForDragDelay();
const containerChildren = newInstance.getDraggableElementsForContainer(draggableElement.parentNode);
const containerChildren = newInstance.getDraggableElementsForContainer(
draggableElement.parentNode,
);
expect(containerChildren).toHaveLength(2);
@ -360,7 +378,10 @@ describe('Draggable', () => {
newInstance.addContainer(dynamicContainer);
expect(newInstance.containers).toStrictEqual([...containers, dynamicContainer]);
expect(newInstance.containers).toStrictEqual([
...containers,
dynamicContainer,
]);
clickMouse(draggableElement);
waitForDragDelay();
@ -374,7 +395,9 @@ describe('Draggable', () => {
describe('#removeContainer', () => {
it('removes single container dynamically', () => {
let dragOverContainerHandler = jest.fn();
const allContainers = document.querySelectorAll('.Container, .DynamicContainer');
const allContainers = document.querySelectorAll(
'.Container, .DynamicContainer',
);
const newInstance = new Draggable(allContainers, {
draggable: 'li',
});
@ -415,7 +438,9 @@ describe('Draggable', () => {
draggable: 'li',
});
expect(draggable.getDraggableElements()).toStrictEqual([...document.querySelectorAll('.Container li')]);
expect(draggable.getDraggableElements()).toStrictEqual([
...document.querySelectorAll('.Container li'),
]);
});
it('returns draggable elements after adding a container', () => {
@ -424,15 +449,21 @@ describe('Draggable', () => {
draggable: 'li',
});
expect(draggable.getDraggableElements()).toStrictEqual([...document.querySelectorAll('.Container li')]);
expect(draggable.getDraggableElements()).toStrictEqual([
...document.querySelectorAll('.Container li'),
]);
draggable.addContainer(dynamicContainer);
expect(draggable.getDraggableElements()).toStrictEqual([...document.querySelectorAll('li')]);
expect(draggable.getDraggableElements()).toStrictEqual([
...document.querySelectorAll('li'),
]);
draggable.removeContainer(dynamicContainer);
expect(draggable.getDraggableElements()).toStrictEqual([...document.querySelectorAll('.Container li')]);
expect(draggable.getDraggableElements()).toStrictEqual([
...document.querySelectorAll('.Container li'),
]);
});
});
@ -694,7 +725,9 @@ describe('Draggable', () => {
// Wait for delay
waitForDragDelay();
expect(newInstance.source.classList).toContain('draggable-source--is-dragging');
expect(newInstance.source.classList).toContain(
'draggable-source--is-dragging',
);
triggerEvent(draggableElement, 'mouseup', {button: 0});
});
@ -839,7 +872,9 @@ describe('Draggable', () => {
// Wait for default draggable.options.placedTimeout delay
jest.advanceTimersByTime(800);
expect(containers[0].classList).not.toContain('draggable-container--placed');
expect(containers[0].classList).not.toContain(
'draggable-container--placed',
);
});
it('adds `container:dragging` classname to draggable container element on mousedown', () => {
@ -855,7 +890,9 @@ describe('Draggable', () => {
// Wait for delay
waitForDragDelay();
expect(containers[0].classList).toContain('draggable-container--is-dragging');
expect(containers[0].classList).toContain(
'draggable-container--is-dragging',
);
triggerEvent(draggableElement, 'mouseup', {button: 0});
});
@ -873,11 +910,15 @@ describe('Draggable', () => {
// Wait for delay
waitForDragDelay();
expect(containers[0].classList).toContain('draggable-container--is-dragging');
expect(containers[0].classList).toContain(
'draggable-container--is-dragging',
);
triggerEvent(document.body, 'mouseup', {button: 0});
expect(containers[0].classList).not.toContain('draggable-container--is-dragging');
expect(containers[0].classList).not.toContain(
'draggable-container--is-dragging',
);
});
it('removes `container:dragging` classname from draggable container element on dragEvent.cancel()', () => {
@ -895,7 +936,9 @@ describe('Draggable', () => {
// Wait for delay
waitForDragDelay();
expect(containers[0].classList).not.toContain('draggable-container--is-dragging');
expect(containers[0].classList).not.toContain(
'draggable-container--is-dragging',
);
triggerEvent(draggableElement, 'mouseup', {button: 0});
});
@ -912,11 +955,19 @@ describe('Draggable', () => {
// Wait for delay
waitForDragDelay();
expect(draggableElement.classList.contains(newInstance.getClassNameFor('source:original'))).toBe(true);
expect(
draggableElement.classList.contains(
newInstance.getClassNameFor('source:original'),
),
).toBe(true);
triggerEvent(document.body, 'mouseup', {button: 0});
expect(draggableElement.classList.contains(newInstance.getClassNameFor('source:original'))).toBe(false);
expect(
draggableElement.classList.contains(
newInstance.getClassNameFor('source:original'),
),
).toBe(false);
});
it('should have multiple classes for `source:original` on start', () => {
@ -935,7 +986,9 @@ describe('Draggable', () => {
// Wait for delay
waitForDragDelay();
expect(newInstance.getClassNamesFor('source:original')).toStrictEqual(sourceOriginalClasses);
expect(newInstance.getClassNamesFor('source:original')).toStrictEqual(
sourceOriginalClasses,
);
triggerEvent(document.body, 'mouseup', {button: 0});
});

View File

@ -2,7 +2,12 @@ import {closest} from 'shared/utils';
import Draggable from '../Draggable';
import {DroppableStartEvent, DroppableDroppedEvent, DroppableReturnedEvent, DroppableStopEvent} from './DroppableEvent';
import {
DroppableStartEvent,
DroppableDroppedEvent,
DroppableReturnedEvent,
DroppableStopEvent,
} from './DroppableEvent';
const onDragStart = Symbol('onDragStart');
const onDragMove = Symbol('onDragMove');
@ -18,8 +23,12 @@ const getDropzones = Symbol('getDropzones');
* @return {String}
*/
function onDroppableDroppedDefaultAnnouncement({dragEvent, dropzone}) {
const sourceText = dragEvent.source.textContent.trim() || dragEvent.source.id || 'draggable element';
const dropzoneText = dropzone.textContent.trim() || dropzone.id || 'droppable element';
const sourceText =
dragEvent.source.textContent.trim() ||
dragEvent.source.id ||
'draggable element';
const dropzoneText =
dropzone.textContent.trim() || dropzone.id || 'droppable element';
return `Dropped ${sourceText} into ${dropzoneText}`;
}
@ -30,8 +39,12 @@ function onDroppableDroppedDefaultAnnouncement({dragEvent, dropzone}) {
* @return {String}
*/
function onDroppableReturnedDefaultAnnouncement({dragEvent, dropzone}) {
const sourceText = dragEvent.source.textContent.trim() || dragEvent.source.id || 'draggable element';
const dropzoneText = dropzone.textContent.trim() || dropzone.id || 'droppable element';
const sourceText =
dragEvent.source.textContent.trim() ||
dragEvent.source.id ||
'draggable element';
const dropzoneText =
dropzone.textContent.trim() || dropzone.id || 'droppable element';
return `Returned ${sourceText} from ${dropzoneText}`;
}
@ -108,7 +121,9 @@ export default class Droppable extends Draggable {
this[onDragMove] = this[onDragMove].bind(this);
this[onDragStop] = this[onDragStop].bind(this);
this.on('drag:start', this[onDragStart]).on('drag:move', this[onDragMove]).on('drag:stop', this[onDragStop]);
this.on('drag:start', this[onDragStart])
.on('drag:move', this[onDragMove])
.on('drag:stop', this[onDragStop]);
}
/**
@ -117,7 +132,9 @@ export default class Droppable extends Draggable {
destroy() {
super.destroy();
this.off('drag:start', this[onDragStart]).off('drag:move', this[onDragMove]).off('drag:stop', this[onDragStop]);
this.off('drag:start', this[onDragStart])
.off('drag:move', this[onDragMove])
.off('drag:stop', this[onDragStop]);
}
/**
@ -153,11 +170,17 @@ export default class Droppable extends Draggable {
this.initialDropzone = dropzone;
for (const dropzoneElement of this.dropzones) {
if (dropzoneElement.classList.contains(this.getClassNameFor('droppable:occupied'))) {
if (
dropzoneElement.classList.contains(
this.getClassNameFor('droppable:occupied'),
)
) {
continue;
}
dropzoneElement.classList.add(...this.getClassNamesFor('droppable:active'));
dropzoneElement.classList.add(
...this.getClassNamesFor('droppable:active'),
);
}
}
@ -172,11 +195,16 @@ export default class Droppable extends Draggable {
}
const dropzone = this[closestDropzone](event.sensorEvent.target);
const overEmptyDropzone = dropzone && !dropzone.classList.contains(this.getClassNameFor('droppable:occupied'));
const overEmptyDropzone =
dropzone &&
!dropzone.classList.contains(this.getClassNameFor('droppable:occupied'));
if (overEmptyDropzone && this[dropInDropzone](event, dropzone)) {
this.lastDropzone = dropzone;
} else if ((!dropzone || dropzone === this.initialDropzone) && this.lastDropzone) {
} else if (
(!dropzone || dropzone === this.initialDropzone) &&
this.lastDropzone
) {
this[returnToOriginalDropzone](event);
this.lastDropzone = null;
}
@ -258,7 +286,9 @@ export default class Droppable extends Draggable {
}
this.initialDropzone.appendChild(event.source);
this.lastDropzone.classList.remove(...this.getClassNamesFor('droppable:occupied'));
this.lastDropzone.classList.remove(
...this.getClassNamesFor('droppable:occupied'),
);
}
/**

View File

@ -1,6 +1,18 @@
import {createSandbox, clickMouse, moveMouse, releaseMouse, waitForDragDelay, DRAG_DELAY} from 'helper';
import {
createSandbox,
clickMouse,
moveMouse,
releaseMouse,
waitForDragDelay,
DRAG_DELAY,
} from 'helper';
import Droppable, {DroppableStartEvent, DroppableDroppedEvent, DroppableReturnedEvent, DroppableStopEvent} from '..';
import Droppable, {
DroppableStartEvent,
DroppableDroppedEvent,
DroppableReturnedEvent,
DroppableStopEvent,
} from '..';
const sampleMarkup = `
<div class="Container">
@ -60,7 +72,9 @@ describe('Droppable', () => {
});
it('droppable:start event', () => {
droppable.on('drag:start', (dragEvent) => originalDragEvents.push(dragEvent));
droppable.on('drag:start', (dragEvent) =>
originalDragEvents.push(dragEvent),
);
droppable.on('droppable:start', eventHandler);
move();
@ -74,7 +88,9 @@ describe('Droppable', () => {
});
it('droppable:dropped event', () => {
droppable.on('drag:move', (dragEvent) => originalDragEvents.push(dragEvent));
droppable.on('drag:move', (dragEvent) =>
originalDragEvents.push(dragEvent),
);
droppable.on('droppable:dropped', eventHandler);
move();
@ -88,7 +104,9 @@ describe('Droppable', () => {
});
it('droppable:returned event', () => {
droppable.on('drag:move', (dragEvent) => originalDragEvents.push(dragEvent));
droppable.on('drag:move', (dragEvent) =>
originalDragEvents.push(dragEvent),
);
droppable.on('droppable:returned', eventHandler);
move(() => {
@ -105,7 +123,9 @@ describe('Droppable', () => {
});
it('droppable:stop event', () => {
droppable.on('drag:stop', (dragEvent) => originalDragEvents.push(dragEvent));
droppable.on('drag:stop', (dragEvent) =>
originalDragEvents.push(dragEvent),
);
droppable.on('droppable:stop', eventHandler);
move();

View File

@ -52,14 +52,18 @@ export default class Collidable extends AbstractPlugin {
* Attaches plugins event listeners
*/
attach() {
this.draggable.on('drag:move', this[onDragMove]).on('drag:stop', this[onDragStop]);
this.draggable
.on('drag:move', this[onDragMove])
.on('drag:stop', this[onDragStop]);
}
/**
* Detaches plugins event listeners
*/
detach() {
this.draggable.off('drag:move', this[onDragMove]).off('drag:stop', this[onDragStop]);
this.draggable
.off('drag:move', this[onDragMove])
.off('drag:stop', this[onDragStop]);
}
/**
@ -71,7 +75,10 @@ export default class Collidable extends AbstractPlugin {
if (typeof collidables === 'string') {
return Array.prototype.slice.call(document.querySelectorAll(collidables));
} else if (collidables instanceof NodeList || collidables instanceof Array) {
} else if (
collidables instanceof NodeList ||
collidables instanceof Array
) {
return Array.prototype.slice.call(collidables);
} else if (collidables instanceof HTMLElement) {
return [collidables];
@ -90,7 +97,9 @@ export default class Collidable extends AbstractPlugin {
[onDragMove](event) {
const target = event.sensorEvent.target;
this.currentAnimationFrame = requestAnimationFrame(this[onRequestAnimationFrame](target));
this.currentAnimationFrame = requestAnimationFrame(
this[onRequestAnimationFrame](target),
);
if (this.currentlyCollidingElement) {
event.cancel();
@ -107,9 +116,12 @@ export default class Collidable extends AbstractPlugin {
});
const enteringCollidable = Boolean(
this.currentlyCollidingElement && this.lastCollidingElement !== this.currentlyCollidingElement,
this.currentlyCollidingElement &&
this.lastCollidingElement !== this.currentlyCollidingElement,
);
const leavingCollidable = Boolean(
!this.currentlyCollidingElement && this.lastCollidingElement,
);
const leavingCollidable = Boolean(!this.currentlyCollidingElement && this.lastCollidingElement);
if (enteringCollidable) {
if (this.lastCollidingElement) {
@ -130,7 +142,8 @@ export default class Collidable extends AbstractPlugin {
* @param {DragStopEvent} event - Drag stop event
*/
[onDragStop](event) {
const lastCollidingElement = this.currentlyCollidingElement || this.lastCollidingElement;
const lastCollidingElement =
this.currentlyCollidingElement || this.lastCollidingElement;
const collidableOutEvent = new CollidableOutEvent({
dragEvent: event,
collidingElement: lastCollidingElement,
@ -153,7 +166,9 @@ export default class Collidable extends AbstractPlugin {
[onRequestAnimationFrame](target) {
return () => {
const collidables = this.getCollidables();
this.currentlyCollidingElement = closest(target, (element) => collidables.includes(element));
this.currentlyCollidingElement = closest(target, (element) =>
collidables.includes(element),
);
};
}
}

View File

@ -134,7 +134,9 @@ export default class ResizeMirror extends AbstractPlugin {
overContainer.appendChild(this.mirror);
}
const overElement = over || this.draggable.getDraggableElementsForContainer(overContainer)[0];
const overElement =
over ||
this.draggable.getDraggableElementsForContainer(overContainer)[0];
if (!overElement) {
return;
@ -143,7 +145,10 @@ export default class ResizeMirror extends AbstractPlugin {
requestNextAnimationFrame(() => {
const overRect = overElement.getBoundingClientRect();
if (this.lastHeight === overRect.height && this.lastWidth === overRect.width) {
if (
this.lastHeight === overRect.height &&
this.lastWidth === overRect.width
) {
return;
}

View File

@ -128,12 +128,16 @@ export default class Snappable extends AbstractPlugin {
this.mirror.style.display = 'none';
}
source.classList.remove(...this.draggable.getClassNamesFor('source:dragging'));
source.classList.remove(
...this.draggable.getClassNamesFor('source:dragging'),
);
source.classList.add(...this.draggable.getClassNamesFor('source:placed'));
// Need to cancel this in drag out
setTimeout(() => {
source.classList.remove(...this.draggable.getClassNamesFor('source:placed'));
source.classList.remove(
...this.draggable.getClassNamesFor('source:placed'),
);
}, this.draggable.options.placedTimeout);
}

View File

@ -87,7 +87,8 @@ export default class SortAnimation extends AbstractPlugin {
*/
[onSortableSort]({dragEvent}) {
const {sourceContainer} = dragEvent;
const elements = this.draggable.getDraggableElementsForContainer(sourceContainer);
const elements =
this.draggable.getDraggableElementsForContainer(sourceContainer);
this.lastElements = Array.from(elements).map((el) => {
return {
domEl: el,
@ -168,5 +169,8 @@ function animate({from, to}, {duration, easingFunction}) {
function resetElementOnTransitionEnd(event) {
event.target.style.transition = '';
event.target.style.pointerEvents = '';
event.target.removeEventListener('transitionend', resetElementOnTransitionEnd);
event.target.removeEventListener(
'transitionend',
resetElementOnTransitionEnd,
);
}

View File

@ -1,6 +1,10 @@
import AbstractPlugin from 'shared/AbstractPlugin';
const onSortableSorted = Symbol('onSortableSorted');
interface Options {
duration: number;
easingFunction: string;
horizontal: boolean;
}
/**
* SwapAnimation default options
@ -10,7 +14,7 @@ const onSortableSorted = Symbol('onSortableSorted');
* @property {Boolean} defaultOptions.horizontal
* @type {Object}
*/
export const defaultOptions = {
export const defaultOptions: Options = {
duration: 150,
easingFunction: 'ease-in-out',
horizontal: false,
@ -23,12 +27,14 @@ export const defaultOptions = {
* @extends AbstractPlugin
*/
export default class SwapAnimation extends AbstractPlugin {
private options: Options;
private lastAnimationFrame: number | null;
/**
* SwapAnimation constructor.
* @constructs SwapAnimation
* @param {Draggable} draggable - Draggable instance
*/
constructor(draggable) {
constructor(draggable: any) {
super(draggable);
/**
@ -50,21 +56,21 @@ export default class SwapAnimation extends AbstractPlugin {
*/
this.lastAnimationFrame = null;
this[onSortableSorted] = this[onSortableSorted].bind(this);
this.onSortableSorted = this.onSortableSorted.bind(this);
}
/**
* Attaches plugins event listeners
*/
attach() {
this.draggable.on('sortable:sorted', this[onSortableSorted]);
this.draggable.on('sortable:sorted', this.onSortableSorted);
}
/**
* Detaches plugins event listeners
*/
detach() {
this.draggable.off('sortable:sorted', this[onSortableSorted]);
this.draggable.off('sortable:sorted', this.onSortableSorted);
}
/**
@ -80,10 +86,12 @@ export default class SwapAnimation extends AbstractPlugin {
* @param {SortableSortedEvent} sortableEvent
* @private
*/
[onSortableSorted]({oldIndex, newIndex, dragEvent}) {
onSortableSorted({oldIndex, newIndex, dragEvent}: any) {
const {source, over} = dragEvent;
cancelAnimationFrame(this.lastAnimationFrame);
if (this.lastAnimationFrame) {
cancelAnimationFrame(this.lastAnimationFrame);
}
// Can be done in a separate frame
this.lastAnimationFrame = requestAnimationFrame(() => {
@ -106,7 +114,11 @@ export default class SwapAnimation extends AbstractPlugin {
* @param {String} options.horizontal
* @private
*/
function animate(from, to, {duration, easingFunction, horizontal}) {
function animate(
from: HTMLElement,
to: HTMLElement,
{duration, easingFunction, horizontal}: any,
) {
for (const element of [from, to]) {
element.style.pointerEvents = 'none';
}
@ -135,8 +147,19 @@ function animate(from, to, {duration, easingFunction, horizontal}) {
* @param {Event} event
* @private
*/
function resetElementOnTransitionEnd(event) {
function resetElementOnTransitionEnd(event: Event) {
if (event.target == null || !isHTMLElement(event.target)) {
return;
}
event.target.style.transition = '';
event.target.style.pointerEvents = '';
event.target.removeEventListener('transitionend', resetElementOnTransitionEnd);
event.target.removeEventListener(
'transitionend',
resetElementOnTransitionEnd,
);
}
function isHTMLElement(eventTarget: EventTarget): eventTarget is HTMLElement {
return Boolean('style' in eventTarget);
}

View File

@ -1,5 +1,14 @@
export {default as Collidable} from './Collidable';
export {default as ResizeMirror, defaultOptions as defaultResizeMirrorOptions} from './ResizeMirror';
export {
default as ResizeMirror,
defaultOptions as defaultResizeMirrorOptions,
} from './ResizeMirror';
export {default as Snappable} from './Snappable';
export {default as SwapAnimation, defaultOptions as defaultSwapAnimationOptions} from './SwapAnimation';
export {default as SortAnimation, defaultOptions as defaultSortAnimationOptions} from './SortAnimation';
export {
default as SwapAnimation,
defaultOptions as defaultSwapAnimationOptions,
} from './SwapAnimation';
export {
default as SortAnimation,
defaultOptions as defaultSortAnimationOptions,
} from './SortAnimation';

View File

@ -1,6 +1,11 @@
import Draggable from '../Draggable';
import {SortableStartEvent, SortableSortEvent, SortableSortedEvent, SortableStopEvent} from './SortableEvent';
import {
SortableStartEvent,
SortableSortEvent,
SortableSortedEvent,
SortableStopEvent,
} from './SortableEvent';
const onDragStart = Symbol('onDragStart');
const onDragOverContainer = Symbol('onDragOverContainer');
@ -14,11 +19,19 @@ const onDragStop = Symbol('onDragStop');
* @return {String}
*/
function onSortableSortedDefaultAnnouncement({dragEvent}) {
const sourceText = dragEvent.source.textContent.trim() || dragEvent.source.id || 'sortable element';
const sourceText =
dragEvent.source.textContent.trim() ||
dragEvent.source.id ||
'sortable element';
if (dragEvent.over) {
const overText = dragEvent.over.textContent.trim() || dragEvent.over.id || 'sortable element';
const isFollowing = dragEvent.source.compareDocumentPosition(dragEvent.over) & Node.DOCUMENT_POSITION_FOLLOWING;
const overText =
dragEvent.over.textContent.trim() ||
dragEvent.over.id ||
'sortable element';
const isFollowing =
dragEvent.source.compareDocumentPosition(dragEvent.over) &
Node.DOCUMENT_POSITION_FOLLOWING;
if (isFollowing) {
return `Placed ${sourceText} after ${overText}`;
@ -106,7 +119,9 @@ export default class Sortable extends Draggable {
* @return {Number}
*/
index(element) {
return this.getSortableElementsForContainer(element.parentNode).indexOf(element);
return this.getSortableElementsForContainer(element.parentNode).indexOf(
element,
);
}
/**
@ -116,11 +131,15 @@ export default class Sortable extends Draggable {
* @return {HTMLElement[]}
*/
getSortableElementsForContainer(container) {
const allSortableElements = container.querySelectorAll(this.options.draggable);
const allSortableElements = container.querySelectorAll(
this.options.draggable,
);
return [...allSortableElements].filter((childElement) => {
return (
childElement !== this.originalSource && childElement !== this.mirror && childElement.parentNode === container
childElement !== this.originalSource &&
childElement !== this.mirror &&
childElement.parentNode === container
);
});
}

View File

@ -1,4 +1,11 @@
import {createSandbox, clickMouse, moveMouse, releaseMouse, waitForDragDelay, DRAG_DELAY} from 'helper';
import {
createSandbox,
clickMouse,
moveMouse,
releaseMouse,
waitForDragDelay,
DRAG_DELAY,
} from 'helper';
import Sortable from '..';
@ -119,14 +126,22 @@ describe('Sortable', () => {
});
it('sorts elements as you drag within a single container', () => {
draggableElements = sortable.getDraggableElementsForContainer(containers[0]);
expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
draggableElements = sortable.getDraggableElementsForContainer(
containers[0],
);
expect(draggableElements).toHaveOrder([
firstItem,
secondItem,
thirdItem,
forthItem,
]);
clickMouse(firstItem);
waitForDragDelay();
moveMouse(secondItem);
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
draggableElements =
sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
secondItem,
// original firstItem
@ -137,7 +152,8 @@ describe('Sortable', () => {
moveMouse(thirdItem);
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
draggableElements =
sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
secondItem,
thirdItem,
@ -148,7 +164,8 @@ describe('Sortable', () => {
moveMouse(forthItem);
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
draggableElements =
sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
secondItem,
thirdItem,
@ -159,25 +176,45 @@ describe('Sortable', () => {
releaseMouse(sortable.source);
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([secondItem, thirdItem, forthItem, firstItem]);
draggableElements =
sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
secondItem,
thirdItem,
forthItem,
firstItem,
]);
});
it('sorts elements as you drag between multiple containers', () => {
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
draggableElements =
sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
firstItem,
secondItem,
thirdItem,
forthItem,
]);
draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
expect(draggableElements).toHaveOrder([fifthItem, sixthItem, seventhItem, eighthItem]);
draggableElements =
sortable.getDraggableElementsForContainer(secondContainer);
expect(draggableElements).toHaveOrder([
fifthItem,
sixthItem,
seventhItem,
eighthItem,
]);
clickMouse(firstItem);
waitForDragDelay();
moveMouse(fifthItem);
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
draggableElements =
sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([secondItem, thirdItem, forthItem]);
draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
draggableElements =
sortable.getDraggableElementsForContainer(secondContainer);
expect(draggableElements).toHaveOrder([
// original firstItem
sortable.source,
@ -189,10 +226,12 @@ describe('Sortable', () => {
moveMouse(eighthItem);
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
draggableElements =
sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([secondItem, thirdItem, forthItem]);
draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
draggableElements =
sortable.getDraggableElementsForContainer(secondContainer);
expect(draggableElements).toHaveOrder([
fifthItem,
sixthItem,
@ -204,11 +243,19 @@ describe('Sortable', () => {
releaseMouse(sortable.source);
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
draggableElements =
sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([secondItem, thirdItem, forthItem]);
draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
expect(draggableElements).toHaveOrder([fifthItem, sixthItem, seventhItem, eighthItem, firstItem]);
draggableElements =
sortable.getDraggableElementsForContainer(secondContainer);
expect(draggableElements).toHaveOrder([
fifthItem,
sixthItem,
seventhItem,
eighthItem,
firstItem,
]);
});
it('prevents sorting when sortable:sort event gets canceled', () => {
@ -220,13 +267,25 @@ describe('Sortable', () => {
waitForDragDelay();
moveMouse(secondItem);
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([sortable.source, secondItem, thirdItem, forthItem]);
draggableElements =
sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
sortable.source,
secondItem,
thirdItem,
forthItem,
]);
releaseMouse(sortable.source);
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
draggableElements =
sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
firstItem,
secondItem,
thirdItem,
forthItem,
]);
});
it('sorts elements into empty container', () => {
@ -237,7 +296,8 @@ describe('Sortable', () => {
releaseMouse(sortable.source);
});
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
draggableElements =
sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
fifthItem,
sixthItem,
@ -249,14 +309,16 @@ describe('Sortable', () => {
forthItem,
]);
draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
draggableElements =
sortable.getDraggableElementsForContainer(secondContainer);
expect(draggableElements).toHaveOrder([]);
clickMouse(firstItem);
waitForDragDelay();
moveMouse(secondContainer);
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
draggableElements =
sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
fifthItem,
sixthItem,
@ -267,12 +329,14 @@ describe('Sortable', () => {
forthItem,
]);
draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
draggableElements =
sortable.getDraggableElementsForContainer(secondContainer);
expect(draggableElements).toHaveOrder([sortable.source]);
releaseMouse(sortable.source);
draggableElements = sortable.getDraggableElementsForContainer(firstContainer);
draggableElements =
sortable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
fifthItem,
sixthItem,
@ -283,7 +347,8 @@ describe('Sortable', () => {
forthItem,
]);
draggableElements = sortable.getDraggableElementsForContainer(secondContainer);
draggableElements =
sortable.getDraggableElementsForContainer(secondContainer);
expect(draggableElements).toHaveOrder([firstItem]);
});
});

View File

@ -1,6 +1,11 @@
import Draggable from '../Draggable';
import {SwappableStartEvent, SwappableSwapEvent, SwappableSwappedEvent, SwappableStopEvent} from './SwappableEvent';
import {
SwappableStartEvent,
SwappableSwapEvent,
SwappableSwappedEvent,
SwappableStopEvent,
} from './SwappableEvent';
const onDragStart = Symbol('onDragStart');
const onDragOver = Symbol('onDragOver');
@ -12,8 +17,14 @@ const onDragStop = Symbol('onDragStop');
* @return {String}
*/
function onSwappableSwappedDefaultAnnouncement({dragEvent, swappedElement}) {
const sourceText = dragEvent.source.textContent.trim() || dragEvent.source.id || 'swappable element';
const overText = swappedElement.textContent.trim() || swappedElement.id || 'swappable element';
const sourceText =
dragEvent.source.textContent.trim() ||
dragEvent.source.id ||
'swappable element';
const overText =
swappedElement.textContent.trim() ||
swappedElement.id ||
'swappable element';
return `Swapped ${sourceText} with ${overText}`;
}
@ -60,7 +71,9 @@ export default class Swappable extends Draggable {
this[onDragOver] = this[onDragOver].bind(this);
this[onDragStop] = this[onDragStop].bind(this);
this.on('drag:start', this[onDragStart]).on('drag:over', this[onDragOver]).on('drag:stop', this[onDragStop]);
this.on('drag:start', this[onDragStart])
.on('drag:over', this[onDragOver])
.on('drag:stop', this[onDragStop]);
}
/**
@ -69,7 +82,9 @@ export default class Swappable extends Draggable {
destroy() {
super.destroy();
this.off('drag:start', this._onDragStart).off('drag:over', this._onDragOver).off('drag:stop', this._onDragStop);
this.off('drag:start', this._onDragStart)
.off('drag:over', this._onDragOver)
.off('drag:stop', this._onDragStop);
}
/**
@ -95,7 +110,11 @@ export default class Swappable extends Draggable {
* @param {DragOverEvent} event - Drag over event
*/
[onDragOver](event) {
if (event.over === event.originalSource || event.over === event.source || event.canceled()) {
if (
event.over === event.originalSource ||
event.over === event.source ||
event.canceled()
) {
return;
}

View File

@ -1,4 +1,11 @@
import {createSandbox, clickMouse, moveMouse, releaseMouse, waitForDragDelay, DRAG_DELAY} from 'helper';
import {
createSandbox,
clickMouse,
moveMouse,
releaseMouse,
waitForDragDelay,
DRAG_DELAY,
} from 'helper';
import Swappable from '..';
@ -119,14 +126,22 @@ describe('Swappable', () => {
});
it('swaps elements as you drag within a single container', () => {
draggableElements = swappable.getDraggableElementsForContainer(containers[0]);
expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
draggableElements = swappable.getDraggableElementsForContainer(
containers[0],
);
expect(draggableElements).toHaveOrder([
firstItem,
secondItem,
thirdItem,
forthItem,
]);
clickMouse(firstItem);
waitForDragDelay();
moveMouse(secondItem);
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
draggableElements =
swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
secondItem,
// original firstItem
@ -137,7 +152,8 @@ describe('Swappable', () => {
moveMouse(thirdItem);
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
draggableElements =
swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
thirdItem,
secondItem,
@ -148,7 +164,8 @@ describe('Swappable', () => {
moveMouse(forthItem);
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
draggableElements =
swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
forthItem,
secondItem,
@ -159,25 +176,50 @@ describe('Swappable', () => {
releaseMouse(swappable.source);
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([forthItem, secondItem, thirdItem, firstItem]);
draggableElements =
swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
forthItem,
secondItem,
thirdItem,
firstItem,
]);
});
it('sorts elements as you drag between multiple containers', () => {
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
draggableElements =
swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
firstItem,
secondItem,
thirdItem,
forthItem,
]);
draggableElements = swappable.getDraggableElementsForContainer(secondContainer);
expect(draggableElements).toHaveOrder([fifthItem, sixthItem, seventhItem, eighthItem]);
draggableElements =
swappable.getDraggableElementsForContainer(secondContainer);
expect(draggableElements).toHaveOrder([
fifthItem,
sixthItem,
seventhItem,
eighthItem,
]);
clickMouse(firstItem);
waitForDragDelay();
moveMouse(fifthItem);
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([fifthItem, secondItem, thirdItem, forthItem]);
draggableElements =
swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
fifthItem,
secondItem,
thirdItem,
forthItem,
]);
draggableElements = swappable.getDraggableElementsForContainer(secondContainer);
draggableElements =
swappable.getDraggableElementsForContainer(secondContainer);
expect(draggableElements).toHaveOrder([
// original firstItem
swappable.source,
@ -188,10 +230,17 @@ describe('Swappable', () => {
moveMouse(eighthItem);
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([eighthItem, secondItem, thirdItem, forthItem]);
draggableElements =
swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
eighthItem,
secondItem,
thirdItem,
forthItem,
]);
draggableElements = swappable.getDraggableElementsForContainer(secondContainer);
draggableElements =
swappable.getDraggableElementsForContainer(secondContainer);
expect(draggableElements).toHaveOrder([
fifthItem,
sixthItem,
@ -202,11 +251,23 @@ describe('Swappable', () => {
releaseMouse(swappable.source);
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([eighthItem, secondItem, thirdItem, forthItem]);
draggableElements =
swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
eighthItem,
secondItem,
thirdItem,
forthItem,
]);
draggableElements = swappable.getDraggableElementsForContainer(secondContainer);
expect(draggableElements).toHaveOrder([fifthItem, sixthItem, seventhItem, firstItem]);
draggableElements =
swappable.getDraggableElementsForContainer(secondContainer);
expect(draggableElements).toHaveOrder([
fifthItem,
sixthItem,
seventhItem,
firstItem,
]);
});
it('prevents sorting when sortable:sort event gets canceled', () => {
@ -218,12 +279,24 @@ describe('Swappable', () => {
waitForDragDelay();
moveMouse(secondItem);
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([swappable.source, secondItem, thirdItem, forthItem]);
draggableElements =
swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
swappable.source,
secondItem,
thirdItem,
forthItem,
]);
releaseMouse(swappable.source);
draggableElements = swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([firstItem, secondItem, thirdItem, forthItem]);
draggableElements =
swappable.getDraggableElementsForContainer(firstContainer);
expect(draggableElements).toHaveOrder([
firstItem,
secondItem,
thirdItem,
forthItem,
]);
});
});

View File

@ -1,5 +1,3 @@
const canceled = Symbol('canceled');
/**
* All events fired by draggable inherit this class. You can call `cancel()` to
* cancel a specific event or you can check if an event has been canceled by
@ -8,7 +6,7 @@ const canceled = Symbol('canceled');
* @class AbstractEvent
* @module AbstractEvent
*/
export default class AbstractEvent {
export class AbstractEvent<T> {
/**
* Event type
* @static
@ -17,7 +15,6 @@ export default class AbstractEvent {
* @type {String}
*/
static type = 'event';
/**
* Event cancelable
* @static
@ -27,15 +24,19 @@ export default class AbstractEvent {
*/
static cancelable = false;
/**
* Private instance variable to track canceled state
* @private
* @type {Boolean}
*/
private _canceled = false;
/**
* AbstractEvent constructor.
* @constructs AbstractEvent
* @param {object} data - Event data
* @param {T} data - Event data
*/
constructor(data) {
this[canceled] = false;
this.data = data;
}
constructor(public data: T) {}
/**
* Read-only type
@ -43,7 +44,7 @@ export default class AbstractEvent {
* @return {String}
*/
get type() {
return this.constructor.type;
return (this.constructor as typeof AbstractEvent).type;
}
/**
@ -52,7 +53,7 @@ export default class AbstractEvent {
* @return {Boolean}
*/
get cancelable() {
return this.constructor.cancelable;
return (this.constructor as typeof AbstractEvent).cancelable;
}
/**
@ -60,7 +61,7 @@ export default class AbstractEvent {
* @abstract
*/
cancel() {
this[canceled] = true;
this._canceled = true;
}
/**
@ -69,17 +70,17 @@ export default class AbstractEvent {
* @return {Boolean}
*/
canceled() {
return Boolean(this[canceled]);
return this._canceled;
}
/**
* Returns new event instance with existing event data.
* This method allows for overriding of event data.
* @param {Object} data
* @param {T} data
* @return {AbstractEvent}
*/
clone(data) {
return new this.constructor({
clone(data: T) {
return new (this.constructor as typeof AbstractEvent)({
...this.data,
...data,
});

View File

@ -1,3 +0,0 @@
import AbstractEvent from './AbstractEvent';
export default AbstractEvent;

View File

@ -0,0 +1 @@
export {AbstractEvent as default} from './AbstractEvent';

View File

@ -1,26 +1,26 @@
import AbstractEvent from '../AbstractEvent';
import {AbstractEvent} from '../AbstractEvent';
describe('AbstractEvent', () => {
it('should be of type AbstractEvent', () => {
const event = new AbstractEvent();
const event = new AbstractEvent({});
expect(event).toBeInstanceOf(AbstractEvent);
});
it('should initialize with correct type', () => {
const event = new AbstractEvent();
const event = new AbstractEvent({});
expect(event.type).toBe('event');
});
it('should initialize in uncancelable state', () => {
const event = new AbstractEvent();
const event = new AbstractEvent({});
expect(event.cancelable).toBe(false);
});
it('should initialize in uncancelled state', () => {
const event = new AbstractEvent();
const event = new AbstractEvent({});
expect(event.canceled()).toBe(false);
});
@ -36,7 +36,7 @@ describe('AbstractEvent', () => {
});
it('should cancel event', () => {
const event = new AbstractEvent();
const event = new AbstractEvent({});
expect(event.canceled()).toBe(false);

View File

@ -4,20 +4,13 @@
* @class AbstractPlugin
* @module AbstractPlugin
*/
export default class AbstractPlugin {
export abstract class AbstractPlugin {
/**
* AbstractPlugin constructor.
* @constructs AbstractPlugin
* @param {Draggable} draggable - Draggable instance
*/
constructor(draggable) {
/**
* Draggable instance
* @property draggable
* @type {Draggable}
*/
this.draggable = draggable;
}
constructor(protected draggable: any) {}
/**
* Override to add listeners

View File

@ -1,3 +0,0 @@
import AbstractPlugin from './AbstractPlugin';
export default AbstractPlugin;

View File

@ -0,0 +1 @@
export {AbstractPlugin as default} from './AbstractPlugin';

View File

@ -1,60 +0,0 @@
const matchFunction =
Element.prototype.matches ||
Element.prototype.webkitMatchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector;
/**
* Get the closest parent element of a given element that matches the given
* selector string or matching function
*
* @param {Element} element The child element to find a parent of
* @param {String|Function} selector The string or function to use to match
* the parent element
* @return {Element|null}
*/
export default function closest(element, value) {
if (!element) {
return null;
}
const selector = value;
const callback = value;
const nodeList = value;
const singleElement = value;
const isSelector = Boolean(typeof value === 'string');
const isFunction = Boolean(typeof value === 'function');
const isNodeList = Boolean(value instanceof NodeList || value instanceof Array);
const isElement = Boolean(value instanceof HTMLElement);
function conditionFn(currentElement) {
if (!currentElement) {
return currentElement;
} else if (isSelector) {
return matchFunction.call(currentElement, selector);
} else if (isNodeList) {
return [...nodeList].includes(currentElement);
} else if (isElement) {
return singleElement === currentElement;
} else if (isFunction) {
return callback(currentElement);
} else {
return null;
}
}
let current = element;
do {
current = current.correspondingUseElement || current.correspondingElement || current;
if (conditionFn(current)) {
return current;
}
current = current.parentNode;
} while (current && current !== document.body && current !== document);
return null;
}

View File

@ -0,0 +1,77 @@
declare global {
export interface Node {
correspondingUseElement: SVGUseElement;
correspondingElement: SVGElement;
}
}
type CallbackFunction = (element: Node) => boolean;
type Value = string | CallbackFunction | NodeList | Node | Node[];
/**
* Get the closest parent element node of a given node that matches the given
* selector string or matching function
*
* @param {Node} node The child element to find a parent of
* @param {String|Function} selector The string or function to use to match
* the parent node
* @return {Node|null}
*/
export default function closest(node?: Node, value?: Value) {
if (node == null) {
return null;
}
function conditionFn(currentNode: Node | null): boolean {
if (currentNode == null || value == null) {
return false;
} else if (isSelector(value)) {
return Element.prototype.matches.call(currentNode, value);
} else if (isNodeList(value)) {
return [...value].includes(currentNode);
} else if (isElement(value)) {
return value === currentNode;
} else if (isFunction(value)) {
return value(currentNode);
} else {
return false;
}
}
let current: Node | null = node;
do {
current =
current.correspondingUseElement ||
current.correspondingElement ||
current;
if (conditionFn(current)) {
return current;
}
current = current?.parentNode || null;
} while (
current != null &&
current !== document.body &&
current !== document
);
return null;
}
function isSelector(value: Value): value is string {
return Boolean(typeof value === 'string');
}
function isNodeList(value: Value): value is NodeList | Node[] {
return Boolean(value instanceof NodeList || value instanceof Array);
}
function isElement(value: Value): value is Node {
return Boolean(value instanceof Node);
}
function isFunction(value: Value): value is (element: Node) => boolean {
return Boolean(typeof value === 'function');
}

View File

@ -13,7 +13,7 @@ const sampleMarkup = `
`;
describe('utils', () => {
let sandbox;
let sandbox: HTMLDivElement;
beforeEach(() => {
sandbox = createSandbox(sampleMarkup);
@ -28,13 +28,13 @@ describe('utils', () => {
});
it('should return null when string selector does not match', () => {
const element = sandbox.querySelector('.leaf');
const element = sandbox.querySelector('.leaf')!;
expect(closest(element, 'will-not-match')).toBeNull();
});
it('should return null when function selector does not match', () => {
const element = sandbox.querySelector('.leaf');
const element = sandbox.querySelector('.leaf')!;
function selector() {
return false;
}
@ -43,24 +43,33 @@ describe('utils', () => {
});
it('should return null when selector targets child element', () => {
const element = sandbox.querySelector('.twig');
const element = sandbox.querySelector('.twig')!;
expect(closest(element, '.leaf')).toBeNull();
});
it('should match element via callback', () => {
const element = sandbox.querySelector('.leaf');
const element = sandbox.querySelector('.leaf')!;
function callback(currentElement) {
return currentElement.classList.contains('leaf');
function callback(currentElement: Node) {
return (currentElement as HTMLElement).classList.contains('leaf');
}
expect(closest(element, callback)).toBe(element);
});
['.twig', 'ul', '.branch', 'section', '.tree', 'div', 'body', 'document'].forEach((expectedMatchingSelector) => {
[
'.twig',
'ul',
'.branch',
'section',
'.tree',
'div',
'body',
'document',
].forEach((expectedMatchingSelector) => {
it(`should return matched element when selector targets parent element matching selector ${expectedMatchingSelector}`, () => {
const element = sandbox.querySelector('.leaf');
const element = sandbox.querySelector('.leaf')!;
const expected = sandbox.querySelector(expectedMatchingSelector);
expect(closest(element, expectedMatchingSelector)).toBe(expected);

View File

@ -6,6 +6,11 @@
* @param {Number} y2 The Y position of the second point
* @return {Number}
*/
export default function distance(x1, y1, x2, y2) {
export default function distance(
x1: number,
y1: number,
x2: number,
y2: number,
) {
return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
}

View File

@ -1,4 +1,4 @@
export default function requestNextAnimationFrame(callback) {
export default function requestNextAnimationFrame(callback: () => void) {
return requestAnimationFrame(() => {
requestAnimationFrame(callback);
});

View File

@ -3,7 +3,7 @@
* @param {TouchEvent} event a touch event
* @return {Touch} a touch object
*/
export default function touchCoords(event = {}) {
export default function touchCoords(event: TouchEvent) {
const {touches, changedTouches} = event;
return (touches && touches[0]) || (changedTouches && changedTouches[0]);
}

View File

@ -1,5 +1,11 @@
import {REQUEST_ANIMATION_FRAME_TIMEOUT} from './helpers/environment';
declare global {
export interface Event {
stoppedPropagation: boolean;
}
}
window.requestAnimationFrame = (callback) => {
return setTimeout(callback, REQUEST_ANIMATION_FRAME_TIMEOUT);
};
@ -9,7 +15,10 @@ window.cancelAnimationFrame = (id) => {
};
Event.prototype.stopPropagation = (function (_super) {
return function (...args) {
return function (
this: Event,
...args: Parameters<typeof Event.prototype.stopPropagation>
) {
const returnValue = _super.call(this, ...args);
this.stoppedPropagation = true;
return returnValue;
@ -17,7 +26,10 @@ Event.prototype.stopPropagation = (function (_super) {
})(Event.prototype.stopPropagation);
Event.prototype.stopImmediatePropagation = (function (_super) {
return function (...args) {
return function (
this: Event,
...args: Parameters<typeof Event.prototype.stopImmediatePropagation>
) {
const returnValue = _super.call(this, ...args);
this.stoppedPropagation = true;
return returnValue;

View File

@ -1,6 +1,6 @@
import {setImmediate} from 'timers';
export function createSandbox(content) {
export function createSandbox(content: string) {
const sandbox = document.createElement('div');
sandbox.innerHTML = content;
document.body.appendChild(sandbox);
@ -8,7 +8,10 @@ export function createSandbox(content) {
return sandbox;
}
export function withElementFromPoint(elementFromPoint, callback) {
export function withElementFromPoint(
elementFromPoint: HTMLElement,
callback: () => void,
) {
const originalElementFromPoint = document.elementFromPoint;
document.elementFromPoint = () => elementFromPoint;
callback();
@ -17,7 +20,9 @@ export function withElementFromPoint(elementFromPoint, callback) {
export const REQUEST_ANIMATION_FRAME_TIMEOUT = 15;
export function waitForRequestAnimationFrame(requestAnimationFrameTimeout = REQUEST_ANIMATION_FRAME_TIMEOUT) {
export function waitForRequestAnimationFrame(
requestAnimationFrameTimeout = REQUEST_ANIMATION_FRAME_TIMEOUT,
) {
jest.advanceTimersByTime(requestAnimationFrameTimeout + 1);
}

View File

@ -1,6 +1,10 @@
import {withElementFromPoint} from './environment';
export function triggerEvent(element, type, data = {}) {
export function triggerEvent(
element: HTMLElement,
type: string,
data: {[key: string]: any} = {},
) {
const event = document.createEvent('Event');
event.initEvent(type, true, true);

View File

@ -12,7 +12,13 @@ import {
dragStop,
} from './sensor';
export function drag({from, to, sensor = 'mouse'}) {
interface Options {
from: HTMLElement;
to: HTMLElement;
sensor: 'mouse' | 'touch' | 'drag';
}
export function drag({from, to, sensor = 'mouse'}: Options) {
if (sensor === 'mouse') {
clickMouse(from);
waitForDragDelay();

20
test/helpers/plugin.ts Normal file
View File

@ -0,0 +1,20 @@
import AbstractPlugin from 'shared/AbstractPlugin';
export class TestPlugin extends AbstractPlugin {
constructor(draggable: any) {
super(draggable);
/* eslint-disable jest/prefer-spy-on */
this.attach = jest.fn();
this.detach = jest.fn();
/* eslint-enable jest/prefer-spy-on */
}
attach() {
return jest.fn();
}
detach() {
return jest.fn();
}
}

View File

@ -1,7 +1,14 @@
import {DRAG_DELAY, defaultTouchEventOptions, defaultMouseEventOptions} from './constants';
import {
DRAG_DELAY,
defaultTouchEventOptions,
defaultMouseEventOptions,
} from './constants';
import {triggerEvent} from './event';
export function waitForDragDelay({dragDelay = DRAG_DELAY, restoreDateMock = true} = {}) {
export function waitForDragDelay({
dragDelay = DRAG_DELAY,
restoreDateMock = true,
} = {}) {
const next = Date.now() + dragDelay + 1;
const dateMock = jest.spyOn(Date, 'now').mockImplementation(() => {
return next;
@ -13,61 +20,70 @@ export function waitForDragDelay({dragDelay = DRAG_DELAY, restoreDateMock = true
return dateMock;
}
export function clickMouse(element, options = {}) {
return triggerEvent(element, 'mousedown', {...defaultMouseEventOptions, ...options});
export function clickMouse(element: HTMLElement, options = {}) {
return triggerEvent(element, 'mousedown', {
...defaultMouseEventOptions,
...options,
});
}
export function moveMouse(element, options = {}) {
return triggerEvent(element, 'mousemove', {...defaultMouseEventOptions, ...options});
export function moveMouse(element: HTMLElement, options = {}) {
return triggerEvent(element, 'mousemove', {
...defaultMouseEventOptions,
...options,
});
}
export function releaseMouse(element, options = {}) {
return triggerEvent(element, 'mouseup', {...defaultMouseEventOptions, ...options});
export function releaseMouse(element: HTMLElement, options = {}) {
return triggerEvent(element, 'mouseup', {
...defaultMouseEventOptions,
...options,
});
}
export function touchStart(element, options) {
export function touchStart(element: HTMLElement, options = {}) {
return triggerEvent(element, 'touchstart', {
...defaultTouchEventOptions,
...options,
});
}
export function touchMove(element, options) {
export function touchMove(element: HTMLElement, options = {}) {
return triggerEvent(element, 'touchmove', {
...defaultTouchEventOptions,
...options,
});
}
export function touchRelease(element, options) {
export function touchRelease(element: HTMLElement, options = {}) {
return triggerEvent(element, 'touchend', {
...defaultTouchEventOptions,
...options,
});
}
export function dragStart(element, options) {
export function dragStart(element: HTMLElement, options = {}) {
return triggerEvent(element, 'dragstart', {
dataTransfer: getDataTransferStub(),
...options,
});
}
export function dragOver(element, options) {
export function dragOver(element: HTMLElement, options = {}) {
return triggerEvent(element, 'dragover', {
dataTransfer: getDataTransferStub(),
...options,
});
}
export function dragDrop(element, options) {
export function dragDrop(element: HTMLElement, options = {}) {
return triggerEvent(element, 'drop', {
dataTransfer: getDataTransferStub(),
...options,
});
}
export function dragStop(element, options) {
export function dragStop(element: HTMLElement, options = {}) {
return triggerEvent(element, 'dragend', {
dataTransfer: getDataTransferStub(),
...options,

View File

@ -1,4 +1,4 @@
function toHaveDefaultPrevented(event) {
function toHaveDefaultPrevented(event: Event) {
const pass = Boolean(event.defaultPrevented);
return {
@ -11,7 +11,7 @@ function toHaveDefaultPrevented(event) {
};
}
function toHaveStoppedPropagation(event) {
function toHaveStoppedPropagation(event: Event) {
const pass = Boolean(event.stoppedPropagation);
return {

View File

@ -1,21 +1,32 @@
import AbstractEvent from 'shared/AbstractEvent';
import {expectation} from './utils';
function toHaveBeenCalledWithEvent(jestFunction, expectedEventConstructor) {
function toHaveBeenCalledWithEvent(
this: any,
jestFunction: ReturnType<typeof jest.fn>,
expectedEventConstructor: typeof AbstractEvent<unknown>,
) {
const mockFunction = jestFunction.mock;
const mockCalls = mockFunction.calls;
let pass;
let pass: boolean;
let message;
// eslint-disable-next-line @babel/no-invalid-this
pass = this.isNot && mockCalls.length === 0;
if (pass) {
message = () => `Expected ${expectedEventConstructor.type} event ${expectation(!pass)} triggered`;
message = () =>
`Expected ${expectedEventConstructor.type} event ${expectation(
!pass,
)} triggered`;
return {pass: !pass, message};
}
pass = !mockCalls.length;
if (pass) {
message = () => `Expected ${expectedEventConstructor.type} event ${expectation(pass)} triggered`;
message = () =>
`Expected ${expectedEventConstructor.type} event ${expectation(
pass,
)} triggered`;
return {pass, message};
}
@ -24,7 +35,9 @@ function toHaveBeenCalledWithEvent(jestFunction, expectedEventConstructor) {
pass = !event;
if (pass) {
message = () =>
`Expected ${expectedEventConstructor.type} event ${expectation(pass)} triggered with an event instance`;
`Expected ${expectedEventConstructor.type} event ${expectation(
pass,
)} triggered with an event instance`;
return {pass, message};
}
@ -33,11 +46,16 @@ function toHaveBeenCalledWithEvent(jestFunction, expectedEventConstructor) {
return {
pass,
message: () =>
`Expected ${event.type} event ${expectation(pass)} triggered with ${expectedEventConstructor.name} instance`,
`Expected ${event.type} event ${expectation(pass)} triggered with ${
expectedEventConstructor.name
} instance`,
};
}
function toHaveBeenCalledWithEventProperties(jestFunction, expectedProperties) {
function toHaveBeenCalledWithEventProperties(
jestFunction: ReturnType<typeof jest.fn>,
expectedProperties: {[key: string]: any},
) {
const mockFunction = jestFunction.mock;
const mockCalls = mockFunction.calls;
const event = mockCalls[0][0];
@ -54,8 +72,12 @@ function toHaveBeenCalledWithEventProperties(jestFunction, expectedProperties) {
return {
pass,
message: () => {
const listOfExpectedProperties = expectedPropertyEntries.map(([key, value]) => `${key}=${JSON.stringify(value)}`);
const listOfReceivedProperties = receivedPropertyEntries.map(([key, value]) => `${key}=${JSON.stringify(value)}`);
const listOfExpectedProperties = expectedPropertyEntries.map(
([key, value]) => `${key}=${JSON.stringify(value)}`,
);
const listOfReceivedProperties = receivedPropertyEntries.map(
([key, value]) => `${key}=${JSON.stringify(value)}`,
);
return `Expected ${event.type} event ${expectation(
pass,

View File

@ -1,4 +1,4 @@
function toHaveOrder(actualOrder, expectedOrder) {
function toHaveOrder(actualOrder: HTMLElement[], expectedOrder: HTMLElement[]) {
const incorrectPositions = expectedOrder
.map((element, index) => actualOrder[index] === element)
.filter((isCorrectOrder) => !isCorrectOrder);
@ -13,7 +13,7 @@ function toHaveOrder(actualOrder, expectedOrder) {
message += expectedOrder
.map((element) => {
return `${element.textContent.trim()}`;
return `${(element.textContent || '').trim()}`;
})
.join('\n');
@ -21,7 +21,7 @@ function toHaveOrder(actualOrder, expectedOrder) {
message += actualOrder
.map((element) => {
return `${element.textContent.trim()}`;
return `${(element.textContent || '').trim()}`;
})
.join('\n');

View File

@ -1,4 +1,8 @@
function toHaveTriggeredSensorEvent(received, expectedEventName, count) {
function toHaveTriggeredSensorEvent(
received: () => void,
expectedEventName: string,
count: number,
) {
let triggered = false;
let callCount = 0;
function callback() {
@ -12,7 +16,8 @@ function toHaveTriggeredSensorEvent(received, expectedEventName, count) {
received();
document.removeEventListener(expectedEventName, callback);
const pass = Boolean(triggered) && Boolean(count === undefined || callCount === count);
const pass =
Boolean(triggered) && Boolean(count === undefined || callCount === count);
return {
pass,
@ -25,10 +30,13 @@ function toHaveTriggeredSensorEvent(received, expectedEventName, count) {
};
}
function toHaveCanceledSensorEvent(received, expectedEventName) {
function toHaveCanceledSensorEvent(
received: () => void,
expectedEventName: string,
) {
let canceled = false;
function callback(event) {
function callback(event: any) {
canceled = event.detail.canceled();
}

View File

@ -1,3 +1,3 @@
export function expectation(passed) {
export function expectation(passed: boolean) {
return passed ? 'not to have' : 'to have';
}

19
tsconfig.json Normal file
View File

@ -0,0 +1,19 @@
{
"extends": "@shopify/typescript-configs/library",
"compilerOptions": {
"baseUrl": ".",
"rootDir": ".",
"lib": ["es2023"],
"resolveJsonModule": false,
"verbatimModuleSyntax": true,
"useUnknownInCatchVariables": false,
"paths": {
"shared/*": ["./src/shared/*"],
"helper": ["./test/helper.ts"]
}
},
"include": [
"./src/**/*",
"./test/**/*"
]
}

428
yarn.lock
View File

@ -1133,6 +1133,13 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
"@cspotcode/source-map-support@^0.8.0":
version "0.8.1"
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
dependencies:
"@jridgewell/trace-mapping" "0.3.9"
"@discoveryjs/json-ext@0.5.7", "@discoveryjs/json-ext@^0.5.0":
version "0.5.7"
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
@ -1406,7 +1413,7 @@
"@jridgewell/sourcemap-codec" "^1.4.10"
"@jridgewell/trace-mapping" "^0.3.9"
"@jridgewell/resolve-uri@^3.1.0":
"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721"
integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==
@ -1429,6 +1436,14 @@
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
"@jridgewell/trace-mapping@0.3.9":
version "0.3.9"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9"
integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
dependencies:
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9":
version "0.3.19"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811"
@ -1437,6 +1452,21 @@
"@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14"
"@microsoft/tsdoc-config@0.16.2":
version "0.16.2"
resolved "https://registry.yarnpkg.com/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz#b786bb4ead00d54f53839a458ce626c8548d3adf"
integrity sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==
dependencies:
"@microsoft/tsdoc" "0.14.2"
ajv "~6.12.6"
jju "~1.4.0"
resolve "~1.19.0"
"@microsoft/tsdoc@0.14.2", "@microsoft/tsdoc@^0.14.2":
version "0.14.2"
resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz#c3ec604a0b54b9a9b87e9735dfc59e1a5da6a5fb"
integrity sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
version "5.1.1-v1"
resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129"
@ -1534,6 +1564,16 @@
pkg-dir "^5.0.0"
pluralize "^8.0.0"
"@shopify/prettier-config@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@shopify/prettier-config/-/prettier-config-1.1.2.tgz#612f87c0cd1196e8b43c85425e587d0fa7f1172d"
integrity sha512-5ugCL9sPGzmOaZjeRGaWUWhHgAbemrS6z+R7v6gwiD+BiqSeoFhIY+imLpfdFCVpuOGalpHeCv6o3gv++EHs0A==
"@shopify/typescript-configs@^5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@shopify/typescript-configs/-/typescript-configs-5.1.0.tgz#f6e8fdd3291bf0a406578b2c6eb21f8c542d3c0a"
integrity sha512-RywGBTR+nQyJLxcrUcihPkHPIG3pIQI6i0YwMrM5rs9nWJ0+9A5HKEcboyGPLH+8V08EXGfFQ6H820O9ajyk4A==
"@sinclair/typebox@^0.27.8":
version "0.27.8"
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e"
@ -1563,6 +1603,26 @@
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
"@tsconfig/node10@^1.0.7":
version "1.0.9"
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2"
integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==
"@tsconfig/node12@^1.0.7":
version "1.0.11"
resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d"
integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==
"@tsconfig/node14@^1.0.0":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1"
integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
"@tsconfig/node16@^1.0.2":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9"
integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
"@types/babel__core@^7.1.14":
version "7.20.2"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.2.tgz#215db4f4a35d710256579784a548907237728756"
@ -1643,6 +1703,14 @@
dependencies:
"@types/istanbul-lib-report" "*"
"@types/jest@^29.5.5":
version "29.5.5"
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.5.tgz#727204e06228fe24373df9bae76b90f3e8236a2a"
integrity sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg==
dependencies:
expect "^29.0.0"
pretty-format "^29.0.0"
"@types/jsdom@^20.0.0":
version "20.0.1"
resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-20.0.1.tgz#07c14bc19bd2f918c1929541cdaacae894744808"
@ -1667,6 +1735,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.2.tgz#a065925409f59657022e9063275cd0b9bd7e1b12"
integrity sha512-Y+/1vGBHV/cYk6OI1Na/LHzwnlNCAfU3ZNGrc1LdRe/LAIbdDPTTv/HU3M7yXN448aTVDq3eKRm2cg7iKLb8gw==
"@types/node@^20.6.3":
version "20.6.3"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.3.tgz#5b763b321cd3b80f6b8dde7a37e1a77ff9358dd9"
integrity sha512-HksnYH4Ljr4VQgEy2lTStbCKv/P590tmPe5HqOnv9Gprffgv5WXAY+Y5Gqniu0GGqeTCUdBnzC3QSrzPkBkAMA==
"@types/semver@^7.3.12", "@types/semver@^7.5.0":
version "7.5.2"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.2.tgz#31f6eec1ed7ec23f4f05608d3a2d381df041f564"
@ -1682,6 +1755,24 @@
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.3.tgz#3d06b6769518450871fbc40770b7586334bdfd90"
integrity sha512-THo502dA5PzG/sfQH+42Lw3fvmYkceefOspdCwpHRul8ik2Jv1K8I5OZz1AT3/rs46kwgMCe9bSBmDLYkkOMGg==
"@types/webpack-bundle-analyzer@^4.6.0":
version "4.6.0"
resolved "https://registry.yarnpkg.com/@types/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.6.0.tgz#8863d62d2432126c2b3a9239cafa469215981c24"
integrity sha512-XeQmQCCXdZdap+A/60UKmxW5Mz31Vp9uieGlHB3T4z/o2OLVLtTI3bvTuS6A2OWd/rbAAQiGGWIEFQACu16szA==
dependencies:
"@types/node" "*"
tapable "^2.2.0"
webpack "^5"
"@types/webpack@^5.28.2":
version "5.28.2"
resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-5.28.2.tgz#a4db514f30b1b593278fbae6d6f9654c3d53c4c8"
integrity sha512-7tcxyrIOd7WGimZIcWU6pDsNh2edGGnwYExOvd3l/nMvuxqwVPrFXnnTbYCnplqV9BJoU7Mo2mfFtiH8CNFvYw==
dependencies:
"@types/node" "*"
tapable "^2.2.0"
webpack "^5"
"@types/yargs-parser@*":
version "21.0.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b"
@ -2008,7 +2099,7 @@ acorn-jsx@^5.3.2:
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
acorn-walk@^8.0.0, acorn-walk@^8.0.2:
acorn-walk@^8.0.0, acorn-walk@^8.0.2, acorn-walk@^8.1.1:
version "8.2.0"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
@ -2018,7 +2109,7 @@ acorn@^2.1.0, acorn@^2.4.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7"
integrity sha512-pXK8ez/pVjqFdAgBkF1YPVRacuLQ9EXBKaKWaeh58WNfMkCmZhOZzu+NtKSPD5PHmCCHheQ5cD29qM1K4QTxIg==
acorn@^8.0.4, acorn@^8.1.0, acorn@^8.7.1, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9.0:
acorn@^8.0.4, acorn@^8.1.0, acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9.0:
version "8.10.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5"
integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
@ -2049,7 +2140,7 @@ ajv-keywords@^5.1.0:
dependencies:
fast-deep-equal "^3.1.3"
ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5:
ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5, ajv@~6.12.6:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
@ -2118,6 +2209,11 @@ anymatch@^3.0.3:
normalize-path "^3.0.0"
picomatch "^2.0.4"
arg@^4.1.0:
version "4.1.3"
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
@ -2277,15 +2373,6 @@ axobject-query@^3.1.1:
dependencies:
dequal "^2.0.3"
babel-code-frame@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-7.0.0-beta.3.tgz#1614a91b2ba0e3848559f410bbacd030726899c9"
integrity sha512-flMsJ9eSpShupt2Gwpka84DoMePvE4HlDObzdEc+1iNkacv3+NHlsJ7dMKmbnVA/AT22UhcGEBHwbJLoXWBO6Q==
dependencies:
chalk "^2.0.0"
esutils "^2.0.2"
js-tokens "^3.0.0"
babel-code-frame@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
@ -2321,84 +2408,6 @@ babel-generator@6.26.1:
source-map "^0.5.7"
trim-right "^1.0.1"
babel-helper-annotate-as-pure@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-helper-annotate-as-pure/-/babel-helper-annotate-as-pure-7.0.0-beta.3.tgz#f86e3f15b48c1f8df1669d890548ad6f7ca252d6"
integrity sha512-C6uYc7RmuPDZmkwTaV/ya0BGuZJFyuU/mAyDDqSfyuUZavk04eKdEWxjaKRGd3UA/fpzLNKViYO4aQgY4TsxCQ==
dependencies:
babel-types "7.0.0-beta.3"
babel-helper-define-map@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-7.0.0-beta.3.tgz#503db9efcac5308d8df70fef48936364ac8e4212"
integrity sha512-F2DrZDfS4EIFi5HTK3eaL8ojJwM6jjEM26D/i7h1YAwlm6PytiOXlhcXNbOoSBv6767WesNWpLVDQoX68SjDrQ==
dependencies:
babel-helper-function-name "7.0.0-beta.3"
babel-types "7.0.0-beta.3"
lodash "^4.2.0"
babel-helper-function-name@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-7.0.0-beta.3.tgz#e86dd2eb2c09e06e392e79e203fc02427b24c871"
integrity sha512-iMWYqwDarQOVlEGcK1MfbtK9vrFGs5Z4UQsdASJUHdhBp918EM5kndwriiIbhUX8gr2B/CEV/udJkFTrHsjdMQ==
dependencies:
babel-helper-get-function-arity "7.0.0-beta.3"
babel-template "7.0.0-beta.3"
babel-traverse "7.0.0-beta.3"
babel-types "7.0.0-beta.3"
babel-helper-get-function-arity@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-7.0.0-beta.3.tgz#61a47709318a31bc2db872f4be9b4c8447198be8"
integrity sha512-ZkYFRMWKx1c9fUW72YNM3eieBG701CMbLjmLLWmJTTPc0F0kddS9Fwok26EAmndUAgD6kFdh7ms3PH94MdGuGQ==
dependencies:
babel-types "7.0.0-beta.3"
babel-helper-module-imports@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-helper-module-imports/-/babel-helper-module-imports-7.0.0-beta.3.tgz#e15764e3af9c8e11810c09f78f498a2bdc71585a"
integrity sha512-bdPrIXbUTYfREhRhjbN8SstwQaj0S4+rW4PKi1f2Wc5fizSh0hGYkfXUdiSSOgyTydm956tAyz4FrG61bqdQyw==
dependencies:
babel-types "7.0.0-beta.3"
lodash "^4.2.0"
babel-helper-module-transforms@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-helper-module-transforms/-/babel-helper-module-transforms-7.0.0-beta.3.tgz#42ccfa323e2d3aaaf0f743e66c2e7a292dc064f7"
integrity sha512-mnCAqH2fpcYny6LMyCg/bMif/D8FxER/at9R3xNWvfAv2N5x5Yhai0g8tBQZuINqZkAxQ4Tl7x/8ImviwKBQSA==
dependencies:
babel-helper-module-imports "7.0.0-beta.3"
babel-helper-simple-access "7.0.0-beta.3"
babel-template "7.0.0-beta.3"
babel-types "7.0.0-beta.3"
lodash "^4.2.0"
babel-helper-optimise-call-expression@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-7.0.0-beta.3.tgz#8c533bf31f05a4aa893700916e6a7e2a5fde7b9c"
integrity sha512-X614MCHT+to5dnH4uecU63VUmOs+4Hn8DfH6vT2090HHE9/swOuNFKpeNeI3hebt59eAYyoWb2iPGv7FTpIh3Q==
dependencies:
babel-types "7.0.0-beta.3"
babel-helper-replace-supers@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-7.0.0-beta.3.tgz#73598401b73feff5a6689a929b77496f15d673c3"
integrity sha512-ZkTdE7XBDW0PUQkKTeax+m1JpZqzo9ze3zbqjRxyt+x328NeGLD3edmNCIxmFt86njxIo3AFfZ00PKd4g/7jqg==
dependencies:
babel-helper-optimise-call-expression "7.0.0-beta.3"
babel-template "7.0.0-beta.3"
babel-traverse "7.0.0-beta.3"
babel-types "7.0.0-beta.3"
babel-helper-simple-access@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-helper-simple-access/-/babel-helper-simple-access-7.0.0-beta.3.tgz#dee94c31289fca79076f7ced2d751a06e430756c"
integrity sha512-4gaS4Eej6+qY35EWuwtkDQ47oKTRIBmGEGMzTigyDVjRfNltAlhN8lZPhNsIcKxG3zJ/UTOhtx7j8dmn757PUw==
dependencies:
babel-template "7.0.0-beta.3"
babel-types "7.0.0-beta.3"
lodash "^4.2.0"
babel-jest@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5"
@ -2477,60 +2486,11 @@ babel-plugin-react-test-id@^1.0.2:
resolved "https://registry.yarnpkg.com/babel-plugin-react-test-id/-/babel-plugin-react-test-id-1.0.2.tgz#90fb7ab91e9623bea47ad1f7eddd9a38e2dfc51b"
integrity sha512-d1bBxX3UNOIaX6NUEsR6Ekfy1fvmCegY9lQodgg6DevjhaNBDnaUeDUHl6JbIh5tuw0EF7FGgt+61yiFLMWwMg==
babel-plugin-syntax-class-properties@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-7.0.0-beta.3.tgz#84480d42dc9ec49f5f8e1e62fb435151cbbe11a3"
integrity sha512-0tNuKFPtKtElgd29PAiOHfA+IMALb6vD+tX8XsgDuaWWtgarqdJ3ia1EfFsG5RL7sUNYzKZM4UguMKzKLuvdQQ==
babel-plugin-syntax-object-rest-spread@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-7.0.0-beta.3.tgz#7f781c180899dafd88f132f69472397549be48e5"
integrity sha512-21/MnmUFduLr4JzxrKMm/MeF+Jjyi5UdZo38IqzrP0sLhmPbal5ZAUJ4HgWH4339SdjnYgENacbY5wfk/zxTGg==
babel-plugin-transform-class-properties@^7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-7.0.0-beta.3.tgz#d7cf0e431512262499421d53582969503f24581a"
integrity sha512-12n5QjNKJlbhRmAfVcM5D+rGpxsDa0AP+ufa5Xylvwcgjpq4YjEQc8L5VBBFLFmByAcXKsknNsAVuSfOIGHNDw==
dependencies:
babel-helper-function-name "7.0.0-beta.3"
babel-plugin-syntax-class-properties "7.0.0-beta.3"
babel-template "7.0.0-beta.3"
babel-plugin-transform-es2015-classes@^7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-7.0.0-beta.3.tgz#578b9604a3ace50a1a92944cb045088cd69474bf"
integrity sha512-4vH3pzhx3oZ6rphe3EDCkxFfMsWlJoEMSk8pIHnfXm4dOL+goij5mrxqoTAh7W/DcMzpakZOdKkgsgg+iujg8Q==
dependencies:
babel-helper-annotate-as-pure "7.0.0-beta.3"
babel-helper-define-map "7.0.0-beta.3"
babel-helper-function-name "7.0.0-beta.3"
babel-helper-optimise-call-expression "7.0.0-beta.3"
babel-helper-replace-supers "7.0.0-beta.3"
babel-template "7.0.0-beta.3"
babel-traverse "7.0.0-beta.3"
babel-types "7.0.0-beta.3"
babel-plugin-transform-es2015-modules-commonjs@^7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-7.0.0-beta.3.tgz#d53ae18f16e0b6a50ab65cdafbe3fa51a22f39b5"
integrity sha512-RcRIKOAerrm2M5+w8ITVoadLynjU4inaw+VtZwq1G10VBNn2bbik7hfXWdgnTUdHE8h3TGAafHX9Iw0Zxxuhrg==
dependencies:
babel-helper-module-transforms "7.0.0-beta.3"
babel-helper-simple-access "7.0.0-beta.3"
babel-types "7.0.0-beta.3"
babel-plugin-transform-inline-environment-variables@^0.4.3:
version "0.4.4"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-environment-variables/-/babel-plugin-transform-inline-environment-variables-0.4.4.tgz#974245008b3cbbd646bd81707af147aea3acca43"
integrity sha512-bJILBtn5a11SmtR2j/3mBOjX4K3weC6cq+NNZ7hG22wCAqpc3qtj/iN7dSe9HDiS46lgp1nHsQgeYrea/RUe+g==
babel-plugin-transform-object-rest-spread@^7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-7.0.0-beta.3.tgz#5c409f3cd70819dbb3382d2056971c5ebe01393a"
integrity sha512-NOlhrq1CmxyuI94vNsqMhRPMuL5VG2EKUOIJQ0bwNiXBiwWRLdPoWyPT+Irrx5g4g0PkFgA46tnRj7Dc4ZGsxg==
dependencies:
babel-plugin-syntax-object-rest-spread "7.0.0-beta.3"
babel-preset-current-node-syntax@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b"
@ -2589,17 +2549,6 @@ babel-runtime@^6.22.0, babel-runtime@^6.26.0, babel-runtime@^6.9.0:
core-js "^2.4.0"
regenerator-runtime "^0.11.0"
babel-template@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-7.0.0-beta.3.tgz#ebb877b6070ce9912b0d0c22fcad3372165913a8"
integrity sha512-urJduLja89kSDGqY8ryw8iIwQnMl30IvhMtMNmDD7vBX0l0oylaLgK+7df/9ODX9vR/PhXuif6HYl5HlzAKXMg==
dependencies:
babel-code-frame "7.0.0-beta.3"
babel-traverse "7.0.0-beta.3"
babel-types "7.0.0-beta.3"
babylon "7.0.0-beta.27"
lodash "^4.2.0"
babel-traverse@6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee"
@ -2615,29 +2564,6 @@ babel-traverse@6.26.0:
invariant "^2.2.2"
lodash "^4.17.4"
babel-traverse@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-7.0.0-beta.3.tgz#3cf0a45d53d934d85275d8770775d7944fc7c199"
integrity sha512-xyh/aPYuedMAfQlSj2kjHjsEmY5/Dpxs576L05DySAVMrV+ADX6l4mTOLysAEGwJfkePJlDLhFuS6SKaxv1V7w==
dependencies:
babel-code-frame "7.0.0-beta.3"
babel-helper-function-name "7.0.0-beta.3"
babel-types "7.0.0-beta.3"
babylon "7.0.0-beta.27"
debug "^3.0.1"
globals "^10.0.0"
invariant "^2.2.0"
lodash "^4.2.0"
babel-types@7.0.0-beta.3:
version "7.0.0-beta.3"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-7.0.0-beta.3.tgz#cd927ca70e0ae8ab05f4aab83778cfb3e6eb20b4"
integrity sha512-36k8J+byAe181OmCMawGhw+DtKO7AwexPVtsPXoMfAkjtZgoCX3bEuHWfdE5sYxRM8dojvtG/+O08M0Z/YDC6w==
dependencies:
esutils "^2.0.2"
lodash "^4.2.0"
to-fast-properties "^2.0.0"
babel-types@^6.10.2, babel-types@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
@ -2653,11 +2579,6 @@ babylon@6.18.0, babylon@^6.18.0:
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==
babylon@7.0.0-beta.27:
version "7.0.0-beta.27"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.27.tgz#b6edd30ef30619e2f630eb52585fdda84e6542cd"
integrity sha512-ksRx+r8eFIfdt63MCgLc9VxGL7W3jcyveQvMpNMVHgW+eb9mq3Xbm45FLCNkw8h92RvoNp4uuiwzcCEwxjDBZg==
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@ -2717,6 +2638,13 @@ browserslist@^4.14.5, browserslist@^4.21.10, browserslist@^4.21.9:
node-releases "^2.0.13"
update-browserslist-db "^1.0.11"
bs-logger@0.x:
version "0.2.6"
resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8"
integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==
dependencies:
fast-json-stable-stringify "2.x"
bser@2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05"
@ -2797,7 +2725,7 @@ chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2:
chalk@^2.4.1, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@ -2806,7 +2734,7 @@ chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@^4.0.0:
chalk@^4.0.0, chalk@^4.1.0:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
@ -3093,6 +3021,11 @@ create-jest@^29.7.0:
jest-util "^29.7.0"
prompts "^2.0.1"
create-require@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
@ -3181,7 +3114,7 @@ debug@^2.6.8:
dependencies:
ms "2.0.0"
debug@^3.0.1, debug@^3.2.7:
debug@^3.2.7:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
@ -3285,6 +3218,11 @@ diff-sequences@^29.6.3:
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921"
integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==
diff@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
dir-glob@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
@ -3420,7 +3358,7 @@ emojis-list@^3.0.0:
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
enhanced-resolve@^5.15.0:
enhanced-resolve@^5.0.0, enhanced-resolve@^5.15.0:
version "5.15.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35"
integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==
@ -3860,6 +3798,14 @@ eslint-plugin-sort-class-members@^1.18.0:
resolved "https://registry.yarnpkg.com/eslint-plugin-sort-class-members/-/eslint-plugin-sort-class-members-1.18.0.tgz#561746eb30abc4e8bb8d582d359c652299e450d8"
integrity sha512-y4r5OC3LJNHJZCWfVwFnnRiNrQ/LRf7Pb1wD6/CP8Y4qmUvjtmkwrLvyY755p8SFTOOXVd33HgFuF3XxVW1xbg==
eslint-plugin-tsdoc@^0.2.17:
version "0.2.17"
resolved "https://registry.yarnpkg.com/eslint-plugin-tsdoc/-/eslint-plugin-tsdoc-0.2.17.tgz#27789495bbd8778abbf92db1707fec2ed3dfe281"
integrity sha512-xRmVi7Zx44lOBuYqG8vzTXuL6IdGOeF9nHX17bjJ8+VE6fsxpdGem0/SBTmAwgYMKYB1WBkqRJVQ+n8GK041pA==
dependencies:
"@microsoft/tsdoc" "0.14.2"
"@microsoft/tsdoc-config" "0.16.2"
eslint-rule-composer@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9"
@ -4029,7 +3975,7 @@ exit@^0.1.2:
resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==
expect@^29.7.0:
expect@^29.0.0, expect@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc"
integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==
@ -4076,7 +4022,7 @@ fast-glob@^3.2.9, fast-glob@^3.3.0:
merge2 "^1.3.0"
micromatch "^4.0.4"
fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0:
fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
@ -4339,11 +4285,6 @@ global@^4.3.0:
min-document "^2.19.0"
process "^0.11.10"
globals@^10.0.0:
version "10.4.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-10.4.0.tgz#5c477388b128a9e4c5c5d01c7a2aca68c68b2da7"
integrity sha512-uNUtxIZpGyuaq+5BqGGQHsL4wUlJAXRqOm6g3Y48/CWNGTLONgBibI0lh6lGxjR2HljFYUfszb+mk4WkgMntsA==
globals@^11.1.0:
version "11.12.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
@ -4650,7 +4591,7 @@ interpret@^3.1.1:
resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4"
integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==
invariant@^2.2.0, invariant@^2.2.2:
invariant@^2.2.2:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
@ -4698,7 +4639,7 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
is-core-module@^2.13.0, is-core-module@^2.9.0:
is-core-module@^2.1.0, is-core-module@^2.13.0, is-core-module@^2.9.0:
version "2.13.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db"
integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==
@ -5300,7 +5241,7 @@ jest-snapshot@^29.7.0:
pretty-format "^29.7.0"
semver "^7.5.3"
jest-util@^29.7.0:
jest-util@^29.0.0, jest-util@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc"
integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==
@ -5367,16 +5308,21 @@ jest@^29.7.0:
import-local "^3.0.2"
jest-cli "^29.7.0"
js-tokens@^3.0.0, js-tokens@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
integrity sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==
jju@~1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a"
integrity sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
js-tokens@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
integrity sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==
js-yaml@3.14.1, js-yaml@^3.13.1:
version "3.14.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
@ -5708,6 +5654,11 @@ lodash.map@^4.4.0:
resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
integrity sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==
lodash.memoize@4.x:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==
lodash.merge@^4.4.0, lodash.merge@^4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
@ -5783,6 +5734,11 @@ make-dir@^4.0.0:
dependencies:
semver "^7.5.3"
make-error@1.x, make-error@^1.1.1:
version "1.3.6"
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
makeerror@1.0.12:
version "1.0.12"
resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a"
@ -5805,7 +5761,7 @@ merge2@^1.3.0, merge2@^1.4.1:
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
micromatch@^4.0.4:
micromatch@^4.0.0, micromatch@^4.0.4:
version "4.0.5"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
@ -6235,7 +6191,7 @@ path-key@^4.0.0:
resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18"
integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==
path-parse@^1.0.7:
path-parse@^1.0.6, path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
@ -6325,7 +6281,7 @@ prettier@^3.0.3:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643"
integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==
pretty-format@^29.7.0:
pretty-format@^29.0.0, pretty-format@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812"
integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==
@ -6631,6 +6587,14 @@ resolve@^2.0.0-next.4:
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
resolve@~1.19.0:
version "1.19.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c"
integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==
dependencies:
is-core-module "^2.1.0"
path-parse "^1.0.6"
reusify@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
@ -6732,7 +6696,7 @@ semver@^6.1.0, semver@^6.3.0, semver@^6.3.1:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
semver@^7.3.7, semver@^7.5.3, semver@^7.5.4:
semver@^7.3.4, semver@^7.3.7, semver@^7.5.3, semver@^7.5.4:
version "7.5.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
@ -7234,6 +7198,49 @@ ts-api-utils@^1.0.1:
resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331"
integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==
ts-jest@^29.1.1:
version "29.1.1"
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.1.tgz#f58fe62c63caf7bfcc5cc6472082f79180f0815b"
integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==
dependencies:
bs-logger "0.x"
fast-json-stable-stringify "2.x"
jest-util "^29.0.0"
json5 "^2.2.3"
lodash.memoize "4.x"
make-error "1.x"
semver "^7.5.3"
yargs-parser "^21.0.1"
ts-loader@^9.4.4:
version "9.4.4"
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.4.4.tgz#6ceaf4d58dcc6979f84125335904920884b7cee4"
integrity sha512-MLukxDHBl8OJ5Dk3y69IsKVFRA/6MwzEqBgh+OXMPB/OD01KQuWPFd1WAQP8a5PeSCAxfnkhiuWqfmFJzJQt9w==
dependencies:
chalk "^4.1.0"
enhanced-resolve "^5.0.0"
micromatch "^4.0.0"
semver "^7.3.4"
ts-node@^10.9.1:
version "10.9.1"
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b"
integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==
dependencies:
"@cspotcode/source-map-support" "^0.8.0"
"@tsconfig/node10" "^1.0.7"
"@tsconfig/node12" "^1.0.7"
"@tsconfig/node14" "^1.0.0"
"@tsconfig/node16" "^1.0.2"
acorn "^8.4.1"
acorn-walk "^8.1.1"
arg "^4.1.0"
create-require "^1.1.0"
diff "^4.0.1"
make-error "^1.1.1"
v8-compile-cache-lib "^3.0.1"
yn "3.1.1"
tsconfig-paths@^3.14.2:
version "3.14.2"
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088"
@ -7341,6 +7348,11 @@ typed-array-length@^1.0.4:
for-each "^0.3.3"
is-typed-array "^1.1.9"
typescript@^5.2.2:
version "5.2.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78"
integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==
unbox-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
@ -7448,6 +7460,11 @@ uuid@^8.0.0:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
v8-compile-cache-lib@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
v8-to-istanbul@^9.0.1:
version "9.1.0"
resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265"
@ -7566,7 +7583,7 @@ webpack-sources@^3.2.3:
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
webpack@^5.88.2:
webpack@^5, webpack@^5.88.2:
version "5.88.2"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.88.2.tgz#f62b4b842f1c6ff580f3fcb2ed4f0b579f4c210e"
integrity sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==
@ -7760,7 +7777,7 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yargs-parser@^21.1.1:
yargs-parser@^21.0.1, yargs-parser@^21.1.1:
version "21.1.1"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
@ -7778,6 +7795,11 @@ yargs@^17.3.1:
y18n "^5.0.5"
yargs-parser "^21.1.1"
yn@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"