diff --git a/api/v0/index.js b/api/v0/index.js index 3f1b025..5358a0f 100644 --- a/api/v0/index.js +++ b/api/v0/index.js @@ -34,357 +34,357 @@ import { generateWKDProfile, generateHKPProfile } from '../../server/index.js' import 'dotenv/config.js' const router = express.Router() -const ajv = new Ajv({coerceTypes: true}) +const ajv = new Ajv({ coerceTypes: true }) const apiProfileSchema = { - type: "object", - properties: { - keyData: { - type: "object", + type: 'object', + properties: { + keyData: { + type: 'object', + properties: { + fingerprint: { + type: 'string' + }, + openpgp4fpr: { + type: 'string' + }, + users: { + type: 'array', + items: { + type: 'object', properties: { - fingerprint: { - type: "string" - }, - openpgp4fpr: { - type: "string" - }, - users: { - type: "array", - items: { - type: "object", + userData: { + type: 'object', + properties: { + id: { type: 'string' }, + name: { type: 'string' }, + email: { type: 'string' }, + comment: { type: 'string' }, + isPrimary: { type: 'boolean' }, + isRevoked: { type: 'boolean' } + } + }, + claims: { + type: 'array', + items: { + type: 'object', + properties: { + claimVersion: { type: 'integer' }, + uri: { type: 'string' }, + fingerprint: { type: 'string' }, + status: { type: 'string' }, + matches: { + type: 'array', + items: { + type: 'object', properties: { - userData: { - type: "object", + serviceProvider: { + type: 'object', + properties: { + type: { type: 'string' }, + name: { type: 'string' } + } + }, + match: { + type: 'object', + properties: { + regularExpression: { type: 'object' }, + isAmbiguous: { type: 'boolean' } + } + }, + profile: { + type: 'object', + properties: { + display: { type: 'string' }, + uri: { type: 'string' }, + qr: { type: 'string' } + } + }, + proof: { + type: 'object', + properties: { + uri: { type: 'string' }, + request: { + type: 'object', properties: { - id: { type: "string" }, - name: { type: "string" }, - email: { type: "string" }, - comment: { type: "string" }, - isPrimary: { type: "boolean" }, - isRevoked: { type: "boolean" }, + fetcher: { type: 'string' }, + access: { type: 'string' }, + format: { type: 'string' }, + data: { type: 'object' } } - }, - claims: { - type: "array", + } + } + }, + claim: { + type: 'object', + properties: { + format: { type: 'string' }, + relation: { type: 'string' }, + path: { + type: 'array', items: { - type: "object", - properties: { - claimVersion: { type: "integer" }, - uri: { type: "string" }, - fingerprint: { type: "string" }, - status: { type: "string" }, - matches: { - type: "array", - items: { - type: "object", - properties: { - serviceProvider: { - type: "object", - properties: { - type: { type: "string" }, - name: { type: "string" }, - } - }, - match: { - type: "object", - properties: { - regularExpression: { type: "object" }, - isAmbiguous: { type: "boolean" }, - } - }, - profile: { - type: "object", - properties: { - display: { type: "string" }, - uri: { type: "string" }, - qr: { type: "string" }, - } - }, - proof: { - type: "object", - properties: { - uri: { type: "string" }, - request: { - type: "object", - properties: { - fetcher: { type: "string" }, - access: { type: "string" }, - format: { type: "string" }, - data: { type: "object" }, - } - }, - } - }, - claim: { - type: "object", - properties: { - format: { type: "string" }, - relation: { type: "string" }, - path: { - type: "array", - items: { - type: "string" - } - }, - } - }, - } - } - }, - verification: { - type: "object" - }, - summary: { - type: "object", - properties: { - profileName: { type: "string" }, - profileURL: { type: "string" }, - serviceProviderName: { type: "string" }, - isVerificationDone: { type: "boolean" }, - isVerified: { type: "boolean" }, - } - } - } + type: 'string' } - }, + } + } + } } + } + }, + verification: { + type: 'object' + }, + summary: { + type: 'object', + properties: { + profileName: { type: 'string' }, + profileURL: { type: 'string' }, + serviceProviderName: { type: 'string' }, + isVerificationDone: { type: 'boolean' }, + isVerified: { type: 'boolean' } + } } - }, - primaryUserIndex: { - type: "integer" - }, - key: { - type: "object", - properties: { - data: { type: "object" }, - fetchMethod: { type: "string" }, - uri: { type: "string" }, - } - }, - }, - }, - keyoxide: { - type: "object", - properties: { - url: { type: "string" }, + } + } + } } + } }, - extra: { - type: "object", - properties: { - avatarURL: { type: "string" }, - } - }, - errors: { - type: "array" + primaryUserIndex: { + type: 'integer' }, + key: { + type: 'object', + properties: { + data: { type: 'object' }, + fetchMethod: { type: 'string' }, + uri: { type: 'string' } + } + } + } }, - required: ["keyData", "keyoxide", "extra", "errors"], - additionalProperties: false + keyoxide: { + type: 'object', + properties: { + url: { type: 'string' } + } + }, + extra: { + type: 'object', + properties: { + avatarURL: { type: 'string' } + } + }, + errors: { + type: 'array' + } + }, + required: ['keyData', 'keyoxide', 'extra', 'errors'], + additionalProperties: false } const apiProfileValidate = ajv.compile(apiProfileSchema) const doVerification = async (data) => { - let promises = [] - let results = [] - let verificationOptions = { - proxy: { - hostname: process.env.PROXY_HOSTNAME, - policy: (process.env.PROXY_HOSTNAME != "") ? 'adaptive' : 'never' - } + const promises = [] + const results = [] + const verificationOptions = { + proxy: { + hostname: process.env.PROXY_HOSTNAME, + policy: (process.env.PROXY_HOSTNAME !== '') ? 'adaptive' : 'never' } + } - for (let iUser = 0; iUser < data.keyData.users.length; iUser++) { - const user = data.keyData.users[iUser] - - for (let iClaim = 0; iClaim < user.claims.length; iClaim++) { - const claim = user.claims[iClaim] - - promises.push( - new Promise(async (resolve, reject) => { - await claim.verify(verificationOptions) - results.push([iUser, iClaim, claim]) - resolve() - }) - ) - } + for (let iUser = 0; iUser < data.keyData.users.length; iUser++) { + const user = data.keyData.users[iUser] + + for (let iClaim = 0; iClaim < user.claims.length; iClaim++) { + const claim = user.claims[iClaim] + + promises.push( + new Promise((resolve, reject) => { + (async () => { + await claim.verify(verificationOptions) + results.push([iUser, iClaim, claim]) + resolve() + })() + }) + ) } - await Promise.all(promises) - - results.forEach(result => { - data.keyData.users[result[0]].claims[result[1]] = result[2] - }) + } + await Promise.all(promises) - return data + results.forEach(result => { + data.keyData.users[result[0]].claims[result[1]] = result[2] + }) + + return data } const sanitize = (data) => { - let results = [] - - const dataClone = JSON.parse(JSON.stringify(data)) - - for (let iUser = 0; iUser < dataClone.keyData.users.length; iUser++) { - const user = dataClone.keyData.users[iUser] - - for (let iClaim = 0; iClaim < user.claims.length; iClaim++) { - const claim = user.claims[iClaim] - - // TODO Fix upstream - for (let iMatch = 0; iMatch < claim.matches.length; iMatch++) { - const match = claim.matches[iMatch]; - if (Array.isArray(match.claim)) { - match.claim = match.claim[0] - } - } - // TODO Fix upstream - if (!claim.verification) { - claim.verification = {} - } - // TODO Fix upstream - claim.matches.forEach(match => { - match.proof.request.access = ['generic', 'nocors', 'granted', 'server'][match.proof.request.access] - match.claim.format = ['uri', 'fingerprint', 'message'][match.claim.format] - match.claim.relation = ['contains', 'equals', 'oneof'][match.claim.relation] - }) + const dataClone = JSON.parse(JSON.stringify(data)) - data.keyData.users[iUser].claims[iClaim] = claim + for (let iUser = 0; iUser < dataClone.keyData.users.length; iUser++) { + const user = dataClone.keyData.users[iUser] + + for (let iClaim = 0; iClaim < user.claims.length; iClaim++) { + const claim = user.claims[iClaim] + + // TODO Fix upstream + for (let iMatch = 0; iMatch < claim.matches.length; iMatch++) { + const match = claim.matches[iMatch] + if (Array.isArray(match.claim)) { + match.claim = match.claim[0] } - } + } + // TODO Fix upstream + if (!claim.verification) { + claim.verification = {} + } + // TODO Fix upstream + claim.matches.forEach(match => { + match.proof.request.access = ['generic', 'nocors', 'granted', 'server'][match.proof.request.access] + match.claim.format = ['uri', 'fingerprint', 'message'][match.claim.format] + match.claim.relation = ['contains', 'equals', 'oneof'][match.claim.relation] + }) - const valid = apiProfileValidate(data) - if (!valid) { - throw new Error(`Profile data sanitization error`) + data.keyData.users[iUser].claims[iClaim] = claim } + } - return data + const valid = apiProfileValidate(data) + if (!valid) { + throw new Error('Profile data sanitization error') + } + + return data } const addSummaryToClaims = (data) => { - // To be removed when data is added by DOIP library - for (let userIndex = 0; userIndex < data.keyData.users.length; userIndex++) { - const user = data.keyData.users[userIndex] - - for (let claimIndex = 0; claimIndex < user.claims.length; claimIndex++) { - const claim = user.claims[claimIndex] + // To be removed when data is added by DOIP library + for (let userIndex = 0; userIndex < data.keyData.users.length; userIndex++) { + const user = data.keyData.users[userIndex] - const isVerificationDone = claim.status === "verified" - const isVerified = isVerificationDone ? claim.verification.result : false - const isAmbiguous = isVerified - ? false - : claim.matches.length > 1 || claim.matches[0].match.isAmbiguous - - data.keyData.users[userIndex].claims[claimIndex].summary = { - profileName: !isAmbiguous ? claim.matches[0].profile.display : claim.uri, - profileURL: !isAmbiguous ? claim.matches[0].profile.uri : "", - serviceProviderName: !isAmbiguous ? claim.matches[0].serviceprovider.name : "", - isVerificationDone: isVerificationDone, - isVerified: isVerified, - } - } + for (let claimIndex = 0; claimIndex < user.claims.length; claimIndex++) { + const claim = user.claims[claimIndex] + + const isVerificationDone = claim.status === 'verified' + const isVerified = isVerificationDone ? claim.verification.result : false + const isAmbiguous = isVerified + ? false + : claim.matches.length > 1 || claim.matches[0].match.isAmbiguous + + data.keyData.users[userIndex].claims[claimIndex].summary = { + profileName: !isAmbiguous ? claim.matches[0].profile.display : claim.uri, + profileURL: !isAmbiguous ? claim.matches[0].profile.uri : '', + serviceProviderName: !isAmbiguous ? claim.matches[0].serviceprovider.name : '', + isVerificationDone, + isVerified + } } + } - return data + return data } router.get('/profile/fetch', - check('query').exists(), - check('protocol').optional().toLowerCase().isIn(["hkp", "wkd"]), - check('doVerification').default(false).isBoolean().toBoolean(), - check('returnPublicKey').default(false).isBoolean().toBoolean(), - async (req, res) => { - const valRes = validationResult(req); - if (!valRes.isEmpty()) { - res.status(400).send(valRes) - return - } - - // Generate profile - let data - switch (req.query.protocol) { - case 'wkd': - data = await generateWKDProfile(req.query.query) - break; - case 'hkp': - data = await generateHKPProfile(req.query.query) - break; - default: - if (req.query.query.includes('@')) { - data = await generateWKDProfile(req.query.query) - } else { - data = await generateHKPProfile(req.query.query) - } - break; - } - - if (data.errors.length > 0) { - delete data.key - res.status(500).send(data) - } - - // Return public key - if (req.query.returnPublicKey) { - data.keyData.key.data = data.key.publicKey - } - delete data.key - - // Do verification - if (req.query.doVerification) { - data = await doVerification(data) - } - - try { - // Sanitize JSON - data = sanitize(data) - } catch (error) { - data.keyData = {} - data.extra = {} - data.errors = [error.message] - } - - // Add missing data - data = addSummaryToClaims(data) - - let statusCode = 200 - if (data.errors.length > 0) { - statusCode = 500 - } - - res.status(statusCode).send(data) + check('query').exists(), + check('protocol').optional().toLowerCase().isIn(['hkp', 'wkd']), + check('doVerification').default(false).isBoolean().toBoolean(), + check('returnPublicKey').default(false).isBoolean().toBoolean(), + async (req, res) => { + const valRes = validationResult(req) + if (!valRes.isEmpty()) { + res.status(400).send(valRes) + return } + + // Generate profile + let data + switch (req.query.protocol) { + case 'wkd': + data = await generateWKDProfile(req.query.query) + break + case 'hkp': + data = await generateHKPProfile(req.query.query) + break + default: + if (req.query.query.includes('@')) { + data = await generateWKDProfile(req.query.query) + } else { + data = await generateHKPProfile(req.query.query) + } + break + } + + if (data.errors.length > 0) { + delete data.key + res.status(500).send(data) + } + + // Return public key + if (req.query.returnPublicKey) { + data.keyData.key.data = data.key.publicKey + } + delete data.key + + // Do verification + if (req.query.doVerification) { + data = await doVerification(data) + } + + try { + // Sanitize JSON + data = sanitize(data) + } catch (error) { + data.keyData = {} + data.extra = {} + data.errors = [error.message] + } + + // Add missing data + data = addSummaryToClaims(data) + + let statusCode = 200 + if (data.errors.length > 0) { + statusCode = 500 + } + + res.status(statusCode).send(data) + } ) router.get('/profile/verify', - check('data').exists().isJSON(), - async (req, res) => { - const valRes = validationResult(req) - if (!valRes.isEmpty()) { - res.status(400).send(valRes) - return - } - - // Do verification - data = await doVerification(req.query.data) - - try { - // Sanitize JSON - data = sanitize(data); - } catch (error) { - data.keyData = {} - data.extra = {} - data.errors = [error.message] - } - - // Add missing data - data = addSummaryToClaims(data) - - let statusCode = 200 - if (data.errors.length > 0) { - statusCode = 500 - } - - res.status(statusCode).send(data) + check('data').exists().isJSON(), + async (req, res) => { + const valRes = validationResult(req) + if (!valRes.isEmpty()) { + res.status(400).send(valRes) + return } + + // Do verification + let data = await doVerification(req.query.data) + + try { + // Sanitize JSON + data = sanitize(data) + } catch (error) { + data.keyData = {} + data.extra = {} + data.errors = [error.message] + } + + // Add missing data + data = addSummaryToClaims(data) + + let statusCode = 200 + if (data.errors.length > 0) { + statusCode = 500 + } + + res.status(statusCode).send(data) + } ) export default router diff --git a/api/v2/keyoxide_profile.js b/api/v2/keyoxide_profile.js index 1cd3454..63a2e6a 100644 --- a/api/v2/keyoxide_profile.js +++ b/api/v2/keyoxide_profile.js @@ -34,357 +34,357 @@ import { generateWKDProfile, generateHKPProfile } from '../../server/index.js' import 'dotenv/config.js' const router = express.Router() -const ajv = new Ajv({coerceTypes: true}) +const ajv = new Ajv({ coerceTypes: true }) const apiProfileSchema = { - type: "object", - properties: { - keyData: { - type: "object", + type: 'object', + properties: { + keyData: { + type: 'object', + properties: { + fingerprint: { + type: 'string' + }, + openpgp4fpr: { + type: 'string' + }, + users: { + type: 'array', + items: { + type: 'object', properties: { - fingerprint: { - type: "string" - }, - openpgp4fpr: { - type: "string" - }, - users: { - type: "array", - items: { - type: "object", + userData: { + type: 'object', + properties: { + id: { type: 'string' }, + name: { type: 'string' }, + email: { type: 'string' }, + comment: { type: 'string' }, + isPrimary: { type: 'boolean' }, + isRevoked: { type: 'boolean' } + } + }, + claims: { + type: 'array', + items: { + type: 'object', + properties: { + claimVersion: { type: 'integer' }, + uri: { type: 'string' }, + fingerprint: { type: 'string' }, + status: { type: 'string' }, + matches: { + type: 'array', + items: { + type: 'object', properties: { - userData: { - type: "object", + serviceProvider: { + type: 'object', + properties: { + type: { type: 'string' }, + name: { type: 'string' } + } + }, + match: { + type: 'object', + properties: { + regularExpression: { type: 'object' }, + isAmbiguous: { type: 'boolean' } + } + }, + profile: { + type: 'object', + properties: { + display: { type: 'string' }, + uri: { type: 'string' }, + qr: { type: 'string' } + } + }, + proof: { + type: 'object', + properties: { + uri: { type: 'string' }, + request: { + type: 'object', properties: { - id: { type: "string" }, - name: { type: "string" }, - email: { type: "string" }, - comment: { type: "string" }, - isPrimary: { type: "boolean" }, - isRevoked: { type: "boolean" }, + fetcher: { type: 'string' }, + access: { type: 'string' }, + format: { type: 'string' }, + data: { type: 'object' } } - }, - claims: { - type: "array", + } + } + }, + claim: { + type: 'object', + properties: { + format: { type: 'string' }, + relation: { type: 'string' }, + path: { + type: 'array', items: { - type: "object", - properties: { - claimVersion: { type: "integer" }, - uri: { type: "string" }, - fingerprint: { type: "string" }, - status: { type: "string" }, - matches: { - type: "array", - items: { - type: "object", - properties: { - serviceProvider: { - type: "object", - properties: { - type: { type: "string" }, - name: { type: "string" }, - } - }, - match: { - type: "object", - properties: { - regularExpression: { type: "object" }, - isAmbiguous: { type: "boolean" }, - } - }, - profile: { - type: "object", - properties: { - display: { type: "string" }, - uri: { type: "string" }, - qr: { type: "string" }, - } - }, - proof: { - type: "object", - properties: { - uri: { type: "string" }, - request: { - type: "object", - properties: { - fetcher: { type: "string" }, - access: { type: "string" }, - format: { type: "string" }, - data: { type: "object" }, - } - }, - } - }, - claim: { - type: "object", - properties: { - format: { type: "string" }, - relation: { type: "string" }, - path: { - type: "array", - items: { - type: "string" - } - }, - } - }, - } - } - }, - verification: { - type: "object" - }, - summary: { - type: "object", - properties: { - profileName: { type: "string" }, - profileURL: { type: "string" }, - serviceProviderName: { type: "string" }, - isVerificationDone: { type: "boolean" }, - isVerified: { type: "boolean" }, - } - } - } + type: 'string' } - }, + } + } + } } + } + }, + verification: { + type: 'object' + }, + summary: { + type: 'object', + properties: { + profileName: { type: 'string' }, + profileURL: { type: 'string' }, + serviceProviderName: { type: 'string' }, + isVerificationDone: { type: 'boolean' }, + isVerified: { type: 'boolean' } + } } - }, - primaryUserIndex: { - type: "integer" - }, - key: { - type: "object", - properties: { - data: { type: "object" }, - fetchMethod: { type: "string" }, - uri: { type: "string" }, - } - }, - }, - }, - keyoxide: { - type: "object", - properties: { - url: { type: "string" }, + } + } + } } + } }, - extra: { - type: "object", - properties: { - avatarURL: { type: "string" }, - } - }, - errors: { - type: "array" + primaryUserIndex: { + type: 'integer' }, + key: { + type: 'object', + properties: { + data: { type: 'object' }, + fetchMethod: { type: 'string' }, + uri: { type: 'string' } + } + } + } }, - required: ["keyData", "keyoxide", "extra", "errors"], - additionalProperties: false + keyoxide: { + type: 'object', + properties: { + url: { type: 'string' } + } + }, + extra: { + type: 'object', + properties: { + avatarURL: { type: 'string' } + } + }, + errors: { + type: 'array' + } + }, + required: ['keyData', 'keyoxide', 'extra', 'errors'], + additionalProperties: false } const apiProfileValidate = ajv.compile(apiProfileSchema) const doVerification = async (data) => { - let promises = [] - let results = [] - let verificationOptions = { - proxy: { - hostname: process.env.PROXY_HOSTNAME, - policy: (process.env.PROXY_HOSTNAME != "") ? 'adaptive' : 'never' - } + const promises = [] + const results = [] + const verificationOptions = { + proxy: { + hostname: process.env.PROXY_HOSTNAME, + policy: (process.env.PROXY_HOSTNAME !== '') ? 'adaptive' : 'never' } + } - for (let iUser = 0; iUser < data.keyData.users.length; iUser++) { - const user = data.keyData.users[iUser] - - for (let iClaim = 0; iClaim < user.claims.length; iClaim++) { - const claim = user.claims[iClaim] - - promises.push( - new Promise(async (resolve, reject) => { - await claim.verify(verificationOptions) - results.push([iUser, iClaim, claim]) - resolve() - }) - ) - } + for (let iUser = 0; iUser < data.keyData.users.length; iUser++) { + const user = data.keyData.users[iUser] + + for (let iClaim = 0; iClaim < user.claims.length; iClaim++) { + const claim = user.claims[iClaim] + + promises.push( + new Promise((resolve, reject) => { + (async () => { + await claim.verify(verificationOptions) + results.push([iUser, iClaim, claim]) + resolve() + })() + }) + ) } - await Promise.all(promises) - - results.forEach(result => { - data.keyData.users[result[0]].claims[result[1]] = result[2] - }) + } + await Promise.all(promises) - return data + results.forEach(result => { + data.keyData.users[result[0]].claims[result[1]] = result[2] + }) + + return data } const sanitize = (data) => { - let results = [] - - const dataClone = JSON.parse(JSON.stringify(data)) - - for (let iUser = 0; iUser < dataClone.keyData.users.length; iUser++) { - const user = dataClone.keyData.users[iUser] - - for (let iClaim = 0; iClaim < user.claims.length; iClaim++) { - const claim = user.claims[iClaim] - - // TODO Fix upstream - for (let iMatch = 0; iMatch < claim.matches.length; iMatch++) { - const match = claim.matches[iMatch]; - if (Array.isArray(match.claim)) { - match.claim = match.claim[0] - } - } - // TODO Fix upstream - if (!claim.verification) { - claim.verification = {} - } - // TODO Fix upstream - claim.matches.forEach(match => { - match.proof.request.access = ['generic', 'nocors', 'granted', 'server'][match.proof.request.access] - match.claim.format = ['uri', 'fingerprint', 'message'][match.claim.format] - match.claim.relation = ['contains', 'equals', 'oneof'][match.claim.relation] - }) + const dataClone = JSON.parse(JSON.stringify(data)) - data.keyData.users[iUser].claims[iClaim] = claim + for (let iUser = 0; iUser < dataClone.keyData.users.length; iUser++) { + const user = dataClone.keyData.users[iUser] + + for (let iClaim = 0; iClaim < user.claims.length; iClaim++) { + const claim = user.claims[iClaim] + + // TODO Fix upstream + for (let iMatch = 0; iMatch < claim.matches.length; iMatch++) { + const match = claim.matches[iMatch] + if (Array.isArray(match.claim)) { + match.claim = match.claim[0] } - } + } + // TODO Fix upstream + if (!claim.verification) { + claim.verification = {} + } + // TODO Fix upstream + claim.matches.forEach(match => { + match.proof.request.access = ['generic', 'nocors', 'granted', 'server'][match.proof.request.access] + match.claim.format = ['uri', 'fingerprint', 'message'][match.claim.format] + match.claim.relation = ['contains', 'equals', 'oneof'][match.claim.relation] + }) - const valid = apiProfileValidate(data) - if (!valid) { - throw new Error(`Profile data sanitization error`) + data.keyData.users[iUser].claims[iClaim] = claim } + } - return data + const valid = apiProfileValidate(data) + if (!valid) { + throw new Error('Profile data sanitization error') + } + + return data } const addSummaryToClaims = (data) => { - // To be removed when data is added by DOIP library - for (let userIndex = 0; userIndex < data.keyData.users.length; userIndex++) { - const user = data.keyData.users[userIndex] - - for (let claimIndex = 0; claimIndex < user.claims.length; claimIndex++) { - const claim = user.claims[claimIndex] + // To be removed when data is added by DOIP library + for (let userIndex = 0; userIndex < data.keyData.users.length; userIndex++) { + const user = data.keyData.users[userIndex] - const isVerificationDone = claim.status === "verified" - const isVerified = isVerificationDone ? claim.verification.result : false - const isAmbiguous = isVerified - ? false - : claim.matches.length > 1 || claim.matches[0].match.isAmbiguous - - data.keyData.users[userIndex].claims[claimIndex].summary = { - profileName: !isAmbiguous ? claim.matches[0].profile.display : claim.uri, - profileURL: !isAmbiguous ? claim.matches[0].profile.uri : "", - serviceProviderName: !isAmbiguous ? claim.matches[0].serviceprovider.name : "", - isVerificationDone: isVerificationDone, - isVerified: isVerified, - } - } + for (let claimIndex = 0; claimIndex < user.claims.length; claimIndex++) { + const claim = user.claims[claimIndex] + + const isVerificationDone = claim.status === 'verified' + const isVerified = isVerificationDone ? claim.verification.result : false + const isAmbiguous = isVerified + ? false + : claim.matches.length > 1 || claim.matches[0].match.isAmbiguous + + data.keyData.users[userIndex].claims[claimIndex].summary = { + profileName: !isAmbiguous ? claim.matches[0].profile.display : claim.uri, + profileURL: !isAmbiguous ? claim.matches[0].profile.uri : '', + serviceProviderName: !isAmbiguous ? claim.matches[0].serviceprovider.name : '', + isVerificationDone, + isVerified + } } + } - return data + return data } router.get('/fetch', - check('query').exists(), - check('protocol').optional().toLowerCase().isIn(["hkp", "wkd"]), - check('doVerification').default(false).isBoolean().toBoolean(), - check('returnPublicKey').default(false).isBoolean().toBoolean(), - async (req, res) => { - const valRes = validationResult(req); - if (!valRes.isEmpty()) { - res.status(400).send(valRes) - return - } - - // Generate profile - let data - switch (req.query.protocol) { - case 'wkd': - data = await generateWKDProfile(req.query.query) - break; - case 'hkp': - data = await generateHKPProfile(req.query.query) - break; - default: - if (req.query.query.includes('@')) { - data = await generateWKDProfile(req.query.query) - } else { - data = await generateHKPProfile(req.query.query) - } - break; - } - - if (data.errors.length > 0) { - delete data.key - res.status(500).send(data) - } - - // Return public key - if (req.query.returnPublicKey) { - data.keyData.key.data = data.key.publicKey - } - delete data.key - - // Do verification - if (req.query.doVerification) { - data = await doVerification(data) - } - - try { - // Sanitize JSON - data = sanitize(data) - } catch (error) { - data.keyData = {} - data.extra = {} - data.errors = [error.message] - } - - // Add missing data - data = addSummaryToClaims(data) - - let statusCode = 200 - if (data.errors.length > 0) { - statusCode = 500 - } - - res.status(statusCode).send(data) + check('query').exists(), + check('protocol').optional().toLowerCase().isIn(['hkp', 'wkd']), + check('doVerification').default(false).isBoolean().toBoolean(), + check('returnPublicKey').default(false).isBoolean().toBoolean(), + async (req, res) => { + const valRes = validationResult(req) + if (!valRes.isEmpty()) { + res.status(400).send(valRes) + return } + + // Generate profile + let data + switch (req.query.protocol) { + case 'wkd': + data = await generateWKDProfile(req.query.query) + break + case 'hkp': + data = await generateHKPProfile(req.query.query) + break + default: + if (req.query.query.includes('@')) { + data = await generateWKDProfile(req.query.query) + } else { + data = await generateHKPProfile(req.query.query) + } + break + } + + if (data.errors.length > 0) { + delete data.key + res.status(500).send(data) + } + + // Return public key + if (req.query.returnPublicKey) { + data.keyData.key.data = data.key.publicKey + } + delete data.key + + // Do verification + if (req.query.doVerification) { + data = await doVerification(data) + } + + try { + // Sanitize JSON + data = sanitize(data) + } catch (error) { + data.keyData = {} + data.extra = {} + data.errors = [error.message] + } + + // Add missing data + data = addSummaryToClaims(data) + + let statusCode = 200 + if (data.errors.length > 0) { + statusCode = 500 + } + + res.status(statusCode).send(data) + } ) router.get('/verify', - check('data').exists().isJSON(), - async (req, res) => { - const valRes = validationResult(req) - if (!valRes.isEmpty()) { - res.status(400).send(valRes) - return - } - - // Do verification - data = await doVerification(req.query.data) - - try { - // Sanitize JSON - data = sanitize(data); - } catch (error) { - data.keyData = {} - data.extra = {} - data.errors = [error.message] - } - - // Add missing data - data = addSummaryToClaims(data) - - let statusCode = 200 - if (data.errors.length > 0) { - statusCode = 500 - } - - res.status(statusCode).send(data) + check('data').exists().isJSON(), + async (req, res) => { + const valRes = validationResult(req) + if (!valRes.isEmpty()) { + res.status(400).send(valRes) + return } + + // Do verification + let data = await doVerification(req.query.data) + + try { + // Sanitize JSON + data = sanitize(data) + } catch (error) { + data.keyData = {} + data.extra = {} + data.errors = [error.message] + } + + // Add missing data + data = addSummaryToClaims(data) + + let statusCode = 200 + if (data.errors.length > 0) { + statusCode = 500 + } + + res.status(statusCode).send(data) + } ) export default router diff --git a/package.json b/package.json index 5b99fbf..e2118a8 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "mini-css-extract-plugin": "^2.5.3", "mocha": "^9.2.1", "nodemon": "^2.0.19", + "standard": "^17.0.0", "style-loader": "^3.3.1", "webpack": "^5.69.1", "webpack-bundle-analyzer": "^4.5.0", @@ -42,12 +43,14 @@ "scripts": { "start": "node --experimental-fetch ./", "dev": "yarn run watch & yarn run build:static:dev", - "test": "mocha", + "test": "yarn run standard:check && mocha", "watch": "./node_modules/.bin/nodemon --config nodemon.json ./", "build": "yarn run build:server & yarn run build:static", "build:server": "ncc build ./src/index.js -e jsdom -o dist", "build:static": "webpack --config webpack.config.js --env static=true --env mode=production", "build:static:dev": "webpack --config webpack.config.js --env static=true --env mode=development", + "standard:check": "./node_modules/.bin/standard ./src ./api ./routes ./server", + "standard:fix": "./node_modules/.bin/standard --fix ./src ./api ./routes ./server", "license:check": "./node_modules/.bin/license-check-and-add check", "license:add": "./node_modules/.bin/license-check-and-add add", "license:remove": "./node_modules/.bin/license-check-and-add remove" diff --git a/routes/main.js b/routes/main.js index e2d2379..ed1aa49 100644 --- a/routes/main.js +++ b/routes/main.js @@ -33,70 +33,70 @@ import { readFileSync } from 'fs' import demoData from '../server/demo.js' const router = express.Router() -const md = markdownImport({typographer: true}) +const md = markdownImport({ typographer: true }) router.get('/', (req, res) => { - let highlights = [] - for (let index = 1; index < 4; index++) { - if (process.env[`KX_HIGHLIGHTS_${index}_NAME`] - && process.env[`KX_HIGHLIGHTS_${index}_FINGERPRINT`]) { - highlights.push({ - name: process.env[`KX_HIGHLIGHTS_${index}_NAME`], - description: process.env[`KX_HIGHLIGHTS_${index}_DESCRIPTION`], - fingerprint: process.env[`KX_HIGHLIGHTS_${index}_FINGERPRINT`], - }) - } + const highlights = [] + for (let index = 1; index < 4; index++) { + if (process.env[`KX_HIGHLIGHTS_${index}_NAME`] && + process.env[`KX_HIGHLIGHTS_${index}_FINGERPRINT`]) { + highlights.push({ + name: process.env[`KX_HIGHLIGHTS_${index}_NAME`], + description: process.env[`KX_HIGHLIGHTS_${index}_DESCRIPTION`], + fingerprint: process.env[`KX_HIGHLIGHTS_${index}_FINGERPRINT`] + }) } + } - res.render('index', { highlights: highlights, demoData: demoData }) + res.render('index', { highlights, demoData }) }) router.get('/privacy', (req, res) => { - let rawContent = readFileSync(`./content/privacy-policy.md`, "utf8") - const content = md.render(rawContent) - res.render(`article`, { title: `Privacy policy`, content: content }) + const rawContent = readFileSync('./content/privacy-policy.md', 'utf8') + const content = md.render(rawContent) + res.render('article', { title: 'Privacy policy', content }) }) router.get('/.well-known/webfinger', (req, res) => { - if (!(process.env.DOMAIN && process.env.ACTIVITYPUB_PUBLIC_KEY)) { - res.status(404).send('
Cannot GET /.well-known/webfinger
') - return - } - - const body = { - 'subject': `acct:keyoxide@${process.env.DOMAIN}`, - 'aliases': [`https://${process.env.DOMAIN}/users/keyoxide`], - 'links': [{ - 'rel': 'self', - 'type': 'application/activity+json', - 'href': `https://${process.env.DOMAIN}/users/keyoxide` - }] - } - res.json(body) + if (!(process.env.DOMAIN && process.env.ACTIVITYPUB_PUBLIC_KEY)) { + res.status(404).send('
Cannot GET /.well-known/webfinger
') + return + } + + const body = { + subject: `acct:keyoxide@${process.env.DOMAIN}`, + aliases: [`https://${process.env.DOMAIN}/users/keyoxide`], + links: [{ + rel: 'self', + type: 'application/activity+json', + href: `https://${process.env.DOMAIN}/users/keyoxide` + }] + } + res.json(body) }) router.get('/users/keyoxide', (req, res) => { - if (!(process.env.DOMAIN && process.env.ACTIVITYPUB_PUBLIC_KEY)) { - res.status(404).send('
Cannot GET /keyoxide
') - return + if (!(process.env.DOMAIN && process.env.ACTIVITYPUB_PUBLIC_KEY)) { + res.status(404).send('
Cannot GET /keyoxide
') + return + } + + const body = { + '@context': [ + 'https://www.w3.org/ns/activitystreams', + 'https://w3id.org/security/v1' + ], + id: `https://${process.env.DOMAIN}/users/keyoxide`, + type: 'Application', + inbox: `https://${process.env.DOMAIN}/users/keyoxide/inbox`, + preferredUsername: `${process.env.DOMAIN}`, + publicKey: { + id: `https://${process.env.DOMAIN}/users/keyoxide#main-key`, + owner: `https://${process.env.DOMAIN}/users/keyoxide`, + publicKeyPem: `${process.env.ACTIVITYPUB_PUBLIC_KEY}` } - - const body = { - '@context': [ - 'https://www.w3.org/ns/activitystreams', - 'https://w3id.org/security/v1' - ], - 'id': `https://${process.env.DOMAIN}/users/keyoxide`, - 'type': 'Application', - 'inbox': `https://${process.env.DOMAIN}/users/keyoxide/inbox`, - 'preferredUsername': `${process.env.DOMAIN}`, - 'publicKey': { - 'id': `https://${process.env.DOMAIN}/users/keyoxide#main-key`, - 'owner': `https://${process.env.DOMAIN}/users/keyoxide`, - 'publicKeyPem': `${process.env.ACTIVITYPUB_PUBLIC_KEY}` - } - } - res.type('application/activity+json').json(body) + } + res.type('application/activity+json').json(body) }) export default router diff --git a/routes/profile.js b/routes/profile.js index a618b33..b4e0049 100644 --- a/routes/profile.js +++ b/routes/profile.js @@ -35,49 +35,49 @@ const router = express.Router() const bodyParser = bodyParserImport.urlencoded({ extended: false }) router.get('/sig', (req, res) => { - res.render('profile', { isSignature: true, signature: null }) + res.render('profile', { isSignature: true, signature: null }) }) router.post('/sig', bodyParser, async (req, res) => { - const data = await generateSignatureProfile(req.body.signature) - const title = utils.generatePageTitle('profile', data) - res.set('ariadne-identity-proof', data.keyData.openpgp4fpr) - res.render('profile', { title: title, data: data, isSignature: true, signature: req.body.signature }) + const data = await generateSignatureProfile(req.body.signature) + const title = utils.generatePageTitle('profile', data) + res.set('ariadne-identity-proof', data.keyData.openpgp4fpr) + res.render('profile', { title, data, isSignature: true, signature: req.body.signature }) }) router.get('/wkd/:id', async (req, res) => { - const data = await generateWKDProfile(req.params.id) - const title = utils.generatePageTitle('profile', data) - res.set('ariadne-identity-proof', data.keyData.openpgp4fpr) - res.render('profile', { title: title, data: data }) + const data = await generateWKDProfile(req.params.id) + const title = utils.generatePageTitle('profile', data) + res.set('ariadne-identity-proof', data.keyData.openpgp4fpr) + res.render('profile', { title, data }) }) router.get('/hkp/:id', async (req, res) => { - const data = await generateHKPProfile(req.params.id) - const title = utils.generatePageTitle('profile', data) - res.set('ariadne-identity-proof', data.keyData.openpgp4fpr) - res.render('profile', { title: title, data: data }) + const data = await generateHKPProfile(req.params.id) + const title = utils.generatePageTitle('profile', data) + res.set('ariadne-identity-proof', data.keyData.openpgp4fpr) + res.render('profile', { title, data }) }) router.get('/hkp/:server/:id', async (req, res) => { - const data = await generateHKPProfile(req.params.id, req.params.server) - const title = utils.generatePageTitle('profile', data) - res.set('ariadne-identity-proof', data.keyData.openpgp4fpr) - res.render('profile', { title: title, data: data }) + const data = await generateHKPProfile(req.params.id, req.params.server) + const title = utils.generatePageTitle('profile', data) + res.set('ariadne-identity-proof', data.keyData.openpgp4fpr) + res.render('profile', { title, data }) }) router.get('/keybase/:username/:fingerprint', async (req, res) => { - const data = await generateKeybaseProfile(req.params.username, req.params.fingerprint) - const title = utils.generatePageTitle('profile', data) - res.set('ariadne-identity-proof', data.keyData.openpgp4fpr) - res.render('profile', { title: title, data: data }) + const data = await generateKeybaseProfile(req.params.username, req.params.fingerprint) + const title = utils.generatePageTitle('profile', data) + res.set('ariadne-identity-proof', data.keyData.openpgp4fpr) + res.render('profile', { title, data }) }) router.get('/:id', async (req, res) => { - const data = await generateAutoProfile(req.params.id) - const title = utils.generatePageTitle('profile', data) - res.set('ariadne-identity-proof', data.keyData.openpgp4fpr) - res.render('profile', { title: title, data: data }) + const data = await generateAutoProfile(req.params.id) + const title = utils.generatePageTitle('profile', data) + res.set('ariadne-identity-proof', data.keyData.openpgp4fpr) + res.render('profile', { title, data }) }) export default router diff --git a/routes/util.js b/routes/util.js index 1e257f5..84412f6 100644 --- a/routes/util.js +++ b/routes/util.js @@ -31,49 +31,49 @@ import express from 'express' const router = express.Router() -router.get('/', function(req, res) { - res.render('util/index') +router.get('/', function (req, res) { + res.render('util/index') }) -router.get('/profile-url', function(req, res) { - res.render('util/profile-url') +router.get('/profile-url', function (req, res) { + res.render('util/profile-url') }) -router.get('/profile-url/:input', function(req, res) { - res.render('util/profile-url', { input: req.params.input }) +router.get('/profile-url/:input', function (req, res) { + res.render('util/profile-url', { input: req.params.input }) }) -router.get('/qr', function(req, res) { - res.render('util/qr') +router.get('/qr', function (req, res) { + res.render('util/qr') }) -router.get('/qr/:input', function(req, res) { - res.render('util/qr', { input: req.params.input }) +router.get('/qr/:input', function (req, res) { + res.render('util/qr', { input: req.params.input }) }) -router.get('/qrfp', function(req, res) { - res.render('util/qrfp') +router.get('/qrfp', function (req, res) { + res.render('util/qrfp') }) -router.get('/qrfp/:input', function(req, res) { - res.render('util/qrfp', { input: req.params.input }) +router.get('/qrfp/:input', function (req, res) { + res.render('util/qrfp', { input: req.params.input }) }) -router.get('/wkd', function(req, res) { - res.render('util/wkd') +router.get('/wkd', function (req, res) { + res.render('util/wkd') }) -router.get('/wkd/:input', function(req, res) { - res.render('util/wkd', { input: req.params.input }) +router.get('/wkd/:input', function (req, res) { + res.render('util/wkd', { input: req.params.input }) }) -router.get('/argon2', function(req, res) { - res.render('util/argon2') +router.get('/argon2', function (req, res) { + res.render('util/argon2') }) -router.get('/argon2/:input', function(req, res) { - res.render('util/argon2', { input: req.params.input }) +router.get('/argon2/:input', function (req, res) { + res.render('util/argon2', { input: req.params.input }) }) -router.get('/bcrypt', function(req, res) { - res.render('util/bcrypt') +router.get('/bcrypt', function (req, res) { + res.render('util/bcrypt') }) -router.get('/bcrypt/:input', function(req, res) { - res.render('util/bcrypt', { input: req.params.input }) +router.get('/bcrypt/:input', function (req, res) { + res.render('util/bcrypt', { input: req.params.input }) }) export default router diff --git a/server/demo.js b/server/demo.js index 2be5113..e03d05d 100644 --- a/server/demo.js +++ b/server/demo.js @@ -28,54 +28,54 @@ if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . */ export default { - "claimVersion": 1, - "uri": "https://fosstodon.org/@keyoxide", - "fingerprint": "9f0048ac0b23301e1f77e994909f6bd6f80f485d", - "status": "verified", - "matches": [ - { - "serviceprovider": { - "type": "web", - "name": "mastodon (demo)" - }, - "match": { - "regularExpression": {}, - "isAmbiguous": true - }, - "profile": { - "display": "@keyoxide@fosstodon.org", - "uri": "https://fosstodon.org/@keyoxide", - "qr": null - }, - "proof": { - "uri": "https://fosstodon.org/@keyoxide", - "request": { - "fetcher": "http", - "access": 0, - "format": "json", - "data": { - "url": "https://fosstodon.org/@keyoxide", - "format": "json" - } - } - }, - "claim": { - "format": 1, - "relation": 0, - "path": [ - "attachment", - "value" - ] - } - } - ], - "verification": { - "result": true, - "completed": true, - "errors": [], - "proof": { - "fetcher": "http", - "viaProxy": false + claimVersion: 1, + uri: 'https://fosstodon.org/@keyoxide', + fingerprint: '9f0048ac0b23301e1f77e994909f6bd6f80f485d', + status: 'verified', + matches: [ + { + serviceprovider: { + type: 'web', + name: 'mastodon (demo)' + }, + match: { + regularExpression: {}, + isAmbiguous: true + }, + profile: { + display: '@keyoxide@fosstodon.org', + uri: 'https://fosstodon.org/@keyoxide', + qr: null + }, + proof: { + uri: 'https://fosstodon.org/@keyoxide', + request: { + fetcher: 'http', + access: 0, + format: 'json', + data: { + url: 'https://fosstodon.org/@keyoxide', + format: 'json' + } } + }, + claim: { + format: 1, + relation: 0, + path: [ + 'attachment', + 'value' + ] + } } + ], + verification: { + result: true, + completed: true, + errors: [], + proof: { + fetcher: 'http', + viaProxy: false + } + } } diff --git a/server/index.js b/server/index.js index 67ae81b..c7d63c6 100644 --- a/server/index.js +++ b/server/index.js @@ -32,198 +32,198 @@ import { fetchWKD, fetchHKP, fetchSignature, fetchKeybase } from './keys.js' import libravatar from 'libravatar' const generateWKDProfile = async (id) => { - return fetchWKD(id) + return fetchWKD(id) .then(async key => { - let keyData = await doipjs.keys.process(key.publicKey) - keyData.openpgp4fpr = `openpgp4fpr:${keyData.fingerprint.toLowerCase()}` - keyData.key.fetchMethod = 'wkd' - keyData.key.uri = key.fetchURL - keyData.key.data = {} - keyData = processKeyData(keyData) + let keyData = await doipjs.keys.process(key.publicKey) + keyData.openpgp4fpr = `openpgp4fpr:${keyData.fingerprint.toLowerCase()}` + keyData.key.fetchMethod = 'wkd' + keyData.key.uri = key.fetchURL + keyData.key.data = {} + keyData = processKeyData(keyData) - let keyoxideData = {} - keyoxideData.url = `https://${process.env.DOMAIN}/wkd/${id}` + const keyoxideData = {} + keyoxideData.url = `https://${process.env.DOMAIN}/wkd/${id}` - return { - key: key, - keyData: keyData, - keyoxide: keyoxideData, - extra: await computeExtraData(key, keyData), - errors: [] - } + return { + key, + keyData, + keyoxide: keyoxideData, + extra: await computeExtraData(key, keyData), + errors: [] + } }) .catch(err => { - return { - key: {}, - keyData: {}, - keyoxide: {}, - extra: {}, - errors: [err.message] - } - }) -} - -const generateHKPProfile = async (id, keyserverDomain) => { - return fetchHKP(id, keyserverDomain) - .then(async key => { - let keyData = await doipjs.keys.process(key.publicKey) - keyData.openpgp4fpr = `openpgp4fpr:${keyData.fingerprint.toLowerCase()}` - keyData.key.fetchMethod = 'hkp' - keyData.key.uri = key.fetchURL - keyData.key.data = {} - keyData = processKeyData(keyData) - - let keyoxideData = {} - if (!keyserverDomain || keyserverDomain === 'keys.openpgp.org') { - keyoxideData.url = `https://${process.env.DOMAIN}/hkp/${id}` - } else { - keyoxideData.url = `https://${process.env.DOMAIN}/hkp/${keyserverDomain}/${id}` - } - - return { - key: key, - keyData: keyData, - keyoxide: keyoxideData, - extra: await computeExtraData(key, keyData), - errors: [] - } - }) - .catch(err => { - return { - key: {}, - keyData: {}, - keyoxide: {}, - extra: {}, - errors: [err.message] - } - }) -} - -const generateAutoProfile = async (id) => { - let result - - if (id.includes('@')) { - result = await generateWKDProfile(id) - - if (result && result.errors.length === 0) { - return result - } - } - - result = await generateHKPProfile(id) - if (result && result.errors.length === 0) { - return result - } - - return { + return { key: {}, keyData: {}, keyoxide: {}, extra: {}, - errors: ["No public keys could be found"] + errors: [err.message] + } + }) +} + +const generateHKPProfile = async (id, keyserverDomain) => { + return fetchHKP(id, keyserverDomain) + .then(async key => { + let keyData = await doipjs.keys.process(key.publicKey) + keyData.openpgp4fpr = `openpgp4fpr:${keyData.fingerprint.toLowerCase()}` + keyData.key.fetchMethod = 'hkp' + keyData.key.uri = key.fetchURL + keyData.key.data = {} + keyData = processKeyData(keyData) + + const keyoxideData = {} + if (!keyserverDomain || keyserverDomain === 'keys.openpgp.org') { + keyoxideData.url = `https://${process.env.DOMAIN}/hkp/${id}` + } else { + keyoxideData.url = `https://${process.env.DOMAIN}/hkp/${keyserverDomain}/${id}` + } + + return { + key, + keyData, + keyoxide: keyoxideData, + extra: await computeExtraData(key, keyData), + errors: [] + } + }) + .catch(err => { + return { + key: {}, + keyData: {}, + keyoxide: {}, + extra: {}, + errors: [err.message] + } + }) +} + +const generateAutoProfile = async (id) => { + let result + + if (id.includes('@')) { + result = await generateWKDProfile(id) + + if (result && result.errors.length === 0) { + return result } + } + + result = await generateHKPProfile(id) + if (result && result.errors.length === 0) { + return result + } + + return { + key: {}, + keyData: {}, + keyoxide: {}, + extra: {}, + errors: ['No public keys could be found'] + } } const generateSignatureProfile = async (signature) => { - return fetchSignature(signature) + return fetchSignature(signature) .then(async key => { - let keyData = key.keyData - keyData.openpgp4fpr = `openpgp4fpr:${keyData.fingerprint.toLowerCase()}` - delete key.keyData - keyData.key.data = {} - keyData = processKeyData(keyData) + let keyData = key.keyData + keyData.openpgp4fpr = `openpgp4fpr:${keyData.fingerprint.toLowerCase()}` + delete key.keyData + keyData.key.data = {} + keyData = processKeyData(keyData) - let keyoxideData = {} + const keyoxideData = {} - return { - key: key, - keyData: keyData, - keyoxide: keyoxideData, - extra: await computeExtraData(key, keyData), - errors: [] - } + return { + key, + keyData, + keyoxide: keyoxideData, + extra: await computeExtraData(key, keyData), + errors: [] + } }) .catch(err => { - return { - key: {}, - keyData: {}, - keyoxide: {}, - extra: {}, - errors: [err.message] - } + return { + key: {}, + keyData: {}, + keyoxide: {}, + extra: {}, + errors: [err.message] + } }) } const generateKeybaseProfile = async (username, fingerprint) => { - return fetchKeybase(username, fingerprint) + return fetchKeybase(username, fingerprint) .then(async key => { - let keyData = await doipjs.keys.process(key.publicKey) - keyData.openpgp4fpr = `openpgp4fpr:${keyData.fingerprint.toLowerCase()}` - keyData.key.fetchMethod = 'hkp' - keyData.key.uri = key.fetchURL - keyData.key.data = {} - keyData = processKeyData(keyData) + let keyData = await doipjs.keys.process(key.publicKey) + keyData.openpgp4fpr = `openpgp4fpr:${keyData.fingerprint.toLowerCase()}` + keyData.key.fetchMethod = 'hkp' + keyData.key.uri = key.fetchURL + keyData.key.data = {} + keyData = processKeyData(keyData) - let keyoxideData = {} - keyoxideData.url = `https://${process.env.DOMAIN}/keybase/${username}/${fingerprint}` + const keyoxideData = {} + keyoxideData.url = `https://${process.env.DOMAIN}/keybase/${username}/${fingerprint}` - return { - key: key, - keyData: keyData, - keyoxide: keyoxideData, - extra: await computeExtraData(key, keyData), - errors: [] - } + return { + key, + keyData, + keyoxide: keyoxideData, + extra: await computeExtraData(key, keyData), + errors: [] + } }) .catch(err => { - return { - key: {}, - keyData: {}, - keyoxide: {}, - extra: {}, - errors: [err.message] - } + return { + key: {}, + keyData: {}, + keyoxide: {}, + extra: {}, + errors: [err.message] + } }) } const processKeyData = (keyData) => { - keyData.users.forEach(user => { - // Remove faulty claims - user.claims = user.claims.filter(claim => { - return claim instanceof doipjs.Claim - }) - - // Match claims - user.claims.forEach(claim => { - claim.match() - }) - - // Sort claims - user.claims.sort((a,b) => { - if (a.matches.length == 0) return 1 - if (b.matches.length == 0) return -1 - - if (a.matches[0].serviceprovider.name < b.matches[0].serviceprovider.name) { - return -1 - } - if (a.matches[0].serviceprovider.name > b.matches[0].serviceprovider.name) { - return 1 - } - return 0 - }) + keyData.users.forEach(user => { + // Remove faulty claims + user.claims = user.claims.filter(claim => { + return claim instanceof doipjs.Claim }) - return keyData + // Match claims + user.claims.forEach(claim => { + claim.match() + }) + + // Sort claims + user.claims.sort((a, b) => { + if (a.matches.length === 0) return 1 + if (b.matches.length === 0) return -1 + + if (a.matches[0].serviceprovider.name < b.matches[0].serviceprovider.name) { + return -1 + } + if (a.matches[0].serviceprovider.name > b.matches[0].serviceprovider.name) { + return 1 + } + return 0 + }) + }) + + return keyData } const computeExtraData = async (key, keyData) => { - // Get the primary user - const primaryUser = await key.publicKey.getPrimaryUser() + // Get the primary user + const primaryUser = await key.publicKey.getPrimaryUser() - // Query libravatar to get the avatar url - return { - avatarURL: await libravatar.get_avatar_url({ email: primaryUser.user.userID.email, size: 128, default: 'mm', https: true }) - } + // Query libravatar to get the avatar url + return { + avatarURL: await libravatar.get_avatar_url({ email: primaryUser.user.userID.email, size: 128, default: 'mm', https: true }) + } } export { generateWKDProfile } diff --git a/server/keys.js b/server/keys.js index b3b2476..512a149 100644 --- a/server/keys.js +++ b/server/keys.js @@ -37,191 +37,199 @@ import Keyv from 'keyv' const c = process.env.ENABLE_EXPERIMENTAL_CACHE ? new Keyv() : null const fetchWKD = (id) => { - return new Promise(async (resolve, reject) => { - let output = { - publicKey: null, - fetchURL: null - } + return new Promise((resolve, reject) => { + (async () => { + const output = { + publicKey: null, + fetchURL: null + } - if (!id.includes('@')) { - reject(new Error(`The WKD identifier "${id}" is invalid`)); - } + if (!id.includes('@')) { + reject(new Error(`The WKD identifier "${id}" is invalid`)) + } - const [, localPart, domain] = /([^\@]*)@(.*)/.exec(id) - if (!localPart || !domain) { - reject(new Error(`The WKD identifier "${id}" is invalid`)); - } - const localEncoded = await computeWKDLocalPart(localPart) - const urlAdvanced = `https://openpgpkey.${domain}/.well-known/openpgpkey/${domain}/hu/${localEncoded}` - const urlDirect = `https://${domain}/.well-known/openpgpkey/hu/${localEncoded}` - let plaintext - - const hash = createHash('md5').update(id).digest('hex') - if (c && await c.get(hash)) { - plaintext = Uint8Array.from((await c.get(hash)).split(',')) + const [, localPart, domain] = /([^@]*)@(.*)/.exec(id) + if (!localPart || !domain) { + reject(new Error(`The WKD identifier "${id}" is invalid`)) + } + const localEncoded = await computeWKDLocalPart(localPart) + const urlAdvanced = `https://openpgpkey.${domain}/.well-known/openpgpkey/${domain}/hu/${localEncoded}` + const urlDirect = `https://${domain}/.well-known/openpgpkey/hu/${localEncoded}` + let plaintext + + const hash = createHash('md5').update(id).digest('hex') + if (c && await c.get(hash)) { + plaintext = Uint8Array.from((await c.get(hash)).split(',')) + } + + if (!plaintext) { + try { + plaintext = await got(urlAdvanced).then((response) => { + if (response.statusCode === 200) { + output.fetchURL = urlAdvanced + return new Uint8Array(response.rawBody) + } else { + return null + } + }) + } catch (e) { + try { + plaintext = await got(urlDirect).then((response) => { + if (response.statusCode === 200) { + output.fetchURL = urlDirect + return new Uint8Array(response.rawBody) + } else { + return null + } + }) + } catch (error) { + reject(new Error('No public keys could be fetched using WKD')) + } } if (!plaintext) { - try { - plaintext = await got(urlAdvanced).then((response) => { - if (response.statusCode === 200) { - output.fetchURL = urlAdvanced - return new Uint8Array(response.rawBody) - } else { - return null - } - }) - } catch (e) { - try { - plaintext = await got(urlDirect).then((response) => { - if (response.statusCode === 200) { - output.fetchURL = urlDirect - return new Uint8Array(response.rawBody) - } else { - return null - } - }) - } catch (error) { - reject(new Error(`No public keys could be fetched using WKD`)) - } - } - - if (!plaintext) { - reject(new Error(`No public keys could be fetched using WKD`)) - } - - if (c && plaintext instanceof Uint8Array) { - await c.set(hash, plaintext.toString(), 60 * 1000) - } + reject(new Error('No public keys could be fetched using WKD')) } - try { - output.publicKey = await readKey({ - binaryKey: plaintext - }) - } catch(error) { - reject(new Error(`No public keys could be read from the data fetched using WKD`)) + if (c && plaintext instanceof Uint8Array) { + await c.set(hash, plaintext.toString(), 60 * 1000) } + } - if (!output.publicKey) { - reject(new Error(`No public keys could be read from the data fetched using WKD`)) - } + try { + output.publicKey = await readKey({ + binaryKey: plaintext + }) + } catch (error) { + reject(new Error('No public keys could be read from the data fetched using WKD')) + } - resolve(output) - }) + if (!output.publicKey) { + reject(new Error('No public keys could be read from the data fetched using WKD')) + } + + resolve(output) + })() + }) } const fetchHKP = (id, keyserverDomain) => { - return new Promise(async (resolve, reject) => { - let output = { - publicKey: null, - fetchURL: null + return new Promise((resolve, reject) => { + (async () => { + const output = { + publicKey: null, + fetchURL: null + } + + keyserverDomain = keyserverDomain || 'keys.openpgp.org' + + let query = '' + if (id.includes('@')) { + query = id + } else { + query = `0x${id}` + } + + output.fetchURL = `https://${keyserverDomain}/pks/lookup?op=get&options=mr&search=${query}` + + const hash = createHash('md5').update(`${id}__${keyserverDomain}`).digest('hex') + + if (c && await c.get(hash)) { + output.publicKey = await readKey({ + armoredKey: await c.get(hash) + }) + } else { + try { + output.publicKey = await doipjs.keys.fetchHKP(id, keyserverDomain) + } catch (error) { + reject(new Error('No public keys could be fetched using HKP')) } + } - keyserverDomain = keyserverDomain ? keyserverDomain : 'keys.openpgp.org' + if (!output.publicKey) { + reject(new Error('No public keys could be fetched using HKP')) + } - let query = '' - if (id.includes('@')) { - query = id - } else { - query = `0x${id}` - } + if (c && output.publicKey instanceof PublicKey) { + await c.set(hash, output.publicKey.armor(), 60 * 1000) + } - output.fetchURL = `https://${keyserverDomain}/pks/lookup?op=get&options=mr&search=${query}` - - const hash = createHash('md5').update(`${id}__${keyserverDomain}`).digest('hex') - - if (c && await c.get(hash)) { - output.publicKey = await readKey({ - armoredKey: await c.get(hash) - }) - } else { - try { - output.publicKey = await doipjs.keys.fetchHKP(id, keyserverDomain) - } catch(error) { - reject(new Error(`No public keys could be fetched using HKP`)) - } - } - - if (!output.publicKey) { - reject(new Error(`No public keys could be fetched using HKP`)) - } - - if (c && output.publicKey instanceof PublicKey) { - await c.set(hash, output.publicKey.armor(), 60 * 1000) - } - - resolve(output) - }) + resolve(output) + })() + }) } const fetchSignature = (signature) => { - return new Promise(async (resolve, reject) => { - let output = { - publicKey: null, - fetchURL: null, - keyData: null - } + return new Promise((resolve, reject) => { + (async () => { + const output = { + publicKey: null, + fetchURL: null, + keyData: null + } - // Check validity of signature - let signatureData - try { - signatureData = await readCleartextMessage({ - cleartextMessage: signature - }) - } catch (error) { - reject(new Error(`Signature could not be properly read (${error.message})`)) - } - - // Process the signature - try { - output.keyData = await doipjs.signatures.process(signature) - output.publicKey = output.keyData.key.data - // TODO Find the URL to the key - output.fetchURL = null - } catch(error) { - reject(new Error(`Signature could not be properly read (${error.message})`)) - } - - // Check if a key was fetched - if (!output.publicKey) { - reject(new Error(`No public keys could be fetched`)) - } - - // Check validity of signature - const verified = await verify({ - message: signatureData, - verificationKeys: output.publicKey + // Check validity of signature + let signatureData + try { + signatureData = await readCleartextMessage({ + cleartextMessage: signature }) - - if (!await verified.signatures[0].verified) { - reject(new Error('Signature was invalid')) - } + } catch (error) { + reject(new Error(`Signature could not be properly read (${error.message})`)) + } - resolve(output) - }) + // Process the signature + try { + output.keyData = await doipjs.signatures.process(signature) + output.publicKey = output.keyData.key.data + // TODO Find the URL to the key + output.fetchURL = null + } catch (error) { + reject(new Error(`Signature could not be properly read (${error.message})`)) + } + + // Check if a key was fetched + if (!output.publicKey) { + reject(new Error('No public keys could be fetched')) + } + + // Check validity of signature + const verified = await verify({ + message: signatureData, + verificationKeys: output.publicKey + }) + + if (!await verified.signatures[0].verified) { + reject(new Error('Signature was invalid')) + } + + resolve(output) + })() + }) } const fetchKeybase = (username, fingerprint) => { - return new Promise(async (resolve, reject) => { - let output = { - publicKey: null, - fetchURL: null - } + return new Promise((resolve, reject) => { + (async () => { + const output = { + publicKey: null, + fetchURL: null + } - try { - output.publicKey = await doipjs.keys.fetchKeybase(username, fingerprint) - output.fetchURL = `https://keybase.io/${username}/pgp_keys.asc?fingerprint=${fingerprint}` - } catch(error) { - reject(new Error(`No public keys could be fetched from Keybase`)) - } + try { + output.publicKey = await doipjs.keys.fetchKeybase(username, fingerprint) + output.fetchURL = `https://keybase.io/${username}/pgp_keys.asc?fingerprint=${fingerprint}` + } catch (error) { + reject(new Error('No public keys could be fetched from Keybase')) + } - if (!output.publicKey) { - reject(new Error(`No public keys could be fetched from Keybase`)) - } + if (!output.publicKey) { + reject(new Error('No public keys could be fetched from Keybase')) + } - resolve(output) - }) + resolve(output) + })() + }) } export { fetchWKD } diff --git a/server/utils.js b/server/utils.js index 7ec8dd7..cd83172 100644 --- a/server/utils.js +++ b/server/utils.js @@ -29,54 +29,52 @@ more information on this, and how to apply and follow the GNU AGPL, see 0 || index < data.length) { + if (bitsLeft < SHIFT) { + if (index < data.length) { + buffer <<= 8 + buffer |= data[index++] & 0xff + bitsLeft += 8 + } else { + const pad = SHIFT - bitsLeft + buffer <<= pad + bitsLeft += pad + } } - const ALPHABET = "ybndrfg8ejkmcpqxot1uwisza345h769"; - const SHIFT = 5; - const MASK = 31; - let buffer = data[0]; - let index = 1; - let bitsLeft = 8; - let result = ''; - while (bitsLeft > 0 || index < data.length) { - if (bitsLeft < SHIFT) { - if (index < data.length) { - buffer <<= 8; - buffer |= data[index++] & 0xff; - bitsLeft += 8; - } else { - const pad = SHIFT - bitsLeft; - buffer <<= pad; - bitsLeft += pad; - } - } - bitsLeft -= SHIFT; - result += ALPHABET[MASK & (buffer >> bitsLeft)]; - } - return result; -} \ No newline at end of file + bitsLeft -= SHIFT + result += ALPHABET[MASK & (buffer >> bitsLeft)] + } + return result +} diff --git a/src/index.js b/src/index.js index fc88b04..9e15e29 100644 --- a/src/index.js +++ b/src/index.js @@ -54,21 +54,21 @@ app.set('onion_url', process.env.ONION_URL) // Middlewares app.use((req, res, next) => { - res.setHeader('Permissions-Policy', 'interest-cohort=()') - next() + res.setHeader('Permissions-Policy', 'interest-cohort=()') + next() }) if (app.get('onion_url')) { - app.get('/*', (req, res, next) => { - res.header('Onion-Location', app.get('onion_url')) - next() - }) + app.get('/*', (req, res, next) => { + res.header('Onion-Location', app.get('onion_url')) + next() + }) } app.use(stringReplace({ - PLACEHOLDER__PROXY_HOSTNAME: process.env.PROXY_HOSTNAME || process.env.DOMAIN || 'null' + PLACEHOLDER__PROXY_HOSTNAME: process.env.PROXY_HOSTNAME || process.env.DOMAIN || 'null' }, { - contentTypeFilterRegexp: /application\/javascript/, + contentTypeFilterRegexp: /application\/javascript/ })) // Routes @@ -82,7 +82,7 @@ app.use('/util', utilRoute) app.use('/', profileRoute) app.listen(app.get('port'), () => { - console.log(`Node server listening at http://localhost:${app.get('port')}`) + console.log(`Node server listening at http://localhost:${app.get('port')}`) }) export default app diff --git a/yarn.lock b/yarn.lock index 0f8d49c..0f1d85f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -281,6 +281,40 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f" integrity sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA== +"@eslint/eslintrc@^1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.3.tgz#2b044ab39fdfa75b4688184f9e573ce3c5b0ff95" + integrity sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.4.0" + globals "^13.15.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@humanwhocodes/config-array@^0.11.6": + version "0.11.7" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.7.tgz#38aec044c6c828f6ed51d5d7ae3d9b9faf6dbb0f" + integrity sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + "@jridgewell/gen-mapping@^0.1.0": version "0.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" @@ -342,11 +376,24 @@ "@nodelib/fs.stat" "2.0.4" run-parallel "^1.1.9" +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + "@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2": version "2.0.4" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz" integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q== +"@nodelib/fs.stat@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + "@nodelib/fs.walk@^1.2.3": version "1.2.6" resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz" @@ -355,6 +402,14 @@ "@nodelib/fs.scandir" "2.1.4" fastq "^1.6.0" +"@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + "@openpgp/hkp-client@^0.0.2": version "0.0.2" resolved "https://registry.yarnpkg.com/@openpgp/hkp-client/-/hkp-client-0.0.2.tgz#d8737358efcf6412c8273f89385e020766613e88" @@ -474,6 +529,11 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + "@types/keyv@*": version "3.1.1" resolved "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz" @@ -912,6 +972,11 @@ acorn-import-assertions@^1.7.6: resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + acorn-walk@^7.1.1: version "7.2.0" resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz" @@ -937,6 +1002,11 @@ acorn@^8.7.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== +acorn@^8.8.0: + version "8.8.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" + integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -963,7 +1033,7 @@ ajv-keywords@^5.0.0: dependencies: fast-deep-equal "^3.1.3" -ajv@^6.12.5: +ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1052,6 +1122,17 @@ array-flatten@1.1.1: resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= +array-includes@^3.1.4, array-includes@^3.1.5: + version "3.1.6" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" + integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + get-intrinsic "^1.1.3" + is-string "^1.0.7" + array-union@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" @@ -1062,6 +1143,26 @@ array-union@^3.0.1: resolved "https://registry.yarnpkg.com/array-union/-/array-union-3.0.1.tgz#da52630d327f8b88cfbfb57728e2af5cd9b6b975" integrity sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw== +array.prototype.flat@^1.2.5: + version "1.3.1" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" + integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + +array.prototype.flatmap@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" + integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + es-shim-unscopables "^1.0.0" + asap@~2.0.3: version "2.0.6" resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz" @@ -1262,6 +1363,13 @@ buffer@^5.4.3: base64-js "^1.3.1" ieee754 "^1.1.13" +builtins@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9" + integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== + dependencies: + semver "^7.0.0" + bytes@3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz" @@ -1298,6 +1406,11 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + camelcase@^5.0.0: version "5.3.1" resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" @@ -1345,7 +1458,7 @@ chalk@^2.0.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.1.0: +chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -1598,7 +1711,7 @@ create-hmac@^1.1.3: safe-buffer "^5.0.1" sha.js "^2.4.8" -cross-spawn@^7.0.3: +cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -1652,14 +1765,14 @@ data-urls@^3.0.2: whatwg-mimetype "^3.0.0" whatwg-url "^11.0.0" -debug@2.6.9: +debug@2.6.9, debug@^2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@4: +debug@4, debug@^4.1.1, debug@^4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -1721,6 +1834,11 @@ deep-eql@^3.0.1: dependencies: type-detect "^4.0.0" +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + deep-is@~0.1.3: version "0.1.3" resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz" @@ -1738,6 +1856,14 @@ define-properties@^1.1.3: dependencies: object-keys "^1.0.12" +define-properties@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" @@ -1775,15 +1901,29 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + doctypes@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz" integrity sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk= -doipjs@^0.17.2: - version "0.17.2" - resolved "https://registry.yarnpkg.com/doipjs/-/doipjs-0.17.2.tgz#ae9696e41e97e237d66af1e36d8d67d0d45551a1" - integrity sha512-p/yWYhXV2E7ygBdG+qV8XyE8Z9JQw4IX+zStv/r/KrhQYMHyCnKs6AJ1hBwPTG6d28uQLVHpaMXdOPz00F+3QQ== +doipjs@^0.17.3: + version "0.17.3" + resolved "https://registry.yarnpkg.com/doipjs/-/doipjs-0.17.3.tgz#5fd2fd1fba1dee3abdcdadf6172fb2cb03de27b4" + integrity sha512-ChRV+JOtEeyZLohw73D9smrug683Mf53dFkm96bQMUUkzj7cdYmp63Z5Q4VjfrJ5G5eJ2TFLSV1BCXrF8HzYvw== dependencies: "@openpgp/hkp-client" "^0.0.2" "@openpgp/wkd-client" "^0.0.3" @@ -1881,6 +2021,13 @@ envinfo@^7.7.3: resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + es-abstract@^1.18.0-next.2: version "1.18.0" resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz" @@ -1903,11 +2050,48 @@ es-abstract@^1.18.0-next.2: string.prototype.trimstart "^1.0.4" unbox-primitive "^1.0.0" +es-abstract@^1.19.0, es-abstract@^1.20.4: + version "1.20.4" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.4.tgz#1d103f9f8d78d4cf0713edcd6d0ed1a46eed5861" + integrity sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.1.3" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-weakref "^1.0.2" + object-inspect "^1.12.2" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.4.3" + safe-regex-test "^1.0.0" + string.prototype.trimend "^1.0.5" + string.prototype.trimstart "^1.0.5" + unbox-primitive "^1.0.2" + es-module-lexer@^0.9.0: version "0.9.3" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-shim-unscopables@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" + integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== + dependencies: + has "^1.0.3" + es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" @@ -1949,6 +2133,97 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" +eslint-config-standard-jsx@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-standard-jsx/-/eslint-config-standard-jsx-11.0.0.tgz#70852d395731a96704a592be5b0bfaccfeded239" + integrity sha512-+1EV/R0JxEK1L0NGolAr8Iktm3Rgotx3BKwgaX+eAuSX8D952LULKtjgZD3F+e6SvibONnhLwoTi9DPxN5LvvQ== + +eslint-config-standard@17.0.0: + version "17.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz#fd5b6cf1dcf6ba8d29f200c461de2e19069888cf" + integrity sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg== + +eslint-import-resolver-node@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" + integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== + dependencies: + debug "^3.2.7" + resolve "^1.20.0" + +eslint-module-utils@^2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" + integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== + dependencies: + debug "^3.2.7" + +eslint-plugin-es@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz#f0822f0c18a535a97c3e714e89f88586a7641ec9" + integrity sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ== + dependencies: + eslint-utils "^2.0.0" + regexpp "^3.0.0" + +eslint-plugin-import@^2.26.0: + version "2.26.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b" + integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== + dependencies: + array-includes "^3.1.4" + array.prototype.flat "^1.2.5" + debug "^2.6.9" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.6" + eslint-module-utils "^2.7.3" + has "^1.0.3" + is-core-module "^2.8.1" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.values "^1.1.5" + resolve "^1.22.0" + tsconfig-paths "^3.14.1" + +eslint-plugin-n@^15.1.0: + version "15.5.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-n/-/eslint-plugin-n-15.5.1.tgz#b3991857d1edaa47e0108ead825470ce63f391c1" + integrity sha512-kAd+xhZm7brHoFLzKLB7/FGRFJNg/srmv67mqb7tto22rpr4wv/LV6RuXzAfv3jbab7+k1wi42PsIhGviywaaw== + dependencies: + builtins "^5.0.1" + eslint-plugin-es "^4.1.0" + eslint-utils "^3.0.0" + ignore "^5.1.1" + is-core-module "^2.11.0" + minimatch "^3.1.2" + resolve "^1.22.1" + semver "^7.3.8" + +eslint-plugin-promise@^6.0.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz#269a3e2772f62875661220631bd4dafcb4083816" + integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig== + +eslint-plugin-react@^7.28.0: + version "7.31.10" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.31.10.tgz#6782c2c7fe91c09e715d536067644bbb9491419a" + integrity sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA== + dependencies: + array-includes "^3.1.5" + array.prototype.flatmap "^1.3.0" + doctrine "^2.1.0" + estraverse "^5.3.0" + jsx-ast-utils "^2.4.1 || ^3.0.0" + minimatch "^3.1.2" + object.entries "^1.1.5" + object.fromentries "^2.0.5" + object.hasown "^1.1.1" + object.values "^1.1.5" + prop-types "^15.8.1" + resolve "^2.0.0-next.3" + semver "^6.3.0" + string.prototype.matchall "^4.0.7" + eslint-scope@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" @@ -1957,11 +2232,109 @@ eslint-scope@5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" +eslint-scope@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" + integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-utils@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== + +eslint@^8.13.0: + version "8.27.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.27.0.tgz#d547e2f7239994ad1faa4bb5d84e5d809db7cf64" + integrity sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ== + dependencies: + "@eslint/eslintrc" "^1.3.3" + "@humanwhocodes/config-array" "^0.11.6" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.1.1" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.3.0" + espree "^9.4.0" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.15.0" + grapheme-splitter "^1.0.4" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-sdsl "^4.1.4" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.1" + regexpp "^3.2.0" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + +espree@^9.4.0: + version "9.4.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.1.tgz#51d6092615567a2c2cff7833445e37c28c0065bd" + integrity sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg== + dependencies: + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.3.0" + esprima@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + esrecurse@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" @@ -1974,6 +2347,11 @@ estraverse@^4.1.1: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== +estraverse@^5.1.0, estraverse@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + estraverse@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz" @@ -2094,7 +2472,7 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= @@ -2111,6 +2489,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" @@ -2145,7 +2530,7 @@ find-cache-dir@^2.0.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-up@5.0.0: +find-up@5.0.0, find-up@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== @@ -2168,11 +2553,24 @@ find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + flat@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== +flatted@^3.1.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + follow-redirects@^1.14.7: version "1.14.9" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" @@ -2231,6 +2629,21 @@ function-bind@^1.1.1: resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + functions-have-names "^1.2.2" + +functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" @@ -2255,6 +2668,20 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.1" +get-intrinsic@^1.1.0, get-intrinsic@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" + integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-stdin@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" + integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== + get-stream@^5.1.0: version "5.2.0" resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" @@ -2267,6 +2694,14 @@ get-stream@^6.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + gitignore-to-glob@^0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/gitignore-to-glob/-/gitignore-to-glob-0.3.0.tgz" @@ -2279,7 +2714,7 @@ glob-parent@^5.1.0, glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -glob-parent@^6.0.1: +glob-parent@^6.0.1, glob-parent@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== @@ -2332,6 +2767,13 @@ globals@^11.1.0: resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +globals@^13.15.0: + version "13.17.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" + integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== + dependencies: + type-fest "^0.20.2" + globby@^10.0.1: version "10.0.2" resolved "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz" @@ -2375,6 +2817,11 @@ got@^11.8.2: p-cancelable "^2.0.0" responselike "^2.0.0" +graceful-fs@^4.1.15: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: version "4.2.6" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz" @@ -2385,6 +2832,11 @@ graceful-fs@^4.2.4, graceful-fs@^4.2.9: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" @@ -2402,6 +2854,11 @@ has-bigints@^1.0.1: resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz" integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== +has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" @@ -2412,11 +2869,30 @@ has-flag@^4.0.0: resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + has-symbols@^1.0.1, has-symbols@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + has@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" @@ -2560,11 +3036,19 @@ ignore@^5.1.1, ignore@^5.1.2: resolved "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== -ignore@^5.1.9: +ignore@^5.1.9, ignore@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + import-local@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" @@ -2573,6 +3057,11 @@ import-local@^3.0.2: pkg-dir "^4.2.0" resolve-cwd "^3.0.0" +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" @@ -2591,6 +3080,15 @@ inherits@2.0.3: resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + interpret@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" @@ -2616,6 +3114,11 @@ irc-upd@^0.11.0: chardet "^1.2.1" iconv-lite "^0.6.2" +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + is-bigint@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.1.tgz" @@ -2640,6 +3143,18 @@ is-callable@^1.1.4, is-callable@^1.2.3: resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz" integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== +is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-core-module@^2.11.0, is-core-module@^2.9.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" + integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== + dependencies: + has "^1.0.3" + is-core-module@^2.2.0: version "2.3.0" resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.3.0.tgz" @@ -2682,6 +3197,13 @@ is-fullwidth-code-point@^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== +is-glob@^4.0.0, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz" @@ -2689,18 +3211,16 @@ is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-glob@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - is-negative-zero@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz" integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== +is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + is-number-object@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz" @@ -2711,6 +3231,11 @@ is-number@^7.0.0: resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-plain-obj@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" @@ -2741,6 +3266,21 @@ is-regex@^1.0.3, is-regex@^1.1.2: call-bind "^1.0.2" has-symbols "^1.0.1" +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + is-stream@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz" @@ -2751,6 +3291,13 @@ is-string@^1.0.5: resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz" integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== +is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + is-symbol@^1.0.2, is-symbol@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz" @@ -2763,6 +3310,13 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + isarray@^2.0.1: version "2.0.5" resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" @@ -2787,17 +3341,22 @@ jest-worker@^27.4.5: merge-stream "^2.0.0" supports-color "^8.0.0" +js-sdsl@^4.1.4: + version "4.1.5" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.5.tgz#1ff1645e6b4d1b028cd3f862db88c9d887f26e2a" + integrity sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q== + js-stringify@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz" integrity sha1-Fzb939lyTyijaCrcYjCufk6Weds= -js-tokens@^4.0.0: +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@4.1.0: +js-yaml@4.1.0, js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== @@ -2847,7 +3406,7 @@ json-buffer@3.0.1: resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== -json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== @@ -2862,6 +3421,18 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + json5@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" @@ -2889,6 +3460,14 @@ jstransformer@1.0.0: is-promise "^2.0.0" promise "^7.0.1" +"jsx-ast-utils@^2.4.1 || ^3.0.0": + version "3.3.3" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" + integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== + dependencies: + array-includes "^3.1.5" + object.assign "^4.1.3" + keyv@^4.0.0: version "4.0.3" resolved "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz" @@ -2913,6 +3492,14 @@ koa-compose@^4.1.0: resolved "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz" integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw== +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + levn@~0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz" @@ -2944,6 +3531,17 @@ linkify-it@^2.0.0: dependencies: uc.micro "^1.0.1" +load-json-file@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-5.3.0.tgz#4d3c1e01fa1c03ea78a60ac7af932c9ce53403f3" + integrity sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw== + dependencies: + graceful-fs "^4.1.15" + parse-json "^4.0.0" + pify "^4.0.1" + strip-bom "^3.0.0" + type-fest "^0.3.0" + loader-runner@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" @@ -2971,6 +3569,11 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + lodash@^4.17.20, lodash@^4.17.21: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" @@ -2984,6 +3587,13 @@ log-symbols@4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" +loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + loupe@^2.3.1: version "2.3.4" resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3" @@ -3144,13 +3754,18 @@ minimatch@3.0.4, minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimatch@^3.1.1: +minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" +minimist@^1.2.0, minimist@^1.2.6: + version "1.2.7" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" + integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== + mocha@^9.2.1: version "9.2.1" resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.1.tgz#a1abb675aa9a8490798503af57e8782a78f1338e" @@ -3216,6 +3831,11 @@ nanoid@^3.3.1: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + negotiator@0.6.2: version "0.6.2" resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz" @@ -3301,6 +3921,11 @@ object-assign@^4, object-assign@^4.1.1: resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= +object-inspect@^1.12.2: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + object-inspect@^1.9.0: version "1.10.2" resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.2.tgz" @@ -3321,6 +3946,34 @@ object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" +object.assign@^4.1.3, object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.entries@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.6.tgz#9737d0e5b8291edd340a3e3264bb8a3b00d5fa23" + integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +object.fromentries@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.6.tgz#cdb04da08c539cffa912dcd368b886e0904bfa73" + integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + object.getownpropertydescriptors@^2.0.3: version "2.1.2" resolved "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz" @@ -3330,6 +3983,23 @@ object.getownpropertydescriptors@^2.0.3: define-properties "^1.1.3" es-abstract "^1.18.0-next.2" +object.hasown@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.2.tgz#f919e21fad4eb38a57bc6345b3afd496515c3f92" + integrity sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw== + dependencies: + define-properties "^1.1.4" + es-abstract "^1.20.4" + +object.values@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" + integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz" @@ -3375,6 +4045,18 @@ optionator@^0.8.1: type-check "~0.3.2" word-wrap "~1.2.3" +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + p-cancelable@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.0.tgz" @@ -3420,6 +4102,21 @@ p-try@^2.0.0: resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz" @@ -3497,6 +4194,14 @@ pirates@^4.0.5: resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== +pkg-conf@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-3.1.0.tgz#d9f9c75ea1bae0e77938cde045b276dac7cc69ae" + integrity sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ== + dependencies: + find-up "^3.0.0" + load-json-file "^5.2.0" + pkg-dir@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz" @@ -3566,6 +4271,11 @@ postcss@^8.4.5: picocolors "^1.0.0" source-map-js "^1.0.2" +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz" @@ -3578,6 +4288,15 @@ promise@^7.0.1: dependencies: asap "~2.0.3" +prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + proxy-addr@~2.0.5: version "2.0.6" resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz" @@ -3784,6 +4503,11 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" @@ -3819,6 +4543,20 @@ regenerator-runtime@^0.13.4: resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz" integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== +regexp.prototype.flags@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + functions-have-names "^1.2.2" + +regexpp@^3.0.0, regexpp@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" @@ -3846,6 +4584,11 @@ resolve-cwd@^3.0.0: dependencies: resolve-from "^5.0.0" +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + resolve-from@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" @@ -3859,6 +4602,15 @@ resolve@^1.15.1: is-core-module "^2.2.0" path-parse "^1.0.6" +resolve@^1.20.0, resolve@^1.22.0, resolve@^1.22.1: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + resolve@^1.9.0: version "1.22.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" @@ -3868,6 +4620,15 @@ resolve@^1.9.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@^2.0.0-next.3: + version "2.0.0-next.4" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660" + integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + responselike@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz" @@ -3880,6 +4641,13 @@ reusify@^1.0.4: resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz" @@ -3905,6 +4673,15 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.0, resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.0: version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" @@ -3971,6 +4748,13 @@ semver@^6.3.0: resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.0.0, semver@^7.3.8: + version "7.3.8" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" + semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" @@ -4056,6 +4840,15 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + signal-exit@^3.0.3: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" @@ -4128,6 +4921,30 @@ sprintf-js@~1.0.2: resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= +standard-engine@^15.0.0: + version "15.0.0" + resolved "https://registry.yarnpkg.com/standard-engine/-/standard-engine-15.0.0.tgz#e37ca2e1a589ef85431043a3e87cb9ce95a4ca4e" + integrity sha512-4xwUhJNo1g/L2cleysUqUv7/btn7GEbYJvmgKrQ2vd/8pkTmN8cpqAZg+BT8Z1hNeEH787iWUdOpL8fmApLtxA== + dependencies: + get-stdin "^8.0.0" + minimist "^1.2.6" + pkg-conf "^3.1.0" + xdg-basedir "^4.0.0" + +standard@^17.0.0: + version "17.0.0" + resolved "https://registry.yarnpkg.com/standard/-/standard-17.0.0.tgz#85718ecd04dc4133908434660788708cca855aa1" + integrity sha512-GlCM9nzbLUkr+TYR5I2WQoIah4wHA2lMauqbyPLV/oI5gJxqhHzhjl9EG2N0lr/nRqI3KCbCvm/W3smxvLaChA== + dependencies: + eslint "^8.13.0" + eslint-config-standard "17.0.0" + eslint-config-standard-jsx "^11.0.0" + eslint-plugin-import "^2.26.0" + eslint-plugin-n "^15.1.0" + eslint-plugin-promise "^6.0.0" + eslint-plugin-react "^7.28.0" + standard-engine "^15.0.0" + "statuses@>= 1.5.0 < 2", statuses@~1.5.0: version "1.5.0" resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" @@ -4173,6 +4990,20 @@ string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string.prototype.matchall@^4.0.7: + version "4.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz#3bf85722021816dcd1bf38bb714915887ca79fd3" + integrity sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + get-intrinsic "^1.1.3" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + regexp.prototype.flags "^1.4.3" + side-channel "^1.0.4" + string.prototype.trimend@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz" @@ -4181,6 +5012,15 @@ string.prototype.trimend@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" +string.prototype.trimend@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" + integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + string.prototype.trimstart@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz" @@ -4189,6 +5029,15 @@ string.prototype.trimstart@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" +string.prototype.trimstart@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" + integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" @@ -4217,12 +5066,17 @@ strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@3.1.1: +strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -4289,6 +5143,11 @@ terser@^5.7.2: commander "^2.20.0" source-map-support "~0.5.20" +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" @@ -4344,11 +5203,28 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== +tsconfig-paths@^3.14.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" + integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.6" + strip-bom "^3.0.0" + tslib@^2.0.0, tslib@^2.3.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== +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + type-check@~0.3.2: version "0.3.2" resolved "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz" @@ -4361,6 +5237,16 @@ type-detect@^4.0.0, type-detect@^4.0.5: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" + integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ== + type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" @@ -4384,6 +5270,16 @@ unbox-primitive@^1.0.0: has-symbols "^1.0.2" which-boxed-primitive "^1.0.2" +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + undefsafe@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" @@ -4636,7 +5532,7 @@ with@^7.0.0: assert-never "^1.2.1" babel-walk "3.0.0-canary-5" -word-wrap@~1.2.3: +word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== @@ -4679,6 +5575,11 @@ ws@^8.4.0, ws@^8.8.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0" integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== +xdg-basedir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" + integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== + xml-name-validator@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835"