2026-08-06 — Extraction into a package
Turned this repository from the Node.js library template into @bayudwiyansatria/cloudflare, the Cloudflare adapter
package, by lifting src/core/cloudflare/ and src/core/http/ out of the application they grew up in.
Moved in
45 files, flattened by one level — everything in this package is core, so the core/cloudflare/ prefix is dropped:
| From (application) | To |
|---|---|
src/core/cloudflare/bindings/ |
src/bindings/ |
src/core/cloudflare/services/ |
src/services/ |
src/core/cloudflare/config/ |
src/config/ |
src/core/cloudflare/CloudflareRequestMetadata.ts |
src/CloudflareRequestMetadata.ts |
src/core/cloudflare/types/env.d.ts |
src/types/CloudflareEnv.ts |
src/core/http/ |
src/middlewares/ |
Removed the template's placeholder domain: src/core/Health.ts, src/core/Metadata.ts, src/types/HealthStatus.ts,
src/types/LibraryMetadata.ts, src/constants/, src/utils/Text.ts, src/exceptions/LibraryException.ts, and the
three specs over them.
Two defects found by verification
Both were found by running the built artifacts, not by review, and neither shows up in a build log.
Importing the package threw before it could be configured. Services construct their accessors at module scope, and
those constructors called resolve(). ES imports are hoisted, so a consumer's configure() call cannot run first — the
import statement itself threw ConfigurationError, and no ordering would have fixed it. Added
src/config/lazySettings.ts, a memoised getter that defers the lookup to first use; Binding now accepts a thunk for
its name, and SecurityMiddleware reads its settings through getters. Caught by a Node smoke test against
lib/index.min.mjs.
SecurityMiddleware.apply() had the same problem one level up. Making the constructor lazy was not enough:
apply() reads the protected pattern and the allowed origins to register routes, which an application does at module
scope. Fixed on the consumer side — the application now calls configure() from src/config/index.ts and app.ts
names that dependency with a side-effect import, so the module graph enforces the order. Caught by running the built
Worker bundle.
Changed in the move
Env(ambient global) →CloudflareEnv(exported interface), with every member optional. Bindings and services are generic over<E extends CloudflareEnv>with a default, so existing call sites are unchanged.resolve('kv')→resolve<KVSettings>('kv'): the kernel cannot know the assembled surface, so the caller declares the shape it expects.- 39 kernel imports collapsed to
@bayudwiyansatria/core; in-package imports use the@/*mapping. - Cross-package
{@link}references became prose — a symbol in another package cannot resolve. AnalyticsService's module-scopeenabledflag became a memoised getter.
Packaging
- Renamed to
@bayudwiyansatria/cloudflareat1.0.0; dependency on@bayudwiyansatria/core, peers on@cloudflare/workers-typesand (optionally)hono. - Two Rollup entries matching the two
exportssubpaths, plustypesVersionsso./middlewaresresolves under classic node10 resolution — without it@rollup/plugin-typescriptcannot find the subpath even whentsccan. - Added
rollup.config.ts#externaland anassertExternalsRollup plugin beside it, so the check runs on every build rather than as a separate step. Verified it fails correctly by building withexternalemptied: it reported both the missing imports and the inlined-kernel marker. - Dropped the UMD output, and turned off
sourcemapfor the declaration bundle —rollup-plugin-dtsemits a map withsources: []that is inert and crashes TypeDoc when a downstream package resolves a symbol from here.
Tooling
- Adopted the three custom ESLint documentation rules the application already ran:
kind-tag-without-argument,no-redundant-tag,one-declaration-per-file. - Replaced the template's leaf-layer boundary with the Hono boundary: only
src/middlewares/may importhono. tsconfig.json:libusesWebWorkerrather thanDOM;typesincludes@cloudflare/workers-types.- Bumped
@types/nodeto^22— Node 18 is past end of life, and its types predate the globalcryptodeclaration thatSignatureneeds.
Tests
47 specs across four suites: Binding lookup and the missing-binding paths including the cross-package instanceof,
the lazy-settings ordering guarantee, KVService degradation with and without a namespace, and SecurityMiddleware
against a real Hono app — API-key admission and refusal, fail-closed on an unconfigured secret, excluded routes, and the
origin guard.
Documentation
Rewrote README.md, AGENTS.md, docs/SUMMARY.md, and docs/reference/directory-structure.md for the package's new
identity. Folded in the application's guide/bindings.md as reference/bindings.md, removed
guides/using-this-template.md, and added guides/migrating-from-boilerplate.md.