diff --git a/.changeset/grumpy-shirts-yell.md b/.changeset/grumpy-shirts-yell.md new file mode 100644 index 0000000000..556ad232af --- /dev/null +++ b/.changeset/grumpy-shirts-yell.md @@ -0,0 +1,5 @@ +--- +"@vue-storefront/nuxt": minor +--- + +Handling buildId for better CND caching. diff --git a/.changeset/orange-lizards-peel.md b/.changeset/orange-lizards-peel.md new file mode 100644 index 0000000000..2f85ed7d6a --- /dev/null +++ b/.changeset/orange-lizards-peel.md @@ -0,0 +1,5 @@ +--- +"@vue-storefront/next": minor +--- + +Handling buildId for better middleware reuests caching. diff --git a/.changeset/plenty-queens-glow.md b/.changeset/plenty-queens-glow.md new file mode 100644 index 0000000000..89b71de3f7 --- /dev/null +++ b/.changeset/plenty-queens-glow.md @@ -0,0 +1,5 @@ +--- +"@vue-storefront/sdk": minor +--- + +Extending SDK of custom method config diff --git a/docs/content/4.sdk/2.getting-started/2.middleware-module.md b/docs/content/4.sdk/2.getting-started/2.middleware-module.md index 676e4351e2..a0b2f54ab7 100644 --- a/docs/content/4.sdk/2.getting-started/2.middleware-module.md +++ b/docs/content/4.sdk/2.getting-started/2.middleware-module.md @@ -126,6 +126,7 @@ The `middlewareModule` accepts the following options: - `apiUrl` - the URL of the middleware server, - `ssrApiUrl` - (Optional) the URL of the middleware server during SSR, - `defaultRequestConfig` - (Optional) default request config for each request, +- `methodsRequestConfig` - (Optional) custom request config for each request, - `httpClient` - (Optional) a custom HTTP client, - `errorHandler` - (Optional) a custom error handler for HTTP requests. @@ -156,6 +157,55 @@ export const sdk = initSDK({ Once you have added the `middlewareModule` to your SDK, you can use it to make requests to the Alokai Middleware. +### Defining Methods Custom Config + +Under the `methodsRequestConfig` you can register your own configuration for any dedicated method. +Existing or custom one. Specifically useful for defining custom headers, e.g. for caching, like `Cache-Control`, or method type. + +Provided config should be of type: + +```typescript +type RequestConfig = { + method?: "GET" | "POST"; + headers?: Record; +}; + +type MethodsRequestConfig = Record; +``` + +#### Config Definition + +```typescript +import type { + ExtendedConfigEndpoints, + MethodsConfig, +} from "@vue-storefront/sdk"; +import type { UnifiedEndpoints } from '[backend]/types'; + +type CustomMethods = 'getUniqueData'; + +const customMethodsRequestConfig = { + getUniqueData: { + method: "GET", + headers: { + "Cache-Control": "custom-cache-rules", + }, + }, +} satisfies MethodsConfig; + +export const sdk = initSDK({ + commerce: buildModule( + middlewareModule>, + { + // ... other config options + methodsRequestConfig: { + ...customMethodsRequestConfig, + }, + } + ), +}); +``` + ## Usage Once you have added the `middlewareModule` to your SDK, you can use it to make requests to the Server Middleware. diff --git a/docs/nuxt.config.ts b/docs/nuxt.config.ts index c53ee3581b..17f209bc11 100644 --- a/docs/nuxt.config.ts +++ b/docs/nuxt.config.ts @@ -1,4 +1,9 @@ // https://nuxt.com/docs/api/configuration/nuxt-config export default defineNuxtConfig({ extends: ["sf-docs-base"], + vite: { + define: { + __NUXT_ASYNC_CONTEXT__: false, + }, + }, }); diff --git a/package.json b/package.json index 3f5d2e9045..a028e8358e 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "scripts": { "prepare": "husky install", "build": "lerna run build", + "build:middleware": "cd packages/middleware && yarn build", "test": "lerna run test", "test:unit": "lerna run test:unit", "test:integration": "lerna run test:integration", diff --git a/packages/next/src/sdk/index.tsx b/packages/next/src/sdk/index.tsx index a83506d962..e3773c4e05 100644 --- a/packages/next/src/sdk/index.tsx +++ b/packages/next/src/sdk/index.tsx @@ -46,19 +46,26 @@ export function createSdk>( options: CreateSdkOptions, configDefinition: Config ): CreateSdkReturn { - function getSdk(dynamicContext: GetSdkContext = { }) { + function getSdk(dynamicContext: GetSdkContext = {}) { const { getRequestHeaders } = resolveDynamicContext(dynamicContext); const middlewareUrl = composeMiddlewareUrl({ options, headers: getRequestHeaders(), }); + if (dynamicContext.buildId && typeof dynamicContext.buildId === "string") { + middlewareModule({ + buildId: dynamicContext.buildId, + apiUrl: "", + cdnCacheBustingId: "", + }); + } const resolvedConfig = configDefinition({ defaults: contextConfig, buildModule, middlewareModule, getRequestHeaders, - middlewareUrl + middlewareUrl, }); return initSDK(resolvedConfig); diff --git a/packages/next/src/sdk/types.ts b/packages/next/src/sdk/types.ts index 7914adeeef..7b058acb9e 100644 --- a/packages/next/src/sdk/types.ts +++ b/packages/next/src/sdk/types.ts @@ -1,6 +1,7 @@ import { SDKApi, buildModule, middlewareModule } from "@vue-storefront/sdk"; import { ReactNode } from "react"; import type { contextConfig } from "@storefront/shared"; + export type GetSdkContext = { /** * A function that returns the request headers. @@ -8,6 +9,7 @@ export type GetSdkContext = { getRequestHeaders?: () => | Record | Headers; + buildId?: string; }; export type DynamicContext = { diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 72c6ac2653..c99755991d 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -41,5 +41,8 @@ "nuxt": "3.7.4", "start-server-and-test": "^2.0.3", "vitest": "^0.34.6" + }, + "resolutions": { + "semver": "7.3.2" } } diff --git a/packages/nuxt/src/runtime/defineSdkConfig.template b/packages/nuxt/src/runtime/defineSdkConfig.template index 2eb6ff246b..34e6c62800 100644 --- a/packages/nuxt/src/runtime/defineSdkConfig.template +++ b/packages/nuxt/src/runtime/defineSdkConfig.template @@ -30,7 +30,7 @@ const moduleConfig: SdkModuleOptions = <%= options.moduleConfig %>; * ContentfulModuleType, * } from "@vsf-enterprise/contentful-sdk"; * import type { UnifiedApiEndpoints } from "../storefront-middleware/types"; - * + * * export default defineSdkConfig( * ({ buildModule, middlewareModule, middlewareUrl, getCookieHeader }) => ({ * unified: buildModule(middlewareModule, { @@ -44,7 +44,7 @@ const moduleConfig: SdkModuleOptions = <%= options.moduleConfig %>; * ); * ``` */ -export function defineSdkConfig(config: Config) { +export function defineSdkConfig(config: Config, dynamicContext?: { buildId?: string }) { return () => { const nuxtApp = useNuxtApp() const runtimeConfig = useRuntimeConfig(); @@ -59,6 +59,13 @@ export function defineSdkConfig(config: Config) { options: resolvedOptions, headers: requestHeaders, }); + if (dynamicContext.buildId && typeof dynamicContext.buildId === "string") { + middlewareModule({ + buildId: dynamicContext.buildId, + apiUrl: '', + cdnCacheBustingId: '', + }); + } const getCookieHeader = () => useRequestHeaders(["cookie"]); const getRequestHeaders = () => useRequestHeaders(); diff --git a/packages/sdk/src/bootstrap.ts b/packages/sdk/src/bootstrap.ts index d972ff233c..d3ebe7237a 100644 --- a/packages/sdk/src/bootstrap.ts +++ b/packages/sdk/src/bootstrap.ts @@ -50,7 +50,7 @@ export const initSDK = (sdkConfig: T): SDKApi => { their property descriptors. The problem is that non-writeable and non-configurable properties cannot be altered by Proxy. See step 10 of the below algorithm https://262.ecma-international.org/8.0/#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver - + Due to this, we recreate connector but without property descriptors. */ diff --git a/packages/sdk/src/modules/middlewareModule/module.ts b/packages/sdk/src/modules/middlewareModule/module.ts index e130cf027a..a44b760eb0 100644 --- a/packages/sdk/src/modules/middlewareModule/module.ts +++ b/packages/sdk/src/modules/middlewareModule/module.ts @@ -46,10 +46,15 @@ import { getRequestSender } from "./utils"; * })); * ``` */ +let storedBuildId: string | undefined; export const middlewareModule = ( options: Options ) => { - const requestSender = getRequestSender(options); + storedBuildId = options.buildId ?? storedBuildId; + const requestSender = getRequestSender({ + ...options, + buildId: storedBuildId, + }); return { connector: connector(requestSender), diff --git a/packages/sdk/src/modules/middlewareModule/types.ts b/packages/sdk/src/modules/middlewareModule/types.ts index 94fe565916..080f3398be 100644 --- a/packages/sdk/src/modules/middlewareModule/types.ts +++ b/packages/sdk/src/modules/middlewareModule/types.ts @@ -264,6 +264,11 @@ export type Options< * Unique identifier for CDN cache busting. */ cdnCacheBustingId: string; + + /** + * Dedicated property to control request caching. + */ + buildId?: string; }; /** @@ -280,3 +285,35 @@ export type Methods = { ...params: [...Parameters, config?: MethodConfig] ) => ReturnType; }; + +/** + * Represents an extension of the `EndpointsConstraint` type. + * It allows for additional methods to be added to the endpoints, with their names specified by the `MethodNames` type parameter. + * The methods can be of any function type, as indicated by the `AnyFunction` type. + * + * @template Endpoints - A type that extends `EndpointsConstraint`, representing the existing endpoints. + * @template MethodNames - A string type representing the names of additional methods to be added to the endpoints. Defaults to `string`. + * + * @property {[K in keyof Endpoints | MethodNames]: AnyFunction} - A mapped type, where each key is either a key of `Endpoints` or a `MethodNames` value, and each value is a function of any type. + */ +export type ExtendedConfigEndpoints< + Endpoints extends EndpointsConstraint, + MethodNames extends string = string +> = { + [K in keyof Endpoints | MethodNames]: AnyFunction; +}; + +/** + * Represents the configuration for methods in the SDK. + * It is derived from the `Options` type, specifically the `methodsRequestConfig` property. + * The `Endpoints` type parameter represents the existing endpoints, while the `MethodNames` type parameter represents additional methods. + * + * @template Endpoints - A type that extends `EndpointsConstraint`, representing the existing endpoints. + * @template MethodNames - A string type representing the names of additional methods to be added to the endpoints. Defaults to `string`. + */ +export type MethodsConfig< + Endpoints extends EndpointsConstraint, + MethodNames extends string = string +> = Options< + ExtendedConfigEndpoints +>["methodsRequestConfig"]; diff --git a/packages/sdk/src/modules/middlewareModule/utils/getRequestSender.ts b/packages/sdk/src/modules/middlewareModule/utils/getRequestSender.ts index b2305021b1..3208154d19 100644 --- a/packages/sdk/src/modules/middlewareModule/utils/getRequestSender.ts +++ b/packages/sdk/src/modules/middlewareModule/utils/getRequestSender.ts @@ -23,6 +23,7 @@ export const getRequestSender = (options: Options): RequestSender => { defaultRequestConfig = {}, methodsRequestConfig = {}, cdnCacheBustingId, + buildId, } = options; const getUrl = ( @@ -116,7 +117,11 @@ export const getRequestSender = (options: Options): RequestSender => { const methodConfig = methodsRequestConfig[methodName] || {}; const finalMethod = method || methodConfig.method || defaultRequestConfig.method || "POST"; - const finalUrl = getUrl(methodName, finalMethod, params); + const finalUrl = getUrl( + methodName, + finalMethod, + buildId ? [buildId, ...params] : params + ); const finalParams = finalMethod === "GET" ? [] : params; const finalConfig = getConfig( { method: finalMethod, headers, ...restConfig }, diff --git a/yarn.lock b/yarn.lock index ff8209467e..c3f8a6433d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5040,7 +5040,7 @@ "@vue-storefront/sdk@^1.4.0": version "1.5.0" - resolved "https://registry.yarnpkg.com/@vue-storefront/sdk/-/sdk-1.5.0.tgz#f283eb57a5113e355206a0590dab874a6739e8e8" + resolved "https://registry.npmjs.org/@vue-storefront/sdk/-/sdk-1.5.0.tgz#f283eb57a5113e355206a0590dab874a6739e8e8" integrity sha512-dV6CBCx3XcEdd9EmAtvyY5sPecRMYMDCpMcbbDKvRgzAh+VjCjvSr11PvRqHx3lSYeKQcQdQZtgkk95lEz07YQ== "@vue-storefront/theme-utilities@^0.2.0": @@ -5977,7 +5977,7 @@ axios@^0.27.2: follow-redirects "^1.14.9" form-data "^4.0.0" -axios@^1.0.0: +axios@^1.0.0, axios@^1.6.7: version "1.7.2" resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.2.tgz#b625db8a7051fbea61c35a3cbb3a1daa7b9c7621" integrity sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw== @@ -5995,15 +5995,6 @@ axios@^1.6.1: form-data "^4.0.0" proxy-from-env "^1.1.0" -axios@^1.6.7: - version "1.6.7" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.7.tgz#7b48c2e27c96f9c68a2f8f31e2ab19f59b06b0a7" - integrity sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA== - dependencies: - follow-redirects "^1.15.4" - form-data "^4.0.0" - proxy-from-env "^1.1.0" - axobject-query@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" @@ -7033,7 +7024,7 @@ check-types@^8.0.3: resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" integrity sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ== -chokidar@^3.4.3, chokidar@^3.5.1, chokidar@^3.5.2: +chokidar@^3.4.3, chokidar@^3.5.1: version "3.5.3" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -7048,7 +7039,7 @@ chokidar@^3.4.3, chokidar@^3.5.1, chokidar@^3.5.2: optionalDependencies: fsevents "~2.3.2" -chokidar@^3.5.3, chokidar@^3.6.0: +chokidar@^3.5.2, chokidar@^3.5.3, chokidar@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== @@ -10041,7 +10032,7 @@ focus-trap@^7.5.4: dependencies: tabbable "^6.2.0" -follow-redirects@^1.14.9, follow-redirects@^1.15.4, follow-redirects@^1.15.6: +follow-redirects@^1.14.9, follow-redirects@^1.15.6: version "1.15.6" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== @@ -11922,7 +11913,7 @@ isobject@^3.0.1: isomorphic-fetch@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" + resolved "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA== dependencies: node-fetch "^2.6.1" @@ -14540,7 +14531,7 @@ node-fetch@2.6.7, node-fetch@^2.6.7: node-fetch@^2.6.1: version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" @@ -14666,13 +14657,6 @@ nopt@^7.0.0: dependencies: abbrev "^2.0.0" -nopt@~1.0.10: - version "1.0.10" - resolved "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" - integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== - dependencies: - abbrev "1" - normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -18213,16 +18197,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -18345,7 +18320,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -18359,13 +18334,6 @@ strip-ansi@^3.0.0: dependencies: ansi-regex "^2.0.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -18843,11 +18811,9 @@ totalist@^3.0.0: integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ== touch@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" - integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== - dependencies: - nopt "~1.0.10" + version "3.1.1" + resolved "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz#097a23d7b161476435e5c1344a95c0f75b4a5694" + integrity sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA== tough-cookie@^4.0.0: version "4.1.3" @@ -20170,7 +20136,7 @@ whatwg-encoding@^1.0.5: whatwg-fetch@^3.4.1: version "3.6.20" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz#580ce6d791facec91d37c72890995a0b48d31c70" + resolved "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz#580ce6d791facec91d37c72890995a0b48d31c70" integrity sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg== whatwg-mimetype@^2.3.0: @@ -20349,7 +20315,7 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -20367,15 +20333,6 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"