joopjs 2.0.5 → 2.1.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.
Files changed (146) hide show
  1. package/.claude/skills/auth.md +235 -0
  2. package/.claude/skills/banking.md +377 -0
  3. package/.claude/skills/encryption.md +265 -0
  4. package/.claude/skills/finance.md +248 -0
  5. package/.claude/skills/observables.md +270 -0
  6. package/.claude/skills/security.md +240 -0
  7. package/.claude/skills/setup.md +196 -0
  8. package/.cursor/rules/joopjs.mdc +150 -0
  9. package/.github/copilot-instructions.md +143 -0
  10. package/.windsurf/rules/joopjs.md +226 -0
  11. package/CHANGELOG.md +81 -0
  12. package/README.md +47 -7
  13. package/ai-rules/AGENTS.md +241 -0
  14. package/ai-rules/GEMINI.md +183 -0
  15. package/dist/ai/index.js +15 -3
  16. package/dist/ai/index.js.map +1 -1
  17. package/dist/ai/index.mjs +15 -3
  18. package/dist/ai/index.mjs.map +1 -1
  19. package/dist/analytics/index.js +10 -2
  20. package/dist/analytics/index.js.map +1 -1
  21. package/dist/analytics/index.mjs +10 -2
  22. package/dist/analytics/index.mjs.map +1 -1
  23. package/dist/angular/index.d.mts +98 -27
  24. package/dist/angular/index.d.ts +98 -27
  25. package/dist/angular/index.js +44 -0
  26. package/dist/angular/index.js.map +1 -1
  27. package/dist/angular/index.mjs +39 -1
  28. package/dist/angular/index.mjs.map +1 -1
  29. package/dist/api/index.js +15 -3
  30. package/dist/api/index.js.map +1 -1
  31. package/dist/api/index.mjs +15 -3
  32. package/dist/api/index.mjs.map +1 -1
  33. package/dist/auth/index.js +15 -3
  34. package/dist/auth/index.js.map +1 -1
  35. package/dist/auth/index.mjs +15 -3
  36. package/dist/auth/index.mjs.map +1 -1
  37. package/dist/banking/index.js +15 -3
  38. package/dist/banking/index.js.map +1 -1
  39. package/dist/banking/index.mjs +15 -3
  40. package/dist/banking/index.mjs.map +1 -1
  41. package/dist/cache/index.js +15 -3
  42. package/dist/cache/index.js.map +1 -1
  43. package/dist/cache/index.mjs +15 -3
  44. package/dist/cache/index.mjs.map +1 -1
  45. package/dist/{index-DFqEoX_l.d.ts → consent.service-CIHNtx9h.d.ts} +1 -2
  46. package/dist/{index-B_ksKpS1.d.mts → consent.service-DQ-JAEJx.d.mts} +1 -2
  47. package/dist/core/index.d.mts +34 -1
  48. package/dist/core/index.d.ts +34 -1
  49. package/dist/core/index.js +56 -5
  50. package/dist/core/index.js.map +1 -1
  51. package/dist/core/index.mjs +54 -6
  52. package/dist/core/index.mjs.map +1 -1
  53. package/dist/deeplink/index.js +15 -3
  54. package/dist/deeplink/index.js.map +1 -1
  55. package/dist/deeplink/index.mjs +15 -3
  56. package/dist/deeplink/index.mjs.map +1 -1
  57. package/dist/device/index.js +15 -3
  58. package/dist/device/index.js.map +1 -1
  59. package/dist/device/index.mjs +15 -3
  60. package/dist/device/index.mjs.map +1 -1
  61. package/dist/forms/index.js +15 -3
  62. package/dist/forms/index.js.map +1 -1
  63. package/dist/forms/index.mjs +15 -3
  64. package/dist/forms/index.mjs.map +1 -1
  65. package/dist/i18n/index.js +15 -3
  66. package/dist/i18n/index.js.map +1 -1
  67. package/dist/i18n/index.mjs +15 -3
  68. package/dist/i18n/index.mjs.map +1 -1
  69. package/dist/index.d.mts +2 -2
  70. package/dist/index.d.ts +2 -2
  71. package/dist/index.js +50 -8
  72. package/dist/index.js.map +1 -1
  73. package/dist/index.mjs +50 -8
  74. package/dist/index.mjs.map +1 -1
  75. package/dist/{joop-CA3DMeOO.d.ts → joop-Dim2yEKG.d.ts} +1 -1
  76. package/dist/{joop-Bx7Iwj5p.d.mts → joop-GkQw13f9.d.mts} +1 -1
  77. package/dist/native-bridge/index.js +10 -2
  78. package/dist/native-bridge/index.js.map +1 -1
  79. package/dist/native-bridge/index.mjs +10 -2
  80. package/dist/native-bridge/index.mjs.map +1 -1
  81. package/dist/network/index.js +15 -3
  82. package/dist/network/index.js.map +1 -1
  83. package/dist/network/index.mjs +15 -3
  84. package/dist/network/index.mjs.map +1 -1
  85. package/dist/observability/index.js +15 -3
  86. package/dist/observability/index.js.map +1 -1
  87. package/dist/observability/index.mjs +15 -3
  88. package/dist/observability/index.mjs.map +1 -1
  89. package/dist/pwa/index.js +15 -3
  90. package/dist/pwa/index.js.map +1 -1
  91. package/dist/pwa/index.mjs +15 -3
  92. package/dist/pwa/index.mjs.map +1 -1
  93. package/dist/react/index.d.mts +2 -2
  94. package/dist/react/index.d.ts +2 -2
  95. package/dist/react/index.js +15 -3
  96. package/dist/react/index.js.map +1 -1
  97. package/dist/react/index.mjs +15 -3
  98. package/dist/react/index.mjs.map +1 -1
  99. package/dist/router/index.js +15 -3
  100. package/dist/router/index.js.map +1 -1
  101. package/dist/router/index.mjs +15 -3
  102. package/dist/router/index.mjs.map +1 -1
  103. package/dist/security/index.js +15 -3
  104. package/dist/security/index.js.map +1 -1
  105. package/dist/security/index.mjs +15 -3
  106. package/dist/security/index.mjs.map +1 -1
  107. package/dist/session/index.js +15 -3
  108. package/dist/session/index.js.map +1 -1
  109. package/dist/session/index.mjs +15 -3
  110. package/dist/session/index.mjs.map +1 -1
  111. package/dist/state/index.js +15 -3
  112. package/dist/state/index.js.map +1 -1
  113. package/dist/state/index.mjs +15 -3
  114. package/dist/state/index.mjs.map +1 -1
  115. package/dist/storage/index.js +15 -3
  116. package/dist/storage/index.js.map +1 -1
  117. package/dist/storage/index.mjs +15 -3
  118. package/dist/storage/index.mjs.map +1 -1
  119. package/dist/sync/index.js +15 -3
  120. package/dist/sync/index.js.map +1 -1
  121. package/dist/sync/index.mjs +15 -3
  122. package/dist/sync/index.mjs.map +1 -1
  123. package/dist/theme/index.js +15 -3
  124. package/dist/theme/index.js.map +1 -1
  125. package/dist/theme/index.mjs +15 -3
  126. package/dist/theme/index.mjs.map +1 -1
  127. package/dist/ui/index.js +15 -3
  128. package/dist/ui/index.js.map +1 -1
  129. package/dist/ui/index.mjs +15 -3
  130. package/dist/ui/index.mjs.map +1 -1
  131. package/dist/utilities/index.js +46 -4
  132. package/dist/utilities/index.js.map +1 -1
  133. package/dist/utilities/index.mjs +46 -4
  134. package/dist/utilities/index.mjs.map +1 -1
  135. package/dist/vue/index.d.mts +2 -2
  136. package/dist/vue/index.d.ts +2 -2
  137. package/dist/vue/index.js +15 -3
  138. package/dist/vue/index.js.map +1 -1
  139. package/dist/vue/index.mjs +15 -3
  140. package/dist/vue/index.mjs.map +1 -1
  141. package/dist/workflow/index.js +15 -3
  142. package/dist/workflow/index.js.map +1 -1
  143. package/dist/workflow/index.mjs +15 -3
  144. package/dist/workflow/index.mjs.map +1 -1
  145. package/package.json +96 -32
  146. package/scripts/setup-ai.mjs +133 -0
