@astrojs/cloudflare 12.2.1 → 12.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,248 +1,264 @@
1
- import { createReadStream } from 'node:fs';
2
- import { appendFile, rename, stat } from 'node:fs/promises';
3
- import { createInterface } from 'node:readline/promises';
4
- import { appendForwardSlash, prependForwardSlash, removeLeadingForwardSlash, } from '@astrojs/internal-helpers/path';
5
- import { createRedirectsFromAstroRoutes } from '@astrojs/underscore-redirects';
6
- import { AstroError } from 'astro/errors';
7
- import { defaultClientConditions } from 'vite';
8
- import { getPlatformProxy } from 'wrangler';
9
- import { cloudflareModuleLoader, } from './utils/cloudflare-module-loader.js';
10
- import { createGetEnv } from './utils/env.js';
11
- import { createRoutesFile, getParts } from './utils/generate-routes-json.js';
12
- import { setImageConfig } from './utils/image-config.js';
1
+ import { createReadStream } from "node:fs";
2
+ import { appendFile, rename, stat } from "node:fs/promises";
3
+ import { createInterface } from "node:readline/promises";
4
+ import {
5
+ appendForwardSlash,
6
+ prependForwardSlash,
7
+ removeLeadingForwardSlash
8
+ } from "@astrojs/internal-helpers/path";
9
+ import { createRedirectsFromAstroRoutes } from "@astrojs/underscore-redirects";
10
+ import { AstroError } from "astro/errors";
11
+ import { defaultClientConditions } from "vite";
12
+ import { getPlatformProxy } from "wrangler";
13
+ import {
14
+ cloudflareModuleLoader
15
+ } from "./utils/cloudflare-module-loader.js";
16
+ import { createGetEnv } from "./utils/env.js";
17
+ import { createRoutesFile, getParts } from "./utils/generate-routes-json.js";
18
+ import { setImageConfig } from "./utils/image-config.js";
13
19
  function wrapWithSlashes(path) {
14
- return prependForwardSlash(appendForwardSlash(path));
20
+ return prependForwardSlash(appendForwardSlash(path));
15
21
  }
