@composed-di/core 0.5.2-alpha → 0.6.0-alpha

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.
Files changed (46) hide show
  1. package/dist/errors.d.ts +0 -2
  2. package/dist/errors.d.ts.map +1 -1
  3. package/dist/errors.js +4 -4
  4. package/dist/errors.js.map +1 -1
  5. package/dist/index.d.ts +0 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +0 -2
  8. package/dist/index.js.map +1 -1
  9. package/dist/serviceFactory.d.ts.map +1 -1
  10. package/dist/serviceFactory.js.map +1 -1
  11. package/dist/serviceKey.d.ts +6 -0
  12. package/dist/serviceKey.d.ts.map +1 -1
  13. package/dist/serviceKey.js.map +1 -1
  14. package/dist/serviceModule.d.ts +1 -11
  15. package/dist/serviceModule.d.ts.map +1 -1
  16. package/dist/serviceModule.js +3 -146
  17. package/dist/serviceModule.js.map +1 -1
  18. package/dist/serviceScope.d.ts.map +1 -1
  19. package/dist/serviceScope.js.map +1 -1
  20. package/dist/serviceSelector.d.ts.map +1 -1
  21. package/dist/serviceSelector.js.map +1 -1
  22. package/dist/utils.d.ts.map +1 -1
  23. package/dist/utils.js.map +1 -1
  24. package/package.json +17 -17
  25. package/src/errors.ts +2 -10
  26. package/src/index.ts +7 -9
  27. package/src/serviceFactory.ts +33 -33
  28. package/src/serviceKey.ts +11 -4
  29. package/src/serviceModule.ts +53 -217
  30. package/src/serviceScope.ts +2 -2
  31. package/src/serviceSelector.ts +4 -4
  32. package/src/utils.ts +103 -103
  33. package/dist/redactingEventListener.d.ts +0 -57
  34. package/dist/redactingEventListener.d.ts.map +0 -1
  35. package/dist/redactingEventListener.js +0 -89
  36. package/dist/redactingEventListener.js.map +0 -1
  37. package/dist/serviceEventListener.d.ts +0 -133
  38. package/dist/serviceEventListener.d.ts.map +0 -1
  39. package/dist/serviceEventListener.js +0 -3
  40. package/dist/serviceEventListener.js.map +0 -1
  41. package/dist/serviceModuleListener.d.ts +0 -133
  42. package/dist/serviceModuleListener.d.ts.map +0 -1
  43. package/dist/serviceModuleListener.js +0 -3
  44. package/dist/serviceModuleListener.js.map +0 -1
  45. package/src/redactingEventListener.ts +0 -132
  46. package/src/serviceModuleListener.ts +0 -139
