diff --git a/.github/workflows/deps.yml b/.github/workflows/deps.yml index 1a0d9e1d..afaa46d2 100644 --- a/.github/workflows/deps.yml +++ b/.github/workflows/deps.yml @@ -11,20 +11,15 @@ jobs: permissions: contents: write services: - postgres: - image: postgres + mongodb: + image: mongo env: - POSTGRES_PASSWORD: keepitsecret - POSTGRES_USER: testdb - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 + MONGO_INITDB_ROOT_PASSWORD: keepitsecret + MONGO_INITDB_ROOT_USERNAME: testdb ports: - - 5432:5432 + - 27017:27017 env: - DATABASE_URL: postgres://testdb:keepitsecret@localhost:5432/testdb + MONGODB_URI: mongodb://testdb:keepitsecret@localhost:27017/testdb?authSource=admin steps: - uses: textbook/take-action@nodejs with: diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 2b7e5a41..aa635d29 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -20,20 +20,15 @@ jobs: node: [20.9, 20, 22] runs-on: ubuntu-latest services: - postgres: - image: postgres + mongodb: + image: mongo env: - POSTGRES_PASSWORD: keepitsecret - POSTGRES_USER: testdb - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 + MONGO_INITDB_ROOT_PASSWORD: keepitsecret + MONGO_INITDB_ROOT_USERNAME: testdb ports: - - 5432:5432 + - 27017:27017 env: - DATABASE_URL: postgres://testdb:keepitsecret@localhost:5432/testdb + MONGODB_URI: mongodb://testdb:keepitsecret@localhost:27017/testdb?authSource=admin steps: - uses: textbook/take-action@nodejs with: @@ -49,18 +44,13 @@ jobs: docker: runs-on: ubuntu-latest services: - postgres: - image: postgres + mongodb: + image: mongo env: - POSTGRES_PASSWORD: keepitsecret - POSTGRES_USER: testdb - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 + MONGO_INITDB_ROOT_PASSWORD: keepitsecret + MONGO_INITDB_ROOT_USERNAME: testdb ports: - - 5432:5432 + - 27017:27017 steps: - uses: textbook/take-action@nodejs with: @@ -74,10 +64,10 @@ jobs: tags: textbook/starter-kit:v2 - id: env-file run: | - echo 'DATABASE_URL=postgres://testdb:keepitsecret@localhost:5432/testdb' >> "$ENV_FILE" echo 'LOG_LEVEL=debug' >> "$ENV_FILE" - echo 'PORT=4321' >> "$ENV_FILE" + echo 'MONGODB_URI=mongodb://testdb:keepitsecret@localhost:27017/testdb?authSource=admin' >> "$ENV_FILE" echo 'NODE_ENV=docker' >> "$ENV_FILE" + echo 'PORT=4321' >> "$ENV_FILE" echo "file=$ENV_FILE" >> "$GITHUB_OUTPUT" env: ENV_FILE: docker.env diff --git a/README.md b/README.md index 04cc751a..c59dab3c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ - [x] [Node] LTS support (verified working on 20.x LTS release) - [x] [Express] server -- [x] [Postgres] database with [`pg`][node-postgres] +- [x] [MongoDB] database with [Mongoose] - [x] Logging with [Winston] and [Morgan] - [x] [React] client with [Vite] - [x] Client-side routing with [React Router] @@ -36,12 +36,12 @@ commonly use: [Google App Engine]: https://cloud.google.com/appengine/?hl=en [Heroku]: https://www.heroku.com/ [Jest]: https://jestjs.io/ +[MongoDB]: https://www.mongodb.com/ +[Mongoose]: https://mongoosejs.com/ [Morgan]: https://github.com/expressjs/morgan [Node]: https://nodejs.org/en/ -[node-postgres]: https://node-postgres.com/ [node-test]: https://nodejs.org/api/test.html [Playwright]: https://playwright.dev/ -[Postgres]: https://www.postgresql.org/ [Prettier]: https://prettier.io/ [React]: https://reactjs.org/ [React Router]: https://reactrouter.com/en/main diff --git a/api/app.js b/api/app.js index 6c0ddba7..08bccdba 100644 --- a/api/app.js +++ b/api/app.js @@ -2,7 +2,7 @@ import express from "express"; import apiRouter from "./api.js"; import { testConnection } from "./db.js"; -import config from "./utils/config.cjs"; +import config from "./utils/config.js"; import { asyncHandler, clientRouter, diff --git a/api/db.js b/api/db.js index 7e290b6f..0ee23959 100644 --- a/api/db.js +++ b/api/db.js @@ -1,34 +1,31 @@ -import pg from "pg"; +import mongoose from "mongoose"; import logger from "./utils/logger.js"; -/** @type {pg.Pool} */ -let pool; +mongoose.connection.on("error", (err) => logger.error("%O", err)); +mongoose.set("debug", (collection, method, query, doc) => { + logger.debug("%O", { collection, method, query, doc }); +}); /** - * @param {import("pg").ClientConfig} config + * @param {string} uri + * @param {import("mongoose").ConnectOptions} [options] */ -export const connectDb = async (config) => { - pool = new pg.Pool(config); - pool.on("error", (err) => logger.error("%O", err)); - const client = await pool.connect(); - logger.info("connected to %s", client.database); - client.release(); +export const connectDb = async (uri, options) => { + const client = await mongoose.connect(uri, { + bufferCommands: false, + ...options, + }); + logger.info("connected to %s", client.connection.name); }; export const disconnectDb = async () => { - if (pool) { - await pool.end(); - } + await mongoose.disconnect(); }; export const testConnection = async () => { - await query("SELECT 1;"); + const state = mongoose.connection.readyState; + if (state !== mongoose.ConnectionStates.connected) { + throw new Error(`database connection state: ${mongoose.STATES[state]}`); + } }; - -function query(...args) { - logger.debug("Postgres query: %O", args); - return pool.query.apply(pool, args); -} - -export default { query }; diff --git a/api/messages/messageRepository.js b/api/messages/messageRepository.js index e3e251d6..47f2299d 100644 --- a/api/messages/messageRepository.js +++ b/api/messages/messageRepository.js @@ -1,6 +1,10 @@ -import db from "../db.js"; +import mongoose from "mongoose"; + +const MessageSchema = new mongoose.Schema({ content: String }); + +const Message = mongoose.model("messages", MessageSchema); export async function getAll() { - const { rows } = await db.query("SELECT * FROM message;"); + const rows = await Message.find(); return rows; } diff --git a/api/migrate-mongo-config.js b/api/migrate-mongo-config.js new file mode 100644 index 00000000..bc599513 --- /dev/null +++ b/api/migrate-mongo-config.js @@ -0,0 +1,16 @@ +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +import config from "./utils/config.js"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +/** @type {import("migrate-mongo").config.Config} */ +export default { + changelogCollectionName: "changelog", + migrationFileExtension: ".js", + migrationsDir: join(__dirname, "migrations"), + moduleSystem: "esm", + mongodb: { url: config.dbUrl }, + useFileHash: false, +}; diff --git a/api/migrations/1707922794590_welcome-message.cjs b/api/migrations/1707922794590_welcome-message.cjs deleted file mode 100644 index 3ef83468..00000000 --- a/api/migrations/1707922794590_welcome-message.cjs +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Template for - * {@link https://salsita.github.io/node-pg-migrate/#/migrations?id=defining-migrations defining migrations}. - * - * @type {{ - * down: (pgm: import("node-pg-migrate").MigrationBuilder) => void | Promise; - * shorthands: Record; - * up: (pgm: import("node-pg-migrate").MigrationBuilder) => void | Promise; - * }} - */ -const migration = { - up(pgm) { - pgm.createTable("message", { - content: { notNull: true, type: "string" }, - }); - pgm.sql("INSERT INTO message (content) VALUES ('Hello, world!')"); - }, - down(pgm) { - pgm.dropTable("message"); - }, - shorthands: undefined, -}; - -module.exports = migration; diff --git a/api/migrations/20240916162136-welcome-message.js b/api/migrations/20240916162136-welcome-message.js new file mode 100644 index 00000000..fe8a4d5f --- /dev/null +++ b/api/migrations/20240916162136-welcome-message.js @@ -0,0 +1,21 @@ +/** + * Template for + * {@link https://github.com/seppevs/migrate-mongo?tab=readme-ov-file#creating-a-new-migration-script defining migrations}. + */ + +/** + * @param {import("mongodb").Db} db + * @param {import("mongodb").MongoClient} client + */ +export const up = async (db) => { + await db.collection("messages").insertOne({ content: "Hello, world!" }); +}; + +/** + * + * @param {import("mongodb").Db} db + * @param {import("mongodb").MongoClient} client + */ +export const down = async (db) => { + await db.collection("messages").drop(); +}; diff --git a/api/migrations/config.cjs b/api/migrations/config.cjs deleted file mode 100644 index b4f5067d..00000000 --- a/api/migrations/config.cjs +++ /dev/null @@ -1,22 +0,0 @@ -const { join } = require("node:path"); - -const config = require("../utils/config.cjs"); - -const migrationConfig = { - "ignore-pattern": "(config|template)\\.cjs$", - "migrations-dir": __dirname, - "template-file-name": join(__dirname, "template.cjs"), - url: config.dbConfig, -}; - -if ( - /* eslint-disable no-restricted-syntax */ - process.env.NODE_ENV?.toLowerCase() !== "production" && - process.env.LOG_LEVEL?.toLowerCase() === "debug" - /* eslint-enable no-restricted-syntax */ -) { - /* eslint-disable-next-line no-console */ - console.debug("migrating with %O", migrationConfig); -} - -module.exports = migrationConfig; diff --git a/api/migrations/sample-migration.js b/api/migrations/sample-migration.js new file mode 100644 index 00000000..7c7c3bf1 --- /dev/null +++ b/api/migrations/sample-migration.js @@ -0,0 +1,20 @@ +/** + * Template for + * {@link https://github.com/seppevs/migrate-mongo?tab=readme-ov-file#creating-a-new-migration-script defining migrations}. + */ + +/** + * @param {import("mongodb").Db} db + * @param {import("mongodb").MongoClient} client + */ +export const up = async (db, client) => { + // TODO write your migration here. +}; + +/** + * @param {import("mongodb").Db} db + * @param {import("mongodb").MongoClient} client + */ +export const down = async (db, client) => { + // TODO reverse your migration here. +}; diff --git a/api/migrations/template.cjs b/api/migrations/template.cjs deleted file mode 100644 index 6a1bfabb..00000000 --- a/api/migrations/template.cjs +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Template for - * {@link https://salsita.github.io/node-pg-migrate/#/migrations?id=defining-migrations defining migrations}. - * - * @type {{ - * down: (pgm: import("node-pg-migrate").MigrationBuilder) => void | Promise; - * shorthands: Record; - * up: (pgm: import("node-pg-migrate").MigrationBuilder) => void | Promise; - * }} - */ -const migration = { - up(pgm) {}, - down(pgm) {}, - shorthands: undefined, -}; - -module.exports = migration; diff --git a/api/package.json b/api/package.json index ccac7399..83105c24 100644 --- a/api/package.json +++ b/api/package.json @@ -7,21 +7,21 @@ "type": "module", "scripts": { "dev": "cross-env LOG_LEVEL=debug node --inspect --watch --watch-path . server.js", - "migration": "node-pg-migrate --config-file ./migrations/config.cjs", - "test": "cross-env DATABASE_URL=http://example.com NODE_OPTIONS='--experimental-vm-modules' jest", + "migration": "migrate-mongo", + "test": "cross-env MONGODB_URI=http://example.com NODE_OPTIONS='--experimental-vm-modules' jest", "test:watch": "npm run test -- --watch" }, "dependencies": { "dotenv": "^16.4.5", "express": "^4.21.0", "helmet": "^7.1.0", + "migrate-mongo": "^11.0.0", + "mongoose": "^8.6.2", "morgan": "^1.10.0", - "node-pg-migrate": "^7.6.1", - "pg": "^8.12.0", "winston": "^3.14.2" }, "devDependencies": { - "@testcontainers/postgresql": "^10.13.1", + "@testcontainers/mongodb": "^10.13.1", "eslint-plugin-jest": "^28.8.3", "eslint-plugin-n": "^17.10.2", "jest": "^29.7.0", diff --git a/api/server.js b/api/server.js index 42fc2252..a92e596a 100644 --- a/api/server.js +++ b/api/server.js @@ -1,10 +1,10 @@ import app from "./app.js"; import { connectDb } from "./db.js"; -import config from "./utils/config.cjs"; +import config from "./utils/config.js"; import logger from "./utils/logger.js"; const { port } = config; -await connectDb(config.dbConfig); +await connectDb(config.dbUrl); app.listen(port, () => logger.info(`listening on ${port}`)); diff --git a/api/setupTests.js b/api/setupTests.js index a1957530..3fca6294 100644 --- a/api/setupTests.js +++ b/api/setupTests.js @@ -1,21 +1,22 @@ import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; -import { PostgreSqlContainer } from "@testcontainers/postgresql"; -import { runner } from "node-pg-migrate"; +import { MongoDBContainer } from "@testcontainers/mongodb"; +import { config, database, up } from "migrate-mongo"; import { connectDb, disconnectDb } from "./db.js"; +import logger from "./utils/logger.js"; const __dirname = dirname(fileURLToPath(import.meta.url)); -/** @type {import("@testcontainers/postgresql").StartedPostgreSqlContainer} */ +/** @type {import("@testcontainers/mongodb").StartedMongoDBContainer} */ let dbContainer; beforeAll(async () => { - dbContainer = await new PostgreSqlContainer().start(); - const connectionString = dbContainer.getConnectionUri(); + dbContainer = await new MongoDBContainer().start(); + const connectionString = dbContainer.getConnectionString(); await applyMigrations(connectionString); - await connectDb({ connectionString }); + await connectDb(connectionString, { directConnection: true }); }, 60_000); afterAll(async () => { @@ -25,11 +26,18 @@ afterAll(async () => { } }); -async function applyMigrations(databaseUrl) { - await runner({ - databaseUrl, - dir: join(__dirname, "migrations"), - direction: "up", - ignorePattern: "(config|template)\\.cjs$", +async function applyMigrations(url) { + config.set({ + changelogCollectionName: "changelog", + migrationFileExtension: ".js", + migrationsDir: join(__dirname, "migrations"), + mongodb: { url, options: { directConnection: true } }, + useFileHash: false, }); + const { db, client } = await database.connect(); + const migrations = await up(db, client); + await client.close(); + for (const migration of migrations) { + logger.info("Run migration: %s", migration); + } } diff --git a/api/utils/README.md b/api/utils/README.md index 742f7514..c8004384 100644 --- a/api/utils/README.md +++ b/api/utils/README.md @@ -6,7 +6,7 @@ - Import from `logger.js`; and - Ignore `middleware.js` entirely (all predefined middleware is already used in `app.js`). -## `config.cjs` +## `config.js` Creates and exposes an object representing the app's configuration. This centralises access to the environment and definition of default values. @@ -14,8 +14,6 @@ Creates and exposes an object representing the app's configuration. This central To check if this is being used correctly, if you search your codebase, _all_ uses of `process.env` in `api/` should be in this file. -**Note** this is CommonJS (`.cjs`) rather than an ES module so that it can be used by `node-pg-migrate` and similar tools, to avoid duplicating configuration. - ## `logger.js` Creates, configures and exports a [Winston] logger, which you can then import and use elsewhere: diff --git a/api/utils/config.cjs b/api/utils/config.js similarity index 52% rename from api/utils/config.cjs rename to api/utils/config.js index 3d84bfdb..48f3c281 100644 --- a/api/utils/config.cjs +++ b/api/utils/config.js @@ -1,6 +1,9 @@ -const { join, resolve } = require("node:path"); +import { dirname, join, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; -const { configDotenv } = require("dotenv"); +import { configDotenv } from "dotenv"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); const dotenvPath = resolve( join(__dirname, "..", "..", process.env.DOTENV_CONFIG_PATH ?? ".env"), @@ -8,33 +11,17 @@ const dotenvPath = resolve( configDotenv({ path: dotenvPath }); -requireArgs(["DATABASE_URL"]); - -const databaseUrl = new URL(process.env.DATABASE_URL); - -const localDb = [ - "0.0.0.0", - "127.0.0.1", - "localhost", - "host.docker.internal", -].includes(databaseUrl.hostname); -const sslMode = ["prefer", "require", "verify-ca", "verify-full"].includes( - databaseUrl.searchParams.get("sslmode") ?? process.env.PGSSLMODE, -); +requireArgs(["MONGODB_URI"]); /** - * @property {import("pg").ClientConfig} dbConfig + * @property {string} dbUrl * @property {string} dotenvPath * @property {string} logLevel * @property {number} port * @property {boolean} production */ -module.exports = { - dbConfig: { - connectionString: databaseUrl.toString(), - connectionTimeoutMillis: 5_000, - ssl: localDb ? false : { rejectUnauthorized: sslMode }, - }, +export default { + dbUrl: process.env.MONGODB_URI, dotenvPath, logLevel: process.env.LOG_LEVEL?.toLowerCase() ?? "info", port: parseInt(process.env.PORT ?? "3000", 10), diff --git a/api/utils/logger.js b/api/utils/logger.js index 1d729fb1..13526a5a 100644 --- a/api/utils/logger.js +++ b/api/utils/logger.js @@ -1,6 +1,6 @@ import { createLogger, format, transports } from "winston"; -import config from "./config.cjs"; +import config from "./config.js"; const logger = createLogger({ format: format.combine( diff --git a/bin/files/README.md b/bin/files/README.md index 3e45f022..507e9e4c 100644 --- a/bin/files/README.md +++ b/bin/files/README.md @@ -4,7 +4,7 @@ - [x] [Node] LTS support (verified working on 20.x LTS release) - [x] [Express] server -- [x] [Postgres] database with [`pg`][node-postgres] +- [x] [MongoDB] database with [Mongoose] - [x] Logging with [Winston] and [Morgan] - [x] [React] client with [Vite] - [x] Client-side routing with [React Router] @@ -72,12 +72,12 @@ principles are followed: [Google App Engine]: https://cloud.google.com/appengine/?hl=en [Heroku]: https://www.heroku.com/ [Jest]: https://jestjs.io/ +[MongoDB]: https://www.mongodb.com/ +[Mongoose]: https://mongoosejs.com/ [Morgan]: https://github.com/expressjs/morgan [Node]: https://nodejs.org/en/ -[node-postgres]: https://node-postgres.com/ [node-test]: https://nodejs.org/api/test.html [Playwright]: https://playwright.dev/ -[Postgres]: https://www.postgresql.org/ [Prettier]: https://prettier.io/ [pull request]: https://help.github.com/en/articles/about-pull-requests [React]: https://reactjs.org/ diff --git a/eslint.config.js b/eslint.config.js index 4e6745ee..ec8ef28d 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -49,16 +49,16 @@ export default [ }, ], }, - ignores: ["api/utils/config.cjs"], + ignores: ["api/utils/config.js"], }, { files: ["**/*.cjs"], ...nodePlugin.configs["flat/recommended-script"], }, { - files: ["api/migrations/template.cjs"], + files: ["api/migrations/sample-migration.js"], rules: { - "no-unused-vars": ["error", { argsIgnorePattern: "pgm" }], + "no-unused-vars": ["error", { argsIgnorePattern: "client|db" }], }, }, { diff --git a/package-lock.json b/package-lock.json index c3260a5f..946ea41c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,13 +42,13 @@ "dotenv": "^16.4.5", "express": "^4.21.0", "helmet": "^7.1.0", + "migrate-mongo": "^11.0.0", + "mongoose": "^8.6.2", "morgan": "^1.10.0", - "node-pg-migrate": "^7.6.1", - "pg": "^8.12.0", "winston": "^3.14.2" }, "devDependencies": { - "@testcontainers/postgresql": "^10.13.1", + "@testcontainers/mongodb": "^10.13.1", "eslint-plugin-jest": "^28.8.3", "eslint-plugin-n": "^17.10.2", "jest": "^29.7.0", @@ -633,7 +633,6 @@ "version": "7.25.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", - "dev": true, "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -2122,6 +2121,15 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@mongodb-js/saslprep": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz", + "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==", + "license": "MIT", + "dependencies": { + "sparse-bitfield": "^3.0.3" + } + }, "node_modules/@mswjs/interceptors": { "version": "0.35.5", "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.35.5.tgz", @@ -2723,10 +2731,10 @@ "@swc/counter": "^0.1.3" } }, - "node_modules/@testcontainers/postgresql": { + "node_modules/@testcontainers/mongodb": { "version": "10.13.1", - "resolved": "https://registry.npmjs.org/@testcontainers/postgresql/-/postgresql-10.13.1.tgz", - "integrity": "sha512-HAh/3uLAzAhOmzXsOE6hVxkvetczPnX/Zoyt+SgK7QotW98Npr1MDx8OKiaLGTJ8XkIvVvS4Ch6bl+frt4pnkQ==", + "resolved": "https://registry.npmjs.org/@testcontainers/mongodb/-/mongodb-10.13.1.tgz", + "integrity": "sha512-7+Ks249cRbi0mZKWYUwdWQIPN44KsPS7NE6B8ocS8TLFdHWci1QVno503z8lCNN++fWfeepsi5f43QufzHy8zg==", "dev": true, "license": "MIT", "dependencies": { @@ -3136,6 +3144,21 @@ "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", "license": "MIT" }, + "node_modules/@types/webidl-conversions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", + "license": "MIT" + }, + "node_modules/@types/whatwg-url": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", + "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", + "license": "MIT", + "dependencies": { + "@types/webidl-conversions": "*" + } + }, "node_modules/@types/wrap-ansi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", @@ -3708,6 +3731,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -4542,6 +4566,15 @@ "node-int64": "^0.4.0" } }, + "node_modules/bson": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz", + "integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=16.20.1" + } + }, "node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", @@ -4835,6 +4868,60 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-table3/node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/cli-table3/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/cli-truncate": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", @@ -4866,6 +4953,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -4880,12 +4968,14 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, "license": "MIT" }, "node_modules/cliui/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4895,6 +4985,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -4909,6 +5000,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -4954,6 +5046,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -5370,11 +5463,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -6104,6 +6212,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -7315,6 +7424,15 @@ "dev": true, "license": "ISC" }, + "node_modules/fn-args": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fn-args/-/fn-args-5.0.0.tgz", + "integrity": "sha512-CtbfI3oFFc3nbdIoHycrfbrxiGgxXBXXuyOl49h47JawM1mYrqpiRqnH5CB2mBatdXvHHOUO6a+RiAuuvKt0lw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/fn.name": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", @@ -7428,6 +7546,29 @@ "dev": true, "license": "MIT" }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-extra/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -7502,6 +7643,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" @@ -7718,7 +7860,6 @@ "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, "license": "ISC" }, "node_modules/graphemer": { @@ -9931,6 +10072,27 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -9947,6 +10109,15 @@ "node": ">=4.0" } }, + "node_modules/kareem": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.3.tgz", + "integrity": "sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -10169,7 +10340,6 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, "license": "MIT" }, "node_modules/lodash.flattendeep": { @@ -10397,6 +10567,12 @@ "node": ">= 0.6" } }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "license": "MIT" + }, "node_modules/merge-descriptors": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", @@ -10446,6 +10622,39 @@ "node": ">=8.6" } }, + "node_modules/migrate-mongo": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/migrate-mongo/-/migrate-mongo-11.0.0.tgz", + "integrity": "sha512-GB/gHzUwp/fL1w6ksNGihTyb+cSrm6NbVLlz1OSkQKaLlzAXMwH7iKK2ZS7W5v+I8vXiY2rL58WTUZSAL6QR+A==", + "license": "MIT", + "dependencies": { + "cli-table3": "^0.6.1", + "commander": "^9.1.0", + "date-fns": "^2.28.0", + "fn-args": "^5.0.0", + "fs-extra": "^10.0.1", + "lodash": "^4.17.21", + "p-each-series": "^2.2.0" + }, + "bin": { + "migrate-mongo": "bin/migrate-mongo.js" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "mongodb": "^4.4.1 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/migrate-mongo/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || >=14" + } + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -10568,6 +10777,156 @@ "dev": true, "license": "MIT" }, + "node_modules/mongodb": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.9.0.tgz", + "integrity": "sha512-UMopBVx1LmEUbW/QE0Hw18u583PEDVQmUmVzzBRH0o/xtE9DBRA5ZYLOjpLIa03i8FXjzvQECJcqoMvCXftTUA==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@mongodb-js/saslprep": "^1.1.5", + "bson": "^6.7.0", + "mongodb-connection-string-url": "^3.0.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", + "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", + "license": "Apache-2.0", + "dependencies": { + "@types/whatwg-url": "^11.0.2", + "whatwg-url": "^13.0.0" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/tr46": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", + "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", + "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", + "license": "MIT", + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/mongoose": { + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.6.2.tgz", + "integrity": "sha512-ErbDVvuUzUfyQpXvJ6sXznmZDICD8r6wIsa0VKjJtB6/LZncqwUn5Um040G1BaNo6L3Jz+xItLSwT0wZmSmUaQ==", + "license": "MIT", + "dependencies": { + "bson": "^6.7.0", + "kareem": "2.6.3", + "mongodb": "6.8.0", + "mpath": "0.9.0", + "mquery": "5.0.0", + "ms": "2.1.3", + "sift": "17.1.3" + }, + "engines": { + "node": ">=16.20.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mongoose/node_modules/mongodb": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.8.0.tgz", + "integrity": "sha512-HGQ9NWDle5WvwMnrvUxsFYPd3JEbqD3RgABHBQRuoCEND0qzhsd0iH5ypHsf1eJ+sXmvmyKpP+FLOKY8Il7jMw==", + "license": "Apache-2.0", + "dependencies": { + "@mongodb-js/saslprep": "^1.1.5", + "bson": "^6.7.0", + "mongodb-connection-string-url": "^3.0.0" + }, + "engines": { + "node": ">=16.20.1" + }, + "peerDependencies": { + "@aws-sdk/credential-providers": "^3.188.0", + "@mongodb-js/zstd": "^1.1.0", + "gcp-metadata": "^5.2.0", + "kerberos": "^2.0.1", + "mongodb-client-encryption": ">=6.0.0 <7", + "snappy": "^7.2.2", + "socks": "^2.7.1" + }, + "peerDependenciesMeta": { + "@aws-sdk/credential-providers": { + "optional": true + }, + "@mongodb-js/zstd": { + "optional": true + }, + "gcp-metadata": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "snappy": { + "optional": true + }, + "socks": { + "optional": true + } + } + }, "node_modules/morgan": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", @@ -10611,6 +10970,27 @@ "node": ">= 0.8" } }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", + "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", + "license": "MIT", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -10741,32 +11121,6 @@ "dev": true, "license": "MIT" }, - "node_modules/node-pg-migrate": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/node-pg-migrate/-/node-pg-migrate-7.6.1.tgz", - "integrity": "sha512-CUocdo8kh25QZU2MeCjss2/OQ/Jq8ejCeilpja1MVOgk2c03r4U7vux9fAZCfrVg0YASwnhnpjz+rSK4tAVB2w==", - "license": "MIT", - "dependencies": { - "yargs": "~17.7.0" - }, - "bin": { - "node-pg-migrate": "bin/node-pg-migrate.js", - "node-pg-migrate-cjs": "bin/node-pg-migrate.js", - "node-pg-migrate-esm": "bin/node-pg-migrate.mjs" - }, - "engines": { - "node": ">=18.19.0" - }, - "peerDependencies": { - "@types/pg": ">=6.0.0 <9.0.0", - "pg": ">=4.3.0 <9.0.0" - }, - "peerDependenciesMeta": { - "@types/pg": { - "optional": true - } - } - }, "node_modules/node-preload": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", @@ -11267,6 +11621,18 @@ "dev": true, "license": "MIT" }, + "node_modules/p-each-series": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", + "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -11493,95 +11859,6 @@ "node": ">= 14.16" } }, - "node_modules/pg": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.12.0.tgz", - "integrity": "sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ==", - "license": "MIT", - "dependencies": { - "pg-connection-string": "^2.6.4", - "pg-pool": "^3.6.2", - "pg-protocol": "^1.6.1", - "pg-types": "^2.1.0", - "pgpass": "1.x" - }, - "engines": { - "node": ">= 8.0.0" - }, - "optionalDependencies": { - "pg-cloudflare": "^1.1.1" - }, - "peerDependencies": { - "pg-native": ">=3.0.1" - }, - "peerDependenciesMeta": { - "pg-native": { - "optional": true - } - } - }, - "node_modules/pg-cloudflare": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", - "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", - "license": "MIT", - "optional": true - }, - "node_modules/pg-connection-string": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz", - "integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==", - "license": "MIT" - }, - "node_modules/pg-int8": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", - "license": "ISC", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/pg-pool": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.2.tgz", - "integrity": "sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==", - "license": "MIT", - "peerDependencies": { - "pg": ">=8.0" - } - }, - "node_modules/pg-protocol": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz", - "integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==", - "license": "MIT" - }, - "node_modules/pg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", - "license": "MIT", - "dependencies": { - "pg-int8": "1.0.1", - "postgres-array": "~2.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.4", - "postgres-interval": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pgpass": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", - "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", - "license": "MIT", - "dependencies": { - "split2": "^4.1.0" - } - }, "node_modules/picocolors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", @@ -11780,45 +12057,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postgres-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/postgres-bytea": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-date": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-interval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "license": "MIT", - "dependencies": { - "xtend": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -12007,7 +12245,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -12258,7 +12495,6 @@ "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true, "license": "MIT" }, "node_modules/regexp.prototype.flags": { @@ -12297,6 +12533,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -12816,6 +13053,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sift": { + "version": "17.1.3", + "resolved": "https://registry.npmjs.org/sift/-/sift-17.1.3.tgz", + "integrity": "sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ==", + "license": "MIT" + }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", @@ -12929,6 +13172,15 @@ "source-map": "^0.6.0" } }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "license": "MIT", + "dependencies": { + "memory-pager": "^1.0.2" + } + }, "node_modules/spawn-wrap": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", @@ -12961,15 +13213,6 @@ "dev": true, "license": "ISC" }, - "node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "license": "ISC", - "engines": { - "node": ">= 10.x" - } - }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -14305,7 +14548,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -14747,19 +14989,11 @@ "dev": true, "license": "MIT" }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, "license": "ISC", "engines": { "node": ">=10" @@ -14789,6 +15023,7 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, "license": "MIT", "dependencies": { "cliui": "^8.0.1", @@ -14807,6 +15042,7 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, "license": "ISC", "engines": { "node": ">=12" @@ -14816,12 +15052,14 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, "license": "MIT" }, "node_modules/yargs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14831,6 +15069,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0",