16
22
  function setProcessEnv(config, env) {
17
- const getEnv = createGetEnv(env);
18
- if (config.env?.schema) {
19
- for (const key of Object.keys(config.env.schema)) {
20
- const value = getEnv(key);
21
- if (value !== undefined) {
22
- process.env[key] = value;
23
- }
24
- }
23
+ const getEnv = createGetEnv(env);
24
+ if (config.env?.schema) {
25
+ for (const key of Object.keys(config.env.schema)) {
26
+ const value = getEnv(key);
27
+ if (value !== void 0) {
28
+ process.env[key] = value;
29
+ }
25
30
  }
31
+ }
26
32
  }
27
- export default function createIntegration(args) {
28
- let _config;
29
- let finalBuildOutput;
30
- const cloudflareModulePlugin = cloudflareModuleLoader(args?.cloudflareModules ?? true);
31
- let _routes;
32
- return {
33
- name: '@astrojs/cloudflare',
34
- hooks: {
35
- 'astro:config:setup': ({ command, config, updateConfig, logger, addWatchFile, addMiddleware, }) => {
36
- updateConfig({
37
- build: {
38
- client: new URL(`.${wrapWithSlashes(config.base)}`, config.outDir),
39
- server: new URL('./_worker.js/', config.outDir),
40
- serverEntry: 'index.js',
41
- redirects: false,
42
- },
43
- vite: {
44
- plugins: [
45
- // https://developers.cloudflare.com/pages/functions/module-support/
46
- // Allows imports of '.wasm', '.bin', and '.txt' file types
47
- cloudflareModulePlugin,
48
- {
49
- name: 'vite:cf-imports',
50
- enforce: 'pre',
51
- resolveId(source) {
52
- if (source.startsWith('cloudflare:')) {
53
- return { id: source, external: true };
54
- }
55
- return null;
56
- },
57
- },
58
- ],
59
- },
60
- image: setImageConfig(args?.imageService ?? 'compile', config.image, command, logger),
61
- });
62
- if (args?.platformProxy?.configPath) {
63
- addWatchFile(new URL(args.platformProxy.configPath, config.root));
64
- }
65
- else {
66
- addWatchFile(new URL('./wrangler.toml', config.root));
67
- addWatchFile(new URL('./wrangler.json', config.root));
68
- addWatchFile(new URL('./wrangler.jsonc', config.root));
69
- }
70
- addMiddleware({
71
- entrypoint: '@astrojs/cloudflare/entrypoints/middleware.js',
72
- order: 'pre',
73
- });
74
- },
75
- 'astro:routes:resolved': ({ routes }) => {
76
- _routes = routes;
77
- },
78
- 'astro:config:done': ({ setAdapter, config, buildOutput, logger }) => {
79
- if (buildOutput === 'static') {
80
- logger.warn('[@astrojs/cloudflare] This adapter is intended to be used with server rendered pages, which this project does not contain any of. As such, this adapter is unnecessary.');
81
- }
82
- _config = config;
83
- finalBuildOutput = buildOutput;
84
- setAdapter({
85
- name: '@astrojs/cloudflare',
86
- serverEntrypoint: '@astrojs/cloudflare/entrypoints/server.js',
87
- exports: ['default'],
88
- adapterFeatures: {
89
- edgeMiddleware: false,
90
- buildOutput: 'server',
91
- },
92
- supportedAstroFeatures: {
93
- serverOutput: 'stable',
94
- hybridOutput: 'stable',
95
- staticOutput: 'unsupported',
96
- i18nDomains: 'experimental',
97
- sharpImageService: {
98
- support: 'limited',
99
- message: 'Cloudflare does not support sharp. You can use the `compile` image service to compile images at build time. It will not work for any on-demand rendered images.',
100
- },
101
- envGetSecret: 'stable',
102
- },
103
- });
104
- },
105
- 'astro:server:setup': async ({ server }) => {
106
- if ((args?.platformProxy?.enabled ?? true) === true) {
107
- const platformProxy = await getPlatformProxy(args?.platformProxy);
108
- setProcessEnv(_config, platformProxy.env);
109
- const clientLocalsSymbol = Symbol.for('astro.locals');
110
- server.middlewares.use(async function middleware(req, res, next) {
111
- Reflect.set(req, clientLocalsSymbol, {
112
- runtime: {
113
- env: platformProxy.env,
114
- cf: platformProxy.cf,
115
- caches: platformProxy.caches,
116
- ctx: {
117
- waitUntil: (promise) => platformProxy.ctx.waitUntil(promise),
118
- // Currently not available: https://developers.cloudflare.com/pages/platform/known-issues/#pages-functions
119
- passThroughOnException: () => {
120
- throw new AstroError('`passThroughOnException` is currently not available in Cloudflare Pages. See https://developers.cloudflare.com/pages/platform/known-issues/#pages-functions.');
121
- },
122
- },
123
- },
124
- });
125
- next();
126
- });
127
- }
128
- },
129
- 'astro:build:setup': ({ vite, target }) => {
130
- if (target === 'server') {
131
- vite.resolve ||= {};
132
- vite.resolve.alias ||= {};
133
- const aliases = [
134
- {
135
- find: 'react-dom/server',
136
- replacement: 'react-dom/server.browser',
137
- },
138
- ];
139
- if (Array.isArray(vite.resolve.alias)) {
140
- vite.resolve.alias = [...vite.resolve.alias, ...aliases];
141
- }
142
- else {
143
- for (const alias of aliases) {
144
- vite.resolve.alias[alias.find] = alias.replacement;
145
- }
146
- }
147
- // Support `workerd` and `worker` conditions for the ssr environment
148
- // (previously supported in esbuild instead: https://github.com/withastro/astro/pull/7092)
149
- vite.ssr ||= {};
150
- vite.ssr.resolve ||= {};
151
- vite.ssr.resolve.conditions ||= [...defaultClientConditions];
152
- vite.ssr.resolve.conditions.push('workerd', 'worker');
153
- vite.ssr.target = 'webworker';
154
- vite.ssr.noExternal = true;
155
- vite.build ||= {};
156
- vite.build.rollupOptions ||= {};
157
- vite.build.rollupOptions.output ||= {};
158
- // @ts-expect-error
159
- vite.build.rollupOptions.output.banner ||=
160
- 'globalThis.process ??= {}; globalThis.process.env ??= {};';
161
- // Cloudflare env is only available per request. This isn't feasible for code that access env vars
162
- // in a global way, so we shim their access as `process.env.*`. This is not the recommended way for users to access environment variables. But we'll add this for compatibility for chosen variables. Mainly to support `@astrojs/db`
163
- vite.define = {
164
- 'process.env': 'process.env',
165
- ...vite.define,
166
- };
33
+ function createIntegration(args) {
34
+ let _config;
35
+ let finalBuildOutput;
36
+ const cloudflareModulePlugin = cloudflareModuleLoader(
37
+ args?.cloudflareModules ?? true
38
+ );
39
+ let _routes;
40
+ return {
41
+ name: "@astrojs/cloudflare",
42
+ hooks: {
43
+ "astro:config:setup": ({
44
+ command,
45
+ config,
46
+ updateConfig,
47
+ logger,
48
+ addWatchFile,
49
+ addMiddleware
50
+ }) => {
51
+ updateConfig({
52
+ build: {
53
+ client: new URL(`.${wrapWithSlashes(config.base)}`, config.outDir),
54
+ server: new URL("./_worker.js/", config.outDir),
55
+ serverEntry: "index.js",
56
+ redirects: false
57
+ },
58
+ vite: {
59
+ plugins: [
60
+ // https://developers.cloudflare.com/pages/functions/module-support/
61
+ // Allows imports of '.wasm', '.bin', and '.txt' file types
62
+ cloudflareModulePlugin,
63
+ {
64
+ name: "vite:cf-imports",
65
+ enforce: "pre",
66
+ resolveId(source) {
67
+ if (source.startsWith("cloudflare:")) {
68
+ return { id: source, external: true };
69
+ }
70
+ return null;
167
71
  }
72
+ }
73
+ ]
74
+ },
75
+ image: setImageConfig(args?.imageService ?? "compile", config.image, command, logger)
76
+ });
77
+ if (args?.platformProxy?.configPath) {
78
+ addWatchFile(new URL(args.platformProxy.configPath, config.root));
79
+ } else {
80
+ addWatchFile(new URL("./wrangler.toml", config.root));
81
+ addWatchFile(new URL("./wrangler.json", config.root));
82
+ addWatchFile(new URL("./wrangler.jsonc", config.root));
83
+ }
84
+ addMiddleware({
85
+ entrypoint: "@astrojs/cloudflare/entrypoints/middleware.js",
86
+ order: "pre"
87
+ });
88
+ },
89
+ "astro:routes:resolved": ({ routes }) => {
90
+ _routes = routes;
91
+ },
92
+ "astro:config:done": ({ setAdapter, config, buildOutput, logger }) => {
93
+ if (buildOutput === "static") {
94
+ logger.warn(
95
+ "[@astrojs/cloudflare] This adapter is intended to be used with server rendered pages, which this project does not contain any of. As such, this adapter is unnecessary."
96
+ );
97
+ }
98
+ _config = config;
99
+ finalBuildOutput = buildOutput;
100
+ setAdapter({
101
+ name: "@astrojs/cloudflare",
102
+ serverEntrypoint: "@astrojs/cloudflare/entrypoints/server.js",
103
+ exports: ["default"],
104
+ adapterFeatures: {
105
+ edgeMiddleware: false,
106
+ buildOutput: "server"
107
+ },
108
+ supportedAstroFeatures: {
109
+ serverOutput: "stable",
110
+ hybridOutput: "stable",
111
+ staticOutput: "unsupported",
112
+ i18nDomains: "experimental",
113
+ sharpImageService: {
114
+ support: "limited",
115
+ message: "Cloudflare does not support sharp. You can use the `compile` image service to compile images at build time. It will not work for any on-demand rendered images."
168
116
  },
169
- 'astro:build:done': async ({ pages, dir, logger, assets }) => {
170
- await cloudflareModulePlugin.afterBuildCompleted(_config);
171
- const PLATFORM_FILES = ['_headers', '_redirects', '_routes.json'];
172
- if (_config.base !== '/') {
173
- for (const file of PLATFORM_FILES) {
174
- try {
175
- await rename(new URL(file, _config.build.client), new URL(file, _config.outDir));
176
- }
177
- catch (e) {
178
- logger.error(`There was an error moving ${file} to the root of the output directory.`);
179
- }
180
- }
181
- }
182
- let redirectsExists = false;
183
- try {
184
- const redirectsStat = await stat(new URL('./_redirects', _config.outDir));
185
- if (redirectsStat.isFile()) {
186
- redirectsExists = true;
187
- }
188
- }
189
- catch (error) {
190
- redirectsExists = false;
191
- }
192
- const redirects = [];
193
- if (redirectsExists) {
194
- const rl = createInterface({
195
- input: createReadStream(new URL('./_redirects', _config.outDir)),
196
- crlfDelay: Number.POSITIVE_INFINITY,
197
- });
198
- for await (const line of rl) {
199
- const parts = line.split(' ');
200
- if (parts.length >= 2) {
201
- const p = removeLeadingForwardSlash(parts[0])
202
- .split('/')
203
- .filter(Boolean)
204
- .map((s) => {
205
- const syntax = s
206
- .replace(/\/:.*?(?=\/|$)/g, '/*')
207
- // remove query params as they are not supported by cloudflare
208
- .replace(/\?.*$/, '');
209
- return getParts(syntax);
210
- });
211
- redirects.push(p);
212
- }
213
- }
214
- }
215
- let routesExists = false;
216
- try {
217
- const routesStat = await stat(new URL('./_routes.json', _config.outDir));
218
- if (routesStat.isFile()) {
219
- routesExists = true;
220
- }
221
- }
222
- catch (error) {
223
- routesExists = false;
117
+ envGetSecret: "stable"
118
+ }
119
+ });
120
+ },
121
+ "astro:server:setup": async ({ server }) => {
122
+ if ((args?.platformProxy?.enabled ?? true) === true) {
123
+ const platformProxy = await getPlatformProxy(args?.platformProxy);
124
+ setProcessEnv(_config, platformProxy.env);
125
+ const clientLocalsSymbol = Symbol.for("astro.locals");
126
+ server.middlewares.use(async function middleware(req, _res, next) {
127
+ Reflect.set(req, clientLocalsSymbol, {
128
+ runtime: {
129
+ env: platformProxy.env,
130
+ cf: platformProxy.cf,
131
+ caches: platformProxy.caches,
132
+ ctx: {
133
+ waitUntil: (promise) => platformProxy.ctx.waitUntil(promise),
134
+ // Currently not available: https://developers.cloudflare.com/pages/platform/known-issues/#pages-functions
135
+ passThroughOnException: () => {
136
+ throw new AstroError(
137
+ "`passThroughOnException` is currently not available in Cloudflare Pages. See https://developers.cloudflare.com/pages/platform/known-issues/#pages-functions."
138
+ );
139
+ }
224
140
  }
225
- if (!routesExists) {
226
- await createRoutesFile(_config, logger, _routes, pages, redirects, args?.routes?.extend?.include, args?.routes?.extend?.exclude);
227
- }
228
- const trueRedirects = createRedirectsFromAstroRoutes({
229
- config: _config,
230
- routeToDynamicTargetMap: new Map(Array.from(_routes
231
- .filter((route) => route.type === 'redirect')
232
- .map((route) => [route, '']))),
233
- dir,
234
- buildOutput: finalBuildOutput,
235
- assets,
236
- });
237
- if (!trueRedirects.empty()) {
238
- try {
239
- await appendFile(new URL('./_redirects', _config.outDir), trueRedirects.print());
240
- }
241
- catch (error) {
242
- logger.error('Failed to write _redirects file');
243
- }
244
- }
245
- },
246
- },
247
- };
141
+ }
142
+ });
143
+ next();
144
+ });
145
+ }
146
+ },
147
+ "astro:build:setup": ({ vite, target }) => {
148
+ if (target === "server") {
149
+ vite.resolve ||= {};
150
+ vite.resolve.alias ||= {};
151
+ const aliases = [
152
+ {
153
+ find: "react-dom/server",
154
+ replacement: "react-dom/server.browser"
155
+ }
156
+ ];
157
+ if (Array.isArray(vite.resolve.alias)) {
158
+ vite.resolve.alias = [...vite.resolve.alias, ...aliases];
159
+ } else {
160
+ for (const alias of aliases) {
161
+ vite.resolve.alias[alias.find] = alias.replacement;
162
+ }
163
+ }
164
+ vite.ssr ||= {};
165
+ vite.ssr.resolve ||= {};
166
+ vite.ssr.resolve.conditions ||= [...defaultClientConditions];
167
+ vite.ssr.resolve.conditions.push("workerd", "worker");
168
+ vite.ssr.target = "webworker";
169
+ vite.ssr.noExternal = true;
170
+ vite.build ||= {};
171
+ vite.build.rollupOptions ||= {};
172
+ vite.build.rollupOptions.output ||= {};
173
+ vite.build.rollupOptions.output.banner ||= "globalThis.process ??= {}; globalThis.process.env ??= {};";
174
+ vite.define = {
175
+ "process.env": "process.env",
176
+ ...vite.define
177
+ };
178
+ }
179
+ },
180
+ "astro:build:done": async ({ pages, dir, logger, assets }) => {
181
+ await cloudflareModulePlugin.afterBuildCompleted(_config);
182
+ const PLATFORM_FILES = ["_headers", "_redirects", "_routes.json"];
183
+ if (_config.base !== "/") {
184
+ for (const file of PLATFORM_FILES) {
185
+ try {
186
+ await rename(new URL(file, _config.build.client), new URL(file, _config.outDir));
187
+ } catch (_e) {
188
+ logger.error(
189
+ `There was an error moving ${file} to the root of the output directory.`
190
+ );
191
+ }
192
+ }
193
+ }
194
+ let redirectsExists = false;
195
+ try {
196
+ const redirectsStat = await stat(new URL("./_redirects", _config.outDir));
197
+ if (redirectsStat.isFile()) {
198
+ redirectsExists = true;
199
+ }
200
+ } catch (_error) {
201
+ redirectsExists = false;
202
+ }
203
+ const redirects = [];
204
+ if (redirectsExists) {
205
+ const rl = createInterface({
206
+ input: createReadStream(new URL("./_redirects", _config.outDir)),
207
+ crlfDelay: Number.POSITIVE_INFINITY
208
+ });
209
+ for await (const line of rl) {
210
+ const parts = line.split(" ");
211
+ if (parts.length >= 2) {
212
+ const p = removeLeadingForwardSlash(parts[0]).split("/").filter(Boolean).map((s) => {
213
+ const syntax = s.replace(/\/:.*?(?=\/|$)/g, "/*").replace(/\?.*$/, "");
214
+ return getParts(syntax);
215
+ });
216
+ redirects.push(p);
217
+ }
218
+ }
219
+ }
220
+ let routesExists = false;
221
+ try {
222
+ const routesStat = await stat(new URL("./_routes.json", _config.outDir));
223
+ if (routesStat.isFile()) {
224
+ routesExists = true;
225
+ }
226
+ } catch (_error) {
227
+ routesExists = false;
228
+ }
229
+ if (!routesExists) {
230
+ await createRoutesFile(
231
+ _config,
232
+ logger,
233
+ _routes,
234
+ pages,
235
+ redirects,
236
+ args?.routes?.extend?.include,
237
+ args?.routes?.extend?.exclude
238
+ );
239
+ }
240
+ const trueRedirects = createRedirectsFromAstroRoutes({
241
+ config: _config,
242
+ routeToDynamicTargetMap: new Map(
243
+ Array.from(
244
+ _routes.filter((route) => route.type === "redirect").map((route) => [route, ""])
245
+ )
246
+ ),
247
+ dir,
248
+ buildOutput: finalBuildOutput,
249
+ assets
250
+ });
251
+ if (!trueRedirects.empty()) {
252
+ try {
253
+ await appendFile(new URL("./_redirects", _config.outDir), trueRedirects.print());
254
+ } catch (_error) {
255
+ logger.error("Failed to write _redirects file");
256
+ }
257
+ }
258
+ }
259
+ }
260
+ };
248
261
  }
262
+ export {
263
+ createIntegration as default
264
+ };
@@ -1,68 +1,70 @@
1
- import { isRemotePath } from '@astrojs/internal-helpers/path';
2
- export function isESMImportedImage(src) {
3
- return typeof src === 'object';
1
+ import { isRemotePath } from "@astrojs/internal-helpers/path";
2
+ function isESMImportedImage(src) {
3
+ return typeof src === "object";
4
4
  }
5
- export function matchHostname(url, hostname, allowWildcard) {
6
- if (!hostname) {
7
- return true;
8
- }
9
- if (!allowWildcard || !hostname.startsWith('*')) {
10
- return hostname === url.hostname;
11
- }
12
- if (hostname.startsWith('**.')) {
13
- const slicedHostname = hostname.slice(2); // ** length
14
- return slicedHostname !== url.hostname && url.hostname.endsWith(slicedHostname);
15
- }
16
- if (hostname.startsWith('*.')) {
17
- const slicedHostname = hostname.slice(1); // * length
18
- const additionalSubdomains = url.hostname
19
- .replace(slicedHostname, '')
20
- .split('.')
21
- .filter(Boolean);
22
- return additionalSubdomains.length === 1;
23
- }
24
- return false;
5
+ function matchHostname(url, hostname, allowWildcard) {
6
+ if (!hostname) {
7
+ return true;
8
+ }
9
+ if (!allowWildcard || !hostname.startsWith("*")) {
10
+ return hostname === url.hostname;
11
+ }
12
+ if (hostname.startsWith("**.")) {
13
+ const slicedHostname = hostname.slice(2);
14
+ return slicedHostname !== url.hostname && url.hostname.endsWith(slicedHostname);
15
+ }
16
+ if (hostname.startsWith("*.")) {
17
+ const slicedHostname = hostname.slice(1);
18
+ const additionalSubdomains = url.hostname.replace(slicedHostname, "").split(".").filter(Boolean);
19
+ return additionalSubdomains.length === 1;
20
+ }
21
+ return false;
25
22
  }
26
- export function matchPort(url, port) {
27
- return !port || port === url.port;
23
+ function matchPort(url, port) {
24
+ return !port || port === url.port;
28
25
  }
29
- export function matchProtocol(url, protocol) {
30
- return !protocol || protocol === url.protocol.slice(0, -1);
26
+ function matchProtocol(url, protocol) {
27
+ return !protocol || protocol === url.protocol.slice(0, -1);
31
28
  }
32
- export function matchPathname(url, pathname, allowWildcard) {
33
- if (!pathname) {
34
- return true;
35
- }
36
- if (!allowWildcard || !pathname.endsWith('*')) {
37
- return pathname === url.pathname;
38
- }
39
- if (pathname.endsWith('/**')) {
40
- const slicedPathname = pathname.slice(0, -2); // ** length
41
- return slicedPathname !== url.pathname && url.pathname.startsWith(slicedPathname);
42
- }
43
- if (pathname.endsWith('/*')) {
44
- const slicedPathname = pathname.slice(0, -1); // * length
45
- const additionalPathChunks = url.pathname
46
- .replace(slicedPathname, '')
47
- .split('/')
48
- .filter(Boolean);
49
- return additionalPathChunks.length === 1;
50
- }
51
- return false;
29
+ function matchPathname(url, pathname, allowWildcard) {
30
+ if (!pathname) {
31
+ return true;
32
+ }
33
+ if (!allowWildcard || !pathname.endsWith("*")) {
34
+ return pathname === url.pathname;
35
+ }
36
+ if (pathname.endsWith("/**")) {
37
+ const slicedPathname = pathname.slice(0, -2);
38
+ return slicedPathname !== url.pathname && url.pathname.startsWith(slicedPathname);
39
+ }
40
+ if (pathname.endsWith("/*")) {
41
+ const slicedPathname = pathname.slice(0, -1);
42
+ const additionalPathChunks = url.pathname.replace(slicedPathname, "").split("/").filter(Boolean);
43
+ return additionalPathChunks.length === 1;
44
+ }
45
+ return false;
52
46
  }
53
- export function matchPattern(url, remotePattern) {
54
- return (matchProtocol(url, remotePattern.protocol) &&
55
- matchHostname(url, remotePattern.hostname, true) &&
56
- matchPort(url, remotePattern.port) &&
57
- matchPathname(url, remotePattern.pathname, true));
47
+ function matchPattern(url, remotePattern) {
48
+ return matchProtocol(url, remotePattern.protocol) && matchHostname(url, remotePattern.hostname, true) && matchPort(url, remotePattern.port) && matchPathname(url, remotePattern.pathname, true);
58
49
  }
59
- export function isRemoteAllowed(src, { domains = [], remotePatterns = [], }) {
60
- if (!isRemotePath(src))
61
- return false;
62
- const url = new URL(src);
63
- return (domains.some((domain) => matchHostname(url, domain)) ||
64
- remotePatterns.some((remotePattern) => matchPattern(url, remotePattern)));
50
+ function isRemoteAllowed(src, {
51
+ domains = [],
52
+ remotePatterns = []
53
+ }) {
54
+ if (!isRemotePath(src)) return false;
55
+ const url = new URL(src);
56
+ return domains.some((domain) => matchHostname(url, domain)) || remotePatterns.some((remotePattern) => matchPattern(url, remotePattern));
65
57
  }
66
- export function isString(path) {
67
- return typeof path === 'string' || path instanceof String;
58
+ function isString(path) {
59
+ return typeof path === "string" || path instanceof String;
68
60
  }
61
+ export {
62
+ isESMImportedImage,
63
+ isRemoteAllowed,
64
+ isString,
65
+ matchHostname,
66
+ matchPathname,
67
+ matchPattern,
68
+ matchPort,
69
+ matchProtocol
70
+ };