@forgerock/sdk-oidc 1.3.0 → 2.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.
@@ -0,0 +1,475 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for src/lib/wellknown.effects.ts</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../../prettify.css" />
9
+ <link rel="stylesheet" href="../../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/lib</a> wellknown.effects.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">100% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>60/60</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">100% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>19/19</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">100% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>5/5</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">100% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>60/60</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line high'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
197
+ <span class="cline-any cline-neutral">&nbsp;</span>
198
+ <span class="cline-any cline-neutral">&nbsp;</span>
199
+ <span class="cline-any cline-neutral">&nbsp;</span>
200
+ <span class="cline-any cline-neutral">&nbsp;</span>
201
+ <span class="cline-any cline-neutral">&nbsp;</span>
202
+ <span class="cline-any cline-neutral">&nbsp;</span>
203
+ <span class="cline-any cline-neutral">&nbsp;</span>
204
+ <span class="cline-any cline-neutral">&nbsp;</span>
205
+ <span class="cline-any cline-neutral">&nbsp;</span>
206
+ <span class="cline-any cline-neutral">&nbsp;</span>
207
+ <span class="cline-any cline-neutral">&nbsp;</span>
208
+ <span class="cline-any cline-neutral">&nbsp;</span>
209
+ <span class="cline-any cline-neutral">&nbsp;</span>
210
+ <span class="cline-any cline-neutral">&nbsp;</span>
211
+ <span class="cline-any cline-neutral">&nbsp;</span>
212
+ <span class="cline-any cline-neutral">&nbsp;</span>
213
+ <span class="cline-any cline-neutral">&nbsp;</span>
214
+ <span class="cline-any cline-neutral">&nbsp;</span>
215
+ <span class="cline-any cline-neutral">&nbsp;</span>
216
+ <span class="cline-any cline-neutral">&nbsp;</span>
217
+ <span class="cline-any cline-neutral">&nbsp;</span>
218
+ <span class="cline-any cline-neutral">&nbsp;</span>
219
+ <span class="cline-any cline-neutral">&nbsp;</span>
220
+ <span class="cline-any cline-neutral">&nbsp;</span>
221
+ <span class="cline-any cline-neutral">&nbsp;</span>
222
+ <span class="cline-any cline-neutral">&nbsp;</span>
223
+ <span class="cline-any cline-neutral">&nbsp;</span>
224
+ <span class="cline-any cline-neutral">&nbsp;</span>
225
+ <span class="cline-any cline-neutral">&nbsp;</span>
226
+ <span class="cline-any cline-neutral">&nbsp;</span>
227
+ <span class="cline-any cline-neutral">&nbsp;</span>
228
+ <span class="cline-any cline-neutral">&nbsp;</span>
229
+ <span class="cline-any cline-yes">3x</span>
230
+ <span class="cline-any cline-yes">3x</span>
231
+ <span class="cline-any cline-yes">3x</span>
232
+ <span class="cline-any cline-yes">3x</span>
233
+ <span class="cline-any cline-yes">3x</span>
234
+ <span class="cline-any cline-yes">3x</span>
235
+ <span class="cline-any cline-yes">3x</span>
236
+ <span class="cline-any cline-yes">3x</span>
237
+ <span class="cline-any cline-neutral">&nbsp;</span>
238
+ <span class="cline-any cline-yes">10x</span>
239
+ <span class="cline-any cline-yes">10x</span>
240
+ <span class="cline-any cline-yes">10x</span>
241
+ <span class="cline-any cline-neutral">&nbsp;</span>
242
+ <span class="cline-any cline-neutral">&nbsp;</span>
243
+ <span class="cline-any cline-neutral">&nbsp;</span>
244
+ <span class="cline-any cline-neutral">&nbsp;</span>
245
+ <span class="cline-any cline-neutral">&nbsp;</span>
246
+ <span class="cline-any cline-neutral">&nbsp;</span>
247
+ <span class="cline-any cline-neutral">&nbsp;</span>
248
+ <span class="cline-any cline-neutral">&nbsp;</span>
249
+ <span class="cline-any cline-neutral">&nbsp;</span>
250
+ <span class="cline-any cline-yes">1x</span>
251
+ <span class="cline-any cline-yes">10x</span>
252
+ <span class="cline-any cline-yes">7x</span>
253
+ <span class="cline-any cline-yes">7x</span>
254
+ <span class="cline-any cline-yes">6x</span>
255
+ <span class="cline-any cline-yes">5x</span>
256
+ <span class="cline-any cline-neutral">&nbsp;</span>
257
+ <span class="cline-any cline-yes">10x</span>
258
+ <span class="cline-any cline-neutral">&nbsp;</span>
259
+ <span class="cline-any cline-neutral">&nbsp;</span>
260
+ <span class="cline-any cline-neutral">&nbsp;</span>
261
+ <span class="cline-any cline-neutral">&nbsp;</span>
262
+ <span class="cline-any cline-neutral">&nbsp;</span>
263
+ <span class="cline-any cline-neutral">&nbsp;</span>
264
+ <span class="cline-any cline-neutral">&nbsp;</span>
265
+ <span class="cline-any cline-neutral">&nbsp;</span>
266
+ <span class="cline-any cline-neutral">&nbsp;</span>
267
+ <span class="cline-any cline-neutral">&nbsp;</span>
268
+ <span class="cline-any cline-neutral">&nbsp;</span>
269
+ <span class="cline-any cline-neutral">&nbsp;</span>
270
+ <span class="cline-any cline-neutral">&nbsp;</span>
271
+ <span class="cline-any cline-neutral">&nbsp;</span>
272
+ <span class="cline-any cline-neutral">&nbsp;</span>
273
+ <span class="cline-any cline-neutral">&nbsp;</span>
274
+ <span class="cline-any cline-neutral">&nbsp;</span>
275
+ <span class="cline-any cline-neutral">&nbsp;</span>
276
+ <span class="cline-any cline-neutral">&nbsp;</span>
277
+ <span class="cline-any cline-neutral">&nbsp;</span>
278
+ <span class="cline-any cline-neutral">&nbsp;</span>
279
+ <span class="cline-any cline-yes">1x</span>
280
+ <span class="cline-any cline-yes">6x</span>
281
+ <span class="cline-any cline-yes">6x</span>
282
+ <span class="cline-any cline-yes">6x</span>
283
+ <span class="cline-any cline-yes">6x</span>
284
+ <span class="cline-any cline-neutral">&nbsp;</span>
285
+ <span class="cline-any cline-yes">6x</span>
286
+ <span class="cline-any cline-yes">6x</span>
287
+ <span class="cline-any cline-yes">6x</span>
288
+ <span class="cline-any cline-neutral">&nbsp;</span>
289
+ <span class="cline-any cline-yes">6x</span>
290
+ <span class="cline-any cline-yes">6x</span>
291
+ <span class="cline-any cline-yes">6x</span>
292
+ <span class="cline-any cline-yes">2x</span>
293
+ <span class="cline-any cline-yes">2x</span>
294
+ <span class="cline-any cline-yes">1x</span>
295
+ <span class="cline-any cline-yes">1x</span>
296
+ <span class="cline-any cline-yes">2x</span>
297
+ <span class="cline-any cline-yes">2x</span>
298
+ <span class="cline-any cline-yes">2x</span>
299
+ <span class="cline-any cline-yes">2x</span>
300
+ <span class="cline-any cline-yes">2x</span>
301
+ <span class="cline-any cline-yes">2x</span>
302
+ <span class="cline-any cline-yes">2x</span>
303
+ <span class="cline-any cline-yes">2x</span>
304
+ <span class="cline-any cline-neutral">&nbsp;</span>
305
+ <span class="cline-any cline-yes">6x</span>
306
+ <span class="cline-any cline-yes">1x</span>
307
+ <span class="cline-any cline-yes">1x</span>
308
+ <span class="cline-any cline-neutral">&nbsp;</span>
309
+ <span class="cline-any cline-yes">6x</span>
310
+ <span class="cline-any cline-yes">1x</span>
311
+ <span class="cline-any cline-yes">1x</span>
312
+ <span class="cline-any cline-yes">1x</span>
313
+ <span class="cline-any cline-yes">1x</span>
314
+ <span class="cline-any cline-yes">1x</span>
315
+ <span class="cline-any cline-yes">1x</span>
316
+ <span class="cline-any cline-yes">1x</span>
317
+ <span class="cline-any cline-yes">1x</span>
318
+ <span class="cline-any cline-yes">1x</span>
319
+ <span class="cline-any cline-yes">1x</span>
320
+ <span class="cline-any cline-yes">1x</span>
321
+ <span class="cline-any cline-neutral">&nbsp;</span>
322
+ <span class="cline-any cline-yes">2x</span>
323
+ <span class="cline-any cline-yes">6x</span>
324
+ <span class="cline-any cline-yes">6x</span>
325
+ <span class="cline-any cline-yes">6x</span>
326
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">/*
327
+ * Copyright (c) 2025 Ping Identity Corporation. All rights reserved.
328
+ *
329
+ * This software may be modified and distributed under the terms
330
+ * of the MIT license. See the LICENSE file for details.
331
+ */
332
+ &nbsp;
333
+ import type { WellknownResponse, GenericError } from '@forgerock/sdk-types';
334
+ &nbsp;
335
+ /**
336
+ * Structural types compatible with RTK Query's shapes.
337
+ * Defined locally to keep the effects layer framework-agnostic
338
+ * (no dependency on @reduxjs/toolkit).
339
+ */
340
+ &nbsp;
341
+ /** Compatible with RTK Query's FetchArgs. */
342
+ interface WellknownFetchArgs {
343
+ url: string;
344
+ headers: Record&lt;string, string&gt;;
345
+ }
346
+ &nbsp;
347
+ /** Compatible with RTK Query's FetchBaseQueryError. */
348
+ interface WellknownQueryError {
349
+ status: number | string;
350
+ data?: unknown;
351
+ error?: string;
352
+ }
353
+ &nbsp;
354
+ /** Compatible with RTK Query's QueryReturnValue. */
355
+ type WellknownQueryResult&lt;T&gt; =
356
+ | { data: T; error?: undefined; meta?: unknown }
357
+ | { data?: undefined; error: WellknownQueryError; meta?: unknown };
358
+ &nbsp;
359
+ function createError(message: string, status: number | string = 'unknown'): GenericError {
360
+ return {
361
+ error: 'Well-known configuration fetch failed',
362
+ message,
363
+ type: 'wellknown_error',
364
+ status,
365
+ };
366
+ }
367
+ &nbsp;
368
+ function isObject(value: unknown): value is Record&lt;string, unknown&gt; {
369
+ return typeof value === 'object' &amp;&amp; value !== null;
370
+ }
371
+ &nbsp;
372
+ /**
373
+ * Validates that the response contains the minimum required OIDC well-known fields.
374
+ *
375
+ * Checks for `issuer`, `authorization_endpoint`, and `token_endpoint` — the
376
+ * minimum subset needed by this SDK. Note that the full OpenID Connect
377
+ * Discovery 1.0 spec defines additional required fields that some providers
378
+ * may not include.
379
+ */
380
+ export function isValidWellknownResponse(data: unknown): data is WellknownResponse {
381
+ if (!isObject(data)) return false;
382
+ return (
383
+ typeof data.issuer === 'string' &amp;&amp;
384
+ typeof data.authorization_endpoint === 'string' &amp;&amp;
385
+ typeof data.token_endpoint === 'string'
386
+ );
387
+ }
388
+ &nbsp;
389
+ /** Callback type for the query builder — wraps RTK Query's `baseQuery`. */
390
+ type QueryCallback = (args: WellknownFetchArgs) =&gt; Promise&lt;WellknownQueryResult&lt;unknown&gt;&gt;;
391
+ &nbsp;
392
+ /**
393
+ * Creates a well-known query builder for use inside RTK Query `queryFn`.
394
+ *
395
+ * Constructs a request object from the URL, then exposes `applyQuery` to
396
+ * execute the request through the caller's `baseQuery`. Response validation
397
+ * uses {@link isValidWellknownResponse}.
398
+ *
399
+ * @param url - The well-known endpoint URL
400
+ * @returns A builder with `applyQuery(callback)` that returns a result compatible with RTK Query's `QueryReturnValue`
401
+ *
402
+ * @example
403
+ * ```typescript
404
+ * queryFn: async (url, _api, _extra, baseQuery) =&gt; {
405
+ * return initWellknownQuery(url).applyQuery(async (req) =&gt; await baseQuery(req));
406
+ * }
407
+ * ```
408
+ */
409
+ export function initWellknownQuery(url: string) {
410
+ const request: WellknownFetchArgs = {
411
+ url,
412
+ headers: { Accept: 'application/json' },
413
+ };
414
+ &nbsp;
415
+ return {
416
+ async applyQuery(callback: QueryCallback): Promise&lt;WellknownQueryResult&lt;WellknownResponse&gt;&gt; {
417
+ let result: WellknownQueryResult&lt;unknown&gt;;
418
+ &nbsp;
419
+ try {
420
+ result = await callback(request);
421
+ } catch (error) {
422
+ const message =
423
+ error instanceof Error
424
+ ? error.message
425
+ : 'An unknown error occurred during well-known fetch';
426
+ return {
427
+ error: {
428
+ status: 'CUSTOM_ERROR',
429
+ error: message,
430
+ data: createError(message),
431
+ },
432
+ };
433
+ }
434
+ &nbsp;
435
+ if (result.error) {
436
+ return { error: result.error };
437
+ }
438
+ &nbsp;
439
+ if (!isValidWellknownResponse(result.data)) {
440
+ return {
441
+ error: {
442
+ status: 'CUSTOM_ERROR',
443
+ error:
444
+ 'Invalid well-known response: missing required fields (issuer, authorization_endpoint, token_endpoint)',
445
+ data: createError(
446
+ 'Invalid well-known response: missing required fields (issuer, authorization_endpoint, token_endpoint)',
447
+ ),
448
+ },
449
+ };
450
+ }
451
+ &nbsp;
452
+ return { data: result.data };
453
+ },
454
+ };
455
+ }
456
+ &nbsp;</pre></td></tr></table></pre>
457
+
458
+ <div class='push'></div><!-- for sticky footer -->
459
+ </div><!-- /wrapper -->
460
+ <div class='footer quiet pad2 space-top1 center small'>
461
+ Code coverage generated by
462
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
463
+ at 2026-03-19T17:04:14.664Z
464
+ </div>
465
+ <script src="../../prettify.js"></script>
466
+ <script>
467
+ window.onload = function () {
468
+ prettyPrint();
469
+ };
470
+ </script>
471
+ <script src="../../sorter.js"></script>
472
+ <script src="../../block-navigation.js"></script>
473
+ </body>
474
+ </html>
475
+
@@ -1,3 +1,4 @@
1
1
  export * from './lib/authorize.effects.js';