@@ -1,8 +1,11 @@
1
- import { J as JoopInstance } from '../joop-Bx7Iwj5p.mjs';
1
+ import * as _angular_router from '@angular/router';
2
+ import { InjectionToken, Injector, DestroyRef, Signal, Provider } from '@angular/core';
3
+ import { HttpInterceptorFn } from '@angular/common/http';
4
+ import { J as JoopInstance } from '../joop-GkQw13f9.mjs';
2
5
  import { J as JoopObservable } from '../index-Dz0gOur2.mjs';
3
6
  import '../config.service-Cz4QQLlf.mjs';
4
7
  import '../config.models-Cqg04fAQ.mjs';
5
- import '../index-B_ksKpS1.mjs';
8
+ import '../consent.service-DQ-JAEJx.mjs';
6
9
  import '../data-storage.service-LvhGRCmw.mjs';
7
10
  import '../index-CqDKWTUP.mjs';
8
11
  import '../auth.service-DNVB-L4U.mjs';
@@ -40,50 +43,48 @@ import '../state/index.mjs';
40
43
  import '../sync-engine-DZqyKHkK.mjs';
41
44
  import '../workflow/index.mjs';
42
45
 
43
- /**
44
- * joopjs/angular — Angular integration
45
- *
46
- * @angular/core 17+ is a required peer dependency.
47
- *
48
- * Standalone (recommended):
49
- * bootstrapApplication(AppComponent, {
50
- * providers: [provideJoop(joopInstance)]
51
- * });
52
- *
53
- * NgModule (legacy):
54
- * @NgModule({ imports: [JoopModule.forRoot(joopInstance)] })
55
- *
56
- * Inject anywhere:
57
- * constructor(@Inject(JOOP) private joop: JoopInstance) {}
58
- *
59
- * RxJS bridge:
60
- * readonly theme$ = fromJoop(this.joop.theme.active$());
61
- */
62
-
63
46
  /**
64
47
  * InjectionToken for the JoopInstance.
65
48
  * Angular's DI accepts any object as a token — use this with @Inject(JOOP).
66
49
  *
67
- * Example with @angular/core InjectionToken (recommended):
68
- * import { InjectionToken } from '@angular/core';
69
- * const JOOP = new InjectionToken<JoopInstance>('JoopInstance');
70
- *
71
50
  * The string form below works for both class-based and object-literal tokens.
51
+ *
52
+ * @deprecated Use the typed {@link JOOP_INSTANCE} token with `inject(JOOP_INSTANCE)`
53
+ * (or {@link injectJoop}) instead — it gives full type inference. The string tokens
54
+ * remain functional but will be removed in a future major.
72
55
  */
73
56
  declare const JOOP: "JOOP_INSTANCE";
57
+ /**
58
+ * Per-service string tokens.
59
+ * @deprecated Inject {@link JOOP_INSTANCE} (or call {@link injectJoop}) and read the
60
+ * service off it (e.g. `injectJoop().auth`). Removed in a future major.
61
+ */
74
62
  declare const JOOP_AUTH: "JOOP_AUTH";
63
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.theme`. */
75
64
  declare const JOOP_THEME: "JOOP_THEME";
65
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.i18n`. */
76
66
  declare const JOOP_I18N: "JOOP_I18N";
67
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.http`. */
77
68
  declare const JOOP_HTTP: "JOOP_HTTP";
69
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.loader`. */
78
70
  declare const JOOP_LOADER: "JOOP_LOADER";
71
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.alert`. */
79
72
  declare const JOOP_ALERT: "JOOP_ALERT";
73
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.router`. */
80
74
  declare const JOOP_ROUTER: "JOOP_ROUTER";
75
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.analytics`. */
81
76
  declare const JOOP_ANALYTICS: "JOOP_ANALYTICS";
77
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.featureFlags`. */
82
78
  declare const JOOP_FEATURE_FLAGS: "JOOP_FEATURE_FLAGS";
79
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.auditLog`. */
83
80
  declare const JOOP_AUDIT_LOG: "JOOP_AUDIT_LOG";
81
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.store`. */
84
82
  declare const JOOP_STORE: "JOOP_STORE";
83
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.keyVault`. */
85
84
  declare const JOOP_KEY_VAULT: "JOOP_KEY_VAULT";
85
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.network`. */
86
86
  declare const JOOP_NETWORK: "JOOP_NETWORK";
