Releases: cloudflare/miniflare
v2.6.0
Features
- 🪣 Add support for R2 bucket bindings. Closes issue #276, thank you so much @CraigglesO for the massive PR.
- Add support for
navigator.userAgent. Closes issue #209, thanks @Electroid. - Return fixed time from
new Date()/Date.now(), unless the--actual-time/actualTime: trueoption is set, to match the behaviour the Workers runtime. Closes issue #225, thanks @ItalyPaleAle. - Add support for
(De)CompressionStream. Closes issue #206, thanks @Electroid. - Add an interactive REPL via the
--replflag. Any other flag can be passed too, and options will automatically be loaded fromwrangler.tomlfiles. Specifying a script is optional when--replis enabled. The REPL can also be started programmatically via theMiniflare#startREPL()method. See for more details. Thanks @threepointone for the idea over at cloudflare/wrangler2#1263.
Fixes
- Load service bindings from
servicesinstead ofexperimental_services, and usebindinginstead ofnamefor the binding name. Thanks @jrencz for the PR. issue #280. - Log warning instead of error when fetching
Request#cfobject fails. Closes issue #224, thanks @threepointone. - Increase the subrequest limit for
unboundworkers from 50 to 1000, and limit the number of calls to internal APIs such as KV/Durable Object to 1000. Closes issue #274, thanks @isaac-mcfadyen. - Fix logging of accessible hosts in Node.js 18
- Remove
namefromDurableObjectIds inDurableObjectStateto match the behaviour of the Workers runtime. Closes issue #219. - Allow failure WebSocket upgrade responses. Closes issue #174, thanks @jinjor.
- Correctly handle internationalised domain names in routes. Closes issue #186, thanks @dsod.
- Improve the error message when Durable Object bindings are missing a script to mention mounting. Closes issue #221, thanks @konsumer.
- Allow WebSockets to be closed without a status code. Closes issue #284, thanks @hansottowirtz.
- Allow Durable Object alarms to be scheduled less than 30 seconds in the future. Closes issue #290, thanks @wighawag and @CraigglesO for the PR.
- Fix
DurableObjectStorage#list()when alarms are scheduled. Closes issue #297, thanks @evanderkoogh and @CraigglesO for the PR.
v2.5.1
⚠️ Security Update
- Upgrade
undicito5.5.1, addressing GHSA-pgw7-wx7w-2w33 - Upgrade
node-forgeto1.3.1, addressing GHSA-2r2c-g63r-vccr, GHSA-x4jg-mjrx-434g and GHSA-cfm4-qjh2-4765 - Upgrade
minimistto1.2.6, addressing GHSA-xvch-5gv4-984h
v2.5.0
Features
- ⏰ Add support for Durable Object alarms. Thanks @CraigglesO for the PR.
- Add support for
URLPattern. Closes issue #199, thanks @Electroid and @tom-sherman for the PR. - Add support for the
Response.json()static method. Closes issue #272, thanks @Cherry. - Add support for the
startAfterDurable Objectlist()option. Closes issue #266, thanks @vlovich. - Add support for Jest 28 and custom export conditions. By default, the Miniflare Jest environment will use the
workercondition, followed bybrowser. Closes issues #249 and #255, thanks @awwong1 and @SupremeTechnopriest.
Fixes
- Fixed issue where
403 Forbiddenresponses were returned when a site behind Cloudflare was set as the upstream. Closes issue #237, thanks @james-maher for the PR. - Respect
env_pathoption inwrangler.tomlwhen using mounts or the Miniflare Jest environment. Closes issue #240, thanks @bkniffler. - Fix cases where BYOB readers didn't notice the end of the stream. Closes issue #192, thanks @vlovich for the PR.
- Wait for unawaited writes within a Durable Object transaction before attempting to commit. Closes issue #250, thanks @vlovich.
- Correctly bind
thisincryptoandcrypto.subtle. Closes issue #256, thanks @lmcarreiro and @awwong1 for the PR. - Bump
busboyto resolve a security issue. Closes issue #267, thanks @grempe and @Cherry for the PR. - Set incoming
Accept-Encodingheaders togzipand put actual client encodings inrequest.cf.clientAcceptEncodingto match the behaviour of the Workers runtime. Closes issue #180, thanks @evanderkoogh and @leader22 for the PR. - Remove restriction on supported
TextDecoderencodings. Closes issue #212. - Make
headerson returnedfetchResponses immutable. Closes issue #242, thanks @nickreese. - Use lexicographic ordering for KV/Durable Object
list()s. Closes issue #235, thanks @vlovich. - Re-export
Request,RequestInfo,RequestInitandResponsefromminiflare. Closes issue #258, thanks @ajwootto. - Add
jest-environment-miniflare's missingdependencies. Thanks @BasixKOR for the PR.
v2.4.0
Features
- Add support for
[text_blobs]. Closes issue #211, thanks @caass for the PR. - Add support for
[data_blobs]. Closes issue #231, thanks @threepointone for the PR. - Do not display the pretty error page when making requests with
curl. Closes issue #198, thanks @GregBrimble for the PR.
Fixes
- Pass correctly-typed value to
webcrypto.getRandomValues(). Closes issue #188, thanks @vlovich. - Fix
fetchwithContent-Length: 0header. Closes issue #193, thanks @orls for the PR. - Bind
thistowebcryptomethods, fixingcrypto.getRandomValues()andcrypto.subtle.generateKey(). Thanks @szkl for the PR.
v2.3.0
Features
- Route
/cdn-cgi/mf/scheduledrequests based on mount routes. Closes issue #163, thanks @jed. - Add clear error if a Durable Object class is missing a
fetchhandler. Closes issue #164, thanks @aboodman. - Upgrade
undicito4.13.0
Fixes
- Fix
instanceofwhen subclassingError. Subclasses ofErrorwere previously treated asErrors themselves ininstanceofchecks. Closes issue #159, thanks @valeriangalliat. - Return
nullbodies whenfetchingResponses with a null status. Closes issue #165, thanks @lukaszczerpak for reporting this and @GregBrimble for the PR. - Clone
ArrayBufferbodies when constructingRequest/Responses. Closes issue #171, thanks @segator and @leader22. - Watch
index.jsby default intype = "webpack"projects - Throw
TypeErrors instead ofstrings onHTMLRewriterparser errors - Disable nested mounts via
Miniflare#getMount().setOptions()
v2.2.0
Features
- Add support for the
HTMLRewriterElement#onEndTag(handler)method - Add support for the
html_rewriter_treats_esi_include_as_void_tagcompatibility flag - Make the error message when attempting to import Node.js built-in modules more helpful
Fixes
- Fix
instanceofchecks withnullvalues. Closes issues #152 and #154. Thanks @Cerberus for the PR, and @bduff9, @huw & @g45t345rt for reporting this. - Fix subdirectory watching on Linux. Closes issue #153, thanks @huw for reporting this.
- Throw a
TypeErrorinstead of astringwhen the parameter passed to aHTMLRewriterhandler is used outside the handler
v2.1.0
Features
-
Allow multiple build watch paths to be set in
wrangler.tomlfiles. Use the[miniflare] build_watch_dirsoption. Note this gets merged with the regular[build] watch_diroption:[build] watch_dir = "src1" [miniflare] build_watch_dirs = ["src2", "src3"]
-
WebSocket handshake headers are now included in responses from the HTTP server and WebSocket upgrade
fetches. Closes issue #151, thanks @jed.
Fixes
- Allow Miniflare to be installed with Yarn PnP. Closes issue #144, thanks @lookfirst, @merceyz, and @DJtheRedstoner.
- Use the actual body length for the
Content-Lengthheader in HTTP server responses, instead of the value provided in theResponseconstructor. Closes issue #148, thanks @lukaszczerpak. - Don't rewrite the
Hostheader to match the upstream URL. Closes issue #149, thanks @hansede. - Bump dependencies, fixing
npm auditwarnings. Thanks @leader22 for the PR. - Make
instanceofspec-compliant, ensuring checks likeObject instanceof Objectsucceed. This particular check was used by Lodash's_.isPlainObject()method, which is internally called by_.merge(), causing unexpected results. - Make the unimplemented
Response#typeproperty non-enumerable - Copy header guard when
clone()ingRequests, ensuringRequests with immutable headers still have immutable headers whenclone()ed - Fix race conditions in file-system watcher
v2.0.0
Miniflare 2 has been completely redesigned from version 1 with 3 primary design goals:
- 📚 Modular: Miniflare 2 splits Workers components (KV, Durable Objects, etc.) into separate packages (
@miniflare/kv,@miniflare/durable-objects, etc.) that you can import separately for testing. - ✨ Lightweight: Miniflare 1 included 122 third-party packages with a total install size of
88MB. Miniflare 2 reduces this to 24 packages and6MBby leveraging features included with Node.js 16. - ✅ Accurate: Miniflare 2 more accurately replicates the quirks and thrown errors of the real Workers runtime, so you'll know before you deploy if things are going to break.
Check out the migration guide if you're upgrading from version 1.
Notable Changes
- ✳️ Node.js 16.7.0 is now the minimum required version
- 🤹 Added a custom Jest test environment, allowing you to run unit tests in the Miniflare sandbox, with isolated storage for each test
- 🔌 Added support for running multiple workers in the same Miniflare instance
- ⚡️ Added a live reload feature (
--live-reload) that automatically refreshes your browser when your worker reloads - 🚪 Added Durable Object input and output gates, and write coalescing
- 🛑 Added the
DurableObjectState#blockConcurrencyWhile(callback)method - 📅 Added support for compatibility dates and flags:
durable_object_fetch_requires_full_url,fetch_refuses_unknown_protocols,formdata_parser_supports_files - 📚 Added a proper CommonJS module loader
- 🗺 Automatically fetch the incoming
Request#cfobject from a trusted Cloudflare endpoint - 🎲 Added support for
crypto.randomUUID() - 🔐 Added support for the
NODE-ED25519algorithm - ✉️ Added support for sending/receiving binary WebSocket messages
Breaking Changes
-
Node.js 16.7.0 is now the minimum required version. You should use the latest Node.js version if possible, as Cloudflare Workers use a very up-to-date version of V8. Consider using a Node.js version manager such as https://volta.sh/ or https://github.com/nvm-sh/nvm.
-
Changed the storage format for Durable Objects and cached responses. If you're using file-system or Redis storage, you'll need to delete these directories/namespaces.
-
Changed the Durable Object ID format to include a hash of the object name. Durable Object IDs generated in Miniflare 1 cannot be used with Miniflare 2.
-
Correctly implement the Durable Object
script_nameoption. In Miniflare 1, this incorrectly expected a script path instead of a script name. This now relies on mounting the other worker. See 📌 Durable Objects for more details. -
Removed the non-standard
DurableObjectStub#storage()method. To access Durable Object storage outside a worker, use the newMiniflare#getDurableObjectStorage(id)method, passing aDurableObjectIdobtained from a stub. See 📌 Durable Objects for more details. -
Renamed the
--disable-cache/disableCache: trueoption to--no-cache/cache: false -
Renamed the
--disable-updateroption to--no-update-check -
When using the API,
wrangler.toml,package.jsonand.envare no longer automatically loaded from their default locations. To re-enable this behaviour, set these options totrue:const mf = new Miniflare({ wranglerConfigPath: true, packagePath: true, envPath: true, });
-
Replaced the
ConsoleLogclass with theLogclass from@miniflare/shared. You can construct this with aLogLevelto control how much information is logged to the console:import { Miniflare, Log, LogLevel } from "miniflare"; const mf = new Miniflare({ log: new Log(LogLevel.DEBUG), });
-
Load WASM bindings from the standard
wasm_moduleswrangler.tomlkey instead ofminiflare.wasm_bindings.[miniflare] wasm_bindings = [ { name = "MODULE1", path="module1.wasm" }, { name = "MODULE2", path="module2.wasm" } ]
...should now be...
[wasm_modules] MODULE1 = "module1.wasm" MODULE2 = "module2.wasm"
-
Renamed the
buildWatchPathoption tobuildWatchPaths. This is now an array of string paths to watch as opposed to a single string. -
Replaced the
Miniflare#reloadOptions()method with theMiniflare#reload()andMiniflare#setOptions({ ... })methods.reload()will reload options fromwrangler.toml(useful if not watching), andsetOptions()accepts the same options object as thenew Miniflareconstructor, applies those options, then reloads the worker. -
Replaced the
Miniflare#getCache()method theMiniflare#getCaches()method. This returns the globalcachesobject. See ✨ Cache . -
Miniflare#createServer()now always returns aPromisewhich you must await to get ahttp.Server/https.Serverinstance. You may want to check out the newMiniflare#startServer()method which automatically starts a server using the configuredhostandport. -
Redis support is no longer included by default. If you're persisting KV, Durable Objects or cached responses in Redis, you must install the
@miniflare/storage-redisoptional peer dependency. -
Replaced how Miniflare sanitises file paths for file-system storage so namespace separators (
/,\,:and|) now create new directories. -
The result of
Miniflare#dispatchScheduledwill no longer includeundefinedif a module scheduled handler doesn't return a value
Features and Fixes
Cache:
- Added support for
cf.cacheKey,cf.cacheTtlandcf.cacheTtlByStatusonRequest. Closes issue #37, thanks @cdloh. - Added the
CF-Cache-Status: HITheader to matchedResponses - Log warning when trying to use cache with
workers_dev = trueinwrangler.toml. Cache operations are a no-op onworkers.devsubdomains. - Throw errors when trying to cache Web Socket, non-
GET,206 Partial Content, orVary: *responses - Throw an error when trying to
opena cache with a name longer than1024characters
CLI:
- Separated command line options into sections
- Validate types of all command line options
Core:
-
Added support for running multiple workers in the same Miniflare instance. See 🔌 Multiple Workers for more details.
-
Added support for compatibility dates and flags, specifically the flags
durable_object_fetch_requires_full_url,fetch_refuses_unknown_protocols,formdata_parser_supports_filesare now supported. This feature is exposed under the--compat-dateand--compat-flagCLI options, in addition to the standard keys inwrangler.toml. Closes issue #48, thanks @PaganMuffin. See 📅 Compatibility Dates for more details. -
Added a proper CommonJS module loader. Workers built with Webpack will be more likely to work with Miniflare now. Closes issue #44, thanks @TimTinkers.
-
Don't crash on unhandled promise rejections when using the CLI. Instead, log them. Closes issue #115, thanks @togglydev.
-
Limit the number of subrequests to 50, as per the Workers runtime. Closes issue #117, thanks @leader22 for the suggestion.
-
To match the behaviour of the Workers runtime, some functionality, such as asynchronous I/O (
fetch, Cache API, KV), timeouts (setTimeout,setInterval), and generating cryptographically-secure random values (crypto.getRandomValues,crypto.subtle.generateKey), can now only be performed while handling a request.This behaviour can be disabled by setting the
--global-async-io/globalAsyncIO,--global-timers/globalTimersand--global-random/globalRandomoptions respectively, which may be useful for tests or libraries that need async I/O for setup during local development. Note the Miniflare Jest environment automatically enables these options.KV namespaces and caches returned from
Miniflare#getKVNamespace()andgetCaches()are unaffected by this change, so they can still be used in tests without setting any additional options. -
To match the behaviour of the Workers runtime, Miniflare now enforces recursion depth limits. Durable Object
fetches can recurse up to 16 times, and service bindings can recurse up to 32 times. This means if a Durable Object fetch triggers another Durable Object fetch, and so on 16 times, an error will be thrown. -
Incoming request headers are now immutable. Closes issue #36, thanks @grahamlyons.
-
Disabled dynamic WebAssembly compilation in the Miniflare sandbox
-
Fixed
instanceofon primitives such asObject,Array,Promise, etc. from outside the Miniflare sandbox. This makes it much easier to run Rust workers in Miniflare, aswasm-bindgenfrequently generates this code. -
Added a new
--verbose/verbose: trueoption that enables verbose logging with more debugging information -
Throw a more helpful error with suggested fixes when Miniflare can't find your worker's script
-
On...
v2.0.0-rc.5
This update is mostly focused on improving mounts for service bindings. It also matches some other core behaviour of the Workers runtime, like blocking asynchronous I/O outside request handlers, and limiting request recursion depth.
Breaking Changes
NOTE: this change will be reverted in the next release. I've thought of an alternative solution that doesn't need this flag.instanceofchecks on primitives such asObject,Array,Promise, etc. from outside the Miniflare sandbox no longer succeed by default. This was initially added to make it easier to run Rust workers in Miniflare, aswasm-bindgenfrequently generates this code. However, the implementation causedObjectprototype/constructor checks to fail in JavaScript. The previous behaviour can be restored with the--proxy-primitive/miniflare.proxy_primitive_instanceof/proxyPrimitiveInstanceOfCLI/wrangler.toml/API option. This should be enabled when developing Rust workers. See this comment for more details. Closes issues #109, #137, #141 and cloudflare/wrangler2#91. Thanks @EmilianoSanchez, @lukaszczerpak, @SirJosh3917 and @johnhenry.- Mount paths defined in
wrangler.tomlare now resolved relative to the directory containing thewrangler.tomlfile - Mount names must match the
namefield inwrangler.tomlif its defined
Features
-
To match the behaviour of the Workers runtime, some functionality, such as asynchronous I/O (
fetch, Cache API, KV), timeouts (setTimeout,setInterval), and generating cryptographically-secure random values (crypto.getRandomValues,crypto.subtle.generateKey), can now only be performed while handling a request.-
This behaviour can be disabled by setting the
--global-async-io/globalAsyncIO,--global-timers/globalTimersand--global-random/globalRandomoptions respectively, which may be useful for tests or libraries that need async I/O for setup during local development. Note the Miniflare Jest environment automatically enables these options. -
KV namespaces and caches returned from
Miniflare#getKVNamespace()andgetCaches()are unaffected by this change, so they can still be used in tests without setting any additional options.
-
-
Adds highly experimental support for service bindings. This is primarily meant for internal testing, and users outside the beta can't deploy workers using this feature yet, but feel free to play around with them locally and let us know what you think in the Cloudflare Workers Discord server.
To enable these, mount your service (so Miniflare knows where to find it) then add the binding. Note the bound service name must match the mounted name:
$ miniflare --mount auth=./auth --service AUTH_SERVICE=auth # or -S# wrangler.toml experimental_services = [ # Note environment is currently ignored { name = "AUTH_SERVICE", service = "auth", environment = "production" } ] [miniflare.mounts] auth = "./auth"
const mf = new Miniflare({ mounts: { auth: "./auth" }, serviceBindings: { AUTH_SERVICE: "auth" }, });
...then to use the service binding:
export default { async fetch(request, env, ctx) { const res = await env.AUTH_SERVICE.fetch("..."); // ... }, };
If
./auth/wrangler.tomlcontains its own service bindings, those services must also be mounted in the root worker (i.e. inwrangler.tomlnot./auth/wrangler.toml). Nested mounts are not supported. -
To match the behaviour of the Workers runtime, Miniflare now enforces recursion depth limits. Durable Object
fetches can recurse up to 16 times, and service bindings can recurse up to 32 times. This means if a Durable Object fetch triggers another Durable Object fetch, and so on 16 times, an error will be thrown. -
The root worker is now routable using
route/routesas with mounts if it has anameset. This means if it has more specific routes than other mounts, they'll be used instead. The root worker is always used as a fallback if no mounts' routes match. -
Mounted workers can now access Durable Objects defined in other mounts or the root worker (assuming a
nameis set) using thescript_nameoption. -
Allow the subrequest limit to be customised using the
MINIFLARE_SUBREQUEST_LIMITenvironment variable. Setting this to a negative number disables the limit. Setting this to 0 disables subrequests. The majority of users should never need to touch this, hence it's configured via an environment variable, not a CLI option. This also makes the implementation much simpler. :slight_smile: Closes issue #132, thanks @DanielAGW.
Fixes
- Allow
env_pathto be set inwrangler.toml - WebSocket client
fetches now contribute to the subrequest limit - Errors raised when reloading (e.g. missing Durable Object classes) in response to mount file changes are now logged, and don't crash
- Fixed issue where deleting
[miniflare.mounts]inwrangler.tomlwouldn't unmount everything
v2.0.0-rc.4
This update incorporates the 2021-12-10 Workers runtime changes. The Miniflare docs now use the Cloudflare Docs Engine.
Features
- Switched back to CommonJS exports. A primary goal of Miniflare is to provide a fun developer experience. Currently, this is not the case when using Miniflare with a certain popular testing framework (cough,
Jest, cough), because it and its ecosystem's support for ESM isn't great yet. This also makes it easier to upgrade from Miniflare 1. Node lets you import CommonJS modules in ES modules so this won't break existing code. Thanks @Kikobeats. - Added
--open/-Ooption that automatically opens your browser once your worker is running. You can optionally specify a different URL to open with--open https://example.com. Closes issue #121, thanks @third774 for the suggestion. - Don't crash on unhandled promise rejections when using the CLI. Instead, log them. Closes issue #115, thanks @togglydev.
- Added support for
AbortSignal.timeout() - Added support for
crypto.DigestStream - Added support for
scheduler.wait() - Added support for
FixedLengthStream. Closes issue #123, thanks @vlovich. - Limit the number of subrequests to 50, as per the Workers runtime. Closes issue #117, thanks @leader22 for the suggestion.
- Raised the Durable Object storage max value size from
32KiBto128KiB - Re-export remaining
fetchtypes fromundiciin@miniflare/core. Closes issue #124, thanks @GregBrimble.
Fixes
- Fixed issue where
Mathwas missing in sandbox when running Worker for module exports injest-environment-miniflare. Closes issue #128, thanks @worenga for the PR. - Fixed the script path for
type = "webpack"Workers Sites projects - Allow
*/*route in mounted workers kv_persist,cache_persistanddurable_objects_persistoptions set in mounted workers'wrangler.tomlfiles are now respected