2
2
  export * from './lib/state-pkce.effects.js';
3
+ export * from './lib/wellknown.effects.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAMA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAOA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC"}
package/dist/src/index.js CHANGED
@@ -6,3 +6,4 @@
6
6
  */
7
7
  export * from './lib/authorize.effects.js';
8
8
  export * from './lib/state-pkce.effects.js';
9
+ export * from './lib/wellknown.effects.js';
@@ -0,0 +1,60 @@
1
+ import type { WellknownResponse } from '@forgerock/sdk-types';
2
+ /**
3
+ * Structural types compatible with RTK Query's shapes.
4
+ * Defined locally to keep the effects layer framework-agnostic
5
+ * (no dependency on @reduxjs/toolkit).
6
+ */
7
+ /** Compatible with RTK Query's FetchArgs. */
8
+ interface WellknownFetchArgs {
9
+ url: string;
10
+ headers: Record<string, string>;
11
+ }
12
+ /** Compatible with RTK Query's FetchBaseQueryError. */
13
+ interface WellknownQueryError {
14
+ status: number | string;
15
+ data?: unknown;
16
+ error?: string;
17
+ }
18
+ /** Compatible with RTK Query's QueryReturnValue. */
19
+ type WellknownQueryResult<T> = {
20
+ data: T;
21
+ error?: undefined;
22
+ meta?: unknown;
23
+ } | {
24
+ data?: undefined;
25
+ error: WellknownQueryError;
26
+ meta?: unknown;
27
+ };
28
+ /**
29
+ * Validates that the response contains the minimum required OIDC well-known fields.
30
+ *
31
+ * Checks for `issuer`, `authorization_endpoint`, and `token_endpoint` — the
32
+ * minimum subset needed by this SDK. Note that the full OpenID Connect
33
+ * Discovery 1.0 spec defines additional required fields that some providers
34
+ * may not include.
35
+ */
36
+ export declare function isValidWellknownResponse(data: unknown): data is WellknownResponse;
37
+ /** Callback type for the query builder — wraps RTK Query's `baseQuery`. */
38
+ type QueryCallback = (args: WellknownFetchArgs) => Promise<WellknownQueryResult<unknown>>;
39
+ /**
40
+ * Creates a well-known query builder for use inside RTK Query `queryFn`.
41
+ *
42
+ * Constructs a request object from the URL, then exposes `applyQuery` to
43
+ * execute the request through the caller's `baseQuery`. Response validation
44
+ * uses {@link isValidWellknownResponse}.
45
+ *
46
+ * @param url - The well-known endpoint URL
47
+ * @returns A builder with `applyQuery(callback)` that returns a result compatible with RTK Query's `QueryReturnValue`
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * queryFn: async (url, _api, _extra, baseQuery) => {
52
+ * return initWellknownQuery(url).applyQuery(async (req) => await baseQuery(req));
53
+ * }
54
+ * ```
55
+ */
56
+ export declare function initWellknownQuery(url: string): {
57
+ applyQuery(callback: QueryCallback): Promise<WellknownQueryResult<WellknownResponse>>;
58
+ };
59
+ export {};
60
+ //# sourceMappingURL=wellknown.effects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wellknown.effects.d.ts","sourceRoot":"","sources":["../../../src/lib/wellknown.effects.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,iBAAiB,EAAgB,MAAM,sBAAsB,CAAC;AAE5E;;;;GAIG;AAEH,6CAA6C;AAC7C,UAAU,kBAAkB;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,uDAAuD;AACvD,UAAU,mBAAmB;IAC3B,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,oDAAoD;AACpD,KAAK,oBAAoB,CAAC,CAAC,IACvB;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9C;IAAE,IAAI,CAAC,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,mBAAmB,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAerE;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,iBAAiB,CAOjF;AAED,2EAA2E;AAC3E,KAAK,aAAa,GAAG,CAAC,IAAI,EAAE,kBAAkB,KAAK,OAAO,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;AAE1F;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM;yBAOf,aAAa,GAAG,OAAO,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;EAuC9F"}
@@ -0,0 +1,88 @@
1
+ /*
2
+ * Copyright (c) 2025 Ping Identity Corporation. All rights reserved.
3
+ *
4
+ * This software may be modified and distributed under the terms
5
+ * of the MIT license. See the LICENSE file for details.
6
+ */
7
+ function createError(message, status = 'unknown') {
8
+ return {
9
+ error: 'Well-known configuration fetch failed',
10
+ message,
11
+ type: 'wellknown_error',
12
+ status,
13
+ };
14
+ }
15
+ function isObject(value) {
16
+ return typeof value === 'object' && value !== null;
17
+ }
18
+ /**
19
+ * Validates that the response contains the minimum required OIDC well-known fields.
20
+ *
21
+ * Checks for `issuer`, `authorization_endpoint`, and `token_endpoint` — the
22
+ * minimum subset needed by this SDK. Note that the full OpenID Connect
23
+ * Discovery 1.0 spec defines additional required fields that some providers
24
+ * may not include.
25
+ */
26
+ export function isValidWellknownResponse(data) {
27
+ if (!isObject(data))
28
+ return false;
29
+ return (typeof data.issuer === 'string' &&
30
+ typeof data.authorization_endpoint === 'string' &&
31
+ typeof data.token_endpoint === 'string');
32
+ }
33
+ /**
34
+ * Creates a well-known query builder for use inside RTK Query `queryFn`.
35
+ *
36
+ * Constructs a request object from the URL, then exposes `applyQuery` to
37
+ * execute the request through the caller's `baseQuery`. Response validation
38
+ * uses {@link isValidWellknownResponse}.
39
+ *
40
+ * @param url - The well-known endpoint URL
41
+ * @returns A builder with `applyQuery(callback)` that returns a result compatible with RTK Query's `QueryReturnValue`
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * queryFn: async (url, _api, _extra, baseQuery) => {
46
+ * return initWellknownQuery(url).applyQuery(async (req) => await baseQuery(req));
47
+ * }
48
+ * ```
49
+ */
50
+ export function initWellknownQuery(url) {
51
+ const request = {
52
+ url,
53
+ headers: { Accept: 'application/json' },
54
+ };
55
+ return {
56
+ async applyQuery(callback) {
57
+ let result;
58
+ try {
59
+ result = await callback(request);
60
+ }
61
+ catch (error) {
62
+ const message = error instanceof Error
63
+ ? error.message
64
+ : 'An unknown error occurred during well-known fetch';
65
+ return {
66
+ error: {
67
+ status: 'CUSTOM_ERROR',
68
+ error: message,
69
+ data: createError(message),
70
+ },
71
+ };
72
+ }
73
+ if (result.error) {
74
+ return { error: result.error };
75
+ }
76
+ if (!isValidWellknownResponse(result.data)) {
77
+ return {
78
+ error: {
79
+ status: 'CUSTOM_ERROR',
80
+ error: 'Invalid well-known response: missing required fields (issuer, authorization_endpoint, token_endpoint)',
81
+ data: createError('Invalid well-known response: missing required fields (issuer, authorization_endpoint, token_endpoint)'),
82
+ },
83
+ };
84
+ }
85
+ return { data: result.data };
86
+ },
87
+ };
88
+ }