diff --git a/libs/shared/mozlog/src/lib/mozlog.service.ts b/libs/shared/mozlog/src/lib/mozlog.service.ts index cdc02f36072..140261a52a3 100644 --- a/libs/shared/mozlog/src/lib/mozlog.service.ts +++ b/libs/shared/mozlog/src/lib/mozlog.service.ts @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { Injectable, Scope } from '@nestjs/common'; +import { Inject, Injectable, Scope } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import mozlog, { Logger as MozLogger, LoggerFactory } from 'mozlog'; @@ -12,7 +12,7 @@ let logFactory: LoggerFactory; export class MozLoggerService { private mozlog: MozLogger; - constructor(configService: ConfigService) { + constructor(@Inject(ConfigService) configService: ConfigService) { if (!logFactory) { logFactory = mozlog(configService.get('log')); } diff --git a/libs/shared/notifier/src/lib/notifier.service.ts b/libs/shared/notifier/src/lib/notifier.service.ts index f2e3fc1c1fd..4bd797abbe1 100644 --- a/libs/shared/notifier/src/lib/notifier.service.ts +++ b/libs/shared/notifier/src/lib/notifier.service.ts @@ -16,8 +16,8 @@ export class NotifierService { private readonly config: NotifierSnsConfig; constructor( - configService: ConfigService, - private readonly log: MozLoggerService, + @Inject(ConfigService) configService: ConfigService, + @Inject(MozLoggerService) private readonly log: MozLoggerService, @Inject(NotifierSnsService) private readonly sns: SNS, @Inject(StatsDService) private readonly statsd: StatsD | undefined ) { diff --git a/packages/fxa-auth-server/bin/key_server.js b/packages/fxa-auth-server/bin/key_server.js index f2c1dc45bde..17890c27599 100755 --- a/packages/fxa-auth-server/bin/key_server.js +++ b/packages/fxa-auth-server/bin/key_server.js @@ -7,6 +7,10 @@ // Important! Must be required first to get proper hooks in place. require('../lib/monitoring'); +// Use nest as a DI framework. This lets us configure and reuse our +// shared libs in hapi as well as nestjs. +const { bridgeTypeDi } = require('../lib/bridge-nestjs'); + const { config } = require('../config'); const { CapabilityManager } = require('@fxa/payments/capability'); @@ -31,7 +35,7 @@ const { Container } = require('typedi'); const { StripeHelper } = require('../lib/payments/stripe'); const { PlayBilling } = require('../lib/payments/iap/google-play'); const { CurrencyHelper } = require('../lib/payments/currencies'); -const { AuthLogger, AuthFirestore, AppConfig } = require('../lib/types'); +const { AuthLogger, AuthFirestore } = require('../lib/types'); const { setupFirestore } = require('../lib/firestore-db'); const { AppleIAP } = require('../lib/payments/iap/apple-app-store/apple-iap'); const { AccountEventsManager } = require('../lib/account-events'); @@ -44,22 +48,9 @@ const { AccountTasksFactory, } = require('@fxa/shared/cloud-tasks'); async function run(config) { - Container.set(AppConfig, config); - - const statsd = config.statsd.enabled - ? new StatsD({ - ...config.statsd, - errorHandler: (err) => { - // eslint-disable-next-line no-use-before-define - log.error('statsd.error', err); - }, - }) - : { - increment: () => {}, - timing: () => {}, - close: () => {}, - }; - Container.set(StatsD, statsd); + // Tranfers DI from nest to typedi + await bridgeTypeDi(); + const statsd = Container.get(StatsD); const log = require('../lib/log')({ ...config.log, diff --git a/packages/fxa-auth-server/config/index.ts b/packages/fxa-auth-server/config/index.ts index 8e1eceeca02..66bf91290b4 100644 --- a/packages/fxa-auth-server/config/index.ts +++ b/packages/fxa-auth-server/config/index.ts @@ -647,6 +647,24 @@ const convictConf = convict({ env: 'SNS_TOPIC_ENDPOINT', default: undefined, }, + + notifier: { + sns: { + snsTopicArn: { + doc: 'Amazon SNS topic on which to send account event notifications. Set to "disabled" to turn off the notifier', + format: String, + env: 'SNS_TOPIC_ARN', + default: '', + }, + + snsTopicEndpoint: { + doc: 'Amazon SNS topic endpoint', + format: String, + env: 'SNS_TOPIC_ENDPOINT', + default: undefined, + }, + }, + }, emailNotifications: { region: { doc: 'The region where the queues live, most likely the same region we are sending email e.g. us-east-1, us-west-2', diff --git a/packages/fxa-auth-server/lib/bridge-nestjs.ts b/packages/fxa-auth-server/lib/bridge-nestjs.ts new file mode 100644 index 00000000000..c8e022a9f0a --- /dev/null +++ b/packages/fxa-auth-server/lib/bridge-nestjs.ts @@ -0,0 +1,49 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { Module } from '@nestjs/common'; +import { NestFactory } from '@nestjs/core'; +import { ConfigModule } from '@nestjs/config'; +import { Container } from 'typedi'; +import { MozLoggerService } from '@fxa/shared/mozlog'; +import { + LegacyStatsDProvider, + StatsD, + StatsDService, +} from '@fxa/shared/metrics/statsd'; +import { NotifierService, NotifierSnsFactory } from '@fxa/shared/notifier'; + +import config, { ConfigType } from '../config'; +import { AppConfig } from './types'; + +@Module({ + imports: [ + ConfigModule.forRoot({ + load: [(): ConfigType => config.getProperties()], + isGlobal: true, + }), + ], + controllers: [], + providers: [ + MozLoggerService, + NotifierSnsFactory, + NotifierService, + LegacyStatsDProvider, + ], +}) +export class AppModule {} + +export async function getAppModuleInstance() { + return await NestFactory.createApplicationContext(AppModule); +} + +export async function bridgeTypeDi() { + const appInstance = await getAppModuleInstance(); + + // Setup type di container for backwards compatibility + Container.set(AppConfig, config.getProperties()); + Container.set(StatsD, appInstance.get(StatsDService)); + Container.set(MozLoggerService, appInstance.resolve(MozLoggerService)); + Container.set(NotifierService, appInstance.get(NotifierService)); +} diff --git a/packages/fxa-auth-server/lib/notifier.js b/packages/fxa-auth-server/lib/notifier.js index b8e162b327d..a508cbf9191 100644 --- a/packages/fxa-auth-server/lib/notifier.js +++ b/packages/fxa-auth-server/lib/notifier.js @@ -3,80 +3,23 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 'use strict'; +import { Container } from 'typedi'; +import { NotifierService } from '../../../libs/shared/notifier/src'; /** * This notifier is called by the logger via `notifyAttachedServices` * to send notifications to Amazon SNS/SQS. */ -const AWS = require('aws-sdk'); -const { config } = require('../config'); - -const notifierSnsTopicArn = config.get('snsTopicArn'); -const notifierSnsTopicEndpoint = config.get('snsTopicEndpoint'); -let sns = { - publish: function (msg, cb) { - cb(null, { disabled: true }); - }, -}; - -if (notifierSnsTopicArn !== 'disabled') { - // Pull the region info out of the topic arn. - // For some reason we need to pass this in explicitly. - // Format is "arn:aws:sns::" - const region = notifierSnsTopicArn.split(':')[3]; - // This will pull in default credentials, region data etc - // from the metadata service available to the instance. - // It's magic, and it's awesome. - sns = new AWS.SNS({ endpoint: notifierSnsTopicEndpoint, region: region }); -} - -function formatMessageAttributes(msg) { - const attrs = {}; - attrs.event_type = { - DataType: 'String', - StringValue: msg.event, - }; - if (msg.email) { - attrs.email_domain = { - DataType: 'String', - StringValue: msg.email.split('@')[1], - }; - } - return attrs; -} - module.exports = function notifierLog(log, statsd) { return { send: (event, callback) => { - const msg = event.data || {}; - msg.event = event.event; - - const startTime = Date.now(); - - sns.publish( - { - TopicArn: notifierSnsTopicArn, - Message: JSON.stringify(msg), - MessageAttributes: formatMessageAttributes(msg), - }, - (err, data) => { - if (statsd) { - statsd.timing('notifier.publish', Date.now() - startTime); - } - - if (err) { - log.error('Notifier.publish', { err: err }); - } else { - log.trace('Notifier.publish', { success: true, data: data }); - } - - if (callback) { - callback(err, data); - } - } - ); + if (!Container.has(NotifierService)) { + throw new Error( + 'Missing Notifier Service! Was it registered at startup?' + ); + } + const notifier = Container.get(NotifierService); + return notifier.send(event, callback); }, - // exported for testing purposes - __sns: sns, }; }; diff --git a/packages/fxa-auth-server/lib/routes/totp.js b/packages/fxa-auth-server/lib/routes/totp.js index fff46a03160..311e46b0761 100644 --- a/packages/fxa-auth-server/lib/routes/totp.js +++ b/packages/fxa-auth-server/lib/routes/totp.js @@ -311,7 +311,7 @@ module.exports = (log, db, mailer, customs, config, glean, profileClient) => { await profileClient.deleteCache(uid); await log.notifyAttachedServices('profileDataChange', request, { - uid + uid, }); } diff --git a/packages/fxa-auth-server/package.json b/packages/fxa-auth-server/package.json index a69d3aabb15..e20108cad09 100644 --- a/packages/fxa-auth-server/package.json +++ b/packages/fxa-auth-server/package.json @@ -70,6 +70,7 @@ "@googlemaps/google-maps-services-js": "^3.4.0", "@hapi/hapi": "^20.2.1", "@hapi/hoek": "^11.0.2", + "@nest/core": "^4.5.4", "@types/convict": "5.2.2", "@types/ejs": "^3.0.6", "@types/mjml": "^4.7.4", diff --git a/packages/fxa-auth-server/test/local/notifier.js b/packages/fxa-auth-server/test/local/notifier.js index 79abe44c597..e6721441d32 100644 --- a/packages/fxa-auth-server/test/local/notifier.js +++ b/packages/fxa-auth-server/test/local/notifier.js @@ -7,174 +7,58 @@ const ROOT_DIR = '../..'; const proxyquire = require('proxyquire'); -const { assert } = require('chai'); const sinon = require('sinon'); +const { NotifierService } = require('@fxa/shared/notifier'); +const { Container } = require('typedi'); -describe('notifier', () => { +describe.only('notifier', () => { const log = { error: sinon.spy(), trace: sinon.spy(), }; + let notifierServiceSendSpy = sinon.spy(); + let config; + let notifier; - beforeEach(() => { + beforeEach(async () => { log.error.resetHistory(); log.trace.resetHistory(); - }); - - describe('with sns configuration', () => { - let config, notifier; - - beforeEach(() => { - config = { - config: { - get: (key) => { - if (key === 'snsTopicArn') { - return 'arn:aws:sns:us-west-2:927034868275:foo'; - } - }, - }, - }; - - notifier = proxyquire(`${ROOT_DIR}/lib/notifier`, { - '../config': config, - })(log); - - notifier.__sns.publish = sinon.spy((event, cb) => { - cb(null, event); - }); - }); - - it('publishes a correctly-formatted message', () => { - notifier.send({ - event: 'stuff', - }); - - assert.equal(log.trace.args[0][0], 'Notifier.publish'); - assert.deepEqual(log.trace.args[0][1], { - data: { - TopicArn: 'arn:aws:sns:us-west-2:927034868275:foo', - Message: '{"event":"stuff"}', - MessageAttributes: { - event_type: { - DataType: 'String', - StringValue: 'stuff', - }, - }, - }, - success: true, - }); - assert.equal(log.error.called, false); - }); - - it('flattens additional data into the message body', () => { - notifier.send({ - event: 'stuff-with-data', - data: { - cool: 'stuff', - more: 'stuff', - }, - }); - - assert.equal(log.trace.args[0][0], 'Notifier.publish'); - assert.deepEqual(log.trace.args[0][1], { - data: { - TopicArn: 'arn:aws:sns:us-west-2:927034868275:foo', - Message: '{"cool":"stuff","more":"stuff","event":"stuff-with-data"}', - MessageAttributes: { - event_type: { - DataType: 'String', - StringValue: 'stuff-with-data', - }, - }, - }, - success: true, - }); - assert.equal(log.error.called, false); - }); - - it('includes email domain in message attributes', () => { - notifier.send({ - event: 'email-change', - data: { - email: 'testme@example.com', - }, - }); - - assert.equal(log.trace.args[0][0], 'Notifier.publish'); - assert.deepEqual(log.trace.args[0][1], { - data: { - TopicArn: 'arn:aws:sns:us-west-2:927034868275:foo', - Message: '{"email":"testme@example.com","event":"email-change"}', - MessageAttributes: { - email_domain: { - DataType: 'String', - StringValue: 'example.com', - }, - event_type: { - DataType: 'String', - StringValue: 'email-change', - }, - }, - }, - success: true, - }); - assert.equal(log.error.called, false); - }); - - it('captures perf stats with statsd when it is present', () => { - const statsd = { timing: sinon.stub() }; - notifier = proxyquire(`${ROOT_DIR}/lib/notifier`, { - '../config': config, - })(log, statsd); - notifier.__sns.publish = sinon.spy((event, cb) => { - cb(null, event); - }); - notifier.send({ - event: 'testo', - }); - assert.equal(statsd.timing.calledOnce, true, 'statsd was called'); - assert.equal( - statsd.timing.args[0][0], - 'notifier.publish', - 'correct stat name was used' - ); - assert.equal( - typeof statsd.timing.args[0][1], - 'number', - 'stat value was a number' - ); - }); - }); - - it('works with disabled configuration', () => { - const config = { + config = { config: { get: (key) => { if (key === 'snsTopicArn') { - return 'disabled'; + return 'arn:aws:sns:us-west-2:927034868275:foo'; } }, }, }; - const notifier = proxyquire(`${ROOT_DIR}/lib/notifier`, { - '../config': config, - })(log); - notifier.send( + const { getAppModuleInstance, bridgeTypeDi } = proxyquire( + `../../lib/bridge-nestjs`, { - event: 'stuff', - }, - () => { - assert.equal(log.trace.args[0][0], 'Notifier.publish'); - assert.deepEqual(log.trace.args[0][1], { - data: { - disabled: true, - }, - success: true, - }); - assert.equal(log.trace.args[0][1].data.disabled, true); - assert.equal(log.error.called, false); + '../config': config, } ); + await getAppModuleInstance(); + await bridgeTypeDi(); + + const notifierService = Container.get(NotifierService); + notifierServiceSendSpy = sinon.spy(notifierService, 'send'); + notifier = proxyquire(`${ROOT_DIR}/lib/notifier`, { + '../config': config, + })(log); + }); + + afterEach(() => { + sinon.reset(); + }); + + it('sends event to notifier service', () => { + const event = { + event: 'stuff', + }; + const cb = () => {}; + notifier.send(event, cb); + sinon.assert.calledWith(notifierServiceSendSpy, event, cb); }); }); diff --git a/packages/fxa-auth-server/test/remote/subscription_tests.js b/packages/fxa-auth-server/test/remote/subscription_tests.js index c405e5711a0..50fa07a245b 100644 --- a/packages/fxa-auth-server/test/remote/subscription_tests.js +++ b/packages/fxa-auth-server/test/remote/subscription_tests.js @@ -15,7 +15,7 @@ const error = require(`${ROOT_DIR}/lib/error`); const testServerFactory = require('../test_server'); const { CapabilityService } = require('../../lib/payments/capability'); const { StripeHelper } = require('../../lib/payments/stripe'); -const { AuthLogger } = require('../../lib/types'); +const { AuthLogger, AppConfig } = require('../../lib/types'); const { ProfileClient } = require('@fxa/profile/client'); const { PlaySubscriptions, @@ -102,6 +102,7 @@ const PRODUCT_NAME = 'All Done Pro'; mockStripeHelper.fetchCustomer = async (uid, email) => ({}); mockStripeHelper.allMergedPlanConfigs = async () => []; mockProfileClient.deleteCache = () => {}; + Container.set(AppConfig, config); Container.set(AuthLogger, { error: () => {} }); Container.set(StripeHelper, mockStripeHelper); Container.set(PlaySubscriptions, mockPlaySubscriptions); diff --git a/packages/fxa-auth-server/tsconfig.json b/packages/fxa-auth-server/tsconfig.json index 7eed3e83231..4db8cbe6a60 100644 --- a/packages/fxa-auth-server/tsconfig.json +++ b/packages/fxa-auth-server/tsconfig.json @@ -8,12 +8,13 @@ "checkJs": false, "outDir": "./dist", "types": ["accept-language", "mocha", "mozlog", "node", "fxa-geodb"], - "lib": ["ESNext"] + "lib": ["ESNext"], + "emitDecoratorMetadata": true }, "include": [ "bin/*", "scripts/*.ts", "scripts/delete-account.js", - "lib/senders/emails/templates/*/includes.ts" + "lib/senders/emails/templates/*/includes.ts", ] } diff --git a/yarn.lock b/yarn.lock index 243cd71b561..c954ee4b81c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13127,6 +13127,25 @@ __metadata: languageName: node linkType: hard +"@nest/core@npm:^4.5.4": + version: 4.5.4 + resolution: "@nest/core@npm:4.5.4" + dependencies: + body-parser: 1.17.2 + class-transformer: ^0.1.8 + class-validator: ^0.7.3 + cli-color: ^1.2.0 + express: 4.16.2 + iterare: 0.0.8 + optional: 0.1.4 + peerDependencies: + "@nest/core": ^4.* + reflect-metadata: 0.1.10 + rxjs: ^5.4.2 + checksum: 46e99ff4334a578b13a1f0919917bd6e4cbbffc453c7a4b145e131a1b0105ed2a3187918a3ae051e9a3b01df824296d5fa6a26955dc7e7df4da5011ecb9dc7c4 + languageName: node + linkType: hard + "@nestjs/apollo@npm:^12.1.0": version: 12.1.0 resolution: "@nestjs/apollo@npm:12.1.0" @@ -27648,7 +27667,7 @@ __metadata: languageName: node linkType: hard -"ansi-regex@npm:^2.0.0": +"ansi-regex@npm:^2.0.0, ansi-regex@npm:^2.1.1": version: 2.1.1 resolution: "ansi-regex@npm:2.1.1" checksum: 190abd03e4ff86794f338a31795d262c1dfe8c91f7e01d04f13f646f1dcb16c5800818f886047876f1272f065570ab86b24b99089f8b68a0e11ff19aed4ca8f1 @@ -30531,6 +30550,42 @@ __metadata: languageName: node linkType: hard +"body-parser@npm:1.17.2": + version: 1.17.2 + resolution: "body-parser@npm:1.17.2" + dependencies: + bytes: 2.4.0 + content-type: ~1.0.2 + debug: 2.6.7 + depd: ~1.1.0 + http-errors: ~1.6.1 + iconv-lite: 0.4.15 + on-finished: ~2.3.0 + qs: 6.4.0 + raw-body: ~2.2.0 + type-is: ~1.6.15 + checksum: 886b4e0e4ed2b084b4dc7b18b1b01e45422360468fd9d68ba45788b8b576f19878709a07d25aa87618ae970135d06dcb0bf50cd2ea157bef1b7bebe81e1e273c + languageName: node + linkType: hard + +"body-parser@npm:1.18.2": + version: 1.18.2 + resolution: "body-parser@npm:1.18.2" + dependencies: + bytes: 3.0.0 + content-type: ~1.0.4 + debug: 2.6.9 + depd: ~1.1.1 + http-errors: ~1.6.2 + iconv-lite: 0.4.19 + on-finished: ~2.3.0 + qs: 6.5.1 + raw-body: 2.3.2 + type-is: ~1.6.15 + checksum: 69901e691127c9eaf36c9e614c818789b2e3a3ba9ee05bbcea834172797abb81f05606e42a115da540dfd14646308bdd43d7a3adef5203a44b69c03f74d55d7e + languageName: node + linkType: hard + "body-parser@npm:1.19.0": version: 1.19.0 resolution: "body-parser@npm:1.19.0" @@ -31321,6 +31376,13 @@ __metadata: languageName: node linkType: hard +"bytes@npm:2.4.0": + version: 2.4.0 + resolution: "bytes@npm:2.4.0" + checksum: 2a3fd827e2e1299f687953384854b35ae2920553efc2062a6640c0dcf555af71f7a37a9d4d18fa0c35f2ac57ad9d0bfff526dbe8062a3996cc1ed30cc3f66392 + languageName: node + linkType: hard + "bytes@npm:3.0.0": version: 3.0.0 resolution: "bytes@npm:3.0.0" @@ -32312,6 +32374,13 @@ __metadata: languageName: node linkType: hard +"class-transformer@npm:^0.1.8": + version: 0.1.10 + resolution: "class-transformer@npm:0.1.10" + checksum: cc5e42403713f17d5a3a9ecb8fe917a77683c7fcccf5eaa87b0f87e794327741da608f4107085e1cb101127066e4d98fda7bf3a346095ff3a5f18fd4626cda2c + languageName: node + linkType: hard + "class-utils@npm:^0.3.5": version: 0.3.6 resolution: "class-utils@npm:0.3.6" @@ -32335,6 +32404,15 @@ __metadata: languageName: node linkType: hard +"class-validator@npm:^0.7.3": + version: 0.7.3 + resolution: "class-validator@npm:0.7.3" + dependencies: + validator: ^7.0.0 + checksum: db8970a2a9960ab3772d773bc79f3886934371000e6d4985c54aa8cf941cb1500232e63150395d3f5660450191f52ba9c02b021b58e599ff94a67d6280dfe870 + languageName: node + linkType: hard + "classnames@npm:*": version: 2.3.1 resolution: "classnames@npm:2.3.1" @@ -32399,6 +32477,20 @@ __metadata: languageName: node linkType: hard +"cli-color@npm:^1.2.0": + version: 1.4.0 + resolution: "cli-color@npm:1.4.0" + dependencies: + ansi-regex: ^2.1.1 + d: 1 + es5-ext: ^0.10.46 + es6-iterator: ^2.0.3 + memoizee: ^0.4.14 + timers-ext: ^0.1.5 + checksum: 5e840cf68c913f3c4e9eb889e45ea8c26260f6253407ee3a95e11ba317454638e7c41b9fd641a1305b9a6d84e996a86c8468c112695290262f6066138a6445f4 + languageName: node + linkType: hard + "cli-cursor@npm:3.1.0, cli-cursor@npm:^3.1.0": version: 3.1.0 resolution: "cli-cursor@npm:3.1.0" @@ -33369,6 +33461,13 @@ __metadata: languageName: node linkType: hard +"content-disposition@npm:0.5.2": + version: 0.5.2 + resolution: "content-disposition@npm:0.5.2" + checksum: 298d7da63255a38f7858ee19c7b6aae32b167e911293174b4c1349955e97e78e1d0b0d06c10e229405987275b417cf36ff65cbd4821a98bc9df4e41e9372cde7 + languageName: node + linkType: hard + "content-disposition@npm:0.5.3": version: 0.5.3 resolution: "content-disposition@npm:0.5.3" @@ -33387,7 +33486,7 @@ __metadata: languageName: node linkType: hard -"content-type@npm:^1.0.4, content-type@npm:~1.0.5": +"content-type@npm:^1.0.4, content-type@npm:~1.0.2, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" checksum: 566271e0a251642254cde0f845f9dd4f9856e52d988f4eb0d0dcffbb7a1f8ec98de7a5215fc628f3bce30fe2fb6fd2bc064b562d721658c59b544e2d34ea2766 @@ -33495,6 +33594,13 @@ __metadata: languageName: node linkType: hard +"cookie@npm:0.3.1": + version: 0.3.1 + resolution: "cookie@npm:0.3.1" + checksum: 5309937344947a049283573861c24bed054fac3334ce5a0fa74b9bc6bf39bd387d3a0fca7f3ed6f4a09f112de82c00b541a0e7d6ce7a8de0f5d1301eec799730 + languageName: node + linkType: hard + "cookie@npm:0.4.0": version: 0.4.0 resolution: "cookie@npm:0.4.0" @@ -34521,6 +34627,16 @@ __metadata: languageName: node linkType: hard +"d@npm:1, d@npm:^1.0.1, d@npm:^1.0.2": + version: 1.0.2 + resolution: "d@npm:1.0.2" + dependencies: + es5-ext: ^0.10.64 + type: ^2.7.2 + checksum: 775db1e8ced6707cddf64a5840522fcf5475d38ef49a5d615be0ac47f86ef64d15f5a73de1522b09327cc466d4dc35ea83dbfeed456f7a0fdcab138deb800355 + languageName: node + linkType: hard + "damerau-levenshtein@npm:^1.0.8": version: 1.0.8 resolution: "damerau-levenshtein@npm:1.0.8" @@ -34708,6 +34824,15 @@ __metadata: languageName: node linkType: hard +"debug@npm:2.6.7": + version: 2.6.7 + resolution: "debug@npm:2.6.7" + dependencies: + ms: 2.0.0 + checksum: ce2241461b343f2be0b37723454a029f825318645a706bf82680ead2084b181357db78ae18cabf04d8b9e15ace7f7b486722f096c7c72d1fd9b8639f846388cf + languageName: node + linkType: hard + "debug@npm:2.6.9, debug@npm:^2.1.3, debug@npm:^2.2.0, debug@npm:^2.3.3, debug@npm:^2.6.0, debug@npm:^2.6.8, debug@npm:^2.6.9": version: 2.6.9 resolution: "debug@npm:2.6.9" @@ -35299,6 +35424,13 @@ __metadata: languageName: node linkType: hard +"depd@npm:1.1.1": + version: 1.1.1 + resolution: "depd@npm:1.1.1" + checksum: f4664059b3f7fd44a201d6b79094ef22f73f48fab69ca883221558abdae99b44e5665ce6403c03ff177e1e9a3b7285db0eb29dd215a9278dee3ed4e534b67ace + languageName: node + linkType: hard + "depd@npm:2.0.0, depd@npm:~2.0.0": version: 2.0.0 resolution: "depd@npm:2.0.0" @@ -35306,7 +35438,7 @@ __metadata: languageName: node linkType: hard -"depd@npm:^1.1.2, depd@npm:~1.1.2": +"depd@npm:^1.1.2, depd@npm:~1.1.0, depd@npm:~1.1.1, depd@npm:~1.1.2": version: 1.1.2 resolution: "depd@npm:1.1.2" checksum: 6b406620d269619852885ce15965272b829df6f409724415e0002c8632ab6a8c0a08ec1f0bd2add05dc7bd7507606f7e2cc034fa24224ab829580040b835ecd9 @@ -36295,7 +36427,7 @@ __metadata: languageName: node linkType: hard -"encodeurl@npm:^1.0.2, encodeurl@npm:~1.0.2": +"encodeurl@npm:^1.0.2, encodeurl@npm:~1.0.1, encodeurl@npm:~1.0.2": version: 1.0.2 resolution: "encodeurl@npm:1.0.2" checksum: e50e3d508cdd9c4565ba72d2012e65038e5d71bdc9198cb125beb6237b5b1ade6c0d343998da9e170fb2eae52c1bed37d4d6d98a46ea423a0cddbed5ac3f780c @@ -36832,6 +36964,18 @@ __metadata: languageName: node linkType: hard +"es5-ext@npm:^0.10.35, es5-ext@npm:^0.10.46, es5-ext@npm:^0.10.62, es5-ext@npm:^0.10.64, es5-ext@npm:~0.10.14, es5-ext@npm:~0.10.2": + version: 0.10.64 + resolution: "es5-ext@npm:0.10.64" + dependencies: + es6-iterator: ^2.0.3 + es6-symbol: ^3.1.3 + esniff: ^2.0.1 + next-tick: ^1.1.0 + checksum: 01179fab0769fdbef213062222f99d0346724dbaccf04b87c0e6ee7f0c97edabf14be647ca1321f0497425ea7145de0fd278d1b3f3478864b8933e7136a5c645 + languageName: node + linkType: hard + "es6-error@npm:^4.0.1": version: 4.1.1 resolution: "es6-error@npm:4.1.1" @@ -36839,6 +36983,17 @@ __metadata: languageName: node linkType: hard +"es6-iterator@npm:^2.0.3": + version: 2.0.3 + resolution: "es6-iterator@npm:2.0.3" + dependencies: + d: 1 + es5-ext: ^0.10.35 + es6-symbol: ^3.1.1 + checksum: 6e48b1c2d962c21dee604b3d9f0bc3889f11ed5a8b33689155a2065d20e3107e2a69cc63a71bd125aeee3a589182f8bbcb5c8a05b6a8f38fa4205671b6d09697 + languageName: node + linkType: hard + "es6-object-assign@npm:^1.1.0": version: 1.1.0 resolution: "es6-object-assign@npm:1.1.0" @@ -36860,6 +37015,28 @@ __metadata: languageName: node linkType: hard +"es6-symbol@npm:^3.1.1, es6-symbol@npm:^3.1.3": + version: 3.1.4 + resolution: "es6-symbol@npm:3.1.4" + dependencies: + d: ^1.0.2 + ext: ^1.7.0 + checksum: 52125ec4b5d1b6b93b8d3d42830bb19f8da21080ffcf45253b614bc6ff3e31349be202fb745d4d1af6778cdf5e38fea30e0c7e7dc37e2aecd44acc43502055f9 + languageName: node + linkType: hard + +"es6-weak-map@npm:^2.0.3": + version: 2.0.3 + resolution: "es6-weak-map@npm:2.0.3" + dependencies: + d: 1 + es5-ext: ^0.10.46 + es6-iterator: ^2.0.3 + es6-symbol: ^3.1.1 + checksum: 19ca15f46d50948ce78c2da5f21fb5b1ef45addd4fe17b5df952ff1f2a3d6ce4781249bc73b90995257264be2a98b2ec749bb2aba0c14b5776a1154178f9c927 + languageName: node + linkType: hard + "esbuild-plugin-alias@npm:^0.2.1": version: 0.2.1 resolution: "esbuild-plugin-alias@npm:0.2.1" @@ -38196,6 +38373,18 @@ __metadata: languageName: node linkType: hard +"esniff@npm:^2.0.1": + version: 2.0.1 + resolution: "esniff@npm:2.0.1" + dependencies: + d: ^1.0.1 + es5-ext: ^0.10.62 + event-emitter: ^0.3.5 + type: ^2.7.2 + checksum: d814c0e5c39bce9925b2e65b6d8767af72c9b54f35a65f9f3d6e8c606dce9aebe35a9599d30f15b0807743f88689f445163cfb577a425de4fb8c3c5bc16710cc + languageName: node + linkType: hard + "espree@npm:^10.0.1": version: 10.0.1 resolution: "espree@npm:10.0.1" @@ -38369,6 +38558,16 @@ __metadata: languageName: node linkType: hard +"event-emitter@npm:^0.3.5": + version: 0.3.5 + resolution: "event-emitter@npm:0.3.5" + dependencies: + d: 1 + es5-ext: ~0.10.14 + checksum: 27c1399557d9cd7e0aa0b366c37c38a4c17293e3a10258e8b692a847dd5ba9fb90429c3a5a1eeff96f31f6fa03ccbd31d8ad15e00540b22b22f01557be706030 + languageName: node + linkType: hard + "event-stream@npm:=3.3.4": version: 3.3.4 resolution: "event-stream@npm:3.3.4" @@ -38689,6 +38888,44 @@ __metadata: languageName: node linkType: hard +"express@npm:4.16.2": + version: 4.16.2 + resolution: "express@npm:4.16.2" + dependencies: + accepts: ~1.3.4 + array-flatten: 1.1.1 + body-parser: 1.18.2 + content-disposition: 0.5.2 + content-type: ~1.0.4 + cookie: 0.3.1 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: ~1.1.1 + encodeurl: ~1.0.1 + escape-html: ~1.0.3 + etag: ~1.8.1 + finalhandler: 1.1.0 + fresh: 0.5.2 + merge-descriptors: 1.0.1 + methods: ~1.1.2 + on-finished: ~2.3.0 + parseurl: ~1.3.2 + path-to-regexp: 0.1.7 + proxy-addr: ~2.0.2 + qs: 6.5.1 + range-parser: ~1.2.0 + safe-buffer: 5.1.1 + send: 0.16.1 + serve-static: 1.13.1 + setprototypeof: 1.1.0 + statuses: ~1.3.1 + type-is: ~1.6.15 + utils-merge: 1.0.1 + vary: ~1.1.2 + checksum: 125cae1887131506a171f1b90f354ab74d6c80f0495c6592fbff620a74d124e37bec5cf53f735f5bcc5ebe614c8702176aa5b876d9ae164bf61c9a6b9b3609c7 + languageName: node + linkType: hard + "express@npm:4.19.2, express@npm:^4.17.1, express@npm:^4.17.3, express@npm:^4.19.2": version: 4.19.2 resolution: "express@npm:4.19.2" @@ -38824,6 +39061,15 @@ __metadata: languageName: node linkType: hard +"ext@npm:^1.7.0": + version: 1.7.0 + resolution: "ext@npm:1.7.0" + dependencies: + type: ^2.7.2 + checksum: ef481f9ef45434d8c867cfd09d0393b60945b7c8a1798bedc4514cb35aac342ccb8d8ecb66a513e6a2b4ec1e294a338e3124c49b29736f8e7c735721af352c31 + languageName: node + linkType: hard + "extend-shallow@npm:^2.0.1": version: 2.0.1 resolution: "extend-shallow@npm:2.0.1" @@ -39560,6 +39806,21 @@ __metadata: languageName: node linkType: hard +"finalhandler@npm:1.1.0": + version: 1.1.0 + resolution: "finalhandler@npm:1.1.0" + dependencies: + debug: 2.6.9 + encodeurl: ~1.0.1 + escape-html: ~1.0.3 + on-finished: ~2.3.0 + parseurl: ~1.3.2 + statuses: ~1.3.1 + unpipe: ~1.0.0 + checksum: fb22b420315378b5c5d8a3a96f50c16a3ba3cc56b1ffa0bc65be63de978d08dc255002e4348663a6b2813e3ec6c930b1f1387aa3a0545d9bf4727b0f90a83ff2 + languageName: node + linkType: hard + "finalhandler@npm:1.2.0": version: 1.2.0 resolution: "finalhandler@npm:1.2.0" @@ -40753,6 +41014,7 @@ fsevents@~2.1.1: "@googlemaps/google-maps-services-js": ^3.4.0 "@hapi/hapi": ^20.2.1 "@hapi/hoek": ^11.0.2 + "@nest/core": ^4.5.4 "@storybook/addon-controls": ^7.4.6 "@storybook/addon-docs": ^7.6.12 "@storybook/addon-toolbars": ^7.0.23 @@ -44446,6 +44708,18 @@ fsevents@~2.1.1: languageName: node linkType: hard +"http-errors@npm:1.6.2": + version: 1.6.2 + resolution: "http-errors@npm:1.6.2" + dependencies: + depd: 1.1.1 + inherits: 2.0.3 + setprototypeof: 1.0.3 + statuses: ">= 1.3.1 < 2" + checksum: d9c5d2972b3b24b4634bbe181941240a474977545ef79f9ce5c444914dd9fe8a6608bf51003fd36fa7d609059ff6fca9f585e2f5642795312e8cab0c577388a8 + languageName: node + linkType: hard + "http-errors@npm:1.7.2": version: 1.7.2 resolution: "http-errors@npm:1.7.2" @@ -44485,7 +44759,7 @@ fsevents@~2.1.1: languageName: node linkType: hard -"http-errors@npm:~1.6.2": +"http-errors@npm:~1.6.1, http-errors@npm:~1.6.2": version: 1.6.3 resolution: "http-errors@npm:1.6.3" dependencies: @@ -44863,6 +45137,20 @@ fsevents@~2.1.1: languageName: node linkType: hard +"iconv-lite@npm:0.4.15": + version: 0.4.15 + resolution: "iconv-lite@npm:0.4.15" + checksum: 858ed660b795386d1ab85c43962d34519d46511d61432f6a74c1488dce2b6023f7eaec82f35f1e94eb20f2cfb36c6ad07e3814f9551a4b7c6058a162bbab382e + languageName: node + linkType: hard + +"iconv-lite@npm:0.4.19": + version: 0.4.19 + resolution: "iconv-lite@npm:0.4.19" + checksum: 74a10d6e71d46ecfef47089588f351ea2d2ae9a7b88536ae16b27293799bf709ca20022da4370e562e76f8558321241115c8f54c5a64f68b27b96ad3d2569dba + languageName: node + linkType: hard + "iconv-lite@npm:0.4.24, iconv-lite@npm:^0.4.24, iconv-lite@npm:^0.4.4, iconv-lite@npm:~0.4.13": version: 0.4.24 resolution: "iconv-lite@npm:0.4.24" @@ -46344,6 +46632,13 @@ fsevents@~2.1.1: languageName: node linkType: hard +"is-promise@npm:^2.2.2": + version: 2.2.2 + resolution: "is-promise@npm:2.2.2" + checksum: 18bf7d1c59953e0ad82a1ed963fb3dc0d135c8f299a14f89a17af312fc918373136e56028e8831700e1933519630cc2fd4179a777030330fde20d34e96f40c78 + languageName: node + linkType: hard + "is-property@npm:^1.0.2": version: 1.0.2 resolution: "is-property@npm:1.0.2" @@ -46861,6 +47156,13 @@ fsevents@~2.1.1: languageName: node linkType: hard +"iterare@npm:0.0.8": + version: 0.0.8 + resolution: "iterare@npm:0.0.8" + checksum: d4f1cbaf9a5923b4954ac496f1b3d7a17f18f3e640756db1910d6c605f0ca6b3a8faeca2646e346205bba2608eeec6fa10ebc314b08e4b4f63469377a4781c23 + languageName: node + linkType: hard + "iterare@npm:1.2.1": version: 1.2.1 resolution: "iterare@npm:1.2.1" @@ -51270,6 +51572,15 @@ fsevents@~2.1.1: languageName: node linkType: hard +"lru-queue@npm:^0.1.0": + version: 0.1.0 + resolution: "lru-queue@npm:0.1.0" + dependencies: + es5-ext: ~0.10.2 + checksum: 7f2c53c5e7f2de20efb6ebb3086b7aea88d6cf9ae91ac5618ece974122960c4e8ed04988e81d92c3e63d60b12c556b14d56ef7a9c5a4627b23859b813e39b1a2 + languageName: node + linkType: hard + "luxon@npm:^3.2.1, luxon@npm:~3.4.0": version: 3.4.4 resolution: "luxon@npm:3.4.4" @@ -51726,6 +52037,22 @@ fsevents@~2.1.1: languageName: node linkType: hard +"memoizee@npm:^0.4.14": + version: 0.4.17 + resolution: "memoizee@npm:0.4.17" + dependencies: + d: ^1.0.2 + es5-ext: ^0.10.64 + es6-weak-map: ^2.0.3 + event-emitter: ^0.3.5 + is-promise: ^2.2.2 + lru-queue: ^0.1.0 + next-tick: ^1.1.0 + timers-ext: ^0.1.7 + checksum: 9f2fa3f55d3b053ddfb7f2ce47ea3f51aa88d4425fa3aee0daf48bd41ecb8f1787b2150b14bcf745d8c4be8e2c07da614d857e11f79a6951420bbb0029b05a9c + languageName: node + linkType: hard + "memoizerific@npm:^1.11.3": version: 1.11.3 resolution: "memoizerific@npm:1.11.3" @@ -52198,6 +52525,15 @@ fsevents@~2.1.1: languageName: node linkType: hard +"mime@npm:1.4.1": + version: 1.4.1 + resolution: "mime@npm:1.4.1" + bin: + mime: cli.js + checksum: 14c9de5c801ddad82619b66049f3314bbced9667689eed769fab64a323e79b3535ab650e9607670e52371b16436a49af3c0473d965ec743de931cb5d73d3adba + languageName: node + linkType: hard + "mime@npm:1.6.0, mime@npm:^1.3.4, mime@npm:^1.4.1, mime@npm:^1.6.0": version: 1.6.0 resolution: "mime@npm:1.6.0" @@ -53751,6 +54087,13 @@ fsevents@~2.1.1: languageName: node linkType: hard +"next-tick@npm:^1.1.0": + version: 1.1.0 + resolution: "next-tick@npm:1.1.0" + checksum: 83b5cf36027a53ee6d8b7f9c0782f2ba87f4858d977342bfc3c20c21629290a2111f8374d13a81221179603ffc4364f38374b5655d17b6a8f8a8c77bdea4fe8b + languageName: node + linkType: hard + "next@npm:14.2.10": version: 14.2.10 resolution: "next@npm:14.2.10" @@ -55421,6 +55764,13 @@ fsevents@~2.1.1: languageName: node linkType: hard +"optional@npm:0.1.4": + version: 0.1.4 + resolution: "optional@npm:0.1.4" + checksum: 81fd9884eac9c13b3624821f99aa825b71d46ffd547cd3f8cf9e1dfb0165e531448005288455895550f804bdd66459e4e7ae6e753805b8bf11a5983050d5b7c4 + languageName: node + linkType: hard + "optionator@npm:^0.8.1, optionator@npm:^0.8.2": version: 0.8.3 resolution: "optionator@npm:0.8.3" @@ -59114,23 +59464,23 @@ fsevents@~2.1.1: languageName: node linkType: hard -"proxy-addr@npm:~2.0.5": - version: 2.0.6 - resolution: "proxy-addr@npm:2.0.6" +"proxy-addr@npm:~2.0.2, proxy-addr@npm:~2.0.7": + version: 2.0.7 + resolution: "proxy-addr@npm:2.0.7" dependencies: - forwarded: ~0.1.2 + forwarded: 0.2.0 ipaddr.js: 1.9.1 - checksum: 2bad9b7a56b847faf606a19328aaaf5fca3e561ebb4e933969a580d94a20f77e74fb21196028a6e417851b3d9d95a0c704732a3362e3ef515d45d96859ac7eb9 + checksum: 29c6990ce9364648255454842f06f8c46fcd124d3e6d7c5066df44662de63cdc0bad032e9bf5a3d653ff72141cc7b6019873d685708ac8210c30458ad99f2b74 languageName: node linkType: hard -"proxy-addr@npm:~2.0.7": - version: 2.0.7 - resolution: "proxy-addr@npm:2.0.7" +"proxy-addr@npm:~2.0.5": + version: 2.0.6 + resolution: "proxy-addr@npm:2.0.6" dependencies: - forwarded: 0.2.0 + forwarded: ~0.1.2 ipaddr.js: 1.9.1 - checksum: 29c6990ce9364648255454842f06f8c46fcd124d3e6d7c5066df44662de63cdc0bad032e9bf5a3d653ff72141cc7b6019873d685708ac8210c30458ad99f2b74 + checksum: 2bad9b7a56b847faf606a19328aaaf5fca3e561ebb4e933969a580d94a20f77e74fb21196028a6e417851b3d9d95a0c704732a3362e3ef515d45d96859ac7eb9 languageName: node linkType: hard @@ -59418,6 +59768,20 @@ fsevents@~2.1.1: languageName: node linkType: hard +"qs@npm:6.4.0": + version: 6.4.0 + resolution: "qs@npm:6.4.0" + checksum: 83518c41a710af2dc998e31013557aaade5cbff10d93a6cad16aa42454db53d448648ad395d1ca83aef54f14032be9ae31041d76d740295d4e77168fa37a0224 + languageName: node + linkType: hard + +"qs@npm:6.5.1": + version: 6.5.1 + resolution: "qs@npm:6.5.1" + checksum: 40967af240d04138b0cc6a70231270871c4a627834cae3e529dab9ee01fb95730bd80299cded185c409a24b03f890831d41ee37e8431372540d62f60f4011fbd + languageName: node + linkType: hard + "qs@npm:6.7.0": version: 6.7.0 resolution: "qs@npm:6.7.0" @@ -59598,13 +59962,25 @@ fsevents@~2.1.1: languageName: node linkType: hard -"range-parser@npm:^1.2.1, range-parser@npm:~1.2.1": +"range-parser@npm:^1.2.1, range-parser@npm:~1.2.0, range-parser@npm:~1.2.1": version: 1.2.1 resolution: "range-parser@npm:1.2.1" checksum: 0a268d4fea508661cf5743dfe3d5f47ce214fd6b7dec1de0da4d669dd4ef3d2144468ebe4179049eff253d9d27e719c88dae55be64f954e80135a0cada804ec9 languageName: node linkType: hard +"raw-body@npm:2.3.2": + version: 2.3.2 + resolution: "raw-body@npm:2.3.2" + dependencies: + bytes: 3.0.0 + http-errors: 1.6.2 + iconv-lite: 0.4.19 + unpipe: 1.0.0 + checksum: d654cdbbb8ffc3d3dae939a8597204459485feee1742ae82d8884f446925df5c234f8963a9b85c9765b1f1e8ad5da669fdc5e98d7259cc76b512da8afa67041e + languageName: node + linkType: hard + "raw-body@npm:2.4.0": version: 2.4.0 resolution: "raw-body@npm:2.4.0" @@ -59651,6 +60027,17 @@ fsevents@~2.1.1: languageName: node linkType: hard +"raw-body@npm:~2.2.0": + version: 2.2.0 + resolution: "raw-body@npm:2.2.0" + dependencies: + bytes: 2.4.0 + iconv-lite: 0.4.15 + unpipe: 1.0.0 + checksum: b072f5e6d7f274c27bf592d9b63fa882cdef6d2b21011991df411bd19678333cbc5b1ca971a814e71e94654f9666f7330628d0f8faad979ca988601046049ec8 + languageName: node + linkType: hard + "rc@npm:^1.2.7": version: 1.2.8 resolution: "rc@npm:1.2.8" @@ -62592,6 +62979,27 @@ resolve@1.1.7: languageName: node linkType: hard +"send@npm:0.16.1": + version: 0.16.1 + resolution: "send@npm:0.16.1" + dependencies: + debug: 2.6.9 + depd: ~1.1.1 + destroy: ~1.0.4 + encodeurl: ~1.0.1 + escape-html: ~1.0.3 + etag: ~1.8.1 + fresh: 0.5.2 + http-errors: ~1.6.2 + mime: 1.4.1 + ms: 2.0.0 + on-finished: ~2.3.0 + range-parser: ~1.2.0 + statuses: ~1.3.1 + checksum: b8c52dfd30ba6fc1008034d1af68d0dde89102271c1eadf6a9697812d5b3ab039eb467b024320c5d56cc549f26d5663faebae5ced450e32a3cb9e921c6c32ac9 + languageName: node + linkType: hard + "send@npm:0.17.1": version: 0.17.1 resolution: "send@npm:0.17.1" @@ -62744,6 +63152,18 @@ resolve@1.1.7: languageName: node linkType: hard +"serve-static@npm:1.13.1": + version: 1.13.1 + resolution: "serve-static@npm:1.13.1" + dependencies: + encodeurl: ~1.0.1 + escape-html: ~1.0.3 + parseurl: ~1.3.2 + send: 0.16.1 + checksum: 99bdc801c57c69f4eb856b15567b973a4ccbb7722c05472ab25dbd70b5b7841c3f74d0b536c92205a02e4709283402269baf12a870d8b046c959ef39934b7c4a + languageName: node + linkType: hard + "serve-static@npm:1.14.1": version: 1.14.1 resolution: "serve-static@npm:1.14.1" @@ -62867,6 +63287,13 @@ resolve@1.1.7: languageName: node linkType: hard +"setprototypeof@npm:1.0.3": + version: 1.0.3 + resolution: "setprototypeof@npm:1.0.3" + checksum: ae520af039feeb3364be586c48c82c6b9eb5bd6834e440b42bfd54f714fcdabab123ff850a3142c00ce1f37eb4c395f06ed4a5ce33b2c3cbf52b36b8297b8cc2 + languageName: node + linkType: hard + "setprototypeof@npm:1.1.0": version: 1.1.0 resolution: "setprototypeof@npm:1.1.0" @@ -64166,13 +64593,20 @@ resolve@1.1.7: languageName: node linkType: hard -"statuses@npm:>= 1.4.0 < 2, statuses@npm:>= 1.5.0 < 2, statuses@npm:^1.5.0, statuses@npm:~1.5.0": +"statuses@npm:>= 1.3.1 < 2, statuses@npm:>= 1.4.0 < 2, statuses@npm:>= 1.5.0 < 2, statuses@npm:^1.5.0, statuses@npm:~1.5.0": version: 1.5.0 resolution: "statuses@npm:1.5.0" checksum: c469b9519de16a4bb19600205cffb39ee471a5f17b82589757ca7bd40a8d92ebb6ed9f98b5a540c5d302ccbc78f15dc03cc0280dd6e00df1335568a5d5758a5c languageName: node linkType: hard +"statuses@npm:~1.3.1": + version: 1.3.1 + resolution: "statuses@npm:1.3.1" + checksum: da573f84ee32303ccb06f51dc1fc2ef592f4837d2d3fde8a9d1440058c6ae05805bca7cd3567c7fb9d6c4455a546ed8582a4ec647c8ceeae1654be8cd77e5a24 + languageName: node + linkType: hard + "stdout-stream@npm:^1.4.0": version: 1.4.1 resolution: "stdout-stream@npm:1.4.1" @@ -66398,6 +66832,16 @@ resolve@1.1.7: languageName: node linkType: hard +"timers-ext@npm:^0.1.5, timers-ext@npm:^0.1.7": + version: 0.1.8 + resolution: "timers-ext@npm:0.1.8" + dependencies: + es5-ext: ^0.10.64 + next-tick: ^1.1.0 + checksum: 7d37f90bdcee900aa4ba13e983905e2d16538bb13d38315f1ea3670656d91e7898f018909caedc8ebe964974ddeb3eedb5ffdc21f2329e34e6bcc353d0ee2903 + languageName: node + linkType: hard + "tiny-emitter@npm:^2.0.0": version: 2.1.0 resolution: "tiny-emitter@npm:2.1.0" @@ -67376,7 +67820,7 @@ resolve@1.1.7: languageName: node linkType: hard -"type-is@npm:^1.6.16, type-is@npm:^1.6.4, type-is@npm:~1.6.17, type-is@npm:~1.6.18": +"type-is@npm:^1.6.16, type-is@npm:^1.6.4, type-is@npm:~1.6.15, type-is@npm:~1.6.17, type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" dependencies: @@ -67386,6 +67830,13 @@ resolve@1.1.7: languageName: node linkType: hard +"type@npm:^2.7.2": + version: 2.7.3 + resolution: "type@npm:2.7.3" + checksum: 69cfda3248847998f93b9d292fd251c10facf8d29513e2047d4684509d67bae82d910d7a00c1e9d9bbf2af242d36425b6616807d6c652c5c370c2be1f0008a47 + languageName: node + linkType: hard + "typed-array-buffer@npm:^1.0.0": version: 1.0.0 resolution: "typed-array-buffer@npm:1.0.0" @@ -68583,6 +69034,13 @@ resolve@1.1.7: languageName: node linkType: hard +"validator@npm:^7.0.0": + version: 7.2.0 + resolution: "validator@npm:7.2.0" + checksum: 382cdcf68e0b245b855969cc957fee45c2f9e779e35a218958e41d8a93e8a471714c7a59e4f9d71d2849c7f936be799c867dbbcdc30c1ae8fb636e660dfd7424 + languageName: node + linkType: hard + "value-or-promise@npm:^1.0.11, value-or-promise@npm:^1.0.12": version: 1.0.12 resolution: "value-or-promise@npm:1.0.12"