@@ -1,133 +0,0 @@
1
- import type { ServiceKey } from './serviceKey';
2
- /**
3
- * A handle representing a single in-flight operation (initialization,
4
- * disposal, or method call), returned by a ServiceEventListener when the
5
- * operation starts.
6
- *
7
- * `end` is invoked exactly once when the operation finishes, so
8
- * implementations can close over per-call state (a start time, a span
9
- * handle, a correlation id) without any bookkeeping to pair concurrent
10
- * start/finish events.
11
- */
12
- export interface EventSpan {
13
- /**
14
- * Optional wrapper around the operation itself. When present, the module
15
- * invokes the operation as `run(() => operation())`, so the listener can
16
- * establish ambient state that the operation body and its async
17
- * continuations inherit — this is what lets spans of nested service
18
- * calls form a parent-child hierarchy.
19
- *
20
- * Implementations must invoke `fn` exactly once, synchronously, and
21
- * return its result unchanged (for async operations, the promise itself).
22
- * `end` is still delivered separately when the operation finishes.
23
- *
24
- * @param fn - A thunk that performs the operation.
25
- * @return The value returned by `fn`.
26
- */
27
- run?<T>(fn: () => T): T;
28
- /**
29
- * Invoked exactly once when the operation finishes, whether it succeeded
30
- * or failed. For methods that return a promise, this fires when the
31
- * promise settles, not when the method returns. On failure, the error is
32
- * rethrown to the caller after this is invoked.
33
- *
34
- * Whether to retain or log the outcome is the implementation's choice;
35
- * values are passed by reference, so implementations must not mutate them.
36
- *
37
- * @param outcome - How the operation finished, and its value or error.
38
- * @return void
39
- */
40
- end?(outcome: EventOutcome): void;
41
- }
42
- /**
43
- * How an operation finished, delivered to EventSpan.end: `success` carries
44
- * the value produced by the operation (the return or resolved value for
45
- * method calls, the service instance for initialize, undefined for
46
- * dispose); `failure` carries the error that was thrown or rejected.
47
- */
48
- export type EventOutcome = {
49
- type: 'success';
50
- value: unknown;
51
- } | {
52
- type: 'failure';
53
- error: unknown;
54
- };
55
- /**
56
- * Context of a service initialization, delivered to onInitialize.
57
- * Future fields are added here rather than as extra parameters.
58
- */
59
- export interface InitializeContext {
60
- /**
61
- * The unique identifier of the service that is being initialized.
62
- */
63
- key: ServiceKey<unknown>;
64
- }
65
- /**
66
- * Context of a service disposal, delivered to onDispose.
67
- * Future fields are added here rather than as extra parameters.
68
- */
69
- export interface DisposeContext {
70
- /**
71
- * The unique identifier of the service that is being disposed.
72
- */
73
- key: ServiceKey<unknown>;
74
- }
75
- /**
76
- * Context of a method invocation, delivered to onMethodCall.
77
- * Future fields are added here rather than as extra parameters.
78
- */
79
- export interface MethodCallContext {
80
- /**
81
- * The unique identifier of the service the method belongs to.
82
- */
83
- key: ServiceKey<unknown>;
84
- /**
85
- * The name of the class implementing the service (the instance's
86
- * constructor name), which may differ from `key.name`. Undefined for
87
- * services that are not instances of a named class, such as plain
88
- * object literals.
89
- */
90
- className?: string;
91
- /**
92
- * The name of the method that is being called.
93
- */
94
- functionName: string;
95
- /**
96
- * The arguments the method was invoked with, passed by reference;
97
- * implementations must not mutate them.
98
- */
99
- args: readonly unknown[];
100
- }
101
- /**
102
- * Interface for listening to service events. Implement this interface to
103
- * observe lifecycle events and method calls of services in a module.
104
- *
105
- * Each method is invoked when the corresponding operation starts and may
106
- * return an EventSpan that is notified when that operation finishes.
107
- * Returning nothing opts out of completion tracking for that call.
108
- */
109
- export interface ServiceModuleListener {
110
- /**
111
- * Invoked at the start of the initialization process for a specific service.
112
- *
113
- * @param context - Context of the initialization, including the service key.
114
- * @return An EventSpan notified when initialization finishes, or void.
115
- */
116
- onInitialize?(context: InitializeContext): EventSpan | void;
117
- /**
118
- * Invoked when the disposal process for a service starts.
119
- *
120
- * @param context - Context of the disposal, including the service key.
121
- * @return An EventSpan notified when disposal finishes, or void.
122
- */
123
- onDispose?(context: DisposeContext): EventSpan | void;
124
- /**
125
- * Invoked when a method call starts on a service instance.
126
- *
127
- * @param context - Context of the invocation, including the service key,
128
- * the method name, and its arguments.
129
- * @return An EventSpan notified when the call finishes, or void.
130
- */
131
- onMethodCall?(context: MethodCallContext): EventSpan | void;
132
- }
133
- //# sourceMappingURL=serviceModuleListener.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"serviceModuleListener.d.ts","sourceRoot":"","sources":["../src/serviceModuleListener.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;;;;;;;;;OAaG;IACH,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAExB;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;CACnC;AAED;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GACtB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAE5E;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,GAAG,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,GAAG,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,GAAG,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IAEzB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,YAAY,CAAC,CAAC,OAAO,EAAE,iBAAiB,GAAG,SAAS,GAAG,IAAI,CAAC;IAE5D;;;;;OAKG;IACH,SAAS,CAAC,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS,GAAG,IAAI,CAAC;IAEtD;;;;;;OAMG;IACH,YAAY,CAAC,CAAC,OAAO,EAAE,iBAAiB,GAAG,SAAS,GAAG,IAAI,CAAC;CAC7D"}
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=serviceModuleListener.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"serviceModuleListener.js","sourceRoot":"","sources":["../src/serviceModuleListener.ts"],"names":[],"mappings":""}
@@ -1,132 +0,0 @@
1
- import type {
2
- DisposeContext,
3
- EventOutcome,
4
- EventSpan,
5
- InitializeContext,
6
- MethodCallContext,
7
- ServiceModuleListener,
8
- } from './serviceModuleListener';
9
- import type { ServiceKey } from './serviceKey';
10
-
11
- /**
12
- * The placeholder that replaces redacted values in event contexts and
13
- * outcomes.
14
- */
15
- export const REDACTED_VALUE = '[redacted]';
16
-
17
- /**
18
- * Marks a service — or specific properties of it — as sensitive, so the
19
- * values flowing through its events are replaced with {@link REDACTED_VALUE}.
20
- */
21
- export interface RedactionRule<T> {
22
- /**
23
- * The service key whose values must be redacted. Matched by key
24
- * identity, like everywhere else in the container.
25
- */
26
- key: ServiceKey<T>;
27
-
28
- /**
29
- * Property names to redact. Optional: when omitted, ALL properties of
30
- * the service are redacted, along with its initialize result (the
31
- * service instance itself may carry credentials or config).
32
- */
33
- properties?: Extract<keyof T, string>[];
34
- }
35
-
36
- export function redactionRule<T>(key: ServiceKey<T>, properties?: Extract<keyof T, string>[]): RedactionRule<T> {
37
- return { key, properties };
38
- }
39
-
40
- /**
41
- * A ServiceEventListener decorator that redacts sensitive values before
42
- * they reach the wrapped listener. Works with any implementation via
43
- * delegation: arguments in MethodCallContext and success values in
44
- * EventOutcome are replaced with {@link REDACTED_VALUE}, so the delegate
45
- * never sees the sensitive data — whatever it captures or exports is
46
- * already scrubbed.
47
- *
48
- * Failure outcomes are passed through unchanged so error reporting keeps
49
- * working; keep secrets out of error messages at the throwing site.
50
- *
51
- * @example
52
- * ```ts
53
- * const listener = new RedactingEventListener(
54
- * new OTELEventListener({ captureArguments: true, captureResults: true }),
55
- * [
56
- * { key: SecretClientKey }, // whole service is sensitive
57
- * { key: VaultKey, properties: ['getSecret'] }, // only these calls
58
- * ],
59
- * );
60
- * ```
61
- */
62
- export class RedactingEventListener implements ServiceModuleListener {
63
- constructor(
64
- private readonly delegate: ServiceModuleListener,
65
- private readonly rules: readonly RedactionRule<any>[],
66
- ) {}
67
-
68
- onInitialize(context: InitializeContext): EventSpan | void {
69
- // The initialize result is the service instance itself, so it is
70
- // redacted only when the whole service is sensitive — a rule without
71
- // `properties`.
72
- return redactSpan(
73
- this.delegate.onInitialize?.(context),
74
- this.isRedacted(context.key),
75
- );
76
- }
77
-
78
- onDispose(context: DisposeContext): EventSpan | void {
79
- // Dispose carries no arguments and no result value; nothing to redact.
80
- return this.delegate.onDispose?.(context);
81
- }
82
-
83
- onMethodCall(context: MethodCallContext): EventSpan | void {
84
- const redacted = this.isRedacted(context.key, context.functionName);
85
- const span = this.delegate.onMethodCall?.(
86
- redacted
87
- ? // Replace each argument rather than the whole array, so the
88
- // delegate still sees the call's arity.
89
- { ...context, args: context.args.map(() => REDACTED_VALUE) }
90
- : context,
91
- );
92
- return redactSpan(span, redacted);
93
- }
94
-
95
- // 1. Si expiro el dbr `EXPIRED` el cron debe mandar a `FACE_MISMATCH`?
96
- // 2. Si hubo un matchLevel intermediario el cron debe mandar a `FACE_MISMATCH`? (Probablemente no)
97
- private isRedacted(key: ServiceKey<any>, propertyName?: string): boolean {
98
- return this.rules.some(
99
- (rule) =>
100
- rule.key === key &&
101
- // A rule without `properties` redacts everything on the key,
102
- // including initialize — where no property name is passed —
103
- // while a rule with `properties` matches only those calls.
104
- (rule.properties === undefined ||
105
- (propertyName !== undefined &&
106
- rule.properties?.includes(propertyName))),
107
- );
108
- }
109
- }
110
-
111
- /**
112
- * Wraps the delegate's EventSpan so success values are redacted before
113
- * `end` sees them. `run` (and any future fields) pass through untouched.
114
- */
115
- function redactSpan(
116
- span: EventSpan | void,
117
- redacted: boolean,
118
- ): EventSpan | void {
119
- if (!redacted || !span?.end) {
120
- return span;
121
- }
122
- const end = span.end.bind(span);
123
- return {
124
- ...span,
125
- end: (outcome: EventOutcome) =>
126
- end(
127
- outcome.type === 'success'
128
- ? { type: 'success', value: REDACTED_VALUE }
129
- : outcome,
130
- ),
131
- };
132
- }
@@ -1,139 +0,0 @@
1
- import type { ServiceKey } from './serviceKey';
2
-
3
- /**
4
- * A handle representing a single in-flight operation (initialization,
5
- * disposal, or method call), returned by a ServiceEventListener when the
6
- * operation starts.
7
- *
8
- * `end` is invoked exactly once when the operation finishes, so
9
- * implementations can close over per-call state (a start time, a span
10
- * handle, a correlation id) without any bookkeeping to pair concurrent
11
- * start/finish events.
12
- */
13
- export interface EventSpan {
14
- /**
15
- * Optional wrapper around the operation itself. When present, the module
16
- * invokes the operation as `run(() => operation())`, so the listener can
17
- * establish ambient state that the operation body and its async
18
- * continuations inherit — this is what lets spans of nested service
19
- * calls form a parent-child hierarchy.
20
- *
21
- * Implementations must invoke `fn` exactly once, synchronously, and
22
- * return its result unchanged (for async operations, the promise itself).
23
- * `end` is still delivered separately when the operation finishes.
24
- *
25
- * @param fn - A thunk that performs the operation.
26
- * @return The value returned by `fn`.
27
- */
28
- run?<T>(fn: () => T): T;
29
-
30
- /**
31
- * Invoked exactly once when the operation finishes, whether it succeeded
32
- * or failed. For methods that return a promise, this fires when the
33
- * promise settles, not when the method returns. On failure, the error is
34
- * rethrown to the caller after this is invoked.
35
- *
36
- * Whether to retain or log the outcome is the implementation's choice;
37
- * values are passed by reference, so implementations must not mutate them.
38
- *
39
- * @param outcome - How the operation finished, and its value or error.
40
- * @return void
41
- */
42
- end?(outcome: EventOutcome): void;
43
- }
44
-
45
- /**
46
- * How an operation finished, delivered to EventSpan.end: `success` carries
47
- * the value produced by the operation (the return or resolved value for
48
- * method calls, the service instance for initialize, undefined for
49
- * dispose); `failure` carries the error that was thrown or rejected.
50
- */
51
- export type EventOutcome =
52
- { type: 'success'; value: unknown } | { type: 'failure'; error: unknown };
53
-
54
- /**
55
- * Context of a service initialization, delivered to onInitialize.
56
- * Future fields are added here rather than as extra parameters.
57
- */
58
- export interface InitializeContext {
59
- /**
60
- * The unique identifier of the service that is being initialized.
61
- */
62
- key: ServiceKey<unknown>;
63
- }
64
-
65
- /**
66
- * Context of a service disposal, delivered to onDispose.
67
- * Future fields are added here rather than as extra parameters.
68
- */
69
- export interface DisposeContext {
70
- /**
71
- * The unique identifier of the service that is being disposed.
72
- */
73
- key: ServiceKey<unknown>;
74
- }
75
-
76
- /**
77
- * Context of a method invocation, delivered to onMethodCall.
78
- * Future fields are added here rather than as extra parameters.
79
- */
80
- export interface MethodCallContext {
81
- /**
82
- * The unique identifier of the service the method belongs to.
83
- */
84
- key: ServiceKey<unknown>;
85
-
86
- /**
87
- * The name of the class implementing the service (the instance's
88
- * constructor name), which may differ from `key.name`. Undefined for
89
- * services that are not instances of a named class, such as plain
90
- * object literals.
91
- */
92
- className?: string;
93
-
94
- /**
95
- * The name of the method that is being called.
96
- */
97
- functionName: string;
98
-
99
- /**
100
- * The arguments the method was invoked with, passed by reference;
101
- * implementations must not mutate them.
102
- */
103
- args: readonly unknown[];
104
- }
105
-
106
- /**
107
- * Interface for listening to service events. Implement this interface to
108
- * observe lifecycle events and method calls of services in a module.
109
- *
110
- * Each method is invoked when the corresponding operation starts and may
111
- * return an EventSpan that is notified when that operation finishes.
112
- * Returning nothing opts out of completion tracking for that call.
113
- */
114
- export interface ServiceModuleListener {
115
- /**
116
- * Invoked at the start of the initialization process for a specific service.
117
- *
118
- * @param context - Context of the initialization, including the service key.
119
- * @return An EventSpan notified when initialization finishes, or void.
120
- */
121
- onInitialize?(context: InitializeContext): EventSpan | void;
122
-
123
- /**
124
- * Invoked when the disposal process for a service starts.
125
- *
126
- * @param context - Context of the disposal, including the service key.
127
- * @return An EventSpan notified when disposal finishes, or void.
128
- */
129
- onDispose?(context: DisposeContext): EventSpan | void;
130
-
131
- /**
132
- * Invoked when a method call starts on a service instance.
133
- *
134
- * @param context - Context of the invocation, including the service key,
135
- * the method name, and its arguments.
136
- * @return An EventSpan notified when the call finishes, or void.
137
- */
138
- onMethodCall?(context: MethodCallContext): EventSpan | void;
139
- }