feat(api): create a demo type provider for typebox (#49536)

* feat: create a demo type provider for typebox

* feat: validate reply + share type

* fix: prettify
This commit is contained in:
Oliver Eyton-Williams
2023-03-15 15:21:25 +01:00
committed by GitHub
parent ea83d87869
commit c2d149ba85
5 changed files with 115 additions and 39 deletions
+6 -1
View File
@@ -4,11 +4,13 @@ import middie from '@fastify/middie';
import fastifySession from '@fastify/session';
import fastifyCookie from '@fastify/cookie';
import MongoStore from 'connect-mongo';
import type { TypeBoxTypeProvider } from '@fastify/type-provider-typebox';
import jwtAuthz from './plugins/fastify-jwt-authz';
import sessionAuth from './plugins/session-auth';
import { testRoutes } from './routes/test';
import { auth0Routes } from './routes/auth0';
import { testValidatedRoutes } from './routes/validation-test';
import { testMiddleware } from './middleware';
import {
@@ -24,7 +26,9 @@ import prismaPlugin from './db/prisma';
const fastify = Fastify({
logger: { level: NODE_ENV === 'development' ? 'debug' : 'fatal' }
});
}).withTypeProvider<TypeBoxTypeProvider>();
export type FastifyInstanceWithTypeProvider = typeof fastify;
fastify.get('/', async (_request, _reply) => {
return { hello: 'world' };
@@ -61,6 +65,7 @@ const start = async () => {
void fastify.register(testRoutes);
void fastify.register(auth0Routes, { prefix: '/auth0' });
void fastify.register(testValidatedRoutes);
try {
const port = Number(PORT);
+3 -1
View File
@@ -9,6 +9,7 @@
"@fastify/session": "^10.1.1",
"@prisma/client": "4.10.1",
"connect-mongo": "4.6.0",
"@sinclair/typebox": "0.25.24",
"fastify": "4.14.1",
"fastify-auth0-verify": "^1.0.0",
"fastify-plugin": "^4.3.0",
@@ -46,6 +47,7 @@
},
"version": "0.0.1",
"devDependencies": {
"prisma": "4.10.1"
"prisma": "4.10.1",
"@fastify/type-provider-typebox": "2.4.0"
}
}
+61
View File
@@ -0,0 +1,61 @@
import { Type } from '@sinclair/typebox';
import type { FastifyInstanceWithTypeProvider } from '..';
import { responseSchema, subSchema } from '../schemas/example';
export const testValidatedRoutes = (
fastify: FastifyInstanceWithTypeProvider,
_options: never,
done: (err?: Error) => void
): void => {
fastify.get(
'/route-with-validation',
{
schema: {
querystring: Type.Object({
foo: Type.Number(),
bar: Type.String()
})
}
},
request => {
const { foo, bar } = request.query;
// Eslint can use the types given by TypeBoxTypeProvider:
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
const fooBar = foo + bar;
return { foo, bar, fooBar };
}
);
fastify.post(
'/route-with-validation-shared-schema',
{
schema: {
body: Type.Object({
foo: Type.Number(),
bar: Type.String(),
sub: subSchema
}),
response: {
200: responseSchema
}
}
},
request => {
const { foo, bar } = request.body;
// The TypeProvider constrains this by requiring value: string and
// otherValue: boolean. Anything else is a type error. 'ignored' is
// neither type checked nor returned, so it's safe. 'optional' is
// self-explanatory.
return {
value: bar,
otherValue: !foo,
ignored: 'not in reply',
...(foo == 2 && { optional: 'optional' })
};
}
);
done();
};
+31
View File
@@ -0,0 +1,31 @@
import { Static, Type } from '@sinclair/typebox';
// The schema that TypeBox generates is compatible with ajv, e.g. the
// Type.Object call below puts the following object into subSchema.
/*
{
type: 'object',
properties: {
bat: { type: 'number' },
baz: { type: 'string' }
},
required: ['bat', 'baz']
}
*/
export const subSchema = Type.Object({
bat: Type.Integer(),
baz: Type.String()
});
export const responseSchema = Type.Object({
value: Type.String(),
otherValue: Type.Boolean(),
optional: Type.Optional(Type.String())
});
// The schema types would be the only code the client needs to import
// { value: string; otherValue: boolean; optional?: string | undefined;}
export type ResponseSchema = Static<typeof responseSchema>;
// { bat: number; baz: string; }
export type SubSchema = Static<typeof subSchema>;
+14 -37
View File
@@ -118,7 +118,9 @@ importers:
'@fastify/cookie': ^8.3.0
'@fastify/middie': '8.1'
'@fastify/session': ^10.1.1
'@fastify/type-provider-typebox': 2.4.0
'@prisma/client': 4.10.1
'@sinclair/typebox': 0.25.24
connect-mongo: 4.6.0
fastify: 4.14.1
fastify-auth0-verify: ^1.0.0
@@ -130,12 +132,14 @@ importers:
'@fastify/middie': 8.1.0
'@fastify/session': 10.1.1
'@prisma/client': 4.10.1_prisma@4.10.1
'@sinclair/typebox': 0.25.24
connect-mongo: 4.6.0_lw7oj3533zfvrhxigrep3g2fam
fastify: 4.14.1
fastify-auth0-verify: 1.0.0
fastify-plugin: 4.5.0
nodemon: 2.0.21
devDependencies:
'@fastify/type-provider-typebox': 2.4.0_naatsb2dmwxq3j32xoqzjtyzqm
prisma: 4.10.1
api-server:
@@ -4675,7 +4679,6 @@ packages:
ajv: 8.12.0
ajv-formats: 2.1.1_ajv@8.12.0
fast-uri: 2.2.0
dev: false
/@fastify/cookie/8.3.0:
resolution: {integrity: sha512-P9hY9GO11L20TnZ33XN3i0bt+3x0zaT7S0ohAzWO950E9PB2xnNhLYzPFJIGFi5AVN0yr5+/iZhWxeYvR6KCzg==}
@@ -4686,17 +4689,14 @@ packages:
/@fastify/deepmerge/1.3.0:
resolution: {integrity: sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==}
dev: false
/@fastify/error/3.2.0:
resolution: {integrity: sha512-KAfcLa+CnknwVi5fWogrLXgidLic+GXnLjijXdpl8pvkvbXU5BGa37iZO9FGvsh9ZL4y+oFi5cbHBm5UOG+dmQ==}
dev: false
/@fastify/fast-json-stringify-compiler/4.2.0:
resolution: {integrity: sha512-ypZynRvXA3dibfPykQN3RB5wBdEUgSGgny8Qc6k163wYPLD4mEGEDkACp+00YmqkGvIm8D/xYoHajwyEdWD/eg==}
dependencies:
fast-json-stringify: 5.6.2
dev: false
/@fastify/jwt/6.6.0:
resolution: {integrity: sha512-D5lYtj8M2Geh/njiNmC9DDw+1jVq9muc36xBrl8rp4n46f4a3vFNzJrCI4dcWIZqUmuki8hwM/zRSvU+Y5wy1g==}
@@ -4723,6 +4723,16 @@ packages:
safe-stable-stringify: 2.4.2
dev: false
/@fastify/type-provider-typebox/2.4.0_naatsb2dmwxq3j32xoqzjtyzqm:
resolution: {integrity: sha512-dP8KnpfyBD1FT1UxNWCRqSpKG69xYAK53q6MqUjuwYL7xvogXBbH/tpAMc1kZkKmgAHPT0migy9DaYtnkTbIIQ==}
peerDependencies:
'@sinclair/typebox': ^0.25.9
fastify: ^4.0.0
dependencies:
'@sinclair/typebox': 0.25.24
fastify: 4.14.1
dev: true
/@fortawesome/fontawesome-common-types/6.3.0:
resolution: {integrity: sha512-4BC1NMoacEBzSXRwKjZ/X/gmnbp/HU5Qqat7E8xqorUtBFZS+bwfGH5/wqOC2K6GV0rgEobp3OjGRMa5fK9pFg==}
engines: {node: '>=6'}
@@ -6193,7 +6203,6 @@ packages:
/@sinclair/typebox/0.25.24:
resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==}
dev: true
/@sindresorhus/is/0.14.0:
resolution: {integrity: sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==}
@@ -9101,7 +9110,6 @@ packages:
/abstract-logging/2.0.1:
resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==}
dev: false
/accept-language/3.0.18:
resolution: {integrity: sha512-sUofgqBPzgfcF20sPoBYGQ1IhQLt2LSkxTnlQSuLF3n5gPEqd5AimbvOvHEi0T1kLMiGVqPWzI5a9OteBRth3A==}
@@ -9262,7 +9270,6 @@ packages:
optional: true
dependencies:
ajv: 8.12.0
dev: false
/ajv-keywords/3.5.2_ajv@6.12.6:
resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==}
@@ -9482,7 +9489,6 @@ packages:
/archy/1.0.0:
resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==}
dev: false
/are-we-there-yet/2.0.0:
resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==}
@@ -9769,7 +9775,6 @@ packages:
/atomic-sleep/1.0.0:
resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
engines: {node: '>=8.0.0'}
dev: false
/automation-events/5.0.2:
resolution: {integrity: sha512-8mfgjeI22tlKeaGY8y0bDt93IIUJhQKR/ISTsnhhFkpAzCirPdQ/Rmfp3xakCTmIihLgDuIWcWygHWozYKVGyQ==}
@@ -9819,7 +9824,6 @@ packages:
fastq: 1.15.0
transitivePeerDependencies:
- supports-color
dev: false
/aws-sdk/2.1326.0:
resolution: {integrity: sha512-LSGiO4RSooupHnkvYbPOuOYqwAxmcnYinwIxBz4P1YI8ulhZZ/pypOj/HKqC629UyhY1ndSMtlM1l56U74UclA==}
@@ -11545,7 +11549,6 @@ packages:
dependencies:
base64-js: 1.5.1
ieee754: 1.2.1
dev: false
/builtin-modules/3.3.0:
resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
@@ -15494,14 +15497,12 @@ packages:
/fast-content-type-parse/1.0.0:
resolution: {integrity: sha512-Xbc4XcysUXcsP5aHUU7Nq3OwvHq97C+WnbkeIefpeYLX+ryzFJlU6OStFJhs6Ol0LkUGpcK+wL0JwfM+FCU5IA==}
dev: false
/fast-copy/2.1.7:
resolution: {integrity: sha512-ozrGwyuCTAy7YgFCua8rmqmytECYk/JYAMXcswOcm0qvGoE3tPb7ivBeIHTOK2DiapBhDZgacIhzhQIKU5TCfA==}
/fast-decode-uri-component/1.0.1:
resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==}
dev: false
/fast-deep-equal/3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
@@ -15550,7 +15551,6 @@ packages:
fast-deep-equal: 3.1.3
fast-uri: 2.2.0
rfdc: 1.3.0
dev: false
/fast-jwt/2.2.0:
resolution: {integrity: sha512-0KSVmXROvYRCHzmmNzFMEDkd1mfbKopW1TfM2fELv5hZb/blUhfc7bxY7dJiagvR116Vhg6itk9LPUGFRQjRSg==}
@@ -15568,19 +15568,16 @@ packages:
resolution: {integrity: sha512-qR2r+e3HvhEFmpdHMv//U8FnFlnYjaC6QKDuaXALDkw2kvHO8WDjxH+f/rHGR4Me4pnk8p9JAkRNTjYHAKRn2Q==}
dependencies:
fast-decode-uri-component: 1.0.1
dev: false
/fast-redact/3.1.2:
resolution: {integrity: sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==}
engines: {node: '>=6'}
dev: false
/fast-safe-stringify/2.1.1:
resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
/fast-uri/2.2.0:
resolution: {integrity: sha512-cIusKBIt/R/oI6z/1nyfe2FvGKVTohVRfvkOhvx0nCEW+xf5NoCXjAHcWp93uOUBchzYcsvPlrapAdX1uW+YGg==}
dev: false
/fast-url-parser/1.1.3:
resolution: {integrity: sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==}
@@ -15645,7 +15642,6 @@ packages:
tiny-lru: 10.0.1
transitivePeerDependencies:
- supports-color
dev: false
/fastparallel/2.4.1:
resolution: {integrity: sha512-qUmhxPgNHmvRjZKBFUNI0oZuuH9OlSIOXmJ98lhKPxMZZ7zS/Fi0wRHOihDSz0R1YiIOjxzOY4bq65YTcdBi2Q==}
@@ -15866,7 +15862,6 @@ packages:
fast-deep-equal: 3.1.3
fast-querystring: 1.1.1
safe-regex2: 2.0.0
dev: false
/find-up/1.1.2:
resolution: {integrity: sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==}
@@ -20213,7 +20208,6 @@ packages:
cookie: 0.5.0
process-warning: 2.1.0
set-cookie-parser: 2.5.1
dev: false
/lilconfig/2.0.6:
resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==}
@@ -22695,7 +22689,6 @@ packages:
/on-exit-leak-free/2.1.0:
resolution: {integrity: sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==}
dev: false
/on-finished/2.3.0:
resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
@@ -23479,11 +23472,9 @@ packages:
dependencies:
readable-stream: 4.3.0
split2: 4.1.0
dev: false
/pino-std-serializers/6.1.0:
resolution: {integrity: sha512-KO0m2f1HkrPe9S0ldjx7za9BJjeHqBku5Ch8JyxETxT8dEFGz1PwgrHaOQupVYitpzbFSYm7nnljxD8dik2c+g==}
dev: false
/pino/8.11.0:
resolution: {integrity: sha512-Z2eKSvlrl2rH8p5eveNUnTdd4AjJk8tAsLkHYZQKGHP4WTh2Gi1cOSOs3eWPqaj+niS3gj4UkoreoaWgF3ZWYg==}
@@ -23500,7 +23491,6 @@ packages:
safe-stable-stringify: 2.4.2
sonic-boom: 3.2.1
thread-stream: 2.3.0
dev: false
/pirates/4.0.5:
resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==}
@@ -24624,7 +24614,6 @@ packages:
/process-warning/2.1.0:
resolution: {integrity: sha512-9C20RLxrZU/rFnxWncDkuF6O999NdIf3E1ws4B0ZeY3sRVPzWBMsYDE2lxjxhiXxg464cQTgKUGm8/i6y2YGXg==}
dev: false
/process/0.11.10:
resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
@@ -24967,7 +24956,6 @@ packages:
/quick-format-unescaped/4.0.4:
resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
dev: false
/quick-lru/5.1.1:
resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
@@ -25791,7 +25779,6 @@ packages:
buffer: 6.0.3
events: 3.3.0
process: 0.11.10
dev: false
/readable-web-to-node-stream/3.0.2:
resolution: {integrity: sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==}
@@ -25820,7 +25807,6 @@ packages:
/real-require/0.2.0:
resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==}
engines: {node: '>= 12.13.0'}
dev: false
/rechoir/0.6.2:
resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==}
@@ -26462,7 +26448,6 @@ packages:
/ret/0.2.2:
resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==}
engines: {node: '>=4'}
dev: false
/retext-english/3.0.4:
resolution: {integrity: sha512-yr1PgaBDde+25aJXrnt3p1jvT8FVLVat2Bx8XeAWX13KXo8OT+3nWGU3HWxM4YFJvmfqvJYJZG2d7xxaO774gw==}
@@ -26640,12 +26625,10 @@ packages:
resolution: {integrity: sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==}
dependencies:
ret: 0.2.2
dev: false
/safe-stable-stringify/2.4.2:
resolution: {integrity: sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA==}
engines: {node: '>=10'}
dev: false
/safer-buffer/2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
@@ -26801,7 +26784,6 @@ packages:
/secure-json-parse/2.7.0:
resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==}
dev: false
/select-hose/2.0.0:
resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==}
@@ -26956,7 +26938,6 @@ packages:
/set-cookie-parser/2.5.1:
resolution: {integrity: sha512-1jeBGaKNGdEq4FgIrORu/N570dwoPYio8lSoYLWmX7sQ//0JY08Xh9o5pBcgmHQ/MbsYp/aZnOe1s1lIsbLprQ==}
dev: false
/set-value/2.0.1:
resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==}
@@ -27312,7 +27293,6 @@ packages:
resolution: {integrity: sha512-iITeTHxy3B9FGu8aVdiDXUVAcHMF9Ss0cCsAOo2HfCrmVGT3/DT5oYaeu0M/YKZDlKTvChEyPq0zI9Hf33EX6A==}
dependencies:
atomic-sleep: 1.0.0
dev: false
/source-list-map/2.0.1:
resolution: {integrity: sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==}
@@ -27470,7 +27450,6 @@ packages:
/split2/4.1.0:
resolution: {integrity: sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==}
engines: {node: '>= 10.x'}
dev: false
/sprintf-js/1.0.3:
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
@@ -28500,7 +28479,6 @@ packages:
resolution: {integrity: sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==}
dependencies:
real-require: 0.2.0
dev: false
/throat/6.0.2:
resolution: {integrity: sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==}
@@ -28554,7 +28532,6 @@ packages:
/tiny-lru/10.0.1:
resolution: {integrity: sha512-Vst+6kEsWvb17Zpz14sRJV/f8bUWKhqm6Dc+v08iShmIJ/WxqWytHzCTd6m88pS33rE2zpX34TRmOpAJPloNCA==}
engines: {node: '>=6'}
dev: false
/tinydate/1.3.0:
resolution: {integrity: sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w==}