@fluojs/testing 1.0.0-beta.1 → 1.0.0-beta.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/README.ko.md CHANGED
@@ -65,6 +65,19 @@ const module = await createTestingModule({ rootModule: AppModule })
65
65
  .compile();
66
66
  ```
67
67
 
68
+ ### `overrideModule()` 사용 시 모듈 identity 보존
69
+
70
+ `createTestingModule({ rootModule })`에는 명시적인 루트 모듈이 필요합니다. 그래야 테스트가 프로덕션 bootstrap과 같은 모듈 그래프 형태를 컴파일합니다. `overrideModule(source, replacement)`로 import된 모듈을 교체해도, 컴파일된 testing module은 provider 해석에 replacement import를 사용하면서 원래 `rootModule`과 컴파일된 `modules[].type` identity를 보존합니다. 따라서 diagnostics, graph assertion, module introspection 헬퍼는 테스트 전용 synthetic wrapper 클래스가 아니라 사용자가 작성한 애플리케이션 모듈 클래스에 계속 연결됩니다.
71
+
72
+ ```typescript
73
+ const module = await createTestingModule({ rootModule: AppModule })
74
+ .overrideModule(StripeModule, FakeStripeModule)
75
+ .compile();
76
+
77
+ expect(module.rootModule).toBe(AppModule);
78
+ expect(module.modules.some((compiledModule) => compiledModule.type === BillingModule)).toBe(true);
79
+ ```
80
+
68
81
  ### HTTP 통합 테스트
69
82
 
70
83
  ```typescript
package/README.md CHANGED
@@ -63,6 +63,19 @@ const module = await createTestingModule({ rootModule: AppModule })
63
63
  .compile();
