mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	fix: Upgrade to @hapi/joi (#543)
This commit is contained in:
		
							parent
							
								
									4089a40fa3
								
							
						
					
					
						commit
						b532c86695
					
				| @ -1,5 +1,9 @@ | ||||
| # Changelog | ||||
| 
 | ||||
| ## 3.2.23 | ||||
| 
 | ||||
| - fix: upgrade to @hapi/joi to version 16.1.8 | ||||
| 
 | ||||
| ## 3.2.22 | ||||
| 
 | ||||
| - fix: add appName as label in usage metrics | ||||
|  | ||||
| @ -1,13 +0,0 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| class ValidationError extends Error { | ||||
|     constructor(message) { | ||||
|         super(); | ||||
|         Error.captureStackTrace(this, this.constructor); | ||||
| 
 | ||||
|         this.name = this.constructor.name; | ||||
|         this.message = message; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| module.exports = ValidationError; | ||||
| @ -1,6 +1,6 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| const joi = require('joi'); | ||||
| const joi = require('@hapi/joi'); | ||||
| const { nameType } = require('./util'); | ||||
| 
 | ||||
| const nameSchema = joi.object().keys({ name: nameType }); | ||||
|  | ||||
| @ -2,7 +2,6 @@ | ||||
| 
 | ||||
| const test = require('ava'); | ||||
| const { featureShema } = require('./feature-schema'); | ||||
| const joi = require('joi'); | ||||
| 
 | ||||
| test('should require URL firendly name', t => { | ||||
|     const toggle = { | ||||
| @ -11,7 +10,7 @@ test('should require URL firendly name', t => { | ||||
|         strategies: [{ name: 'default' }], | ||||
|     }; | ||||
| 
 | ||||
|     const { error } = joi.validate(toggle, featureShema); | ||||
|     const { error } = featureShema.validate(toggle); | ||||
|     t.deepEqual(error.details[0].message, '"name" must be URL friendly'); | ||||
| }); | ||||
| 
 | ||||
| @ -22,7 +21,7 @@ test('should be valid toggle name', t => { | ||||
|         strategies: [{ name: 'default' }], | ||||
|     }; | ||||
| 
 | ||||
|     const { value } = joi.validate(toggle, featureShema); | ||||
|     const { value } = featureShema.validate(toggle); | ||||
|     t.deepEqual(value, toggle); | ||||
| }); | ||||
| 
 | ||||
| @ -40,7 +39,7 @@ test('should strip extra variant fields', t => { | ||||
|         ], | ||||
|     }; | ||||
| 
 | ||||
|     const { value } = joi.validate(toggle, featureShema); | ||||
|     const { value } = featureShema.validate(toggle); | ||||
|     t.notDeepEqual(value, toggle); | ||||
|     t.falsy(value.variants[0].unkown); | ||||
| }); | ||||
| @ -64,7 +63,7 @@ test('should be possible to define variant overrides', t => { | ||||
|         ], | ||||
|     }; | ||||
| 
 | ||||
|     const { value, error } = joi.validate(toggle, featureShema); | ||||
|     const { value, error } = featureShema.validate(toggle); | ||||
|     t.deepEqual(value, toggle); | ||||
|     t.falsy(error); | ||||
| }); | ||||
| @ -88,9 +87,12 @@ test('variant overrides must have corect shape', async t => { | ||||
|     }; | ||||
| 
 | ||||
|     try { | ||||
|         await joi.validate(toggle, featureShema); | ||||
|         await featureShema.validateAsync(toggle); | ||||
|     } catch (error) { | ||||
|         t.is(error.details[0].message, '"overrides" must be an array'); | ||||
|         t.is( | ||||
|             error.details[0].message, | ||||
|             '"variants[0].overrides" must be an array' | ||||
|         ); | ||||
|     } | ||||
| }); | ||||
| 
 | ||||
| @ -112,7 +114,7 @@ test('should keep constraints', t => { | ||||
|         ], | ||||
|     }; | ||||
| 
 | ||||
