@sveltejs/adapter-cloudflare
Advanced tools
Comparing version 2.0.2 to 2.1.0
import { Adapter } from '@sveltejs/kit'; | ||
import './ambient.js'; | ||
export default function plugin(): Adapter; | ||
export default function plugin(options?: AdapterOptions): Adapter; | ||
export interface AdapterOptions { | ||
/** | ||
* Customize the automatically-generated `_routes.json` file | ||
* https://developers.cloudflare.com/pages/platform/functions/routing/#create-a-_routesjson-file | ||
*/ | ||
routes?: { | ||
/** | ||
* Routes that will be invoked by functions. Accepts wildcards. | ||
* @default ["/*"] | ||
*/ | ||
include?: string[]; | ||
/** | ||
* Routes that will not be invoked by functions. Accepts wildcards. | ||
* `exclude` takes priority over `include`. | ||
* | ||
* To have the adapter automatically exclude certain things, you can use these placeholders: | ||
* | ||
* - `<build>` to exclude build artifacts (files generated by Vite) | ||
* - `<files>` for the contents of your `static` directory | ||
* - `<prerendered>` for prerendered routes | ||
* - `<all>` to exclude all of the above | ||
* | ||
* @default ["<all>"] | ||
*/ | ||
exclude?: string[]; | ||
}; | ||
} | ||
export interface RoutesJSONSpec { | ||
@@ -7,0 +36,0 @@ version: 1; |
90
index.js
@@ -7,3 +7,3 @@ import { writeFileSync } from 'node:fs'; | ||
/** @type {import('.').default} */ | ||
export default function () { | ||
export default function (options = {}) { | ||
return { | ||
@@ -34,3 +34,3 @@ name: '@sveltejs/adapter-cloudflare', | ||
`${dest}/_routes.json`, | ||
JSON.stringify(get_routes_json(builder, written_files)) | ||
JSON.stringify(get_routes_json(builder, written_files, options.routes ?? {}), null, '\t') | ||
); | ||
@@ -65,46 +65,58 @@ | ||
* @param {string[]} assets | ||
* @param {import('./index').AdapterOptions['routes']} routes | ||
* @returns {import('.').RoutesJSONSpec} | ||
*/ | ||
function get_routes_json(builder, assets) { | ||
/** | ||
* The list of routes that will _not_ invoke functions (which cost money). | ||
* This is done on a best-effort basis, as there is a limit of 100 rules | ||
*/ | ||
const exclude = [ | ||
`/${builder.config.kit.appDir}/*`, | ||
...assets | ||
.filter( | ||
(file) => | ||
!( | ||
file.startsWith(`${builder.config.kit.appDir}/`) || | ||
file === '_headers' || | ||
file === '_redirects' | ||
function get_routes_json(builder, assets, { include = ['/*'], exclude = ['<all>'] }) { | ||
if (!Array.isArray(include) || !Array.isArray(exclude)) { | ||
throw new Error(`routes.include and routes.exclude must be arrays`); | ||
} | ||
if (include.length === 0) { | ||
throw new Error(`routes.include must contain at least one route`); | ||
} | ||
if (include.length > 100) { | ||
throw new Error(`routes.include must contain 100 or fewer routes`); | ||
} | ||
exclude = exclude | ||
.flatMap((rule) => (rule === '<all>' ? ['<build>', '<files>', '<prerendered>'] : rule)) | ||
.flatMap((rule) => { | ||
if (rule === '<build>') { | ||
return `/${builder.config.kit.appDir}/*`; | ||
} | ||
if (rule === '<files>') { | ||
return assets | ||
.filter( | ||
(file) => | ||
!( | ||
file.startsWith(`${builder.config.kit.appDir}/`) || | ||
file === '_headers' || | ||
file === '_redirects' | ||
) | ||
) | ||
) | ||
.map((file) => `/${file}`) | ||
]; | ||
.map((file) => `/${file}`); | ||
} | ||
const MAX_EXCLUSIONS = 99; // 100 minus existing `include` rules | ||
let excess; | ||
if (rule === '<prerendered>') { | ||
const prerendered = []; | ||
for (const path of builder.prerendered.paths) { | ||
if (!builder.prerendered.redirects.has(path)) { | ||
prerendered.push(path); | ||
} | ||
} | ||
if (exclude.length > MAX_EXCLUSIONS) { | ||
excess = 'static assets'; | ||
return prerendered; | ||
} | ||
if (builder.prerendered.paths.length > 0) { | ||
excess += ' or prerendered routes'; | ||
} | ||
} else if (exclude.length + builder.prerendered.paths.length > MAX_EXCLUSIONS) { | ||
excess = 'prerendered routes'; | ||
} | ||
return rule; | ||
}); | ||
for (const path of builder.prerendered.paths) { | ||
if (!builder.prerendered.redirects.has(path)) { | ||
exclude.push(path); | ||
} | ||
} | ||
const excess = include.length + exclude.length - 100; | ||
if (excess > 0) { | ||
const message = `Function includes/excludes exceeds _routes.json limits (see https://developers.cloudflare.com/pages/platform/functions/routing/#limits). Dropping ${excess} exclude rules — this will cause unnecessary function invocations.`; | ||
builder.log.warn(message); | ||
if (excess) { | ||
const message = `Static file count exceeds _routes.json limits (see https://developers.cloudflare.com/pages/platform/functions/routing/#limits). Accessing some ${excess} will cause function invocations.`; | ||
builder.log.warn(message); | ||
exclude.length = 99; | ||
exclude.length -= excess; | ||
} | ||
@@ -115,3 +127,3 @@ | ||
description: 'Generated by @sveltejs/adapter-cloudflare', | ||
include: ['/*'], | ||
include, | ||
exclude | ||
@@ -118,0 +130,0 @@ }; |
{ | ||
"name": "@sveltejs/adapter-cloudflare", | ||
"version": "2.0.2", | ||
"version": "2.1.0", | ||
"repository": { | ||
@@ -5,0 +5,0 @@ "type": "git", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
10801
248