diff --git a/.changeset/red-bugs-pump.md b/.changeset/red-bugs-pump.md new file mode 100644 index 000000000000..3dcc9d260b7a --- /dev/null +++ b/.changeset/red-bugs-pump.md @@ -0,0 +1,5 @@ +--- +'create-astro': patch +--- + +Uses `@bluwy/giget-core` instead of `giget` for smaller installation size when downloading the CLI diff --git a/packages/create-astro/package.json b/packages/create-astro/package.json index 35f29e83c6f9..c5833a3c622b 100644 --- a/packages/create-astro/package.json +++ b/packages/create-astro/package.json @@ -32,7 +32,7 @@ "//b": "DEPENDENCIES IS FOR UNBUNDLED PACKAGES", "dependencies": { "@astrojs/cli-kit": "^0.4.1", - "giget": "1.2.3" + "@bluwy/giget-core": "^0.1.0" }, "devDependencies": { "arg": "^5.0.2", diff --git a/packages/create-astro/src/actions/template.ts b/packages/create-astro/src/actions/template.ts index d67b54ee0176..e1775ee51d48 100644 --- a/packages/create-astro/src/actions/template.ts +++ b/packages/create-astro/src/actions/template.ts @@ -3,7 +3,7 @@ import type { Context } from './context.js'; import fs from 'node:fs'; import path from 'node:path'; import { color } from '@astrojs/cli-kit'; -import { downloadTemplate } from 'giget'; +import { downloadTemplate } from '@bluwy/giget-core'; import { error, info, title } from '../messages.js'; export async function template( @@ -125,14 +125,6 @@ export default async function copyTemplate(tmpl: string, ctx: Context) { throw new Error(`Unable to download template ${color.reset(tmpl)}`); } - // It's possible the repo exists (ex. `withastro/astro`), - // But the template route is invalid (ex. `withastro/astro/examples/DNE`). - // `giget` doesn't throw for this case, - // so check if the directory is still empty as a heuristic. - if (fs.readdirSync(ctx.cwd).length === 0) { - throw new Error(`Template ${color.reset(tmpl)} ${color.dim('is empty!')}`); - } - // Post-process in parallel const removeFiles = FILES_TO_REMOVE.map(async (file) => { const fileLoc = path.resolve(path.join(ctx.cwd, file)); diff --git a/packages/create-astro/src/actions/verify.ts b/packages/create-astro/src/actions/verify.ts index e620a9ca812c..7f446c8695cb 100644 --- a/packages/create-astro/src/actions/verify.ts +++ b/packages/create-astro/src/actions/verify.ts @@ -2,6 +2,7 @@ import type { Context } from './context.js'; import dns from 'node:dns/promises'; import { color } from '@astrojs/cli-kit'; +import { verifyTemplate } from '@bluwy/giget-core'; import { bannerAbort, error, info, log } from '../messages.js'; import { getTemplateTarget } from './template.js'; @@ -19,7 +20,8 @@ export async function verify( } if (ctx.template) { - const ok = await verifyTemplate(ctx.template, ctx.ref); + const target = getTemplateTarget(ctx.template, ctx.ref); + const ok = await verifyTemplate(target); if (!ok) { bannerAbort(); log(''); @@ -36,59 +38,3 @@ function isOnline(): Promise { () => false, ); } - -async function verifyTemplate(tmpl: string, ref?: string) { - const target = getTemplateTarget(tmpl, ref); - const { repo, subdir, ref: branch } = parseGitURI(target.replace('github:', '')); - const url = new URL(`/repos/${repo}/contents${subdir}?ref=${branch}`, 'https://api.github.com/'); - - let res = await fetch(url.toString(), { - headers: { - Accept: 'application/vnd.github+json', - 'X-GitHub-Api-Version': '2022-11-28', - }, - }); - - // If users hit a ratelimit, fallback to the GitHub website - if (res.status === 403) { - res = await fetch(`https://github.com/${repo}/tree/${branch}${subdir}`); - } - - return res.status === 200; -} - -// Adapted from https://github.com/unjs/giget/blob/main/src/_utils.ts -// MIT License - -// Copyright (c) Pooya Parsa - -// 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. -// Disable eslint rule to not touch the original code -// eslint-disable-next-line regexp/no-misleading-capturing-group -const GIT_RE = /^(?[\w.-]+\/[\w.-]+)(?[^#]+)?(?#[\w.-]+)?/; - -function parseGitURI(input: string) { - const m = GIT_RE.exec(input)?.groups; - if (!m) throw new Error(`Unable to parse "${input}"`); - return { - repo: m.repo, - subdir: m.subdir || '/', - ref: m.ref ? m.ref.slice(1) : 'main', - }; -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d2488100f115..c432f59b085d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4280,9 +4280,9 @@ importers: '@astrojs/cli-kit': specifier: ^0.4.1 version: 0.4.1 - giget: - specifier: 1.2.3 - version: 1.2.3 + '@bluwy/giget-core': + specifier: ^0.1.0 + version: 0.1.0 devDependencies: arg: specifier: ^5.0.2 @@ -5980,6 +5980,10 @@ packages: cpu: [x64] os: [win32] + '@bluwy/giget-core@0.1.0': + resolution: {integrity: sha512-cN/YvB0WW3hmYjAHeFqPMX4SWJNyWOBQCXwEbUP4kFPNFGK4xcB/+JDAclNXcL1MsTsB3FRqQtv5GGeRbXkv/A==} + engines: {node: '>=18'} + '@builder.io/partytown@0.10.2': resolution: {integrity: sha512-A9U+4PREWcS+CCYzKGIPovtGB/PBgnH/8oQyCE6Nr9drDJk6cMPpLQIEajpGPmG9tYF7N3FkRvhXm/AS9+0iKg==} engines: {node: '>=18.0.0'} @@ -7637,10 +7641,6 @@ packages: resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} engines: {node: '>= 14.16.0'} - chownr@2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} - ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} @@ -7649,9 +7649,6 @@ packages: resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} engines: {node: '>=8'} - citty@0.1.6: - resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} - clean-css@4.2.4: resolution: {integrity: sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==} engines: {node: '>= 4.0'} @@ -7750,10 +7747,6 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - consola@3.2.3: - resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} - engines: {node: ^14.18.0 || >=16.10.0} - content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -7903,9 +7896,6 @@ packages: resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} engines: {node: '>=12'} - defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -8361,10 +8351,6 @@ packages: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} - fs-minipass@2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - fsevents@2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -8397,10 +8383,6 @@ packages: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} - giget@1.2.3: - resolution: {integrity: sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==} - hasBin: true - github-slugger@2.0.0: resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} @@ -9205,33 +9187,16 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} - - minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} - minizlib@2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} - mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} mj-context-menu@0.6.1: resolution: {integrity: sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA==} - mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -9266,6 +9231,9 @@ packages: resolution: {integrity: sha512-TUes3xKIX33re4QzdxwZ6tdbodjmn3tWXCEc1uokiEmo14sI1EaGYNs2k3bU2pyyGNmBqFGAVl6jAGWd06AVIg==} engines: {node: ^18.0.0 || >=20.0.0} + nanotar@0.1.1: + resolution: {integrity: sha512-AiJsGsSF3O0havL1BydvI4+wR76sKT+okKRwWIaK96cZUnXqH0uNBOsHlbwZq3+m2BR1VKqHDVudl3gO4mYjpQ==} + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -9290,9 +9258,6 @@ packages: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} - node-fetch-native@1.6.4: - resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} - node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -9342,11 +9307,6 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - nypm@0.3.8: - resolution: {integrity: sha512-IGWlC6So2xv6V4cIDmoV0SwwWx7zLG086gyqkyumteH2fIgCAM4nDVFB2iDRszDvmdSVW9xb1N+2KjQ6C7d4og==} - engines: {node: ^14.16.0 || >=16.10.0} - hasBin: true - object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -9355,9 +9315,6 @@ packages: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} - ohash@1.1.3: - resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==} - on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -10370,10 +10327,6 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - tar@6.2.1: - resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} - engines: {node: '>=10'} - term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} @@ -10564,9 +10517,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - ufo@1.5.3: - resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} - uglify-js@3.17.4: resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} engines: {node: '>=0.8.0'} @@ -11054,9 +11004,6 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - yaml-language-server@1.15.0: resolution: {integrity: sha512-N47AqBDCMQmh6mBLmI6oqxryHRzi33aPFPsJhYy3VTUGCdLHYjGh4FZzpUjRlphaADBBkDmnkM/++KNIOHi5Rw==} hasBin: true @@ -11507,6 +11454,10 @@ snapshots: '@biomejs/cli-win32-x64@1.8.3': optional: true + '@bluwy/giget-core@0.1.0': + dependencies: + nanotar: 0.1.1 + '@builder.io/partytown@0.10.2': {} '@changesets/apply-release-plan@7.0.5': @@ -13366,16 +13317,10 @@ snapshots: dependencies: readdirp: 4.0.1 - chownr@2.0.0: {} - ci-info@3.9.0: {} ci-info@4.0.0: {} - citty@0.1.6: - dependencies: - consola: 3.2.3 - clean-css@4.2.4: dependencies: source-map: 0.6.1 @@ -13462,8 +13407,6 @@ snapshots: concat-map@0.0.1: {} - consola@3.2.3: {} - content-disposition@0.5.4: dependencies: safe-buffer: 5.2.1 @@ -13588,8 +13531,6 @@ snapshots: define-lazy-prop@3.0.0: {} - defu@6.1.4: {} - delayed-stream@1.0.0: {} depd@1.1.2: {} @@ -13996,10 +13937,6 @@ snapshots: jsonfile: 4.0.0 universalify: 0.1.2 - fs-minipass@2.1.0: - dependencies: - minipass: 3.3.6 - fsevents@2.3.2: optional: true @@ -14018,17 +13955,6 @@ snapshots: get-stream@8.0.1: {} - giget@1.2.3: - dependencies: - citty: 0.1.6 - consola: 3.2.3 - defu: 6.1.4 - node-fetch-native: 1.6.4 - nypm: 0.3.8 - ohash: 1.1.3 - pathe: 1.1.2 - tar: 6.2.1 - github-slugger@2.0.0: {} glob-parent@5.1.2: @@ -15225,25 +15151,12 @@ snapshots: minimist@1.2.8: {} - minipass@3.3.6: - dependencies: - yallist: 4.0.0 - - minipass@5.0.0: {} - minipass@7.1.2: {} - minizlib@2.1.2: - dependencies: - minipass: 3.3.6 - yallist: 4.0.0 - mitt@3.0.1: {} mj-context-menu@0.6.1: {} - mkdirp@1.0.4: {} - mri@1.2.0: {} mrmime@2.0.0: {} @@ -15266,6 +15179,8 @@ snapshots: nanostores@0.11.3: {} + nanotar@0.1.1: {} + natural-compare@1.4.0: {} negotiator@0.6.3: {} @@ -15287,8 +15202,6 @@ snapshots: node-domexception@1.0.0: {} - node-fetch-native@1.6.4: {} - node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 @@ -15335,20 +15248,10 @@ snapshots: dependencies: boolbase: 1.0.0 - nypm@0.3.8: - dependencies: - citty: 0.1.6 - consola: 3.2.3 - execa: 8.0.1 - pathe: 1.1.2 - ufo: 1.5.3 - object-assign@4.1.1: {} object-hash@3.0.0: {} - ohash@1.1.3: {} - on-finished@2.4.1: dependencies: ee-first: 1.1.1 @@ -16549,15 +16452,6 @@ snapshots: tapable@2.2.1: {} - tar@6.2.1: - dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 5.0.0 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 - term-size@2.2.1: {} terminal-link@3.0.0: @@ -16707,8 +16601,6 @@ snapshots: typescript@5.6.2: {} - ufo@1.5.3: {} - uglify-js@3.17.4: {} uhyphen@0.2.0: {} @@ -17214,8 +17106,6 @@ snapshots: yallist@3.1.1: {} - yallist@4.0.0: {} - yaml-language-server@1.15.0: dependencies: ajv: 8.17.1