@acmekit/acmekit 2.13.85 → 2.13.87

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.
@@ -450,29 +450,23 @@ describe("MyProvider", () => {
450
450
 
451
451
  ---
452
452
 
453
- ## Asserting Domain Events (module mode)
453
+ ## Asserting Domain Events
454
454
 
455
- ```typescript
456
- import { MockEventBusService } from "@acmekit/test-utils"
457
-
458
- let eventBusSpy: jest.SpyInstance
459
-
460
- beforeEach(() => {
461
- eventBusSpy = jest.spyOn(MockEventBusService.prototype, "emit")
462
- })
455
+ `MockEventBusService` accumulates emitted events — use `.getEmittedEvents()` directly, no spy needed.
463
456
 
464
- afterEach(() => {
465
- eventBusSpy.mockClear()
466
- })
457
+ ```typescript
458
+ import { Modules } from "@acmekit/framework/utils"
467
459
 
468
460
  it("should emit post.created event", async () => {
469
461
  await service.createPosts([{ title: "Event Test" }])
470
462
 
471
- const events = eventBusSpy.mock.calls[0][0]
463
+ // Access events directly from the mock event bus — no spy needed
464
+ const eventBus = getContainer().resolve(Modules.EVENT_BUS)
465
+ const events = eventBus.getEmittedEvents()
472
466
  expect(events).toEqual(
473
467
  expect.arrayContaining([
474
468
  expect.objectContaining({
475
- name: "post.created",
469
+ name: "post.created", // NOTE: property is "name", NOT "eventName"
476
470
  data: expect.objectContaining({ id: expect.any(String) }),
477
471
  }),
478
472
  ])
@@ -480,6 +474,8 @@ it("should emit post.created event", async () => {
480
474
  })
481
475
  ```
482
476
 
477
+ > `emitEventStep` maps `eventName` to `name` internally — always assert on `event.name`.
478
+
483
479
  ---
484
480
 
485
481
  ## What to Test
@@ -520,29 +520,18 @@ expect(response.data).toEqual({
520
520
 
521
521
  ## Asserting Domain Events
522
522
 
523
- Both runners inject `MockEventBusService` under `Modules.EVENT_BUS` in module mode. Spy on the **prototype**, not an instance.
523
+ `MockEventBusService` accumulates all emitted events. Use `.getEmittedEvents()` no spy needed.
524
524
 
525
525
  ```typescript
526
- import { MockEventBusService } from "@acmekit/test-utils"
527
-
528
- let eventBusSpy: jest.SpyInstance
529
-
530
- beforeEach(() => {
531
- eventBusSpy = jest.spyOn(MockEventBusService.prototype, "emit")
532
- })
533
-
534
- afterEach(() => {
535
- eventBusSpy.mockClear()
536
- })
537
-
538
526
  it("should emit post.created event", async () => {
539
527
  await service.createPosts([{ title: "Event Test" }])
540
528
 
541
- const events = eventBusSpy.mock.calls[0][0]
529
+ const eventBus = getContainer().resolve(Modules.EVENT_BUS)
530
+ const events = eventBus.getEmittedEvents()
542
531
  expect(events).toEqual(
543
532
  expect.arrayContaining([
544
533
  expect.objectContaining({
545
- name: "post.created",
534
+ name: "post.created", // NOTE: property is "name", NOT "eventName"
546
535
  data: expect.objectContaining({ id: expect.any(String) }),
547
536
  }),
548
537
  ])
@@ -550,6 +539,8 @@ it("should emit post.created event", async () => {
550
539
  })
551
540
  ```
552
541
 
542
+ > `emitEventStep` maps `eventName` to `name` internally — always assert on `event.name`.
543
+
553
544
  ---
554
545
 
555
546
  ## Waiting for Subscribers
@@ -904,6 +895,42 @@ await expect(provider.process(badInput)).rejects.toThrow("validation")
904
895
 
905
896
  ---
906
897
 
898
+ ## Auto-Injected Infrastructure Mocks
899
+
900
+ The test runner automatically injects mock implementations for infrastructure modules in plugin and module modes. You do NOT need to manually inject these:
901
+
902
+ | Module | Mock class | Behavior |
903
+ |---|---|---|
904
+ | `Modules.EVENT_BUS` | `MockEventBusService` | Accumulates events — call `.getEmittedEvents()` to inspect |
905
+ | `Modules.LOCKING` | `MockLockingService` | In-memory locking — `execute()` runs job immediately, acquire/release tracked |
906
+ | `Modules.SECRETS` | `MockSecretsService` | In-memory store — pre-populate with `.setSecret(id, value)` |
907
+
908
+ Override any mock via `injectedDependencies` if needed — user overrides take precedence.
909
+
910
+ ### Asserting emitted events (no spy needed)
911
+
912
+ ```typescript
913
+ const eventBus = getContainer().resolve(Modules.EVENT_BUS)
914
+
915
+ await createPostWorkflow(getContainer()).run({ input: { title: "Test" } })
916
+
917
+ // Inspect emitted events directly — no jest.spyOn needed
918
+ const events = eventBus.getEmittedEvents()
919
+ const postEvent = events.find((e: any) => e.name === "post.created")
920
+ expect(postEvent).toBeDefined()
921
+ expect(postEvent.data).toEqual(expect.objectContaining({ id: expect.any(String) }))
922
+ ```
923
+
924
+ > Event objects have `{ name, data, metadata?, options? }`. The property is `name`, NOT `eventName` — `emitEventStep` maps `eventName` to `name` internally.
925
+
926
+ ---
927
+
928
+ ## Client Routes Require API Key
929
+
930
+ Routes under `/client/*` use `AcmeKitTypedRequest` (non-authenticated), but they are NOT fully public. AcmeKit middleware enforces a client API key header on all `/client/*` routes. "Public" means "no user authentication" — a client API key is still required.
931
+
932
+ ---
933
+
907
934
  ## Anti-Patterns — NEVER Do These
908
935
 
909
936
  ```typescript
@@ -1068,4 +1095,15 @@ const re = new RegExp("^(\\*|[0-9]+)(\\/[0-9]+)?$")
1068
1095
  const result = await provider.process(bad)
1069
1096
  expect(result.success).toBe(false) // ❌ actually throws
1070
1097
  // RIGHT — read implementation first to check if it throws or returns
1098
+
1099
+ // WRONG — using jest.spyOn to inspect emitted events
1100
+ jest.spyOn(MockEventBusService.prototype, "emit") // ❌ fragile, complex extraction
1101
+ // RIGHT — use built-in event accumulation
1102
+ const eventBus = getContainer().resolve(Modules.EVENT_BUS)
1103
+ const events = eventBus.getEmittedEvents()
1104
+
1105
+ // WRONG — checking event.eventName (emitEventStep maps eventName → name internally)
1106
+ expect(event.eventName).toBe("post.created") // ❌ property doesn't exist
1107
+ // RIGHT
1108
+ expect(event.name).toBe("post.created")
1071
1109
  ```
@@ -258,7 +258,7 @@ integrationTestRunner({
258
258
 
259
259
  **Fixtures (container-only):** `container`, `acmekitApp`, `MikroOrmWrapper`, `dbConfig`.
260
260
 
261
- **When plugin depends on other plugins:** Add `skipDependencyValidation: true` and mock peer services via `injectedDependencies`.
261
+ **When plugin depends on other plugins:** Use `additionalPlugins` to load real peer plugins with their modules, migrations, and services. Only fall back to `skipDependencyValidation: true` + `injectedDependencies` mocks when peer plugins can't be installed.
262
262
 
263
263
  **When plugin has providers needing options:** Use `pluginModuleOptions` keyed by module name:
264
264
  ```typescript
@@ -471,31 +471,22 @@ describe("MyProvider", () => {
471
471
 
472
472
  ## Asserting Domain Events (container-only mode)
473
473
 
474
- Plugin mode (without HTTP) injects `MockEventBusService`. Spy on the **prototype**, not an instance.
474
+ `MockEventBusService` accumulates emitted events use `.getEmittedEvents()` directly, no spy needed.
475
475
 
476
476
  ```typescript
477
- import { MockEventBusService } from "@acmekit/test-utils"
478
-
479
- let eventBusSpy: jest.SpyInstance
480
-
481
- beforeEach(() => {
482
- eventBusSpy = jest.spyOn(MockEventBusService.prototype, "emit")
483
- })
484
-
485
- afterEach(() => {
486
- eventBusSpy.mockClear()
487
- })
477
+ import { Modules } from "@acmekit/framework/utils"
488
478
 
489
479
  it("should emit greeting.created event", async () => {
490
480
  const service: any = container.resolve(GREETING_MODULE)
491
481
  await service.createGreetings([{ message: "Event Test" }])
492
482
 
493
- // MockEventBusService.emit receives an ARRAY of events
494
- const events = eventBusSpy.mock.calls[0][0]
483
+ // Access events directly from the mock event bus — no spy needed
484
+ const eventBus = container.resolve(Modules.EVENT_BUS)
485
+ const events = eventBus.getEmittedEvents()
495
486
  expect(events).toEqual(
496
487
  expect.arrayContaining([
497
488
  expect.objectContaining({
498
- name: "greeting.created",
489
+ name: "greeting.created", // NOTE: property is "name", NOT "eventName"
499
490
  data: expect.objectContaining({ id: expect.any(String) }),
500
491
  }),
501
492
  ])
@@ -503,6 +494,8 @@ it("should emit greeting.created event", async () => {
503
494
  })
504
495
  ```
505
496
 
497
+ > `emitEventStep` maps `eventName` to `name` internally — always assert on `event.name`.
498
+
506
499
  ---
507
500
 
508
501
  ## What to Test
@@ -538,8 +531,8 @@ it("should emit greeting.created event", async () => {
538
531
  - Auth: 401 without JWT, 400 without client API key
539
532
 
540
533
  **Events (container mode):**
541
- - Spy on `MockEventBusService.prototype.emit` (prototype, not instance)
542
- - Access events via `eventBusSpy.mock.calls[0][0]` (array of event objects)
534
+ - Use `container.resolve(Modules.EVENT_BUS).getEmittedEvents()` no spy needed
535
+ - Event objects have `{ name, data }` property is `name`, NOT `eventName`
543
536
 
544
537
  ---
545
538
 
@@ -576,8 +569,8 @@ it("should emit greeting.created event", async () => {
576
569
  - Use realistic test data ("Launch Announcement", "Quarterly Report") not "test", "foo"
577
570
  - Pass body directly: `api.post(url, body, headers)` — NOT `{ body: {...} }`
578
571
  - Runners handle DB setup/teardown — no manual cleanup needed
579
- - Spy on `MockEventBusService.prototype` — not an instance
580
- - `jest.restoreAllMocks()` in `afterEach` when spying
572
+ - Use `eventBus.getEmittedEvents()` for event assertions no spy ceremony
573
+ - Event property is `name`, NOT `eventName` (`emitEventStep` maps internally)
581
574
  - NEVER use JSDoc blocks or type casts in test files
582
575
  - **Always `beforeEach(() => jest.clearAllMocks())`** in unit tests — mock state leaks between describes
583
576
  - **Never reference file-level `const`/`let` inside `jest.mock()` factories** — TDZ error
@@ -128,9 +128,10 @@ integrationTestRunner({
128
128
  | `pluginPath` | `string` | **(required)** | Path to plugin root — always use `process.cwd()` |
129
129
  | `pluginOptions` | `Record<string, unknown>` | `{}` | Simulates host app plugin config |
130
130
  | `http` | `boolean` | `false` | Set `true` to boot full Express server for HTTP tests |
131
+ | `additionalPlugins` | `Array<{ resolve, options? }>` | `[]` | Peer plugins to load alongside the plugin under test — real modules, migrations, services |
131
132
  | `additionalModules` | `Record<string, any>` | `{}` | Extra modules to load alongside the plugin |
132
133
  | `injectedDependencies` | `Record<string, any>` | `{}` | Mock services to register in the container |
133
- | `skipDependencyValidation` | `boolean` | `false` | Skip `definePlugin({ dependencies })` validation — use when peer plugins aren't installed |
134
+ | `skipDependencyValidation` | `boolean` | `false` | Escape hatch: skip `definePlugin({ dependencies })` validation when peer plugins can't be installed |
134
135
  | `pluginModuleOptions` | `Record<string, Record<string, any>>` | `{}` | Per-module options keyed by module name (e.g., provider config) |
135
136
  | `dbName` | `string` | auto-generated | Override the computed DB name |
136
137
  | `schema` | `string` | `"public"` | Postgres schema |
@@ -491,34 +492,27 @@ integrationTestRunner({
491
492
 
492
493
  ## Asserting Domain Events
493
494
 
494
- Plugin mode (without HTTP) injects `MockEventBusService`. Spy on the **prototype**, not an instance.
495
+ `MockEventBusService` accumulates all emitted events. Use `.getEmittedEvents()` no spy needed.
495
496
 
496
497
  ```typescript
497
- import { MockEventBusService } from "@acmekit/test-utils"
498
+ it("should emit greeting.created event", async () => {
499
+ const service = container.resolve(GREETING_MODULE)
500
+ await service.createGreetings([{ message: "Hello" }])
498
501
 
499
- it("should capture events", async () => {
500
- const spy = jest.spyOn(MockEventBusService.prototype, "emit")
501
502
  const eventBus = container.resolve(Modules.EVENT_BUS)
502
-
503
- await eventBus.emit([
504
- { name: "greeting.created", data: { id: "g1", message: "Hello" } },
505
- ])
506
-
507
- expect(spy).toHaveBeenCalledTimes(1)
508
- expect(spy.mock.calls[0][0]).toEqual(
503
+ const events = eventBus.getEmittedEvents()
504
+ expect(events).toEqual(
509
505
  expect.arrayContaining([
510
506
  expect.objectContaining({
511
- name: "greeting.created",
512
- data: expect.objectContaining({ id: "g1" }),
507
+ name: "greeting.created", // NOTE: property is "name", NOT "eventName"
508
+ data: expect.objectContaining({ id: expect.any(String) }),
513
509
  }),
514
510
  ])
515
511
  )
516
-
517
- spy.mockRestore()
518
512
  })
519
513
  ```
520
514
 
521
- **Note:** MockEventBusService `emit` takes an **array** of events. Real event bus `emit` takes a single `{ name, data }` object.
515
+ > `emitEventStep` maps `eventName` to `name` internally always assert on `event.name`.
522
516
 
523
517
  ---
524
518
 
@@ -724,7 +718,28 @@ await expect(provider.process(badInput)).rejects.toThrow("validation")
724
718
 
725
719
  ## Testing Plugins with Dependencies
726
720
 
727
- When your plugin depends on other plugins (declared in `definePlugin({ dependencies })`), the test runner validates that all dependencies are installed. For workspace plugins that depend on other workspace plugins, use `skipDependencyValidation`:
721
+ When your plugin depends on other plugins (declared in `definePlugin({ dependencies })`), use `additionalPlugins` to load them alongside the plugin under test. This boots real modules, runs real migrations, and registers real services — the same as production:
722
+
723
+ ```typescript
724
+ integrationTestRunner({
725
+ mode: "plugin",
726
+ pluginPath: process.cwd(),
727
+ additionalPlugins: [
728
+ { resolve: "@acmekit/plugin-reviews" },
729
+ { resolve: "@acmekit/plugin-loyalty", options: { tier: "gold" } },
730
+ ],
731
+ testSuite: ({ container }) => {
732
+ // container has REAL services from all plugins
733
+ it("uses review service", async () => {
734
+ const reviewService = container.resolve(REVIEW_MODULE)
735
+ const reviews = await reviewService.listReviews()
736
+ expect(reviews).toBeDefined()
737
+ })
738
+ },
739
+ })
740
+ ```
741
+
742
+ **Escape hatch:** When peer plugins genuinely can't be installed (e.g., CI without optional deps), use `skipDependencyValidation` to bypass validation and mock the services manually:
728
743
 
729
744
  ```typescript
730
745
  integrationTestRunner({
@@ -739,9 +754,13 @@ integrationTestRunner({
739
754
  })
740
755
  ```
741
756
 
757
+ > **Prefer `additionalPlugins` over `skipDependencyValidation` + mocks.** Mocked services can silently drift from the real API — tests pass but production breaks.
758
+
742
759
  ## Configuring Providers in Plugin Tests
743
760
 
744
- Use `pluginModuleOptions` to pass per-module options (e.g., provider configuration) keyed by module name:
761
+ Providers CANNOT be mocked with `jest.mock({ virtual: true })`. The module loader uses `require.resolve()` which bypasses jest. Providers must be **real files on disk** exporting `ModuleProvider()`.
762
+
763
+ Use `pluginModuleOptions` to register providers keyed by module name. Provider `resolve` paths must be **absolute** (the loader resolves from `modules-sdk` dist, not your test file):
745
764
 
746
765
  ```typescript
747
766
  integrationTestRunner({
@@ -751,8 +770,8 @@ integrationTestRunner({
751
770
  tron: {
752
771
  providers: [
753
772
  {
754
- resolve: "./src/providers/energy/own-pool",
755
- id: "own-pool",
773
+ resolve: process.cwd() + "/integration-tests/helpers/mock-energy-provider",
774
+ id: "mock-energy",
756
775
  options: { apiKey: "test-key" },
757
776
  },
758
777
  ],
@@ -762,10 +781,108 @@ integrationTestRunner({
762
781
  })
763
782
  ```
764
783
 
784
+ The helper file must be a real module:
785
+
786
+ ```typescript
787
+ // integration-tests/helpers/mock-energy-provider.ts
788
+ import { ModuleProvider } from "@acmekit/framework/utils"
789
+
790
+ class MockEnergyService {
791
+ static identifier = "mock-energy"
792
+ // implement provider interface methods
793
+ }
794
+
795
+ export default ModuleProvider("tron", { services: [MockEnergyService] })
796
+ ```
797
+
765
798
  `pluginModuleOptions` is merged into the discovered module config AFTER `pluginOptions`, so module-specific options override plugin-level ones.
766
799
 
767
800
  ---
768
801
 
802
+ ## Auto-Injected Infrastructure Mocks
803
+
804
+ The test runner automatically injects mock implementations for infrastructure modules in plugin and module modes. You do NOT need to manually inject these:
805
+
806
+ | Module | Mock class | Behavior |
807
+ |---|---|---|
808
+ | `Modules.EVENT_BUS` | `MockEventBusService` | Accumulates events — call `.getEmittedEvents()` to inspect |
809
+ | `Modules.LOCKING` | `MockLockingService` | In-memory locking — `execute()` runs job immediately, acquire/release tracked |
810
+ | `Modules.SECRETS` | `MockSecretsService` | In-memory store — pre-populate with `.setSecret(id, value)` |
811
+
812
+ Override any mock via `injectedDependencies` if needed — user overrides take precedence.
813
+
814
+ ### Asserting emitted events (no spy needed)
815
+
816
+ ```typescript
817
+ // Resolve the mock event bus from the container
818
+ const eventBus = container.resolve(Modules.EVENT_BUS)
819
+
820
+ // Run your workflow/operation that emits events
821
+ await createGreetingsWorkflow(container).run({ input: { greetings: [{ message: "Hi" }] } })
822
+
823
+ // Inspect emitted events directly — no jest.spyOn needed
824
+ const events = eventBus.getEmittedEvents()
825
+ const greetingEvent = events.find((e: any) => e.name === "greeting.created")
826
+ expect(greetingEvent).toBeDefined()
827
+ expect(greetingEvent.data).toEqual(expect.objectContaining({ id: expect.any(String) }))
828
+ ```
829
+
830
+ > Event objects have `{ name, data, metadata?, options? }`. The property is `name`, NOT `eventName` — `emitEventStep` maps `eventName` to `name` internally.
831
+
832
+ ### Pre-populating secrets for tests
833
+
834
+ ```typescript
835
+ integrationTestRunner({
836
+ mode: "plugin",
837
+ pluginPath: process.cwd(),
838
+ testSuite: ({ container }) => {
839
+ beforeEach(() => {
840
+ const secrets = container.resolve(Modules.SECRETS)
841
+ secrets.setSecret("prod/wallet", { address: "0xtest123" })
842
+ })
843
+
844
+ it("resolves wallet address from secrets", async () => {
845
+ const addr = await container.resolve(Modules.SECRETS).getKey("prod/wallet", "address")
846
+ expect(addr).toBe("0xtest123")
847
+ })
848
+ },
849
+ })
850
+ ```
851
+
852
+ ---
853
+
854
+ ## injectedDependencies vs pluginModuleOptions
855
+
856
+ | | `injectedDependencies` | `pluginModuleOptions` |
857
+ |---|---|---|
858
+ | **Injects into** | Root container | Per-module config |
859
+ | **Use for** | Infrastructure mocks (locking, secrets, custom services) | Provider registration, module-specific config |
860
+ | **Shape** | `{ [Modules.X]: mockInstance }` | `{ moduleName: { providers: [...], options } }` |
861
+ | **Path resolution** | N/A | Must be **absolute** (`process.cwd() + "/path"`) |
862
+
863
+ ---
864
+
865
+ ## Client Routes Require API Key
866
+
867
+ Routes under `/client/*` use `AcmeKitTypedRequest` (non-authenticated), but they are NOT fully public. AcmeKit middleware enforces a client API key header on all `/client/*` routes.
868
+
869
+ ```typescript
870
+ // WRONG — 401 "Client API key required"
871
+ const response = await api.get("/client/plugin/greetings") // ❌
872
+
873
+ // RIGHT — create client API key and pass header
874
+ const apiKey = await apiKeyModule.createApiKeys({
875
+ title: "Test Client Key",
876
+ type: ApiKeyType.CLIENT,
877
+ created_by: "test",
878
+ })
879
+ const response = await api.get("/client/plugin/greetings", {
880
+ headers: { [CLIENT_API_KEY_HEADER]: apiKey.token },
881
+ })
882
+ ```
883
+
884
+ ---
885
+
769
886
  ## Anti-Patterns — NEVER Do These
770
887
 
771
888
  ```typescript
@@ -891,4 +1008,26 @@ const re = new RegExp("^(\\*|[0-9]+)(\\/[0-9]+)?$")
891
1008
  const result = await provider.process(bad)
892
1009
  expect(result.success).toBe(false) // ❌ actually throws
893
1010
  // RIGHT — read implementation first to check if it throws or returns
1011
+
1012
+ // WRONG — jest virtual mock for providers (require.resolve bypasses jest)
1013
+ jest.mock("../../src/providers/mock-provider", () => ({ ... }), { virtual: true }) // ❌
1014
+ // RIGHT — create a real file and use absolute path
1015
+ // integration-tests/helpers/mock-provider.ts (real file with ModuleProvider export)
1016
+ pluginModuleOptions: { mod: { providers: [{ resolve: process.cwd() + "/integration-tests/helpers/mock-provider" }] } }
1017
+
1018
+ // WRONG — relative provider resolve path (resolved from modules-sdk dist, not test file)
1019
+ { resolve: "../../src/providers/my-provider" } // ❌
1020
+ // RIGHT
1021
+ { resolve: process.cwd() + "/src/providers/my-provider" }
1022
+
1023
+ // WRONG — using jest.spyOn to inspect emitted events
1024
+ jest.spyOn(MockEventBusService.prototype, "emit") // ❌ fragile, complex extraction
1025
+ // RIGHT — use built-in event accumulation
1026
+ const eventBus = container.resolve(Modules.EVENT_BUS)
1027
+ const events = eventBus.getEmittedEvents()
1028
+
1029
+ // WRONG — checking event.eventName (emitEventStep maps eventName → name internally)
1030
+ expect(event.eventName).toBe("greeting.created") // ❌ property doesn't exist
1031
+ // RIGHT
1032
+ expect(event.name).toBe("greeting.created")
894
1033
  ```
@@ -356,7 +356,7 @@ pnpm test:integration:http # Plugin HTTP tests
356
356
  - Always use `pluginPath: process.cwd()` — never hardcode paths
357
357
  - Container-only tests: access services via `container.resolve(MODULE_CONSTANT)` — no `api` fixture
358
358
  - HTTP tests: full auth setup with `generateJwtToken` + `ApiKeyType.CLIENT` — no `createAdminUser` helper
359
- - Plugin depends on other plugins: add `skipDependencyValidation: true` + mock peer services via `injectedDependencies`
359
+ - Plugin depends on other plugins: use `additionalPlugins: [{ resolve: "@acmekit/plugin-name" }]` to load real peers. Fall back to `skipDependencyValidation: true` + `injectedDependencies` only when peers can't be installed
360
360
  - Plugin providers need options: use `pluginModuleOptions: { moduleName: { providers: [...] } }`
361
361
  - Pass body directly: `api.post(url, body, headers)` — NOT `{ body: {...} }`
362
362
  - Use `.catch((e: any) => e)` for error assertions — axios throws on 4xx/5xx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acmekit/acmekit",
3
- "version": "2.13.85",
3
+ "version": "2.13.87",
4
4
  "description": "Generic application bootstrap and loaders for the AcmeKit framework",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
@@ -49,45 +49,45 @@
49
49
  "test:integration": "../../node_modules/.bin/jest --passWithNoTests --forceExit --testPathPattern=\"src/.*/integration-tests/__tests__/.*\\.ts\""
50
50
  },
51
51
  "devDependencies": {
52
- "@acmekit/framework": "2.13.85"
52
+ "@acmekit/framework": "2.13.87"
53
53
  },
54
54
  "dependencies": {
55
- "@acmekit/admin-bundler": "2.13.85",
56
- "@acmekit/analytics": "2.13.85",
57
- "@acmekit/analytics-local": "2.13.85",
58
- "@acmekit/analytics-posthog": "2.13.85",
59
- "@acmekit/api-key": "2.13.85",
60
- "@acmekit/auth": "2.13.85",
61
- "@acmekit/auth-emailpass": "2.13.85",
62
- "@acmekit/auth-github": "2.13.85",
63
- "@acmekit/auth-google": "2.13.85",
64
- "@acmekit/cache-inmemory": "2.13.85",
65
- "@acmekit/cache-redis": "2.13.85",
66
- "@acmekit/caching": "2.13.85",
67
- "@acmekit/caching-redis": "2.13.85",
68
- "@acmekit/core-flows": "2.13.85",
69
- "@acmekit/event-bus-local": "2.13.85",
70
- "@acmekit/event-bus-redis": "2.13.85",
71
- "@acmekit/file": "2.13.85",
72
- "@acmekit/file-local": "2.13.85",
73
- "@acmekit/file-s3": "2.13.85",
74
- "@acmekit/index": "2.13.85",
75
- "@acmekit/link-modules": "2.13.85",
76
- "@acmekit/locking": "2.13.85",
77
- "@acmekit/locking-postgres": "2.13.85",
78
- "@acmekit/locking-redis": "2.13.85",
79
- "@acmekit/notification": "2.13.85",
80
- "@acmekit/notification-local": "2.13.85",
81
- "@acmekit/notification-sendgrid": "2.13.85",
82
- "@acmekit/rbac": "2.13.85",
83
- "@acmekit/secrets-aws": "2.13.85",
84
- "@acmekit/secrets-local": "2.13.85",
85
- "@acmekit/settings": "2.13.85",
86
- "@acmekit/telemetry": "2.13.85",
87
- "@acmekit/translation": "2.13.85",
88
- "@acmekit/user": "2.13.85",
89
- "@acmekit/workflow-engine-inmemory": "2.13.85",
90
- "@acmekit/workflow-engine-redis": "2.13.85",
55
+ "@acmekit/admin-bundler": "2.13.87",
56
+ "@acmekit/analytics": "2.13.87",
57
+ "@acmekit/analytics-local": "2.13.87",
58
+ "@acmekit/analytics-posthog": "2.13.87",
59
+ "@acmekit/api-key": "2.13.87",
60
+ "@acmekit/auth": "2.13.87",
61
+ "@acmekit/auth-emailpass": "2.13.87",
62
+ "@acmekit/auth-github": "2.13.87",
63
+ "@acmekit/auth-google": "2.13.87",
64
+ "@acmekit/cache-inmemory": "2.13.87",
65
+ "@acmekit/cache-redis": "2.13.87",
66
+ "@acmekit/caching": "2.13.87",
67
+ "@acmekit/caching-redis": "2.13.87",
68
+ "@acmekit/core-flows": "2.13.87",
69
+ "@acmekit/event-bus-local": "2.13.87",
70
+ "@acmekit/event-bus-redis": "2.13.87",
71
+ "@acmekit/file": "2.13.87",
72
+ "@acmekit/file-local": "2.13.87",
73
+ "@acmekit/file-s3": "2.13.87",
74
+ "@acmekit/index": "2.13.87",
75
+ "@acmekit/link-modules": "2.13.87",
76
+ "@acmekit/locking": "2.13.87",
77
+ "@acmekit/locking-postgres": "2.13.87",
78
+ "@acmekit/locking-redis": "2.13.87",
79
+ "@acmekit/notification": "2.13.87",
80
+ "@acmekit/notification-local": "2.13.87",
81
+ "@acmekit/notification-sendgrid": "2.13.87",
82
+ "@acmekit/rbac": "2.13.87",
83
+ "@acmekit/secrets-aws": "2.13.87",
84
+ "@acmekit/secrets-local": "2.13.87",
85
+ "@acmekit/settings": "2.13.87",
86
+ "@acmekit/telemetry": "2.13.87",
87
+ "@acmekit/translation": "2.13.87",
88
+ "@acmekit/user": "2.13.87",
89
+ "@acmekit/workflow-engine-inmemory": "2.13.87",
90
+ "@acmekit/workflow-engine-redis": "2.13.87",
91
91
  "@inquirer/checkbox": "^2.3.11",
92
92
  "@inquirer/input": "^2.2.9",
93
93
  "boxen": "^5.0.1",
@@ -106,7 +106,7 @@
106
106
  },
107
107
  "peerDependencies": {
108
108
  "@acmekit/docs-bundler": "^2.13.42",
109
- "@acmekit/framework": "2.13.85",
109
+ "@acmekit/framework": "2.13.87",
110
110
  "@jimsheen/yalc": "^1.2.2",
111
111
  "@swc/core": "^1.7.28",
112
112
  "posthog-node": "^5.11.0",