diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff07c4c57a1c..60fee5929f80 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,22 +14,32 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 12.x + node-version: 16.x - run: yarn install --frozen-lockfile --ignore-engines - run: yarn lint - run: yarn lint-docs + docs: + name: Generate docs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 16.x + - run: yarn install --frozen-lockfile --ignore-engines + - run: yarn docs test-typings: strategy: fail-fast: false matrix: - ts-version: ["3.9", "4.0", "4.1"] + ts-version: ["3.9", "4.0", "4.1", "4.2", "4.3", "4.4", "4.5"] name: TS Typings (${{ matrix.ts-version }}) runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 12.x + node-version: 16.x - run: yarn install --frozen-lockfile --ignore-engines - run: yarn add --dev typescript@~${{ matrix.ts-version }} --ignore-engines - run: yarn test-typings @@ -37,7 +47,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [10, 12] + node-version: [10, 16] name: SQLite (Node ${{ matrix.node-version }}) runs-on: ubuntu-latest env: @@ -56,7 +66,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [10, 12] + node-version: [10, 16] postgres-version: [9.5, 10] # Does not work with 12 minify-aliases: [true, false] native: [true, false] @@ -102,7 +112,7 @@ jobs: - name: MySQL 5.7 image: mysql:5.7 dialect: mysql - node-version: 12 + node-version: 16 - name: MySQL 8.0 image: mysql:8.0 dialect: mysql @@ -110,7 +120,7 @@ jobs: - name: MySQL 8.0 image: mysql:8.0 dialect: mysql - node-version: 12 + node-version: 16 - name: MariaDB 10.3 image: mariadb:10.3 dialect: mariadb @@ -118,7 +128,7 @@ jobs: - name: MariaDB 10.3 image: mariadb:10.3 dialect: mariadb - node-version: 12 + node-version: 16 - name: MariaDB 10.5 image: mariadb:10.5 dialect: mariadb @@ -126,7 +136,7 @@ jobs: - name: MariaDB 10.5 image: mariadb:10.5 dialect: mariadb - node-version: 12 + node-version: 16 name: ${{ matrix.name }} (Node ${{ matrix.node-version }}) runs-on: ubuntu-latest services: @@ -158,7 +168,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [10, 12] + node-version: [10, 16] mssql-version: [2017, 2019] name: MSSQL ${{ matrix.mssql-version }} (Node ${{ matrix.node-version }}) runs-on: ubuntu-latest @@ -192,12 +202,32 @@ jobs: run: yarn test-unit - name: Integration Tests run: yarn test-integration + test-snowflake: + strategy: + fail-fast: false + matrix: + node-version: [10, 16] + name: SNOWFLAKE (Node ${{ matrix.node-version }}) + runs-on: ubuntu-latest + env: + DIALECT: snowflake + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: yarn install --frozen-lockfile --ignore-engines + - name: Unit Tests + run: yarn test-unit + # - name: Integration Tests + # run: yarn test-integration release: name: Release runs-on: ubuntu-latest needs: [ lint, + docs, test-typings, test-sqlite, test-postgres, @@ -212,6 +242,6 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 12.x + node-version: 16.x - run: yarn install --frozen-lockfile --ignore-engines - run: npx semantic-release diff --git a/.gitignore b/.gitignore index f2551fe6573f..212837714c4f 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,4 @@ test/binary/tmp/* .vscode/ esdoc node_modules -dist/* +dist diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 000000000000..d71a03b9f3e0 --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +yarn commitlint --edit $1 diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 000000000000..d2ae35e84b09 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +yarn lint-staged diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b7b25a556cf1..efc9a97d2bd0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -94,7 +94,7 @@ Most operating systems provide all the needed tools (including Windows, Linux an - Mandatory: - - [Node.js](http://nodejs.org) + - [Node.js](http://nodejs.org), it is preferred to use the current LTS version of Node - [Git](https://git-scm.com/) - Optional (recommended): @@ -115,6 +115,10 @@ Clone the repository (if you haven't already) via `git clone https://github.com/ Run `npm install` (or `yarn install`) within the cloned repository folder. +#### 2.1 Adding and updating dependencies + +[Yarn v1](https://classic.yarnpkg.com/en/) is used in the CI/CD pipeline so adding and updating dependencies must be done with Yarn v1. Depending on the Node version used, you might encounter a `Found incompatible module` error. To solve that, you can pass the `--ignore-engines` flag. This is not needed if you use Node `^14.17.0 || >=16.0.0`. + ### 3. Prepare local databases to run tests If you're happy to run tests only against an SQLite database, you can skip this section. diff --git a/README.md b/README.md index f8325b1f34de..63d75ba4bf29 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ -# Sequelize +

+ +

Sequelize

+

[![npm version](https://badgen.net/npm/v/sequelize)](https://www.npmjs.com/package/sequelize) [![Build Status](https://github.com/sequelize/sequelize/workflows/CI/badge.svg)](https://github.com/sequelize/sequelize/actions?query=workflow%3ACI) diff --git a/build.js b/build.js index 00cfc4588053..27c331908889 100644 --- a/build.js +++ b/build.js @@ -8,7 +8,6 @@ const copyFiles = promisify( require('copyfiles')); const path = require('path'); const exec = promisify(require('child_process').exec); -const rmdir = promisify(fs.rmdir); const stat = promisify(fs.stat); // if this script is moved, this will need to be adjusted @@ -20,11 +19,16 @@ const nodeMajorVersion = Number(process.version.match(/(?<=^v)\d+/)); async function rmDistDir() { try { await stat(outdir); - if (nodeMajorVersion >= 12) { - await rmdir(outdir, { recursive: true }); + if (nodeMajorVersion >= 14) { + const rm = promisify(fs.rm); + await rm(outdir, { recursive: true }); } else { - await rmdir(outdir); - } + const rmdir = promisify(fs.rmdir); + if (nodeMajorVersion >= 12) { + await rmdir(outdir, { recursive: true }); + } else { + await rmdir(outdir); + }} } catch { /* no-op */ } @@ -61,12 +65,7 @@ async function main() { outdir, entryPoints: filesToCompile .concat('./index.js') - .map(file => path.resolve(file)), - - // minify the compiled code - minify: true, - // Keep `constructor.name` the same (used for associations) - keepNames: true + .map(file => path.resolve(file)) }), exec('tsc', { diff --git a/docs/css/style.css b/docs/css/style.css index c99916d7bb00..5e3c8b469438 100644 --- a/docs/css/style.css +++ b/docs/css/style.css @@ -1,15 +1,23 @@ @import url(https://fonts.googleapis.com/css?family=Titillium+Web); +div.logo { + display: flex; + align-content: center; +} + div.logo img { - width: 200px; - height: 200px; + width: 100px; + height: 100px; box-shadow: none !important; + margin-right: 16px; } +div.logo h1, div.sequelize { color: #399af3; font-size: 60px; - font-family: 'Titillium Web', sans-serif; + font-family: "Titillium Web", sans-serif; + border-width: 0; } .center { @@ -55,8 +63,8 @@ div.sequelize { padding-bottom: 0; } -.search-box>span { - display:block; +.search-box > span { + display: block; width: 100%; } @@ -129,11 +137,11 @@ code { display: inline-block; } - .layout-container .navigation>div { + .layout-container .navigation > div { display: none; } - .layout-container .navigation.open>div { + .layout-container .navigation.open > div { display: block; } @@ -175,4 +183,4 @@ header a { a[href="source.html"], a[href^="file/lib/"] { display: none; -} \ No newline at end of file +} diff --git a/docs/index.md b/docs/index.md index c49d1a0fc882..b138089ccab8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,8 +1,6 @@ -
- -
Sequelize
+ [![npm version](https://badgen.net/npm/v/sequelize)](https://www.npmjs.com/package/sequelize) diff --git a/docs/manual-groups.json b/docs/manual-groups.json index 91bf48cc2753..a4a0596ec7dd 100644 --- a/docs/manual-groups.json +++ b/docs/manual-groups.json @@ -1,51 +1,52 @@ -{ - "Core Concepts": [ - "core-concepts/getting-started.md", - "core-concepts/model-basics.md", - "core-concepts/model-instances.md", - "core-concepts/model-querying-basics.md", - "core-concepts/model-querying-finders.md", - "core-concepts/getters-setters-virtuals.md", - "core-concepts/validations-and-constraints.md", - "core-concepts/raw-queries.md", - "core-concepts/assocs.md", - "core-concepts/paranoid.md" - ], - "Advanced Association Concepts": [ - "advanced-association-concepts/eager-loading.md", - "advanced-association-concepts/creating-with-associations.md", - "advanced-association-concepts/advanced-many-to-many.md", - "advanced-association-concepts/association-scopes.md", - "advanced-association-concepts/polymorphic-associations.md" - ], - "Other Topics": [ - "other-topics/dialect-specific-things.md", - "other-topics/transactions.md", - "other-topics/hooks.md", - "other-topics/query-interface.md", - "other-topics/naming-strategies.md", - "other-topics/scopes.md", - "other-topics/sub-queries.md", - "other-topics/other-data-types.md", - "other-topics/constraints-and-circularities.md", - "other-topics/extending-data-types.md", - "other-topics/indexes.md", - "other-topics/optimistic-locking.md", - "other-topics/read-replication.md", - "other-topics/connection-pool.md", - "other-topics/legacy.md", - "other-topics/migrations.md", - "other-topics/typescript.md", - "other-topics/resources.md", - "other-topics/upgrade-to-v6.md", - "other-topics/whos-using.md", - "other-topics/legal.md" - ], - "__hidden__": [ - "moved/associations.md", - "moved/data-types.md", - "moved/models-definition.md", - "moved/models-usage.md", - "moved/querying.md" - ] -} +{ + "Core Concepts": [ + "core-concepts/getting-started.md", + "core-concepts/model-basics.md", + "core-concepts/model-instances.md", + "core-concepts/model-querying-basics.md", + "core-concepts/model-querying-finders.md", + "core-concepts/getters-setters-virtuals.md", + "core-concepts/validations-and-constraints.md", + "core-concepts/raw-queries.md", + "core-concepts/assocs.md", + "core-concepts/paranoid.md" + ], + "Advanced Association Concepts": [ + "advanced-association-concepts/eager-loading.md", + "advanced-association-concepts/creating-with-associations.md", + "advanced-association-concepts/advanced-many-to-many.md", + "advanced-association-concepts/association-scopes.md", + "advanced-association-concepts/polymorphic-associations.md" + ], + "Other Topics": [ + "other-topics/dialect-specific-things.md", + "other-topics/transactions.md", + "other-topics/hooks.md", + "other-topics/query-interface.md", + "other-topics/naming-strategies.md", + "other-topics/scopes.md", + "other-topics/sub-queries.md", + "other-topics/other-data-types.md", + "other-topics/constraints-and-circularities.md", + "other-topics/extending-data-types.md", + "other-topics/indexes.md", + "other-topics/optimistic-locking.md", + "other-topics/read-replication.md", + "other-topics/connection-pool.md", + "other-topics/legacy.md", + "other-topics/migrations.md", + "other-topics/typescript.md", + "other-topics/resources.md", + "other-topics/upgrade-to-v6.md", + "other-topics/whos-using.md", + "other-topics/aws-lambda.md", + "other-topics/legal.md" + ], + "__hidden__": [ + "moved/associations.md", + "moved/data-types.md", + "moved/models-definition.md", + "moved/models-usage.md", + "moved/querying.md" + ] +} diff --git a/docs/manual/other-topics/aws-lambda.md b/docs/manual/other-topics/aws-lambda.md new file mode 100644 index 000000000000..002d9b277cf7 --- /dev/null +++ b/docs/manual/other-topics/aws-lambda.md @@ -0,0 +1,730 @@ +# Using sequelize in AWS Lambda + +[AWS Lambda](https://aws.amazon.com/lambda/) is a serverless computing service that allows customers +to run code without having to worry about the underlying servers. Using `sequelize` in AWS Lambda +can be tricky if certain concepts are not properly understood and an appropriate configuration is +not used. This guide seeks to clarify some of these concepts so users of the library can properly +configure `sequelize` for AWS Lambda and troubleshoot issues. + +## TL;DR + +If you just want to learn how to properly configure `sequelize` +[connection pooling](./connection-pool.html) for AWS Lambda, all you need to know is that +`sequelize` connection pooling does not get along well with AWS Lambda's Node.js runtime and it ends +up causing more problems than it solves. Therefore, the most appropriate configuration is to **use +pooling within the same invocation** and **avoid pooling across invocations** (i.e. close all +connections at the end): + +```js +const { Sequelize } = require("sequelize"); + +let sequelize = null; + +async function loadSequelize() { + const sequelize = new Sequelize(/* (...) */, { + // (...) + pool: { + /* + * Lambda functions process one request at a time but your code may issue multiple queries + * concurrently. Be wary that `sequelize` has methods that issue 2 queries concurrently + * (e.g. `Model.findAndCountAll()`). Using a value higher than 1 allows concurrent queries to + * be executed in parallel rather than serialized. Careful with executing too many queries in + * parallel per Lambda function execution since that can bring down your database with an + * excessive number of connections. + * + * Ideally you want to choose a `max` number where this holds true: + * max * EXPECTED_MAX_CONCURRENT_LAMBDA_INVOCATIONS < MAX_ALLOWED_DATABASE_CONNECTIONS * 0.8 + */ + max: 2, + /* + * Set this value to 0 so connection pool eviction logic eventually cleans up all connections + * in the event of a Lambda function timeout. + */ + min: 0, + /* + * Set this value to 0 so connections are eligible for cleanup immediately after they're + * returned to the pool. + */ + idle: 0, + // Choose a small enough value that fails fast if a connection takes too long to be established. + acquire: 3000, + /* + * Ensures the connection pool attempts to be cleaned up automatically on the next Lambda + * function invocation, if the previous invocation timed out. + */ + evict: CURRENT_LAMBDA_FUNCTION_TIMEOUT + } + }); + + // or `sequelize.sync()` + await sequelize.authenticate(); + + return sequelize; +} + +module.exports.handler = async function (event, callback) { + // re-use the sequelize instance across invocations to improve performance + if (!sequelize) { + sequelize = await loadSequelize(); + } else { + // restart connection pool to ensure connections are not re-used across invocations + sequelize.connectionManager.initPools(); + + // restore `getConnection()` if it has been overwritten by `close()` + if (sequelize.connectionManager.hasOwnProperty("getConnection")) { + delete sequelize.connectionManager.getConnection; + } + } + + try { + return await doSomethingWithSequelize(sequelize); + } finally { + // close any opened connections during the invocation + // this will wait for any in-progress queries to finish before closing the connections + await sequelize.connectionManager.close(); + } +}; +``` + +### Using AWS RDS Proxy + +If your are using [AWS RDS](https://aws.amazon.com/rds/) and you are using +[Aurora](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/rds-proxy.html) or a +[supported database engine](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html), +then connect to your database using [AWS RDS Proxy](https://aws.amazon.com/rds/proxy/). This will +make sure that opening/closing connections on each invocation is not an expensive operation for +your underlying database server. + +--- + +If you want to understand why you must use sequelize this way in AWS Lambda, continue reading the +rest of this document: + +## The Node.js event loop + +The [Node.js event loop](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/) is: + +> what allows Node.js to perform non-blocking I/O operations — despite the fact that JavaScript is +> single-threaded — + +While the event loop implementation is in C++, here's a simplified JavaScript pseudo-implementation +that illustrates how Node.js would execute a script named `index.js`: + +```js +// see: https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/ +// see: https://www.youtube.com/watch?v=P9csgxBgaZ8 +// see: https://www.youtube.com/watch?v=PNa9OMajw9w +const process = require('process'); + +/* + * counter of pending events + * + * reference counter is increased for every: + * + * 1. scheduled timer: `setTimeout()`, `setInterval()`, etc. + * 2. scheduled immediate: `setImmediate()`. + * 3. syscall of non-blocking IO: `require('net').Server.listen()`, etc. + * 4. scheduled task to the thread pool: `require('fs').WriteStream.write()`, etc. + * + * reference counter is decreased for every: + * + * 1. elapsed timer + * 2. executed immediate + * 3. completed non-blocking IO + * 4. completed thread pool task + * + * references can be explicitly decreased by invoking `.unref()` on some + * objects like: `require('net').Socket.unref()` + */ +let refs = 0; + +/* + * a heap of timers, sorted by next ocurrence + * + * whenever `setTimeout()` or `setInterval()` is invoked, a timer gets added here + */ +const timersHeap = /* (...) */; + +/* + * a FIFO queue of immediates + * + * whenever `setImmediate()` is invoked, it gets added here + */ +const immediates = /* (...) */; + +/* + * a FIFO queue of next tick callbacks + * + * whenever `require('process').nextTick()` is invoked, the callback gets added here + */ +const nextTickCallbacks = []; + +/* + * a heap of Promise-related callbacks, sorted by promise constructors callbacks first, + * and then resolved/rejected callbacks + * + * whenever a new Promise instance is created via `new Promise` or a promise resolves/rejects + * the appropriate callback (if any) gets added here + */ +const promiseCallbacksHeap = /* ... */; + +function execTicksAndPromises() { + while (nextTickCallbacks.length || promiseCallbacksHeap.size()) { + // execute all callbacks scheduled with `process.nextTick()` + while (nextTickCallbacks.length) { + const callback = nextTickCallbacks.shift(); + callback(); + } + + // execute all promise-related callbacks + while (promiseCallbacksHeap.size()) { + const callback = promiseCallbacksHeap.pop(); + callback(); + } + } +} + +try { + // execute index.js + require('./index'); + execTicksAndPromises(); + + do { + // timers phase: executes all elapsed timers + getElapsedTimerCallbacks(timersHeap).forEach(callback => { + callback(); + execTicksAndPromises(); + }); + + // pending callbacks phase: executes some system operations (like `TCP errors`) that are not + // executed in the poll phase + getPendingCallbacks().forEach(callback => { + callback(); + execTicksAndPromises(); + }) + + // poll phase: gets completed non-blocking I/O events or thread pool tasks and invokes the + // corresponding callbacks; if there are none and there's no pending immediates, + // it blocks waiting for events/completed tasks for a maximum of `maxWait` + const maxWait = computeWhenNextTimerElapses(timersHeap); + pollForEventsFromKernelOrThreadPool(maxWait, immediates).forEach(callback => { + callback(); + execTicksAndPromises(); + }); + + // check phase: execute available immediates; if an immediate callback invokes `setImmediate()` + // it will be invoked on the next event loop iteration + getImmediateCallbacks(immediates).forEach(callback => { + callback(); + execTicksAndPromises(); + }); + + // close callbacks phase: execute special `.on('close')` callbacks + getCloseCallbacks().forEach(callback => { + callback(); + execTicksAndPromises(); + }); + + if (refs === 0) { + // listeners of this event may execute code that increments `refs` + process.emit('beforeExit'); + } + } while (refs > 0); +} catch (err) { + if (!process.listenerCount('uncaughtException')) { + // default behavior: print stack and exit with status code 1 + console.error(err.stack); + process.exit(1); + } else { + // there are listeners: emit the event and exit using `process.exitCode || 0` + process.emit('uncaughtException'); + process.exit(); + } +} +``` + +## AWS Lambda function handler types in Node.js + +AWS Lambda handlers come in two flavors in Node.js: + +[Non-async handlers](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html#nodejs-handler-sync) +(i.e. `callback`): + +```js +module.exports.handler = function (event, context, callback) { + try { + doSomething(); + callback(null, "Hello World!"); // Lambda returns "Hello World!" + } catch (err) { + // try/catch is not required, uncaught exceptions invoke `callback(err)` implicitly + callback(err); // Lambda fails with `err` + } +}; +``` + +[Async handlers](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html#nodejs-handler-async) +(i.e. use `async`/`await` or `Promise`s): + +```js +// async/await +module.exports.handler = async function (event, context) { + try { + await doSomethingAsync(); + return "Hello World!"; // equivalent of: callback(null, "Hello World!"); + } catch (err) { + // try/cath is not required, async functions always return a Promise + throw err; // equivalent of: callback(err); + } +}; + +// Promise +module.exports.handler = function (event, context) { + /* + * must return a `Promise` to be considered an async handler + * + * an uncaught exception that prevents a `Promise` to be returned + * by the handler will "downgrade" the handler to non-async + */ + return Promise.resolve() + .then(() => doSomethingAsync()) + .then(() => "Hello World!"); +}; +``` + +While at first glance it seems like async VS non-async handlers are simply a code styling choice, +there is a fundamental difference between the two: + +- In async handlers, a Lambda function execution finishes when the `Promise` returned by the handler + resolves or rejects, regardless of whether the event loop is empty or not. +- In non-async handlers, a Lambda function execution finishes when one of the following conditions + occur: + - The event loop is empty + ([process `'beforeExit'` event](https://nodejs.org/dist/latest-v12.x/docs/api/process.html#process_event_beforeexit) + is used to detect this). + - The `callback` argument is invoked and + [`context.callbackWaitsForEmptyEventLoop`](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-context.html) + is set to `false`. + +This fundamental difference is very important to understand in order to rationalize how `sequelize` +may be affected by it. Here are a few examples to illustrate the difference: + +```js +// no callback invoked +module.exports.handler = function () { + // Lambda finishes AFTER `doSomething()` is invoked + setTimeout(() => doSomething(), 1000); +}; + +// callback invoked +module.exports.handler = function (event, context, callback) { + // Lambda finishes AFTER `doSomething()` is invoked + setTimeout(() => doSomething(), 1000); + callback(null, "Hello World!"); +}; + +// callback invoked, context.callbackWaitsForEmptyEventLoop = false +module.exports.handler = function (event, context, callback) { + // Lambda finishes BEFORE `doSomething()` is invoked + context.callbackWaitsForEmptyEventLoop = false; + setTimeout(() => doSomething(), 2000); + setTimeout(() => callback(null, "Hello World!"), 1000); +}; + +// async/await +module.exports.handler = async function () { + // Lambda finishes BEFORE `doSomething()` is invoked + setTimeout(() => doSomething(), 1000); + return "Hello World!"; +}; + +// Promise +module.exports.handler = function () { + // Lambda finishes BEFORE `doSomething()` is invoked + setTimeout(() => doSomething(), 1000); + return Promise.resolve("Hello World!"); +}; +``` + +## AWS Lambda execution environments (i.e. containers) + +AWS Lambda function handlers are invoked by built-in or custom +[runtimes](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html) which run in +execution environments (i.e. containers) that +[may or may not be re-used](https://aws.amazon.com/blogs/compute/container-reuse-in-lambda/) +across invocations. Containers can only process +[one request at a time](https://docs.aws.amazon.com/lambda/latest/dg/configuration-concurrency.html). +Concurrent invocations of a Lambda function means that a container instance will be created for each +concurrent request. + +In practice, this means that Lambda functions should be designed to be stateless but developers can +use state for caching purposes: + +```js +let sequelize = null; + +module.exports.handler = async function () { + /* + * sequelize will already be loaded if the container is re-used + * + * containers are never re-used when a Lambda function's code change + * + * while the time elapsed between Lambda invocations is used as a factor to determine whether + * a container is re-used, no assumptions should be made of when a container is actually re-used + * + * AWS does not publicly document the rules of container re-use "by design" since containers + * can be recycled in response to internal AWS Lambda events (e.g. a Lambda function container + * may be recycled even if the function is constanly invoked) + */ + if (!sequelize) { + sequelize = await loadSequelize(); + } + + return await doSomethingWithSequelize(sequelize); +}; +``` + +When a Lambda function doesn't wait for the event loop to be empty and a container is re-used, +the event loop will be "paused" until the next invocation occurs. For example: + +```js +let counter = 0; + +module.exports.handler = function (event, context, callback) { + /* + * The first invocation (i.e. container initialized) will: + * - log: + * - Fast timeout invoked. Request id: 00000000-0000-0000-0000-000000000000 | Elapsed ms: 5XX + * - return: 1 + * + * Wait 3 seconds and invoke the Lambda again. The invocation (i.e. container re-used) will: + * - log: + * - Slow timeout invoked. Request id: 00000000-0000-0000-0000-000000000000 | Elapsed ms: 3XXX + * - Fast timeout invoked. Request id: 11111111-1111-1111-1111-111111111111 | Elapsed ms: 5XX + * - return: 3 + */ + const now = Date.now(); + + context.callbackWaitsForEmptyEventLoop = false; + + setTimeout(() => { + console.log( + "Slow timeout invoked. Request id:", + context.awsRequestId, + "| Elapsed ms:", + Date.now() - now + ); + counter++; + }, 1000); + + setTimeout(() => { + console.log( + "Fast timeout invoked. Request id:", + context.awsRequestId, + "| Elapsed ms:", + Date.now() - now + ); + counter++; + callback(null, counter); + }, 500); +}; +``` + +## Sequelize connection pooling in AWS Lambda + +`sequelize` uses connection pooling for optimizing usage of database connections. The connection +pool used by `sequelize` is implemented using `setTimeout()` callbacks (which are processed by the +Node.js event loop). + +Given the fact that AWS Lambda containers process one request at a time, one would be tempted to +configure `sequelize` as follows: + +```js +const { Sequelize } = require('sequelize'); + +const sequelize = new Sequelize(/* (...) */, { + // (...) + pool: { min: 1, max: 1 } +}); +``` + +This configuration prevents Lambda containers from overwhelming the database server with an +excessive number of connections (since each container takes at most 1 connection). It also makes +sure that the container's connection is not garbage collected when idle so the connection does not +need to be re-established when the Lambda container is re-used. Unfortunately, this configuration +presents a set of issues: + +1. Lambdas that wait for the event loop to be empty will always time out. `sequelize` connection + pools schedule a `setTimeout` every + [`options.pool.evict`](../class/lib/sequelize.js~Sequelize.html#instance-constructor-constructor) + ms until **all idle connections have been closed**. However, since `min` is set to `1`, there + will always be at least one idle connection in the pool, resulting in an infinite event loop. +1. Some operations like + [`Model.findAndCountAll()`](../class/lib/model.js~Model.html#static-method-findAndCountAll) + execute multiple queries asynchronously (e.g. + [`Model.count()`](..class/lib/model.js~Model.html#static-method-count) and + [`Model.findAll()`](../class/lib/model.js~Model.html#static-method-findAll)). Using a maximum of + one connection forces the queries to be exectued serially (rather than in parallel using two + connections). While this may be an acceptable performance compromise in order to + maintain a manageable number of database connections, long running queries may result in + [`ConnectionAcquireTimeoutError`](../class/lib/errors/connection/connection-acquire-timeout-error.js~ConnectionAcquireTimeoutError.html) + if a query takes more than the default or configured + [`options.pool.acquire`](../class/lib/sequelize.js~Sequelize.html#instance-constructor-constructor) + timeout to complete. This is because the serialized query will be stuck waiting on the pool until + the connection used by the other query is released. +1. If the AWS Lambda function times out (i.e. the configured AWS Lambda timeout is exceeded), the + Node.js event loop will be "paused" regardless of its state. This can cause race conditions that + result in connection errors. For example, you may encounter situations where a very expensive + query causes a Lambda function to time out, the event loop is "paused" before the expensive query + finishes and the connection is released back to the pool, and subsequent Lambda invocations fail + with a `ConnectionAcquireTimeoutError` if the container is re-used and the connection has not + been returned after `options.pool.acquire` ms. + +You can attempt to mitigate issue **#2** by using `{ min: 1, max: 2 }`. However, this will still +suffer from issues **#1** and **#3** whilst introducing additional ones: + +1. Race conditions may occur where the even loop "pauses" before a connection pool eviction callback + executes or more than `options.pool.evict` time elapses between Lambda invocations. This can + result in timeout errors, handshake errors, and other connection-related errors. +1. If you use an operation like `Model.findAndCountAll()` and either the underlying `Model.count()` + or `Model.findAll()` queries fail, you won't be able to ensure that the other query has finished + executing (and the connection is put back into the pool) before the Lambda function execution + finishes and the event loop is "paused". This can leave connections in a stale state which can + result in prematurely closed TCP connections and other connection-related errors. + +Using `{ min: 2, max: 2 }` mitigates additional issue **#1**. However, the configuration still +suffers from all the other issues (original **#1**, **#3**, and additional **#2**). + +### Detailed race condition example + +In order to make sense of the example, you'll need a bit more context of how certain parts of +Lambda and `sequelize` are implemented. + +The built-in AWS Lambda runtime for `nodejs.12x` is implemented in Node.js. You can access the +entire source code of the runtime by reading the contents of `/var/runtime/` inside a Node.js Lambda +function. The relevant subset of the code is as follows: + +**runtime/Runtime.js** + +```js +class Runtime { + // (...) + + // each iteration is executed in the event loop `check` phase + scheduleIteration() { + setImmediate(() => this.handleOnce().then(/* (...) */)); + } + + async handleOnce() { + // get next invocation. see: https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html#runtimes-api-next + let { bodyJson, headers } = await this.client.nextInvocation(); + + // prepare `context` handler parameter + let invokeContext = new InvokeContext(headers); + invokeContext.updateLoggingContext(); + + // prepare `callback` handler parameter + let [callback, callbackContext] = CallbackContext.build( + this.client, + invokeContext.invokeId, + this.scheduleIteration.bind(this) + ); + + try { + // this listener is subscribed to process.on('beforeExit') + // so that when when `context.callbackWaitsForEmptyEventLoop === true` + // the Lambda execution finishes after the event loop is empty + this._setDefaultExitListener(invokeContext.invokeId); + + // execute handler + const result = this.handler( + JSON.parse(bodyJson), + invokeContext.attachEnvironmentData(callbackContext), + callback + ); + + // finish the execution if the handler is async + if (_isPromise(result)) { + result + .then(callbackContext.succeed, callbackContext.fail) + .catch(callbackContext.fail); + } + } catch (err) { + callback(err); + } + } +} +``` + +The runtime schedules an iteration at the end of the initialization code: + +**runtime/index.js** + +```js +// (...) + +new Runtime(client, handler, errorCallbacks).scheduleIteration(); +``` + +All SQL queries invoked by a Lambda handler using `sequelize` are ultimately executed using +[Sequelize.prototype.query()](../class/lib/sequelize.js~Sequelize.html#instance-method-query). +This method is responsible for obtaining a connection from the pool, executing the query, and +releasing the connection back to the pool when the query completes. The following snippet shows +a simplification of the method's logic for queries without transactions: + +**sequelize.js** + +```js +class Sequelize { + // (...) + + query(sql, options) { + // (...) + + const connection = await this.connectionManager.getConnection(options); + const query = new this.dialect.Query(connection, this, options); + + try { + return await query.run(sql, bindParameters); + } finally { + await this.connectionManager.releaseConnection(connection); + } + } +} +``` + +The field `this.connectionManager` is an instance of a dialect-specific `ConnectionManager` class. +All dialect-specific managers inherit from an abstract `ConnectionManager` class which initializes +the connection pool and configures it to invoke the dialect-specific class' `connect()` method +everytime a new connection needs to be created. The following snippet shows a simplification of the +`mysql` dialect `connect()` method: + +**mysql/connection-manager.js** + +```js +class ConnectionManager { + // (...) + + async connect(config) { + // (...) + return await new Promise((resolve, reject) => { + // uses mysql2's `new Connection()` + const connection = this.lib.createConnection(connectionConfig); + + const errorHandler = (e) => { + connection.removeListener("connect", connectHandler); + connection.removeListener("error", connectHandler); + reject(e); + }; + + const connectHandler = () => { + connection.removeListener("error", errorHandler); + resolve(connection); + }; + + connection.on("error", errorHandler); + connection.once("connect", connectHandler); + }); + } +} +``` + +The field `this.lib` refers to [`mysql2`](https://www.npmjs.com/package/mysql2) and the function +`createConnection()` creates a connection by creating an instance of a `Connection` class. The +relevant subset of this class is as follows: + +**mysql2/connection.js** + +```js +class Connection extends EventEmitter { + constructor(opts) { + // (...) + + // create Socket + this.stream = /* (...) */; + + // when data is received, clear timeout + this.stream.on('data', data => { + if (this.connectTimeout) { + Timers.clearTimeout(this.connectTimeout); + this.connectTimeout = null; + } + this.packetParser.execute(data); + }); + + // (...) + + // when handshake is completed, emit the 'connect' event + handshakeCommand.on('end', () => { + this.emit('connect', handshakeCommand.handshake); + }); + + // set a timeout to trigger if no data is received on the socket + if (this.config.connectTimeout) { + const timeoutHandler = this._handleTimeoutError.bind(this); + this.connectTimeout = Timers.setTimeout( + timeoutHandler, + this.config.connectTimeout + ); + } + } + + // (...) + + _handleTimeoutError() { + if (this.connectTimeout) { + Timers.clearTimeout(this.connectTimeout); + this.connectTimeout = null; + } + this.stream.destroy && this.stream.destroy(); + const err = new Error('connect ETIMEDOUT'); + err.errorno = 'ETIMEDOUT'; + err.code = 'ETIMEDOUT'; + err.syscall = 'connect'; + + // this will emit the 'error' event + this._handleNetworkError(err); + } +} +``` + +Based on the previous code, the following sequence of events shows how a connection pooling +race condition with `{ min: 1, max: 1 }` can result with in a `ETIMEDOUT` error: + +1. A Lambda invocation is received (new container): + 1. The event loop enters the `check` phase and `runtime/Runtime.js`'s `handleOnce()` method is + invoked. + 1. The `handleOnce()` method invokes `await this.client.nextInvocation()` and waits. + 1. The event loop skips the `timers` phase since there no pending timers. + 1. The event loop enters the `poll` phase and the `handleOnce()` method continues. + 1. The Lambda handler is invoked. + 1. The Lambda handler invokes `Model.count()` which invokes `sequelize.js`'s `query()` which + invokes `connectionManager.getConnection()`. + 1. The connection pool initializes a `setTimeout(..., config.pool.acquire)` for `Model.count()` + and invokes `mysql/connection-manager.js`'s `connect()` to create a new connection. + 1. `mysql2/connection.js` creates the TCP socket and initializes a `setTimeout()` for failing + the connection with `ETIMEDOUT`. + 1. The promise returned by the handler rejects (for reasons not detailed here) so the Lambda + function execution finishes and the Node.js event loop is "paused". +1. Enough time elapses beween invocations so that: + 1. `config.pool.acquire` timer elapses. + 1. `mysql2` connection timer has not elapsed yet but has almost elapsed (i.e. race condition). +1. A second Lambda invocation is received (container re-used): + 1. The event loop is "resumed". + 1. The event loop enters the `check` phase and `runtime/Runtime.js`'s `handleOnce()` method is + invoked. + 1. The event loop enters the `timers` phase and the `config.pool.acquire` timer elapses, causing + the previous invocation's `Model.count()` promise to reject with + `ConnectionAcquireTimeoutError`. + 1. The event loop enters the `poll` phase and the `handleOnce()` method continues. + 1. The Lambda handler is invoked. + 1. The Lambda handler invokes `Model.count()` which invokes `sequelize.js`'s `query()` which + invokes `connectionManager.getConnection()`. + 1. The connection pool initializes a `setTimeout(..., config.pool.acquire)` for `Model.count()` + and since `{ max : 1 }` it waits for the pending `connect()` promise to complete. + 1. The event loop skips the `check` phase since there are no pending immediates. + 1. **Race condition:** The event loop enters the `timers` phase and the `mysql2` connection + timeout elapses, resulting in a `ETIMEDOUT` error that is emitted using + `connection.emit('error')`. + 1. The emitted event rejects the promise in `mysql/connection-manager.js`'s `connect()` which + in turn forwards the rejected promise to the `Model.count()` query's promise. + 1. The lambda function fails with an `ETIMEDOUT` error. diff --git a/docs/manual/other-topics/dialect-specific-things.md b/docs/manual/other-topics/dialect-specific-things.md index d7c5e9427609..666bc30d2cab 100644 --- a/docs/manual/other-topics/dialect-specific-things.md +++ b/docs/manual/other-topics/dialect-specific-things.md @@ -1,218 +1,237 @@ -# Dialect-Specific Things - -## Underlying Connector Libraries - -### MySQL - -The underlying connector library used by Sequelize for MySQL is the [mysql2](https://www.npmjs.com/package/mysql2) npm package (version 1.5.2 or higher). - -You can provide custom options to it using the `dialectOptions` in the Sequelize constructor: - -```js -const sequelize = new Sequelize('database', 'username', 'password', { - dialect: 'mysql', - dialectOptions: { - // Your mysql2 options here - } -}) -``` - -### MariaDB - -The underlying connector library used by Sequelize for MariaDB is the [mariadb](https://www.npmjs.com/package/mariadb) npm package. - -You can provide custom options to it using the `dialectOptions` in the Sequelize constructor: - -```js -const sequelize = new Sequelize('database', 'username', 'password', { - dialect: 'mariadb', - dialectOptions: { - // Your mariadb options here - // connectTimeout: 1000 - } -}); -``` - -### SQLite - -The underlying connector library used by Sequelize for SQLite is the [sqlite3](https://www.npmjs.com/package/sqlite3) npm package (version 4.0.0 or above). - -You specify the storage file in the Sequelize constructor with the `storage` option (use `:memory:` for an in-memory SQLite instance). - -You can provide custom options to it using the `dialectOptions` in the Sequelize constructor: - -```js -const sequelize = new Sequelize('database', 'username', 'password', { - dialect: 'sqlite', - storage: 'path/to/database.sqlite' // or ':memory:' - dialectOptions: { - // Your sqlite3 options here - } -}); -``` - -### PostgreSQL - -The underlying connector library used by Sequelize for PostgreSQL is the [pg](https://www.npmjs.com/package/pg) npm package (version 7.0.0 or above). The module [pg-hstore](https://www.npmjs.com/package/pg-hstore) is also necessary. - -You can provide custom options to it using the `dialectOptions` in the Sequelize constructor: - -```js -const sequelize = new Sequelize('database', 'username', 'password', { - dialect: 'postgres', - dialectOptions: { - // Your pg options here - } -}); -``` - -To connect over a unix domain socket, specify the path to the socket directory in the `host` option. The socket path must start with `/`. - -```js -const sequelize = new Sequelize('database', 'username', 'password', { - dialect: 'postgres', - host: '/path/to/socket_directory' -}); -``` - -### MSSQL - -The underlying connector library used by Sequelize for MSSQL is the [tedious](https://www.npmjs.com/package/tedious) npm package (version 6.0.0 or above). - -You can provide custom options to it using `dialectOptions.options` in the Sequelize constructor: - -```js -const sequelize = new Sequelize('database', 'username', 'password', { - dialect: 'mssql', - dialectOptions: { - // Observe the need for this nested `options` field for MSSQL - options: { - // Your tedious options here - useUTC: false, - dateFirst: 1 - } - } -}); -``` - -#### MSSQL Domain Account - -In order to connect with a domain account, use the following format. - -```js -const sequelize = new Sequelize('database', null, null, { - dialect: 'mssql', - dialectOptions: { - authentication: { - type: 'ntlm', - options: { - domain: 'yourDomain', - userName: 'username', - password: 'password' - } - }, - options: { - instanceName: 'SQLEXPRESS' - } - } -}) -``` - -## Data type: TIMESTAMP WITHOUT TIME ZONE - PostgreSQL only - -If you are working with the PostgreSQL `TIMESTAMP WITHOUT TIME ZONE` and you need to parse it to a different timezone, please use the pg library's own parser: - -```js -require('pg').types.setTypeParser(1114, stringValue => { - return new Date(stringValue + '+0000'); - // e.g., UTC offset. Use any offset that you would like. -}); -``` - -## Data type: ARRAY(ENUM) - PostgreSQL only - -Array(Enum) type requireS special treatment. Whenever Sequelize will talk to the database, it has to typecast array values with ENUM name. - -So this enum name must follow this pattern `enum__`. If you are using `sync` then correct name will automatically be generated. - -## Table Hints - MSSQL only - -The `tableHint` option can be used to define a table hint. The hint must be a value from `TableHints` and should only be used when absolutely necessary. Only a single table hint is currently supported per query. - -Table hints override the default behavior of MSSQL query optimizer by specifing certain options. They only affect the table or view referenced in that clause. - -```js -const { TableHints } = require('sequelize'); -Project.findAll({ - // adding the table hint NOLOCK - tableHint: TableHints.NOLOCK - // this will generate the SQL 'WITH (NOLOCK)' -}) -``` - -## Index Hints - MySQL/MariaDB only - -The `indexHints` option can be used to define index hints. The hint type must be a value from `IndexHints` and the values should reference existing indexes. - -Index hints [override the default behavior of the MySQL query optimizer](https://dev.mysql.com/doc/refman/5.7/en/index-hints.html). - -```js -const { IndexHints } = require("sequelize"); -Project.findAll({ - indexHints: [ - { type: IndexHints.USE, values: ['index_project_on_name'] } - ], - where: { - id: { - [Op.gt]: 623 - }, - name: { - [Op.like]: 'Foo %' - } - } -}); -``` - -The above will generate a MySQL query that looks like this: - -```sql -SELECT * FROM Project USE INDEX (index_project_on_name) WHERE name LIKE 'FOO %' AND id > 623; -``` - -`Sequelize.IndexHints` includes `USE`, `FORCE`, and `IGNORE`. - -See [Issue #9421](https://github.com/sequelize/sequelize/issues/9421) for the original API proposal. - -## Engines - MySQL/MariaDB only - -The default engine for a model is InnoDB. - -You can change the engine for a model with the `engine` option (e.g., to MyISAM): - -```js -const Person = sequelize.define('person', { /* attributes */ }, { - engine: 'MYISAM' -}); -``` - -Like every option for the definition of a model, this setting can also be changed globally with the `define` option of the Sequelize constructor: - -```js -const sequelize = new Sequelize(db, user, pw, { - define: { engine: 'MYISAM' } -}) -``` - -## Table comments - MySQL/MariaDB/PostgreSQL only - -You can specify a comment for a table when defining the model: - -```js -class Person extends Model {} -Person.init({ /* attributes */ }, { - comment: "I'm a table comment!", - sequelize -}) -``` - -The comment will be set when calling `sync()`. +# Dialect-Specific Things + +## Underlying Connector Libraries + +### MySQL + +The underlying connector library used by Sequelize for MySQL is the [mysql2](https://www.npmjs.com/package/mysql2) npm package (version 1.5.2 or higher). + +You can provide custom options to it using the `dialectOptions` in the Sequelize constructor: + +```js +const sequelize = new Sequelize('database', 'username', 'password', { + dialect: 'mysql', + dialectOptions: { + // Your mysql2 options here + } +}) +``` + +### MariaDB + +The underlying connector library used by Sequelize for MariaDB is the [mariadb](https://www.npmjs.com/package/mariadb) npm package. + +You can provide custom options to it using the `dialectOptions` in the Sequelize constructor: + +```js +const sequelize = new Sequelize('database', 'username', 'password', { + dialect: 'mariadb', + dialectOptions: { + // Your mariadb options here + // connectTimeout: 1000 + } +}); +``` + +### SQLite + +The underlying connector library used by Sequelize for SQLite is the [sqlite3](https://www.npmjs.com/package/sqlite3) npm package (version 4.0.0 or above). + +You specify the storage file in the Sequelize constructor with the `storage` option (use `:memory:` for an in-memory SQLite instance). + +You can provide custom options to it using the `dialectOptions` in the Sequelize constructor: + +```js +const sequelize = new Sequelize('database', 'username', 'password', { + dialect: 'sqlite', + storage: 'path/to/database.sqlite' // or ':memory:' + dialectOptions: { + // Your sqlite3 options here + } +}); +``` + +### PostgreSQL + +The underlying connector library used by Sequelize for PostgreSQL is the [pg](https://www.npmjs.com/package/pg) npm package (version 7.0.0 or above). The module [pg-hstore](https://www.npmjs.com/package/pg-hstore) is also necessary. + +You can provide custom options to it using the `dialectOptions` in the Sequelize constructor: + +```js +const sequelize = new Sequelize('database', 'username', 'password', { + dialect: 'postgres', + dialectOptions: { + // Your pg options here + } +}); +``` + +To connect over a unix domain socket, specify the path to the socket directory in the `host` option. The socket path must start with `/`. + +```js +const sequelize = new Sequelize('database', 'username', 'password', { + dialect: 'postgres', + host: '/path/to/socket_directory' +}); +``` + +The default `client_min_messages` config in sequelize is `WARNING`. + +### Redshift + +Most configuration is same as PostgreSQL above. + +Redshift doesn't support `client_min_messages`, 'ignore' is needed to skip the configuration: + +```js +const sequelize = new Sequelize('database', 'username', 'password', { + dialect: 'postgres', + dialectOptions: { + // Your pg options here + // ... + clientMinMessages: 'ignore' // case insensitive + } +}); +``` + +### MSSQL + +The underlying connector library used by Sequelize for MSSQL is the [tedious](https://www.npmjs.com/package/tedious) npm package (version 6.0.0 or above). + +You can provide custom options to it using `dialectOptions.options` in the Sequelize constructor: + +```js +const sequelize = new Sequelize('database', 'username', 'password', { + dialect: 'mssql', + dialectOptions: { + // Observe the need for this nested `options` field for MSSQL + options: { + // Your tedious options here + useUTC: false, + dateFirst: 1 + } + } +}); +``` + +#### MSSQL Domain Account + +In order to connect with a domain account, use the following format. + +```js +const sequelize = new Sequelize('database', null, null, { + dialect: 'mssql', + dialectOptions: { + authentication: { + type: 'ntlm', + options: { + domain: 'yourDomain', + userName: 'username', + password: 'password' + } + }, + options: { + instanceName: 'SQLEXPRESS' + } + } +}) +``` + +## Data type: TIMESTAMP WITHOUT TIME ZONE - PostgreSQL only + +If you are working with the PostgreSQL `TIMESTAMP WITHOUT TIME ZONE` and you need to parse it to a different timezone, please use the pg library's own parser: + +```js +require('pg').types.setTypeParser(1114, stringValue => { + return new Date(stringValue + '+0000'); + // e.g., UTC offset. Use any offset that you would like. +}); +``` + +## Data type: ARRAY(ENUM) - PostgreSQL only + +Array(Enum) type requireS special treatment. Whenever Sequelize will talk to the database, it has to typecast array values with ENUM name. + +So this enum name must follow this pattern `enum__`. If you are using `sync` then correct name will automatically be generated. + +## Table Hints - MSSQL only + +The `tableHint` option can be used to define a table hint. The hint must be a value from `TableHints` and should only be used when absolutely necessary. Only a single table hint is currently supported per query. + +Table hints override the default behavior of MSSQL query optimizer by specifing certain options. They only affect the table or view referenced in that clause. + +```js +const { TableHints } = require('sequelize'); +Project.findAll({ + // adding the table hint NOLOCK + tableHint: TableHints.NOLOCK + // this will generate the SQL 'WITH (NOLOCK)' +}) +``` + +## Index Hints - MySQL/MariaDB only + +The `indexHints` option can be used to define index hints. The hint type must be a value from `IndexHints` and the values should reference existing indexes. + +Index hints [override the default behavior of the MySQL query optimizer](https://dev.mysql.com/doc/refman/5.7/en/index-hints.html). + +```js +const { IndexHints } = require("sequelize"); +Project.findAll({ + indexHints: [ + { type: IndexHints.USE, values: ['index_project_on_name'] } + ], + where: { + id: { + [Op.gt]: 623 + }, + name: { + [Op.like]: 'Foo %' + } + } +}); +``` + +The above will generate a MySQL query that looks like this: + +```sql +SELECT * FROM Project USE INDEX (index_project_on_name) WHERE name LIKE 'FOO %' AND id > 623; +``` + +`Sequelize.IndexHints` includes `USE`, `FORCE`, and `IGNORE`. + +See [Issue #9421](https://github.com/sequelize/sequelize/issues/9421) for the original API proposal. + +## Engines - MySQL/MariaDB only + +The default engine for a model is InnoDB. + +You can change the engine for a model with the `engine` option (e.g., to MyISAM): + +```js +const Person = sequelize.define('person', { /* attributes */ }, { + engine: 'MYISAM' +}); +``` + +Like every option for the definition of a model, this setting can also be changed globally with the `define` option of the Sequelize constructor: + +```js +const sequelize = new Sequelize(db, user, pw, { + define: { engine: 'MYISAM' } +}) +``` + +## Table comments - MySQL/MariaDB/PostgreSQL only + +You can specify a comment for a table when defining the model: + +```js +class Person extends Model {} +Person.init({ /* attributes */ }, { + comment: "I'm a table comment!", + sequelize +}) +``` + +The comment will be set when calling `sync()`. diff --git a/lib/associations/belongs-to-many.js b/lib/associations/belongs-to-many.js index 6de259eb3f4b..cf0cebce2612 100644 --- a/lib/associations/belongs-to-many.js +++ b/lib/associations/belongs-to-many.js @@ -264,7 +264,7 @@ class BelongsToMany extends Association { // but ignore any keys that are part of this association (#5865) _.each(this.through.model.rawAttributes, (attribute, attributeName) => { if (attribute.primaryKey === true && attribute._autoGenerated === true) { - if (attributeName === this.foreignKey || attributeName === this.otherKey) { + if ([this.foreignKey, this.otherKey].includes(attributeName)) { // this key is still needed as it's part of the association // so just set primaryKey to false attribute.primaryKey = false; diff --git a/lib/associations/belongs-to.js b/lib/associations/belongs-to.js index cf78bd5b021c..a7ad48fa24bd 100644 --- a/lib/associations/belongs-to.js +++ b/lib/associations/belongs-to.js @@ -185,7 +185,7 @@ class BelongsTo extends Association { * Set the associated model. * * @param {Model} sourceInstance the source instance - * @param {?|string|number} [associatedInstance] An persisted instance or the primary key of an instance to associate with this. Pass `null` or `undefined` to remove the association. + * @param {?Model|string|number} [associatedInstance] An persisted instance or the primary key of an instance to associate with this. Pass `null` or `undefined` to remove the association. * @param {object} [options={}] options passed to `this.save` * @param {boolean} [options.save=true] Skip saving this after setting the foreign key if false. * diff --git a/lib/associations/has-one.js b/lib/associations/has-one.js index 6d19f4263c0a..df9d74fad649 100644 --- a/lib/associations/has-one.js +++ b/lib/associations/has-one.js @@ -185,7 +185,7 @@ class HasOne extends Association { * Set the associated model. * * @param {Model} sourceInstance the source instance - * @param {?|string|number} [associatedInstance] An persisted instance or the primary key of an instance to associate with this. Pass `null` or `undefined` to remove the association. + * @param {?Model|string|number} [associatedInstance] An persisted instance or the primary key of an instance to associate with this. Pass `null` or `undefined` to remove the association. * @param {object} [options] Options passed to getAssociation and `target.save` * * @returns {Promise} diff --git a/lib/data-types.js b/lib/data-types.js index 90640c9608d7..44d841ead541 100644 --- a/lib/data-types.js +++ b/lib/data-types.js @@ -802,7 +802,7 @@ class ARRAY extends ABSTRACT { * DataTypes.GEOMETRY('POINT', 4326) * * @example Create a new point - * const point = { type: 'Point', coordinates: [39.807222,-76.984722]}; + * const point = { type: 'Point', coordinates: [-76.984722, 39.807222]}; // GeoJson format: [lng, lat] * * User.create({username: 'username', geometry: point }); * @@ -822,7 +822,7 @@ class ARRAY extends ABSTRACT { * @example Create a new point with a custom SRID * const point = { * type: 'Point', - * coordinates: [39.807222,-76.984722], + * coordinates: [-76.984722, 39.807222], // GeoJson format: [lng, lat] * crs: { type: 'name', properties: { name: 'EPSG:4326'} } * }; * @@ -1056,6 +1056,7 @@ dialectMap.mysql = require('./dialects/mysql/data-types')(DataTypes); dialectMap.mariadb = require('./dialects/mariadb/data-types')(DataTypes); dialectMap.sqlite = require('./dialects/sqlite/data-types')(DataTypes); dialectMap.mssql = require('./dialects/mssql/data-types')(DataTypes); +dialectMap.snowflake = require('./dialects/snowflake/data-types')(DataTypes); const dialectList = Object.values(dialectMap); diff --git a/lib/dialects/abstract/query-generator.js b/lib/dialects/abstract/query-generator.js index 5a438cd3268b..9e09271ddc97 100644 --- a/lib/dialects/abstract/query-generator.js +++ b/lib/dialects/abstract/query-generator.js @@ -180,14 +180,33 @@ class QueryGenerator { let onDuplicateKeyUpdate = ''; + // `options.updateOnDuplicate` is the list of field names to update if a duplicate key is hit during the insert. It + // contains just the field names. This option is _usually_ explicitly set by the corresponding query-interface + // upsert function. if (this._dialect.supports.inserts.updateOnDuplicate && options.updateOnDuplicate) { if (this._dialect.supports.inserts.updateOnDuplicate == ' ON CONFLICT DO UPDATE SET') { // postgres / sqlite // If no conflict target columns were specified, use the primary key names from options.upsertKeys const conflictKeys = options.upsertKeys.map(attr => this.quoteIdentifier(attr)); const updateKeys = options.updateOnDuplicate.map(attr => `${this.quoteIdentifier(attr)}=EXCLUDED.${this.quoteIdentifier(attr)}`); - onDuplicateKeyUpdate = ` ON CONFLICT (${conflictKeys.join(',')}) DO UPDATE SET ${updateKeys.join(',')}`; + onDuplicateKeyUpdate = ` ON CONFLICT (${conflictKeys.join(',')})`; + // if update keys are provided, then apply them here. if there are no updateKeys provided, then do not try to + // do an update. Instead, fall back to DO NOTHING. + onDuplicateKeyUpdate += _.isEmpty(updateKeys) ? ' DO NOTHING ' : ` DO UPDATE SET ${updateKeys.join(',')}`; } else { const valueKeys = options.updateOnDuplicate.map(attr => `${this.quoteIdentifier(attr)}=VALUES(${this.quoteIdentifier(attr)})`); + // the rough equivalent to ON CONFLICT DO NOTHING in mysql, etc is ON DUPLICATE KEY UPDATE id = id + // So, if no update values were provided, fall back to the identifier columns provided in the upsertKeys array. + // This will be the primary key in most cases, but it could be some other constraint. + if (_.isEmpty(valueKeys) && options.upsertKeys) { + valueKeys.push(...options.upsertKeys.map(attr => `${this.quoteIdentifier(attr)}=${this.quoteIdentifier(attr)}`)); + } + + // edge case... but if for some reason there were no valueKeys, and there were also no upsertKeys... then we + // can no longer build the requested query without a syntax error. Let's throw something more graceful here + // so the devs know what the problem is. + if (_.isEmpty(valueKeys)) { + throw new Error('No update values found for ON DUPLICATE KEY UPDATE clause, and no identifier fields could be found to use instead.'); + } onDuplicateKeyUpdate += `${this._dialect.supports.inserts.updateOnDuplicate} ${valueKeys.join(',')}`; } } @@ -286,6 +305,9 @@ class QueryGenerator { tuples.push(`(${values.join(',')})`); } + // `options.updateOnDuplicate` is the list of field names to update if a duplicate key is hit during the insert. It + // contains just the field names. This option is _usually_ explicitly set by the corresponding query-interface + // upsert function. if (this._dialect.supports.inserts.updateOnDuplicate && options.updateOnDuplicate) { if (this._dialect.supports.inserts.updateOnDuplicate == ' ON CONFLICT DO UPDATE SET') { // postgres / sqlite // If no conflict target columns were specified, use the primary key names from options.upsertKeys @@ -1395,7 +1417,7 @@ class QueryGenerator { if (typeof options.lock === 'object') { lock = options.lock.level; } - if (this._dialect.supports.lockKey && (lock === 'KEY SHARE' || lock === 'NO KEY UPDATE')) { + if (this._dialect.supports.lockKey && ['KEY SHARE', 'NO KEY UPDATE'].includes(lock)) { query += ` FOR ${lock}`; } else if (lock === 'SHARE') { query += ` ${this._dialect.supports.forShare}`; diff --git a/lib/dialects/abstract/query-generator/helpers/quote.js b/lib/dialects/abstract/query-generator/helpers/quote.js index 19a1d983b5e5..6b799efb703a 100644 --- a/lib/dialects/abstract/query-generator/helpers/quote.js +++ b/lib/dialects/abstract/query-generator/helpers/quote.js @@ -21,6 +21,14 @@ const Utils = require('../../../../utils'); */ const postgresReservedWords = 'all,analyse,analyze,and,any,array,as,asc,asymmetric,authorization,binary,both,case,cast,check,collate,collation,column,concurrently,constraint,create,cross,current_catalog,current_date,current_role,current_schema,current_time,current_timestamp,current_user,default,deferrable,desc,distinct,do,else,end,except,false,fetch,for,foreign,freeze,from,full,grant,group,having,ilike,in,initially,inner,intersect,into,is,isnull,join,lateral,leading,left,like,limit,localtime,localtimestamp,natural,not,notnull,null,offset,on,only,or,order,outer,overlaps,placing,primary,references,returning,right,select,session_user,similar,some,symmetric,table,tablesample,then,to,trailing,true,union,unique,user,using,variadic,verbose,when,where,window,with'.split(','); +/** + * list of reserved words in Snowflake + * source: https://docs.snowflake.com/en/sql-reference/reserved-keywords.html + * + * @private + */ +const snowflakeReservedWords = 'account,all,alter,and,any,as,between,by,case,cast,check,column,connect,connections,constraint,create,cross,current,current_date,current_time,current_timestamp,current_user,database,delete,distinct,drop,else,exists,false,following,for,from,full,grant,group,gscluster,having,ilike,in,increment,inner,insert,intersect,into,is,issue,join,lateral,left,like,localtime,localtimestamp,minus,natural,not,null,of,on,or,order,organization,qualify,regexp,revoke,right,rlike,row,rows,sample,schema,select,set,some,start,table,tablesample,then,to,trigger,true,try_cast,union,unique,update,using,values,view,when,whenever,where,with'.split(','); + /** * * @param {string} dialect Dialect name @@ -45,7 +53,7 @@ function quoteIdentifier(dialect, identifier, options) { case 'mariadb': case 'mysql': return Utils.addTicks(Utils.removeTicks(identifier, '`'), '`'); - + case 'snowflake': case 'postgres': const rawIdentifier = Utils.removeTicks(identifier, '"'); @@ -54,9 +62,9 @@ function quoteIdentifier(dialect, identifier, options) { options.quoteIdentifiers === false && !identifier.includes('.') && !identifier.includes('->') && - !postgresReservedWords.includes(rawIdentifier.toLowerCase()) + (dialect === 'postgres' && !postgresReservedWords.includes(rawIdentifier.toLowerCase()) || dialect === 'snowflake' && !snowflakeReservedWords.includes(rawIdentifier.toLowerCase())) ) { - // In Postgres, if tables or attributes are created double-quoted, + // In Postgres and Snowflake, if tables or attributes are created double-quoted, // they are also case sensitive. If they contain any uppercase // characters, they must always be double-quoted. This makes it // impossible to write queries in portable SQL if tables are created in diff --git a/lib/dialects/mariadb/data-types.js b/lib/dialects/mariadb/data-types.js index aa4098535631..c163f206701f 100644 --- a/lib/dialects/mariadb/data-types.js +++ b/lib/dialects/mariadb/data-types.js @@ -54,8 +54,12 @@ module.exports = BaseTypes => { return this._length ? `DATETIME(${this._length})` : 'DATETIME'; } _stringify(date, options) { - date = this._applyTimezone(date, options); - return date.format('YYYY-MM-DD HH:mm:ss.SSS'); + if (_.isDate(date)) { + date = this._applyTimezone(date, options); + return date.format('YYYY-MM-DD HH:mm:ss.SSS'); + } + + return date; } static parse(value, options) { value = value.string(); diff --git a/lib/dialects/mssql/query-generator.js b/lib/dialects/mssql/query-generator.js index 94e643ee0b23..3e44de52da72 100644 --- a/lib/dialects/mssql/query-generator.js +++ b/lib/dialects/mssql/query-generator.js @@ -449,7 +449,7 @@ class MSSQLQueryGenerator extends AbstractQueryGenerator { //IDENTITY_INSERT Condition identityAttrs.forEach(key => { - if (updateValues[key] && updateValues[key] !== null) { + if (insertValues[key] && insertValues[key] !== null) { needIdentityInsertWrapper = true; /* * IDENTITY_INSERT Column Cannot be updated, only inserted @@ -501,16 +501,18 @@ class MSSQLQueryGenerator extends AbstractQueryGenerator { } // Remove the IDENTITY_INSERT Column from update - const updateSnippet = updateKeys.filter(key => !identityAttrs.includes(key)) + const filteredUpdateClauses = updateKeys.filter(key => !identityAttrs.includes(key)) .map(key => { const value = this.escape(updateValues[key]); key = this.quoteIdentifier(key); return `${targetTableAlias}.${key} = ${value}`; - }).join(', '); + }); + const updateSnippet = filteredUpdateClauses.length > 0 ? `WHEN MATCHED THEN UPDATE SET ${filteredUpdateClauses.join(', ')}` : ''; const insertSnippet = `(${insertKeysQuoted}) VALUES(${insertValuesEscaped})`; + let query = `MERGE INTO ${tableNameQuoted} WITH(HOLDLOCK) AS ${targetTableAlias} USING (${sourceTableQuery}) AS ${sourceTableAlias}(${insertKeysQuoted}) ON ${joinCondition}`; - query += ` WHEN MATCHED THEN UPDATE SET ${updateSnippet} WHEN NOT MATCHED THEN INSERT ${insertSnippet} OUTPUT $action, INSERTED.*;`; + query += ` ${updateSnippet} WHEN NOT MATCHED THEN INSERT ${insertSnippet} OUTPUT $action, INSERTED.*;`; if (needIdentityInsertWrapper) { query = `SET IDENTITY_INSERT ${tableNameQuoted} ON; ${query} SET IDENTITY_INSERT ${tableNameQuoted} OFF;`; } diff --git a/lib/dialects/mssql/query.js b/lib/dialects/mssql/query.js index bbead007705a..f35c43d948e7 100644 --- a/lib/dialects/mssql/query.js +++ b/lib/dialects/mssql/query.js @@ -216,6 +216,11 @@ class Query extends AbstractQuery { return data; } if (this.isUpsertQuery()) { + // if this was an upsert and no data came back, that means the record exists, but the update was a noop. + // return the current instance and mark it as an "not an insert". + if (data && data.length === 0) { + return [this.instance || data, false]; + } this.handleInsertQuery(data); return [this.instance || data, data[0].$action === 'INSERT']; } diff --git a/lib/dialects/mysql/data-types.js b/lib/dialects/mysql/data-types.js index c0beec964da9..017b74c130dd 100644 --- a/lib/dialects/mysql/data-types.js +++ b/lib/dialects/mysql/data-types.js @@ -53,12 +53,16 @@ module.exports = BaseTypes => { return this._length ? `DATETIME(${this._length})` : 'DATETIME'; } _stringify(date, options) { - date = this._applyTimezone(date, options); - // Fractional DATETIMEs only supported on MySQL 5.6.4+ - if (this._length) { - return date.format('YYYY-MM-DD HH:mm:ss.SSS'); + if (_.isDate(date)) { + date = this._applyTimezone(date, options); + // Fractional DATETIMEs only supported on MySQL 5.6.4+ + if (this._length) { + return date.format('YYYY-MM-DD HH:mm:ss.SSS'); + } + return date.format('YYYY-MM-DD HH:mm:ss'); } - return date.format('YYYY-MM-DD HH:mm:ss'); + + return date; } static parse(value, options) { value = value.string(); diff --git a/lib/dialects/mysql/query-interface.js b/lib/dialects/mysql/query-interface.js index bcdec9d2e5a7..4c7a43108e70 100644 --- a/lib/dialects/mysql/query-interface.js +++ b/lib/dialects/mysql/query-interface.js @@ -46,6 +46,7 @@ class MySQLQueryInterface extends QueryInterface { options.type = QueryTypes.UPSERT; options.updateOnDuplicate = Object.keys(updateValues); + options.upsertKeys = Object.values(options.model.primaryKeys).map(item => item.field); const model = options.model; const sql = this.queryGenerator.insertQuery(tableName, insertValues, model.rawAttributes, options); diff --git a/lib/dialects/postgres/connection-manager.js b/lib/dialects/postgres/connection-manager.js index 841b9e65f9a3..2d12b11176fa 100644 --- a/lib/dialects/postgres/connection-manager.js +++ b/lib/dialects/postgres/connection-manager.js @@ -209,8 +209,18 @@ class ConnectionManager extends AbstractConnectionManager { query += 'SET standard_conforming_strings=on;'; } - if (this.sequelize.options.clientMinMessages !== false) { - query += `SET client_min_messages TO ${this.sequelize.options.clientMinMessages};`; + if (this.sequelize.options.clientMinMessages !== undefined) { + console.warn('Usage of "options.clientMinMessages" is deprecated and will be removed in v7.'); + console.warn('Please use the sequelize option "dialectOptions.clientMinMessages" instead.'); + } + + // Redshift dosen't support client_min_messages, use 'ignore' to skip this settings. + // If no option, the default value in sequelize is 'warning' + if ( !( config.dialectOptions && config.dialectOptions.clientMinMessages && config.dialectOptions.clientMinMessages.toLowerCase() === 'ignore' || + this.sequelize.options.clientMinMessages === false ) ) { + const clientMinMessages = config.dialectOptions && config.dialectOptions.clientMinMessages || this.sequelize.options.clientMinMessages || 'warning'; + query += `SET client_min_messages TO ${clientMinMessages};`; + } if (!this.sequelize.config.keepDefaultTimezone) { diff --git a/lib/dialects/postgres/data-types.js b/lib/dialects/postgres/data-types.js index fc9ab0f420a7..39c0a75d0fa4 100644 --- a/lib/dialects/postgres/data-types.js +++ b/lib/dialects/postgres/data-types.js @@ -142,7 +142,7 @@ module.exports = BaseTypes => { } if (typeof value === 'string') { // Only take action on valid boolean strings. - return value === 'true' || value === 't' ? true : value === 'false' || value === 'f' ? false : value; + return ['true', 't'].includes(value) ? true : ['false', 'f'].includes(value) ? false : value; } if (typeof value === 'number') { // Only take action on valid boolean integers. diff --git a/lib/dialects/postgres/query-generator.js b/lib/dialects/postgres/query-generator.js index f5d10c949298..9df262c6417b 100644 --- a/lib/dialects/postgres/query-generator.js +++ b/lib/dialects/postgres/query-generator.js @@ -534,7 +534,7 @@ class PostgresQueryGenerator extends AbstractQueryGenerator { } if (attribute.comment && typeof attribute.comment === 'string') { - if (options && (options.context === 'addColumn' || options.context === 'changeColumn')) { + if (options && ['addColumn', 'changeColumn'].includes(options.context)) { const quotedAttr = this.quoteIdentifier(options.key); const escapedCommentText = this.escape(attribute.comment); sql += `; COMMENT ON COLUMN ${this.quoteTable(options.table)}.${quotedAttr} IS ${escapedCommentText}`; diff --git a/lib/dialects/postgres/query.js b/lib/dialects/postgres/query.js index 3640bda38648..8d63110340b2 100644 --- a/lib/dialects/postgres/query.js +++ b/lib/dialects/postgres/query.js @@ -267,7 +267,7 @@ class Query extends AbstractQuery { if (this.instance && this.instance.dataValues) { // If we are creating an instance, and we get no rows, the create failed but did not throw. // This probably means a conflict happened and was ignored, to avoid breaking a transaction. - if (this.isInsertQuery() && rowCount === 0) { + if (this.isInsertQuery() && !this.isUpsertQuery() && rowCount === 0) { throw new sequelizeErrors.EmptyResultError(); } diff --git a/lib/dialects/snowflake/connection-manager.js b/lib/dialects/snowflake/connection-manager.js new file mode 100644 index 000000000000..1d0c97d0f29d --- /dev/null +++ b/lib/dialects/snowflake/connection-manager.js @@ -0,0 +1,151 @@ +'use strict'; + +const AbstractConnectionManager = require('../abstract/connection-manager'); +const SequelizeErrors = require('../../errors'); +const { logger } = require('../../utils/logger'); +const DataTypes = require('../../data-types').snowflake; +const debug = logger.debugContext('connection:snowflake'); +const parserStore = require('../parserStore')('snowflake'); + +/** + * Snowflake Connection Manager + * + * Get connections, validate and disconnect them. + * + * @private + */ +class ConnectionManager extends AbstractConnectionManager { + constructor(dialect, sequelize) { + sequelize.config.port = sequelize.config.port || 3306; + super(dialect, sequelize); + this.lib = this._loadDialectModule('snowflake-sdk'); + this.refreshTypeParser(DataTypes); + } + + _refreshTypeParser(dataType) { + parserStore.refresh(dataType); + } + + _clearTypeParser() { + parserStore.clear(); + } + + static _typecast(field, next) { + if (parserStore.get(field.type)) { + return parserStore.get(field.type)(field, this.sequelize.options, next); + } + return next(); + } + + /** + * Connect with a snowflake database based on config, Handle any errors in connection + * Set the pool handlers on connection.error + * Also set proper timezone once connection is connected. + * + * @param {object} config + * @returns {Promise} + * @private + */ + async connect(config) { + const connectionConfig = { + account: config.host, + username: config.username, + password: config.password, + database: config.database, + warehouse: config.warehouse, + role: config.role, + /* + flags: '-FOUND_ROWS', + timezone: this.sequelize.options.timezone, + typeCast: ConnectionManager._typecast.bind(this), + bigNumberStrings: false, + supportBigNumbers: true, + */ + ...config.dialectOptions + }; + + try { + + const connection = await new Promise((resolve, reject) => { + this.lib.createConnection(connectionConfig).connect((err, conn) => { + if (err) { + console.log(err); + reject(err); + } else { + resolve(conn); + } + }); + }); + + debug('connection acquired'); + + if (!this.sequelize.config.keepDefaultTimezone) { + // default value is '+00:00', put a quick workaround for it. + const tzOffset = this.sequelize.options.timezone === '+00:00' ? 'Etc/UTC' : this.sequelize.options.timezone; + const isNamedTzOffset = /\//.test(tzOffset); + if ( isNamedTzOffset ) { + await new Promise((resolve, reject) => { + connection.execute({ + sqlText: `ALTER SESSION SET timezone = '${tzOffset}'`, + complete(err) { + if (err) { + console.log(err); + reject(err); + } else { + resolve(); + } + } + }); + }); + } else { + throw Error('only support time zone name for snowflake!'); + } + } + + return connection; + } catch (err) { + switch (err.code) { + case 'ECONNREFUSED': + throw new SequelizeErrors.ConnectionRefusedError(err); + case 'ER_ACCESS_DENIED_ERROR': + throw new SequelizeErrors.AccessDeniedError(err); + case 'ENOTFOUND': + throw new SequelizeErrors.HostNotFoundError(err); + case 'EHOSTUNREACH': + throw new SequelizeErrors.HostNotReachableError(err); + case 'EINVAL': + throw new SequelizeErrors.InvalidConnectionError(err); + default: + throw new SequelizeErrors.ConnectionError(err); + } + } + } + + async disconnect(connection) { + // Don't disconnect connections with CLOSED state + if (connection._closing) { + debug('connection tried to disconnect but was already at CLOSED state'); + return; + } + + return new Promise((resolve, reject) => { + connection.destroy(err => { + if (err) { + console.error(`Unable to disconnect: ${err.message}`); + reject(err); + } else { + console.log(`Disconnected connection with id: ${connection.getId()}`); + resolve(connection.getId()); + } + }); + }); + } + + validate(connection) { + return connection.isUp(); + } +} + +module.exports = ConnectionManager; +module.exports.ConnectionManager = ConnectionManager; +module.exports.default = ConnectionManager; diff --git a/lib/dialects/snowflake/data-types.js b/lib/dialects/snowflake/data-types.js new file mode 100644 index 000000000000..8d424d0abde2 --- /dev/null +++ b/lib/dialects/snowflake/data-types.js @@ -0,0 +1,102 @@ +'use strict'; + +const moment = require('moment-timezone'); +module.exports = BaseTypes => { + BaseTypes.ABSTRACT.prototype.dialectTypes = 'https://dev.snowflake.com/doc/refman/5.7/en/data-types.html'; + + /** + * types: [buffer_type, ...] + * + * @see buffer_type here https://dev.snowflake.com/doc/refman/5.7/en/c-api-prepared-statement-type-codes.html + * @see hex here https://github.com/sidorares/node-mysql2/blob/master/lib/constants/types.js + */ + + BaseTypes.DATE.types.snowflake = ['DATETIME']; + BaseTypes.STRING.types.snowflake = ['VAR_STRING']; + BaseTypes.CHAR.types.snowflake = ['STRING']; + BaseTypes.TEXT.types.snowflake = ['BLOB']; + BaseTypes.TINYINT.types.snowflake = ['TINY']; + BaseTypes.SMALLINT.types.snowflake = ['SHORT']; + BaseTypes.MEDIUMINT.types.snowflake = ['INT24']; + BaseTypes.INTEGER.types.snowflake = ['LONG']; + BaseTypes.BIGINT.types.snowflake = ['LONGLONG']; + BaseTypes.FLOAT.types.snowflake = ['FLOAT']; + BaseTypes.TIME.types.snowflake = ['TIME']; + BaseTypes.DATEONLY.types.snowflake = ['DATE']; + BaseTypes.BOOLEAN.types.snowflake = ['TINY']; + BaseTypes.BLOB.types.snowflake = ['TINYBLOB', 'BLOB', 'LONGBLOB']; + BaseTypes.DECIMAL.types.snowflake = ['NEWDECIMAL']; + BaseTypes.UUID.types.snowflake = false; + // Enum is not supported + // https://docs.snowflake.com/en/sql-reference/data-types-unsupported.html + BaseTypes.ENUM.types.snowflake = false; + BaseTypes.REAL.types.snowflake = ['DOUBLE']; + BaseTypes.DOUBLE.types.snowflake = ['DOUBLE']; + BaseTypes.GEOMETRY.types.snowflake = ['GEOMETRY']; + BaseTypes.JSON.types.snowflake = ['JSON']; + + class DATE extends BaseTypes.DATE { + toSql() { + return 'TIMESTAMP'; + } + _stringify(date, options) { + date = this._applyTimezone(date, options); + if (this._length) { + return date.format('YYYY-MM-DD HH:mm:ss.SSS'); + } + return date.format('YYYY-MM-DD HH:mm:ss'); + } + static parse(value, options) { + value = value.string(); + if (value === null) { + return value; + } + if (moment.tz.zone(options.timezone)) { + value = moment.tz(value, options.timezone).toDate(); + } + else { + value = new Date(`${value} ${options.timezone}`); + } + return value; + } + } + + class DATEONLY extends BaseTypes.DATEONLY { + static parse(value) { + return value.string(); + } + } + class UUID extends BaseTypes.UUID { + toSql() { + // https://community.snowflake.com/s/question/0D50Z00009LH2fl/what-is-the-best-way-to-store-uuids + return 'VARCHAR(36)'; + } + } + + class TEXT extends BaseTypes.TEXT { + toSql() { + return 'TEXT'; + } + } + + class BOOLEAN extends BaseTypes.BOOLEAN { + toSql() { + return 'BOOLEAN'; + } + } + + class JSONTYPE extends BaseTypes.JSON { + _stringify(value, options) { + return options.operation === 'where' && typeof value === 'string' ? value : JSON.stringify(value); + } + } + + return { + TEXT, + DATE, + BOOLEAN, + DATEONLY, + UUID, + JSON: JSONTYPE + }; +}; diff --git a/lib/dialects/snowflake/index.js b/lib/dialects/snowflake/index.js new file mode 100644 index 000000000000..dcf28cce30bb --- /dev/null +++ b/lib/dialects/snowflake/index.js @@ -0,0 +1,66 @@ +'use strict'; + +const _ = require('lodash'); +const AbstractDialect = require('../abstract'); +const ConnectionManager = require('./connection-manager'); +const Query = require('./query'); +const QueryGenerator = require('./query-generator'); +const DataTypes = require('../../data-types').snowflake; +const { SnowflakeQueryInterface } = require('./query-interface'); + +class SnowflakeDialect extends AbstractDialect { + constructor(sequelize) { + super(); + this.sequelize = sequelize; + this.connectionManager = new ConnectionManager(this, sequelize); + this.queryGenerator = new QueryGenerator({ + _dialect: this, + sequelize + }); + this.queryInterface = new SnowflakeQueryInterface(sequelize, this.queryGenerator); + } +} + +SnowflakeDialect.prototype.supports = _.merge(_.cloneDeep(AbstractDialect.prototype.supports), { + 'VALUES ()': true, + 'LIMIT ON UPDATE': true, + lock: true, + forShare: 'LOCK IN SHARE MODE', + settingIsolationLevelDuringTransaction: false, + inserts: { + ignoreDuplicates: ' IGNORE', + // disable for now, but could be enable by approach below + // https://stackoverflow.com/questions/54828745/how-to-migrate-on-conflict-do-nothing-from-postgresql-to-snowflake + updateOnDuplicate: false + }, + index: { + collate: false, + length: true, + parser: true, + type: true, + using: 1 + }, + constraints: { + dropConstraint: false, + check: false + }, + indexViaAlter: true, + indexHints: true, + NUMERIC: true, + // disable for now, need more work to enable the GEOGRAPHY MAPPING + GEOMETRY: false, + JSON: false, + REGEXP: true, + schemas: true +}); + +SnowflakeDialect.prototype.defaultVersion = '5.7.0'; +SnowflakeDialect.prototype.Query = Query; +SnowflakeDialect.prototype.QueryGenerator = QueryGenerator; +SnowflakeDialect.prototype.DataTypes = DataTypes; +SnowflakeDialect.prototype.name = 'snowflake'; +SnowflakeDialect.prototype.TICK_CHAR = '"'; +SnowflakeDialect.prototype.TICK_CHAR_LEFT = SnowflakeDialect.prototype.TICK_CHAR; +SnowflakeDialect.prototype.TICK_CHAR_RIGHT = SnowflakeDialect.prototype.TICK_CHAR; + +module.exports = SnowflakeDialect; diff --git a/lib/dialects/snowflake/query-generator.js b/lib/dialects/snowflake/query-generator.js new file mode 100644 index 000000000000..7f1a953a5ae1 --- /dev/null +++ b/lib/dialects/snowflake/query-generator.js @@ -0,0 +1,651 @@ +'use strict'; + +const _ = require('lodash'); +const Utils = require('../../utils'); +const AbstractQueryGenerator = require('../abstract/query-generator'); +const util = require('util'); +const Op = require('../../operators'); + + +const JSON_FUNCTION_REGEX = /^\s*((?:[a-z]+_){0,2}jsonb?(?:_[a-z]+){0,2})\([^)]*\)/i; +const JSON_OPERATOR_REGEX = /^\s*(->>?|@>|<@|\?[|&]?|\|{2}|#-)/i; +const TOKEN_CAPTURE_REGEX = /^\s*((?:([`"'])(?:(?!\2).|\2{2})*\2)|[\w\d\s]+|[().,;+-])/i; +const FOREIGN_KEY_FIELDS = [ + 'CONSTRAINT_NAME as constraint_name', + 'CONSTRAINT_NAME as constraintName', + 'CONSTRAINT_SCHEMA as constraintSchema', + 'CONSTRAINT_SCHEMA as constraintCatalog', + 'TABLE_NAME as tableName', + 'TABLE_SCHEMA as tableSchema', + 'TABLE_SCHEMA as tableCatalog', + 'COLUMN_NAME as columnName', + 'REFERENCED_TABLE_SCHEMA as referencedTableSchema', + 'REFERENCED_TABLE_SCHEMA as referencedTableCatalog', + 'REFERENCED_TABLE_NAME as referencedTableName', + 'REFERENCED_COLUMN_NAME as referencedColumnName' +].join(','); + +const typeWithoutDefault = new Set(['BLOB', 'TEXT', 'GEOMETRY', 'JSON']); + +class SnowflakeQueryGenerator extends AbstractQueryGenerator { + constructor(options) { + super(options); + + this.OperatorMap = { + ...this.OperatorMap, + [Op.regexp]: 'REGEXP', + [Op.notRegexp]: 'NOT REGEXP' + }; + } + + createDatabaseQuery(databaseName, options) { + options = { + charset: null, + collate: null, + ...options + }; + + return Utils.joinSQLFragments([ + 'CREATE DATABASE IF NOT EXISTS', + this.quoteIdentifier(databaseName), + options.charset && `DEFAULT CHARACTER SET ${this.escape(options.charset)}`, + options.collate && `DEFAULT COLLATE ${this.escape(options.collate)}`, + ';' + ]); + } + + dropDatabaseQuery(databaseName) { + return `DROP DATABASE IF EXISTS ${this.quoteIdentifier(databaseName)};`; + } + + createSchema() { + return 'SHOW TABLES'; + } + + showSchemasQuery() { + return 'SHOW TABLES'; + } + + versionQuery() { + return 'SELECT CURRENT_VERSION()'; + } + + createTableQuery(tableName, attributes, options) { + options = { + charset: null, + rowFormat: null, + ...options + }; + + const primaryKeys = []; + const foreignKeys = {}; + const attrStr = []; + + for (const attr in attributes) { + if (!Object.prototype.hasOwnProperty.call(attributes, attr)) continue; + const dataType = attributes[attr]; + let match; + + if (dataType.includes('PRIMARY KEY')) { + primaryKeys.push(attr); + + if (dataType.includes('REFERENCES')) { + match = dataType.match(/^(.+) (REFERENCES.*)$/); + attrStr.push(`${this.quoteIdentifier(attr)} ${match[1].replace('PRIMARY KEY', '')}`); + foreignKeys[attr] = match[2]; + } else { + attrStr.push(`${this.quoteIdentifier(attr)} ${dataType.replace('PRIMARY KEY', '')}`); + } + } else if (dataType.includes('REFERENCES')) { + match = dataType.match(/^(.+) (REFERENCES.*)$/); + attrStr.push(`${this.quoteIdentifier(attr)} ${match[1]}`); + foreignKeys[attr] = match[2]; + } else { + attrStr.push(`${this.quoteIdentifier(attr)} ${dataType}`); + } + } + + const table = this.quoteTable(tableName); + let attributesClause = attrStr.join(', '); + const pkString = primaryKeys.map(pk => this.quoteIdentifier(pk)).join(', '); + + if (options.uniqueKeys) { + _.each(options.uniqueKeys, (columns, indexName) => { + if (columns.customIndex) { + if (typeof indexName !== 'string') { + indexName = `uniq_${tableName}_${columns.fields.join('_')}`; + } + attributesClause += `, UNIQUE ${this.quoteIdentifier(indexName)} (${columns.fields.map(field => this.quoteIdentifier(field)).join(', ')})`; + } + }); + } + + if (pkString.length > 0) { + attributesClause += `, PRIMARY KEY (${pkString})`; + } + + for (const fkey in foreignKeys) { + if (Object.prototype.hasOwnProperty.call(foreignKeys, fkey)) { + attributesClause += `, FOREIGN KEY (${this.quoteIdentifier(fkey)}) ${foreignKeys[fkey]}`; + } + } + + return Utils.joinSQLFragments([ + 'CREATE TABLE IF NOT EXISTS', + table, + `(${attributesClause})`, + options.comment && typeof options.comment === 'string' && `COMMENT ${this.escape(options.comment)}`, + options.charset && `DEFAULT CHARSET=${options.charset}`, + options.collate && `COLLATE ${options.collate}`, + options.rowFormat && `ROW_FORMAT=${options.rowFormat}`, + ';' + ]); + } + + describeTableQuery(tableName, schema, schemaDelimiter) { + const table = this.quoteTable( + this.addSchema({ + tableName, + _schema: schema, + _schemaDelimiter: schemaDelimiter + }) + ); + + return `SHOW FULL COLUMNS FROM ${table};`; + } + + showTablesQuery(database) { + return Utils.joinSQLFragments([ + 'SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = \'BASE TABLE\'', + database ? `AND TABLE_SCHEMA = ${this.escape(database)}` : 'AND TABLE_SCHEMA NOT IN ( \'INFORMATION_SCHEMA\', \'PERFORMANCE_SCHEMA\', \'SYS\')', + ';' + ]); + } + + addColumnQuery(table, key, dataType) { + return Utils.joinSQLFragments([ + 'ALTER TABLE', + this.quoteTable(table), + 'ADD', + this.quoteIdentifier(key), + this.attributeToSQL(dataType, { + context: 'addColumn', + tableName: table, + foreignKey: key + }), + ';' + ]); + } + + removeColumnQuery(tableName, attributeName) { + return Utils.joinSQLFragments([ + 'ALTER TABLE', + this.quoteTable(tableName), + 'DROP', + this.quoteIdentifier(attributeName), + ';' + ]); + } + + changeColumnQuery(tableName, attributes) { + const query = (...subQuerys) => Utils.joinSQLFragments([ + 'ALTER TABLE', + this.quoteTable(tableName), + 'ALTER COLUMN', + ...subQuerys, + ';' + ]); + const sql = []; + for (const attributeName in attributes) { + let definition = this.dataTypeMapping(tableName, attributeName, attributes[attributeName]); + const attrSql = []; + + if (definition.includes('NOT NULL')) { + attrSql.push(query(this.quoteIdentifier(attributeName), 'SET NOT NULL')); + + definition = definition.replace('NOT NULL', '').trim(); + } else if (!definition.includes('REFERENCES')) { + attrSql.push(query(this.quoteIdentifier(attributeName), 'DROP NOT NULL')); + } + + if (definition.includes('DEFAULT')) { + attrSql.push(query(this.quoteIdentifier(attributeName), 'SET DEFAULT', definition.match(/DEFAULT ([^;]+)/)[1])); + + definition = definition.replace(/(DEFAULT[^;]+)/, '').trim(); + } else if (!definition.includes('REFERENCES')) { + attrSql.push(query(this.quoteIdentifier(attributeName), 'DROP DEFAULT')); + } + + if (definition.match(/UNIQUE;*$/)) { + definition = definition.replace(/UNIQUE;*$/, ''); + attrSql.push(query('ADD UNIQUE (', this.quoteIdentifier(attributeName), ')').replace('ALTER COLUMN', '')); + } + + if (definition.includes('REFERENCES')) { + definition = definition.replace(/.+?(?=REFERENCES)/, ''); + attrSql.push(query('ADD FOREIGN KEY (', this.quoteIdentifier(attributeName), ')', definition).replace('ALTER COLUMN', '')); + } else { + attrSql.push(query(this.quoteIdentifier(attributeName), 'TYPE', definition)); + } + + sql.push(attrSql.join('')); + } + + return sql.join(''); + } + + renameColumnQuery(tableName, attrBefore, attributes) { + const attrString = []; + + for (const attrName in attributes) { + const definition = attributes[attrName]; + attrString.push(`'${attrBefore}' '${attrName}' ${definition}`); + } + + return Utils.joinSQLFragments([ + 'ALTER TABLE', + this.quoteTable(tableName), + 'RENAME COLUMN', + attrString.join(' to '), + ';' + ]); + } + + handleSequelizeMethod(attr, tableName, factory, options, prepend) { + if (attr instanceof Utils.Json) { + // Parse nested object + if (attr.conditions) { + const conditions = this.parseConditionObject(attr.conditions).map(condition => + `${this.jsonPathExtractionQuery(condition.path[0], _.tail(condition.path))} = '${condition.value}'` + ); + + return conditions.join(' AND '); + } + if (attr.path) { + let str; + + // Allow specifying conditions using the sqlite json functions + if (this._checkValidJsonStatement(attr.path)) { + str = attr.path; + } else { + // Also support json property accessors + const paths = _.toPath(attr.path); + const column = paths.shift(); + str = this.jsonPathExtractionQuery(column, paths); + } + + if (attr.value) { + str += util.format(' = %s', this.escape(attr.value)); + } + + return str; + } + } else if (attr instanceof Utils.Cast) { + if (/timestamp/i.test(attr.type)) { + attr.type = 'datetime'; + } else if (attr.json && /boolean/i.test(attr.type)) { + // true or false cannot be casted as booleans within a JSON structure + attr.type = 'char'; + } else if (/double precision/i.test(attr.type) || /boolean/i.test(attr.type) || /integer/i.test(attr.type)) { + attr.type = 'decimal'; + } else if (/text/i.test(attr.type)) { + attr.type = 'char'; + } + } + + return super.handleSequelizeMethod(attr, tableName, factory, options, prepend); + } + + truncateTableQuery(tableName) { + return Utils.joinSQLFragments([ + 'TRUNCATE', + this.quoteTable(tableName) + ]); + } + + deleteQuery(tableName, where, options = {}, model) { + const table = this.quoteTable(tableName); + let whereClause = this.getWhereConditions(where, null, model, options); + const limit = options.limit && ` LIMIT ${this.escape(options.limit)}`; + let primaryKeys = ''; + let primaryKeysSelection = ''; + + if (whereClause) { + whereClause = `WHERE ${whereClause}`; + } + + if (limit) { + if (!model) { + throw new Error('Cannot LIMIT delete without a model.'); + } + + const pks = Object.values(model.primaryKeys).map(pk => this.quoteIdentifier(pk.field)).join(','); + + primaryKeys = model.primaryKeyAttributes.length > 1 ? `(${pks})` : pks; + primaryKeysSelection = pks; + + return Utils.joinSQLFragments([ + 'DELETE FROM', + table, + 'WHERE', + primaryKeys, + 'IN (SELECT', + primaryKeysSelection, + 'FROM', + table, + whereClause, + limit, + ')', + ';' + ]); + } + return Utils.joinSQLFragments([ + 'DELETE FROM', + table, + whereClause, + ';' + ]); + } + + showIndexesQuery() { + return 'SELECT \'\' FROM DUAL'; + } + + showConstraintsQuery(table, constraintName) { + const tableName = table.tableName || table; + const schemaName = table.schema; + + return Utils.joinSQLFragments([ + 'SELECT CONSTRAINT_CATALOG AS constraintCatalog,', + 'CONSTRAINT_NAME AS constraintName,', + 'CONSTRAINT_SCHEMA AS constraintSchema,', + 'CONSTRAINT_TYPE AS constraintType,', + 'TABLE_NAME AS tableName,', + 'TABLE_SCHEMA AS tableSchema', + 'from INFORMATION_SCHEMA.TABLE_CONSTRAINTS', + `WHERE table_name='${tableName}'`, + constraintName && `AND constraint_name = '${constraintName}'`, + schemaName && `AND TABLE_SCHEMA = '${schemaName}'`, + ';' + ]); + } + + removeIndexQuery(tableName, indexNameOrAttributes) { + let indexName = indexNameOrAttributes; + + if (typeof indexName !== 'string') { + indexName = Utils.underscore(`${tableName}_${indexNameOrAttributes.join('_')}`); + } + + return Utils.joinSQLFragments([ + 'DROP INDEX', + this.quoteIdentifier(indexName), + 'ON', + this.quoteTable(tableName), + ';' + ]); + } + + attributeToSQL(attribute, options) { + if (!_.isPlainObject(attribute)) { + attribute = { + type: attribute + }; + } + + const attributeString = attribute.type.toString({ escape: this.escape.bind(this) }); + let template = attributeString; + + if (attribute.allowNull === false) { + template += ' NOT NULL'; + } + + if (attribute.autoIncrement) { + template += ' AUTOINCREMENT'; + } + + // BLOB/TEXT/GEOMETRY/JSON cannot have a default value + if (!typeWithoutDefault.has(attributeString) + && attribute.type._binary !== true + && Utils.defaultValueSchemable(attribute.defaultValue)) { + template += ` DEFAULT ${this.escape(attribute.defaultValue)}`; + } + + if (attribute.unique === true) { + template += ' UNIQUE'; + } + + if (attribute.primaryKey) { + template += ' PRIMARY KEY'; + } + + if (attribute.comment) { + template += ` COMMENT ${this.escape(attribute.comment)}`; + } + + if (attribute.first) { + template += ' FIRST'; + } + if (attribute.after) { + template += ` AFTER ${this.quoteIdentifier(attribute.after)}`; + } + + if (attribute.references) { + if (options && options.context === 'addColumn' && options.foreignKey) { + const attrName = this.quoteIdentifier(options.foreignKey); + const fkName = this.quoteIdentifier(`${options.tableName}_${attrName}_foreign_idx`); + + template += `, ADD CONSTRAINT ${fkName} FOREIGN KEY (${attrName})`; + } + + template += ` REFERENCES ${this.quoteTable(attribute.references.model)}`; + + if (attribute.references.key) { + template += ` (${this.quoteIdentifier(attribute.references.key)})`; + } else { + template += ` (${this.quoteIdentifier('id')})`; + } + + if (attribute.onDelete) { + template += ` ON DELETE ${attribute.onDelete.toUpperCase()}`; + } + + if (attribute.onUpdate) { + template += ` ON UPDATE ${attribute.onUpdate.toUpperCase()}`; + } + } + + return template; + } + + attributesToSQL(attributes, options) { + const result = {}; + + for (const key in attributes) { + const attribute = attributes[key]; + result[attribute.field || key] = this.attributeToSQL(attribute, options); + } + + return result; + } + + /** + * Check whether the statmement is json function or simple path + * + * @param {string} stmt The statement to validate + * @returns {boolean} true if the given statement is json function + * @throws {Error} throw if the statement looks like json function but has invalid token + * @private + */ + _checkValidJsonStatement(stmt) { + if (typeof stmt !== 'string') { + return false; + } + + let currentIndex = 0; + let openingBrackets = 0; + let closingBrackets = 0; + let hasJsonFunction = false; + let hasInvalidToken = false; + + while (currentIndex < stmt.length) { + const string = stmt.substr(currentIndex); + const functionMatches = JSON_FUNCTION_REGEX.exec(string); + if (functionMatches) { + currentIndex += functionMatches[0].indexOf('('); + hasJsonFunction = true; + continue; + } + + const operatorMatches = JSON_OPERATOR_REGEX.exec(string); + if (operatorMatches) { + currentIndex += operatorMatches[0].length; + hasJsonFunction = true; + continue; + } + + const tokenMatches = TOKEN_CAPTURE_REGEX.exec(string); + if (tokenMatches) { + const capturedToken = tokenMatches[1]; + if (capturedToken === '(') { + openingBrackets++; + } else if (capturedToken === ')') { + closingBrackets++; + } else if (capturedToken === ';') { + hasInvalidToken = true; + break; + } + currentIndex += tokenMatches[0].length; + continue; + } + + break; + } + + // Check invalid json statement + if (hasJsonFunction && (hasInvalidToken || openingBrackets !== closingBrackets)) { + throw new Error(`Invalid json statement: ${stmt}`); + } + + // return true if the statement has valid json function + return hasJsonFunction; + } + + dataTypeMapping(tableName, attr, dataType) { + if (dataType.includes('PRIMARY KEY')) { + dataType = dataType.replace('PRIMARY KEY', ''); + } + + if (dataType.includes('SERIAL')) { + if (dataType.includes('BIGINT')) { + dataType = dataType.replace('SERIAL', 'BIGSERIAL'); + dataType = dataType.replace('BIGINT', ''); + } else if (dataType.includes('SMALLINT')) { + dataType = dataType.replace('SERIAL', 'SMALLSERIAL'); + dataType = dataType.replace('SMALLINT', ''); + } else { + dataType = dataType.replace('INTEGER', ''); + } + dataType = dataType.replace('NOT NULL', ''); + } + + return dataType; + } + + /** + * Generates an SQL query that returns all foreign keys of a table. + * + * @param {object} table The table. + * @param {string} schemaName The name of the schema. + * @returns {string} The generated sql query. + * @private + */ + getForeignKeysQuery(table, schemaName) { + const tableName = table.tableName || table; + return Utils.joinSQLFragments([ + 'SELECT', + FOREIGN_KEY_FIELDS, + `FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = '${tableName}'`, + `AND CONSTRAINT_NAME!='PRIMARY' AND CONSTRAINT_SCHEMA='${schemaName}'`, + 'AND REFERENCED_TABLE_NAME IS NOT NULL', + ';' + ]); + } + + /** + * Generates an SQL query that returns the foreign key constraint of a given column. + * + * @param {object} table The table. + * @param {string} columnName The name of the column. + * @returns {string} The generated sql query. + * @private + */ + getForeignKeyQuery(table, columnName) { + const quotedSchemaName = table.schema ? wrapSingleQuote(table.schema) : ''; + const quotedTableName = wrapSingleQuote(table.tableName || table); + const quotedColumnName = wrapSingleQuote(columnName); + + return Utils.joinSQLFragments([ + 'SELECT', + FOREIGN_KEY_FIELDS, + 'FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE', + 'WHERE (', + [ + `REFERENCED_TABLE_NAME = ${quotedTableName}`, + table.schema && `AND REFERENCED_TABLE_SCHEMA = ${quotedSchemaName}`, + `AND REFERENCED_COLUMN_NAME = ${quotedColumnName}` + ], + ') OR (', + [ + `TABLE_NAME = ${quotedTableName}`, + table.schema && `AND TABLE_SCHEMA = ${quotedSchemaName}`, + `AND COLUMN_NAME = ${quotedColumnName}`, + 'AND REFERENCED_TABLE_NAME IS NOT NULL' + ], + ')' + ]); + } + + /** + * Generates an SQL query that removes a foreign key from a table. + * + * @param {string} tableName The name of the table. + * @param {string} foreignKey The name of the foreign key constraint. + * @returns {string} The generated sql query. + * @private + */ + dropForeignKeyQuery(tableName, foreignKey) { + return Utils.joinSQLFragments([ + 'ALTER TABLE', + this.quoteTable(tableName), + 'DROP FOREIGN KEY', + this.quoteIdentifier(foreignKey), + ';' + ]); + } + + addLimitAndOffset(options) { + let fragment = ''; + + /* eslint-disable */ + if (options.offset != null && options.limit == null) { + fragment += ' LIMIT ' + this.escape(options.limit) + ' OFFSET ' + 10000000000000; + } else if (options.limit != null) { + if (options.offset != null) { + fragment += ' LIMIT ' + this.escape(options.limit) + ' OFFSET ' + this.escape(options.offset); + } else { + fragment += ' LIMIT ' + this.escape(options.limit); + } + } + /* eslint-enable */ + + return fragment; + } +} + +// private methods +function wrapSingleQuote(identifier) { + return Utils.addTicks(identifier, '\''); +} + +module.exports = SnowflakeQueryGenerator; diff --git a/lib/dialects/snowflake/query-interface.js b/lib/dialects/snowflake/query-interface.js new file mode 100644 index 000000000000..43b7d2f14a07 --- /dev/null +++ b/lib/dialects/snowflake/query-interface.js @@ -0,0 +1,85 @@ +'use strict'; + +const sequelizeErrors = require('../../errors'); +const { QueryInterface } = require('../abstract/query-interface'); +const QueryTypes = require('../../query-types'); + +/** + * The interface that Sequelize uses to talk with Snowflake database + */ +class SnowflakeQueryInterface extends QueryInterface { + /** + * A wrapper that fixes Snowflake's inability to cleanly remove columns from existing tables if they have a foreign key constraint. + * + * @override + */ + async removeColumn(tableName, columnName, options) { + options = options || {}; + + const [results] = await this.sequelize.query( + this.queryGenerator.getForeignKeyQuery(tableName.tableName ? tableName : { + tableName, + schema: this.sequelize.config.database + }, columnName), + { raw: true, ...options } + ); + + //Exclude primary key constraint + if (results.length && results[0].constraint_name !== 'PRIMARY') { + await Promise.all(results.map(constraint => this.sequelize.query( + this.queryGenerator.dropForeignKeyQuery(tableName, constraint.constraint_name), + { raw: true, ...options } + ))); + } + + return await this.sequelize.query( + this.queryGenerator.removeColumnQuery(tableName, columnName), + { raw: true, ...options } + ); + } + + /** @override */ + async upsert(tableName, insertValues, updateValues, where, options) { + options = { ...options }; + + options.type = QueryTypes.UPSERT; + options.updateOnDuplicate = Object.keys(updateValues); + + const model = options.model; + const sql = this.queryGenerator.insertQuery(tableName, insertValues, model.rawAttributes, options); + return await this.sequelize.query(sql, options); + } + + /** @override */ + async removeConstraint(tableName, constraintName, options) { + const sql = this.queryGenerator.showConstraintsQuery( + tableName.tableName ? tableName : { + tableName, + schema: this.sequelize.config.database + }, constraintName); + + const constraints = await this.sequelize.query(sql, { ...options, + type: this.sequelize.QueryTypes.SHOWCONSTRAINTS }); + + const constraint = constraints[0]; + let query; + if (!constraint || !constraint.constraintType) { + throw new sequelizeErrors.UnknownConstraintError( + { + message: `Constraint ${constraintName} on table ${tableName} does not exist`, + constraint: constraintName, + table: tableName + }); + } + + if (constraint.constraintType === 'FOREIGN KEY') { + query = this.queryGenerator.dropForeignKeyQuery(tableName, constraintName); + } else { + query = this.queryGenerator.removeIndexQuery(constraint.tableName, constraint.constraintName); + } + + return await this.sequelize.query(query, options); + } +} + +exports.SnowflakeQueryInterface = SnowflakeQueryInterface; diff --git a/lib/dialects/snowflake/query.js b/lib/dialects/snowflake/query.js new file mode 100644 index 000000000000..6a9b241d00b8 --- /dev/null +++ b/lib/dialects/snowflake/query.js @@ -0,0 +1,312 @@ +'use strict'; + +const AbstractQuery = require('../abstract/query'); +const sequelizeErrors = require('../../errors'); +const _ = require('lodash'); +const { logger } = require('../../utils/logger'); + +const ER_DUP_ENTRY = 1062; +const ER_DEADLOCK = 1213; +const ER_ROW_IS_REFERENCED = 1451; +const ER_NO_REFERENCED_ROW = 1452; + +const debug = logger.debugContext('sql:snowflake'); + +class Query extends AbstractQuery { + static formatBindParameters(sql, values, dialect) { + const bindParam = []; + const replacementFunc = (_match, key, values_) => { + if (values_[key] !== undefined) { + bindParam.push(values_[key]); + return '?'; + } + return undefined; + }; + sql = AbstractQuery.formatBindParameters(sql, values, dialect, replacementFunc)[0]; + return [sql, bindParam.length > 0 ? bindParam : undefined]; + } + + async run(sql, parameters) { + this.sql = sql; + const { connection, options } = this; + + const showWarnings = this.sequelize.options.showWarnings || options.showWarnings; + + const complete = this._logQuery(sql, debug, parameters); + + if (parameters) { + debug('parameters(%j)', parameters); + } + + let results; + + try { + results = await new Promise((resolve, reject) => { + connection.execute({ + sqlText: sql, + binds: parameters, + complete(err, _stmt, rows) { + if (err) { + reject(err); + } else { + resolve(rows); + } + } + }); + }); + } catch (error) { + if (options.transaction && error.errno === ER_DEADLOCK) { + try { + await options.transaction.rollback(); + } catch (error_) { + // ignore errors + } + + options.transaction.finished = 'rollback'; + } + + error.sql = sql; + error.parameters = parameters; + throw this.formatError(error); + } finally { + complete(); + } + + if (showWarnings && results && results.warningStatus > 0) { + await this.logWarnings(results); + } + return this.formatResults(results); + } + + /** + * High level function that handles the results of a query execution. + * + * + * Example: + * query.formatResults([ + * { + * id: 1, // this is from the main table + * attr2: 'snafu', // this is from the main table + * Tasks.id: 1, // this is from the associated table + * Tasks.title: 'task' // this is from the associated table + * } + * ]) + * + * @param {Array} data - The result of the query execution. + * @private + */ + formatResults(data) { + let result = this.instance; + + if (this.isInsertQuery(data)) { + this.handleInsertQuery(data); + + if (!this.instance) { + // handle bulkCreate AI primary key + if ( + data.constructor.name === 'ResultSetHeader' + && this.model + && this.model.autoIncrementAttribute + && this.model.autoIncrementAttribute === this.model.primaryKeyAttribute + && this.model.rawAttributes[this.model.primaryKeyAttribute] + ) { + const startId = data[this.getInsertIdField()]; + result = []; + for (let i = startId; i < startId + data.affectedRows; i++) { + result.push({ [this.model.rawAttributes[this.model.primaryKeyAttribute].field]: i }); + } + } else { + result = data[this.getInsertIdField()]; + } + } + } + + if (this.isSelectQuery()) { + // Snowflake will treat tables as case-insensitive, so fix the case + // of the returned values to match attributes + if (this.options.raw === false && this.sequelize.options.quoteIdentifiers === false) { + const sfAttrMap = _.reduce(this.model.rawAttributes, (m, v, k) => { + m[k.toUpperCase()] = k; + return m; + }, {}); + + data = data.map(data => _.reduce(data, (prev, value, key) => { + if ( value !== undefined && sfAttrMap[key] ) { + prev[sfAttrMap[key]] = value; + delete prev[key]; + } + return prev; + }, data)); + } + + this.options.fieldMap = _.mapKeys(this.options.fieldMap, (v, k) => { return k.toUpperCase(); }); + + return this.handleSelectQuery(data); + } + + if (this.isShowTablesQuery()) { + return this.handleShowTablesQuery(data); + } + + if (this.isDescribeQuery()) { + result = {}; + + for (const _result of data) { + result[_result.Field] = { + type: _result.Type.toUpperCase(), + allowNull: _result.Null === 'YES', + defaultValue: _result.Default, + primaryKey: _result.Key === 'PRI', + autoIncrement: Object.prototype.hasOwnProperty.call(_result, 'Extra') + && _result.Extra.toLowerCase() === 'auto_increment', + comment: _result.Comment ? _result.Comment : null + }; + } + return result; + } + if (this.isShowIndexesQuery()) { + return this.handleShowIndexesQuery(data); + } + if (this.isCallQuery()) { + return data[0]; + } + if (this.isBulkUpdateQuery() || this.isBulkDeleteQuery()) { + return data[0]['number of rows updated']; + } + if (this.isVersionQuery()) { + return data[0].version; + } + if (this.isForeignKeysQuery()) { + return data; + } + if (this.isUpsertQuery()) { + return [result, data.affectedRows === 1]; + } + if (this.isInsertQuery() || this.isUpdateQuery()) { + return [result, data.affectedRows]; + } + if (this.isShowConstraintsQuery()) { + return data; + } + if (this.isRawQuery()) { + return [data, data]; + } + + return result; + } + + async logWarnings(results) { + const warningResults = await this.run('SHOW WARNINGS'); + const warningMessage = `Snowflake Warnings (${this.connection.uuid || 'default'}): `; + const messages = []; + for (const _warningRow of warningResults) { + if (_warningRow === undefined || typeof _warningRow[Symbol.iterator] !== 'function') { + continue; + } + for (const _warningResult of _warningRow) { + if (Object.prototype.hasOwnProperty.call(_warningResult, 'Message')) { + messages.push(_warningResult.Message); + } else { + for (const _objectKey of _warningResult.keys()) { + messages.push([_objectKey, _warningResult[_objectKey]].join(': ')); + } + } + } + } + + this.sequelize.log(warningMessage + messages.join('; '), this.options); + + return results; + } + + formatError(err) { + const errCode = err.errno || err.code; + + switch (errCode) { + case ER_DUP_ENTRY: { + const match = err.message.match(/Duplicate entry '([\s\S]*)' for key '?((.|\s)*?)'?$/); + let fields = {}; + let message = 'Validation error'; + const values = match ? match[1].split('-') : undefined; + const fieldKey = match ? match[2] : undefined; + const fieldVal = match ? match[1] : undefined; + const uniqueKey = this.model && this.model.uniqueKeys[fieldKey]; + + if (uniqueKey) { + if (uniqueKey.msg) message = uniqueKey.msg; + fields = _.zipObject(uniqueKey.fields, values); + } else { + fields[fieldKey] = fieldVal; + } + + const errors = []; + _.forOwn(fields, (value, field) => { + errors.push(new sequelizeErrors.ValidationErrorItem( + this.getUniqueConstraintErrorMessage(field), + 'unique violation', // sequelizeErrors.ValidationErrorItem.Origins.DB, + field, + value, + this.instance, + 'not_unique' + )); + }); + + return new sequelizeErrors.UniqueConstraintError({ message, errors, parent: err, fields }); + } + + case ER_ROW_IS_REFERENCED: + case ER_NO_REFERENCED_ROW: { + // e.g. CONSTRAINT `example_constraint_name` FOREIGN KEY (`example_id`) REFERENCES `examples` (`id`) + const match = err.message.match( + /CONSTRAINT ([`"])(.*)\1 FOREIGN KEY \(\1(.*)\1\) REFERENCES \1(.*)\1 \(\1(.*)\1\)/ + ); + const quoteChar = match ? match[1] : '`'; + const fields = match ? match[3].split(new RegExp(`${quoteChar}, *${quoteChar}`)) : undefined; + + return new sequelizeErrors.ForeignKeyConstraintError({ + reltype: String(errCode) === String(ER_ROW_IS_REFERENCED) ? 'parent' : 'child', + table: match ? match[4] : undefined, + fields, + value: fields && fields.length && this.instance && this.instance[fields[0]] || undefined, + index: match ? match[2] : undefined, + parent: err + }); + } + + default: + return new sequelizeErrors.DatabaseError(err); + } + } + + handleShowIndexesQuery(data) { + // Group by index name, and collect all fields + data = data.reduce((acc, item) => { + if (!(item.Key_name in acc)) { + acc[item.Key_name] = item; + item.fields = []; + } + + acc[item.Key_name].fields[item.Seq_in_index - 1] = { + attribute: item.Column_name, + length: item.Sub_part || undefined, + order: item.Collation === 'A' ? 'ASC' : undefined + }; + delete item.column_name; + + return acc; + }, {}); + + return _.map(data, item => ({ + primary: item.Key_name === 'PRIMARY', + fields: item.fields, + name: item.Key_name, + tableName: item.Table, + unique: item.Non_unique !== 1, + type: item.Index_type + })); + } +} + +module.exports = Query; +module.exports.Query = Query; +module.exports.default = Query; diff --git a/lib/dialects/sqlite/query.js b/lib/dialects/sqlite/query.js index 499cf21694f3..a97bb31b8cda 100644 --- a/lib/dialects/sqlite/query.js +++ b/lib/dialects/sqlite/query.js @@ -313,7 +313,7 @@ class Query extends AbstractQuery { constraintSql = constraintSql.replace(/\(.+\)/, ''); const constraint = constraintSql.split(' '); - if (constraint[1] === 'PRIMARY' || constraint[1] === 'FOREIGN') { + if (['PRIMARY', 'FOREIGN'].includes(constraint[1])) { constraint[1] += ' KEY'; } diff --git a/lib/instance-validator.js b/lib/instance-validator.js index 1e4f343a4160..4bec84edfc5f 100644 --- a/lib/instance-validator.js +++ b/lib/instance-validator.js @@ -197,7 +197,7 @@ class InstanceValidator { const validators = []; _.forIn(this.modelInstance.validators[field], (test, validatorType) => { - if (validatorType === 'isUrl' || validatorType === 'isURL' || validatorType === 'isEmail') { + if (['isUrl', 'isURL', 'isEmail'].includes(validatorType)) { // Preserve backwards compat. Validator.js now expects the second param to isURL and isEmail to be an object if (typeof test === 'object' && test !== null && test.msg) { test = { @@ -318,7 +318,7 @@ class InstanceValidator { */ _extractValidatorArgs(test, validatorType, field) { let validatorArgs = test.args || test; - const isLocalizedValidator = typeof validatorArgs !== 'string' && (validatorType === 'isAlpha' || validatorType === 'isAlphanumeric' || validatorType === 'isMobilePhone'); + const isLocalizedValidator = typeof validatorArgs !== 'string' && ['isAlpha', 'isAlphanumeric', 'isMobilePhone'].includes(validatorType); if (!Array.isArray(validatorArgs)) { if (validatorType === 'isImmutable') { diff --git a/lib/model.js b/lib/model.js index 9960422d2383..4e2dc95d4472 100644 --- a/lib/model.js +++ b/lib/model.js @@ -791,7 +791,7 @@ class Model { if (Array.isArray(objValue) && Array.isArray(srcValue)) { return _.union(objValue, srcValue); } - if (key === 'where' || key === 'having') { + if (['where', 'having'].includes(key)) { if (srcValue instanceof Utils.SequelizeMethod) { srcValue = { [Op.and]: srcValue }; } @@ -1672,7 +1672,7 @@ class Model { * @param {object} [options.having] Having options * @param {string} [options.searchPath=DEFAULT] An optional parameter to specify the schema search_path (Postgres only) * @param {boolean|Error} [options.rejectOnEmpty=false] Throws an error when no records found - * @param {boolean} [options.dotNotation] Allows including tables having the same attribute/column names - which have a dot in them. + * @param {boolean} [options.dotNotation] Allows including tables having the same attribute/column names - which have a dot in them. * * @see * {@link Sequelize#query} @@ -2438,7 +2438,7 @@ class Model { * @param {object} values hash of values to upsert * @param {object} [options] upsert options * @param {boolean} [options.validate=true] Run validations before the row is inserted - * @param {Array} [options.fields=Object.keys(this.attributes)] The fields to insert / update. Defaults to all changed fields + * @param {Array} [options.fields=Object.keys(this.attributes)] The fields to update if the record already exists. Defaults to all changed fields. If none of the specified fields are present on the provided `values` object, an insert will still be attempted, but duplicate key conflicts will be ignored. * @param {boolean} [options.hooks=true] Run before / after upsert hooks? * @param {boolean} [options.returning=true] If true, fetches back auto generated values * @param {Transaction} [options.transaction] Transaction to run query under @@ -3315,6 +3315,15 @@ class Model { } return f; }); + } else if (fields && typeof fields === 'object') { + fields = Object.keys(fields).reduce((rawFields, f) => { + if (this.rawAttributes[f] && this.rawAttributes[f].field && this.rawAttributes[f].field !== f) { + rawFields[this.rawAttributes[f].field] = fields[f]; + } else { + rawFields[f] = fields[f]; + } + return rawFields; + }, {}); } this._injectScope(options); @@ -3692,10 +3701,10 @@ class Model { !options.raw && ( // True when sequelize method - (value instanceof Utils.SequelizeMethod || + value instanceof Utils.SequelizeMethod || // Check for data type type comparators !(value instanceof Utils.SequelizeMethod) && this.constructor._dataTypeChanges[key] && this.constructor._dataTypeChanges[key].call(this, value, originalValue, options) || // Check default - !this.constructor._dataTypeChanges[key] && !_.isEqual(value, originalValue)) + !this.constructor._dataTypeChanges[key] && !_.isEqual(value, originalValue) ) ) { this._previousDataValues[key] = originalValue; diff --git a/lib/sequelize.js b/lib/sequelize.js index 2dcac640cc65..af4dff04f70c 100644 --- a/lib/sequelize.js +++ b/lib/sequelize.js @@ -127,7 +127,7 @@ class Sequelize { * @param {string} [password=null] The password which is used to authenticate against the database. Supports SQLCipher encryption for SQLite. * @param {object} [options={}] An object with options. * @param {string} [options.host='localhost'] The host of the relational database. - * @param {number} [options.port=] The port of the relational database. + * @param {number} [options.port] The port of the relational database. * @param {string} [options.username=null] The username which is used to authenticate against the database. * @param {string} [options.password=null] The password which is used to authenticate against the database. * @param {string} [options.database=null] The name of the database @@ -143,7 +143,7 @@ class Sequelize { * @param {object} [options.set={}] Default options for sequelize.set * @param {object} [options.sync={}] Default options for sequelize.sync * @param {string} [options.timezone='+00:00'] The timezone used when converting a date from the database into a JavaScript date. The timezone is also used to SET TIMEZONE when connecting to the server, to ensure that the result of NOW, CURRENT_TIMESTAMP and other time related functions have in the right timezone. For best cross platform performance use the format +/-HH:MM. Will also accept string versions of timezones used by moment.js (e.g. 'America/Los_Angeles'); this is useful to capture daylight savings time changes. - * @param {string|boolean} [options.clientMinMessages='warning'] The PostgreSQL `client_min_messages` session parameter. Set to `false` to not override the database's default. + * @param {string|boolean} [options.clientMinMessages='warning'] (Deprecated) The PostgreSQL `client_min_messages` session parameter. Set to `false` to not override the database's default. * @param {boolean} [options.standardConformingStrings=true] The PostgreSQL `standard_conforming_strings` session parameter. Set to `false` to not set the option. WARNING: Setting this to false may expose vulnerabilities and is not recommended! * @param {Function} [options.logging=console.log] A function that gets executed every time Sequelize would log something. Function may receive multiple parameters but only first one is printed by `console.log`. To print all values use `(...msg) => console.log(msg)` * @param {boolean} [options.benchmark=false] Pass query execution time in milliseconds as second argument to logging function (options.logging). @@ -236,7 +236,7 @@ class Sequelize { // For postgres, we can use this helper to load certs directly from the // connection string. - if (options.dialect === 'postgres' || options.dialect === 'postgresql') { + if (['postgres', 'postgresql'].includes(options.dialect)) { Object.assign(options.dialectOptions, pgConnectionString.parse(arguments[0])); } } else { @@ -257,7 +257,6 @@ class Sequelize { query: {}, sync: {}, timezone: '+00:00', - clientMinMessages: 'warning', standardConformingStrings: true, // eslint-disable-next-line no-console logging: console.log, @@ -340,6 +339,9 @@ class Sequelize { case 'sqlite': Dialect = require('./dialects/sqlite'); break; + case 'snowflake': + Dialect = require('./dialects/snowflake'); + break; default: throw new Error(`The dialect ${this.getDialect()} is not supported. Supported dialects: mssql, mariadb, mysql, postgres, and sqlite.`); } @@ -886,8 +888,7 @@ class Sequelize { * @returns {Sequelize.fn} */ random() { - const dia = this.getDialect(); - if (dia === 'postgres' || dia === 'sqlite') { + if (['postgres', 'sqlite', 'snowflake'].includes(this.getDialect())) { return this.fn('RANDOM'); } return this.fn('RAND'); @@ -1227,11 +1228,9 @@ class Sequelize { attribute.type = this.normalizeDataType(attribute.type); if (Object.prototype.hasOwnProperty.call(attribute, 'defaultValue')) { - if (typeof attribute.defaultValue === 'function' && ( - attribute.defaultValue === DataTypes.NOW || - attribute.defaultValue === DataTypes.UUIDV1 || - attribute.defaultValue === DataTypes.UUIDV4 - )) { + if (typeof attribute.defaultValue === 'function' && + [DataTypes.NOW, DataTypes.UUIDV1, DataTypes.UUIDV4].includes(attribute.defaultValue) + ) { attribute.defaultValue = new attribute.defaultValue(); } } diff --git a/lib/sql-string.js b/lib/sql-string.js index 2e334309d984..15a40c532838 100644 --- a/lib/sql-string.js +++ b/lib/sql-string.js @@ -28,7 +28,7 @@ function escape(val, timeZone, dialect, format) { // SQLite doesn't have true/false support. MySQL aliases true/false to 1/0 // for us. Postgres actually has a boolean type with true/false literals, // but sequelize doesn't use it yet. - if (dialect === 'sqlite' || dialect === 'mssql') { + if (['sqlite', 'mssql'].includes(dialect)) { return +!!val; } return (!!val).toString(); @@ -65,7 +65,7 @@ function escape(val, timeZone, dialect, format) { throw new Error(`Invalid value ${logger.inspect(val)}`); } - if (dialect === 'postgres' || dialect === 'sqlite' || dialect === 'mssql') { + if (['postgres', 'sqlite', 'mssql', 'snowflake'].includes(dialect)) { // http://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS // http://stackoverflow.com/q/603572/130598 val = val.replace(/'/g, "''"); @@ -75,6 +75,7 @@ function escape(val, timeZone, dialect, format) { val = val.replace(/\0/g, '\\0'); } } else { + // eslint-disable-next-line no-control-regex val = val.replace(/[\0\n\r\b\t\\'"\x1a]/g, s => { switch (s) { diff --git a/lib/utils.js b/lib/utils.js index 65b4c75dcf93..42cc952d82e1 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -43,7 +43,7 @@ exports.underscoredIf = underscoredIf; function isPrimitive(val) { const type = typeof val; - return type === 'string' || type === 'number' || type === 'boolean'; + return ['string', 'number', 'boolean'].includes(type); } exports.isPrimitive = isPrimitive; diff --git a/package.json b/package.json index 568a36837a37..fbb2bc2bf99f 100644 --- a/package.json +++ b/package.json @@ -29,83 +29,78 @@ "license": "MIT", "dependencies": { "@types/debug": "^4.1.7", - "debug": "^4.1.1", - "dottie": "^2.0.0", - "inflection": "1.13.1", - "lodash": "^4.17.20", - "moment": "^2.26.0", - "moment-timezone": "^0.5.31", + "debug": "^4.3.3", + "dottie": "^2.0.2", + "inflection": "^1.13.1", + "lodash": "^4.17.21", + "moment": "^2.29.1", + "moment-timezone": "^0.5.34", "pg-connection-string": "^2.5.0", - "retry-as-promised": "^3.2.0", - "semver": "^7.3.2", - "sequelize-pool": "^6.0.0", + "retry-as-promised": "^4.0.0", + "semver": "^7.3.5", + "sequelize-pool": "^7.1.0", "toposort-class": "^1.0.1", - "uuid": "^8.1.0", + "uuid": "^8.3.2", "validator": "^13.7.0", "wkx": "^0.5.0" }, "devDependencies": { - "@commitlint/cli": "^11.0.0", - "@commitlint/config-angular": "^11.0.0", + "@commitlint/cli": "^15.0.0", + "@commitlint/config-angular": "^15.0.0", "@types/chai": "^4.2.22", "@types/mocha": "^9.0.0", - "@types/node": "^12.12.42", + "@types/node": "^16.11.11", "@types/sinon": "^10.0.6", - "@types/validator": "^13.1.4", - "@typescript-eslint/eslint-plugin": "^5.3.0", - "@typescript-eslint/parser": "^5.3.0", - "acorn": "^8.0.4", - "axios": ">=0.21.2", - "chai": "^4.x", - "chai-as-promised": "^7.x", - "chai-datetime": "^1.6.0", - "cheerio": "^1.0.0-rc.3", + "@types/validator": "^13.7.0", + "@typescript-eslint/eslint-plugin": "^5.5.0", + "@typescript-eslint/parser": "^5.5.0", + "acorn": "^8.6.0", + "chai": "^4.3.4", + "chai-as-promised": "^7.1.1", + "chai-datetime": "^1.8.0", + "cheerio": "^1.0.0-rc.10", "cls-hooked": "^4.2.2", "copyfiles": "^2.4.1", - "cross-env": "^7.0.2", - "delay": "^4.3.0", - "esbuild": "^0.13.12", + "cross-env": "^7.0.3", + "delay": "^5.0.0", + "esbuild": "^0.14.1", "esdoc": "^1.1.0", "esdoc-ecmascript-proposal-plugin": "^1.0.0", "esdoc-inject-style-plugin": "^1.0.0", "esdoc-standard-plugin": "^1.0.0", - "eslint": "^6.8.0", - "eslint-plugin-jsdoc": "^20.4.0", - "eslint-plugin-mocha": "^6.2.2", - "expect-type": "^0.11.0", + "eslint": "^8.3.0", + "eslint-plugin-jsdoc": "^37.0.3", + "eslint-plugin-mocha": "^9.0.0", + "expect-type": "^0.12.0", "fast-glob": "^3.2.7", - "fs-jetpack": "^4.1.0", - "husky": "^4.2.5", - "js-combinatorics": "^0.5.5", - "lcov-result-merger": "^3.0.0", - "lint-staged": "^10.2.6", - "mariadb": "^2.3.1", - "markdownlint-cli": "^0.26.0", - "marked": "^1.1.0", - "mocha": "^7.1.2", + "fs-jetpack": "^4.3.0", + "husky": "^7.0.4", + "js-combinatorics": "^0.6.1", + "lcov-result-merger": "^3.1.0", + "lint-staged": "^12.1.2", + "mariadb": "^2.5.5", + "markdownlint-cli": "^0.30.0", + "mocha": "^7.2.0", "module-alias": "^2.2.2", - "mysql2": "^2.1.0", + "mysql2": "^2.3.3", "node-hook": "^1.0.0", - "nth-check": ">=2.0.1", - "nyc": "^15.0.0", + "nyc": "^15.1.0", "p-map": "^4.0.0", "p-props": "^4.0.0", "p-settle": "^4.1.1", "p-timeout": "^4.0.0", - "path-parse": ">=1.0.7", - "pg": "^8.2.1", - "pg-hstore": "^2.x", + "pg": "^8.7.1", + "pg-hstore": "^2.3.4", "rimraf": "^3.0.2", - "semantic-release": "^17.3.0", + "semantic-release": "^18.0.1", "semantic-release-fail-on-major-bump": "^1.0.0", - "semver-regex": ">=3.1.3", - "sinon": "^9.0.2", - "sinon-chai": "^3.3.0", - "source-map-support": "^0.5.20", - "sqlite3": "^4.2.0", - "tar": ">=4.4.18", + "sinon": "^12.0.1", + "sinon-chai": "^3.7.0", + "snowflake-sdk": "^1.6.1", + "source-map-support": "^0.5.21", + "sqlite3": "^5.0.2", "tedious": "8.3.0", - "typescript": "^4.1.3" + "typescript": "^4.5.2" }, "peerDependenciesMeta": { "pg": { @@ -117,6 +112,9 @@ "mysql2": { "optional": true }, + "snowflake-sdk": { + "optional": true + }, "mariadb": { "optional": true }, @@ -137,6 +135,7 @@ "mssql", "sql", "sqlserver", + "snowflake", "orm", "nodejs", "object relational mapper", @@ -170,12 +169,6 @@ "lint-staged": { "*!(d).[tj]s": "eslint" }, - "husky": { - "hooks": { - "pre-commit": "lint-staged", - "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" - } - }, "release": { "plugins": [ "@semantic-release/commit-analyzer", @@ -203,7 +196,7 @@ "----------------------------------------- documentation -------------------------------------------": "", "docs": "rimraf esdoc && esdoc -c docs/esdoc-config.js && cp docs/favicon.ico esdoc/favicon.ico && cp docs/ROUTER.txt esdoc/ROUTER && node docs/run-docs-transforms.js && node docs/redirects/create-redirects.js && rimraf esdoc/file esdoc/source.html", "----------------------------------------- tests ---------------------------------------------------": "", - "mocha": "mocha -r ./test/requireHook", + "mocha": "mocha -r ./test/registerEsbuild", "test-unit": "yarn mocha \"test/unit/**/*.test.[tj]s\"", "test-integration": "yarn mocha \"test/integration/**/*.test.[tj]s\"", "teaser": "node test/teaser.js", @@ -234,6 +227,8 @@ "test-unit-postgres-native": "cross-env DIALECT=postgres-native npm run test-unit", "test-unit-sqlite": "cross-env DIALECT=sqlite npm run test-unit", "test-unit-mssql": "cross-env DIALECT=mssql npm run test-unit", + "test-unit-snowflake": "cross-env DIALECT=snowflake npm run test-unit", + "test-unit-all": "npm run test-unit-mariadb && npm run test-unit-mysql && npm run test-unit-postgres && npm run test-unit-postgres-native && npm run test-unit-mssql && npm run test-unit-sqlite && npm run test-unit-snowflake", "test-integration-mariadb": "cross-env DIALECT=mariadb npm run test-integration", "test-integration-mysql": "cross-env DIALECT=mysql npm run test-integration", "test-integration-postgres": "cross-env DIALECT=postgres npm run test-integration", @@ -254,7 +249,7 @@ "sscce-postgres-native": "cross-env DIALECT=postgres-native node sscce.js", "sscce-sqlite": "cross-env DIALECT=sqlite node sscce.js", "sscce-mssql": "cross-env DIALECT=mssql node sscce.js", - "prepare": "node ./build.js", + "prepare": "node ./build.js && husky install", "---------------------------------------------------------------------------------------------------": "" } } diff --git a/test/config/config.js b/test/config/config.js index b15453ab3db6..914b334c6af5 100644 --- a/test/config/config.js +++ b/test/config/config.js @@ -33,6 +33,18 @@ module.exports = { } }, + snowflake: { + username: env.SEQ_SNOWFLAKE_USER || env.SEQ_USER || 'root', + password: env.SEQ_SNOWFLAKE_PW || env.SEQ_PW || null, + database: env.SEQ_SNOWFLAKE_DB || env.SEQ_DB || 'sequelize_test', + dialectOptions: { + account: env.SEQ_SNOWFLAKE_ACCOUNT || env.SEQ_ACCOUNT || 'sequelize_test', + role: env.SEQ_SNOWFLAKE_ROLE || env.SEQ_ROLE || 'role', + warehouse: env.SEQ_SNOWFLAKE_WH || env.SEQ_WH || 'warehouse', + schema: env.SEQ_SNOWFLAKE_SCHEMA || env.SEQ_SCHEMA || '' + } + }, + mariadb: { database: env.SEQ_MARIADB_DB || env.SEQ_DB || 'sequelize_test', username: env.SEQ_MARIADB_USER || env.SEQ_USER || 'sequelize_test', diff --git a/test/integration/associations/belongs-to-many.test.js b/test/integration/associations/belongs-to-many.test.js index 0a82207e0656..be67c5b1f3d8 100644 --- a/test/integration/associations/belongs-to-many.test.js +++ b/test/integration/associations/belongs-to-many.test.js @@ -193,7 +193,7 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => { expect(project.ProjectUsers.status).to.equal('active'); await this.sequelize.dropSchema('acme'); const schemas = await this.sequelize.showAllSchemas(); - if (dialect === 'postgres' || dialect === 'mssql' || dialect === 'mariadb') { + if (['postgres', 'mssql', 'mariadb'].includes(dialect)) { expect(schemas).to.not.have.property('acme'); } }); @@ -1223,7 +1223,7 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => { describe('hasAssociations with binary key', () => { beforeEach(function() { - const keyDataType = dialect === 'mysql' || dialect === 'mariadb' ? 'BINARY(255)' : DataTypes.BLOB('tiny'); + const keyDataType = ['mysql', 'mariadb'].includes(dialect) ? 'BINARY(255)' : DataTypes.BLOB('tiny'); this.Article = this.sequelize.define('Article', { id: { type: keyDataType, @@ -2919,7 +2919,7 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => { await this.sequelize.sync({ force: true }); let result = await this.sequelize.getQueryInterface().showAllTables(); - if (dialect === 'mssql' || dialect === 'mariadb') { + if (['mssql', 'mariadb'].includes(dialect)) { result = result.map(v => v.tableName); } @@ -2936,7 +2936,7 @@ describe(Support.getTestDialectTeaser('BelongsToMany'), () => { await this.sequelize.sync({ force: true }); let result = await this.sequelize.getQueryInterface().showAllTables(); - if (dialect === 'mssql' || dialect === 'mariadb') { + if (['mssql', 'mariadb'].includes(dialect)) { result = result.map(v => v.tableName); } diff --git a/test/integration/associations/belongs-to.test.js b/test/integration/associations/belongs-to.test.js index 02acd3ba79f2..3ba08273d13f 100644 --- a/test/integration/associations/belongs-to.test.js +++ b/test/integration/associations/belongs-to.test.js @@ -123,7 +123,7 @@ describe(Support.getTestDialectTeaser('BelongsTo'), () => { expect(user).to.be.ok; await this.sequelize.dropSchema('archive'); const schemas = await this.sequelize.showAllSchemas(); - if (dialect === 'postgres' || dialect === 'mssql' || dialect === 'mariadb') { + if (['postgres', 'mssql', 'mariadb'].includes(dialect)) { expect(schemas).to.not.have.property('archive'); } }); diff --git a/test/integration/associations/has-many.test.js b/test/integration/associations/has-many.test.js index 0f9cfbf3e3df..75624e7406f3 100644 --- a/test/integration/associations/has-many.test.js +++ b/test/integration/associations/has-many.test.js @@ -412,7 +412,7 @@ describe(Support.getTestDialectTeaser('HasMany'), () => { expect(users[1].tasks[1].subtasks[1].title).to.equal('a'); await this.sequelize.dropSchema('work'); const schemas = await this.sequelize.showAllSchemas(); - if (dialect === 'postgres' || dialect === 'mssql' || schemas === 'mariadb') { + if (['postgres', 'mssql'].includes(dialect) || schemas === 'mariadb') { expect(schemas).to.be.empty; } }); diff --git a/test/integration/associations/has-one.test.js b/test/integration/associations/has-one.test.js index 2ffd7369bebe..f0d0b6db4bdd 100644 --- a/test/integration/associations/has-one.test.js +++ b/test/integration/associations/has-one.test.js @@ -122,7 +122,7 @@ describe(Support.getTestDialectTeaser('HasOne'), () => { expect(associatedUser.id).not.to.equal(fakeUser.id); await this.sequelize.dropSchema('admin'); const schemas = await this.sequelize.showAllSchemas(); - if (dialect === 'postgres' || dialect === 'mssql' || dialect === 'mariadb') { + if (['postgres', 'mssql', 'mariadb'].includes(dialect)) { expect(schemas).to.not.have.property('admin'); } }); diff --git a/test/integration/associations/scope.test.js b/test/integration/associations/scope.test.js index 6c1d9378ce7e..00e9cfe96dba 100644 --- a/test/integration/associations/scope.test.js +++ b/test/integration/associations/scope.test.js @@ -321,7 +321,7 @@ describe(Support.getTestDialectTeaser('associations'), () => { this.Post.belongsToMany(this.Tag, { as: 'tags', through: this.PostTag, scope: { type: 'tag' } }); }); - it('should create, find and include associations with scope values', async function() { + it('[Flaky] should create, find and include associations with scope values', async function() { await Promise.all([this.Post.sync({ force: true }), this.Tag.sync({ force: true })]); await this.PostTag.sync({ force: true }); @@ -341,35 +341,41 @@ describe(Support.getTestDialectTeaser('associations'), () => { await Promise.all([ postA0.addCategory(categoryA), - postB0.setCategories([categoryB]), - postC0.createCategory(), postA0.createTag(), + postB0.setCategories([categoryB]), postB0.addTag(tagA), + postC0.createCategory(), postC0.setTags([tagB]) ]); - const [postACategories, postATags, postBCategories, postBTags, postCCategories, postCTags] = await Promise.all([ + const [postACategories, postBCategories, postCCategories, postATags, postBTags, postCTags] = await Promise.all([ this.postA.getCategories(), - this.postA.getTags(), this.postB.getCategories(), - this.postB.getTags(), this.postC.getCategories(), + this.postA.getTags(), + this.postB.getTags(), this.postC.getTags() ]); - expect(postACategories.length).to.equal(1); - expect(postATags.length).to.equal(1); - expect(postBCategories.length).to.equal(1); - expect(postBTags.length).to.equal(1); - expect(postCCategories.length).to.equal(1); - expect(postCTags.length).to.equal(1); - - expect(postACategories[0].get('type')).to.equal('category'); - expect(postATags[0].get('type')).to.equal('tag'); - expect(postBCategories[0].get('type')).to.equal('category'); - expect(postBTags[0].get('type')).to.equal('tag'); - expect(postCCategories[0].get('type')).to.equal('category'); - expect(postCTags[0].get('type')).to.equal('tag'); + // Flaky test: randomly one of the value on B will be 0 sometimes, for + // now no solution. Not reproducible at local or cloud with logging enabled + expect([ + postACategories.length, + postATags.length, + postBCategories.length, + postBTags.length, + postCCategories.length, + postCTags.length + ]).to.eql([1, 1, 1, 1, 1, 1]); + + expect([ + postACategories[0].get('type'), + postATags[0].get('type'), + postBCategories[0].get('type'), + postBTags[0].get('type'), + postCCategories[0].get('type'), + postCTags[0].get('type') + ]).to.eql(['category', 'tag', 'category', 'tag', 'category', 'tag']); const [postA, postB, postC] = await Promise.all([this.Post.findOne({ where: { diff --git a/test/integration/data-types.test.js b/test/integration/data-types.test.js index a2764fd19b27..a7d0571b1e68 100644 --- a/test/integration/data-types.test.js +++ b/test/integration/data-types.test.js @@ -429,10 +429,10 @@ describe(Support.getTestDialectTeaser('DataTypes'), () => { //This case throw unhandled exception const users = await User.findAll(); - if (dialect === 'mysql' || dialect === 'mariadb') { + if (['mysql', 'mariadb'].includes(dialect)) { // MySQL will return NULL, because they lack EMPTY geometry data support. expect(users[0].field).to.be.eql(null); - } else if (dialect === 'postgres' || dialect === 'postgres-native') { + } else if (['postgres', 'postgres-native'].includes(dialect)) { //Empty Geometry data [0,0] as per https://trac.osgeo.org/postgis/ticket/1996 expect(users[0].field).to.be.deep.eql({ type: 'Point', coordinates: [0, 0] }); } else { @@ -462,7 +462,7 @@ describe(Support.getTestDialectTeaser('DataTypes'), () => { }); } - if (dialect === 'postgres' || dialect === 'sqlite') { + if (['postgres', 'sqlite'].includes(dialect)) { // postgres actively supports IEEE floating point literals, and sqlite doesn't care what we throw at it it('should store and parse IEEE floating point literals (NaN and Infinity)', async function() { const Model = this.sequelize.define('model', { @@ -487,7 +487,7 @@ describe(Support.getTestDialectTeaser('DataTypes'), () => { }); } - if (dialect === 'postgres' || dialect === 'mysql') { + if (['postgres', 'mysql'].includes(dialect)) { it('should parse DECIMAL as string', async function() { const Model = this.sequelize.define('model', { decimal: Sequelize.DECIMAL, @@ -526,7 +526,7 @@ describe(Support.getTestDialectTeaser('DataTypes'), () => { }); } - if (dialect === 'postgres' || dialect === 'mysql' || dialect === 'mssql') { + if (['postgres', 'mysql', 'mssql'].includes(dialect)) { it('should parse BIGINT as string', async function() { const Model = this.sequelize.define('model', { jewelPurity: Sequelize.BIGINT diff --git a/test/integration/dialects/postgres/connection-manager.test.js b/test/integration/dialects/postgres/connection-manager.test.js index 787433554568..44d9505a82d0 100644 --- a/test/integration/dialects/postgres/connection-manager.test.js +++ b/test/integration/dialects/postgres/connection-manager.test.js @@ -27,19 +27,32 @@ if (dialect.match(/^postgres/)) { expect(result[0].client_min_messages).to.equal('warning'); }); - it('should allow overriding client_min_messages', async () => { + it('should allow overriding client_min_messages (deprecated in v7)', async () => { const sequelize = Support.createSequelizeInstance({ clientMinMessages: 'ERROR' }); const result = await sequelize.query('SHOW client_min_messages'); expect(result[0].client_min_messages).to.equal('error'); }); - it('should not set client_min_messages if clientMinMessages is false', async () => { + it('should not set client_min_messages if clientMinMessages is false (deprecated in v7)', async () => { const sequelize = Support.createSequelizeInstance({ clientMinMessages: false }); const result = await sequelize.query('SHOW client_min_messages'); // `notice` is Postgres's default expect(result[0].client_min_messages).to.equal('notice'); }); + it('should allow overriding client_min_messages', async () => { + const sequelize = Support.createSequelizeInstance({ dialectOptions: { clientMinMessages: 'ERROR' } }); + const result = await sequelize.query('SHOW client_min_messages'); + expect(result[0].client_min_messages).to.equal('error'); + }); + + it('should not set client_min_messages if clientMinMessages is ignore', async () => { + const sequelize = Support.createSequelizeInstance({ dialectOptions: { clientMinMessages: 'IGNORE' } }); + const result = await sequelize.query('SHOW client_min_messages'); + // `notice` is Postgres's default + expect(result[0].client_min_messages).to.equal('notice'); + }); + it('should time out the query request when the query runs beyond the configured query_timeout', async () => { const sequelize = Support.createSequelizeInstance({ dialectOptions: { query_timeout: 100 } diff --git a/test/integration/dialects/snowflake/connector-manager.test.js b/test/integration/dialects/snowflake/connector-manager.test.js new file mode 100644 index 000000000000..f3ee74304eaa --- /dev/null +++ b/test/integration/dialects/snowflake/connector-manager.test.js @@ -0,0 +1,39 @@ +'use strict'; + +const chai = require('chai'); +const expect = chai.expect; +const Support = require('../../support'); +const dialect = Support.getTestDialect(); +const DataTypes = require('sequelize/lib/data-types'); + +if (dialect === 'snowflake') { + describe('[SNOWFLAKE Specific] Connection Manager', () => { + it('-FOUND_ROWS can be suppressed to get back legacy behavior', async () => { + const sequelize = Support.createSequelizeInstance(); + const User = sequelize.define('User', { username: DataTypes.STRING }); + + await User.sync({ force: true }); + await User.create({ id: 1, username: 'jozef' }); + + const [affectedCount] = await User.update({ username: 'jozef' }, { + where: { + id: 1 + } + }); + + // https://github.com/sequelize/sequelize/issues/7184 + await affectedCount.should.equal(1); + }); + + it('should acquire a valid connection when keepDefaultTimezone is true', async () => { + const sequelize = Support.createSequelizeInstance({ keepDefaultTimezone: true, pool: { min: 1, max: 1, handleDisconnects: true, idle: 5000 } }); + const cm = sequelize.connectionManager; + + await sequelize.sync(); + + const connection = await cm.getConnection(); + expect(cm.validate(connection)).to.be.ok; + await cm.releaseConnection(connection); + }); + }); +} diff --git a/test/integration/dialects/snowflake/smoke.test.js b/test/integration/dialects/snowflake/smoke.test.js new file mode 100644 index 000000000000..6d07f075e0e3 --- /dev/null +++ b/test/integration/dialects/snowflake/smoke.test.js @@ -0,0 +1,112 @@ +'use strict'; + +const Support = require('../../support'); +const dialect = Support.getTestDialect(); +const DataTypes = require('sequelize/lib/data-types'); +const moment = require('moment'); + +if (dialect === 'snowflake') { + describe('[SNOWFLAKE Specific] Smoke test', () => { + describe('[SNOWFLAKE Specific] Basic test for one table', () => { + let User; + + before(async () => { + const sequelize = Support.createSequelizeInstance(); + User = sequelize.define('User', { + username: DataTypes.STRING, + lastActivity: { + type: DataTypes.DATE, + get() { + const value = this.getDataValue('lastActivity'); + return value ? value.valueOf() : 0; + } + } + }); + + await User.sync({ force: true }); + await User.create({ id: 1, username: 'jozef', lastActivity: new Date(Date.UTC(2021, 5, 21)) }); + await User.create({ id: 2, username: 'jeff', lastActivity: moment(Date.UTC(2021, 5, 22)).format('YYYY-MM-DD HH:mm:ss Z') }); + }); + + after(async () =>{ + await User.drop(); + }); + + it('findOne with where', async () => { + const user = await User.findOne({ + where: + { + username: 'jeff' + } + }); + user.id.should.equal(2); + }); + + it('findOne with date attribute', async () => { + const user = await User.findOne({ + where: + { + username: 'jeff' + } + }); + // user.lastActivity.should.be.equalTime(new Date(Date.UTC(2021, 5, 22))); + user.lastActivity.should.equal(Date.UTC(2021, 5, 22)); + }); + + it('findAll with orderby', async () => { + const username = 'test'; + await User.create({ id: 3, username }); + const users = await User.findAll({ + order: [['createdAt', 'ASC']] + }); + await users[users.length - 1].username.should.equal(username); + }); + + it('Update', async () => { + const res = await User.update({ username: 'jozef1' }, { + where: { + id: 1 + } + }); + // https://github.com/sequelize/sequelize/issues/7184 + await res[0].should.equal(1); + }); + }); + + + describe('[SNOWFLAKE Specific] Test for auto_increment', () => { + let Task; + + before(async () => { + const sequelize = Support.createSequelizeInstance(); + Task = sequelize.define('Task', { + id: { + type: 'INTEGER', + primaryKey: true, + autoIncrement: true + }, + taskName: DataTypes.STRING + }); + + await Task.sync({ force: true }); + await Task.create({ taskName: 'task1' }); + await Task.create({ taskName: 'task2' }); + }); + + after(async () =>{ + await Task.drop(); + }); + + it('findOne with where', async () => { + const user = await Task.findOne({ + where: + { + taskName: 'task2' + } + }); + user.id.should.equal(2); + }); + + }); + }); +} diff --git a/test/integration/include/separate.test.js b/test/integration/include/separate.test.js index 3cc9bec25bd6..17243bd24263 100644 --- a/test/integration/include/separate.test.js +++ b/test/integration/include/separate.test.js @@ -463,7 +463,7 @@ if (current.dialect.supports.groupedLimit) { expect(result[1].tasks[1].title).to.equal('c'); await this.sequelize.dropSchema('archive'); const schemas = await this.sequelize.showAllSchemas(); - if (dialect === 'postgres' || dialect === 'mssql' || dialect === 'mariadb') { + if (['postgres', 'mssql', 'mariadb'].includes(dialect)) { expect(schemas).to.not.have.property('archive'); } }); diff --git a/test/integration/instance/increment.test.js b/test/integration/instance/increment.test.js index ab1b15224823..d8345c25af9a 100644 --- a/test/integration/instance/increment.test.js +++ b/test/integration/instance/increment.test.js @@ -28,6 +28,7 @@ describe(Support.getTestDialectTeaser('Instance'), () => { touchedAt: { type: DataTypes.DATE, defaultValue: DataTypes.NOW }, aNumber: { type: DataTypes.INTEGER }, bNumber: { type: DataTypes.INTEGER }, + cNumber: { type: DataTypes.INTEGER, field: 'CNumberColumn' }, aDate: { type: DataTypes.DATE }, validateTest: { @@ -57,7 +58,7 @@ describe(Support.getTestDialectTeaser('Instance'), () => { describe('increment', () => { beforeEach(async function() { - await this.User.create({ id: 1, aNumber: 0, bNumber: 0 }); + await this.User.create({ id: 1, aNumber: 0, bNumber: 0, cNumber: 0 }); }); if (current.dialect.supports.transactions) { @@ -150,6 +151,27 @@ describe(Support.getTestDialectTeaser('Instance'), () => { expect(user3.bNumber).to.be.equal(2); }); + it('single value should work when field name is different from database column name', async function() { + const user = await this.User.findByPk(1); + await user.increment('cNumber'); + const user2 = await this.User.findByPk(1); + expect(user2.cNumber).to.be.equal(1); + }); + + it('array should work when field name is different from database column name', async function() { + const user = await this.User.findByPk(1); + await user.increment(['cNumber']); + const user2 = await this.User.findByPk(1); + expect(user2.cNumber).to.be.equal(1); + }); + + it('key value should work when field name is different from database column name', async function() { + const user = await this.User.findByPk(1); + await user.increment({ cNumber: 1 }); + const user2 = await this.User.findByPk(1); + expect(user2.cNumber).to.be.equal(1); + }); + it('with timestamps set to true', async function() { const User = this.sequelize.define('IncrementUser', { aNumber: DataTypes.INTEGER diff --git a/test/integration/model.test.js b/test/integration/model.test.js index d6aa15cb86e8..248a738af56e 100644 --- a/test/integration/model.test.js +++ b/test/integration/model.test.js @@ -14,7 +14,7 @@ const chai = require('chai'), Op = Sequelize.Op, semver = require('semver'), pMap = require('p-map'); - + describe(Support.getTestDialectTeaser('Model'), () => { let isMySQL8; @@ -382,7 +382,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { if (!isMySQL8) { return; } - + const indices = [{ name: 'a_b_uniq', unique: true, @@ -407,7 +407,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { indexes: indices, engine: 'MyISAM' }); - + try { await this.sequelize.sync(); expect.fail(); @@ -420,7 +420,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { if (!isMySQL8) { return; } - + const indices = [{ name: 'a_b_uniq', unique: true, @@ -2298,7 +2298,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { await Post.sync({ logging: _.once(sql => { if (dialect === 'postgres') { expect(sql).to.match(/"authorId" INTEGER REFERENCES "authors" \("id"\)/); - } else if (dialect === 'mysql' || dialect === 'mariadb') { + } else if (['mysql', 'mariadb'].includes(dialect)) { expect(sql).to.match(/FOREIGN KEY \(`authorId`\) REFERENCES `authors` \(`id`\)/); } else if (dialect === 'mssql') { expect(sql).to.match(/FOREIGN KEY \(\[authorId\]\) REFERENCES \[authors\] \(\[id\]\)/); @@ -2322,7 +2322,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { await Post.sync({ logging: _.once(sql => { if (dialect === 'postgres') { expect(sql).to.match(/"authorId" INTEGER REFERENCES "authors" \("id"\)/); - } else if (dialect === 'mysql' || dialect === 'mariadb') { + } else if (['mysql', 'mariadb'].includes(dialect)) { expect(sql).to.match(/FOREIGN KEY \(`authorId`\) REFERENCES `authors` \(`id`\)/); } else if (dialect === 'sqlite') { expect(sql).to.match(/`authorId` INTEGER REFERENCES `authors` \(`id`\)/); diff --git a/test/integration/model/create.test.js b/test/integration/model/create.test.js index 3f2b5b2a8532..18d1e0058022 100644 --- a/test/integration/model/create.test.js +++ b/test/integration/model/create.test.js @@ -569,7 +569,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { describe('findCreateFind', () => { if (dialect !== 'sqlite') { - it('should work with multiple concurrent calls', async function() { + it('[Flaky] should work with multiple concurrent calls', async function() { const [ [instance1, created1], [instance2, created2], @@ -581,9 +581,11 @@ describe(Support.getTestDialectTeaser('Model'), () => { ]); // All instances are the same - expect(instance1.id).to.equal(1); - expect(instance2.id).to.equal(1); - expect(instance3.id).to.equal(1); + // Flaky test: sometimes the id is 2, not 1. Here whe just need to assert + // all the id1 === id2 === id3 + expect(instance1.id).to.equal(instance2.id); + expect(instance2.id).to.equal(instance3.id); + // Only one of the createdN values is true expect(!!(created1 ^ created2 ^ created3)).to.be.true; }); @@ -829,7 +831,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { } it('is possible to use casting when creating an instance', async function() { - const type = dialect === 'mysql' || dialect === 'mariadb' ? 'signed' : 'integer'; + const type = ['mysql', 'mariadb'].includes(dialect) ? 'signed' : 'integer'; let match = false; const user = await this.User.create({ @@ -850,7 +852,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { let type = this.sequelize.cast(this.sequelize.cast(this.sequelize.literal('1-2'), 'integer'), 'integer'), match = false; - if (dialect === 'mysql' || dialect === 'mariadb') { + if (['mysql', 'mariadb'].includes(dialect)) { type = this.sequelize.cast(this.sequelize.cast(this.sequelize.literal('1-2'), 'unsigned'), 'signed'); } @@ -858,7 +860,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { intVal: type }, { logging(sql) { - if (dialect === 'mysql' || dialect === 'mariadb') { + if (['mysql', 'mariadb'].includes(dialect)) { expect(sql).to.contain('CAST(CAST(1-2 AS UNSIGNED) AS SIGNED)'); } else { expect(sql).to.contain('CAST(CAST(1-2 AS INTEGER) AS INTEGER)'); @@ -1009,7 +1011,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { } }); - if (dialect === 'postgres' || dialect === 'sqlite') { + if (['postgres', 'sqlite'].includes(dialect)) { it("doesn't allow case-insensitive duplicated records using CITEXT", async function() { const User = this.sequelize.define('UserWithUniqueCITEXT', { username: { type: Sequelize.CITEXT, unique: true } diff --git a/test/integration/model/findAll.test.js b/test/integration/model/findAll.test.js index 5a4aa748547d..eae031ed1384 100644 --- a/test/integration/model/findAll.test.js +++ b/test/integration/model/findAll.test.js @@ -481,7 +481,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { expect(users[1].intVal).to.equal(10); }); - if (dialect === 'postgres' || dialect === 'sqlite') { + if (['postgres', 'sqlite'].includes(dialect)) { it('should be able to find multiple users with case-insensitive on CITEXT type', async function() { const User = this.sequelize.define('UsersWithCaseInsensitiveName', { username: Sequelize.CITEXT diff --git a/test/integration/model/findAll/groupedLimit.test.js b/test/integration/model/findAll/groupedLimit.test.js index 76760d25b7f4..19edc663b639 100644 --- a/test/integration/model/findAll/groupedLimit.test.js +++ b/test/integration/model/findAll/groupedLimit.test.js @@ -115,7 +115,7 @@ if (current.dialect.supports['UNION ALL']) { }); }); - it('works with computed order', async function() { + it('[Flaky] works with computed order', async function() { const users = await this.User.findAll({ attributes: ['id'], groupedLimit: { @@ -133,7 +133,7 @@ if (current.dialect.supports['UNION ALL']) { project1 - 1, 3, 4 project2 - 3, 5, 4 */ - expect(users).to.have.length(4); + // Flaky test expect(users.map(u => u.get('id'))).to.deep.equal([1, 3, 5, 4]); }); diff --git a/test/integration/model/findOne.test.js b/test/integration/model/findOne.test.js index 76e982ffe095..73c499b15b62 100644 --- a/test/integration/model/findOne.test.js +++ b/test/integration/model/findOne.test.js @@ -259,7 +259,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { expect(user.ID).to.equal(1); }); - if (dialect === 'postgres' || dialect === 'sqlite') { + if (['postgres', 'sqlite'].includes(dialect)) { it('should allow case-insensitive find on CITEXT type', async function() { const User = this.sequelize.define('UserWithCaseInsensitiveName', { username: Sequelize.CITEXT diff --git a/test/integration/model/upsert.test.js b/test/integration/model/upsert.test.js index bfbab5e27e13..c007d8868563 100644 --- a/test/integration/model/upsert.test.js +++ b/test/integration/model/upsert.test.js @@ -61,7 +61,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { describe('upsert', () => { it('works with upsert on id', async function() { const [, created0] = await this.User.upsert({ id: 42, username: 'john' }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created0).to.be.null; } else { expect(created0).to.be.true; @@ -69,7 +69,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { this.clock.tick(1000); const [, created] = await this.User.upsert({ id: 42, username: 'doe' }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { expect(created).to.be.false; @@ -83,7 +83,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { it('works with upsert on a composite key', async function() { const [, created0] = await this.User.upsert({ foo: 'baz', bar: 19, username: 'john' }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created0).to.be.null; } else { expect(created0).to.be.true; @@ -91,7 +91,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { this.clock.tick(1000); const [, created] = await this.User.upsert({ foo: 'baz', bar: 19, username: 'doe' }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { expect(created).to.be.false; @@ -142,7 +142,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { User.upsert({ a: 'a', b: 'a', username: 'curt' }) ]); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created1[1]).to.be.null; expect(created2[1]).to.be.null; } else { @@ -153,7 +153,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { this.clock.tick(1000); // Update the first one const [, created] = await User.upsert({ a: 'a', b: 'b', username: 'doe' }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { expect(created).to.be.false; @@ -198,7 +198,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { await User.sync({ force: true }); const [, created] = await User.upsert({ id: 1, email: 'notanemail' }, options); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { expect(created).to.be.true; @@ -207,7 +207,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { it('works with BLOBs', async function() { const [, created0] = await this.User.upsert({ id: 42, username: 'john', blob: Buffer.from('kaj') }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created0).to.be.null; } else { expect(created0).to.be.ok; @@ -215,7 +215,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { this.clock.tick(1000); const [, created] = await this.User.upsert({ id: 42, username: 'doe', blob: Buffer.from('andrea') }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { expect(created).to.be.false; @@ -230,14 +230,14 @@ describe(Support.getTestDialectTeaser('Model'), () => { it('works with .field', async function() { const [, created0] = await this.User.upsert({ id: 42, baz: 'foo' }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created0).to.be.null; } else { expect(created0).to.be.ok; } const [, created] = await this.User.upsert({ id: 42, baz: 'oof' }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { expect(created).to.be.false; @@ -249,7 +249,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { it('works with primary key using .field', async function() { const [, created0] = await this.ModelWithFieldPK.upsert({ userId: 42, foo: 'first' }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created0).to.be.null; } else { expect(created0).to.be.ok; @@ -257,7 +257,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { this.clock.tick(1000); const [, created] = await this.ModelWithFieldPK.upsert({ userId: 42, foo: 'second' }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { expect(created).to.be.false; @@ -269,7 +269,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { it('works with database functions', async function() { const [, created0] = await this.User.upsert({ id: 42, username: 'john', foo: this.sequelize.fn('upper', 'mixedCase1') }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created0).to.be.null; } else { expect(created0).to.be.ok; @@ -277,7 +277,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { this.clock.tick(1000); const [, created] = await this.User.upsert({ id: 42, username: 'doe', foo: this.sequelize.fn('upper', 'mixedCase2') }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { expect(created).to.be.false; @@ -311,6 +311,30 @@ describe(Support.getTestDialectTeaser('Model'), () => { clock.restore(); }); + it('falls back to a noop if no update values are found in the upsert data', async function() { + const User = this.sequelize.define('user', { + username: DataTypes.STRING, + email: { + type: DataTypes.STRING, + field: 'email_address', + defaultValue: 'xxx@yyy.zzz' + } + }, { + // note, timestamps: false is important here because this test is attempting to see what happens + // if there are NO updatable fields (including timestamp values). + timestamps: false + }); + + await User.sync({ force: true }); + // notice how the data does not actually have the update fields. + await User.upsert({ id: 42, username: 'jack' }, { fields: ['email'] }); + await User.upsert({ id: 42, username: 'jill' }, { fields: ['email'] }); + const user = await User.findByPk(42); + // just making sure the user exists, i.e. the insert happened. + expect(user).to.be.ok; + expect(user.username).to.equal('jack'); // second upsert should not have updated username. + }); + it('does not update using default values', async function() { await this.User.create({ id: 42, username: 'john', baz: 'new baz value' }); const user0 = await this.User.findByPk(42); @@ -330,7 +354,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { await this.User.create({ id: 42, username: 'john' }); const user = await this.User.findByPk(42); const [, created] = await this.User.upsert({ id: user.id, username: user.username }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { // After set node-mysql flags = '-FOUND_ROWS' / foundRows=false @@ -357,14 +381,14 @@ describe(Support.getTestDialectTeaser('Model'), () => { const clock = sinon.useFakeTimers(); await User.sync({ force: true }); const [, created0] = await User.upsert({ username: 'user1', email: 'user1@domain.ext', city: 'City' }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created0).to.be.null; } else { expect(created0).to.be.ok; } clock.tick(1000); const [, created] = await User.upsert({ username: 'user1', email: 'user1@domain.ext', city: 'New City' }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { expect(created).to.be.false; @@ -393,13 +417,13 @@ describe(Support.getTestDialectTeaser('Model'), () => { await User.sync({ force: true }); const [, created0] = await User.upsert({ username: 'user1', email: 'user1@domain.ext', city: 'City' }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created0).to.be.null; } else { expect(created0).to.be.ok; } const [, created] = await User.upsert({ username: 'user1', email: 'user1@domain.ext', city: 'New City' }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { expect(created).to.be.false; @@ -423,13 +447,13 @@ describe(Support.getTestDialectTeaser('Model'), () => { await User.sync({ force: true }); const [, created0] = await User.upsert({ name: 'user1', address: 'address', city: 'City' }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created0).to.be.null; } else { expect(created0).to.be.ok; } const [, created] = await User.upsert({ name: 'user1', address: 'address', city: 'New City' }); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { expect(created).not.to.be.ok; @@ -505,7 +529,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { const [user0, created0] = await this.User.upsert({ id: 42, username: 'john' }, { returning: true }); expect(user0.get('id')).to.equal(42); expect(user0.get('username')).to.equal('john'); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created0).to.be.null; } else { expect(created0).to.be.true; @@ -514,7 +538,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { const [user, created] = await this.User.upsert({ id: 42, username: 'doe' }, { returning: true }); expect(user.get('id')).to.equal(42); expect(user.get('username')).to.equal('doe'); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { expect(created).to.be.false; @@ -538,7 +562,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { const [user0, created0] = await User.upsert({ id: 42, username: 'john' }, { returning: true }); expect(user0.get('id')).to.equal(42); expect(user0.get('username')).to.equal('john'); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created0).to.be.null; } else { expect(created0).to.be.true; @@ -547,7 +571,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { const [user, created] = await User.upsert({ id: 42, username: 'doe' }, { returning: true }); expect(user.get('id')).to.equal(42); expect(user.get('username')).to.equal('doe'); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { expect(created).to.be.false; @@ -570,7 +594,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { const [user0, created0] = await User.upsert({ id: 'surya', username: 'john' }, { returning: true }); expect(user0.get('id')).to.equal('surya'); expect(user0.get('username')).to.equal('john'); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created0).to.be.null; } else { expect(created0).to.be.true; @@ -579,7 +603,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { const [user, created] = await User.upsert({ id: 'surya', username: 'doe' }, { returning: true }); expect(user.get('id')).to.equal('surya'); expect(user.get('username')).to.equal('doe'); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { expect(created).to.be.false; @@ -599,7 +623,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { expect(user.name).to.be.equal('Test default value'); expect(user.code).to.be.equal(2020); - if (dialect === 'sqlite' || dialect === 'postgres') { + if (['sqlite', 'postgres'].includes(dialect)) { expect(created).to.be.null; } else { expect(created).to.be.true; diff --git a/test/integration/operators.test.js b/test/integration/operators.test.js index 7d104c7bd6d0..72ec3f82dc63 100644 --- a/test/integration/operators.test.js +++ b/test/integration/operators.test.js @@ -41,7 +41,7 @@ describe(Support.getTestDialectTeaser('Operators'), () => { }); }); - if (dialect === 'mysql' || dialect === 'postgres') { + if (['mysql', 'postgres'].includes(dialect)) { describe('case sensitive', () => { it('should work with a regexp where', async function() { await this.User.create({ name: 'Foobar' }); diff --git a/test/integration/pool.test.js b/test/integration/pool.test.js index 0bd4bdfa1202..90550b0beed7 100644 --- a/test/integration/pool.test.js +++ b/test/integration/pool.test.js @@ -40,6 +40,7 @@ function assertNewConnection(newConnection, oldConnection) { break; case 'mssql': + // Flaky test expect(newConnection.dummyId).to.not.be.ok; expect(oldConnection.dummyId).to.be.ok; break; diff --git a/test/integration/query-interface.test.js b/test/integration/query-interface.test.js index 73cc1cc5fab9..6c1078a423b3 100644 --- a/test/integration/query-interface.test.js +++ b/test/integration/query-interface.test.js @@ -65,7 +65,7 @@ describe(Support.getTestDialectTeaser('QueryInterface'), () => { }); } - if (dialect === 'mysql' || dialect === 'mariadb') { + if (['mysql', 'mariadb'].includes(dialect)) { it('should show all tables in all databases', async function() { await this.queryInterface.createTable('my_test_table1', { name: DataTypes.STRING }); await this.sequelize.query('CREATE DATABASE my_test_db'); @@ -96,7 +96,7 @@ describe(Support.getTestDialectTeaser('QueryInterface'), () => { }); await this.queryInterface.renameTable('my_test_table', 'my_test_table_new'); let tableNames = await this.queryInterface.showAllTables(); - if (dialect === 'mssql' || dialect === 'mariadb') { + if (['mssql', 'mariadb'].includes(dialect)) { tableNames = tableNames.map(v => v.tableName); } expect(tableNames).to.contain('my_test_table_new'); @@ -138,7 +138,7 @@ describe(Support.getTestDialectTeaser('QueryInterface'), () => { }); await this.queryInterface.dropAllTables({ skip: ['skipme'] }); let tableNames = await this.queryInterface.showAllTables(); - if (dialect === 'mssql' || dialect === 'mariadb') { + if (['mssql', 'mariadb'].includes(dialect)) { tableNames = tableNames.map(v => v.tableName); } expect(tableNames).to.contain('skipme'); @@ -453,7 +453,7 @@ describe(Support.getTestDialectTeaser('QueryInterface'), () => { expect(Object.keys(foreignKeys[2])).to.have.length(7); } else if (dialect === 'sqlite') { expect(Object.keys(foreignKeys[0])).to.have.length(8); - } else if (dialect === 'mysql' || dialect === 'mariadb' || dialect === 'mssql') { + } else if (['mysql', 'mariadb', 'mssql'].includes(dialect)) { expect(Object.keys(foreignKeys[0])).to.have.length(12); } else { throw new Error(`This test doesn't support ${dialect}`); @@ -593,7 +593,7 @@ describe(Support.getTestDialectTeaser('QueryInterface'), () => { constraints = constraints.map(constraint => constraint.constraintName); // The name of primaryKey constraint is always `PRIMARY` in case of MySQL and MariaDB - const expectedConstraintName = dialect === 'mysql' || dialect === 'mariadb' ? 'PRIMARY' : 'users_username_pk'; + const expectedConstraintName = ['mysql', 'mariadb'].includes(dialect) ? 'PRIMARY' : 'users_username_pk'; expect(constraints).to.include(expectedConstraintName); await this.queryInterface.removeConstraint('users', expectedConstraintName); diff --git a/test/integration/query-interface/changeColumn.test.js b/test/integration/query-interface/changeColumn.test.js index 2df81c8d522f..bcac4528745c 100644 --- a/test/integration/query-interface/changeColumn.test.js +++ b/test/integration/query-interface/changeColumn.test.js @@ -44,7 +44,7 @@ describe(Support.getTestDialectTeaser('QueryInterface'), () => { schema: 'archive' }); - if (dialect === 'postgres' || dialect === 'postgres-native') { + if (['postgres', 'postgres-native'].includes(dialect)) { expect(table.currency.type).to.equal('DOUBLE PRECISION'); } else { expect(table.currency.type).to.equal('FLOAT'); @@ -72,7 +72,7 @@ describe(Support.getTestDialectTeaser('QueryInterface'), () => { tableName: 'users' }); - if (dialect === 'postgres' || dialect === 'postgres-native') { + if (['postgres', 'postgres-native'].includes(dialect)) { expect(table.currency.type).to.equal('DOUBLE PRECISION'); } else { expect(table.currency.type).to.equal('FLOAT'); diff --git a/test/integration/query-interface/createTable.test.js b/test/integration/query-interface/createTable.test.js index ee7e3211f702..0fe233c8bbb7 100644 --- a/test/integration/query-interface/createTable.test.js +++ b/test/integration/query-interface/createTable.test.js @@ -28,7 +28,7 @@ describe(Support.getTestDialectTeaser('QueryInterface'), () => { const result = await this.queryInterface.describeTable('TableWithPK'); - if (dialect === 'mssql' || dialect === 'mysql' || dialect === 'mariadb') { + if (['mssql', 'mysql', 'mariadb'].includes(dialect)) { expect(result.table_id.autoIncrement).to.be.true; } else if (dialect === 'postgres') { expect(result.table_id.defaultValue).to.equal('nextval("TableWithPK_table_id_seq"::regclass)'); diff --git a/test/integration/query-interface/describeTable.test.js b/test/integration/query-interface/describeTable.test.js index 318b142322b4..31ce11e7adf6 100644 --- a/test/integration/query-interface/describeTable.test.js +++ b/test/integration/query-interface/describeTable.test.js @@ -123,7 +123,7 @@ describe(Support.getTestDialectTeaser('QueryInterface'), () => { expect(enumVals.type).to.eql('ENUM(\'hello\',\'world\')'); } - if (dialect === 'postgres' || dialect === 'mysql' || dialect === 'mssql') { + if (['postgres', 'mysql', 'mssql'].includes(dialect)) { expect(city.comment).to.equal('Users City'); expect(username.comment).to.equal(null); } diff --git a/test/integration/sequelize.test.js b/test/integration/sequelize.test.js index 6139899ff5b6..1e99dde1711e 100644 --- a/test/integration/sequelize.test.js +++ b/test/integration/sequelize.test.js @@ -12,10 +12,10 @@ const sinon = require('sinon'); const current = Support.sequelize; const qq = str => { - if (dialect === 'postgres' || dialect === 'mssql') { + if (['postgres', 'mssql'].includes(dialect)) { return `"${str}"`; } - if (dialect === 'mysql' || dialect === 'mariadb' || dialect === 'sqlite') { + if (['mysql', 'mariadb', 'sqlite'].includes(dialect)) { return `\`${str}\``; } return str; @@ -360,7 +360,7 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => { const Photo = this.sequelize.define('Foto', { name: DataTypes.STRING }, { tableName: 'photos' }); await Photo.sync({ force: true }); let tableNames = await this.sequelize.getQueryInterface().showAllTables(); - if (dialect === 'mssql' || dialect === 'mariadb') { + if (['mssql', 'mariadb'].includes(dialect)) { tableNames = tableNames.map(v => v.tableName); } expect(tableNames).to.include('photos'); @@ -439,7 +439,7 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => { await User2.sync(); expect.fail(); } catch (err) { - if (dialect === 'postgres' || dialect === 'postgres-native') { + if (['postgres', 'postgres-native'].includes(dialect)) { assert([ 'fe_sendauth: no password supplied', 'role "bar" does not exist', diff --git a/test/integration/sequelize/query.test.js b/test/integration/sequelize/query.test.js index 37dd1f6e4ce1..1a590b6e4fd9 100644 --- a/test/integration/sequelize/query.test.js +++ b/test/integration/sequelize/query.test.js @@ -10,10 +10,10 @@ const moment = require('moment'); const { DatabaseError, UniqueConstraintError, ForeignKeyConstraintError } = Support.Sequelize; const qq = str => { - if (dialect === 'postgres' || dialect === 'mssql') { + if (['postgres', 'mssql'].includes(dialect)) { return `"${str}"`; } - if (dialect === 'mysql' || dialect === 'mariadb' || dialect === 'sqlite') { + if (['mysql', 'mariadb', 'sqlite'].includes(dialect)) { return `\`${str}\``; } return str; @@ -549,7 +549,7 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => { let logSql; const result = await this.sequelize.query({ query: `select $1${typeCast} as foo, $2${typeCast} as bar`, bind: [1, 2] }, { type: this.sequelize.QueryTypes.SELECT, logging(s) { logSql = s; } }); expect(result).to.deep.equal([{ foo: 1, bar: 2 }]); - if (dialect === 'postgres' || dialect === 'sqlite') { + if (['postgres', 'sqlite'].includes(dialect)) { expect(logSql).to.include('$1'); expect(logSql).to.include('$2'); } else if (dialect === 'mssql') { @@ -561,14 +561,14 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => { }); it('dot separated attributes when doing a raw query without nest', async function() { - const tickChar = dialect === 'postgres' || dialect === 'mssql' ? '"' : '`', + const tickChar = ['postgres', 'mssql'].includes(dialect) ? '"' : '`', sql = `select 1 as ${Sequelize.Utils.addTicks('foo.bar.baz', tickChar)}`; await expect(this.sequelize.query(sql, { raw: true, nest: false }).then(obj => obj[0])).to.eventually.deep.equal([{ 'foo.bar.baz': 1 }]); }); it('destructs dot separated attributes when doing a raw query using nest', async function() { - const tickChar = dialect === 'postgres' || dialect === 'mssql' ? '"' : '`', + const tickChar = ['postgres', 'mssql'].includes(dialect) ? '"' : '`', sql = `select 1 as ${Sequelize.Utils.addTicks('foo.bar.baz', tickChar)}`; const result = await this.sequelize.query(sql, { raw: true, nest: true }); @@ -605,7 +605,7 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => { let logSql; const result = await this.sequelize.query(`select $1${typeCast} as foo, $2${typeCast} as bar`, { type: this.sequelize.QueryTypes.SELECT, bind: [1, 2], logging(s) { logSql = s;} }); expect(result).to.deep.equal([{ foo: 1, bar: 2 }]); - if (dialect === 'postgres' || dialect === 'sqlite') { + if (['postgres', 'sqlite'].includes(dialect)) { expect(logSql).to.include('$1'); } }); @@ -646,7 +646,7 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => { let logSql; const result = await this.sequelize.query(`select $1${typeCast} as foo, '$$ / $$1' as bar`, { raw: true, bind: [1], logging(s) { logSql = s;} }); expect(result[0]).to.deep.equal([{ foo: 1, bar: '$ / $1' }]); - if (dialect === 'postgres' || dialect === 'sqlite') { + if (['postgres', 'sqlite'].includes(dialect)) { expect(logSql).to.include('$1'); } }); @@ -663,7 +663,7 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => { expect(result[0]).to.deep.equal([{ foo$bar: 1 }]); }); - if (dialect === 'postgres' || dialect === 'sqlite' || dialect === 'mssql') { + if (['postgres', 'sqlite', 'mssql'].includes(dialect)) { it('does not improperly escape arrays of strings bound to named parameters', async function() { const result = await this.sequelize.query('select :stringArray as foo', { raw: true, replacements: { stringArray: ['"string"'] } }); expect(result[0]).to.deep.equal([{ foo: '"string"' }]); diff --git a/test/integration/timezone.test.js b/test/integration/timezone.test.js index 8349288e74db..d20f6671f673 100644 --- a/test/integration/timezone.test.js +++ b/test/integration/timezone.test.js @@ -37,7 +37,7 @@ if (dialect !== 'sqlite') { expect(now1[0].now.getTime()).to.be.closeTo(now2[0].now.getTime(), elapsedQueryTime); }); - if (dialect === 'mysql' || dialect === 'mariadb') { + if (['mysql', 'mariadb'].includes(dialect)) { it('handles existing timestamps', async function() { const NormalUser = this.sequelize.define('user', {}), TimezonedUser = this.sequelizeWithTimezone.define('user', {}); diff --git a/test/integration/transaction.test.js b/test/integration/transaction.test.js index 0bceb3378096..ad3624f38f17 100644 --- a/test/integration/transaction.test.js +++ b/test/integration/transaction.test.js @@ -421,7 +421,7 @@ if (current.dialect.supports.transactions) { } }); - if (dialect === 'mysql' || dialect === 'mariadb') { + if (['mysql', 'mariadb'].includes(dialect)) { describe('deadlock handling', () => { // Create the `Task` table and ensure it's initialized with 2 rows const getAndInitializeTaskModel = async sequelize => { diff --git a/test/unit/configuration.test.js b/test/unit/configuration.test.js index 0cade77cc358..1a0f807a44d2 100644 --- a/test/unit/configuration.test.js +++ b/test/unit/configuration.test.js @@ -145,7 +145,7 @@ describe('Sequelize', () => { if (dialect === 'mysql') { port = 3306; - } else if (dialect === 'postgres' || dialect === 'postgres-native') { + } else if (['postgres', 'postgres-native'].includes(dialect)) { port = 5432; } else { // sqlite has no concept of ports when connecting @@ -185,7 +185,7 @@ describe('Sequelize', () => { expect(sequelizeWithOptions.options.dialectOptions.options.encrypt).to.be.true; expect(sequelizeWithOptions.options.dialectOptions.anotherOption).to.equal('1'); }); - + it('should use query string host if specified', () => { const sequelize = new Sequelize('mysql://localhost:9821/dbname?host=example.com'); diff --git a/test/unit/dialect-module-configuration.test.js b/test/unit/dialect-module-configuration.test.js index e6d05d6f21c6..5310d1c434d7 100644 --- a/test/unit/dialect-module-configuration.test.js +++ b/test/unit/dialect-module-configuration.test.js @@ -31,6 +31,7 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => { case 'mariadb': dialectPath = path.join(dialectPath, 'mariadb'); break; case 'mssql': dialectPath = path.join(dialectPath, 'tedious'); break; case 'sqlite': dialectPath = path.join(dialectPath, 'sqlite3'); break; + case 'snowflake': dialectPath = path.join(dialectPath, 'snowflake-sdk'); break; default: throw Error('Unsupported dialect'); } diff --git a/test/unit/dialects/snowflake/errors.test.js b/test/unit/dialects/snowflake/errors.test.js new file mode 100644 index 000000000000..6de3d13ccf56 --- /dev/null +++ b/test/unit/dialects/snowflake/errors.test.js @@ -0,0 +1,57 @@ +'use strict'; + +const chai = require('chai'); +const expect = chai.expect; +const Support = require('../../support'); +const Sequelize = Support.Sequelize; +const dialect = Support.getTestDialect(); +const queryProto = Support.sequelize.dialect.Query.prototype; + +if (dialect === 'snowflake') { + describe('[SNOWFLAKE Specific] ForeignKeyConstraintError - error message parsing', () => { + it('FK Errors with ` quotation char are parsed correctly', () => { + const fakeErr = new Error('Cannot delete or update a parent row: a foreign key constraint fails (`table`.`brothers`, CONSTRAINT `brothers_ibfk_1` FOREIGN KEY (`personId`) REFERENCES `people` (`id`) ON UPDATE CASCADE).'); + + fakeErr.code = 1451; + + const parsedErr = queryProto.formatError(fakeErr); + + expect(parsedErr).to.be.instanceOf(Sequelize.ForeignKeyConstraintError); + expect(parsedErr.parent).to.equal(fakeErr); + expect(parsedErr.reltype).to.equal('parent'); + expect(parsedErr.table).to.equal('people'); + expect(parsedErr.fields).to.be.an('array').to.deep.equal(['personId']); + expect(parsedErr.value).to.be.undefined; + expect(parsedErr.index).to.equal('brothers_ibfk_1'); + }); + + it('FK Errors with " quotation char are parsed correctly', () => { + const fakeErr = new Error('Cannot delete or update a parent row: a foreign key constraint fails ("table"."brothers", CONSTRAINT "brothers_ibfk_1" FOREIGN KEY ("personId") REFERENCES "people" ("id") ON UPDATE CASCADE).'); + + fakeErr.code = 1451; + + const parsedErr = queryProto.formatError(fakeErr); + + expect(parsedErr).to.be.instanceOf(Sequelize.ForeignKeyConstraintError); + expect(parsedErr.parent).to.equal(fakeErr); + expect(parsedErr.reltype).to.equal('parent'); + expect(parsedErr.table).to.equal('people'); + expect(parsedErr.fields).to.be.an('array').to.deep.equal(['personId']); + expect(parsedErr.value).to.be.undefined; + expect(parsedErr.index).to.equal('brothers_ibfk_1'); + }); + + it('newlines contained in err message are parsed correctly', () => { + const fakeErr = new Error("Duplicate entry '13888888888\r' for key 'num'"); + + fakeErr.code = 1062; + + const parsedErr = queryProto.formatError(fakeErr); + + expect(parsedErr).to.be.instanceOf(Sequelize.UniqueConstraintError); + expect(parsedErr.parent).to.equal(fakeErr); + expect(parsedErr.fields.num).to.equal('13888888888\r'); + }); + + }); +} diff --git a/test/unit/dialects/snowflake/query-generator.test.js b/test/unit/dialects/snowflake/query-generator.test.js new file mode 100644 index 000000000000..a629a58eee77 --- /dev/null +++ b/test/unit/dialects/snowflake/query-generator.test.js @@ -0,0 +1,1493 @@ +'use strict'; + +const chai = require('chai'), + expect = chai.expect, + Support = require('../../support'), + dialect = Support.getTestDialect(), + _ = require('lodash'), + Op = require('sequelize/lib/operators'), + IndexHints = require('sequelize/lib/index-hints'), + QueryGenerator = require('sequelize/lib/dialects/mysql/query-generator'); + +if (dialect === 'snowflake') { + describe('[SNOWFLAKE Specific] QueryGenerator', () => { + const suites = { + createDatabaseQuery: [ + { + arguments: ['myDatabase'], + expectation: 'CREATE DATABASE IF NOT EXISTS "myDatabase";' + }, + { + arguments: ['myDatabase', { charset: 'utf8mb4' }], + expectation: 'CREATE DATABASE IF NOT EXISTS "myDatabase" DEFAULT CHARACTER SET \'utf8mb4\';' + }, + { + arguments: ['myDatabase', { collate: 'utf8mb4_unicode_ci' }], + expectation: 'CREATE DATABASE IF NOT EXISTS "myDatabase" DEFAULT COLLATE \'utf8mb4_unicode_ci\';' + }, + { + arguments: ['myDatabase', { charset: 'utf8mb4', collate: 'utf8mb4_unicode_ci' }], + expectation: 'CREATE DATABASE IF NOT EXISTS "myDatabase" DEFAULT CHARACTER SET \'utf8mb4\' DEFAULT COLLATE \'utf8mb4_unicode_ci\';' + }, + + // Variants when quoteIdentifiers is false + { + arguments: ['myDatabase'], + expectation: 'CREATE DATABASE IF NOT EXISTS myDatabase;', + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: ['myDatabase', { charset: 'utf8mb4' }], + expectation: 'CREATE DATABASE IF NOT EXISTS myDatabase DEFAULT CHARACTER SET \'utf8mb4\';', + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: ['myDatabase', { collate: 'utf8mb4_unicode_ci' }], + expectation: 'CREATE DATABASE IF NOT EXISTS myDatabase DEFAULT COLLATE \'utf8mb4_unicode_ci\';', + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: ['myDatabase', { charset: 'utf8mb4', collate: 'utf8mb4_unicode_ci' }], + expectation: 'CREATE DATABASE IF NOT EXISTS myDatabase DEFAULT CHARACTER SET \'utf8mb4\' DEFAULT COLLATE \'utf8mb4_unicode_ci\';', + context: { options: { quoteIdentifiers: false } } + } + ], + dropDatabaseQuery: [ + { + arguments: ['myDatabase'], + expectation: 'DROP DATABASE IF EXISTS "myDatabase";' + }, + + // Variants when quoteIdentifiers is false + { + arguments: ['myDatabase'], + expectation: 'DROP DATABASE IF EXISTS myDatabase;', + context: { options: { quoteIdentifiers: false } } + } + ], + arithmeticQuery: [ + { + title: 'Should use the plus operator', + arguments: ['+', 'myTable', {}, { foo: 'bar' }, {}, {}], + expectation: 'UPDATE "myTable" SET "foo"="foo"+ \'bar\'' + }, + { + title: 'Should use the plus operator with where clause', + arguments: ['+', 'myTable', { bar: 'biz' }, { foo: 'bar' }, {}, {}], + expectation: 'UPDATE "myTable" SET "foo"="foo"+ \'bar\' WHERE "bar" = \'biz\'' + }, + { + title: 'Should use the minus operator', + arguments: ['-', 'myTable', {}, { foo: 'bar' }, {}, {}], + expectation: 'UPDATE "myTable" SET "foo"="foo"- \'bar\'' + }, + { + title: 'Should use the minus operator with negative value', + arguments: ['-', 'myTable', {}, { foo: -1 }, {}, {}], + expectation: 'UPDATE "myTable" SET "foo"="foo"- -1' + }, + { + title: 'Should use the minus operator with where clause', + arguments: ['-', 'myTable', { bar: 'biz' }, { foo: 'bar' }, {}, {}], + expectation: 'UPDATE "myTable" SET "foo"="foo"- \'bar\' WHERE "bar" = \'biz\'' + }, + + // Variants when quoteIdentifiers is false + { + title: 'Should use the plus operator', + arguments: ['+', 'myTable', {}, { foo: 'bar' }, {}, {}], + expectation: 'UPDATE myTable SET foo=foo+ \'bar\'', + context: { options: { quoteIdentifiers: false } } + }, + { + title: 'Should use the plus operator with where clause', + arguments: ['+', 'myTable', { bar: 'biz' }, { foo: 'bar' }, {}, {}], + expectation: 'UPDATE myTable SET foo=foo+ \'bar\' WHERE bar = \'biz\'', + context: { options: { quoteIdentifiers: false } } + }, + { + title: 'Should use the minus operator', + arguments: ['-', 'myTable', {}, { foo: 'bar' }, {}, {}], + expectation: 'UPDATE myTable SET foo=foo- \'bar\'', + context: { options: { quoteIdentifiers: false } } + }, + { + title: 'Should use the minus operator with negative value', + arguments: ['-', 'myTable', {}, { foo: -1 }, {}, {}], + expectation: 'UPDATE myTable SET foo=foo- -1', + context: { options: { quoteIdentifiers: false } } + }, + { + title: 'Should use the minus operator with where clause', + arguments: ['-', 'myTable', { bar: 'biz' }, { foo: 'bar' }, {}, {}], + expectation: 'UPDATE myTable SET foo=foo- \'bar\' WHERE bar = \'biz\'', + context: { options: { quoteIdentifiers: false } } + } + ], + attributesToSQL: [ + { + arguments: [{ id: 'INTEGER' }], + expectation: { id: 'INTEGER' } + }, + { + arguments: [{ id: 'INTEGER', foo: 'VARCHAR(255)' }], + expectation: { id: 'INTEGER', foo: 'VARCHAR(255)' } + }, + { + arguments: [{ id: { type: 'INTEGER' } }], + expectation: { id: 'INTEGER' } + }, + { + arguments: [{ id: { type: 'INTEGER', allowNull: false } }], + expectation: { id: 'INTEGER NOT NULL' } + }, + { + arguments: [{ id: { type: 'INTEGER', allowNull: true } }], + expectation: { id: 'INTEGER' } + }, + { + arguments: [{ id: { type: 'INTEGER', primaryKey: true, autoIncrement: true } }], + expectation: { id: 'INTEGER auto_increment PRIMARY KEY' } + }, + { + arguments: [{ id: { type: 'INTEGER', defaultValue: 0 } }], + expectation: { id: 'INTEGER DEFAULT 0' } + }, + { + title: 'Add column level comment', + arguments: [{ id: { type: 'INTEGER', comment: 'Test' } }], + expectation: { id: 'INTEGER COMMENT \'Test\'' } + }, + { + arguments: [{ id: { type: 'INTEGER', unique: true } }], + expectation: { id: 'INTEGER UNIQUE' } + }, + { + arguments: [{ id: { type: 'INTEGER', after: 'Bar' } }], + expectation: { id: 'INTEGER AFTER "Bar"' } + }, + // No Default Values allowed for certain types + { + title: 'No Default value for SNOWFLAKE BLOB allowed', + arguments: [{ id: { type: 'BLOB', defaultValue: [] } }], + expectation: { id: 'BLOB' } + }, + { + title: 'No Default value for SNOWFLAKE TEXT allowed', + arguments: [{ id: { type: 'TEXT', defaultValue: [] } }], + expectation: { id: 'TEXT' } + }, + { + title: 'No Default value for SNOWFLAKE GEOMETRY allowed', + arguments: [{ id: { type: 'GEOMETRY', defaultValue: [] } }], + expectation: { id: 'GEOMETRY' } + }, + { + title: 'No Default value for SNOWFLAKE JSON allowed', + arguments: [{ id: { type: 'JSON', defaultValue: [] } }], + expectation: { id: 'JSON' } + }, + // New references style + { + arguments: [{ id: { type: 'INTEGER', references: { model: 'Bar' } } }], + expectation: { id: 'INTEGER REFERENCES "Bar" ("id")' } + }, + { + arguments: [{ id: { type: 'INTEGER', references: { model: 'Bar', key: 'pk' } } }], + expectation: { id: 'INTEGER REFERENCES "Bar" ("pk")' } + }, + { + arguments: [{ id: { type: 'INTEGER', references: { model: 'Bar' }, onDelete: 'CASCADE' } }], + expectation: { id: 'INTEGER REFERENCES "Bar" ("id") ON DELETE CASCADE' } + }, + { + arguments: [{ id: { type: 'INTEGER', references: { model: 'Bar' }, onUpdate: 'RESTRICT' } }], + expectation: { id: 'INTEGER REFERENCES "Bar" ("id") ON UPDATE RESTRICT' } + }, + { + arguments: [{ id: { type: 'INTEGER', allowNull: false, autoIncrement: true, defaultValue: 1, references: { model: 'Bar' }, onDelete: 'CASCADE', onUpdate: 'RESTRICT' } }], + expectation: { id: 'INTEGER NOT NULL auto_increment DEFAULT 1 REFERENCES "Bar" ("id") ON DELETE CASCADE ON UPDATE RESTRICT' } + }, + + // Variants when quoteIdentifiers is false + { + arguments: [{ id: { type: 'INTEGER', references: { model: 'Bar' } } }], + expectation: { id: 'INTEGER REFERENCES Bar (id)' }, + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: [{ id: { type: 'INTEGER', references: { model: 'Bar', key: 'pk' } } }], + expectation: { id: 'INTEGER REFERENCES Bar (pk)' }, + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: [{ id: { type: 'INTEGER', references: { model: 'Bar' }, onDelete: 'CASCADE' } }], + expectation: { id: 'INTEGER REFERENCES Bar (id) ON DELETE CASCADE' }, + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: [{ id: { type: 'INTEGER', references: { model: 'Bar' }, onUpdate: 'RESTRICT' } }], + expectation: { id: 'INTEGER REFERENCES Bar (id) ON UPDATE RESTRICT' }, + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: [{ id: { type: 'INTEGER', allowNull: false, autoIncrement: true, defaultValue: 1, references: { model: 'Bar' }, onDelete: 'CASCADE', onUpdate: 'RESTRICT' } }], + expectation: { id: 'INTEGER NOT NULL auto_increment DEFAULT 1 REFERENCES Bar (id) ON DELETE CASCADE ON UPDATE RESTRICT' }, + context: { options: { quoteIdentifiers: false } } + } + ], + + createTableQuery: [ + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)' }], + expectation: 'CREATE TABLE IF NOT EXISTS "myTable" ("title" VARCHAR(255), "name" VARCHAR(255)) ENGINE=InnoDB;' + }, + { + arguments: ['myTable', { data: 'BLOB' }], + expectation: 'CREATE TABLE IF NOT EXISTS "myTable" ("data" BLOB) ENGINE=InnoDB;' + }, + { + arguments: ['myTable', { data: 'LONGBLOB' }], + expectation: 'CREATE TABLE IF NOT EXISTS "myTable" ("data" LONGBLOB) ENGINE=InnoDB;' + }, + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)' }, { engine: 'MyISAM' }], + expectation: 'CREATE TABLE IF NOT EXISTS "myTable" ("title" VARCHAR(255), "name" VARCHAR(255)) ENGINE=MyISAM;' + }, + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)' }, { charset: 'utf8', collate: 'utf8_unicode_ci' }], + expectation: 'CREATE TABLE IF NOT EXISTS "myTable" ("title" VARCHAR(255), "name" VARCHAR(255)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;' + }, + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)' }, { charset: 'latin1' }], + expectation: 'CREATE TABLE IF NOT EXISTS "myTable" ("title" VARCHAR(255), "name" VARCHAR(255)) ENGINE=InnoDB DEFAULT CHARSET=latin1;' + }, + { + arguments: ['myTable', { title: 'ENUM("A", "B", "C")', name: 'VARCHAR(255)' }, { charset: 'latin1' }], + expectation: 'CREATE TABLE IF NOT EXISTS "myTable" ("title" ENUM("A", "B", "C"), "name" VARCHAR(255)) ENGINE=InnoDB DEFAULT CHARSET=latin1;' + }, + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)' }, { rowFormat: 'default' }], + expectation: 'CREATE TABLE IF NOT EXISTS "myTable" ("title" VARCHAR(255), "name" VARCHAR(255)) ENGINE=InnoDB ROW_FORMAT=default;' + }, + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)', id: 'INTEGER PRIMARY KEY' }], + expectation: 'CREATE TABLE IF NOT EXISTS "myTable" ("title" VARCHAR(255), "name" VARCHAR(255), "id" INTEGER , PRIMARY KEY ("id")) ENGINE=InnoDB;' + }, + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)', otherId: 'INTEGER REFERENCES "otherTable" ("id") ON DELETE CASCADE ON UPDATE NO ACTION' }], + expectation: 'CREATE TABLE IF NOT EXISTS "myTable" ("title" VARCHAR(255), "name" VARCHAR(255), "otherId" INTEGER, FOREIGN KEY ("otherId") REFERENCES "otherTable" ("id") ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB;' + }, + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)' }, { uniqueKeys: [{ fields: ['title', 'name'], customIndex: true }] }], + expectation: 'CREATE TABLE IF NOT EXISTS "myTable" ("title" VARCHAR(255), "name" VARCHAR(255), UNIQUE "uniq_myTable_title_name" ("title", "name")) ENGINE=InnoDB;' + }, + { + arguments: ['myTable', { id: 'INTEGER auto_increment PRIMARY KEY' }, { initialAutoIncrement: 1000001 }], + expectation: 'CREATE TABLE IF NOT EXISTS "myTable" ("id" INTEGER auto_increment , PRIMARY KEY ("id")) ENGINE=InnoDB AUTO_INCREMENT=1000001;' + }, + + // Variants when quoteIdentifiers is false + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)' }], + expectation: 'CREATE TABLE IF NOT EXISTS myTable (title VARCHAR(255), name VARCHAR(255)) ENGINE=InnoDB;', + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: ['myTable', { data: 'BLOB' }], + expectation: 'CREATE TABLE IF NOT EXISTS myTable (data BLOB) ENGINE=InnoDB;', + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: ['myTable', { data: 'LONGBLOB' }], + expectation: 'CREATE TABLE IF NOT EXISTS myTable (data LONGBLOB) ENGINE=InnoDB;', + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)' }, { engine: 'MyISAM' }], + expectation: 'CREATE TABLE IF NOT EXISTS myTable (title VARCHAR(255), name VARCHAR(255)) ENGINE=MyISAM;', + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)' }, { charset: 'utf8', collate: 'utf8_unicode_ci' }], + expectation: 'CREATE TABLE IF NOT EXISTS myTable (title VARCHAR(255), name VARCHAR(255)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;', + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)' }, { charset: 'latin1' }], + expectation: 'CREATE TABLE IF NOT EXISTS myTable (title VARCHAR(255), name VARCHAR(255)) ENGINE=InnoDB DEFAULT CHARSET=latin1;', + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: ['myTable', { title: 'ENUM("A", "B", "C")', name: 'VARCHAR(255)' }, { charset: 'latin1' }], + expectation: 'CREATE TABLE IF NOT EXISTS myTable (title ENUM("A", "B", "C"), name VARCHAR(255)) ENGINE=InnoDB DEFAULT CHARSET=latin1;', + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)' }, { rowFormat: 'default' }], + expectation: 'CREATE TABLE IF NOT EXISTS myTable (title VARCHAR(255), name VARCHAR(255)) ENGINE=InnoDB ROW_FORMAT=default;', + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)', id: 'INTEGER PRIMARY KEY' }], + expectation: 'CREATE TABLE IF NOT EXISTS myTable (title VARCHAR(255), name VARCHAR(255), id INTEGER , PRIMARY KEY (id)) ENGINE=InnoDB;', + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)', otherId: 'INTEGER REFERENCES otherTable (id) ON DELETE CASCADE ON UPDATE NO ACTION' }], + expectation: 'CREATE TABLE IF NOT EXISTS myTable (title VARCHAR(255), name VARCHAR(255), otherId INTEGER, FOREIGN KEY (otherId) REFERENCES otherTable (id) ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB;', + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: ['myTable', { title: 'VARCHAR(255)', name: 'VARCHAR(255)' }, { uniqueKeys: [{ fields: ['title', 'name'], customIndex: true }] }], + expectation: 'CREATE TABLE IF NOT EXISTS myTable (title VARCHAR(255), name VARCHAR(255), UNIQUE uniq_myTable_title_name (title, name)) ENGINE=InnoDB;', + context: { options: { quoteIdentifiers: false } } + }, + { + arguments: ['myTable', { id: 'INTEGER auto_increment PRIMARY KEY' }, { initialAutoIncrement: 1000001 }], + expectation: 'CREATE TABLE IF NOT EXISTS myTable (id INTEGER auto_increment , PRIMARY KEY (id)) ENGINE=InnoDB AUTO_INCREMENT=1000001;', + context: { options: { quoteIdentifiers: false } } + } + ], + + dropTableQuery: [ + { + arguments: ['myTable'], + expectation: 'DROP TABLE IF EXISTS "myTable";' + }, + + // Variants when quoteIdentifiers is false + { + arguments: ['myTable'], + expectation: 'DROP TABLE IF EXISTS myTable;', + context: { options: { quoteIdentifiers: false } } + } + ], + + selectQuery: [ + { + arguments: ['myTable'], + expectation: 'SELECT * FROM "myTable";', + context: QueryGenerator + }, { + arguments: ['myTable', { attributes: ['id', 'name'] }], + expectation: 'SELECT "id", "name" FROM "myTable";', + context: QueryGenerator + }, { + arguments: ['myTable', { where: { id: 2 } }], + expectation: 'SELECT * FROM "myTable" WHERE "myTable"."id" = 2;', + context: QueryGenerator + }, { + arguments: ['myTable', { where: { name: 'foo' } }], + expectation: 'SELECT * FROM "myTable" WHERE "myTable"."name" = \'foo\';', + context: QueryGenerator + }, { + arguments: ['myTable', { where: { name: "foo';DROP TABLE myTable;" } }], + expectation: 'SELECT * FROM "myTable" WHERE "myTable"."name" = \'foo\'\';DROP TABLE myTable;\';', + context: QueryGenerator + }, { + arguments: ['myTable', { where: 2 }], + expectation: 'SELECT * FROM "myTable" WHERE "myTable"."id" = 2;', + context: QueryGenerator + }, { + arguments: ['foo', { attributes: [['count(*)', 'count']] }], + expectation: 'SELECT count(*) AS "count" FROM "foo";', + context: QueryGenerator + }, { + arguments: ['myTable', { order: ['id'] }], + expectation: 'SELECT * FROM "myTable" ORDER BY "id";', + context: QueryGenerator + }, { + arguments: ['myTable', { order: ['id', 'DESC'] }], + expectation: 'SELECT * FROM "myTable" ORDER BY "id", "DESC";', + context: QueryGenerator + }, { + arguments: ['myTable', { order: ['myTable.id'] }], + expectation: 'SELECT * FROM "myTable" ORDER BY "myTable"."id";', + context: QueryGenerator + }, { + arguments: ['myTable', { order: [['myTable.id', 'DESC']] }], + expectation: 'SELECT * FROM "myTable" ORDER BY "myTable"."id" DESC;', + context: QueryGenerator + }, { + arguments: ['myTable', { order: [['id', 'DESC']] }, function(sequelize) {return sequelize.define('myTable', {});}], + expectation: 'SELECT * FROM "myTable" AS "myTable" ORDER BY "myTable"."id" DESC;', + context: QueryGenerator, + needsSequelize: true + }, { + arguments: ['myTable', { order: [['id', 'DESC'], ['name']] }, function(sequelize) {return sequelize.define('myTable', {});}], + expectation: 'SELECT * FROM "myTable" AS "myTable" ORDER BY "myTable"."id" DESC, "myTable"."name";', + context: QueryGenerator, + needsSequelize: true + }, { + title: 'functions can take functions as arguments', + arguments: ['myTable', function(sequelize) { + return { + order: [[sequelize.fn('f1', sequelize.fn('f2', sequelize.col('id'))), 'DESC']] + }; + }], + expectation: 'SELECT * FROM "myTable" ORDER BY f1(f2("id")) DESC;', + context: QueryGenerator, + needsSequelize: true + }, { + title: 'functions can take all types as arguments', + arguments: ['myTable', function(sequelize) { + return { + order: [ + [sequelize.fn('f1', sequelize.col('myTable.id')), 'DESC'], + [sequelize.fn('f2', 12, 'lalala', new Date(Date.UTC(2011, 2, 27, 10, 1, 55))), 'ASC'] + ] + }; + }], + expectation: 'SELECT * FROM "myTable" ORDER BY f1("myTable"."id") DESC, f2(12, \'lalala\', \'2011-03-27 10:01:55\') ASC;', + context: QueryGenerator, + needsSequelize: true + }, { + title: 'sequelize.where with .fn as attribute and default comparator', + arguments: ['myTable', function(sequelize) { + return { + where: sequelize.and( + sequelize.where(sequelize.fn('LOWER', sequelize.col('user.name')), 'jan'), + { type: 1 } + ) + }; + }], + expectation: 'SELECT * FROM "myTable" WHERE (LOWER("user"."name") = \'jan\' AND "myTable"."type" = 1);', + context: QueryGenerator, + needsSequelize: true + }, { + title: 'sequelize.where with .fn as attribute and LIKE comparator', + arguments: ['myTable', function(sequelize) { + return { + where: sequelize.and( + sequelize.where(sequelize.fn('LOWER', sequelize.col('user.name')), 'LIKE', '%t%'), + { type: 1 } + ) + }; + }], + expectation: 'SELECT * FROM "myTable" WHERE (LOWER("user"."name") LIKE \'%t%\' AND "myTable"."type" = 1);', + context: QueryGenerator, + needsSequelize: true + }, { + title: 'single string argument should be quoted', + arguments: ['myTable', { group: 'name' }], + expectation: 'SELECT * FROM "myTable" GROUP BY "name";', + context: QueryGenerator + }, { + arguments: ['myTable', { group: ['name'] }], + expectation: 'SELECT * FROM "myTable" GROUP BY "name";', + context: QueryGenerator + }, { + title: 'functions work for group by', + arguments: ['myTable', function(sequelize) { + return { + group: [sequelize.fn('YEAR', sequelize.col('createdAt'))] + }; + }], + expectation: 'SELECT * FROM "myTable" GROUP BY YEAR("createdAt");', + context: QueryGenerator, + needsSequelize: true + }, { + title: 'It is possible to mix sequelize.fn and string arguments to group by', + arguments: ['myTable', function(sequelize) { + return { + group: [sequelize.fn('YEAR', sequelize.col('createdAt')), 'title'] + }; + }], + expectation: 'SELECT * FROM "myTable" GROUP BY YEAR("createdAt"), "title";', + context: QueryGenerator, + needsSequelize: true + }, { + arguments: ['myTable', { group: 'name', order: [['id', 'DESC']] }], + expectation: 'SELECT * FROM "myTable" GROUP BY "name" ORDER BY "id" DESC;', + context: QueryGenerator + }, { + title: 'HAVING clause works with where-like hash', + arguments: ['myTable', function(sequelize) { + return { + attributes: ['*', [sequelize.fn('YEAR', sequelize.col('createdAt')), 'creationYear']], + group: ['creationYear', 'title'], + having: { creationYear: { [Op.gt]: 2002 } } + }; + }], + expectation: 'SELECT *, YEAR("createdAt") AS "creationYear" FROM "myTable" GROUP BY "creationYear", "title" HAVING "creationYear" > 2002;', + context: QueryGenerator, + needsSequelize: true + }, { + title: 'Combination of sequelize.fn, sequelize.col and { in: ... }', + arguments: ['myTable', function(sequelize) { + return { + where: sequelize.and( + { archived: null }, + sequelize.where(sequelize.fn('COALESCE', sequelize.col('place_type_codename'), sequelize.col('announcement_type_codename')), { [Op.in]: ['Lost', 'Found'] }) + ) + }; + }], + expectation: 'SELECT * FROM "myTable" WHERE ("myTable"."archived" IS NULL AND COALESCE("place_type_codename", "announcement_type_codename") IN (\'Lost\', \'Found\'));', + context: QueryGenerator, + needsSequelize: true + }, { + arguments: ['myTable', { limit: 10 }], + expectation: 'SELECT * FROM "myTable" LIMIT 10;', + context: QueryGenerator + }, { + arguments: ['myTable', { limit: 10, offset: 2 }], + expectation: 'SELECT * FROM "myTable" LIMIT 2, 10;', + context: QueryGenerator + }, { + title: 'uses default limit if only offset is specified', + arguments: ['myTable', { offset: 2 }], + expectation: 'SELECT * FROM "myTable" LIMIT 2, 10000000000000;', + context: QueryGenerator + }, { + title: 'uses limit 0', + arguments: ['myTable', { limit: 0 }], + expectation: 'SELECT * FROM "myTable" LIMIT 0;', + context: QueryGenerator + }, { + title: 'uses offset 0', + arguments: ['myTable', { offset: 0 }], + expectation: 'SELECT * FROM "myTable" LIMIT 0, 10000000000000;', + context: QueryGenerator + }, { + title: 'multiple where arguments', + arguments: ['myTable', { where: { boat: 'canoe', weather: 'cold' } }], + expectation: 'SELECT * FROM "myTable" WHERE "myTable"."boat" = \'canoe\' AND "myTable"."weather" = \'cold\';', + context: QueryGenerator + }, { + title: 'no where arguments (object)', + arguments: ['myTable', { where: {} }], + expectation: 'SELECT * FROM "myTable";', + context: QueryGenerator + }, { + title: 'no where arguments (string)', + arguments: ['myTable', { where: [''] }], + expectation: 'SELECT * FROM "myTable" WHERE 1=1;', + context: QueryGenerator + }, { + title: 'no where arguments (null)', + arguments: ['myTable', { where: null }], + expectation: 'SELECT * FROM "myTable";', + context: QueryGenerator + }, { + title: 'buffer as where argument', + arguments: ['myTable', { where: { field: Buffer.from('Sequelize') } }], + expectation: 'SELECT * FROM "myTable" WHERE "myTable"."field" = X\'53657175656c697a65\';', + context: QueryGenerator + }, { + title: 'use != if ne !== null', + arguments: ['myTable', { where: { field: { [Op.ne]: 0 } } }], + expectation: 'SELECT * FROM "myTable" WHERE "myTable"."field" != 0;', + context: QueryGenerator + }, { + title: 'use IS NOT if ne === null', + arguments: ['myTable', { where: { field: { [Op.ne]: null } } }], + expectation: 'SELECT * FROM "myTable" WHERE "myTable"."field" IS NOT NULL;', + context: QueryGenerator + }, { + title: 'use IS NOT if not === BOOLEAN', + arguments: ['myTable', { where: { field: { [Op.not]: true } } }], + expectation: 'SELECT * FROM "myTable" WHERE "myTable"."field" IS NOT true;', + context: QueryGenerator + }, { + title: 'use != if not !== BOOLEAN', + arguments: ['myTable', { where: { field: { [Op.not]: 3 } } }], + expectation: 'SELECT * FROM "myTable" WHERE "myTable"."field" != 3;', + context: QueryGenerator + }, { + title: 'Regular Expression in where clause', + arguments: ['myTable', { where: { field: { [Op.regexp]: '^[h|a|t]' } } }], + expectation: 'SELECT * FROM "myTable" WHERE "myTable"."field" REGEXP \'^[h|a|t]\';', + context: QueryGenerator + }, { + title: 'Regular Expression negation in where clause', + arguments: ['myTable', { where: { field: { [Op.notRegexp]: '^[h|a|t]' } } }], + expectation: 'SELECT * FROM "myTable" WHERE "myTable"."field" NOT REGEXP \'^[h|a|t]\';', + context: QueryGenerator + }, { + title: 'Empty having', + arguments: ['myTable', function() { + return { + having: {} + }; + }], + expectation: 'SELECT * FROM "myTable";', + context: QueryGenerator, + needsSequelize: true + }, { + title: 'Having in subquery', + arguments: ['myTable', function() { + return { + subQuery: true, + tableAs: 'test', + having: { creationYear: { [Op.gt]: 2002 } } + }; + }], + expectation: 'SELECT "test".* FROM (SELECT * FROM "myTable" AS "test" HAVING "creationYear" > 2002) AS "test";', + context: QueryGenerator, + needsSequelize: true + }, { + title: 'Contains fields with "." characters.', + arguments: ['myTable', { + attributes: ['foo.bar.baz'], + model: { + rawAttributes: { + 'foo.bar.baz': {} + } + } + }], + expectation: 'SELECT "foo.bar.baz" FROM "myTable";', + context: QueryGenerator + }, + + // Variants when quoteIdentifiers is false + { + arguments: ['myTable'], + expectation: 'SELECT * FROM myTable;', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { attributes: ['id', 'name'] }], + expectation: 'SELECT id, name FROM myTable;', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { where: { id: 2 } }], + expectation: 'SELECT * FROM myTable WHERE myTable.id = 2;', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { where: { name: 'foo' } }], + expectation: 'SELECT * FROM myTable WHERE myTable.name = \'foo\';', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { where: { name: "foo';DROP TABLE myTable;" } }], + expectation: 'SELECT * FROM myTable WHERE myTable.name = \'foo\'\';DROP TABLE myTable;\';', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { where: 2 }], + expectation: 'SELECT * FROM myTable WHERE myTable.id = 2;', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['foo', { attributes: [['count(*)', 'count']] }], + expectation: 'SELECT count(*) AS count FROM foo;', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { order: ['id'] }], + expectation: 'SELECT * FROM myTable ORDER BY id;', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { order: ['id', 'DESC'] }], + expectation: 'SELECT * FROM myTable ORDER BY id, DESC;', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { order: ['myTable.id'] }], + expectation: 'SELECT * FROM myTable ORDER BY myTable.id;', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { order: [['myTable.id', 'DESC']] }], + expectation: 'SELECT * FROM myTable ORDER BY myTable.id DESC;', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { order: [['id', 'DESC']] }, function(sequelize) {return sequelize.define('myTable', {});}], + expectation: 'SELECT * FROM myTable AS myTable ORDER BY myTable.id DESC;', + context: { options: { quoteIdentifiers: false } }, + needsSequelize: true + }, { + arguments: ['myTable', { order: [['id', 'DESC'], ['name']] }, function(sequelize) {return sequelize.define('myTable', {});}], + expectation: 'SELECT * FROM myTable AS myTable ORDER BY myTable.id DESC, myTable.name;', + context: { options: { quoteIdentifiers: false } }, + needsSequelize: true + }, { + title: 'functions can take functions as arguments', + arguments: ['myTable', function(sequelize) { + return { + order: [[sequelize.fn('f1', sequelize.fn('f2', sequelize.col('id'))), 'DESC']] + }; + }], + expectation: 'SELECT * FROM myTable ORDER BY f1(f2(id)) DESC;', + context: { options: { quoteIdentifiers: false } }, + needsSequelize: true + }, { + title: 'functions can take all types as arguments', + arguments: ['myTable', function(sequelize) { + return { + order: [ + [sequelize.fn('f1', sequelize.col('myTable.id')), 'DESC'], + [sequelize.fn('f2', 12, 'lalala', new Date(Date.UTC(2011, 2, 27, 10, 1, 55))), 'ASC'] + ] + }; + }], + expectation: 'SELECT * FROM myTable ORDER BY f1(myTable.id) DESC, f2(12, \'lalala\', \'2011-03-27 10:01:55\') ASC;', + context: { options: { quoteIdentifiers: false } }, + needsSequelize: true + }, { + title: 'sequelize.where with .fn as attribute and default comparator', + arguments: ['myTable', function(sequelize) { + return { + where: sequelize.and( + sequelize.where(sequelize.fn('LOWER', sequelize.col('user.name')), 'jan'), + { type: 1 } + ) + }; + }], + expectation: 'SELECT * FROM myTable WHERE (LOWER(user.name) = \'jan\' AND myTable.type = 1);', + context: { options: { quoteIdentifiers: false } }, + needsSequelize: true + }, { + title: 'sequelize.where with .fn as attribute and LIKE comparator', + arguments: ['myTable', function(sequelize) { + return { + where: sequelize.and( + sequelize.where(sequelize.fn('LOWER', sequelize.col('user.name')), 'LIKE', '%t%'), + { type: 1 } + ) + }; + }], + expectation: 'SELECT * FROM myTable WHERE (LOWER(user.name) LIKE \'%t%\' AND myTable.type = 1);', + context: { options: { quoteIdentifiers: false } }, + needsSequelize: true + }, { + title: 'single string argument should be quoted', + arguments: ['myTable', { group: 'name' }], + expectation: 'SELECT * FROM myTable GROUP BY name;', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { group: ['name'] }], + expectation: 'SELECT * FROM myTable GROUP BY name;', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'functions work for group by', + arguments: ['myTable', function(sequelize) { + return { + group: [sequelize.fn('YEAR', sequelize.col('createdAt'))] + }; + }], + expectation: 'SELECT * FROM myTable GROUP BY YEAR(createdAt);', + context: { options: { quoteIdentifiers: false } }, + needsSequelize: true + }, { + title: 'It is possible to mix sequelize.fn and string arguments to group by', + arguments: ['myTable', function(sequelize) { + return { + group: [sequelize.fn('YEAR', sequelize.col('createdAt')), 'title'] + }; + }], + expectation: 'SELECT * FROM myTable GROUP BY YEAR(createdAt), title;', + context: { options: { quoteIdentifiers: false } }, + needsSequelize: true + }, { + arguments: ['myTable', { group: 'name', order: [['id', 'DESC']] }], + expectation: 'SELECT * FROM myTable GROUP BY name ORDER BY id DESC;', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'HAVING clause works with where-like hash', + arguments: ['myTable', function(sequelize) { + return { + attributes: ['*', [sequelize.fn('YEAR', sequelize.col('createdAt')), 'creationYear']], + group: ['creationYear', 'title'], + having: { creationYear: { [Op.gt]: 2002 } } + }; + }], + expectation: 'SELECT *, YEAR(createdAt) AS creationYear FROM myTable GROUP BY creationYear, title HAVING creationYear > 2002;', + context: { options: { quoteIdentifiers: false } }, + needsSequelize: true + }, { + title: 'Combination of sequelize.fn, sequelize.col and { in: ... }', + arguments: ['myTable', function(sequelize) { + return { + where: sequelize.and( + { archived: null }, + sequelize.where(sequelize.fn('COALESCE', sequelize.col('place_type_codename'), sequelize.col('announcement_type_codename')), { [Op.in]: ['Lost', 'Found'] }) + ) + }; + }], + expectation: 'SELECT * FROM myTable WHERE (myTable.archived IS NULL AND COALESCE(place_type_codename, announcement_type_codename) IN (\'Lost\', \'Found\'));', + context: { options: { quoteIdentifiers: false } }, + needsSequelize: true + }, { + arguments: ['myTable', { limit: 10 }], + expectation: 'SELECT * FROM myTable LIMIT 10;', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { limit: 10, offset: 2 }], + expectation: 'SELECT * FROM myTable LIMIT 2, 10;', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'uses default limit if only offset is specified', + arguments: ['myTable', { offset: 2 }], + expectation: 'SELECT * FROM myTable LIMIT 2, 10000000000000;', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'uses limit 0', + arguments: ['myTable', { limit: 0 }], + expectation: 'SELECT * FROM myTable LIMIT 0;', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'uses offset 0', + arguments: ['myTable', { offset: 0 }], + expectation: 'SELECT * FROM myTable LIMIT 0, 10000000000000;', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'multiple where arguments', + arguments: ['myTable', { where: { boat: 'canoe', weather: 'cold' } }], + expectation: 'SELECT * FROM myTable WHERE myTable.boat = \'canoe\' AND myTable.weather = \'cold\';', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'no where arguments (object)', + arguments: ['myTable', { where: {} }], + expectation: 'SELECT * FROM myTable;', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'no where arguments (string)', + arguments: ['myTable', { where: [''] }], + expectation: 'SELECT * FROM myTable WHERE 1=1;', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'no where arguments (null)', + arguments: ['myTable', { where: null }], + expectation: 'SELECT * FROM myTable;', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'buffer as where argument', + arguments: ['myTable', { where: { field: Buffer.from('Sequelize') } }], + expectation: 'SELECT * FROM myTable WHERE myTable.field = X\'53657175656c697a65\';', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'use != if ne !== null', + arguments: ['myTable', { where: { field: { [Op.ne]: 0 } } }], + expectation: 'SELECT * FROM myTable WHERE myTable.field != 0;', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'use IS NOT if ne === null', + arguments: ['myTable', { where: { field: { [Op.ne]: null } } }], + expectation: 'SELECT * FROM myTable WHERE myTable.field IS NOT NULL;', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'use IS NOT if not === BOOLEAN', + arguments: ['myTable', { where: { field: { [Op.not]: true } } }], + expectation: 'SELECT * FROM myTable WHERE myTable.field IS NOT true;', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'use != if not !== BOOLEAN', + arguments: ['myTable', { where: { field: { [Op.not]: 3 } } }], + expectation: 'SELECT * FROM myTable WHERE myTable.field != 3;', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'Regular Expression in where clause', + arguments: ['myTable', { where: { field: { [Op.regexp]: '^[h|a|t]' } } }], + expectation: 'SELECT * FROM myTable WHERE myTable.field REGEXP \'^[h|a|t]\';', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'Regular Expression negation in where clause', + arguments: ['myTable', { where: { field: { [Op.notRegexp]: '^[h|a|t]' } } }], + expectation: 'SELECT * FROM myTable WHERE myTable.field NOT REGEXP \'^[h|a|t]\';', + context: { options: { quoteIdentifiers: false } } + }, { + title: 'Empty having', + arguments: ['myTable', function() { + return { + having: {} + }; + }], + expectation: 'SELECT * FROM myTable;', + context: { options: { quoteIdentifiers: false } }, + needsSequelize: true + }, { + title: 'Having in subquery', + arguments: ['myTable', function() { + return { + subQuery: true, + tableAs: 'test', + having: { creationYear: { [Op.gt]: 2002 } } + }; + }], + expectation: 'SELECT test.* FROM (SELECT * FROM myTable AS test HAVING creationYear > 2002) AS test;', + context: { options: { quoteIdentifiers: false } }, + needsSequelize: true + }, { + title: 'Contains fields with "." characters.', + arguments: ['myTable', { + attributes: ['foo.bar.baz'], + model: { + rawAttributes: { + 'foo.bar.baz': {} + } + } + }], + expectation: 'SELECT "foo.bar.baz" FROM myTable;', + context: { options: { quoteIdentifiers: false } } + } + ], + + insertQuery: [ + { + arguments: ['myTable', { name: 'foo' }], + expectation: { + query: 'INSERT INTO "myTable" ("name") VALUES ($1);', + bind: ['foo'] + } + }, { + arguments: ['myTable', { name: "foo';DROP TABLE myTable;" }], + expectation: { + query: 'INSERT INTO "myTable" ("name") VALUES ($1);', + bind: ["foo';DROP TABLE myTable;"] + } + }, { + arguments: ['myTable', { name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55)) }], + expectation: { + query: 'INSERT INTO "myTable" ("name","birthday") VALUES ($1,$2);', + bind: ['foo', new Date(Date.UTC(2011, 2, 27, 10, 1, 55))] + } + }, { + arguments: ['myTable', { name: 'foo', foo: 1 }], + expectation: { + query: 'INSERT INTO "myTable" ("name","foo") VALUES ($1,$2);', + bind: ['foo', 1] + } + }, { + arguments: ['myTable', { data: Buffer.from('Sequelize') }], + expectation: { + query: 'INSERT INTO "myTable" ("data") VALUES ($1);', + bind: [Buffer.from('Sequelize')] + } + }, { + arguments: ['myTable', { name: 'foo', foo: 1, nullValue: null }], + expectation: { + query: 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES ($1,$2,$3);', + bind: ['foo', 1, null] + } + }, { + arguments: ['myTable', { name: 'foo', foo: 1, nullValue: null }], + expectation: { + query: 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES ($1,$2,$3);', + bind: ['foo', 1, null] + }, + context: { options: { omitNull: false } } + }, { + arguments: ['myTable', { name: 'foo', foo: 1, nullValue: null }], + expectation: { + query: 'INSERT INTO "myTable" ("name","foo") VALUES ($1,$2);', + bind: ['foo', 1] + }, + context: { options: { omitNull: true } } + }, { + arguments: ['myTable', { name: 'foo', foo: 1, nullValue: undefined }], + expectation: { + query: 'INSERT INTO "myTable" ("name","foo") VALUES ($1,$2);', + bind: ['foo', 1] + }, + context: { options: { omitNull: true } } + }, { + arguments: ['myTable', { foo: false }], + expectation: { + query: 'INSERT INTO "myTable" ("foo") VALUES ($1);', + bind: [false] + } + }, { + arguments: ['myTable', { foo: true }], + expectation: { + query: 'INSERT INTO "myTable" ("foo") VALUES ($1);', + bind: [true] + } + }, { + arguments: ['myTable', function(sequelize) { + return { + foo: sequelize.fn('NOW') + }; + }], + expectation: { + query: 'INSERT INTO "myTable" ("foo") VALUES (NOW());', + bind: [] + }, + needsSequelize: true + }, + + // Variants when quoteIdentifiers is false + { + arguments: ['myTable', { name: 'foo' }], + expectation: { + query: 'INSERT INTO myTable (name) VALUES ($1);', + bind: ['foo'] + }, + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { name: "foo';DROP TABLE myTable;" }], + expectation: { + query: 'INSERT INTO myTable (name) VALUES ($1);', + bind: ["foo';DROP TABLE myTable;"] + }, + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55)) }], + expectation: { + query: 'INSERT INTO myTable (name,birthday) VALUES ($1,$2);', + bind: ['foo', new Date(Date.UTC(2011, 2, 27, 10, 1, 55))] + }, + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { name: 'foo', foo: 1 }], + expectation: { + query: 'INSERT INTO myTable (name,foo) VALUES ($1,$2);', + bind: ['foo', 1] + }, + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { data: Buffer.from('Sequelize') }], + expectation: { + query: 'INSERT INTO myTable (data) VALUES ($1);', + bind: [Buffer.from('Sequelize')] + }, + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { name: 'foo', foo: 1, nullValue: null }], + expectation: { + query: 'INSERT INTO myTable (name,foo,nullValue) VALUES ($1,$2,$3);', + bind: ['foo', 1, null] + }, + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { name: 'foo', foo: 1, nullValue: null }], + expectation: { + query: 'INSERT INTO myTable (name,foo,nullValue) VALUES ($1,$2,$3);', + bind: ['foo', 1, null] + }, + context: { options: { omitNull: false, quoteIdentifiers: false } } + }, { + arguments: ['myTable', { name: 'foo', foo: 1, nullValue: null }], + expectation: { + query: 'INSERT INTO myTable (name,foo) VALUES ($1,$2);', + bind: ['foo', 1] + }, + context: { options: { omitNull: true, quoteIdentifiers: false } } + }, { + arguments: ['myTable', { name: 'foo', foo: 1, nullValue: undefined }], + expectation: { + query: 'INSERT INTO myTable (name,foo) VALUES ($1,$2);', + bind: ['foo', 1] + }, + context: { options: { omitNull: true, quoteIdentifiers: false } } + }, { + arguments: ['myTable', { foo: false }], + expectation: { + query: 'INSERT INTO myTable (foo) VALUES ($1);', + bind: [false] + }, + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { foo: true }], + expectation: { + query: 'INSERT INTO myTable (foo) VALUES ($1);', + bind: [true] + }, + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', function(sequelize) { + return { + foo: sequelize.fn('NOW') + }; + }], + expectation: { + query: 'INSERT INTO myTable (foo) VALUES (NOW());', + bind: [] + }, + needsSequelize: true, + context: { options: { quoteIdentifiers: false } } + } + ], + + bulkInsertQuery: [ + { + arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }]], + expectation: 'INSERT INTO "myTable" ("name") VALUES (\'foo\'),(\'bar\');' + }, { + arguments: ['myTable', [{ name: "foo';DROP TABLE myTable;" }, { name: 'bar' }]], + expectation: 'INSERT INTO "myTable" ("name") VALUES (\'foo\'\';DROP TABLE myTable;\'),(\'bar\');' + }, { + arguments: ['myTable', [{ name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55)) }, { name: 'bar', birthday: new Date(Date.UTC(2012, 2, 27, 10, 1, 55)) }]], + expectation: 'INSERT INTO "myTable" ("name","birthday") VALUES (\'foo\',\'2011-03-27 10:01:55\'),(\'bar\',\'2012-03-27 10:01:55\');' + }, { + arguments: ['myTable', [{ name: 'foo', foo: 1 }, { name: 'bar', foo: 2 }]], + expectation: 'INSERT INTO "myTable" ("name","foo") VALUES (\'foo\',1),(\'bar\',2);' + }, { + arguments: ['myTable', [{ name: 'foo', foo: 1, nullValue: null }, { name: 'bar', nullValue: null }]], + expectation: 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES (\'foo\',1,NULL),(\'bar\',NULL,NULL);' + }, { + arguments: ['myTable', [{ name: 'foo', foo: 1, nullValue: null }, { name: 'bar', foo: 2, nullValue: null }]], + expectation: 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES (\'foo\',1,NULL),(\'bar\',2,NULL);', + context: { options: { omitNull: false } } + }, { + arguments: ['myTable', [{ name: 'foo', foo: 1, nullValue: null }, { name: 'bar', foo: 2, nullValue: null }]], + expectation: 'INSERT INTO "myTable" ("name","foo","nullValue") VALUES (\'foo\',1,NULL),(\'bar\',2,NULL);', + context: { options: { omitNull: true } } // Note: We don't honour this because it makes little sense when some rows may have nulls and others not + }, { + arguments: ['myTable', [{ name: 'foo', foo: 1, nullValue: undefined }, { name: 'bar', foo: 2, undefinedValue: undefined }]], + expectation: 'INSERT INTO "myTable" ("name","foo","nullValue","undefinedValue") VALUES (\'foo\',1,NULL,NULL),(\'bar\',2,NULL,NULL);', + context: { options: { omitNull: true } } // Note: As above + }, { + arguments: ['myTable', [{ name: 'foo', value: true }, { name: 'bar', value: false }]], + expectation: 'INSERT INTO "myTable" ("name","value") VALUES (\'foo\',true),(\'bar\',false);' + }, { + arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }], { ignoreDuplicates: true }], + expectation: 'INSERT IGNORE INTO "myTable" ("name") VALUES (\'foo\'),(\'bar\');' + }, + + // Variants when quoteIdentifiers is false + { + arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }]], + expectation: 'INSERT INTO myTable (name) VALUES (\'foo\'),(\'bar\');', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', [{ name: "foo';DROP TABLE myTable;" }, { name: 'bar' }]], + expectation: 'INSERT INTO myTable (name) VALUES (\'foo\'\';DROP TABLE myTable;\'),(\'bar\');', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', [{ name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55)) }, { name: 'bar', birthday: new Date(Date.UTC(2012, 2, 27, 10, 1, 55)) }]], + expectation: 'INSERT INTO myTable (name,birthday) VALUES (\'foo\',\'2011-03-27 10:01:55\'),(\'bar\',\'2012-03-27 10:01:55\');', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', [{ name: 'foo', foo: 1 }, { name: 'bar', foo: 2 }]], + expectation: 'INSERT INTO myTable (name,foo) VALUES (\'foo\',1),(\'bar\',2);', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', [{ name: 'foo', foo: 1, nullValue: null }, { name: 'bar', nullValue: null }]], + expectation: 'INSERT INTO myTable (name,foo,nullValue) VALUES (\'foo\',1,NULL),(\'bar\',NULL,NULL);', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', [{ name: 'foo', foo: 1, nullValue: null }, { name: 'bar', foo: 2, nullValue: null }]], + expectation: 'INSERT INTO myTable (name,foo,nullValue) VALUES (\'foo\',1,NULL),(\'bar\',2,NULL);', + context: { options: { omitNull: false, quoteIdentifiers: false } } + }, { + arguments: ['myTable', [{ name: 'foo', foo: 1, nullValue: null }, { name: 'bar', foo: 2, nullValue: null }]], + expectation: 'INSERT INTO myTable (name,foo,nullValue) VALUES (\'foo\',1,NULL),(\'bar\',2,NULL);', + context: { options: { omitNull: true, quoteIdentifiers: false } } // Note: We don't honour this because it makes little sense when some rows may have nulls and others not + }, { + arguments: ['myTable', [{ name: 'foo', foo: 1, nullValue: undefined }, { name: 'bar', foo: 2, undefinedValue: undefined }]], + expectation: 'INSERT INTO myTable (name,foo,nullValue,undefinedValue) VALUES (\'foo\',1,NULL,NULL),(\'bar\',2,NULL,NULL);', + context: { options: { omitNull: true, quoteIdentifiers: false } } // Note: As above + }, { + arguments: ['myTable', [{ name: 'foo', value: true }, { name: 'bar', value: false }]], + expectation: 'INSERT INTO myTable (name,value) VALUES (\'foo\',true),(\'bar\',false);', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', [{ name: 'foo' }, { name: 'bar' }], { ignoreDuplicates: true }], + expectation: 'INSERT IGNORE INTO myTable (name) VALUES (\'foo\'),(\'bar\');', + context: { options: { quoteIdentifiers: false } } + } + ], + + updateQuery: [ + { + arguments: ['myTable', { name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55)) }, { id: 2 }], + expectation: { + query: 'UPDATE "myTable" SET "name"=$1,"birthday"=$2 WHERE "id" = $3', + bind: ['foo', new Date(Date.UTC(2011, 2, 27, 10, 1, 55)), 2] + } + + }, { + arguments: ['myTable', { name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55)) }, { id: 2 }], + expectation: { + query: 'UPDATE "myTable" SET "name"=$1,"birthday"=$2 WHERE "id" = $3', + bind: ['foo', new Date(Date.UTC(2011, 2, 27, 10, 1, 55)), 2] + } + }, { + arguments: ['myTable', { bar: 2 }, { name: 'foo' }], + expectation: { + query: 'UPDATE "myTable" SET "bar"=$1 WHERE "name" = $2', + bind: [2, 'foo'] + } + }, { + arguments: ['myTable', { name: "foo';DROP TABLE myTable;" }, { name: 'foo' }], + expectation: { + query: 'UPDATE "myTable" SET "name"=$1 WHERE "name" = $2', + bind: ["foo';DROP TABLE myTable;", 'foo'] + } + }, { + arguments: ['myTable', { bar: 2, nullValue: null }, { name: 'foo' }], + expectation: { + query: 'UPDATE "myTable" SET "bar"=$1,"nullValue"=$2 WHERE "name" = $3', + bind: [2, null, 'foo'] + } + }, { + arguments: ['myTable', { bar: 2, nullValue: null }, { name: 'foo' }], + expectation: { + query: 'UPDATE "myTable" SET "bar"=$1,"nullValue"=$2 WHERE "name" = $3', + bind: [2, null, 'foo'] + }, + context: { options: { omitNull: false } } + }, { + arguments: ['myTable', { bar: 2, nullValue: null }, { name: 'foo' }], + expectation: { + query: 'UPDATE "myTable" SET "bar"=$1 WHERE "name" = $2', + bind: [2, 'foo'] + }, + context: { options: { omitNull: true } } + }, { + arguments: ['myTable', { bar: false }, { name: 'foo' }], + expectation: { + query: 'UPDATE "myTable" SET "bar"=$1 WHERE "name" = $2', + bind: [false, 'foo'] + } + }, { + arguments: ['myTable', { bar: true }, { name: 'foo' }], + expectation: { + query: 'UPDATE "myTable" SET "bar"=$1 WHERE "name" = $2', + bind: [true, 'foo'] + } + }, { + arguments: ['myTable', function(sequelize) { + return { + bar: sequelize.fn('NOW') + }; + }, { name: 'foo' }], + expectation: { + query: 'UPDATE "myTable" SET "bar"=NOW() WHERE "name" = $1', + bind: ['foo'] + }, + needsSequelize: true + }, { + arguments: ['myTable', function(sequelize) { + return { + bar: sequelize.col('foo') + }; + }, { name: 'foo' }], + expectation: { + query: 'UPDATE "myTable" SET "bar"="foo" WHERE "name" = $1', + bind: ['foo'] + }, + needsSequelize: true + }, + + // Variants when quoteIdentifiers is false + { + arguments: ['myTable', { name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55)) }, { id: 2 }], + expectation: { + query: 'UPDATE myTable SET name=$1,birthday=$2 WHERE id = $3', + bind: ['foo', new Date(Date.UTC(2011, 2, 27, 10, 1, 55)), 2] + }, + context: { options: { quoteIdentifiers: false } } + + }, { + arguments: ['myTable', { name: 'foo', birthday: new Date(Date.UTC(2011, 2, 27, 10, 1, 55)) }, { id: 2 }], + expectation: { + query: 'UPDATE myTable SET name=$1,birthday=$2 WHERE id = $3', + bind: ['foo', new Date(Date.UTC(2011, 2, 27, 10, 1, 55)), 2] + }, + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { bar: 2 }, { name: 'foo' }], + expectation: { + query: 'UPDATE myTable SET bar=$1 WHERE name = $2', + bind: [2, 'foo'] + }, + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { name: "foo';DROP TABLE myTable;" }, { name: 'foo' }], + expectation: { + query: 'UPDATE myTable SET name=$1 WHERE name = $2', + bind: ["foo';DROP TABLE myTable;", 'foo'] + }, + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { bar: 2, nullValue: null }, { name: 'foo' }], + expectation: { + query: 'UPDATE myTable SET bar=$1,nullValue=$2 WHERE name = $3', + bind: [2, null, 'foo'] + }, + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { bar: 2, nullValue: null }, { name: 'foo' }], + expectation: { + query: 'UPDATE myTable SET bar=$1,nullValue=$2 WHERE name = $3', + bind: [2, null, 'foo'] + }, + context: { options: { omitNull: false, quoteIdentifiers: false } } + }, { + arguments: ['myTable', { bar: 2, nullValue: null }, { name: 'foo' }], + expectation: { + query: 'UPDATE myTable SET bar=$1 WHERE name = $2', + bind: [2, 'foo'] + }, + context: { options: { omitNull: true, quoteIdentifiers: false } } + }, { + arguments: ['myTable', { bar: false }, { name: 'foo' }], + expectation: { + query: 'UPDATE myTable SET bar=$1 WHERE name = $2', + bind: [false, 'foo'] + }, + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', { bar: true }, { name: 'foo' }], + expectation: { + query: 'UPDATE myTable SET bar=$1 WHERE name = $2', + bind: [true, 'foo'] + }, + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', function(sequelize) { + return { + bar: sequelize.fn('NOW') + }; + }, { name: 'foo' }], + expectation: { + query: 'UPDATE myTable SET bar=NOW() WHERE name = $1', + bind: ['foo'] + }, + needsSequelize: true, + context: { options: { quoteIdentifiers: false } } + }, { + arguments: ['myTable', function(sequelize) { + return { + bar: sequelize.col('foo') + }; + }, { name: 'foo' }], + expectation: { + query: 'UPDATE myTable SET bar=foo WHERE name = $1', + bind: ['foo'] + }, + needsSequelize: true, + context: { options: { quoteIdentifiers: false } } + } + ], + + getForeignKeyQuery: [ + { + arguments: ['User', 'email'], + expectation: "SELECT CONSTRAINT_NAME as constraint_name,CONSTRAINT_NAME as constraintName,CONSTRAINT_SCHEMA as constraintSchema,CONSTRAINT_SCHEMA as constraintCatalog,TABLE_NAME as tableName,TABLE_SCHEMA as tableSchema,TABLE_SCHEMA as tableCatalog,COLUMN_NAME as columnName,REFERENCED_TABLE_SCHEMA as referencedTableSchema,REFERENCED_TABLE_SCHEMA as referencedTableCatalog,REFERENCED_TABLE_NAME as referencedTableName,REFERENCED_COLUMN_NAME as referencedColumnName FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE (REFERENCED_TABLE_NAME = 'User' AND REFERENCED_COLUMN_NAME = 'email') OR (TABLE_NAME = 'User' AND COLUMN_NAME = 'email' AND REFERENCED_TABLE_NAME IS NOT NULL)" + }, + + // Variants when quoteIdentifiers is false + { + arguments: ['User', 'email'], + expectation: "SELECT CONSTRAINT_NAME as constraint_name,CONSTRAINT_NAME as constraintName,CONSTRAINT_SCHEMA as constraintSchema,CONSTRAINT_SCHEMA as constraintCatalog,TABLE_NAME as tableName,TABLE_SCHEMA as tableSchema,TABLE_SCHEMA as tableCatalog,COLUMN_NAME as columnName,REFERENCED_TABLE_SCHEMA as referencedTableSchema,REFERENCED_TABLE_SCHEMA as referencedTableCatalog,REFERENCED_TABLE_NAME as referencedTableName,REFERENCED_COLUMN_NAME as referencedColumnName FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE (REFERENCED_TABLE_NAME = 'User' AND REFERENCED_COLUMN_NAME = 'email') OR (TABLE_NAME = 'User' AND COLUMN_NAME = 'email' AND REFERENCED_TABLE_NAME IS NOT NULL)", + context: { options: { quoteIdentifiers: false } } + + } + ], + + selectFromTableFragment: [ + { + arguments: [{}, null, ['*'], '"Project"'], + expectation: 'SELECT * FROM "Project"' + }, { + arguments: [ + { indexHints: [{ type: IndexHints.USE, values: ['index_project_on_name'] }] }, + null, + ['*'], + '"Project"' + ], + expectation: 'SELECT * FROM "Project" USE INDEX ("index_project_on_name")' + }, { + arguments: [ + { indexHints: [{ type: IndexHints.FORCE, values: ['index_project_on_name'] }] }, + null, + ['*'], + '"Project"' + ], + expectation: 'SELECT * FROM "Project" FORCE INDEX ("index_project_on_name")' + }, { + arguments: [ + { indexHints: [{ type: IndexHints.IGNORE, values: ['index_project_on_name'] }] }, + null, + ['*'], + '"Project"' + ], + expectation: 'SELECT * FROM "Project" IGNORE INDEX ("index_project_on_name")' + }, { + arguments: [ + { indexHints: [{ type: IndexHints.USE, values: ['index_project_on_name', 'index_project_on_name_and_foo'] }] }, + null, + ['*'], + '"Project"' + ], + expectation: 'SELECT * FROM "Project" USE INDEX ("index_project_on_name","index_project_on_name_and_foo")' + }, { + arguments: [ + { indexHints: [{ type: 'FOO', values: ['index_project_on_name'] }] }, + null, + ['*'], + '"Project"' + ], + expectation: 'SELECT * FROM "Project"' + }, + + // Variants when quoteIdentifiers is false + { + arguments: [{}, null, ['*'], 'Project'], + expectation: 'SELECT * FROM Project', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: [ + { indexHints: [{ type: IndexHints.USE, values: ['index_project_on_name'] }] }, + null, + ['*'], + 'Project' + ], + expectation: 'SELECT * FROM Project USE INDEX (index_project_on_name)', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: [ + { indexHints: [{ type: IndexHints.FORCE, values: ['index_project_on_name'] }] }, + null, + ['*'], + 'Project' + ], + expectation: 'SELECT * FROM Project FORCE INDEX (index_project_on_name)', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: [ + { indexHints: [{ type: IndexHints.IGNORE, values: ['index_project_on_name'] }] }, + null, + ['*'], + 'Project' + ], + expectation: 'SELECT * FROM Project IGNORE INDEX (index_project_on_name)', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: [ + { indexHints: [{ type: IndexHints.USE, values: ['index_project_on_name', 'index_project_on_name_and_foo'] }] }, + null, + ['*'], + 'Project' + ], + expectation: 'SELECT * FROM Project USE INDEX (index_project_on_name,index_project_on_name_and_foo)', + context: { options: { quoteIdentifiers: false } } + }, { + arguments: [ + { indexHints: [{ type: 'FOO', values: ['index_project_on_name'] }] }, + null, + ['*'], + 'Project' + ], + expectation: 'SELECT * FROM Project', + context: { options: { quoteIdentifiers: false } } + } + ] + }; + + _.each(suites, (tests, suiteTitle) => { + describe(suiteTitle, () => { + beforeEach(function() { + this.queryGenerator = new QueryGenerator({ + sequelize: this.sequelize, + _dialect: this.sequelize.dialect + }); + }); + + tests.forEach(test => { + const query = test.expectation.query || test.expectation; + const title = test.title || `SNOWFLAKE correctly returns ${query} for ${JSON.stringify(test.arguments)}`; + it(title, function() { + if (test.needsSequelize) { + if (typeof test.arguments[1] === 'function') test.arguments[1] = test.arguments[1](this.sequelize); + if (typeof test.arguments[2] === 'function') test.arguments[2] = test.arguments[2](this.sequelize); + } + + // Options would normally be set by the query interface that instantiates the query-generator, but here we specify it explicitly + this.queryGenerator.options = { ...this.queryGenerator.options, ...test.context && test.context.options }; + + const conditions = this.queryGenerator[suiteTitle](...test.arguments); + expect(conditions).to.deep.equal(test.expectation); + }); + }); + }); + }); + }); +} diff --git a/test/unit/dialects/snowflake/query.test.js b/test/unit/dialects/snowflake/query.test.js new file mode 100644 index 000000000000..9f0360b9093a --- /dev/null +++ b/test/unit/dialects/snowflake/query.test.js @@ -0,0 +1,36 @@ +'use strict'; + +const path = require('path'); +const Query = require('sequelize/lib/dialects/snowflake/query.js'); +const Support = require(path.join(__dirname, './../../support')); +const chai = require('chai'); +const sinon = require('sinon'); + +const current = Support.sequelize; +const expect = chai.expect; + +describe('[SNOWFLAKE Specific] Query', () => { + describe('logWarnings', () => { + beforeEach(() => { + sinon.spy(console, 'log'); + }); + + afterEach(() => { + console.log.restore(); + }); + + it('check iterable', async () => { + const validWarning = []; + const invalidWarning = {}; + const warnings = [validWarning, undefined, invalidWarning]; + + const query = new Query({}, current, {}); + const stub = sinon.stub(query, 'run'); + stub.onFirstCall().resolves(warnings); + + const results = await query.logWarnings('dummy-results'); + expect('dummy-results').to.equal(results); + expect(true).to.equal(console.log.calledOnce); + }); + }); +}); diff --git a/test/unit/errors.test.js b/test/unit/errors.test.js index 76790b3b23ea..5462c00ae323 100644 --- a/test/unit/errors.test.js +++ b/test/unit/errors.test.js @@ -47,7 +47,7 @@ describe('errors', () => { expect(err).to.exist; const stackParts = err.stack.split('\n'); - const fullErrorName = `Sequelize${errorName}`; + const fullErrorName = `Sequelize${errorName}: `; expect(stackParts[0]).to.equal(fullErrorName); expect(stackParts[1]).to.match(/^ {4}at throwError \(.*errors.test.js:\d+:\d+\)$/); }); diff --git a/test/unit/model/define.test.js b/test/unit/model/define.test.js index 6ee8358cdb5c..f3c292854bcf 100644 --- a/test/unit/model/define.test.js +++ b/test/unit/model/define.test.js @@ -117,7 +117,7 @@ describe(Support.getTestDialectTeaser('Model'), () => { } }); - if (dialect === 'postgres' || dialect === 'sqlite' || dialect === 'mssql') { + if (['postgres', 'sqlite', 'mssql'].includes(dialect)) { expect(true).to.equal(console.warn.calledOnce); expect(console.warn.args[0][0]).to.contain("does not support 'TINYINT'"); } else { diff --git a/test/unit/sql/change-column.test.js b/test/unit/sql/change-column.test.js index bc67524811fa..893e4a611353 100644 --- a/test/unit/sql/change-column.test.js +++ b/test/unit/sql/change-column.test.js @@ -42,7 +42,8 @@ if (current.dialect.name !== 'sqlite') { mssql: 'ALTER TABLE [users] ALTER COLUMN [level_id] FLOAT NOT NULL;', mariadb: 'ALTER TABLE `users` CHANGE `level_id` `level_id` FLOAT NOT NULL;', mysql: 'ALTER TABLE `users` CHANGE `level_id` `level_id` FLOAT NOT NULL;', - postgres: 'ALTER TABLE "users" ALTER COLUMN "level_id" SET NOT NULL;ALTER TABLE "users" ALTER COLUMN "level_id" DROP DEFAULT;ALTER TABLE "users" ALTER COLUMN "level_id" TYPE FLOAT;' + postgres: 'ALTER TABLE "users" ALTER COLUMN "level_id" SET NOT NULL;ALTER TABLE "users" ALTER COLUMN "level_id" DROP DEFAULT;ALTER TABLE "users" ALTER COLUMN "level_id" TYPE FLOAT;', + snowflake: 'ALTER TABLE "users" ALTER COLUMN "level_id" SET NOT NULL;ALTER TABLE "users" ALTER COLUMN "level_id" DROP DEFAULT;ALTER TABLE "users" ALTER COLUMN "level_id" TYPE FLOAT;' }); }); }); @@ -61,7 +62,8 @@ if (current.dialect.name !== 'sqlite') { mssql: 'ALTER TABLE [users] ADD FOREIGN KEY ([level_id]) REFERENCES [level] ([id]) ON DELETE CASCADE;', mariadb: 'ALTER TABLE `users` ADD FOREIGN KEY (`level_id`) REFERENCES `level` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;', mysql: 'ALTER TABLE `users` ADD FOREIGN KEY (`level_id`) REFERENCES `level` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;', - postgres: 'ALTER TABLE "users" ADD FOREIGN KEY ("level_id") REFERENCES "level" ("id") ON DELETE CASCADE ON UPDATE CASCADE;' + postgres: 'ALTER TABLE "users" ADD FOREIGN KEY ("level_id") REFERENCES "level" ("id") ON DELETE CASCADE ON UPDATE CASCADE;', + snowflake: 'ALTER TABLE "users" ADD FOREIGN KEY ("level_id") REFERENCES "level" ("id") ON DELETE CASCADE ON UPDATE CASCADE;' }); }); }); diff --git a/test/unit/sql/create-table.test.js b/test/unit/sql/create-table.test.js index 2a896b465b6a..bd8e55c8b636 100644 --- a/test/unit/sql/create-table.test.js +++ b/test/unit/sql/create-table.test.js @@ -8,6 +8,9 @@ const Support = require('../support'), _ = require('lodash'); describe(Support.getTestDialectTeaser('SQL'), () => { + if (current.dialect.name === 'snowflake') { + return; + } describe('createTable', () => { const FooUser = current.define('user', { mood: DataTypes.ENUM('happy', 'sad') diff --git a/test/unit/sql/data-types.test.js b/test/unit/sql/data-types.test.js index 6c2f2a73a644..d4614a0ccc07 100644 --- a/test/unit/sql/data-types.test.js +++ b/test/unit/sql/data-types.test.js @@ -146,7 +146,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { mssql: 'BIT', mariadb: 'TINYINT(1)', mysql: 'TINYINT(1)', - sqlite: 'TINYINT(1)' + sqlite: 'TINYINT(1)', + snowflake: 'BOOLEAN' }); describe('validate', () => { @@ -177,7 +178,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { mssql: 'DATETIMEOFFSET', mariadb: 'DATETIME', mysql: 'DATETIME', - sqlite: 'DATETIME' + sqlite: 'DATETIME', + snowflake: 'TIMESTAMP' }); testsql('DATE(6)', DataTypes.DATE(6), { @@ -185,7 +187,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { mssql: 'DATETIMEOFFSET', mariadb: 'DATETIME(6)', mysql: 'DATETIME(6)', - sqlite: 'DATETIME' + sqlite: 'DATETIME', + snowflake: 'TIMESTAMP' }); describe('validate', () => { @@ -231,7 +234,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { mssql: 'CHAR(36)', mariadb: 'CHAR(36) BINARY', mysql: 'CHAR(36) BINARY', - sqlite: 'UUID' + sqlite: 'UUID', + snowflake: 'VARCHAR(36)' }); describe('validate', () => { @@ -1436,7 +1440,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { if (current.dialect.supports.GEOMETRY) { describe('GEOMETRY', () => { testsql('GEOMETRY', DataTypes.GEOMETRY, { - default: 'GEOMETRY' + default: 'GEOMETRY', + snowflake: 'GEOGRAPHY' }); testsql('GEOMETRY(\'POINT\')', DataTypes.GEOMETRY('POINT'), { diff --git a/test/unit/sql/delete.test.js b/test/unit/sql/delete.test.js index 9e3e47230f8f..15d2fd676844 100644 --- a/test/unit/sql/delete.test.js +++ b/test/unit/sql/delete.test.js @@ -38,7 +38,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { mssql: 'TRUNCATE TABLE [public].[test_users]', mariadb: 'TRUNCATE `public`.`test_users`', mysql: 'TRUNCATE `public.test_users`', - sqlite: 'DELETE FROM `public.test_users`' + sqlite: 'DELETE FROM `public.test_users`', + snowflake: 'TRUNCATE "public"."test_users"' } ); }); @@ -65,7 +66,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { mssql: 'TRUNCATE TABLE [public].[test_users]', mariadb: 'TRUNCATE `public`.`test_users`', mysql: 'TRUNCATE `public.test_users`', - sqlite: 'DELETE FROM `public.test_users`; DELETE FROM `sqlite_sequence` WHERE `name` = \'public.test_users\';' + sqlite: 'DELETE FROM `public.test_users`; DELETE FROM `sqlite_sequence` WHERE `name` = \'public.test_users\';', + snowflake: 'TRUNCATE "public"."test_users"' } ); }); @@ -91,7 +93,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { postgres: 'DELETE FROM "public"."test_users" WHERE "name" = \'foo\'', mariadb: 'DELETE FROM `public`.`test_users` WHERE `name` = \'foo\'', sqlite: "DELETE FROM `public.test_users` WHERE `name` = 'foo'", - mssql: "DELETE FROM [public].[test_users] WHERE [name] = N'foo'; SELECT @@ROWCOUNT AS AFFECTEDROWS;" + mssql: "DELETE FROM [public].[test_users] WHERE [name] = N'foo'; SELECT @@ROWCOUNT AS AFFECTEDROWS;", + snowflake: 'DELETE FROM "public"."test_users" WHERE "name" = \'foo\';' } ); }); @@ -117,7 +120,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { mariadb: "DELETE FROM `public`.`test_users` WHERE `name` = 'foo\\';DROP TABLE mySchema.myTable;' LIMIT 10", sqlite: "DELETE FROM `public.test_users` WHERE rowid IN (SELECT rowid FROM `public.test_users` WHERE `name` = 'foo'';DROP TABLE mySchema.myTable;' LIMIT 10)", mssql: "DELETE TOP(10) FROM [public].[test_users] WHERE [name] = N'foo'';DROP TABLE mySchema.myTable;'; SELECT @@ROWCOUNT AS AFFECTEDROWS;", - default: "DELETE FROM [public.test_users] WHERE `name` = 'foo\\';DROP TABLE mySchema.myTable;' LIMIT 10" + default: "DELETE FROM [public.test_users] WHERE `name` = 'foo\\';DROP TABLE mySchema.myTable;' LIMIT 10", + snowflake: 'DELETE FROM "public"."test_users" WHERE "id" IN (SELECT "id" FROM "public"."test_users" WHERE "name" = \'foo\'\';DROP TABLE mySchema.myTable;\' LIMIT 10);' } ); }); @@ -150,7 +154,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { mariadb: "DELETE FROM `public`.`test_users` WHERE `name` = 'foo\\';DROP TABLE mySchema.myTable;' LIMIT 10", sqlite: "DELETE FROM `public.test_users` WHERE rowid IN (SELECT rowid FROM `public.test_users` WHERE `name` = 'foo'';DROP TABLE mySchema.myTable;' LIMIT 10)", mssql: "DELETE TOP(10) FROM [public].[test_users] WHERE [name] = N'foo'';DROP TABLE mySchema.myTable;'; SELECT @@ROWCOUNT AS AFFECTEDROWS;", - default: "DELETE FROM [public.test_users] WHERE `name` = 'foo\\';DROP TABLE mySchema.myTable;' LIMIT 10" + default: "DELETE FROM [public.test_users] WHERE `name` = 'foo\\';DROP TABLE mySchema.myTable;' LIMIT 10", + snowflake: new Error('Cannot LIMIT delete without a model.') } ); }); @@ -185,6 +190,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { postgres: 'DELETE FROM "test_user" WHERE "test_user_id" = 100', sqlite: 'DELETE FROM `test_user` WHERE `test_user_id` = 100', mssql: 'DELETE FROM [test_user] WHERE [test_user_id] = 100; SELECT @@ROWCOUNT AS AFFECTEDROWS;', + snowflake: 'DELETE FROM "test_user" WHERE "test_user_id" = 100;', default: 'DELETE FROM [test_user] WHERE [test_user_id] = 100' } ); diff --git a/test/unit/sql/group.test.js b/test/unit/sql/group.test.js index 76320220d2f0..805daaaa1e2f 100644 --- a/test/unit/sql/group.test.js +++ b/test/unit/sql/group.test.js @@ -39,7 +39,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { }, { default: 'SELECT * FROM `Users` AS `User` GROUP BY `name`;', postgres: 'SELECT * FROM "Users" AS "User" GROUP BY "name";', - mssql: 'SELECT * FROM [Users] AS [User] GROUP BY [name];' + mssql: 'SELECT * FROM [Users] AS [User] GROUP BY [name];', + snowflake: 'SELECT * FROM "Users" AS "User" GROUP BY "name";' }); testsql({ @@ -48,7 +49,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { }, { default: 'SELECT * FROM `Users` AS `User`;', postgres: 'SELECT * FROM "Users" AS "User";', - mssql: 'SELECT * FROM [Users] AS [User];' + mssql: 'SELECT * FROM [Users] AS [User];', + snowflake: 'SELECT * FROM "Users" AS "User";' }); }); }); diff --git a/test/unit/sql/index.test.js b/test/unit/sql/index.test.js index 18f6161c3ad3..4518cde3669d 100644 --- a/test/unit/sql/index.test.js +++ b/test/unit/sql/index.test.js @@ -9,6 +9,9 @@ const Support = require('../support'), // Notice: [] will be replaced by dialect specific tick/quote character when there is not dialect specific expectation but only a default expectation describe(Support.getTestDialectTeaser('SQL'), () => { + if (current.dialect.name === 'snowflake') { + return; + } describe('addIndex', () => { it('naming', () => { expectsql(sql.addIndexQuery('table', ['column1', 'column2'], {}, 'table'), { @@ -155,19 +158,19 @@ describe(Support.getTestDialectTeaser('SQL'), () => { it('show indexes', () => { expectsql(sql.showIndexesQuery('table'), { postgres: 'SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, ' + - 'array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) ' + - 'AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a ' + - 'WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND ' + - 't.relkind = \'r\' and t.relname = \'table\' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;' + 'array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) ' + + 'AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a ' + + 'WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND ' + + 't.relkind = \'r\' and t.relname = \'table\' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;' }); expectsql(sql.showIndexesQuery({ tableName: 'table', schema: 'schema' }), { postgres: 'SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, ' + - 'array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) ' + - 'AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a, pg_namespace s ' + - 'WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND ' + - 't.relkind = \'r\' and t.relname = \'table\' AND s.oid = t.relnamespace AND s.nspname = \'schema\' ' + - 'GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;' + 'array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) ' + + 'AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a, pg_namespace s ' + + 'WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND ' + + 't.relkind = \'r\' and t.relname = \'table\' AND s.oid = t.relnamespace AND s.nspname = \'schema\' ' + + 'GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;' }); }); } diff --git a/test/unit/sql/insert.test.js b/test/unit/sql/insert.test.js index 13c269f21161..67cfe9da61c6 100644 --- a/test/unit/sql/insert.test.js +++ b/test/unit/sql/insert.test.js @@ -30,7 +30,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { query: { mssql: 'DECLARE @tmp TABLE ([id] INTEGER,[user_name] NVARCHAR(255)); INSERT INTO [users] ([user_name]) OUTPUT INSERTED.[id],INSERTED.[user_name] INTO @tmp VALUES ($1); SELECT * FROM @tmp;', postgres: 'INSERT INTO "users" ("user_name") VALUES ($1) RETURNING "id","user_name";', - default: 'INSERT INTO `users` (`user_name`) VALUES ($1);' + default: 'INSERT INTO `users` (`user_name`) VALUES ($1);', + snowflake: 'INSERT INTO "users" ("user_name") VALUES ($1);' }, bind: ['triggertest'] }); @@ -51,6 +52,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { query: { mssql: 'SET IDENTITY_INSERT [ms] ON; INSERT INTO [ms] ([id]) VALUES ($1); SET IDENTITY_INSERT [ms] OFF;', postgres: 'INSERT INTO "ms" ("id") VALUES ($1);', + snowflake: 'INSERT INTO "ms" ("id") VALUES ($1);', default: 'INSERT INTO `ms` (`id`) VALUES ($1);' }, bind: [0] @@ -76,12 +78,14 @@ describe(Support.getTestDialectTeaser('SQL'), () => { { query: { postgres: 'INSERT INTO "users" ("date") VALUES ($1);', + snowflake: 'INSERT INTO "users" ("date") VALUES ($1);', mssql: 'INSERT INTO [users] ([date]) VALUES ($1);', default: 'INSERT INTO `users` (`date`) VALUES ($1);' }, bind: { sqlite: ['2015-01-20 00:00:00.000 +00:00'], mysql: ['2015-01-20 01:00:00'], + snowflake: ['2015-01-20 01:00:00'], mariadb: ['2015-01-20 01:00:00.000'], default: ['2015-01-20 01:00:00.000 +01:00'] } @@ -105,6 +109,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { { query: { postgres: 'INSERT INTO "users" ("date") VALUES ($1);', + snowflake: 'INSERT INTO "users" ("date") VALUES ($1);', mssql: 'INSERT INTO [users] ([date]) VALUES ($1);', default: 'INSERT INTO `users` (`date`) VALUES ($1);' }, @@ -112,6 +117,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { sqlite: ['2015-01-20 01:02:03.089 +00:00'], mariadb: ['2015-01-20 02:02:03.089'], mysql: ['2015-01-20 02:02:03.089'], + snowflake: ['2015-01-20 02:02:03.089'], default: ['2015-01-20 02:02:03.089 +01:00'] } }); @@ -133,6 +139,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { { query: { postgres: 'INSERT INTO "users" ("user_name") VALUES ($1);', + snowflake: 'INSERT INTO "users" ("user_name") VALUES ($1);', mssql: 'INSERT INTO [users] ([user_name]) VALUES ($1);', default: 'INSERT INTO `users` (`user_name`) VALUES ($1);' }, @@ -174,6 +181,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { expectsql(sql.bulkInsertQuery(User.tableName, [{ user_name: 'testuser', pass_word: '12345' }], { updateOnDuplicate: ['user_name', 'pass_word', 'updated_at'], upsertKeys: primaryKeys }, User.fieldRawAttributesMap), { default: 'INSERT INTO `users` (`user_name`,`pass_word`) VALUES (\'testuser\',\'12345\');', + snowflake: 'INSERT INTO "users" ("user_name","pass_word") VALUES (\'testuser\',\'12345\');', postgres: 'INSERT INTO "users" ("user_name","pass_word") VALUES (\'testuser\',\'12345\') ON CONFLICT ("user_name") DO UPDATE SET "user_name"=EXCLUDED."user_name","pass_word"=EXCLUDED."pass_word","updated_at"=EXCLUDED."updated_at";', mssql: 'INSERT INTO [users] ([user_name],[pass_word]) VALUES (N\'testuser\',N\'12345\');', mariadb: 'INSERT INTO `users` (`user_name`,`pass_word`) VALUES (\'testuser\',\'12345\') ON DUPLICATE KEY UPDATE `user_name`=VALUES(`user_name`),`pass_word`=VALUES(`pass_word`),`updated_at`=VALUES(`updated_at`);', @@ -196,6 +204,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { query: { mssql: 'SET IDENTITY_INSERT [ms] ON; INSERT INTO [ms] DEFAULT VALUES;INSERT INTO [ms] ([id]) VALUES (0),(NULL);; SET IDENTITY_INSERT [ms] OFF;', postgres: 'INSERT INTO "ms" ("id") VALUES (0),(DEFAULT);', + snowflake: 'INSERT INTO "ms" ("id") VALUES (0),(NULL);', default: 'INSERT INTO `ms` (`id`) VALUES (0),(NULL);' } }); diff --git a/test/unit/sql/offset-limit.test.js b/test/unit/sql/offset-limit.test.js index 5b5fc3afb36e..65e78c984a7e 100644 --- a/test/unit/sql/offset-limit.test.js +++ b/test/unit/sql/offset-limit.test.js @@ -50,6 +50,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { ] }, { default: ' LIMIT 20, 10', + snowflake: ' LIMIT 10 OFFSET 20', postgres: ' LIMIT 10 OFFSET 20', mssql: ' OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY' }); @@ -62,6 +63,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { }, { default: " LIMIT ''';DELETE FROM user'", mariadb: " LIMIT '\\';DELETE FROM user'", + snowflake: " LIMIT ''';DELETE FROM user'", mysql: " LIMIT '\\';DELETE FROM user'", mssql: " OFFSET 0 ROWS FETCH NEXT N''';DELETE FROM user' ROWS ONLY" }); @@ -76,6 +78,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { sqlite: " LIMIT ''';DELETE FROM user', 10", postgres: " LIMIT 10 OFFSET ''';DELETE FROM user'", mariadb: " LIMIT '\\';DELETE FROM user', 10", + snowflake: " LIMIT 10 OFFSET ''';DELETE FROM user'", mysql: " LIMIT '\\';DELETE FROM user', 10", mssql: " OFFSET N''';DELETE FROM user' ROWS FETCH NEXT 10 ROWS ONLY" }); diff --git a/test/unit/sql/order.test.js b/test/unit/sql/order.test.js index fc79a7ec6ee9..ed519e0a46ea 100644 --- a/test/unit/sql/order.test.js +++ b/test/unit/sql/order.test.js @@ -355,6 +355,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { mariadb: 'SELECT `id`, `name` FROM `subtask` AS `Subtask` ORDER BY RAND();', mysql: 'SELECT `id`, `name` FROM `subtask` AS `Subtask` ORDER BY RAND();', postgres: 'SELECT "id", "name" FROM "subtask" AS "Subtask" ORDER BY RANDOM();', + snowflake: 'SELECT "id", "name" FROM "subtask" AS "Subtask" ORDER BY RANDOM();', sqlite: 'SELECT `id`, `name` FROM `subtask` AS `Subtask` ORDER BY RANDOM();' }); diff --git a/test/unit/sql/remove-column.test.js b/test/unit/sql/remove-column.test.js index 9b5d186513c0..08b038a996ae 100644 --- a/test/unit/sql/remove-column.test.js +++ b/test/unit/sql/remove-column.test.js @@ -18,7 +18,8 @@ if (current.dialect.name !== 'sqlite') { mssql: 'ALTER TABLE [archive].[user] DROP COLUMN [email];', mariadb: 'ALTER TABLE `archive`.`user` DROP `email`;', mysql: 'ALTER TABLE `archive.user` DROP `email`;', - postgres: 'ALTER TABLE "archive"."user" DROP COLUMN "email";' + postgres: 'ALTER TABLE "archive"."user" DROP COLUMN "email";', + snowflake: 'ALTER TABLE "archive"."user" DROP "email";' }); }); }); diff --git a/test/unit/sql/select.test.js b/test/unit/sql/select.test.js index 107bb79596c4..a91e856da232 100644 --- a/test/unit/sql/select.test.js +++ b/test/unit/sql/select.test.js @@ -585,6 +585,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { } }, User), { postgres: 'SELECT "name", "age", "data" FROM "User" AS "User" WHERE "User"."data" IN (E\'\\\\x313233\');', + snowflake: 'SELECT "name", "age", "data" FROM "User" AS "User" WHERE "User"."data" IN (X\'313233\');', mariadb: 'SELECT `name`, `age`, `data` FROM `User` AS `User` WHERE `User`.`data` IN (X\'313233\');', mysql: 'SELECT `name`, `age`, `data` FROM `User` AS `User` WHERE `User`.`data` IN (X\'313233\');', sqlite: 'SELECT `name`, `age`, `data` FROM `User` AS `User` WHERE `User`.`data` IN (X\'313233\');', @@ -598,6 +599,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { attributes: ['* FROM [User]; DELETE FROM [User];SELECT [id]'.replace(/\[/g, Support.sequelize.dialect.TICK_CHAR_LEFT).replace(/\]/g, Support.sequelize.dialect.TICK_CHAR_RIGHT)] }), { default: 'SELECT \'* FROM [User]; DELETE FROM [User];SELECT [id]\' FROM [User];', + snowflake: 'SELECT \'* FROM "User"; DELETE FROM "User";SELECT "id"\' FROM "User";', mssql: 'SELECT [* FROM User; DELETE FROM User;SELECT id] FROM [User];' }); }); @@ -734,7 +736,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { it('*', () => { expectsql(sql.selectQuery('User'), { default: 'SELECT * FROM [User];', - postgres: 'SELECT * FROM "User";' + postgres: 'SELECT * FROM "User";', + snowflake: 'SELECT * FROM User;' }); }); @@ -743,7 +746,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { attributes: ['name', 'age'] }), { default: 'SELECT [name], [age] FROM [User];', - postgres: 'SELECT name, age FROM "User";' + postgres: 'SELECT name, age FROM "User";', + snowflake: 'SELECT name, age FROM User;' }); }); @@ -776,7 +780,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { model: User }, User), { default: 'SELECT [User].[name], [User].[age], [Posts].[id] AS [Posts.id], [Posts].[title] AS [Posts.title] FROM [User] AS [User] LEFT OUTER JOIN [Post] AS [Posts] ON [User].[id] = [Posts].[user_id];', - postgres: 'SELECT "User".name, "User".age, Posts.id AS "Posts.id", Posts.title AS "Posts.title" FROM "User" AS "User" LEFT OUTER JOIN Post AS Posts ON "User".id = Posts.user_id;' + postgres: 'SELECT "User".name, "User".age, Posts.id AS "Posts.id", Posts.title AS "Posts.title" FROM "User" AS "User" LEFT OUTER JOIN Post AS Posts ON "User".id = Posts.user_id;', + snowflake: 'SELECT User.name, User.age, Posts.id AS "Posts.id", Posts.title AS "Posts.title" FROM User AS User LEFT OUTER JOIN Post AS Posts ON User.id = Posts.user_id;' }); }); @@ -822,7 +827,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { model: User }, User), { default: 'SELECT [User].[name], [User].[age], [Posts].[id] AS [Posts.id], [Posts].[title] AS [Posts.title], [Posts->Comments].[id] AS [Posts.Comments.id], [Posts->Comments].[title] AS [Posts.Comments.title], [Posts->Comments].[createdAt] AS [Posts.Comments.createdAt], [Posts->Comments].[updatedAt] AS [Posts.Comments.updatedAt], [Posts->Comments].[post_id] AS [Posts.Comments.post_id] FROM [User] AS [User] LEFT OUTER JOIN [Post] AS [Posts] ON [User].[id] = [Posts].[user_id] LEFT OUTER JOIN [Comment] AS [Posts->Comments] ON [Posts].[id] = [Posts->Comments].[post_id];', - postgres: 'SELECT "User".name, "User".age, Posts.id AS "Posts.id", Posts.title AS "Posts.title", "Posts->Comments".id AS "Posts.Comments.id", "Posts->Comments".title AS "Posts.Comments.title", "Posts->Comments".createdAt AS "Posts.Comments.createdAt", "Posts->Comments".updatedAt AS "Posts.Comments.updatedAt", "Posts->Comments".post_id AS "Posts.Comments.post_id" FROM "User" AS "User" LEFT OUTER JOIN Post AS Posts ON "User".id = Posts.user_id LEFT OUTER JOIN Comment AS "Posts->Comments" ON Posts.id = "Posts->Comments".post_id;' + postgres: 'SELECT "User".name, "User".age, Posts.id AS "Posts.id", Posts.title AS "Posts.title", "Posts->Comments".id AS "Posts.Comments.id", "Posts->Comments".title AS "Posts.Comments.title", "Posts->Comments".createdAt AS "Posts.Comments.createdAt", "Posts->Comments".updatedAt AS "Posts.Comments.updatedAt", "Posts->Comments".post_id AS "Posts.Comments.post_id" FROM "User" AS "User" LEFT OUTER JOIN Post AS Posts ON "User".id = Posts.user_id LEFT OUTER JOIN Comment AS "Posts->Comments" ON Posts.id = "Posts->Comments".post_id;', + snowflake: 'SELECT User.name, User.age, Posts.id AS "Posts.id", Posts.title AS "Posts.title", "Posts->Comments".id AS "Posts.Comments.id", "Posts->Comments".title AS "Posts.Comments.title", "Posts->Comments".createdAt AS "Posts.Comments.createdAt", "Posts->Comments".updatedAt AS "Posts.Comments.updatedAt", "Posts->Comments".post_id AS "Posts.Comments.post_id" FROM User AS User LEFT OUTER JOIN Post AS Posts ON User.id = Posts.user_id LEFT OUTER JOIN Comment AS "Posts->Comments" ON Posts.id = "Posts->Comments".post_id;' }); }); @@ -858,7 +864,8 @@ describe(Support.getTestDialectTeaser('SQL'), () => { dotNotation: true }, User), { default: 'SELECT [User].[name], [User].[age], [User].[status.label], [Posts].[id] AS [Posts.id], [Posts].[title] AS [Posts.title], [Posts].[status.label] AS [Posts.status.label] FROM [User] AS [User] LEFT OUTER JOIN [Post] AS [Posts] ON [User].[id] = [Posts].[user_id];', - postgres: 'SELECT "User".name, "User".age, "User"."status.label", Posts.id AS "Posts.id", Posts.title AS "Posts.title", Posts."status.label" AS "Posts.status.label" FROM "User" AS "User" LEFT OUTER JOIN Post AS Posts ON "User".id = Posts.user_id;' + postgres: 'SELECT "User".name, "User".age, "User"."status.label", Posts.id AS "Posts.id", Posts.title AS "Posts.title", Posts."status.label" AS "Posts.status.label" FROM "User" AS "User" LEFT OUTER JOIN Post AS Posts ON "User".id = Posts.user_id;', + snowflake: 'SELECT User.name, User.age, User."status.label", Posts.id AS "Posts.id", Posts.title AS "Posts.title", Posts."status.label" AS "Posts.status.label" FROM User AS User LEFT OUTER JOIN Post AS Posts ON User.id = Posts.user_id;' }); }); diff --git a/test/unit/sql/show-constraints.test.js b/test/unit/sql/show-constraints.test.js index f6cbc239fddb..459b723b1e27 100644 --- a/test/unit/sql/show-constraints.test.js +++ b/test/unit/sql/show-constraints.test.js @@ -13,6 +13,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { postgres: 'SELECT constraint_catalog AS "constraintCatalog", constraint_schema AS "constraintSchema", constraint_name AS "constraintName", table_catalog AS "tableCatalog", table_schema AS "tableSchema", table_name AS "tableName", constraint_type AS "constraintType", is_deferrable AS "isDeferrable", initially_deferred AS "initiallyDeferred" from INFORMATION_SCHEMA.table_constraints WHERE table_name=\'myTable\';', mariadb: "SELECT CONSTRAINT_CATALOG AS constraintCatalog, CONSTRAINT_NAME AS constraintName, CONSTRAINT_SCHEMA AS constraintSchema, CONSTRAINT_TYPE AS constraintType, TABLE_NAME AS tableName, TABLE_SCHEMA AS tableSchema from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE table_name='myTable';", mysql: "SELECT CONSTRAINT_CATALOG AS constraintCatalog, CONSTRAINT_NAME AS constraintName, CONSTRAINT_SCHEMA AS constraintSchema, CONSTRAINT_TYPE AS constraintType, TABLE_NAME AS tableName, TABLE_SCHEMA AS tableSchema from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE table_name='myTable';", + snowflake: "SELECT CONSTRAINT_CATALOG AS constraintCatalog, CONSTRAINT_NAME AS constraintName, CONSTRAINT_SCHEMA AS constraintSchema, CONSTRAINT_TYPE AS constraintType, TABLE_NAME AS tableName, TABLE_SCHEMA AS tableSchema from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE table_name='myTable';", default: "SELECT sql FROM sqlite_master WHERE tbl_name='myTable';" }); }); @@ -23,6 +24,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { postgres: 'SELECT constraint_catalog AS "constraintCatalog", constraint_schema AS "constraintSchema", constraint_name AS "constraintName", table_catalog AS "tableCatalog", table_schema AS "tableSchema", table_name AS "tableName", constraint_type AS "constraintType", is_deferrable AS "isDeferrable", initially_deferred AS "initiallyDeferred" from INFORMATION_SCHEMA.table_constraints WHERE table_name=\'myTable\';', mariadb: "SELECT CONSTRAINT_CATALOG AS constraintCatalog, CONSTRAINT_NAME AS constraintName, CONSTRAINT_SCHEMA AS constraintSchema, CONSTRAINT_TYPE AS constraintType, TABLE_NAME AS tableName, TABLE_SCHEMA AS tableSchema from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE table_name='myTable' AND constraint_name = 'myConstraintName';", mysql: "SELECT CONSTRAINT_CATALOG AS constraintCatalog, CONSTRAINT_NAME AS constraintName, CONSTRAINT_SCHEMA AS constraintSchema, CONSTRAINT_TYPE AS constraintType, TABLE_NAME AS tableName, TABLE_SCHEMA AS tableSchema from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE table_name='myTable' AND constraint_name = 'myConstraintName';", + snowflake: "SELECT CONSTRAINT_CATALOG AS constraintCatalog, CONSTRAINT_NAME AS constraintName, CONSTRAINT_SCHEMA AS constraintSchema, CONSTRAINT_TYPE AS constraintType, TABLE_NAME AS tableName, TABLE_SCHEMA AS tableSchema from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE table_name='myTable' AND constraint_name = 'myConstraintName';", default: "SELECT sql FROM sqlite_master WHERE tbl_name='myTable' AND sql LIKE '%myConstraintName%';" }); }); diff --git a/test/unit/sql/update.test.js b/test/unit/sql/update.test.js index 28a9050f1bd7..8f7b3bed95c8 100644 --- a/test/unit/sql/update.test.js +++ b/test/unit/sql/update.test.js @@ -54,6 +54,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { query: { mssql: 'DECLARE @tmp TABLE ([id] INTEGER,[user_name] NVARCHAR(255)); UPDATE [users] SET [user_name]=$1 OUTPUT INSERTED.[id],INSERTED.[user_name] INTO @tmp WHERE [id] = $2; SELECT * FROM @tmp', postgres: 'UPDATE "users" SET "user_name"=$1 WHERE "id" = $2 RETURNING "id","user_name"', + snowflake: 'UPDATE "users" SET "user_name"=$1 WHERE "id" = $2', default: 'UPDATE `users` SET `user_name`=$1 WHERE `id` = $2' }, bind: { @@ -80,6 +81,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { mariadb: 'UPDATE `Users` SET `username`=$1 WHERE `username` = $2 LIMIT 1', mysql: 'UPDATE `Users` SET `username`=$1 WHERE `username` = $2 LIMIT 1', sqlite: 'UPDATE `Users` SET `username`=$1 WHERE rowid IN (SELECT rowid FROM `Users` WHERE `username` = $2 LIMIT 1)', + snowflake: 'UPDATE "Users" SET "username"=$1 WHERE "username" = $2 LIMIT 1', default: 'UPDATE [Users] SET [username]=$1 WHERE [username] = $2' }, bind: { diff --git a/test/unit/sql/where.test.js b/test/unit/sql/where.test.js index 71b27b456d34..b227b0736a58 100644 --- a/test/unit/sql/where.test.js +++ b/test/unit/sql/where.test.js @@ -58,6 +58,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { expectsql(sql.whereQuery({ id: 1 }, { prefix: current.literal(sql.quoteTable.call(current.dialect.queryGenerator, { schema: 'yolo', tableName: 'User' })) }), { default: 'WHERE [yolo.User].[id] = 1', postgres: 'WHERE "yolo"."User"."id" = 1', + snowflake: 'WHERE "yolo"."User"."id" = 1', mariadb: 'WHERE `yolo`.`User`.`id` = 1', mssql: 'WHERE [yolo].[User].[id] = 1' }); @@ -91,6 +92,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { name: 'here is a null char: \0' }, { default: "WHERE [name] = 'here is a null char: \\0'", + snowflake: 'WHERE "name" = \'here is a null char: \0\'', mssql: "WHERE [name] = N'here is a null char: \0'", sqlite: "WHERE `name` = 'here is a null char: \0'" }); @@ -115,6 +117,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { testsql('deleted', null, { default: '`deleted` IS NULL', postgres: '"deleted" IS NULL', + snowflake: '"deleted" IS NULL', mssql: '[deleted] IS NULL' }); @@ -152,6 +155,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { sqlite: "`field` = X'53657175656c697a65'", mariadb: "`field` = X'53657175656c697a65'", mysql: "`field` = X'53657175656c697a65'", + snowflake: '"field" = X\'53657175656c697a65\'', mssql: '[field] = 0x53657175656c697a65' }); }); @@ -495,6 +499,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { }, { default: "[date] BETWEEN '2013-01-01 00:00:00.000 +00:00' AND '2013-01-11 00:00:00.000 +00:00'", mysql: "`date` BETWEEN '2013-01-01 00:00:00' AND '2013-01-11 00:00:00'", + snowflake: '"date" BETWEEN \'2013-01-01 00:00:00\' AND \'2013-01-11 00:00:00\'', mariadb: "`date` BETWEEN '2013-01-01 00:00:00.000' AND '2013-01-11 00:00:00.000'" }); @@ -1137,6 +1142,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { }, { mariadb: "`username` REGEXP '^sw.*r$'", mysql: "`username` REGEXP '^sw.*r$'", + snowflake: '"username" REGEXP \'^sw.*r$\'', postgres: '"username" ~ \'^sw.*r$\'' }); }); @@ -1147,6 +1153,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { }, { mariadb: "`newline` REGEXP '^new\\nline$'", mysql: "`newline` REGEXP '^new\\nline$'", + snowflake: '"newline" REGEXP \'^new\nline$\'', postgres: '"newline" ~ \'^new\nline$\'' }); }); @@ -1157,6 +1164,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { }, { mariadb: "`username` NOT REGEXP '^sw.*r$'", mysql: "`username` NOT REGEXP '^sw.*r$'", + snowflake: '"username" NOT REGEXP \'^sw.*r$\'', postgres: '"username" !~ \'^sw.*r$\'' }); }); @@ -1167,6 +1175,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => { }, { mariadb: "`newline` NOT REGEXP '^new\\nline$'", mysql: "`newline` NOT REGEXP '^new\\nline$'", + snowflake: '"newline" NOT REGEXP \'^new\nline$\'', postgres: '"newline" !~ \'^new\nline$\'' }); }); diff --git a/types/lib/associations/belongs-to-many.d.ts b/types/lib/associations/belongs-to-many.d.ts index c82e9294d971..b7106ffb197b 100644 --- a/types/lib/associations/belongs-to-many.d.ts +++ b/types/lib/associations/belongs-to-many.d.ts @@ -9,8 +9,7 @@ import { Model, ModelCtor, ModelType, - Transactionable, - WhereOptions, + Transactionable } from '../model'; import { Association, AssociationScope, ForeignKeyOptions, ManyToManyOptions, MultiAssociationAccessors } from './base'; @@ -304,7 +303,7 @@ export interface BelongsToManyCreateAssociationMixinOptions extends CreateOption * @see Instance */ export type BelongsToManyCreateAssociationMixin = ( - values?: Model['_creationAttributes'], + values?: TModel['_creationAttributes'], options?: BelongsToManyCreateAssociationMixinOptions ) => Promise; diff --git a/types/lib/associations/has-many.d.ts b/types/lib/associations/has-many.d.ts index d98a96485af3..26b62444b13f 100644 --- a/types/lib/associations/has-many.d.ts +++ b/types/lib/associations/has-many.d.ts @@ -6,7 +6,7 @@ import { InstanceUpdateOptions, Model, ModelCtor, - Transactionable, + Transactionable } from '../model'; import { Association, ManyToManyOptions, MultiAssociationAccessors } from './base'; @@ -210,7 +210,7 @@ export interface HasManyCreateAssociationMixinOptions extends CreateOptions * @see Instance */ export type HasManyCreateAssociationMixin = ( - values?: Model['_creationAttributes'], + values?: TModel['_creationAttributes'], options?: HasManyCreateAssociationMixinOptions ) => Promise; diff --git a/types/lib/model.d.ts b/types/lib/model.d.ts index 4f760f7e8655..d6a0862f5138 100644 --- a/types/lib/model.d.ts +++ b/types/lib/model.d.ts @@ -146,18 +146,18 @@ export interface WhereOperators { */ /** Example: `[Op.eq]: 6,` becomes `= 6` */ - [Op.eq]?: null | boolean | string | number | Literal | WhereOperators; + [Op.eq]?: null | boolean | string | number | Literal | WhereOperators | Col; [Op.any]?: readonly (string | number | Literal)[] | Literal; /** Example: `[Op.gte]: 6,` becomes `>= 6` */ - [Op.gte]?: number | string | Date | Literal; + [Op.gte]?: number | string | Date | Literal | Col; /** Example: `[Op.lt]: 10,` becomes `< 10` */ - [Op.lt]?: number | string | Date | Literal; + [Op.lt]?: number | string | Date | Literal | Col; /** Example: `[Op.lte]: 10,` becomes `<= 10` */ - [Op.lte]?: number | string | Date | Literal; + [Op.lte]?: number | string | Date | Literal | Col; /** Example: `[Op.match]: Sequelize.fn('to_tsquery', 'fat & rat')` becomes `@@ to_tsquery('fat & rat')` */ [Op.match]?: Fn; @@ -225,7 +225,7 @@ export interface WhereOperators { [Op.contained]?: readonly (string | number)[] | Rangable; /** Example: `[Op.gt]: 6,` becomes `> 6` */ - [Op.gt]?: number | string | Date | Literal; + [Op.gt]?: number | string | Date | Literal | Col; /** * PG only @@ -2888,6 +2888,7 @@ export abstract class Model(): T; + public toJSON(): object; /** * Helper method to determine if a instance is "soft deleted". This is diff --git a/types/lib/sequelize.d.ts b/types/lib/sequelize.d.ts index a17d0fdb9021..e82b19ca3f96 100644 --- a/types/lib/sequelize.d.ts +++ b/types/lib/sequelize.d.ts @@ -365,6 +365,9 @@ export interface Options extends Logging { * The PostgreSQL `client_min_messages` session parameter. * Set to `false` to not override the database's default. * + * Deprecated in v7, please use the sequelize option "dialectOptions.clientMinMessages" instead + * + * @deprecated * @default 'warning' */ clientMinMessages?: string | boolean; @@ -390,6 +393,11 @@ export interface Options extends Logging { logQueryParameters?: boolean; retry?: RetryOptions; + + /** + * If defined the connection will use the provided schema instead of the default ("public"). + */ + schema?: string; } export interface QueryOptionsTransactionRequired { } @@ -426,6 +434,7 @@ export class Sequelize extends Hooks { * @param args All further arguments will be passed as arguments to the function */ public static fn: typeof fn; + public fn: typeof fn; /** * Creates a object representing a column in the DB. This is often useful in conjunction with @@ -434,6 +443,7 @@ export class Sequelize extends Hooks { * @param col The name of the column */ public static col: typeof col; + public col: typeof col; /** * Creates a object representing a call to the cast function. @@ -442,6 +452,7 @@ export class Sequelize extends Hooks { * @param type The type to cast it to */ public static cast: typeof cast; + public cast: typeof cast; /** * Creates a object representing a literal, i.e. something that will not be escaped. @@ -449,6 +460,7 @@ export class Sequelize extends Hooks { * @param val */ public static literal: typeof literal; + public literal: typeof literal; /** * An AND query @@ -456,6 +468,7 @@ export class Sequelize extends Hooks { * @param args Each argument will be joined by AND */ public static and: typeof and; + public and: typeof and; /** * An OR query @@ -463,6 +476,7 @@ export class Sequelize extends Hooks { * @param args Each argument will be joined by OR */ public static or: typeof or; + public or: typeof or; /** * Creates an object representing nested where conditions for postgres's json data-type. @@ -473,6 +487,7 @@ export class Sequelize extends Hooks { * ''". */ public static json: typeof json; + public json: typeof json; /** * A way of specifying attr = condition. @@ -493,6 +508,7 @@ export class Sequelize extends Hooks { * etc.) */ public static where: typeof where; + public where: typeof where; /** * A hook that is run before validation diff --git a/types/test/model.ts b/types/test/model.ts index a1bc9ea67c92..ee809ca22e4f 100644 --- a/types/test/model.ts +++ b/types/test/model.ts @@ -215,9 +215,22 @@ class FilmModelToJson extends Model implements FilmToJson { } const film = FilmModelToJson.build(); +class FilmModelExtendToJson extends Model implements FilmToJson { + id!: number; + name?: string; + + public toJSON() { + return { id: this.id } + } +} +const filmOverrideToJson = FilmModelExtendToJson.build(); + const result = film.toJSON(); expectTypeOf(result).toEqualTypeOf() type FilmNoNameToJson = Omit const resultDerived = film.toJSON(); -expectTypeOf(resultDerived).toEqualTypeOf() \ No newline at end of file +expectTypeOf(resultDerived).toEqualTypeOf() + +const resultOverrideToJson = filmOverrideToJson.toJSON(); +expectTypeOf(resultOverrideToJson).toEqualTypeOf(); diff --git a/types/test/sequelize.ts b/types/test/sequelize.ts index 150b61449e67..54931e58255d 100644 --- a/types/test/sequelize.ts +++ b/types/test/sequelize.ts @@ -1,4 +1,4 @@ -import { Config, Sequelize, Model, QueryTypes, ModelCtor } from 'sequelize'; +import { Config, Sequelize, Model, QueryTypes, ModelCtor, Op } from 'sequelize'; import { Fn } from 'sequelize/lib/utils'; Sequelize.useCLS({ @@ -20,6 +20,24 @@ export const sequelize = new Sequelize({ } }); +// static members +Sequelize.fn('max', Sequelize.col('age')) +Sequelize.literal('1-2') +Sequelize.cast('123', 'integer') +Sequelize.and() +Sequelize.or() +Sequelize.json('data.id') +Sequelize.where(Sequelize.col("ABS"), Op.is, null); + +// instance members +sequelize.fn('max', sequelize.col('age')) +sequelize.literal('1-2') +sequelize.cast('123', 'integer') +sequelize.and() +sequelize.or() +sequelize.json('data.id') +sequelize.where(sequelize.col("ABS"), Op.is, null); + const databaseName = sequelize.getDatabaseName(); const conn = sequelize.connectionManager; diff --git a/types/test/typescriptDocs/ModelInit.ts b/types/test/typescriptDocs/ModelInit.ts index 163cb8ec88ee..a8848a0bc1cd 100644 --- a/types/test/typescriptDocs/ModelInit.ts +++ b/types/test/typescriptDocs/ModelInit.ts @@ -2,17 +2,9 @@ * Keep this file in sync with the code in the "Usage" section in typescript.md */ import { - Sequelize, - Model, - ModelDefined, - DataTypes, - HasManyGetAssociationsMixin, - HasManyAddAssociationMixin, - HasManyHasAssociationMixin, - Association, - HasManyCountAssociationsMixin, - HasManyCreateAssociationMixin, - Optional, + Association, DataTypes, HasManyAddAssociationMixin, HasManyCountAssociationsMixin, + HasManyCreateAssociationMixin, HasManyGetAssociationsMixin, HasManyHasAssociationMixin, Model, + ModelDefined, Optional, Sequelize } from "sequelize"; const sequelize = new Sequelize("mysql://root:asd123@localhost:3306/mydb"); @@ -59,6 +51,7 @@ interface ProjectAttributes { id: number; ownerId: number; name: string; + description?: string; } interface ProjectCreationAttributes extends Optional {} @@ -114,6 +107,10 @@ Project.init( type: new DataTypes.STRING(128), allowNull: false, }, + description: { + type: new DataTypes.STRING(128), + allowNull: true, + }, }, { sequelize, @@ -204,6 +201,7 @@ async function doStuffWithUser() { const project = await newUser.createProject({ name: "first!", + ownerId: 123, }); const ourUser = await User.findByPk(1, { diff --git a/types/test/where.ts b/types/test/where.ts index cd178333f205..c52467a895be 100644 --- a/types/test/where.ts +++ b/types/test/where.ts @@ -45,10 +45,15 @@ expectTypeOf({ expectTypeOf({ [Op.eq]: 6, // = 6 + [Op.eq]: Sequelize.col('SOME_COL'), // = [Op.gt]: 6, // > 6 + [Op.gt]: Sequelize.col('SOME_COL'), // > [Op.gte]: 6, // >= 6 + [Op.gte]: Sequelize.col('SOME_COL'), // >= [Op.lt]: 10, // < 10 + [Op.lt]: Sequelize.col('SOME_COL'), // < [Op.lte]: 10, // <= 10 + [Op.lte]: Sequelize.col('SOME_COL'), // <= [Op.ne]: 20, // != 20 [Op.not]: true, // IS NOT TRUE [Op.is]: null, // IS NULL @@ -222,12 +227,18 @@ MyModel.findAll({ where: { id: { // casting here to check a missing operator is not accepted as field name + [Op.eq]: 6, // id = 6 + [Op.eq]: Sequelize.col('SOME_COL'), // id = [Op.and]: { a: 5 }, // AND (a = 5) [Op.or]: [{ a: 5 }, { a: 6 }], // (a = 5 OR a = 6) [Op.gt]: 6, // id > 6 + [Op.gt]: Sequelize.col('SOME_COL'), // id > [Op.gte]: 6, // id >= 6 + [Op.gte]: Sequelize.col('SOME_COL'), // id >= [Op.lt]: 10, // id < 10 + [Op.lt]: Sequelize.col('SOME_COL'), // id < [Op.lte]: 10, // id <= 10 + [Op.lte]: Sequelize.col('SOME_COL'), // id <= [Op.ne]: 20, // id != 20 [Op.between]: [6, 10] || [new Date(), new Date()] || ["2020-01-01", "2020-12-31"], // BETWEEN 6 AND 10 [Op.notBetween]: [11, 15], // NOT BETWEEN 11 AND 15 diff --git a/yarn.lock b/yarn.lock index f5214447ba4c..f6d0cc87a8b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,7 +9,12 @@ dependencies: tslib "^2.0.0" -"@azure/core-auth@^1.1.4": +"@azure/core-asynciterator-polyfill@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.0.tgz#dcccebb88406e5c76e0e1d52e8cc4c43a68b3ee7" + integrity sha512-kmv8CGrPfN9SwMwrkiBK9VTQYxdFQEGe0BmQk+M8io56P9KNzpAxcWE/1fxJj7uouwN4kXF0BHW8DNlgx+wtCg== + +"@azure/core-auth@^1.1.4", "@azure/core-auth@^1.3.0": version "1.3.2" resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.3.2.tgz#6a2c248576c26df365f6c7881ca04b7f6d08e3d0" integrity sha512-7CU6DmCHIZp5ZPiZ9r3J17lTKMmYsm/zGvNkjArQwPkrLlZ1TZ+EUYfGgh2X31OLMVAQCTJZW4cXHJi02EbJnA== @@ -17,6 +22,60 @@ "@azure/abort-controller" "^1.0.0" tslib "^2.2.0" +"@azure/core-http@^2.0.0": + version "2.2.2" + resolved "https://registry.yarnpkg.com/@azure/core-http/-/core-http-2.2.2.tgz#573798f087d808d39aa71fd7c52b8d7b89f440da" + integrity sha512-V1DdoO9V/sFimKpdWoNBgsE+QUjQgpXYnxrTdUp5RyhsTJjvEVn/HKmTQXIHuLUUo6IyIWj+B+Dg4VaXse9dIA== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-asynciterator-polyfill" "^1.0.0" + "@azure/core-auth" "^1.3.0" + "@azure/core-tracing" "1.0.0-preview.13" + "@azure/logger" "^1.0.0" + "@types/node-fetch" "^2.5.0" + "@types/tunnel" "^0.0.3" + form-data "^4.0.0" + node-fetch "^2.6.0" + process "^0.11.10" + tough-cookie "^4.0.0" + tslib "^2.2.0" + tunnel "^0.0.6" + uuid "^8.3.0" + xml2js "^0.4.19" + +"@azure/core-lro@^2.2.0": + version "2.2.2" + resolved "https://registry.yarnpkg.com/@azure/core-lro/-/core-lro-2.2.2.tgz#1f81a712d6bea6912918c5157553e6c7883e08d9" + integrity sha512-pn30b+HyJHg0+G4ZRgpL3BJa6LQnKdKl1X4JDMpuVsX+kPxs2FNoweNqD3Li199ROroIvFbi6pE29y0J2vvyIg== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-tracing" "1.0.0-preview.13" + "@azure/logger" "^1.0.0" + tslib "^2.2.0" + +"@azure/core-paging@^1.1.1": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@azure/core-paging/-/core-paging-1.2.0.tgz#3754da429e8687bdc3613c750e79a564582e802b" + integrity sha512-ZX1bCjm/MjKPCN6kQD/9GJErYSoKA8YWp6YWoo5EIzcTWlSBLXu3gNaBTUl8usGl+UShiKo7b4Gdy1NSTIlpZg== + dependencies: + "@azure/core-asynciterator-polyfill" "^1.0.0" + tslib "^2.2.0" + +"@azure/core-tracing@1.0.0-preview.13": + version "1.0.0-preview.13" + resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz#55883d40ae2042f6f1e12b17dd0c0d34c536d644" + integrity sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ== + dependencies: + "@opentelemetry/api" "^1.0.1" + tslib "^2.2.0" + +"@azure/logger@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.3.tgz#6e36704aa51be7d4a1bae24731ea580836293c96" + integrity sha512-aK4s3Xxjrx3daZr3VylxejK3vG5ExXck5WOHDJ8in/k9AqlfIyFMMT1uG7u8mNjX+QRILTIn0/Xgschfh/dQ9g== + dependencies: + tslib "^2.2.0" + "@azure/ms-rest-azure-env@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@azure/ms-rest-azure-env/-/ms-rest-azure-env-1.1.2.tgz#8505873afd4a1227ec040894a64fdd736b4a101f" @@ -45,6 +104,20 @@ "@azure/ms-rest-js" "^1.8.7" adal-node "^0.1.28" +"@azure/storage-blob@^12.5.0": + version "12.8.0" + resolved "https://registry.yarnpkg.com/@azure/storage-blob/-/storage-blob-12.8.0.tgz#97b7ecc6c7b17bcbaf0281c79c16af6f512d6130" + integrity sha512-c8+Wz19xauW0bGkTCoqZH4dYfbtBniPiGiRQOn1ca6G5jsjr4azwaTk9gwjVY8r3vY2Taf95eivLzipfIfiS4A== + dependencies: + "@azure/abort-controller" "^1.0.0" + "@azure/core-http" "^2.0.0" + "@azure/core-lro" "^2.2.0" + "@azure/core-paging" "^1.1.1" + "@azure/core-tracing" "1.0.0-preview.13" + "@azure/logger" "^1.0.0" + events "^3.0.0" + tslib "^2.2.0" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431" @@ -53,9 +126,9 @@ "@babel/highlight" "^7.16.0" "@babel/compat-data@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.0.tgz#ea269d7f78deb3a7826c39a4048eecda541ebdaa" - integrity sha512-DGjt2QZse5SGd9nfOSqO4WLJ8NN/oHkijbXbPrxuoJO3oIPJL3TciZs9FX+cOHNiY9E9l0opL8g7BmLe3T+9ew== + version "7.16.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.4.tgz#081d6bbc336ec5c2435c6346b2ae1fb98b5ac68e" + integrity sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q== "@babel/core@^7.7.5": version "7.16.0" @@ -88,13 +161,13 @@ source-map "^0.5.0" "@babel/helper-compilation-targets@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.0.tgz#01d615762e796c17952c29e3ede9d6de07d235a8" - integrity sha512-S7iaOT1SYlqK0sQaCi21RX4+13hmdmnxIEAnQUB/eh7GeAnRjOUgTYpLkUOiRXzD+yog1JxP0qyAQZ7ZxVxLVg== + version "7.16.3" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz#5b480cd13f68363df6ec4dc8ac8e2da11363cbf0" + integrity sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA== dependencies: "@babel/compat-data" "^7.16.0" "@babel/helper-validator-option" "^7.14.5" - browserslist "^4.16.6" + browserslist "^4.17.5" semver "^6.3.0" "@babel/helper-function-name@^7.16.0": @@ -190,12 +263,12 @@ integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== "@babel/helpers@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.0.tgz#875519c979c232f41adfbd43a3b0398c2e388183" - integrity sha512-dVRM0StFMdKlkt7cVcGgwD8UMaBfWJHl3A83Yfs8GQ3MO0LHIIIMvK7Fa0RGOGUQ10qikLaX6D7o5htcQWgTMQ== + version "7.16.3" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.3.tgz#27fc64f40b996e7074dc73128c3e5c3e7f55c43c" + integrity sha512-Xn8IhDlBPhvYTvgewPKawhADichOsbkZuzN7qz2BusOM0brChsyXMDJvldWaYMMUNiCQdQzNEioXTp3sC8Nt8w== dependencies: "@babel/template" "^7.16.0" - "@babel/traverse" "^7.16.0" + "@babel/traverse" "^7.16.3" "@babel/types" "^7.16.0" "@babel/highlight@^7.16.0": @@ -207,17 +280,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.16.0": - version "7.16.2" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.2.tgz#3723cd5c8d8773eef96ce57ea1d9b7faaccd12ac" - integrity sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw== - -"@babel/runtime@^7.11.2": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.0.tgz#e27b977f2e2088ba24748bf99b5e1dece64e4f0b" - integrity sha512-Nht8L0O8YCktmsDV6FqFue7vQLRx3Hb0B37lS5y0jDRqRxlBG4wIJHnf9/bgSE2UyipKFA01YtS+npRdTWBUyw== - dependencies: - regenerator-runtime "^0.13.4" +"@babel/parser@^7.16.0", "@babel/parser@^7.16.3": + version "7.16.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.4.tgz#d5f92f57cf2c74ffe9b37981c0e72fee7311372e" + integrity sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng== "@babel/template@^7.16.0": version "7.16.0" @@ -228,17 +294,17 @@ "@babel/parser" "^7.16.0" "@babel/types" "^7.16.0" -"@babel/traverse@^7.16.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.0.tgz#965df6c6bfc0a958c1e739284d3c9fa4a6e3c45b" - integrity sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ== +"@babel/traverse@^7.16.0", "@babel/traverse@^7.16.3": + version "7.16.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.3.tgz#f63e8a938cc1b780f66d9ed3c54f532ca2d14787" + integrity sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag== dependencies: "@babel/code-frame" "^7.16.0" "@babel/generator" "^7.16.0" "@babel/helper-function-name" "^7.16.0" "@babel/helper-hoist-variables" "^7.16.0" "@babel/helper-split-export-declaration" "^7.16.0" - "@babel/parser" "^7.16.0" + "@babel/parser" "^7.16.3" "@babel/types" "^7.16.0" debug "^4.1.0" globals "^11.1.0" @@ -251,152 +317,213 @@ "@babel/helper-validator-identifier" "^7.15.7" to-fast-properties "^2.0.0" -"@commitlint/cli@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-11.0.0.tgz#698199bc52afed50aa28169237758fa14a67b5d3" - integrity sha512-YWZWg1DuqqO5Zjh7vUOeSX76vm0FFyz4y0cpGMFhrhvUi5unc4IVfCXZ6337R9zxuBtmveiRuuhQqnRRer+13g== - dependencies: - "@babel/runtime" "^7.11.2" - "@commitlint/format" "^11.0.0" - "@commitlint/lint" "^11.0.0" - "@commitlint/load" "^11.0.0" - "@commitlint/read" "^11.0.0" - chalk "4.1.0" - core-js "^3.6.1" - get-stdin "8.0.0" +"@commitlint/cli@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-15.0.0.tgz#8e78e86ee2b6955c1a5d140e734a6c171ce367ee" + integrity sha512-Y5xmDCweytqzo4N4lOI2YRiuX35xTjcs8n5hUceBH8eyK0YbwtgWX50BJOH2XbkwEmII9blNhlBog6AdQsqicg== + dependencies: + "@commitlint/format" "^15.0.0" + "@commitlint/lint" "^15.0.0" + "@commitlint/load" "^15.0.0" + "@commitlint/read" "^15.0.0" + "@commitlint/types" "^15.0.0" lodash "^4.17.19" resolve-from "5.0.0" resolve-global "1.0.0" - yargs "^15.1.0" + yargs "^17.0.0" -"@commitlint/config-angular-type-enum@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/config-angular-type-enum/-/config-angular-type-enum-11.0.0.tgz#7a7f6982e45d3696d72eb343a5d1dc23b2f003e0" - integrity sha512-dSyxdkU36aEgDUWBSiM5lsZ/h2K7uCyKf+A5Sf3+Z5JhcLD9GzTo5W+c8KgwTBdL39dkL7sN+EVgsXNjW99pJg== +"@commitlint/config-angular-type-enum@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/config-angular-type-enum/-/config-angular-type-enum-15.0.0.tgz#52a2b6c90e577d0cd794231d9ee24fc6d96bf675" + integrity sha512-KBGoII2yo76KtbKbeCym5PxCt5CZvti7YbCEGOF5GiyZd/9AaJur/UhbzX3pcoLMgXd9u3Ru+qydm79TlRLuJA== -"@commitlint/config-angular@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/config-angular/-/config-angular-11.0.0.tgz#c1cc1dd902a4b9d2a5c072ff38e3ace9be7138e0" - integrity sha512-H8QSEOmfRsPW0Iehid5fY7NZ2HXmyKC6Q83MLFf9KRnmCcbgJtH+faECtqlvPntayO3CYbA4UenIerOaQ0vOAg== +"@commitlint/config-angular@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/config-angular/-/config-angular-15.0.0.tgz#e6f174ae46a7d122fa628a58c867a2a93082c8f0" + integrity sha512-1gpyAZkGB+v9hTvw4G8AGU7vzq49/pANifShUsoyuSLAmHzxC3YgE+ZyqlVoB+T6gjE90NXjUQbLmNpi/7ZFYg== dependencies: - "@commitlint/config-angular-type-enum" "^11.0.0" + "@commitlint/config-angular-type-enum" "^15.0.0" -"@commitlint/ensure@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/ensure/-/ensure-11.0.0.tgz#3e796b968ab5b72bc6f8a6040076406306c987fb" - integrity sha512-/T4tjseSwlirKZdnx4AuICMNNlFvRyPQimbZIOYujp9DSO6XRtOy9NrmvWujwHsq9F5Wb80QWi4WMW6HMaENug== +"@commitlint/ensure@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/ensure/-/ensure-15.0.0.tgz#06a63738e2393970a085b428e6cf80fa1fe76f48" + integrity sha512-7DV4iNIald3vycwaWBNGk5FbonaNzOlU8nBe5m5AgU2dIeNKuXwLm+zzJzG27j0Ho56rgz//3F6RIvmsoxY9ZA== dependencies: - "@commitlint/types" "^11.0.0" + "@commitlint/types" "^15.0.0" lodash "^4.17.19" -"@commitlint/execute-rule@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-11.0.0.tgz#3ed60ab7a33019e58d90e2d891b75d7df77b4b4d" - integrity sha512-g01p1g4BmYlZ2+tdotCavrMunnPFPhTzG1ZiLKTCYrooHRbmvqo42ZZn4QMStUEIcn+jfLb6BRZX3JzIwA1ezQ== +"@commitlint/execute-rule@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-15.0.0.tgz#6bff7962df38e89ff9fdbc00abd79b8849c7e9f9" + integrity sha512-pyE4ApxjbWhb1TXz5vRiGwI2ssdMMgZbaaheZq1/7WC0xRnqnIhE1yUC1D2q20qPtvkZPstTYvMiRVtF+DvjUg== -"@commitlint/format@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/format/-/format-11.0.0.tgz#ac47b0b9ca46540c0082c721b290794e67bdc51b" - integrity sha512-bpBLWmG0wfZH/svzqD1hsGTpm79TKJWcf6EXZllh2J/LSSYKxGlv967lpw0hNojme0sZd4a/97R3qA2QHWWSLg== +"@commitlint/format@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/format/-/format-15.0.0.tgz#10935180913de9384bea4c9217f4c6c5ee100ab3" + integrity sha512-bPhAfqwRhPk92WiuY0ktEJNpRRHSCd+Eg1MdhGyL9Bl3U25E5zvuInA+dNctnzZiOBSH/37ZaD0eOKCpQE6acg== dependencies: - "@commitlint/types" "^11.0.0" + "@commitlint/types" "^15.0.0" chalk "^4.0.0" -"@commitlint/is-ignored@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/is-ignored/-/is-ignored-11.0.0.tgz#7b803eda56276dbe7fec51eb1510676198468f39" - integrity sha512-VLHOUBN+sOlkYC4tGuzE41yNPO2w09sQnOpfS+pSPnBFkNUUHawEuA44PLHtDvQgVuYrMAmSWFQpWabMoP5/Xg== - dependencies: - "@commitlint/types" "^11.0.0" - semver "7.3.2" - -"@commitlint/lint@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/lint/-/lint-11.0.0.tgz#01e062cd1b0e7c3d756aa2c246462e0b6a3348a4" - integrity sha512-Q8IIqGIHfwKr8ecVZyYh6NtXFmKw4YSEWEr2GJTB/fTZXgaOGtGFZDWOesCZllQ63f1s/oWJYtVv5RAEuwN8BQ== - dependencies: - "@commitlint/is-ignored" "^11.0.0" - "@commitlint/parse" "^11.0.0" - "@commitlint/rules" "^11.0.0" - "@commitlint/types" "^11.0.0" - -"@commitlint/load@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-11.0.0.tgz#f736562f0ffa7e773f8808fea93319042ee18211" - integrity sha512-t5ZBrtgvgCwPfxmG811FCp39/o3SJ7L+SNsxFL92OR4WQxPcu6c8taD0CG2lzOHGuRyuMxZ7ps3EbngT2WpiCg== - dependencies: - "@commitlint/execute-rule" "^11.0.0" - "@commitlint/resolve-extends" "^11.0.0" - "@commitlint/types" "^11.0.0" - chalk "4.1.0" +"@commitlint/is-ignored@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/is-ignored/-/is-ignored-15.0.0.tgz#382bf9f6f8d810f2ffc59ccc527f4389eadd7949" + integrity sha512-edtnkf2QZ/7e/YCJDgn1WDw9wfF1WfOitW5YEoSOb4SxjJEb/oE87kxNPZ2j8mnDMuunspcMfGHeg6fRlwaEWg== + dependencies: + "@commitlint/types" "^15.0.0" + semver "7.3.5" + +"@commitlint/lint@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/lint/-/lint-15.0.0.tgz#a93b8896fb25b05ab2ed0246d365f4908654588d" + integrity sha512-hUi2+Im/2dJ5FBvWnodypTkg+5haCgsDzB0fyMApWLUA1IucYUAqRCQCW5em1Mhk9Crw1pd5YzFNikhIclkqCw== + dependencies: + "@commitlint/is-ignored" "^15.0.0" + "@commitlint/parse" "^15.0.0" + "@commitlint/rules" "^15.0.0" + "@commitlint/types" "^15.0.0" + +"@commitlint/load@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-15.0.0.tgz#5bd391c1387aafe92b54cf2a86b76a5228fcf4ef" + integrity sha512-Ak1YPeOhvxmY3ioe0o6m1yLGvUAYb4BdfGgShU8jiTCmU3Mnmms0Xh/kfQz8AybhezCC3AmVTyBLaBZxOHR8kg== + dependencies: + "@commitlint/execute-rule" "^15.0.0" + "@commitlint/resolve-extends" "^15.0.0" + "@commitlint/types" "^15.0.0" + "@endemolshinegroup/cosmiconfig-typescript-loader" "^3.0.2" + chalk "^4.0.0" cosmiconfig "^7.0.0" lodash "^4.17.19" resolve-from "^5.0.0" + typescript "^4.4.3" -"@commitlint/message@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/message/-/message-11.0.0.tgz#83554c3cbbc884fd07b473593bc3e94bcaa3ee05" - integrity sha512-01ObK/18JL7PEIE3dBRtoMmU6S3ecPYDTQWWhcO+ErA3Ai0KDYqV5VWWEijdcVafNpdeUNrEMigRkxXHQLbyJA== +"@commitlint/message@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/message/-/message-15.0.0.tgz#98a38aca1b3cd996a0fcdbd9ad67e9039df60b0a" + integrity sha512-L8euabzboKavPuDJsdIYAY2wx97LbiGEYsckMo6NmV8pOun50c8hQx6ouXFSAx4pp+mX9yUGmMiVqfrk2LKDJQ== -"@commitlint/parse@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/parse/-/parse-11.0.0.tgz#d18b08cf67c35d02115207d7009306a2e8e7c901" - integrity sha512-DekKQAIYWAXIcyAZ6/PDBJylWJ1BROTfDIzr9PMVxZRxBPc1gW2TG8fLgjZfBP5mc0cuthPkVi91KQQKGri/7A== +"@commitlint/parse@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/parse/-/parse-15.0.0.tgz#cac77b7514748b8d01d00c0e67d5e54c695c302c" + integrity sha512-7fweM67tZfBNS7zw1KTuuT5K2u9nGytUJqFqT/1Ln3Na9cBCsoAqR47mfsNOTlRCgGwakm4xiQ7BpS2gN0OGuw== dependencies: - conventional-changelog-angular "^5.0.0" - conventional-commits-parser "^3.0.0" + "@commitlint/types" "^15.0.0" + conventional-changelog-angular "^5.0.11" + conventional-commits-parser "^3.2.2" -"@commitlint/read@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/read/-/read-11.0.0.tgz#f24240548c63587bba139fa5a364cab926077016" - integrity sha512-37V0V91GSv0aDzMzJioKpCoZw6l0shk7+tRG8RkW1GfZzUIytdg3XqJmM+IaIYpaop0m6BbZtfq+idzUwJnw7g== +"@commitlint/read@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/read/-/read-15.0.0.tgz#da839f3b4d49b05586a9cd2666cc8c4a36b9ec91" + integrity sha512-5yI1o2HKZFVe7RTjL7IhuhHMKar/MDNY34vEHqqz9gMI7BK/rdP8uVb4Di1efl2V0UPnwID0nPKWESjQ8Ti0gw== dependencies: - "@commitlint/top-level" "^11.0.0" - fs-extra "^9.0.0" + "@commitlint/top-level" "^15.0.0" + "@commitlint/types" "^15.0.0" + fs-extra "^10.0.0" git-raw-commits "^2.0.0" -"@commitlint/resolve-extends@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-11.0.0.tgz#158ecbe27d4a2a51d426111a01478e216fbb1036" - integrity sha512-WinU6Uv6L7HDGLqn/To13KM1CWvZ09VHZqryqxXa1OY+EvJkfU734CwnOEeNlSCK7FVLrB4kmodLJtL1dkEpXw== +"@commitlint/resolve-extends@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-15.0.0.tgz#baf21227e2ac52cef546ec35dd6732e9b0b6e57c" + integrity sha512-7apfRJjgJsKja7lHsPfEFixKjA/fk/UeD3owkOw1174yYu4u8xBDLSeU3IinGPdMuF9m245eX8wo7vLUy+EBSg== dependencies: import-fresh "^3.0.0" lodash "^4.17.19" resolve-from "^5.0.0" resolve-global "^1.0.0" -"@commitlint/rules@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/rules/-/rules-11.0.0.tgz#bdb310cc6fc55c9f8d7d917a22b69055c535c375" - integrity sha512-2hD9y9Ep5ZfoNxDDPkQadd2jJeocrwC4vJ98I0g8pNYn/W8hS9+/FuNpolREHN8PhmexXbkjrwyQrWbuC0DVaA== +"@commitlint/rules@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/rules/-/rules-15.0.0.tgz#326370abc004492fcb5543198d1d55b14e25e3c8" + integrity sha512-SqXfp6QUlwBS+0IZm4FEA/NmmAwcFQIkG3B05BtemOVWXQdZ8j1vV6hDwvA9oMPCmUSrrGpHOtZK7HaHhng2yA== dependencies: - "@commitlint/ensure" "^11.0.0" - "@commitlint/message" "^11.0.0" - "@commitlint/to-lines" "^11.0.0" - "@commitlint/types" "^11.0.0" + "@commitlint/ensure" "^15.0.0" + "@commitlint/message" "^15.0.0" + "@commitlint/to-lines" "^15.0.0" + "@commitlint/types" "^15.0.0" + execa "^5.0.0" -"@commitlint/to-lines@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/to-lines/-/to-lines-11.0.0.tgz#86dea151c10eea41e39ea96fa4de07839258a7fe" - integrity sha512-TIDTB0Y23jlCNubDROUVokbJk6860idYB5cZkLWcRS9tlb6YSoeLn1NLafPlrhhkkkZzTYnlKYzCVrBNVes1iw== +"@commitlint/to-lines@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/to-lines/-/to-lines-15.0.0.tgz#b86ac98f319688990ecc2e09227fadf591b65c92" + integrity sha512-mY3MNA9ujPqVpiJjTYG9MDsYCobue5PJFO0MfcIzS1mCVvngH8ZFTPAh1fT5t+t1h876boS88+9WgqjRvbYItw== -"@commitlint/top-level@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/top-level/-/top-level-11.0.0.tgz#bb2d1b6e5ed3be56874633b59e1f7de118c32783" - integrity sha512-O0nFU8o+Ws+py5pfMQIuyxOtfR/kwtr5ybqTvR+C2lUPer2x6lnQU+OnfD7hPM+A+COIUZWx10mYQvkR3MmtAA== +"@commitlint/top-level@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/top-level/-/top-level-15.0.0.tgz#467ec8377e81dfc916e1a20a27558862be1a4254" + integrity sha512-7Gz3t7xcuuUw1d1Nou6YLaztzp2Em+qZ6YdCzrqYc+aquca3Vt0O696nuiBDU/oE+tls4Hx2CNpAbWhTgEwB5A== dependencies: find-up "^5.0.0" -"@commitlint/types@^11.0.0": - version "11.0.0" - resolved "https://registry.yarnpkg.com/@commitlint/types/-/types-11.0.0.tgz#719cf05fcc1abb6533610a2e0f5dd1e61eac14fe" - integrity sha512-VoNqai1vR5anRF5Tuh/+SWDFk7xi7oMwHrHrbm1BprYXjB2RJsWLhUrStMssDxEl5lW/z3EUdg8RvH/IUBccSQ== +"@commitlint/types@^15.0.0": + version "15.0.0" + resolved "https://registry.yarnpkg.com/@commitlint/types/-/types-15.0.0.tgz#46fa7bda3e6340caf3e3a2e415bcb78ff0195eed" + integrity sha512-OMSLX+QJnyNoTwws54ULv9sOvuw9GdVezln76oyUd4YbMMJyaav62aSXDuCdWyL2sm9hTkSzyEi52PNaIj/vqw== + dependencies: + chalk "^4.0.0" + +"@dabh/diagnostics@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31" + integrity sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q== + dependencies: + colorspace "1.1.x" + enabled "2.0.x" + kuler "^2.0.0" + +"@endemolshinegroup/cosmiconfig-typescript-loader@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz#eea4635828dde372838b0909693ebd9aafeec22d" + integrity sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA== + dependencies: + lodash.get "^4" + make-error "^1" + ts-node "^9" + tslib "^2" + +"@es-joy/jsdoccomment@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.12.0.tgz#47de05d86e9728ae3a5f1c57d6e9b63b07c6dc98" + integrity sha512-Gw4/j9v36IKY8ET+W0GoOzrRw17xjf21EIFFRL3zx21fF5MnqmeNpNi+PU/LKjqLpPb2Pw2XdlJbYM31VVo/PQ== + dependencies: + comment-parser "1.2.4" + esquery "^1.4.0" + jsdoc-type-pratt-parser "2.0.0" + +"@eslint/eslintrc@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.0.4.tgz#dfe0ff7ba270848d10c5add0715e04964c034b31" + integrity sha512-h8Vx6MdxwWI2WM8/zREHMoqdgLNXEL4QX3MWSVMdyNJGvXVOs+6lp+m2hc3FnuMHDc4poxFNI20vCk0OmI4G0Q== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.0.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" "@gar/promisify@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.2.tgz#30aa825f11d438671d585bd44e7fd564535fc210" integrity sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw== +"@humanwhocodes/config-array@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.6.0.tgz#b5621fdb3b32309d2d16575456cbc277fa8f021a" + integrity sha512-JQlEKbcgEUjBFhLIF4iqM7u/9lwgHRBcpHrmUNCALK0Q3amXN6lxdoXLnF0sm11E9VqTmBALR87IlUg1bZ8A9A== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + "@isaacs/string-locale-compare@^1.0.1", "@isaacs/string-locale-compare@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz#291c227e93fd407a96ecd59879a35809120e432b" @@ -488,9 +615,9 @@ integrity sha512-3BGrt6FLjqM6br5AhWRKTr3u5GIVkjRYeAFrMp3HjnfICrg4xOrVRwFavKT6tsp++bq5dluL5t8ME/Nha/6c1Q== "@npmcli/config@^2.3.0": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@npmcli/config/-/config-2.3.1.tgz#41d80ce272831461b5cb158afa110525d4be0fed" - integrity sha512-F/8R/Zqun8682TgaCILUNoaVfd1LVaYZ/jcVt9KWzfKpzcPus1zEApAl54PqVqVJbNq6f01QTDQHD6L/n56BXw== + version "2.3.2" + resolved "https://registry.yarnpkg.com/@npmcli/config/-/config-2.3.2.tgz#6027efc132fcc809abef749c2f2e13dc4dcd6e0b" + integrity sha512-2/9dj143BFgQR8qxJbYptd8k+4+Po2uHYq3H6498ynZcRu4LrsDlngov5HGrvo2+f0pe0fBJwDEP2rRtaW8bkw== dependencies: ini "^2.0.0" mkdirp-infer-owner "^2.0.0" @@ -697,16 +824,21 @@ dependencies: "@octokit/openapi-types" "^11.2.0" -"@semantic-release/commit-analyzer@^8.0.0": - version "8.0.1" - resolved "https://registry.yarnpkg.com/@semantic-release/commit-analyzer/-/commit-analyzer-8.0.1.tgz#5d2a37cd5a3312da0e3ac05b1ca348bf60b90bca" - integrity sha512-5bJma/oB7B4MtwUkZC2Bf7O1MHfi4gWe4mA+MIQ3lsEV0b422Bvl1z5HRpplDnMLHH3EXMoRdEng6Ds5wUqA3A== +"@opentelemetry/api@^1.0.1": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.0.3.tgz#13a12ae9e05c2a782f7b5e84c3cbfda4225eaf80" + integrity sha512-puWxACExDe9nxbBB3lOymQFrLYml2dVOrd7USiVRnSbgXE+KwBu+HxFvxrzfqsiSda9IWsXJG1ef7C1O2/GmKQ== + +"@semantic-release/commit-analyzer@^9.0.2": + version "9.0.2" + resolved "https://registry.yarnpkg.com/@semantic-release/commit-analyzer/-/commit-analyzer-9.0.2.tgz#a78e54f9834193b55f1073fa6258eecc9a545e03" + integrity sha512-E+dr6L+xIHZkX4zNMe6Rnwg4YQrWNXK+rNsvwOPpdFppvZO1olE2fIgWhv89TkQErygevbjsZFSIxp+u6w2e5g== dependencies: conventional-changelog-angular "^5.0.0" conventional-commits-filter "^2.0.0" - conventional-commits-parser "^3.0.7" + conventional-commits-parser "^3.2.3" debug "^4.0.0" - import-from "^3.0.0" + import-from "^4.0.0" lodash "^4.17.4" micromatch "^4.0.2" @@ -715,10 +847,15 @@ resolved "https://registry.yarnpkg.com/@semantic-release/error/-/error-2.2.0.tgz#ee9d5a09c9969eade1ec864776aeda5c5cddbbf0" integrity sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg== -"@semantic-release/github@^7.0.0": - version "7.2.3" - resolved "https://registry.yarnpkg.com/@semantic-release/github/-/github-7.2.3.tgz#20a83abd42dca43d97f03553de970eac72856c85" - integrity sha512-lWjIVDLal+EQBzy697ayUNN8MoBpp+jYIyW2luOdqn5XBH4d9bQGfTnjuLyzARZBHejqh932HVjiH/j4+R7VHw== +"@semantic-release/error@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@semantic-release/error/-/error-3.0.0.tgz#30a3b97bbb5844d695eb22f9d3aa40f6a92770c2" + integrity sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw== + +"@semantic-release/github@^8.0.0": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@semantic-release/github/-/github-8.0.2.tgz#80114a41f6ec8ab6c0d38a436b48ff3f2223ab16" + integrity sha512-wIbfhOeuxlYzMTjtSAa2xgr54n7ZuPAS2gadyTWBpUt2PNAPgla7A6XxCXJnaKPgfVF0iFfSk3B+KlVKk6ByVg== dependencies: "@octokit/rest" "^18.0.0" "@semantic-release/error" "^2.2.0" @@ -728,21 +865,21 @@ dir-glob "^3.0.0" fs-extra "^10.0.0" globby "^11.0.0" - http-proxy-agent "^4.0.0" + http-proxy-agent "^5.0.0" https-proxy-agent "^5.0.0" issue-parser "^6.0.0" lodash "^4.17.4" - mime "^2.4.3" + mime "^3.0.0" p-filter "^2.0.0" p-retry "^4.0.0" url-join "^4.0.0" -"@semantic-release/npm@^7.0.0": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@semantic-release/npm/-/npm-7.1.3.tgz#1d64c41ff31b100299029c766ecc4d1f03aa5f5b" - integrity sha512-x52kQ/jR09WjuWdaTEHgQCvZYMOTx68WnS+TZ4fya5ZAJw4oRtJETtrvUw10FdfM28d/keInQdc66R1Gw5+OEQ== +"@semantic-release/npm@^8.0.0": + version "8.0.3" + resolved "https://registry.yarnpkg.com/@semantic-release/npm/-/npm-8.0.3.tgz#69378ce529bbd263aa8fc899b2d0f874114e0302" + integrity sha512-Qbg7x/O1t3sJqsv2+U0AL4Utgi/ymlCiUdt67Ftz9HL9N8aDML4t2tE0T9MBaYdqwD976hz57DqHHXKVppUBoA== dependencies: - "@semantic-release/error" "^2.2.0" + "@semantic-release/error" "^3.0.0" aggregate-error "^3.0.0" execa "^5.0.0" fs-extra "^10.0.0" @@ -756,47 +893,47 @@ semver "^7.1.2" tempy "^1.0.0" -"@semantic-release/release-notes-generator@^9.0.0": - version "9.0.3" - resolved "https://registry.yarnpkg.com/@semantic-release/release-notes-generator/-/release-notes-generator-9.0.3.tgz#d541221c6512e9619f25ba8079527e34288e6904" - integrity sha512-hMZyddr0u99OvM2SxVOIelHzly+PP3sYtJ8XOLHdMp8mrluN5/lpeTnIO27oeCYdupY/ndoGfvrqDjHqkSyhVg== +"@semantic-release/release-notes-generator@^10.0.0": + version "10.0.3" + resolved "https://registry.yarnpkg.com/@semantic-release/release-notes-generator/-/release-notes-generator-10.0.3.tgz#85f7ca78bfa6b01fb5fda0ac48112855d69171dc" + integrity sha512-k4x4VhIKneOWoBGHkx0qZogNjCldLPRiAjnIpMnlUh6PtaWXp/T+C9U7/TaNDDtgDa5HMbHl4WlREdxHio6/3w== dependencies: conventional-changelog-angular "^5.0.0" - conventional-changelog-writer "^4.0.0" + conventional-changelog-writer "^5.0.0" conventional-commits-filter "^2.0.0" - conventional-commits-parser "^3.0.0" + conventional-commits-parser "^3.2.3" debug "^4.0.0" get-stream "^6.0.0" - import-from "^3.0.0" + import-from "^4.0.0" into-stream "^6.0.0" lodash "^4.17.4" read-pkg-up "^7.0.0" -"@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.8.1": +"@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.8.3": version "1.8.3" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== dependencies: type-detect "4.0.8" -"@sinonjs/fake-timers@^6.0.0", "@sinonjs/fake-timers@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40" - integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA== - dependencies: - "@sinonjs/commons" "^1.7.0" - -"@sinonjs/fake-timers@^7.1.0": +"@sinonjs/fake-timers@^7.0.4", "@sinonjs/fake-timers@^7.1.0": version "7.1.2" resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5" integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg== dependencies: "@sinonjs/commons" "^1.7.0" -"@sinonjs/samsam@^5.3.1": - version "5.3.1" - resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-5.3.1.tgz#375a45fe6ed4e92fca2fb920e007c48232a6507f" - integrity sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg== +"@sinonjs/fake-timers@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" + integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@sinonjs/samsam@^6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-6.0.2.tgz#a0117d823260f282c04bff5f8704bdc2ac6910bb" + integrity sha512-jxPRPp9n93ci7b8hMfJOFDPRLFYadN6FSpeROFTR4UNF4i5b+EK6m4QXPO46BDhFgRy1JuS87zAnFOzCUwMJcQ== dependencies: "@sinonjs/commons" "^1.6.0" lodash.get "^4.4.2" @@ -812,6 +949,11 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + "@types/chai@^4.2.22": version "4.2.22" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.22.tgz#47020d7e4cf19194d43b5202f35f75bd2ad35ce7" @@ -849,20 +991,23 @@ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== -"@types/node@*": - version "16.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" - integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== +"@types/node-fetch@^2.5.0": + version "2.5.12" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.12.tgz#8a6f779b1d4e60b7a57fb6fd48d84fb545b9cc66" + integrity sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw== + dependencies: + "@types/node" "*" + form-data "^3.0.0" -"@types/node@^12.12.42": - version "12.20.36" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.36.tgz#5bd54d2383e714fc4d2c258107ee70c5bad86d0c" - integrity sha512-+5haRZ9uzI7rYqzDznXgkuacqb6LJhAti8mzZKWxIXn/WEtvB+GHVJ7AuMwcN1HMvXOSJcrvA6PPoYHYOYYebA== +"@types/node@*", "@types/node@^16.11.11": + version "16.11.11" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.11.tgz#6ea7342dfb379ea1210835bada87b3c512120234" + integrity sha512-KB0sixD67CeecHC33MYn+eYARkqTheIRNuu97y2XMjR7Wu3XibO1vaY6VBV6O/a89SPI81cEUIYT87UqUWlZNw== "@types/node@^14.14.28": - version "14.17.32" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.32.tgz#2ca61c9ef8c77f6fa1733be9e623ceb0d372ad96" - integrity sha512-JcII3D5/OapPGx+eJ+Ik1SQGyt6WvuqdRfh9jUwL6/iHGjmyOriBDciBUu7lEIBTL2ijxwrR70WUnw5AEDmFvQ== + version "14.17.34" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.34.tgz#fe4b38b3f07617c0fa31ae923fca9249641038f0" + integrity sha512-USUftMYpmuMzeWobskoPfzDi+vkpe0dvcOBRNOscFrGxVp4jomnRxWuVohgqBow2xyIPC0S3gjxV/5079jhmDg== "@types/node@^8.0.47": version "8.10.66" @@ -891,18 +1036,25 @@ dependencies: "@sinonjs/fake-timers" "^7.1.0" -"@types/validator@^13.1.4": - version "13.6.6" - resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.6.6.tgz#6e6e2d086148db5ae14851614971b715670cbd52" - integrity sha512-+qogUELb4gMhrMjSh/seKmGVvN+uQLfyqJAqYRWqVHsvBsUO2xDBCL8CJ/ZSukbd8vXaoYbpIssAmfLEzzBHEw== +"@types/tunnel@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@types/tunnel/-/tunnel-0.0.3.tgz#f109e730b072b3136347561fc558c9358bb8c6e9" + integrity sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA== + dependencies: + "@types/node" "*" -"@typescript-eslint/eslint-plugin@^5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.3.0.tgz#a55ae72d28ffeb6badd817fe4566c9cced1f5e29" - integrity sha512-ARUEJHJrq85aaiCqez7SANeahDsJTD3AEua34EoQN9pHS6S5Bq9emcIaGGySt/4X2zSi+vF5hAH52sEen7IO7g== +"@types/validator@^13.7.0": + version "13.7.0" + resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.7.0.tgz#fa25263656d234473025c2d48249a900053c355a" + integrity sha512-+jBxVvXVuggZOrm04NR8z+5+bgoW4VZyLzUO+hmPPW1mVFL/HaitLAkizfv4yg9TbG8lkfHWVMQ11yDqrVVCzA== + +"@typescript-eslint/eslint-plugin@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.5.0.tgz#12d5f47f127af089b985f3a205c0e34a812f8fce" + integrity sha512-4bV6fulqbuaO9UMXU0Ia0o6z6if+kmMRW8rMRyfqXj/eGrZZRGedS4n0adeGNnjr8LKAM495hrQ7Tea52UWmQA== dependencies: - "@typescript-eslint/experimental-utils" "5.3.0" - "@typescript-eslint/scope-manager" "5.3.0" + "@typescript-eslint/experimental-utils" "5.5.0" + "@typescript-eslint/scope-manager" "5.5.0" debug "^4.3.2" functional-red-black-tree "^1.0.1" ignore "^5.1.8" @@ -910,60 +1062,60 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.3.0.tgz#ee56b4957547ed2b0fc7451205e41502e664f546" - integrity sha512-NFVxYTjKj69qB0FM+piah1x3G/63WB8vCBMnlnEHUsiLzXSTWb9FmFn36FD9Zb4APKBLY3xRArOGSMQkuzTF1w== +"@typescript-eslint/experimental-utils@5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.5.0.tgz#3fe2514dc2f3cd95562206e4058435ea51df609e" + integrity sha512-kjWeeVU+4lQ1SLYErRKV5yDXbWDPkpbzTUUlfAUifPYvpX0qZlrcCZ96/6oWxt3QxtK5WVhXz+KsnwW9cIW+3A== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.3.0" - "@typescript-eslint/types" "5.3.0" - "@typescript-eslint/typescript-estree" "5.3.0" + "@typescript-eslint/scope-manager" "5.5.0" + "@typescript-eslint/types" "5.5.0" + "@typescript-eslint/typescript-estree" "5.5.0" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/parser@^5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.3.0.tgz#7879f15e26d370ed3f653fb7dd06479531ed3ab9" - integrity sha512-rKu/yAReip7ovx8UwOAszJVO5MgBquo8WjIQcp1gx4pYQCwYzag+I5nVNHO4MqyMkAo0gWt2gWUi+36gWAVKcw== +"@typescript-eslint/parser@^5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.5.0.tgz#a38070e225330b771074daa659118238793f7fcd" + integrity sha512-JsXBU+kgQOAgzUn2jPrLA+Rd0Y1dswOlX3hp8MuRO1hQDs6xgHtbCXEiAu7bz5hyVURxbXcA2draasMbNqrhmg== dependencies: - "@typescript-eslint/scope-manager" "5.3.0" - "@typescript-eslint/types" "5.3.0" - "@typescript-eslint/typescript-estree" "5.3.0" + "@typescript-eslint/scope-manager" "5.5.0" + "@typescript-eslint/types" "5.5.0" + "@typescript-eslint/typescript-estree" "5.5.0" debug "^4.3.2" -"@typescript-eslint/scope-manager@5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.3.0.tgz#97d0ccc7c9158e89e202d5e24ce6ba49052d432e" - integrity sha512-22Uic9oRlTsPppy5Tcwfj+QET5RWEnZ5414Prby465XxQrQFZ6nnm5KnXgnsAJefG4hEgMnaxTB3kNEyjdjj6A== +"@typescript-eslint/scope-manager@5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.5.0.tgz#2b9f3672fa6cddcb4160e7e8b49ef1fd00f83c09" + integrity sha512-0/r656RmRLo7CbN4Mdd+xZyPJ/fPCKhYdU6mnZx+8msAD8nJSP8EyCFkzbd6vNVZzZvWlMYrSNekqGrCBqFQhg== dependencies: - "@typescript-eslint/types" "5.3.0" - "@typescript-eslint/visitor-keys" "5.3.0" + "@typescript-eslint/types" "5.5.0" + "@typescript-eslint/visitor-keys" "5.5.0" -"@typescript-eslint/types@5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.3.0.tgz#af29fd53867c2df0028c57c36a655bd7e9e05416" - integrity sha512-fce5pG41/w8O6ahQEhXmMV+xuh4+GayzqEogN24EK+vECA3I6pUwKuLi5QbXO721EMitpQne5VKXofPonYlAQg== +"@typescript-eslint/types@5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.5.0.tgz#fee61ae510e84ed950a53937a2b443e078107003" + integrity sha512-OaYTqkW3GnuHxqsxxJ6KypIKd5Uw7bFiQJZRyNi1jbMJnK3Hc/DR4KwB6KJj6PBRkJJoaNwzMNv9vtTk87JhOg== -"@typescript-eslint/typescript-estree@5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.3.0.tgz#4f68ddd46dc2983182402d2ab21fb44ad94988cf" - integrity sha512-FJ0nqcaUOpn/6Z4Jwbtf+o0valjBLkqc3MWkMvrhA2TvzFXtcclIM8F4MBEmYa2kgcI8EZeSAzwoSrIC8JYkug== +"@typescript-eslint/typescript-estree@5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.5.0.tgz#12f422698c1636bd0206086bbec9844c54625ebc" + integrity sha512-pVn8btYUiYrjonhMAO0yG8lm7RApzy2L4RC7Td/mC/qFkyf6vRbGyZozoA94+w6D2Y2GRqpMoCWcwx/EUOzyoQ== dependencies: - "@typescript-eslint/types" "5.3.0" - "@typescript-eslint/visitor-keys" "5.3.0" + "@typescript-eslint/types" "5.5.0" + "@typescript-eslint/visitor-keys" "5.5.0" debug "^4.3.2" globby "^11.0.4" is-glob "^4.0.3" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@5.3.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.3.0.tgz#a6258790f3b7b2547f70ed8d4a1e0c3499994523" - integrity sha512-oVIAfIQuq0x2TFDNLVavUn548WL+7hdhxYn+9j3YdJJXB7mH9dAmZNJsPDa7Jc+B9WGqoiex7GUDbyMxV0a/aw== +"@typescript-eslint/visitor-keys@5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.5.0.tgz#4787586897b61f26068a3db5c50b3f5d254f9083" + integrity sha512-4GzJ1kRtsWzHhdM40tv0ZKHNSbkDhF0Woi/TDwVJX6UICwJItvP7ZTXbjTkCdrors7ww0sYe0t+cIKDAJwZ7Kw== dependencies: - "@typescript-eslint/types" "5.3.0" + "@typescript-eslint/types" "5.5.0" eslint-visitor-keys "^3.0.0" JSONStream@^1.0.4: @@ -991,7 +1143,7 @@ acorn-globals@^1.0.4: dependencies: acorn "^2.1.0" -acorn-jsx@^5.2.0: +acorn-jsx@^5.3.1: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== @@ -1001,15 +1153,10 @@ acorn@^2.1.0, acorn@^2.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7" integrity sha1-q259nYhqrKiwhbwzEreaGYQz8Oc= -acorn@^7.1.1: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -acorn@^8.0.4: - version "8.5.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2" - integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== +acorn@^8.6.0: + version "8.6.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" + integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== adal-node@^0.1.28: version "0.1.28" @@ -1033,6 +1180,13 @@ agent-base@6, agent-base@^6.0.2: dependencies: debug "4" +agent-base@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" + integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== + dependencies: + es6-promisify "^5.0.0" + agentkeepalive@^4.1.3: version "4.1.4" resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.1.4.tgz#d928028a4862cb11718e55227872e842a44c945b" @@ -1050,7 +1204,7 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3: +ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1070,7 +1224,7 @@ ansi-colors@^4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== -ansi-escapes@^4.2.1, ansi-escapes@^4.3.0, ansi-escapes@^4.3.1: +ansi-escapes@^4.3.0, ansi-escapes@^4.3.1: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== @@ -1097,6 +1251,11 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -1116,6 +1275,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0, ansi-styles@^4.3.0: dependencies: color-convert "^2.0.1" +ansi-styles@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.0.tgz#87313c102b8118abd57371afab34618bf7350ed3" + integrity sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ== + ansicolors@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" @@ -1184,6 +1348,11 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" +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" @@ -1221,6 +1390,53 @@ asap@^2.0.0: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= +asn1.js-rfc2560@^4.0.0: + version "4.0.6" + resolved "https://registry.yarnpkg.com/asn1.js-rfc2560/-/asn1.js-rfc2560-4.0.6.tgz#0975ce84768a8401e95884ad13e2d00e7b25a280" + integrity sha512-ysf48ni+f/efNPilq4+ApbifUPcSW/xbDeQAh055I+grr2gXgNRQqHew7kkO70WSMQ2tEOURVwsK+dJqUNjIIg== + dependencies: + asn1.js-rfc5280 "^2.0.0" + +asn1.js-rfc2560@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/asn1.js-rfc2560/-/asn1.js-rfc2560-5.0.1.tgz#cff99b903e714756b29503ad49de01c72f131e60" + integrity sha512-1PrVg6kuBziDN3PGFmRk3QrjpKvP9h/Hv5yMrFZvC1kpzP6dQRzf5BpKstANqHBkaOUmTpakJWhicTATOA/SbA== + dependencies: + asn1.js-rfc5280 "^3.0.0" + +asn1.js-rfc5280@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/asn1.js-rfc5280/-/asn1.js-rfc5280-2.0.1.tgz#072f3dfc03f86d1faae7485c6197584ba2bb5ddc" + integrity sha512-1e2ypnvTbYD/GdxWK77tdLBahvo1fZUHlQJqAVUuZWdYj0rdjGcf2CWYUtbsyRYpYUMwMWLZFUtLxog8ZXTrcg== + dependencies: + asn1.js "^4.5.0" + +asn1.js-rfc5280@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/asn1.js-rfc5280/-/asn1.js-rfc5280-3.0.0.tgz#94e60498d5d4984b842d1a825485837574ccc902" + integrity sha512-Y2LZPOWeZ6qehv698ZgOGGCZXBQShObWnGthTrIFlIQjuV1gg2B8QOhWFRExq/MR1VnPpIIe7P9vX2vElxv+Pg== + dependencies: + asn1.js "^5.0.0" + +asn1.js@^4.5.0, asn1.js@^4.8.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1.js@^5.0.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + asn1@~0.2.3: version "0.2.6" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" @@ -1238,11 +1454,6 @@ assertion-error@^1.1.0: resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" @@ -1255,20 +1466,35 @@ async-hook-jl@^1.7.6: dependencies: stack-chain "^1.3.7" -async@>=0.6.0: +async@>=0.6.0, async@^3.1.0: version "3.2.2" resolved "https://registry.yarnpkg.com/async/-/async-3.2.2.tgz#2eb7671034bb2194d45d30e31e24ec7e7f9670cd" integrity sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g== +async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== +aws-sdk@^2.878.0: + version "2.1042.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1042.0.tgz#c3385bf6cbb8f97c2cde427c0ab3d9720fa4b82a" + integrity sha512-JWjs6+Zhuo990WYH1iQR1njGOvoCFzaf2azX/zh3JdL7QNwzdqczoODMj0wb22831/7EoPDGaXHqp7aQwDsxwA== + dependencies: + buffer "4.9.2" + events "1.1.1" + ieee754 "1.1.13" + jmespath "0.15.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + uuid "3.3.2" + xml2js "0.4.19" aws-sign2@~0.7.0: version "0.7.0" @@ -1280,14 +1506,7 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== -axios@>=0.21.2: - version "0.24.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6" - integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA== - dependencies: - follow-redirects "^1.14.4" - -axios@^0.21.1: +axios@^0.21.1, axios@^0.21.4: version "0.21.4" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== @@ -1379,6 +1598,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base64-js@^1.0.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + bcrypt-pbkdf@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" @@ -1391,6 +1615,16 @@ before-after-hook@^2.2.0: resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e" integrity sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ== +big-integer@^1.6.43: + version "1.6.51" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + +bignumber.js@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-2.4.0.tgz#838a992da9f9d737e0f4b2db0be62bb09dd0c5e8" + integrity sha1-g4qZLan51zfg9LLbC+YrsJ3Qxeg= + bin-links@^2.2.1: version "2.3.0" resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-2.3.0.tgz#1ff241c86d2c29b24ae52f49544db5d78a4eb967" @@ -1408,6 +1642,11 @@ binary-extensions@^2.0.0, binary-extensions@^2.2.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== +binascii@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/binascii/-/binascii-0.0.2.tgz#a7f8a8801dbccf8b1756b743daa0fee9e2d9e0ee" + integrity sha1-p/iogB28z4sXVrdD2qD+6eLZ4O4= + bl@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/bl/-/bl-3.0.1.tgz#1cbb439299609e419b5a74d7fce2f8b37d8e5c6f" @@ -1415,6 +1654,18 @@ bl@^3.0.0: dependencies: readable-stream "^3.0.1" +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +bn.js@^4.0.0: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + boolbase@^1.0.0, boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" @@ -1440,18 +1691,23 @@ braces@^3.0.1, braces@~3.0.2: dependencies: fill-range "^7.0.1" +browser-request@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/browser-request/-/browser-request-0.3.3.tgz#9ece5b5aca89a29932242e18bf933def9876cc17" + integrity sha1-ns5bWsqJopkyJC4Yv5M975h2zBc= + browser-stdout@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== -browserslist@^4.16.6: - version "4.17.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.6.tgz#c76be33e7786b497f66cad25a73756c8b938985d" - integrity sha512-uPgz3vyRTlEiCv4ee9KlsKgo2V6qPk7Jsn0KAn2OBqbqKo3iNcPEC1Ti6J4dwnz+aIRfEEEuOzC9IBk8tXUomw== +browserslist@^4.17.5: + version "4.18.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.18.1.tgz#60d3920f25b6860eb917c6c7b185576f4d8b017f" + integrity sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ== dependencies: - caniuse-lite "^1.0.30001274" - electron-to-chromium "^1.3.886" + caniuse-lite "^1.0.30001280" + electron-to-chromium "^1.3.896" escalade "^3.1.1" node-releases "^2.0.1" picocolors "^1.0.0" @@ -1476,6 +1732,15 @@ buffer-writer@2.0.0: resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== +buffer@4.9.2: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + builtins@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" @@ -1542,10 +1807,10 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-lite@^1.0.30001274: - version "1.0.30001278" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001278.tgz#51cafc858df77d966b17f59b5839250b24417fff" - integrity sha512-mpF9KeH8u5cMoEmIic/cr7PNS+F5LWBk0t2ekGT60lFf0Wq+n9LspAj0g3P+o7DQhD3sUdlMln4YFAWhFYn9jg== +caniuse-lite@^1.0.30001280: + version "1.0.30001283" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001283.tgz#8573685bdae4d733ef18f78d44ba0ca5fe9e896b" + integrity sha512-9RoKo841j1GQFSJz/nCXOj0sD7tHBtlowjYlrqIUS812x9/emfBLBt6IyMz1zIaYc/eRL8Cs6HPUVi2Hzq4sIg== cardinal@^2.1.1: version "2.1.1" @@ -1560,21 +1825,21 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chai-as-promised@^7.x: +chai-as-promised@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA== dependencies: check-error "^1.0.2" -chai-datetime@^1.6.0: +chai-datetime@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/chai-datetime/-/chai-datetime-1.8.0.tgz#95a1ff58130f60f16f6d882ec5c014e63aa6d75f" integrity sha512-qBG84K8oQNz8LWacuzmCBfdoeG2UBFfbGKTSQj6lS+sjuzGUdBvjJxfZfGA4zDAMiCSqApKcuqSLO0lQQ25cHw== dependencies: chai ">1.9.0" -chai@>1.9.0, chai@^4.x: +chai@>1.9.0, chai@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" integrity sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA== @@ -1586,14 +1851,6 @@ chai@>1.9.0, chai@^4.x: pathval "^1.1.1" type-detect "^4.0.5" -chalk@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -1605,7 +1862,7 @@ chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.2, chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.3.2, 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== @@ -1622,11 +1879,6 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - check-error@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" @@ -1690,7 +1942,7 @@ cheerio@1.0.0-rc.2: lodash "^4.15.0" parse5 "^3.0.1" -cheerio@^1.0.0-rc.3: +cheerio@^1.0.0-rc.10: version "1.0.0-rc.10" resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.10.tgz#2ba3dcdfcc26e7956fc1f440e61d51c643379f3e" integrity sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw== @@ -1728,11 +1980,6 @@ chownr@^2.0.0: resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - cidr-regex@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/cidr-regex/-/cidr-regex-3.1.1.tgz#ba1972c57c66f61875f18fd7dd487469770b571d" @@ -1778,10 +2025,13 @@ cli-truncate@^2.1.0: slice-ansi "^3.0.0" string-width "^4.2.0" -cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" - integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== +cli-truncate@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389" + integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== + dependencies: + slice-ansi "^5.0.0" + string-width "^5.0.0" cliui@^5.0.0: version "5.0.0" @@ -1825,7 +2075,7 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= -clone@^2.1.1, clone@^2.1.2: +clone@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= @@ -1860,7 +2110,7 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -color-convert@^1.9.0: +color-convert@^1.9.0, color-convert@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -1889,26 +2139,50 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@~1.1.4: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-string@^1.6.0: + version "1.8.2" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.8.2.tgz#08bd49fa5f3889c27b0c670052ed746dd7a671de" + integrity sha512-w5ZkKRdLsc5NOYsmnpS2DpyRW71npwZGwbRpLrJTuqjfTs2Bhrba7UiV59IX9siBlCPl2pne5NtiwnVWUzvYFA== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + color-support@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== +color@^3.1.3: + version "3.2.1" + resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164" + integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA== + dependencies: + color-convert "^1.9.3" + color-string "^1.6.0" + colorette@^2.0.16: version "2.0.16" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== -colors@^1.1.2: +colors@^1.1.2, colors@^1.2.1: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== +colorspace@1.1.x: + version "1.1.4" + resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.4.tgz#8d442d1186152f60453bf8070cd66eb364e59243" + integrity sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w== + dependencies: + color "^3.1.3" + text-hex "1.0.x" + columnify@~1.5.4: version "1.5.4" resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" @@ -1917,22 +2191,22 @@ columnify@~1.5.4: strip-ansi "^3.0.0" wcwidth "^1.0.0" -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" -commander@^6.2.0, commander@~6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" - integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== +commander@^8.3.0, commander@~8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== -comment-parser@^0.7.2: - version "0.7.6" - resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-0.7.6.tgz#0e743a53c8e646c899a1323db31f6cd337b10f12" - integrity sha512-GKNxVA7/iuTnAqGADlTWX4tkhzxZKXp5fLJqKTlQLHkE65XDUKutZ3BHaJC5IGcper2tT3QRD1xr4o3jNpgXXg== +comment-parser@1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.2.4.tgz#489f3ee55dfd184a6e4bffb31baba284453cb760" + integrity sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw== common-ancestor-path@^1.0.1: version "1.0.1" @@ -1952,11 +2226,6 @@ compare-func@^2.0.0: array-ify "^1.0.0" dot-prop "^5.1.0" -compare-versions@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" - integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -1967,7 +2236,7 @@ console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control- resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= -conventional-changelog-angular@^5.0.0: +conventional-changelog-angular@^5.0.0, conventional-changelog-angular@^5.0.11: version "5.0.13" resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz#896885d63b914a70d4934b59d2fe7bde1832b28c" integrity sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA== @@ -1975,12 +2244,11 @@ conventional-changelog-angular@^5.0.0: compare-func "^2.0.0" q "^1.5.1" -conventional-changelog-writer@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.1.0.tgz#1ca7880b75aa28695ad33312a1f2366f4b12659f" - integrity sha512-WwKcUp7WyXYGQmkLsX4QmU42AZ1lqlvRW9mqoyiQzdD+rJWbTepdWoKJuwXTS+yq79XKnQNa93/roViPQrAQgw== +conventional-changelog-writer@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-5.0.0.tgz#c4042f3f1542f2f41d7d2e0d6cad23aba8df8eec" + integrity sha512-HnDh9QHLNWfL6E1uHz6krZEQOgm8hN7z/m7tT16xwd802fwgMN0Wqd7AQYVkhpsjDUx/99oo+nGgvKF657XP5g== dependencies: - compare-func "^2.0.0" conventional-commits-filter "^2.0.7" dateformat "^3.0.0" handlebars "^4.7.6" @@ -1999,7 +2267,7 @@ conventional-commits-filter@^2.0.0, conventional-commits-filter@^2.0.7: lodash.ismatch "^4.4.0" modify-values "^1.0.0" -conventional-commits-parser@^3.0.0, conventional-commits-parser@^3.0.7: +conventional-commits-parser@^3.2.2, conventional-commits-parser@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.2.3.tgz#fc43704698239451e3ef35fd1d8ed644f46bd86e" integrity sha512-YyRDR7On9H07ICFpRm/igcdjIqebXbvf4Cff+Pf0BrBys1i1EOzx9iFXNlAbdrLAR8jf7bkUYkDAr8pEy0q4Pw== @@ -2036,11 +2304,6 @@ core-js@^2.4.0: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== -core-js@^3.6.1: - version "3.19.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.19.1.tgz#f6f173cae23e73a7d88fa23b6e9da329276c6641" - integrity sha512-Tnc7E9iKd/b/ff7GFbhwPVzJzPztGrChB8X8GLqoYGdEOG8IpLnK1xPyo3ZoO3HsK6TodJS58VGPOxA+hLHQMg== - core-util-is@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -2062,25 +2325,19 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" -cross-env@^7.0.2: +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-env@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== dependencies: cross-spawn "^7.0.1" -cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.1, 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" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -2166,10 +2423,10 @@ debug@3.2.6: dependencies: ms "^2.1.1" -debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== +debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== dependencies: ms "2.1.2" @@ -2180,7 +2437,7 @@ debug@^2.6.8: dependencies: ms "2.0.0" -debug@^3.2.6: +debug@^3.1.0, debug@^3.2.6: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -2205,11 +2462,6 @@ decamelize@^1.1.0, decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= -dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= - deep-eql@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" @@ -2222,7 +2474,7 @@ deep-extend@^0.6.0, deep-extend@~0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -deep-is@~0.1.3: +deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== @@ -2262,10 +2514,10 @@ del@^6.0.0: rimraf "^3.0.2" slash "^3.0.0" -delay@^4.3.0: - version "4.4.1" - resolved "https://registry.yarnpkg.com/delay/-/delay-4.4.1.tgz#6e02d02946a1b6ab98b39262ced965acba2ac4d1" - integrity sha512-aL3AhqtfhOlT/3ai6sWXeqwnw63ATNpnUiN4HL7x9q+My5QtHlO3OIkasmug9LKzpheLdmUKGRKnYXYAS7FQkQ== +delay@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/delay/-/delay-5.0.0.tgz#137045ef1b96e5071060dd5be60bf9334436bd1d" + integrity sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw== delayed-stream@~1.0.0: version "1.0.0" @@ -2336,7 +2588,7 @@ diff@3.5.0: resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== -diff@^4.0.2: +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== @@ -2448,7 +2700,7 @@ dot-prop@^5.1.0: dependencies: is-obj "^2.0.0" -dottie@^2.0.0: +dottie@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/dottie/-/dottie-2.0.2.tgz#cc91c0726ce3a054ebf11c55fbc92a7f266dd154" integrity sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg== @@ -2485,10 +2737,10 @@ ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer "^5.0.1" -electron-to-chromium@^1.3.886: - version "1.3.890" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.890.tgz#e7143b659f73dc4d0512d1ae4baeb0fb9e7bc835" - integrity sha512-VWlVXSkv0cA/OOehrEyqjUTHwV8YXCPTfPvbtoeU2aHR21vI4Ejh5aC4AxUwOmbLbBgb6Gd3URZahoCxtBqCYQ== +electron-to-chromium@^1.3.896: + version "1.4.5" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.5.tgz#912e8fd1645edee2f0f212558f40916eb538b1f9" + integrity sha512-YKaB+t8ul5crdh6OeqT2qXdxJGI0fAYb6/X8pDIyye+c3a7ndOCk5gVeKX+ABwivCGNS56vOAif3TN0qJMpEHw== emitter-listener@^1.0.1: version "1.1.2" @@ -2507,6 +2759,16 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +enabled@2.0.x: + version "2.0.0" + resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" + integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== + encoding@^0.1.12: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" @@ -2521,7 +2783,7 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enquirer@^2.3.6: +enquirer@^2.3.5, enquirer@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== @@ -2543,10 +2805,10 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== -entities@~2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f" - integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== +entities@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" + integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== env-ci@^5.0.0: version "5.4.1" @@ -2614,113 +2876,125 @@ es6-error@^4.0.1: resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== -esbuild-android-arm64@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.13.12.tgz#e1f199dc05405cdc6670c00fb6c793822bf8ae4c" - integrity sha512-TSVZVrb4EIXz6KaYjXfTzPyyRpXV5zgYIADXtQsIenjZ78myvDGaPi11o4ZSaHIwFHsuwkB6ne5SZRBwAQ7maw== - -esbuild-darwin-64@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.13.12.tgz#f5c59e622955c01f050e5a7ac9c1d41db714b94d" - integrity sha512-c51C+N+UHySoV2lgfWSwwmlnLnL0JWj/LzuZt9Ltk9ub1s2Y8cr6SQV5W3mqVH1egUceew6KZ8GyI4nwu+fhsw== - -esbuild-darwin-arm64@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.12.tgz#8abae74c2956a8aa568fc52c78829338c4a4b988" - integrity sha512-JvAMtshP45Hd8A8wOzjkY1xAnTKTYuP/QUaKp5eUQGX+76GIie3fCdUUr2ZEKdvpSImNqxiZSIMziEiGB5oUmQ== - -esbuild-freebsd-64@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.12.tgz#6ad2ab8c0364ee7dd2d6e324d876a8e60ae75d12" - integrity sha512-r6On/Skv9f0ZjTu6PW5o7pdXr8aOgtFOEURJZYf1XAJs0IQ+gW+o1DzXjVkIoT+n1cm3N/t1KRJfX71MPg/ZUA== - -esbuild-freebsd-arm64@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.12.tgz#6f38155f4c300ac4c8adde1fde3cc6a4440a8294" - integrity sha512-F6LmI2Q1gii073kmBE3NOTt/6zLL5zvZsxNLF8PMAwdHc+iBhD1vzfI8uQZMJA1IgXa3ocr3L3DJH9fLGXy6Yw== - -esbuild-linux-32@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.13.12.tgz#b1d15e330188a8c21de75c3f0058628a3eefade7" - integrity sha512-U1UZwG3UIwF7/V4tCVAo/nkBV9ag5KJiJTt+gaCmLVWH3bPLX7y+fNlhIWZy8raTMnXhMKfaTvWZ9TtmXzvkuQ== - -esbuild-linux-64@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.13.12.tgz#25bd64b66162b02348e32d8f12e4c9ee61f1d070" - integrity sha512-YpXSwtu2NxN3N4ifJxEdsgd6Q5d8LYqskrAwjmoCT6yQnEHJSF5uWcxv783HWN7lnGpJi9KUtDvYsnMdyGw71Q== - -esbuild-linux-arm64@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.12.tgz#ba582298457cc5c9ac823a275de117620c06537f" - integrity sha512-sgDNb8kb3BVodtAlcFGgwk+43KFCYjnFOaOfJibXnnIojNWuJHpL6aQJ4mumzNWw8Rt1xEtDQyuGK9f+Y24jGA== - -esbuild-linux-arm@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.13.12.tgz#6bc81c957bff22725688cc6359c29a25765be09b" - integrity sha512-SyiT/JKxU6J+DY2qUiSLZJqCAftIt3uoGejZ0HDnUM2MGJqEGSGh7p1ecVL2gna3PxS4P+j6WAehCwgkBPXNIw== - -esbuild-linux-mips64le@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.12.tgz#ef3c4aba3e585d847cbade5945a8b4a5c62c7ce2" - integrity sha512-qQJHlZBG+QwVIA8AbTEtbvF084QgDi4DaUsUnA+EolY1bxrG+UyOuGflM2ZritGhfS/k7THFjJbjH2wIeoKA2g== - -esbuild-linux-ppc64le@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.12.tgz#a21fb64e80c38bef06122e48283990fc6db578e1" - integrity sha512-2dSnm1ldL7Lppwlo04CGQUpwNn5hGqXI38OzaoPOkRsBRWFBozyGxTFSee/zHFS+Pdh3b28JJbRK3owrrRgWNw== - -esbuild-netbsd-64@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.12.tgz#1ea7fc8cfce88a20a4047b867ef184049a6641ae" - integrity sha512-D4raxr02dcRiQNbxOLzpqBzcJNFAdsDNxjUbKkDMZBkL54Z0vZh4LRndycdZAMcIdizC/l/Yp/ZsBdAFxc5nbA== - -esbuild-openbsd-64@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.12.tgz#adde32f2f1b05dc4bd4fc544d6ea5a4379f9ca4d" - integrity sha512-KuLCmYMb2kh05QuPJ+va60bKIH5wHL8ypDkmpy47lzwmdxNsuySeCMHuTv5o2Af1RUn5KLO5ZxaZeq4GEY7DaQ== - -esbuild-sunos-64@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.13.12.tgz#a7ecaf52b7364fbee76dc8aa707fa3e1cff3342c" - integrity sha512-jBsF+e0woK3miKI8ufGWKG3o3rY9DpHvCVRn5eburMIIE+2c+y3IZ1srsthKyKI6kkXLvV4Cf/E7w56kLipMXw== - -esbuild-windows-32@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.13.12.tgz#a8756033dc905c4b7bea19be69f7ee68809f8770" - integrity sha512-L9m4lLFQrFeR7F+eLZXG82SbXZfUhyfu6CexZEil6vm+lc7GDCE0Q8DiNutkpzjv1+RAbIGVva9muItQ7HVTkQ== - -esbuild-windows-64@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.13.12.tgz#ae694aa66ca078acb8509b2da31197ed1f40f798" - integrity sha512-k4tX4uJlSbSkfs78W5d9+I9gpd+7N95W7H2bgOMFPsYREVJs31+Q2gLLHlsnlY95zBoPQMIzHooUIsixQIBjaQ== - -esbuild-windows-arm64@0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.12.tgz#782c5a8bd6d717ea55aaafe648f9926ca36a4a88" - integrity sha512-2tTv/BpYRIvuwHpp2M960nG7uvL+d78LFW/ikPItO+2GfK51CswIKSetSpDii+cjz8e9iSPgs+BU4o8nWICBwQ== - -esbuild@^0.13.12: - version "0.13.12" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.13.12.tgz#9cac641594bf03cf34145258c093d743ebbde7ca" - integrity sha512-vTKKUt+yoz61U/BbrnmlG9XIjwpdIxmHB8DlPR0AAW6OdS+nBQBci6LUHU2q9WbBobMEIQxxDpKbkmOGYvxsow== +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + +esbuild-android-arm64@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.1.tgz#470b99c1c4b49f33fd0a20ed153b15008173fd63" + integrity sha512-elQd3hTg93nU2GQ5PPCDAFe5+utxZX96RG8RixqIPxf8pzmyIzcpKG76L/9FabPf3LT1z+nLF1sajCU8eVRDyg== + +esbuild-darwin-64@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.1.tgz#135f48f299f2ce3eb3ca1b1f3ec03d81108ab79e" + integrity sha512-PR3HZgbPRwsQbbOR1fJrfkt/Cs0JDyI3yzOKg2PPWk0H1AseZDBqPUY9b/0+BIjFwA5Jz/aAiq832hppsuJtNw== + +esbuild-darwin-arm64@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.1.tgz#7117a857bac99ece28ebba859a47dce47f565f9f" + integrity sha512-/fiSSOkOEa3co6yYtwgXouz8jZrG0qnXPEKiktFf2BQE8NON3ARTw43ZegaH+xMRFNgYBJEOOZIdzI3sIFEAxw== + +esbuild-freebsd-64@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.1.tgz#2b7ca5ec572f2800b1ec88988affc4482c5ac4b7" + integrity sha512-ZJV+nfa8E8PdXnRc05PO3YMfgSj7Ko+kdHyGDE6OaNo1cO8ZyfacqLaWkY35shDDaeacklhD8ZR4qq5nbJKX1A== + +esbuild-freebsd-arm64@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.1.tgz#63e8b77643ea8270d878cfab7dd9201a114f20fb" + integrity sha512-6N9zTD+SecJr2g9Ohl9C10WIk5FpQ+52bNamRy0sJoHwP31G5ObzKzq8jAtg1Jeggpu6P8auz3P/UL+3YioSwQ== + +esbuild-linux-32@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.1.tgz#f00ae7f12d2abc0dc37e2a7e7c7c29764da87093" + integrity sha512-RtPgE6e7WefbAxRjVryisKFJ0nUwR2DMjwmYW/a1a0F1+Ge6FR+RqvgiY0DrM9TtxSUU0eryDXNF4n3UfxX3mg== + +esbuild-linux-64@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.1.tgz#2ee9dd76be1185abb1e967052e3b6ab16a1d3da4" + integrity sha512-JpxM0ar6Z+2v3vfFrxP7bFb8Wzb6gcGL9MxRqAJplDfGnee8HbfPge6svaazXeX9XJceeEqwxwWGB0qyCcxo7A== + +esbuild-linux-arm64@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.1.tgz#601e855b78e0636e120771296b43eb4f7d68a314" + integrity sha512-cFbeZf171bIf+PPLlQDBzagK85lCCxxVdMV1IVUA96Y3kvEgqcy2n9mha+QE1M/T+lIOPDsmLRgH1XqMFwLTSg== + +esbuild-linux-arm@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.1.tgz#c0d364a20f12a653bdd2f41436788b99502dc287" + integrity sha512-eBRHexCijAYWzcvQLGHxyxIlYOkYhXvcb/O7HvzJfCAVWCnTx9TxxYJ3UppBC6dDFbAq4HwKhskvmesQdKMeBg== + +esbuild-linux-mips64le@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.1.tgz#a5f6e9c6e7950a3fad08bb3653bc3f5d71b4e249" + integrity sha512-UGb+sqHkL7wOQFLH0RoFhcRAlJNqbqs6GtJd1It5jJ2juOGqAkCv8V12aGDX9oRB6a+Om7cdHcH+6AMZ+qlaww== + +esbuild-linux-ppc64le@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.1.tgz#762cec24cf5afeee3f805a4679a3f5e29702173a" + integrity sha512-LIHGkGdy9wYlmkkoVHm6feWhkoi4VBXDiEVyNjXEhlzsBcP/CaRy+B8IJulzaU1ALLiGcsCQ2MC5UbFn/iTvmA== + +esbuild-netbsd-64@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.1.tgz#66ec7ac0b3eeb84f8c1ac27eecf16f59d93706a8" + integrity sha512-TWc1QIgtPwaK5nC1GT2ASTuy/CJhNKHN4h5PJRP1186VfI+k2uvXakS7bqO/M26F6jAMy8jDeCtilacqpwsvfA== + +esbuild-openbsd-64@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.1.tgz#7515049bc7032ca2fb6811dc260f5ec9e1d9fe65" + integrity sha512-Z9/Zb77K+pK9s7mAsvwS56K8tCbLvNZ9UI4QVJSYqDgOmmDJOBT4owWnCqZ5cJI+2y4/F9KwCpFFTNUdPglPKA== + +esbuild-sunos-64@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.1.tgz#795f6bc7ce8c5177afb65f8d6c161a02f0c3e125" + integrity sha512-c4sF8146kNW8529wfkB6vO0ZqPgokyS2hORqKa4p/QKZdp+xrF2NPmvX5aN+Zt14oe6wVZuhYo6LGv7V4Gg04g== + +esbuild-windows-32@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.1.tgz#ffffa6378733eeaa23ed5cfe539e2fbe1e635ef6" + integrity sha512-XP8yElaJtLGGjH7D72t5IWtP0jmc1Jqm4IjQARB17l0LTJO/n+N2X64rDWePJv6qimYxa5p2vTjkZc5v+YZTSQ== + +esbuild-windows-64@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.1.tgz#46f3b4a90f937a8ad6456cd70478ebfc6771814f" + integrity sha512-fe+ShdyfiuGcCEdVKW//6MaM4MwikiWBWSBn8mebNAbjRqicH0injDOFVI7aUovAfrEt7+FGkf402s//hi0BVg== + +esbuild-windows-arm64@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.1.tgz#c7067389d28139e6a18db1996178c3a3e07a22b3" + integrity sha512-wBVakhcIzQ3NZ33DFM6TjIObXPHaXOsqzvPwefXHvwBSC/N/e/g6fBeM7N/Moj3AmxLjKaB+vePvTGdxk6RPCg== + +esbuild@^0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.1.tgz#b834da3aa5858073205a6d4f948ffde0d650e4e3" + integrity sha512-J/LhUwELcmz0+CJfiaKzu7Rnj9ffWFLvMx+dKvdOfg+fQmoP6q9glla26LCm9BxpnPUjXChHeubLiMlKab/PYg== optionalDependencies: - esbuild-android-arm64 "0.13.12" - esbuild-darwin-64 "0.13.12" - esbuild-darwin-arm64 "0.13.12" - esbuild-freebsd-64 "0.13.12" - esbuild-freebsd-arm64 "0.13.12" - esbuild-linux-32 "0.13.12" - esbuild-linux-64 "0.13.12" - esbuild-linux-arm "0.13.12" - esbuild-linux-arm64 "0.13.12" - esbuild-linux-mips64le "0.13.12" - esbuild-linux-ppc64le "0.13.12" - esbuild-netbsd-64 "0.13.12" - esbuild-openbsd-64 "0.13.12" - esbuild-sunos-64 "0.13.12" - esbuild-windows-32 "0.13.12" - esbuild-windows-64 "0.13.12" - esbuild-windows-arm64 "0.13.12" + esbuild-android-arm64 "0.14.1" + esbuild-darwin-64 "0.14.1" + esbuild-darwin-arm64 "0.14.1" + esbuild-freebsd-64 "0.14.1" + esbuild-freebsd-arm64 "0.14.1" + esbuild-linux-32 "0.14.1" + esbuild-linux-64 "0.14.1" + esbuild-linux-arm "0.14.1" + esbuild-linux-arm64 "0.14.1" + esbuild-linux-mips64le "0.14.1" + esbuild-linux-ppc64le "0.14.1" + esbuild-netbsd-64 "0.14.1" + esbuild-openbsd-64 "0.14.1" + esbuild-sunos-64 "0.14.1" + esbuild-windows-32 "0.14.1" + esbuild-windows-64 "0.14.1" + esbuild-windows-arm64 "0.14.1" escalade@^3.1.1: version "3.1.1" @@ -2737,6 +3011,11 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1 resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + escodegen@^1.6.1: version "1.14.3" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" @@ -2863,29 +3142,30 @@ esdoc@^1.1.0: minimist "1.2.0" taffydb "2.7.3" -eslint-plugin-jsdoc@^20.4.0: - version "20.4.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-20.4.0.tgz#ea6725c3d1e68cd1ac0e633d935aa7e932b624c2" - integrity sha512-c/fnEpwWLFeQn+A7pb1qLOdyhovpqGCWCeUv1wtzFNL5G+xedl9wHUnXtp3b1sGHolVimi9DxKVTuhK/snXoOw== +eslint-plugin-jsdoc@^37.0.3: + version "37.0.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-37.0.3.tgz#42ddd0393c166c2724a7fdee808b94ab1d9dfb00" + integrity sha512-Qg/gIZAfcrM4Qu/JzcnxPGD45Je6wPLFzMZQboeqit/CL4aY6wuzBTkgUMiWXfw/PaPl+sb0GF1XdBlV23ReDA== dependencies: - comment-parser "^0.7.2" - debug "^4.1.1" - jsdoctypeparser "^6.1.0" - lodash "^4.17.15" - object.entries-ponyfill "^1.0.1" - regextras "^0.7.0" - semver "^6.3.0" - spdx-expression-parse "^3.0.0" + "@es-joy/jsdoccomment" "0.12.0" + comment-parser "1.2.4" + debug "^4.3.2" + esquery "^1.4.0" + jsdoc-type-pratt-parser "^2.0.0" + lodash "^4.17.21" + regextras "^0.8.0" + semver "^7.3.5" + spdx-expression-parse "^3.0.1" -eslint-plugin-mocha@^6.2.2: - version "6.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-6.3.0.tgz#72bfd06a5c4323e17e30ef41cd726030e8cdb8fd" - integrity sha512-Cd2roo8caAyG21oKaaNTj7cqeYRWW1I2B5SfpKRp0Ip1gkfwoR1Ow0IGlPWnNjzywdF4n+kHL8/9vM6zCJUxdg== +eslint-plugin-mocha@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-9.0.0.tgz#b4457d066941eecb070dc06ed301c527d9c61b60" + integrity sha512-d7knAcQj1jPCzZf3caeBIn3BnW6ikcvfz0kSqQpwPYcVGLoJV5sz0l0OJB2LR8I7dvTDbqq1oV6ylhSgzA10zg== dependencies: - eslint-utils "^2.0.0" - ramda "^0.27.0" + eslint-utils "^3.0.0" + ramda "^0.27.1" -eslint-scope@^5.0.0, eslint-scope@^5.1.1: +eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -2893,19 +3173,13 @@ eslint-scope@^5.0.0, eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-utils@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== +eslint-scope@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.0.tgz#c1f6ea30ac583031f203d65c73e723b01298f153" + integrity sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg== dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-utils@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" + esrecurse "^4.3.0" + estraverse "^5.2.0" eslint-utils@^3.0.0: version "3.0.0" @@ -2914,79 +3188,75 @@ eslint-utils@^3.0.0: dependencies: eslint-visitor-keys "^2.0.0" -eslint-visitor-keys@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - eslint-visitor-keys@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint-visitor-keys@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz#e32e99c6cdc2eb063f204eda5db67bfe58bb4186" - integrity sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q== +eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz#eee4acea891814cda67a7d8812d9647dd0179af2" + integrity sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA== -eslint@^6.8.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" - integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== +eslint@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.3.0.tgz#a3c2409507403c1c7f6c42926111d6cbefbc3e85" + integrity sha512-aIay56Ph6RxOTC7xyr59Kt3ewX185SaGnAr8eWukoPLeriCrvGjvAubxuvaXOfsxhtwV5g0uBOsyhAom4qJdww== dependencies: - "@babel/code-frame" "^7.0.0" + "@eslint/eslintrc" "^1.0.4" + "@humanwhocodes/config-array" "^0.6.0" ajv "^6.10.0" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" doctrine "^3.0.0" - eslint-scope "^5.0.0" - eslint-utils "^1.4.3" - eslint-visitor-keys "^1.1.0" - espree "^6.1.2" - esquery "^1.0.1" + enquirer "^2.3.5" + escape-string-regexp "^4.0.0" + eslint-scope "^7.1.0" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.1.0" + espree "^9.1.0" + esquery "^1.4.0" esutils "^2.0.2" - file-entry-cache "^5.0.1" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^12.1.0" + glob-parent "^6.0.1" + globals "^13.6.0" ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" - inquirer "^7.0.0" is-glob "^4.0.0" - js-yaml "^3.13.1" + js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.14" + levn "^0.4.1" + lodash.merge "^4.6.2" minimatch "^3.0.4" - mkdirp "^0.5.1" natural-compare "^1.4.0" - optionator "^0.8.3" + optionator "^0.9.1" progress "^2.0.0" - regexpp "^2.0.1" - semver "^6.1.2" - strip-ansi "^5.2.0" - strip-json-comments "^3.0.1" - table "^5.2.3" + regexpp "^3.2.0" + semver "^7.2.1" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" - integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== +espree@^9.0.0, espree@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.1.0.tgz#ba9d3c9b34eeae205724124e31de4543d59fbf74" + integrity sha512-ZgYLvCS1wxOczBYGcQT9DDWgicXwJ4dbocr9uYN+/eresBAUuBu+O4WzB21ufQ/JqQT8gyp7hJ3z8SHii32mTQ== dependencies: - acorn "^7.1.1" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.1.0" + acorn "^8.6.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^3.1.0" esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.0.1: +esquery@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== @@ -3015,22 +3285,17 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -execa@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" - integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== - dependencies: - cross-spawn "^7.0.0" - get-stream "^5.0.0" - human-signals "^1.1.1" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.0" - onetime "^5.1.0" - signal-exit "^3.0.2" - strip-final-newline "^2.0.0" +events@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= + +events@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -execa@^5.0.0: +execa@^5.0.0, execa@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== @@ -3045,25 +3310,23 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -expect-type@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-0.11.0.tgz#bce1a3e283f0334eedb39699b57dd27be7009cc1" - integrity sha512-hkObxepDKhTYloH/UZoxYTT2uUzdhvDEwAi0oqdk29XEkHF8p+5ZRpX/BZES2PtGN9YgyEqutIjXfnL9iMflMw== +expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" -extend@^3.0.0, extend@~3.0.2: +expect-type@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-0.12.0.tgz#133534b5e2561158c371e74af63fd8f18a9f3d42" + integrity sha512-IHwziEOjpjXqxQhtOAD5zMiQpGztaEKM4Q8wnwoRN9NIFlnyNHNjRxKWv+18UqRfsqi6vVnZIYFU16ePf+HaqA== + +extend@^3.0.0, extend@^3.0.2, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" @@ -3074,7 +3337,7 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== -fast-deep-equal@^3.1.1: +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== @@ -3095,7 +3358,7 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= @@ -3112,6 +3375,11 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +fecha@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce" + integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q== + figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -3126,12 +3394,12 @@ figures@^3.0.0: dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: - flat-cache "^2.0.1" + flat-cache "^3.0.4" fill-range@^7.0.1: version "7.0.1" @@ -3186,14 +3454,13 @@ find-versions@^4.0.0: dependencies: semver-regex "^3.1.2" -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" + flatted "^3.1.0" + rimraf "^3.0.2" flat@^4.1.0: version "4.1.1" @@ -3202,10 +3469,10 @@ flat@^4.1.0: dependencies: is-buffer "~2.0.3" -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== +flatted@^3.1.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2" + integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw== flush-write-stream@^1.0.2: version "1.1.1" @@ -3215,7 +3482,12 @@ flush-write-stream@^1.0.2: inherits "^2.0.3" readable-stream "^2.3.6" -follow-redirects@^1.14.0, follow-redirects@^1.14.4: +fn.name@1.x.x: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" + integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== + +follow-redirects@^1.14.0: version "1.14.5" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381" integrity sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA== @@ -3242,6 +3514,24 @@ form-data@^2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -3291,20 +3581,10 @@ fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^9.0.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-jetpack@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/fs-jetpack/-/fs-jetpack-4.2.0.tgz#a3efc00abdb36f0f43ebd44405a4826098399d97" - integrity sha512-b7kFUlXAA4Q12qENTdU5DCQkf8ojEk4fpaXXu/bqayobwm0EfjjlwBCFqRBM2t8I75s0ifk0ajRqddXy2bAHJg== +fs-jetpack@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/fs-jetpack/-/fs-jetpack-4.3.0.tgz#8202abd21c9160faadf3c258b4cf918a74f680de" + integrity sha512-Zx4OJ8HyKvZL9sgxegMGRCgAJSQET5Cqpj/SESwnzqHruHvhkilJBGLoZf6EiYr3UWJDqcPoWDX7aAfaj7D9Qw== dependencies: minimatch "^3.0.2" rimraf "^2.6.3" @@ -3341,6 +3621,16 @@ fsevents@~2.1.1: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== +fstream@^1.0.0, fstream@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -3387,11 +3677,21 @@ generate-function@^2.3.1: dependencies: is-property "^1.0.2" +generic-pool@^3.8.2: + version "3.8.2" + resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-3.8.2.tgz#aab4f280adb522fdfbdc5e5b64d718d3683f04e9" + integrity sha512-nGToKy6p3PAbYQ7p1UlWl6vSPwfwU6TMSWK7TTu+WUY4ZjyZQGniGGt2oNVvyNSpyZYSB43zMXVLcBm08MTMkg== + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== +get-caller-file@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -3411,32 +3711,20 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.1" -get-own-enumerable-property-symbols@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" - integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== - get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== -get-stdin@8.0.0, get-stdin@~8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" - integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== - get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= -get-stream@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" +get-stdin@~8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" + integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== get-stream@^6.0.0: version "6.0.1" @@ -3489,13 +3777,20 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.0.0, glob-parent@^5.1.2, glob-parent@~5.1.0: +glob-parent@^5.1.2, glob-parent@~5.1.0: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + glob-stream@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" @@ -3524,7 +3819,7 @@ glob@7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.5, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0: +glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0, glob@~7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -3536,18 +3831,6 @@ glob@^7.0.5, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" -glob@~7.1.6: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - global-dirs@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" @@ -3560,12 +3843,12 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globals@^12.1.0: - version "12.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" - integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== +globals@^13.6.0, globals@^13.9.0: + version "13.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e" + integrity sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg== dependencies: - type-fest "^0.8.1" + type-fest "^0.20.2" globals@^9.18.0: version "9.18.0" @@ -3683,6 +3966,13 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + hook-std@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/hook-std/-/hook-std-2.0.0.tgz#ff9aafdebb6a989a354f729bb6445cf4a3a7077c" @@ -3743,7 +4033,7 @@ http-cache-semantics@^4.1.0: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== -http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.1: +http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== @@ -3752,6 +4042,15 @@ http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.1: agent-base "6" debug "4" +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -3761,6 +4060,14 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +https-proxy-agent@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz#b8c286433e87602311b01c8ea34413d856a4af81" + integrity sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg== + dependencies: + agent-base "^4.3.0" + debug "^3.1.0" + https-proxy-agent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" @@ -3769,11 +4076,6 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" -human-signals@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" - integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== - human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -3786,21 +4088,10 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" -husky@^4.2.5: - version "4.3.8" - resolved "https://registry.yarnpkg.com/husky/-/husky-4.3.8.tgz#31144060be963fd6850e5cc8f019a1dfe194296d" - integrity sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow== - dependencies: - chalk "^4.0.0" - ci-info "^2.0.0" - compare-versions "^3.6.0" - cosmiconfig "^7.0.0" - find-versions "^4.0.0" - opencollective-postinstall "^2.0.2" - pkg-dir "^5.0.0" - please-upgrade-node "^3.2.0" - slash "^3.0.0" - which-pm-runs "^1.0.0" +husky@^7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.4.tgz#242048245dc49c8fb1bf0cc7cfb98dd722531535" + integrity sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ== ice-cap@0.0.4: version "0.0.4" @@ -3810,7 +4101,7 @@ ice-cap@0.0.4: cheerio "0.20.0" color-logger "0.0.3" -iconv-lite@^0.4.24, iconv-lite@^0.4.4: +iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -3831,6 +4122,16 @@ iconv-lite@^0.6.2, iconv-lite@^0.6.3: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" +ieee754@1.1.13: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +ieee754@^1.1.4: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore-walk@^3.0.1, ignore-walk@^3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335" @@ -3843,7 +4144,7 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.1.4, ignore@^5.1.8, ignore@~5.1.8: +ignore@^5.1.4, ignore@^5.1.8, ignore@~5.1.9: version "5.1.9" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.9.tgz#9ec1a5cbe8e1446ec60d4420060d43aa6e7382fb" integrity sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ== @@ -3856,12 +4157,10 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" -import-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/import-from/-/import-from-3.0.0.tgz#055cfec38cd5a27d8057ca51376d7d3bf0891966" - integrity sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ== - dependencies: - resolve-from "^5.0.0" +import-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-4.0.0.tgz#2710b8d66817d232e16f4166e319248d3d5492e2" + integrity sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ== imurmurhash@^0.1.4: version "0.1.4" @@ -3878,7 +4177,7 @@ infer-owner@^1.0.4: resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== -inflection@1.13.1: +inflection@^1.13.1: version "1.13.1" resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.13.1.tgz#c5cadd80888a90cf84c2e96e340d7edc85d5f0cb" integrity sha512-dldYtl2WlN0QDkIDtg8+xFwOS2Tbmp12t1cHa5/YClU6ZQjTFm7B66UcVbh9NQB+HvT5BAd2t5+yKsBkw5pcqA== @@ -3891,7 +4190,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -3901,7 +4200,7 @@ ini@^1.3.4, ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -ini@^2.0.0: +ini@^2.0.0, ini@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== @@ -3919,25 +4218,6 @@ init-package-json@^2.0.5: validate-npm-package-license "^3.0.4" validate-npm-package-name "^3.0.0" -inquirer@^7.0.0: - version "7.3.3" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" - integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.19" - mute-stream "0.0.8" - run-async "^2.4.0" - rxjs "^6.6.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - internal-slot@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" @@ -3985,6 +4265,11 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + is-bigint@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" @@ -4043,6 +4328,11 @@ is-date-object@^1.0.1: dependencies: has-tostringtag "^1.0.0" +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -4070,6 +4360,11 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-fullwidth-code-point@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" + integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== + is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" @@ -4111,11 +4406,6 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= - is-obj@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" @@ -4154,11 +4444,6 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" - integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= - is-relative@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" @@ -4209,11 +4494,6 @@ is-unc-path@^1.0.0: dependencies: unc-path-regex "^0.1.2" -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - is-utf8@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" @@ -4236,12 +4516,19 @@ is-windows@^1.0.1, is-windows@^1.0.2: resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== +is-wsl@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= -isarray@~1.0.0: +isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= @@ -4333,10 +4620,15 @@ java-properties@^1.0.0: resolved "https://registry.yarnpkg.com/java-properties/-/java-properties-1.0.2.tgz#ccd1fa73907438a5b5c38982269d0e771fe78211" integrity sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ== -js-combinatorics@^0.5.5: - version "0.5.5" - resolved "https://registry.yarnpkg.com/js-combinatorics/-/js-combinatorics-0.5.5.tgz#78d68a6db24bbd58173ded714deee75bc4335e75" - integrity sha512-WglFY9EQvwndNhuJLxxyjnC16649lfZly/G3M3zgQMwcWlJDJ0Jn9niPWeYjnLXwWOEycYVxR2Tk98WLeFkrcw== +jmespath@0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" + integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= + +js-combinatorics@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/js-combinatorics/-/js-combinatorics-0.6.1.tgz#d26e9a7aaac03a463611d18309fa9010ff903eff" + integrity sha512-VDPHc5J++qdzvngxUhOnUGwegFB9vlNzyWTD6oXKCd9qvw8NAsZdFaWK44W91U0GtBR9R0yppMgzNwTJQYymqg== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" @@ -4356,7 +4648,7 @@ js-yaml@3.13.1: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^3.13.1, 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" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== @@ -4364,6 +4656,13 @@ js-yaml@^3.13.1, js-yaml@~3.14.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsbi@^3.1.1: version "3.2.5" resolved "https://registry.yarnpkg.com/jsbi/-/jsbi-3.2.5.tgz#b37bb90e0e5c2814c1c2a1bcd8c729888a2e37d6" @@ -4374,10 +4673,10 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -jsdoctypeparser@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsdoctypeparser/-/jsdoctypeparser-6.1.0.tgz#acfb936c26300d98f1405cb03e20b06748e512a8" - integrity sha512-UCQBZ3xCUBv/PLfwKAJhp6jmGOSLFNKzrotXGNgbKhWvz27wPsCsVeP7gIcHPElQw2agBmynAitXqhxR58XAmA== +jsdoc-type-pratt-parser@2.0.0, jsdoc-type-pratt-parser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.0.0.tgz#ec739a0868922515fcb179852e990e89b52b9044" + integrity sha512-sUuj2j48wxrEpbFjDp1sAesAxPiLT+z0SWVmMafyIINs6Lj5gIPKh3VrkBZu4E/Dv+wHpOot0m6H8zlHQjwqeQ== jsdom@^7.0.2: version "7.2.2" @@ -4425,10 +4724,10 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" @@ -4485,14 +4784,30 @@ jsonparse@^1.2.0, jsonparse@^1.3.1: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= +jsonwebtoken@^8.5.1: + version "8.5.1" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" + integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^5.6.0" + jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + version "1.4.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== dependencies: assert-plus "1.0.0" extsprintf "1.3.0" - json-schema "0.2.3" + json-schema "0.4.0" verror "1.10.0" just-diff-apply@^3.0.0: @@ -4519,7 +4834,7 @@ jwa@^1.4.1: ecdsa-sig-formatter "1.0.11" safe-buffer "^5.0.1" -jws@3.x.x: +jws@3.x.x, jws@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== @@ -4539,6 +4854,11 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" +kuler@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" + integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== + lazystream@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.1.tgz#494c831062f1f9408251ec44db1cba29242a2638" @@ -4546,7 +4866,7 @@ lazystream@^1.0.0: dependencies: readable-stream "^2.0.5" -lcov-result-merger@^3.0.0: +lcov-result-merger@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/lcov-result-merger/-/lcov-result-merger-3.1.0.tgz#ae6d1be663dbf7d586d8004642359d39de72039e" integrity sha512-vGXaMNGZRr4cYvW+xMVg+rg7qd5DX9SbGXl+0S3k85+gRZVK4K7UvxPWzKb/qiMwe+4bx3EOrW2o4mbdb1WnsA== @@ -4562,7 +4882,15 @@ lead@^1.0.0: dependencies: flush-write-stream "^1.0.2" -levn@^0.3.0, levn@~0.3.0: +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= @@ -4680,10 +5008,15 @@ libnpmversion@^1.2.1: semver "^7.3.5" stringify-package "^1.0.1" +lilconfig@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.4.tgz#f4507d043d7058b380b6a8f5cb7bcd4b34cee082" + integrity sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA== + lines-and-columns@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" - integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== linkify-it@^3.0.1: version "3.0.3" @@ -4692,37 +5025,36 @@ linkify-it@^3.0.1: dependencies: uc.micro "^1.0.1" -lint-staged@^10.2.6: - version "10.5.4" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.5.4.tgz#cd153b5f0987d2371fc1d2847a409a2fe705b665" - integrity sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg== +lint-staged@^12.1.2: + version "12.1.2" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-12.1.2.tgz#90c571927e1371fc133e720671dd7989eab53f74" + integrity sha512-bSMcQVqMW98HLLLR2c2tZ+vnDCnx4fd+0QJBQgN/4XkdspGRPc8DGp7UuOEBe1ApCfJ+wXXumYnJmU+wDo7j9A== dependencies: - chalk "^4.1.0" - cli-truncate "^2.1.0" - commander "^6.2.0" - cosmiconfig "^7.0.0" - debug "^4.2.0" - dedent "^0.7.0" + cli-truncate "^3.1.0" + colorette "^2.0.16" + commander "^8.3.0" + debug "^4.3.2" enquirer "^2.3.6" - execa "^4.1.0" - listr2 "^3.2.2" - log-symbols "^4.0.0" - micromatch "^4.0.2" + execa "^5.1.1" + lilconfig "2.0.4" + listr2 "^3.13.3" + micromatch "^4.0.4" normalize-path "^3.0.0" - please-upgrade-node "^3.2.0" - string-argv "0.3.1" - stringify-object "^3.3.0" + object-inspect "^1.11.0" + string-argv "^0.3.1" + supports-color "^9.0.2" + yaml "^1.10.2" -listr2@^3.2.2: - version "3.13.3" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.13.3.tgz#d8f6095c9371b382c9b1c2bc33c5941d8e177f11" - integrity sha512-VqAgN+XVfyaEjSaFewGPcDs5/3hBbWVaX1VgWv2f52MF7US45JuARlArULctiB44IIcEk3JF7GtoFCLqEdeuPA== +listr2@^3.13.3: + version "3.13.5" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.13.5.tgz#105a813f2eb2329c4aae27373a281d610ee4985f" + integrity sha512-3n8heFQDSk+NcwBn3CgxEibZGaRzx+pC64n3YjpMD1qguV4nWus3Al+Oo3KooqFKTQEJ1v7MmnbnyyNspgx3NA== dependencies: cli-truncate "^2.1.0" - clone "^2.1.2" colorette "^2.0.16" log-update "^4.0.0" p-map "^4.0.0" + rfdc "^1.3.0" rxjs "^7.4.0" through "^2.3.8" wrap-ansi "^7.0.0" @@ -4817,16 +5149,36 @@ lodash.foreach@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM= -lodash.get@^4.4.2: +lodash.get@^4, lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= + lodash.ismatch@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" integrity sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc= +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= + lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" @@ -4842,11 +5194,16 @@ lodash.map@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= -lodash.merge@^4.4.0: +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" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= + lodash.pick@^4.2.1: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" @@ -4872,7 +5229,7 @@ lodash.uniqby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" integrity sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI= -lodash@^4.1.0, lodash@^4.15.0, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.2.0: +lodash@^4.1.0, lodash@^4.15.0, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.2.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -4884,14 +5241,6 @@ log-symbols@3.0.0: dependencies: chalk "^2.4.2" -log-symbols@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - log-update@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" @@ -4902,6 +5251,17 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" +logform@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/logform/-/logform-2.3.0.tgz#a3997a05985de2ebd325ae0d166dffc9c6fe6b57" + integrity sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ== + dependencies: + colors "^1.2.1" + fecha "^4.2.0" + ms "^2.1.1" + safe-stable-stringify "^1.1.0" + triple-beam "^1.3.0" + long@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" @@ -4936,6 +5296,11 @@ make-dir@^3.0.0, make-dir@^3.0.2: dependencies: semver "^6.0.0" +make-error@^1, 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== + make-fetch-happen@^9.0.1, make-fetch-happen@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" @@ -4968,7 +5333,7 @@ map-obj@^4.0.0: resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== -mariadb@^2.3.1: +mariadb@^2.5.5: version "2.5.5" resolved "https://registry.yarnpkg.com/mariadb/-/mariadb-2.5.5.tgz#a9aff9f1e57231a415a21254489439beb501c803" integrity sha512-6dklvcKWuuaV1JjAwnE2ezR+jTt7JrZHftgeHHBmjB0wgfaUpdxol1DPWclwMcCrsO9yoM0FuCOiCcCgXc//9Q== @@ -4981,48 +5346,48 @@ mariadb@^2.3.1: moment-timezone "^0.5.33" please-upgrade-node "^3.2.0" -markdown-it@12.0.2: - version "12.0.2" - resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.0.2.tgz#4401beae8df8aa2221fc6565a7188e60a06ef0ed" - integrity sha512-4Lkvjbv2kK+moL9TbeV+6/NHx+1Q+R/NIdUlFlkqkkzUcTod4uiyTJRiBidKR9qXSdkNFkgv+AELY8KN9vSgVA== +markdown-it@12.2.0: + version "12.2.0" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.2.0.tgz#091f720fd5db206f80de7a8d1f1a7035fd0d38db" + integrity sha512-Wjws+uCrVQRqOoJvze4HCqkKl1AsSh95iFAeQDwnyfxM09divCBSXlDR1uTvyUP3Grzpn4Ru8GeCxYPM8vkCQg== dependencies: argparse "^2.0.1" - entities "~2.0.0" + entities "~2.1.0" linkify-it "^3.0.1" mdurl "^1.0.1" uc.micro "^1.0.5" -markdownlint-cli@^0.26.0: - version "0.26.0" - resolved "https://registry.yarnpkg.com/markdownlint-cli/-/markdownlint-cli-0.26.0.tgz#cd89e3e39a049303ec125c8aa291da4f3325df29" - integrity sha512-biLfeGNZG9nw0yJbtFBzRlew2/P5w7JSseKwolSox3zejs7dLpGvPgqbC+iqJnqqGWcWLtXaXh8bBEKWmfl10A== +markdownlint-cli@^0.30.0: + version "0.30.0" + resolved "https://registry.yarnpkg.com/markdownlint-cli/-/markdownlint-cli-0.30.0.tgz#4ec0ab85a491eb161182e5c26eff308bf90f18f3" + integrity sha512-NiG8iERjwsRZtJAIyLMDdYL2O3bJVn3fUxzDl+6Iv61/YYz9H9Nzgke/v0/cW9HfGvgZHhbfI19LFMp6gbKdyw== dependencies: - commander "~6.2.1" + commander "~8.3.0" deep-extend "~0.6.0" get-stdin "~8.0.0" - glob "~7.1.6" - ignore "~5.1.8" - js-yaml "~3.14.1" + glob "~7.2.0" + ignore "~5.1.9" + js-yaml "^4.1.0" jsonc-parser "~3.0.0" lodash.differencewith "~4.5.0" lodash.flatten "~4.4.0" - markdownlint "~0.22.0" - markdownlint-rule-helpers "~0.13.0" + markdownlint "~0.24.0" + markdownlint-rule-helpers "~0.15.0" minimatch "~3.0.4" minimist "~1.2.5" - rc "~1.2.8" + run-con "~1.2.10" -markdownlint-rule-helpers@~0.13.0: - version "0.13.0" - resolved "https://registry.yarnpkg.com/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.13.0.tgz#7cc6553bc7f8c4c8a43cf66fb2a3a652124f46f9" - integrity sha512-rRY0itbcHG4e+ntz0bbY3AIceSJMKS0TafEMgEtKVHRZ54/JUSy6/4ypCL618RlJvYRej+xMLxX5nkJqIeTZaQ== +markdownlint-rule-helpers@~0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.15.0.tgz#11434c573649b9235ae70b967314f5711f7d8fa8" + integrity sha512-A+9mswc3m/kkqpJCqntmte/1VKhDJ+tjZsERLz5L4h/Qr7ht2/BkGkgY5E7/wsxIhcpl+ctIfz+oS3PQrMOB2w== -markdownlint@~0.22.0: - version "0.22.0" - resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.22.0.tgz#4ed95b61c17ae9f4dfca6a01f038c744846c0a72" - integrity sha512-J4B+iMc12pOdp/wfYi03W2qfAfEyiZzq3qvQh/8vOMNU8vXYY6Jg440EY7dWTBCqROhb1i4nAn3BTByJ5kdx1w== +markdownlint@~0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.24.0.tgz#224b53f671367a237d40c8be1745c7be9a322671" + integrity sha512-OJIGsGFV/rC9irI5E1FMy6v9hdACSwaa+EN3224Y5KG8zj2EYzdHOw0pOJovIYmjNfEZ9BtxUY4P7uYHTSNnbQ== dependencies: - markdown-it "12.0.2" + markdown-it "12.2.0" marked-terminal@^4.1.1: version "4.2.0" @@ -5041,11 +5406,6 @@ marked@0.3.19: resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.19.tgz#5d47f709c4c9fc3c216b6d46127280f40b39d790" integrity sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg== -marked@^1.1.0: - version "1.2.9" - resolved "https://registry.yarnpkg.com/marked/-/marked-1.2.9.tgz#53786f8b05d4c01a2a5a76b7d1ec9943d29d72dc" - integrity sha512-H8lIX2SvyitGX+TRdtS06m1jHMijKN/XjfH6Ooii9fvxMlh8QdqBfBDkGUpMWH2kQNrtixjzYUa3SH8ROTgRRw== - marked@^2.0.0: version "2.1.3" resolved "https://registry.yarnpkg.com/marked/-/marked-2.1.3.tgz#bd017cef6431724fd4b27e0657f5ceb14bff3753" @@ -5091,22 +5451,22 @@ micromatch@^4.0.2, micromatch@^4.0.4: braces "^3.0.1" picomatch "^2.2.3" -mime-db@1.50.0: - version "1.50.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.50.0.tgz#abd4ac94e98d3c0e185016c67ab45d5fde40c11f" - integrity sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A== +mime-db@1.51.0: + version "1.51.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.33" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.33.tgz#1fa12a904472fafd068e48d9e8401f74d3f70edb" - integrity sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g== +mime-types@^2.1.12, mime-types@^2.1.29, mime-types@~2.1.19: + version "2.1.34" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" + integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== dependencies: - mime-db "1.50.0" + mime-db "1.51.0" -mime@^2.4.3: - version "2.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" - integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== +mime@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== mimic-fn@^2.1.0: version "2.1.0" @@ -5118,6 +5478,11 @@ min-indent@^1.0.0: resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -5230,7 +5595,7 @@ mkdirp-infer-owner@^2.0.0: infer-owner "^1.0.4" mkdirp "^1.0.3" -mkdirp@0.5.5, mkdirp@^0.5.1, mkdirp@^0.5.5: +mkdirp@0.5.5, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.5: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -5242,7 +5607,7 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mocha@^7.1.2: +mocha@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.2.0.tgz#01cc227b00d875ab1eed03a75106689cfed5a604" integrity sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ== @@ -5272,6 +5637,14 @@ mocha@^7.1.2: yargs-parser "13.1.2" yargs-unparser "1.6.0" +mock-require@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/mock-require/-/mock-require-3.0.3.tgz#ccd544d9eae81dd576b3f219f69ec867318a1946" + integrity sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg== + dependencies: + get-caller-file "^1.0.2" + normalize-path "^2.1.1" + modify-values@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" @@ -5282,14 +5655,14 @@ module-alias@^2.2.2: resolved "https://registry.yarnpkg.com/module-alias/-/module-alias-2.2.2.tgz#151cdcecc24e25739ff0aa6e51e1c5716974c0e0" integrity sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q== -moment-timezone@^0.5.31, moment-timezone@^0.5.33: - version "0.5.33" - resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.33.tgz#b252fd6bb57f341c9b59a5ab61a8e51a73bbd22c" - integrity sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w== +moment-timezone@^0.5.15, moment-timezone@^0.5.33, moment-timezone@^0.5.34: + version "0.5.34" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.34.tgz#a75938f7476b88f155d3504a9343f7519d9a405c" + integrity sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg== dependencies: moment ">= 2.9.0" -"moment@>= 2.9.0", moment@^2.26.0: +"moment@>= 2.9.0", moment@^2.23.0, moment@^2.29.1: version "2.29.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== @@ -5314,15 +5687,15 @@ ms@^2.0.0, ms@^2.1.1, ms@^2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -mute-stream@0.0.8, mute-stream@~0.0.4: +mute-stream@~0.0.4: version "0.0.8" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -mysql2@^2.1.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/mysql2/-/mysql2-2.3.2.tgz#3efe9814dbf1c2a3d7c2a1fc4666235939943ff9" - integrity sha512-JUSA50rt/nSew8aq8xe3pRk5Q4y/M5QdSJn7Ey3ndOlPp2KXuialQ0sS35DNhPT5Z5PnOiIwSSQvKkl1WorqRA== +mysql2@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/mysql2/-/mysql2-2.3.3.tgz#944f3deca4b16629052ff8614fbf89d5552545a0" + integrity sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA== dependencies: denque "^2.0.1" generate-function "^2.3.1" @@ -5340,11 +5713,6 @@ named-placeholders@^1.1.2: dependencies: lru-cache "^4.1.3" -nan@^2.12.1: - version "2.15.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" - integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== - native-duplexpair@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/native-duplexpair/-/native-duplexpair-1.0.0.tgz#7899078e64bf3c8a3d732601b3d40ff05db58fa0" @@ -5379,22 +5747,22 @@ nerf-dart@^1.0.0: resolved "https://registry.yarnpkg.com/nerf-dart/-/nerf-dart-1.0.0.tgz#e6dab7febf5ad816ea81cf5c629c5a0ebde72c1a" integrity sha1-5tq3/r9a2Bbqgc9cYpxaDr3nLBo= -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -nise@^4.0.4: - version "4.1.0" - resolved "https://registry.yarnpkg.com/nise/-/nise-4.1.0.tgz#8fb75a26e90b99202fa1e63f448f58efbcdedaf6" - integrity sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA== +nise@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/nise/-/nise-5.1.0.tgz#713ef3ed138252daef20ec035ab62b7a28be645c" + integrity sha512-W5WlHu+wvo3PaKLsJJkgPup2LrsXCcm7AWwyNZkUnn5rwPkuPBi3Iwk5SQtN0mv+K65k7nKKjwNQ30wg3wLAQQ== dependencies: "@sinonjs/commons" "^1.7.0" - "@sinonjs/fake-timers" "^6.0.0" + "@sinonjs/fake-timers" "^7.0.4" "@sinonjs/text-encoding" "^0.7.1" just-extend "^4.0.2" path-to-regexp "^1.7.0" +node-addon-api@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" + integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== + node-emoji@^1.10.0: version "1.11.0" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" @@ -5410,13 +5778,31 @@ node-environment-flags@1.0.6: object.getownpropertydescriptors "^2.0.3" semver "^5.7.0" -node-fetch@^2.6.1: +node-fetch@^2.6.0, node-fetch@^2.6.1: version "2.6.6" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89" integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA== dependencies: whatwg-url "^5.0.0" +node-gyp@3.x: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "^2.87.0" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + node-gyp@^7.1.0, node-gyp@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-7.1.2.tgz#21a810aebb187120251c3bcec979af1587b188ae" @@ -5474,6 +5860,13 @@ noms@0.0.0: inherits "^2.0.1" readable-stream "~1.0.31" +"nopt@2 || 3": + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + nopt@^4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" @@ -5616,7 +6009,7 @@ npm-registry-fetch@^11.0.0: minizlib "^2.0.0" npm-package-arg "^8.0.0" -npm-run-path@^4.0.0, npm-run-path@^4.0.1: +npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -5704,7 +6097,7 @@ npm@^7.0.0: which "^2.0.2" write-file-atomic "^3.0.3" -npmlog@^4.0.2, npmlog@^4.1.2: +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.2, npmlog@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== @@ -5724,7 +6117,7 @@ npmlog@^5.0.1: gauge "^3.0.0" set-blocking "^2.0.0" -nth-check@>=2.0.1, nth-check@^2.0.0: +nth-check@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== @@ -5748,7 +6141,7 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.4.tgz#2285631f34a95f0d0395cd900c96ed39b58f346e" integrity sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ== -nyc@^15.0.0: +nyc@^15.1.0: version "15.1.0" resolved "https://registry.yarnpkg.com/nyc/-/nyc-15.1.0.tgz#1335dae12ddc87b6e249d5a1994ca4bdaea75f02" integrity sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A== @@ -5821,11 +6214,6 @@ object.assign@^4.0.4, object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.entries-ponyfill@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object.entries-ponyfill/-/object.entries-ponyfill-1.0.1.tgz#29abdf77cbfbd26566dd1aa24e9d88f65433d256" - integrity sha1-Kavfd8v70mVm3RqiTp2I9lQz0lY= - object.getownpropertydescriptors@^2.0.3: version "2.1.3" resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz#b223cf38e17fefb97a63c10c91df72ccb386df9e" @@ -5835,6 +6223,17 @@ object.getownpropertydescriptors@^2.0.3: define-properties "^1.1.3" es-abstract "^1.19.1" +ocsp@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ocsp/-/ocsp-1.2.0.tgz#469a1776b457dee67eb0201408c1946bac4076cc" + integrity sha1-RpoXdrRX3uZ+sCAUCMGUa6xAdsw= + dependencies: + asn1.js "^4.8.0" + asn1.js-rfc2560 "^4.0.0" + asn1.js-rfc5280 "^2.0.0" + async "^1.5.2" + simple-lru-cache "0.0.2" + once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -5842,6 +6241,13 @@ once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: dependencies: wrappy "1" +one-time@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" + integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== + dependencies: + fn.name "1.x.x" + onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" @@ -5849,17 +6255,20 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -opencollective-postinstall@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" - integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q== +open@^7.3.1: + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" opener@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== -optionator@^0.8.1, optionator@^0.8.3: +optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== @@ -5871,6 +6280,18 @@ optionator@^0.8.1, optionator@^0.8.3: type-check "~0.3.2" word-wrap "~1.2.3" +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + ordered-read-streams@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" @@ -5883,12 +6304,12 @@ os-homedir@^1.0.0: resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= -os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: +os-tmpdir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@^0.1.4: +osenv@0, osenv@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== @@ -6103,6 +6524,11 @@ parse-json@^5.0.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + parse5-htmlparser2-tree-adapter@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" @@ -6147,17 +6573,12 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@>=1.0.7, path-parse@^1.0.6: +path-parse@^1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== @@ -6189,7 +6610,7 @@ pg-connection-string@^2.5.0: resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34" integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ== -pg-hstore@^2.x: +pg-hstore@^2.3.4: version "2.3.4" resolved "https://registry.yarnpkg.com/pg-hstore/-/pg-hstore-2.3.4.tgz#4425e3e2a3e15d2a334c35581186c27cf2e9b8dd" integrity sha512-N3SGs/Rf+xA1M2/n0JBiXFDVMzdekwLZLAO0g7mpDY9ouX+fDI7jS6kTq3JujmYbtNSJ53TJ0q4G98KVZSM4EA== @@ -6222,7 +6643,7 @@ pg-types@^2.1.0: postgres-date "~1.0.4" postgres-interval "^1.1.0" -pg@^8.2.1: +pg@^8.7.1: version "8.7.1" resolved "https://registry.yarnpkg.com/pg/-/pg-8.7.1.tgz#9ea9d1ec225980c36f94e181d009ab9f4ce4c471" integrity sha512-7bdYcv7V6U3KAtWjpQJJBww0UEsWuh4yQ/EjNf2HeO/NnvKjpvhEIe/A/TleP6wtmSKnUnghs5A9jUoK6iDdkA== @@ -6272,13 +6693,6 @@ pkg-dir@^4.1.0: dependencies: find-up "^4.0.0" -pkg-dir@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" - integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== - dependencies: - find-up "^5.0.0" - please-upgrade-node@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" @@ -6308,6 +6722,11 @@ postgres-interval@^1.1.0: dependencies: xtend "^4.0.0" +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -6330,6 +6749,11 @@ process-on-spawn@^1.0.0: dependencies: fromentries "^1.2.0" +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + progress@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" @@ -6370,7 +6794,7 @@ pseudomap@^1.0.2: resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= -psl@^1.1.28: +psl@^1.1.28, psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== @@ -6383,14 +6807,6 @@ pump@^2.0.0: end-of-stream "^1.1.0" once "^1.3.1" -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - pumpify@^1.3.5: version "1.5.1" resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" @@ -6400,11 +6816,23 @@ pumpify@^1.3.5: inherits "^2.0.3" pump "^2.0.0" +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +python-struct@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/python-struct/-/python-struct-1.1.3.tgz#f0ff1845ec520408e94dd8492bfd770aad26cae3" + integrity sha512-UsI/mNvk25jRpGKYI38Nfbv84z48oiIWwG67DLVvjRhy8B/0aIK+5Ju5WOHgw/o9rnEmbAS00v4rgKFQeC332Q== + dependencies: + long "^4.0.0" + q@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -6420,6 +6848,11 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -6430,12 +6863,12 @@ quick-lru@^4.0.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== -ramda@^0.27.0: +ramda@^0.27.1: version "0.27.1" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.1.tgz#66fc2df3ef873874ffc2da6aa8984658abacf5c9" integrity sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw== -rc@^1.2.7, rc@^1.2.8, rc@~1.2.8: +rc@^1.2.7, rc@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -6504,7 +6937,7 @@ readable-stream@1.1: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.1, readable-stream@^3.1.1, readable-stream@^3.6.0: +readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.1, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -6513,7 +6946,7 @@ readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.1, readable-stre string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: +readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@^2.3.7, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -6573,25 +7006,15 @@ regenerator-runtime@^0.11.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== -regenerator-runtime@^0.13.4: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - regexpp@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== -regextras@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/regextras/-/regextras-0.7.1.tgz#be95719d5f43f9ef0b9fa07ad89b7c606995a3b2" - integrity sha512-9YXf6xtW+qzQ+hcMQXx95MOvfqXFgsKDZodX3qZB0x2n5Z94ioetIITsBtvJbiOyxa/6s9AtyweBLCdPmPko/w== +regextras@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/regextras/-/regextras-0.8.0.tgz#ec0f99853d4912839321172f608b544814b02217" + integrity sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ== registry-auth-token@^4.0.0: version "4.2.1" @@ -6648,7 +7071,7 @@ replace-ext@^1.0.0: resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a" integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== -"request@>= 2.52.0", request@^2.55.0, request@^2.88.2: +"request@>= 2.52.0", request@^2.55.0, request@^2.87.0, request@^2.88.0, request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -6674,6 +7097,14 @@ replace-ext@^1.0.0: tunnel-agent "^0.6.0" uuid "^3.3.2" +requestretry@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/requestretry/-/requestretry-6.0.0.tgz#a213b2133ee3b18f74c2bbc0f4e094e561b57335" + integrity sha512-X7O+BMlfHgzetfSDtgQIMinLn1BuT+95W12iffDzyOS+HLoBEIQqCZv++UTChUWVjOu+pudbocD76+4j+jK9ww== + dependencies: + extend "^3.0.2" + lodash "^4.17.15" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -6724,10 +7155,10 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" -retry-as-promised@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/retry-as-promised/-/retry-as-promised-3.2.0.tgz#769f63d536bec4783549db0777cb56dadd9d8543" - integrity sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg== +retry-as-promised@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/retry-as-promised/-/retry-as-promised-4.0.0.tgz#e19dc63474860f751e371ccccbfa16f6c1efeaa0" + integrity sha512-zuqltYoBckZPoqLjC0eyvGpmM/psgpcreq0PLYVzBSb0Xq382XJrKNgu+fgHDy9U3R66adgFe5Viyx3D+gRvXA== dependencies: any-promise "^1.3.0" @@ -6746,14 +7177,12 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -rimraf@^2.6.1, rimraf@^2.6.3: +rimraf@2, rimraf@^2.6.1, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -6767,10 +7196,15 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== +run-con@~1.2.10: + version "1.2.10" + resolved "https://registry.yarnpkg.com/run-con/-/run-con-1.2.10.tgz#90de9d43d20274d00478f4c000495bd72f417d22" + integrity sha512-n7PZpYmMM26ZO21dd8y3Yw1TRtGABjRtgPSgFS/nhzfvbJMXFtJhJVyEgayMiP+w/23craJjsnfDvx4W4ue/HQ== + dependencies: + deep-extend "^0.6.0" + ini "~2.0.0" + minimist "^1.2.5" + strip-json-comments "~3.1.1" run-parallel@^1.1.9: version "1.2.0" @@ -6779,13 +7213,6 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rxjs@^6.6.0: - version "6.6.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" - integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== - dependencies: - tslib "^1.9.0" - rxjs@^7.4.0: version "7.4.0" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.4.0.tgz#a12a44d7eebf016f5ff2441b87f28c9a51cebc68" @@ -6803,11 +7230,21 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-stable-stringify@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz#c8a220ab525cd94e60ebf47ddc404d610dc5d84a" + integrity sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw== + "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sax@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o= + sax@>=0.6.0, sax@^1.1.4, sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" @@ -6818,16 +7255,16 @@ semantic-release-fail-on-major-bump@^1.0.0: resolved "https://registry.yarnpkg.com/semantic-release-fail-on-major-bump/-/semantic-release-fail-on-major-bump-1.0.0.tgz#a4fe055258415040f6170c175596cedb4d4ffb82" integrity sha512-vFbUVEQC60p3n+0NJc4D+Z6TS+5Q4AdG72pe5hsmcVEcaK+w+nPxjefLl3bJjphxc6AVH9cAZM0ZTnmiTG6eLA== -semantic-release@^17.3.0: - version "17.4.7" - resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-17.4.7.tgz#88e1dce7294cc43acc54c4e0a83f582264567206" - integrity sha512-3Ghu8mKCJgCG3QzE5xphkYWM19lGE3XjFdOXQIKBM2PBpBvgFQ/lXv31oX0+fuN/UjNFO/dqhNs8ATLBhg6zBg== +semantic-release@^18.0.1: + version "18.0.1" + resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-18.0.1.tgz#df5ad44b9c2fd67fe3cdbc660b3d1f55298b9f34" + integrity sha512-xTdKCaEnCzHr+Fqyhg/5I8P9pvY9z7WHa8TFCYIwcdPbuzAtQShOTzw3VNPsqBT+Yq1kFyBQFBKBYkGOlqWmfA== dependencies: - "@semantic-release/commit-analyzer" "^8.0.0" - "@semantic-release/error" "^2.2.0" - "@semantic-release/github" "^7.0.0" - "@semantic-release/npm" "^7.0.0" - "@semantic-release/release-notes-generator" "^9.0.0" + "@semantic-release/commit-analyzer" "^9.0.2" + "@semantic-release/error" "^3.0.0" + "@semantic-release/github" "^8.0.0" + "@semantic-release/npm" "^8.0.0" + "@semantic-release/release-notes-generator" "^10.0.0" aggregate-error "^3.0.0" cosmiconfig "^7.0.0" debug "^4.0.0" @@ -6864,60 +7301,48 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" -semver-regex@>=3.1.3: - version "4.0.2" - resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-4.0.2.tgz#fd3124efe81647b33eb90a9de07cb72992424a02" - integrity sha512-xyuBZk1XYqQkB687hMQqrCP+J9bdJSjPpZwdmmNjyxKW1K3LDXxqxw91Egaqkh/yheBIVtKPt4/1eybKVdCx3g== - semver-regex@^3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-3.1.3.tgz#b2bcc6f97f63269f286994e297e229b6245d0dc3" integrity sha512-Aqi54Mk9uYTjVexLnR67rTyBusmwd04cLkHy9hNvk3+G3nT2Oyg7E0l4XVbOaNwIvQ3hHeYxGcyEy+mKreyBFQ== -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.7.0: +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.6.0, semver@^5.7.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@7.3.2: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== - -semver@^6.0.0, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^7.1.1, semver@^7.1.2, semver@^7.1.3, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: +semver@7.3.5, semver@^7.1.1, semver@^7.1.2, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== dependencies: lru-cache "^6.0.0" +semver@^6.0.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= + seq-queue@^0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/seq-queue/-/seq-queue-0.0.5.tgz#d56812e1c017a6e4e7c3e3a37a1da6d78dd3c93e" integrity sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4= -sequelize-pool@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-6.1.0.tgz#caaa0c1e324d3c2c3a399fed2c7998970925d668" - integrity sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg== +sequelize-pool@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-7.1.0.tgz#210b391af4002762f823188fd6ecfc7413020768" + integrity sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg== set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -6925,11 +7350,6 @@ shebang-command@^2.0.0: dependencies: shebang-regex "^3.0.0" -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - shebang-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" @@ -6950,9 +7370,9 @@ side-channel@^1.0.4: object-inspect "^1.9.0" signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: - version "3.0.5" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f" - integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ== + version "3.0.6" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" + integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== signale@^1.2.1: version "1.4.0" @@ -6963,37 +7383,40 @@ signale@^1.2.1: figures "^2.0.0" pkg-conf "^2.1.0" -sinon-chai@^3.3.0: +simple-lru-cache@0.0.2, simple-lru-cache@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/simple-lru-cache/-/simple-lru-cache-0.0.2.tgz#d59cc3a193c1a5d0320f84ee732f6e4713e511dd" + integrity sha1-1ZzDoZPBpdAyD4Tucy9uRxPlEd0= + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + +sinon-chai@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-3.7.0.tgz#cfb7dec1c50990ed18c153f1840721cf13139783" integrity sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g== -sinon@^9.0.2: - version "9.2.4" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-9.2.4.tgz#e55af4d3b174a4443a8762fa8421c2976683752b" - integrity sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg== +sinon@^12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-12.0.1.tgz#331eef87298752e1b88a662b699f98e403c859e9" + integrity sha512-iGu29Xhym33ydkAT+aNQFBINakjq69kKO6ByPvTsm3yyIACfyQttRTP03aBP/I8GfhFmLzrnKwNNkr0ORb1udg== dependencies: - "@sinonjs/commons" "^1.8.1" - "@sinonjs/fake-timers" "^6.0.1" - "@sinonjs/samsam" "^5.3.1" - diff "^4.0.2" - nise "^4.0.4" - supports-color "^7.1.0" + "@sinonjs/commons" "^1.8.3" + "@sinonjs/fake-timers" "^8.1.0" + "@sinonjs/samsam" "^6.0.2" + diff "^5.0.0" + nise "^5.1.0" + supports-color "^7.2.0" slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - slice-ansi@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" @@ -7012,15 +7435,63 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +slice-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" + integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== + dependencies: + ansi-styles "^6.0.0" + is-fullwidth-code-point "^4.0.0" + smart-buffer@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== +snowflake-sdk@^1.6.1: + version "1.6.5" + resolved "https://registry.yarnpkg.com/snowflake-sdk/-/snowflake-sdk-1.6.5.tgz#9cbf1fb85cd595b6a69d8b6d42fab7961af727ec" + integrity sha512-TBIbC2DO4ahxq2s3oDNaIsm8G1oI9r3BFxW5JLra+Ph/Ci5nXo6jHb2KjrvPbzLfbjEJgs0mnpOQCgSz/xuvBQ== + dependencies: + "@azure/storage-blob" "^12.5.0" + agent-base "^4.3.0" + asn1.js-rfc2560 "^5.0.0" + asn1.js-rfc5280 "^3.0.0" + aws-sdk "^2.878.0" + axios "^0.21.4" + big-integer "^1.6.43" + bignumber.js "^2.4.0" + binascii "0.0.2" + browser-request "^0.3.3" + debug "^3.2.6" + expand-tilde "^2.0.2" + extend "^3.0.2" + generic-pool "^3.8.2" + glob "^7.1.6" + https-proxy-agent "^3.0.0" + jsonwebtoken "^8.5.1" + lodash "^4.17.21" + mime-types "^2.1.29" + mkdirp "^1.0.3" + mock-require "^3.0.3" + moment "^2.23.0" + moment-timezone "^0.5.15" + ocsp "^1.2.0" + open "^7.3.1" + python-struct "^1.1.3" + request "^2.88.0" + requestretry "^6.0.0" + simple-lru-cache "^0.0.2" + string-similarity "^4.0.4" + test-console "^2.0.0" + tmp "^0.2.1" + uuid "^3.3.2" + winston "^3.1.0" + socks-proxy-agent@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.1.0.tgz#869cf2d7bd10fea96c7ad3111e81726855e285c3" - integrity sha512-57e7lwCN4Tzt3mXz25VxOErJKXlPfXmkMLnk310v/jwW20jWRVcgsOit+xNkN3eIEdB47GwnfAEBLacZ/wVIKg== + version "6.1.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz#e664e8f1aaf4e1fb3df945f09e3d94f911137f87" + integrity sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew== dependencies: agent-base "^6.0.2" debug "^4.3.1" @@ -7034,10 +7505,10 @@ socks@^2.6.1: ip "^1.1.5" smart-buffer "^4.1.0" -source-map-support@^0.5.20: - version "0.5.20" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" - integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== +source-map-support@^0.5.17, source-map-support@^0.5.21: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -7082,7 +7553,7 @@ spdx-exceptions@^2.1.0: resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== -spdx-expression-parse@^3.0.0: +spdx-expression-parse@^3.0.0, spdx-expression-parse@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== @@ -7091,9 +7562,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.10" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz#0d9becccde7003d6c658d487dd48a32f0bf3014b" - integrity sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA== + version "3.0.11" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" + integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== split2@^3.0.0, split2@^3.1.1: version "3.2.2" @@ -7126,13 +7597,15 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sqlite3@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-4.2.0.tgz#49026d665e9fc4f922e56fb9711ba5b4c85c4901" - integrity sha512-roEOz41hxui2Q7uYnWsjMOTry6TcNUNmp8audCx18gF10P2NknwdpF+E+HKvz/F2NvPKGGBF4NGc+ZPQ+AABwg== +sqlite3@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.0.2.tgz#00924adcc001c17686e0a6643b6cbbc2d3965083" + integrity sha512-1SdTNo+BVU211Xj1csWa8lV6KM0CtucDwRyA0VHl91wEH1Mgh7RxUpI4rVvG7OhHrzCSGaVyW5g8vKvlrk9DJA== dependencies: - nan "^2.12.1" + node-addon-api "^3.0.0" node-pre-gyp "^0.11.0" + optionalDependencies: + node-gyp "3.x" sqlstring@^2.3.2: version "2.3.2" @@ -7166,6 +7639,11 @@ stack-chain@^1.3.7: resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285" integrity sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU= +stack-trace@0.0.x: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= + stream-combiner2@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe" @@ -7179,11 +7657,16 @@ stream-shift@^1.0.0: resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== -string-argv@0.3.1: +string-argv@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== +string-similarity@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/string-similarity/-/string-similarity-4.0.4.tgz#42d01ab0b34660ea8a018da8f56a3309bb8b2a5b" + integrity sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ== + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -7219,6 +7702,15 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" +string-width@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.0.1.tgz#0d8158335a6cfd8eb95da9b6b262ce314a036ffd" + integrity sha512-5ohWO/M4//8lErlUUtrFy3b11GtNOuMOU0ysKCDXFcfXuuvUXu95akgj/i8ofmaGdN0hCqyl6uu9i8dS/mQp5g== + dependencies: + emoji-regex "^9.2.2" + is-fullwidth-code-point "^4.0.0" + strip-ansi "^7.0.1" + string.prototype.trimend@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" @@ -7254,15 +7746,6 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -stringify-object@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" - integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== - dependencies: - get-own-enumerable-property-symbols "^3.0.0" - is-obj "^1.0.1" - is-regexp "^1.0.0" - stringify-package@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/stringify-package/-/stringify-package-1.0.1.tgz#e5aa3643e7f74d0f28628b72f3dad5cecfc3ba85" @@ -7296,6 +7779,13 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-ansi@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" + integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== + dependencies: + ansi-regex "^6.0.1" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -7323,7 +7813,7 @@ strip-json-comments@2.0.1, strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= -strip-json-comments@^3.0.1: +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1, strip-json-comments@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -7347,13 +7837,18 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.0.0, supports-color@^7.1.0: +supports-color@^7.0.0, supports-color@^7.1.0, supports-color@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" +supports-color@^9.0.2: + version "9.2.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.2.1.tgz#599dc9d45acf74c6176e0d880bab1d7d718fe891" + integrity sha512-Obv7ycoCTG51N7y175StI9BlAXrmgZrFhZOb0/PyjHBher/NmsdBgbbQ1Inhq+gIhz6+7Gb+jWF2Vqi7Mf1xnQ== + supports-hyperlinks@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" @@ -7367,16 +7862,6 @@ supports-hyperlinks@^2.1.0: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - taffydb@2.7.2: version "2.7.2" resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.7.2.tgz#7bf8106a5c1a48251b3e3bc0a0e1732489fd0dc8" @@ -7387,17 +7872,14 @@ taffydb@2.7.3: resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.7.3.tgz#2ad37169629498fca5bc84243096d3cde0ec3a34" integrity sha1-KtNxaWKUmPylvIQkMJbTzeDsOjQ= -tar@>=4.4.18, tar@^6.0.2, tar@^6.1.0, tar@^6.1.11: - version "6.1.11" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" - integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== +tar@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" + integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^3.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" + block-stream "*" + fstream "^1.0.12" + inherits "2" tar@^4: version "4.4.19" @@ -7412,6 +7894,18 @@ tar@^4: safe-buffer "^5.2.1" yallist "^3.1.1" +tar@^6.0.2, tar@^6.1.0, tar@^6.1.11: + version "6.1.11" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" + integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + tedious@8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/tedious/-/tedious-8.3.0.tgz#74d3d434638b0bdd02b6266f041c003ceca93f67" @@ -7444,6 +7938,11 @@ tempy@^1.0.0: type-fest "^0.16.0" unique-string "^2.0.0" +test-console@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/test-console/-/test-console-2.0.0.tgz#a279f7e2e148815224d8446ffa5208f0077d68fb" + integrity sha512-ciILzfCQCny8zy1+HEw2yBLKus7LNMsAHymsp2fhvGTVh5pWE5v2EB7V+5ag3WM9aO2ULtgsXVQePWYE+fb7pA== + test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" @@ -7458,6 +7957,11 @@ text-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== +text-hex@1.0.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" + integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== + text-table@^0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -7486,7 +7990,7 @@ through2@^4.0.0: dependencies: readable-stream "3" -through@2, "through@>=2.2.7 <3", through@^2.3.6, through@^2.3.8: +through@2, "through@>=2.2.7 <3", through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -7496,12 +8000,12 @@ tiny-relative-date@^1.3.0: resolved "https://registry.yarnpkg.com/tiny-relative-date/-/tiny-relative-date-1.3.0.tgz#fa08aad501ed730f31cc043181d995c39a935e07" integrity sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A== -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== dependencies: - os-tmpdir "~1.0.2" + rimraf "^3.0.0" to-absolute-glob@^2.0.0: version "2.0.2" @@ -7548,6 +8052,15 @@ tough-cookie@^2.2.0, tough-cookie@^2.4.3, tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" + tr46@~0.0.1, tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -7573,12 +8086,29 @@ trim-right@^1.0.1: resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= -tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.2: +triple-beam@^1.2.0, triple-beam@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" + integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== + +ts-node@^9: + version "9.1.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" + integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== + dependencies: + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.17" + yn "3.1.1" + +tslib@^1.8.1, tslib@^1.9.2: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.2.0: +tslib@^2, tslib@^2.0.0, tslib@^2.2.0: version "2.3.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== @@ -7602,7 +8132,7 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -tunnel@0.0.6: +tunnel@0.0.6, tunnel@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== @@ -7612,6 +8142,13 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -7634,6 +8171,11 @@ type-fest@^0.18.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f" integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" @@ -7656,10 +8198,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@^4.1.3: - version "4.4.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.4.tgz#2cd01a1a1f160704d3101fd5a58ff0f9fcb8030c" - integrity sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA== +typescript@^4.4.3, typescript@^4.5.2: + version "4.5.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.2.tgz#8ac1fba9f52256fdb06fb89e4122fa6a346c2998" + integrity sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw== uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" @@ -7725,7 +8267,7 @@ universal-user-agent@^6.0.0: resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== -universalify@^0.1.0: +universalify@^0.1.0, universalify@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== @@ -7752,17 +8294,30 @@ url-join@^4.0.0: resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== +url@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + integrity sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +uuid@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + uuid@^3.1.0, uuid@^3.2.1, uuid@^3.3.2, uuid@^3.3.3: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -uuid@^8.1.0: +uuid@^8.3.0, uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== @@ -7907,12 +8462,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which-pm-runs@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" - integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= - -which@1.3.1, which@^1.2.9: +which@1, which@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -7940,6 +8490,29 @@ wide-align@^1.1.0, wide-align@^1.1.2: dependencies: string-width "^1.0.2 || 2 || 3 || 4" +winston-transport@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59" + integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw== + dependencies: + readable-stream "^2.3.7" + triple-beam "^1.2.0" + +winston@^3.1.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.3.3.tgz#ae6172042cafb29786afa3d09c8ff833ab7c9170" + integrity sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw== + dependencies: + "@dabh/diagnostics" "^2.0.2" + async "^3.1.0" + is-stream "^2.0.0" + logform "^2.2.0" + one-time "^1.0.0" + readable-stream "^3.4.0" + stack-trace "0.0.x" + triple-beam "^1.3.0" + winston-transport "^4.4.0" + wkx@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.5.0.tgz#c6c37019acf40e517cc6b94657a25a3d4aa33e8c" @@ -7947,7 +8520,7 @@ wkx@^0.5.0: dependencies: "@types/node" "*" -word-wrap@~1.2.3: +word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== @@ -7999,18 +8572,19 @@ write-file-atomic@^3.0.0, write-file-atomic@^3.0.3: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - "xml-name-validator@>= 2.0.1 < 3.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635" integrity sha1-TYuPHszTQZqjYgYb7O9RXh5VljU= +xml2js@0.4.19: + version "0.4.19" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" + integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== + dependencies: + sax ">=0.6.0" + xmlbuilder "~9.0.1" + xml2js@^0.4.19: version "0.4.23" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" @@ -8024,6 +8598,11 @@ xmlbuilder@~11.0.0: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== +xmlbuilder@~9.0.1: + version "9.0.7" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= + "xmldom@>= 0.1.x": version "0.6.0" resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.6.0.tgz#43a96ecb8beece991cef382c08397d82d4d0c46f" @@ -8064,7 +8643,7 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.10.0: +yaml@^1.10.0, yaml@^1.10.2: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== @@ -8115,7 +8694,7 @@ yargs@13.3.2, yargs@^13.3.0: y18n "^4.0.0" yargs-parser "^13.1.2" -yargs@^15.0.2, yargs@^15.1.0: +yargs@^15.0.2: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== @@ -8145,6 +8724,24 @@ yargs@^16.1.0, yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yargs@^17.0.0: + version "17.2.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.2.1.tgz#e2c95b9796a0e1f7f3bf4427863b42e0418191ea" + integrity sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +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"