64
64
  ```
65
65
 
66
+ ### Preserve module identity with `overrideModule()`
67
+
68
+ `createTestingModule({ rootModule })` requires an explicit root module so tests compile the same module graph shape that production bootstrap uses. When `overrideModule(source, replacement)` swaps imported modules, the compiled testing module preserves the original `rootModule` and compiled `modules[].type` identities while using the replacement imports for provider resolution. This keeps diagnostics, graph assertions, and module-introspection helpers tied to the application module classes you authored instead of synthetic test-only wrapper classes.
69
+
70
+ ```ts
71
+ const module = await createTestingModule({ rootModule: AppModule })
72
+ .overrideModule(StripeModule, FakeStripeModule)
73
+ .compile();
74
+
75
+ expect(module.rootModule).toBe(AppModule);
76
+ expect(module.modules.some((compiledModule) => compiledModule.type === BillingModule)).toBe(true);
77
+ ```
78
+
66
79
  ### Request-level tests with `createTestApp()`
67
80
 
68
81
  ```ts
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,SAAS,EAId,KAAK,QAAQ,EACd,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAqC,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAMrF,OAAO,KAAK,EAA2B,oBAAoB,EAAE,oBAAoB,EAAoB,MAAM,YAAY,CAAC;AAExH;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,UAAU,GAAG,QAAQ,EAAE,CAQzE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,EAAE,CAQ5E;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,EAAE,CAQzE;AAiaD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,oBAAoB,CAEvF;AAED;;GAEG;AACH,eAAO,MAAM,IAAI;;CAEhB,CAAC"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,SAAS,EAId,KAAK,QAAQ,EACd,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAqC,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAMrF,OAAO,KAAK,EAA2B,oBAAoB,EAAE,oBAAoB,EAAoB,MAAM,YAAY,CAAC;AAExH;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,UAAU,GAAG,QAAQ,EAAE,CAQzE;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,EAAE,CAQ5E;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,UAAU,GAAG,UAAU,EAAE,CAQzE;AAubD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,oBAAoB,CAEvF;AAED;;GAEG;AACH,eAAO,MAAM,IAAI;;CAEhB,CAAC"}
package/dist/module.js CHANGED
@@ -250,6 +250,7 @@ class DefaultOverrideProviderBuilder {
250
250
  class DefaultTestingModuleBuilder {
251
251
  overrides = [];
252
252
  moduleReplacements = new Map();
253
+ originalModuleDefinitions = new Map();
253
254
  constructor(options) {
254
255
  this.options = options;
255
256
  }
@@ -308,15 +309,22 @@ class DefaultTestingModuleBuilder {
308
309
  return this.createTestingModuleRef(bootstrapped);
309
310
  }
310
311
  bootstrapTestingModule() {
311
- const rootModule = this._applyModuleReplacements(this.options.rootModule);
312
- const bootstrapped = bootstrapModule(rootModule, {
313
- providers: this.options.providers
314
- });
312
+ const bootstrapped = this.bootstrapWithPatchedModuleImports();
315
313
  if (this.overrides.length > 0) {
316
314
  bootstrapped.container.override(...this.overrides);
317
315
  }
318
316
  return bootstrapped;
319
317
  }
318
+ bootstrapWithPatchedModuleImports() {
319
+ try {
320
+ const rootModule = this._applyModuleReplacements(this.options.rootModule);
321
+ return bootstrapModule(rootModule, {
322
+ providers: this.options.providers
323
+ });
324
+ } finally {
325
+ this.restorePatchedModuleImports();
326
+ }
327
+ }
320
328
  createTestingModuleRef(bootstrapped) {
321
329
  const dispatcher = createTestingDispatcher(bootstrapped);
322
330
  const getSync = createSyncResolver(bootstrapped.container);
@@ -367,17 +375,27 @@ class DefaultTestingModuleBuilder {
367
375
  if (!hasChange) {
368
376
  return module;
369
377
  }
370
- class PatchedModule {}
371
- const patchedModule = PatchedModule;
372
- defineModule(patchedModule, {
373
- ...metadata,
374
- imports: rewrittenImports
375
- });
376
- return patchedModule;
378
+ this.patchModuleImports(module, metadata, rewrittenImports);
379
+ return module;
377
380
  }
378
381
  rewriteModuleImports(imports) {
379
382
  return imports.map(moduleImport => this._applyModuleReplacements(moduleImport));
380
383
  }
384
+ patchModuleImports(module, metadata, imports) {
385
+ if (!this.originalModuleDefinitions.has(module)) {
386
+ this.originalModuleDefinitions.set(module, metadata);
387
+ }
388
+ defineModule(module, {
389
+ ...metadata,
390
+ imports
391
+ });
392
+ }
393
+ restorePatchedModuleImports() {
394
+ for (const [module, metadata] of this.originalModuleDefinitions) {
395
+ defineModule(module, metadata);
396
+ }
397
+ this.originalModuleDefinitions.clear();
398
+ }
381
399
  }
382
400
 
383
401
  /**
@@ -61,7 +61,13 @@ export declare class HttpAdapterPortabilityHarness<TBootstrapOptions extends obj
61
61
  assertPreservesMalformedCookieValues(): Promise<void>;
62
62
  assertPreservesRawBodyForJsonAndText(): Promise<void>;
63
63
  assertExcludesRawBodyForMultipart(): Promise<void>;
64
+ assertDefaultsMultipartTotalLimitToMaxBodySize(): Promise<void>;
64
65
  assertSupportsSseStreaming(): Promise<void>;
66
+ /**
67
+ * Asserts that adapter stream backpressure waiters settle when the response
68
+ * closes before a `drain` event is emitted.
69
+ */
70
+ assertSettlesStreamDrainWaitOnClose(): Promise<void>;
65
71
  assertReportsConfiguredHostInStartupLogs(): Promise<void>;
66
72
  assertReportsHttpsStartupUrl(https: {
67
73
  cert: string;
@@ -1 +1 @@
1
- {"version":3,"file":"http-adapter-portability.d.ts","sourceRoot":"","sources":["../../src/portability/http-adapter-portability.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,UAAU,EACf,KAAK,YAAY,EAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,QAAQ,cAAc,CAAC;IAC5B,UAAU,gBAAgB;QACxB,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;QACvB,OAAO,CAAC,EAAE,UAAU,CAAC;KACtB;CACF;AAED,KAAK,OAAO,GAAG;IACb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,WAAW,oCAAoC,CACnD,iBAAiB,SAAS,MAAM,EAChC,WAAW,SAAS,MAAM,EAC1B,IAAI,SAAS,OAAO,GAAG,OAAO;IAE9B;;;;;;OAMG;IACH,SAAS,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjF;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;;OAMG;IACH,GAAG,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE;AAuDD;;;;;;;GAOG;AACH,qBAAa,6BAA6B,CACxC,iBAAiB,SAAS,MAAM,EAChC,WAAW,SAAS,MAAM,EAC1B,IAAI,SAAS,OAAO,GAAG,OAAO;IAOlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC;;;;OAIG;gBAC0B,OAAO,EAAE,oCAAoC,CAAC,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC;IAEhH;;;OAGG;IACG,oCAAoC,IAAI,OAAO,CAAC,IAAI,CAAC;IA+CrD,oCAAoC,IAAI,OAAO,CAAC,IAAI,CAAC;IA8DrD,iCAAiC,IAAI,OAAO,CAAC,IAAI,CAAC;IA8ClD,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC;IAkD3C,wCAAwC,IAAI,OAAO,CAAC,IAAI,CAAC;IAuDzD,4BAA4B,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAuDjF,8CAA8C,IAAI,OAAO,CAAC,IAAI,CAAC;CA2CtE;AAED;;;;;;;;GAQG;AACH,wBAAgB,mCAAmC,CACjD,iBAAiB,SAAS,MAAM,EAChC,WAAW,SAAS,MAAM,EAC1B,IAAI,SAAS,OAAO,GAAG,OAAO,EAE9B,OAAO,EAAE,oCAAoC,CAAC,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,GAClF,6BAA6B,CAAC,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,CAErE"}
1
+ {"version":3,"file":"http-adapter-portability.d.ts","sourceRoot":"","sources":["../../src/portability/http-adapter-portability.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,UAAU,EACf,KAAK,YAAY,EAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,QAAQ,cAAc,CAAC;IAC5B,UAAU,gBAAgB;QACxB,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;QACvB,OAAO,CAAC,EAAE,UAAU,CAAC;KACtB;CACF;AAED,KAAK,OAAO,GAAG;IACb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,WAAW,oCAAoC,CACnD,iBAAiB,SAAS,MAAM,EAChC,WAAW,SAAS,MAAM,EAC1B,IAAI,SAAS,OAAO,GAAG,OAAO;IAE9B;;;;;;OAMG;IACH,SAAS,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjF;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;;OAMG;IACH,GAAG,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE;AAuDD;;;;;;;GAOG;AACH,qBAAa,6BAA6B,CACxC,iBAAiB,SAAS,MAAM,EAChC,WAAW,SAAS,MAAM,EAC1B,IAAI,SAAS,OAAO,GAAG,OAAO;IAOlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC;;;;OAIG;gBAC0B,OAAO,EAAE,oCAAoC,CAAC,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC;IAEhH;;;OAGG;IACG,oCAAoC,IAAI,OAAO,CAAC,IAAI,CAAC;IA+CrD,oCAAoC,IAAI,OAAO,CAAC,IAAI,CAAC;IA8DrD,iCAAiC,IAAI,OAAO,CAAC,IAAI,CAAC;IA8ClD,8CAA8C,IAAI,OAAO,CAAC,IAAI,CAAC;IAwD/D,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC;IAkDjD;;;OAGG;IACG,mCAAmC,IAAI,OAAO,CAAC,IAAI,CAAC;IAqDpD,wCAAwC,IAAI,OAAO,CAAC,IAAI,CAAC;IAuDzD,4BAA4B,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAuDjF,8CAA8C,IAAI,OAAO,CAAC,IAAI,CAAC;CA2CtE;AAED;;;;;;;;GAQG;AACH,wBAAgB,mCAAmC,CACjD,iBAAiB,SAAS,MAAM,EAChC,WAAW,SAAS,MAAM,EAC1B,IAAI,SAAS,OAAO,GAAG,OAAO,EAE9B,OAAO,EAAE,oCAAoC,CAAC,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,GAClF,6BAA6B,CAAC,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,CAErE"}
@@ -272,18 +272,76 @@ export class HttpAdapterPortabilityHarness {
272
272
  await closeSilently(app);
273
273
  }
274
274
  }
275
- async assertSupportsSseStreaming() {
275
+ async assertDefaultsMultipartTotalLimitToMaxBodySize() {
276
276
  let _initProto4, _initClass4;
277
+ let _UploadController2;
278
+ class UploadController {
279
+ static {
280
+ ({
281
+ e: [_initProto4],
282
+ c: [_UploadController2, _initClass4]
283
+ } = _applyDecs(this, [Controller('/uploads')], [[Post('/'), 2, "upload"]]));
284
+ }
285
+ constructor() {
286
+ _initProto4(this);
287
+ }
288
+ upload(_input, context) {
289
+ return {
290
+ body: context.request.body,
291
+ fileCount: context.request.files?.length ?? 0
292
+ };
293
+ }
294
+ static {
295
+ _initClass4();
296
+ }
297
+ }
298
+ class AppModule {}
299
+ defineModule(AppModule, {
300
+ controllers: [_UploadController2]
301
+ });
302
+ const port = await findAvailablePort();
303
+ const app = await this.options.bootstrap(AppModule, {
304
+ cors: false,
305
+ maxBodySize: 8,
306
+ multipart: {
307
+ maxFileSize: 1024
308
+ },
309
+ port
310
+ });
311
+ await app.listen();
312
+ try {
313
+ const form = new FormData();
314
+ form.set('name', 'Ada');
315
+ form.set('payload', new Blob(['12345678'], {
316
+ type: 'text/plain'
317
+ }), 'payload.txt');
318
+ const response = await fetch(`http://127.0.0.1:${String(port)}/uploads`, {
319
+ body: form,
320
+ method: 'POST'
321
+ });
322
+ if (response.status !== 413) {
323
+ throw new Error(`${this.options.name} adapter did not default multipart.maxTotalSize to maxBodySize.`);
324
+ }
325
+ const body = await response.json();
326
+ if (typeof body !== 'object' || body === null || body.error?.code !== 'PAYLOAD_TOO_LARGE') {
327
+ throw new Error(`${this.options.name} adapter changed multipart limit error semantics.`);
328
+ }
329
+ } finally {
330
+ await closeSilently(app);
331
+ }
332
+ }
333
+ async assertSupportsSseStreaming() {
334
+ let _initProto5, _initClass5;
277
335
  let _EventsController;
278
336
  class EventsController {
279
337
  static {
280
338
  ({
281
- e: [_initProto4],
282
- c: [_EventsController, _initClass4]
339
+ e: [_initProto5],
340
+ c: [_EventsController, _initClass5]
283
341
  } = _applyDecs(this, [Controller('/events')], [[Get('/'), 2, "stream"]]));
284
342
  }
285
343
  constructor() {
286
- _initProto4(this);
344
+ _initProto5(this);
287
345
  }
288
346
  stream(_input, context) {
289
347
  const stream = new SseResponse(context);
@@ -300,7 +358,7 @@ export class HttpAdapterPortabilityHarness {
300
358
  return stream;
301
359
  }
302
360
  static {
303
- _initClass4();
361
+ _initClass5();
304
362
  }
305
363
  }
306
364
  class AppModule {}
@@ -334,8 +392,72 @@ export class HttpAdapterPortabilityHarness {
334
392
  await closeSilently(app);
335
393
  }
336
394
  }
395
+
396
+ /**
397
+ * Asserts that adapter stream backpressure waiters settle when the response
398
+ * closes before a `drain` event is emitted.
399
+ */
400
+ async assertSettlesStreamDrainWaitOnClose() {
401
+ let _initProto6, _initClass6;
402
+ const adapterName = this.options.name;
403
+ let resolveDrainWait;
404
+ const drainWaitSettled = new Promise(resolve => {
405
+ resolveDrainWait = resolve;
406
+ });
407
+ let _EventsController2;
408
+ class EventsController {
409
+ static {
410
+ ({
411
+ e: [_initProto6],
412
+ c: [_EventsController2, _initClass6]
413
+ } = _applyDecs(this, [Controller('/events')], [[Get('/'), 2, "stream"]]));
414
+ }
415
+ constructor() {
416
+ _initProto6(this);
417
+ }
418
+ async stream(_input, context) {
419
+ const stream = new SseResponse(context);
420
+ const responseStream = context.response.stream;
421
+ if (!responseStream?.waitForDrain) {
422
+ throw new Error(`${adapterName} adapter did not expose response.stream.waitForDrain().`);
423
+ }
424
+ const drainWait = responseStream.waitForDrain();
425
+ stream.close();
426
+ await drainWait;
427
+ resolveDrainWait();
428
+ return stream;
429
+ }
430
+ static {
431
+ _initClass6();
432
+ }
433
+ }
434
+ class AppModule {}
435
+ defineModule(AppModule, {
436
+ controllers: [_EventsController2]
437
+ });
438
+ const port = await findAvailablePort();
439
+ const app = await this.options.bootstrap(AppModule, {
440
+ cors: false,
441
+ port
442
+ });
443
+ await app.listen();
444
+ try {
445
+ const response = await fetch(`http://127.0.0.1:${String(port)}/events`, {
446
+ headers: {
447
+ accept: 'text/event-stream'
448
+ }
449
+ });
450
+ if (response.status !== 200) {
451
+ throw new Error(`${this.options.name} adapter changed closed stream response status semantics.`);
452
+ }
453
+ await response.text();
454
+ await withTimeout(drainWaitSettled, 2_000, `${this.options.name} adapter left response.stream.waitForDrain() pending after close.`);
455
+ } finally {
456
+ await closeSilently(app);
457
+ }
458
+ }
337
459
  async assertReportsConfiguredHostInStartupLogs() {
338
- let _initProto5, _initClass5;
460
+ let _initProto7, _initClass7;
339
461
  const loggerEvents = [];
340
462
  const logger = {
341
463
  debug() {},
@@ -351,12 +473,12 @@ export class HttpAdapterPortabilityHarness {
351
473
  class HealthController {
352
474
  static {
353
475
  ({
354
- e: [_initProto5],
355
- c: [_HealthController, _initClass5]
476
+ e: [_initProto7],
477
+ c: [_HealthController, _initClass7]
356
478
  } = _applyDecs(this, [Controller('/health')], [[Get('/'), 2, "getHealth"]]));
357
479
  }
358
480
  constructor() {
359
- _initProto5(this);
481
+ _initProto7(this);
360
482
  }
361
483
  getHealth() {
362
484
  return {
@@ -364,7 +486,7 @@ export class HttpAdapterPortabilityHarness {
364
486
  };
365
487
  }
366
488
  static {
367
- _initClass5();
489
+ _initClass7();
368
490
  }
369
491
  }
370
492
  class AppModule {}
@@ -398,7 +520,7 @@ export class HttpAdapterPortabilityHarness {
398
520
  }
399
521
  }
400
522
  async assertReportsHttpsStartupUrl(https) {
401
- let _initProto6, _initClass6;
523
+ let _initProto8, _initClass8;
402
524
  const loggerEvents = [];
403
525
  const logger = {
404
526
  debug() {},
@@ -414,12 +536,12 @@ export class HttpAdapterPortabilityHarness {
414
536
  class HealthController {
415
537
  static {
416
538
  ({
417
- e: [_initProto6],
418
- c: [_HealthController2, _initClass6]
539
+ e: [_initProto8],
540
+ c: [_HealthController2, _initClass8]
419
541
  } = _applyDecs(this, [Controller('/health')], [[Get('/'), 2, "getHealth"]]));
420
542
  }
421
543
  constructor() {
422
- _initProto6(this);
544
+ _initProto8(this);
423
545
  }
424
546
  getHealth() {
425
547
  return {
@@ -427,7 +549,7 @@ export class HttpAdapterPortabilityHarness {
427
549
  };
428
550
  }
429
551
  static {
430
- _initClass6();
552
+ _initClass8();
431
553
  }
432
554
  }
433
555
  class AppModule {}
@@ -461,7 +583,7 @@ export class HttpAdapterPortabilityHarness {
461
583
  }
462
584
  }
463
585
  async assertRemovesShutdownSignalListenersAfterClose() {
464
- let _initProto7, _initClass7;
586
+ let _initProto9, _initClass9;
465
587
  const logger = {
466
588
  debug() {},
467
589
  error() {},
@@ -472,12 +594,12 @@ export class HttpAdapterPortabilityHarness {
472
594
  class HealthController {
473
595
  static {
474
596
  ({
475
- e: [_initProto7],
476
- c: [_HealthController3, _initClass7]
597
+ e: [_initProto9],
598
+ c: [_HealthController3, _initClass9]
477
599
  } = _applyDecs(this, [Controller('/health')], [[Get('/'), 2, "getHealth"]]));
478
600
  }
479
601
  constructor() {
480
- _initProto7(this);
602
+ _initProto9(this);
481
603
  }
482
604
  getHealth() {
483
605
  return {
@@ -485,7 +607,7 @@ export class HttpAdapterPortabilityHarness {
485
607
  };
486
608
  }
487
609
  static {
488
- _initClass7();
610
+ _initClass9();
489
611
  }
490
612
  }
491
613
  class AppModule {}
@@ -525,4 +647,17 @@ export class HttpAdapterPortabilityHarness {
525
647
  */
526
648
  export function createHttpAdapterPortabilityHarness(options) {
527
649
  return new HttpAdapterPortabilityHarness(options);
650
+ }
651
+ function withTimeout(promise, timeoutMs, message) {
652
+ let timeout;
653
+ const timeoutPromise = new Promise((_resolve, reject) => {
654
+ timeout = setTimeout(() => {
655
+ reject(new Error(message));
656
+ }, timeoutMs);
657
+ });
658
+ return Promise.race([promise, timeoutPromise]).finally(() => {
659
+ if (timeout !== undefined) {
660
+ clearTimeout(timeout);
661
+ }
662
+ });
528
663
  }
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "override",
10
10
  "module-builder"
11
11
  ],
12
- "version": "1.0.0-beta.1",
12
+ "version": "1.0.0-beta.2",
13
13
  "private": false,
14
14
  "license": "MIT",
15
15
  "repository": {
@@ -76,11 +76,11 @@
76
76
  "dist"
77
77
  ],
78
78
  "dependencies": {
79
- "@fluojs/di": "^1.0.0-beta.1",
80
- "@fluojs/core": "^1.0.0-beta.1",
79
+ "@fluojs/config": "^1.0.0-beta.2",
81
80
  "@fluojs/http": "^1.0.0-beta.1",
82
- "@fluojs/runtime": "^1.0.0-beta.1",
83
- "@fluojs/config": "^1.0.0-beta.1"
81
+ "@fluojs/di": "^1.0.0-beta.2",
82
+ "@fluojs/runtime": "^1.0.0-beta.2",
83
+ "@fluojs/core": "^1.0.0-beta.1"
84
84
  },
85
85
  "peerDependencies": {
86
86
  "@babel/core": ">=7.0.0",
@@ -88,9 +88,9 @@
88
88
  },
89
89
  "devDependencies": {
90
90
  "vitest": "^3.2.4",
91
- "@fluojs/platform-nodejs": "^1.0.0-beta.1",
92
- "@fluojs/platform-fastify": "^1.0.0-beta.1",
93
- "@fluojs/platform-express": "^1.0.0-beta.1"
91
+ "@fluojs/platform-nodejs": "^1.0.0-beta.2",
92
+ "@fluojs/platform-express": "^1.0.0-beta.2",
93
+ "@fluojs/platform-fastify": "^1.0.0-beta.3"
94
94
  },
95
95
  "scripts": {
96
96
  "prebuild": "node ../../tooling/scripts/clean-dist.mjs",