|     const { value, error } = joi.validate(toggle, featureShema); | ||||
|     const { value, error } = featureShema.validate(toggle); | ||||
|     t.deepEqual(value, toggle); | ||||
|     t.falsy(error); | ||||
| }); | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| const Controller = require('../controller'); | ||||
| const joi = require('joi'); | ||||
| 
 | ||||
| const { | ||||
|     FEATURE_CREATED, | ||||
| @ -56,7 +55,7 @@ class FeatureController extends Controller { | ||||
|         const name = req.body.name; | ||||
| 
 | ||||
|         try { | ||||
|             await joi.validate({ name }, nameSchema); | ||||
|             await nameSchema.validateAsync({ name }); | ||||
|             await this.validateUniqueName(name); | ||||
|             res.status(201).end(); | ||||
|         } catch (error) { | ||||
| @ -87,11 +86,11 @@ class FeatureController extends Controller { | ||||
| 
 | ||||
|         try { | ||||
|             await this.validateUniqueName(toggleName); | ||||
|             const featureToggle = await joi.validate(req.body, featureShema); | ||||
|             const value = await featureShema.validateAsync(req.body); | ||||
|             await this.eventStore.store({ | ||||
|                 type: FEATURE_CREATED, | ||||
|                 createdBy: userName, | ||||
|                 data: featureToggle, | ||||
|                 data: value, | ||||
|             }); | ||||
|             res.status(201).end(); | ||||
|         } catch (error) { | ||||
| @ -108,7 +107,7 @@ class FeatureController extends Controller { | ||||
| 
 | ||||
|         try { | ||||
|             await this.featureToggleStore.getFeature(featureName); | ||||
|             await joi.validate(updatedFeature, featureShema); | ||||
|             await featureShema.validateAsync(updatedFeature); | ||||
|             await this.eventStore.store({ | ||||
|                 type: FEATURE_UPDATED, | ||||
|                 createdBy: userName, | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| const joi = require('joi'); | ||||
| const joi = require('@hapi/joi'); | ||||
| const { nameType } = require('./util'); | ||||
| 
 | ||||
| const applicationSchema = joi | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| const joi = require('joi'); | ||||
| const Controller = require('../controller'); | ||||
| const ClientMetrics = require('../../client-metrics'); | ||||
| const schema = require('./metrics-schema'); | ||||
| @ -80,7 +79,7 @@ class MetricsController extends Controller { | ||||
|         const input = Object.assign({}, req.body, { | ||||
|             appName: req.params.appName, | ||||
|         }); | ||||
|         const { value: applicationData, error } = joi.validate(input, schema); | ||||
|         const { value: applicationData, error } = schema.validate(input); | ||||
| 
 | ||||
|         if (error) { | ||||
|             this.logger.warn('Invalid application data posted', error); | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| const joi = require('joi'); | ||||
| const joi = require('@hapi/joi'); | ||||
| const { nameType } = require('./util'); | ||||
| 
 | ||||
| const strategySchema = joi.object().keys({ | ||||
|  | ||||
| @ -1,7 +1,6 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| const Controller = require('../controller'); | ||||
| const joi = require('joi'); | ||||
| 
 | ||||
| const eventType = require('../../event-type'); | ||||
| const NameExistsError = require('../../error/name-exists-error'); | ||||
| @ -65,12 +64,12 @@ class StrategyController extends Controller { | ||||
| 
 | ||||
|     async createStrategy(req, res) { | ||||
|         try { | ||||
|             const newStrategy = await joi.validate(req.body, strategySchema); | ||||
|             await this._validateStrategyName(newStrategy); | ||||
|             const value = await strategySchema.validateAsync(req.body); | ||||
|             await this._validateStrategyName(value); | ||||
|             await this.eventStore.store({ | ||||
|                 type: eventType.STRATEGY_CREATED, | ||||
|                 createdBy: extractUser(req), | ||||
|                 data: newStrategy, | ||||
|                 data: value, | ||||
|             }); | ||||
|             res.status(201).end(); | ||||
|         } catch (error) { | ||||
| @ -82,14 +81,14 @@ class StrategyController extends Controller { | ||||
|         const input = req.body; | ||||
| 
 | ||||
|         try { | ||||
|             const updatedStrategy = await joi.validate(input, strategySchema); | ||||
|             const value = await strategySchema.validateAsync(input); | ||||
|             const strategy = await this.strategyStore.getStrategy(input.name); | ||||
|             await this._validateEditable(strategy); | ||||
| 
 | ||||
|             await this.eventStore.store({ | ||||
|                 type: eventType.STRATEGY_UPDATED, | ||||
|                 createdBy: extractUser(req), | ||||
|                 data: updatedStrategy, | ||||
|                 data: value, | ||||
|             }); | ||||
|             res.status(200).end(); | ||||
|         } catch (error) { | ||||
|  | ||||
| @ -59,7 +59,7 @@ test('require a name when creating a new stratey', t => { | ||||
|         .send({}) | ||||
|         .expect(400) | ||||
|         .expect(res => { | ||||
|             t.true(res.body.name === 'ValidationError'); | ||||
|             t.true(res.body.details[0].message === '"name" is required'); | ||||
|         }); | ||||
| }); | ||||
| 
 | ||||
| @ -73,7 +73,10 @@ test('require parameters array when creating a new stratey', t => { | ||||
|         .send({ name: 'TestStrat' }) | ||||
|         .expect(400) | ||||
|         .expect(res => { | ||||
|             t.true(res.body.name === 'ValidationError'); | ||||
|             t.deepEqual( | ||||
|                 res.body.details[0].message, | ||||
|                 '"parameters" is required' | ||||
|             ); | ||||
|         }); | ||||
| }); | ||||
| 
 | ||||
|  | ||||
| @ -1,34 +1,23 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| const joi = require('joi'); | ||||
| const joi = require('@hapi/joi'); | ||||
| 
 | ||||
| const customJoi = joi.extend(j => ({ | ||||
|     type: 'isUrlFriendly', | ||||
|     base: j.string(), | ||||
|     name: 'string', | ||||
|     language: { | ||||
|         isUrlFriendly: 'must be URL friendly', | ||||
|     messages: { | ||||
|         'isUrlFriendly.base': '"{{#label}}" must be URL friendly', | ||||
|     }, | ||||
|     validate(value, helpers) { | ||||
|         // Base validation regardless of the rules applied
 | ||||
|         if (encodeURIComponent(value) !== value) { | ||||
|             // Generate an error, state and options need to be passed
 | ||||
|             return { value, errors: helpers.error('isUrlFriendly.base') }; | ||||
|         } | ||||
|     }, | ||||
|     rules: [ | ||||
|         { | ||||
|             name: 'isUrlFriendly', | ||||
|             validate(params, value, state, options) { | ||||
|                 if (encodeURIComponent(value) !== value) { | ||||
|                     // Generate an error, state and options need to be passed
 | ||||
|                     return this.createError( | ||||
|                         'string.isUrlFriendly', | ||||
|                         { v: value }, | ||||
|                         state, | ||||
|                         options | ||||
|                     ); | ||||
|                 } | ||||
|                 return value; // Everything is OK
 | ||||
|             }, | ||||
|         }, | ||||
|     ], | ||||
| })); | ||||
| 
 | ||||
| const nameType = customJoi | ||||
|     .string() | ||||
|     .isUrlFriendly() | ||||
|     .min(2) | ||||
|     .max(100) | ||||
| @ -41,6 +30,7 @@ const handleErrors = (res, logger, error) => { | ||||
|             return res.status(404).end(); | ||||
|         case 'NameExistsError': | ||||
|         case 'ValidationError': | ||||
|             error.isJoi = true; | ||||
|             return res | ||||
|                 .status(400) | ||||
|                 .json(error) | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| const joi = require('joi'); | ||||
| const joi = require('@hapi/joi'); | ||||
| 
 | ||||
| const countSchema = joi | ||||
|     .object() | ||||
|  | ||||
| @ -1,7 +1,5 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| const joi = require('joi'); | ||||
| 
 | ||||
| const Controller = require('../controller'); | ||||
| const { clientMetricsSchema } = require('./metrics-schema'); | ||||
| 
 | ||||
| @ -19,7 +17,7 @@ class ClientMetricsController extends Controller { | ||||
|         const data = req.body; | ||||
|         const clientIp = req.ip; | ||||
| 
 | ||||
|         const { error, value } = joi.validate(data, clientMetricsSchema); | ||||
|         const { error, value } = clientMetricsSchema.validate(data); | ||||
| 
 | ||||
|         if (error) { | ||||
|             this.logger.warn('Invalid metrics posted', error); | ||||
|  | ||||
| @ -2,7 +2,6 @@ | ||||
| 
 | ||||
| const test = require('ava'); | ||||
| const supertest = require('supertest'); | ||||
| const joi = require('joi'); | ||||
| const store = require('./../../../test/fixtures/store'); | ||||
| const getLogger = require('../../../test/fixtures/no-logger'); | ||||
| const getApp = require('../../app'); | ||||
| @ -132,7 +131,7 @@ test('shema allow empty strings', t => { | ||||
|             stop: '2019-05-06T09:30:50.515Z', | ||||
|         }, | ||||
|     }; | ||||
|     const { error, value } = joi.validate(data, clientMetricsSchema); | ||||
|     const { error, value } = clientMetricsSchema.validate(data); | ||||
|     t.falsy(error); | ||||
|     t.is(value.bucket.toggles.Demo2.yes, 0); | ||||
|     t.is(value.bucket.toggles.Demo2.no, 0); | ||||
| @ -148,7 +147,7 @@ test('shema allow yes=<string nbr>', t => { | ||||
|             stop: '2019-05-06T09:30:50.515Z', | ||||
|         }, | ||||
|     }; | ||||
|     const { error, value } = joi.validate(data, clientMetricsSchema); | ||||
|     const { error, value } = clientMetricsSchema.validate(data); | ||||
|     t.falsy(error); | ||||
|     t.is(value.bucket.toggles.Demo2.yes, 12); | ||||
|     t.is(value.bucket.toggles.Demo2.no, 256); | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| const joi = require('joi'); | ||||
| const joi = require('@hapi/joi'); | ||||
| 
 | ||||
| const clientRegisterSchema = joi | ||||
|     .object() | ||||
|  | ||||
| @ -1,7 +1,5 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| const joi = require('joi'); | ||||
| 
 | ||||
| const Controller = require('../controller'); | ||||
| const { clientRegisterSchema: schema } = require('./register-schema'); | ||||
| 
 | ||||
| @ -17,19 +15,19 @@ class RegisterController extends Controller { | ||||
| 
 | ||||
|     async handleRegister(req, res) { | ||||
|         const data = req.body; | ||||
|         const { value: clientRegistration, error } = joi.validate(data, schema); | ||||
|         const { value, error } = schema.validate(data); | ||||
| 
 | ||||
|         if (error) { | ||||
|             this.logger.warn('Invalid client data posted', error); | ||||
|             return res.status(400).json(error); | ||||
|         } | ||||
| 
 | ||||
|         clientRegistration.clientIp = req.ip; | ||||
|         value.clientIp = req.ip; | ||||
| 
 | ||||
|         try { | ||||
|             await this.clientApplicationsStore.upsert(clientRegistration); | ||||
|             await this.clientInstanceStore.insert(clientRegistration); | ||||
|             const { appName, instanceId } = clientRegistration; | ||||
|             await this.clientApplicationsStore.upsert(value); | ||||
|             await this.clientInstanceStore.insert(value); | ||||
|             const { appName, instanceId } = value; | ||||
|             this.logger.info( | ||||
|                 `New client registration: appName=${appName}, instanceId=${instanceId}` | ||||
|             ); | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| const joi = require('joi'); | ||||
| const joi = require('@hapi/joi'); | ||||
| const fs = require('fs'); | ||||
| const mime = require('mime'); | ||||
| const { featureShema } = require('./routes/admin-api/feature-schema'); | ||||
| @ -52,7 +52,7 @@ class StateService { | ||||
|     async import({ data, userName, dropBeforeImport }) { | ||||
|         const { eventStore } = this.config.stores; | ||||
| 
 | ||||
|         const importData = await joi.validate(data, dataSchema); | ||||
|         const importData = await dataSchema.validateAsync(data); | ||||
| 
 | ||||
|         if (importData.features) { | ||||
|             this.logger.info( | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| const gravatar = require('gravatar'); | ||||
| const Joi = require('joi'); | ||||
| const Joi = require('@hapi/joi'); | ||||
| 
 | ||||
| module.exports = class User { | ||||
|     constructor({ name, email, permissions, imageUrl } = {}) { | ||||
|  | ||||
| @ -72,7 +72,7 @@ | ||||
|     "errorhandler": "^1.5.1", | ||||
|     "express": "^4.17.1", | ||||
|     "gravatar": "^1.8.0", | ||||
|     "joi": "^14.3.1", | ||||
|     "@hapi/joi": "^16.1.8", | ||||
|     "js-yaml": "^3.12.2", | ||||
|     "knex": "^0.20.0", | ||||
|     "log4js": "^6.0.0", | ||||
|  | ||||
							
								
								
									
										70
									
								
								yarn.lock
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								yarn.lock
									
									
									
									
									
								
							| @ -439,6 +439,44 @@ | ||||
|   dependencies: | ||||
|     arrify "^1.0.1" | ||||
| 
 | ||||
| "@hapi/address@^2.1.2": | ||||
|   version "2.1.4" | ||||
|   resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" | ||||
|   integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ== | ||||
| 
 | ||||
| "@hapi/formula@^1.2.0": | ||||
|   version "1.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/@hapi/formula/-/formula-1.2.0.tgz#994649c7fea1a90b91a0a1e6d983523f680e10cd" | ||||
|   integrity sha512-UFbtbGPjstz0eWHb+ga/GM3Z9EzqKXFWIbSOFURU0A/Gku0Bky4bCk9/h//K2Xr3IrCfjFNhMm4jyZ5dbCewGA== | ||||
| 
 | ||||
| "@hapi/hoek@^8.2.4", "@hapi/hoek@^8.3.0": | ||||
|   version "8.5.0" | ||||
|   resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.0.tgz#2f9ce301c8898e1c3248b0a8564696b24d1a9a5a" | ||||
|   integrity sha512-7XYT10CZfPsH7j9F1Jmg1+d0ezOux2oM2GfArAzLwWe4mE2Dr3hVjsAL6+TFY49RRJlCdJDMw3nJsLFroTc8Kw== | ||||
| 
 | ||||
| "@hapi/joi@^16.1.8": | ||||
|   version "16.1.8" | ||||
|   resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-16.1.8.tgz#84c1f126269489871ad4e2decc786e0adef06839" | ||||
|   integrity sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg== | ||||
|   dependencies: | ||||
|     "@hapi/address" "^2.1.2" | ||||
|     "@hapi/formula" "^1.2.0" | ||||
|     "@hapi/hoek" "^8.2.4" | ||||
|     "@hapi/pinpoint" "^1.0.2" | ||||
|     "@hapi/topo" "^3.1.3" | ||||
| 
 | ||||
| "@hapi/pinpoint@^1.0.2": | ||||
|   version "1.0.2" | ||||
|   resolved "https://registry.yarnpkg.com/@hapi/pinpoint/-/pinpoint-1.0.2.tgz#025b7a36dbbf4d35bf1acd071c26b20ef41e0d13" | ||||
|   integrity sha512-dtXC/WkZBfC5vxscazuiJ6iq4j9oNx1SHknmIr8hofarpKUZKmlUVYVIhNVzIEgK5Wrc4GMHL5lZtt1uS2flmQ== | ||||
| 
 | ||||
| "@hapi/topo@^3.1.3": | ||||
|   version "3.1.6" | ||||
|   resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29" | ||||
|   integrity sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ== | ||||
|   dependencies: | ||||
|     "@hapi/hoek" "^8.3.0" | ||||
| 
 | ||||
| "@istanbuljs/load-nyc-config@^1.0.0": | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz#10602de5570baea82f8afbfa2630b24e7a8cfe5b" | ||||
| @ -2801,10 +2839,6 @@ hasha@^5.0.0: | ||||
|     is-stream "^1.1.0" | ||||
|     type-fest "^0.3.0" | ||||
| 
 | ||||
| hoek@6.x.x: | ||||
|   version "6.1.2" | ||||
|   resolved "https://registry.yarnpkg.com/hoek/-/hoek-6.1.2.tgz#99e6d070561839de74ee427b61aa476bd6bddfd6" | ||||
| 
 | ||||
| homedir-polyfill@^1.0.1: | ||||
|   version "1.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" | ||||
| @ -3253,12 +3287,6 @@ isarray@1.0.0, isarray@~1.0.0: | ||||
|   version "1.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" | ||||
| 
 | ||||
| isemail@3.x.x: | ||||
|   version "3.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/isemail/-/isemail-3.2.0.tgz#59310a021931a9fb06bbb51e155ce0b3f236832c" | ||||
|   dependencies: | ||||
|     punycode "2.x.x" | ||||
| 
 | ||||
| isexe@^2.0.0: | ||||
|   version "2.0.0" | ||||
|   resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" | ||||
| @ -3350,14 +3378,6 @@ jest-docblock@^21.0.0: | ||||
|   version "21.2.0" | ||||
|   resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" | ||||
| 
 | ||||
| joi@^14.3.1: | ||||
|   version "14.3.1" | ||||
|   resolved "https://registry.yarnpkg.com/joi/-/joi-14.3.1.tgz#164a262ec0b855466e0c35eea2a885ae8b6c703c" | ||||
|   dependencies: | ||||
|     hoek "6.x.x" | ||||
|     isemail "3.x.x" | ||||
|     topo "3.x.x" | ||||
| 
 | ||||
| js-string-escape@^1.0.1: | ||||
|   version "1.0.1" | ||||
|   resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" | ||||
| @ -4853,15 +4873,15 @@ pump@^3.0.0: | ||||
|     end-of-stream "^1.1.0" | ||||
|     once "^1.3.1" | ||||
| 
 | ||||
| punycode@2.x.x, punycode@^2.1.0: | ||||
|   version "2.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" | ||||
| 
 | ||||
| punycode@^1.4.1: | ||||
|   version "1.4.1" | ||||
|   resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" | ||||
|   integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= | ||||
| 
 | ||||
| punycode@^2.1.0: | ||||
|   version "2.1.1" | ||||
|   resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" | ||||
| 
 | ||||
| qs@6.7.0: | ||||
|   version "6.7.0" | ||||
|   resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" | ||||
| @ -5879,12 +5899,6 @@ toidentifier@1.0.0: | ||||
|   resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" | ||||
|   integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== | ||||
| 
 | ||||
| topo@3.x.x: | ||||
|   version "3.0.3" | ||||
|   resolved "https://registry.yarnpkg.com/topo/-/topo-3.0.3.tgz#d5a67fb2e69307ebeeb08402ec2a2a6f5f7ad95c" | ||||
|   dependencies: | ||||
|     hoek "6.x.x" | ||||
| 
 | ||||
| tough-cookie@~2.4.3: | ||||
|   version "2.4.3" | ||||
|   resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user