ts-ioc-container 72.3.0 → 72.3.1

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 (2) hide show
  1. package/README.md +73 -0
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -52,6 +52,7 @@ provider pipelines, aliases, and custom injector strategies.
52
52
  - [Registration](#registration) `@register`
53
53
  - [Token](#token) `bindTo`
54
54
  - [Scope](#scope) `scope`
55
+ - [Environment-based registration](#environment-based-registration) `Env`
55
56
  - [Composing decorators](#composing-decorators) `createComposeClassDecorator`
56
57
  - [Feature flags](#feature-flags) `MultiVariantFeatureToken` `ToggleFeatureToken`
57
58
  - [Module](#module)
@@ -2796,6 +2797,78 @@ describe('Scopes', function () {
2796
2797
 
2797
2798
  ```
2798
2799
 
2800
+ ### Environment-based registration
2801
+
2802
+ Picking an implementation by deployment environment (`prod` / `dev` / `test`)
2803
+ needs no dedicated API - it is the same `scope()` mechanism as above: tag the
2804
+ container with its env and scope each implementation to the env it belongs to.
2805
+ Multiple registrations share the same key; only the one whose scope rule
2806
+ matches the container's tag registers there.
2807
+
2808
+ ```typescript
2809
+ import { bindTo, Container, register, Registration as R, scope, SingleToken } from 'ts-ioc-container';
2810
+
2811
+ /**
2812
+ * Environment-based Registration
2813
+ *
2814
+ * An app often needs a different implementation per deployment environment -
2815
+ * a real payment gateway in production, a stub in tests, a verbose one in dev.
2816
+ * This is a plain application of `scope()`: tag the container with its env and
2817
+ * scope each implementation to the env tag it belongs to. No dedicated API is
2818
+ * needed - the same `ScopeMatchRule` mechanism used for `request` / `transaction`
2819
+ * scopes applies here too.
2820
+ */
2821
+ type Env = 'prod' | 'dev' | 'test';
2822
+
2823
+ interface IPaymentGateway {
2824
+ charge(amount: number): string;
2825
+ }
2826
+
2827
+ const PaymentGatewayToken = new SingleToken<IPaymentGateway>('IPaymentGateway');
2828
+
2829
+ @register(bindTo(PaymentGatewayToken), scope((c) => c.hasTag('prod')))
2830
+ class StripeGateway implements IPaymentGateway {
2831
+ charge(amount: number): string {
2832
+ return `charged $${amount} via Stripe`;
2833
+ }
2834
+ }
2835
+
2836
+ @register(bindTo(PaymentGatewayToken), scope((c) => c.hasTag('dev')))
2837
+ class LoggingGateway implements IPaymentGateway {
2838
+ charge(amount: number): string {
2839
+ return `[dev] would charge $${amount}`;
2840
+ }
2841
+ }
2842
+
2843
+ @register(bindTo(PaymentGatewayToken), scope((c) => c.hasTag('test')))
2844
+ class FakeGateway implements IPaymentGateway {
2845
+ charge(amount: number): string {
2846
+ return `faked charge of $${amount}`;
2847
+ }
2848
+ }
2849
+
2850
+ const createContainerForEnv = (env: Env) =>
2851
+ new Container({ tags: [env] })
2852
+ .addRegistration(R.fromClass(StripeGateway))
2853
+ .addRegistration(R.fromClass(LoggingGateway))
2854
+ .addRegistration(R.fromClass(FakeGateway));
2855
+
2856
+ describe('Environment-based registration', function () {
2857
+ it('should resolve the implementation whose scope tag matches the container env', function () {
2858
+ expect(PaymentGatewayToken.resolve(createContainerForEnv('prod'))).toBeInstanceOf(StripeGateway);
2859
+ expect(PaymentGatewayToken.resolve(createContainerForEnv('dev'))).toBeInstanceOf(LoggingGateway);
2860
+ expect(PaymentGatewayToken.resolve(createContainerForEnv('test'))).toBeInstanceOf(FakeGateway);
2861
+ });
2862
+
2863
+ it('should behave like the environment it was resolved for', function () {
2864
+ const gateway = PaymentGatewayToken.resolve(createContainerForEnv('test'));
2865
+
2866
+ expect(gateway.charge(10)).toBe('faked charge of $10');
2867
+ });
2868
+ });
2869
+
2870
+ ```
2871
+
2799
2872
  ### Composing decorators
2800
2873
 
2801
2874
  A decorator stack repeated on every class of a layer is worth a name.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-ioc-container",
3
- "version": "72.3.0",
3
+ "version": "72.3.1",
4
4
  "description": "Fast, lightweight TypeScript dependency injection container with a clean API, scoped lifecycles, decorators, tokens, hooks, lazy injection, customizable providers, and no global container objects.",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -90,7 +90,7 @@
90
90
  "build:cjm": "node ../scripts/build.mjs cjm",
91
91
  "build:esm": "node ../scripts/build.mjs esm",
92
92
  "build:types": "node ../scripts/build.mjs types",
93
- "generate:docs": "../scripts/generate-readme/generate-readme.ts && git add README.md",
93
+ "generate:docs": "../scripts/generate-readme/generate-readme.ts",
94
94
  "build": "pnpm run build:cjm && pnpm run build:esm && pnpm run build:types",
95
95
  "test": "vitest run",
96
96
  "test:spec": "vitest run __tests__/specs",