From 5d232fd17847321cfc352de5491ad65708806bcc Mon Sep 17 00:00:00 2001 From: Michael Brich Date: Thu, 9 May 2024 14:35:31 -0700 Subject: [PATCH] Integrating custom verifiers and custom schemas both into same customTypes registry per schema. --- package.json | 4 +- src/custom/type/verifier.ts | 31 +++++++ src/custom/{schemas.ts => types.ts} | 72 ++++++++++++++-- src/custom/{schemas => types}/data.ts | 8 +- src/custom/{schemas => types}/init.ts | 8 +- src/index.ts | 6 +- src/schema.ts | 56 +++--------- src/schema/field/types.ts | 2 - src/schema/init.ts | 4 +- tests/schema.spec.ts | 57 +++++++++++- yarn.lock | 119 ++------------------------ 11 files changed, 187 insertions(+), 180 deletions(-) create mode 100644 src/custom/type/verifier.ts rename src/custom/{schemas.ts => types.ts} (61%) rename src/custom/{schemas => types}/data.ts (86%) rename src/custom/{schemas => types}/init.ts (89%) diff --git a/package.json b/package.json index 4047e17..3518eb3 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "@typescript-eslint/typescript-estree": "^7.5.0", "@typhonjs-typedoc/typedoc-pkg": "^0.0.5", "big.js": "^6.2.1", - "eslint": "^9.2.0", - "eslint-config-prettier": "^9.1.0", + "eslint": "^8.57.0", + "eslint-config-prettier": "^8.10.0", "eslint-plugin-prettier": "^5.1.3", "gulp": "^4.0.2", "jest": "^29.7.0", diff --git a/src/custom/type/verifier.ts b/src/custom/type/verifier.ts new file mode 100644 index 0000000..4e3249a --- /dev/null +++ b/src/custom/type/verifier.ts @@ -0,0 +1,31 @@ +/** + * MIT License + * + * Copyright (c) 2019 - 2024 Toreda, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +import {Fate} from '@toreda/fate'; + +/** + * @category Schemas - Custom Types + */ +export type CustomTypeVerifier = (value?: unknown | null) => Promise>; diff --git a/src/custom/schemas.ts b/src/custom/types.ts similarity index 61% rename from src/custom/schemas.ts rename to src/custom/types.ts index 557b3c1..b0d2e73 100644 --- a/src/custom/schemas.ts +++ b/src/custom/types.ts @@ -26,24 +26,26 @@ import {Log} from '@toreda/log'; import {Schema} from '../schema'; import {type SchemaData} from '../schema/data'; -import {type CustomSchemasInit} from './schemas/init'; -import {type CustomSchemasData} from './schemas/data'; +import {type CustomTypesInit} from './types/init'; +import {type CustomTypesData} from './types/data'; +import {CustomTypeVerifier} from './type/verifier'; +import {Fate} from '@toreda/fate'; /** - * @category Schemas + * @category Schemas - Custom Types */ -export class CustomSchemas { +export class CustomTypes, VerifiedT = InputT> { public readonly log: Log; public readonly registered: Map>>; - constructor(init: CustomSchemasInit) { + constructor(init: CustomTypesInit) { this.registered = new Map>>(); this.log = init.base.makeLog('schemaTypes'); this.registerTypes(init.data); } - public registerTypes(data?: CustomSchemasData): void { + public registerTypes(data?: CustomTypesData): void { if (!data) { return; } @@ -66,6 +68,26 @@ export class CustomSchemas { return this.registered.has(id); } + public hasSchema(id: string): boolean { + if (!this.has(id)) { + return false; + } + + const o = this.registered.get(id); + + return typeof o?.verify === 'function'; + } + + public hasVerifier(id: string): boolean { + if (!this.has(id)) { + return false; + } + + const o = this.registered.get(id); + + return typeof o === 'function'; + } + public register(id: string, schema: Schema>): boolean { if (typeof id !== 'string') { return false; @@ -92,4 +114,42 @@ export class CustomSchemas { return schema ? schema : null; } + + public getVerifier(id: string): CustomTypeVerifier | null { + if (typeof id !== 'string') { + return null; + } + + const o = this.registered.get(id); + + return typeof o === 'function' ? o : null; + } + + public getSchema(id: string): Schema> | null { + if (typeof id !== 'string') { + return null; + } + + const schema = this.registered.get(id); + if (typeof schema?.verify !== 'function') { + return null; + } + + return schema; + } + + public async verifyValue(type: string, value: unknown): Promise> { + const fate = new Fate(); + + return fate; + } + + public async verifySchema( + type: string, + value: unknown | SchemaData + ): Promise>> { + const fate = new Fate>(); + + return fate; + } } diff --git a/src/custom/schemas/data.ts b/src/custom/types/data.ts similarity index 86% rename from src/custom/schemas/data.ts rename to src/custom/types/data.ts index 541964f..7a571f5 100644 --- a/src/custom/schemas/data.ts +++ b/src/custom/types/data.ts @@ -6,7 +6,7 @@ * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights - * to use, copy, modify, mezzwrge, publish, distribute, sublicense, and/or sell + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: @@ -27,8 +27,8 @@ import {Schema} from '../../schema'; import {type SchemaData} from '../../schema/data'; /** - * @category Schemas + * @category Schemas - Custom Types */ -export interface CustomSchemasData { - [k: string]: Schema>; +export interface CustomTypesData { + [k: string]: Schema; } diff --git a/src/custom/schemas/init.ts b/src/custom/types/init.ts similarity index 89% rename from src/custom/schemas/init.ts rename to src/custom/types/init.ts index e593cbd..b480c73 100644 --- a/src/custom/schemas/init.ts +++ b/src/custom/types/init.ts @@ -24,12 +24,12 @@ */ import {Log} from '@toreda/log'; -import {type CustomSchemasData} from './data'; +import {type CustomTypesData} from './data'; /** - * @category Custom Types + * @category Schemas - Custom Types */ -export interface CustomSchemasInit { - data?: CustomSchemasData; +export interface CustomTypesInit { + data?: CustomTypesData; base: Log; } diff --git a/src/index.ts b/src/index.ts index 97d1ade..1edd8ed 100644 --- a/src/index.ts +++ b/src/index.ts @@ -25,9 +25,9 @@ export {booleanVerify} from './boolean/verify'; export {Code} from './code'; export {CodeDefaults} from './code/defaults'; export {Codes} from './codes'; -export {CustomSchemas} from './custom/schemas'; -export {CustomSchemasData} from './custom/schemas/data'; -export {CustomSchemasInit} from './custom/schemas/init'; +export {CustomTypes} from './custom/types'; +export {CustomTypesData} from './custom/types/data'; +export {CustomTypesInit} from './custom/types/init'; export {divisible} from './divisible'; export {empty} from './empty'; export {emptyArrayVerify} from './empty/array/verify'; diff --git a/src/schema.ts b/src/schema.ts index 7f93d7e..ab5e547 100644 --- a/src/schema.ts +++ b/src/schema.ts @@ -37,7 +37,7 @@ import {isDbl, isFloat, isUrl} from '@toreda/strong-types'; import {isUInt} from './is/uint'; import {isInt} from './is/int'; import {type SchemaFieldData} from './schema/field/data'; -import {CustomSchemas} from './custom/schemas'; +import {CustomTypes} from './custom/types'; import {schemaBuiltIns} from './schema/built/ins'; /** @@ -48,7 +48,7 @@ export class Schema, VerifiedT = InputT> public readonly fields: Map>; public readonly cfg: SchemaConfig; public readonly outputTransform: SchemaOutputTransformer; - public readonly customSchemas: CustomSchemas; + public readonly customTypes: CustomTypes; public readonly base: Log; constructor(init: SchemaInit) { @@ -57,8 +57,8 @@ export class Schema, VerifiedT = InputT> this.cfg = new SchemaConfig(init.options); this.base = init.base.makeLog(`schema___${init.name}`); - this.customSchemas = new CustomSchemas({ - data: init.customSchemas, + this.customTypes = new CustomTypes({ + data: init.customTypes, base: this.base }); this.outputTransform = init.outputTransform ? init.outputTransform : simpleOutputTransform; @@ -139,12 +139,6 @@ export class Schema, VerifiedT = InputT> ); } - public customTypeSupported(type: SchemaFieldType, _value: unknown): _value is SchemaData { - const custom = this.customSchemas.get(type); - - return custom !== null && custom !== undefined; - } - public isBuiltIn(type: SchemaFieldType): boolean { if (typeof type !== 'string') { return false; @@ -158,7 +152,7 @@ export class Schema, VerifiedT = InputT> return true; } - return this.customSchemas.has(type); + return this.customTypes.has(type); } /** * Check if `type` is supported by the schema. Doesn't check if value actuallyz @@ -201,28 +195,6 @@ export class Schema, VerifiedT = InputT> } } - public async verifySchemaData( - type: SchemaFieldType, - value: SchemaData - ): Promise | null>> { - const fate = new Fate | null>({ - data: null - }); - - const custom = this.customSchemas.get(type); - if (!custom) { - return fate.setErrorCode(`unsupported_type:${type?.toString()}`); - } - - const result = await custom.verify(value as SchemaData, this.base); - if (!result.ok()) { - return fate.setErrorCode(`bad_schema_property:${result.errorCode()}`); - } - - fate.data = result.data; - return fate.setSuccess(true); - } - /** * Check if value's content matches `type`. Some types are primitives verified by type checks. * Others require more in depth validation, like URLs or Schema Data. @@ -231,32 +203,32 @@ export class Schema, VerifiedT = InputT> */ public async verifyValue( type: SchemaFieldType, - value: unknown + value: unknown | SchemaData ): Promise>> { const fate = new Fate>(); if (this.valueIsBuiltInType(type, value)) { + // TODO: Add validation here. Type match does not automatically prove valid content. fate.data = value; return fate.setSuccess(true); } - if (!this.customTypeSupported(type, value)) { + if (!this.customTypes.has(type)) { return fate.setErrorCode( schemaError(`unsupported_type:${typeof value}`, `${this.schemaName}.verifyValue`) ); } - const custom = this.customSchemas.get(type); - if (!custom) { - return fate.setErrorCode(`field_does_not_support_custom_type:${type?.toString()}`); + if (this.customTypes.hasSchema(type)) { + return this.customTypes.verifySchema(type, value); } - const result = await custom.verify(value, this.base); - if (!result.data) { - return fate.setErrorCode(`schema_verify_returned_no_data:${type?.toString()}`); + //const custom = await this.customTypes.verify(type, value, this.base); + if (this.customTypes.hasVerifier(type)) { + return this.customTypes.verifyValue(type, value); } - return result; + return fate.setErrorCode(`field_cant_verify_custom_type:${type?.toString()}`); } public async verify(data: SchemaData, base: Log): Promise> { diff --git a/src/schema/field/types.ts b/src/schema/field/types.ts index b26165c..1db4e35 100644 --- a/src/schema/field/types.ts +++ b/src/schema/field/types.ts @@ -34,7 +34,6 @@ export const schemaFieldTypes: SchemaFieldType[] = [ 'array', 'bigint', 'boolean', - 'custom', 'datetime', 'dbl', 'double', @@ -46,7 +45,6 @@ export const schemaFieldTypes: SchemaFieldType[] = [ 'null', 'number', 'real', - 'schema', 'string', 'time', 'uint', diff --git a/src/schema/init.ts b/src/schema/init.ts index 7085e81..8cf74e2 100644 --- a/src/schema/init.ts +++ b/src/schema/init.ts @@ -27,7 +27,7 @@ import {type SchemaFieldData} from './field/data'; import type {SchemaOptions} from './options'; import {type SchemaOutputTransformer} from './output/transformer'; import {Log} from '@toreda/log'; -import {type CustomSchemasData} from '../custom/schemas/data'; +import {type CustomTypesData} from '../custom/types/data'; /** * @name Schema Init @@ -51,6 +51,6 @@ export interface SchemaInit { */ options?: SchemaOptions; outputTransform?: SchemaOutputTransformer; - customSchemas?: CustomSchemasData; + customTypes?: CustomTypesData; base: Log; } diff --git a/tests/schema.spec.ts b/tests/schema.spec.ts index 5919ddb..f0c942f 100644 --- a/tests/schema.spec.ts +++ b/tests/schema.spec.ts @@ -9,6 +9,53 @@ import {SchemaField} from '../src'; const EMPTY_OBJECT = {}; const EMPTY_STRING = ''; +class SampleSchemaSubB extends Schema { + constructor(base: Log) { + super({ + name: 'SchemaB', + fields: [ + { + name: 'str2b', + types: ['string'] + }, + { + name: 'int2b', + types: ['number'] + } + ], + options: {}, + base: base + }); + } +} + +class SampleSchemaSubA extends Schema { + constructor(schemaB: SampleSchemaSubB, base: Log) { + super({ + name: 'SampleSchema', + fields: [ + { + name: 'str1a', + types: ['string'] + }, + { + name: 'int1a', + types: ['number'] + }, + { + name: 'bool1a', + types: ['boolean', 'null'] + } + ], + options: {}, + customTypes: { + customtype2: schemaB + }, + base: base + }); + } +} + class SampleSchema extends Schema { constructor(base: Log) { super({ @@ -39,9 +86,16 @@ interface SampleData extends SchemaData { bool1: boolean; } +interface SampleBData extends SchemaData { + str2b: string; + int2b: number; +} + describe('schemaVerify', () => { let sampleData: SampleData; let schema: SampleSchema; + let schemaSubA: SampleSchemaSubA; + let schemaSubB: SampleSchemaSubB; let base: Log; beforeAll(() => { @@ -50,7 +104,8 @@ describe('schemaVerify', () => { groupsStartEnabled: true, consoleEnabled: true }); - + schemaSubB = new SampleSchemaSubB(base); + schemaSubA = new SampleSchemaSubA(schemaSubB, base); schema = new SampleSchema(base); }); diff --git a/yarn.lock b/yarn.lock index 93ed23f..eca8187 100644 --- a/yarn.lock +++ b/yarn.lock @@ -313,28 +313,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/eslintrc@^3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.0.2.tgz#36180f8e85bf34d2fe3ccc2261e8e204a411ab4e" - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^10.0.1" - globals "^14.0.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" - "@eslint/js@8.57.0": version "8.57.0" resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f" -"@eslint/js@9.2.0": - version "9.2.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.2.0.tgz#b0a9123e8e91a3d9a2eed3a04a6ed44fdab639aa" - "@gulp-sourcemaps/identity-map@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz#a6e8b1abec8f790ec6be2b8c500e6e68037c0019" @@ -360,26 +342,14 @@ debug "^4.3.1" minimatch "^3.0.5" -"@humanwhocodes/config-array@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" - dependencies: - "@humanwhocodes/object-schema" "^2.0.3" - debug "^4.3.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" -"@humanwhocodes/object-schema@^2.0.2", "@humanwhocodes/object-schema@^2.0.3": +"@humanwhocodes/object-schema@^2.0.2": version "2.0.3" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" -"@humanwhocodes/retry@^0.2.3": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.2.4.tgz#4f3059423823bd8176132ceea9447dee101dfac1" - "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -1619,7 +1589,7 @@ acorn@^7.1.1: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" -acorn@^8.11.3, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: +acorn@^8.2.4, acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: version "8.11.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" @@ -2857,14 +2827,10 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@^8.5.0: +eslint-config-prettier@^8.10.0, eslint-config-prettier@^8.5.0: version "8.10.0" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" -eslint-config-prettier@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" - eslint-plugin-prettier@^4.0.0: version "4.2.1" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" @@ -2892,22 +2858,11 @@ eslint-scope@^7.2.2: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-scope@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.0.1.tgz#a9601e4b81a0b9171657c343fb13111688963cfc" - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" -eslint-visitor-keys@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz#e3adc021aa038a2a8e0b2f8b0ce8f66b9483b1fb" - -eslint@^8.14.0: +eslint@^8.14.0, eslint@^8.57.0: version "8.57.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668" dependencies: @@ -2950,45 +2905,6 @@ eslint@^8.14.0: strip-ansi "^6.0.1" text-table "^0.2.0" -eslint@^9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.2.0.tgz#0700ebc99528753315d78090876911d3cdbf19fe" - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^3.0.2" - "@eslint/js" "9.2.0" - "@humanwhocodes/config-array" "^0.13.0" - "@humanwhocodes/module-importer" "^1.0.1" - "@humanwhocodes/retry" "^0.2.3" - "@nodelib/fs.walk" "^1.2.8" - ajv "^6.12.4" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - escape-string-regexp "^4.0.0" - eslint-scope "^8.0.1" - eslint-visitor-keys "^4.0.0" - espree "^10.0.1" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^8.0.0" - find-up "^5.0.0" - glob-parent "^6.0.2" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - 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.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - esniff@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308" @@ -2998,14 +2914,6 @@ esniff@^2.0.1: event-emitter "^0.3.5" type "^2.7.2" -espree@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-10.0.1.tgz#600e60404157412751ba4a6f3a2ee1a42433139f" - dependencies: - acorn "^8.11.3" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^4.0.0" - espree@^9.6.0, espree@^9.6.1: version "9.6.1" resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" @@ -3205,12 +3113,6 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -file-entry-cache@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f" - dependencies: - flat-cache "^4.0.0" - filing-cabinet@^4.1.6: version "4.2.0" resolved "https://registry.yarnpkg.com/filing-cabinet/-/filing-cabinet-4.2.0.tgz#bd81241edce6e0c051882bef7b69ffa4c017baf9" @@ -3310,13 +3212,6 @@ flat-cache@^3.0.4: keyv "^4.5.3" rimraf "^3.0.2" -flat-cache@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c" - dependencies: - flatted "^3.2.9" - keyv "^4.5.4" - flat@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" @@ -3521,10 +3416,6 @@ globals@^13.19.0: dependencies: type-fest "^0.20.2" -globals@^14.0.0: - version "14.0.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" - globby@^11.0.1, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" @@ -4880,7 +4771,7 @@ just-debounce@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.1.0.tgz#2f81a3ad4121a76bc7cb45dbf704c0d76a8e5ddf" -keyv@^4.5.3, keyv@^4.5.4: +keyv@^4.5.3: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" dependencies: