@birtalanrobert/context 0.1.0 → 1.0.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,116 @@
1
+ # Changelog
2
+
3
+ Each package carries its own version. A release publishes only the packages
4
+ whose version is not yet on the registry; `pnpm release` asks npm and skips the
5
+ rest.
6
+
7
+ ## 1.0.0
8
+
9
+ The version numbers become meaningful.
10
+
11
+ Until now every package shared one version and all twelve were republished
12
+ together. That does not survive contact with per-package releases while the
13
+ major is `0`: under semver a `^0.2.0` range excludes `0.3.0`, so changing one
14
+ package and releasing only it leaves every dependent pinned to the old copy —
15
+ and npm resolves that by installing both. Two copies of `observability` means
16
+ two distinct `MORTAR_LOGGER` symbols, and dependency injection stops working
17
+ with an error that names neither.
18
+
19
+ At `1.x` a caret range accepts later minors, so a package can be released on
20
+ its own and its dependents pick it up on their next install. From here:
21
+
22
+ - **patch** — a fix that changes no signature
23
+ - **minor** — anything added
24
+ - **major** — anything removed or changed in shape
25
+
26
+ ### Added
27
+
28
+ - **`DatabaseModule` can run migrations at boot** — `migrationsRun: true`.
29
+
30
+ Guarded by a Postgres advisory lock, so several replicas starting at once are
31
+ safe: one applies while the others wait, then find nothing pending. TypeORM
32
+ takes no lock of its own, and without one the second replica to reach a
33
+ `CREATE TABLE` fails and that container crash-loops. Also exported directly
34
+ as `runMigrationsWithLock` for release-step scripts.
35
+
36
+ - **`LoggerModule` provides `NestLoggerAdapter` and `LoggingInterceptor`.**
37
+ Both were exported but never registered, so `app.get(NestLoggerAdapter)` and
38
+ `{ provide: APP_INTERCEPTOR, useExisting: LoggingInterceptor }` — the two
39
+ documented ways to use them — both failed. Constructing them by hand still
40
+ works.
41
+
42
+ - **`PUBLIC_ROUTE_KEY` and `PublicRoute()` in `@birtalanrobert/http`**, and the
43
+ health controller now carries them. `@birtalanrobert/auth` re-exports the key
44
+ as `PUBLIC_KEY`, unchanged, so `PermissionsGuard` and `@Public()` behave
45
+ exactly as before — but a globally registered guard no longer 401s the
46
+ readiness probe, which previously left pods that never joined the load
47
+ balancer.
48
+
49
+ - **`auditEntities` and `idempotencyEntities`**, so every package that ships
50
+ entities exports them as an array the same way it exports its migrations.
51
+
52
+ ### Fixed
53
+
54
+ - **A circular import between `logger.module.ts` and the two classes it now
55
+ provides** left `MORTAR_LOGGER` `undefined` at decorator evaluation time, so
56
+ `@Inject(MORTAR_LOGGER)` silently degraded to reflected-type injection and
57
+ Nest reported that it could not resolve `Function`. The tokens moved to a
58
+ leaf module. Under CommonJS this class of bug fails at wiring time, never at
59
+ build time.
60
+
61
+ ### Testing
62
+
63
+ `@nestjs/testing` and `unplugin-swc` are now dev dependencies, and the Nest
64
+ modules are exercised by building a real container rather than by inspecting
65
+ the `DynamicModule` object. Every defect above was invisible to a test that
66
+ asserts on `module.providers` and obvious to one that calls `moduleRef.get()`.
67
+
68
+ ## 0.2.0
69
+
70
+ Composing the packages into a real application surfaced three problems that
71
+ package-level tests could not.
72
+
73
+ ### Added
74
+
75
+ - **`forRootAsync` on every configurable module** — `LoggerModule`,
76
+ `DatabaseModule`, `RedisModule`, `HttpModule`, `TenancyModule`, `AuthModule`,
77
+ `IdempotencyModule` and `JobsModule`.
78
+
79
+ Previously each module took its options synchronously, which meant a consumer
80
+ had to read `process.env` at import time — before anything had validated it —
81
+ to configure a database URL or a Redis connection. That defeats having a
82
+ configuration layer at all. Options can now come from any provider, including
83
+ the validated config.
84
+
85
+ - **`ConfigModule.token()`**, so a wiring site can write
86
+ `inject: [ConfigModule.token()]` rather than importing the raw symbol.
87
+
88
+ - **`AsyncModuleOptions<T>`** in `@birtalanrobert/context`: the shared shape for
89
+ the above.
90
+
91
+ ### Fixed
92
+
93
+ - **`HttpModule` and `TenancyModule` no longer hold module options in static
94
+ fields.** Both middlewares now receive their options through dependency
95
+ injection. The previous arrangement meant a second `forRoot()` call silently
96
+ overwrote the first — which is exactly what happens when a test suite builds
97
+ more than one application in a process.
98
+
99
+ - **`@birtalanrobert/http` accepts `class-validator` 0.15**, which is current.
100
+ The peer range previously stopped at 0.14 and produced an unmet-peer warning
101
+ on every install.
102
+
103
+ - **Internal dependencies publish as `^x.y.z` rather than an exact pin.** Exact
104
+ pins across a family released together make npm install several copies of the
105
+ same package as soon as two versions coexist in one tree.
106
+
107
+ ### Note on compatibility
108
+
109
+ `HttpModule.contextOptions` and `TenancyModule.resolvers` are no longer present
110
+ as static properties. They were declared `private` and were never part of the
111
+ documented surface — TypeScript consumers could not reach them — but a
112
+ JavaScript consumer reading them would break. Nothing else changed shape.
113
+
114
+ ## 0.1.0
115
+
116
+ First release.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export type { AsyncModuleOptions } from './module-options';
1
2
  export type { Actor, ContextSource, RequestContext } from './types';
