diff --git a/.env.development.sample b/.env.development.sample
index 255b88e1..41e7d515 100644
--- a/.env.development.sample
+++ b/.env.development.sample
@@ -1 +1,3 @@
-NEXT_PUBLIC_GRAPHQL_URI="http://localhost:3001"
\ No newline at end of file
+NEXT_PUBLIC_GRAPHQL_URI="http://localhost:3001"
+MONGO_URI="mongodb://localhost:27017/vns"
+APOLLO_SERVER_CORS_WHITELIST="http://localhost:3000"
\ No newline at end of file
diff --git a/README.md b/README.md
index 73857c6e..28841770 100644
--- a/README.md
+++ b/README.md
@@ -32,13 +32,14 @@ You can start editing the page by modifying `pages/index.js`. The page auto-upda
...To be completed.
-## Other Next frameworks, and Next+Apollo boilerplates
+## Other cool Next stuff
- [Official Apollo example from Next](https://github.com/zeit/next.js/tree/canary/examples/with-apollo)
- [Next Right Now](https://github.com/UnlyEd/next-right-now) (a complete Next Starter, relying on Prisma cloud solutions for the backend)
- [Blitz](https://blitzjs.com/) (fullstack Next without GraphQL)
- [Next react Graphql Apollo Bootstrap](https://github.com/Sebastp/Next-react-graphql-apollo_Boostrap)
-- [Next advanced starter](https://github.com/borisowsky/next-advanced-starter)
+- [Next advanced starter](https://github.com/borisowsky/next-advanced-starter),
+- [Next - Mongo](https://github.com/hoangvvo/nextjs-mongodb-app) (no Express, no GraphQL, just Next and Mongo)
# About Next
diff --git a/cypress/integration/vns/mongo.spec.ts b/cypress/integration/vns/mongo.spec.ts
new file mode 100644
index 00000000..dcd16773
--- /dev/null
+++ b/cypress/integration/vns/mongo.spec.ts
@@ -0,0 +1,6 @@
+describe("connect to mongo", () => {
+ it("get the best restaurants in town", () => {
+ cy.visit("/vns/debug/mongo");
+ cy.get("li").should("have.length", 5);
+ });
+});
diff --git a/docs/features.md b/docs/features.md
index a03a5c7a..6b73d256 100644
--- a/docs/features.md
+++ b/docs/features.md
@@ -40,6 +40,22 @@ GraphQL Playground is available on `api/graphql`. All API routes of Next are loc
Open `api/debug/graphql-voyager` and explore your API visually.
+## MongoDB
+
+### Lambda safe connection
+
+Relevant docs:
+
+[Official tutorial without mongoose](https://developer.mongodb.com/how-to/nextjs-building-modern-applications)
+
+[Best practice for Mongo in AWS Lambda](https://docs.atlas.mongodb.com/best-practices-connecting-to-aws-lambda/)
+
+### Mongoose for schema modelling
+
+### Conversion between GraphQL ID and Mongoose ID types
+
+https://github.com/apollographql/apollo-server/issues/1633
+
## Code architecture and build
### Code in `src`
diff --git a/package.json b/package.json
index 88972074..39d4619c 100644
--- a/package.json
+++ b/package.json
@@ -66,6 +66,7 @@
"i18next-http-backend": "^1.0.15",
"isomorphic-unfetch": "3.0.0",
"lodash": "^4.17.15",
+ "mongoose": "^5.9.19",
"next": "9.4.0",
"next-i18next": "5.0.0-beta.2",
"next-with-apollo": "5.0.1",
@@ -89,6 +90,7 @@
"@testing-library/react": "^10.2.0",
"@testing-library/react-hooks": "^3.3.0",
"@types/jest": "^25.2.3",
+ "@types/mongoose": "^5.7.27",
"@types/node": "^13.7.6",
"@types/react": "^16.9.23",
"@types/react-dom": "^16.9.5",
diff --git a/src/lib/api/cors.ts b/src/api/cors.ts
similarity index 78%
rename from src/lib/api/cors.ts
rename to src/api/cors.ts
index f068cba7..b058500a 100644
--- a/src/lib/api/cors.ts
+++ b/src/api/cors.ts
@@ -1,4 +1,6 @@
import { parseEnvVariableArray } from "~/lib/utils";
+import debug from "debug";
+const debugCors = debug("vns:cors");
const corsWhitelist = parseEnvVariableArray(
process.env.APOLLO_SERVER_CORS_WHITELIST
@@ -9,6 +11,7 @@ const corsWhitelist = parseEnvVariableArray(
*/
const corsOptions = {
origin: function (origin, callback) {
+ debugCors("Origin is", origin, "Allowed origins are ", corsWhitelist);
if (!origin) {
// same origin
callback(null, true);
diff --git a/src/api/middlewares/mongoConnection.ts b/src/api/middlewares/mongoConnection.ts
new file mode 100644
index 00000000..ac278dc5
--- /dev/null
+++ b/src/api/middlewares/mongoConnection.ts
@@ -0,0 +1,68 @@
+/**
+ * This middleware relies on Express
+ *
+ * @see https://developer.mongodb.com/how-to/nextjs-building-modern-applications
+ * @see https://docs.atlas.mongodb.com/best-practices-connecting-to-aws-lambda/
+ * @see https://github.com/vercel/next.js/discussions/12229
+ */
+
+import { Request, Response } from "express";
+import mongoose from "mongoose";
+// Import mongoose models here
+import "~/api/mongoose/models";
+
+/*
+async function closeDbConnection() {
+ try {
+ await mongoose.connection.close();
+ } catch (err) {
+ // Catch locally error
+ }
+}
+*/
+
+import debug from "debug";
+const debugMongo = debug("vns:mongo");
+
+// trigger the initial connection on app startup
+export const connectToDb = async () => {
+ if (![1, 2].includes(mongoose.connection.readyState)) {
+ debugMongo("Call mongoose connect");
+ return await mongoose.connect(process.env.MONGO_URI, {
+ useNewUrlParser: true,
+ });
+ }
+ debugMongo("Ran connectToDb, already connected or connecting to Mongo");
+};
+
+const mongoConnectionMiddleware = () => {
+ // init the first database connection on server startup
+ connectToDb();
+ // mongoose.set("useFindAndModify", false);
+
+ // then return a middleware that checks the connection on every call
+ return async (req: Request, res: Response, next) => {
+ try {
+ // To debug the number of connections in Mongo client: db.serverStatus().connections
+ await connectToDb();
+
+ // Do not forget to close connection on finish and close events
+ // NOTE: actually we don't need this. Db connection close should happen on lambda destruction instead.
+ // res.on("finish", closeDbConnection);
+ // res.on("close", closeDbConnection);
+ next();
+ } catch (err) {
+ res.status(500);
+ res.send("Could not connect to db");
+ }
+ };
+};
+
+export default mongoConnectionMiddleware;
+
+// We need to add a converter between Mongoose ID and Apollo Server
+// @see https://github.com/apollographql/apollo-server/issues/1633
+const ObjectId = require("mongoose").Types.ObjectId;
+ObjectId.prototype.valueOf = function () {
+ return this.toString();
+};
diff --git a/src/api/mongoose/models.ts b/src/api/mongoose/models.ts
new file mode 100644
index 00000000..2378b75e
--- /dev/null
+++ b/src/api/mongoose/models.ts
@@ -0,0 +1,2 @@
+// Add your models here
+import "mongoose";
diff --git a/src/pages/api/graphql.ts b/src/pages/api/graphql.ts
index 7409147d..b40828bd 100644
--- a/src/pages/api/graphql.ts
+++ b/src/pages/api/graphql.ts
@@ -1,8 +1,10 @@
import express from "express";
import cors from "cors";
-import corsOptions from "~/lib/api/cors";
+import mongoose from "mongoose";
+import corsOptions from "~/api/cors";
import { ApolloServer, gql } from "apollo-server-express";
import { makeExecutableSchema } from "graphql-tools";
+import mongoConnection from "~/api/middlewares/mongoConnection";
/**
* Sample, naive, Apollo server. You can move this code in `src/server`
@@ -14,16 +16,32 @@ import { makeExecutableSchema } from "graphql-tools";
const typeDefs = gql`
type Query {
users: [User!]!
+ restaurants: [Restaurant]
}
type User {
name: String
}
+ type Restaurant {
+ _id: ID!
+ name: String
+ }
`;
const resolvers = {
Query: {
users() {
return [{ name: "Rick" }, { name: "Morty" }];
},
+ // Demo with mongoose
+ // Expected the database to be setup with the demo "restaurant" API from mongoose
+ async restaurants() {
+ const db = mongoose.connection;
+ const restaurants = await db
+ .collection("restaurants")
+ .find(null, null)
+ .limit(5)
+ .toArray();
+ return restaurants;
+ },
},
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
@@ -47,8 +65,11 @@ const app = express();
app.set("trust proxy", true);
const gqlPath = "/api/graphql";
+// setup cors
app.use(gqlPath, cors(corsOptions));
-// You could init the db connection here too
+// init the db
+app.use(gqlPath, mongoConnection());
+
server.applyMiddleware({ app, path: "/api/graphql" });
export default app;
diff --git a/src/pages/vns/debug/mongo.tsx b/src/pages/vns/debug/mongo.tsx
new file mode 100644
index 00000000..cbcd9e0b
--- /dev/null
+++ b/src/pages/vns/debug/mongo.tsx
@@ -0,0 +1,38 @@
+import { useQuery } from "@apollo/react-hooks";
+import gql from "graphql-tag";
+import { withApollo } from "@vulcan/next-apollo";
+const MongoDebugPage = () => {
+ const { data, loading, error } = useQuery(
+ gql`
+ query restaurants {
+ restaurants {
+ _id
+ name
+ }
+ }
+ `
+ );
+ if (loading) return <>Thinking about restaurants...>; // NOTE: in TypeScript with React we can't return just a string
+ if (error)
+ return (
+
+ I could not remember any restaurant, sorry... Error: {error.message}
+
+ );
+
+ const { restaurants } = data;
+
+ return (
+
+
First 5 restaurants that comes to my mind:
+
+ {restaurants.map(({ _id, name }) => (
+ - {name}
+ ))}
+
+
+ );
+};
+export default withApollo(MongoDebugPage, {
+ graphqlUri: "http://localhost:3000/api/graphql",
+});
diff --git a/yarn.lock b/yarn.lock
index 319ac3df..a25bfe1d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2994,6 +2994,13 @@
resolved "https://registry.yarnpkg.com/@types/braces/-/braces-3.0.0.tgz#7da1c0d44ff1c7eb660a36ec078ea61ba7eb42cb"
integrity sha512-TbH79tcyi9FHwbyboOKeRachRq63mSuWYXOflsNO9ZyE5ClQ/JaozNKl+aWUq87qPNsXasXxi2AbgfwIJ+8GQw==
+"@types/bson@*":
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/@types/bson/-/bson-4.0.2.tgz#7accb85942fc39bbdb7515d4de437c04f698115f"
+ integrity sha512-+uWmsejEHfmSjyyM/LkrP0orfE2m5Mx9Xel4tXNeqi1ldK5XMQcDsFkBmLDtuyKUbxj2jGDo0H240fbCRJZo7Q==
+ dependencies:
+ "@types/node" "*"
+
"@types/color-name@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
@@ -3221,6 +3228,22 @@
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
+"@types/mongodb@*":
+ version "3.5.23"
+ resolved "https://registry.yarnpkg.com/@types/mongodb/-/mongodb-3.5.23.tgz#e360ca025348bcc11328ce9a22099734401a2330"
+ integrity sha512-v4Ay/0av+oDUsj3P6TT6UIGDlLKnpnokO5e3TFR53FSOngc7QX+BBZ0KgnIk4Vtna6ODoL6Jcy/uQobvmCnn8g==
+ dependencies:
+ "@types/bson" "*"
+ "@types/node" "*"
+
+"@types/mongoose@^5.7.27":
+ version "5.7.27"
+ resolved "https://registry.yarnpkg.com/@types/mongoose/-/mongoose-5.7.27.tgz#8cb259fa463c466aba305937a31967727ad804d1"
+ integrity sha512-6+QFJg4jUM91dJYsJk32FuREOJ7ghgzxj4c+BV3+aK7a9fFGbghQRteB14P94fGXhJN63b2mBqf7luBHvCRFtg==
+ dependencies:
+ "@types/mongodb" "*"
+ "@types/node" "*"
+
"@types/node-fetch@2.5.7", "@types/node-fetch@^2.5.4":
version "2.5.7"
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c"
@@ -4930,6 +4953,19 @@ bindings@^1.5.0:
dependencies:
file-uri-to-path "1.0.0"
+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"
+ integrity sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==
+
bluebird@3.5.3:
version "3.5.3"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7"
@@ -5251,6 +5287,11 @@ bser@2.1.1:
dependencies:
node-int64 "^0.4.0"
+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-crc32@~0.2.3:
version "0.2.13"
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
@@ -6567,6 +6608,13 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
dependencies:
ms "2.0.0"
+debug@3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
+ integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
+ dependencies:
+ ms "2.0.0"
+
debug@4.1.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
@@ -6684,6 +6732,11 @@ delegates@^1.0.0:
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
+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==
+
depd@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
@@ -10308,6 +10361,11 @@ jsx-ast-utils@^2.2.3:
array-includes "^3.1.1"
object.assign "^4.1.0"
+kareem@2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.3.1.tgz#def12d9c941017fabfb00f873af95e9c99e1be87"
+ integrity sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw==
+
kind-of@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5"
@@ -10794,6 +10852,11 @@ memory-fs@^0.5.0:
errno "^0.1.3"
readable-stream "^2.0.1"
+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-deep@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/merge-deep/-/merge-deep-3.0.2.tgz#f39fa100a4f1bd34ff29f7d2bf4508fbb8d83ad2"
@@ -11057,6 +11120,41 @@ moment@2.24.0:
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
+mongodb@3.5.9:
+ version "3.5.9"
+ resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.5.9.tgz#799b72be8110b7e71a882bb7ce0d84d05429f772"
+ integrity sha512-vXHBY1CsGYcEPoVWhwgxIBeWqP3dSu9RuRDsoLRPTITrcrgm1f0Ubu1xqF9ozMwv53agmEiZm0YGo+7WL3Nbug==
+ 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"
+ integrity sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==
+
+mongoose@^5.9.19:
+ version "5.9.19"
+ resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-5.9.19.tgz#fadedce84e3f49b7ea335b73d2a60d2df97d69e1"
+ integrity sha512-wJ5FR2ykvyd17MRHA6sku/N1CMaC/kf4CnN357htD48RpzJhW60YDkxPSPLbkLg8Woa+i7jYi0glhzC0EcBcRQ==
+ dependencies:
+ bson "^1.1.4"
+ kareem "2.3.1"
+ mongodb "3.5.9"
+ mongoose-legacy-pluralize "1.0.2"
+ mpath "0.7.0"
+ mquery "3.2.2"
+ ms "2.1.2"
+ regexp-clone "1.0.0"
+ safe-buffer "5.1.2"
+ sift "7.0.1"
+ sliced "1.0.1"
+
move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
@@ -11069,6 +11167,22 @@ move-concurrently@^1.0.1:
rimraf "^2.5.4"
run-queue "^1.0.3"
+mpath@0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.7.0.tgz#20e8102e276b71709d6e07e9f8d4d0f641afbfb8"
+ integrity sha512-Aiq04hILxhz1L+f7sjGyn7IxYzWm1zLNNXcfhDtx04kZ2Gk7uvFdgZ8ts1cWa/6d0TQmag2yR8zSGZUmp0tFNg==
+
+mquery@3.2.2:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/mquery/-/mquery-3.2.2.tgz#e1383a3951852ce23e37f619a9b350f1fb3664e7"
+ integrity sha512-XB52992COp0KP230I3qloVUbkLUxJIu328HBP2t2EsxSFtf4W1HPSOBWOXf1bqxK4Xbb66lfMJ+Bpfd9/yZE1Q==
+ dependencies:
+ bluebird "3.5.1"
+ debug "3.1.0"
+ regexp-clone "^1.0.0"
+ safe-buffer "5.1.2"
+ sliced "1.0.1"
+
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@@ -11079,7 +11193,7 @@ ms@2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
-ms@^2.1.1:
+ms@2.1.2, ms@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
@@ -13063,7 +13177,7 @@ read-pkg@^5.2.0:
parse-json "^5.0.0"
type-fest "^0.6.0"
-"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
+"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, 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==
@@ -13202,6 +13316,11 @@ regex-parser@2.2.10:
resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.10.tgz#9e66a8f73d89a107616e63b39d4deddfee912b37"
integrity sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA==
+regexp-clone@1.0.0, regexp-clone@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/regexp-clone/-/regexp-clone-1.0.0.tgz#222db967623277056260b992626354a04ce9bf63"
+ integrity sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==
+
regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75"
@@ -13394,6 +13513,14 @@ require-main-filename@^2.0.0:
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
+require_optional@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/require_optional/-/require_optional-1.0.1.tgz#4cf35a4247f64ca3df8c2ef208cc494b1ca8fc2e"
+ integrity sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==
+ dependencies:
+ resolve-from "^2.0.0"
+ semver "^5.1.0"
+
resize-observer-polyfill@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
@@ -13406,6 +13533,11 @@ resolve-cwd@^3.0.0:
dependencies:
resolve-from "^5.0.0"
+resolve-from@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57"
+ integrity sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=
+
resolve-from@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
@@ -13621,6 +13753,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"
+
sass-loader@8.0.2:
version "8.0.2"
resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-8.0.2.tgz#debecd8c3ce243c76454f2e8290482150380090d"
@@ -13683,7 +13822,7 @@ select@^1.1.2:
resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=
-"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0:
+"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -13876,6 +14015,11 @@ side-channel@^1.0.2:
es-abstract "^1.17.0-next.1"
object-inspect "^1.7.0"
+sift@7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/sift/-/sift-7.0.1.tgz#47d62c50b159d316f1372f8b53f9c10cd21a4b08"
+ integrity sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g==
+
signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
@@ -13942,6 +14086,11 @@ slice-ansi@^2.1.0:
astral-regex "^1.0.0"
is-fullwidth-code-point "^2.0.0"
+sliced@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/sliced/-/sliced-1.0.1.tgz#0b3a662b5d04c3177b1926bea82b03f837a2ef41"
+ integrity sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=
+
snapdragon-node@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
@@ -14035,6 +14184,13 @@ space-separated-tokens@^1.0.0:
resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899"
integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==
+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"
+
spawn-wrap@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-2.0.0.tgz#103685b8b8f9b79771318827aa78650a610d457e"