Просмотр исходного кода

Merge branch 'master' into feat/sticky-event-features

jam411 3 лет назад
Родитель
Сommit
f1284db858

+ 5 - 3
packages/app/package.json

@@ -54,7 +54,8 @@
     "openid-client": "Node.js 12 or higher is required for openid-client@3 and above.",
     "escape-string-regexp": "5.0.0 or above exports only ESM",
     "next": "/Sandbox rendering is crashed with v12.3 or above ",
-    "string-width": "5.0.0 or above exports only ESM."
+    "string-width": "5.0.0 or above exports only ESM.",
+    "prom-client": "!!DO NOT REMOVE!! A peer dependency of @promster."
   },
   "dependencies": {
     "@akebifiky/remark-simple-plantuml": "^1.0.2",
@@ -73,8 +74,8 @@
     "@growi/remark-growi-directive": "^6.0.1-RC.0",
     "@growi/remark-lsx": "^6.0.1-RC.0",
     "@growi/slack": "^6.0.1-RC.0",
-    "@promster/express": "^7.0.2",
-    "@promster/server": "^7.0.4",
+    "@promster/express": "^7.0.6",
+    "@promster/server": "^7.0.8",
     "@slack/web-api": "^6.2.4",
     "@slack/webhook": "^6.0.0",
     "JSONStream": "^1.3.5",
@@ -146,6 +147,7 @@
     "passport-ldapauth": "^3.0.1",
     "passport-local": "^1.0.0",
     "passport-saml": "^3.2.0",
+    "prom-client": "^14.1.1",
     "rate-limiter-flexible": "^2.3.7",
     "react": "^18.2.0",
     "react-bootstrap-typeahead": "^5.2.2",

+ 0 - 11
packages/app/src/server/middlewares/promster.js

@@ -1,11 +0,0 @@
-module.exports = (crowi, app) => {
-  const { configManager } = crowi;
-
-  // when disabled
-  if (!configManager.getConfig('crowi', 'promster:isEnabled')) {
-    return (req, res, next) => next();
-  }
-
-  const { createMiddleware } = require('@promster/express');
-  return createMiddleware({ app });
-};

+ 26 - 0
packages/app/src/server/middlewares/promster.ts

@@ -0,0 +1,26 @@
+import {
+  Request, Response, NextFunction,
+} from 'express';
+
+import loggerFactory from '~/utils/logger';
+
+const logger = loggerFactory('growi:middlewares:promster');
+
+type Middleware = (req: Request, res: Response, next: NextFunction) => void;
+
+// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+function middleware(crowi: any, app): Middleware {
+  const { configManager } = crowi;
+
+  // when disabled
+  if (!configManager.getConfig('crowi', 'promster:isEnabled')) {
+    return (req, res, next) => next();
+  }
+
+  logger.info('Promster is enabled');
+
+  const { createMiddleware } = require('@promster/express');
+  return createMiddleware({ app });
+}
+
+module.exports = middleware;

+ 13 - 10
packages/app/src/server/models/page.ts

@@ -196,10 +196,11 @@ export class PageQueryBuilder {
 
   /**
    * generate the query to find the pages '{path}/*' (exclude '{path}' self).
-   * If top page, return without doing anything.
    */
-  addConditionToListOnlyDescendants(path, option): PageQueryBuilder {
-    // No request is set for the top page
+  addConditionToListOnlyDescendants(path: string, option): PageQueryBuilder {
+    // exclude the target page
+    this.query = this.query.and({ path: { $ne: path } });
+
     if (isTopPage(path)) {
       return this;
     }
@@ -209,22 +210,24 @@ export class PageQueryBuilder {
     const startsPattern = escapeStringRegexp(pathWithTrailingSlash);
 
     this.query = this.query
-      .and({ path: new RegExp(`^${startsPattern}`) });
+      .and(
+        { path: new RegExp(`^${startsPattern}`) },
+      );
 
     return this;
 
   }
 
-  addConditionToListOnlyAncestors(path): PageQueryBuilder {
+  addConditionToListOnlyAncestors(path: string): PageQueryBuilder {
     const pathNormalized = pathUtils.normalizePath(path);
     const ancestorsPaths = extractToAncestorsPaths(pathNormalized);
 
     this.query = this.query
-      .and({
-        path: {
-          $in: ancestorsPaths,
-        },
-      });
+      // exclude the target page
+      .and({ path: { $ne: path } })
+      .and(
+        { path: { $in: ancestorsPaths } },
+      );
 
     return this;
 

+ 2 - 0
packages/app/test/cypress/integration/20-basic-features/20-basic-features--access-to-page.spec.ts

@@ -37,6 +37,7 @@ context('Access to page', () => {
     // https://stackoverflow.com/questions/5041494/selecting-and-manipulating-css-pseudo-elements-such-as-before-and-after-usin/21709814#21709814
     cy.get('#mdcont-headers').invoke('removeClass', 'blink');
 
+    cy.collapseSidebar(true);
     cy.screenshot(`${ssPrefix}-sandbox-headers`);
   });
 
@@ -50,6 +51,7 @@ context('Access to page', () => {
 
     cy.get('.math').should('be.visible');
 
+    cy.collapseSidebar(true);
     cy.screenshot(`${ssPrefix}-sandbox-math`);
   });
 

+ 1 - 1
packages/app/test/cypress/support/index.ts

@@ -36,7 +36,7 @@ declare global {
     interface Chainable {
        getByTestid(selector: string, options?: Partial<Loggable & Timeoutable & Withinable & Shadow>): Chainable<JQuery<Element>>,
        login(username: string, password: string): Chainable<void>,
-       collapseSidebar(isCollapsed: boolean, force?: boolean): Chainable<void>,
+       collapseSidebar(isCollapsed: boolean, waitUntilSaving?: boolean): Chainable<void>,
        waitUntilSkeletonDisappear(): Chainable<void>,
        waitUntilSpinnerDisappear(): Chainable<void>,
     }

+ 13 - 8
packages/remark-growi-directive/src/micromark-extension-growi-directive/lib/factory-attributes.js

@@ -7,9 +7,8 @@
 import { factorySpace } from 'micromark-factory-space';
 import { factoryWhitespace } from 'micromark-factory-whitespace';
 import {
-  asciiAlpha,
-  asciiAlphanumeric,
   markdownLineEnding,
+  markdownLineEndingOrSpace,
   markdownSpace,
 } from 'micromark-util-character';
 import { codes } from 'micromark-util-symbol/codes.js';
@@ -82,11 +81,16 @@ export function factoryAttributes(
       return shortcutStart(code);
     }
 
-    if (disallowEol && markdownSpace(code)) {
-      return factorySpace(effects, between, types.whitespace)(code);
+    if (disallowEol) {
+      if (markdownSpace(code)) {
+        return factorySpace(effects, between, types.whitespace)(code);
+      }
+      if (code === codes.comma) {
+        return factoryAttributesDevider(effects, between)(code);
+      }
     }
 
-    if (!disallowEol && (markdownLineEndingOrSpaceOrComma(code))) {
+    if (!disallowEol && markdownLineEndingOrSpaceOrComma(code)) {
       return factoryAttributesDevider(effects, between)(code);
     }
 
@@ -129,7 +133,7 @@ export function factoryAttributes(
       || code === codes.greaterThan
       || code === codes.graveAccent
       || code === codes.rightParenthesis
-      || markdownLineEndingOrSpaceOrComma(code)
+      || code === codes.comma
     ) {
       return nok(code);
     }
@@ -186,6 +190,7 @@ export function factoryAttributes(
         && code !== codes.graveAccent
         && code !== codes.rightParenthesis
         && code !== codes.space
+        && code !== codes.comma
     ) {
       effects.consume(code);
       return name;
@@ -197,7 +202,7 @@ export function factoryAttributes(
       return factorySpace(effects, nameAfter, types.whitespace)(code);
     }
 
-    if (!disallowEol && markdownLineEndingOrSpaceOrComma(code)) {
+    if (!disallowEol && markdownLineEndingOrSpace(code)) {
       return factoryAttributesDevider(effects, nameAfter)(code);
     }
 
@@ -245,7 +250,7 @@ export function factoryAttributes(
       return factorySpace(effects, valueBefore, types.whitespace)(code);
     }
 
-    if (!disallowEol && markdownLineEndingOrSpaceOrComma(code)) {
+    if (!disallowEol && markdownLineEndingOrSpace(code)) {
       return factoryAttributesDevider(effects, valueBefore)(code);
     }
 

+ 8 - 0
packages/remark-growi-directive/test/micromark-extension-growi-directive.test.js

@@ -792,12 +792,16 @@ test('micromark-extension-directive (compile)', (t) => {
         'a $lsx()',
         'a $lsx(num=1)',
         'a $lsx(/)',
+        'a $lsx(/,num=5,depth=1)',
+        'a $lsx(/, num=5, depth=1)',
         'a $lsx(💚)',
         'Leaf:',
         '$lsx',
         '$lsx()',
         '$lsx(num=1)',
         '$lsx(/)',
+        '$lsx(/,num=5,depth=1)',
+        '$lsx(/, num=5, depth=1)',
         '$lsx(💚)',
       ].join('\n\n'),
       options({ lsx }),
@@ -808,12 +812,16 @@ test('micromark-extension-directive (compile)', (t) => {
       '<p>a <lsx ></lsx></p>',
       '<p>a <lsx num="1"></lsx></p>',
       '<p>a <lsx prefix="/"></lsx></p>',
+      '<p>a <lsx prefix="/" num="5" depth="1"></lsx></p>',
+      '<p>a <lsx prefix="/" num="5" depth="1"></lsx></p>',
       '<p>a <lsx prefix="💚"></lsx></p>',
       '<p>Leaf:</p>',
       '<lsx ></lsx>',
       '<lsx ></lsx>',
       '<lsx num="1"></lsx>',
       '<lsx prefix="/"></lsx>',
+      '<lsx prefix="/" num="5" depth="1"></lsx>',
+      '<lsx prefix="/" num="5" depth="1"></lsx>',
       '<lsx prefix="💚"></lsx>',
     ].join('\n'),
     'should support directives (lsx)',

+ 20 - 26
packages/remark-lsx/src/server/routes/lsx.js

@@ -1,10 +1,15 @@
-const { customTagUtils } = require('@growi/core');
+import createError, { isHttpError } from 'http-errors';
+
+const { pagePathUtils, customTagUtils } = require('@growi/core');
 
 const { OptionParser } = customTagUtils;
 
 
 const DEFAULT_PAGES_NUM = 50;
 
+
+const { isTopPage } = pagePathUtils;
+
 class Lsx {
 
   /**
@@ -21,7 +26,7 @@ class Lsx {
   static addDepthCondition(query, pagePath, optionsDepth) {
     // when option strings is 'depth=', the option value is true
     if (optionsDepth == null || optionsDepth === true) {
-      throw new Error('The value of depth option is invalid.');
+      throw createError(400, 'The value of depth option is invalid.');
     }
 
     const range = OptionParser.parseRange(optionsDepth);
@@ -29,11 +34,13 @@ class Lsx {
     const end = range.end;
 
     if (start < 1 || end < 1) {
-      throw new Error(`specified depth is [${start}:${end}] : start and end are must be larger than 1`);
+      throw createError(400, `specified depth is [${start}:${end}] : start and end are must be larger than 1`);
     }
 
     // count slash
-    const slashNum = pagePath.split('/').length - 1;
+    const slashNum = isTopPage(pagePath)
+      ? 1
+      : pagePath.split('/').length;
     const depthStart = slashNum; // start is not affect to fetch page
     const depthEnd = slashNum + end - 1;
 
@@ -56,7 +63,7 @@ class Lsx {
   static addNumCondition(query, pagePath, optionsNum) {
     // when option strings is 'num=', the option value is true
     if (optionsNum == null || optionsNum === true) {
-      throw new Error('The value of num option is invalid.');
+      throw createError(400, 'The value of num option is invalid.');
     }
 
     if (typeof optionsNum === 'number') {
@@ -68,7 +75,7 @@ class Lsx {
     const end = range.end;
 
     if (start < 1 || end < 1) {
-      throw new Error(`specified num is [${start}:${end}] : start and end are must be larger than 1`);
+      throw createError(400, `specified num is [${start}:${end}] : start and end are must be larger than 1`);
     }
 
     const skip = start - 1;
@@ -92,7 +99,7 @@ class Lsx {
   static addFilterCondition(query, pagePath, optionsFilter, isExceptFilter = false) {
     // when option strings is 'filter=', the option value is true
     if (optionsFilter == null || optionsFilter === true) {
-      throw new Error('filter option require value in regular expression.');
+      throw createError(400, 'filter option require value in regular expression.');
     }
 
     let filterPath = '';
@@ -141,7 +148,7 @@ class Lsx {
     const isReversed = optionsReverse === 'true';
 
     if (optionsSort !== 'path' && optionsSort !== 'createdAt' && optionsSort !== 'updatedAt') {
-      throw new Error(`The specified value '${optionsSort}' for the sort option is invalid. It must be 'path', 'createdAt' or 'updatedAt'.`);
+      throw createError(400, `The specified value '${optionsSort}' for the sort option is invalid. It must be 'path', 'createdAt' or 'updatedAt'.`);
     }
 
     const sortOption = {};
@@ -163,26 +170,10 @@ module.exports = (crowi, app) => {
    * @return {Promise<Query>} query
    */
   async function generateBaseQueryBuilder(pagePath, user) {
-    let baseQuery = Page.find();
-    if (Page.PageQueryBuilder == null) {
-      if (Page.generateQueryToListWithDescendants != null) { // for Backward compatibility (<= GROWI v3.2.x)
-        baseQuery = Page.generateQueryToListWithDescendants(pagePath, user, {});
-      }
-      else if (Page.generateQueryToListByStartWith != null) { // for Backward compatibility (<= crowi-plus v2.0.7)
-        baseQuery = Page.generateQueryToListByStartWith(pagePath, user, {});
-      }
-
-      // return dummy PageQueryBuilder object
-      return Promise.resolve({ query: baseQuery });
-    }
+    const baseQuery = Page.find();
 
     const builder = new Page.PageQueryBuilder(baseQuery);
-    if (builder.addConditionToListOnlyDescendants == null) { // for Backward compatibility (<= GROWI v4.0.x)
-      builder.addConditionToListWithDescendants(pagePath);
-    }
-    else {
-      builder.addConditionToListOnlyDescendants(pagePath);
-    }
+    builder.addConditionToListOnlyDescendants(pagePath);
 
     builder
       .addConditionToExcludeTrashed();
@@ -245,6 +236,9 @@ module.exports = (crowi, app) => {
       res.status(200).send({ pages, toppageViewersCount });
     }
     catch (error) {
+      if (isHttpError) {
+        return res.status(error.status).send(error);
+      }
       return res.status(500).send(error);
     }
   };

+ 4 - 2
packages/remark-lsx/src/stores/lsx.tsx

@@ -124,10 +124,12 @@ type LsxNodeTree = {
 export const useSWRxNodeTree = (lsxContext: LsxContext, isImmutable?: boolean): SWRResponse<LsxNodeTree, Error> => {
   const { data, error } = useSWRxLsxResponse(lsxContext.pagePath, lsxContext.options, isImmutable);
 
+  const isLoading = data === undefined && error == null;
+
   return useSWR(
-    data === undefined ? null : ['lsxNodeTree', lsxContext.pagePath, lsxContext.options, isImmutable, data],
+    !isLoading ? ['lsxNodeTree', lsxContext.pagePath, lsxContext.options, isImmutable, data, error] : null,
     (key, pagePath, options, isImmutable, data) => {
-      if (error != null) {
+      if (data === undefined || error != null) {
         throw error;
       }
       return {

+ 77 - 68
yarn.lock

@@ -2907,15 +2907,15 @@
     google-libphonenumber ">=3.2.10"
     lodash ">=4.17.15"
 
-"@mapbox/node-pre-gyp@^1.0.5":
-  version "1.0.8"
-  resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz#32abc8a5c624bc4e46c43d84dfb8b26d33a96f58"
-  integrity sha512-CMGKi28CF+qlbXh26hDe6NxCd7amqeAzEqnS6IHeO6LoaKyM/n+Xw3HT1COdq8cuioOdlKdqn/hCmqPUOMOywg==
+"@mapbox/node-pre-gyp@^1.0.10":
+  version "1.0.10"
+  resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c"
+  integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==
   dependencies:
-    detect-libc "^1.0.3"
+    detect-libc "^2.0.0"
     https-proxy-agent "^5.0.0"
     make-dir "^3.1.0"
-    node-fetch "^2.6.5"
+    node-fetch "^2.6.7"
     nopt "^5.0.0"
     npmlog "^5.0.1"
     rimraf "^3.0.2"
@@ -3323,38 +3323,37 @@
   resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64"
   integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==
 
-"@promster/express@^7.0.2":
-  version "7.0.2"
-  resolved "https://registry.yarnpkg.com/@promster/express/-/express-7.0.2.tgz#d60b10d373fd572275714426dc90a7049fd26d4f"
-  integrity sha512-HnNxb9bVZpUPbPU6/1UjACe2PeZEJmVw3tVxzZA8CdzGvPMwewe1e1TXNR9PASWRA/pJj6FBHHUPuTq0daEcgg==
+"@promster/express@^7.0.6":
+  version "7.0.6"
+  resolved "https://registry.yarnpkg.com/@promster/express/-/express-7.0.6.tgz#8352a572536fcabd4e1fd39239f21c341ae51bb6"
+  integrity sha512-pS3A0sYND8zcnFNdc/N98f73zC9r8kCrpmP2Pc8SRkobvFo4x/Dy1M/i5KqdZr9L3wjNn8t+BsuOQlq9gvHaEA==
   dependencies:
-    "@promster/metrics" "^9.1.1"
+    "@promster/metrics" "^9.1.6"
     merge-options "3.0.4"
-    tslib "2.3.1"
+    tslib "2.4.1"
 
-"@promster/metrics@^9.1.1", "@promster/metrics@^9.1.2":
-  version "9.1.2"
-  resolved "https://registry.yarnpkg.com/@promster/metrics/-/metrics-9.1.2.tgz#2468fae02adf87febdba8a25a4203111ea347f66"
-  integrity sha512-kKcawgTJahHUFjnX/TOr6vju+196rSKlGQUfjC6am6sBxqFbccsBW/nEPusUEUswvnC4zv+ddbNz4uLJcu1w7A==
+"@promster/metrics@^9.1.6":
+  version "9.1.6"
+  resolved "https://registry.yarnpkg.com/@promster/metrics/-/metrics-9.1.6.tgz#3f5490541cf6459deb181260745c72db226fd17e"
+  integrity sha512-zksYRQrY8yvG+iiNAh6b6pnGtnb4hcXD8Go3Ai/xeSY6TqGZaR1dG0R1kTKBBXVGeQJpPKhSxo+1Dgcb2gPJiQ==
   dependencies:
     lodash.memoize "4.1.2"
     lodash.once "4.1.1"
     merge-options "3.0.4"
     optional "0.1.4"
-    ts-essentials "9.0.0"
-    tslib "2.3.1"
-    url "0.11.0"
-    url-value-parser "2.1.0"
+    ts-essentials "9.3.0"
+    tslib "2.4.1"
+    url-value-parser "2.2.0"
   optionalDependencies:
-    "@sematext/gc-stats" "1.5.5"
+    "@sematext/gc-stats" "1.5.8"
 
-"@promster/server@^7.0.4":
-  version "7.0.4"
-  resolved "https://registry.yarnpkg.com/@promster/server/-/server-7.0.4.tgz#b4c6babb6dd4d185c164020054a78f2d5da03755"
-  integrity sha512-JDOBVBe2Iqd29kLL5J3HuNyHuVhiX65sJdmZkY3GTBAOmmZFom/k+rT+JIBZRefhALhzU3pzMbpvxpvXlm0TOA==
+"@promster/server@^7.0.8":
+  version "7.0.8"
+  resolved "https://registry.yarnpkg.com/@promster/server/-/server-7.0.8.tgz#f4a84f0ed95bbaaa8b06be07ae987ab18e949f7d"
+  integrity sha512-sRd8voUcsk0bXWg7IfTcXLbJDbR9ny9eu0oPNnCIBvRi86FoAjTTQ6WayAT/8hOAtQb2BYjtTleFt/aesfurpg==
   dependencies:
-    "@promster/metrics" "^9.1.2"
-    tslib "2.3.1"
+    "@promster/metrics" "^9.1.6"
+    tslib "2.4.1"
 
 "@react-dnd/asap@^4.0.0":
   version "4.0.0"
@@ -3390,13 +3389,13 @@
   resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.3.tgz#6801033be7ff87a6b7cadaf5b337c9f366a3c4b0"
   integrity sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==
 
-"@sematext/gc-stats@1.5.5":
-  version "1.5.5"
-  resolved "https://registry.yarnpkg.com/@sematext/gc-stats/-/gc-stats-1.5.5.tgz#3461e818454b95de26085b65f0d95417b9f183d6"
-  integrity sha512-OetiHJ7vVPy2xvM+qyTuGoDvnSy4B6JGEhoIRmAONhaa8oOL2NaBiBg2HEI+DQPwOpUeCTUVBV3/uiBt24Ru7Q==
+"@sematext/gc-stats@1.5.8":
+  version "1.5.8"
+  resolved "https://registry.yarnpkg.com/@sematext/gc-stats/-/gc-stats-1.5.8.tgz#73edb27bcbe0f3976041e2dc42cc86874128eeb9"
+  integrity sha512-6RjKpdZ1x1EGya3l0oV4oTY2a1Mj5vtaEUcSloN3gl+bBwv1EvcsyjS25JzPtfUQDod5f0SDbIbHgqMhn7p90g==
   dependencies:
-    "@mapbox/node-pre-gyp" "^1.0.5"
-    nan "^2.15.0"
+    "@mapbox/node-pre-gyp" "^1.0.10"
+    nan "^2.17.0"
 
 "@sinclair/typebox@^0.24.1":
   version "0.24.27"
@@ -5834,6 +5833,11 @@ bindings@^1.5.0:
   dependencies:
     file-uri-to-path "1.0.0"
 
+bintrees@1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/bintrees/-/bintrees-1.0.2.tgz#49f896d6e858a4a499df85c38fb399b9aff840f8"
+  integrity sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==
+
 bl@^4.0.3, bl@^4.1.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
@@ -7991,10 +7995,10 @@ detect-indent@^7.0.0:
   resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-7.0.0.tgz#cab58e6ab1129c669e2101181a6c677917d43577"
   integrity sha512-/6kJlmVv6RDFPqaHC/ZDcU8bblYcoph2dUQ3kB47QqhkUEqXe3VZPELK9BaEMrC73qu+wn0AQ7iSteceN+yuMw==
 
-detect-libc@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
-  integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
+detect-libc@^2.0.0:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd"
+  integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==
 
 detect-newline@^3.0.0:
   version "3.1.0"
@@ -15732,10 +15736,10 @@ nan@^2.12.1, nan@^2.14.0:
   resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
   integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
 
-nan@^2.15.0:
-  version "2.15.0"
-  resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
-  integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==
+nan@^2.17.0:
+  version "2.17.0"
+  resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb"
+  integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==
 
 nanoid@^3.1.30:
   version "3.2.0"
@@ -15964,7 +15968,7 @@ node-fetch-h2@^2.3.0:
   dependencies:
     http2-client "^1.2.5"
 
-node-fetch@2.6.7:
+node-fetch@2.6.7, node-fetch@^2.6.7:
   version "2.6.7"
   resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
   integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
@@ -15988,13 +15992,6 @@ node-fetch@^2.6.1:
   resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
   integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
 
-node-fetch@^2.6.5:
-  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-forge@^0.10.0:
   version "0.10.0"
   resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
@@ -17622,6 +17619,13 @@ progress@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f"
 
+prom-client@^14.1.1:
+  version "14.1.1"
+  resolved "https://registry.yarnpkg.com/prom-client/-/prom-client-14.1.1.tgz#e9bebef0e2269bfde22a322f4ca803cb52b4a0c0"
+  integrity sha512-hFU32q7UZQ59bVJQGUtm3I2PrJ3gWvoCkilX9sF165ks1qflhugVCeK+S1JjJYHvyt3o5kj68+q3bchormjnzw==
+  dependencies:
+    tdigest "^0.1.1"
+
 promise-inflight@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
@@ -21898,6 +21902,13 @@ tar@^6.0.2, tar@^6.1.0, tar@^6.1.11:
     mkdirp "^1.0.3"
     yallist "^4.0.0"
 
+tdigest@^0.1.1:
+  version "0.1.2"
+  resolved "https://registry.yarnpkg.com/tdigest/-/tdigest-0.1.2.tgz#96c64bac4ff10746b910b0e23b515794e12faced"
+  integrity sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==
+  dependencies:
+    bintrees "1.0.2"
+
 teeny-request@^7.0.0:
   version "7.1.0"
   resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-7.1.0.tgz#be7593e62d5f2d656646a0c35fc7c3f18f6300f9"
@@ -22536,10 +22547,10 @@ ts-deepmerge@^3.0.0:
   resolved "https://registry.yarnpkg.com/ts-deepmerge/-/ts-deepmerge-3.0.0.tgz#231c48901606eb104ab51a74cb447af0e9e669e4"
   integrity sha512-gpjFrde/nE3jp7l5cJTDpyhdbGdAIO/AkNjaz4V9odnopdLd9NVrQcBDEBiE/ucMV9dmNOcdgzOVwS7U6SsBhA==
 
-ts-essentials@9.0.0:
-  version "9.0.0"
-  resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-9.0.0.tgz#6196b7f390926429256c70951c8edd260e8e5097"
-  integrity sha512-pow5YBSknf/PyoDhr8vsb93+hZah/jSzhdHA3GMjSzUuZIDZH+rV7tvN5DCbN4hi7QJXdteDv8D9HdDCSwXBUw==
+ts-essentials@9.3.0:
+  version "9.3.0"
+  resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-9.3.0.tgz#7e639c1a76b1805c3c60d6e1b5178da2e70aea02"
+  integrity sha512-XeiCboEyBG8UqXZtXl59bWEi4ZgOqRsogFDI6WDGIF1LmzbYiAkIwjkXN6zZWWl4re/lsOqMlYfe8KA0XiiEPw==
 
 ts-jest@^28.0.7:
   version "28.0.7"
@@ -22667,16 +22678,21 @@ tslib@2.2.0:
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c"
   integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==
 
-tslib@2.3.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1:
-  version "2.3.1"
-  resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
-  integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
+tslib@2.4.1:
+  version "2.4.1"
+  resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e"
+  integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==
 
 tslib@^1.10.0, tslib@^1.11.1, tslib@^1.8.1, tslib@^1.9.0:
   version "1.14.1"
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
   integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
 
+tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1:
+  version "2.3.1"
+  resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
+  integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
+
 tsscmp@1.0.6:
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb"
@@ -23390,10 +23406,10 @@ url-join@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.0.tgz#4d3340e807d3773bda9991f8305acdcc2a665d2a"
 
-url-value-parser@2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/url-value-parser/-/url-value-parser-2.1.0.tgz#fe1ae776122b2eea4bbf284896bbdcd7fc75e1fa"
-  integrity sha512-gIYPWXujdUdwd/9TGCHTf5Vvgw6lOxjE5Q/k+7WNByYyS0vW5WX0k+xuVlhvPq6gRNhzXVv/ezC+OfeAet5Kcw==
+url-value-parser@2.2.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/url-value-parser/-/url-value-parser-2.2.0.tgz#f38ae8cd24604ec69bc219d66929ddbbd93a2b32"
+  integrity sha512-yIQdxJpgkPamPPAPuGdS7Q548rLhny42tg8d4vyTNzFqvOnwqrgHXvgehT09U7fwrzxi3RxCiXjoNUNnNOlQ8A==
 
 url@0.10.3:
   version "0.10.3"
@@ -23402,13 +23418,6 @@ url@0.10.3:
     punycode "1.3.2"
     querystring "0.2.0"
 
-url@0.11.0:
-  version "0.11.0"
-  resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
-  dependencies:
-    punycode "1.3.2"
-    querystring "0.2.0"
-
 use-sync-external-store@1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"