@acmekit/acmekit 2.13.85 → 2.13.86

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.
@@ -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
@@ -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 |
@@ -724,7 +725,28 @@ await expect(provider.process(badInput)).rejects.toThrow("validation")
724
725
 
725
726
  ## Testing Plugins with Dependencies
726
727
 
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`:
728
+ 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:
729
+
730
+ ```typescript
731
+ integrationTestRunner({
732
+ mode: "plugin",
733
+ pluginPath: process.cwd(),
734
+ additionalPlugins: [
735
+ { resolve: "@acmekit/plugin-reviews" },
736
+ { resolve: "@acmekit/plugin-loyalty", options: { tier: "gold" } },
737
+ ],
738
+ testSuite: ({ container }) => {
739
+ // container has REAL services from all plugins
740
+ it("uses review service", async () => {
741
+ const reviewService = container.resolve(REVIEW_MODULE)
742
+ const reviews = await reviewService.listReviews()
743
+ expect(reviews).toBeDefined()
744
+ })
745
+ },
746
+ })
747
+ ```
748
+
749
+ **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
750
 
729
751
  ```typescript
730
752
  integrationTestRunner({
@@ -739,6 +761,8 @@ integrationTestRunner({
739
761
  })
740
762
  ```
741
763
 
764
+ > **Prefer `additionalPlugins` over `skipDependencyValidation` + mocks.** Mocked services can silently drift from the real API — tests pass but production breaks.
765
+
742
766
  ## Configuring Providers in Plugin Tests
743
767
 
744
768
  Use `pluginModuleOptions` to pass per-module options (e.g., provider configuration) keyed by module name:
@@ -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.86",
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.86"
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.86",
56
+ "@acmekit/analytics": "2.13.86",
57
+ "@acmekit/analytics-local": "2.13.86",
58
+ "@acmekit/analytics-posthog": "2.13.86",
59
+ "@acmekit/api-key": "2.13.86",
60
+ "@acmekit/auth": "2.13.86",
61
+ "@acmekit/auth-emailpass": "2.13.86",
62
+ "@acmekit/auth-github": "2.13.86",
63
+ "@acmekit/auth-google": "2.13.86",
64
+ "@acmekit/cache-inmemory": "2.13.86",
65
+ "@acmekit/cache-redis": "2.13.86",
66
+ "@acmekit/caching": "2.13.86",
67
+ "@acmekit/caching-redis": "2.13.86",
68
+ "@acmekit/core-flows": "2.13.86",
69
+ "@acmekit/event-bus-local": "2.13.86",
70
+ "@acmekit/event-bus-redis": "2.13.86",
71
+ "@acmekit/file": "2.13.86",
72
+ "@acmekit/file-local": "2.13.86",
73
+ "@acmekit/file-s3": "2.13.86",
74
+ "@acmekit/index": "2.13.86",
75
+ "@acmekit/link-modules": "2.13.86",
76
+ "@acmekit/locking": "2.13.86",
77
+ "@acmekit/locking-postgres": "2.13.86",
78
+ "@acmekit/locking-redis": "2.13.86",
79
+ "@acmekit/notification": "2.13.86",
80
+ "@acmekit/notification-local": "2.13.86",
81
+ "@acmekit/notification-sendgrid": "2.13.86",
82
+ "@acmekit/rbac": "2.13.86",
83
+ "@acmekit/secrets-aws": "2.13.86",
84
+ "@acmekit/secrets-local": "2.13.86",
85
+ "@acmekit/settings": "2.13.86",
86
+ "@acmekit/telemetry": "2.13.86",
87
+ "@acmekit/translation": "2.13.86",
88
+ "@acmekit/user": "2.13.86",
89
+ "@acmekit/workflow-engine-inmemory": "2.13.86",
90
+ "@acmekit/workflow-engine-redis": "2.13.86",
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.86",
110
110
  "@jimsheen/yalc": "^1.2.2",
111
111
  "@swc/core": "^1.7.28",
112
112
  "posthog-node": "^5.11.0",