2
3
  export { contextSnapshot, createContext, elapsedMs, getActor, getAttribute, getContext, getCorrelationId, getLocale, getRequestId, getTenantId, requireActor, requireContext, requireTenantId, runInChildContext, runInContext, runWithContext, setAttribute, setContextValues, type CreateContextOptions, } from './context';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EACL,eAAe,EACf,aAAa,EACb,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,KAAK,oBAAoB,GAC1B,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EACL,eAAe,EACf,aAAa,EACb,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,KAAK,oBAAoB,GAC1B,MAAM,WAAW,CAAC"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,qCAoBmB;AAnBjB,0GAAA,eAAe,OAAA;AACf,wGAAA,aAAa,OAAA;AACb,oGAAA,SAAS,OAAA;AACT,mGAAA,QAAQ,OAAA;AACR,uGAAA,YAAY,OAAA;AACZ,qGAAA,UAAU,OAAA;AACV,2GAAA,gBAAgB,OAAA;AAChB,oGAAA,SAAS,OAAA;AACT,uGAAA,YAAY,OAAA;AACZ,sGAAA,WAAW,OAAA;AACX,uGAAA,YAAY,OAAA;AACZ,yGAAA,cAAc,OAAA;AACd,0GAAA,eAAe,OAAA;AACf,4GAAA,iBAAiB,OAAA;AACjB,uGAAA,YAAY,OAAA;AACZ,yGAAA,cAAc,OAAA;AACd,uGAAA,YAAY,OAAA;AACZ,2GAAA,gBAAgB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,qCAoBmB;AAnBjB,0GAAA,eAAe,OAAA;AACf,wGAAA,aAAa,OAAA;AACb,oGAAA,SAAS,OAAA;AACT,mGAAA,QAAQ,OAAA;AACR,uGAAA,YAAY,OAAA;AACZ,qGAAA,UAAU,OAAA;AACV,2GAAA,gBAAgB,OAAA;AAChB,oGAAA,SAAS,OAAA;AACT,uGAAA,YAAY,OAAA;AACZ,sGAAA,WAAW,OAAA;AACX,uGAAA,YAAY,OAAA;AACZ,yGAAA,cAAc,OAAA;AACd,0GAAA,eAAe,OAAA;AACf,4GAAA,iBAAiB,OAAA;AACjB,uGAAA,YAAY,OAAA;AACZ,yGAAA,cAAc,OAAA;AACd,uGAAA,YAAY,OAAA;AACZ,2GAAA,gBAAgB,OAAA"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The standard shape for configuring a module from other providers.
3
+ *
4
+ * Every mortar module that takes options offers `forRootAsync`, because the
5
+ * options almost always come from validated configuration — and a module that
6
+ * can only be configured synchronously forces its consumer to read
7
+ * `process.env` directly at import time, which defeats having a config layer
8
+ * at all.
9
+ *
10
+ * Declared here rather than duplicated because it is a type, erased at
11
+ * runtime, and every mortar package already depends on this one.
12
+ */
13
+ export interface AsyncModuleOptions<TOptions> {
14
+ /** Modules whose providers the factory injects. Rarely needed for globals. */
15
+ imports?: unknown[];
16
+ /** Tokens passed to the factory, in order. */
17
+ inject?: unknown[];
18
+ useFactory: (...args: never[]) => TOptions | Promise<TOptions>;
19
+ }
20
+ //# sourceMappingURL=module-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-options.d.ts","sourceRoot":"","sources":["../src/module-options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,kBAAkB,CAAC,QAAQ;IAC1C,8EAA8E;IAC9E,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAChE"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=module-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-options.js","sourceRoot":"","sources":["../src/module-options.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@birtalanrobert/context",
3
- "version": "0.1.0",
3
+ "version": "1.0.0",
4
4
  "description": "AsyncLocalStorage request context",
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "commonjs",
@@ -14,7 +14,8 @@
14
14
  "!src/**/__tests__",
15
15
  "README.md",
16
16
  "LICENSE",
17
- "NOTICE"
17
+ "NOTICE",
18
+ "CHANGELOG.md"
18
19
  ],
19
20
  "exports": {
20
21
  ".": {
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export type { AsyncModuleOptions } from './module-options';
1
2
  export type { Actor, ContextSource, RequestContext } from './types';
2
3
  export {
3
4
  contextSnapshot,
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The standard shape for configuring a module from other providers.
3
+ *
4
+ * Every mortar module that takes options offers `forRootAsync`, because the
5
+ * options almost always come from validated configuration — and a module that
6
+ * can only be configured synchronously forces its consumer to read
7
+ * `process.env` directly at import time, which defeats having a config layer
8
+ * at all.
9
+ *
10
+ * Declared here rather than duplicated because it is a type, erased at
11
+ * runtime, and every mortar package already depends on this one.
12
+ */
13
+ export interface AsyncModuleOptions<TOptions> {
14
+ /** Modules whose providers the factory injects. Rarely needed for globals. */
15
+ imports?: unknown[];
16
+ /** Tokens passed to the factory, in order. */
17
+ inject?: unknown[];
18
+ useFactory: (...args: never[]) => TOptions | Promise<TOptions>;
19
+ }