87
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.lifecycle`. */
87
88
  declare const JOOP_LIFECYCLE: "JOOP_LIFECYCLE";
88
89
  interface JoopProvider {
89
90
  provide: string;
@@ -94,6 +95,9 @@ interface JoopProvider {
94
95
  * Use with bootstrapApplication() or provideEnvironmentInitializer().
95
96
  *
96
97
  * providers: [...provideJoop(await createJoop(config))]
98
+ *
99
+ * @deprecated Use {@link provideJoopAngular} — it registers the typed
100
+ * {@link JOOP_INSTANCE} token (plus these legacy string tokens for compatibility).
97
101
  */
98
102
  declare function provideJoop(instance: JoopInstance): JoopProvider[];
99
103
  /**
@@ -106,6 +110,9 @@ declare function provideJoop(instance: JoopInstance): JoopProvider[];
106
110
  * directly in your app's providers:
107
111
  *
108
112
  * @NgModule({ providers: JoopModule.forRoot(instance) })
113
+ *
114
+ * @deprecated Standalone APIs are preferred. Use `provideJoopAngular(instance)` in
115
+ * your `ApplicationConfig`/bootstrap providers instead.
109
116
  */
110
117
  declare const JoopModule: {
111
118
  readonly forRoot: (instance: JoopInstance) => {
@@ -119,6 +126,9 @@ declare const JoopModule: {
119
126
  *
120
127
  * readonly loading$ = fromJoop(this.joop.loader.isLoading$());
121
128
  * readonly theme$ = fromJoop(this.joop.theme.active$());
129
+ *
130
+ * @deprecated For Angular 17+ prefer {@link joopSignal} (signals over Observables).
131
+ * Use `fromJoop` only when an RxJS stream is specifically required.
122
132
  */
123
133
  declare function fromJoop<T>(joopObs: JoopObservable<T>): RxJSLike<T>;
124
134
  /**
@@ -144,5 +154,66 @@ interface RxJSLike<T> {
144
154
  * readonly theme$ = zonedFromJoop(this.joop.theme.active$());
145
155
  */
146
156
  declare function createZonedFromJoop(zoneRun: <T>(fn: () => T) => T): <T>(obs: JoopObservable<T>) => RxJSLike<T>;
157
+ /**
158
+ * Typed InjectionToken for the JoopInstance. Prefer this over the string `JOOP`
159
+ * token — it gives full type inference at the injection site.
160
+ *
161
+ * private joop = inject(JOOP_INSTANCE); // typed as JoopInstance
162
+ */
163
+ declare const JOOP_INSTANCE: InjectionToken<JoopInstance>;
164
+ /**
165
+ * Angular providers for the JoopInstance keyed by the typed token (and the
166
+ * legacy string tokens, so existing @Inject(JOOP_*) sites keep working).
167
+ *
168
+ * bootstrapApplication(AppComponent, {
169
+ * providers: [...provideJoopAngular(await createJoop(config))],
170
+ * });
171
+ */
172
+ declare function provideJoopAngular(instance: JoopInstance): Provider[];
173
+ /** Convenience for `inject(JOOP_INSTANCE)` — must run in an injection context. */
174
+ declare function injectJoop(): JoopInstance;
175
+ interface JoopSignalOptions {
176
+ /** Injector to resolve DestroyRef from when called outside an injection context. */
177
+ injector?: Injector;
178
+ /** Explicit teardown ref — bypasses DestroyRef resolution (handy in tests). */
179
+ destroyRef?: Pick<DestroyRef, 'onDestroy'>;
180
+ }
181
+ /**
182
+ * Bridges a JoopObservable into an Angular signal. The signal seeds with the
183
+ * observable's current value (for JoopBehaviorSubject-backed streams) and
184
+ * updates on every emission. The subscription is torn down automatically via
185
+ * DestroyRef when the owning component/service is destroyed.
186
+ *
187
+ * readonly balance = joopSignal(this.joop.wallet.balance$());
188
+ * // template: {{ balance() }}
189
+ *
190
+ * Call from an injection context (field initializer / constructor), or pass an
191
+ * `injector`/`destroyRef` explicitly.
192
+ */
193
+ declare function joopSignal<T>(source: JoopObservable<T>, options?: JoopSignalOptions): Signal<T | undefined>;
194
+ interface JoopAuthGuardOptions {
195
+ /** Where to redirect when not authenticated. Default: '/login'. */
196
+ redirectTo?: string;
197
+ }
198
+ /**
199
+ * Functional CanActivateFn backed by JoopAuthService. Returns true when logged
200
+ * in, otherwise a UrlTree redirecting to `redirectTo`.
201
+ *
202
+ * { path: 'account', canActivate: [joopAuthGuard()], component: AccountComponent }
203
+ */
204
+ declare function joopAuthGuard(options?: JoopAuthGuardOptions): () => true | _angular_router.UrlTree;
205
+ interface JoopAuthInterceptorOptions {
206
+ /** Header name. Default: 'Authorization'. */
207
+ header?: string;
208
+ /** Token scheme prefix. Default: 'Bearer'. Pass '' for a bare token. */
209
+ scheme?: string;
210
+ }
211
+ /**
212
+ * Functional HttpInterceptorFn that attaches the current access token from
213
+ * JoopTokenService to outgoing requests.
214
+ *
215
+ * provideHttpClient(withInterceptors([joopAuthInterceptor()]))
216
+ */
217
+ declare function joopAuthInterceptor(options?: JoopAuthInterceptorOptions): HttpInterceptorFn;
147
218
 
148
- export { JOOP, JOOP_ALERT, JOOP_ANALYTICS, JOOP_AUDIT_LOG, JOOP_AUTH, JOOP_FEATURE_FLAGS, JOOP_HTTP, JOOP_I18N, JOOP_KEY_VAULT, JOOP_LIFECYCLE, JOOP_LOADER, JOOP_NETWORK, JOOP_ROUTER, JOOP_STORE, JOOP_THEME, JoopModule, type JoopProvider, type RxJSLike, createZonedFromJoop, fromJoop, provideJoop, toJoop };
219
+ export { JOOP, JOOP_ALERT, JOOP_ANALYTICS, JOOP_AUDIT_LOG, JOOP_AUTH, JOOP_FEATURE_FLAGS, JOOP_HTTP, JOOP_I18N, JOOP_INSTANCE, JOOP_KEY_VAULT, JOOP_LIFECYCLE, JOOP_LOADER, JOOP_NETWORK, JOOP_ROUTER, JOOP_STORE, JOOP_THEME, type JoopAuthGuardOptions, type JoopAuthInterceptorOptions, JoopModule, type JoopProvider, type JoopSignalOptions, type RxJSLike, createZonedFromJoop, fromJoop, injectJoop, joopAuthGuard, joopAuthInterceptor, joopSignal, provideJoop, provideJoopAngular, toJoop };
@@ -1,8 +1,11 @@
1
- import { J as JoopInstance } from '../joop-CA3DMeOO.js';
1
+ import * as _angular_router from '@angular/router';
2
+ import { InjectionToken, Injector, DestroyRef, Signal, Provider } from '@angular/core';
3
+ import { HttpInterceptorFn } from '@angular/common/http';
4
+ import { J as JoopInstance } from '../joop-Dim2yEKG.js';
2
5
  import { J as JoopObservable } from '../index-Dz0gOur2.js';
3
6
  import '../config.service-CrCvI-JS.js';
4
7
  import '../config.models-Cqg04fAQ.js';
5
- import '../index-DFqEoX_l.js';
8
+ import '../consent.service-CIHNtx9h.js';
6
9
  import '../data-storage.service-DT6xaTxE.js';
7
10
  import '../index-CqDKWTUP.js';
8
11
  import '../auth.service-PjUUSUIt.js';
@@ -40,50 +43,48 @@ import '../state/index.js';
40
43
  import '../sync-engine-DCIMRG5s.js';
41
44
  import '../workflow/index.js';
42
45
 
43
- /**
44
- * joopjs/angular — Angular integration
45
- *
46
- * @angular/core 17+ is a required peer dependency.
47
- *
48
- * Standalone (recommended):
49
- * bootstrapApplication(AppComponent, {
50
- * providers: [provideJoop(joopInstance)]
51
- * });
52
- *
53
- * NgModule (legacy):
54
- * @NgModule({ imports: [JoopModule.forRoot(joopInstance)] })
55
- *
56
- * Inject anywhere:
57
- * constructor(@Inject(JOOP) private joop: JoopInstance) {}
58
- *
59
- * RxJS bridge:
60
- * readonly theme$ = fromJoop(this.joop.theme.active$());
61
- */
62
-
63
46
  /**
64
47
  * InjectionToken for the JoopInstance.
65
48
  * Angular's DI accepts any object as a token — use this with @Inject(JOOP).
66
49
  *
67
- * Example with @angular/core InjectionToken (recommended):
68
- * import { InjectionToken } from '@angular/core';
69
- * const JOOP = new InjectionToken<JoopInstance>('JoopInstance');
70
- *
71
50
  * The string form below works for both class-based and object-literal tokens.
51
+ *
52
+ * @deprecated Use the typed {@link JOOP_INSTANCE} token with `inject(JOOP_INSTANCE)`
53
+ * (or {@link injectJoop}) instead — it gives full type inference. The string tokens
54
+ * remain functional but will be removed in a future major.
72
55
  */
73
56
  declare const JOOP: "JOOP_INSTANCE";
57
+ /**
58
+ * Per-service string tokens.
59
+ * @deprecated Inject {@link JOOP_INSTANCE} (or call {@link injectJoop}) and read the
60
+ * service off it (e.g. `injectJoop().auth`). Removed in a future major.
61
+ */
74
62
  declare const JOOP_AUTH: "JOOP_AUTH";
63
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.theme`. */
75
64
  declare const JOOP_THEME: "JOOP_THEME";
65
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.i18n`. */
76
66
  declare const JOOP_I18N: "JOOP_I18N";
67
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.http`. */
77
68
  declare const JOOP_HTTP: "JOOP_HTTP";
69
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.loader`. */
78
70
  declare const JOOP_LOADER: "JOOP_LOADER";
71
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.alert`. */
79
72
  declare const JOOP_ALERT: "JOOP_ALERT";
73
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.router`. */
80
74
  declare const JOOP_ROUTER: "JOOP_ROUTER";
75
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.analytics`. */
81
76
  declare const JOOP_ANALYTICS: "JOOP_ANALYTICS";
77
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.featureFlags`. */
82
78
  declare const JOOP_FEATURE_FLAGS: "JOOP_FEATURE_FLAGS";
79
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.auditLog`. */
83
80
  declare const JOOP_AUDIT_LOG: "JOOP_AUDIT_LOG";
