@@ -14,7 +14,8 @@ import { readBuildOutput } from "../read";
1414import { writeSettingsConfig , writeWorkerConfig } from "../write" ;
1515import type { ParsedOutputWorkerConfig } from "@cloudflare/config" ;
1616
17- const manifest : ParsedOutputWorkerConfig [ "manifest" ] = {
17+ const completeManifest : ParsedOutputWorkerConfig [ "manifest" ] = {
18+ type : "complete" ,
1819 mainModule : "index.js" ,
1920 modules : { "index.js" : { type : "esm" } } ,
2021} ;
@@ -34,6 +35,18 @@ function inputWorkerConfig(name: string) {
3435 } ) ;
3536}
3637
38+ async function writeBundleFiles (
39+ root : string ,
40+ files : Record < string , string >
41+ ) : Promise < void > {
42+ const bundleDir = getWorkerBundleDir ( root ) ;
43+ for ( const [ fileName , contents ] of Object . entries ( files ) ) {
44+ const filePath = path . join ( bundleDir , fileName ) ;
45+ await fsp . mkdir ( path . dirname ( filePath ) , { recursive : true } ) ;
46+ await fsp . writeFile ( filePath , contents ) ;
47+ }
48+ }
49+
3750/**
3851 * Seed a Worker into the Build Output Specification tree, optionally creating
3952 * the `bundle/` and `assets/` directories on disk.
@@ -62,7 +75,7 @@ async function seedWorker(
6275 await writeWorkerConfig ( {
6376 root,
6477 config : inputWorkerConfig ( name ) ,
65- manifest : hasBundle ? manifest : undefined ,
78+ manifest : hasBundle ? completeManifest : undefined ,
6679 workerDirectoryName,
6780 } ) ;
6881 if ( bundleDir ) {
@@ -95,7 +108,7 @@ describe("readBuildOutput", () => {
95108 expect ( output . workers . default . assetsDir ) . toBeUndefined ( ) ;
96109
97110 expect ( output . workers . default . config . name ) . toBe ( "my-worker" ) ;
98- expect ( output . workers . default . config . manifest ) . toEqual ( manifest ) ;
111+ expect ( output . workers . default . config . manifest ) . toEqual ( completeManifest ) ;
99112 expect ( output . workers . default . config ) . not . toHaveProperty ( "entrypoint" ) ;
100113 } ) ;
101114
@@ -116,6 +129,103 @@ describe("readBuildOutput", () => {
116129 ) ;
117130 } ) ;
118131
132+ it ( "resolves a partial manifest from bundle files and explicit overrides" , async ( {
133+ expect,
134+ } ) => {
135+ const root = process . cwd ( ) ;
136+ await seedWorker ( root ) ;
137+ await writeWorkerConfig ( {
138+ root,
139+ config : inputWorkerConfig ( "my-worker" ) ,
140+ manifest : {
141+ type : "partial" ,
142+ mainModule : "index.js" ,
143+ modules : {
144+ "chunks/worker.mjs" : { type : "cjs" } ,
145+ "data.txt" : { type : "text" } ,
146+ } ,
147+ } ,
148+ } ) ;
149+ await writeBundleFiles ( root , {
150+ "index.js" : "module.exports = {};" ,
151+ "chunks/worker.mjs" : "export default {};" ,
152+ "chunks/worker.mjs.map" : "{}" ,
153+ "data.txt" : "data" ,
154+ "ignored.json" : "{}" ,
155+ } ) ;
156+
157+ const { manifest : resolvedManifest } = ( await readBuildOutput ( root ) ) . workers
158+ . default . config ;
159+
160+ expect ( resolvedManifest ) . toEqual ( {
161+ type : "complete" ,
162+ mainModule : "index.js" ,
163+ modules : {
164+ "chunks/worker.mjs" : { type : "cjs" } ,
165+ "chunks/worker.mjs.map" : { type : "sourcemap" } ,
166+ "data.txt" : { type : "text" } ,
167+ "index.js" : { type : "esm" } ,
168+ } ,
169+ } ) ;
170+ } ) ;
171+
172+ it ( "does not scan bundle files for a complete manifest" , async ( {
173+ expect,
174+ } ) => {
175+ const root = process . cwd ( ) ;
176+ await seedWorker ( root ) ;
177+ await writeBundleFiles ( root , {
178+ "index.js" : "export default {};" ,
179+ "unlisted.js" : "export default {};" ,
180+ } ) ;
181+
182+ const { manifest : resolvedManifest } = ( await readBuildOutput ( root ) ) . workers
183+ . default . config ;
184+
185+ expect ( resolvedManifest ) . toEqual ( completeManifest ) ;
186+ } ) ;
187+
188+ it ( "throws when a partial manifest's main module cannot be resolved" , async ( {
189+ expect,
190+ } ) => {
191+ const root = process . cwd ( ) ;
192+ await seedWorker ( root ) ;
193+ await writeWorkerConfig ( {
194+ root,
195+ config : inputWorkerConfig ( "my-worker" ) ,
196+ manifest : {
197+ type : "partial" ,
198+ mainModule : "missing.js" ,
199+ modules : { } ,
200+ } ,
201+ } ) ;
202+
203+ await expect ( readBuildOutput ( root ) ) . rejects . toThrow (
204+ / p a r t i a l m a n i f e s t .* h a s m a i n m o d u l e " m i s s i n g \. j s " , b u t i t w a s n o t f o u n d a s a n E S m o d u l e /
205+ ) ;
206+ } ) ;
207+
208+ it ( "throws when a partial manifest's main module is a source map" , async ( {
209+ expect,
210+ } ) => {
211+ const root = process . cwd ( ) ;
212+ await seedWorker ( root ) ;
213+ await writeWorkerConfig ( {
214+ root,
215+ config : inputWorkerConfig ( "my-worker" ) ,
216+ manifest : {
217+ type : "partial" ,
218+ mainModule : "index.js.map" ,
219+ modules : { } ,
220+ } ,
221+ } ) ;
222+ await writeBundleFiles ( root , { "index.js.map" : "{}" } ) ;
223+
224+ await expect ( readBuildOutput ( root ) ) . rejects . toThrow (
225+ / p a r t i a l m a n i f e s t .* h a s m a i n m o d u l e " i n d e x \. j s \. m a p " , b u t i t w a s n o t f o u n d a s a n E S m o d u l e /
226+ ) ;
227+ } ) ;
228+
119229 it ( "resolves the assets directory when present and leaves bundle undefined for assets-only Workers" , async ( {
120230 expect,
121231 } ) => {
0 commit comments