diff --git a/.circleci/config.yml b/.circleci/config.yml index 4a80d8d..f7015fd 100755 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -85,6 +85,7 @@ workflows: ignore: - master - release + - /release-.*/ - test: context: library requires: @@ -94,8 +95,11 @@ workflows: ignore: - master - release + - /release-.*/ - deploy: context: library filters: branches: - only: release + only: + - release + - /release-.*/ diff --git a/bin/migrate.js b/bin/migrate.js new file mode 100755 index 0000000..6e63a85 --- /dev/null +++ b/bin/migrate.js @@ -0,0 +1,41 @@ +#! /usr/bin/env node + +const program = require("commander"); +const migrate = require("../dist/migration"); +const pkgjson = require("../package.json"); + +program.version(pkgjson.version); + +program + .command("init") + .description("initialize a new migration project") + .action(() => + migrate + .init() + .then(() => console.log(`Initialization successful. Check out \`${migrate.DEFAULT_CONFIG_FILE_NAME}\` file`)) + .catch(err => { + console.error(`ERROR: ${err.message}`); + process.exit(1); + }) + ); + +program + .command("create [description]") + .description("create a new database migration with the provided description") + .option("-f --file ", "use a custom config file") + .action((description, options) => { + global.options = options; + migrate + .create(description) + .then(destination => console.log(`Created: ${destination}`)) + .catch(err => { + console.error(`ERROR: ${err.message}`); + process.exit(1); + }); + }); + +program.parse(process.argv); + +if (!program.rawArgs || program.rawArgs.length === 0) { + program.outputHelp(); +} diff --git a/package.json b/package.json index 51a8324..37c54c4 100755 --- a/package.json +++ b/package.json @@ -1,9 +1,12 @@ { "name": "@random-guys/bucket", - "version": "0.8.1", + "version": "0.9.0-rc.4", "description": "Wrapper around axios for interservice communication", "main": "dist/index.js", "types": "dist/index.d.ts", + "bin": { + "bucket-migrate": "bin/migrate.js" + }, "scripts": { "build": "tsc -p ./tsconfig.json", "watch": "tsc -w -p ./tsconfig.json", @@ -20,6 +23,7 @@ "homepage": "https://github.com/random-guys/bucket#readme", "devDependencies": { "@types/jest": "^25.2.3", + "@types/migrate-mongo": "^7.0.1", "@types/mongoose": "^5.5.18", "@types/supertest": "^2.0.9", "@types/uuid": "^3.4.4", @@ -29,10 +33,14 @@ "typescript": "^3.5.2" }, "files": [ - "dist/" + "dist/", + "samples/" ], "dependencies": { + "commander": "^5.1.0", + "date-fns": "^2.14.0", "http-status-codes": "^1.3.2", + "migrate-mongo": "^7.2.1", "mongoose": "^5.7.1", "uuid": "^3.3.2" } diff --git a/samples/migrate-mongo-config.js b/samples/migrate-mongo-config.js new file mode 100644 index 0000000..d542aac --- /dev/null +++ b/samples/migrate-mongo-config.js @@ -0,0 +1,15 @@ +// In this file you can configure migrate-mongo + +const config = { + // The migrations dir, can be an relative or absolute path. Only edit this when really necessary. + migrationsDir: "dist/migrations", + + // The mongodb collection where the applied changes are stored. Only edit this when really necessary. + changelogCollectionName: "changelog", + + // The file extension to create migrations and search for in migration dir + migrationFileExtension: ".js" +}; + +// Return the config as a promise +module.exports = config; diff --git a/samples/sample-migration.ts b/samples/sample-migration.ts new file mode 100644 index 0000000..85ffbbb --- /dev/null +++ b/samples/sample-migration.ts @@ -0,0 +1,13 @@ +import { Db, MongoClient } from "mongodb"; + +export async function up(db: Db, conn: MongoClient) { + // TODO write your migration here. + // Example: + // await db.collection('albums').updateOne({artist: 'The Beatles'}, {$set: {blacklisted: true}}); +} + +export async function down(db: Db, conn: MongoClient) { + // TODO write the statements to rollback your migration (if possible) + // Example: + // await db.collection('albums').updateOne({artist: 'The Beatles'}, {$set: {blacklisted: false}}); +} diff --git a/src/index.ts b/src/index.ts index a15e618..33f9a1d 100755 --- a/src/index.ts +++ b/src/index.ts @@ -3,5 +3,6 @@ export * from "./base.repo"; export * from "./base.schema"; export * from "./connect"; export * from "./errors"; +export * from "./migration"; export * from "./query"; export * from "./utils.schema"; diff --git a/src/migration.ts b/src/migration.ts new file mode 100644 index 0000000..6cf3aea --- /dev/null +++ b/src/migration.ts @@ -0,0 +1,68 @@ +import fs from "fs"; +import { down, up, config } from "migrate-mongo"; +import { Connection } from "mongoose"; +import path from "path"; +import format from "date-fns/format"; + +const PREFIX_FORMAT = "yyyyMMddHHmmss"; +export const DEFAULT_MIGRATION_DIR = "src/migrations"; +export const DEFAULT_CONFIG_FILE_NAME = "migrate-mongo-config.js"; + +/** + * Applies all unapplied migrations to the DB. Note that it passes the mongoose + * connection in place of `MongoClient` due to being unable to access + * that from mongoose. + * @param connection mongoose connection to be used for migration + */ +export function migrateUp(connection: Connection) { + // @ts-ignore wrong typing + return up(connection.db, connection.client); +} + +/** + * Undo the last applied migration. Note that it passes the mongoose + * connection in place of `MongoClient` due to being unable to access + * that from mongoose. + * @param connection mongoose connection to be used for migration + */ +export function migrateDown(connection: Connection) { + // @ts-ignore wrong typing + return down(connection.db, connection.client); +} + +export async function create(description: string) { + if (!description) { + throw new Error("Missing parameter: description"); + } + + // where should we store the new migration + await config.shouldExist(); + const migrationConfig = await config.read(); + const configuredDir = migrationConfig.migrationsDir?.replace("dist", "src") ?? DEFAULT_MIGRATION_DIR; + const migrationsDir = path.isAbsolute(configuredDir) ? configuredDir : path.join(process.cwd(), configuredDir); + + try { + await fs.promises.access(migrationsDir); + } catch (err) { + throw new Error(`migrations directory does not exist: ${migrationsDir}`); + } + + // construct the file name + const source = path.join(__dirname, "../samples/sample-migration.ts"); + const prefix = format(new Date(), PREFIX_FORMAT); + const filename = `${prefix}-${description.split(" ").join("_")}.ts`; + + // copy sample file to new file + const destination = path.join(migrationsDir, filename); + await fs.promises.copyFile(source, destination); + + return destination; +} + +export async function init() { + const source = path.join(__dirname, `../samples/${DEFAULT_CONFIG_FILE_NAME}`); + const destination = path.join(process.cwd(), DEFAULT_CONFIG_FILE_NAME); + + await fs.promises.copyFile(source, destination); + return fs.promises.mkdir(path.join(process.cwd(), "src/migrations")); +} diff --git a/yarn.lock b/yarn.lock index 410cdde..1787857 100644 --- a/yarn.lock +++ b/yarn.lock @@ -683,6 +683,13 @@ jest-diff "^25.2.1" pretty-format "^25.2.1" +"@types/migrate-mongo@^7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@types/migrate-mongo/-/migrate-mongo-7.0.1.tgz#dcb4d49deeb774a78d11c6f3a81946d3f9bb4978" + integrity sha512-iUNLH0bOt2kp1EEq7sLqUmpfPTaqVW3hkW2rquPnCS9+RZzdK8sC7uM+5U4Yvgwm4vHVVi+rX//0oskAKYdoRQ== + dependencies: + "@types/mongodb" "*" + "@types/mongodb@*": version "3.1.28" resolved "https://registry.yarnpkg.com/@types/mongodb/-/mongodb-3.1.28.tgz#c049cdff343788d77f5cc8c5f2e4af72ba7d047b" @@ -976,6 +983,14 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +bl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-2.2.0.tgz#e1a574cdf528e4053019bb800b041c0ac88da493" + integrity sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + bluebird@3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" @@ -1036,6 +1051,11 @@ bson@^1.1.1, bson@~1.1.1: resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.1.tgz#4330f5e99104c4e751e7351859e2d408279f2f13" integrity sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg== +bson@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/bson/-/bson-1.1.4.tgz#f76870d799f15b854dffb7ee32f0a874797f7e89" + integrity sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q== + buffer-from@1.x, buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -1128,6 +1148,16 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +cli-table3@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.0.tgz#b7b1bc65ca8e7b5cef9124e13dc2b21e2ce4faee" + integrity sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ== + dependencies: + object-assign "^4.1.0" + string-width "^4.2.0" + optionalDependencies: + colors "^1.1.2" + cliui@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" @@ -1179,6 +1209,11 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +colors@^1.1.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -1186,6 +1221,16 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" +commander@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-5.0.0.tgz#dbf1909b49e5044f8fdaf0adc809f0c0722bdfd0" + integrity sha512-JrDGPAKjMGSP1G0DUoaceEJ3DZgAfr/q6X7FVk4+U5KxUSKviYGM2k6zWkfyyBHy5rAtzgYJFa1ro2O9PtoxwQ== + +commander@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" + integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== + component-emitter@^1.2.0, component-emitter@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" @@ -1278,6 +1323,16 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" +date-fns@2.12.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.12.0.tgz#01754c8a2f3368fc1119cf4625c3dad8c1845ee6" + integrity sha512-qJgn99xxKnFgB1qL4jpxU7Q2t0LOn1p8KMIveef3UZD7kqjT3tpFNNdXJelEHhE+rUgffriXriw/sOSU+cS1Hw== + +date-fns@^2.14.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.14.0.tgz#359a87a265bb34ef2e38f93ecf63ac453f9bc7ba" + integrity sha512-1zD+68jhFgDIM0rF05rcwYO8cExdNqxjq4xP1QKM60Q45mnO6zaMWB4tOzrIr4M4GSLntsKeE4c9Bdl2jhL/yw== + debug@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" @@ -1358,6 +1413,11 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= +denque@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/denque/-/denque-1.4.1.tgz#6744ff7641c148c3f8a69c307e51235c1f4a37cf" + integrity sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ== + detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -1598,6 +1658,11 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +fn-args@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/fn-args/-/fn-args-5.0.0.tgz#7a18e105c8fb3bf0a51c30389bf16c9ebe740bb3" + integrity sha512-CtbfI3oFFc3nbdIoHycrfbrxiGgxXBXXuyOl49h47JawM1mYrqpiRqnH5CB2mBatdXvHHOUO6a+RiAuuvKt0lw== + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -1638,6 +1703,15 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" +fs-extra@8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1718,7 +1792,7 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -graceful-fs@^4.2.4: +graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.4" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== @@ -2529,6 +2603,13 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -2608,7 +2689,7 @@ lodash.sortby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= -lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15: +lodash@4.17.15, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -2644,6 +2725,11 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +memory-pager@^1.0.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5" + integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg== + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -2681,6 +2767,20 @@ micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" +migrate-mongo@^7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/migrate-mongo/-/migrate-mongo-7.2.1.tgz#f4b3f9ef45de5255aa8a54cf3899f631236abb91" + integrity sha512-3Z5sqn6p3/++HDirFcGHof4AhFqbQKn5eaSnGGnTPUNXa5B3RZZvGVlwRJRDj0/wqchsujfC/DITAM+FzZFx5Q== + dependencies: + cli-table3 "0.6.0" + commander "5.0.0" + date-fns "2.12.0" + fn-args "5.0.0" + fs-extra "8.1.0" + lodash "4.17.15" + mongodb "3.5.6" + p-each-series "2.1.0" + mime-db@1.40.0: version "1.40.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" @@ -2742,6 +2842,19 @@ mongodb@3.3.2: require_optional "^1.0.1" safe-buffer "^5.1.2" +mongodb@3.5.6: + version "3.5.6" + resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.5.6.tgz#a1be2d9796c8a8a5b0e6bcbc6baaaa406bd5c0d5" + integrity sha512-sh3q3GLDLT4QmoDLamxtAECwC3RGjq+oNuK1ENV8+tnipIavss6sMYt77hpygqlMOCt0Sla5cl7H4SKCVBCGEg== + dependencies: + bl "^2.2.0" + bson "^1.1.4" + denque "^1.4.1" + require_optional "^1.0.1" + safe-buffer "^5.1.2" + optionalDependencies: + saslprep "^1.0.0" + mongoose-legacy-pluralize@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz#3ba9f91fa507b5186d399fb40854bff18fb563e4" @@ -2885,6 +2998,11 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== +object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" @@ -2934,7 +3052,7 @@ optionator@^0.8.1: type-check "~0.3.2" wordwrap "~1.0.0" -p-each-series@^2.1.0: +p-each-series@2.1.0, p-each-series@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.1.0.tgz#961c8dd3f195ea96c747e636b262b800a6b1af48" integrity sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ== @@ -3286,6 +3404,11 @@ safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, s resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-buffer@^5.1.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -3313,6 +3436,13 @@ sane@^4.0.3: minimist "^1.1.1" walker "~1.0.5" +saslprep@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226" + integrity sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag== + dependencies: + sparse-bitfield "^3.0.3" + saxes@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" @@ -3488,6 +3618,13 @@ source-map@^0.7.3: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== +sparse-bitfield@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11" + integrity sha1-/0rm5oZWBWuks+eSqzM004JzyhE= + dependencies: + memory-pager "^1.0.2" + spdx-correct@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" @@ -3828,6 +3965,11 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^0.4.3" +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559"