diff --git a/e2e-tests/adapters/cypress/e2e/remote-file.cy.ts b/e2e-tests/adapters/cypress/e2e/remote-file.cy.ts
index 81b3acb000e2c..5f168eab76c80 100644
--- a/e2e-tests/adapters/cypress/e2e/remote-file.cy.ts
+++ b/e2e-tests/adapters/cypress/e2e/remote-file.cy.ts
@@ -222,12 +222,17 @@ for (const config of configs) {
it(`File CDN`, () => {
cy.get('[data-testid="file-public"]').then(async $urls => {
- const urls = Array.from(
- $urls.map((_, $url) => $url.getAttribute("href"))
+ const fileCdnFixtures = Array.from(
+ $urls.map((_, $url) => {
+ return {
+ urlWithoutOrigin: $url.getAttribute("href"),
+ allowed: $url.getAttribute("data-allowed") === "true",
+ }
+ })
)
// urls is array of href attribute, not absolute urls, so it already is stripped of origin
- for (const urlWithoutOrigin of urls) {
+ for (const { urlWithoutOrigin, allowed } of fileCdnFixtures) {
// using Netlify Image CDN
expect(urlWithoutOrigin).to.match(
new RegExp(`^${PATH_PREFIX}/_gatsby/file`)
@@ -235,7 +240,12 @@ for (const config of configs) {
const res = await fetch(urlWithoutOrigin, {
method: "HEAD",
})
- expect(res.ok).to.be.true
+ if (allowed) {
+ expect(res.ok).to.be.true
+ } else {
+ expect(res.ok).to.be.false
+ expect(res.status).to.be.equal(500)
+ }
}
})
})
diff --git a/e2e-tests/adapters/gatsby-node.ts b/e2e-tests/adapters/gatsby-node.ts
index e054bf7e56693..9342bb30fa191 100644
--- a/e2e-tests/adapters/gatsby-node.ts
+++ b/e2e-tests/adapters/gatsby-node.ts
@@ -47,6 +47,7 @@ export const createPages: GatsbyNode["createPages"] = async ({
url
filename
publicUrl
+ isAllowed
}
}
}
@@ -138,7 +139,9 @@ export const createSchemaCustomization: GatsbyNode["createSchemaCustomization"]
addRemoteFilePolyfillInterface(
schema.buildObjectType({
name: "MyRemoteFile",
- fields: {},
+ fields: {
+ isAllowed: `String!`,
+ },
interfaces: ["Node", "RemoteFile"],
}),
{
@@ -148,6 +151,13 @@ export const createSchemaCustomization: GatsbyNode["createSchemaCustomization"]
}
)
)
+
+ if (typeof actions.addRemoteFileAllowedUrl === `function`) {
+ actions.addRemoteFileAllowedUrl([
+ `https://images.unsplash.com/*`,
+ `https://www.gatsbyjs.com/*`,
+ ])
+ }
}
export const sourceNodes: GatsbyNode["sourceNodes"] = function sourceNodes({
@@ -191,6 +201,16 @@ export const sourceNodes: GatsbyNode["sourceNodes"] = function sourceNodes({
mimeType: "image/svg+xml",
filename: "Gatsby-Logo.svg",
type: `MyRemoteFile`,
+ isAllowed: true,
+ },
+ {
+ // svg is not considered for image cdn - file cdn will be used
+ name: "fileB.svg",
+ url: "https://www.not-allowed.com/not-allowed.svg",
+ mimeType: "image/svg+xml",
+ filename: "Gatsby-Logo.svg",
+ type: `MyRemoteFile`,
+ isAllowed: false,
},
]
diff --git a/e2e-tests/adapters/src/pages/routes/remote-file.jsx b/e2e-tests/adapters/src/pages/routes/remote-file.jsx
index c93c3f7eff70b..8f2ceba8a1756 100644
--- a/e2e-tests/adapters/src/pages/routes/remote-file.jsx
+++ b/e2e-tests/adapters/src/pages/routes/remote-file.jsx
@@ -43,7 +43,11 @@ const RemoteFile = ({ data }) => {
return (
@@ -91,6 +95,7 @@ export const pageQuery = graphql`
url
filename
publicUrl
+ isAllowed
}
}
}
diff --git a/e2e-tests/adapters/src/pages/routes/ssr/remote-file.jsx b/e2e-tests/adapters/src/pages/routes/ssr/remote-file.jsx
index 923831a179b6d..87477e2ea3b9c 100644
--- a/e2e-tests/adapters/src/pages/routes/ssr/remote-file.jsx
+++ b/e2e-tests/adapters/src/pages/routes/ssr/remote-file.jsx
@@ -43,7 +43,11 @@ const RemoteFile = ({ data }) => {
return (
@@ -98,6 +102,7 @@ export const pageQuery = graphql`
url
filename
publicUrl
+ isAllowed
}
}
}
diff --git a/e2e-tests/adapters/src/templates/remote-file-from-context.jsx b/e2e-tests/adapters/src/templates/remote-file-from-context.jsx
index d6532903dce06..4773a88beb1cb 100644
--- a/e2e-tests/adapters/src/templates/remote-file-from-context.jsx
+++ b/e2e-tests/adapters/src/templates/remote-file-from-context.jsx
@@ -42,7 +42,11 @@ const RemoteFile = ({ pageContext: data }) => {
return (
diff --git a/packages/gatsby-adapter-netlify/.babelrc b/packages/gatsby-adapter-netlify/.babelrc
index 84af48678d3f0..264f094569e08 100644
--- a/packages/gatsby-adapter-netlify/.babelrc
+++ b/packages/gatsby-adapter-netlify/.babelrc
@@ -3,7 +3,7 @@
[
"babel-preset-gatsby-package",
{
- "keepDynamicImports": ["./src/index.ts"]
+ "keepDynamicImports": ["./src/index.ts", "./src/allowed-remote-urls.ts"]
}
]
]
diff --git a/packages/gatsby-adapter-netlify/package.json b/packages/gatsby-adapter-netlify/package.json
index 0dd2e1552ae59..f5a230377d993 100644
--- a/packages/gatsby-adapter-netlify/package.json
+++ b/packages/gatsby-adapter-netlify/package.json
@@ -33,6 +33,7 @@
"dependencies": {
"@babel/runtime": "^7.20.13",
"@netlify/cache-utils": "^5.1.5",
+ "@netlify/config": "^20.10.0",
"@netlify/functions": "^1.6.0",
"cookie": "^0.5.0",
"fastq": "^1.15.0",
diff --git a/packages/gatsby-adapter-netlify/src/allowed-remote-urls.ts b/packages/gatsby-adapter-netlify/src/allowed-remote-urls.ts
new file mode 100644
index 0000000000000..daddb94d64a3d
--- /dev/null
+++ b/packages/gatsby-adapter-netlify/src/allowed-remote-urls.ts
@@ -0,0 +1,54 @@
+import type { Reporter, RemoteFileAllowedUrls } from "gatsby"
+
+export async function handleAllowedRemoteUrlsNetlifyConfig({
+ remoteFileAllowedUrls,
+ reporter,
+}: {
+ remoteFileAllowedUrls: RemoteFileAllowedUrls
+ reporter: Reporter
+}): Promise
{
+ const { resolveConfig } = await import(`@netlify/config`)
+ const cfg = await resolveConfig()
+
+ if (cfg?.config) {
+ const allowedUrlsInNetlifyToml: Array =
+ cfg.config.images?.remote_images ?? []
+
+ const allowedUrlsInNetlifyTomlRegexes = allowedUrlsInNetlifyToml.map(
+ regexSource => new RegExp(regexSource)
+ )
+
+ const missingAllowedUrlsInNetlifyToml: Array = []
+ for (const remoteFileAllowedUrl of remoteFileAllowedUrls) {
+ // test if url pattern already passes one of the regexes in netlify.toml
+ const isAlreadyAllowed = allowedUrlsInNetlifyTomlRegexes.some(
+ allowedRegex => allowedRegex.test(remoteFileAllowedUrl.urlPattern)
+ )
+
+ if (!isAlreadyAllowed) {
+ missingAllowedUrlsInNetlifyToml.push(remoteFileAllowedUrl.regexSource)
+ }
+ }
+
+ if (missingAllowedUrlsInNetlifyToml.length > 0) {
+ const entriesToAddToToml = `${missingAllowedUrlsInNetlifyToml
+ .map(
+ missingAllowedUrlInNetlifyToml =>
+ ` ${JSON.stringify(missingAllowedUrlInNetlifyToml)}`
+ )
+ .join(`,\n`)},\n`
+
+ if (typeof cfg.config.images?.remote_images === `undefined`) {
+ reporter.warn(
+ `Missing allowed URLs in your Netlify configuration. Add following to your netlify.toml:\n\`\`\`toml\n[images]\nremote_images = [\n${entriesToAddToToml}]\n\`\`\``
+ )
+ } else {
+ reporter.warn(
+ `Missing allowed URLs in your Netlify configuration. Add following entries to your existing \`images.remote_images\` configuration in netlify.toml:\n\`\`\`toml\n${entriesToAddToToml}\`\`\``
+ )
+ }
+ }
+ } else {
+ reporter.verbose(`[gatsby-adapter-netlify] no netlify.toml found`)
+ }
+}
diff --git a/packages/gatsby-adapter-netlify/src/file-cdn-handler.ts b/packages/gatsby-adapter-netlify/src/file-cdn-handler.ts
index cc8482c790c04..39f26c18c3023 100644
--- a/packages/gatsby-adapter-netlify/src/file-cdn-handler.ts
+++ b/packages/gatsby-adapter-netlify/src/file-cdn-handler.ts
@@ -3,6 +3,8 @@ import * as path from "path"
import packageJson from "gatsby-adapter-netlify/package.json"
+import type { RemoteFileAllowedUrls } from "gatsby"
+
export interface IFunctionManifest {
version: 1
functions: Array<
@@ -27,8 +29,10 @@ export interface IFunctionManifest {
export async function prepareFileCdnHandler({
pathPrefix,
+ remoteFileAllowedUrls,
}: {
pathPrefix: string
+ remoteFileAllowedUrls: RemoteFileAllowedUrls
}): Promise {
const functionId = `file-cdn`
@@ -48,21 +52,20 @@ export async function prepareFileCdnHandler({
)
const handlerSource = /* typescript */ `
- import type { Context } from "@netlify/edge-functions"
+ const allowedUrlPatterns = [${remoteFileAllowedUrls.map(
+ allowedUrl => `new RegExp(\`${allowedUrl.regexSource}\`)`
+ )}]
- export default async (req: Request, context: Context): Promise => {
+ export default async (req: Request): Promise => {
const url = new URL(req.url)
const remoteUrl = url.searchParams.get("url")
-
- // @todo: use allowed remote urls to decide wether request should be allowed
- // blocked by https://github.com/gatsbyjs/gatsby/pull/38719
- const isAllowed = true
+
+ const isAllowed = allowedUrlPatterns.some(allowedUrlPattern => allowedUrlPattern.test(remoteUrl))
if (isAllowed) {
- console.log(\`URL allowed\`, { remoteUrl })
return fetch(remoteUrl);
} else {
console.error(\`URL not allowed: \${remoteUrl}\`)
- return new Response("Not allowed", { status: 403 })
+ return new Response("Bad request", { status: 500 })
}
}
`
diff --git a/packages/gatsby-adapter-netlify/src/file-cdn-url-generator.ts b/packages/gatsby-adapter-netlify/src/file-cdn-url-generator.ts
index 1bc3e37abfe64..f24efd9c8281c 100644
--- a/packages/gatsby-adapter-netlify/src/file-cdn-url-generator.ts
+++ b/packages/gatsby-adapter-netlify/src/file-cdn-url-generator.ts
@@ -29,8 +29,8 @@ export const generateFileUrl: FileCdnUrlGeneratorFn = function generateFileUrl(
baseURL.searchParams.append(`url`, source.url)
baseURL.searchParams.append(`cd`, source.internal.contentDigest)
- return `${baseURL.pathname}${baseURL.search}`
}
+
return `${baseURL.pathname}${baseURL.search}`
}
diff --git a/packages/gatsby-adapter-netlify/src/index.ts b/packages/gatsby-adapter-netlify/src/index.ts
index 09c802a27fcf4..b34fafbb8718a 100644
--- a/packages/gatsby-adapter-netlify/src/index.ts
+++ b/packages/gatsby-adapter-netlify/src/index.ts
@@ -4,6 +4,7 @@ import { prepareFunctionVariants } from "./lambda-handler"
import { prepareFileCdnHandler } from "./file-cdn-handler"
import { handleRoutesManifest } from "./route-handler"
import packageJson from "gatsby-adapter-netlify/package.json"
+import { handleAllowedRemoteUrlsNetlifyConfig } from "./allowed-remote-urls"
interface INetlifyCacheUtils {
restore: (paths: Array) => Promise
@@ -84,9 +85,19 @@ const createNetlifyAdapter: AdapterInit = options => {
functionsManifest,
headerRoutes,
pathPrefix,
+ remoteFileAllowedUrls,
+ reporter,
}): Promise {
if (useNetlifyImageCDN) {
- await prepareFileCdnHandler({ pathPrefix })
+ await handleAllowedRemoteUrlsNetlifyConfig({
+ remoteFileAllowedUrls,
+ reporter,
+ })
+
+ await prepareFileCdnHandler({
+ pathPrefix,
+ remoteFileAllowedUrls,
+ })
}
const { lambdasThatUseCaching } = await handleRoutesManifest(
diff --git a/packages/gatsby-source-contentful/src/gatsby-node.js b/packages/gatsby-source-contentful/src/gatsby-node.js
index 99528f805a6c1..8f582ab7a9916 100644
--- a/packages/gatsby-source-contentful/src/gatsby-node.js
+++ b/packages/gatsby-source-contentful/src/gatsby-node.js
@@ -43,7 +43,10 @@ const validateContentfulAccess = async pluginOptions => {
return undefined
}
-export const onPreInit = async ({ store, reporter }) => {
+export const onPreInit = async (
+ { store, reporter, actions },
+ pluginOptions
+) => {
// if gatsby-plugin-image is not installed
try {
await import(`gatsby-plugin-image/graphql-utils`)
@@ -69,6 +72,12 @@ export const onPreInit = async ({ store, reporter }) => {
},
})
}
+
+ if (typeof actions?.addRemoteFileAllowedUrl === `function`) {
+ actions.addRemoteFileAllowedUrl(
+ `https://images.ctfassets.net/${pluginOptions.spaceId}/*`
+ )
+ }
}
export const pluginOptionsSchema = ({ Joi }) =>
diff --git a/packages/gatsby-source-drupal/src/gatsby-node.ts b/packages/gatsby-source-drupal/src/gatsby-node.ts
index 275aea5c3f949..8317b65758058 100644
--- a/packages/gatsby-source-drupal/src/gatsby-node.ts
+++ b/packages/gatsby-source-drupal/src/gatsby-node.ts
@@ -132,8 +132,12 @@ function gracefullyRethrow(activity, error) {
}
}
-exports.onPreBootstrap = (_, pluginOptions) => {
+exports.onPreBootstrap = ({ actions }, pluginOptions) => {
setOptions(pluginOptions)
+
+ if (typeof actions?.addRemoteFileAllowedUrl === `function`) {
+ actions.addRemoteFileAllowedUrl(urlJoin(pluginOptions.baseUrl, `*`))
+ }
}
exports.sourceNodes = async (
diff --git a/packages/gatsby-source-wordpress/src/gatsby-node.ts b/packages/gatsby-source-wordpress/src/gatsby-node.ts
index a14f388f84c02..4c6c62f21bf98 100644
--- a/packages/gatsby-source-wordpress/src/gatsby-node.ts
+++ b/packages/gatsby-source-wordpress/src/gatsby-node.ts
@@ -24,6 +24,7 @@ exports.createSchemaCustomization = runApiSteps(
steps.ensurePluginRequirementsAreMet,
steps.ingestRemoteSchema,
steps.createSchemaCustomization,
+ steps.addRemoteFileAllowedUrl,
],
`createSchemaCustomization`
)
diff --git a/packages/gatsby-source-wordpress/src/steps/add-remote-file-allowed-url.ts b/packages/gatsby-source-wordpress/src/steps/add-remote-file-allowed-url.ts
new file mode 100644
index 0000000000000..249a01827e041
--- /dev/null
+++ b/packages/gatsby-source-wordpress/src/steps/add-remote-file-allowed-url.ts
@@ -0,0 +1,21 @@
+import nodePath from "path"
+import { getStore } from "~/store"
+
+import type { Step } from "~/utils/run-steps"
+
+export const addRemoteFileAllowedUrl: Step = ({ actions }): void => {
+ if (typeof actions?.addRemoteFileAllowedUrl !== `function`) {
+ return
+ }
+
+ const { wpUrl } = getStore().getState().remoteSchema
+
+ if (!wpUrl) {
+ return
+ }
+
+ const wordpressUrl = new URL(wpUrl)
+ wordpressUrl.pathname = nodePath.posix.join(wordpressUrl.pathname, `*`)
+
+ actions.addRemoteFileAllowedUrl(wordpressUrl.href)
+}
diff --git a/packages/gatsby-source-wordpress/src/steps/index.ts b/packages/gatsby-source-wordpress/src/steps/index.ts
index 7f3845abd5510..e0bfdec0a1c24 100644
--- a/packages/gatsby-source-wordpress/src/steps/index.ts
+++ b/packages/gatsby-source-wordpress/src/steps/index.ts
@@ -21,6 +21,7 @@ export { logPostBuildWarnings } from "~/steps/log-post-build-warnings"
export { imageRoutes } from "~/steps/image-routes"
export { setRequestHeaders } from "./set-request-headers"
+export { addRemoteFileAllowedUrl } from "./add-remote-file-allowed-url"
export {
hideAuthPluginOptions,
diff --git a/packages/gatsby/index.d.ts b/packages/gatsby/index.d.ts
index c95953df30f8f..6ef0ef1a31c02 100644
--- a/packages/gatsby/index.d.ts
+++ b/packages/gatsby/index.d.ts
@@ -50,6 +50,7 @@ export {
ImageCdnTransformArgs,
FileCdnUrlGeneratorFn,
FileCdnSourceImage,
+ RemoteFileAllowedUrls,
} from "./dist/utils/adapter/types"
export const useScrollRestoration: (key: string) => {
@@ -1518,7 +1519,15 @@ export interface Actions {
/**
* Marks the source plugin that called this function as stateful. Gatsby will not check for stale nodes for any plugin that calls this.
*/
- enableStatefulSourceNodes?(this: void, plugin?: ActionPlugin)
+ enableStatefulSourceNodes?(this: void, plugin?: ActionPlugin): void
+
+ /** @see https://www.gatsbyjs.com/docs/actions/#addRemoteFileAllowedUrl */
+ addRemoteFileAllowedUrl?(
+ this: void,
+ url: string | Array,
+ plugin?: ActionPlugin,
+ traceId?: string
+ ): void
}
export interface Store {
diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json
index 617962f238521..725aeaca54084 100644
--- a/packages/gatsby/package.json
+++ b/packages/gatsby/package.json
@@ -137,6 +137,7 @@
"opentracing": "^0.14.7",
"p-defer": "^3.0.0",
"parseurl": "^1.3.3",
+ "path-to-regexp": "0.1.7",
"physical-cpu-count": "^2.0.0",
"platform": "^1.3.6",
"postcss": "^8.4.24",
diff --git a/packages/gatsby/src/redux/actions/restricted.ts b/packages/gatsby/src/redux/actions/restricted.ts
index d74000d2977a5..0764b763f8010 100644
--- a/packages/gatsby/src/redux/actions/restricted.ts
+++ b/packages/gatsby/src/redux/actions/restricted.ts
@@ -22,6 +22,7 @@ import {
ICreateResolverContext,
IGatsbyPluginContext,
ICreateSliceAction,
+ IAddImageCdnAllowedUrl,
} from "../types"
import { generateComponentChunkName } from "../../utils/js-chunk-names"
import { store } from "../index"
@@ -36,6 +37,7 @@ type RestrictionActionNames =
| "addThirdPartySchema"
| "printTypeDefinitions"
| "createSlice"
+ | "addRemoteFileAllowedUrl"
type SomeActionCreator =
| ActionCreator
@@ -533,6 +535,31 @@ export const actions = {
throw new Error(`createSlice is only available in Gatsby v5`)
}
},
+ /**
+ * Declares URL Pattern that should be allowed to be used for Image or File CDN to prevent using of unexpected RemoteFile URLs.
+ *
+ * @availableIn [onPreInit, onPreBootstrap, onPluginInit, createSchemaCustomization]
+ *
+ * @param {string | string []} url URLPattern or Array of URL Patternss that should be allowed.
+ * URLPattern is a string that can contain wildcards (*) or parameter placeholders (e.g. :id).
+ * @example
+ * exports.onPreInit = ({ actions }) => {
+ * actions.addRemoteFileAllowedUrl(`https://your-wordpress-instance.com/*`)
+ * }
+ */
+ addRemoteFileAllowedUrl: (
+ url: string | Array,
+ plugin: IGatsbyPlugin,
+ traceId?: string
+ ): IAddImageCdnAllowedUrl => {
+ const urls = Array.isArray(url) ? url : [url]
+ return {
+ type: `ADD_REMOTE_FILE_ALLOWED_URL`,
+ payload: { urls },
+ plugin,
+ traceId,
+ }
+ },
}
const withDeprecationWarning =
@@ -656,4 +683,12 @@ export const availableActionsByAPI = mapAvailableActionsToAPIs({
createSlice: {
[ALLOWED_IN]: [`createPages`],
},
+ addRemoteFileAllowedUrl: {
+ [ALLOWED_IN]: [
+ `onPreInit`,
+ `onPreBootstrap`,
+ `onPluginInit`,
+ `createSchemaCustomization`,
+ ],
+ },
})
diff --git a/packages/gatsby/src/redux/reducers/index.ts b/packages/gatsby/src/redux/reducers/index.ts
index 54e4ef76e47ed..e2b394a5de986 100644
--- a/packages/gatsby/src/redux/reducers/index.ts
+++ b/packages/gatsby/src/redux/reducers/index.ts
@@ -38,6 +38,7 @@ import { slicesReducer } from "./slices"
import { componentsUsingSlicesReducer } from "./components-using-slices"
import { slicesByTemplateReducer } from "./slices-by-template"
import { adapterReducer } from "./adapter"
+import { remoteFileAllowedUrlsReducer } from "./remote-file-allowed-urls"
/**
* @property exports.nodesTouched Set
@@ -83,4 +84,5 @@ export {
slicesByTemplateReducer as slicesByTemplate,
telemetryReducer as telemetry,
adapterReducer as adapter,
+ remoteFileAllowedUrlsReducer as remoteFileAllowedUrls,
}
diff --git a/packages/gatsby/src/redux/reducers/remote-file-allowed-urls.ts b/packages/gatsby/src/redux/reducers/remote-file-allowed-urls.ts
new file mode 100644
index 0000000000000..b076cdea80642
--- /dev/null
+++ b/packages/gatsby/src/redux/reducers/remote-file-allowed-urls.ts
@@ -0,0 +1,18 @@
+import { IGatsbyState, ActionsUnion } from "../types"
+
+export const remoteFileAllowedUrlsReducer = (
+ state: IGatsbyState["remoteFileAllowedUrls"] = new Set(),
+ action: ActionsUnion
+): IGatsbyState["remoteFileAllowedUrls"] => {
+ switch (action.type) {
+ case `ADD_REMOTE_FILE_ALLOWED_URL`: {
+ for (const url of action.payload.urls) {
+ state.add(url)
+ }
+
+ return state
+ }
+ default:
+ return state
+ }
+}
diff --git a/packages/gatsby/src/redux/types.ts b/packages/gatsby/src/redux/types.ts
index 01c409da25475..44e8abaafcfa2 100644
--- a/packages/gatsby/src/redux/types.ts
+++ b/packages/gatsby/src/redux/types.ts
@@ -425,6 +425,7 @@ export interface IGatsbyState {
manager: IAdapterManager
config: IAdapterFinalConfig
}
+ remoteFileAllowedUrls: Set
}
export type GatsbyStateKeys = keyof IGatsbyState
@@ -539,6 +540,7 @@ export type ActionsUnion =
| IClearGatsbyImageSourceUrlAction
| ISetAdapterAction
| IDisablePluginsByNameAction
+ | IAddImageCdnAllowedUrl
export interface IInitAction {
type: `INIT`
@@ -1218,6 +1220,15 @@ export interface IDisablePluginsByNameAction {
}
}
+export interface IAddImageCdnAllowedUrl {
+ type: `ADD_REMOTE_FILE_ALLOWED_URL`
+ payload: {
+ urls: Array
+ }
+ plugin: IGatsbyPlugin
+ traceId?: string
+}
+
export interface ITelemetry {
gatsbyImageSourceUrls: Set
}
diff --git a/packages/gatsby/src/utils/adapter/manager.ts b/packages/gatsby/src/utils/adapter/manager.ts
index 8e97c6c737ae7..fbe10be215dd0 100644
--- a/packages/gatsby/src/utils/adapter/manager.ts
+++ b/packages/gatsby/src/utils/adapter/manager.ts
@@ -7,6 +7,7 @@ import { posix } from "path"
import { sync as globSync } from "glob"
import telemetry from "gatsby-telemetry"
import { copy, pathExists, unlink } from "fs-extra"
+import pathToRegexp from "path-to-regexp"
import type {
FunctionsManifest,
IAdaptContext,
@@ -18,6 +19,7 @@ import type {
IAdapterFinalConfig,
IAdapterConfig,
HeaderRoutes,
+ RemoteFileAllowedUrls,
} from "./types"
import { store, readState } from "../../redux"
import { getPageMode } from "../page-mode"
@@ -204,6 +206,7 @@ export async function initAdapterManager(): Promise {
let _routesManifest: RoutesManifest | undefined = undefined
let _functionsManifest: FunctionsManifest | undefined = undefined
let _headerRoutes: HeaderRoutes | undefined = undefined
+ let _imageCdnAllowedUrls: RemoteFileAllowedUrls | undefined = undefined
const adaptContext: IAdaptContext = {
get routesManifest(): RoutesManifest {
if (!_routesManifest) {
@@ -230,6 +233,20 @@ export async function initAdapterManager(): Promise {
return _headerRoutes
},
+ get remoteFileAllowedUrls(): RemoteFileAllowedUrls {
+ if (!_imageCdnAllowedUrls) {
+ _imageCdnAllowedUrls = Array.from(
+ store.getState().remoteFileAllowedUrls
+ ).map(urlPattern => {
+ return {
+ urlPattern,
+ regexSource: pathToRegexp(urlPattern).source,
+ }
+ })
+ }
+
+ return _imageCdnAllowedUrls
+ },
reporter,
// Our internal Gatsby config allows this to be undefined but for the adapter we should always pass through the default values and correctly show this in the TypeScript types
trailingSlash: trailingSlash as TrailingSlash,
diff --git a/packages/gatsby/src/utils/adapter/types.ts b/packages/gatsby/src/utils/adapter/types.ts
index d5f7b8d1a617b..c22e15019c5d1 100644
--- a/packages/gatsby/src/utils/adapter/types.ts
+++ b/packages/gatsby/src/utils/adapter/types.ts
@@ -117,6 +117,17 @@ interface IDefaultContext {
reporter: typeof reporter
}
+export type RemoteFileAllowedUrls = Array<{
+ /**
+ * Allowed url in URLPattern format. In particular it uses wildcard `*` and param `:param` syntax.
+ */
+ urlPattern: string
+ /**
+ *Allowed url in regex source format
+ */
+ regexSource: string
+}>
+
export interface IAdaptContext extends IDefaultContext {
routesManifest: RoutesManifest
functionsManifest: FunctionsManifest
@@ -129,6 +140,12 @@ export interface IAdaptContext extends IDefaultContext {
* @see https://www.gatsbyjs.com/docs/reference/config-files/gatsby-config/#trailingslash
*/
trailingSlash: TrailingSlash
+ /**
+ * List of allowed remote file URLs represented in URLPattern and Regex formats.
+ * Allowed urls are provided by user or plugins using `addRemoteFileAllowedUrl` action.
+ * @see https://www.gatsbyjs.com/docs/reference/config-files/actions/#addRemoteFileAllowedUrl
+ */
+ remoteFileAllowedUrls: RemoteFileAllowedUrls
}
export interface ICacheContext extends IDefaultContext {
diff --git a/yarn.lock b/yarn.lock
index edca74a7eaf04..9604f412e782f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3262,6 +3262,36 @@
path-exists "^5.0.0"
readdirp "^3.4.0"
+"@netlify/config@^20.10.0":
+ version "20.10.0"
+ resolved "https://registry.yarnpkg.com/@netlify/config/-/config-20.10.0.tgz#df51f277c7eaa984105f4e90c3ea676b935c5df3"
+ integrity sha512-7CNoL5IPSRBzDVzxuQgltZ71D/vZ/oYR29sfN8EXjAFOZPSLtnZgborcPa9V9BXLN4N5h0hFp2A26lnnCttEFg==
+ dependencies:
+ chalk "^5.0.0"
+ cron-parser "^4.1.0"
+ deepmerge "^4.2.2"
+ dot-prop "^7.0.0"
+ execa "^6.0.0"
+ fast-safe-stringify "^2.0.7"
+ figures "^5.0.0"
+ filter-obj "^5.0.0"
+ find-up "^6.0.0"
+ indent-string "^5.0.0"
+ is-plain-obj "^4.0.0"
+ js-yaml "^4.0.0"
+ map-obj "^5.0.0"
+ netlify "^13.1.11"
+ netlify-headers-parser "^7.1.2"
+ netlify-redirect-parser "^14.2.0"
+ node-fetch "^3.3.1"
+ omit.js "^2.0.2"
+ p-locate "^6.0.0"
+ path-type "^5.0.0"
+ toml "^3.0.0"
+ tomlify-j0.4 "^3.0.0"
+ validate-npm-package-name "^4.0.0"
+ yargs "^17.6.0"
+
"@netlify/edge-functions@^2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@netlify/edge-functions/-/edge-functions-2.2.0.tgz#5f7f5c7602a7f98888a4b4421576ca609dad2083"
@@ -3274,6 +3304,11 @@
dependencies:
is-promise "^4.0.0"
+"@netlify/open-api@^2.26.0":
+ version "2.26.0"
+ resolved "https://registry.yarnpkg.com/@netlify/open-api/-/open-api-2.26.0.tgz#cdc8033371079955501f4b9a5323f2dcd76741c2"
+ integrity sha512-B7q+ySzQm6rJhaGbY0Pzqnb1p3FsBqwiPLnLtA17JgTsqmXgQ7j6OQImW9fRJy/Al1ob9M6Oxng/FA2c7aIW1g==
+
"@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3":
version "2.1.8-no-fsevents.3"
resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz#323d72dd25103d0c4fbdce89dadf574a787b1f9b"
@@ -7165,6 +7200,13 @@ builtins@^2.0.0:
dependencies:
semver "^6.0.0"
+builtins@^5.0.0:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9"
+ integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==
+ dependencies:
+ semver "^7.0.0"
+
busboy@^1.0.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893"
@@ -7531,6 +7573,11 @@ chalk@^4.0, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
+chalk@^5.0.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385"
+ integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==
+
change-case-all@1.0.14:
version "1.0.14"
resolved "https://registry.yarnpkg.com/change-case-all/-/change-case-all-1.0.14.tgz#bac04da08ad143278d0ac3dda7eccd39280bfba1"
@@ -8765,6 +8812,13 @@ createerror@1.3.0, createerror@^1.2.0, createerror@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/createerror/-/createerror-1.3.0.tgz#c666bd4cd6b94e35415396569d4649dd0cdb3313"
+cron-parser@^4.1.0:
+ version "4.9.0"
+ resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-4.9.0.tgz#0340694af3e46a0894978c6f52a6dbb5c0f11ad5"
+ integrity sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==
+ dependencies:
+ luxon "^3.2.1"
+
cross-env@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
@@ -9288,6 +9342,11 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
+data-uri-to-buffer@^4.0.0:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e"
+ integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==
+
data-urls@^1.0.0, data-urls@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe"
@@ -10028,6 +10087,13 @@ dot-prop@^5.1.0, dot-prop@^5.2.0:
dependencies:
is-obj "^2.0.0"
+dot-prop@^7.0.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-7.2.0.tgz#468172a3529779814d21a779c1ba2f6d76609809"
+ integrity sha512-Ol/IPXUARn9CSbkrdV4VJo7uCy1I3VuSiWCaFSg+8BdUOzF9n3jefIpcgAydvUZbTdEBZs2vEiTiS9m61ssiDA==
+ dependencies:
+ type-fest "^2.11.2"
+
dotenv-expand@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0"
@@ -10420,7 +10486,7 @@ escape-html@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
-escape-string-regexp@5.0.0:
+escape-string-regexp@5.0.0, escape-string-regexp@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8"
integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==
@@ -11032,6 +11098,21 @@ execa@^5.0.0, execa@^5.1.1:
signal-exit "^3.0.3"
strip-final-newline "^2.0.0"
+execa@^6.0.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/execa/-/execa-6.1.0.tgz#cea16dee211ff011246556388effa0818394fb20"
+ integrity sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==
+ dependencies:
+ cross-spawn "^7.0.3"
+ get-stream "^6.0.1"
+ human-signals "^3.0.1"
+ is-stream "^3.0.0"
+ merge-stream "^2.0.0"
+ npm-run-path "^5.1.0"
+ onetime "^6.0.0"
+ signal-exit "^3.0.7"
+ strip-final-newline "^3.0.0"
+
execall@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/execall/-/execall-2.0.0.tgz#16a06b5fe5099df7d00be5d9c06eecded1663b45"
@@ -11280,7 +11361,7 @@ fast-redact@^3.0.0:
resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.1.2.tgz#d58e69e9084ce9fa4c1a6fa98a3e1ecf5d7839aa"
integrity sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw==
-fast-safe-stringify@2.1.1:
+fast-safe-stringify@2.1.1, fast-safe-stringify@^2.0.7, fast-safe-stringify@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884"
integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==
@@ -11337,6 +11418,14 @@ fd-slicer@~1.1.0:
dependencies:
pend "~1.2.0"
+fetch-blob@^3.1.2, fetch-blob@^3.1.4:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9"
+ integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==
+ dependencies:
+ node-domexception "^1.0.0"
+ web-streams-polyfill "^3.0.3"
+
figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
version "3.5.1"
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
@@ -11361,6 +11450,14 @@ figures@^3.0.0, figures@^3.1.0, figures@^3.2.0:
dependencies:
escape-string-regexp "^1.0.5"
+figures@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/figures/-/figures-5.0.0.tgz#126cd055052dea699f8a54e8c9450e6ecfc44d5f"
+ integrity sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==
+ dependencies:
+ escape-string-regexp "^5.0.0"
+ is-unicode-supported "^1.2.0"
+
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"
@@ -11456,6 +11553,11 @@ filter-obj@^1.1.0:
resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b"
integrity sha1-mzERErxsYSehbgFsbF1/GeCAXFs=
+filter-obj@^5.0.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-5.1.0.tgz#5bd89676000a713d7db2e197f660274428e524ed"
+ integrity sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==
+
finalhandler@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32"
@@ -11534,6 +11636,14 @@ find-up@^5.0.0:
locate-path "^6.0.0"
path-exists "^4.0.0"
+find-up@^6.0.0:
+ version "6.3.0"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-6.3.0.tgz#2abab3d3280b2dc7ac10199ef324c4e002c8c790"
+ integrity sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==
+ dependencies:
+ locate-path "^7.1.0"
+ path-exists "^5.0.0"
+
find-yarn-workspace-root@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd"
@@ -11731,6 +11841,13 @@ form-data@~2.3.2:
combined-stream "^1.0.6"
mime-types "^2.1.12"
+formdata-polyfill@^4.0.10:
+ version "4.0.10"
+ resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423"
+ integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==
+ dependencies:
+ fetch-blob "^3.1.2"
+
forwarded@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
@@ -13278,6 +13395,11 @@ human-signals@^2.1.0:
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
+human-signals@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-3.0.1.tgz#c740920859dafa50e5a3222da9d3bf4bb0e5eef5"
+ integrity sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==
+
humanize-ms@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed"
@@ -14209,6 +14331,11 @@ is-stream@^2.0.0:
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3"
integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==
+is-stream@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac"
+ integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==
+
is-string@^1.0.5, is-string@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd"
@@ -14256,6 +14383,11 @@ 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-unicode-supported@^1.2.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz#d824984b616c292a2e198207d4a609983842f714"
+ integrity sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==
+
is-upper-case@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-2.0.2.tgz#f1105ced1fe4de906a5f39553e7d3803fd804649"
@@ -14911,7 +15043,7 @@ js-levenshtein@^1.1.6:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
-js-yaml@4.1.0, js-yaml@^4.1.0:
+js-yaml@4.1.0, js-yaml@^4.0.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==
@@ -15641,7 +15773,7 @@ locate-path@^6.0.0:
dependencies:
p-locate "^5.0.0"
-locate-path@^7.0.0:
+locate-path@^7.0.0, locate-path@^7.1.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a"
integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==
@@ -16035,6 +16167,11 @@ lru-queue@^0.1.0:
dependencies:
es5-ext "~0.10.2"
+luxon@^3.2.1:
+ version "3.4.4"
+ resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.4.tgz#cf20dc27dc532ba41a169c43fdcc0063601577af"
+ integrity sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==
+
lz-string@^1.4.4, lz-string@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941"
@@ -16127,6 +16264,11 @@ map-obj@^4.0.0, map-obj@^4.1.0:
resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a"
integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==
+map-obj@^5.0.0:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-5.0.2.tgz#174ad9f7e5e4e777a219126d9a734ff3e14a1c68"
+ integrity sha512-K6K2NgKnTXimT3779/4KxSvobxOtMmx1LBZ3NwRxT/MDIR3Br/fQ4Q+WCX5QxjyUR8zg5+RV9Tbf2c5pAWTD2A==
+
map-stream@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194"
@@ -16693,6 +16835,11 @@ methods@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
+micro-api-client@^3.3.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/micro-api-client/-/micro-api-client-3.3.0.tgz#52dd567d322f10faffe63d19d4feeac4e4ffd215"
+ integrity sha512-y0y6CUB9RLVsy3kfgayU28746QrNMpSm9O/AYGNsBgOkJr/X/Jk0VLGoO8Ude7Bpa8adywzF+MzXNZRFRsNPhg==
+
microbundle@^0.15.0, microbundle@^0.15.1:
version "0.15.1"
resolved "https://registry.yarnpkg.com/microbundle/-/microbundle-0.15.1.tgz#3fa67128934b31736823b5c868dae4b92d94e766"
@@ -17170,6 +17317,11 @@ mimic-fn@^3.1.0:
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-3.1.0.tgz#65755145bbf3e36954b949c16450427451d5ca74"
integrity sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==
+mimic-fn@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc"
+ integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==
+
mimic-response@^1.0.0, mimic-response@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
@@ -17575,11 +17727,47 @@ nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0:
resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61"
integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==
+netlify-headers-parser@^7.1.2:
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/netlify-headers-parser/-/netlify-headers-parser-7.1.2.tgz#5b2f76e030eb8ba423c370c4e4814ddcc9c65e3b"
+ integrity sha512-DfoboA8PrcLXMan3jIVyLsQtKS+nepKDx6WwZKk5EQDMr2AJoBPCtSHTOLuABzkde1UXdOITf3snmcAmzlNLqw==
+ dependencies:
+ escape-string-regexp "^5.0.0"
+ fast-safe-stringify "^2.0.7"
+ is-plain-obj "^4.0.0"
+ map-obj "^5.0.0"
+ path-exists "^5.0.0"
+ toml "^3.0.0"
+
netlify-identity-widget@^1.9.2:
version "1.9.2"
resolved "https://registry.yarnpkg.com/netlify-identity-widget/-/netlify-identity-widget-1.9.2.tgz#4339c9155fc4c2570ae3ddd61825d952b574b02e"
integrity sha512-IbS1JHhs7BflCCvp3C9f6tmNSZqbyBhZ4Gs5+Qxt4IlPybTOVv0PqJ4TAsA7uxh1R+oXOAmk0OOMAkEaPYeCtA==
+netlify-redirect-parser@^14.2.0:
+ version "14.2.0"
+ resolved "https://registry.yarnpkg.com/netlify-redirect-parser/-/netlify-redirect-parser-14.2.0.tgz#8da1b911b43ea51e0c5fa5dd1401157d1301a8f5"
+ integrity sha512-3Mi7sMH7XXZhjvXx/5RtJ/rU/E6zKkE4etcYQbEu8B3r872D0opoYyGdPW/MvaYQyVdfg23XEFaEI4zzQTupaw==
+ dependencies:
+ fast-safe-stringify "^2.1.1"
+ filter-obj "^5.0.0"
+ is-plain-obj "^4.0.0"
+ path-exists "^5.0.0"
+ toml "^3.0.0"
+
+netlify@^13.1.11:
+ version "13.1.11"
+ resolved "https://registry.yarnpkg.com/netlify/-/netlify-13.1.11.tgz#f5151bbd5e05cd5a67713f89c05a57dd6377b599"
+ integrity sha512-exrD6cqwo5avDNtU7YT9iuN0+yoW+aaEUxvr/39oP36wZRKreoPm6KNVisTR9d4lXrPeUG8XI+rERuLhwMQmdw==
+ dependencies:
+ "@netlify/open-api" "^2.26.0"
+ lodash-es "^4.17.21"
+ micro-api-client "^3.3.0"
+ node-fetch "^3.0.0"
+ omit.js "^2.0.2"
+ p-wait-for "^4.0.0"
+ qs "^6.9.6"
+
next-tick@1, next-tick@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb"
@@ -17654,6 +17842,11 @@ node-dir@^0.1.10, node-dir@^0.1.17:
dependencies:
minimatch "^3.0.2"
+node-domexception@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5"
+ integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==
+
node-environment-flags@^1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088"
@@ -17692,6 +17885,15 @@ node-fetch@^2.5.0, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.11, nod
dependencies:
whatwg-url "^5.0.0"
+node-fetch@^3.0.0, node-fetch@^3.3.1:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.2.tgz#d1e889bacdf733b4ff3b2b243eb7a12866a0b78b"
+ integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==
+ dependencies:
+ data-uri-to-buffer "^4.0.0"
+ fetch-blob "^3.1.4"
+ formdata-polyfill "^4.0.10"
+
node-gyp-build-optional-packages@5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz#92a89d400352c44ad3975010368072b41ad66c17"
@@ -17934,6 +18136,13 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1:
dependencies:
path-key "^3.0.0"
+npm-run-path@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00"
+ integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==
+ dependencies:
+ path-key "^4.0.0"
+
npmlog@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
@@ -18096,6 +18305,11 @@ octokit-pagination-methods@^1.1.0:
resolved "https://registry.yarnpkg.com/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz#cf472edc9d551055f9ef73f6e42b4dbb4c80bea4"
integrity sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ==
+omit.js@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/omit.js/-/omit.js-2.0.2.tgz#dd9b8436fab947a5f3ff214cb2538631e313ec2f"
+ integrity sha512-hJmu9D+bNB40YpL9jYebQl4lsTW6yEHRTroJzNLqQJYHm7c+NQnJGfZmIWh8S3q3KoaxV1aLhV6B3+0N0/kyJg==
+
on-exit-leak-free@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209"
@@ -18132,6 +18346,13 @@ onetime@^5.1.0, onetime@^5.1.2:
dependencies:
mimic-fn "^2.1.0"
+onetime@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4"
+ integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==
+ dependencies:
+ mimic-fn "^4.0.0"
+
open@^7.0.3:
version "7.3.1"
resolved "https://registry.yarnpkg.com/open/-/open-7.3.1.tgz#111119cb919ca1acd988f49685c4fdd0f4755356"
@@ -18442,6 +18663,11 @@ p-timeout@^3.1.0, p-timeout@^3.2.0:
dependencies:
p-finally "^1.0.0"
+p-timeout@^5.0.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-5.1.0.tgz#b3c691cf4415138ce2d9cfe071dba11f0fee085b"
+ integrity sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==
+
p-try@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
@@ -18451,6 +18677,13 @@ p-try@^2.0.0, p-try@^2.1.0:
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
+p-wait-for@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/p-wait-for/-/p-wait-for-4.1.0.tgz#290f126f49bbd7c84e0cedccb342cd631aaa0f16"
+ integrity sha512-i8nE5q++9h8oaQHWltS1Tnnv4IoMDOlqN7C0KFG2OdbK0iFJIt6CROZ8wfBM+K4Pxqfnq4C4lkkpXqTEpB5DZw==
+ dependencies:
+ p-timeout "^5.0.0"
+
p-waterfall@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-waterfall/-/p-waterfall-1.0.0.tgz#7ed94b3ceb3332782353af6aae11aa9fc235bb00"
@@ -18773,6 +19006,11 @@ path-key@^3.0.0, path-key@^3.1.0:
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
+path-key@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18"
+ integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==
+
path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
@@ -18830,6 +19068,11 @@ path-type@^4.0.0:
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+path-type@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-5.0.0.tgz#14b01ed7aea7ddf9c7c3f46181d4d04f9c785bb8"
+ integrity sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==
+
pause-stream@0.0.11:
version "0.0.11"
resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445"
@@ -20109,7 +20352,7 @@ qs@6.11.0:
dependencies:
side-channel "^1.0.4"
-qs@^6.1.0, qs@^6.11.0, qs@^6.4.0, qs@^6.5.2, qs@^6.9.4:
+qs@^6.1.0, qs@^6.11.0, qs@^6.4.0, qs@^6.5.2, qs@^6.9.4, qs@^6.9.6:
version "6.11.2"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9"
integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==
@@ -21749,6 +21992,13 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
+semver@^7.0.0, semver@^7.5.4:
+ version "7.5.4"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
+ integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
+ dependencies:
+ lru-cache "^6.0.0"
+
semver@^7.1.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3:
version "7.5.3"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e"
@@ -21756,13 +22006,6 @@ semver@^7.1.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semve
dependencies:
lru-cache "^6.0.0"
-semver@^7.5.4:
- version "7.5.4"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
- integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
- dependencies:
- lru-cache "^6.0.0"
-
send@0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
@@ -22768,6 +23011,11 @@ strip-final-newline@^2.0.0:
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
+strip-final-newline@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd"
+ integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==
+
strip-indent@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2"
@@ -23544,6 +23792,16 @@ toml@^2.3.2, toml@^2.3.6:
resolved "https://registry.yarnpkg.com/toml/-/toml-2.3.6.tgz#25b0866483a9722474895559088b436fd11f861b"
integrity sha512-gVweAectJU3ebq//Ferr2JUY4WKSDe5N+z0FvjDncLGyHmIDoxgY/2Ie4qfEIDm4IS7OA6Rmdm7pdEEdMcV/xQ==
+toml@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee"
+ integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==
+
+tomlify-j0.4@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/tomlify-j0.4/-/tomlify-j0.4-3.0.0.tgz#99414d45268c3a3b8bf38be82145b7bba34b7473"
+ integrity sha512-2Ulkc8T7mXJ2l0W476YC/A209PR38Nw8PuaCNtk9uI3t1zzFdGQeWYGQvmj2PZkVvRC/Yoi4xQKMRnWc/N29tQ==
+
topo@3.x.x:
version "3.0.3"
resolved "https://registry.yarnpkg.com/topo/-/topo-3.0.3.tgz#d5a67fb2e69307ebeeb08402ec2a2a6f5f7ad95c"
@@ -23801,7 +24059,7 @@ type-fest@^1.0.1, type-fest@^1.2.1, type-fest@^1.2.2:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1"
integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==
-type-fest@^2.19.0:
+type-fest@^2.11.2, type-fest@^2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b"
integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==
@@ -24579,6 +24837,13 @@ validate-npm-package-name@^3.0.0:
dependencies:
builtins "^1.0.3"
+validate-npm-package-name@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz#fe8f1c50ac20afdb86f177da85b3600f0ac0d747"
+ integrity sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==
+ dependencies:
+ builtins "^5.0.0"
+
validator@13.9.0:
version "13.9.0"
resolved "https://registry.yarnpkg.com/validator/-/validator-13.9.0.tgz#33e7b85b604f3bbce9bb1a05d5c3e22e1c2ff855"
@@ -24891,6 +25156,11 @@ web-namespaces@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.2.tgz#c8dc267ab639505276bae19e129dbd6ae72b22b4"
+web-streams-polyfill@^3.0.3:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6"
+ integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==
+
web-vitals@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-1.1.2.tgz#06535308168986096239aa84716e68b4c6ae6d1c"
@@ -25665,6 +25935,19 @@ yargs@^17.2.1, yargs@^17.3.1:
y18n "^5.0.5"
yargs-parser "^21.1.1"
+yargs@^17.6.0:
+ version "17.7.2"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
+ integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
+ dependencies:
+ cliui "^8.0.1"
+ escalade "^3.1.1"
+ get-caller-file "^2.0.5"
+ require-directory "^2.1.1"
+ string-width "^4.2.3"
+ y18n "^5.0.5"
+ yargs-parser "^21.1.1"
+
yauzl@^2.10.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"