81
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.store`. */
84
82
  declare const JOOP_STORE: "JOOP_STORE";
83
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.keyVault`. */
85
84
  declare const JOOP_KEY_VAULT: "JOOP_KEY_VAULT";
85
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.network`. */
86
86
  declare const JOOP_NETWORK: "JOOP_NETWORK";
87
+ /** @deprecated Inject {@link JOOP_INSTANCE} and read `.lifecycle`. */
87
88
  declare const JOOP_LIFECYCLE: "JOOP_LIFECYCLE";
88
89
  interface JoopProvider {
89
90
  provide: string;
@@ -94,6 +95,9 @@ interface JoopProvider {
94
95
  * Use with bootstrapApplication() or provideEnvironmentInitializer().
95
96
  *
96
97
  * providers: [...provideJoop(await createJoop(config))]
98
+ *
99
+ * @deprecated Use {@link provideJoopAngular} — it registers the typed
100
+ * {@link JOOP_INSTANCE} token (plus these legacy string tokens for compatibility).
97
101
  */
98
102
  declare function provideJoop(instance: JoopInstance): JoopProvider[];
99
103
  /**
@@ -106,6 +110,9 @@ declare function provideJoop(instance: JoopInstance): JoopProvider[];
106
110
  * directly in your app's providers:
107
111
  *
108
112
  * @NgModule({ providers: JoopModule.forRoot(instance) })
113
+ *
114
+ * @deprecated Standalone APIs are preferred. Use `provideJoopAngular(instance)` in
115
+ * your `ApplicationConfig`/bootstrap providers instead.
109
116
  */
110
117
  declare const JoopModule: {
111
118
  readonly forRoot: (instance: JoopInstance) => {
@@ -119,6 +126,9 @@ declare const JoopModule: {
119
126
  *
120
127
  * readonly loading$ = fromJoop(this.joop.loader.isLoading$());
121
128
  * readonly theme$ = fromJoop(this.joop.theme.active$());
129
+ *
130
+ * @deprecated For Angular 17+ prefer {@link joopSignal} (signals over Observables).
131
+ * Use `fromJoop` only when an RxJS stream is specifically required.
122
132
  */
123
133
  declare function fromJoop<T>(joopObs: JoopObservable<T>): RxJSLike<T>;
124
134
  /**
@@ -144,5 +154,66 @@ interface RxJSLike<T> {
144
154
  * readonly theme$ = zonedFromJoop(this.joop.theme.active$());
145
155
  */
146
156
  declare function createZonedFromJoop(zoneRun: <T>(fn: () => T) => T): <T>(obs: JoopObservable<T>) => RxJSLike<T>;
157
+ /**
158
+ * Typed InjectionToken for the JoopInstance. Prefer this over the string `JOOP`
159
+ * token — it gives full type inference at the injection site.
160
+ *
161
+ * private joop = inject(JOOP_INSTANCE); // typed as JoopInstance
162
+ */
163
+ declare const JOOP_INSTANCE: InjectionToken<JoopInstance>;
164
+ /**
165
+ * Angular providers for the JoopInstance keyed by the typed token (and the
166
+ * legacy string tokens, so existing @Inject(JOOP_*) sites keep working).
167
+ *
168
+ * bootstrapApplication(AppComponent, {
169
+ * providers: [...provideJoopAngular(await createJoop(config))],
170
+ * });
171
+ */
172
+ declare function provideJoopAngular(instance: JoopInstance): Provider[];
173
+ /** Convenience for `inject(JOOP_INSTANCE)` — must run in an injection context. */
174
+ declare function injectJoop(): JoopInstance;
175
+ interface JoopSignalOptions {
176
+ /** Injector to resolve DestroyRef from when called outside an injection context. */
177
+ injector?: Injector;
178
+ /** Explicit teardown ref — bypasses DestroyRef resolution (handy in tests). */
179
+ destroyRef?: Pick<DestroyRef, 'onDestroy'>;
180
+ }
181
+ /**
182
+ * Bridges a JoopObservable into an Angular signal. The signal seeds with the
183
+ * observable's current value (for JoopBehaviorSubject-backed streams) and
184
+ * updates on every emission. The subscription is torn down automatically via
185
+ * DestroyRef when the owning component/service is destroyed.
186
+ *
187
+ * readonly balance = joopSignal(this.joop.wallet.balance$());
188
+ * // template: {{ balance() }}
189
+ *
190
+ * Call from an injection context (field initializer / constructor), or pass an
191
+ * `injector`/`destroyRef` explicitly.
192
+ */
193
+ declare function joopSignal<T>(source: JoopObservable<T>, options?: JoopSignalOptions): Signal<T | undefined>;
194
+ interface JoopAuthGuardOptions {
195
+ /** Where to redirect when not authenticated. Default: '/login'. */
196
+ redirectTo?: string;
197
+ }
198
+ /**
199
+ * Functional CanActivateFn backed by JoopAuthService. Returns true when logged
200
+ * in, otherwise a UrlTree redirecting to `redirectTo`.
201
+ *
202
+ * { path: 'account', canActivate: [joopAuthGuard()], component: AccountComponent }
203
+ */
204
+ declare function joopAuthGuard(options?: JoopAuthGuardOptions): () => true | _angular_router.UrlTree;
205
+ interface JoopAuthInterceptorOptions {
206
+ /** Header name. Default: 'Authorization'. */
207
+ header?: string;
208
+ /** Token scheme prefix. Default: 'Bearer'. Pass '' for a bare token. */
209
+ scheme?: string;
210
+ }
211
+ /**
212
+ * Functional HttpInterceptorFn that attaches the current access token from
213
+ * JoopTokenService to outgoing requests.
214
+ *
215
+ * provideHttpClient(withInterceptors([joopAuthInterceptor()]))
216
+ */
217
+ declare function joopAuthInterceptor(options?: JoopAuthInterceptorOptions): HttpInterceptorFn;
147
218
 
148
- export { JOOP, JOOP_ALERT, JOOP_ANALYTICS, JOOP_AUDIT_LOG, JOOP_AUTH, JOOP_FEATURE_FLAGS, JOOP_HTTP, JOOP_I18N, JOOP_KEY_VAULT, JOOP_LIFECYCLE, JOOP_LOADER, JOOP_NETWORK, JOOP_ROUTER, JOOP_STORE, JOOP_THEME, JoopModule, type JoopProvider, type RxJSLike, createZonedFromJoop, fromJoop, provideJoop, toJoop };
219
+ export { JOOP, JOOP_ALERT, JOOP_ANALYTICS, JOOP_AUDIT_LOG, JOOP_AUTH, JOOP_FEATURE_FLAGS, JOOP_HTTP, JOOP_I18N, JOOP_INSTANCE, JOOP_KEY_VAULT, JOOP_LIFECYCLE, JOOP_LOADER, JOOP_NETWORK, JOOP_ROUTER, JOOP_STORE, JOOP_THEME, type JoopAuthGuardOptions, type JoopAuthInterceptorOptions, JoopModule, type JoopProvider, type JoopSignalOptions, type RxJSLike, createZonedFromJoop, fromJoop, injectJoop, joopAuthGuard, joopAuthInterceptor, joopSignal, provideJoop, provideJoopAngular, toJoop };
@@ -1,5 +1,8 @@
1
1
  'use strict';
2
2
 
3
+ var core = require('@angular/core');
4
+ var router = require('@angular/router');
5
+
3
6
  // src/angular/index.ts
4
7
  var JOOP = "JOOP_INSTANCE";
5
8
  var JOOP_AUTH = "JOOP_AUTH";
@@ -97,6 +100,41 @@ function createZonedFromJoop(zoneRun) {
97
100
  };
98
101
  };
99
102
  }
103
+ var JOOP_INSTANCE = new core.InjectionToken("joopjs.JoopInstance");
104
+ function provideJoopAngular(instance) {
105
+ return [
106
+ { provide: JOOP_INSTANCE, useValue: instance },
107
+ ...provideJoop(instance)
108
+ ];
109
+ }
110
+ function injectJoop() {
111
+ return core.inject(JOOP_INSTANCE);
112
+ }
113
+ function joopSignal(source, options = {}) {
114
+ const seed = source.getOnce();
115
+ const sig = core.signal(seed);
116
+ const unsubscribe = source.subscribe((v) => sig.set(v));
117
+ const destroyRef = options.destroyRef ?? options.injector?.get(core.DestroyRef) ?? core.inject(core.DestroyRef);
118
+ destroyRef.onDestroy(() => unsubscribe());
119
+ return sig.asReadonly();
120
+ }
121
+ function joopAuthGuard(options = {}) {
122
+ return () => {
123
+ const joop = core.inject(JOOP_INSTANCE);
124
+ if (joop.auth.isLoggedIn()) return true;
125
+ return core.inject(router.Router).parseUrl(options.redirectTo ?? "/login");
126
+ };
127
+ }
128
+ function joopAuthInterceptor(options = {}) {
129
+ const header = options.header ?? "Authorization";
130
+ const scheme = options.scheme ?? "Bearer";
131
+ return (req, next) => {
132
+ const token = core.inject(JOOP_INSTANCE).token.getAccessToken();
133
+ if (!token) return next(req);
134
+ const value = scheme ? `${scheme} ${token}` : token;
135
+ return next(req.clone({ setHeaders: { [header]: value } }));
136
+ };
137
+ }
100
138
 
101
139
  exports.JOOP = JOOP;
102
140
  exports.JOOP_ALERT = JOOP_ALERT;
@@ -106,6 +144,7 @@ exports.JOOP_AUTH = JOOP_AUTH;
106
144
  exports.JOOP_FEATURE_FLAGS = JOOP_FEATURE_FLAGS;
107
145
  exports.JOOP_HTTP = JOOP_HTTP;
108
146
  exports.JOOP_I18N = JOOP_I18N;
147
+ exports.JOOP_INSTANCE = JOOP_INSTANCE;
109
148
  exports.JOOP_KEY_VAULT = JOOP_KEY_VAULT;
110
149
  exports.JOOP_LIFECYCLE = JOOP_LIFECYCLE;
111
150
  exports.JOOP_LOADER = JOOP_LOADER;
@@ -116,7 +155,12 @@ exports.JOOP_THEME = JOOP_THEME;
116
155
  exports.JoopModule = JoopModule;
117
156
  exports.createZonedFromJoop = createZonedFromJoop;
118
157
  exports.fromJoop = fromJoop;
158
+ exports.injectJoop = injectJoop;
159
+ exports.joopAuthGuard = joopAuthGuard;
160
+ exports.joopAuthInterceptor = joopAuthInterceptor;
161
+ exports.joopSignal = joopSignal;
119
162
  exports.provideJoop = provideJoop;
163
+ exports.provideJoopAngular = provideJoopAngular;
120
164
  exports.toJoop = toJoop;
121
165
  //# sourceMappingURL=index.js.map
122
166
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/angular/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * joopjs/angular — Angular integration\n *\n * @angular/core 17+ is a required peer dependency.\n *\n * Standalone (recommended):\n * bootstrapApplication(AppComponent, {\n * providers: [provideJoop(joopInstance)]\n * });\n *\n * NgModule (legacy):\n * @NgModule({ imports: [JoopModule.forRoot(joopInstance)] })\n *\n * Inject anywhere:\n * constructor(@Inject(JOOP) private joop: JoopInstance) {}\n *\n * RxJS bridge:\n * readonly theme$ = fromJoop(this.joop.theme.active$());\n */\n\nimport type { JoopInstance } from '../joop';\nimport type { JoopObservable } from '../events';\n\n// ── Injection token ───────────────────────────────────────────────────────────\n\n/**\n * InjectionToken for the JoopInstance.\n * Angular's DI accepts any object as a token — use this with @Inject(JOOP).\n *\n * Example with @angular/core InjectionToken (recommended):\n * import { InjectionToken } from '@angular/core';\n * const JOOP = new InjectionToken<JoopInstance>('JoopInstance');\n *\n * The string form below works for both class-based and object-literal tokens.\n */\nexport const JOOP = 'JOOP_INSTANCE' as const;\nexport const JOOP_AUTH = 'JOOP_AUTH' as const;\nexport const JOOP_THEME = 'JOOP_THEME' as const;\nexport const JOOP_I18N = 'JOOP_I18N' as const;\nexport const JOOP_HTTP = 'JOOP_HTTP' as const;\nexport const JOOP_LOADER = 'JOOP_LOADER' as const;\nexport const JOOP_ALERT = 'JOOP_ALERT' as const;\nexport const JOOP_ROUTER = 'JOOP_ROUTER' as const;\nexport const JOOP_ANALYTICS = 'JOOP_ANALYTICS' as const;\nexport const JOOP_FEATURE_FLAGS = 'JOOP_FEATURE_FLAGS' as const;\nexport const JOOP_AUDIT_LOG = 'JOOP_AUDIT_LOG' as const;\nexport const JOOP_STORE = 'JOOP_STORE' as const;\nexport const JOOP_KEY_VAULT = 'JOOP_KEY_VAULT' as const;\nexport const JOOP_NETWORK = 'JOOP_NETWORK' as const;\nexport const JOOP_LIFECYCLE = 'JOOP_LIFECYCLE' as const;\n\n// ── Provider types ────────────────────────────────────────────────────────────\n\nexport interface JoopProvider {\n provide: string;\n useValue: unknown;\n}\n\n// ── Provider factory ──────────────────────────────────────────────────────────\n\n/**\n * Returns an array of Angular providers for the JoopInstance and its services.\n * Use with bootstrapApplication() or provideEnvironmentInitializer().\n *\n * providers: [...provideJoop(await createJoop(config))]\n */\nexport function provideJoop(instance: JoopInstance): JoopProvider[] {\n return [\n { provide: JOOP, useValue: instance },\n { provide: JOOP_AUTH, useValue: instance.auth },\n { provide: JOOP_THEME, useValue: instance.theme },\n { provide: JOOP_I18N, useValue: instance.i18n },\n { provide: JOOP_HTTP, useValue: instance.http },\n { provide: JOOP_LOADER, useValue: instance.loader },\n { provide: JOOP_ALERT, useValue: instance.alert },\n { provide: JOOP_ROUTER, useValue: instance.router },\n { provide: JOOP_ANALYTICS, useValue: instance.analytics },\n { provide: JOOP_FEATURE_FLAGS,useValue: instance.featureFlags },\n { provide: JOOP_AUDIT_LOG, useValue: instance.auditLog },\n { provide: JOOP_STORE, useValue: instance.store },\n { provide: JOOP_KEY_VAULT, useValue: instance.keyVault },\n { provide: JOOP_NETWORK, useValue: instance.network },\n { provide: JOOP_LIFECYCLE, useValue: instance.lifecycle },\n ];\n}\n\n// ── NgModule helper ───────────────────────────────────────────────────────────\n\n/**\n * Minimal NgModule descriptor for use with @NgModule imports.\n * Call JoopModule.forRoot(instance) and spread the result into the imports array.\n *\n * @NgModule({ imports: [...JoopModule.forRoot(instance).providers ?? []] })\n *\n * For proper Angular NgModule integration, use the returned providers array\n * directly in your app's providers:\n *\n * @NgModule({ providers: JoopModule.forRoot(instance) })\n */\nexport const JoopModule = {\n forRoot(instance: JoopInstance): { providers: JoopProvider[] } {\n return { providers: provideJoop(instance) };\n },\n} as const;\n\n// ── RxJS bridge ───────────────────────────────────────────────────────────────\n\n/**\n * Converts a JoopObservable (JoopBehaviorSubject) into an RxJS-compatible\n * Observable. The returned object implements the Observable contract:\n * subscribe(observer) returns a Subscription with unsubscribe().\n *\n * readonly loading$ = fromJoop(this.joop.loader.isLoading$());\n * readonly theme$ = fromJoop(this.joop.theme.active$());\n */\nexport function fromJoop<T>(joopObs: JoopObservable<T>): RxJSLike<T> {\n return {\n subscribe(\n observerOrNext:\n | ((value: T) => void)\n | { next?: (v: T) => void; error?: (e: unknown) => void; complete?: () => void },\n ): { unsubscribe(): void } {\n const next =\n typeof observerOrNext === 'function'\n ? observerOrNext\n : (observerOrNext.next?.bind(observerOrNext) ?? ((_: T) => {}));\n const unsubscribe = joopObs.subscribe(next);\n return { unsubscribe };\n },\n pipe(...operators: Array<(obs: RxJSLike<T>) => RxJSLike<unknown>>): RxJSLike<unknown> {\n return operators.reduce((acc, op) => op(acc), this as RxJSLike<unknown>);\n },\n };\n}\n\n/**\n * Converts an RxJS Observable into a JoopObservable-compatible object.\n * Useful for bridging existing RxJS streams into JoopJS services.\n */\nexport function toJoop<T>(rxjsObs: RxJSLike<T>): JoopObservable<T> {\n const handlers = new Set<(v: T) => void>();\n let rxSub: { unsubscribe(): void } | null = null;\n\n return {\n subscribe(fn: (v: T) => void): () => void {\n handlers.add(fn);\n if (!rxSub) {\n rxSub = rxjsObs.subscribe(v => handlers.forEach(h => h(v)));\n }\n return () => {\n handlers.delete(fn);\n if (handlers.size === 0) { rxSub?.unsubscribe(); rxSub = null; }\n };\n },\n pipe(transform: (v: T) => unknown): JoopObservable<unknown> {\n return toJoop({\n subscribe: (obs) => rxjsObs.subscribe({\n next: (v) => typeof obs === 'function' ? obs(transform(v)) : obs.next?.(transform(v) as never),\n }),\n pipe: () => { throw new Error('pipe chaining not supported in toJoop bridge'); },\n }) as JoopObservable<unknown>;\n },\n } as unknown as JoopObservable<T>;\n}\n\n// ── Minimal RxJS-compatible Observable type ───────────────────────────────────\n\nexport interface RxJSLike<T> {\n subscribe(\n observerOrNext:\n | ((value: T) => void)\n | { next?: (v: T) => void; error?: (e: unknown) => void; complete?: () => void },\n ): { unsubscribe(): void };\n pipe(...operators: Array<(obs: RxJSLike<T>) => RxJSLike<unknown>>): RxJSLike<unknown>;\n}\n\n// ── Change detection helper ───────────────────────────────────────────────────\n\n/**\n * Returns a factory for wrapping JoopObservable subscriptions inside Angular's\n * change detection zone. Pass NgZone.run as the runner.\n *\n * const zonedFromJoop = createZonedFromJoop(zone.run.bind(zone));\n * readonly theme$ = zonedFromJoop(this.joop.theme.active$());\n */\nexport function createZonedFromJoop(\n zoneRun: <T>(fn: () => T) => T,\n): <T>(obs: JoopObservable<T>) => RxJSLike<T> {\n return <T>(obs: JoopObservable<T>): RxJSLike<T> => {\n return {\n subscribe(observerOrNext) {\n const next =\n typeof observerOrNext === 'function'\n ? observerOrNext\n : (observerOrNext.next?.bind(observerOrNext) ?? ((_: T) => {}));\n const unsubscribe = obs.subscribe(v => zoneRun(() => next(v)));\n return { unsubscribe };\n },\n pipe(...operators) {\n return operators.reduce((acc, op) => op(acc), this as RxJSLike<unknown>);\n },\n };\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/angular/index.ts"],"names":["InjectionToken","inject","signal","DestroyRef","Router"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * joopjs/angular — Angular integration\n *\n * @angular/core 17+ is a required peer dependency.\n *\n * Standalone (recommended):\n * bootstrapApplication(AppComponent, {\n * providers: [provideJoop(joopInstance)]\n * });\n *\n * NgModule (legacy):\n * @NgModule({ imports: [JoopModule.forRoot(joopInstance)] })\n *\n * Inject anywhere:\n * constructor(@Inject(JOOP) private joop: JoopInstance) {}\n *\n * RxJS bridge:\n * readonly theme$ = fromJoop(this.joop.theme.active$());\n */\n\nimport {\n InjectionToken,\n inject,\n signal,\n DestroyRef,\n type Signal,\n type Injector,\n type Provider,\n} from '@angular/core';\nimport { Router } from '@angular/router';\nimport type { HttpInterceptorFn } from '@angular/common/http';\nimport type { JoopInstance } from '../joop';\nimport type { JoopObservable } from '../events';\n\n// ── Injection token ───────────────────────────────────────────────────────────\n\n/**\n * InjectionToken for the JoopInstance.\n * Angular's DI accepts any object as a token — use this with @Inject(JOOP).\n *\n * The string form below works for both class-based and object-literal tokens.\n *\n * @deprecated Use the typed {@link JOOP_INSTANCE} token with `inject(JOOP_INSTANCE)`\n * (or {@link injectJoop}) instead — it gives full type inference. The string tokens\n * remain functional but will be removed in a future major.\n */\nexport const JOOP = 'JOOP_INSTANCE' as const;\n/**\n * Per-service string tokens.\n * @deprecated Inject {@link JOOP_INSTANCE} (or call {@link injectJoop}) and read the\n * service off it (e.g. `injectJoop().auth`). Removed in a future major.\n */\nexport const JOOP_AUTH = 'JOOP_AUTH' as const;\n/** @deprecated Inject {@link JOOP_INSTANCE} and read `.theme`. */\nexport const JOOP_THEME = 'JOOP_THEME' as const;\n/** @deprecated Inject {@link JOOP_INSTANCE} and read `.i18n`. */\nexport const JOOP_I18N = 'JOOP_I18N' as const;\n/** @deprecated Inject {@link JOOP_INSTANCE} and read `.http`. */\nexport const JOOP_HTTP = 'JOOP_HTTP' as const;\n/** @deprecated Inject {@link JOOP_INSTANCE} and read `.loader`. */\nexport const JOOP_LOADER = 'JOOP_LOADER' as const;\n/** @deprecated Inject {@link JOOP_INSTANCE} and read `.alert`. */\nexport const JOOP_ALERT = 'JOOP_ALERT' as const;\n/** @deprecated Inject {@link JOOP_INSTANCE} and read `.router`. */\nexport const JOOP_ROUTER = 'JOOP_ROUTER' as const;\n/** @deprecated Inject {@link JOOP_INSTANCE} and read `.analytics`. */\nexport const JOOP_ANALYTICS = 'JOOP_ANALYTICS' as const;\n/** @deprecated Inject {@link JOOP_INSTANCE} and read `.featureFlags`. */\nexport const JOOP_FEATURE_FLAGS = 'JOOP_FEATURE_FLAGS' as const;\n/** @deprecated Inject {@link JOOP_INSTANCE} and read `.auditLog`. */\nexport const JOOP_AUDIT_LOG = 'JOOP_AUDIT_LOG' as const;\n/** @deprecated Inject {@link JOOP_INSTANCE} and read `.store`. */\nexport const JOOP_STORE = 'JOOP_STORE' as const;\n/** @deprecated Inject {@link JOOP_INSTANCE} and read `.keyVault`. */\nexport const JOOP_KEY_VAULT = 'JOOP_KEY_VAULT' as const;\n/** @deprecated Inject {@link JOOP_INSTANCE} and read `.network`. */\nexport const JOOP_NETWORK = 'JOOP_NETWORK' as const;\n/** @deprecated Inject {@link JOOP_INSTANCE} and read `.lifecycle`. */\nexport const JOOP_LIFECYCLE = 'JOOP_LIFECYCLE' as const;\n\n// ── Provider types ────────────────────────────────────────────────────────────\n\nexport interface JoopProvider {\n provide: string;\n useValue: unknown;\n}\n\n// ── Provider factory ──────────────────────────────────────────────────────────\n\n/**\n * Returns an array of Angular providers for the JoopInstance and its services.\n * Use with bootstrapApplication() or provideEnvironmentInitializer().\n *\n * providers: [...provideJoop(await createJoop(config))]\n *\n * @deprecated Use {@link provideJoopAngular} — it registers the typed\n * {@link JOOP_INSTANCE} token (plus these legacy string tokens for compatibility).\n */\nexport function provideJoop(instance: JoopInstance): JoopProvider[] {\n return [\n { provide: JOOP, useValue: instance },\n { provide: JOOP_AUTH, useValue: instance.auth },\n { provide: JOOP_THEME, useValue: instance.theme },\n { provide: JOOP_I18N, useValue: instance.i18n },\n { provide: JOOP_HTTP, useValue: instance.http },\n { provide: JOOP_LOADER, useValue: instance.loader },\n { provide: JOOP_ALERT, useValue: instance.alert },\n { provide: JOOP_ROUTER, useValue: instance.router },\n { provide: JOOP_ANALYTICS, useValue: instance.analytics },\n { provide: JOOP_FEATURE_FLAGS,useValue: instance.featureFlags },\n { provide: JOOP_AUDIT_LOG, useValue: instance.auditLog },\n { provide: JOOP_STORE, useValue: instance.store },\n { provide: JOOP_KEY_VAULT, useValue: instance.keyVault },\n { provide: JOOP_NETWORK, useValue: instance.network },\n { provide: JOOP_LIFECYCLE, useValue: instance.lifecycle },\n ];\n}\n\n// ── NgModule helper ───────────────────────────────────────────────────────────\n\n/**\n * Minimal NgModule descriptor for use with @NgModule imports.\n * Call JoopModule.forRoot(instance) and spread the result into the imports array.\n *\n * @NgModule({ imports: [...JoopModule.forRoot(instance).providers ?? []] })\n *\n * For proper Angular NgModule integration, use the returned providers array\n * directly in your app's providers:\n *\n * @NgModule({ providers: JoopModule.forRoot(instance) })\n *\n * @deprecated Standalone APIs are preferred. Use `provideJoopAngular(instance)` in\n * your `ApplicationConfig`/bootstrap providers instead.\n */\nexport const JoopModule = {\n forRoot(instance: JoopInstance): { providers: JoopProvider[] } {\n return { providers: provideJoop(instance) };\n },\n} as const;\n\n// ── RxJS bridge ───────────────────────────────────────────────────────────────\n\n/**\n * Converts a JoopObservable (JoopBehaviorSubject) into an RxJS-compatible\n * Observable. The returned object implements the Observable contract:\n * subscribe(observer) returns a Subscription with unsubscribe().\n *\n * readonly loading$ = fromJoop(this.joop.loader.isLoading$());\n * readonly theme$ = fromJoop(this.joop.theme.active$());\n *\n * @deprecated For Angular 17+ prefer {@link joopSignal} (signals over Observables).\n * Use `fromJoop` only when an RxJS stream is specifically required.\n */\nexport function fromJoop<T>(joopObs: JoopObservable<T>): RxJSLike<T> {\n return {\n subscribe(\n observerOrNext:\n | ((value: T) => void)\n | { next?: (v: T) => void; error?: (e: unknown) => void; complete?: () => void },\n ): { unsubscribe(): void } {\n const next =\n typeof observerOrNext === 'function'\n ? observerOrNext\n : (observerOrNext.next?.bind(observerOrNext) ?? ((_: T) => {}));\n const unsubscribe = joopObs.subscribe(next);\n return { unsubscribe };\n },\n pipe(...operators: Array<(obs: RxJSLike<T>) => RxJSLike<unknown>>): RxJSLike<unknown> {\n return operators.reduce((acc, op) => op(acc), this as RxJSLike<unknown>);\n },\n };\n}\n\n/**\n * Converts an RxJS Observable into a JoopObservable-compatible object.\n * Useful for bridging existing RxJS streams into JoopJS services.\n */\nexport function toJoop<T>(rxjsObs: RxJSLike<T>): JoopObservable<T> {\n const handlers = new Set<(v: T) => void>();\n let rxSub: { unsubscribe(): void } | null = null;\n\n return {\n subscribe(fn: (v: T) => void): () => void {\n handlers.add(fn);\n if (!rxSub) {\n rxSub = rxjsObs.subscribe(v => handlers.forEach(h => h(v)));\n }\n return () => {\n handlers.delete(fn);\n if (handlers.size === 0) { rxSub?.unsubscribe(); rxSub = null; }\n };\n },\n pipe(transform: (v: T) => unknown): JoopObservable<unknown> {\n return toJoop({\n subscribe: (obs) => rxjsObs.subscribe({\n next: (v) => typeof obs === 'function' ? obs(transform(v)) : obs.next?.(transform(v) as never),\n }),\n pipe: () => { throw new Error('pipe chaining not supported in toJoop bridge'); },\n }) as JoopObservable<unknown>;\n },\n } as unknown as JoopObservable<T>;\n}\n\n// ── Minimal RxJS-compatible Observable type ───────────────────────────────────\n\nexport interface RxJSLike<T> {\n subscribe(\n observerOrNext:\n | ((value: T) => void)\n | { next?: (v: T) => void; error?: (e: unknown) => void; complete?: () => void },\n ): { unsubscribe(): void };\n pipe(...operators: Array<(obs: RxJSLike<T>) => RxJSLike<unknown>>): RxJSLike<unknown>;\n}\n\n// ── Change detection helper ───────────────────────────────────────────────────\n\n/**\n * Returns a factory for wrapping JoopObservable subscriptions inside Angular's\n * change detection zone. Pass NgZone.run as the runner.\n *\n * const zonedFromJoop = createZonedFromJoop(zone.run.bind(zone));\n * readonly theme$ = zonedFromJoop(this.joop.theme.active$());\n */\nexport function createZonedFromJoop(\n zoneRun: <T>(fn: () => T) => T,\n): <T>(obs: JoopObservable<T>) => RxJSLike<T> {\n return <T>(obs: JoopObservable<T>): RxJSLike<T> => {\n return {\n subscribe(observerOrNext) {\n const next =\n typeof observerOrNext === 'function'\n ? observerOrNext\n : (observerOrNext.next?.bind(observerOrNext) ?? ((_: T) => {}));\n const unsubscribe = obs.subscribe(v => zoneRun(() => next(v)));\n return { unsubscribe };\n },\n pipe(...operators) {\n return operators.reduce((acc, op) => op(acc), this as RxJSLike<unknown>);\n },\n };\n };\n}\n\n// ══════════════════════════════════════════════════════════════════════════════\n// Real Angular DI (requires @angular/core; @angular/router for guards)\n//\n// The string tokens and bridges above are kept for backward compatibility and\n// for zero-Angular environments. The exports below are the recommended,\n// idiomatic API for Angular 17+ apps: a typed InjectionToken, a signal bridge,\n// a functional route guard, and an HttpInterceptorFn.\n// ══════════════════════════════════════════════════════════════════════════════\n\n// ── Typed injection token ──────────────────────────────────────────────────────\n\n/**\n * Typed InjectionToken for the JoopInstance. Prefer this over the string `JOOP`\n * token — it gives full type inference at the injection site.\n *\n * private joop = inject(JOOP_INSTANCE); // typed as JoopInstance\n */\nexport const JOOP_INSTANCE = new InjectionToken<JoopInstance>('joopjs.JoopInstance');\n\n/**\n * Angular providers for the JoopInstance keyed by the typed token (and the\n * legacy string tokens, so existing @Inject(JOOP_*) sites keep working).\n *\n * bootstrapApplication(AppComponent, {\n * providers: [...provideJoopAngular(await createJoop(config))],\n * });\n */\nexport function provideJoopAngular(instance: JoopInstance): Provider[] {\n return [\n { provide: JOOP_INSTANCE, useValue: instance },\n ...provideJoop(instance),\n ];\n}\n\n/** Convenience for `inject(JOOP_INSTANCE)` — must run in an injection context. */\nexport function injectJoop(): JoopInstance {\n return inject(JOOP_INSTANCE);\n}\n\n// ── Signal bridge ──────────────────────────────────────────────────────────────\n\nexport interface JoopSignalOptions {\n /** Injector to resolve DestroyRef from when called outside an injection context. */\n injector?: Injector;\n /** Explicit teardown ref — bypasses DestroyRef resolution (handy in tests). */\n destroyRef?: Pick<DestroyRef, 'onDestroy'>;\n}\n\n/**\n * Bridges a JoopObservable into an Angular signal. The signal seeds with the\n * observable's current value (for JoopBehaviorSubject-backed streams) and\n * updates on every emission. The subscription is torn down automatically via\n * DestroyRef when the owning component/service is destroyed.\n *\n * readonly balance = joopSignal(this.joop.wallet.balance$());\n * // template: {{ balance() }}\n *\n * Call from an injection context (field initializer / constructor), or pass an\n * `injector`/`destroyRef` explicitly.\n */\nexport function joopSignal<T>(\n source: JoopObservable<T>,\n options: JoopSignalOptions = {},\n): Signal<T | undefined> {\n const seed = source.getOnce();\n const sig = signal<T | undefined>(seed);\n const unsubscribe = source.subscribe(v => sig.set(v));\n\n const destroyRef =\n options.destroyRef ?? options.injector?.get(DestroyRef) ?? inject(DestroyRef);\n destroyRef.onDestroy(() => unsubscribe());\n\n return sig.asReadonly();\n}\n\n// ── Functional route guard ──────────────────────────────────────────────────────\n\nexport interface JoopAuthGuardOptions {\n /** Where to redirect when not authenticated. Default: '/login'. */\n redirectTo?: string;\n}\n\n/**\n * Functional CanActivateFn backed by JoopAuthService. Returns true when logged\n * in, otherwise a UrlTree redirecting to `redirectTo`.\n *\n * { path: 'account', canActivate: [joopAuthGuard()], component: AccountComponent }\n */\nexport function joopAuthGuard(options: JoopAuthGuardOptions = {}) {\n return () => {\n const joop = inject(JOOP_INSTANCE);\n if (joop.auth.isLoggedIn()) return true;\n return inject(Router).parseUrl(options.redirectTo ?? '/login');\n };\n}\n\n// ── HTTP interceptor ─────────────────────────────────────────────────────────────\n\nexport interface JoopAuthInterceptorOptions {\n /** Header name. Default: 'Authorization'. */\n header?: string;\n /** Token scheme prefix. Default: 'Bearer'. Pass '' for a bare token. */\n scheme?: string;\n}\n\n/**\n * Functional HttpInterceptorFn that attaches the current access token from\n * JoopTokenService to outgoing requests.\n *\n * provideHttpClient(withInterceptors([joopAuthInterceptor()]))\n */\nexport function joopAuthInterceptor(options: JoopAuthInterceptorOptions = {}): HttpInterceptorFn {\n const header = options.header ?? 'Authorization';\n const scheme = options.scheme ?? 'Bearer';\n return (req, next) => {\n const token = inject(JOOP_INSTANCE).token.getAccessToken();\n if (!token) return next(req);\n const value = scheme ? `${scheme} ${token}` : token;\n return next(req.clone({ setHeaders: { [header]: value } }));\n };\n}\n"]}
@@ -1,3 +1,6 @@
1
+ import { InjectionToken, inject, signal, DestroyRef } from '@angular/core';
2
+ import { Router } from '@angular/router';
3
+
1
4
  // src/angular/index.ts
2
5
  var JOOP = "JOOP_INSTANCE";
3
6
  var JOOP_AUTH = "JOOP_AUTH";
@@ -95,7 +98,42 @@ function createZonedFromJoop(zoneRun) {
95
98
  };
96
99
  };
97
100
  }
101
+ var JOOP_INSTANCE = new InjectionToken("joopjs.JoopInstance");
102
+ function provideJoopAngular(instance) {
103
+ return [
104
+ { provide: JOOP_INSTANCE, useValue: instance },
105
+ ...provideJoop(instance)
106
+ ];
107
+ }
108
+ function injectJoop() {
109
+ return inject(JOOP_INSTANCE);
110
+ }
111
+ function joopSignal(source, options = {}) {
112
+ const seed = source.getOnce();
113
+ const sig = signal(seed);
114
+ const unsubscribe = source.subscribe((v) => sig.set(v));
115
+ const destroyRef = options.destroyRef ?? options.injector?.get(DestroyRef) ?? inject(DestroyRef);
116
+ destroyRef.onDestroy(() => unsubscribe());
117
+ return sig.asReadonly();
118
+ }
119
+ function joopAuthGuard(options = {}) {
120
+ return () => {
121
+ const joop = inject(JOOP_INSTANCE);
122
+ if (joop.auth.isLoggedIn()) return true;
123
+ return inject(Router).parseUrl(options.redirectTo ?? "/login");
124
+ };
125
+ }
126
+ function joopAuthInterceptor(options = {}) {
127
+ const header = options.header ?? "Authorization";
128
+ const scheme = options.scheme ?? "Bearer";
129
+ return (req, next) => {
130
+ const token = inject(JOOP_INSTANCE).token.getAccessToken();
131
+ if (!token) return next(req);
132
+ const value = scheme ? `${scheme} ${token}` : token;
133
+ return next(req.clone({ setHeaders: { [header]: value } }));
134
+ };
135
+ }
98
136
 
99
- export { JOOP, JOOP_ALERT, JOOP_ANALYTICS, JOOP_AUDIT_LOG, JOOP_AUTH, JOOP_FEATURE_FLAGS, JOOP_HTTP, JOOP_I18N, JOOP_KEY_VAULT, JOOP_LIFECYCLE, JOOP_LOADER, JOOP_NETWORK, JOOP_ROUTER, JOOP_STORE, JOOP_THEME, JoopModule, createZonedFromJoop, fromJoop, provideJoop, toJoop };
137
+ export { JOOP, JOOP_ALERT, JOOP_ANALYTICS, JOOP_AUDIT_LOG, JOOP_AUTH, JOOP_FEATURE_FLAGS, JOOP_HTTP, JOOP_I18N, JOOP_INSTANCE, JOOP_KEY_VAULT, JOOP_LIFECYCLE, JOOP_LOADER, JOOP_NETWORK, JOOP_ROUTER, JOOP_STORE, JOOP_THEME, JoopModule, createZonedFromJoop, fromJoop, injectJoop, joopAuthGuard, joopAuthInterceptor, joopSignal, provideJoop, provideJoopAngular, toJoop };
100
138
  //# sourceMappingURL=index.mjs.map
101
139
  //# sourceMappingURL=index.mjs.map